订单簿数据结构:Level 1/2/3数据、订单簿快照与增量更新、Tick级数据流、数据存储与回放
做量化交易这些年,我越来越觉得——订单簿就是市场的「心跳」。你听懂了它,就能感知到资金流向的脉搏。今天咱们就聊聊订单簿的数据结构,这东西看着基础,但真用起来,坑不少。
Level 1/2/3 数据:你到底需要多深?
交易所给的数据,通常分三个层级。我刚开始做的时候,以为越深越好,结果被数据量淹没了。
| 层级 | 包含内容 | 典型用途 |
|---|---|---|
| Level 1 | 最优买卖价、最新成交价、成交量 | 简单盯盘、散户策略 |
| Level 2 | 前N档买卖盘口(通常5-10档) | 短线交易、盘口分析 |
| Level 3 | 全部挂单、逐笔委托数据 | 高频做市、订单流分析 |
我个人习惯,做日内策略至少用Level 2。Level 3呢?说实话,大部分散户用不上。我曾经在某个项目里接了Level 3数据,结果服务器带宽直接被打满,回放时磁盘IO成了瓶颈。嗯,这里要注意——数据深度和你的硬件能力要匹配。
订单簿快照与增量更新
你想想看,如果每次都要全量拉取订单簿,那网络开销得多大?所以交易所通常提供两种方式:
- 快照(Snapshot):某一时刻的完整订单簿状态。一般每隔几秒或几十毫秒推送一次。
- 增量更新(Incremental Update):只推送变化的部分,比如「价格100.5元,买一数量增加200手」。
实际应用中,我们通常这样配合:
# 伪代码示例:维护本地订单簿
class OrderBook:
def __init__(self):
self.bids = {} # 买盘,价格->数量
self.asks = {} # 卖盘,价格->数量
def apply_snapshot(self, snapshot):
self.bids = snapshot['bids']
self.asks = snapshot['asks']
def apply_update(self, update):
# 增量更新:价格、方向、数量
price = update['price']
side = update['side'] # 'bid' or 'ask'
size = update['size']
if side == 'bid':
if size == 0:
self.bids.pop(price, None) # 删除该价位
else:
self.bids[price] = size
else:
if size == 0:
self.asks.pop(price, None)
else:
self.asks[price] = size
避坑指南:我曾经遇到过增量更新丢失的情况,导致本地订单簿和交易所不一致。后来我加了个定时校验机制——每30秒拉一次快照做全量同步。记住,增量更新再快,也要有快照兜底。
Tick级数据流:毫秒间的博弈
Tick级数据,说白了就是每一笔成交或每一次订单簿变化。它的特点是:
- 高频:A股大概每秒几十到几百笔,期货能到上千笔,加密货币更是夸张
- 带时间戳:精确到毫秒甚至微秒
- 包含细节:成交价、成交量、买卖方向、订单编号等
我建议你关注几个关键字段:
{
"timestamp": 1699000000123, // 毫秒时间戳
"price": 100.50, // 成交价
"size": 200, // 成交量
"side": "buy", // 主动买还是主动卖
"trade_id": "abc123" // 成交编号
}
为什么会关注买卖方向?因为主动买代表买方更急切,主动卖代表卖方更急切。这是判断资金流向的核心。
数据存储与回放:让历史告诉你答案
做策略回测,数据存储是基本功。我见过有人把Tick数据存成CSV,结果一个月的文件就几十GB,查询慢得要命。这里分享我的经验:
- 列式存储:比如Parquet格式,压缩率高,查询快
- 按时间分区:每天一个文件或表,方便增量读取
- 索引优化:对时间戳、价格字段建索引
回放时,核心逻辑是模拟时间流逝:
# 回放引擎伪代码
def replay(data_stream, start_time, end_time):
for tick in data_stream:
if tick.timestamp < start_time:
continue
if tick.timestamp > end_time:
break
# 更新订单簿
order_book.apply_update(tick)
# 触发策略逻辑
strategy.on_tick(tick)
小技巧:回放时我习惯加个「加速因子」,比如10倍速回放。这样既能快速验证策略,又能发现数据中的异常点。有一次我回放时发现某个时间段的成交量突然归零,后来排查发现是交易所数据源出了问题。
知识体系总览
下面这张图,是我自己梳理的订单簿数据结构核心逻辑。你看一眼,基本就明白各模块怎么配合了。
核心要点:
- Level 1 看趋势,Level 2 看博弈,Level 3 看细节
- 快照保证一致性,增量保证实时性,两者缺一不可
- Tick数据是原始素材,存储和回放是加工工具
说实话,订单簿数据结构这块,没有太多花哨的东西。但就是这些基础,决定了你策略的上限。我见过太多人一上来就搞复杂模型,结果连数据都处理不对。嗯,先把地基打牢,后面的楼才能盖得高。