1. 行情数据基础:高频行情数据定义、Tick与Snapshot数据模型、Level2行情协议解析

1.1 高频行情数据到底是什么?

做量化交易这些年,我见过不少新手一上来就盯着K线图猛看。说实话,K线只是二手数据,真正的源头是高频行情。高频行情,说白了就是交易所实时推送的每一笔交易细节。

我个人习惯把行情数据分成两类:

  • Tick数据:每一笔成交的完整记录。谁在什么时间、什么价格、买了多少股。
  • Snapshot数据:某个时间点的快照。比如每3秒拍一张照片,记录当前买卖盘口的情况。

你想想看,如果你只看到K线,你根本不知道中间发生了什么。但有了Tick数据,你能看到每一笔大单是怎么吃掉的,能感受到市场的呼吸节奏。

核心要点:高频行情是量化交易的「原材料」。没有它,你的策略就是空中楼阁。

1.2 Tick数据模型:每一笔成交都值得记录

我在项目中遇到过最头疼的事,就是Tick数据量太大,存储和传输都成了瓶颈。所以,设计Tick数据模型时,一定要精打细算。

一个标准的Tick记录,通常包含这些字段:

字段名 类型 说明
symbol string 股票代码,比如"000001.SZ"
timestamp int64 精确到微秒的时间戳
price float64 成交价格
volume int64 成交量(股数)
turnover float64 成交金额
buy_sell_flag int8 买卖方向:1买、-1卖、0未知

嗯,这里要注意。时间戳一定要用微秒级。我见过有人用毫秒,结果回测时发现很多订单时间重叠,根本分不清先后顺序。那回测结果就完全失真了。

避坑指南:我曾经因为时间戳精度不够,导致回测时订单成交顺序错乱,白白浪费了两周时间。后来统一改用微秒级时间戳,问题才解决。

1.3 Snapshot数据模型:快照里藏着什么?

Snapshot,也叫快照数据。它不像Tick那样记录每一笔,而是每隔固定时间(比如3秒)拍一张「市场全景图」。

一个典型的Snapshot包含:

  • 当前最新成交价、成交量
  • 买一到买五(或买十)的挂单价格和数量
  • 卖一到卖五(或卖十)的挂单价格和数量
  • 当日开盘价、最高价、最低价、收盘价
  • 总成交量、总成交额

为什么需要Snapshot?因为Tick数据太密了,存储成本高。而Snapshot可以帮你快速重建市场状态。我个人的做法是:Tick数据保留7天,Snapshot数据保留3个月。这样既保证了近期分析的精度,又控制了存储成本。

经验之谈:做回测时,先用Snapshot重建市场状态,再用Tick数据做精细模拟。两者结合,效果最好。

1.4 Level2行情协议解析:别被协议吓到

Level2行情,说白了就是比普通行情多了一层细节。普通行情只能看到买卖五档,Level2能看到买卖十档,还能看到逐笔成交和委托队列。

国内常见的Level2协议有两种:

  • 深交所协议:基于STEP协议,消息体是二进制格式
  • 上交所协议:基于FAST协议,压缩率更高

我第一次解析深交所的Level2协议时,看着那一堆二进制字节,头都大了。后来发现,其实核心就是三步:

  1. 读取消息头,判断消息类型
  2. 根据消息类型,解析对应的消息体
  3. 把解析结果转换成统一的数据结构

下面是我写的一个简化版解析器,帮你理解核心逻辑:

class Level2Parser:
    def __init__(self):
        self.msg_handlers = {
            0x01: self._parse_tick,
            0x02: self._parse_snapshot,
            0x03: self._parse_order_book
        }
    
    def parse(self, raw_bytes):
        msg_type = raw_bytes[0]  # 第一个字节是消息类型
        handler = self.msg_handlers.get(msg_type)
        if handler:
            return handler(raw_bytes[1:])
        else:
            raise ValueError(f"未知消息类型: {msg_type}")
    
    def _parse_tick(self, data):
        # 解析Tick数据
        return {
            'price': struct.unpack('>d', data[0:8])[0],
            'volume': struct.unpack('>I', data[8:12])[0],
            'timestamp': struct.unpack('>Q', data[12:20])[0]
        }

注意:不同交易所的协议细节差异很大。千万不要以为解析了深交所的协议,就能直接套用到上交所。我当年就吃过这个亏,上线后才发现数据全是乱的。

1.5 知识体系总览

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

高频行情数据知识体系 Tick数据 每笔成交记录 Snapshot数据 定时快照 Level2协议 数据解析规则 行情数据流处理引擎 三者关系 Tick数据是「点」,Snapshot是「面」,Level2协议是「桥」 三者结合,才能构建完整的高频行情处理能力

从这张图你能看到,Tick和Snapshot是数据本身,Level2协议是获取这些数据的规则。三者缺一不可。

1.6 实战中的坑与经验

最后,分享几个我踩过的坑:

  • 数据对齐问题:Tick和Snapshot的时间戳可能不同步。我建议以Tick的时间戳为准,把Snapshot对齐到最近的Tick时间。
  • 数据缺失处理:网络波动可能导致数据丢包。我的做法是:如果连续3个Snapshot缺失,就标记该时间段为「不可用」。
  • 协议版本兼容:交易所会更新协议版本。记得在解析器里加版本号判断,避免上线后出问题。

小技巧:解析Level2协议时,先用一小段真实数据做单元测试。我每次对接新交易所,都会先跑一遍测试数据,确保解析结果和交易所官方工具一致。

好了,这一章的内容就到这里。记住,高频行情数据是量化交易的基石。把Tick、Snapshot和Level2协议搞明白,后面的路就好走了。


专注资料整理