第二章:宏观经济数据获取

做量化模型,最头疼的是什么?不是算法,不是策略,而是——数据。

我刚开始做宏观因子模型那会儿,花在数据上的时间占了整个项目的一大半。你想想看,模型再漂亮,数据是垃圾,结果就是垃圾。说白了,数据获取和清洗,才是整个系统的地基。

2.1 数据来源:央行、统计局、Wind 等

宏观数据从哪里来?我列几个最常用的,也是我个人习惯用的。

2.1.1 央行(中国人民银行)

央行的数据,主要是货币政策相关的。比如:

  • M2、M1、M0 货币供应量
  • 贷款市场报价利率(LPR)
  • 存款准备金率
  • 外汇储备

这些数据在央行官网的「统计数据」栏目下都能找到。不过,手动下载太慢了。我一般用 Python 直接爬,或者用现成的接口。

2.1.2 国家统计局

统计局的数据,覆盖面最广。比如:

  • GDP(季度、年度)
  • CPI、PPI(月度)
  • 工业增加值
  • 固定资产投资
  • 社会消费品零售总额

统计局官网有 Excel 下载,但格式经常变。嗯,这里要注意:不同年份的数据,表格结构可能不一样。我踩过这个坑,后面会讲怎么处理。

2.1.3 Wind(万得)

Wind 是国内金融圈最常用的数据终端。数据全、更新快,但贵。如果你在机构工作,大概率有 Wind 账号。Wind 有 Python 接口(WindPy),可以直接拉数据。

我个人建议:如果预算允许,Wind 是首选。数据质量高,省去很多清洗的麻烦。

2.1.4 其他来源

  • 财政部:国债收益率、财政收支
  • 海关总署:进出口数据
  • 中国货币网:Shibor、回购利率
  • 国际来源:美联储(FRED)、世界银行、IMF

2.2 Python 数据获取工具

有了数据源,怎么用 Python 拿数据?我常用的三个工具:

2.2.1 pandas-datareader

这个库是 pandas 的扩展,专门用来获取金融数据。支持 FRED、世界银行、Yahoo 等。

import pandas_datareader.data as web
import datetime

# 从 FRED 获取美国 GDP 数据
start = datetime.datetime(2000, 1, 1)
end = datetime.datetime(2024, 12, 31)
gdp = web.DataReader('GDP', 'fred', start, end)
print(gdp.head())

FRED 的数据很全,宏观指标应有尽有。我经常用它来获取美国利率、失业率等数据。

2.2.2 yfinance

yfinance 是 Yahoo Finance 的 Python 接口。虽然 Yahoo 在国内访问不太稳定,但用来获取美股、ETF 数据还是不错的。

import yfinance as yf

# 获取标普500指数数据
sp500 = yf.download('^GSPC', start='2000-01-01', end='2024-12-31')
print(sp500.head())

注意:yfinance 返回的是 DataFrame,包含开盘、收盘、最高、最低、成交量等字段。做因子模型时,我一般用收盘价计算收益率。

2.2.3 akshare

akshare 是我最推荐的国内数据工具。它封装了央行、统计局、交易所等几十个数据源,接口统一,用起来很爽。

import akshare as ak

# 获取中国 GDP 数据
gdp_china = ak.macro_china_gdp()
print(gdp_china.head())

# 获取 CPI 数据
cpi = ak.macro_china_cpi_monthly()
print(cpi.head())

akshare 的文档很详细,基本上你想得到的宏观数据,它都有。我做过一个项目,需要同时拉取 M2、CPI、工业增加值、PMI 四个指标,用 akshare 一行一个,十分钟搞定。

我的建议:国内宏观数据首选 akshare,国外数据用 pandas-datareader 或 yfinance。三个工具配合使用,基本覆盖所有需求。

2.3 数据清洗与预处理

数据拿到手,别急着建模。先看看数据长什么样。我见过太多人,数据都没看清楚,直接跑模型,结果跑出来一堆垃圾。

2.3.1 缺失值处理

宏观数据经常有缺失。比如 GDP 是季度数据,CPI 是月度数据,频率不一样。合并的时候,低频数据会有很多空值。

import pandas as pd

# 假设有两个 DataFrame:gdp(季度)和 cpi(月度)
# 合并后,GDP 列会有大量 NaN
merged = pd.merge(gdp, cpi, on='date', how='outer')

# 方法1:向前填充(用上一个值填充)
merged['gdp'].fillna(method='ffill', inplace=True)

# 方法2:插值法
merged['gdp'].interpolate(method='linear', inplace=True)

我个人习惯用向前填充。为什么?因为宏观数据发布有滞后性,比如 3 月份的 GDP 数据,可能 4 月底才公布。用前一个值填充,更符合实际情况。

2.3.2 异常值处理

数据里偶尔会有离谱的值。比如 CPI 突然跳了 10%,一看是数据录入错误。

# 用 3 倍标准差法检测异常值
mean = data['cpi'].mean()
std = data['cpi'].std()
outliers = data[(data['cpi'] > mean + 3*std) | (data['cpi'] < mean - 3*std)]

# 处理:用中位数替换
data.loc[outliers.index, 'cpi'] = data['cpi'].median()
避坑指南:我曾经遇到过统计局某年 CPI 数据格式变了,列名从「居民消费价格指数」改成了「CPI(上年同月=100)」。如果不检查,直接读进来,数据全乱套。所以,每次拉数据,先打印 head() 看一眼。

2.3.3 频率对齐

宏观因子模型需要统一频率。常见做法:

  • 低频转高频:用插值或填充
  • 高频转低频:用均值或期末值
# 将季度 GDP 转为月度(用插值)
gdp_monthly = gdp.resample('M').interpolate()

# 将日度利率转为月度(用月末值)
rate_monthly = rate.resample('M').last()

2.3.4 数据标准化

不同指标量纲不同,比如 GDP 是万亿,CPI 是百分比。建模前需要标准化。

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)
data_scaled = pd.DataFrame(data_scaled, columns=data.columns, index=data.index)

标准化后,所有指标均值为 0,标准差为 1。这样在因子模型中,系数大小可以直接比较。

2.4 本章知识体系

下面这张图,是我自己总结的数据获取与处理流程。你照着这个走,基本不会出错。

宏观数据获取与处理流程 数据源 央行 / 统计局 / Wind Python 获取工具 pandas-datareader / yfinance / akshare 原始数据 DataFrame 数据清洗与预处理 缺失值处理 填充 / 插值 异常值检测 3σ / IQR 频率对齐 resample 标准化 StandardScaler 清洗后数据 可直接建模

这张图把整个流程串起来了。从数据源开始,到获取工具,再到清洗预处理,最后得到可以直接建模的数据。每一步都有对应的 Python 工具和方法。

核心要点:
  • 数据源要可靠:央行、统计局、Wind 是首选
  • 获取工具要顺手:akshare 是国内数据的最佳选择
  • 清洗要仔细:缺失值、异常值、频率对齐,一步都不能少
  • 标准化要统一:让不同量纲的指标可以比较

好了,数据获取和清洗就讲到这里。下一章,我们会把这些数据真正用起来,构建宏观因子。但在此之前,我建议你先把本章的代码跑一遍,亲手拉一次数据,清洗一次。只有亲手做过,才知道坑在哪里。


专注资料整理