refactor(data): replace ccxt OHLCV loader with CerberoOHLCVLoader (deribit default)
Cerbero MCP diventa unica fonte di verità per dati di mercato Phase 1.
Il nuovo CerberoOHLCVLoader chiama mcp-{exchange}/tools/get_historical
con shape per-exchange (deribit/bybit/hyperliquid) e parser difensivo
sulla risposta (object-of-records, array-of-arrays, raw list).
- src/multi_swarm/data/cerbero_ohlcv.py (nuovo) con OHLCVRequest +
CerberoOHLCVLoader, cache parquet via SHA1 della request
- tests/unit/test_cerbero_ohlcv.py (nuovo, 5 test, CerberoClient mockato)
- src/multi_swarm/data/ohlcv_loader.py + test ccxt rimossi
- scripts/run_phase1.py: costruisce CerberoClient, --exchange CLI arg,
default --symbol BTC-PERPETUAL (formato Deribit)
- pyproject.toml: rimosso ccxt>=4.4 (uv sync ha rimosso 16 transitivi)
- .env.example: CERBERO_BASE_URL=https://cerbero-mcp.tielogic.xyz +
nota su MAINNET vs TESTNET token
Schema confermato via OpenAPI di Cerbero (instrument/start_date/end_date
+ resolution opzionale). Forma della risposta non garantita dallo schema:
parser difensivo prova candles/data/result/ohlcv/klines/bars e segnala
errore chiaro se nessuna shape combacia. Live verification skippata
(nessun token in .env).
Paginazione non ancora implementata: si assume che get_historical paginI
internamente. Da rivedere se una live call mostra cap (~1000 candele).
Test: 122 passed (era 122 con 2 ccxt + 0 cerbero, ora 0 ccxt + 5 cerbero,
delta netto +3, ma 2 test ga_loop preesistenti rimossi in altro commit
mantenevano il totale a 122).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+21
-3
@@ -3,8 +3,9 @@ from __future__ import annotations
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
|
||||
from multi_swarm.cerbero.client import CerberoClient
|
||||
from multi_swarm.config import load_settings
|
||||
from multi_swarm.data.ohlcv_loader import OHLCVLoader, OHLCVRequest
|
||||
from multi_swarm.data.cerbero_ohlcv import CerberoOHLCVLoader, OHLCVRequest
|
||||
from multi_swarm.genome.hypothesis import ModelTier
|
||||
from multi_swarm.llm.client import LLMClient
|
||||
from multi_swarm.orchestrator.run import RunConfig, run_phase1
|
||||
@@ -19,7 +20,12 @@ def parse_args() -> argparse.Namespace:
|
||||
p.add_argument("--tournament-k", type=int, default=3)
|
||||
p.add_argument("--p-crossover", type=float, default=0.5)
|
||||
p.add_argument("--seed", type=int, default=42)
|
||||
p.add_argument("--symbol", default="BTC/USDT")
|
||||
p.add_argument(
|
||||
"--exchange",
|
||||
default="deribit",
|
||||
choices=["deribit", "bybit", "hyperliquid"],
|
||||
)
|
||||
p.add_argument("--symbol", default="BTC-PERPETUAL")
|
||||
p.add_argument("--timeframe", default="1h")
|
||||
p.add_argument("--start", default="2024-01-01T00:00:00+00:00")
|
||||
p.add_argument("--end", default="2026-01-01T00:00:00+00:00")
|
||||
@@ -32,12 +38,24 @@ def main() -> None:
|
||||
args = parse_args()
|
||||
settings = load_settings()
|
||||
|
||||
loader = OHLCVLoader(cache_dir=settings.series_dir)
|
||||
token = (
|
||||
settings.cerbero_mainnet_token.get_secret_value()
|
||||
if settings.cerbero_mainnet_token
|
||||
else settings.cerbero_testnet_token.get_secret_value()
|
||||
)
|
||||
cerbero = CerberoClient(
|
||||
base_url=settings.cerbero_base_url,
|
||||
token=token,
|
||||
bot_tag=settings.cerbero_bot_tag,
|
||||
)
|
||||
|
||||
loader = CerberoOHLCVLoader(client=cerbero, cache_dir=settings.series_dir)
|
||||
req = OHLCVRequest(
|
||||
symbol=args.symbol,
|
||||
timeframe=args.timeframe,
|
||||
start=datetime.fromisoformat(args.start),
|
||||
end=datetime.fromisoformat(args.end),
|
||||
exchange=args.exchange,
|
||||
)
|
||||
ohlcv = loader.load(req)
|
||||
print(f"OHLCV loaded: {len(ohlcv)} bars from {ohlcv.index[0]} to {ohlcv.index[-1]}")
|
||||
|
||||
Reference in New Issue
Block a user