【问题标题】:Rolling Max/Min/Sum for time series over last x Mins interval在过去 x 分钟间隔内滚动时间序列的最大/最小/总和
【发布时间】:2018-02-06 10:02:15
【问题描述】:

我有一个微秒精度的金融时间序列数据帧:

timestamp                    price  volume
2017-08-29 08:00:00.345678   99.1   10
2017-08-29 08:00:00.674566   98.2   5
....
2017-08-29 16:00:00.111234   97.0   3
2017-08-29 16:00:01.445678   96.5   5

总共:每天大约 10 万条记录。

我看到了几个可以指定滚动窗口宽度的函数,例如k = 10。但 k 表示为观察次数而不是分钟数。

我需要像这样计算价格系列的运行/滚动最大值、最小值和体积系列的运行/滚动总和:

  1. 从时间序列开始后 5 分钟的时间戳开始
  2. 对于随后的每个时间戳:回顾 5 分钟间隔和
  3. 计算滚动统计数据。

如何有效计算?

【问题讨论】:

    标签: r time-series


    【解决方案1】:

    当我在寻找反向计算时(从时间戳开始并向后看 5 分钟),我对 #CPak 的出色解决方案稍作修改,如下所示:

    mdf <- map(1:nrow(df), ~df[df$timestamp <= df[.x,]$timestamp & df$timestamp > df[.x,]$timestamp - timeinterval,])
    
    statdf <- map_df(mdf, ~.x %>% 
                          summarise(timestamp_to = tail(timestamp,1),
                                    timestamp_from = head(timestamp,1),
                                    max.price = max(price), 
                                    min.price = min(price),
                                    sum.volume = sum(volume),
                                    records = n()))
    

    另外,我添加了 records = n() 来查看间隔中使用了多少条记录。

    一个警告:在具有 100K+ 记录的数据集上,代码在 mdf 上需要 10 分钟,而在 statdf 上需要 6 分钟。

    任何想法如何优化它?谢谢!

    【讨论】:

      【解决方案2】:

      您的数据

      我无法捕捉毫秒(但该解决方案应该仍然有效)

      library(lubridate)
      df <- data.frame(timestamp = ymd_hms("2017-08-29 08:00:00.345678", "2017-08-29 08:00:00.674566", "2017-08-29 16:00:00.111234", "2017-08-29 16:00:01.445678"),
                       price=c(99.1, 98.2, 97.0, 96.5),
                       volume=c(10,5,3,5))
      

      purrr 和 dplyr 解决方案

      library(purrr)
      library(dplyr)
      timeinterval <- 5*60   # 5 minute
      

      过滤df在时间间隔内的观察,保存为列表

      mdf <- map(1:nrow(df), ~df[df$timestamp >= df[.x,]$timestamp & df$timestamp < df[.x,]$timestamp+timeinterval,])
      

      总结列表中的每个data.frame

      statdf <- map_df(mdf, ~.x %>% 
                                summarise(timestamp = head(timestamp,1),
                                          max.price = max(price), 
                                          max.volume = max(volume),
                                          sum.price = sum(price),
                                          sum.volume = sum(volume),
                                          min.price = min(price), 
                                          min.volume = min(volume)))
      

      输出

                      timestamp max.price max.volume sum.price sum.volume
      1 2017-08-29 08:00:00      99.1         10     197.3         15
      2 2017-08-29 08:00:00      98.2          5      98.2          5
      3 2017-08-29 16:00:00      97.0          5     193.5          8
      4 2017-08-29 16:00:01      96.5          5      96.5          5
        min.price min.volume
      1      98.2          5
      2      98.2          5
      3      96.5          3
      4      96.5          5
      

      【讨论】:

      • 是的,太好了!我稍微修改了您的代码,因为它“向前看”而不是向后看。将其作为单独的答案发布。在具有 100K+ 的数据集上,mdf 部分运行 10 分钟,statdf 再运行 6 分钟。也许有人会知道如何让它更快?
      • 要显示微秒,您需要按如下方式设置选项: opts
      猜你喜欢
      • 2016-08-31
      • 2016-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多