0413 分钟
CANCEL · REPLACE · SELF-TRADE

改价为什么要重新排队?

撤掉一张订单再改价,观察时间优先如何重置,以及自成交保护如何阻止虚假的成交量。

本章目标学完后,你应该能:
  • 解释撤改单为什么会失去原来的时间优先级
  • 观察自成交保护如何取消新订单剩余
  • 区分风控拒绝、撤单和真实成交事件
章节位置第 4 / 4 章
  1. 上一章价差是谁留下的?
  2. 本章改价为什么要重新排队?

    撤掉一张订单再改价,观察时间优先如何重置,以及自成交保护如何阻止虚假的成交量。

  3. 下一章自由实验室
阅读前

先想一想这几个问题

展开答案前,可以先在心里做个判断。与预期不同的内容可以加入复习列表。

Q01只是把价格改好一点,为什么订单要重新排队?
简要回答

改价会改变你向市场承诺的条件,相当于一张新订单。若保留旧时间优先级,交易者可以用反复修改占住队首,对后来者不公平。

和原先判断相比:

撮合引擎不仅要找到对手方,还要阻止错误的状态转换。撤改单、自成交保护和冻结资产规则,决定一条看似普通的报价会变成真实成交、被取消,还是被风控拒绝。

改价不是编辑一行文字

先把买单挂在 100 分,再把它改成 102 分。系统不会原地修改原订单,因为那会让一个新价格继承旧的时间优先级。正确的状态变化是:释放旧订单的冻结资产,结束旧订单,再用新序号提交一张新的订单。

ENGINE RUNNINGLAB / 积分
ORDERBOOK 001 · PRICE / TIME PRIORITY

LAB / 积分

限价订单先进入队列;只有盘口交叉,撮合引擎才会把它们变成成交。

最近成交分 / LAB
买一98最高买价
卖一102最低卖价
价差4
已成交0LAB
CANCEL · REPLACE · SELF-TRADE

改价不是“编辑”,而是一次新的排队

撤改单会释放旧订单的冻结资产,并用新的序号重新进入队列。若新价格穿过盘口,系统仍会执行自成交保护。

当前挂单 最近动作 系统状态 守恒且无交叉
实时订单簿价格 / 剩余 / 来源
卖单(ASK)买单(BID)
1022A
1023B
1055A
983B
965A
卖一:102买一:98
观察提示

先读盘口:卖一是当前最低卖价,买一是当前最高买价。只有买价不低于卖价时,撮合循环才会启动。

引擎事件1 EVENTS
  1. 01

    盘口创建:卖一 102 分(两个价位相同的订单),买一 98 分。价格和时间都需要被保留。

操作记录实验时间轴
1 个状态快照

拖动滑块可以回到此前的步骤。从那里继续操作时,后续记录会替换为新的操作序列。

初始状态
查看实验记录 →

自成交会制造虚假的市场信号

如果同一个账户同时有买 100 和卖 99,简单的撮合循环会让账户“和自己成交”。这不会创造真正的风险转移,却会增加成交量、改变最近成交价,并制造虚假的需求。实验室采用取消新进入订单剩余的自成交保护:历史订单不被抹掉,冻结资产被释放,事件日志明确写出原因。

展开:这一步如何实现
replace(old, newPrice, newQuantity):
  release(old.remaining)
  close(old)
  new = enqueue(newPrice, newQuantity, nextSequence)
  match(new)

if buyer.trader == seller.trader:
  cancel(new.remaining)
  emit("SELF_TRADE_PREVENTED")

风控不是撮合之后的装饰,而是状态机的一部分。每个拒绝、取消和成交都应该留下可重放的事件,才能让审计者判断余额、冻结资产和订单簿是否仍然一致。

理解检查

为什么撤改单后,新价格不能继续沿用旧订单的时间优先级?

读懂一条风控事件

  1. 这是订单被拒绝、被取消,还是已经成交?
  2. 哪一部分资产仍被冻结,哪一部分已经结算?
  3. 新订单的序号是否真的晚于旧订单?
  4. 事件重放后,订单簿是否仍然无交叉、总资产是否守恒?

这套检查会贯穿交易所、链上订单簿和清算引擎。安全不是某个按钮,而是每一步状态转换都有明确边界。

本章小结完成练习和理解检查后,可以保存本章