如何使用R下载股票市场的日内交易数据

21

大家好,

我想要从Yahoo或Google下载股票数据,时间间隔为15到60分钟,尽可能多地获取历史数据。我已经想出了一个简单的解决方案,如下所示:

library(RCurl)
tmp <- getURL('https://www.google.com/finance/getprices?i=900&p=1000d&f=d,o,h,l,c,v&df=cpct&q=AAPL')
tmp <- strsplit(tmp,'\n')
tmp <- tmp[[1]]
tmp <- tmp[-c(1:8)]
tmp <- strsplit(tmp,',')
tmp <- do.call('rbind',tmp)
tmp <- apply(tmp,2,as.numeric)
tmp <- tmp[-apply(tmp,1,function(x) any(is.na(x))),]

考虑到我想要导入的数据量很大,我担心这可能会带来计算上的负担。而且我完全不明白Yahoo和Google中的时间戳是如何编码的。

所以我的问题有两个方面——有什么简单、优雅的方法可以快速将一系列股票的数据导入到R中,以及如何解释我将使用的Google/Yahoo文件中的时间戳?


当我尝试使用getURL时,它会给我授权失败。我一直在为一些拍卖网站使用它,并且使用Emacs应用程序的函数来定时运行代码。它甚至可以在您编写代码时为您编辑文本。我不知道时间部分是否仍未解决? - PascalVKooten
4个回答

22

首先,我将尝试回答时间戳的问题。请注意,这是我的解释,我可能会有所错误。

使用您示例中的链接https://www.google.com/finance/getprices?i=900&p=1000d&f=d,o,h,l,c,v&df=cpct&q=AAPL,我获得以下数据:

EXCHANGE%3DNASDAQ
MARKET_OPEN_MINUTE=570
MARKET_CLOSE_MINUTE=960
INTERVAL=900
COLUMNS=DATE,CLOSE,HIGH,LOW,OPEN,VOLUME
DATA=
TIMEZONE_OFFSET=-300
a1357828200,528.5999,528.62,528.14,528.55,129259
1,522.63,528.72,522,528.6499,2054578
2,523.11,523.69,520.75,522.77,1422586
3,520.48,523.11,519.6501,523.09,1130409
4,518.28,520.579,517.86,520.34,1215466
5,518.8501,519.48,517.33,517.94,832100
6,518.685,520.22,518.63,518.85,565411
7,516.55,519.2,516.55,518.64,617281
...
...

请注意第一列的第一个值a1357828200,我有直觉这与POSIXct有关。因此进行了快速检查:

> as.POSIXct(1357828200, origin = '1970-01-01', tz='EST')
[1] "2013-01-10 14:30:00 EST"

所以我的直觉似乎是正确的。但时间似乎有误差。现在我们在数据中有一个更多的信息。TIMEZONE_OFFSET=-300。因此,如果我们将我们的时间戳按这个数量进行偏移,我们应该得到:

as.POSIXct(1357828200-300*60, origin = '1970-01-01', tz='EST')
[1] "2013-01-10 09:30:00 EST"

请注意,我不知道您请求的数据是哪一天。但是在谷歌财经上快速检查发现,这些确实是2013年1月10日的价格水平。

enter image description here

第一列中剩余的值似乎都是相对于第一行值的某种偏移量。


好问题。好答案!几天前我意识到这个谷歌财经API不再起作用了。所以当我复制粘贴你的答案/问题链接时,如果我在谷歌搜索栏中输入“AAPL”,我会被转到标准的谷歌搜索结果页面。有人有解决方案吗?或者有一个新的网址我还没有找到吗?谢谢。 - maxatSOflow

3
下载和规范化数据比我想象的要困难得多,需要大约150行代码。问题在于,虽然谷歌为所有交易所交易的股票提供了过去50个交易日的数据,但是这些交易日内的时间戳并不是标准化的:例如,索引“1”可能指的是数据集中第一个交易日上的第一或第二个时间增量。更糟糕的是,低交易量的股票只有在记录交易时才有条目。对于像APPL这样的高交易量股票来说,这并不是问题,但对于低交易量的小市值股票来说,这意味着你的系列将缺少很多甚至大部分的数据。这是有问题的,因为我需要所有的股票系列整齐地排列在分析所需的位置。
幸运的是,数据仍然有一个普遍的结构。使用这个链接:
https://www.google.com/finance/getprices?i=1800&p=1000d&f=d,o,h,l,c,v&df=cpct&q=AAPL 

