Files
Cerbero-mcp/services/mcp-macro/src/mcp_macro/server.py
T
AdrianoDev a13e3fe045 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>
2026-04-27 23:58:07 +02:00

163 lines
5.5 KiB
Python

from __future__ import annotations
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.server import build_app
from pydantic import BaseModel
from mcp_macro.fetchers import (
fetch_asset_price,
fetch_breakeven_inflation,
fetch_economic_indicators,
fetch_equity_futures,
fetch_macro_calendar,
fetch_market_overview,
fetch_treasury_yields,
fetch_yield_curve_slope,
)
# --- Body models ---
class GetEconomicIndicatorsReq(BaseModel):
indicators: list[str] | None = None
class GetMacroCalendarReq(BaseModel):
days: int = 7
country_filter: list[str] | None = None
importance_min: str | None = None
start: str | None = None
end: str | None = None
class GetMarketOverviewReq(BaseModel):
pass
class GetAssetPriceReq(BaseModel):
ticker: str
class GetTreasuryYieldsReq(BaseModel):
pass
class GetEquityFuturesReq(BaseModel):
pass
class GetYieldCurveSlopeReq(BaseModel):
pass
class GetBreakevenInflationReq(BaseModel):
pass
# --- ACL helper ---
def _check(principal: Principal, *, core: bool = False, observer: bool = False) -> None:
allowed: set[str] = set()
if core:
allowed.add("core")
if observer:
allowed.add("observer")
if not (principal.capabilities & allowed):
raise HTTPException(403, f"capability required: {allowed}")
# --- App factory ---
def create_app(*, fred_api_key: str = "", finnhub_api_key: str = "", token_store: TokenStore) -> FastAPI:
app = build_app(name="mcp-macro", version="0.1.0", token_store=token_store)
@app.post("/tools/get_economic_indicators", tags=["reads"])
async def t_get_economic_indicators(
body: GetEconomicIndicatorsReq, principal: Principal = Depends(require_principal)
):
_check(principal, core=True, observer=True)
return await fetch_economic_indicators(
fred_api_key=fred_api_key, indicators=body.indicators
)
@app.post("/tools/get_macro_calendar", tags=["reads"])
async def t_get_macro_calendar(
body: GetMacroCalendarReq, principal: Principal = Depends(require_principal)
):
_check(principal, core=True, observer=True)
return await fetch_macro_calendar(
finnhub_api_key=finnhub_api_key,
days_ahead=body.days,
country_filter=body.country_filter,
importance_min=body.importance_min,
start=body.start,
end=body.end,
)
@app.post("/tools/get_market_overview", tags=["reads"])
async def t_get_market_overview(
body: GetMarketOverviewReq, principal: Principal = Depends(require_principal)
):
_check(principal, core=True, observer=True)
return await fetch_market_overview()
@app.post("/tools/get_asset_price", tags=["reads"])
async def t_get_asset_price(
body: GetAssetPriceReq, principal: Principal = Depends(require_principal)
):
_check(principal, core=True, observer=True)
return await fetch_asset_price(body.ticker)
@app.post("/tools/get_treasury_yields", tags=["reads"])
async def t_get_treasury_yields(
body: GetTreasuryYieldsReq, principal: Principal = Depends(require_principal)
):
_check(principal, core=True, observer=True)
return await fetch_treasury_yields()
@app.post("/tools/get_equity_futures", tags=["reads"])
async def t_get_equity_futures(
body: GetEquityFuturesReq, principal: Principal = Depends(require_principal)
):
_check(principal, core=True, observer=True)
return await fetch_equity_futures()
@app.post("/tools/get_yield_curve_slope", tags=["reads"])
async def t_get_yield_curve_slope(
body: GetYieldCurveSlopeReq, principal: Principal = Depends(require_principal)
):
_check(principal, core=True, observer=True)
return await fetch_yield_curve_slope()
@app.post("/tools/get_breakeven_inflation", tags=["reads"])
async def t_get_breakeven_inflation(
body: GetBreakevenInflationReq, principal: Principal = Depends(require_principal)
):
_check(principal, core=True, observer=True)
return await fetch_breakeven_inflation(fred_api_key=fred_api_key)
# ───── MCP endpoint (/mcp) — bridge verso /tools/* ─────
port = int(os.environ.get("PORT", "9013"))
mount_mcp_endpoint(
app,
name="cerbero-macro",
version="0.1.0",
token_store=token_store,
internal_base_url=f"http://localhost:{port}",
tools=[
{"name": "get_economic_indicators", "description": "FRED economic indicators (Fed rate, CPI, ecc)."},
{"name": "get_macro_calendar", "description": "Eventi macro con filtri country/importance/date range."},
{"name": "get_market_overview", "description": "Snapshot overview mercato macro."},
{"name": "get_asset_price", "description": "Prezzo cross-asset: WTI, DXY, SPX, VIX, yields, FX, ecc."},
{"name": "get_treasury_yields", "description": "Curva US Treasury 2y/5y/10y/30y + shape detection."},
{"name": "get_equity_futures", "description": "Futures ES/NQ/YM/RTY con session status."},
{"name": "get_yield_curve_slope", "description": "Slope 2y10y/5y30y + butterfly + regime (steep/normal/flat/inverted)."},
{"name": "get_breakeven_inflation", "description": "Breakeven inflation 5Y/10Y + 5y5y forward (FRED T5YIE/T10YIE/T5YIFR)."},
],
)
return app