yfinance 完全实战指南:从安装到市场数据获取避坑
【免费下载链接】yfinanceDownload market data from Yahoo! Finance's API项目地址: https://gitcode.com/GitHub_Trending/yf/yfinance
敲下import yfinance as yf的那一刻,大多数人以为 yfinance 安装完毕、市场数据到手,工作就结束了。恰恰相反,真正决定你的管道能否长期稳定跑起来的,是装完之后那些不显眼的细节:缓存放哪、价格断档怎么修、429 限流怎么扛。这篇文章按"装好 → 拉数 → 修数 → 提速 → 长跑"的真实顺序,把每一步的坑一次讲清。
yfinance 安装:一条命令部署,一个参数解锁数据修复
yfinance 支持 Python 3.8 及以上版本(当前版本 1.6.0),依赖会自动带上 pandas、numpy、requests 等。如果你会碰美国以外的市场数据,强烈建议连repair扩展一起装——它补上 scipy 和 scikit-learn,后面的价格自动修复全靠它们:
python -m pip install "yfinance[repair]"这一条命令装完即含数据修复能力;纯美股日线用户装yfinance本体也够用。装完用下面这行确认版本:
python -c "import yfinance; print(yfinance.__version__)"很多人会忽略一个细节:yfinance 会在本地维护时区、Cookie、ISIN 三类缓存,Linux 下默认落在~/.cache/py-yfinance。在容器或无家目录写权限的服务器上跑定时任务时,这里写不进去就会静默降级,建议在拉数前先指定位置:
import yfinance as yf yf.set_tz_cache_location("/var/cache/yf") # 必须在第一次请求前调用缓存目录设置只写一次,之后所有时区查询都走本地 SQLite,不再反复问 Yahoo。
第一次拉数:三行代码,注意 end 是"左闭右开"
最小可用的拉数代码就三行:
import yfinance as yf px = yf.download("AAPL", period="1y", auto_adjust=True) print(px.tail())period="1y"取最近一年日线;auto_adjust=True会让 OHLC 自动按分红拆股复权,想要原始未复权价就设False。
单只股票默认返回的是双层列(字段 × 股票代码),直接当普通表用会别扭。加一个参数拿扁平结构:
px = yf.download("AAPL", period="1y", multi_level_index=False)multi_level_index=False让单票结果变成普通 DataFrame,px["Close"]直接可用。
用start/end指定日期时要记住一个反直觉的坑:end是不包含的。想拿到 2022 年最后一天,得写end="2023-01-01"。另外 1 分钟级的分钟数据只有最近 60 天内的可用,拿更久的细粒度数据只能换interval="1h"或"1d"。
数据不对劲:先用 repair=True 试,再怀疑数据源
拉出来的价格出现"某一天突然翻倍"、"分红日价格纹丝不动",先别急着质疑 Yahoo——这些是非美股市场的高频毛刺,yfinance 内置的修复逻辑专门处理它们。核心就一个参数:
px = yf.Ticker("MOB.ST").history(period="max", repair=True) px["Repaired?"] # 新列,记录哪些行被修过repair=True会自动检测并修复下面四类典型异常,结果里多出一列Repaired?告诉你动了哪几行。
分红/拆股调整缺失
数据里有分红记录,但前一日Adj Close等于Close,说明复权漏了。修复会手动补上分红调整(下例为 8TRA.DE):
拆股场景同理,Yahoo 偶尔漏调拆股当日及之前的价格,修复会按拆股比例重算(下例为 MOB.ST):
100 倍货币单位错乱
同一只股票的前段价格莫名其妙放大 100 倍,多半是货币单位混用。检测出 100x 跳变后,修复会把异常段缩回正确量级,同时注意:真实货币要看Ticker.history_metadata['currency'],不是Ticker.info里那个字段。
缺行与坏数据
某天整行缺失或数值明显损坏时,修复逻辑会退到更细的粒度(比如用 1 小时数据)去重建日线,而不是留一个洞:
429 限流与空数据:把请求代码写成能扛的样子
短时间请求过密时,yfinance 会抛出YFRateLimitError(对应 HTTP 429)。正确姿势不是裸奔,而是把"限流"当成一类显式异常来处理:
from yfinance.exceptions import YFRateLimitError try: px = yf.download("^GSPC", period="max") except YFRateLimitError: print("被限流,稍后再来")批量脚本里更实用的写法是包一层指数退避重试,限流、瞬时网络错误一并兜住:
import time import yfinance as yf def safe_download(ticker, max_retries=3): for attempt in range(max_retries): try: return yf.download(ticker, period="1y") except Exception: if attempt == max_retries - 1: raise time.sleep(2 ** attempt)退避间隔按 1s、2s、4s 递增,比固定 sleep 更不容易触发下一轮限流。
再往下还有两个常被遗忘的开关,直接作用在网络层:
import yfinance as yf yf.config.network.retries = 2 # HTTP 层自动重试次数 yf.config.network.proxy = "http://127.0.0.1:7890" # 需要代理时启用retries让底层请求在超时后自动重试,省得你为小抖动写逻辑;proxy则解决网络环境受限的问题。想彻底搞清某次请求到底发生了什么,打开调试日志:
yf.config.debug.logging = True开启后 yfinance 会逐条打印每个 HTTP 请求的状态,排查"为什么这只票总是空"时是头等功臣。
批量下载加速:一次 download 拉一百只票
批量场景下别写 for 循环逐只请求。download的tickers参数直接接受空格分隔的字符串,内部并行拉取:
px = yf.download("AAPL MSFT GOOG JPM TSLA", period="1y", threads=True, group_by="ticker") px["AAPL"] # 按代码分组后直接取threads=True启用多线程并发;group_by="ticker"让顶层索引是股票代码,取某只票的整段数据一步到位。
历史跨度很长的票(比如十几年日线),单次请求容易超时。拆段拉取再拼接,比反复重试更可靠:
import pandas as pd d1 = yf.download("MSFT", start="2015-01-01", end="2018-01-01") d2 = yf.download("MSFT", start="2018-01-01", end="2021-01-01") px = pd.concat([d1, d2])注意前一段的end和后一段的start用同一个日期即可,因为end不含当天,天然不会重复。
拿到数据后花两秒钟做质量校验,能拦掉大部分下游事故:
px.isna().sum().sum() # 0 说明没有空洞 px.index.inferred_freq # 推断出的频率应稳定(日线为 D 附近)长期稳定跑:三个让定时任务不翻车的小习惯
第一,把版本当依赖管理。Yahoo 的接口会不定期变更,旧 yfinance 遇到新版接口常表现为"某只票突然没数据"这种难以定位的故障。每次排查前先确认版本,再看仓库根目录的 CHANGELOG.rst 里对应版本修了什么:
import yfinance print(yfinance.__version__) # 当前应为 1.6.0第二,给空数据留显式分支。退市股、代码写错、区间无数据,最终都可能落到YFPricesMissingError/YFTickerMissingError上。定时任务里捕获这两类异常并记录 ticker,比让整批任务崩掉更经济:
from yfinance.exceptions import YFPricesMissingError, YFTickerMissingError try: yf.download("DELISTED", period="1y") except (YFPricesMissingError, YFTickerMissingError) as e: print(f"跳过无数据代码:{e}")第三,升级前看一眼变更轨迹。项目的改动通常先在特性分支上进行,合并回主干后随版本发布,像下面这张分支结构图展示的那样:
所以"小步升级 + 对照 CHANGELOG 回归验证"比"一年一次大升级"安全得多。
想深入某个专题,可以直接翻仓库文档:缓存机制见 doc/source/advanced/caching.rst,价格修复原理见 doc/source/advanced/price_repair.rst,全部 API 速查见 doc/source/reference/index.rst。把上面几节的参数和习惯落进代码,yfinance 从"能跑一次"到"天天跑不坏"的距离,其实就差这几行配置。
【免费下载链接】yfinanceDownload market data from Yahoo! Finance's API项目地址: https://gitcode.com/GitHub_Trending/yf/yfinance
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考