合成订单簿通常涉及两种核心逻辑:“撮合法”和“成交消减法”。
合成订单簿主要有两大应用场景:一是基于实盘实时逐笔行情动态合成订单簿;二是基于历史逐笔行情静态数据重建历史订单簿(注:若能将实时合成的订单簿归档存储,则通常无需进行历史重建)。针对不同场景,可选择不同的合成逻辑,也可混合使用以进行交叉验证。
订单簿的用途广泛,目前主流应用包括做市策略、高频日内策略以及基于订单簿的高精度策略回测。
1. 撮合法 (Matching Method)
撮合法是一种主动式的订单处理机制。其核心特点是,在收到新订单后,立即模拟交易所“价格优先、时间优先”的撮合规则进行处理,无需等待后续成交信息。
该方法的逻辑在于主动判断对手盘口是否存在价格交叉(即最高买价 ≥ 最低卖价),并按照价格、时间优先的原则消除交叉盘口。由于能精确复刻交易所的撮合逻辑,撮合法广泛应用于高频交易策略回测、日内T0策略的模拟交易等场景,能有效保障回测结果的真实性与参考价值。
2. 成交消减法 (Trade Reduction Method)
成交消减法是一种相对被动的订单处理机制。在收到新增订单后,它不进行主动撮合,而是等待接收交易所后续推送的撤单、成交等消息,并严格按照消息顺序对订单簿中对应订单的数量进行扣减更新。
3. 二者核心区别
从实际应用角度看,两种方法并无优劣之分,关键在于根据需求选择。
从原理上分析,主要区别在于:
- 主动性:撮合法是主动的,收到订单立即检查并撮合,然后更新订单簿;成交消减法是被动的,依赖成交消息驱动更新。
- 订单簿状态:成交消减法可能导致订单簿出现短暂的非法状态(如交叉盘口),直至成交消息到来才消除;撮合法则通过主动撮合,始终维持订单簿的合法与可预测状态。
- 复杂度与适用性:撮合法需要完整实现交易所撮合规则,复杂度高,但结果精准,尤其适合回测场景;成交消减法则实现相对简单可靠,更适用于基于历史行情重建静态订单簿数据。
4. 结合交易所撮合机制的理解
在实盘交易中,订单发送至交易所,由交易所进行实时撮合,并随后向市场参与者发送逐笔委托和逐笔成交信息。对接收方而言,委托和成交消息是异步到达的,虽然交易所会保证基本的顺序(先委托,后成交),但行情源头或传输链路异常可能导致乱序,这是在系统设计中必须考虑的现实情况。
5. 撮合法实现思路
1) 核心逻辑
收到新订单时,立即检查是否与对手方盘口存在交叉,若存在则进行撮合成交,确保订单簿始终处于合法状态。
2) 处理流程
- 接收新订单。
- 检查交叉:买单检查是否价格≥卖一价;卖单检查是否价格≤买一价。
- 若存在交叉,则与对手方订单按价格优先、时间优先的原则进行撮合,直至新订单完全成交或交叉消失。
- 若新订单仍有剩余,则将其插入订单簿。
3) 伪代码示例
def process_order_with_matching(self, order: Order):
"""撮合法处理订单"""
# 1. 先与对手方撮合
if order.side == "BUY":
# 买单:价格 >= 卖一价时撮合
while self.asks and order.price >= self.asks[0].price and order.leaves_qty > 0:
self._match_with_asks(order)
else:
# 卖单:价格 <= 买一价时撮合
while self.bids and order.price <= self.bids[0].price and order.leaves_qty > 0:
self._match_with_bids(order)
# 2. 剩余部分插入订单簿
if order.leaves_qty > 0:
self._insert_to_orderbook(order)
# 3. 清理空档位
self._clean_empty_levels()
6. 成交消减法实现思路
1) 核心逻辑
严格遵循交易所消息推送顺序处理,不主动撮合,交叉盘口由后续到达的成交消息自然消除。
2) 处理流程
- 接收新订单,直接插入订单簿(即使与对手盘产生交叉)。
- 等待接收成交(Trade)消息。
- 根据成交消息更新订单簿中对应订单的剩余数量。若数量归零,则删除该订单。
3) 伪代码示例
def process_order_with_reduction(self, order: Order):
"""成交消减法处理订单:直接插入"""
# 直接插入订单簿,即使产生交叉(订单簿可能暂时非法)
self._insert_to_orderbook(order)
def process_trade_for_reduction(self, trade: Trade):
"""通过成交消息消减订单"""
# 1. 找到对应订单
order = self.all_orders.get(trade.order_id)
if not order:
return
# 2. 更新订单状态
order.leaves_qty -= trade.qty
# 3. 如果订单完成,移除
if order.leaves_qty <= 0:
self._remove_order(order)
# 4. 成交可能消除了交叉盘口
self._clean_empty_levels()
7. 示例演示
假设当前订单簿状态:
- 买一:10.5元 × 100股
- 卖一:10.3元 × 80股
此时收到新卖单:10.2元 × 150股(价格低于买一价,存在交叉)。
撮合法的处理过程:
# 1. 立即发现交叉:卖单价格10.2 < 买一价10.5
# 2. 主动撮合:
# - 以10.5元成交80股(与买一)
# - 新卖单剩余70股
# 3. 更新订单簿:
# - 买一减少80股,剩余20股
# - 插入新卖单剩余70股,价格10.2元
# 4. 最终状态:
# - 买一:10.5元 × 20股
# - 卖一:10.2元 × 70股
成交消减法的处理过程:
# 1. 直接插入订单簿:
# - 插入卖单:10.2元 × 150股
# - 此时订单簿状态(暂时非法,买价>卖价):
# 买一:10.5元 × 100股
# 卖一:10.2元 × 150股
# 2. 等待交易所成交消息:
# - 收到成交:买一订单成交80股
# - 更新:买一剩余20股
# 3. 交叉盘口被此成交消息自然消解。
对于订单簿状态管理与高频数据处理,选择适合的合成方法是构建稳定系统的基础。