yfinance 使用指南:用 Python 优雅地下载 Yahoo! Finance 市场数据
2026/9/12 4:32:05 网站建设 项目流程

yfinance 使用指南:用 Python 优雅地下载 Yahoo! Finance 市场数据

【免费下载链接】yfinanceDownload market data from Yahoo! Finance's API项目地址: https://gitcode.com/GitHub_Trending/yf/yfinance

导读

yfinance 是一个面向 Yahoo! Finance 公开 API 的 Python 市场数据下载库,它提供了一套 Pythonic(符合 Python 习惯)的接口,让你可以用几行代码获取股票历史行情、基本面数据、期权链、实时行情流、行业板块信息乃至市场筛选结果。本文以仓库 README.md 为骨架,结合仓库内的官方示例(doc/source/reference/examples/)与源码实现,完整讲解 yfinance 的安装方式、八大核心组件(TickerTickersdownloadMarketWebSocketSearchSector/IndustryScreener)的用法,以及CalendarsAuth、代理等进阶能力,帮助你快速搭建自己的行情数据管道。


一、yfinance 是什么

yfinance提供了一种 Pythonic 的方式来从 Yahoo! Finance 获取金融与市场数据。它的核心设计理念是:以面向对象的方式封装 Yahoo 的公开 API,让"取数"这件事足够简单直接——你不需要手写 HTTP 请求、处理 cookie 与 crumb 校验,只需要创建对象、访问属性即可。

从源码的顶层导出(yfinance/init.py)可以看到,yfinance 对外开放的能力相当完整:

顶层导出类型用途
Ticker单个标的全量数据(历史、财务、期权等)
Tickers批量管理多个标的
download函数一键下载多个标的的历史行情
Market/MarketRegion类/枚举市场状态与摘要信息
WebSocket/AsyncWebSocket实时行情流(同步/异步)
Search报价与新闻搜索
Lookup标的查找
Sector/Industry行业板块信息
EquityQuery/FundQuery/ETFQuery/screen类/函数构建查询并筛选市场
Calendars财报、IPO、拆股等事件日历
Auth登录态管理与订阅层级查询
config/set_config配置全局配置(代理、重试等)

这些正是 README 中 "Main components"(主要组件)一节的完整落地。


二、安装

从 PyPI 安装 yfinance 非常简单:

$ pip install yfinance

安装后,在 Python 中即可直接导入:

import yfinance as yf

需要说明两点:

  1. 依赖说明:yfinance 默认依赖curl_cffi作为 HTTP 传输层。如果希望不使用curl_cffi而回退到requests,可以参考仓库文档 doc/source/advanced/install.rst 中的高级安装说明进行配置。
  2. 底层会话约束:从源码 yfinance/data.py 可以看到,yfinance 通过YfData单例管理全局请求会话。缓存型会话(如requests_cache)以及非 curl_cffi/requests 的会话类型会被直接拒绝(抛出YFDataException),原因是缓存会破坏数据一致性——yfinance 自己就内置了 crumb、cookie 与响应缓存机制。

三、核心组件一:Ticker——单个标的数据中心

Ticker是 yfinance 最常用的入口,封装了单个股票、ETF、基金或指数的几乎所有公开数据。官方示例(doc/source/reference/examples/ticker.py)展示了它的典型用法:

import yfinance as yf dat = yf.Ticker("MSFT") # 获取历史行情数据 dat.history(period='1mo') # 期权链(取第一个到期日) dat.option_chain(dat.options[0]).calls # 财务报表 dat.balance_sheet dat.quarterly_income_stmt # 日历信息(财报日期、除息日等) dat.calendar # 综合信息(市值、PE、行业等) dat.info # 分析师目标价 dat.analyst_price_targets # WebSocket 实时行情 dat.live()

从源码结构看(yfinance/ticker.py),Ticker继承自TickerBase(yfinance/base.py),其中:

  • history():拉取历史 OHLCV 数据,支持period(如1mo)或start/end日期区间两种模式,返回 pandas DataFrame;
  • option_chain(date=None, tz=None):通过 Yahoo 的/v7/finance/options/{ticker}接口获取期权数据,返回包含callsputsunderlying三个字段的 namedtuple。若指定的到期日不在dat.options列表中,会抛出ValueError并列出可用到期日(yfinance/ticker.py);
  • 属性访问infocalendaranalyst_price_targetsmajor_holdersinstitutional_holdersisin等均为延迟加载属性,首次访问时才会真正发起网络请求。

3.1 常见属性速查

