第三章:数据采集实战——从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 本章知识体系

下面这张图,帮你理清数据采集到对齐的完整流程:

FRED(美国数据) Tushare(中国数据) GDP(季度) CPI(月度) 失业率(月度) 中国GDP(季度) 中国CPI(月度) 中国失业率(月度) 频率对齐处理 插值(低频→高频) | 聚合(高频→低频) | 保留原始频率 统一频率的宏观因子库

3.6 避坑指南

做数据采集这几年,我踩过的坑不少。挑几个典型的说说:

  • 日期格式不一致:FRED返回的是美国日期格式,Tushare返回的是字符串。我建议统一转成 pd.Timestamp,省得后面报错。
  • 数据更新延迟:FRED的GDP数据通常滞后一个季度。你拉取最新数据时,可能发现最后几行是NaN。别慌,这是正常的。
  • API Key泄露:千万别把Key硬编码在代码里。我习惯用环境变量或者配置文件,.gitignore里记得加进去。
我的习惯:每次拉取数据后,先打印shape和dtypes,确认数据完整性。这一步花不了10秒,但能避免后面排查半天。

好了,数据采集这块就聊到这儿。你想想看,从FRED和Tushare拉数据,再对齐频率,其实核心就三步:获取、清洗、对齐。代码量不大,但细节不少。多跑几次,你就能找到感觉了。


专注资料整理