diff --git a/src/live/dashboard.py b/src/live/dashboard.py
index 02a493b..7fbf77d 100644
--- a/src/live/dashboard.py
+++ b/src/live/dashboard.py
@@ -22,6 +22,7 @@ from src.version import APP_VERSION
PAPER = PROJECT_ROOT / "data" / "paper_portfolio" / "state.json"
PREVDAY = PROJECT_ROOT / "data" / "paper_prevday" / "state.json"
COMBO = PROJECT_ROOT / "data" / "paper_combo" / "state.json"
+STATARB = PROJECT_ROOT / "data" / "paper_statarb" / "state.json"
_CACHE = {"t": 0.0, "data": None}
_TTL = 120.0
@@ -53,6 +54,7 @@ def build():
paper = json.loads(PAPER.read_text()) if PAPER.exists() else None
prevday = json.loads(PREVDAY.read_text()) if PREVDAY.exists() else None
combo = json.loads(COMBO.read_text()) if COMBO.exists() else None
+ statarb = json.loads(STATARB.read_text()) if STATARB.exists() else None
try:
gtaa_w = gtaa_weights() # pesi ETF correnti azionabili (cache eq_*)
except Exception:
@@ -75,7 +77,7 @@ def build():
full=bt["full"], holdout=bt["holdout"], weights=bt["weights"],
per_sleeve=bt["per_sleeve"], yearly=bt["yearly"],
positions=pf.current_positions(), spark=spark, paper=paper, prevday=prevday,
- combo=combo, gtaa_weights=gtaa_w, deribit=deribit,
+ combo=combo, statarb=statarb, gtaa_weights=gtaa_w, deribit=deribit,
shadow=shadow, trades=trades, freq=freq, bh=None,
)
_CACHE.update(t=time.time(), data=data)
@@ -143,6 +145,22 @@ def html():
f"forward da {pd.Timestamp(pv['start_ts'], unit='ms').date()}")
else:
prevday_html = "non inizializzato (gira scripts/live/paper_prevday.py)"
+ sa = d.get("statarb")
+ if sa:
+ days = (sa["last_ts"] - sa["start_ts"]) / 86400_000
+ rm = sa["cap_modeled"] / 2000.0 - 1
+ rr = sa["cap_real"] / 600.0 - 1
+ statarb_html = (
+ f"${sa['cap_modeled']:,.2f} modeled (€2k nom.) · "
+ f"${sa['cap_real']:,.2f} real-$600 (min-order $5)
"
+ f"ret {rm*100:+.2f}% / {rr*100:+.2f}% · "
+ f"maxDD {sa['dd_modeled']*100:.1f}% / {sa['dd_real']*100:.1f}% · "
+ f"fill-haircut {(rm-rr)*100:+.2f}pp
"
+ f"posizione spread (long ETH / short BTC per unità): {sa['pos_real']:+.3f} · "
+ f"{sa['n_bars']} barre 1d (~{days:.0f}g) · {sa['n_trades']} flip · "
+ f"forward da {pd.Timestamp(sa['start_ts'], unit='ms').date()}")
+ else:
+ statarb_html = "non inizializzato (gira scripts/live/paper_statarb.py)"
cb = d.get("combo")
if cb:
cdays = (pd.Timestamp(cb["last"]) - pd.Timestamp(cb["start"])).days
@@ -288,7 +306,8 @@ th{{color:#8a93a0;font-weight:500}}.y{{display:inline-block;background:#161b22;b
⚠️ Accumulo = proiezione condizionata (storico bull crypto → pianifica sul conservativo); nessuna leva; SKH01 research/forward-monitor (solo TP01 armato live). A €50/g servono ~€177k @conservativo: la via è capitale+tempo, non leva.
⚠️ LEAD in osservazione, NON deployato. Sopravvissuto alla verifica avversariale dell'onda intraday; lo teniamo in paper per validarlo fuori-campione-vero. I due libri (modeled vs real-$600) mostrano l'haircut di fill che lo scettico aveva segnalato.
+⚠️ LEAD in osservazione, NON deployati. PREVDAY è sopravvissuto alla verifica avversariale dell'onda intraday. STATARB-RESID (sweep 5-thread 2026-06-29) rompe i muri di ortogonalità ed eseguibilità ma resta sotto il deflated-Sharpe (Sharpe ~0.84, DSR <0.95 su storia ~2.5 anni) → il forward serve a confermare l'edge fuori-campione-vero prima di un eventuale deploy a 2 gambe. I due libri (modeled vs real-$600) mostrano l'haircut di fill (atteso ~0 a 1d).
⚠️ Paper/monitor. XS01 e' STAT-MODE (book a 19 gambe market-neutral, non eseguibile a €2k, storia ~2.5 anni). VRP01 = lead short-vol MODELLATO (non deploy pieno). SKH01 (Skyhook dual-TF regime+breakout, BTC/ETH) = diversificatore quasi-ortogonale (corr ~0.09) aggiunto @25%: alza il FULL Sharpe del portafoglio 1.68→2.13 e dimezza il DD (14→8%) — RESEARCH/forward-monitor (book a 230m, causalita' verificata su harness ma costi reali e codice d'esecuzione da validare prima del deploy). TP01 e' l'unico deployable pieno.