4. 因子数据获取:数据源选择与数据清洗预处理
做量化策略,第一步就是搞数据。这步要是没做好,后面再牛的模型也是白搭。我见过太多人花大把时间调参数,结果问题出在数据上——脏数据、缺失值、幸存者偏差,随便一个就能让你的回测结果变成笑话。
今天咱们就聊聊数据源怎么选,数据怎么洗。说白了,就是怎么把原材料弄到手,再加工成能下锅的食材。
4.1 数据源选择:三大主流方案
目前国内做量化,主流数据源就三个:Wind、Bloomberg、Tushare。我三个都用过,各有各的脾气。
| 数据源 | 覆盖范围 | 更新频率 | 成本 | 适合场景 |
|---|---|---|---|---|
| Wind | A股、港股、期货、基金 | 实时/日频 | 高(年费数万) | 机构、专业团队 |
| Bloomberg | 全球股票、债券、衍生品 | 实时/日频 | 极高(年费数十万) | 跨境、全球配置 |
| Tushare | A股、基金、指数 | 日频/分钟 | 低(积分制) | 个人、小团队 |
Wind 是国内机构的标准配置。数据全,接口稳定,但贵。我记得刚入行那会儿,公司每年光Wind终端就花好几万。不过说实话,值这个价——数据质量高,字段齐全,做Smart Beta因子研究基本离不开它。
Bloomberg 做全球市场必备。如果你只做A股,没必要上Bloomberg。但要是涉及美股、港股或者跨境套利,那Bloomberg的实时数据流确实香。不过价格嘛...嗯,小团队基本不用想。
Tushare 是个人玩家的福音。免费版够用,付费版也不贵。我有个朋友自己在家做量化,就用Tushare,跑得也挺好。缺点就是数据偶尔会有延迟,做高频肯定不行,但做日频因子研究完全够用。
4.2 数据清洗:脏数据是最大的敌人
数据拿到手,别急着用。先洗一洗。我做过一个统计,在真实的因子研究中,数据清洗和预处理的时间占了整个流程的60%以上。为什么?因为数据太脏了。
常见的脏数据问题:
- 缺失值:停牌、退市、节假日,各种原因导致数据缺失
- 异常值:价格突变、成交量异常,可能是数据录入错误
- 幸存者偏差:只保留了当前存活的股票,退市的被删掉了
- 前视偏差:用到了未来数据,回测结果虚高
我曾经接手过一个策略,回测年化收益30%,实盘直接亏成狗。查了半天,发现数据里用了未来函数——用当天的收盘价去算当天的因子值。你说这能不出问题吗?
4.3 数据预处理实战流程
下面是我个人习惯的一套预处理流程,供你参考:
# 伪代码示例:数据预处理流程
def preprocess_data(df):
# 1. 去重
df = df.drop_duplicates()
# 2. 处理缺失值
# 停牌日期的数据用前值填充
df = df.fillna(method='ffill')
# 3. 剔除异常值
# 用3倍标准差法
mean = df['factor'].mean()
std = df['factor'].std()
df = df[(df['factor'] > mean - 3*std) &
(df['factor'] < mean + 3*std)]
# 4. 标准化
df['factor'] = (df['factor'] - mean) / std
return df
这里有几个坑要注意:
- 处理缺失值时,千万别用全局均值填充。不同股票的波动率差异很大,用全局均值会引入偏差。
- 剔除异常值时,要分行业处理。银行股的市盈率普遍低,科技股普遍高,混在一起剔除会误杀。
- 标准化一定要在截面内做,不能跨时间。否则会引入未来信息。
4.4 数据对齐:时间序列的命门
做因子研究,最怕的就是数据没对齐。比如你拿到的股票价格是收盘价,但因子数据用的是开盘价,那算出来的相关性就是错的。
我一般这样处理:
- 所有数据统一到同一个时间戳(比如都用交易日收盘时间)
- 遇到节假日,用前一个交易日的数据填充
- 不同频率的数据(日频、周频),统一降采样到最低频率
说白了,就是让所有数据站在同一个时间点上说话。不然你想想看,一个说今天的数据,一个说昨天的数据,这能对得上吗?
4.5 知识体系总览
下面这张图,是我自己总结的数据获取与预处理的核心逻辑。你可以对照着看,每一步都别跳过。
核心要点: 数据获取和预处理是整个因子研究的基础。数据源选对了,能省一半的力气。数据洗得干净,回测结果才可信。别嫌麻烦,这一步值得花时间。
好了,今天就聊到这儿。数据这块儿,说白了就是「慢工出细活」。你花在数据上的每一分钟,都会在后面的策略开发中加倍回报给你。