Files
PythagorasGoal/CLAUDE.md
T
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

130 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
```bash
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:
```python
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.