"""PROBE CERBERO MCP — quali exchange/fonti serve davvero? (cerca IBKR & alt) Non si fida del commento nel codice: interroga il server v2 (/mcp/tools/get_historical con `exchange=...`) su una matrice di nomi exchange + naming strumento, e riporta chi risponde con candele vere. Cerca in particolare IBKR e Alpaca (spot US reale). uv run python scripts/analysis/cerbero_probe.py """ from __future__ import annotations import sys from pathlib import Path PROJECT_ROOT = Path(__file__).resolve().parents[2] sys.path.insert(0, str(PROJECT_ROOT)) import requests from src.live.cerbero_client import CerberoClient, is_mainnet C = CerberoClient() START, END, INTERVAL = "2026-05-20", "2026-05-27", "1h" # exchange -> naming strumento BTC da provare (varianti) EXCHANGES = { "deribit": ["BTC-PERPETUAL"], "hyperliquid": ["BTC"], "bybit": ["BTCUSDT", "BTC-PERPETUAL", "BTCUSD"], "alpaca": ["BTC/USD", "BTCUSD", "BTC/USDT", "BTC"], "ibkr": ["BTC", "BTC.USD", "BTCUSD"], "interactivebrokers": ["BTC", "BTCUSD"], "binance": ["BTCUSDT", "BTC/USDT", "BTC-PERPETUAL"], "coinbase": ["BTC-USD", "BTC/USD", "BTCUSD"], "kraken": ["XBTUSD", "BTC/USD", "BTCUSD"], "okx": ["BTC-USDT", "BTC-USD-SWAP"], } def try_v2(exchange: str, instrument: str) -> str: try: candles = C.get_historical_v2(instrument, START, END, INTERVAL, exchange=exchange) if candles: c0, c1 = candles[0], candles[-1] return f"OK {len(candles):>4} candele close {c1.get('close')}" return "vuoto (0 candele)" except requests.HTTPError as e: code = e.response.status_code if e.response is not None else "?" return f"HTTP {code}" except Exception as e: return f"{type(e).__name__}: {str(e)[:50]}" def list_tools() -> None: """Tenta di enumerare i tool/endpoint del server (best-effort).""" for path in ("/mcp/tools", "/mcp/tools/list", "/tools", "/mcp"): try: r = requests.post(f"{C.base_url}{path}", headers=C._headers(), json={}, timeout=10) print(f" POST {path:<18} -> HTTP {r.status_code} {str(r.text)[:200]}") except Exception as e: print(f" POST {path:<18} -> {type(e).__name__}: {str(e)[:60]}") def main(): print("=" * 80) print(f" PROBE CERBERO MCP @ {C.base_url} (mainnet={is_mainnet()})") print("=" * 80) print("\n[1] Enumerazione endpoint/tool (best-effort):") list_tools() print(f"\n[2] get_historical_v2 BTC {INTERVAL} {START}->{END} per exchange:") print(f" {'exchange':<20s}{'instrument':<16s}esito") print(" " + "-" * 70) for ex, syms in EXCHANGES.items(): for sym in syms: res = try_v2(ex, sym) print(f" {ex:<20s}{sym:<16s}{res}") if res.startswith("OK"): break # trovato il naming giusto, basta if __name__ == "__main__": main()