yfinance Ticker 股票数据方法完全指南:从行情历史到 ISIN、分红、拆股与新闻
【免费下载链接】yfinanceDownload market data from Yahoo! Finance's API项目地址: https://gitcode.com/GitHub_Trending/yf/yfinance
本篇技术指南围绕 yfinance 项目中Ticker对象在“股票数据(stock)场景”下提供的全部公开接口展开,聚焦 yfinance.stock.rst 所收录的方法——get_isin/isin、history、get_history_metadata、get_dividends/dividends、get_splits/splits、get_actions/actions、get_capital_gains/capital_gains、get_shares_full、get_info/info、get_fast_info/fast_info、get_news/news。读完本文,你将掌握每个方法的调用方式、返回结构、参数语义,以及它们在 ticker.py、base.py 与 scrapers/history.py 中的底层实现原理,可以直接在量化分析、数据清洗与自动化监控任务中落地使用。
1. 方法总览与约定
1.1 方法 vs 属性
yfinance.Ticker为同一份数据提供两种访问形式,二者等价(属性实现为方法调用的封装):
| 方法形式 | 属性形式 | 返回类型 |
|---|---|---|
get_isin() | isin | str |
history(...) | — | pd.DataFrame |
get_history_metadata() | history_metadata | dict |
get_dividends(period) | dividends | pd.Series |
get_splits(period) | splits | pd.Series |
get_actions(period) | actions | pd.DataFrame |
get_capital_gains(period) | capital_gains | pd.Series |
get_shares_full(start, end) | — | pd.Series |
get_info() | info | dict |
get_fast_info() | fast_info | FastInfo |
get_news(count, tab) | news | list |
从 ticker.py 的源码结构可以看到,属性全部是对get_*方法的薄封装,例如isin返回self.get_isin()、dividends返回self.get_dividends()、news返回self.get_news()。因此本文统一以get_*方法为讲解主线,属性形式仅在使用时提及。
1.2 依赖的数据来源
Ticker内部并非单点实现,而是按功能拆分到多个 scraper 模块(见 base.py 的初始化代码):
- 行情与历史事件(OHLC、分红、拆股、资本利得、历史元数据)→
PriceHistory(scrapers/history.py) - 快照报价与估值 →
Quote、FastInfo(scrapers/quote.py) - 基本面与股本 →
Fundamentals(scrapers/fundamentals.py)
此外Ticker还支持以元组('OR', 'XPAR')形式传入“代码 + 市场标识符(MIC)”,底层会通过_MIC_TO_YAHOO_SUFFIX映射为 Yahoo 后缀(如OR.PA),详见 base.py。同时它也接受 ISIN 作为 ticker 输入(源码中会调用utils.is_isin判断并通过缓存反查代码),这与下文get_isin()的查询能力形成闭环。
2. 历史行情:history()与get_history_metadata()
2.1history()完整参数
history()是Ticker最核心的方法,定义于 base.py,实际委托给PriceHistory.history()(scrapers/history.py)。其参数与语义如下:
| 参数 | 默认值 | 说明 |
|---|---|---|
period | '1mo' | 有效区间:1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max;可与start/end组合(如end = start + period) |
interval | '1d' | 有效周期:1m,2m,5m,15m,30m,60m,90m,1h,1d,5d,1wk,1mo,3mo;分钟/小时级日内数据不能超过最近 60 天 |
start | 99 年前 | 开始日期(含),接受YYYY-MM-DD字符串或_datetime |
end | 现在 | 结束日期(不含),如end="2023-01-01"则最后一条数据为2022-12-31 |
prepost | False | 是否包含盘前/盘后数据 |
auto_adjust | True | 是否自动复权所有 OHLC |
back_adjust | False | 是否使用后向复权模拟真实历史价格 |
repair | False | 是否修复 Yahoo 数据中的价格错误(100x、缺失、错误分红调整),详见 price_repair |
keepna | False | 是否保留 Yahoo 返回的 NaN 行 |
rounding | False | 是否四舍五入到 2 位小数 |
timeout | 10 | 请求超时秒数 |
raise_errors | False | 是否将错误以异常抛出(已被yf.config.debug.hide_exceptions取代,调用时会发出 DeprecationWarning) |
2.2 底层请求构造与行为细节
从 scrapers/history.py 可以看出几个值得注意的实现事实:
- 30m 数据的 Yahoo bug 规避:源码注释明确说明 Yahoo 对
30m返回 60m 数据,因此请求时先以15m拉取,再在本地重采样为 30m(见 history.py 与 L340-L351)。 - 多日区间的 repair 特例:当
repair=True且interval为5d/1wk/1mo/3mo时,源码会改为拉取1d数据、执行修复后再本地重采样(L102-L128),其中5d直接被判定为 "nonsense" 并抛出ValueError。 - 事件参数:请求恒带
params["events"] = "div,splits,capitalGains"(L202),即一次请求同时取回分红、拆股与资本利得事件。 - 缓存策略:当请求时间范围完全落在过去(结束时间早于当前时间 30 分钟以上)时,会改用
cache_get走缓存(L216-L221)。 - 时区处理:返回 DataFrame 的索引会被本地化到交易所时区(
exchangeTimezoneName),并调用fix_Yahoo_dst_issue处理 DST 问题(L358-L359);未请求prepost的日内数据还会剔除 Yahoo 多返回的盘前盘后行(L361-L363)。 - 返回列:包含
Open/High/Low/Close/Adj Close/Volume,以及合并进的事件列Dividends、Stock Splits,ETF/共同基金还会出现Capital Gains(L439-L458);开启repair时可能附带Repaired?标记列。
2.3get_history_metadata():历史元数据
get_history_metadata()(base.py)返回行情请求附带或单独拉取的元数据字典,典型字段包括:
currency、exchangeTimezoneName、instrumentType(用于判断是否为 ETF/共同基金)firstTradeDate、regularMarketTime、regularMarketPrice等validRanges(校验用户传入的period是否合法)tradingPeriods(交易时段表)、lastTrade(最近成交价与时间)currentTradingPeriod(含开盘/收盘时间戳)YF repair?(是否对数据执行过价格修复)
其实现要点(history.py)是:如果元数据尚未缓存,会主动请求一次5d/1h的日内数据,因为 Yahoo 只在日内响应中返回tradingPeriods等字段;随后用utils.format_history_metadata(utils.py)把firstTradeDate、regularMarketTime、currentTradingPeriod等 UNIX 时间戳转换为带交易所时区的 pandas 时间戳。
repair参数的默认值取_SENTINEL_哨兵,含义是“跟随上一次history()调用是否启用了价格修复”,测试 test_ticker.py 专门验证了这一点。
3. 公司事件:分红、拆股、资本利得与 actions
3.1 三个get_*方法与实现
divs = ticker.get_dividends(period="max") # pd.Series,索引为除息日 splits = ticker.get_splits(period="max") # pd.Series,索引为拆股生效日 cg = ticker.get_capital_gains(period="max") # pd.Series,仅 ETF/共同基金有数据三者定义于 base.py,内部统一走PriceHistory的缓存路径_get_history_cache(interval='1d', ...)(见 history.py),也就是说它们总是基于1d 日线请求获取事件数据,再分别取出dividends、splits、capital gains字段:
get_dividends返回纯分红序列,值为每股派息金额;get_splits返回拆股比率序列;get_capital_gains返回资本利得分配(只有instrumentType为MUTUALFUND或ETF时才解析,见 history.py 与 L374-L375)。
三者的共同period参数默认"max"(全量历史),也可以传入history()支持的区间值。
3.2get_actions():合并后的公司行为表
get_actions(period="max")(history.py)返回一个合并了所有事件的pd.DataFrame,列可能包含Dividends、Dividends FX、Stock Splits、Capital Gains。其内部逻辑是:
- 从历史缓存取价格与分红数据;若分红带
currency列(常见于越南市场或以外币派息的公司),则合并为Dividends FX列; - 只保留事件值不全为 0 的行(
(actions[cols_numeric]!=0).any(axis=1)); - 若某事件列全为 0,则直接删除该列。
注意:
get_actions()返回类型为pd.Series(方法签名标注如此),但源码实际返回合并后的pd.DataFrame;Ticker.actions属性同样如此,测试 test_ticker.py 断言其为pd.DataFrame。使用时以 DataFrame 处理即可。
由于get_dividends/splits/capital_gains/actions全部共享历史缓存,首次调用某个方法会触发一次 1d 历史请求,后续调用直接命中缓存——测试test_chained_history_calls(test_ticker.py)验证了“先调history()再取dividends”不会重复请求。
4. 股本数据:get_shares_full()
get_shares_full(start=None, end=None)(base.py)返回一个pd.Series:索引为带交易所时区的日期时间,值为该日期的流通股数。实现细节:
- 日期处理:默认结束时间为当前时刻;默认起始时间为“结束时间往前推 548 天(约 18 个月)”;
start/end会被解析到交易所时区并做floor/ceil对齐;若start >= end会记录错误并返回None。 - 数据源:请求
https://query2.finance.yahoo.com/ws/fundamentals-timeseries/v1/finance/timeseries/{ticker}的shares_out字段,失败时(JSON 解析失败、请求异常、Yahoo 返回Bad Request)默认记录日志并返回None(除非关闭YfConfig.debug.hide_exceptions)。 - 缓存:走
self._data.cache_get。
这个接口适合需要跟踪股本随时间变化的场景(如加权平均股本、回购对股本的影响),而get_shares()(未在本文档的 API 列表内)只提供当前的快照股本。
5. 公司概况:get_info()与get_fast_info()
5.1get_info():完整快照
get_info()(base.py)返回一个包含公司全面信息的dict,由Quote.info提供(scrapers/quote.py),涵盖公司简介、市值、市盈率、每股收益、52 周高低、行业板块、分析师目标价等大量字段。Ticker.info属性与其等价。
5.2get_fast_info():轻量惰性字典
get_fast_info()(base.py)返回FastInfo对象(scrapers/quote.py),它的设计目标是“比info更快地拿到常用字段”,实现要点(quote.py):
- 模仿 dict 行为,支持
keys()、items()、values()、get()、in、[]取值,且同时支持 snake_case 与 camelCase 两种键名(如market_cap与marketCap)。 - 通过
_get_1y_prices()(调用history(period="1y", auto_adjust=False))与get_history_metadata()惰性加载数据,因此首次访问某字段才会触发请求,后续访问命中实例缓存。 - 公开键集合(
keys())包括:currency、quote_type、exchange、timezone、shares、market_cap、last_price、previous_close、open、day_high、day_low、regular_market_previous_close、last_volume、fifty_day_average、two_hundred_day_average、ten_day_average_volume、three_month_average_volume、year_high、year_low、year_change等。
测试test_fast_info(test_ticker.py)通过遍历for k in f的方式验证了其 dict 行为。当需要快速获取“现价、市值、52 周高低”等少量指标时,优先使用fast_info而不是完整的info。
6. 新闻:get_news()
get_news(count=10, tab="news")(base.py)返回与该股票相关的新闻列表:
count:请求的新闻条数(snippetCount);tab:可选"news"(最新新闻)、"all"(全部)、"press releases"(新闻稿),非法值会抛出ValueError;- 返回
list,每个元素是一篇新闻文章 dict;源码会过滤掉ad广告条目(L630); - 结果缓存在
self._news,首次调用后再次调用直接返回缓存; - 若 Yahoo 返回
"Will be right back"或请求失败,会抛出YFDataException(提示 Yahoo Finance 暂时不可用)。
注意:get_news走的是_ROOT_URL_/xhr/ncp的 POST 接口(ncp_fin服务),与history使用的/v8/finance/chart不同。
7. ISIN 识别:get_isin()
get_isin()(base.py)用于查询股票的国际证券识别码(ISIN),标注为experimental:
- 结果缓存在
self._isin,同一Ticker实例只查询一次; - 若 ticker 含
-或^(如指数^GSPC、部分衍生品),直接返回'-'; - 查询逻辑:先用
Quote.info取shortName,然后请求 businessinsider 的搜索建议接口,按"{ticker}|"模式解析 ISIN;解析失败返回'-'或None; - 反向支持:
Ticker构造函数本身接受 ISIN 作为输入(base.py),会通过cache.get_isin_cache()与utils.get_ticker_by_isin反查 Yahoo 代码,测试test_isin、test_isin_info(test_ticker.py)覆盖了这两种场景。
8. 组合使用示例
把上述 API 组合起来,可以构建一个典型的“单只股票数据速览”脚本(参考 reference/examples/ticker.py):
import yfinance as yf ticker = yf.Ticker("MSFT") # 1) 历史行情(默认 1mo / 1d) hist = ticker.history(period="1y", interval="1d", auto_adjust=True, repair=True) print(hist.tail()) # 2) 历史元数据:时区、货币、首次上市日 md = ticker.get_history_metadata() print(md["currency"], md["exchangeTimezoneName"], md["firstTradeDate"]) # 3) 分红、拆股、资本利得、合并 actions divs = ticker.get_dividends() # pd.Series splits = ticker.get_splits() # pd.Series actions = ticker.get_actions() # pd.DataFrame(可能含 Dividends/Stock Splits/Capital Gains) # 4) 历史股本(默认约 18 个月窗口) shares = ticker.get_shares_full() # 5) 公司概况:轻量快照 vs 完整信息 f = ticker.get_fast_info() print(f["market_cap"], f["last_price"], f["year_high"]) info = ticker.get_info() # 完整 dict # 6) 新闻与 ISIN news = ticker.get_news(count=5, tab="news") isin = ticker.get_isin() print(isin)运行环境要求:安装本项目(pip install -e .或按 pyproject.toml 依赖安装),依赖 pandas、numpy、requests、beautifulsoup4 等,并保持网络可访问 Yahoo Finance 接口。所有示例均基于当前仓库源码的行为编写,可通过 tests/test_ticker.py 中的对应测试进一步验证。
9. 常见问题与注意事项
- 返回类型差异:
get_dividends/splits/capital_gains返回pd.Series,get_actions实际返回pd.DataFrame(方法签名标注pd.Series,以源码实现与测试为准)。 raise_errors已弃用:改用yf.config.debug.hide_exceptions = False(见 history.py)。- 日内数据时效限制:分钟/小时级数据只覆盖最近约 60 天(1m 更短),跨月历史请使用日线以上周期。
repair=True与多日区间:5d区间不受支持,1wk/1mo/3mo会先拉日线修复再重采样,耗时更长但更准确;完整原理见 price_repair。- 缓存机制:
Ticker内部使用请求级缓存(YfData.cache_get)与实例级缓存(如_news、_isin、_history_cache),同一进程内重复调用不会重复请求;跨进程持久化缓存可参考 caching。 - ISIN 为实验性功能:查询依赖第三方站点接口,失败时返回
'-'或None,建议在业务代码中做容错。 - 数据来源稳定性:
history依赖/v8/finance/chart,get_news依赖/xhr/ncp,get_earnings_dates等依赖 HTML 爬取(见 base.py);这些端点若变更,接口行为可能随之调整,升级依赖版本前建议先阅读 CHANGELOG.md。
10. 小结
yfinance.Ticker的 stock 方法族覆盖了股票数据场景下最常用的数据维度:历史行情(含元数据与价格修复)、分红/拆股/资本利得事件、历史股本、公司概况(完整与轻量两种粒度)、新闻与 ISIN。理解其“属性=方法封装”“scraper 分工”“惰性加载与多级缓存”三个设计特点,可以更高效地构建稳定、可复现的金融数据管道。进一步的 API 细节可在 reference/index.rst 找到各模块的 autosummary 文档。
【免费下载链接】yfinanceDownload market data from Yahoo! Finance's API项目地址: https://gitcode.com/GitHub_Trending/yf/yfinance
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考