Files
PythagorasGoal/Old/docs/specs/2026-05-27-multi-strategy-paper-trader.md
T
Adriano Dal Pastro 14522262e6 chore(reset): v2.0.0 — storico certificato Deribit mainnet, ripartenza pulita
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>
2026-06-19 15:20:59 +00:00

5.0 KiB

Multi-Strategy Paper Trader — Design Spec

Obiettivo

Eseguire N strategie di trading in parallelo su Deribit testnet (paper trading locale), ognuna con capitale virtuale indipendente di €1000 USDC. Lo storico trade di ogni strategia persiste tra restart. Nuove strategie aggiungibili in corso d'opera via config YAML senza perdere lo storico delle esistenti.

Architettura

Un singolo container Docker esegue un orchestratore (MultiStrategyRunner) che gestisce N StrategyWorker. Ogni worker è indipendente: proprio capital, propri trade, proprio stato.

Docker Container
├── MultiStrategyRunner (orchestratore, loop principale)
│   ├── StrategyWorker[SQ02_BTC_15m] → paper trade → JSONL
│   ├── StrategyWorker[ML01_ETH_15m] → paper trade → JSONL
│   └── ...altri worker da YAML
├── CerberoClient (condiviso, fetch prezzi)
└── TelegramNotifier (condiviso)

Componenti

1. strategies.yml — Configurazione

defaults:
  capital: 1000
  position_size: 0.15
  leverage: 3
  hold_bars: 3
  poll_seconds: 60
  retrain_hours: 24

strategies:
  - name: SQ02_antifake_vol
    asset: BTC
    tf: 15m
    enabled: true

  - name: SQ02_antifake_vol
    asset: ETH
    tf: 15m
    enabled: true

  - name: ML01_squeeze_gbm
    asset: ETH
    tf: 15m
    enabled: true
    position_size: 0.20
    params:
      ml_threshold: 0.70
      bb_window: 14
      sq_threshold: 0.8

Ogni entry eredita defaults. Override per-strategia possibile su tutti i campi. Il campo params passa kwargs a generate_signals() o al backtest ML.

2. StrategyWorker — Worker per singola strategia

Responsabilità:

  • Importa la classe Strategy corrispondente da scripts/strategies/
  • Mantiene stato: capital, posizione aperta, equity
  • Al startup: ricarica status.json se esiste (resume), altrimenti inizia da zero
  • Ad ogni tick: riceve DataFrame candele, genera segnali, paper-trade
  • Logga ogni evento in trades.jsonl (append-only)
  • Aggiorna status.json ad ogni tick

Stato persistente (status.json):

{
  "capital": 1023.45,
  "in_position": true,
  "direction": "long",
  "entry_price": 2534.20,
  "entry_time": "2026-05-27T14:30:00Z",
  "bars_held": 1,
  "total_trades": 15,
  "total_wins": 12,
  "started_at": "2026-05-27T10:00:00Z"
}

Trade log (trades.jsonl), append-only:

{"ts": "2026-05-27T14:30:00Z", "event": "OPEN", "direction": "long", "price": 2534.20, "size": 0.18, "capital": 1023.45}
{"ts": "2026-05-27T15:15:00Z", "event": "CLOSE", "reason": "hold_limit", "entry": 2534.20, "exit": 2560.10, "pnl": 3.45, "fee": 0.92, "net_pnl": 2.53, "capital": 1025.98}

3. MultiStrategyRunner — Orchestratore

Loop principale:

  1. Carica strategies.yml
  2. Per ogni entry, crea StrategyWorker (o riprende se già esiste)
  3. Ogni 60s: a. Fetch candele live da Cerbero (una volta per asset/tf unico) b. Passa DataFrame a ogni worker c. Ogni worker valuta segnali e gestisce posizione d. Worker ML: retrain ogni 24h
  4. Notifica Telegram per ogni trade

Ottimizzazione: fetch candele raggruppato per (asset, tf). Se 3 strategie usano BTC 15m, fetch una volta sola.

4. Persistenza

data/paper_trades/
  SQ02_antifake_vol__BTC__15m/
    trades.jsonl
    status.json
  SQ02_antifake_vol__ETH__15m/
    trades.jsonl
    status.json
  ML01_squeeze_gbm__ETH__15m/
    trades.jsonl
    status.json

Directory naming: {strategy_name}__{asset}__{tf} con double underscore separatore.

Volume Docker: ./data:/app/data — persiste tra restart.

5. Aggiunta strategia in corso

  1. Aggiungi entry in strategies.yml
  2. docker compose restart
  3. Runner carica YAML, trova nuova entry senza status.json → parte da €1000
  4. Strategie esistenti riprendono da status.json → storico intatto

6. Docker

Dockerfile — invariato, aggiunge strategies.yml alla COPY.

docker-compose.yml:

services:
  paper-trader:
    build: .
    container_name: pythagoras-multi
    restart: unless-stopped
    volumes:
      - ./data:/app/data
      - ./strategies.yml:/app/strategies.yml:ro
    env_file:
      - .env
    environment:
      - PYTHONUNBUFFERED=1

CMD cambia a: uv run python -m src.live.multi_runner

7. Strategia-specifica: ML01

ML01 richiede training del modello GBM. Il worker ML01:

  • Al primo avvio: train su storico (365 giorni via Cerbero)
  • Ogni retrain_hours: retrain
  • Usa SignalEngine esistente per check_signal()
  • Le strategie SQ* non hanno training — solo regole deterministiche

8. File da creare/modificare

Nuovi:

  • src/live/multi_runner.py — orchestratore
  • src/live/strategy_worker.py — worker per singola strategia
  • strategies.yml — config
  • src/live/strategy_loader.py — import dinamico classi Strategy

Modifiche:

  • docker-compose.yml — nuovo CMD, volume strategies.yml
  • Dockerfile — COPY strategies.yml

Invariati:

  • src/live/cerbero_client.py
  • src/live/telegram_notifier.py
  • src/live/signal_engine.py (usato da ML01 worker)