R语言Quantmod下载Yahoo Finance期权链报错及修复分支安装失败求助
解决Quantmod获取期权链的401错误及修复分支安装失败问题
问题根源
- 401 Unauthorized错误是因为Yahoo Finance的API接口更新了权限验证规则,旧版Quantmod的请求方式不再被允许,导致
getOptionChain拉不到数据,进而触发后续的数值运算错误(Error in Exp/86400 : non-numeric argument to binary operator)。 - 安装修复分支失败基本是网络访问限制,没法连接到GitHub的API地址。
可行解决方案
方案一:手动替换getOptionChain函数
直接用修复分支里的修正代码覆盖原函数,不用折腾GitHub安装:
- 先加载quantmod:
library(quantmod) - 确保安装了
httr和jsonlite包,没装的话先跑:install.packages(c("httr", "jsonlite")) - 复制以下完整的修复后函数代码到R控制台运行:
getOptionChain <- function(Symbols, Exp, ...) { if (!requireNamespace("httr", quietly = TRUE)) { stop("httr package required. Please install it.", call. = FALSE) } if (!requireNamespace("jsonlite", quietly = TRUE)) { stop("jsonlite package required. Please install it.", call. = FALSE) } ua <- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" url_base <- "https://query2.finance.yahoo.com/v7/finance/options/%s" get_one_chain <- function(symbol, exp = NULL) { url <- sprintf(url_base, symbol) if (!is.null(exp)) { exp <- as.Date(exp) url <- paste0(url, "?date=", format(exp, "%Y%m%d")) } resp <- httr::GET(url, httr::user_agent(ua)) if (httr::http_error(resp)) { stop(sprintf("Yahoo Finance API request failed for %s. HTTP status code: %s", symbol, httr::status_code(resp)), call. = FALSE) } json <- httr::content(resp, "parsed") if (length(json$optionChain$result) == 0) { stop(sprintf("No options data found for %s", symbol), call. = FALSE) } data <- json$optionChain$result[[1]] exp_dates <- as.Date(unlist(data$expirationDates), origin = "1970-01-01") if (!is.null(exp)) { exp_idx <- which(exp_dates == exp) if (length(exp_idx) == 0) { stop(sprintf("Expiration date %s not found for %s", exp, symbol), call. = FALSE) } chains <- data$options[[exp_idx]] } else { chains <- data$options } process_chain <- function(chain) { calls <- chain$calls puts <- chain$puts if (!is.null(calls)) { calls <- as.data.frame(calls) calls$type <- "call" calls$expiration <- as.Date(chain$expirationDate, origin = "1970-01-01") } if (!is.null(puts)) { puts <- as.data.frame(puts) puts$type <- "put" puts$expiration <- as.Date(chain$expirationDate, origin = "1970-01-01") } rbind(calls, puts) } all_chains <- lapply(chains, process_chain) all_chains <- do.call(rbind, all_chains) all_chains$symbol <- symbol all_chains } if (length(Symbols) > 1) { lapply(Symbols, function(s) get_one_chain(s, Exp)) } else { get_one_chain(Symbols, Exp) } }
- 之后再运行
uOUT.OPT <- getOptionChain("TSLA","2024")应该就能正常获取数据了。
方案二:换用替代包获取期权数据
如果不想折腾Quantmod,直接用其他更稳定的包:
- tidyquant:基于tidyverse的工具包,请求逻辑更新及时,用法简单:
install.packages("tidyquant") library(tidyquant) # 获取TSLA 2024年到期的期权链 tsla_options <- tq_get("TSLA", get = "options", expiration = "2024") - IBrokers:如果有Interactive Brokers账户,用这个包连接IB接口,能拿到更全的期权数据,完全不受Yahoo API限制。
方案三:解决GitHub访问问题(若坚持安装修复分支)
要是必须装joshuaulrich的修复分支,试试这两个办法:
- 切换网络环境,比如用手机热点,或者找能正常访问GitHub的网络;
- 手动下载修复分支的源码压缩包,然后本地安装:
- 找到Quantmod的修复分支页面,下载源码压缩包;
- 在R里运行
install.packages("本地压缩包的完整路径", repos = NULL, type = "source")。
内容的提问来源于stack exchange,提问作者itmc009
相关产品推荐
相关产品推荐

