- src/live/multi_runner.py: orchestratore con fetch raggruppato per asset/tf - src/live/strategy_worker.py: worker indipendente con stato persistente JSONL - src/live/strategy_loader.py: import dinamico classi Strategy - strategies.yml: config dichiarativa con defaults e override per strategia - Docker: container unico, strategies.yml montato come volume read-only - Supporta hot-add: aggiungi riga YAML + restart, storico intatto - Ogni strategia: €1000 USDC virtuale, equity tracking, Telegram notify Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.jsonse 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.jsonad 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:
- Carica
strategies.yml - Per ogni entry, crea
StrategyWorker(o riprende se già esiste) - 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
- 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
- Aggiungi entry in
strategies.yml docker compose restart- Runner carica YAML, trova nuova entry senza
status.json→ parte da €1000 - 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
SignalEngineesistente per check_signal() - Le strategie SQ* non hanno training — solo regole deterministiche
8. File da creare/modificare
Nuovi:
src/live/multi_runner.py— orchestratoresrc/live/strategy_worker.py— worker per singola strategiastrategies.yml— configsrc/live/strategy_loader.py— import dinamico classi Strategy
Modifiche:
docker-compose.yml— nuovo CMD, volume strategies.ymlDockerfile— COPY strategies.yml
Invariati:
src/live/cerbero_client.pysrc/live/telegram_notifier.pysrc/live/signal_engine.py(usato da ML01 worker)