Files
PythagorasGoal/CLAUDE.md
Adriano Dal Pastro 48435f6858 feat(live): worker con exit TP/SL/max_bars per MR01 + doc aggiornata
StrategyWorker ora supporta exit guidati dalla strategia via Signal.metadata
(take-profit alla media / stop-loss ad ATR / time-limit), con fallback al
vecchio hold_bars/stop -2% per strategie senza metadata. Usa fee_rt della
strategia (MR01 = 0.10% RT reale Deribit, non piu' 0.20% hardcoded).
Persistenza di tp/sl/max_bars in status.json per resume.

Re-validato col worker reale (replay finestre mobili 1h, fee 0.10%):
  BTC 1h MR01: +196% OOS, ETH 1h: +251% OOS (nov 2023->mag 2026) — coerente col backtest.

README + CLAUDE.md riscritti: squeeze = artefatto di look-ahead -> waste,
MR01 mean-reversion unica attiva, metodologia anti-look-ahead e fee reali 0.10% RT.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 20:46:35 +00:00

8.4 KiB
Raw Permalink Blame History

PythagorasGoal — Istruzioni per agenti

Panoramica

Progetto di ricerca: riconoscimento pattern frattali per trading algoritmico su criptovalute (BTC, ETH). L'obiettivo è arrivare a €50/giorno di profitto partendo da €1.000, entro 68 mesi.

Stack

  • Linguaggio: Python 3.11+
  • Package manager: uv (dipendenze in pyproject.toml, lock in uv.lock)
  • Dati: Parquet in data/raw/ (non committati, ~70 MB)
  • ML: scikit-learn (GradientBoostingClassifier)
  • Analisi: numpy, pandas, scipy
  • API dati: Cerbero MCP su cerbero-mcp.tielogic.xyz (Deribit, Bybit, Hyperliquid), ccxt/Binance come fallback
  • Config: pyyaml per strategies.yml

Struttura

src/data/              → download e caricamento dati (downloader.py)
src/fractal/           → indicatori frattali (patterns.py, indicators.py, similarity.py)
src/backtest/          → engine di backtesting (engine.py)
src/strategies/        → classe base Strategy ABC + indicatori condivisi
  base.py              → Strategy, Signal, BacktestResult, YearlyStats
  indicators.py        → keltner_ratio, detect_squeezes, ema, atr, rv, correlation
src/live/              → paper trading live multi-strategia
  multi_runner.py      → orchestratore: carica YAML, fetch candele, tick worker
  strategy_worker.py   → worker indipendente: capital, trade log, stato persistente.
                         Exit guidati da strategia (TP/SL/max_bars via Signal.metadata),
                         fallback hold_bars/stop -2%. Usa fee_rt della strategia.
  strategy_loader.py   → import dinamico classi Strategy da scripts/strategies/
  cerbero_client.py    → client HTTP per Cerbero MCP (Deribit testnet)
  signal_engine.py     → squeeze + ML real-time (legacy ML01, ora in waste) + validazione OOS
  telegram_notifier.py → notifiche Telegram per trade
scripts/strategies/    → strategie con edge validato OOS (solo MR01_bollinger_fade)
scripts/waste/         → strategie scartate (W01-W28 + famiglia squeeze SQ/MT/ML/AD/CM/PD)
scripts/analysis/      → ricerca/validazione OOS fee-aware (strategy_research, oos_validation, ...)
strategies.yml         → config multi-strategy paper trader
docs/diary/            → diario di ricerca giornaliero
docs/specs/            → specifiche di design
data/raw/              → file .parquet OHLCV (gitignored)

Comandi

uv sync                                              # installa dipendenze
uv run python -m src.data.downloader                  # scarica dati storici
uv run python scripts/strategies/MR01_bollinger_fade.py        # strategia attiva (mean-reversion)
uv run python scripts/analysis/strategy_research.py            # ricerca strategie fee-aware OOS
uv run python scripts/analysis/oos_validation.py               # perche' la famiglia squeeze e' scartata
uv run python scripts/analysis/validate_worker_mr01.py         # replay worker reale su MR01
uv run python -m src.live.multi_runner                # paper trading live multi-strategia
docker compose up -d                                  # deploy Docker
uv run pytest                                         # test

Dati storici

Scaricati e salvati localmente in Parquet. Per rigenerarli:

from src.data.downloader import download_all, load_data
download_all()           # scarica BTC + ETH su 5m/15m/1h dal 2018
df = load_data("ETH", "15m")  # carica un asset/timeframe

Fonte primaria: Cerbero MCP (endpoint /mcp-deribit/tools/get_historical). Token observer: nel file secrets/observer.token del progetto CerberoSuite.

Strategie attive

LEZIONE CRITICA (2026-05-28). L'intera famiglia squeeze-breakout (SQ01-04, MT01, ML01, AD01, CM01, PD01) è stata scartata in scripts/waste/: le accuratezze storiche 76-82% erano un artefatto di look-ahead. Quei backtest decidono la direzione con sign(close[i]-close[i-1]) (la candela di breakout i) ma entrano a close[i-1] — cioè comprano prima della candela che usano per scegliere la direzione. Dal vivo il worker scopre il breakout solo a close[i] ed entra lì: l'edge sparisce (win-rate ~47%, lancio di moneta). Sotto ingresso onesto e fee reali tutte perdono, anche a fee zero. Inoltre i breakout rientrano (mean-reversion > continuation). Vedi scripts/analysis/oos_validation.py e intrabar_test.py.

Tutte le strategie estendono src.strategies.base.Strategy (generate_signals() → backtest()). Unica strategia con edge netto validato:

Codice Nome Tipo Edge OOS netto DD Note
MR01 Bollinger Fade Mean-reversion BTC 1h n50 k2.5: +201% / +196% (worker) 15% Fada la banda, TP alla media, SL ad ATR

MR01 è robusto su tutta la griglia parametri (n∈{14,20,30,50} × k∈{2.0,2.5,3.0}, entrambi gli asset → tutte positive OOS) e su tutte le fee 0.00-0.20% RT. Validato col worker reale: BTC +196% / ETH +251% OOS (nov 2023→mag 2026). Ricerca completa: scripts/analysis/strategy_research.py.

Metodologia obbligatoria per ogni nuova strategia (per non ripetere l'errore squeeze):

  1. Ingresso eseguibile: direzione e prezzo decisi con dati fino a close[i], mai close[i-1] con direzione da i.
  2. Backtest NETTO dopo fee realistiche Deribit (0.10% RT taker, non 0.20%) + leva.
  3. Validazione out-of-sample (held-out) + robustezza su griglia parametri + sweep fee.
  4. Crea script in scripts/strategies/, aggiungi a MODULE_MAP (strategy_loader.py) e a strategies.yml.

Strategie scartate storiche in scripts/waste/ (W01-W28 + la famiglia squeeze).

Multi-Strategy Paper Trader

Orchestratore che esegue N strategie in parallelo su dati live Cerbero, ognuna con €1000 USDC virtuali indipendenti.

Config: strategies.yml — lista strategie con asset, tf, sizing, parametri. Attualmente solo MR01 (BTC/ETH 1h). Persistenza: data/paper_trades/{strategy}___{asset}__{tf}/ con trades.jsonl (append-only) + status.json (resume al restart, include tp/sl/max_bars). Hot-add: aggiungi riga YAML → docker compose restart → storico intatto. Exit strategia: se un Signal porta tp/sl/max_bars in metadata (come MR01), il worker esce su take-profit/stop-loss/time-limit a quei livelli; altrimenti usa il fallback hold_bars/stop -2%. Notifiche: Telegram per ogni trade (richiede .env con TELEGRAM_BOT_TOKEN e TELEGRAM_CHAT_ID).

Convenzioni

  • Strategie in scripts/strategies/ con codice univoco (MR01, ...).
  • Script scartati in scripts/waste/ (W01-W28 + famiglia squeeze).
  • Diario in docs/diary/YYYY-MM-DD.md. Aggiornare dopo ogni esperimento significativo.
  • Nessun dato sensibile nei commit (token, chiavi API). Usare .gitignore.
  • Verificare sempre assenza di data leakage prima di fidarsi dei risultati. In particolare: returns[i-w : i] include close[i] che è un candle nel futuro — usare returns[i-w : i-1].

Attenzione

  • Data leakage: è stata trovata e corretta nello script 05. Ogni volta che si usano rendimenti logaritmici (np.diff(np.log(close))), ricordare che returns[k] usa close[k+1]. I feature devono fermarsi a returns[i-2] se il prezzo corrente è close[i-1].
  • Fee: Deribit perp reale = taker ~0.05%/lato (0.10% round-trip), maker ~0%. Usare 0.10% RT come baseline (lo 0.20% storico era pessimista 2x). Includere SEMPRE nel backtest: sono vincolo di prim'ordine, molte operazioni = morte per fee. Il worker usa strategy.fee_rt (MR01 = 0.001).
  • Leva: testato con 3x. Aumentare a 5x migliora i rendimenti ma raddoppia il drawdown.
  • GBM: GradientBoostingClassifier di scikit-learn. Ensemble di alberi decisionali sequenziali. Walk-forward per evitare leakage temporale.
  • Cerbero get_historical (fix 2026-05-28): end_date come data nuda è inclusivo dell'intera giornata fino all'ultima candela chiusa (es. end=oggi arriva fino ad ora, non più a mezzanotte); accettati anche timestamp con orario (...T14:00:00, naive=UTC); nessun cap a ~5000 righe (paginazione interna). Il client passa già end=oggi, ora corretto. Prima del fix il paper trader restava a zero trade perché il feed era fermo a mezzanotte.
  • Dati ETH Deribit 15m: 14-30%/anno di candele flat (O=H=L=C, volume 0, run fino a ~54h) per bassa liquidità del perpetuo. Verificato (2026-05-28): escluderle NON cambia i backtest (Δacc ≤0.5pp) → edge robusto. Resta un caveat operativo (slippage/fill in trading reale, irrilevante per paper). BTC pulito eccetto picco ~8% nel 2024.