第三章 金融数据获取:把市场装进你的数据库
做量化交易,第一步就是搞数据。这就像盖房子要先打地基,数据质量直接决定策略的生死。我见过太多人花几个月写策略,结果数据源一换,回测曲线直接崩盘——说白了,数据获取这个环节,再怎么重视都不为过。
这一章,我带你搞定三件事:股票数据怎么拿、经济数据怎么拿、拿完之后怎么存。咱们用 Python 里最趁手的两个库——yfinance 和 pandas-datareader,再加点存储技巧,把整个流程跑通。
核心知识点一览:
- yfinance:获取美股、A股(部分)的日线/分钟线数据
- pandas-datareader:获取宏观经济指标(GDP、CPI、利率等)
- CSV vs HDF5:两种存储方式的优劣对比与实战选择
3.1 用 yfinance 拿股票数据
yfinance 这个库,我用了快五年了。它底层接的是 Yahoo Finance 的接口,免费、稳定、覆盖广。美股数据尤其全,A股也能拿到大部分,但港股偶尔会缺字段。
安装很简单,一行命令搞定:
pip install yfinance
来,直接上手。拿苹果公司(AAPL)最近一年的日线数据:
import yfinance as yf
# 下载数据
aapl = yf.download('AAPL', start='2023-01-01', end='2024-01-01')
print(aapl.head())
输出长这样:
| Date | Open | High | Low | Close | Volume |
|---|---|---|---|---|---|
| 2023-01-03 | 130.28 | 131.74 | 128.12 | 129.93 | 73456700 |
| 2023-01-04 | 128.90 | 130.39 | 127.52 | 129.62 | 63245600 |
你看,Open、High、Low、Close、Volume 全齐了。做技术分析完全够用。
我的小技巧: 如果你要拿多只股票,别一个个下载。用列表传参,yfinance 会自动返回一个 MultiIndex 的 DataFrame,处理起来特别方便。
tickers = ['AAPL', 'MSFT', 'GOOGL']
data = yf.download(tickers, start='2023-01-01', end='2024-01-01')
# data['Close'] 就是三只股票的收盘价矩阵
嗯,这里要注意一点:yfinance 默认返回的是调整后的价格(Adjusted Close),已经考虑了分红和拆股。我个人建议直接用调整价做回测,更贴近真实收益。
3.2 用 pandas-datareader 拿经济数据
股票数据只是半边天。做量化策略,宏观经济数据往往能提供大方向。比如利率变化影响估值、CPI 数据影响消费板块——这些因子,有时候比技术指标还管用。
pandas-datareader 就像一个数据中转站,它帮你从 FRED(美联储经济数据库)、世界银行、雅虎财经等源拉数据。安装:
pip install pandas-datareader
举个例子,拿美国联邦基金利率(FRED 代码:FEDFUNDS):
import pandas_datareader.data as web
import datetime
start = datetime.datetime(2020, 1, 1)
end = datetime.datetime(2024, 1, 1)
rate = web.DataReader('FEDFUNDS', 'fred', start, end)
print(rate.head())
输出:
| DATE | FEDFUNDS |
|---|---|
| 2020-01-01 | 1.55 |
| 2020-02-01 | 1.58 |
| 2023-07-01 | 5.12 |
你看,从 2020 年的 1.55% 到 2023 年的 5.12%,这中间的变化,对股市的影响是巨大的。
避坑指南: 我曾经在回测里直接用 FRED 的月度数据,没注意它发布有滞后。比如 1 月份的数据,实际 2 月中旬才公布。如果你在回测里假设 1 月初就知道这个数据,那就是未来函数!记得用 shift(1) 或者对齐到实际公布日期。
除了 FRED,世界银行的数据也很实用。比如拿中国的 GDP 增长率:
gdp = web.DataReader('NY.GDP.MKTP.KD.ZG', 'worldbank', start=2010, end=2023)
print(gdp.loc['CN']) # 只看中国
3.3 数据存储:CSV 还是 HDF5?
数据拿到了,总不能每次都重新下载吧?存下来才是王道。我常用的两种格式:CSV 和 HDF5。
CSV: 简单、通用、人类可读。适合小数据量、调试阶段、或者需要跟别人分享的场景。
# 保存
aapl.to_csv('aapl_2023.csv')
# 读取
df = pd.read_csv('aapl_2023.csv', index_col=0, parse_dates=True)
HDF5: 二进制格式,读写快、压缩率高、支持复杂数据结构。适合大数据量、生产环境。
# 保存
aapl.to_hdf('market_data.h5', key='aapl', mode='a')
# 读取
df = pd.read_hdf('market_data.h5', key='aapl')
我个人的经验是:
- 数据量小于 100MB,用 CSV 就行,省心
- 超过 100MB,或者你有几十只股票、几年数据,果断上 HDF5
- 如果你需要频繁读写(比如每天增量更新),HDF5 的优势更明显
实战建议: 我一般这样组织存储结构:
- 一个 HDF5 文件,里面按股票代码分 key(比如 'AAPL'、'MSFT')
- 每个 key 存一个 DataFrame,包含该股票的所有历史数据
- 经济数据单独存一个文件,按指标分 key
这样既清晰,又方便后续策略调用。
最后,给你一个完整的示例,把今天学的串起来:
import yfinance as yf
import pandas_datareader.data as web
import pandas as pd
from datetime import datetime
# 1. 获取股票数据
sp500 = yf.download('^GSPC', start='2020-01-01', end='2024-01-01')
# 2. 获取经济数据(联邦基金利率)
start = datetime(2020, 1, 1)
end = datetime(2024, 1, 1)
fed_rate = web.DataReader('FEDFUNDS', 'fred', start, end)
# 3. 合并到同一个 DataFrame
# 注意:股票数据是日频,利率是月频,需要对齐
sp500['FedRate'] = fed_rate.reindex(sp500.index, method='ffill')
# 4. 存储到 HDF5
sp500.to_hdf('sp500_with_fed.h5', key='sp500', mode='w')
print("数据获取与存储完成!")
print(sp500.tail())
你看,整个流程其实不复杂。但就是这些基础操作,决定了你后续策略开发的效率。数据拿对了、存好了,后面写策略的时候才能心不慌。
最后提醒一句: 数据源偶尔会挂。yfinance 有时候会限流,FRED 偶尔维护。我建议你写个定时任务,每天收盘后自动拉数据,存到本地。这样即使源站出问题,你手里也有一份历史数据兜底。