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协议时,看着那一堆二进制字节,头都大了。后来发现,其实核心就是三步:
- 读取消息头,判断消息类型
- 根据消息类型,解析对应的消息体
- 把解析结果转换成统一的数据结构
下面是我写的一个简化版解析器,帮你理解核心逻辑:
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协议是获取这些数据的规则。三者缺一不可。
1.6 实战中的坑与经验
最后,分享几个我踩过的坑:
- 数据对齐问题:Tick和Snapshot的时间戳可能不同步。我建议以Tick的时间戳为准,把Snapshot对齐到最近的Tick时间。
- 数据缺失处理:网络波动可能导致数据丢包。我的做法是:如果连续3个Snapshot缺失,就标记该时间段为「不可用」。
- 协议版本兼容:交易所会更新协议版本。记得在解析器里加版本号判断,避免上线后出问题。
小技巧:解析Level2协议时,先用一小段真实数据做单元测试。我每次对接新交易所,都会先跑一遍测试数据,确保解析结果和交易所官方工具一致。
好了,这一章的内容就到这里。记住,高频行情数据是量化交易的基石。把Tick、Snapshot和Level2协议搞明白,后面的路就好走了。