第四章:数据准备与清洗

说实话,在量化投资这个行当里,我见过太多人把精力花在因子挖掘和模型调参上。结果呢?数据一塌糊涂,模型跑出来的结果自己都不敢信。数据准备这件事,说白了就是盖楼打地基。地基没打好,楼盖得再漂亮也得塌。

我个人习惯,花在数据清洗上的时间,至少占整个项目周期的40%。别嫌多,这很值得。今天咱们就聊聊数据准备里那些绕不开的坑。

核心观点: 数据质量决定了模型的上限。再牛的算法也救不了垃圾数据。

4.1 数据源选择:别在源头就输了

数据源的选择,我把它比作选食材。你要做一道顶级料理,结果买回来的菜是烂的,那再好的厨艺也白搭。

常见的金融数据源有这么几类:

  • 交易所官方数据:最权威,但贵,而且接口往往不太友好。我早期做美股策略时,直接跟纳斯达克买数据,那价格...嗯,不提了。
  • 第三方数据商:比如Wind、Bloomberg、Quandl。方便,但要注意数据加工过程中可能引入的偏差。
  • 开源数据:比如Yahoo Finance、Google Finance。免费的东西最贵,你想想看,这些数据经常有延迟、断点、甚至错误。

我个人建议,如果你做的是实盘策略,至少要有两个独立数据源做交叉验证。我在项目中遇到过,同一个股票的同一天收盘价,两个数据源差了0.5%。0.5%看似不多,但做高频策略时,这就是盈亏的分界线。

小技巧: 选数据源时,重点关注三个维度——完整性、及时性、准确性。别只看价格。

4.2 缺失值处理:别让NaN毁了你的模型

缺失值,每个做量化的人都会遇到。股票停牌、数据源断更、节假日...原因太多了。

处理缺失值,我一般分三步走:

  1. 诊断:先搞清楚缺失的模式。是随机缺失?还是系统性缺失?
  2. 评估:缺失比例有多大?超过30%的变量,我通常直接扔掉。
  3. 处理:根据情况选择方法。

常用的处理方法有这些:

方法 适用场景 我的评价
删除法 缺失比例极小(<5%) 简单粗暴,但会损失样本
均值/中位数填充 数据分布较稳定 容易引入偏差,慎用
前向/后向填充 时间序列数据 我最常用的方法,但要注意边界
插值法 数据有趋势性 线性插值简单,但别过度拟合
模型预测 缺失值较多且重要 计算量大,但效果最好

举个例子,处理股票停牌导致的缺失值:

# 前向填充停牌数据
df['close'] = df['close'].fillna(method='ffill')
# 注意:停牌复牌后,要检查价格跳空

警告: 千万别用全局均值填充时间序列数据。我见过有人这么干,结果模型在停牌日附近疯狂报错。为什么?因为破坏了时间序列的自相关性。

4.3 异常值检测:那些离谱的数据点

异常值,说白了就是那些「看着就不对」的数据。比如某股票一天涨了1000%,或者成交量突然变成平时的100倍。这些数据点,要么是数据错误,要么是极端事件。

检测异常值,我常用的方法:

  • 3σ法则:假设数据正态分布,超过均值±3个标准差的就是异常。简单,但金融数据往往不服从正态分布。
  • IQR方法:四分位距法。用Q1-1.5*IQR和Q3+1.5*IQR作为阈值。这个更稳健。
  • MAD方法:绝对中位差。对异常值本身不敏感,适合金融数据。

我曾经在构建A股因子时,发现某个小市值股票的市盈率是-9999。一看就是数据录入错误。如果不处理,这个异常值会严重扭曲因子的分布。

经验之谈: 处理异常值,我建议先「标记」再「处理」。别一上来就删。有时候异常值本身包含重要信息,比如2008年金融危机时的数据。

4.4 幸存者偏差:你看到的都是活下来的

幸存者偏差,这是量化新手最容易踩的坑。什么意思?你回测时用的股票池,是今天还活着的股票。但那些退市、破产的股票呢?它们的数据被自动过滤掉了。

结果就是:你的回测结果看起来很美,但实盘一跑就崩。为什么?因为你只看到了活下来的「幸存者」,忽略了那些「牺牲者」。

我记得有一次帮朋友看一个策略,回测年化收益30%,夏普比率2.5。我一看数据,用的是当前沪深300的成分股。我说:「你把2015年股灾时退市的那些股票加进去试试。」结果一加,年化收益直接掉到8%。

怎么避免?

  • 使用全量历史数据:包括已退市、已停牌的股票。
  • 定期更新股票池:别用静态的股票列表做回测。
  • 做生存分析:看看你的策略在「将死」的股票上表现如何。

切记: 幸存者偏差会让你的回测结果虚高20%-50%。这不是危言耸听,我见过太多人栽在这个坑里。

4.5 前瞻性偏差:别用未来的信息做今天的决策

前瞻性偏差,也叫「未来函数」。说白了,就是你在回测时,不小心用到了当时还不知道的信息。

举个例子:你用今天的财务数据去预测明天的收益,这没问题。但如果你用今天发布的财报数据去预测昨天的收益,这就是前瞻性偏差。

常见的坑:

  • 财务数据发布时间差:财报发布日与实际数据截止日之间有延迟。比如Q3财报在10月底发布,但数据截止日是9月30日。如果你在回测时把Q3数据用在10月之前,那就错了。
  • 指数成分股调整:指数调整成分股是提前公告的,但生效日有延迟。如果你在生效日前就用了新成分股的数据,那也是前瞻性偏差。
  • 数据清洗中的未来信息:比如你用全样本的均值去填充缺失值,这其实引入了未来信息。

我个人的做法是:

  1. 建立数据时间戳:每条数据都标记「可获取时间」和「数据截止时间」。
  2. 滚动窗口处理:所有数据清洗操作,都只用历史窗口内的数据。
  3. 做「事后检验」:回测完成后,随机抽取一些交易记录,手动验证当时是否真的能获取到这些数据。

一句话总结: 回测时,假设你只有当时的信息。别做「事后诸葛亮」。

知识体系总览

下面这张图,是我梳理的数据准备与清洗的核心逻辑。你可以把它当作一个检查清单,每次做数据准备时对照着来。

数据准备与清洗核心流程 数据源选择 缺失值处理 异常值检测 幸存者偏差 前瞻性偏差 交易所/第三方/开源 填充/删除/插值 3σ/IQR/MAD 全量历史/生存分析 时间戳/滚动窗口 数据质量 = 模型上限

这张图把五个核心环节串起来了。从左到右是数据获取和清洗的流程,从上到下是偏差控制。记住,每一步都不能跳过。

最后说一句: 数据准备没有捷径。你花在清洗上的每一分钟,都会在模型表现上得到回报。别偷懒,别侥幸。


公众号:蓝海资料掘金营,微信deep3321