第二章:因子数据获取——数据源选择、清洗与对齐实战
做多因子策略,第一步就是搞数据。这一步要是没做好,后面再牛的模型也是白搭。我见过太多人,模型跑得飞起,结果一查,数据里全是坑。今天咱们就聊聊,怎么把数据这块地基打牢。
2.1 数据源怎么选?我的实战经验
国内主流的数据源,说白了就三个:Wind、Tushare、聚宽。每个我都用过,各有各的脾气。
| 数据源 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|
| Wind | 数据全、权威、更新快 | 贵、接口复杂、本地部署 | 机构、实盘 |
| Tushare | 免费、社区活跃、文档好 | 有积分限制、偶尔不稳定 | 个人研究、回测 |
| 聚宽 | 一站式、因子库丰富、云平台 | 数据深度不够、定制化弱 | 快速验证、入门 |
我个人习惯是:研究阶段用Tushare,实盘前用Wind做交叉验证。为什么?因为Tushare免费,而且社区里有很多现成的因子代码,能省不少时间。但实盘时,Wind的数据质量确实更靠谱。
2.2 数据清洗——别让脏数据毁了你的模型
数据拿到手,第一件事不是跑模型,而是清洗。你想想看,如果原始数据里就有错误,那算出来的因子能准吗?
常见的脏数据有这些:
- 缺失值: 某天某只股票停牌,数据是空的
- 异常值: 比如市盈率突然变成10000倍
- 重复值: 同一天同一只股票出现两条记录
- 格式问题: 日期格式不统一,有的用"2024-01-01",有的用"2024/01/01"
嗯,这里要注意。清洗不是一股脑全删掉。我曾经在项目里遇到过一个情况:某只股票因为重大资产重组停牌了三个月,复牌后数据全是缺失的。如果直接删掉,那这只股票的历史数据就全没了。后来我用了前向填充法,用停牌前的最后一个值填充,才保住了数据。
2.3 数据对齐——多因子的核心难点
多因子模型里,不同因子的数据频率可能不一样。比如动量因子是日频的,而估值因子可能是季频的。怎么把它们对齐到同一个时间点上?
我常用的方法是:以交易日为基准,向后填充。什么意思呢?
- 先拿到所有交易日的列表
- 对于日频因子,直接对齐
- 对于低频因子(如季频),用最近一次公布的数据填充
举个例子:某公司2024年一季报在4月30日公布,那从4月30日到下一次公布日之前,都用这个数据。这叫做"无偏填充"——因为你只能用已经知道的信息。
2.4 缺失值处理实战——三种方法对比
缺失值处理,说白了就三种思路:删、填、预测。我直接上代码,你们感受一下。
import pandas as pd
import numpy as np
# 模拟数据
dates = pd.date_range('2024-01-01', periods=10, freq='D')
data = {
'PE': [15, 16, np.nan, 14, 15, np.nan, 17, 16, 15, 14],
'PB': [1.5, 1.6, 1.4, np.nan, 1.5, 1.6, 1.7, np.nan, 1.5, 1.4],
'MOM': [0.02, 0.01, 0.03, 0.02, np.nan, 0.01, 0.02, 0.03, 0.01, 0.02]
}
df = pd.DataFrame(data, index=dates)
# 方法1:删除缺失值
df_drop = df.dropna()
print("删除后行数:", len(df_drop))
# 方法2:前向填充(我最常用的)
df_ffill = df.ffill()
print("前向填充后:\n", df_ffill)
# 方法3:线性插值
df_interp = df.interpolate(method='linear')
print("线性插值后:\n", df_interp)
这三种方法,我个人的使用频率是:前向填充占70%,线性插值占20%,删除占10%。为什么?因为金融数据有很强的时序相关性,前向填充最符合"用已知信息推断未知"的逻辑。
2.5 数据对齐的完整流程
说了这么多,咱们画个图,把整个流程串起来。这样你心里就有谱了。
你看,整个流程是环环相扣的。数据源选对了,清洗干净了,缺失值处理好了,对齐做好了,后面的因子计算才能放心。
2.6 实战中的几个坑
最后,分享几个我在实战中踩过的坑,你们能避就避:
- 坑一: 不同数据源的股票代码格式不一样。Wind是"000001.SZ",Tushare是"000001"。我一开始没注意,结果合并数据时全乱了。后来统一用"symbol"字段,自己写个映射表。
- 坑二: 复权数据要小心。前复权和后复权算出来的收益率不一样。我建议统一用后复权,因为前复权会改变历史价格,容易出问题。
- 坑三: 停牌股票的处理。停牌期间没有交易数据,但财务数据可能还在更新。我的做法是:停牌期间用最后交易日的价格,但财务数据正常更新。
好了,数据获取这块就聊到这儿。记住一句话:数据质量决定了策略的上限。把数据搞干净了,后面的工作才能事半功倍。