第三章:数据获取——用 yfinance 搞定美股历史数据

做量化交易,数据就是你的石油。没有数据,再牛的模型也是空中楼阁。

这一章,我们来聊聊怎么用 Python 把美股数据拉下来。我用的工具是 yfinance,一个非常轻量的库。说实话,我刚开始做美股回测时,也试过各种付费数据源,后来发现 yfinance 对于大多数策略研究来说,完全够用。

3.1 安装与基本用法

先装库,一行命令搞定:

pip install yfinance

然后拉取单只股票的历史数据。比如苹果:

import yfinance as yf

# 下载 AAPL 从 2020-01-01 到 2023-12-31 的日线数据
aapl = yf.download("AAPL", start="2020-01-01", end="2023-12-31")
print(aapl.head())

返回的是一个 DataFrame,包含 Open、High、Low、Close、Volume、Adj Close 六列。嗯,这里要注意:Adj Close 是复权收盘价,做回测时一定要用它,否则分红拆股会把你坑惨。

💡 我的习惯: 每次下载数据后,先检查一下数据长度。有时候节假日或者停牌会导致数据缺失,提前发现比跑完策略才发现要好得多。

3.2 多股票数据获取

单只股票太孤单,我们通常要处理一篮子股票。比如标普500的成份股。

yfinance 支持一次性传入多个 ticker:

tickers = ["AAPL", "MSFT", "GOOGL", "AMZN", "META"]
data = yf.download(tickers, start="2020-01-01", end="2023-12-31")
print(data.head())

返回的数据结构是 MultiIndex DataFrame。列名变成了两层:第一层是价格类型(Open、Close...),第二层是股票代码。

我个人习惯把它整理成更易用的格式。比如只取收盘价:

close_prices = data["Close"]
print(close_prices.head())

这样每列就是一只股票的收盘价序列,做相关性分析、协整检验都方便多了。

⚠️ 我曾经踩过的坑: 有些 ticker 可能已经退市或者改名了。比如 FB 改成了 META。如果你用旧 ticker 去拉数据,yfinance 会返回空 DataFrame。建议先验证一下 ticker 的有效性。

3.3 数据频率选择:日线 vs 分钟线

yfinance 默认返回日线数据。但如果你想做高频策略,就需要分钟线。

获取分钟线数据,加一个 interval 参数:

# 获取 1 分钟线数据
aapl_1min = yf.download("AAPL", period="5d", interval="1m")
print(aapl_1min.head())

# 获取 5 分钟线数据
aapl_5min = yf.download("AAPL", period="1mo", interval="5m")
print(aapl_5min.head())

这里有个限制:yfinance 的分钟线数据最多只能拉取过去 60 天。而且数据量很大,1 分钟线一天就有 390 根 K 线(美股交易时间 6.5 小时)。

频率 interval 参数 最大可获取周期 适用场景
日线 "1d" 无限制 中长线策略、基本面分析
周线 "1wk" 无限制 趋势跟踪、宏观分析
月线 "1mo" 无限制 长期投资、资产配置
1 分钟 "1m" 过去 7 天 日内高频交易
5 分钟 "5m" 过去 60 天 日内短线策略
15 分钟 "15m" 过去 60 天 日内波段交易
30 分钟 "30m" 过去 60 天 日内趋势跟踪
60 分钟 "60m" 过去 730 天 短线至中线策略
🔑 核心建议: 做策略研究时,先用日线验证逻辑。日线跑通了,再考虑用分钟线做精细化回测。别一上来就搞分钟线,数据量大、噪音多,容易过度拟合。

3.4 数据清洗与预处理

数据拉下来之后,别急着用。先做三件事:

  1. 检查缺失值:用 isnull().sum() 看看哪些列有空值
  2. 处理停牌日:美股没有涨跌停,但有停牌。停牌日的价格会保持不变,或者直接缺失
  3. 对齐时间戳:不同股票的交易时间可能略有差异,尤其是盘前盘后数据

我常用的清洗代码:

# 检查缺失值
print(close_prices.isnull().sum())

# 向前填充(停牌日沿用前一日价格)
close_prices_filled = close_prices.fillna(method='ffill')

# 删除仍然缺失的行(比如某只股票刚上市)
close_prices_clean = close_prices_filled.dropna(axis=1, how='any')
💡 避坑指南: 我曾经用未清洗的数据跑回测,结果某只股票因为停牌三天,策略在那三天里疯狂交易,回测收益高得离谱。后来发现是数据问题。所以,数据清洗是回测的第一道防线

3.5 本章知识体系

下面这张图,帮你理清数据获取的完整流程:

数据获取流程 安装 yfinance 单只股票下载 多只股票下载 频率选择 日线 (1d) 周线 (1wk) 分钟线 (1m/5m/15m...) 月线 (1mo) 数据清洗与预处理

从安装到清洗,每一步都有坑。但只要你按照这个流程走,数据质量就有保障。

3.6 实战小贴士

  • 缓存数据:每次跑策略都重新下载数据太慢了。我习惯把数据存成 CSV 或 Parquet 格式,下次直接读取。
  • 注意时区:yfinance 返回的时间是 UTC 时间。美股交易时间对应的是美东时间。做分钟线策略时,一定要转换时区。
  • 限流问题:yfinance 没有官方 API Key,但频繁请求会被限流。我一般每次请求间隔 0.5 秒,批量下载时分批处理。
📌 总结一下: yfinance 是入门美股数据获取的最佳选择。它免费、轻量、支持多股票和多频率。但要注意数据清洗和频率限制。下一章,我们会用这些数据来构建第一个预测模型。

专注资料整理