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:
@@ -141,6 +141,13 @@ def multi_asset_section() -> str:
|
||||
d = Path(sp).parent
|
||||
st = json.loads(Path(sp).read_text())
|
||||
book = st.get("positions") if "positions" in st else st.get("weights")
|
||||
if book is None and "books" in st:
|
||||
# XS01 tranched (2026-06-11): aggrega i sub-book in un book medio per-asset
|
||||
k = max(1, len(st["books"]))
|
||||
book = {}
|
||||
for b in st["books"]:
|
||||
for a, v in (b.get("weights") or {}).items():
|
||||
book[a] = book.get(a, 0.0) + v / k
|
||||
if book is None:
|
||||
continue # single-leg/pairs: gia' coperti da collect()
|
||||
held = {a: v for a, v in book.items() if v > 0}
|
||||
|
||||
Reference in New Issue
Block a user