feat(dashboard): frontend web PORT06 — stato live, PnL totale/per-strategia, grafici, trade

Server stdlib http.server (zero dipendenze nuove) che legge data/: KPI equity/PnL/DD,
grafico equity (Chart.js CDN + fallback), PnL per-strategia (barre, realizzato reale),
trade attivi in TEMPO REALE (mark Cerbero best-effort, PnL non realizzato, barre, eta
stantio) e chiusi (ultimi 50). Servizio docker-compose 'dashboard' porta 8787, stessa
immagine, monta data/, restart unless-stopped + healthcheck. Nessuna auth -> rete interna.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-06-13 19:46:47 +00:00
parent dc22256e0e
commit 31f08ddf32
3 changed files with 394 additions and 0 deletions
+40
View File
@@ -0,0 +1,40 @@
# 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://<host>: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)".