# 2026-06-13 — Dashboard web PORT06 (stato live + PnL + grafici + trade) Richiesta utente: frontend per visualizzare lo stato con PnL totale e per-strategia, grafici, e liste trade (attivi in tempo reale + chiusi). ## Cosa `src/live/dashboard.py` — server **stdlib `http.server`** (zero nuove dipendenze), legge i file `data/` e serve: - `GET /api/state` → JSON con tutto lo stato calcolato - `GET /` → single-page HTML (vanilla JS, polling ogni 5s) Contenuto della pagina: - **KPI**: equity, PnL totale (€ e %), max DD, peak - **Grafico equity** (Chart.js da CDN, fallback testuale se offline) dalla `equity.jsonl` del ledger (downsample a 400 punti) - **PnL per strategia** (barre verdi/rosse): realizzato netto fee = Σ `pnl` reali dai CLOSE (REAL-TRUTH), n trade, win-rate, capitale; tag `paper` per i multi-asset non eseguiti, `•aperta` se in posizione - **Trade attivi in tempo reale**: lato, entry, **mark corrente** (Cerbero best-effort, cache 20s), **PnL non realizzato** (€ e %, da `real_entry_notional`), barre/max_bars, distanza al TP, età dello status (⚠ se >15min = stantio) - **Trade chiusi** (ultimi 50): ora, strategia, motivo, PnL reale, sim, esito ## Deploy Servizio docker-compose `dashboard` (stessa immagine del runner, monta gli stessi `data/`, porta **8787**), `restart: unless-stopped` + healthcheck sull'API. Accesso: `http://:8787`. **Nessuna auth** → solo rete interna/VPN, non esporre pubblicamente. Avvio: `docker compose up -d --build dashboard` (il runner non viene toccato). uv run python -m src.live.dashboard --port 8787 # anche standalone su host ## Note - Il PnL per-strategia usa il PnL REALE (real_truth), coerente col report orario. - I 6 fade 1h ritirati dallo swap restano in lista (hanno storico CLOSE): flat, mostrano il loro PnL realizzato storico accanto ai gemelli 15m attivi. - Unrealized € sui pairs non mostrato (posizione a 2 gambe, z-based) → "pairs (z)".