使用R中的Quantmod无法从Yahoo Finance下载数据

14

我正在尝试使用以下代码从Yahoo下载数据:

library(quantmod)
getSymbols("WOW", auto.assign=F)

在过去的每一个场合,这对我都起作用,但现在距离小组任务截止日期还有5天,却不行了。

现在我遇到了这个错误:

Error in download.file(paste(yahoo.URL, "s=", Symbols.name, "&a=", from.m,  : cannot download all files
In addition: Warning message:
In download.file(paste(yahoo.URL, "s=", Symbols.name, "&a=", from.m,  :
  URL 'https://ichart.finance.yahoo.com/table.csv?
s=WOW&a=0&b=01&c=2007&d=4&e=17&f=2017&g=d&q=q&y=0&z=WOW&x=.csv': status was 
'502 Bad Gateway'

2
这是雅虎服务器目前存在的问题。您只能等待他们修复,或使用其他数据源。 - neilfws
@neilws 啊,没错,我仍然可以从网站下载历史数据吗?你在下载数据方面有类似的问题吗? - Daniel
2
您可以从此处下载CSV文件:https://finance.yahoo.com/quote/WOW.AX/history?p=WOW.AX - neilfws
是的,没错。但是将其导入R并使用quantmod处理数据需要付出很多努力。我想我会等待它重新上线。 - Daniel
即使采取了解决方法,雅虎的免费数据源也变得越来越不可靠。 现在似乎下载的数据中的“Adj Close”列实际上没有被调整。 我想知道是否有适度价格的历史数据源,其API可以从R中调用? - ted thedog
显示剩余2条评论
6个回答

11

价格历史记录的CSV网址似乎已更改。

旧版: https://chart.finance.yahoo.com/table.csv?s=AAPL&a=2&b=17&c=2017&d=3&e=17&f=2017&g=d&ignore=.csv

新版: https://query1.finance.yahoo.com/v7/finance/download/AAPL?period1=1492438581&period2=1495030581&interval=1d&events=history&crumb=XXXXXXX

新版本附加了一个“crumb”字段,似乎反映用户浏览器中的cookie信息。它似乎是有意阻止价格历史记录的自动下载,并强制查询提供信息以验证Web浏览器中的Cookie。


2
酷,那么我该如何从新的URL下载数据? - Daniel

9

谢谢!但是我还是不能让它工作。当我尝试运行代码时,会出现以下错误:错误:命令失败(1)我对R编程非常新手。这是我到目前为止的代码:library(quantmod) library(curl) remotes::install_github("joshuaulrich/quantmod") # 或者 devtools::install_github("joshuaulrich/quantmod") getSymbols("WOW", auto.assign = F) - Daniel
没问题,我解决了!对于未来阅读此内容的任何人,我必须使用我的Windows电脑并安装Devtools。然后只需运行这些代码行,它就会开始工作。 - Daniel

3

quantmod 0.4-9版本已修复此问题,现在可以在CRAN上获取。


2

我一直想知道为什么雅虎会提供数据下载功能,如果他们停止这样做,我将会有多大的困难。幸运的是,Joshua Ulrich提供了帮助。

尽管现在可能已经没有意义,但我编写了一个修复程序,展示了解决下载问题的一种方法。

library(xts)
getSymbols.yahoo.fix <- function (symbol, 
                                  from       = "2007-01-01", 
                                  to         = Sys.Date(), 
                                  period     = c("daily","weekly","monthly"),
                                  envir      = globalenv(),
                                  crumb      = "YourCrumb",
                                  DLdir      = "~/Downloads/") { #1
     # build yahoo query
     query1    <- paste("https://query1.finance.yahoo.com/v7/finance/download/",symbol,"?",sep="")
     fromPosix <- as.numeric(as.POSIXlt(from))
     toPosix   <- as.numeric(as.POSIXlt(to))
     query2    <- paste("period1=", fromPosix, "&period2=", toPosix, sep = "")
     interval  <- switch(period[1], daily = "1d", weekly = "1wk", monthly = "1mo")
     query3    <- paste("&interval=", interval, "&events=history&crumb=", crumb, sep = "")
     yahooURL  <- paste(query1, query2, query3, sep = "")
     #' requires browser to be open
     utils::browseURL("https://www.google.com")
     #' run the query - downloads the security as a csv file
     #' DLdir defaults to download directory in browser preferences
     utils::browseURL(yahooURL)
     #' wait 500 msec for download to complete - mileage may vary
     Sys.sleep(time = 0.5)
     yahooCSV  <- paste(DLdir, symbol, ".csv", sep = "")
     yahooDF   <- utils::read.csv(yahooCSV, header = TRUE)
     #' ------- 
     #' if you get: Error in file(file, "rt") : cannot open the connection
     #' it's because the csv file has not completed downloading
     #' try increasing the time for Sys.sleep(time = x)
     #' ------- 
     #' delete the csv file
     file.remove(yahooCSV)
     # convert date as character to date format
     yahooDF$Date <- as.Date(yahooDF$Date)
     # convert to xts
     yahoo.xts    <- xts(yahooDF[,-1],order.by=yahooDF$Date)
     # assign the xts file to the specified environment
     # default is globalenv()
     assign(symbol, yahoo.xts, envir = as.environment(envir))
     print(symbol)
} #1

它的工作方式如下:
  • 访问https://finance.yahoo.com/quote/AAPL/history?p=AAPL
  • 右键单击“下载数据”并复制链接
  • 复制“&crumb=”后面的碎片,并在函数调用中使用它
  • 将DLdir设置为浏览器首选项中的默认下载目录
  • 将envir = as.environment("yourEnvir")设置为默认值globalenv()
  • 下载后,CSV文件将从您的下载目录中删除,以避免混乱
  • 请注意,这将在浏览器中留下一个未命名的窗口
  • 作为简单的测试:getSymbols.yahoo.fix("AAPL")
  • -

您还可以使用getSymbols.yahoo.fix和lapply一起使用,以获取资产数据列表

from       <- "2016-04-01"
to         <- Sys.Date()
period     <- "daily"
envir      <- globalenv()
crumb      <- "yourCrumb"
DLdir      <- "~/Downloads/"
assetList  <- c("AAPL", "ADBE", "AMAT")
lapply(assetList, getSymbols.yahoo.fix, from, to, envir = globalenv(), crumb = crumb, DLdir)}

该代码是在Mac OSX 10.11上使用Safari作为默认浏览器的RStudio中编写的。它似乎也可以与Chrome一起使用,但您需要使用Chrome的cookie crumb。我使用了一个cookie阻止器,但必须将finance.yahoo.com列入白名单,以保留cookie供将来的浏览器会话使用。

getSymbols.yahoo.fix可能非常有用。quantmod::getSymbols出于必要性,具有更多内置的选项和异常处理代码。我编写个人工作的代码,因此我经常从软件包函数中提取我需要的那些代码片段。我还没有对getSymbols.yahoo.fix进行基准测试,因为我当然没有GetSymbol的工作版本可供比较。此外,我不能放过进入我的第一个stackoverflow答案的机会。


1

我也遇到了这个错误。Mrexcel论坛上的用户(jonathanwang003)解释说,新的URL使用Unix时间编码来表示日期。更新后的VBA代码应该是这样的:

qurl = "https://query1.finance.yahoo.com/v7/finance/download/" & Symbol
qurl = qurl & "?period1=" & (StartDate - DateSerial(1970, 1, 1)) * 86400 & _
       "&period2=" & (EndDate - DateSerial(1970, 1, 1)) * 86400 & _
       "&interval=1d&events=history&crumb=" & **Crumb**

QueryQuote:
With Sheets(Symbol).QueryTables.Add(Connection:="URL;" & qurl, Destination:=Sheets(Symbol).Range("a1"))
    .BackgroundQuery = True
    .TablesOnlyFromHTML = False
    .Refresh BackgroundQuery:=False
    .SaveData = True
End With

这里缺少的部分是如何从浏览器中检索包含cookie信息的"Crumb"字段。大家有什么想法吗?我发现了这篇帖子,可能会有所帮助:https://www.mrexcel.com/forum/excel-questions/1001259-when-using-querytables-what-posttext-syntax-click-button-webpage.html(查看john_w的最后一篇文章)。

-1

它还接受 Unix 时间戳格式的输入日期,enddate 是可选的。您可以使用“new SimpleDateFormat("dd-MMM-yy", Locale.ENGLISH)”解析输出日期。 - Melinda Green
谷歌财经的问题在于有时无法识别股票符号。有时需要我们知道cid,即使知道了之后,有时仍然无法正确下载... - Lex L

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