이 페이지는 자동 번역되었습니다. 영어 원문이 정본입니다. 영어로 읽기 →
메인 콘텐츠로 건너뛰기

마켓메이커 보호 장치 (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는 다음과 같은 방식으로 마켓메이커를 급격한 불리한 체결로부터 보호합니다.

  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: 선택 항목인 수량 한도 (계약 단위), 10진수 문자열로 직렬화됩니다
  • delta_limit: 선택 항목인 델타 한도, 10진수 문자열로 직렬화됩니다
  • vega_limit: 선택 항목인 베가 한도, 10진수 문자열로 직렬화됩니다
  • nonce: 재전송 방지용 nonce로, 인증된 읽기 요청이 반환하는 최신 커밋 nonce보다 정확히 1 커야 합니다
  • signature: 모든 요청 필드에 대한 EIP-712 SetMmpConfig 서명

응답: ApiResponse<MmpConfigData>

MMP 설정 조회​

엔드포인트: GET /mmp-config?wallet=...&currency=...

쿼리 파라미터:

  • 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 윈도우에 집계됩니다. 해당 주문이 호가창에 대기 중이었는지(메이커) 새로 들어온 주문인지(테이커)는 관계없습니다.

  • 대기 호가: 들어오는 주문이 MMP가 활성화된 대기 주문과 체결되면 해당 체결이 윈도우에 추가됩니다. MMP가 존재하는 이유가 바로 이 경우입니다. 호가에 대한 체결이 짧은 시간에 몰리면 MMP가 트리거되어 해당 기초자산의 나머지 MMP 활성 호가가 취소됩니다.
  • 들어오는 주문: 유동성을 가져가는 MMP 활성 주문도 자신의 체결을 같은 방식으로 집계합니다.
  • 콤보 및 암시 주문: 패키지의 보호 대상 참여자는 자신이 거래한 모든 레그를 집계하며, 평가는 패키지당 한 번 이루어집니다.
  • RFQ 및 RPI 체결은 아직 MMP에 집계되지 않습니다. 다만 MMP 동결 상태에서는 동결된 호가 제공자의 신규 RFQ 체결이 차단됩니다.

각 체결은 자신의 측 기준으로 측정됩니다. 콜을 매도하는 체결은 매도자의 윈도우에 음(-)의 델타를, 매수자의 윈도우에 양(+)의 델타를 더합니다.

주문에 mmp_enabled=true가 설정되어 있지만 해당 지갑에 그 기초자산에 대한 MMP 설정이 없으면, MMP는 안전 측(fail closed)으로 동작합니다. 첫 체결에서 즉시 트리거되어 해당 기초자산에 대한 그 지갑의 MMP 활성 주문이 취소됩니다. 주문에 플래그를 설정하기 전에 먼저 MMP를 설정하십시오.

체결 처리 순서​

MMP 평가는 체결 이후(POST-FILL)에 이루어집니다:

  1. 엔진이 매칭을 수행하고 먼저 체결을 확정합니다
  2. 이후 MMP가 체결의 각 보호 대상 측에 대해 누적 지표를 확인합니다
  3. 어느 측의 한도가 초과된 경우:
    • 해당 측의 지갑과 기초자산에 대해 MMP가 트리거됩니다
    • 엔진이 MmpTriggered 이벤트를 발생시킵니다
    • 엔진이 해당 지갑+기초자산의 모든 MMP 활성 미체결 주문을 자동 취소합니다
    • 한도를 초과한 측이 들어오는 주문이었다면, 남은 수량의 체결이 중단되고 주문은 "MMP triggered during fill processing" 사유와 함께 CANCELED 상태가 됩니다
    • 한도를 초과한 측이 대기 중인 메이커였다면, 들어오는 주문은 다른 유동성과 계속 매칭되며, 메이커의 다른 MMP 활성 호가는 이미 취소된 상태입니다

시사점: MMP가 트리거되기 전에 설정한 임계값을 넘어서는 체결을 받을 수 있습니다.

트리거 조건​

설정된 한도 중 하나라도 초과되면 MMP가 트리거됩니다.

  • 수량 한도: cumulative_qty > qty_limit
  • 델타 한도: |cumulative_delta| > delta_limit
  • 베가 한도: |cumulative_vega| > vega_limit

누적 지표는 롤링 윈도우(interval_ms)를 기준으로 계산됩니다.

취소 동작​

MMP가 트리거되면 다음과 같이 처리됩니다.

  1. 트리거를 유발한 들어오는 주문: 남은 수량의 체결이 중단되고, 주문은 "MMP triggered during fill processing" 사유와 함께 CANCELED 상태가 됩니다
  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보다 오래된 체결은 윈도우에서 자동으로 제거됩니다.

  • 제거는 다음 체결이 처리될 때, 새 체결이 추가되기 전에 실행됩니다
  • 오래된 체결이 제거되면서 누적 지표도 그만큼 차감됩니다

윈도우 초기화​

POST /mmp-config/reset으로 MMP 상태를 초기화합니다.

  • 윈도우 내 모든 체결을 삭제합니다
  • 누적 지표를 0으로 재설정합니다
  • 통화의 동결을 해제합니다

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 활성 주문을 점검합니다.