feat(dashboard): pannello COMBO cross-venue (TP01 Deribit + GTAA IB)
Aggiunge alla dashboard la sezione "COMBO DEPLOYABLE — cross-venue (paper)": equity paper forward del blend 50/50 TP01+GTAA (da data/paper_combo/state.json) + posizioni azionabili IB correnti (gtaa_weights: peso ETF + cash, asof). Nota onesta: paper rischio-zero, Sharpe ~1.5 ottimistico, il robusto e' la diversificazione (corr 0.21, DD dimezzato); XS01/VRP01 esclusi (STAT-MODE). Container ricostruito (codice baked nell'immagine). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -15,11 +15,13 @@ sys.path.insert(0, str(PROJECT_ROOT))
|
||||
import numpy as np, pandas as pd
|
||||
from src.portfolio.portfolio import StrategyPortfolio, metrics, HOLDOUT
|
||||
from src.portfolio.sleeves import active_sleeves
|
||||
from src.portfolio.gtaa import gtaa_weights
|
||||
from src.live.shadow import shadow_report, tp01_trades
|
||||
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"
|
||||
_CACHE = {"t": 0.0, "data": None}
|
||||
_TTL = 120.0
|
||||
|
||||
@@ -35,6 +37,11 @@ def build():
|
||||
spark = [(str(idx[i].date()), float(eq[i])) for i in range(0, len(eq), step)]
|
||||
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
|
||||
try:
|
||||
gtaa_w = gtaa_weights() # pesi ETF correnti azionabili (cache eq_*)
|
||||
except Exception:
|
||||
gtaa_w = None
|
||||
try:
|
||||
shadow = shadow_report() # mainnet sola lettura, best-effort
|
||||
except Exception as e:
|
||||
@@ -49,6 +56,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,
|
||||
shadow=shadow, trades=trades, bh=None,
|
||||
)
|
||||
_CACHE.update(t=time.time(), data=data)
|
||||
@@ -104,6 +112,24 @@ def html():
|
||||
f"forward da {pd.Timestamp(pv['start_ts'], unit='ms').date()}")
|
||||
else:
|
||||
prevday_html = "non inizializzato (gira <code>scripts/live/paper_prevday.py</code>)"
|
||||
cb = d.get("combo")
|
||||
if cb:
|
||||
cdays = (pd.Timestamp(cb["last"]) - pd.Timestamp(cb["start"])).days
|
||||
cret = cb["equity"] / cb["initial"] - 1
|
||||
wc = cb.get("w_crypto", 0.5)
|
||||
combo_html = (f"<b>{cb['equity']:.2f}</b> (start {cb['initial']:.0f}, {cb['start'][:10]} → "
|
||||
f"{cb['last'][:10]}, {cdays}g, {cb['n_days']} barre) ret <b>{cret*100:+.2f}%</b> "
|
||||
f" maxDD {cb['max_dd']*100:.1f}% blend {wc*100:.0f}/{(1-wc)*100:.0f} TP01/GTAA")
|
||||
else:
|
||||
combo_html = "non inizializzato (gira <code>scripts/live/paper_combo.py</code>)"
|
||||
gw = d.get("gtaa_weights")
|
||||
if gw:
|
||||
asof = gw.get("_asof", "?"); cash = gw.get("_cash")
|
||||
gw_html = (", ".join(f"{k} <b>{v:.0%}</b>" for k, v in gw.items() if not k.startswith("_") and v)
|
||||
+ (f" · cash <b>{cash:.0%}</b>" if cash is not None else "")
|
||||
+ f" <span style='color:#8a93a0'>(asof {asof})</span>")
|
||||
else:
|
||||
gw_html = "n/d (cache ETF assente — gira fetch_ib_equities.py)"
|
||||
sh = d.get("shadow")
|
||||
if sh and "error" not in sh:
|
||||
bits = " · ".join(
|
||||
@@ -175,6 +201,10 @@ th{{color:#8a93a0;font-weight:500}}.y{{display:inline-block;background:#161b22;b
|
||||
<h3 style="font-size:14px;color:#8a93a0">Trades TP01 — entry/exit (segnale causale, ultimi 15)</h3>
|
||||
<table><tr><th>data</th><th>asset</th><th>azione</th><th>posizione</th><th>prezzo</th></tr>{trows}</table>
|
||||
<div style="margin-top:10px">{yrs}</div>
|
||||
<div class="section">COMBO DEPLOYABLE — cross-venue (paper, forward-only)</div>
|
||||
<div class=box><b>TP01 (Deribit) + GTAA (IB)</b> — le DUE gambe ESEGUIBILI a basso capitale, scorrelate (corr ~0.21) → blend Sharpe ~1.5, drawdown dimezzato. <b>Nessuna esecuzione reale</b>:<br>{combo_html}<br>
|
||||
<span style="color:#8a93a0;font-size:13px">posizioni azionabili IB (GTAA, peso ETF):</span> {gw_html}</div>
|
||||
<p class=warn>⚠️ PAPER cross-venue: valida l'operativita' su due conti (Deribit + IB) a rischio zero. Lo Sharpe ~1.5 e' ottimistico (finestra crypto corta/favorevole); il dato robusto e' la diversificazione (corr 0.21, DD dimezzato), non il livello. XS01/VRP01 esclusi (STAT-MODE): qui solo TP01+GTAA.</p>
|
||||
<div class="section">FORWARD-MONITOR — lead paper (non deploy)</div>
|
||||
<div class=box><b>PREVDAY range-breakout</b> — lead ORTOGONALE a TP01 (corr ~0.15 full / ~0 hold; marginal ADDS, non-hedge, robusto allo shift del confine-giorno). Forward-only, <b>nessuna esecuzione reale</b>:<br>{prevday_html}</div>
|
||||
<p class=warn>⚠️ 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.</p>
|
||||
|
||||
Reference in New Issue
Block a user