chore(reset): v2.0.0 — storico certificato Deribit mainnet, ripartenza pulita
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>
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
# 2026-06-04 — EXIT LAB: ricerca massiva exit dinamiche (34 agenti) → EXIT-16 close-confirm SL PROMOSSO
|
||||
|
||||
## Obiettivo
|
||||
|
||||
Cercare exit migliori per le fade attive: TP dinamici, SL dinamici/protettivi,
|
||||
meccanismi per "cavalcare il prezzo". Mandato: ≥20 agenti con specifiche
|
||||
differenti, guardia anti-overfitting, test su tutto lo storico disponibile.
|
||||
|
||||
**Esito in una riga: "cavalcare" non esiste (17ª conferma), ma la ricerca ha
|
||||
trovato una cosa più grossa — LO STOP-LOSS INTRABAR FISSO È IL COMPONENTE CHE
|
||||
DISTRUGGE PIÙ VALORE NELLE FADE, e la forma robusta del fix (SL confermato in
|
||||
chiusura, EXIT-16) è PROMOSSA a livello PORT06: OOS Sharpe 8.82→10.06,
|
||||
FULL DD 4.10→2.60.**
|
||||
|
||||
## Infrastruttura (riusabile)
|
||||
|
||||
- `scripts/analysis/exit_lab.py` — harness CONDIVISO: cache segnali live-params
|
||||
delle 3 fade (`data/cache/exit_lab_signals.pkl`, 73.6k barre 1h 2018→2026-05,
|
||||
BTC+ETH), engine intrabar identico a `fade_base` (parità verificata al punto
|
||||
percentuale su tutti e 6 gli sleeve), contratto anti-look-ahead esplicito
|
||||
(`levels(j)` solo dati ≤ j-1; `after_bar(j)` sul close = eseguibile al poll),
|
||||
protocollo train/OOS (selezione parametri SOLO su pre-2023-11; OOS letto una
|
||||
volta), fill parziali, `ExitPolicy` pluggable.
|
||||
- `scripts/analysis/exit_policies/` — 23 policy + 10 script di verifica.
|
||||
- `scripts/analysis/exit16_port06_impact.py` — replay canonico `build_trades`/
|
||||
`fade_daily_equity` con parità ESATTA (corr 1.00000) + innesto EXIT-16 +
|
||||
ricalcolo PORT06 (cap pairs 0.33, leva 2x).
|
||||
|
||||
## Fase 1 — Explore: 23 agenti, una famiglia ciascuno
|
||||
|
||||
Tally: **3 PROMISING, 5 NEUTRAL, 15 REJECT.**
|
||||
|
||||
REJECT (la famiglia "cavalca il prezzo" è stata falcidiata): trail_atr_ride,
|
||||
trail_pct, breakeven, sar_trail, tp_decay, tp_extend_momentum, tp_moving_mean,
|
||||
partial_tp_trail, hurst_exit, giveback, loser_timestop, donchian_trail,
|
||||
ema_cross_exit, vol_rescale, sl_tp_ride. Autopsia ricorrente: **il TP delle
|
||||
fade sta ALLA MEDIA; lì il movimento è esaurito per costruzione → oltre quel
|
||||
punto non c'è coda da cavalcare** (il runner finiva oltre il TP ~3% delle
|
||||
volte). Caso da manuale `trail_atr_ride`: train 5/6 a favore, **OOS 0/6**
|
||||
(MR01 ETH ret 134%→1%) — senza l'embargo train/OOS l'avremmo promosso.
|
||||
|
||||
NEUTRAL: ratchet, sl_tighten, z_overshoot, wide_sl_trail, swing_stop
|
||||
(miglioramenti misti, mai 5/6).
|
||||
|
||||
PROMISING — tre meccanismi diversi, UNA stessa tesi ("gli stop intrabar da
|
||||
wick sono falsi negativi: l'overshoot che buca lo stop è esattamente ciò che
|
||||
la fade vuole fadare, e rientra"):
|
||||
- **EXIT-02 trail_atr_keep_tp** (chandelier k=1.5 + TP fisso): 6/6 train, 5/6 OOS.
|
||||
- **EXIT-16 close_confirm_sl** (SL solo se la barra CHIUDE oltre sl0±0.5·ATR):
|
||||
**6/6 train E 6/6 OOS**, plateau.
|
||||
- **EXIT-22 no_sl** (diagnostica: SL rimosso): 6/6+6/6, plateau monotono
|
||||
perfetto `SL stretto < base < SL 2x < niente SL`.
|
||||
|
||||
## Fase 2 — Verify: 10 avversari (leakage / overfit / stress × 3 + tail-risk)
|
||||
|
||||
- **EXIT-02 CONFUTATO (2/3).** (a) Overfit: è **Pareto-dominato da no_sl a
|
||||
ZERO parametri** su tutti i 6 sleeve OOS (Sharpe base→trail→noSL: MR01 BTC
|
||||
2.77→3.08→5.67; MR02 ETH 12.35→11.41→17.24 — il trail PEGGIORA lo sleeve di
|
||||
punta) → overfit di selezione: la forma parametrizzata sbagliata di una tesi
|
||||
giusta. (b) Leakage: codice pulito MA **scoperta di metodo: il 54% degli
|
||||
stop del trail è GAP-THROUGH** (l'open del bar è già oltre il livello;
|
||||
gap mediano 62-174 bps): l'engine che filla gli stop "al livello" SOVRASTIMA
|
||||
ogni policy a stop stretti; col fill realistico `worse(level, open)` il
|
||||
confronto si ribalta. **Da oggi ogni ricerca con stop tight deve modellare
|
||||
il gap-through.** Lo SL largo della base ne è quasi immune.
|
||||
- **EXIT-16 SUPERA 4/4.** Leakage: contratto pulito, robusto a 1-3 bar di lag
|
||||
e al fill a `open[j+1]` (esce deliberatamente tardi → il timing fine è
|
||||
irrilevante per costruzione). Overfit: plateau monotono su buffer 0.4→1.0
|
||||
FUORI griglia, il ponte SL-largo k=1.5→4 converge, 4 finestre temporali ok,
|
||||
e **indipendente dal loss-guard Hurst** (segnali rigenerati senza guard:
|
||||
la tesi regge anche nel regime trending). Stress: fee 2x 6/6, slippage
|
||||
20 bps simmetrico 6/6, bear 2021-22 ok.
|
||||
- **EXIT-22 invalidato SENZA mitigazione (tail-risk).** p99 MAE ~raddoppia
|
||||
(MR01 ETH −38.8→−59.7%); finestra FTX 2022-11: MR02 ETH **−39% (worst −48%,
|
||||
MAE −70%)** dove la base faceva +2.7% uscendo in 2-3 barre. E un fatto di
|
||||
wiring: con `sl=0` il worker cade nel ramo `elif max_bars` → **il fallback
|
||||
−2% è codice morto: no_sl live girerebbe SENZA ALCUNO stop**. Il disaster-SL
|
||||
4× tiene ~95% del ritorno ma il worst pooled resta −47%.
|
||||
- **Raccomandazione convergente del tail-auditor: EXIT-16** — neutralizza
|
||||
quasi tutta la coda DA SOLO (p99/worst ≈ base; FTX: +2.4%) mantenendo
|
||||
l'immunità ai wick. Mai usare uno stop stretto −2% come fallback (cappa
|
||||
l'edge insieme alla coda).
|
||||
|
||||
## Fase 3 — Test decisivo a livello PORT06 (path canonico)
|
||||
|
||||
Replay di `build_trades`/`fade_daily_equity` con **parità ESATTA** (corr
|
||||
1.00000, ritorni identici, PORT06 base == `Portfolio.backtest()` al centesimo:
|
||||
FULL 6.47/4.10%, OOS 8.82/1.30% — i numeri 6.07/8.19 citati in CLAUDE.md sono
|
||||
pre-refresh-dati). Poi SOLO il ramo SL sostituito col close-confirm 0.5·ATR:
|
||||
|
||||
| PORT06 | FULL Sharpe | FULL DD | FULL CAGR | OOS Sharpe | OOS DD | OOS CAGR |
|
||||
|--------|------------|---------|-----------|-----------|--------|----------|
|
||||
| base | 6.47 | 4.10% | 61% | 8.82 | 1.30% | 86% |
|
||||
| **EXIT-16** | **7.84** | **2.60%** | **79%** | **10.06** | **1.15%** | **102%** |
|
||||
|
||||
Gate (lo stesso del loss-guard Hurst): **PROMOSSO** — migliora OGNI metrica,
|
||||
FULL e OOS. Per-sleeve: ritorni FULL ~4-10x (MR01 BTC 299→1963%) e DD giù su
|
||||
5/6 (eccezione MR02 ETH +3.4pp, assorbita in aggregato).
|
||||
|
||||
## Verdetto e piano di deploy (DA FARE, non ancora implementato)
|
||||
|
||||
**EXIT-16 close_confirm_sl, buffer 0.5·ATR14, SOLO sulle 6 fade.**
|
||||
1. Param `sl_confirm_atr=0.5` nelle fade (default None = comportamento
|
||||
attuale, per non rompere i backtest canonici/regression-lock).
|
||||
2. `FadeStrategy.backtest` + `StrategyWorker.tick`: disattivare l'uscita
|
||||
intrabar a sl0; aggiungere il ramo sul CLOSE del bar (long: esci se
|
||||
`close < sl0 − 0.5·ATR14`; short speculare). TP intrabar e max_bars
|
||||
INVARIATI. ATR14 causale già disponibile.
|
||||
3. Shadow reale: nessun nuovo tipo d'ordine (il close-confirm esce al close
|
||||
del worker → market reduce-only come oggi; il limit resting al TP di
|
||||
v1.0.7 resta identico).
|
||||
4. DIP01/pairs/rotation/tsmom/shape NON toccati.
|
||||
|
||||
## Caveat onesti
|
||||
|
||||
- L'uscita al close può essere PEGGIO di sl0 sui veri sfondamenti (già nei
|
||||
numeri del backtest, ma la coda dipende dai gap: campione 1h crypto,
|
||||
stress estremi sottorappresentati).
|
||||
- Niente stop fisico sul book → rischio gap/disconnessione fra i poll
|
||||
(mitigazione possibile in futuro: disaster-SL intrabar a 4× come cintura,
|
||||
costa ~5% del guadagno).
|
||||
- avg_bars +~18% (esposizione su; già nei numeri via non-overlap).
|
||||
- I numeri per-sleeve FULL (ret 4-10x) vanno letti col solito sconto del
|
||||
compounding su 8 anni; la decisione è presa sul gate PORT06, non su quelli.
|
||||
|
||||
## Scoperte collaterali da NON perdere
|
||||
|
||||
1. **Gap-through fill**: l'engine intrabar filla gli stop al livello anche
|
||||
quando l'open è già oltre → bias sistematico PRO stop-stretti. Aggiungere
|
||||
il fill `worse(level, open)` all'harness prima di future ricerche su stop.
|
||||
2. **Wiring worker**: una strategia con `sl=0`+`max_bars` gira nel ramo
|
||||
`elif max_bars` → il fallback −2% non si applica. Oggi nessuna strategia
|
||||
attiva emette sl=0, ma il ramo va reso esplicito se mai si deployasse
|
||||
una policy senza SL.
|
||||
3. Il prior ladder di stamattina è confermato e generalizzato: 4 conferme
|
||||
indipendenti che oltre il TP non c'è nulla da cavalcare.
|
||||
|
||||
## Costi della ricerca
|
||||
|
||||
34 agenti (23 explore + 10 verify + 1 PORT06), ~1.65M token subagente,
|
||||
~70 minuti wall-clock su 2 core. Workflow: `exit-policy-explore`
|
||||
(wf_4b23e922-f48) + `exit-policy-verify` (wf_f2bb98df-c43).
|
||||
|
||||
## IMPLEMENTATO E DEPLOYATO (sera stessa, v1.1.0)
|
||||
|
||||
Param `sl_confirm_atr` (default None = comportamento storico):
|
||||
- `src/strategies/fade_base.py` `FadeStrategy.backtest` + `scripts/strategies/
|
||||
MR01_bollinger_fade.py` (ha un backtest proprio, duplicato storico — patch
|
||||
identica): ramo close-confirm al posto dell'SL intrabar; TP intrabar e
|
||||
max_bars invariati; in modalità confirm il TP ha priorità nel bar (come la
|
||||
policy validata in exit_lab).
|
||||
- `src/live/strategy_worker.py` `tick`: con `sl_confirm_atr` nei params dello
|
||||
sleeve, TP intrabar al livello come prima; stop SOLO se `close` sfonda
|
||||
`sl ∓ buf·ATR14(df)`, uscita al prezzo corrente (reason `stop_loss`
|
||||
invariata → il monitor stop-rate di `hourly_report` continua a funzionare).
|
||||
- `scripts/portfolios/_defs.py`: `SL_CONFIRM_ATR = 0.5` sulle 6 fade (path
|
||||
live, come `hurst_max`). Il backtest canonico resta NON filtrato.
|
||||
- Test: `tests/portfolio/test_close_confirm_sl.py` (wick non stoppa; breach
|
||||
sul close stoppa al close; TP intrabar resta; buffer regge; regressione
|
||||
senza param). 59/59 verdi.
|
||||
|
||||
**Nota onesta dal sanity-check sul path GREZZO (nessun filtro):** il ritorno
|
||||
esplode (MR02 ETH cap 366k→3.0M) ma il **DD per-sleeve SALE** (MR01 BTC
|
||||
32→52%): senza trend-filter/hurst il close-confirm tiene posizione anche nei
|
||||
trend profondi. La riduzione di DD vive nella config live (trend_max 3.0 +
|
||||
hurst 0.55) e nella diversificazione — esattamente ciò che il test PORT06
|
||||
canonico ha misurato (DD 4.10→2.60). Le tre protezioni sono COMPLEMENTARI:
|
||||
hurst toglie l'esposizione al regime tossico, il trend-filter gli ingressi
|
||||
sovra-estesi, il close-confirm i falsi stop da wick.
|
||||
|
||||
**Monitoraggio live:** lo stop-rate fade su `hourly_report` dovrebbe scendere
|
||||
sotto il ~38% atteso post-hurst; gli stop avranno exit leggermente oltre il
|
||||
livello (uscita al close), i TP restano al livello (e nello shadow reale al
|
||||
limit reduce-only di v1.0.7).
|
||||
|
||||
Deploy: commit `a2579d2` (+ research `ad65a0b`), release v1.1.0.
|
||||
Reference in New Issue
Block a user