yfinance 下载的非美股数据价格出现 100 倍偏差怎么排查和修复
【免费下载链接】yfinanceDownload market data from Yahoo! Finance's API项目地址: https://gitcode.com/GitHub_Trending/yf/yfinance
用 yfinance 的Ticker.history()或yf.download()拉取非美股(尤其是伦敦证交所 £/pence 混用的股票)数据时,部分价格会整体偏大 100 倍——原因是 Yahoo 在数据源里把货币单位搞混了($/cents、£/pence)。yfinance 官方文档指出"Only US market data appears perfect",即这类问题主要出现在美股之外。本文说明如何确认这是 Yahoo 的 100x 货币单位错误,并用 yfinance 内置的repair=True参数完成修复和验证。
先确认偏差形态:随机散布还是整段切换
100x 偏差在数据里有两种典型形态(来源:doc/source/advanced/price_repair.rst):
- 随机散布:错误行随机分布在整段数据中,个别价格突然放大 100 倍。这类错误由
scipy模块检测(对 OHLC 做局部中值滤波,找出与邻域比值约为 100 的离群值)。 - 整段切换:从某个日期起 Yahoo "决定永久切换货币",之后整段数据都是 cents/pence 计价,表现为价格序列从某一天起整体跳变 100 倍。
排查时先看返回表的Close/Open序列:如果是孤立几天异常,属于第一种;如果从某个日期开始整段都大 100 倍,属于第二种。两种形态repair=True都会处理。
另外,因为 100x 错误本质是货币混用,修复前后真实货币单位可能发生变化。文档明确提醒:
import yfinance as yf t = yf.Ticker("AET.L") t.history(period="1y", interval="1d", repair=True) # 修复后检查真实货币,看 history_metadata,不要看 Ticker.info print(t.history_metadata['currency'])Ticker.info里的货币字段不可靠,Ticker.history_metadata['currency']才是修复逻辑使用并更新的真实货币。
用repair=True执行修复
history()和download()都支持repair参数,默认False:
- history() 源码参数说明:
repair : bool — Fixes price errors in Yahoo data: 100x, missing, bad dividend adjust. - download() 参数说明:
repair: bool — Detect currency unit 100x mixups and attempt repair. Default is False
对单个 ticker:
import yfinance as yf dat = yf.Ticker("AET.L") df = dat.history(period="1y", interval="1d", repair=True) print(df)批量下载时同样传该参数:
import yfinance as yf df = yf.download(["AET.L", "SSW.JO"], period="1y", interval="1d", repair=True)两点关于interval的适用条件(来源:history() 实现):
- 使用
repair=True且interval为1wk、1mo、3mo时,yfinance 会改为先取 1d 数据、修复后再重采样到目标周期(文档说明这是顺带解决 Yahoo 多日周期 dividend 调整缺陷的方式)。 interval="5d"与repair=True组合会直接抛出ValueError,不支持。
验证修复结果
修复后的返回表会多出一列Repaired?,逐行标记该行是否被修复过:
df = dat.history(period="1y", interval="1d", repair=True) print(df[df["Repaired?"]]) # 只看被修复过的行验证时核对三个点:
- 之前整体偏大 100 倍的时间段,价格是否回落到与前后邻域同一数量级;
Repaired?列是否精确标记了被改动的行(未修复的行保持False);dat.history_metadata['currency']是否为修复后的真实货币单位。
修复失败的值会被还原为 Yahoo 原始值(而不是留下错误结果),所以Repaired?为False的行即使仍有异常也说明该处无法自动修复。
已知限制与误报边界
- 只修复 1d 周期的 dividend 相关错误:文档指出误报率(false positive)随周期变长而上升,所以 dividend 修复只针对 1d;请求多日周期时会自动取 1d 修复后重采样。
- 微小 dividend 的误报:修复逻辑依赖价格行为判断,极小的 dividend(如 0.5%)可能被把正常波动误判为除息下跌。文档给出的处理建议:要么接受该风险,要么抓取 6-12 个月、至少包含 2 次 dividend 的价格数据,把几次 dividend 放在一起分析以识别误报。
- 重建数据与 Yahoo 后续修复的数据可能略有差异:如果某段数据是用更小周期(如
1h)重建的,之后 Yahoo 自己修好了原始数据,两者会略有不同、volume 可能差异明显——文档说明重建结果"beats missing data",但数值不完全一致属于预期行为。 - 适用范围:修复针对 Yahoo 返回的价格错误(100x、缺失、坏 dividend 调整、坏拆股等)。100x 检测需要至少两行数据、依赖
scipy(仅在实际请求repair=True时才导入),单行表格无法做 100x 检测。
排查路径总结:先按"随机散布 vs 整段切换"确认偏差形态 →repair=True重取数据 → 用Repaired?列和history_metadata['currency']验证。若修复后Repaired?仍无法覆盖某些异常行,说明该处超出了自动修复能力,需要人工核对对应日期前后的价格。
【免费下载链接】yfinanceDownload market data from Yahoo! Finance's API项目地址: https://gitcode.com/GitHub_Trending/yf/yfinance
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考