14522262e6
Reset del progetto su fondamenta verificate dopo la scoperta che l'intera libreria "validata OOS" era artefatto di feed contaminato (print fantasma del feed Cerbero TESTNET + storico Binance/USDT). - Storico ricostruito da Deribit MAINNET (ccxt pubblico, tokenless) e CERTIFICATO (certify_feed.py): BTC/ETH puliti su TUTTA la storia (mediana 2-6 bps vs Coinbase USD), integrita' OHLC + coerenza resample (maxΔ 0.00) + cross-venue OK. Alt esclusi (illiquidi/divergenti: LTC/DOGE 50-82% barre flat; XRP/BNB non certificabili). - Verdetto sul feed pulito: FADE / PAIRS / XS01 / TSM01 morti (ogni portafoglio Sharpe -2.3..-3.0, DD ~40%); solo SH01 e frammenti HONEST con segnale residuo, da ri-validare in isolamento. - Cleanup "restart pulito": strategie, stack live (src/live, src/portfolio, runner/executor, yml, docker), ~100 script ricerca/gate, waste/games/ portfolios, dati non certificati + cache e 60+ diari -> archiviati in Old/ (preservati, non cancellati). Diario consolidato in un unico documento. - Skeleton ricerca tenuto: Strategy ABC + indicatori + src/fractal + src/backtest/engine + load_data; tool dati certificati (rebuild_history, certify_feed, audit_feed, multi_source_check). - Universo dati ATTIVO: solo BTC/ETH (5m/15m/1h); guardrail fisico (load_data su alt -> FileNotFoundError). Esecuzione DISABILITATA, conto flat. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
87 lines
5.9 KiB
Markdown
87 lines
5.9 KiB
Markdown
# 2026-06-11 — Sweep di stabilità su tutte le strategie (anti-overfit)
|
||
|
||
Obiettivo: analisi di tutte le 19 sleeve cercando miglioramenti/correzioni/protezioni che
|
||
aumentino la STABILITÀ, con disciplina anti-overfit (ipotesi pre-registrate, griglie fissate
|
||
prima di guardare i numeri, verdetti su TRAIN E OOS con plateau, gate PORT06; nessun re-test
|
||
di idee già bocciate: ADX/vol-target/time-stop/hurst/stop SH01/multi-TF/entry-guard ecc.).
|
||
|
||
## Audit di drift (nessun fitting)
|
||
|
||
- `report_families` sui dati correnti: correlazioni cross-famiglia ancora ≈0 (pairs 0.03-0.11,
|
||
XS01 0.01, SH 0.03-0.04 vs MASTER-9) → la diversificazione NON è driftata.
|
||
- **Regression-lock trend_max** (`trendmax_port06_impact`) rieseguito su dati freschi:
|
||
parità 1.00000 su tutte e 6 le fade (engine live-path integro) e **plateau trend_max
|
||
2.5/3.0/3.5 confermato** (OOS Sh 11.14/11.24/10.98, DD 1.33 identico).
|
||
- **Percentile del rolling-return PORT06** (cap weights, storia 2021+): finestra corrente
|
||
60g al 19°, 120g al 21°, 160g al 28° percentile → periodo fiacco ma in variazione normale.
|
||
- ⚠️ **FADE in coda storica**: il rolling 120g equal-weight delle 6 fade è a **−1.0% =
|
||
2° percentile** della propria storia (p5 = +0.4%). È il tratto peggiore mai attraversato
|
||
dalla famiglia. Decisione esplicita: NESSUN ritocco ai parametri (sarebbe fit sul regime
|
||
corrente, l'errore che il progetto evita da sempre); la protezione è la diversificazione
|
||
(già in atto: il portafoglio regge al 19-28° pct) + monitoraggio. Follow-up in TODO:
|
||
alert di drift per-famiglia nel hourly_report (distribuzione storica precomputata).
|
||
|
||
## Correzione: bug contabile TR01 worker (FIXATO)
|
||
|
||
`BasketTrendWorker.tick` usava `mean(rets)` sui SOLI asset in posizione → con paniere
|
||
parziale sovrappesa N/k (con 1 solo long: 0.45 del capitale invece di 0.09). Era l'origine
|
||
della divergenza replay −44% vs reference +42% annotata nel TODO. La convenzione canonica
|
||
(backtest PORT06 via `_tr_basket_daily`) è equal-weight 1/N sull'universo: fix 1 riga
|
||
(`sum(rets)/len(universe)`). Replay post-fix: **TR01 +32% vs reference +42%** (stesso segno
|
||
e ordine di grandezza = gate del validatore; il residuo è la differenza dichiarata
|
||
capitale-unico vs media-equity). ROT02 +171%==ref, TSM01 +5%==ref invariati. Solo
|
||
statistica PAPER: nessun effetto su pool/ordini. NB: il forming-bar su ROT02/TSM01 segnato
|
||
nel TODO era GIÀ fixato (v1.1.10, `_panel` scarta la barra in formazione) — TODO aggiornato.
|
||
|
||
## Protezione 1 (pre-registrata): disaster-cap z sui pairs → **NO-GO**
|
||
|
||
Ipotesi: exit immediata se |z| ≥ z_stop dopo l'ingresso taglia la coda da structural-break
|
||
senza toccare i trade normali. Griglia fissata: z_stop {3.0,3.5,4.0,5.0} × 5 coppie 1h +
|
||
{2.5,3.0,3.5,4.0} sul 15m, train <2023-11-01 / OOS, engine con regression-lock ESATTO su
|
||
`pairs_sim`/`pairs_sim_flat`. Esito (potere statistico AMPIO, centinaia di trigger):
|
||
**bocciata su tutti e 3 i criteri** — il DD peggiora quasi ovunque, il worst-trade OOS
|
||
peggiora su 4 coppie su 6 (ETH/BTC −62→−168%!), Sharpe OOS cala oltre il −10% relativo in
|
||
TUTTE le celle, e il "plateau" esiste solo per il danno (monotono: più stretto, peggio).
|
||
Meccanismi: (i) lo stop realizza la perdita al massimo overshoot — il movimento che la
|
||
strategia fada (stessa lezione EXIT-16/SH01, **5ª conferma**); (ii) l'engine non-overlap
|
||
rientra subito nello spread ancora divergente → churn di fee a 2 gambe e stop ripetuti.
|
||
I pairs restano senza stop by design; la mitigazione resta la taglia
|
||
(`position_size_family` PAIRS 0.20). Record: `scripts/analysis/pairs_zstop_research.py`.
|
||
|
||
## Protezione 2 (pre-registrata): phase-tranching XS01 → **PROMOSSA e LIVE**
|
||
|
||
Diagnosi: il roll non-sovrapposto di XS01 ha una FASE arbitraria (dipende da quando il
|
||
worker parte) e l'esito ne dipende parecchio — sulle 12 fasi possibili: Sharpe daily FULL
|
||
1.52-2.33, DD per-trade 13.8-33.1% (`xs01_tranche_research.py`). È timing-luck puro: il
|
||
backtest canonico (fase 0) è una delle estrazioni FORTUNATE sul FULL (DD 15.4 vs mediana
|
||
~21). Rimedio senza parametri fittati: **ensemble di fase** — K sub-book sfasati di hold/K
|
||
barre su capitale comune (PnL/K). Gate onesto su equity daily (`xs01_tranche_gate.py`):
|
||
|
||
- standalone OOS: Sharpe 3.79→4.27 (K=2) →4.85 (K=3), DD 7.99→7.25→5.56;
|
||
- FULL standalone: il DD sale verso la mediana di fase (~21%) — il "peggioramento" è la
|
||
RIMOZIONE della fortuna della fase 0, non un costo;
|
||
- PORT06 swap-sleeve: FULL invariato (7.33/3.46), OOS Sh 10.07→10.11 (K=2) →10.15 (K=3),
|
||
OOS DD 1.48→1.43→1.38. **Plateau: K=2 E K=3 entrambi promossi** (non best-pick).
|
||
|
||
Implementazione: `CrossSectionalWorker` param `tranches` (default 1 = storico; live K=3 in
|
||
`_defs.py`), books indipendenti con sfasamento iniziale `wait`, capitale comune, migrazione
|
||
automatica dello status legacy (il vecchio book → tranche 0), `last_bar_ts` solo-avanti
|
||
(robustezza ai panel accorciati da feed in ritardo). Solo path LIVE come `disp_min` (il
|
||
backtest canonico resta single-phase → il confronto live/backtest va letto con la mediana
|
||
di fase in mente). **Validatore esteso e PASSATO**: K=1 replay == `xsec_sim` ESATTO
|
||
(1427 trade, cap 4993==4993); K=3 replay == unione fasi 0/4/8 ESATTO (4279 trade,
|
||
4512==4512). Osservabilità: `hourly_report` aggrega i sub-book nel book medio.
|
||
|
||
## Non toccati (per evidenza, non per pigrizia)
|
||
|
||
- **Fade/DIP01**: exit-lab già esaustivo (23+11 famiglie); plateau e parità riconfermati oggi.
|
||
- **SH01**: 11 famiglie di stop già bocciate; cap famiglia + monitor trade-rate in essere.
|
||
- **ROT02/TSM01**: replay == reference; forming-bar già fixato.
|
||
- **TR01 come sleeve** (3 anni negativi su 6): rimosso? NO — sarebbe una decisione guidata
|
||
dal regime recente (recency bias); il suo ruolo è catturare i trend che le fade non
|
||
prendono. Resta, con la statistica ora contabilizzata correttamente.
|
||
|
||
## Esito test
|
||
|
||
`pytest`: 99 passed. Validatori: honest workers OK, xsec K=1/K=3 OK, trendmax lock OK.
|