Эта страница переведена автоматически. Оригинал на английском языке является каноническим. Читать на английском →
Перейти к основному содержимому

Защита маркетмейкера (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 защищает маркетмейкеров от серии быстрых неблагоприятных исполнений:

  1. Отслеживает накопленные показатели исполнений в скользящем временном окне
  2. Отменяет заявки при превышении лимитов
  3. Автоматически отменяет все остальные заявки с включённым 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-712 SetMmpConfig по всем полям запроса

Ответ: ApiResponse<MmpConfigData>

Получение конфигурации MMP​

Эндпоинт: GET /mmp-config?wallet=...&currency=...

Параметры запроса:

  • 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 проверяется ПОСЛЕ исполнения:

  1. Движок сопоставляет заявки и сначала принимает исполнение
  2. Затем MMP проверяет накопленные показатели для каждой защищённой стороны исполнения
  3. Если у стороны превышены лимиты:
    • 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:

  1. Входящая заявка, вызвавшая срабатывание: исполнение остатка прекращается, заявка получает статус CANCELED с причиной "MMP triggered during fill processing"
  2. Стоящая заявка, вызвавшая срабатывание: исполнение остаётся в силе; остаток заявки, если он есть, отменяется вместе с другими заявками с включённым MMP
  3. Остальные заявки: все открытые заявки с включённым 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,
}

Рекомендации​

Конфигурация​

  1. Выставляйте адекватные лимиты: исходя из вашей толерантности к риску и типичного размера исполнений
  2. Настраивайте конфигурацию по каждому активу: отдельно для каждого базового актива (BTC, ETH и т. д.)
  3. Следите за срабатываниями MMP: частые срабатывания могут говорить о неверно настроенных лимитах или неблагоприятной рыночной конъюнктуре

Управление заявками​

  1. Включайте MMP выборочно: ставьте mmp_enabled=true только для заявок, которые нужно защитить
  2. Используйте одинаковый актив: убедитесь, что все заявки по одному базовому активу соответствуют активу в конфигурации MMP
  3. Обрабатывайте отмены по MMP: реализуйте логику, которая распознаёт отмены по срабатыванию MMP и корректирует котирование

Мониторинг​

  1. Отслеживайте срабатывания MMP: следите за причинами "MMP triggered during fill processing" и "Order canceled by MMP trigger"
  2. Анализируйте окна исполнений: накопленные показатели окна пока не доступны через API; ведите учёт собственных исполнений по каждому базовому активу
  3. Корректируйте лимиты: если 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 по этому базовому активу.