计算24小时内最大价格波动window

Calculate the maximum price fluctuation in a 24 hour window

我有一个包含两列的数据框 - 时间和价格。它包含在不同时间对特定商品价格的一系列观察。这是一个示例。

> df
                  time price
1  2014-12-12 14:57:15 45.81
2  2014-12-12 14:57:15 45.90
3  2014-12-12 15:00:08 45.76
4  2014-12-12 15:00:37 45.72
5  2014-12-12 15:00:49 45.73
6  2014-12-12 15:00:49 45.72
7  2014-12-12 15:00:49 45.76
8  2014-12-12 15:00:49 45.76
9  2014-12-12 15:00:50 45.78
10 2014-12-12 15:00:57 45.76
11 2014-12-12 15:00:57 45.76
12 2014-12-12 15:01:01 45.74
13 2014-12-12 15:01:01 45.74
14 2014-12-12 15:01:08 45.74
15 2014-12-12 15:01:08 45.74
16 2014-12-12 15:01:22 48.79
17 2014-12-12 15:01:23 45.72
18 2014-12-12 15:01:26 45.86
19 2014-12-12 15:01:50 45.72
20 2014-12-12 15:02:00 45.80

在每个观察点我想计算未来24小时内任一方向的最大价格波动window。

> max(df$price - df$price[1])
[1] 2.98
> min(df$price - df$price[1])
[1] -0.09

所以对于上面示例中的观察 1,最大波动是 2.98 和 -0.09。我可以写一个像

这样的函数
 fluc <- function(i) {
     c(max(df$price - df$price[i]), min(df$price - df$price[i]))
 }

并使用 lapply 但这将计算整个数据帧的差异。我想将计算限制在接下来的 24 小时内,因此对于不同的观察点,要计算的差异数量会有所不同。

我可以编写一个 n^2 函数来执行此操作,但是否有 R 友好的方法来实现此操作?理想情况下,我还希望出现最大波动的时间。

谢谢。

添加 dput 输出:

structure(list(time = structure(c(1418425035.677, 1418425035.677, 
1418425208.407, 1418425237.587, 1418425249.22, 1418425249.22, 
1418425249.38, 1418425249.38, 1418425250.64, 1418425257.97, 1418425257.97, 
1418425261.397, 1418425261.397, 1418425268.333, 1418425268.333, 
1418425282.207, 1418425283.403, 1418425286.083, 1418425310.893, 
1418425320.42), class = c("POSIXct", "POSIXt"), tzone = ""), 
    price = c(45.81, 45.9, 45.76, 45.72, 45.73, 45.72, 45.76, 
    45.76, 45.78, 45.76, 45.76, 45.74, 45.74, 45.74, 45.74, 48.79, 
    45.72, 45.86, 45.72, 45.8)), .Names = c("time", "price"), row.names = c(NA, 
20L), class = "data.frame")

我想它会起作用。我认为这不是最好的方法,但我知道您想玩弄数据。

            myFunc <- function(df, startDate, endDate) {
                df <- df[df$time > startDate & df$time <= endDate, ]
                gain <- as.numeric(NA)
                for(i in 2:nrow(df)) {
                    gain <- c(gain, df$price[i] - df$price[i-1])
                }

                max <- df[which(gain == max(gain, na.rm=TRUE)), ]
                min <- df[which(gain == min(gain, na.rm=TRUE)), ]
                list(max=max, min=min)
            }

            x <- myFunc(df, time[5], time[15])

这似乎有效。我试图将日期用作底部 window 截止日期,但后来重复添加 0 作为最小值,否则不会有其他情况。

as.POSIXct 可能不是必需的,具体取决于您的日期格式。我也用了60秒让它变得有趣

# create upper cutoff for each row
df$cutoff <- as.POSIXct(df$time) + 60 # 24 is 60*60*24

# a for loop works well too
result <- mapply(function(end,rowid,x){
  # create window, and return min/max
  window <- x[as.numeric(row.names(x)) >= rowid & x$time <= end,'price']
  c(min(window - window[1]),max(window - window[1]))
},end = df$cutoff,rowid = 1:nrow(df),MoreArgs = list(x = df[ ,c('time','price')]))

# do whatever with the result
cbind(df,t(result))

更新,包括最大波动时间:

df$cutoff <- as.POSIXct(df$time) + 60 # 24 is 60*60*24

result <- list()

for(i in 1:(nrow(df)-1)){
  # create window, add diffs, send matching window result
  window <- df[as.numeric(row.names(df)) >= i + 1 & df$time <= df$cutoff[i],c('time','price')]
  window$diffs <- window$price - window$price[1]
  result[[i]] <- (c(i,window[window$diffs == max(window$diffs), ],window[window$diffs == min(window$diffs), ]))
}

# prep data for merging
resultdf <- as.data.frame(do.call('rbind',result))
names(resultdf) <- c('i','maxtime','maxprice','maxdiff','mintime','minprice','mindiff')
df$rowid <- 1:nrow(df)

# merge
merge(df,resultdf,by.x = 'row.names',by.y = 'i',all.x = T,sort = F)

我的猜测是 *pply 函数不会使任何事情变得更优雅,因为每次迭代都需要起始行、主要行 data.frame 和最大行。预处理和矢量化可能会有所帮助。