数据清洗基础:重复数据去重、异常价格过滤、零值与负值处理、时间序列对齐
做量化交易这几年,我越来越觉得数据清洗是门手艺活。很多人一上来就搞特征工程、搭模型,结果跑出来的策略回测曲线漂亮得不行,一上实盘就崩。为什么?说白了,数据里藏着脏东西。
订单簿数据尤其如此。高频数据里,重复记录、异常价格、零值负值、时间戳错位,这些坑我几乎都踩过。今天咱们就把这四块硬骨头啃下来。
重复数据去重:别让同一笔订单算两次
先说说重复数据。交易所的数据推送偶尔会抽风,同一笔订单发两次。你想想看,如果不去重,你的订单簿深度统计就全歪了。
我个人习惯的做法是:先按时间戳和订单ID联合去重。为什么?因为单纯按时间戳去重可能会误删真正的连续报价。
核心思路:用 (timestamp, order_id) 作为唯一键,保留第一条记录。
# 伪代码示例
df = df.drop_duplicates(subset=['timestamp', 'order_id'], keep='first')
我在项目中遇到过一种特殊情况:某些小交易所的订单ID会重置。这时候就得加上交易对字段一起判断。嗯,这里要注意,去重前最好先排序,确保保留的是最早到达的那条数据。
小技巧:去重后检查一下数据量,如果减少超过1%,大概率是数据源有问题,建议排查一下推送逻辑。
异常价格过滤:把离谱的报价扔出去
异常价格是订单簿数据里最头疼的问题之一。我记得有一次,某个山寨币的卖一价突然飙到100万美金,明显是机器人报错了。如果不处理,你的流动性指标直接爆炸。
怎么过滤?我一般用两种方法:
- 基于统计的过滤:用中位数绝对偏差(MAD)或者Z-score。我个人偏好MAD,因为它对极端值更鲁棒。
- 基于业务逻辑的过滤:比如价格不能超过最近N笔成交均价的X倍,或者不能低于某个合理阈值。
# 基于MAD的异常价格过滤
median_price = df['price'].median()
mad = np.median(np.abs(df['price'] - median_price))
threshold = 3 * mad # 3倍MAD作为阈值
df = df[np.abs(df['price'] - median_price) < threshold]
你可能会问:阈值设多少合适?这得看品种。比特币波动小,3倍MAD够用;一些山寨币波动大,我有时会放宽到5倍。说白了,没有万能参数,得根据历史数据调。
避坑指南:我曾经直接用Z-score过滤,结果遇到极端行情时把正常数据也误杀了。后来改用MAD,情况好很多。另外,过滤前最好先分组,按交易对和时间窗口分别处理。
零值与负值处理:这些数据不能留
零值和负值在订单簿里基本是垃圾数据。为什么?价格为零意味着免费送,负价格意味着倒贴钱,这在正常市场里不可能出现。
我的处理原则很简单:
- 价格字段:零值和负值直接删除,或者替换为NaN然后填充。
- 数量字段:零值可以保留(表示该价位没有挂单),负值必须删除。
# 零值和负值处理
df = df[(df['price'] > 0) & (df['volume'] >= 0)]
这里有个细节:有些数据源会用-1表示无效数据。我建议统一转成NaN,方便后续处理。嗯,别问我怎么知道的,都是泪。
经验之谈:处理完零值和负值后,最好做个统计报告,看看每种异常占比多少。如果某个交易对的异常比例超过5%,建议直接弃用该数据源。
时间序列对齐:让不同数据源步调一致
最后说说时间序列对齐。做量化交易,你经常需要合并多个数据源的数据。比如订单簿数据来自交易所A,成交数据来自交易所B。如果时间戳不对齐,特征计算就全乱了。
我常用的对齐方法有两种:
| 方法 | 适用场景 | 优缺点 |
|---|---|---|
| 向前填充(ffill) | 低频数据对齐到高频数据 | 简单,但会引入未来信息 |
| 向后填充(bfill) | 高频数据对齐到低频数据 | 避免未来信息,但可能有延迟 |
| 线性插值 | 缺失值较少的情况 | 平滑,但可能失真 |
我个人习惯用向前填充,然后做一次时间戳对齐检查。具体做法是:
# 时间序列对齐示例
# 假设df1是订单簿数据,df2是成交数据
df1.set_index('timestamp', inplace=True)
df2.set_index('timestamp', inplace=True)
aligned_df = df1.reindex(df2.index, method='ffill')
你想想看,如果两个数据源的时间戳精度不一样(一个到毫秒,一个到微秒),直接合并会出大问题。我建议先统一时间戳精度,比如都截断到毫秒级。
避坑指南:我曾经因为时间戳没对齐,导致回测时策略信号和实际成交差了整整一秒。后来我加了一步:对齐后检查时间差的最大值和最小值,确保在合理范围内。
知识体系总览
下面这张图把数据清洗的四个核心步骤串起来了。你可以把它当作操作手册,每次处理数据前过一遍。
这四个步骤做完,你的订单簿数据基本就干净了。但记住,数据清洗不是一劳永逸的事。市场在变,数据源在变,你的清洗规则也得跟着调整。我每个月都会复盘一次清洗效果,看看有没有漏网之鱼。
最后说一句:数据清洗花的时间,往往比建模还多。但这是值得的。干净的数据,是量化交易的基石。
公众号:蓝海资料掘金营,微信deep3321