更改股票代码并在结尾处将其转换,即可获得过去50个交易日的数据,每半小时为一个增量。时间戳以POSIX格式显示在时间戳列中,由@geektrader提供了很好的解码方法,并且每3周显示一次。虽然时间戳索引不总是方便地对应1:1(我几乎怀疑这是谷歌故意的),但存在某种模式。例如,在我查看的半小时系列中,每个三周增量的第一个交易日都有时间戳索引在1:15附近运行。这可能是1:13、1:14、2:15-这完全取决于股票。我不确定第14和15条目是什么:我怀疑它们要么是每日摘要,要么是盘后交易信息。关键是没有可靠的模式可以依赖。遗憾的是,训练日的第一个标记并不总是包含开盘数据,最后一个条目也是如此。我发现唯一知道实际上代表交易数据的方法是将数字与Google Maps上的系列进行比较。经过数天试图从数据中推导出1:1映射模式而毫无结果后,我采用了“大致”策略。我抓取了APPL的数据(一个非常高交易量的股票),并将其每个交易日的时间戳索引设置为整个市场的参考值。所有日期都有至少13个增量,对应于6.5小时的交易日,但有些有14或15个。在这种情况下,我只取前13个索引。从那里开始,我使用while循环来逐步处理每个股票代码的下载数据,并将其在给定训练日内的时间戳索引与APPL时间戳进行比较。我保留了重叠部分,填补了缺失的数据,并剪切掉了不重叠的部分。
听起来像是一个简单的修复,但对于交易数据稀疏的低交易量股票,我必须加入几十个特殊情况,并且需要插值大量数据。对于一些我知道不正确的情况,我得到了一些非常奇怪的结果。然而,对于高交易量、中型和大型市值股票,这种解决方案非常有效:在大多数情况下,系列要么非常整齐地与APPL数据同步,并完美地匹配它们在Google Finance档案中的资料。
无论如何,这种方法都会引入一些误差,我仍然需要为小市值股票微调该方法。尽管如此,将系列移动半小时或填补单个时间增量只会引入非常小的误差,相对于市场和股票的整体运动而言。我有信心认为这个数据集足够“好”,可以让我得到一些相关问题的答案。商业获取这些数据实际上需要成千上万美元。
您有什么想法或建议吗?

1
交互经纪商不需要花费数千美元,您可以获得数千只股票、债券、期货、外汇、期权等的盘中数据。请参阅IBrokers包和我的twsInstrument包。其他想法请参考:https://stat.ethz.ch/pipermail/r-sig-finance/2013q1/011417.html。 - GSee
这看起来不错。您需要一个ibrokers账户来实现这些包,对吗?目前我使用的是Optionshouse,短期内将需要依靠我的解决方案来爬取Google。然而,持续访问高分辨率数据可能会成为另一个切换的动力。 - aaron
是的,您需要一个IB账户。我想每个月有大约$10-$20的维护费,但如果您在佣金上花费了这么多,则可以免除此费用。 - GSee
明白了,谢谢。在我设置IB之前,似乎爬取Google或Yahoo的数据是最好的选择。这些都是很好的指针。事实上,有R包可以让用户与IB的数据流进行交互,这非常酷! - aaron

1

对于时区偏移量,请尝试:

as.POSIXct(1357828200, origin = '1970-01-01', tz=Sys.timezone(location = TRUE))

(该时区将根据您的位置自动调整)


这是一个旧问题,已经有一个被接受的答案。您能否补充说明为什么您的答案更好/不同? - Peter Szekeli
这是一个国际性的答案。在as.POSIXct函数中不需要调整时区。(通过添加tz=Sys.timezone(location = TRUE)) - sempedocles

1

为什么不从Quandl加载数据呢?例如:

library(Quandl)
Quandl('YAHOO/AAPL')

更新:抱歉,我刚刚意识到 Quandl 只提供每日数据获取 - 但是我还是保留我的答案,因为 Quandl 在类似情况下查询非常容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接