做市商保护 (MMP)
面向做市商的成交窗口限额与自动撤单行为。
所有钱包范围的 MMP 端点均需要 EIP-712 认证。配置写入操作接受钱包所有者或该钱包的授权代理签名。读取操作仅限所有者,拒绝授权代理签名。
MMP 作用于持有成交的交易账户。对于组合保证金管理者,以管理者钱包签名的读取和写入操作会解析到其 Account.sol 交易账户,即下单所使用的同一账户。响应在 wallet_address 中报告该账户,MMP nonce 序列也归属于该账户。
如需写后读一致性,请在任何 MMP 变更请求中发送 X-Hypercall-Fence-Wait: 1。成功的响应将包含 X-Hypercall-Fence;请在经认证的 GET 请求中将该值作为 X-Hypercall-Fence 回传。未携带该可选等待请求头的变更请求有意不返回 fence。
概述
MMP 通过以下方式保护做市商免受快速不利成交的影响:
- 在滚动时间窗口内跟踪累计成交指标
- 在突破限额时撤销订单
- 自动撤销同一钱包+标的资产下所有其他启用 MMP 的订单
配置
设置 MMP 配置
端点:POST /mmp-config
请求:SetMmpConfigRequest
{
"wallet": "0x...",
"currency": "BTC",
"interval_ms": 60000,
"frozen_time_ms": 300000,
"qty_limit": "1000000",
"delta_limit": "10.0",
"vega_limit": "5.0",
"nonce": 1,
"signature": "0x..."
}
字段:
wallet:钱包地址currency:标的资产币种(例如"BTC"、"ETH")interval_ms:滚动窗口长度(毫秒)frozen_time_ms:触发后的冻结时长(毫秒)qty_limit:可选的数量限额(合约单位),以十进制字符串序列化delta_limit:可选的 Delta 限额,以十进制字符串序列化vega_limit:可选的 Vega 限额,以十进制字符串序列化nonce:防重放 nonce,必须恰好比经认证读取返回的最新已提交 nonce 大 1signature:覆盖所有请求字段的 EIP-712SetMmpConfig签名
响应:ApiResponse<MmpConfigData>
获取 MMP 配置
端点:GET /mmp-config?wallet=...¤cy=...
查询参数:
wallet(必填)currency(可选过滤条件)
必需的请求头:
X-Hypercall-Expires-At-Ms:以毫秒表示的 Unix 过期时间,不得晚于当前时间 60 秒以上X-Hypercall-Signature:覆盖wallet、currency(省略时为空字符串)及请求头过期时间的GetMmpConfig签名
恢复出的签名者必须是钱包所有者。此读取操作不接受授权代理签名。
响应:MmpConfigResponse
{
"success": true,
"data": [
{
"wallet_address": "0x...",
"currency": "BTC",
"interval_ms": 60000,
"frozen_time_ms": 300000,
"qty_limit": "1000000",
"delta_limit": "10.0",
"vega_limit": "5.0",
"enabled": true,
"nonce": 1
}
]
}
删除 MMP 配置
端点:DELETE /mmp-config
请求:DeleteMmpConfigRequest
{
"wallet": "0x...",
"currency": "BTC",
"nonce": 1,
"signature": "0x..."
}
响应:ApiResponse<String>。成功的命令会禁用该钱包/标的资产的数值权威状态。若携带请求头 X-Hypercall-Fence-Wait: 1,响应将包含用于投影读取的 X-Hypercall-Fence。
重置 MMP 状态
端点:POST /mmp-config/reset
请求:ResetMmpRequest
{
"wallet": "0x...",
"currency": "BTC",
"nonce": 1,
"signature": "0x..."
}
响应:ApiResponse<String>。成功的命令会在可重放的权威状态中清除 MMP 成交窗口和冻结状态。若携带请求头 X-Hypercall-Fence-Wait: 1,响应将包含用于投影读取的 X-Hypercall-Fence。
MMP 行为(务必理解)
哪些成交会被计入
每笔成交都会计入订单设置了 mmp_enabled=true 的每一方的 MMP 窗口,无论该订单是挂在订单簿上的(Maker)还是新进入的(Taker):
- 挂单报价: 当新进入的订单与您启用 MMP 的挂单成交时,该成交会被计入您的窗口。这正是 MMP 存在的意义:针对您报价的一连串成交会触发 MMP,并撤销您在该标的资产上剩余的启用 MMP 的报价。
- 新进入订单: 启用 MMP 的吃单订单以同样方式计入其自身成交。
- 组合订单与隐含订单: 组合包中每个受保护的参与方都会计入其成交的每一条腿,并按每个组合包评估一次。
- RFQ 和 RPI 成交目前尚不计入 MMP。 MMP 冻结会阻止被冻结报价方的新 RFQ 执行。
每笔成交均从您自身的方向计量:卖出看涨期权的成交会为卖方窗口增加负 Delta,为买方窗口增加正 Delta。
如果订单设置了 mmp_enabled=true,但其钱包在该标的资产上没有 MMP 配置,MMP 将以失败关闭方式处理:第一笔成交即会触发,并撤销该钱包在该标的资产上所有启用 MMP 的订单。请在标记订单之前先配置 MMP。
成交处理顺序
MMP 评估在成交之后进行:
- 引擎完成撮合并先接受成交
- 随后 MMP 针对成交中每个受保护的一方检查累计指标
- 如果某一方突破限额:
- MMP 针对该方的钱包和标的资产触发
- 引擎发出
MmpTriggered事件 - 引擎自动撤销该钱包+标的资产下所有启用 MMP 的未成交订单
- 如果突破限额的一方是新进入订单,其剩余数量停止撮合,订单变为
CANCELED,原因为"MMP triggered during fill processing" - 如果突破限额的一方是挂单 Maker,新进入订单将继续与其他流动性撮合;该 Maker 其他启用 MMP 的报价已被撤销
影响:在 MMP 触发之前,您可能会收到使您超出所配置阈值的成交。
触发条件
只要任一已配置的限额被突破,MMP 即会触发:
- 数量限额:
cumulative_qty > qty_limit - Delta 限额:
|cumulative_delta| > delta_limit - Vega 限额:
|cumulative_vega| > vega_limit
累计指标在滚动窗口(interval_ms)内计算。
撤单行为
MMP 触发时:
- 触发 MMP 的新进入订单:剩余数量停止撮合,订单变为
CANCELED,原因为"MMP triggered during fill processing" - 触发 MMP 的挂单:成交保持有效;订单的剩余部分(如有)将与其他启用 MMP 的订单一并撤销
- 其他订单:同一钱包+标的资产下所有启用 MMP 的未成交订单将被自动撤销,原因为
"Order canceled by MMP trigger"
注意:只有启用 MMP 的订单会被撤销。mmp_enabled=false 的订单不受影响。
冻结行为
MMP 触发后:
- 该钱包和标的资产将被冻结
frozen_time_ms毫秒 - 冻结期间,该钱包被排除在该标的资产的 RPI 拍卖和 RFQ 之外,会使其成交的组合或隐含执行将被拒绝
- 冻结期间启用 MMP 的订单发生的直接成交仍然有效,随后会再次触发 MMP,并撤销该钱包在该标的资产上所有启用 MMP 的订单
POST /mmp-config/reset可提前结束冻结
成交指标计算
数量
- 来源:成交的
size(合约单位) - 累计:滚动窗口内所有成交之和
Delta
- 来源:根据成交合约代码和 GreeksCache 计算
- 累计:滚动窗口内所有成交 Delta 之和
Vega
- 来源:根据成交合约代码和 GreeksCache 计算
- 累计:滚动窗口内所有成交 Vega 之和
滚动窗口
窗口淘汰
早于 interval_ms 的成交会自动从窗口中淘汰:
- 淘汰在处理下一笔成交时、新成交加入之前执行
- 移除旧成交时相应递减累计指标
窗口重置
通过 POST /mmp-config/reset 重置 MMP 状态:
- 清除窗口内的所有成交
- 将累计指标重置为零
- 解除该币种的冻结
MMP 事件
MmpTriggered 事件
内部事件(目前不会转发给 WS 客户端):
MmpTriggeredMessage {
wallet: WalletAddress,
currency: String,
reason: String, // "MMP triggered during fill processing" | "MMP triggered by a resting order fill"
timestamp: u64,
}
最佳实践
配置
- 设置合适的限额:根据您的风险承受能力和典型成交规模设定
- 使用按币种的配置:按标的资产(BTC、ETH 等)分别配置
- 监控 MMP 触发:触发频率过高可能意味着限额配置不当或市场环境不利
订单管理
- 有选择地启用 MMP:仅为需要保护的订单设置
mmp_enabled=true - 使用一致的币种:确保同一标的资产的所有订单在 MMP 配置中使用相同的币种
- 处理 MMP 撤单:实现检测 MMP 触发撤单并调整报价的逻辑
监控
- 跟踪 MMP 触发:监控原因为
"MMP triggered during fill processing"和"Order canceled by MMP trigger"的事件 - 复核成交窗口:累计窗口指标目前尚未通过 API 公开;请自行按标的资产跟踪您的成交
- 调整限额:如果 MMP 触发过于频繁,请提高限额;如果触发过少,请降低限额
常见问题
MMP 触发过于频繁
原因:
- 限额相对于典型成交规模过低
- 市场环境不利
- 快速报价导致大量成交
解决方案:
- 提高
qty_limit、delta_limit或vega_limit - 增大
interval_ms,允许窗口内容纳更多成交 - 降低报价频率
MMP 未触发
原因:
- 限额过高
- 订单未启用 MMP(
mmp_enabled=false) - 币种不匹配(MMP 配置币种 != 订单标的资产)
解决方案:
- 降低限额
- 确认订单已设置
mmp_enabled=true - 确认 MMP 配置币种与订单标的资产一致
意外撤单
现象:订单以原因 "Order canceled by MMP trigger" 被撤销,但您并未预期到。
原因:同一钱包+标的资产下的另一笔订单触发了 MMP。
解决方案:当某笔订单触发 MMP 时,复核同一标的资产下所有启用 MMP 的订单。