yfinance 事件数据 · 分红、拆股与价格修复

分红、拆股与 repair:Yahoo 的价格错误怎么发现、又怎么修

分红与拆股是价格序列里最容易被忽略、又最容易毁掉结论的两类事件。yfinance 把 Dividends、Stock Splits、Capital Gains 作为独立列返回,并提供 repair=True 去尝试修正 Yahoo 侧的价格错误——但官方文档同时坦白:Only US market data appears perfect,且修复存在假阳性风险。本页把「事件怎么进序列」「能修什么」「什么时候别修」三件事分开讲清楚。

实测版本:0.2.58 与 1.7.0依据:官方 price_repair 文档 + 源码 + 本机实测repair 仅对 1 日线口径生效
Dividends / Splits 列
repair=True 检测
标记 Repaired?
货币看 history_metadata
依据官方 price repair 文档与源码绘制的修复流程示意;非官方流程图,亦不代表修复一定生效。
yfinance · Events

三列事件数据:它们是怎么进序列的

先把「事件列」和「价格列」分清,后面讨论修复才有共同语言。

列名含义本站实测情况与复权的关系
Dividends除息日的每股分红金额AAPL 实测 92 条记录,最近一条为 2026-08-10复权比率就是由分红与价格共同推出的,分红列本身不做复权
Stock Splits拆股比例(未拆股为 0)AAPL 实测 5 条记录拆股会改变价格量级,复权价对它做了回溯调整
Capital Gains资本利得分派(主要出现在 ETF/基金)实测 SPY 的日线返回 8 列,比股票多出该列官方 repair 文档专门列出「资本利得被重复计算」这一类错误,并已有修复逻辑
Repaired?该行是否被 repair 修改过实测仅 repair=True 时出现,dtype 为 bool与复权是两个独立开关,可叠加使用
Volume成交量实测 int64(跨市场并集时会变 float64)成交量不做复权——源码里复权只乘到 OHLC 上
yfinance · Repair scope

repair=True 能修什么:8 类错误逐条对照

下表按官方 price repair 文档归类整理,第三列是本站判断「你多久会遇上」。

错误类型官方描述的处理方式出现频率(本站判断)修完要不要复核
漏做分红调整若数据里有分红、但调整前的 Adj Close 等于 Close,则手工应用分红调整中等,非美市场更常见要——官方特别说明这类修复不会把 Repaired? 置为 True
漏做拆股调整若数据里有拆股但之前的价格没调整,则手工应用拆股;需要区间包含拆股后 1 天用于校准较低要——官方说明 Yahoo 有时在拆股当天没调价
整行数据缺失或损坏用更小粒度数据重建(例如用小时线补日线)较低,多发生在冷门标的要——重建价格与 Yahoo 后续自己修好的版本会有差异
100 倍货币错位检测 $/cents、£/pence 之类单位混用并修正;散点用统计方法检测,成块的是货币切换较低,但一旦出现影响很大要——这是最容易被误读成「暴涨暴跌」的一类
分红调整缺失或量级错误按分红与除权日价格关系修正(过大、过小都修)中等要
7 天内重复分红识别并删除重复记录较低要
除权日错位价格实际在几天/几周后下跌时,修正除权日较低要
资本利得被重复计算当价格跌幅与「分红」比与「分红+资本利得」更吻合时,修正分红金额较低(ETF/基金)要
yfinance · Limits

哪些情况下不要指望 repair:四条边界

官方把限制写得很直接,照抄成四条结论。

① 只修 1 日线

假阳性率随区间变长而上升,因此修复只在 1 日线上做。你请求周线时,实现会先取 1 日线、修完再重采样——官方自己也承认,这个副作用顺带改善了 Yahoo 对多日区间做分红调整的方式。

② 重建受取数窗口限制

重建缺失数据要用更细粒度的数据,而细粒度数据有窗口限制(官方举例:小时线不能取到两年以前)。太老的区间会直接报「too old, Yahoo will reject request for finer-grain data」。

③ 假阳性无法消除

修复「分红过大」依赖价格走势,官方承认存在把正常波动误判为错误的可能,尤其在小额分红上。官方给的缓解方式是拉长区间、至少覆盖两次分红,一起判断。

④ 修的是「你的数据」,不是「Yahoo 的数据」

如果 Yahoo 之后自己修好了,你手里的重建结果与它会有差异。官方立场是「有总比缺好」。因此修复结果要落盘留证据,不要指望下次取数完全一致。

一个实用建议:把 repair=True 的结果与 repair=False 的结果做一次差集,看被修的是哪些日期。这比直接相信 Repaired? 更直观,也便于写进研究记录。
yfinance · Recipe

检查脚本怎么用:一段可直接复用的代码

先用事件列对照价格,再决定要不要修——把判断过程写进代码,而不是写进记忆。

import yfinance as yf
import pandas as pd

