diff --git a/src/live/dashboard.py b/src/live/dashboard.py index be670f0..944c2ae 100644 --- a/src/live/dashboard.py +++ b/src/live/dashboard.py @@ -15,7 +15,7 @@ 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.live.shadow import shadow_report +from src.live.shadow import shadow_report, tp01_trades from src.version import APP_VERSION PAPER = PROJECT_ROOT / "data" / "paper_portfolio" / "state.json" @@ -37,12 +37,16 @@ def build(): shadow = shadow_report() # mainnet sola lettura, best-effort except Exception as e: shadow = {"error": f"{type(e).__name__}: {e}"} + try: + trades = tp01_trades(limit=15) # entry/exit TP01 dal segnale causale + except Exception: + trades = [] data = dict( version=APP_VERSION, last_data=str(idx[-1].date()), 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, shadow=shadow, + positions=pf.current_positions(), spark=spark, paper=paper, shadow=shadow, trades=trades, bh=None, ) _CACHE.update(t=time.time(), data=data) @@ -99,6 +103,15 @@ def html(): f"TP01 target: {bits}
→ per gli ordini reali: uv run python scripts/live/live_trend.py (host)") else: shadow_html = "non disponibile" + (f" — {sh['error']}" if sh and sh.get('error') else "") + trows = "" + for t in d.get("trades", []): + cls = "g" if t["action"] == "ENTRY" else "r" + trows += (f"{t['date']}{t['asset']}" + f"{t['action']}" + f"{t['from_pos']:+.2f} → {t['to_pos']:+.2f}x" + f"${t['price']:,.0f}") + if not trows: + trows = "nessun trade ancora (TP01 flat / in cash)" return f""" PythagorasGoal — Portafoglio