3. 撮合引擎核心原理
撮合引擎是交易系统的“心脏”,它把买卖双方提交的订单按一套确定、可复现的规则配对成交。理解这套规则,才能理解为什么同样的委托在不同时刻、不同价格上会得到完全不同的成交结果。本节围绕两条优先级原则、两种竞价模式,以及限价单与市价单在订单簿中的实际处理流程展开。
一、订单簿:撮合引擎的工作台
订单簿(Order Book)是撮合引擎维护的核心数据结构,分为买盘(Bid)与卖盘(Ask)两侧。买盘按价格从高到低排列,卖盘按价格从低到高排列,同一价格档位内再按订单到达时间先后排队。订单簿的“最优买价”记作 Bid1,“最优卖价”记作 Ask1,两者之差即买卖价差(Spread)。当 Bid1 ≥ Ask1 时,市场具备成交条件,撮合立即发生;否则订单进入挂单队列等待。
需要特别说明参照约定:本文所有“价格高低”均指委托价格本身,买盘价格越高越优先,卖盘价格越低越优先,这一约定在全文与图示中保持一致。
二、价格优先与时间优先
价格优先指:对买单而言,出价更高的订单优先成交;对卖单而言,要价更低的订单优先成交。它保证市场以对买方最有利的卖价、对卖方最有利的买价成交,是价格发现的基础。
时间优先指:当价格相同时,先到达撮合引擎的订单先成交。它保证同一价格档位内的排队公平性,先挂单者获得优先权。两条原则合起来构成一个全序:先比价格,价格相同再比时间,任何时刻订单簿中任意两笔同方向订单的优先级都是唯一确定的。
举个教学示例(示例参数,非实测):卖盘 Ask1 挂有 100 手 @10.00(订单 A,09:30:01 到达),随后订单 B 以 10.00 挂 200 手(09:30:05 到达)。此时新来一笔市价买单 150 手,先与 A 成交 100 手,再与 B 成交 50 手,B 剩余 150 手继续排队。若新来的是限价买单 @10.00 共 250 手,则同样先吃 A 的 100 手、再吃 B 的 150 手,剩余 0 手,全部成交。可见价格相同的情况下,时间先后直接决定谁先被“吃掉”。
三、连续竞价与集合竞价
连续竞价在交易时段内逐笔处理订单:每来一笔新订单,立即与订单簿对手方按价格优先、时间优先逐档撮合,未成交部分挂入订单簿。它的特点是成交连续、价格随每笔委托实时变动,适合流动性充足的连续交易时段。
集合竞价则在一个时间窗口内只接收订单、不立即成交,窗口结束时把所有订单集中起来,按“最大成交量原则”计算出一个统一成交价:在该价格上,能够撮合的买方总量与卖方总量最大;若存在多个价格满足最大成交量,则取使未成交量最小、或最接近参考价的价格(不同市场细则略有差异)。所有可成交订单统一以该价格成交,未成交部分转入连续竞价或作废。集合竞价常用于开盘、收盘等需要集中形成公允价格的时点。
两种模式的关键差异在于“成交时点”与“成交价格”:连续竞价是逐笔、多价成交;集合竞价是集中、单一价格成交。下图以订单簿视角展示限价单与市价单在连续竞价中的处理路径,以及集合竞价的集中撮合位置。
四、限价单与市价单在订单簿中的处理流程
限价单的处理分两步。第一步是“能否立即成交”:引擎拿限价单与对手方最优价比较,若买单限价 ≥ Ask1(或卖单限价 ≤ Bid1),则按价格优先、时间优先逐档撮合,成交价取对手方挂单价(即“被动方价格优先”),直到限价不再满足或对手盘耗尽。第二步是“剩余挂单”:未成交部分以原限价进入本方队列,按价格优先插入对应档位,同价则排在队尾。限价单因此同时具备“成交”与“提供流动性”两种角色。
市价单只表达“立即成交”的意愿,不指定价格。引擎从对手方最优价开始逐档吃单,直到委托数量全部成交或对手盘耗尽。若对手盘深度不足,剩余部分通常按交易所规则撤销(IOC 语义)或转为限价单,具体取决于订单的时效指令(如 IOC、FOK)。市价单成交价可能跨越多个档位,产生“滑点”,这是它与限价单最本质的差异:限价单锁定价格上限/下限,市价单锁定成交速度但放弃价格控制。
下面用一组教学示例参数(示例数据,非实测)演示逐档撮合的计算过程。假设卖盘为:Ask1 10.02×300、Ask2 10.05×500、Ask3 10.08×200。一笔市价买单 900 手到达:先吃 Ask1 的 300 手,再吃 Ask2 的 500 手,此时已成交 800 手,剩余 100 手继续吃 Ask3,成交 100 手后全部完成。成交明细为 300@10.02、500@10.05、100@10.08,加权均价约 10.0433。若换成限价买单 @10.05 共 900 手,则只能吃到 Ask1 与 Ask2 共 800 手,剩余 100 手以 10.05 挂入买盘,成为新的 Bid1(若原 Bid1 低于 10.05)。
五、规则落地时的关键细节
实际工程中还有几处容易出错的地方。其一,同价排队顺序必须严格按到达时间维护,任何重排都会破坏时间优先的公平性,通常用有序链表或带序号的优先队列实现。其二,集合竞价的成交价计算需要遍历候选价格并累计买卖双方可成交量,取最大成交量对应的价格;若并列,再按未成交量最小、最接近参考价等次级规则裁决,不同市场细则不同,实现前必须核对交易所规则。其三,自成交防范:同一账户的买卖单若在撮合中相遇,部分市场要求撤单或改价,引擎需在撮合前做账户校验。其四,价格笼子与涨跌停会限制可挂价格范围,限价单超出范围应被拒单而非静默挂入。
把这些规则串起来看:价格优先决定“谁的价格更优谁先成交”,时间优先决定“同价谁先排队”,连续竞价负责逐笔实时撮合,集合竞价负责集中形成单一公允价,限价单在成交与挂单之间切换角色,市价单则以价格不确定性换取成交确定性。掌握这五者的配合关系,就能对任意一笔委托的成交路径做出可验证的推演。