除示例中的属性外,Ticker还暴露了大量常用数据接口(见 yfinance/ticker.py 与 yfinance/base.py):

属性/方法说明
history()历史行情(OHLCV),可选actions=True附带分红拆股
actions/dividends/splits/capital_gains公司行为数据
financials/income_stmt/balance_sheet/cashflow三大财务报表(及季度版quarterly_*
info综合行情快照(市值、PE、52 周高低等)
analyst_price_targets/recommendations分析师评级与目标价
calendar财报与除息日历
funds_data基金/ETF 专属数据(见后文)
live()订阅该标的的 WebSocket 实时行情
get_isin()查询 ISIN 代码

四、核心组件二:Tickers——批量管理多个标的

当需要同时跟踪多个标的时,使用Tickers可以一次性创建多个Ticker对象,并按代码访问(官方示例 doc/source/reference/examples/tickers.py):

import yfinance as yf tickers = yf.Tickers('msft aapl goog') # 通过 .tickers 字典按代码访问(自动转为大写) tickers.tickers['MSFT'].info tickers.tickers['AAPL'].history(period="1mo") tickers.tickers['GOOG'].actions # WebSocket 实时行情 tickers.live()

从源码看(yfinance/tickers.py),Tickers内部还封装了download()方法,本质上委托给multi.download(),参数与下文download函数完全一致——也就是说,Tickers既是对象容器,也是批量取数的便捷入口。


五、核心组件三:download——一键批量下载历史行情

yf.download()是 yfinance 最经典、最常用的函数级 API,一行代码即可下载多标的历史数据:

import yfinance as yf data = yf.download("SPY AAPL", period="1mo")

返回结果是一个多级索引(MultiIndex)的 pandas DataFrame,默认按列(group_by='column')组织,即顶层为价格字段(Open/High/Low/Close/Volume),下一层为标的代码。

5.1 完整参数详解

download()的完整签名定义在 yfinance/multi.py,所有参数说明如下:

参数类型/默认值说明
tickersstr, list要下载的标的列表。字符串可用空格或逗号分隔,如"SPY AAPL""SPY, AAPL";也可传 list。支持 ISIN(如"US0378331005",内部会自动转换为 ticker)
periodstr,默认'1mo'有效区间:1d, 5d, 1mo, 3mo, 6mo, 1y, 2y, 5y, 10y, ytd, max。默认在未指定start/end时为'1mo'periodstart/end二选一
intervalstr,默认"1d"有效周期:1m, 2m, 5m, 15m, 30m, 60m, 90m, 1h, 1d, 5d, 1wk, 1mo, 3mo分钟级日内数据最多回溯 60 天。注意:30m数据实际是从 Yahoo 拉取15m后重采样得到的,以规避 Yahoo API 的 bug
start/endstr(YYYY-MM-DD)或 datetime起始日期包含(如start="2020-01-01"的首个数据点就在当天);结束日期不包含(如end="2023-01-01"的最后数据点是2022-12-31)。start默认 99 年前,end默认当前
group_bystr,默认'column''ticker''column'分组组织 MultiIndex
prepostbool,默认False是否包含盘前盘后数据
auto_adjustbool,默认True是否自动复权所有 OHLC 数据
back_adjustbool,默认False是否使用后复权
repairbool,默认False是否检测"货币单位 100 倍错乱"(currency unit 100x mixups)并尝试修复——这是 yfinance 的特色数据修复功能,仓库为其准备了大量测试用例(见 tests/test_price_repair.py 与 tests/data/ 下的*-fixed.csv对照数据)
keepnabool,默认False是否保留 Yahoo 返回的 NaN 行
actionsbool,默认False是否同时下载分红与拆股数据
threadsbool / int,默认True批量下载使用的线程数。True时自动取min(标的数据, CPU 核数 * 2)(见 yfinance/multi.py)
ignore_tzbool合并不同时区数据时是否忽略时区部分。默认取决于interval:日内数据(分钟/小时级)为False,日线及以上为True;同时控制返回索引的时区属性
roundingbool,默认False是否将数值四舍五入到 2 位小数
timeoutNone 或 float,默认10请求超时秒数(支持小数,如0.01
sessionSession自定义请求会话对象
multi_level_indexbool,默认True是否总是返回 MultiIndex DataFrame

5.2 底层执行流程

从源码看(yfinance/multi.py),download()的执行分为几步:

  1. 将字符串 tickers 统一转为大写并去重,ISIN 自动转换为 ticker;
  2. 若开启threads,通过_multitasking并行发起下载,并显示进度条;
  3. 所有标的数据下载完成后,统一对齐时间索引并合并为 MultiIndex DataFrame。

调试提示:当开启 DEBUG 日志时,yfinance 会自动关闭多线程和进度条(yfinance/multi.py),避免日志交错,这在排查问题时非常有用。


六、核心组件四:Market——市场状态与摘要

Market用于获取某个市场的整体状态(开盘/收盘)与摘要信息。官方示例(doc/source/reference/examples/market.py):

import yfinance as yf EUROPE = yf.Market("EUROPE") status = EUROPE.status # 市场当前状态 summary = EUROPE.summary # 市场摘要

从源码看,市场区域由MarketRegion枚举定义(yfinance/init.py、yfinance/domain/market.py),Market接受区域名称(如"EUROPE")进行构造。该组件适合做"交易日判断"和"市场概况"类的应用——例如在交易策略启动前先检查目标市场是否处于交易时段。


七、核心组件五:WebSocket 与 AsyncWebSocket——实时行情流

yfinance 提供同步与异步两套 WebSocket 客户端,用于订阅实时行情(定价数据流)。官方示例提供了完整的两种写法(doc/source/reference/examples/live_sync.py、doc/source/reference/examples/live_async.py)。

7.1 同步版 WebSocket

import yfinance as yf # 定义消息回调 def message_handler(message): print("Received message:", message) # ======================= # 方式一:上下文管理器(推荐) # ======================= with yf.WebSocket() as ws: ws.subscribe(["AAPL", "BTC-USD"]) ws.listen(message_handler) # ======================= # 方式二:手动管理 # ======================= ws = yf.WebSocket() ws.subscribe(["AAPL", "BTC-USD"]) ws.listen(message_handler)

7.2 异步版 AsyncWebSocket

import asyncio import yfinance as yf # 定义消息回调 def message_handler(message): print("Received message:", message) async def main(): # ======================= # 方式一:异步上下文管理器 # ======================= async with yf.AsyncWebSocket() as ws: await ws.subscribe(["AAPL", "BTC-USD"]) await ws.listen() # ======================= # 方式二:手动管理 # ======================= ws = yf.AsyncWebSocket() await ws.subscribe(["AAPL", "BTC-USD"]) await ws.listen() asyncio.run(main())

从源码看(yfinance/live.py、yfinance/live.py),两个类均基于wss://streamer.finance.yahoo.com/?version=2端点,AsyncWebSocket继承自BaseWebSocket,二者 API 对齐(subscribe订阅代码列表、listen持续监听并回调消息)。注意示例中同时订阅了股票(AAPL)与加密货币(BTC-USD)代码,说明该流不局限于股票。

另外,Ticker.live()Tickers.live()也封装了实时流入口(见 yfinance/base.py 与 yfinance/tickers.py),可以按对象粒度直接启动订阅。


八、核心组件六:Search——报价与新闻搜索

Search用于搜索 Yahoo Finance 中的报价(quotes)、新闻(news)与研究内容(research)。官方示例(doc/source/reference/examples/search.py):

import yfinance as yf # 获取报价列表 quotes = yf.Search("AAPL", max_results=10).quotes # 获取新闻列表 news = yf.Search("Google", news_count=10).news # 获取相关研究内容 research = yf.Search("apple", include_research=True).research

Search的构造参数支持max_results(报价结果数量上限)、news_count(新闻数量)与include_research(是否包含研究内容),三个属性quotesnewsresearch分别对应三类结果(实现见 yfinance/search.py)。该组件适合做关键词驱动的投研信息聚合,例如按行业热点收集新闻。


九、核心组件七:Sector 与 Industry——行业板块信息

SectorIndustry分别封装 Yahoo 的行业板块数据。官方示例(doc/source/reference/examples/sector_industry.py):

import yfinance as yf tech = yf.Sector('technology') software = yf.Industry('software-infrastructure') # 公共信息(Sector 与 Industry 通用) tech.key tech.name tech.symbol tech.ticker # 与该板块关联的 Ticker 对象 tech.overview tech.top_companies tech.research_reports # Sector 独有信息 tech.top_etfs tech.top_mutual_funds tech.industries # Industry 独有信息 software.sector_key software.sector_name software.top_performing_companies software.top_growth_companies

9.1 与 Ticker 双向联动

板块与个股之间可以互相转换(官方示例 doc/source/reference/examples/sector_industry_ticker.py):

import yfinance as yf # Ticker -> Sector 和 Industry msft = yf.Ticker('MSFT') tech = yf.Sector(msft.info.get('sectorKey')) software = yf.Industry(msft.info.get('industryKey')) # Sector/Industry -> Ticker(获取代表性标的) tech_ticker = tech.ticker tech_ticker.info software_ticker = software.ticker software_ticker.history()

这个双向转换能力非常实用:你可以从任意个股出发拿到它所属的板块与行业,再借助top_companiestop_etfstop_mutual_funds等属性扩展出"同板块候选池",从而构建行业轮动或同业对比的分析流程。相关实现位于 yfinance/domain/sector.py 与 yfinance/domain/industry.py。


十、核心组件八:EquityQuery 与 Screener——市场筛选

EquityQuery(以及FundQueryETFQuery)用于构建结构化筛选条件,screen()函数则执行筛选。从源码看(yfinance/screener/query.py):

  • 值运算EQ(等于)、IS-IN(属于)、BTWN(介于)、GT(大于)、LT(小于)、GTE(大于等于)、LTE(小于等于);
  • 逻辑组合ANDOR

例如,可以基于地区(region)、行业(sector)、交易所(exchange)等条件构造股票筛选器,然后通过 yfinance/screener/screener.py 中的screen(query, offset, size, sortField, sortAsc, ...)执行,返回符合条件的标的列表。该模块还预置了一批常用筛选查询(PREDEFINED_SCREENER_QUERIES,见 yfinance/init.py),可直接用于快速筛选"最活跃"、"涨幅榜"等场景(Calendars示例中就曾用到screen(query="MOST_ACTIVES"))。


十一、进阶能力:Calendars、FundsData、Auth 与代理

除了 README 列出的八大组件,yfinance 还提供了几项值得掌握的进阶能力。

11.1 Calendars——事件日历

Calendars提供财报、IPO、拆股、经济事件四类日历数据,并支持按市值、活跃度过滤(官方示例 doc/source/reference/examples/calendars.py):

import yfinance as yf from datetime import datetime, timedelta # 默认初始化(今天 + 7 天) calendar = yf.Calendars() # 只取今天之后 1 天的事件 tomorrow = datetime.now() + timedelta(days=1) calendar = yf.Calendars(end=tomorrow) # 默认查询:访问属性即触发数据获取 calendar.earnings_calendar calendar.ipo_info_calendar calendar.splits_calendar calendar.economic_events_calendar # 手动查询(带自定义参数) calendar.get_earnings_calendar( market_cap=100_000_000, # 过滤掉小市值公司 filter_most_active=True, # 只显示活跃交易标的(内部使用 screen(query="MOST_ACTIVES")) ) # 实战示例:找出临近发布但尚未披露财报的公司 today = datetime.now() is_friday = today.weekday() == 4 day_after_tomorrow = today + timedelta(days=4 if is_friday else 2) calendar = yf.Calendars(today, day_after_tomorrow) df = calendar.get_earnings_calendar(limit=100) unreported_df = df[df["Reported EPS"].isnull()]

11.2 FundsData——基金/ETF 专属数据

对于 ETF 或共同基金标的,Ticker.funds_data提供持仓与运作信息(官方示例 doc/source/reference/examples/funds_data.py):

import yfinance as yf spy = yf.Ticker('SPY') data = spy.funds_data data.description # 基金描述 data.fund_overview # 基金概览 data.fund_operations # 运作信息 data.asset_classes # 资产类别 data.top_holdings # 前十大持仓 data.equity_holdings # 股票持仓明细 data.bond_holdings # 债券持仓明细 data.bond_ratings # 债券评级 data.sector_weightings # 行业权重

该能力让 yfinance 从"股票工具"扩展到了"基金研究工具",相关实现位于 yfinance/scrapers/funds.py。

11.3 Auth——登录态与会话管理

Auth允许你将浏览器中获得的登录 Cookie 注入会话,从而以登录用户身份请求数据(官方示例 doc/source/reference/examples/auth.py):

import yfinance as yf import os auth = yf.Auth() # 设置从浏览器获取的登录 Cookie。该调用会存储、实时校验并返回登录结果。 if auth.set_login_cookies(os.getenv("COOKIE_T"), os.getenv("COOKIE_Y")): print("Logged in") else: print("Invalid or expired cookies") # 此后所有发往 Yahoo Finance 的请求都携带该登录态。 # 随时重新校验实时登录状态(每次调用都会重新查询,不做缓存)。 auth.check_login() # -> True / False # 查询账户的订阅层级。 auth.subscription_tier() # -> 'gold' / 'silver' / 'bronze' / 'free' / None # 访问用户信息。 auth.user # -> {'guid': ...} or None

从源码看(yfinance/data.py),set_login_cookies会以线程安全的方式把TY两个 Cookie 写入全局会话,并清除旧 crumb(crumb 可能与匿名态不匹配),强制在下一请求重新生成与当前 Cookie 匹配的 crumb,从而让登录态干净生效。同时,会话的 cookie 策略切换(basic/csrf)在登录态下不会清空用户 Cookie 锅,避免"静默登出"(yfinance/data.py)。

11.4 代理(Proxy)支持

所有请求级接口都支持proxy参数(官方示例 doc/source/reference/examples/proxy.py):

import yfinance as yf msft = yf.Ticker("MSFT") msft.history(..., proxy="PROXY_SERVER") msft.get_actions(proxy="PROXY_SERVER") msft.get_dividends(proxy="PROXY_SERVER") msft.get_splits(proxy="PROXY_SERVER") msft.get_capital_gains(proxy="PROXY_SERVER") msft.get_balance_sheet(proxy="PROXY_SERVER") msft.get_cashflow(proxy="PROXY_SERVER") msft.option_chain(..., proxy="PROXY_SERVER")

此外,也可以通过全局配置设置代理:yf.config.network.proxy = proxy(旧的yf.set_config(proxy=...)方式已被标记为弃用,见 yfinance/init.py)。底层实现会将字符串代理统一规范化为{"http": ..., "https": ...}字典后挂到会话上(yfinance/data.py)。


十二、底层架构:YfData 单例与缓存机制

理解 yfinance 的底层架构有助于你更好地使用它。从源码看(yfinance/data.py):

  • YfData是单例(通过SingletonMeta元类实现):整个进程共享一个请求会话、一份 cookie 和一份 crumb,这既保证了多线程并发下的数据一致性,也大幅提升了请求效率(cookie/crumb 只需获取一次)。
  • 自带响应缓存YfData通过lru_cache装饰器缓存数据(yfinance/data.py),把字典/列表参数冻结后作为缓存键,默认缓存容量为 64。
  • cookie 策略自动切换:默认使用basic策略,失败时回退到csrf(yfinance/data.py)。
  • 瞬时错误重试:对TimeoutErrorConnectionError等瞬时网络错误(yfinance/data.py),请求层会自动重试。

这正是上一节提到"缓存型会话会被拒绝"的原因:yfinance 已经内置了完整的缓存与重试链路,外部再叠加requests_cache反而会引入脏数据。


十三、调试与测试

排查问题时可以开启调试日志:

import yfinance as yf yf.enable_debug_mode()

该函数由 yfinance/utils.py 提供,开启后能观察每次请求的 URL、cookie 策略切换与重试过程(yfinance/data.py 中的日志即由此输出)。

仓库自带完整测试套件(tests/),其中与下载、价格修复相关的重点测试文件包括:

  • tests/test_prices.py——历史行情下载与复权逻辑;
  • tests/test_price_repair.py——repair=True的价格修复逻辑,配套 tests/data/ 目录下大量*-bad-*.csv/*-fixed.csv成对数据,覆盖了"分红错乱"(bad-div)、"拆股错乱"(bad-stock-split)、"100 倍单位错乱"(100x-error)等真实场景;
  • tests/test_ticker.py、tests/test_multi.py、tests/test_live.py——分别覆盖Ticker、批量下载与 WebSocket 功能。

如果你想运行测试验证环境,可按 doc/source/development/running.rst 与 doc/source/development/testing.rst 中的说明操作。


十四、法律与合规提示

最后必须强调 README 中明确说明的事项:

  1. 商标声明:Yahoo!、Y!Finance 与 Yahoo! finance 是 Yahoo, Inc. 的注册商标。
  2. 非官方工具:yfinance 与 Yahoo, Inc. 没有任何从属、背书或审查关系。它是一个使用 Yahoo 公开 API 的开源工具,仅用于研究与教育目的。
  3. 使用条款:在使用下载的数据前,你应当自行查阅 Yahoo! 的服务条款,确认你对所下载数据的使用权利。Yahoo! Finance API 仅限个人用途。
  4. 开源协议:yfinance 基于Apache Software License分发,详见 LICENSE.txt。

如果你希望参与社区共建、提交 Bug 报告或贡献代码,可以参考 CONTRIBUTING.md 中的指引。

【免费下载链接】yfinanceDownload market data from Yahoo! Finance's API项目地址: https://gitcode.com/GitHub_Trending/yf/yfinance

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询