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"