Protección del market maker (MMP)
Límites de ventana de ejecuciones y cancelación automática para market makers.
Todos los endpoints de MMP con ámbito de wallet requieren autenticación EIP-712. Las escrituras de configuración aceptan al propietario de la wallet o a un agente autorizado para esa wallet. Las lecturas son exclusivas del propietario y rechazan firmas de agentes autorizados.
MMP se aplica a la cuenta de trading propietaria de las ejecuciones. Para un manager de margen de cartera, las lecturas y escrituras firmadas por la wallet del manager se resuelven en su cuenta de trading Account.sol, la misma cuenta que utiliza la colocación de órdenes. Las respuestas reportan esa cuenta en wallet_address, y la secuencia de nonces de MMP pertenece a esa cuenta.
Para obtener consistencia de lectura tras escritura, envíe X-Hypercall-Fence-Wait: 1 en cualquier mutación de MMP. Una respuesta exitosa incluirá entonces X-Hypercall-Fence; reenvíe ese valor como X-Hypercall-Fence en el GET autenticado. Las mutaciones sin el encabezado opcional de espera no devuelven un fence de forma intencionada.
Descripción general
MMP protege a los market makers frente a ejecuciones adversas rápidas mediante:
- El seguimiento de métricas acumuladas de ejecuciones dentro de una ventana temporal móvil
- La cancelación de órdenes cuando se superan los límites
- La cancelación automática de todas las demás órdenes con MMP habilitado para la misma wallet y activo subyacente
Configuración
Establecer la configuración de MMP
Endpoint: POST /mmp-config
Solicitud: 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..."
}
Campos:
wallet: Dirección de la walletcurrency: Moneda del activo subyacente (p. ej.,"BTC","ETH")interval_ms: Duración de la ventana móvil en milisegundosfrozen_time_ms: Duración del congelamiento tras el disparo (milisegundos)qty_limit: Límite de cantidad opcional (unidades de contrato), serializado como cadena decimaldelta_limit: Límite de delta opcional, serializado como cadena decimalvega_limit: Límite de vega opcional, serializado como cadena decimalnonce: Nonce de protección contra repetición, exactamente uno mayor que el último nonce confirmado devuelto por la lectura autenticadasignature: Firma EIP-712SetMmpConfigsobre todos los campos de la solicitud
Respuesta: ApiResponse<MmpConfigData>
Obtener la configuración de MMP
Endpoint: GET /mmp-config?wallet=...¤cy=...
Parámetros de consulta:
wallet(obligatorio)currency(filtro opcional)
Encabezados obligatorios:
X-Hypercall-Expires-At-Ms: Expiración Unix en milisegundos, no más de 60 segundos en el futuroX-Hypercall-Signature: FirmaGetMmpConfigsobrewallet,currency(cadena vacía si se omite) y la expiración del encabezado
El firmante recuperado debe ser el propietario de la wallet. No se aceptan firmas de agentes autorizados para esta lectura.
Respuesta: 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
}
]
}
Eliminar la configuración de MMP
Endpoint: DELETE /mmp-config
Solicitud: DeleteMmpConfigRequest
{
"wallet": "0x...",
"currency": "BTC",
"nonce": 1,
"signature": "0x..."
}
Respuesta: ApiResponse<String>. Un comando exitoso deshabilita el estado numérico de autoridad de la wallet y el activo subyacente. Con el encabezado de solicitud X-Hypercall-Fence-Wait: 1, la respuesta incluye X-Hypercall-Fence para la lectura respaldada por la proyección.
Restablecer el estado de MMP
Endpoint: POST /mmp-config/reset
Solicitud: ResetMmpRequest
{
"wallet": "0x...",
"currency": "BTC",
"nonce": 1,
"signature": "0x..."
}
Respuesta: ApiResponse<String>. Un comando exitoso borra la ventana de ejecuciones de MMP y el estado de congelamiento en la autoridad reproducible. Con el encabezado de solicitud X-Hypercall-Fence-Wait: 1, la respuesta incluye X-Hypercall-Fence para la lectura respaldada por la proyección.
Comportamiento de MMP (fundamental para entenderlo)
Qué ejecuciones cuentan
Cada ejecución cuenta para la ventana de MMP de cada lado cuya orden tenga mmp_enabled=true, ya sea que esa orden estuviera en reposo en el libro (maker) o entrando (taker):
- Cotizaciones en reposo: cuando una orden entrante se ejecuta contra su orden en reposo con MMP habilitado, esa ejecución se añade a su ventana. Este es el caso para el que existe MMP: una ráfaga de ejecuciones contra sus cotizaciones dispara MMP y cancela sus cotizaciones restantes con MMP habilitado en ese activo subyacente.
- Órdenes entrantes: una orden con MMP habilitado que toma liquidez cuenta sus propias ejecuciones de la misma manera.
- Combos y órdenes implícitas: cada participante protegido de un paquete cuenta cada pata que negocia, evaluada una sola vez por paquete.
- Las ejecuciones de RFQ y RPI todavía no cuentan para MMP. Un congelamiento de MMP sí bloquea nuevas ejecuciones de RFQ para el proveedor de cotizaciones congelado.
Cada ejecución se mide desde su propio lado: una ejecución que vende una opción call añade delta negativa a la ventana del vendedor y delta positiva a la del comprador.
Si una orden tiene mmp_enabled=true pero su wallet no tiene configuración de MMP para ese activo subyacente, MMP falla de forma cerrada: la primera ejecución lo dispara y cancela las órdenes con MMP habilitado de esa wallet en el activo subyacente. Configure MMP antes de marcar órdenes.
Orden de procesamiento de ejecuciones
La evaluación de MMP es POSTERIOR A LA EJECUCIÓN:
- El motor empareja y acepta primero la ejecución
- Luego MMP verifica las métricas acumuladas de cada lado protegido de la ejecución
- Si se superan los límites de un lado:
- MMP se dispara para la wallet y el activo subyacente de ese lado
- El motor emite el evento
MmpTriggered - El motor cancela automáticamente todas las órdenes abiertas con MMP habilitado para esa wallet y activo subyacente
- Si el lado que superó el límite era la orden entrante, su cantidad restante se detiene y pasa a
CANCELEDcon el motivo"MMP triggered during fill processing" - Si el lado que superó el límite era un maker en reposo, la orden entrante sigue emparejándose contra otra liquidez; las demás cotizaciones con MMP habilitado del maker ya están canceladas
Implicación: Puede recibir ejecuciones que lo lleven más allá de sus umbrales configurados antes de que MMP se dispare.
Condiciones de disparo
MMP se dispara si se supera cualquier límite configurado:
- Límite de cantidad:
cumulative_qty > qty_limit - Límite de delta:
|cumulative_delta| > delta_limit - Límite de vega:
|cumulative_vega| > vega_limit
Las métricas acumuladas se calculan sobre la ventana móvil (interval_ms).
Comportamiento de cancelación
Cuando MMP se dispara:
- Orden entrante que lo disparó: la cantidad restante se detiene y la orden pasa a
CANCELEDcon el motivo"MMP triggered during fill processing" - Orden en reposo que lo disparó: la ejecución se mantiene; el remanente de la orden, si lo hay, se cancela junto con las demás órdenes con MMP habilitado
- Otras órdenes: Todas las órdenes abiertas con MMP habilitado para la misma wallet y activo subyacente se cancelan automáticamente con el motivo
"Order canceled by MMP trigger"
Nota: Solo se cancelan las órdenes con MMP habilitado. Las órdenes con mmp_enabled=false no se ven afectadas.
Comportamiento de congelamiento
Después de que MMP se dispara:
- La wallet y el activo subyacente quedan congelados durante
frozen_time_msmilisegundos - Mientras está congelada, la wallet queda excluida de las subastas RPI y de los RFQ en ese activo subyacente, y se rechazan las ejecuciones de combos u órdenes implícitas que la ejecutarían
- Una ejecución directa sobre una orden con MMP habilitado durante el congelamiento se mantiene, pero vuelve a disparar MMP y cancela las órdenes con MMP habilitado de esa wallet en el activo subyacente
POST /mmp-config/resetfinaliza el congelamiento de forma anticipada
Cálculo de métricas de ejecución
Cantidad
- Fuente:
sizede la ejecución (unidades de contrato) - Acumulado: Suma de todas las ejecuciones en la ventana móvil
Delta
- Fuente: Calculada a partir del símbolo de la ejecución y GreeksCache
- Acumulado: Suma de las deltas de todas las ejecuciones en la ventana móvil
Vega
- Fuente: Calculada a partir del símbolo de la ejecución y GreeksCache
- Acumulado: Suma de las vegas de todas las ejecuciones en la ventana móvil
Ventana móvil
Expulsión de la ventana
Las ejecuciones con una antigüedad mayor que interval_ms se expulsan automáticamente de la ventana:
- La expulsión se ejecuta al procesar la siguiente ejecución, antes de añadir la nueva
- Las métricas acumuladas se reducen a medida que se eliminan las ejecuciones antiguas
Restablecimiento de la ventana
Restablezca el estado de MMP mediante POST /mmp-config/reset:
- Borra todas las ejecuciones de la ventana
- Restablece las métricas acumuladas a cero
- Descongela la moneda
Eventos de MMP
Evento MmpTriggered
Evento interno (actualmente no se reenvía a los clientes WS):
MmpTriggeredMessage {
wallet: WalletAddress,
currency: String,
reason: String, // "MMP triggered during fill processing" | "MMP triggered by a resting order fill"
timestamp: u64,
}
Buenas prácticas
Configuración
- Establezca límites adecuados: En función de su tolerancia al riesgo y del tamaño habitual de sus ejecuciones
- Use configuraciones específicas por moneda: Configure por activo subyacente (BTC, ETH, etc.)
- Supervise los disparos de MMP: Una tasa alta de disparos puede indicar límites mal configurados o condiciones de mercado adversas
Gestión de órdenes
- Habilite MMP de forma selectiva: Establezca
mmp_enabled=truesolo en las órdenes que desee proteger - Use una moneda coherente: Asegúrese de que todas las órdenes del mismo activo subyacente usen la misma moneda en la configuración de MMP
- Gestione las cancelaciones de MMP: Implemente lógica para detectar cancelaciones disparadas por MMP y ajustar sus cotizaciones
Monitoreo
- Haga seguimiento de los disparos de MMP: Supervise los motivos
"MMP triggered during fill processing"y"Order canceled by MMP trigger" - Revise las ventanas de ejecuciones: Las métricas acumuladas de la ventana todavía no se exponen a través de la API; lleve el registro de sus propias ejecuciones por activo subyacente
- Ajuste los límites: Si MMP se dispara con demasiada frecuencia, aumente los límites; si se dispara muy rara vez, redúzcalos
Problemas comunes
MMP se dispara con demasiada frecuencia
Causas:
- Límites demasiado bajos para el tamaño habitual de las ejecuciones
- Condiciones de mercado adversas
- Cotización rápida que provoca muchas ejecuciones
Soluciones:
- Aumente
qty_limit,delta_limitovega_limit - Aumente
interval_mspara permitir más ejecuciones en la ventana - Reduzca la frecuencia de cotización
MMP no se dispara
Causas:
- Límites demasiado altos
- MMP no habilitado en las órdenes (
mmp_enabled=false) - Discrepancia de moneda (moneda de la configuración de MMP != activo subyacente de la orden)
Soluciones:
- Reduzca los límites
- Verifique
mmp_enabled=trueen las órdenes - Verifique que la moneda de la configuración de MMP coincida con el activo subyacente de la orden
Cancelaciones inesperadas
Síntoma: Órdenes canceladas con el motivo "Order canceled by MMP trigger" sin que usted lo esperara.
Causa: Otra orden de la misma wallet y activo subyacente disparó MMP.
Solución: Revise todas las órdenes con MMP habilitado del mismo activo subyacente cuando una de ellas lo dispare.