Protection des teneurs de marché (MMP)
Limites sur fenêtre de fills et comportement d'annulation automatique pour les teneurs de marché.
Chaque endpoint MMP rattaché à un portefeuille exige une authentification EIP-712. Les écritures de configuration acceptent le propriétaire du portefeuille ou un agent autorisé pour ce portefeuille. Les lectures sont réservées au propriétaire et rejettent les signatures d'agents autorisés.
La MMP s'applique au compte de trading qui détient les fills. Pour un gestionnaire en marge de portefeuille,
les lectures et écritures signées pour le portefeuille du gestionnaire sont résolues vers son compte de trading
Account.sol, le même compte que celui utilisé pour le placement des ordres.
Les réponses indiquent ce compte dans wallet_address, et la séquence de nonces MMP
appartient à ce compte.
Pour une cohérence lecture-après-écriture, envoyez X-Hypercall-Fence-Wait: 1 sur toute
mutation MMP. Une réponse réussie inclut alors X-Hypercall-Fence ; renvoyez cette
valeur dans X-Hypercall-Fence sur le GET authentifié. Les mutations sans
l'en-tête d'attente optionnel ne renvoient volontairement pas de fence.
Vue d'ensemble
La MMP protège les teneurs de marché contre des fills défavorables rapides en :
- Suivant les métriques cumulées de fills sur une fenêtre temporelle glissante
- Annulant les ordres lorsque les limites sont dépassées
- Annulant automatiquement tous les autres ordres avec MMP activée pour le même portefeuille+sous-jacent
Configuration
Définir la configuration MMP
Endpoint : POST /mmp-config
Requête : 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..."
}
Champs :
wallet: adresse du portefeuillecurrency: devise sous-jacente (par ex."BTC","ETH")interval_ms: durée de la fenêtre glissante en millisecondesfrozen_time_ms: durée du gel après déclenchement (millisecondes)qty_limit: limite de quantité optionnelle (unités de contrat), sérialisée sous forme de chaîne décimaledelta_limit: limite de delta optionnelle, sérialisée sous forme de chaîne décimalevega_limit: limite de véga optionnelle, sérialisée sous forme de chaîne décimalenonce: nonce de protection contre le rejeu, supérieur d'exactement un au dernier nonce validé renvoyé par la lecture authentifiéesignature: signature EIP-712SetMmpConfigcouvrant tous les champs de la requête
Réponse : ApiResponse<MmpConfigData>
Lire la configuration MMP
Endpoint : GET /mmp-config?wallet=...¤cy=...
Paramètres de requête :
wallet(obligatoire)currency(filtre optionnel)
En-têtes obligatoires :
X-Hypercall-Expires-At-Ms: expiration Unix en millisecondes, au plus 60 secondes dans le futurX-Hypercall-Signature: signatureGetMmpConfigcouvrantwallet,currency(chaîne vide si omis) et l'expiration de l'en-tête
Le signataire récupéré doit être le propriétaire du portefeuille. Les signatures d'agents autorisés ne sont pas acceptées pour cette lecture.
Réponse : 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
}
]
}
Supprimer la configuration MMP
Endpoint : DELETE /mmp-config
Requête : DeleteMmpConfigRequest
{
"wallet": "0x...",
"currency": "BTC",
"nonce": 1,
"signature": "0x..."
}
Réponse : ApiResponse<String>. Une commande réussie désactive l'état d'autorité
numérique du couple portefeuille/sous-jacent. Avec l'en-tête de requête
X-Hypercall-Fence-Wait: 1, la réponse inclut X-Hypercall-Fence pour la
lecture adossée à la projection.
Réinitialiser l'état MMP
Endpoint : POST /mmp-config/reset
Requête : ResetMmpRequest
{
"wallet": "0x...",
"currency": "BTC",
"nonce": 1,
"signature": "0x..."
}
Réponse : ApiResponse<String>. Une commande réussie efface la fenêtre de fills
et l'état de gel MMP dans l'autorité rejouable. Avec l'en-tête de requête
X-Hypercall-Fence-Wait: 1, la réponse inclut X-Hypercall-Fence pour la
lecture adossée à la projection.
Comportement de la MMP (essentiel à comprendre)
Quels fills sont comptabilisés
Chaque fill est comptabilisé dans la fenêtre MMP de chaque côté dont l'ordre a
mmp_enabled=true, que cet ordre soit au repos dans le carnet d'ordres (maker) ou
entrant (taker) :
- Cotations au repos : lorsqu'un ordre entrant s'exécute contre votre ordre au repos avec MMP activée, ce fill est ajouté à votre fenêtre. C'est le cas pour lequel la MMP existe : une rafale de fills contre vos cotations déclenche la MMP et annule vos cotations restantes avec MMP activée sur ce sous-jacent.
- Ordres entrants : un ordre avec MMP activée qui prend de la liquidité comptabilise ses propres fills de la même manière.
- Combos et ordres implicites : chaque participant protégé d'un package comptabilise chaque jambe qu'il négocie, évaluée une seule fois par package.
- Les fills RFQ et RPI ne sont pas encore comptabilisés par la MMP. Un gel MMP bloque cependant les nouvelles exécutions RFQ pour le fournisseur de cotations gelé.
Chaque fill est mesuré de votre propre point de vue : un fill qui vend un call ajoute un delta négatif à la fenêtre du vendeur et un delta positif à celle de l'acheteur.
Si un ordre a mmp_enabled=true mais que son portefeuille n'a aucune configuration MMP
pour ce sous-jacent, la MMP échoue en mode fermé : le premier fill déclenche et annule les
ordres avec MMP activée de ce portefeuille sur le sous-jacent. Configurez la MMP avant de marquer
vos ordres.
Ordre de traitement des fills
L'évaluation MMP a lieu APRÈS LE FILL :
- Le moteur apparie et accepte d'abord le fill
- Puis la MMP vérifie les métriques cumulées pour chaque côté protégé du fill
- Si les limites d'un côté sont dépassées :
- La MMP se déclenche pour le portefeuille et le sous-jacent de ce côté
- Le moteur émet un événement
MmpTriggered - Le moteur annule automatiquement tous les ordres ouverts avec MMP activée pour ce portefeuille+sous-jacent
- Si le côté en dépassement était l'ordre entrant, sa quantité restante
s'arrête et il passe à
CANCELEDavec le motif"MMP triggered during fill processing" - Si le côté en dépassement était un maker au repos, l'ordre entrant continue de s'apparier contre d'autres liquidités ; les autres cotations avec MMP activée du maker sont déjà annulées
Conséquence : vous pouvez recevoir des fills qui vous font dépasser vos seuils configurés avant que la MMP ne se déclenche.
Conditions de déclenchement
La MMP se déclenche si n'importe quelle limite configurée est dépassée :
- Limite de quantité :
cumulative_qty > qty_limit - Limite de delta :
|cumulative_delta| > delta_limit - Limite de véga :
|cumulative_vega| > vega_limit
Les métriques cumulées sont calculées sur la fenêtre glissante (interval_ms).
Comportement d'annulation
Lorsque la MMP se déclenche :
- Ordre entrant ayant déclenché : la quantité restante s'arrête, l'ordre passe à
CANCELEDavec le motif"MMP triggered during fill processing" - Ordre au repos ayant déclenché : le fill est maintenu ; le reliquat éventuel de l'ordre est annulé avec les autres ordres avec MMP activée
- Autres ordres : tous les ordres ouverts avec MMP activée pour le même portefeuille+sous-jacent sont annulés automatiquement avec le motif
"Order canceled by MMP trigger"
Remarque : seuls les ordres avec MMP activée sont annulés. Les ordres avec mmp_enabled=false ne sont pas affectés.
Comportement de gel
Après le déclenchement de la MMP :
- Le portefeuille et le sous-jacent sont gelés pendant
frozen_time_msmillisecondes - Pendant le gel, le portefeuille est exclu des enchères RPI et des RFQ sur ce sous-jacent, et les exécutions combo ou implicites qui le rempliraient sont rejetées
- Un fill direct sur un ordre avec MMP activée pendant le gel est tout de même maintenu, puis déclenche à nouveau la MMP et annule les ordres avec MMP activée de ce portefeuille sur le sous-jacent
POST /mmp-config/resetmet fin au gel de manière anticipée
Calcul des métriques de fills
Quantité
- Source :
sizedu fill (unités de contrat) - Cumul : somme de tous les fills dans la fenêtre glissante
Delta
- Source : calculé à partir du symbole du fill et du GreeksCache
- Cumul : somme des deltas de tous les fills dans la fenêtre glissante
Véga
- Source : calculé à partir du symbole du fill et du GreeksCache
- Cumul : somme des végas de tous les fills dans la fenêtre glissante
Fenêtre glissante
Éviction de la fenêtre
Les fills plus anciens que interval_ms sont automatiquement retirés de la fenêtre :
- L'éviction s'exécute lors du traitement du fill suivant, avant l'ajout du nouveau fill
- Les métriques cumulées sont décrémentées à mesure que les anciens fills sont retirés
Réinitialisation de la fenêtre
Réinitialisez l'état MMP via POST /mmp-config/reset :
- Efface tous les fills de la fenêtre
- Remet les métriques cumulées à zéro
- Dégèle la devise
Événements MMP
Événement MmpTriggered
Événement interne (actuellement non transmis aux clients WS) :
MmpTriggeredMessage {
wallet: WalletAddress,
currency: String,
reason: String, // "MMP triggered during fill processing" | "MMP triggered by a resting order fill"
timestamp: u64,
}
Bonnes pratiques
Configuration
- Définissez des limites appropriées : en fonction de votre tolérance au risque et de la taille habituelle de vos fills
- Utilisez des configurations par devise : configurez par sous-jacent (BTC, ETH, etc.)
- Surveillez les déclenchements MMP : un taux de déclenchement élevé peut indiquer des limites mal configurées ou des conditions de marché défavorables
Gestion des ordres
- Activez la MMP de manière sélective : définissez
mmp_enabled=trueuniquement pour les ordres que vous souhaitez protéger - Utilisez une devise cohérente : assurez-vous que tous les ordres d'un même sous-jacent utilisent la même devise dans la configuration MMP
- Gérez les annulations MMP : implémentez une logique pour détecter les annulations déclenchées par la MMP et ajuster vos cotations
Surveillance
- Suivez les déclenchements MMP : surveillez les motifs
"MMP triggered during fill processing"et"Order canceled by MMP trigger" - Examinez les fenêtres de fills : les métriques cumulées de la fenêtre ne sont pas encore exposées via l'API ; suivez vos propres fills par sous-jacent
- Ajustez les limites : si la MMP se déclenche trop souvent, augmentez les limites ; si elle se déclenche trop rarement, diminuez-les
Problèmes courants
La MMP se déclenche trop souvent
Causes :
- Limites trop basses par rapport à la taille habituelle des fills
- Conditions de marché défavorables
- Cotations rapides générant de nombreux fills
Solutions :
- Augmentez
qty_limit,delta_limitouvega_limit - Augmentez
interval_mspour autoriser davantage de fills dans la fenêtre - Réduisez la fréquence de cotation
La MMP ne se déclenche pas
Causes :
- Limites trop élevées
- MMP non activée sur les ordres (
mmp_enabled=false) - Devise incohérente (devise de la configuration MMP != sous-jacent de l'ordre)
Solutions :
- Diminuez les limites
- Vérifiez
mmp_enabled=truesur les ordres - Vérifiez que la devise de la configuration MMP correspond au sous-jacent de l'ordre
Annulations inattendues
Symptôme : des ordres sont annulés avec le motif "Order canceled by MMP trigger" alors que vous ne vous y attendiez pas.
Cause : un autre ordre pour le même portefeuille+sous-jacent a déclenché la MMP.
Solution : lorsqu'un déclenchement survient, examinez tous les ordres avec MMP activée pour le même sous-jacent.