第三章 金融数据获取:把市场装进你的数据库

做量化交易,第一步就是搞数据。这就像盖房子要先打地基,数据质量直接决定策略的生死。我见过太多人花几个月写策略,结果数据源一换,回测曲线直接崩盘——说白了,数据获取这个环节,再怎么重视都不为过。

这一章,我带你搞定三件事:股票数据怎么拿、经济数据怎么拿、拿完之后怎么存。咱们用 Python 里最趁手的两个库——yfinancepandas-datareader,再加点存储技巧,把整个流程跑通。

核心知识点一览:

  • yfinance:获取美股、A股(部分)的日线/分钟线数据
  • pandas-datareader:获取宏观经济指标(GDP、CPI、利率等)
  • CSV vs HDF5:两种存储方式的优劣对比与实战选择
金融数据获取 股票数据 yfinance 库 日线/分钟线/分红 经济数据 pandas-datareader FRED / 世界银行 数据存储 CSV(通用/调试) 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())

输出长这样:

DateOpenHighLowCloseVolume
2023-01-03130.28131.74128.12129.9373456700
2023-01-04128.90130.39127.52129.6263245600

你看,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())

输出:

DATEFEDFUNDS
2020-01-011.55
2020-02-011.58
2023-07-015.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 偶尔维护。我建议你写个定时任务,每天收盘后自动拉数据,存到本地。这样即使源站出问题,你手里也有一份历史数据兜底。

专注资料整理