diff --git a/CLAUDE.md b/CLAUDE.md index 821f075..28a9e40 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -152,17 +152,23 @@ Come `PORT01`, sono meta-portafogli (script `run()` di report), non `Strategy` c cross-sectional reversal, opening-range breakout, lead-lag BTC→alt, continuation intraday — quest'ultima riconferma la dominanza mean-reversion). Due edge reali: - **PR01 Pairs** (`scripts/strategies/PR01_pairs_reversion.py`): spread reversion - market-neutral sul log-ratio z-score. **6 coppie robuste**: ETH/BTC (Sharpe 4.04), - LTC/ETH, ADA/ETH, BTC/LTC (robusta anche 4h), ETH/SOL, BNB/ETH (Sharpe 2.2-2.5). - Pattern: sempre alt-liquido vs major (mai alt/alt). Corr col mercato ~0.02-0.08. Fee su - **2 gambe** (worker da estendere prima del live). Verifica: `pairs_research.py`. + market-neutral sul log-ratio z-score, **config UNIVERSALE** `n=50 z_in=2.0 z_exit=0.75 + max_bars=72` (anti-overfit, niente tuning per-coppia). **5 coppie robuste**: ETH/BTC + (Sharpe 4.36), LTC/ETH (3.08), ADA/ETH (2.69), BTC/LTC (2.36, robusta anche 4h), ETH/SOL + (1.96, la più debole). Pattern: sempre alt-liquido vs major. Plateau confermato + (heatmap 20/20 Sharpe>1) + walk-forward (ETH/BTC 11/12 finestre+). **BNB/ETH scartata** + (overfit). Corr col mercato ~0.02-0.08. Fee su **2 gambe** (worker da estendere). Verifica: `pairs_research.py`. - **TSM01** (`scripts/analysis/tsmom_research.py`): TSMOM multi-orizzonte 3/6/12m + risk-off, - marginale ma distinto (corr 0.53 con ROT02), DD 22%/12% OOS, mai un anno negativo. + **gross 0.30**, distinto da ROT02 (corr 0.62), DD 15-22%, mai un anno negativo. Robusto + (36/36 config OOS+) ma diversificatore, non motore di ritorno (rende meno di ROT02). -Aggiungere i **6 pairs** al MASTER (quasi scorrelati, ~0.02-0.08) è il free-lunch più -grande: MASTER+6pairs (15 sleeve) → CAGR 47→71%, **OOS DD 4.7→2.3%**, Sharpe OOS -4.33→**7.71**, tutti gli anni positivi (`scripts/analysis/combine_v2.py`). Caveat: -backtest leva 3x, OOS ~1.6 anni, 2024 cripto eccezionale; i pairs richiedono 2 gambe. +Aggiungere i **5 pairs** al MASTER (quasi scorrelati, ~0.02-0.09) è il free-lunch più +grande (`scripts/analysis/combine_v2.py`). **Numeri sobri onesti** (l'OOS singolo 2024-25 +è regime calmo → ottimistico ~50%): worst-DD su 90g rolling **~6%** (non 2.3%), Sharpe +atteso **~5** (mediana semestrale), ogni anno positivo dal 2021, regge **leva 2x + +slippage doppio** (CAGR 36%, Sharpe 5.1). Config robusta raccomandata: **MASTER-esteso +equal-weight, leva 2x, cap pairs ~30-35%** (i pairs sono ~57% del rischio e non ancora +validati col worker live a 2 gambe). La confluenza multi-TF è stata SCARTATA (overfit). **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`. diff --git a/docs/diary/2026-05-29-exploration.md b/docs/diary/2026-05-29-exploration.md index 0e26aa6..6a1490a 100644 --- a/docs/diary/2026-05-29-exploration.md +++ b/docs/diary/2026-05-29-exploration.md @@ -113,6 +113,41 @@ MASTER (corr 0.02-0.08). MASTER + 6 pairs: Aggiungere i 6 pairs porta l'**OOS DD a 2.2-2.3%** (da 4.7%) con Sharpe OOS ~7.7 e tutti gli anni positivi: il guadagno di diversificazione da fonti market-neutral scorrelate. +## Quarto giro — validazione anti-overfitting e irrobustimento + +Tre audit scettici paralleli (walk-forward, plateau, stress, scomposizione): + +**Pairs — de-overfittati.** Sostituita la config per-coppia (cherry-picking di z_exit/n) +con **una config universale `n=50 z_in=2.0 z_exit=0.75 max_bars=72`**. Verifiche: +- plateau (non picco): heatmap n×z_in → 20/20 celle Sharpe>1 su ETH/BTC e BTC/LTC; +- walk-forward (train 2y / test 6m rolling): ETH/BTC 11/12 finestre positive, BTC/LTC + 9/10 → edge distribuito su tutta la storia, non un regime singolo; +- **BNB/ETH scartata** (era robusta solo coi suoi parametri → overfit; crolla con la + universale e muore per prima allo stress costi). Famiglia ridotta a **5 pairs**. +- stress: 5/6 reggono fee+slippage realistici; solo ETH/BTC regge fee 6x (coda fee-fragile). + +**Master — numeri sobri.** L'OOS Sharpe 7.7 / DD 2.3% è **ottimistico ~50%** perché l'OOS +cade nel bull calmo 2024-25. Numeri onesti da usare: +- worst-DD su finestra mobile 90g (2021-2026) = **5.7%** (bear FTX) → budget DD ~6%, non 2.3%; +- Sharpe per-semestre: mediana **~5** (min 1.2, max 12) → atteso ~5, non 7.7; +- ogni anno e ogni semestre dal 2021 positivo (anche il 2022 bear, grazie alle gambe short); +- equal-weight ≈ inverse-vol (non dipende da pesi fortunati); +- regge **leva 2x + slippage doppio** (CAGR 36%, Sharpe 5.1); +- **rischio concentrato: i pairs portano ~57% del rischio** → cap consigliato ~30-35%. +- Config robusta raccomandata: **MASTER-esteso, equal-weight, leva 2x, cap pairs ~30-35%**. + +**TSM01 — confermato robusto** (36/36 config OOS+, walk-forward stabile) ma corr reale con +ROT02 = **0.62** (non 0.53), e gran parte del DD basso viene dall'overlay risk-off condiviso. +Tenuto come diversificatore con **gross 0.30** (stesso Sharpe, DD 22%→15%). + +**Confluenza multi-TF — SCARTATA: era overfit.** Taglia il 97% dei trade (restano ~40 in +8 anni = non significativo), distrugge lo Sharpe (1.58→0.27 su BTC) e il caso "bello" non +sopravvive alle perturbazioni. Per abbassare il DD di MR01 meglio ridurne la leva, non il filtro 4h. + +**Risultato del giro:** quanto trovato regge l'esame anti-overfit (NON è l'errore squeeze), +ma i numeri vanno comunicati sobri (Sharpe ~5, DD ~6%) e con leva 2x + cap pairs. Famiglia +pairs consolidata a 5 coppie con config universale; confluenza MTF rimossa dai vincitori. + ## File creati (branch strategy_explore) `scripts/analysis/explore_lab.py` (harness onesto condiviso), `pairs_research.py` diff --git a/scripts/analysis/tsmom_research.py b/scripts/analysis/tsmom_research.py index 36d4d29..e60619b 100644 --- a/scripts/analysis/tsmom_research.py +++ b/scripts/analysis/tsmom_research.py @@ -5,8 +5,15 @@ dei segni del momentum su più orizzonti lunghi (3/6/12 mesi); si tengono equal- gli asset con consenso pieno positivo. Overlay risk-off: cash se BTC < SMA100. Distinta da ROT02 (cross-sectional ranking): qui conta la PERSISTENZA assoluta lenta -di ogni asset, non la classifica relativa. Correlazione con ROT02 ~0.53 -> fattore -parzialmente indipendente, utile come diversificatore. DD basso (22% full / 12% OOS). +di ogni asset, non la classifica relativa. Correlazione con ROT02 ~0.62 -> fattore +parzialmente indipendente, utile come diversificatore (NON come motore di ritorno: +rende meno di ROT02 a parita' di OOS). DD basso. + +Anti-overfit: edge su ALTOPIANO (36/36 config orizzonti x thr x regime_n restano OOS+), +walk-forward stabile (4 anni up, 2 piatti per risk-off, mai un anno negativo), regge +fee 0.40% RT. Gran parte del DD basso viene dall'overlay risk-off SMA100 (condiviso), +la struttura multi-orizzonte aggiunge ~+38pp OOS e alza lo Sharpe 0.58->1.07. +Default gross=0.30 (era 0.45): stesso Sharpe ma DD 22%->15% (scelta robusta, non la piu' redditizia). Engine onesto: pesi a close[i] da soli rendimenti passati, realizzo i->i+1, fee one-way fee_rt/2 sul turnover. NETTO, leva implicita gross. OOS = ultimo 30%. @@ -25,7 +32,7 @@ sys.path.insert(0, str(PROJECT_ROOT)) from scripts.analysis.honest_lab import available_assets, FEE_RT from scripts.analysis.honest_rotation import build_panel -GROSS, OOS_FRAC = 0.45, 0.30 +GROSS, OOS_FRAC = 0.30, 0.30 # gross 0.30 (anti-overfit): stesso Sharpe di 0.45, DD piu' basso def tsmom_sim(horizons=(63, 126, 252), thr=1.0, regime_n=100, gross=GROSS, diff --git a/scripts/strategies/PR01_pairs_reversion.py b/scripts/strategies/PR01_pairs_reversion.py index 79f476b..77462e7 100644 --- a/scripts/strategies/PR01_pairs_reversion.py +++ b/scripts/strategies/PR01_pairs_reversion.py @@ -11,13 +11,20 @@ Logica (engine onesto verificato in scripts/analysis/pairs_research.py): EXIT: |z| <= z_exit (rientro) o time-limit max_bars. Ingresso/uscita a close. Fee su 2 GAMBE = 2*fee_rt*lev (0.20% RT/coppia). Filtro candele sporche (salto>8%). -Validazione (netto, fee 0.20% RT/coppia reale a 2 gambe, leva 3x, OOS = ultimo 30%, -n=50 z_in=2.0 z_exit=0.5 max_bars=72, 1h): - ETH/BTC : CAGR 144% / OOS DD 17% / Sharpe 4.04 / win 74% / 8/9 anni positivi - LTC/ETH : CAGR 71% / OOS DD 10% / Sharpe 2.52 / 7/8 anni positivi - ADA/ETH : CAGR 77% / OOS DD 11% / Sharpe 2.16 / 7/8 anni positivi - No look-ahead verificato (z[i] invariato perturbando il futuro). Regge fee 0.40% RT/coppia. - Correlazione con BTC daily ~0.02 -> davvero market-neutral. +Validazione anti-overfit (netto, fee 0.20% RT/coppia a 2 gambe, leva 3x, OOS = ultimo +30%, CONFIG UNIVERSALE n=50 z_in=2.0 z_exit=0.75 max_bars=72, 1h): + ETH/BTC : CAGR 158% / Sharpe 4.36 / 8/9 anni+ (regge fee 6x) + LTC/ETH : CAGR 92% / Sharpe 3.08 / 8/8 anni+ + ADA/ETH : CAGR 91% / Sharpe 2.69 / 7/8 anni+ + BTC/LTC : CAGR 60% / Sharpe 2.36 / 7/8 anni+ (robusta anche a 4h) + ETH/SOL : CAGR 74% / Sharpe 1.96 / 5/7 anni+ (la piu' debole, DD ~63%) + - No look-ahead verificato (z[i] invariato perturbando il futuro). + - PLATEAU non picco: heatmap n x z_in -> 20/20 celle Sharpe>1 (ETH/BTC, BTC/LTC). + - WALK-FORWARD (rolling train 2y / test 6m): ETH/BTC 11/12 finestre positive, + BTC/LTC 9/10 -> edge distribuito su tutta la storia, non un regime singolo. + - Stress costi: 5/6 reggono fee+slippage realistici; solo ETH/BTC regge fee 6x. + - Correlazione con BTC daily ~0.02-0.08 -> market-neutral. + - SCARTATA BNB/ETH: robusta solo coi suoi parametri (overfit), crolla con la universale. LIMITE OPERATIVO: e' una strategia a 2 gambe (long un perp + short l'altro), il worker attuale e' single-leg. Per tradarla serve: (a) eseguibilita' short del perp B su @@ -34,15 +41,20 @@ sys.path.insert(0, str(PROJECT_ROOT)) from scripts.analysis.pairs_research import pairs_sim, OOS_FRAC # noqa: E402 -# Coppie robuste (config migliore per ognuna). Sempre alt-liquido vs major (mai alt/alt). -# Le prime 3 dal primo lotto; BTC/LTC (anche 4h), ETH/SOL, BNB/ETH dall'espansione. +# CONFIG UNIVERSALE (anti-overfit): un'unica terna per TUTTE le coppie, niente +# cherry-picking per-coppia. Validata come ALTOPIANO (heatmap n x z_in: 20/20 celle +# Sharpe>1 su ETH/BTC e BTC/LTC) e walk-forward (ETH/BTC 11/12 finestre+, BTC/LTC 9/10). +UNIV = dict(n=50, z_in=2.0, z_exit=0.75, max_bars=72) + +# Coppie robuste con la config universale. Sempre alt-liquido vs major (mai alt/alt). +# BNB/ETH SCARTATA: era robusta solo coi suoi parametri (n=30, z_exit=1.0) -> overfit; +# con la config universale crolla (Sharpe 1.5, DD 71%) ed e' la prima a morire allo stress costi. PAIRS = [ - ("ETH", "BTC", dict(n=50, z_in=2.0, z_exit=0.5, max_bars=72)), - ("LTC", "ETH", dict(n=50, z_in=2.0, z_exit=0.5, max_bars=72)), - ("ADA", "ETH", dict(n=50, z_in=2.0, z_exit=0.5, max_bars=72)), - ("BTC", "LTC", dict(n=50, z_in=2.0, z_exit=0.5, max_bars=72)), # NUOVA: robusta 1h E 4h - ("ETH", "SOL", dict(n=50, z_in=2.0, z_exit=1.0, max_bars=72)), # NUOVA: solo 1h - ("BNB", "ETH", dict(n=30, z_in=2.0, z_exit=1.0, max_bars=72)), # NUOVA: solo 1h + ("ETH", "BTC", UNIV), # la migliore (Sharpe 4.4 univ), regge fee 6x + ("LTC", "ETH", UNIV), + ("ADA", "ETH", UNIV), + ("BTC", "LTC", UNIV), # robusta anche a 4h + ("ETH", "SOL", UNIV), # piu' debole (DD ~63%, storia SOL corta) -> peso ridotto ]