第四章:数据获取与处理——Tick级数据、Level2行情、数据清洗、数据对齐、数据存储方案
做高频做市,说白了就是跟数据谈恋爱。你爱它,它才给你回报。
我见过太多团队,策略逻辑写得天花乱坠,结果一上实盘就崩。为什么?数据源就有问题。Tick级数据、Level2行情,这些东西看着简单,处理起来全是坑。今天我就把这几年的血泪经验掰开了讲。
4.1 Tick级数据:高频交易的“心跳”
先搞清楚一个概念:Tick数据不是K线。K线是人为聚合的,Tick是每一笔成交的原始记录。
举个例子,螺纹钢期货在0.1秒内可能成交了3笔,每笔价格、成交量、买卖方向都不一样。这些原始记录,就是Tick数据。
核心字段:
- 时间戳(精确到毫秒甚至微秒)
- 成交价格
- 成交量
- 成交方向(主动买/主动卖)
- 合约代码
我个人习惯,拿到Tick数据第一件事就是检查时间戳。很多交易所返回的时间戳是服务器时间,跟你的本地时间可能有偏差。我曾经因为这个偏差,导致策略在开盘瞬间频繁报错,后来加了时间同步才解决。
4.2 Level2行情:比Tick更“深”一层
Level2行情,说白了就是能看到“排队的人”。Tick只告诉你成交了,Level2告诉你现在买一、卖一挂了多少钱,挂了多少量,甚至能看到前50档的挂单。
做市策略最依赖的就是这个。你想啊,如果你能看到买一挂了100手,卖一挂了50手,你就能判断短期压力在哪边。
| 数据类型 | 包含信息 | 更新频率 |
|---|---|---|
| Tick数据 | 每笔成交明细 | 每笔成交触发 |
| Level2行情 | 买卖十档/五十档、逐笔委托 | 每500ms或实时 |
小技巧:Level2的“逐笔委托”数据非常宝贵。它能告诉你大单是拆单进来的还是一口气砸进来的。我曾在铁矿石合约上,通过逐笔委托识别出某机构在偷偷吸筹,提前调整了做市报价。
4.3 数据清洗:脏数据是策略的“毒药”
数据源再牛,也免不了有脏数据。我遇到过的情况包括:
- 时间戳乱跳(比如下一秒的时间戳比上一秒还早)
- 价格异常(突然出现一个0或者99999)
- 成交量负数(交易所偶尔抽风)
- 重复数据(同一笔成交推送了两次)
我的清洗流程是这样的:
- 去重:按时间戳+价格+成交量+方向,四字段联合去重
- 过滤异常值:价格超出当日涨跌停板,直接丢弃
- 时间排序:按时间戳升序排列,发现逆序的标记出来人工核查
- 缺失值处理:如果连续缺失超过3秒,我建议直接跳过这段时间,不要插值
警告:千万不要在Tick数据上做线性插值!Tick数据是非均匀时间序列,插值会引入虚假信息。我曾经犯过这个错,回测曲线漂亮得不行,实盘直接亏成狗。
4.4 数据对齐:让不同数据源“说同一种语言”
做高频策略,你往往需要同时使用Tick数据和Level2行情。这两个数据源的时间戳可能不一样——Tick是成交时间,Level2是快照时间。怎么对齐?
我的做法是:
- 以Tick数据的时间戳为基准
- 对于每个Tick,找到它发生前最近的一次Level2快照
- 把那个快照的买卖盘口信息“贴”到这个Tick上
说白了,就是“用过去最近的快照来解释当前的成交”。
# 伪代码示例
def align_tick_with_level2(tick_df, l2_df):
# 对每个tick,找到最近的前一个l2快照
aligned = []
for _, tick in tick_df.iterrows():
t_time = tick['timestamp']
# 找到小于等于t_time的最大l2时间戳
mask = l2_df['timestamp'] <= t_time
if mask.any():
l2_row = l2_df[mask].iloc[-1]
aligned.append({**tick, **l2_row})
return pd.DataFrame(aligned)
注意:如果Tick和Level2来自不同的数据商,时间戳精度可能不同。一个用毫秒,一个用微秒。对齐前先统一精度,否则你会对出一堆空值。
4.5 数据存储方案:别让数据成为瓶颈
高频数据量有多大?我算过,一个活跃的期货合约,一天就能产生几十万条Tick数据。如果做全品种,一年下来几个TB很正常。
存储方案我推荐分层设计:
| 层级 | 存储介质 | 用途 |
|---|---|---|
| 热数据(近7天) | 内存数据库(如Redis) | 策略实时计算 |
| 温数据(近3个月) | SSD + 列式存储(如Parquet) | 回测与调参 |
| 冷数据(历史全量) | HDD + 压缩存储(如Zstd) | 长期归档与复盘 |
我个人习惯用Parquet格式存Tick数据。为什么?因为它压缩率高,而且支持按列读取。回测时我只想读价格和时间两列,Parquet能让我只加载这两列,速度比CSV快几十倍。
避坑指南:我曾经把所有Tick数据存在一个巨大的CSV文件里,结果每次回测光读数据就要半小时。后来改成按天分文件,用Parquet格式,读取时间降到了几秒。嗯,这个坑我替你们踩过了。
4.6 本章知识体系总览
下面这张图,是我自己梳理的数据处理全流程。你照着这个框架搭,基本不会出大问题。
数据获取与处理,是整个高频做市策略的地基。地基不稳,楼盖得再高也得塌。我见过太多人把精力花在策略优化上,却忽略了数据质量。你想想看,如果输入都是错的,输出能对吗?
好了,这一章的内容就到这里。数据这块,多花时间打磨,后面你会感谢自己的。