撮合系统

独立模块

合约撮合位于 coinex-contract-match/contract-match-provider/src/main/java/com/exch/contract/match,使用 ContractMatchEntrustDTO 和 MatchEngineManager。不能直接把现货 DTO 和事件字段套用到合约。

已核对的处理分支

MatchingBusinessHandler.onEvent 检查 matchEngineManager.isRunning 和 event.isSaveFile() 后进入分支:

事件 订单簿操作
ADD_ORDER orderbook.enter(ContractMatchEntrustDTO)
CANCEL_ORDER orderbook.cancel(id, BigDecimal.ZERO, Boolean.TRUE)
INIT_MATCH orderbook.enterInit(dto, event.isInitCompleted())

合约 enter 传入整个 DTO;现货 enter 则拆开订单 ID、方向、价格、数量和交易对等参数。这是入口形态的差异,具体合约约束应继续在订单簿和前置处理代码中确认。

服务入口与扩展职责

provider/ContractMatchEngineService 暴露 addOrder、cancelOrder、forceCancelOrder,同时包含条件单、保证金、账户与杠杆相关入口。这说明引擎服务承担了多类业务请求,分析时应分开交易事件和账户事件。

异常与资源释放

该处理器会记录异常,将 MatchingSaveFileException 继续抛出,并在 finally 中释放 ResizeSemaphore。捕获异常不代表业务成功;需要追踪上层响应和持久化状态。

源码阅读路线

ContractMatchEngineService → 事件与 service/MatchEngineManager → disruptor/SaveOrderHandler → disruptor/MatchingBusinessHandler → book/OrderBook、book/RBTreeOrderBook → 成交及仓位处理。

其中事件分支已经核对;完整前置校验、成交价格规则和跨服务后续处理仍需逐段确认。

验证场景

覆盖开仓与平仓、部分成交撤单、保证金不足、强制撤单、恢复初始化。对每个场景同时检查委托、仓位、账户和手续费,避免只验证订单是否成交。

引擎内已确认的串联

service/MatchEngineManager.java 使用 handleEventsWith(new SaveOrderHandler(...)).then(new MatchingBusinessHandler(...))。普通 addOrder 构造 ADD_ORDER 事件,cancelOrder 在缓存和状态检查后构造 CANCEL_ORDER。

ContractMatchEngineService
    → RequestMatchEvent → 对应引擎
    → SaveOrderHandler → MatchingBusinessHandler
    → OrderBook / PriceLevel
    → 订单、仓位和账户相关处理
    → 深度、成交及结果消息

图中的仓位账户处理并非仅发生在订单簿之后的单一函数,应按实际前置处理和成交处理分支核对事务边界。

账户与配置事件

SaveOrderHandler 的实际事件包括 RECHARGE、WITHDRAW、CHANGE_CONTRACT_LEVEL、ADD_MARGIN、SUB_MARGIN、UPDATE_USER_ACCOUNT、UPDATE_USER_POSITION_FROZEN 及配置变化。它们不是普通下单事件,不应全部当作订单进入撮合。

输出与子工程

entity/PriceLevel.java 可见 sendDepthMsg、sendTradeMsg、sendMatchResultMsg 调用。辅助器调用、缓存、真正消息投递和消费分别取证。工程包含 contract-match-api、contract-match-provider、contract-match-es,没有以现货 matching-admin 名称命名的同构子工程,不能照搬现货管理目录。

恢复与管理接口见撮合管理与恢复。