Захист маркетмейкера (MMP)
Ліміти виконань у вікні та поведінка автоматичного скасування для маркетмейкерів.
Кожен ендпоінт MMP, прив'язаний до гаманця, вимагає автентифікації EIP-712. Запис конфігурації приймає підпис власника гаманця або авторизованого агента для цього гаманця. Читання доступне лише власнику, підписи авторизованих агентів відхиляються.
MMP застосовується до торгового акаунта, якому належать виконання. Для менеджера
з портфельною маржею операції читання та запису, підписані гаманцем менеджера, спрямовуються до його
торгового акаунта Account.sol, того самого акаунта, який використовується для розміщення заявок.
Відповіді вказують цей акаунт у wallet_address, а послідовність nonce MMP
належить цьому акаунту.
Для узгодженості читання після запису надсилайте X-Hypercall-Fence-Wait: 1 у будь-якому запиті
на зміну MMP. Успішна відповідь тоді містить X-Hypercall-Fence; передайте це
значення як X-Hypercall-Fence в автентифікованому GET. Запити на зміну без
заголовка очікування навмисно не повертають 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: необов'язковий ліміт дельти, серіалізований як десятковий рядокvega_limit: необов'язковий ліміт веги, серіалізований як десятковий рядокnonce: nonce для захисту від повторного відтворення, рівно на одиницю більший за останній зафіксований nonce, повернутий автентифікованим читаннямsignature: підпис EIP-712SetMmpConfigнад усіма полями запиту
Відповідь: ApiResponse<MmpConfigData>
Отримання конфігурації MMP
Ендпоінт: GET /mmp-config?wallet=...¤cy=...
Параметри запиту:
wallet(обов'язковий)currency(необов'язковий фільтр)
Обов'язкові заголовки:
X-Hypercall-Expires-At-Ms: час закінчення дії в Unix-форматі в мілісекундах, не більше ніж на 60 секунд у майбутньомуX-Hypercall-Signature: підписGetMmpConfigнадwallet,currency(порожній рядок, якщо пропущено) та часом закінчення дії із заголовка
Відновлений підписант має бути власником гаманця. Підписи авторизованих агентів для цього читання не приймаються.
Відповідь: 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 кожної сторони, заявка якої має
mmp_enabled=true, незалежно від того, чи ця заявка стояла в книзі (мейкер), чи
надійшла (тейкер):
- Котирування в книзі: коли вхідна заявка торгує проти вашої заявки з увімкненим MMP, що стоїть у книзі, це виконання додається до вашого вікна. Саме для цього випадку існує MMP: серія виконань проти ваших котирувань спрацьовує MMP і скасовує ваші решту котирувань з увімкненим MMP за цим базовим активом.
- Вхідні заявки: заявка з увімкненим MMP, яка забирає ліквідність, враховує власні виконання так само.
- Комбо та імпліцитні заявки: кожен захищений учасник пакета враховує кожну ногу, якою він торгує, з оцінкою один раз на пакет.
- Виконання RFQ та RPI поки не враховуються в MMP. Заморожування MMP блокує нові виконання RFQ для замороженого постачальника котирувань.
Кожне виконання вимірюється з вашої сторони: виконання, яке продає колл, додає від'ємну дельту до вікна продавця та додатну до вікна покупця.
Якщо заявка має mmp_enabled=true, але її гаманець не має конфігурації MMP
для цього базового активу, MMP закривається в безпечний бік: перше виконання спрацьовує і скасовує
заявки цього гаманця з увімкненим MMP за базовим активом. Налаштуйте MMP перед тим, як позначати
заявки.
Порядок обробки виконань
Оцінка MMP відбувається ПІСЛЯ ВИКОНАННЯ:
- Рушій зіставляє та спочатку приймає виконання
- Потім MMP перевіряє кумулятивні метрики для кожної захищеної сторони виконання
- Якщо ліміти сторони перевищено:
- MMP спрацьовує для гаманця та базового активу цієї сторони
- Рушій генерує подію
MmpTriggered - Рушій автоматично скасовує всі відкриті заявки з увімкненим MMP для цієї пари гаманець+базовий актив
- Якщо стороною, що перевищила ліміт, була вхідна заявка, її залишок
зупиняється, і вона переходить у статус
CANCELEDз причиною"MMP triggered during fill processing" - Якщо стороною, що перевищила ліміт, був мейкер у книзі, вхідна заявка продовжує зіставлятися з іншою ліквідністю; інші котирування мейкера з увімкненим MMP вже скасовано
Наслідок: ви можете отримати виконання, які виводять вас за налаштовані пороги, перш ніж MMP спрацює.
Умови спрацювання
MMP спрацьовує, якщо перевищено будь-який налаштований ліміт:
- Ліміт кількості:
cumulative_qty > qty_limit - Ліміт дельти:
|cumulative_delta| > delta_limit - Ліміт веги:
|cumulative_vega| > vega_limit
Кумулятивні метрики обчислюються в межах ковзного вікна (interval_ms).
Поведінка скасування
Коли MMP спрацьовує:
- Вхідна заявка, що спричинила спрацювання: залишок зупиняється, заявка переходить у статус
CANCELEDз причиною"MMP triggered during fill processing" - Заявка в книзі, що спричинила спрацювання: виконання залишається в силі; залишок заявки, якщо він є, скасовується разом з іншими заявками з увімкненим 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виконання (у контрактних одиницях) - Кумулятивно: сума всіх виконань у ковзному вікні
Дельта
- Джерело: обчислюється на основі символу виконання та GreeksCache
- Кумулятивно: сума дельт усіх виконань у ковзному вікні
Вега
- Джерело: обчислюється на основі символу виконання та GreeksCache
- Кумулятивно: сума вег усіх виконань у ковзному вікні
Ковзне вікно
Витіснення з вікна
Виконання, старші за interval_ms, автоматично витісняються з вікна:
- Витіснення виконується під час обробки наступного виконання, перед додаванням нового
- Кумулятивні метрики зменшуються в міру видалення старих виконань
Скидання вікна
Скиньте стан MMP через POST /mmp-config/reset:
- Очищає всі виконання у вікні
- Скидає кумулятивні метрики до нуля
- Розморожує валюту
Події 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 за тим самим базовим активом.