"""Ri-validazione SH01 col train-window del REGIME LIVE (sweep punto 10). Diagnosi (improvement-sweep 2026-06-06): tutta la validazione SH01 (`shape_ml_validate.py`) usa training EXPANDING full-history (~73k barre dal 2018), ma il worker live fetcha solo `_ML_LOOKBACK_DAYS=365` (~8760 barre 1h) -> la LogReg allenata su train piccolo e' OVER-CONFIDENT: frac(proba>=0.58) 44.8% vs 3.8%, trade-rate live 25.1% delle barre vs 2.9% validato, WR live 1/9. La soglia th=0.58 e' di fatto inerte nel regime live. Questo harness misura l'edge SH01 (W24 H12 logit th0.58, protocollo explore_lab: FULL / OOS ultimo 30% / sweep fee / anni positivi) in funzione del train-window ROLLING (`ml_wf_entries(train_window=...)`): 8760 = regime live ATTUALE (365g) <- la validazione mai fatta 17520 = 2 anni (gia' noto: BTC regge, +166%/+96%) 26280 = 3 anni None = EXPANDING full-history <- la validazione canonica (riferimento) + diagnostica trade-rate per variante e, per il regime live, sweep della soglia (SOLO diagnostica: la lezione del sweep e' di NON ri-tunare th a forza — se l'edge non sopravvive a 8760 la risposta e' cambiare il regime di training del live, non la soglia). Esiti possibili: a) edge OK a 8760 -> il live va bene cosi' (e la diagnosi WR 1/9 e' altro); b) edge OK da un lookback X > 8760 -> portare il train live a X (bootstrap storico dal parquet locale + append feed, o lookback maggiore); c) edge solo expanding -> bootstrap parquet full-history o riconsiderare SH01. uv run python scripts/analysis/sh01_trainwindow_validate.py """ from __future__ import annotations import sys from pathlib import Path PROJECT_ROOT = Path(__file__).resolve().parents[2] sys.path.insert(0, str(PROJECT_ROOT)) from scripts.analysis.explore_lab import get_df, evaluate, robust # noqa: E402 from scripts.analysis.shape_ml_research import ml_wf_entries # noqa: E402 CFG = dict(W=24, H=12, model="logit", thresh=0.58) WINDOWS = [8760, 17520, 26280, None] # None = expanding (canonico) TH_DIAG = [0.58, 0.62, 0.66, 0.70] # sweep soglia SOLO per il regime live def main(): print("=" * 108) print(" SH01 — edge vs train-window ROLLING (W24 H12 logit th0.58, protocollo explore_lab)") print(" regime live = 8760 barre (365g); canonico = expanding full-history") print("=" * 108) for asset in ("BTC", "ETH"): df = get_df(asset, "1h") nbars = len(df) print(f"\n--- {asset} ({nbars} barre 1h) ---") for tw in WINDOWS: tag = f"tw={tw}" if tw else "EXPANDING" ents = ml_wf_entries(df, train_window=tw, **CFG) rate = len(ents) / nbars * 100 print(f" [{tag:<10s}] trade-rate {rate:4.1f}% delle barre") res = evaluate(f"{asset} {tag}", ents, df) print(f" -> {'ROBUSTO' if robust(res) else 'NON robusto'}") print(f"\n diagnostica soglia nel REGIME LIVE (tw=8760), {asset}:") for th in TH_DIAG: ents = ml_wf_entries(df, train_window=8760, **{**CFG, "thresh": th}) rate = len(ents) / nbars * 100 print(f" [th={th:<5}] trade-rate {rate:4.1f}%") evaluate(f"{asset} tw8760 th{th}", ents, df) if __name__ == "__main__": main()