22、做市商数据基础设施:实时数据流、历史数据库、数据清洗与存储。

做市商这行,说白了就是跟数据打交道。你策略再牛,模型再漂亮,底层数据一塌糊涂,那全是白搭。我见过太多团队,策略回测曲线漂亮得像艺术品,一上实盘就崩,十有八九是数据基础设施没搭好。

今天我们就来拆解一下,做市商的数据基础设施到底该怎么搭。核心就三块:实时数据流、历史数据库、数据清洗与存储。这三者缺一不可,而且顺序不能乱。

实时数据流:做市商的“神经末梢”

实时数据流,就是你的行情源。做市商对行情的要求,跟普通交易者完全不是一个量级。普通交易者看个1秒快照可能就够了,但做市商需要的是逐笔成交、逐笔挂单的深度数据。

我个人习惯,至少接三路独立的行情源。为什么?因为单点故障太可怕了。我曾经遇到过一次,交易所的行情网关挂了,整整5分钟没推送数据。如果你只接了一路,那5分钟你的报价就是瞎报,风险敞口无限大。

实时数据流的核心指标,我列个表给你看:

指标 普通交易者 做市商要求
数据频率 1秒快照 逐笔(Tick级)
延迟要求 100ms以内 1ms以内
冗余备份 单路 至少3路独立源
数据完整性 允许丢包 零容忍,需校验

嗯,这里要注意。实时数据流不仅仅是接收,还要做“对齐”。不同行情源的时间戳可能不同,甚至同一个交易所的不同产品,时间基准都可能不一致。我建议在数据入口处就做一次统一的时间戳校准,用NTP服务器同步,精度至少到微秒级。

核心原则:实时数据流是“活水”,必须保证它的纯净度和流速。任何一点污染或延迟,都会直接传导到你的报价模型里。

历史数据库:回测的“照妖镜”

历史数据库,说白了就是你的“记忆”。做市商策略的回测,对历史数据的要求极其苛刻。你不能拿日线数据去回测一个高频做市策略,那等于拿望远镜看蚂蚁打架。

我建议历史数据库至少存储以下三个层级的数据:

  • 原始Tick数据:每一笔成交、每一次挂单变动,原封不动地存下来。这是最宝贵的资产。
  • 切片数据:按固定时间间隔(比如100ms)对订单簿进行快照。方便快速回测,不用每次都从头扫描Tick数据。
  • 衍生数据:比如计算好的买卖价差、订单簿不平衡度、成交量加权价格等。这些是特征工程的结果,存下来可以加速后续分析。

存储历史数据,我踩过一个坑。当时用MySQL存Tick数据,结果一张表几个月就几十亿条记录,查询慢得像蜗牛。后来我换成了时序数据库,比如InfluxDB或ClickHouse,专门为这种时间序列数据优化的,查询速度快了几个数量级。

避坑指南:我曾经以为历史数据存得越多越好,结果发现数据量太大,回测一次要跑好几天。后来我学会了“分层存储”——热数据用SSD,冷数据用HDD,归档数据用对象存储。这样既保证了速度,又控制了成本。

数据清洗与存储:脏活累活,但必须干

数据清洗,是数据基础设施里最不起眼、但最重要的一环。你想想看,交易所的数据也不是完美的。偶尔会有错误订单、异常价格、数据缺失、重复推送。如果你不把这些“脏数据”洗掉,你的模型就会被它们带偏。

我总结了一套数据清洗的流程,你可以参考:

  1. 去重:同一个事件被推送了两次,只保留第一条。
  2. 异常值过滤:价格超过3个标准差,或者买卖价差为负数,直接丢弃。
  3. 时间戳校验:检查时间戳是否单调递增,如果出现倒挂,说明数据有问题。
  4. 缺失值填充:如果某一段数据缺失,用前一个有效值填充,或者标记为“无效”。
  5. 数据对齐:不同数据源的时间戳统一到同一个基准上。

下面是一个简单的数据清洗代码示例,用Python写的,你可以看看:

import pandas as pd
import numpy as np

def clean_tick_data(df):
    # 1. 去重
    df = df.drop_duplicates(subset=['timestamp', 'price', 'volume'])
    
    # 2. 异常值过滤
    mean_price = df['price'].mean()
    std_price = df['price'].std()
    df = df[(df['price'] > mean_price - 3*std_price) & 
            (df['price'] < mean_price + 3*std_price)]
    
    # 3. 时间戳校验
    df = df.sort_values('timestamp')
    df = df[df['timestamp'].diff() >= 0]
    
    # 4. 缺失值填充(用前向填充)
    df = df.fillna(method='ffill')
    
    return df

存储方面,我建议采用“冷热分离”的策略。最近7天的数据放在高性能的SSD上,7天到3个月的数据放在普通HDD上,3个月以上的数据压缩后存到对象存储(比如S3)里。这样既能保证实时查询的速度,又能控制存储成本。

警告:千万不要把原始数据和清洗后的数据混在一起存。我见过有人图省事,直接在原表上做修改,结果回测时发现数据对不上,查了三天才发现是清洗逻辑变了,但历史数据已经被污染了。正确的做法是:原始数据只读不写,清洗后的数据另存一份,并记录清洗的版本号。

知识体系框架

为了让你更直观地理解这三者的关系,我画了一张图:

做市商数据基础设施架构 实时数据流 行情源接入 时间戳校准 延迟监控 数据清洗 去重/异常过滤 缺失值填充 数据对齐 历史数据库 Tick数据存储 切片数据 衍生数据 存储层(冷热分离) 热数据(SSD,7天) 温数据(HDD,3个月) 冷数据(对象存储)

这张图清晰地展示了数据从源头到存储的完整链路。实时数据流进来后,先经过清洗,再分流到历史数据库和存储层。注意,清洗这一步不能省,它是整个数据基础设施的“守门员”。

最后说一句,数据基础设施的建设,没有一劳永逸的方案。随着你的交易品种增加、交易量上升,这套架构需要不断迭代。我每年都会做一次数据基础设施的复盘,看看哪些地方可以优化。毕竟,做市商拼到最后,拼的就是数据处理的效率。

交易系统化学习资料 微信Strategy888888