将 Google 金融股票数据中的时间戳转换为正确的日期时间

Convert timestamps in Google Finance stock data to proper datetime

我正在尝试将股票数据中的时间戳从 Google 金融 API 转换为更有用的日期时间格式。

我已经用data.table::fread读取了数据here:

fread(<url>)

      datetime    open     high      low    close  volume
1: a1497619800 154.230 154.2300 154.2300 154.2300     500
2:           1 153.720 154.3200 153.7000 154.2500 1085946
3:           2 153.510 153.8000 153.2000 153.7700   34882
4:           3 153.239 153.4800 153.1400 153.4800   24343
5:           4 153.250 153.3000 152.9676 153.2700   20212

如您所见,“日期时间”格式很奇怪。格式在此 link:

中描述

The full timestamps are denoted by the leading 'a'. Like this: a1092945600. The number after the 'a' is a Unix timestamp. [...]

The numbers without a leading 'a' are "intervals". So, for example, the second row in the data set below has an interval of 1. You can multiply this number by our interval size [...] and add it to the last Unix Timestamp.

在我的例子中,“间隔大小”是 300 秒(5 分钟)。此格式在每个新的一天开始时重新启动,因此尝试格式化它非常困难!

我可以通过使用 grep 并搜索“a”来提取一天开始的索引位置;

newDay <- grep(df$V1, pattern = "a") 

然后我的想法是根据索引位置将数据帧分成块,然后分别延长每一天的 unix 时间,然后在存储之前将它们组合回 data.table。

data.table::split 看起来它会完成这项工作,但我不确定如何为它提供休息时间以按索引位置拆分,或者是否有更合乎逻辑的方法来实现相同的结果而不必须将其分解为每一天。

谢谢。

与:

DT[grep('^a', date), datetime := as.integer(gsub('\D+','',date))
   ][, datetime := zoo::na.locf(datetime)
     ][nchar(date) < 4, datetime := datetime + (300 * as.integer(date))
       ][, datetime := as.POSIXct(datetime, origin = '1970-01-01', tz = 'America/New_York')][]

你得到:

             date  close     high    low     open volume            datetime
   1: a1500298200 153.57 153.7100 153.57 153.5900   1473 2017-07-17 09:30:00
   2:           1 153.51 153.8700 153.33 153.7500 205057 2017-07-17 09:35:00
   3:           2 153.49 153.7800 153.34 153.5800  70023 2017-07-17 09:40:00
   4:           3 153.68 153.7300 153.42 153.5400  53050 2017-07-17 09:45:00
   5:           4 153.06 153.7500 153.06 153.7200 120899 2017-07-17 09:50:00
  ---                                                                       
2348:         937 143.94 144.0052 143.91 143.9917  36651 2017-08-25 15:40:00
2349:         938 143.90 143.9958 143.90 143.9400  40769 2017-08-25 15:45:00
2350:         939 143.94 143.9500 143.87 143.8900  56616 2017-08-25 15:50:00
2351:         940 143.97 143.9700 143.89 143.9400  56381 2017-08-25 15:55:00
2352:         941 143.74 143.9700 143.74 143.9655 179811 2017-08-25 16:00:00

已用数据:

DT <- fread('https://www.google.com/finance/getprices?i=300&p=30d&f=d,t,o,h,l,c,v&df=cpct&q=IBM', skip = 7, header = FALSE)
setnames(DT, 1:6, c('date','close','high','low','open','volume'))

您可以使用 grepl 在 "datetime" 中搜索 "a",这会产生一个布尔向量。 cumsum 用于创建分组变量的布尔值 - 对于每个 "a" (TRUE),计数器将增加一个。

在每个组中,使用适当的 formatorigin(以及时区 tz?)将第一个元素转换为 POSIXct。添加 'interval size' 的倍数(300 秒),第一个元素使用零,其他元素使用 "datetime" 的倍数。

d[ , time := {
  t1 <- as.POSIXct(datetime[1], format = "a%s", origin = "1970-01-01")
  .(t1 + c(0, as.numeric(datetime[-1]) * 300))
}
, by = .(cumsum(grepl("^a", datetime)))]

d
#       datetime                time
# 1: a1497619800 2017-06-16 15:30:00
# 2:           1 2017-06-16 15:35:00
# 3:           2 2017-06-16 15:40:00
# 4:           3 2017-06-16 15:45:00
# 5:           4 2017-06-16 15:50:00
# 6: a1500000000 2017-07-14 04:40:00
# 7:           3 2017-07-14 04:55:00
# 8:           5 2017-07-14 05:05:00
# 9:           7 2017-07-14 05:15:00

一些玩具数据:

d <- fread(input = "datetime    
a1497619800 
          1 
          2 
           3 
           4
a1500000000
3
5
7")