撮合系统
独立模块
合约撮合位于 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 名称命名的同构子工程,不能照搬现货管理目录。
恢复与管理接口见撮合管理与恢复。