14522262e6
Reset del progetto su fondamenta verificate dopo la scoperta che l'intera libreria "validata OOS" era artefatto di feed contaminato (print fantasma del feed Cerbero TESTNET + storico Binance/USDT). - Storico ricostruito da Deribit MAINNET (ccxt pubblico, tokenless) e CERTIFICATO (certify_feed.py): BTC/ETH puliti su TUTTA la storia (mediana 2-6 bps vs Coinbase USD), integrita' OHLC + coerenza resample (maxΔ 0.00) + cross-venue OK. Alt esclusi (illiquidi/divergenti: LTC/DOGE 50-82% barre flat; XRP/BNB non certificabili). - Verdetto sul feed pulito: FADE / PAIRS / XS01 / TSM01 morti (ogni portafoglio Sharpe -2.3..-3.0, DD ~40%); solo SH01 e frammenti HONEST con segnale residuo, da ri-validare in isolamento. - Cleanup "restart pulito": strategie, stack live (src/live, src/portfolio, runner/executor, yml, docker), ~100 script ricerca/gate, waste/games/ portfolios, dati non certificati + cache e 60+ diari -> archiviati in Old/ (preservati, non cancellati). Diario consolidato in un unico documento. - Skeleton ricerca tenuto: Strategy ABC + indicatori + src/fractal + src/backtest/engine + load_data; tool dati certificati (rebuild_history, certify_feed, audit_feed, multi_source_check). - Universo dati ATTIVO: solo BTC/ETH (5m/15m/1h); guardrail fisico (load_data su alt -> FileNotFoundError). Esecuzione DISABILITATA, conto flat. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
78 lines
2.9 KiB
Python
78 lines
2.9 KiB
Python
"""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()
|