refactor(mcp-deribit): replace risk_guard with local leverage_cap

This commit is contained in:
AdrianoDev
2026-04-27 17:49:35 +02:00
parent a163947205
commit ecb2d0e4c2
3 changed files with 18 additions and 95 deletions
@@ -36,7 +36,7 @@ def main():
core_token_file=os.environ.get("CORE_TOKEN_FILE"),
observer_token_file=os.environ.get("OBSERVER_TOKEN_FILE"),
)
app = create_app(client=client, token_store=token_store)
app = create_app(client=client, token_store=token_store, creds=creds)
uvicorn.run(
app,
log_config=None, # CER-P5-009: delega al root JSON logger
+9 -60
View File
@@ -5,11 +5,8 @@ import os
from fastapi import Depends, FastAPI, HTTPException
from mcp_common.auth import Principal, TokenStore, require_principal
from mcp_common.mcp_bridge import mount_mcp_endpoint
from mcp_common.risk_guard import (
enforce_aggregate,
enforce_leverage,
enforce_single_notional,
)
from mcp_deribit.leverage_cap import enforce_leverage as _enforce_leverage
from mcp_deribit.leverage_cap import get_max_leverage
from mcp_common.server import build_app
from pydantic import BaseModel, field_validator, model_validator
@@ -208,48 +205,6 @@ class ClosePositionReq(BaseModel):
instrument_name: str
# --- CER-016 notional helpers ---
async def _compute_notional_deribit(client: DeribitClient, body: PlaceOrderReq) -> float:
"""Stima notional in USD per un ordine Deribit.
- Perp USDC: contract size = 1 USD → amount è già notional USD.
- Options: amount è in base asset (BTC/ETH) → moltiplica per index price.
- Altri perp BTC/ETH: amount in USD notional.
"""
name = body.instrument_name.upper()
if name.endswith("-PERPETUAL"):
return float(body.amount)
ref_price: float | None = body.price
if ref_price is None:
try:
tk = await client.get_ticker(body.instrument_name)
ref_price = tk.get("mark_price") or tk.get("last_price")
except Exception:
ref_price = None
if not ref_price:
return float(body.amount)
return float(body.amount) * float(ref_price)
async def _current_aggregate_deribit(client: DeribitClient) -> float:
"""Somma notional posizioni aperte su Deribit (USDC)."""
try:
positions = await client.get_positions("USDC")
except Exception:
return 0.0
total = 0.0
for p in positions or []:
size = abs(float(p.get("size") or 0))
name = str(p.get("instrument") or "").upper()
if name.endswith("-PERPETUAL"):
total += size
else:
mark = float(p.get("mark_price") or 0)
total += size * mark
return total
# --- ACL helper ---
def _check(principal: Principal, *, core: bool = False, observer: bool = False) -> None:
@@ -264,16 +219,17 @@ def _check(principal: Principal, *, core: bool = False, observer: bool = False)
# --- App factory ---
def create_app(*, client: DeribitClient, token_store: TokenStore) -> FastAPI:
def create_app(*, client: DeribitClient, token_store: TokenStore, creds: dict) -> FastAPI:
from contextlib import asynccontextmanager
# CER-016: pre-set leverage 3x su perp principali al boot (best-effort).
cap_default = get_max_leverage(creds)
# CER-016: pre-set leverage cap su perp principali al boot (best-effort).
@asynccontextmanager
async def _lifespan(_app: FastAPI):
cap = enforce_leverage(None)
for inst in ("BTC-PERPETUAL", "ETH-PERPETUAL"):
try:
await client.set_leverage(inst, cap)
await client.set_leverage(inst, cap_default)
except Exception:
pass
yield
@@ -476,15 +432,8 @@ def create_app(*, client: DeribitClient, token_store: TokenStore) -> FastAPI:
body: PlaceOrderReq, principal: Principal = Depends(require_principal)
):
_check(principal, core=True)
lev = enforce_leverage(body.leverage)
if not body.reduce_only:
notional = await _compute_notional_deribit(client, body)
enforce_single_notional(
notional, exchange="deribit", instrument=body.instrument_name
)
agg = await _current_aggregate_deribit(client)
enforce_aggregate(agg, notional)
if lev != enforce_leverage(None):
lev = _enforce_leverage(body.leverage, creds=creds, exchange="deribit")
if lev != cap_default:
try:
await client.set_leverage(body.instrument_name, lev)
except Exception: