一、高频交易数据基础

做高频交易这些年,我最大的感触就是:数据是命根子。你策略再牛,模型再花哨,数据不行,一切都是白扯。今天咱们就来聊聊高频交易里最基础、也最容易被忽视的东西——数据本身。

1.1 Tick数据:最原始的脉搏

Tick数据,说白了就是交易所每一笔成交的原始记录。它不像K线那样被加工过,是赤裸裸的真相。

一个标准的Tick数据长什么样?我直接贴个结构出来:

{
  "symbol": "BTC-USDT",      // 交易对
  "timestamp": 1704067200123, // 毫秒级时间戳
  "price": 42850.12,         // 成交价
  "volume": 0.0234,          // 成交量
  "side": "buy",             // 主动成交方向
  "trade_id": "123456789"    // 唯一成交ID
}

嗯,这里要注意一个坑:时间戳。不同交易所给的时间戳精度不一样,有的到毫秒,有的到微秒,甚至纳秒。我早期做回测时,就因为没注意这个精度差异,导致策略信号和实际成交差了十几毫秒——这在高频里可是致命的。

避坑指南:我曾经在对接某二线交易所时,发现它的Tick时间戳居然是秒级的。这意味着同一秒内的所有成交,你根本分不清先后顺序。做高频?别想了,数据精度不够,策略就是瞎蒙。

1.2 Order Book数据:市场的深度与博弈

如果说Tick是成交的结果,那Order Book就是成交前的博弈过程。它告诉你:现在有多少人在买,多少人在卖,价格挂在哪里。

一个典型的Order Book快照结构:

{
  "symbol": "BTC-USDT",
  "timestamp": 1704067200123,
  "bids": [                    // 买单,按价格从高到低
    [42850.00, 1.2345],        // [价格, 数量]
    [42849.50, 5.6789],
    ...
  ],
  "asks": [                    // 卖单,按价格从低到高
    [42851.00, 0.9876],
    [42851.50, 3.4567],
    ...
  ]
}

我个人习惯把Order Book数据分成两类:

  • 快照型:每隔固定时间(比如100ms)拍一张全量快照。优点是完整,缺点是数据量大,而且两次快照之间的变化你完全不知道。
  • 增量型:只记录每次挂单、撤单、成交的变化。优点是数据量小,能还原完整过程,缺点是你得自己维护一个本地的Order Book状态。

你想想看,如果你做的是高频做市策略,增量型数据几乎是必须的。因为你需要知道每一笔挂单的来龙去脉,才能判断市场情绪的变化。

1.3 交易数据:成交的最终记录

交易数据,其实就是你账户里实际发生的成交记录。它和Tick数据很像,但多了一些账户相关的字段:

{
  "account": "sub_account_01",
  "symbol": "BTC-USDT",
  "trade_time": 1704067200123,
  "side": "sell",
  "price": 42850.12,
  "volume": 0.5,
  "fee": 0.0005,           // 手续费
  "fee_asset": "BNB",      // 手续费币种
  "order_id": "ord_98765"  // 关联的订单ID
}

这里有个细节:手续费。别小看这零点几的手续费,高频交易一天几千上万笔,手续费累积起来可能比你的利润还高。我见过不少团队,策略回测时跑得飞起,实盘一跑就亏,查来查去发现是手续费没算对。

1.4 数据频率:Tick级、秒级、分钟级

数据频率的选择,直接决定了你的策略能做什么、不能做什么。我画了一张图,帮你理清思路:

数据频率与策略适用场景 Tick级 毫秒级 适用策略: 高频做市 套利策略 订单簿预测 数据量:极大 存储成本:高 秒级 1秒~60秒 适用策略: 趋势跟踪 均值回归 盘口分析 数据量:中等 存储成本:中 分钟级 1分钟以上 适用策略: CTA策略 组合管理 风险控制 数据量:小 存储成本:低 频率越高 → 策略越短 → 数据量越大 → 存储要求越高

说白了,你选什么频率,取决于你的策略周期。做高频做市的,必须用Tick级数据,毫秒级的延迟都不能忍。做日内趋势的,秒级数据就够用了。做中长线的,分钟级甚至小时级都行。

我的建议:如果你刚开始做量化,别一上来就搞Tick级数据。先拿分钟级数据跑通策略,验证逻辑没问题了,再逐步往高频走。不然数据量太大,存储和计算成本都扛不住。

1.5 数据质量与清洗:被低估的关键

这一节,我想重点聊聊。因为数据质量这个问题,我吃过太多亏了。

你以为交易所给的数据就是干净的?太天真了。我遇到过的情况包括但不限于:

  • 重复数据:同一笔成交被推送了两次
  • 缺失数据:某几秒的数据突然断了
  • 乱序数据:后发生的成交先到了
  • 异常值:价格突然跳到一个离谱的数字
  • 精度问题:小数点后位数不一致

为什么会这样?交易所的架构再牛逼,也架不住网络抖动、系统故障、数据同步延迟。你想想看,如果数据本身就有问题,你的策略回测结果能信吗?

我分享一个我自己的清洗流程:

def clean_tick_data(df):
    # 1. 去重:按trade_id去重
    df = df.drop_duplicates(subset=['trade_id'])
    
    # 2. 排序:按时间戳排序
    df = df.sort_values('timestamp')
    
    # 3. 检查缺失:看时间戳是否连续
    time_gaps = df['timestamp'].diff().dt.total_seconds()
    if (time_gaps > 1).any():
        print(f"发现时间缺口,最大缺口:{time_gaps.max()}秒")
    
    # 4. 异常值过滤:价格超出3个标准差
    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)]
    
    # 5. 精度统一:保留4位小数
    df['price'] = df['price'].round(4)
    df['volume'] = df['volume'].round(4)
    
    return df
核心观点:数据清洗不是可有可无的步骤,而是高频交易系统的基石。我见过太多团队,策略代码写得漂亮,结果数据一塌糊涂,回测曲线漂亮得像假的一样。记住一句话:垃圾进,垃圾出。

1.6 本章小结

这一章我们聊了高频交易数据的几个核心概念:

  • Tick数据:最原始的成交记录,精度要求极高
  • Order Book数据:市场的深度信息,分快照型和增量型
  • 交易数据:账户维度的成交记录,手续费不能忽略
  • 数据频率:Tick级、秒级、分钟级,各有适用场景
  • 数据清洗:去重、排序、异常值处理,一步都不能少

嗯,这些都是最基础的东西。但基础往往是最重要的。就像盖房子,地基没打好,上面盖得再漂亮也没用。下一章,我们会深入聊聊如何高效地存储这些数据——毕竟,数据量大了以后,怎么存、怎么查,都是大问题。


专注资料整理