sym, period = "AAPL", "2y"
t = yf.Ticker(sym)

clean   = t.history(period=period, auto_adjust=False, repair=False)
repaired = t.history(period=period, auto_adjust=False, repair=True)

print("rows:", len(clean), "| repaired flags:", int(repaired["Repaired?"].sum()))
if "Repaired?" in repaired.columns:
    fixed = repaired.index[repaired["Repaired?"]]
    print("repaired dates:", [str(d.date()) for d in fixed][:10])

# 事件与价格对照:除息日附近的收盘跌幅是否与分红量级匹配
ev = clean[clean["Dividends"] > 0]
for dt, row in ev.tail(5).iterrows():
    i = clean.index.get_loc(dt)
    if i == 0:
        continue
    drop = clean["Close"].iloc[i - 1] - clean["Close"].iloc[i]
    print(str(dt.date()), "div=%.4f" % row["Dividends"], "price_drop=%.4f" % drop)

# 复权比率是否连续(跳变处往往就是复权出错的位置)
ratio = (clean["Adj Close"] / clean["Close"]).round(6)
print("ratio changed on:", [str(d.date()) for d in ratio[ratio.diff() != 0].index][:10])

# 真货币以 history_metadata 为准,不要看 info
print("currency:", t.history_metadata.get("currency"))
yfinance · Honesty

本站没有做哪些验证:避免误读的说明

把边界写清楚,比多写一段功能更值得。

没有对 repair 做效果验证

本站实测只覆盖 AAPL、SPY 等流动性很好的美股标的,这些标的两代版本实测都没有触发修复(Repaired? 全为假)。官方文档里的错误案例集中在欧洲与香港标的。因此本站不宣称「repair 一定有效」或「repair 一定有害」。

没有实测多日区间的重采样路径

官方说明多日区间会先取 1 日线再重采样。本站对 yfinance 的实测区间集中在 1mo 与 1y 的日线口径,没有对 1wk/1mo 的重采样结果逐行核对。

没有覆盖分红税的语义

返回的 Dividends 是名义金额,不含预扣税、不含你的持仓税务处理。把分红算进组合收益时,税务口径要你自己补。

FAQ

yfinance 常见问题

下面的回答都指向可核验的官方文件或本站实测;与官方表述冲突时,以官方仓库与 docs 为准。

分红和拆股怎么体现在返回数据里?

yfinance 把它们作为独立的列返回:Dividends、Stock Splits,以及 ETF/基金可能出现的 Capital Gains。本站实测 AAPL 的 actions 表覆盖 1987-05-11 起的 97 行记录、其中分红记录 92 条、拆股记录 5 条。要拿到这些列,history 保持默认 actions=True;download 需要显式 actions=True。

repair=True 到底修什么?

官方文档把它分成两大类:价格修复(漏做分红调整、漏做拆股调整、整行缺失/损坏、100 倍货币错位)与分红修复(分红调整缺失或量级错误、7 天内重复分红、除权日错位、资本利得被重复计算)。修复过的行会被标记:返回表里会多出一列 Repaired?(布尔),本站实测为 bool 类型。

修不了的情况有哪些?

官方给了三条明确边界:①只修 1 日线——假阳性率随区间变长而上升,所以多日区间会先取 1 日线、修完再重采样;②缺数据的重建有时效——重建要用更细粒度数据,而更细粒度有取数窗口限制(例如小时线不能取到两年以前);③Yahoo 后来自己修好之后,你手里的重建结果会与它略有不同,成交量甚至差异明显。官方原话是「Best I can do」。

什么是假阳性(FP)?我要担心吗?

要。官方说明:判断「分红是否过大」依赖价格走势,因此存在把正常波动误判成错误的可能;区间越长 FP 率越高;1 日线上的 FP 率很小,且多发生在极小额分红(例如 0.5%)的情形。官方给的建议是:要么接受这个风险,要么取 6–12 个月、包含至少两次分红的区间,把分红放在一起判断。

修复后货币怎么确认?

官方明确要求看 Ticker.history_metadata['currency'],不是 Ticker.info。原因是 repair 会处理 100 倍货币错位(例如英镑/便士、美元/美分混用),涉及货币单位切换时 history_metadata 里还会出现内部标记字段。

不做修复,只用干净数据行不行?

可以,但要接受后果。官方文档的立场是「No exchange is safe」(没有哪个交易所绝对安全),并给出多个真实错误示例(德国、瑞士、瑞典、英国、香港等标的)。本站的建议是:先把 Dividends 与价格序列对照一遍,看除权日附近价格是否出现无法解释的跳变,再决定要不要开 repair——把「是否需要修」变成一个有证据的判断,而不是默认开关。

下一步:财务与期权数据

价格与事件处理干净之后,如果你要做的是基本面或衍生品研究,下一站是财务报表与期权链的字段口径。