第三章:数据采集实战——从FRED到Tushare的宏观数据获取
数据采集,说白了就是给量化模型找「食材」。没有干净的数据,再牛的模型也是白搭。我在做宏观因子库的时候,最头疼的不是策略设计,反而是数据源怎么对齐、频率怎么统一。今天咱们就手把手搞定这件事。
3.1 为什么选FRED和Tushare?
做宏观量化,数据源的选择很关键。我个人习惯用FRED拿美国数据,用Tushare拿中国数据。为什么?
- FRED:圣路易斯联储维护,数据全、历史长、免费。美国GDP、CPI、失业率这些核心指标,它都有。
- Tushare:国内最成熟的金融数据接口之一,覆盖中国宏观、股票、基金等。关键是文档清晰,社区活跃。
小提示:FRED的数据是公开的,但需要注册API Key。Tushare也是免费注册,但部分高频数据需要积分。建议先注册好,省得后面卡壳。
3.2 从FRED获取美国GDP、CPI、失业率
FRED的数据获取,我推荐用 fredapi 这个库。它封装了FRED的REST API,用起来很顺手。
先安装:
pip install fredapi
然后写个函数,一次性拉取三个指标:
from fredapi import Fred
import pandas as pd
# 初始化,填入你的API Key
fred = Fred(api_key='你的API_KEY')
# 定义指标代码
series_dict = {
'GDP': 'GDPC1', # 实际GDP,季度数据
'CPI': 'CPIAUCSL', # 消费者价格指数,月度数据
'UNRATE': 'UNRATE' # 失业率,月度数据
}
def fetch_fred_data(series_dict, start='2000-01-01', end='2024-12-31'):
df = pd.DataFrame()
for name, code in series_dict.items():
data = fred.get_series(code, observation_start=start, observation_end=end)
df[name] = data
return df
us_data = fetch_fred_data(series_dict)
print(us_data.head())
注意:FRED的API有调用频率限制,每分钟最多120次。我建议一次性拉取,不要循环里反复请求。曾经有个学员在循环里逐条拉取,结果被限流了半小时。
跑完代码,你会得到一个DataFrame。但注意,GDP是季度数据,CPI和失业率是月度数据。频率不一致,这就是我们后面要对齐的原因。
3.3 用Tushare获取中国宏观数据
Tushare的用法类似,但需要先注册获取token。安装命令:
pip install tushare
获取中国GDP、CPI、失业率的代码:
import tushare as ts
# 设置token
ts.set_token('你的TUSHARE_TOKEN')
pro = ts.pro_api()
# 获取中国GDP(季度)
gdp_cn = pro.cn_gdp(start_q='2000Q1', end_q='2024Q4')
# 获取中国CPI(月度)
cpi_cn = pro.cn_cpi(start_m='200001', end_m='202412')
# 获取城镇调查失业率(月度)
unemp_cn = pro.cn_unemp(start_m='200001', end_m='202412')
print(gdp_cn.head())
嗯,这里要注意。Tushare返回的数据字段名是中文的,比如「季度」、「同比」之类的。我建议拿到后统一重命名,方便后续处理。
3.4 数据频率对齐——最头疼的部分
数据拉回来了,但频率不一样。GDP是季度,CPI和失业率是月度。怎么对齐?
我个人总结了三种常用方法:
| 方法 | 适用场景 | 代码实现 |
|---|---|---|
| 低频转高频(插值) | 季度GDP转月度 | df.resample('M').interpolate() |
| 高频转低频(聚合) | 月度CPI转季度 | df.resample('Q').mean() |
| 保留原始频率 | 多因子模型 | 分别存储,建模时对齐 |
举个例子,把美国GDP从季度插值到月度:
# 确保索引是日期格式
us_data.index = pd.to_datetime(us_data.index)
# 只对GDP列做插值
gdp_monthly = us_data['GDP'].resample('M').interpolate(method='linear')
us_data['GDP_monthly'] = gdp_monthly
print(us_data[['GDP', 'GDP_monthly']].head(12))
核心原则:插值会引入「虚假信息」,低频转高频时慎用。如果模型对数据质量要求高,我建议保留原始频率,在建模时用时间戳对齐。
反过来,把月度CPI聚合成季度:
cpi_quarterly = us_data['CPI'].resample('Q').mean()
us_data['CPI_quarterly'] = cpi_quarterly
你看,就这么几行代码,频率对齐就搞定了。但实际项目中,你可能会遇到节假日、缺失值、数据更新延迟等问题。这些坑,我后面会专门讲。
3.5 本章知识体系
下面这张图,帮你理清数据采集到对齐的完整流程:
3.6 避坑指南
做数据采集这几年,我踩过的坑不少。挑几个典型的说说:
- 日期格式不一致:FRED返回的是美国日期格式,Tushare返回的是字符串。我建议统一转成
pd.Timestamp,省得后面报错。 - 数据更新延迟:FRED的GDP数据通常滞后一个季度。你拉取最新数据时,可能发现最后几行是NaN。别慌,这是正常的。
- API Key泄露:千万别把Key硬编码在代码里。我习惯用环境变量或者配置文件,.gitignore里记得加进去。
我的习惯:每次拉取数据后,先打印shape和dtypes,确认数据完整性。这一步花不了10秒,但能避免后面排查半天。
好了,数据采集这块就聊到这儿。你想想看,从FRED和Tushare拉数据,再对齐频率,其实核心就三步:获取、清洗、对齐。代码量不大,但细节不少。多跑几次,你就能找到感觉了。