订单簿重建:数据结构、增量更新与快照重建
做市商的核心工作,说白了就是跟订单簿打交道。你想想看,我们每天盯着盘口,看到的那些买一卖一、深度数据,背后都是订单簿在支撑。今天我就带你把这个底层逻辑彻底搞明白。
订单簿的数据结构设计
我个人习惯用字典来存储订单簿。为什么?因为订单簿本质上就是个价格到数量的映射。买盘和卖盘分开存,结构清晰,查询也快。
class OrderBook:
def __init__(self):
self.bids = {} # 买盘: {price: volume}
self.asks = {} # 卖盘: {price: volume}
self.timestamp = None
self.last_update_id = None
这里有个细节要注意:价格用浮点数做key?千万别。我在项目中遇到过浮点数精度问题,两个看起来一样的价格,字典里却当成两个不同的key。我建议用整数,比如把价格乘以10000再存。
增量更新 vs 快照重建
交易所推送数据有两种方式:快照和增量。快照就是给你当前订单簿的全量数据,增量就是告诉你"刚才发生了什么变化"。
增量更新的逻辑其实很简单:
def apply_update(self, update):
side = update['side'] # 'bid' or 'ask'
price = update['price']
volume = update['volume']
if side == 'bid':
if volume == 0:
# 删除这个价格档位
self.bids.pop(price, None)
else:
self.bids[price] = volume
else:
if volume == 0:
self.asks.pop(price, None)
else:
self.asks[price] = volume
嗯,这里要注意:volume为0表示删除这个档位。这是交易所的通用约定,别搞反了。
快照重建的时机
为什么需要快照重建?因为增量更新可能会丢数据。网络抖动、程序重启、或者增量序列号对不上,都会导致订单簿状态不一致。
我一般这样设计重建策略:
- 每5分钟强制拉一次快照
- 检测到增量序列号跳跃时立即重建
- 程序启动时先拉快照再订阅增量
订单簿深度计算
深度计算,说白了就是算"在某个价格区间内,有多少买单和卖单"。
def calculate_depth(self, levels=10):
bid_prices = sorted(self.bids.keys(), reverse=True)[:levels]
ask_prices = sorted(self.asks.keys())[:levels]
bid_depth = sum(self.bids[p] for p in bid_prices)
ask_depth = sum(self.asks[p] for p in ask_prices)
return {
'bid_depth': bid_depth,
'ask_depth': ask_depth,
'bid_prices': bid_prices,
'ask_prices': ask_prices
}
这里有个小技巧:买盘按价格降序排列,卖盘按价格升序排列。这样取前N个就是离当前价格最近的档位。
买卖盘口分析
盘口分析不只是看买一卖一的价格差。我通常会关注这几个指标:
| 指标 | 计算方式 | 含义 |
|---|---|---|
| 买卖价差 | ask_price_1 - bid_price_1 | 市场流动性最直接的体现 |
| 深度不平衡 | (bid_depth - ask_depth) / (bid_depth + ask_depth) | 正数表示买方力量强,负数反之 |
| 加权平均价格 | Σ(price * volume) / Σvolume | 大单成交的参考价格 |
举个例子,如果深度不平衡突然从0.2变成-0.3,说明卖压突然增大。这时候我可能会调整做市策略,减少买单挂单量。
订单簿的完整生命周期
让我用一张图来展示订单簿从初始化到持续更新的完整流程:
这张图把整个流程串起来了。你想想看,从初始化到持续运行,核心就是快照和增量的配合。一旦发现异常,马上回到快照那一步重新来。
性能优化建议
订单簿操作频率很高,性能优化很重要。我分享几个经验:
- 用OrderedDict:Python 3.7+的字典已经有序,但OrderedDict在频繁增删时性能更好
- 预分配内存:如果知道最大档位数,提前分配好内存空间
- 批量处理:增量更新可以攒一批再处理,减少锁竞争
嗯,订单簿重建这块内容就这些。核心就是数据结构要选对,增量更新和快照重建要配合好,深度计算和盘口分析要能落地到策略里。你把这些搞明白了,做市策略的基础就扎实了。
公众号:蓝海资料掘金营,微信deep3321