yfinance 版本演进全史:从 0.0.1 到 1.6.0 的功能全景与源码级解读
【免费下载链接】yfinanceDownload market data from Yahoo! Finance's API项目地址: https://gitcode.com/GitHub_Trending/yf/yfinance
yfinance 是一个通过 Yahoo! Finance 公开 API 下载市场数据的 Python 库,从 0.0.1 的 alpha 版本起步,到当前仓库中的 1.6.0(见 yfinance/version.py),其能力早已超出"下载股价"的范畴。本文以仓库根目录的 CHANGELOG.rst(共 1021 行,覆盖 0.0.1 至 1.6.0 全部版本记录)为骨架,结合 price repair 专项文档 与核心模块源码,为你还原这条演进主线:数据获取 → 数据清洗 → 数据修复 → 市场全景查询,并逐版本解读关键特性背后的实现。
为什么值得读这份 Changelog
一份 changelog 不只是"改了什么"的记录,它还是一个开源项目技术决策与架构演进的编年史。通过它你可以回答三类问题:
- 当前能力边界:最新版能做什么(日历、搜索、Screener、WebSocket 实时行情、价格修复、登录态等);
- 依赖与兼容性:为什么强制
curl_cffi>=0.15、为什么升级到 Pandas 3.0、为什么引入可选依赖; - 踩坑经验:
price repair的几十次迭代、cookie/crumb 认证策略的反复修补、时区缓存的多次重写,都直接对应真实世界的 Yahoo 数据质量问题。
项目模块全景(截至 1.6.0)
从 yfinance 包结构 与 README 的 Main components 可以看出,项目已经形成完整的模块矩阵:
| 模块 | 源码位置 | 核心职责 |
|---|---|---|
Ticker/Tickers | yfinance/ticker.py、yfinance/tickers.py | 单/多标的的历史、基本面、持有人、期权、新闻 |
download | yfinance/multi.py | 多标的高并发批量下载 |
Market | yfinance/market.py | 市场状态与摘要 |
Search/lookup | yfinance/search.py、yfinance/lookup.py | 搜索与 Ticker 解析(含 ISIN 识别) |
Screener | yfinance/screener/screener.py | 结构化筛选查询(Equity/ETF/FundQuery) |
Sector/Industry | yfinance/domain/ | 行业与板块信息 |
WebSocket | yfinance/live.py | 实时行情流(基于 Yahoo protobuf,见 pricing.proto) |
Calendar | yfinance/calendars.py | 财报、IPO、经济事件、拆股日历 |
config | yfinance/config.py | 全局配置(代理、重试、locale) |
Auth | yfinance/data.py | 登录 Yahoo 以获取完整数据权限 |
1.6.0:最新版本特性解读
CHANGELOG 中 1.6.0 是篇幅最大的一个版本,可分为四组:
1.6.0 特性与修复
- 资产负债表补全:新增
FixedMaturityInvestments、EquityInvestments等键(PR #2879),对应 fundamentals.py 中财务表构建逻辑; - Screener 字段修复:补充
dividendyield与dividendpershare.lasttwelvemonths(#2888); - 错误信息改进:不再在 Yahoo 已解释缺数据原因时误报 "possibly delisted"(#2903);修正 30m 请求却显示内部 15m interval 的错误提示(#2900);
- 多种崩溃修复:只读
Adj Close数组在股息调整修复中的崩溃(#2897)、Lookup 错误处理中self.ticker应为self.query的 AttributeError(#2896)、Yahoo API 返回 None 时_fetch_info的处理(#2906)、多日 interval 的 TypeError 以及 numpy>=2.5 的 Timedelta 警告(#2915)。
1.6.0 的价格修复改进
价格修复是 1.6.0 的重头戏:
- 修复了
repair=True不应把 GBp/ZAc/ILA 等报价永久转换为主要货币的问题(#2907); - 两次 price repair 的合并改进(#2908、#2943)。
1.6.0 工程与文档
- 打包方式全面迁移到 pyproject.toml(#2920、#2849),配合 ruff.toml 固定 lint 规则集保证 CI 确定性;
- 文档明确
download()返回索引的时区契约(#2936); - 无需
requests_cache也能重新启用test_no_expensive_calls_introduced测试(#2911)。
1.5.x:网络层与登录态的现代化
1.5.x 系列主要围绕"网络请求的健壮性":
- 1.5.2修复与
curl_cffi>=0.16的兼容性问题——这是对 1.4.0 引入"curl_cffi 可选、回退 requests"策略的持续跟进; - 1.5.1引入多项重要改动:
- 基本面单 URL 抓取超时时回退到分块请求(#2811);
- 用 timeseries API 取代估值指标的 HTML 爬取(#2851);
- 通过 subscriptions API 判定登录与订阅等级(#2845);
- 在 cookie 策略切换时保留用户登录 cookie(#2850);
- 规范化用户配置的代理字符串(#2853);
- 价格修复方面:修复单位切换被应用两次(#2842)、处理盘前"恶意报价"造成的错误股息误判(#2843)、NaN 成交量触发的错误(#2859)、
Adj Close趋于无穷的股息修复问题(#2860)。
这些改动说明:yfinance 与 Yahoo 接口之间存在着持续的"猫鼠游戏",cookie/crumb 与请求特征需要不断适配。
1.4.x:登录能力与地区作用域
- 新增
Auth类用于登录(#2761):通过 yfinance/data.py 中的check_login()、subscription_tier()、user()等接口判断登录态与订阅等级,登录后可请求更多数据权限; - Sector / Industry 支持 region 作用域(#2803,对应 domain/sector.py 与 domain/industry.py);
curl_cffi变为可选(#2802),未安装时回退到requests,对应 _http.py 中的会话创建逻辑;yf.download()变为可重入:移除共享模块级全局变量(#2805),配合互斥锁保证线程安全;Ticker支持 lang / region 作用域(#2804);- 修复
get_history_metadata()缺repair参数(#2777)、1mo区间判断忽略年份(#2780)、本地化盘中download()总是返回 UTC(#2825)等问题。
1.0:稳定化里程碑
CHANGELOG 中写道"yfinance been stable a long time now, time to grow up"——1.0 没有破坏性变更,但伴随弃用警告。核心新增:
- 全局配置类
yf.config(#2524):即 yfinance/config.py 中的ConfigMgr单例,默认提供network.proxy、network.retries、debug.hide_exceptions、debug.logging、locale.lang(默认 "en-US")、locale.region(默认 "US")等配置项; - 日历功能(#2615):Earnings Calendar 等,落地为 yfinance/calendars.py 中的
get_earnings_calendar()、get_ipo_info_calendar()、get_economic_events_calendar()、get_splits_calendar(); - 可选网络重试机制(#2627):针对瞬时网络错误;
- 修复 NSE/早开市市场 30m 区间对齐(#2642)、Screener 行业映射(#2648)、股息修复丢弃 NaN 行(#2651)等问题。
专题:price repair —— 项目最具特色的能力
价格修复在 CHANGELOG 中反复出现(0.2.0rc1、0.2.10、0.2.37、0.2.42、0.2.44、0.2.45、0.2.49、0.2.50、0.2.55、0.2.64、0.2.65、1.1.0、1.5.1、1.6.0 等均有记录),其权威文档在 doc/source/advanced/price_repair.rst,实现代码在 yfinance/scrapers/history.py,测试在 tests/test_price_repair.py。
使用方式与输出
在history()或download()中传入repair=True即会尝试修复 Yahoo 返回的多种价格错误。返回表中会新增一列Repaired?标记哪些行被修复过。注意:货币混合问题修复后,应以Ticker.history_metadata['currency']为准判断真实币种,而不是Ticker.info。
import yfinance as yf df = yf.Ticker("8TRA.DE", session=None).history(period="1mo", repair=True) print(df[["Close", "Adj Close", "Repaired?"]])从 multi.py 的 download 签名 可以看到repair=False是默认值,且repair参数同时存在于Tickers.history()、Ticker.history()(history.py)与download()三层 API 中。
价格修复的几类场景
- 缺失股息调整:数据中存在股息,但前一日
Adj Close等于Close,则手动对Adj Close施加股息调整;此类修复不改Close,因此Repaired?不会置 True。下图即文档中的示例(8TRA.DE):
- 缺失拆股调整:数据中有拆股记录但价格未调整,则手动施加拆股因子;要求日期范围覆盖拆股日之后至少 1 天用于校准(MOB.ST 案例)。
- 缺失数据重建:明显缺失或损坏的价格行,用小周期(如用 1h 修复 1d)重建。算法会分组抓取以减少请求量,并感知数据限制(如 1h 无法取到 2 年以前)。即使 Yahoo 日后修复了原始数据,重建值与真实值也仅有微小差异。
- 100x 错误:Yahoo 偶尔把货币单位搞混($/cents、£/pence),导致部分价格偏差 100 倍。随机散布的 100x 错误借助
scipy检测;成块出现的则是因为 Yahoo 在某天永久切换了币种(AET.L 案例):
股息修复的六大检测项
- 调整缺失或与股息偏差 100x;
- 7 天内重复股息(去重);
- 股息相对除息日价格跌幅偏大/偏小 100x;
- 除息日记录错误(价格跌幅滞后数日/数周);
- 资本利得被重复计算(1.1.0 新增,#2667,常见于 DODFX 等基金标的);
- 调整在除息日前一天被施加了两次。
文档 price_repair.rst 为每种场景给出了原始/修复后对照数据表(如 1398.HK、ALC.SW、LTI.L、BVT.L、2020.OL、TETY.ST 等)。修复逻辑的核心实现在 history.py 的_fix_bad_div_adjust()、_fix_bad_stock_splits()、_repair_capital_gains()、_fix_unit_switch()、_fix_zeroes()、_fix_unit_mixups()等方法中,配套cluster_dividends()、denoise_volume()、map_signals_to_ranges()等辅助函数。
误报风险与规避
由于"股息偏大/偏小"依赖价格行为判断,存在误报(FP)可能。FP 率随周期拉长而上升,因此仅修复 1d 数据;对周线等跨日区间请求修复时,会先抓取 1d 修复后再重采样——这顺带解决了 Yahoo 对多日区间股息调整的缺陷(test_resampling 测试 专门验证了 1wk/1mo/3mo 与 1d 修复重采样后行数与成交量的吻合度)。对极小股息(如 0.5%)可拉取 6–12 个月、含至少 2 次股息的数据做交叉分析以剔除误报。
0.2.x 系列:功能爆发期
0.2.x 是功能增长最快的阶段,以下是按功能线梳理的演进:
- Screener(0.2.45 → 0.2.52 → 1.0 → 1.3.0 → 1.6.0):从初版到
EquityQuery/FundQuery/ETFQuery结构化查询(yfinance/screener/query.py),并持续修复预定义 screen 的 offset/size/count; - Search 与 Lookup(0.2.52 → 0.2.56 → 1.0):
Search支持 quotes/news/lists/research/nav 及模糊查询(yfinance/search.py);Ticker.lookups提供按类型(股票/ETF/指数/货币/加密货币等)检索(yfinance/lookup.py); - WebSocket 实时行情(0.2.59 → 0.2.60 → 0.2.61):live price data,配套
AsyncWebSocket与pricing.proto的 protobuf 解码(yfinance/live.py); - 财务数据重构(0.2.42 → 0.2.45 → 0.2.50 → 0.2.52 → 0.2.55 → 1.0):SEC 文件(
sec_filings)、分析数据(analysis)、TTM 财务报表、估值指标表(valuation_measures)、get_shares_full();0.2.0rc4 引入get_income_stmt(legacy=True)访问旧版财务表,并将财务抓取提速 2 倍; - 缓存与线程安全(0.2.20 → 0.2.29 → 0.2.30):从 sqlite3 迁移到 peewee 保证 100% 线程安全;用 platformdirs 取代已死的 appdirs(0.2.40);0.2.4 起用数据库锁修复多线程下载的锁冲突;
- 认证与反爬(0.2.32 → 0.2.33 → 0.2.62 → 1.4.0):cookie & crumb 注入、CSRF cookie 备份策略、DNS 阻断 fc.yahoo.com 的处理、限流检测(
YfRateLimitError)、curl_cffi 逐步取代 requests; - 时区与索引(0.2.20 → 0.2.56 → 0.2.64 → 1.4.1):时区缓存多次重写提速、
download()保持原有时区语义、multi_level_index参数(0.2.47/48); - 异常体系(0.2.42 → 0.2.52):专门化的异常类与
raise_errors=True可选抛出,见 yfinance/exceptions.py。
0.1.x 与 0.0.x:奠定数据能力的地基
0.1.x 的关键里程碑:
- ISIN 支持(0.1.53 → 0.1.65):
get_isin()、get_all_by_isin()等工具,且Ticker/Tickers/download可自动识别并转换 ISIN(yfinance/utils.py); - 财务数据体系(0.1.39 → 0.1.46 → 0.1.65 → 0.2.2):
financials/balance_sheet/cashflow、季度数据、分析师推荐、财报日历,并保留financials作为income_stmt的映射; - 持有人与内部交易(0.1.51 → 0.2.34):
major_holders、institutional_holders、insider 交易/名册(yfinance/scrapers/holders.py); - 期权链(0.1.41 → 0.2.28):
option_chain()返回含底层数据的期权链; - 性能与修复:用正则而非 HTML 解析加速 JSON(0.1.51/52)、
fast_info加速版info(0.2.5 → 0.2.7 → 0.2.10)、30m 数据被 Yahoo 返回为 60m/15m 时的重采样修复(0.1.26/30)。
0.0.x 时期则奠定了架构基调:0.0.1 起依赖 Selenium/Chrome Driver,0.0.5 改用requests彻底移除浏览器依赖;0.0.8 引入进度条与失败重试;0.0.9 引入多线程;0.1.0 对接 v8 API 并完整重写、引入Ticker模块。
关键依赖与兼容性时间线
从 CHANGELOG 可以梳理出明确的依赖策略:
| 版本 | 依赖决策 |
|---|---|
| 0.1.68 | 移除 Python 3.5 支持 |
| 0.2.10 | 允许 sqlite3 < 3.8.2 |
| 1.0 | 封锁 curl_cffi 0.14(#2653) |
| 1.2.1 | 强制 curl_cffi>=0.15(CVE #2743) |
| 1.4.0 | curl_cffi 可选,回退 requests(#2802) |
| 1.5.2 | 修复与 curl_cffi>=0.16 的兼容 |
| 1.1.0 | 升级到 Pandas 3.0(#2683) |
此外,pyproject.toml 定义了可选依赖(如用于 100x 错误检测的 scipy、实时行情的 websockets 等),pip install yfinance[optional]方式安装。
演进趋势总结
通读 CHANGELOG.rst 可以提炼出 yfinance 的三条演进主线:
- 从"能下载"到"下载得对":早期版本专注于抓取成功率(cookie、重试、进度条),后期重心转移到数据正确性——price repair 从 0.2.0rc1 诞生后历经二十余次迭代,覆盖股息、拆股、单位、缺行、资本利得等 Yahoo 数据的系统性缺陷;
- 从"单一入口"到"生态矩阵":由
Ticker单一对象扩展出Tickers、download、Search、Screener、Market、Sector/Industry、Calendar、WebSocket的完整数据生态; - 从"硬编码"到"可配置可登录":1.0 引入
yf.config全局配置、1.4.0 引入Auth登录能力,让库在面对 Yahoo 接口变化时具备更强的适配弹性。
对于使用者而言,这份 changelog 最直接的实战价值在于:当你需要"更正确的历史数据"时,记得开启repair=True;当你需要批量下载时,参考 multi.py 的并发与线程安全设计;当 Yahoo 接口再次变化导致异常时,exceptions.py 与 data.py 的 cookie 策略切换机制是排查的第一落点。所有特性均可结合仓库源码与 tests/ 下的测试用例逐一验证。
【免费下载链接】yfinanceDownload market data from Yahoo! Finance's API项目地址: https://gitcode.com/GitHub_Trending/yf/yfinance
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考