feat(stability): sweep stabilità — fix TR01 mean(rets), XS01 phase-tranching K=3, z-stop pairs bocciato

Audit anti-overfit su tutte le 19 sleeve (diario 2026-06-11-stability-sweep.md):

- FIX BasketTrendWorker: mean(rets) sui soli asset in posizione sovrappesava N/k
  a paniere parziale (1 long = 0.45 del capitale invece di 0.09) -> replay -44%
  vs ref +42%. Ora sum(rets)/N (convenzione canonica 1/N): replay +32% vs +42%
  (residuo = convenzione dichiarata). Solo statistica PAPER.
- XS01 PHASE-TRANCHING (gate xs01_tranche_gate: plateau K=2 E K=3 promossi,
  PORT06 OOS Sh 10.07->10.15 DD 1.48->1.38, FULL pari): la fase del roll e'
  timing-luck (Sharpe daily 1.52-2.33, DD 13.8-33% sulle 12 fasi). Worker con
  param tranches (default 1), 3 sub-book sfasati hold/3 su capitale comune,
  migrazione status legacy, last_bar_ts solo-avanti; runner forward del param;
  _defs tranches=3; hourly_report aggrega i sub-book; validatore esteso e
  PASSATO (K=1 == xsec_sim esatto, K=3 == unione fasi esatto).
- Disaster-cap z sui pairs: pre-registrato e BOCCIATO su tutti i criteri (coda
  OOS peggiora 4/6 coppie, Sharpe -10..-49%, plateau solo del danno; 5a conferma
  stop-su-MR). Record pairs_zstop_research.py; pairs restano senza stop.
- Audit drift: regression-lock trendmax OK (parita' 1.00000, plateau 2.5/3.0/3.5
  confermato), correlazioni cross-famiglia ~0 invariate; PORT06 rolling al
  19-28mo pct (normale) ma FADE 120g al 2o percentile storico -> monitor in TODO
  (nessun ritocco parametri).
- TODO: forming-bar ROT02/TSM01 era gia' fixato (v1.1.10), item chiuso.

Test: pytest 99 passed; validate_honest_workers OK; validate_xsec_worker OK.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-06-11 13:29:14 +00:00
parent ba5ec7bd6b
commit 9d15506b05
12 changed files with 693 additions and 72 deletions
+13 -9
View File
@@ -39,20 +39,18 @@
## Follow-up dal code-review (bassa priorità, non urgenti)
- [ ] **forming-bar su ROT02/TSM01**: i worker daily valutano la candela 1d IN FORMAZIONE al primo
poll dopo mezzanotte UTC (stessa classe del fix TR01/Pairs, pre-esistente). Ora è banale:
usare `src.live.bars.last_settled_idx` in `_panel` / nei due tick. Impatto basso (1d) ma
stessa famiglia di bug.
- [x] ~~forming-bar su ROT02/TSM01~~ — GIÀ FIXATO (v1.1.10, 2026-06-08): `_panel` condiviso
scarta la barra in formazione via `last_bar_is_forming`. Item rimasto stantio nel TODO.
- [ ] **ancora bfill di `_daily_equity`**: la serie a punti-trade reindexata su IDX àncora il primo
valore della finestra al PRIMO trade in-finestra, non al capitale portato avanti. Tocca le
metriche canoniche di TUTTI gli sleeve a punti-trade (honest/pairs/tsm). Valutare se
correggere OVUNQUE in un colpo (cambierebbe i numeri canonici di riferimento). Scoperto nel
gate DIP01 (parità inizialmente fallita per questo).
- [ ] **convenzione TR01 worker vs reference**: il replay `validate_honest_workers` dà TR01 worker
-44% vs reference +42% (identico pre/post fix di oggi). È la divergenza capitale-unico
(`mean(rets)` solo sugli asset in posizione) vs media-equity 1/N del reference. Indagare:
sospetto che `mean(rets)` sovrappesi gli asset in posizione quando il paniere è parzialmente
investito.
- [x] ~~convenzione TR01 worker vs reference~~ — ERA UN BUG, FIXATO (2026-06-11): `mean(rets)`
sui soli asset in posizione sovrappesava N/k a paniere parziale (con 1 long: 0.45 del
capitale invece di 0.09). Fix: `sum(rets)/len(universe)` (equal-weight 1/N canonico).
Replay post-fix: +32% vs reference +42% (residuo = convenzione capitale-unico vs
media-equity, dichiarata). Diario `2026-06-11-stability-sweep.md`.
- [ ] **engine duplicato nei 3 gate** `*_port06_impact.py` (exit16/trendmax/dip01): `build_trades_variant`
/ `port_metrics` copiati quasi verbatim. Sono regression-lock per decisioni live → la
copy-drift corrompe i verdetti. Fattorizzare in un modulo condiviso.
@@ -68,6 +66,12 @@
## Monitoraggio (osservare, non agire subito)
- [ ] **FADE in coda storica (2026-06-11)**: il rolling 120g equal-weight delle 6 fade è al
**2° percentile** della propria storia (1.0% vs p5 +0.4%); il PORT06 complessivo resta
in variazione normale (19-28° pct). NESSUN ritocco parametri (= fit sul regime corrente);
osservare se rientra. Follow-up tecnico: alert di drift per-FAMIGLIA nel `hourly_report`
(precomputare la distribuzione storica dei rolling-return di famiglia dal backtest
canonico → confrontare il rolling live; notifica sotto p5).
- [ ] **PnL live post-swap trend** (epoca TREND in `hourly_report`): verdetto stop-rate fade a n>=30.
- [ ] **SH01 post-bootstrap**: il trade-rate live deve scendere da ~25% a ~10% delle barre
(selettività della soglia ripristinata). Controllare nel report orario.