feat: 15 nuovi indicatori quant (common + deribit + bybit + macro + sentiment)
Common (mcp_common): - indicators.py: vol_cone, hurst_exponent, half_life_mean_reversion, garch11_forecast, autocorrelation, rolling_sharpe, var_cvar - options.py (nuovo): oi_weighted_skew, smile_asymmetry, atm_vs_wings_vol, dealer_gamma_profile, vanna_charm_aggregate - microstructure.py (nuovo): orderbook_imbalance (ratio + microprice + slope) - stats.py (nuovo): cointegration_test Engle-Granger + ADF helper Deribit (+6 tool MCP): - get_dealer_gamma_profile (net dealer gamma + flip level) - get_vanna_charm (vanna/charm aggregati pesati OI) - get_oi_weighted_skew, get_smile_asymmetry, get_atm_vs_wings_vol - get_orderbook_imbalance Bybit (+2 tool MCP): - get_orderbook_imbalance, get_basis_term_structure (futures dated curve) Macro (+2 tool MCP): - get_yield_curve_slope (2y10y/5y30y + butterfly + regime) - get_breakeven_inflation (FRED T5YIE/T10YIE/T5YIFR) Sentiment (+3 tool MCP): - get_funding_arb_spread (opportunità arb compatte annualizzate) - get_liquidation_heatmap (heuristic da OI delta + funding extreme, no feed paid Coinglass) - get_cointegration_pairs (Engle-Granger su coppie crypto Binance hourly) Tutto in TDD pure-Python (no numpy/scipy in mcp_common). README aggiornato con elenco completo. 442 test totali verdi. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -62,6 +62,11 @@ class GetOrderbookReq(BaseModel):
|
||||
depth: int = 10
|
||||
|
||||
|
||||
class OrderbookImbalanceReq(BaseModel):
|
||||
instrument_name: str
|
||||
depth: int = 10
|
||||
|
||||
|
||||
class GetPositionsReq(BaseModel):
|
||||
currency: str = "USDC"
|
||||
|
||||
@@ -110,6 +115,15 @@ class GetGexReq(BaseModel):
|
||||
top_n_strikes: int = 50
|
||||
|
||||
|
||||
class OptionFlowReq(BaseModel):
|
||||
"""Body comune per indicatori option-flow (dealer gamma, vanna/charm,
|
||||
OI-weighted skew, smile asymmetry, ATM vs wings)."""
|
||||
currency: str
|
||||
expiry_from: str | None = None
|
||||
expiry_to: str | None = None
|
||||
top_n_strikes: int = 100
|
||||
|
||||
|
||||
class GetPcRatioReq(BaseModel):
|
||||
currency: str
|
||||
|
||||
@@ -336,6 +350,13 @@ def create_app(
|
||||
_check(principal, core=True, observer=True)
|
||||
return await client.get_orderbook(body.instrument_name, body.depth)
|
||||
|
||||
@app.post("/tools/get_orderbook_imbalance", tags=["reads"])
|
||||
async def t_get_ob_imbalance(
|
||||
body: OrderbookImbalanceReq, principal: Principal = Depends(require_principal)
|
||||
):
|
||||
_check(principal, core=True, observer=True)
|
||||
return await client.get_orderbook_imbalance(body.instrument_name, body.depth)
|
||||
|
||||
@app.post("/tools/get_positions", tags=["reads"])
|
||||
async def t_get_positions(
|
||||
body: GetPositionsReq, principal: Principal = Depends(require_principal)
|
||||
@@ -384,6 +405,51 @@ def create_app(
|
||||
body.currency, body.expiry_from, body.expiry_to, body.top_n_strikes
|
||||
)
|
||||
|
||||
@app.post("/tools/get_dealer_gamma_profile", tags=["reads"])
|
||||
async def t_get_dealer_gamma_profile(
|
||||
body: OptionFlowReq, principal: Principal = Depends(require_principal)
|
||||
):
|
||||
_check(principal, core=True, observer=True)
|
||||
return await client.get_dealer_gamma_profile(
|
||||
body.currency, body.expiry_from, body.expiry_to, body.top_n_strikes
|
||||
)
|
||||
|
||||
@app.post("/tools/get_vanna_charm", tags=["reads"])
|
||||
async def t_get_vanna_charm(
|
||||
body: OptionFlowReq, principal: Principal = Depends(require_principal)
|
||||
):
|
||||
_check(principal, core=True, observer=True)
|
||||
return await client.get_vanna_charm(
|
||||
body.currency, body.expiry_from, body.expiry_to, body.top_n_strikes
|
||||
)
|
||||
|
||||
@app.post("/tools/get_oi_weighted_skew", tags=["reads"])
|
||||
async def t_get_oi_weighted_skew(
|
||||
body: OptionFlowReq, principal: Principal = Depends(require_principal)
|
||||
):
|
||||
_check(principal, core=True, observer=True)
|
||||
return await client.get_oi_weighted_skew(
|
||||
body.currency, body.expiry_from, body.expiry_to, body.top_n_strikes
|
||||
)
|
||||
|
||||
@app.post("/tools/get_smile_asymmetry", tags=["reads"])
|
||||
async def t_get_smile_asymmetry(
|
||||
body: OptionFlowReq, principal: Principal = Depends(require_principal)
|
||||
):
|
||||
_check(principal, core=True, observer=True)
|
||||
return await client.get_smile_asymmetry(
|
||||
body.currency, body.expiry_from, body.expiry_to, body.top_n_strikes
|
||||
)
|
||||
|
||||
@app.post("/tools/get_atm_vs_wings_vol", tags=["reads"])
|
||||
async def t_get_atm_vs_wings_vol(
|
||||
body: OptionFlowReq, principal: Principal = Depends(require_principal)
|
||||
):
|
||||
_check(principal, core=True, observer=True)
|
||||
return await client.get_atm_vs_wings_vol(
|
||||
body.currency, body.expiry_from, body.expiry_to, body.top_n_strikes
|
||||
)
|
||||
|
||||
@app.post("/tools/get_pc_ratio", tags=["reads"])
|
||||
async def t_get_pc_ratio(
|
||||
body: GetPcRatioReq, principal: Principal = Depends(require_principal)
|
||||
@@ -563,6 +629,7 @@ def create_app(
|
||||
{"name": "get_ticker_batch", "description": "Ticker per N instruments in parallelo (max 20)."},
|
||||
{"name": "get_instruments", "description": "Lista instruments per currency."},
|
||||
{"name": "get_orderbook", "description": "Orderbook L1/L2 per instrument."},
|
||||
{"name": "get_orderbook_imbalance", "description": "Microstructure: imbalance ratio + microprice + slope."},
|
||||
{"name": "get_positions", "description": "Posizioni aperte."},
|
||||
{"name": "get_account_summary", "description": "Summary account (equity, balance)."},
|
||||
{"name": "get_trade_history", "description": "Storia trade recenti."},
|
||||
@@ -577,6 +644,11 @@ def create_app(
|
||||
{"name": "get_skew_25d", "description": "Skew 25-delta put/call IV + risk reversal + butterfly per expiry."},
|
||||
{"name": "get_pc_ratio", "description": "Put/Call ratio aggregato su OI e volume 24h."},
|
||||
{"name": "get_gex", "description": "Gamma exposure per strike + zero gamma level (top N strikes per OI)."},
|
||||
{"name": "get_dealer_gamma_profile", "description": "Net dealer gamma per strike (short calls/long puts) + gamma flip level."},
|
||||
{"name": "get_vanna_charm", "description": "Vanna (∂delta/∂IV) e Charm (∂delta/∂t) aggregati pesati OI."},
|
||||
{"name": "get_oi_weighted_skew", "description": "Skew aggregato pesato per OI: IV puts - IV calls. Positivo = paura."},
|
||||
{"name": "get_smile_asymmetry", "description": "Asymmetry IV otm-puts vs otm-calls + ATM IV reference."},
|
||||
{"name": "get_atm_vs_wings_vol", "description": "IV ATM vs IV ali 25-delta. wing_richness > 0 = smile/kurtosis."},
|
||||
{"name": "get_technical_indicators", "description": "Indicatori tecnici (RSI, MACD, ATR, ADX)."},
|
||||
{"name": "get_realized_vol", "description": "Volatilità realizzata annualizzata (log-return std) BTC/ETH + spread IV−RV."},
|
||||
{"name": "place_order", "description": "Invia ordine (CORE only, testnet)."},
|
||||
|
||||
Reference in New Issue
Block a user