docs: il README era fermo a 15 giorni PRIMA del reset — riscritto contro lo stato vero
Ultimo commit del README: 2026-06-04. Reset v2.0.0: 2026-06-19. Per 75 giorni la prima pagina del repo ha pubblicato la libreria pre-reset (FADE/HONEST/PAIRS/TSMOM/SHAPE, PORT01-06) con Sharpe 7,84/10,06 e CAGR ~79% come risultati correnti — cioe' esattamente i numeri che §2 elenca sotto "non citare", dalla libreria che il reset aveva dichiarato artefatto. Meta' dei file citati non esiste piu' (strategies.yml, portfolios.yml, scripts/waste, scripts/portfolios, src/live/multi_runner.py), e l'esecuzione descritta era su TESTNET, che e' la causa del reset. - README riscritto (423 -> 152 righe): cosa gira adesso (TP01+SKH01 75/25, ~$2.050, cadenza oraria :47), i numeri nella lente di §2 (TWR +10,6%, non la crescita del conto), la riga che ordina il piano, il metodo e i suoi sei requisiti, il dato, la struttura VERIFICATA file per file, i comandi, i gate con le loro date, l'obiettivo con la sua onesta'. - CLAUDE.md §0 e memoria 40: registrato il difetto e la lezione — un reset invalida anche i documenti che nessuno rilegge; l'inventario di cosa cita numeri morti va fatto il giorno del reset, non 75 giorni dopo per caso. - Diario 02/09c: sezione col confronto riga per riga; coda dichiarata (l'inventario completo degli altri documenti pre-reset non e' stato fatto). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XDJsH3iDSaBns3ccpPBwiu
This commit is contained in:
@@ -1,423 +1,153 @@
|
||||
# PythagorasGoal
|
||||
|
||||
Sistema di riconoscimento pattern frattali e predizione per il trading di criptovalute (BTC, ETH), ispirato al framework teorico di Serleto & Malanga (*Pythagoras Trading Prediction*).
|
||||
Ricerca e esecuzione di strategie algoritmiche su BTC/ETH, con **un libro che gira con soldi veri**
|
||||
su Deribit mainnet dal 20 giugno 2026.
|
||||
|
||||
## Obiettivo
|
||||
> 🚨 **v2.0.0 — RESET del 2026-06-19. Tutto ciò che questo README diceva prima è archiviato in
|
||||
> `Old/` e non è fidato.** L'intera libreria di strategie "validata out-of-sample" (le famiglie
|
||||
> FADE/HONEST/PAIRS/TSMOM/SHAPE, i portafogli PORT01-06, gli Sharpe fra 6 e 10) era un **artefatto
|
||||
> di uno storico contaminato**: print fantasma di un feed *testnet* più storico Binance/USDT.
|
||||
> Ri-testate sul feed reale ricostruito da Deribit mainnet, **perdono ogni anno**. Documento di
|
||||
> fondazione: `docs/diary/2026-06-19-deribit-history.md`.
|
||||
>
|
||||
> Questo README descrive il progetto **dopo** il reset. È stato riscritto il 2026-09-02, dopo
|
||||
> essere rimasto fermo al 4 giugno — quindici giorni prima del reset — mentre pubblicava i numeri
|
||||
> che il progetto aveva già dichiarato falsi.
|
||||
|
||||
Partendo da un capitale iniziale di €1.000, raggiungere un profitto medio di €50 al giorno entro 6–8 mesi, tramite un portafoglio di strategie algoritmiche poco correlate fra loro — mean-reversion, trend/rotazione e spread market-neutral — validate out-of-sample e fee-aware.
|
||||
**L'autorità sui numeri e sulle decisioni è `CLAUDE.md`**, e il racconto completo sta in
|
||||
`docs/memory/`. Questo file è l'ingresso, non la fonte.
|
||||
|
||||
## Risultati
|
||||
---
|
||||
|
||||
> ⚠️ **Revisione 2026-05-28.** La famiglia squeeze-breakout (SQ/MT/ML/AD/CM/PD, con
|
||||
> accuracy storiche dichiarate 76-82%) è stata **scartata**: quei numeri erano un
|
||||
> **artefatto di look-ahead**. I backtest decidevano la direzione dalla candela di
|
||||
> breakout `close[i]` ma entravano a `close[i-1]` — impossibile dal vivo. Sotto
|
||||
> ingresso onesto (`close[i]`) e fee reali, l'edge sparisce e tutte perdono, anche
|
||||
> a fee zero. Dettagli e prove: `scripts/analysis/oos_validation.py`.
|
||||
## Cos'è vivo, adesso
|
||||
|
||||
Dopo una validazione **out-of-sample, fee-aware** di molte famiglie di strategie,
|
||||
emergono cinque famiglie con edge netto reale, tutte radicate nella stessa lezione
|
||||
(in cripto la **mean-reversion** funziona, la continuazione no) o nella diversificazione:
|
||||
| | |
|
||||
|---|---|
|
||||
| libro live | **TP01 + SKH01 a 75/25**, nettati in software su una sola posizione per asset (50/50 BTC/ETH) |
|
||||
| venue | Deribit mainnet, perpetual lineari USDC. Esecuzione **armata** dal 2026-06-20 |
|
||||
| capitale | ~$2.050 (USDC + USDE), non i €2.000 nominali di nessun paper trader |
|
||||
| cadenza | **oraria**, minuto `:47` (`scripts/cron_book.sh`) |
|
||||
| leva | lorda ~0,28x su un tetto di 1,00x. Il cap non ha mai morso: **il vincolo è il segnale** |
|
||||
| protezione on-book | un solo disaster-SL rotolante al −30% sulla posizione netta |
|
||||
|
||||
| Famiglia | Meccanismo | Strategie | Profilo (netto OOS) |
|
||||
|----------|-----------|-----------|---------------------|
|
||||
| **FADE** | mean-reversion intraday 1h (long/short, BTC/ETH) | MR01 Bollinger, MR02 Donchian, MR07 Return-reversal | Acc 52-55%, DD 18-34% |
|
||||
| **HONEST** | long-only multi-regime multi-crypto | DIP01 dip-buy, TR01 EMA-trend, ROT02 dual-momentum | CAGR 31-56%, DD 15-27% |
|
||||
| **PAIRS** | spread reversion *market-neutral* (2 gambe) | PR01 ETH/BTC, LTC/ETH, ADA/ETH, BTC/LTC, ETH/SOL | Sharpe 2.0-4.4, corr col mercato ~0.05 |
|
||||
| **TSMOM** | time-series momentum multi-orizzonte | TSM01 (3/6/12m + risk-off) | diversificatore, DD 15-22% |
|
||||
| **SHAPE** | ML walk-forward su feature di *forma* del prezzo | SH01 (LogisticRegression, orizzonte 12 barre) | diversificatore, corr +0.08 col resto |
|
||||
**Non** sono nel libro live: XS01, VRP01, GTAA01, XSR01. Vivono nel portafoglio di **ricerca**
|
||||
(paper, 5 sleeve), che è una serie diversa da quella che gira — quasi tutti i numeri di portafoglio
|
||||
del progetto sono su quella, non su questa.
|
||||
|
||||
Tutti i numeri sono **netti** dopo fee realistiche (Deribit 0.10% RT single-leg, 0.20%
|
||||
RT/coppia sui pairs), leva 3x, su finestra held-out. Le strategie sono robuste su griglia
|
||||
parametri, sweep fee 0.00-0.20% RT e — per i pairs — validate con **walk-forward** e
|
||||
config universale (niente cherry-picking).
|
||||
## I numeri, con la loro lente
|
||||
|
||||
### Portafoglio combinato (la vera leva anti-drawdown)
|
||||
Ogni numero va scritto con la lente e la banda che gli appartengono. La tabella completa
|
||||
("non citare" ↔ "citare") è in `CLAUDE.md` §2; qui i tre che contano.
|
||||
|
||||
Le famiglie sono **quasi scorrelate fra loro** (~0.05). Combinandole in un unico
|
||||
portafoglio equipesato il drawdown crolla sotto quello di ogni singola sleeve:
|
||||
| grandezza | valore onesto |
|
||||
|---|---|
|
||||
| rendimento del libro live | **TWR +10,6%** dall'armamento, spezzato sul versamento del 25/08: +11,61% prima, −0,9% dopo |
|
||||
| crescita di trading | **+$50** in 71 giorni, su 30 round-trip chiusi e $0,87 di fee totali |
|
||||
| Sharpe del portafoglio di ricerca | **1,95** [1,81 – 2,12] full, **1,54** [1,11 – 1,91] hold-out |
|
||||
|
||||
| Portafoglio | CAGR | Max DD | Sharpe |
|
||||
|-------------|------|--------|--------|
|
||||
| FADE (6 sleeve) | ~46% | 8% | 3.9 |
|
||||
| HONEST (3 sleeve) | ~46% | 13% | 2.2 |
|
||||
| **MASTER** (FADE + HONEST, 9) | ~47% | **5%** | 4.2 |
|
||||
| **MASTER + PAIRS + TSM01** (15) | ~67% | ~5% | ~6 |
|
||||
| **PORT06 live** (17 sleeve, cap pairs 33%, leva 2×, config EXIT-16) | ~79% | **2.6%** | 7.8 (FULL) / 10.1 (OOS) |
|
||||
⚠️ Il rendimento dell'equity **non** è la performance: il 96% della crescita del conto è un
|
||||
bonifico. Chi legge una percentuale su questo progetto deve sapere se è un TWR o un rapporto fra
|
||||
due saldi — è stato un difetto reale, riparato il 2026-09-02.
|
||||
|
||||
> 🔎 **Numeri sobri (anti-overfit).** L'OOS singolo cade nel regime favorevole 2024-25:
|
||||
> i valori di Sharpe/DD sopra sono ottimistici di circa il 50%. Da pianificare per le
|
||||
> decisioni: **Sharpe atteso ~5**, **worst-drawdown su 90 giorni ~6%**, profilo che regge
|
||||
> a leva 2x con slippage raddoppiato. Configurazione raccomandata: equal-weight, leva 2x,
|
||||
> con un cap sull'allocazione ai pairs (~30-35%, poiché concentrano ~57% del rischio).
|
||||
> Tutto resta da confermare nel paper trading live.
|
||||
## La riga che ordina tutto il resto
|
||||
|
||||
## Come funziona
|
||||
> La ricerca ha smesso di essere il vincolo il 2026-07-26, e **sei ondate successive lo hanno
|
||||
> confermato invece che ribaltarlo**. I vincoli sono **il capitale che entra** e **il conto che non
|
||||
> sparisce**.
|
||||
|
||||
### MR01 — Bollinger Fade (mean-reversion)
|
||||
Misurato: il miglior candidato nuovo vale **+0,046 €/giorno**; versare €500/mese invece di €250
|
||||
porta la probabilità di arrivare al traguardo in 20 anni **dal 14% all'85%**. E €100/mese in più
|
||||
equivalgono a **+4,07%/anno di drift**, cioè più di tutta la leva autorizzabile.
|
||||
|
||||
La strategia attiva sfrutta il fatto, emerso dai dati, che su BTC/ETH a 1h gli estremi
|
||||
di prezzo **rientrano verso la media** più di quanto proseguano:
|
||||
## Metodo — cosa deve superare una strategia nuova
|
||||
|
||||
1. **Bollinger Bands** (window `n`, `k` deviazioni standard) sul close.
|
||||
2. **Entry** — quando il close esce *sotto* la banda inferiore → **long** (o *sopra* la superiore → **short**). Ingresso a `close[i]`, eseguibile dal vivo.
|
||||
3. **Take-profit** alla media mobile (il rientro atteso).
|
||||
4. **Stop-loss** a `sl_atr × ATR` oltre l'estremo; **time-limit** a `max_bars`.
|
||||
Sei requisiti, nessuno negoziabile (`CLAUDE.md` §8, gate in `scripts/research/alt/altlib.py`):
|
||||
|
||||
Nessun look-ahead: direzione e livelli sono calcolati con dati fino a `close[i]`.
|
||||
1. **ingresso eseguibile** — direzione e prezzo da dati fino a `close[i]`, mai l'estremo di una candela;
|
||||
2. **backtest netto** dopo fee Deribit realistiche, più la leva;
|
||||
3. **out-of-sample** held-out, robustezza su griglia, sweep fee;
|
||||
4. **liquidità e plausibilità** — un edge su un book fermo o su wick fantasma non è un edge;
|
||||
5. i **gate**: `marginal_vs_tp01` (Sharpe marginale, non assoluto), `study_family_honest` con
|
||||
deflated-Sharpe ≥ 0,95, `day_boundary_robust`, `anchor_luck_band`, `weights_tilt_null`;
|
||||
6. codice, test e diario.
|
||||
|
||||
### Le altre famiglie
|
||||
Il progetto ha **73 regole di prim'ordine** (`CLAUDE.md` §6) — sul dato, sul metodo, sui costi,
|
||||
sulla produzione e sul piano — ognuna pagata almeno una volta. La più
|
||||
ricorrente, cinque occorrenze: *un sorvegliante deve derivare il proprio bersaglio dal codice
|
||||
sorvegliato, mai ridichiararlo — un controllo puntato su una configurazione diversa da quella che
|
||||
gira passa sempre, e non sta controllando niente.*
|
||||
|
||||
- **FADE** (oltre MR01): MR02 fada la rottura del canale Donchian verso il centro;
|
||||
MR07 fada il movimento di barra estremo misurato in deviazioni standard dei
|
||||
rendimenti. Stessa logica di reversione, indicatori indipendenti.
|
||||
- **HONEST** (long-only, multi-crypto): DIP01 compra i dip estremi e rivende al
|
||||
recupero; TR01 segue il trend con incrocio di EMA su un paniere; ROT02 ruota ogni
|
||||
giorno sui tre asset col momentum più forte, andando in cash quando BTC è sotto la
|
||||
sua media (risk-off). Coprono i regimi di trend e rotazione, complementari alle fade.
|
||||
- **PAIRS** (market-neutral): scommette sul rientro verso la media del log-ratio fra
|
||||
due cripto (z-score). Long su una, short sull'altra: l'esposizione netta al mercato è
|
||||
quasi nulla (correlazione ~0.02), il che la rende un diversificatore eccellente.
|
||||
- **TSMOM**: tiene gli asset con momentum positivo persistente su più orizzonti
|
||||
(3/6/12 mesi), con overlay risk-off. Rende meno ma è poco correlato, utile in ensemble.
|
||||
## Il dato
|
||||
|
||||
### Perché lo squeeze breakout è stato abbandonato
|
||||
- **La verità è Deribit mainnet**, perché è dove si esegue. Binance è un audit indipendente, mai
|
||||
un'ancora per "ripulire": è USDT, ~10 bps fuori, fino al 3% sotto depeg.
|
||||
- Universo certificato: **solo BTC/ETH**, ogni timeframe. Gli alt sono esclusi.
|
||||
- Lo storico si aggiorna **solo** con `rebuild_history.py` e si certifica **sempre** con
|
||||
`certify_feed.py`. Il vecchio downloader è la causa del reset.
|
||||
- La catena opzioni si **raccoglie** ogni ora (`collect_chain.py`, minuto `:25`): un'ora non
|
||||
raccolta è persa per sempre.
|
||||
|
||||
L'ipotesi originale era opposta — *continuazione* dopo la compressione di volatilità
|
||||
(Bollinger dentro Keltner → breakout direzionale). Su dati storici sembrava dare
|
||||
76-82% di accuracy, ma era un **artefatto di look-ahead**: il backtest entrava a
|
||||
`close[i-1]` con direzione decisa da `close[i]`. Replicando l'esecuzione reale
|
||||
(ingresso a `close[i]`) l'edge collassa al ~47% (lancio di moneta) e i costi fanno
|
||||
il resto. Il test sui breakout intra-barra a 5m conferma che il movimento *rientra*
|
||||
subito (mean-reversion), giustificando MR01. Tutta la famiglia squeeze è in `scripts/waste/`.
|
||||
|
||||
### Lezione metodologica
|
||||
|
||||
Ogni nuova strategia deve passare: (1) **ingresso eseguibile** senza look-ahead,
|
||||
(2) backtest **netto** dopo fee realistiche (0.10% RT Deribit), (3) validazione
|
||||
**out-of-sample** + robustezza su griglia parametri + sweep fee. Strumenti in
|
||||
`scripts/analysis/` (`strategy_research.py`, `oos_validation.py`, `intrabar_test.py`).
|
||||
|
||||
## Struttura progetto
|
||||
## Struttura
|
||||
|
||||
```
|
||||
PythagorasGoal/
|
||||
├── src/
|
||||
│ ├── data/ # Download e gestione dati (Cerbero MCP + Binance)
|
||||
│ ├── fractal/ # Indicatori frattali: Hurst, Higuchi FD, self-similarity
|
||||
│ ├── backtest/ # Motore di backtesting con fee e metriche
|
||||
│ ├── strategies/ # Classe base Strategy ABC + indicatori condivisi
|
||||
│ │ ├── base.py # Strategy, Signal, BacktestResult, YearlyStats
|
||||
│ │ └── indicators.py # keltner_ratio, detect_squeezes, ema, atr, rv, corr
|
||||
│ ├── live/ # Paper trading live su Deribit testnet
|
||||
│ │ ├── multi_runner.py # Orchestratore multi-strategia (strategie + pairs)
|
||||
│ │ ├── strategy_worker.py # Worker single-leg con stato persistente
|
||||
│ │ ├── pairs_worker.py # Worker a 2 gambe per i pairs (market-neutral)
|
||||
│ │ ├── strategy_loader.py # Import dinamico classi Strategy
|
||||
│ │ ├── cerbero_client.py # Client HTTP per Cerbero MCP
|
||||
│ │ ├── signal_engine.py # Squeeze + ML real-time (legacy) + validazione OOS
|
||||
│ │ └── telegram_notifier.py
|
||||
│ └── portfolio/ # Portafogli di prima classe (capitale condiviso, backtest + live)
|
||||
│ ├── base.py # SleeveSpec, Portfolio (.backtest), load_active_portfolio
|
||||
│ ├── weighting.py # Schemi di ponderazione: equal, cap, inverse_vol, cluster_rp, manual
|
||||
│ ├── sleeves.py # Builder unificato equity-per-sleeve (fonte unica, parità report)
|
||||
│ ├── ledger.py # PortfolioLedger: PnL/DD aggregati, persistenza e resume
|
||||
│ └── runner.py # PortfolioRunner live (Cerbero v2, sizing, ribilancio giornaliero)
|
||||
├── scripts/
|
||||
│ ├── strategies/ # Strategie con edge validato OOS (FADE, HONEST, PAIRS, TSMOM + portafogli)
|
||||
│ ├── portfolios/ # Definizioni PORT01-06 e report run() dei portafogli di prima classe
|
||||
│ ├── waste/ # Strategie scartate (squeeze SQ/MT/ML/AD/CM/PD, MR03, ROT01, W01-W28)
|
||||
│ └── analysis/ # Ricerca/validazione OOS fee-aware, gestione rischio, report
|
||||
├── strategies.yml # Config multi-strategy paper trader
|
||||
├── data/
|
||||
│ ├── raw/ # Parquet OHLCV (gitignored, ~70 MB)
|
||||
│ └── regime/ # DVOL + funding (Deribit mainnet) + cache feature regime (gitignored)
|
||||
├── VERSION # versione semver (cotta nell'immagine, mostrata nei msg Telegram)
|
||||
├── docs/
|
||||
│ ├── diary/ # Diario di ricerca giornaliero
|
||||
│ └── specs/ # Specifiche di design
|
||||
├── Dockerfile
|
||||
├── docker-compose.yml
|
||||
└── pyproject.toml
|
||||
src/
|
||||
data/downloader.py load_data(asset, tf) sui parquet certificati
|
||||
strategies/ trend_portfolio.py (TP01) · skyhook.py (SKH01) · base · indicators
|
||||
portfolio/ portfolio.py (N sleeve + weights_tilt_null) · sleeves.py · gtaa.py
|
||||
backtest/harness.py backtest onesto, senza look-ahead
|
||||
live/ book.py (esecutore netto) · deribit · livefeed · usde
|
||||
venue_watch · venue_probe · venue_news · monitor_health · scale_watch
|
||||
tradesdb · journal · analista · notifier · cli
|
||||
scripts/
|
||||
live/ book_execute · trades_db · journal · analista · balance_watch
|
||||
paper_* (forward-monitor) · usde_watch · usde_convert · fee_watch
|
||||
research/ r<data>_*.py — un file per esperimento, harness in alt/altlib.py
|
||||
analysis/ rebuild_history · certify_feed · audit_feed · multi_source_check
|
||||
cron_{book,daily,chain,balance,usde,opt_snapshot,vol_term}.sh
|
||||
docs/
|
||||
memory/ LA MEMORIA — 6 file, indicizzati in testa a CLAUDE.md
|
||||
research/ RESULTS-0822 (§1-73, un registro per filone) · BRIEF-0822 · SPEC-scale-key
|
||||
diary/ una voce per esperimento (144)
|
||||
journal/ libro di bordo, una voce al giorno, 4 livelli per provenienza
|
||||
tests/ 910, tutti verdi
|
||||
Old/ archivio pre-reset — consultabile, non fidato
|
||||
```
|
||||
|
||||
## Strategie attive
|
||||
|
||||
Le strategie single-asset estendono `src.strategies.base.Strategy`
|
||||
(`generate_signals() → backtest()`); i pairs hanno un worker dedicato a 2 gambe.
|
||||
|
||||
| Codice | Script | Famiglia | Descrizione |
|
||||
|--------|--------|----------|-------------|
|
||||
| **MR01** | `MR01_bollinger_fade.py` | FADE | Fada la banda di Bollinger, TP alla media, SL ad ATR |
|
||||
| **MR02** | `MR02_donchian_fade.py` | FADE | Fada la rottura del canale Donchian, TP al centro |
|
||||
| **MR07** | `MR07_return_reversal.py` | FADE | Fada il movimento di barra estremo (z dei rendimenti) |
|
||||
| **DIP01** | `DIP01_dip_reversion.py` | HONEST | Dip-buy long-only su z-score estremo |
|
||||
| **TR01** | `TR01_ema_trend.py` | HONEST | EMA 20/100 trend-following su paniere cripto (4h) |
|
||||
| **ROT02** | `ROT02_dual_momentum.py` | HONEST | Rotazione cross-sectional top-3 + risk-off (1d) |
|
||||
| **PR01** | `PR01_pairs_reversion.py` | PAIRS | Spread reversion market-neutral su 5 coppie |
|
||||
| **TSM01** | `tsmom_research.py` | TSMOM | Time-series momentum multi-orizzonte + risk-off |
|
||||
| **SH01** | `SH01_shape_ml.py` | SHAPE | LogisticRegression walk-forward su 17 feature di forma, orizzonte 12 barre (diversificatore) |
|
||||
|
||||
Le fade applicano tre protezioni live: un **filtro trend** (`trend_max`/`ema_long`,
|
||||
salta i segnali col prezzo troppo esteso rispetto alla EMA200), un **loss-guard Hurst**
|
||||
(`hurst_max=0.55`, salta i segnali in regime persistente/trending dove si concentrano gli stop-loss
|
||||
— dimezza il drawdown del portafoglio, calcolato dalle sole close) e l'**EXIT-16 close-confirm SL**
|
||||
(`sl_confirm_atr=0.5`, 2026-06-04: lo stop scatta solo se la barra *chiude* oltre `sl ∓ 0.5·ATR14` —
|
||||
gli stop intrabar da wick erano falsi negativi, l'overshoot che buca lo stop è proprio il movimento
|
||||
che la fade fada; a livello PORT06 porta l'OOS Sharpe da 8.82 a 10.06). Più un filtro `min_tp_frac`
|
||||
che scarta i micro-scalp col take-profit entro il costo delle fee. Le tre protezioni sono
|
||||
complementari: Hurst toglie il regime tossico, il trend-filter gli ingressi sovra-estesi, il
|
||||
close-confirm i falsi stop. Portafogli pronti: `PORT01`
|
||||
(honest), `PORT02` (fade), `PORT03` (master fade+honest), **`PORT06`** (master esteso, default live).
|
||||
|
||||
**Scartate** (in `scripts/waste/`): la famiglia squeeze (SQ01-04, ML01, MT01, PD01,
|
||||
CM01, AD01 — artefatto di look-ahead), MR03 Keltner (debole/ridondante con MR01) e
|
||||
ROT01 (dominata da ROT02).
|
||||
|
||||
### Comandi utili
|
||||
## Comandi
|
||||
|
||||
```bash
|
||||
# Backtest di una strategia
|
||||
uv run python scripts/strategies/MR01_bollinger_fade.py
|
||||
uv run python scripts/strategies/PR01_pairs_reversion.py
|
||||
|
||||
# Ricerca e validazione fee-aware out-of-sample
|
||||
uv run python scripts/analysis/strategy_research.py # screening famiglie + deep-dive fade
|
||||
uv run python scripts/analysis/strategy_research_v2.py # MR02 / MR03 / MR07
|
||||
uv run python scripts/analysis/oos_validation.py # perche' la famiglia squeeze e' scartata
|
||||
uv run python scripts/analysis/pairs_research.py # ricerca + verifica no-look-ahead dei pairs
|
||||
|
||||
# Gestione rischio, combinazione, report
|
||||
uv run python scripts/analysis/risk_management.py # filtro trend + portafoglio fade
|
||||
uv run python scripts/analysis/combine_portfolio.py # combinare fade + honest
|
||||
uv run python scripts/analysis/combine_v2.py # master esteso con pairs + TSM01
|
||||
uv run python scripts/analysis/report_families.py # report per anno di tutte le famiglie
|
||||
|
||||
# Validazione dei worker live (replay == backtest)
|
||||
uv run python scripts/analysis/validate_worker_mr01.py # worker single-leg su MR01
|
||||
uv run python scripts/analysis/validate_worker_pairs.py # worker a 2 gambe sui pairs
|
||||
uv run python scripts/analysis/live_smoke_pairs.py # smoke test feed live reale dei pairs
|
||||
uv sync # dipendenze
|
||||
uv run python scripts/analysis/rebuild_history.py --asset BTC ETH # storico da Deribit mainnet
|
||||
uv run python scripts/analysis/certify_feed.py # certifica i feed
|
||||
uv run python scripts/live/trades_db.py --report # stato del libro + TWR
|
||||
uv run python scripts/live/journal.py # voce del giorno
|
||||
uv run python scripts/live/analista.py --secco # analisi del giorno, senza salvare
|
||||
uv run python scripts/portfolio/run_portfolio.py # portafoglio di ricerca
|
||||
uv run pytest # 910 test
|
||||
```
|
||||
|
||||
## Paper Trading Live
|
||||
Ogni script di `scripts/live/` accetta `--help` e **rifiuta un flag che non conosce** (esce 2): fino
|
||||
al 2026-09-02 un flag sbagliato eseguiva l'azione di default, e su tre script quell'azione scriveva.
|
||||
|
||||
Il multi-strategy runner esegue N strategie in parallelo su dati live da Cerbero MCP,
|
||||
ognuna con €1000 USDC virtuali indipendenti. Gestisce due tipi di worker:
|
||||
## Gate aperti
|
||||
|
||||
- **Single-leg** (`strategy_worker.py`): per le strategie direzionali. Se un `Signal`
|
||||
porta `tp`/`sl`/`max_bars` in `metadata` (come le fade), chiude su take-profit /
|
||||
stop-loss / time-limit; altrimenti usa il fallback `hold_bars`/stop -2%.
|
||||
- **Due gambe** (`pairs_worker.py`): per i pairs market-neutral. Apre long su una gamba
|
||||
e short sull'altra, esce sul rientro dello z-score o per time-limit, conta le fee su
|
||||
entrambe le gambe. Validato: il replay storico coincide *esattamente* col backtest.
|
||||
Un gate si decide **alla data**, coi criteri scritti **prima**. Elenco completo in `CLAUDE.md` §4.
|
||||
|
||||
### Avvio
|
||||
| gate | data | dove punta oggi |
|
||||
|---|---|---|
|
||||
| STATARB | 2026-09-27 | ritiro (Sharpe −1,61 sulla serie vera) |
|
||||
| SCALA-01 — leva 1,00 → 1,25 | non prima del 2026-10-01 | chiave costruita e **inerte**; 9 condizioni, 2 fatte |
|
||||
| XSR01 | 2026-10-23 | sotto la lente rendita il meccanismo vale ~0 |
|
||||
| DVOLSPREAD | kill 2026-10-24 | serie −4,41 |
|
||||
| GTAA01 tenere/bloccare | al book a $15k | contributo reale +0,10/+0,12 di Sharpe, non incassabile sotto la soglia |
|
||||
|
||||
```bash
|
||||
# Locale
|
||||
uv run python -m src.live.multi_runner
|
||||
## Obiettivo, e cosa lo rende difficile
|
||||
|
||||
# Docker
|
||||
docker compose up -d
|
||||
```
|
||||
Il target dichiarato è **€50/giorno partendo da €1.000**. Non è raggiungibile a questo capitale:
|
||||
servono ~$313k (banda [$187k – $1,14M]) o **€1.733/mese per dieci anni** per averlo al 90% di
|
||||
probabilità. La leva non è la scorciatoia — quella difendibile vale quanto €100-150/mese di
|
||||
versamento. La via è target-vol, capitale e tempo.
|
||||
|
||||
### Configurazione
|
||||
|
||||
Le strategie attive sono definite in `strategies.yml`:
|
||||
|
||||
```yaml
|
||||
defaults:
|
||||
capital: 1000
|
||||
position_size: 0.15
|
||||
leverage: 3
|
||||
|
||||
strategies: # strategie single-leg
|
||||
- name: MR01_bollinger_fade
|
||||
asset: BTC
|
||||
tf: 1h
|
||||
enabled: true
|
||||
params: { bb_window: 50, k: 2.5, sl_atr: 2.0, max_bars: 24, trend_max: 3.0, ema_long: 200 }
|
||||
|
||||
pairs: # strategie a 2 gambe (market-neutral)
|
||||
- name: PR01_pairs_reversion
|
||||
a: ETH
|
||||
b: BTC
|
||||
tf: 1h
|
||||
enabled: true
|
||||
params: { n: 50, z_in: 2.0, z_exit: 0.75, max_bars: 72, jump_max: 0.08 }
|
||||
```
|
||||
|
||||
Per aggiungere una strategia: nuova riga in `strategies.yml` (sezione `strategies` o
|
||||
`pairs`), poi `docker compose restart`. Lo storico delle strategie esistenti rimane intatto.
|
||||
|
||||
### Persistenza
|
||||
|
||||
Ogni strategia ha la sua directory in `data/paper_trades/`:
|
||||
|
||||
```
|
||||
data/paper_trades/
|
||||
MR01_bollinger_fade__BTC__1h/
|
||||
trades.jsonl # Storico trade append-only
|
||||
status.json # Stato corrente (resume al restart, include tp/sl/max_bars)
|
||||
```
|
||||
|
||||
Notifiche Telegram per ogni trade (richiede `TELEGRAM_BOT_TOKEN` e `TELEGRAM_CHAT_ID` in `.env`).
|
||||
|
||||
## Paper Trading a Portafoglio
|
||||
|
||||
Accanto al multi-strategy runner originale — in cui ogni strategia gestisce autonomamente il proprio conto virtuale da €1.000 — il progetto dispone ora di un **paper trader a portafoglio** (`src/portfolio/`) che tratta l'insieme delle strategie come un unico organismo con un capitale condiviso.
|
||||
|
||||
### Come funziona
|
||||
|
||||
La definizione di un portafoglio (`SleeveSpec` + schema di peso) ha due facce sulla stessa sorgente dati:
|
||||
|
||||
- **Backtest** (`.backtest()`): ricostruisce le equity-curve di ogni sleeve tramite il builder unificato in `sleeves.py`, le pondera secondo lo schema scelto e calcola le metriche aggregate (CAGR, Sharpe, max DD). La parità con i report prodotti da `report_families.py` è garantita dalla fonte unica.
|
||||
- **Live** (`PortfolioRunner`): ogni ora il runner scarica le candele aggiornate via Cerbero v2, calcola i pesi correnti, avvia i worker appropriati per ogni sleeve attiva e registra il PnL aggregato nel ledger (`data/portfolios/{code}/`). Il ledger persiste tra i riavvii.
|
||||
|
||||
### Schemi di ponderazione
|
||||
|
||||
Il modulo `weighting.py` mette a disposizione cinque schemi: `equal` (default), `cap` (tetto per famiglia — p.es. `pairs: 0.33` per limitare la concentrazione), `inverse_vol` (pesi inversamente proporzionali alla volatilità storica), `cluster_rp` (equal tra cluster naturali poi inverse-vol all'interno del cluster) e `manual` (pesi liberi). Lo schema si specifica in `portfolios.yml` insieme al codice portafoglio e alla leva.
|
||||
|
||||
### Portafoglio di default: PORT06
|
||||
|
||||
La configurazione raccomandata è **PORT06** (`scripts/portfolios/PORT06_master_shape.py`): portafoglio master esteso che include tutte e sei le famiglie (FADE, HONEST, PAIRS, TSMOM, SHAPE), con schema `cap` che limita i pairs al 33% del capitale per moderare la loro concentrazione di rischio. Backtest canonico (dati al 2026-05-28): Sharpe 6.47 (FULL) / 8.82 (OOS), drawdown massimo 4.10% (FULL) / 1.30% (OOS), leva 2×; **con la config live attuale (EXIT-16 close-confirm): Sharpe 7.84 / 10.06, DD 2.60% / 1.15%**.
|
||||
|
||||
### Scope live
|
||||
|
||||
Il runner esegue **tutti e 17 gli sleeve** di PORT06: **fade** (MR01, MR02, MR07 × BTC/ETH),
|
||||
**honest** (DIP01, TR01-basket 4h, ROT02-rotation 1d), **pairs** (PR01, cinque coppie),
|
||||
**TSMOM** (TSM01 1d) e **shape** (SH01 × BTC/ETH). Worker dedicati: `StrategyWorker` (single-leg, fade/
|
||||
dip/**shape**), `PairsWorker` (2 gambe), `BasketTrendWorker`, `RotationWorker`, `TsmomWorker`. Il runner
|
||||
fetcha 1h da Cerbero v2 e resampla a 4h/1d; il pool di capitale, il ribilancio giornaliero e il ledger
|
||||
sono validati == backtest.
|
||||
|
||||
> **SH01 (2026-06-01):** gira come `StrategyWorker` normale (il walk-forward è interno a
|
||||
> `generate_signals`). Il vecchio `MLWorkerWrapper` usava il `SignalEngine` **squeeze scartato** —
|
||||
> rimosso. **Loss-guard Hurst (2026-06-02):** le fade saltano i segnali in regime persistente
|
||||
> (rolling-Hurst ≥ 0.55), dove si concentrano gli stop-loss — dimezza il drawdown del portafoglio
|
||||
> (FULL 4.1%→2.4%; stop-loss fade −67% in numero, perdite totali −68%). Calcolato dalle sole close,
|
||||
> attivo live (`hurst_max` nei params). Il report orario su Telegram **monitora lo stop-rate fade
|
||||
> prima/dopo l'attivazione** e dà il verdetto automatico quando il campione è sufficiente.
|
||||
|
||||
### Esecuzione reale (shadow, Deribit testnet)
|
||||
|
||||
Sette sleeve single-leg — le **6 fade** (MR01/MR02/MR07 × BTC/ETH) e **DIP01** (dal 2026-06-04) —
|
||||
eseguono ordini **reali su Deribit testnet** accanto al fill simulato (*shadow*: il sim resta la
|
||||
verità che guida le decisioni; il reale misura la fattibilità). Punti chiave:
|
||||
|
||||
- **Strumenti lineari USDC** (`BTC_USDC`/`ETH_USDC-PERPETUAL`): payoff lineare = matematica del
|
||||
backtest; fee e PnL in USDC. Quantizzazione `Decimal` di amount (step) e prezzi (tick).
|
||||
- **Take-profit reale = limit reduce-only AL livello** (v1.0.7): piazzato all'apertura, copre la
|
||||
sola quota del worker (gli strumenti sono condivisi fra worker e nettati per conto); alla
|
||||
chiusura il worker cancella il resting, riconcilia i fill dal trade history per `order_id` e
|
||||
chiude a market solo il residuo. Fix della divergenza misurata: il market-on-poll usciva
|
||||
+235 bps oltre il livello TP. Fill da resting = fee maker (~0%).
|
||||
- **Stop-loss close-confirm** (v1.1.0): uscita al close che sfonda il livello → market
|
||||
reduce-only al poll (nessun ordine stop sul book, per scelta: i trigger Deribit generano un
|
||||
nuovo order_id allo scatto, non verificabile, e i wick non devono stoppare).
|
||||
- **Verifica sul trade** (order_id in `get_trade_history`), fee reali dai `trades[]`, ledger
|
||||
reale parallelo persistito (`real_capital`), eventi `REAL_OPEN`/`REAL_TP_RESTING`/`REAL_CLOSE`
|
||||
nel log + alert Telegram (`REAL_EXEC_LIVE`, `REAL_OPEN_FAIL`).
|
||||
- Config in `portfolios.yml` → `overrides.execution {enabled, sleeves, instruments}`.
|
||||
**Pairs/rotation/TSMOM/shape restano simulati**: i pairs richiedono un executor a 2 gambe
|
||||
(leg-risk), i multi-asset un rebalance-to-target; roadmap nel diario.
|
||||
|
||||
### Versione & deploy
|
||||
|
||||
Ogni deploy ha una **versione** (file `VERSION`, semver) che compare nei messaggi Telegram (notifiche
|
||||
trade + report orario), così correli ogni messaggio al codice che l'ha generato. Il sorgente è **cotto
|
||||
nell'immagine** → per aggiornare il live serve un **rebuild**, non un semplice restart:
|
||||
|
||||
```bash
|
||||
./scripts/deploy.sh # bump patch (1.0.0 → 1.0.1) + commit + rebuild + ricrea container
|
||||
./scripts/deploy.sh minor # 1.0.x → 1.1.0
|
||||
```
|
||||
|
||||
Il volume `data/` persiste tra i deploy → i worker fanno RESUME dello stato (capitale, posizioni aperte).
|
||||
|
||||
### Avvio del paper trader a portafoglio
|
||||
|
||||
```bash
|
||||
# Backtest del portafoglio di default (PORT06)
|
||||
uv run python scripts/portfolios/PORT06_master_shape.py
|
||||
|
||||
# Paper trading live a portafoglio
|
||||
uv run python -m src.portfolio.runner
|
||||
|
||||
# Report orario su Telegram (stato + stop-rate fade prima/dopo loss-guard) — via cron
|
||||
uv run python scripts/portfolios/hourly_report.py
|
||||
|
||||
# Smoke test del data layer Cerbero v2
|
||||
uv run python scripts/analysis/smoke_portfolio.py
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
# Clona e installa
|
||||
git clone <repo-url> && cd PythagorasGoal
|
||||
uv sync
|
||||
|
||||
# Scarica dati storici (~70 MB)
|
||||
uv run python -m src.data.downloader
|
||||
|
||||
# Backtest strategia attiva
|
||||
uv run python scripts/strategies/MR01_bollinger_fade.py
|
||||
|
||||
# Paper trading live
|
||||
uv run python -m src.live.multi_runner
|
||||
```
|
||||
|
||||
### Requisiti
|
||||
|
||||
- Python ≥ 3.11
|
||||
- [uv](https://docs.astral.sh/uv/) come package manager
|
||||
- Accesso a Cerbero MCP (`cerbero-mcp.tielogic.xyz`) per dati Deribit live
|
||||
- Docker (opzionale, per deploy su VPS)
|
||||
|
||||
## Dati
|
||||
|
||||
| Asset | Timeframe | Copertura |
|
||||
|-------|-----------|-----------|
|
||||
| BTC, ETH | 5m / 15m / 1h | 2018-01 → oggi |
|
||||
| SOL, LTC, ADA, XRP, BNB, DOGE | 15m / 1h | 2019-2022 → oggi (variabile per asset) |
|
||||
|
||||
Fonte primaria: perpetual Deribit via Cerbero MCP. Fallback: Binance spot via ccxt.
|
||||
Formato: Apache Parquet (in `data/raw/`, gitignored).
|
||||
|
||||
> **Nota sul naming Deribit (per il feed live).** I major sono perpetui *inverse*
|
||||
> (`BTC-PERPETUAL`, `ETH-PERPETUAL`); gli altcoin sono perpetui *lineari USDC*
|
||||
> (`SOL_USDC-PERPETUAL`, `LTC_USDC-PERPETUAL`, …) con storia dal 2022. Attenzione:
|
||||
> `LTC-PERPETUAL`/`ADA-PERPETUAL` non esistono e `SOL-PERPETUAL` restituisce dati
|
||||
> errati — per gli altcoin usare sempre la forma `_USDC-PERPETUAL`.
|
||||
|
||||
### Discovery & validazione strumenti
|
||||
|
||||
`src/data/instruments.py` scopre e **valida** gli strumenti disponibili sugli
|
||||
exchange implementati — **Deribit** e **Hyperliquid** (esclusi Alpaca/stocks e
|
||||
**Bybit**, feed testnet inaffidabile). Ogni perpetuo viene testato sui dati
|
||||
storici realmente raccoglibili: esistenza, congruenza OHLC, contratto non-morto,
|
||||
liquidità e **congruenza prezzo cross-exchange** (mediana per base-coin, tolleranza
|
||||
5%) — così feed farlocchi e contratti sbagliati (es. `SOL-PERPETUAL`=9.6) vengono
|
||||
scartati. Il risultato è `data/instruments_registry.json` (strumenti validi +
|
||||
timeframe + data d'inizio).
|
||||
|
||||
**Solo gli strumenti validati possono essere scaricati**: il downloader ha un gate
|
||||
(`_download_cerbero_range`) che rifiuta quelli non nel registry. Rigenera con:
|
||||
|
||||
```bash
|
||||
uv run python -m src.data.instruments
|
||||
```
|
||||
|
||||
Simboli Deribit: BTC/ETH = `<COIN>-PERPETUAL` (inverse); altcoin =
|
||||
`<COIN>_USDC-PERPETUAL` (lineari USDC). Registry attuale (testnet): Deribit 18/106
|
||||
validi (major liquidi, BTC dal 2018), Hyperliquid 66/74.
|
||||
|
||||
## Riferimenti
|
||||
|
||||
- Serleto, L. & Malanga, C. — *Pythagoras Trading Prediction* (2024)
|
||||
- Serleto, L. & Malanga, C. — *Libro dei Frattali* (2024)
|
||||
|
||||
## Licenza
|
||||
|
||||
Uso privato. Non destinato alla distribuzione.
|
||||
**Onestà prima di tutto**: nessun numero va creduto finché non è netto fee, out-of-sample, robusto
|
||||
su griglia, e su dati certificati, liquidi ed eseguibili. Il resto di questo repo esiste per rendere
|
||||
quella frase verificabile invece che dichiarata.
|
||||
|
||||
Reference in New Issue
Block a user