bd6b03ce43
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
338 lines
11 KiB
Python
338 lines
11 KiB
Python
"""Router /mcp-deribit/* — DI per env, client e (write) creds.
|
|
|
|
Mappa 1:1 i tool di `cerbero_mcp.exchanges.deribit.tools` a endpoint
|
|
`POST /mcp-deribit/tools/{tool_name}`. L'autenticazione bearer è gestita
|
|
dal middleware in `cerbero_mcp.auth`; qui leggiamo solo `request.state.environment`.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Literal, cast
|
|
|
|
from fastapi import APIRouter, Depends, Request
|
|
|
|
from cerbero_mcp.client_registry import ClientRegistry
|
|
from cerbero_mcp.common.audit_helpers import audit_call
|
|
from cerbero_mcp.exchanges.deribit import tools as t
|
|
from cerbero_mcp.exchanges.deribit.client import DeribitClient
|
|
|
|
Environment = Literal["testnet", "mainnet"]
|
|
|
|
|
|
def get_environment(request: Request) -> Environment:
|
|
return cast(Environment, request.state.environment)
|
|
|
|
|
|
async def get_deribit_client(
|
|
request: Request, env: Environment = Depends(get_environment)
|
|
) -> DeribitClient:
|
|
registry: ClientRegistry = request.app.state.registry
|
|
return cast(DeribitClient, await registry.get("deribit", env))
|
|
|
|
|
|
def _build_creds(request: Request) -> dict:
|
|
"""Costruisce dict `creds` minimale per leverage cap / metadata.
|
|
|
|
Le credenziali vere sono già iniettate nel client da ClientRegistry;
|
|
qui passiamo solo il cap di leverage e il client_id (metadata audit).
|
|
"""
|
|
settings = request.app.state.settings
|
|
return {
|
|
"max_leverage": settings.deribit.max_leverage,
|
|
"client_id": settings.deribit.client_id,
|
|
}
|
|
|
|
|
|
def make_router() -> APIRouter:
|
|
r = APIRouter(prefix="/mcp-deribit", tags=["deribit"])
|
|
|
|
# === READ tools ===
|
|
|
|
@r.post("/tools/is_testnet")
|
|
async def _is_testnet(client: DeribitClient = Depends(get_deribit_client)):
|
|
return await t.is_testnet(client)
|
|
|
|
@r.post("/tools/environment_info")
|
|
async def _environment_info(
|
|
request: Request,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
creds = _build_creds(request)
|
|
return await t.environment_info(client, creds=creds)
|
|
|
|
@r.post("/tools/get_ticker")
|
|
async def _get_ticker(
|
|
params: t.GetTickerReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_ticker(client, params)
|
|
|
|
@r.post("/tools/get_ticker_batch")
|
|
async def _get_ticker_batch(
|
|
params: t.GetTickerBatchReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_ticker_batch(client, params)
|
|
|
|
@r.post("/tools/get_instruments")
|
|
async def _get_instruments(
|
|
params: t.GetInstrumentsReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_instruments(client, params)
|
|
|
|
@r.post("/tools/get_orderbook")
|
|
async def _get_orderbook(
|
|
params: t.GetOrderbookReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_orderbook(client, params)
|
|
|
|
@r.post("/tools/get_orderbook_imbalance")
|
|
async def _get_orderbook_imbalance(
|
|
params: t.OrderbookImbalanceReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_orderbook_imbalance(client, params)
|
|
|
|
@r.post("/tools/get_positions")
|
|
async def _get_positions(
|
|
params: t.GetPositionsReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_positions(client, params)
|
|
|
|
@r.post("/tools/get_account_summary")
|
|
async def _get_account_summary(
|
|
params: t.GetAccountSummaryReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_account_summary(client, params)
|
|
|
|
@r.post("/tools/get_trade_history")
|
|
async def _get_trade_history(
|
|
params: t.GetTradeHistoryReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_trade_history(client, params)
|
|
|
|
@r.post("/tools/get_historical")
|
|
async def _get_historical(
|
|
params: t.GetHistoricalReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_historical(client, params)
|
|
|
|
@r.post("/tools/get_dvol")
|
|
async def _get_dvol(
|
|
params: t.GetDvolReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_dvol(client, params)
|
|
|
|
@r.post("/tools/get_gex")
|
|
async def _get_gex(
|
|
params: t.GetGexReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_gex(client, params)
|
|
|
|
@r.post("/tools/get_dealer_gamma_profile")
|
|
async def _get_dealer_gamma_profile(
|
|
params: t.OptionFlowReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_dealer_gamma_profile(client, params)
|
|
|
|
@r.post("/tools/get_vanna_charm")
|
|
async def _get_vanna_charm(
|
|
params: t.OptionFlowReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_vanna_charm(client, params)
|
|
|
|
@r.post("/tools/get_oi_weighted_skew")
|
|
async def _get_oi_weighted_skew(
|
|
params: t.OptionFlowReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_oi_weighted_skew(client, params)
|
|
|
|
@r.post("/tools/get_smile_asymmetry")
|
|
async def _get_smile_asymmetry(
|
|
params: t.OptionFlowReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_smile_asymmetry(client, params)
|
|
|
|
@r.post("/tools/get_atm_vs_wings_vol")
|
|
async def _get_atm_vs_wings_vol(
|
|
params: t.OptionFlowReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_atm_vs_wings_vol(client, params)
|
|
|
|
@r.post("/tools/get_pc_ratio")
|
|
async def _get_pc_ratio(
|
|
params: t.GetPcRatioReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_pc_ratio(client, params)
|
|
|
|
@r.post("/tools/get_skew_25d")
|
|
async def _get_skew_25d(
|
|
params: t.GetSkew25dReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_skew_25d(client, params)
|
|
|
|
@r.post("/tools/get_term_structure")
|
|
async def _get_term_structure(
|
|
params: t.GetTermStructureReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_term_structure(client, params)
|
|
|
|
@r.post("/tools/run_backtest")
|
|
async def _run_backtest(
|
|
params: t.RunBacktestReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.run_backtest(client, params)
|
|
|
|
@r.post("/tools/calculate_spread_payoff")
|
|
async def _calculate_spread_payoff(
|
|
params: t.CalculateSpreadPayoffReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.calculate_spread_payoff(client, params)
|
|
|
|
@r.post("/tools/find_by_delta")
|
|
async def _find_by_delta(
|
|
params: t.FindByDeltaReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.find_by_delta(client, params)
|
|
|
|
@r.post("/tools/get_iv_rank")
|
|
async def _get_iv_rank(
|
|
params: t.GetIvRankReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_iv_rank(client, params)
|
|
|
|
@r.post("/tools/get_dvol_history")
|
|
async def _get_dvol_history(
|
|
params: t.GetDvolHistoryReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_dvol_history(client, params)
|
|
|
|
@r.post("/tools/get_realized_vol")
|
|
async def _get_realized_vol(
|
|
params: t.GetRealizedVolReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_realized_vol(client, params)
|
|
|
|
@r.post("/tools/get_technical_indicators")
|
|
async def _get_technical_indicators(
|
|
params: t.GetIndicatorsReq,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await t.get_technical_indicators(client, params)
|
|
|
|
# === WRITE tools (richiedono creds per leverage cap / audit) ===
|
|
|
|
@r.post("/tools/place_order")
|
|
async def _place_order(
|
|
params: t.PlaceOrderReq,
|
|
request: Request,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
creds = _build_creds(request)
|
|
return await audit_call(
|
|
request=request,
|
|
exchange="deribit",
|
|
action="place_order",
|
|
target_field="instrument_name",
|
|
params=params,
|
|
tool_fn=lambda: t.place_order(client, params, creds=creds),
|
|
)
|
|
|
|
@r.post("/tools/place_combo_order")
|
|
async def _place_combo_order(
|
|
params: t.PlaceComboOrderReq,
|
|
request: Request,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
creds = _build_creds(request)
|
|
return await audit_call(
|
|
request=request,
|
|
exchange="deribit",
|
|
action="place_combo_order",
|
|
params=params,
|
|
tool_fn=lambda: t.place_combo_order(client, params, creds=creds),
|
|
)
|
|
|
|
@r.post("/tools/cancel_order")
|
|
async def _cancel_order(
|
|
params: t.CancelOrderReq,
|
|
request: Request,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await audit_call(
|
|
request=request,
|
|
exchange="deribit",
|
|
action="cancel_order",
|
|
target_field="order_id",
|
|
params=params,
|
|
tool_fn=lambda: t.cancel_order(client, params),
|
|
)
|
|
|
|
@r.post("/tools/set_stop_loss")
|
|
async def _set_stop_loss(
|
|
params: t.SetStopLossReq,
|
|
request: Request,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await audit_call(
|
|
request=request,
|
|
exchange="deribit",
|
|
action="set_stop_loss",
|
|
target_field="order_id",
|
|
params=params,
|
|
tool_fn=lambda: t.set_stop_loss(client, params),
|
|
)
|
|
|
|
@r.post("/tools/set_take_profit")
|
|
async def _set_take_profit(
|
|
params: t.SetTakeProfitReq,
|
|
request: Request,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await audit_call(
|
|
request=request,
|
|
exchange="deribit",
|
|
action="set_take_profit",
|
|
target_field="order_id",
|
|
params=params,
|
|
tool_fn=lambda: t.set_take_profit(client, params),
|
|
)
|
|
|
|
@r.post("/tools/close_position")
|
|
async def _close_position(
|
|
params: t.ClosePositionReq,
|
|
request: Request,
|
|
client: DeribitClient = Depends(get_deribit_client),
|
|
):
|
|
return await audit_call(
|
|
request=request,
|
|
exchange="deribit",
|
|
action="close_position",
|
|
target_field="instrument_name",
|
|
params=params,
|
|
tool_fn=lambda: t.close_position(client, params),
|
|
)
|
|
|
|
return r
|