diff --git a/public/index.html b/public/index.html
index 759c5b4..5c06ec1 100644
--- a/public/index.html
+++ b/public/index.html
@@ -164,8 +164,8 @@
diff --git a/src/api/server.ts b/src/api/server.ts
index 36b5050..e6c632e 100644
--- a/src/api/server.ts
+++ b/src/api/server.ts
@@ -96,16 +96,38 @@ export function createServer(): express.Application {
WHERE recorded_at >= datetime('now', '-' || ? || ' hours')
ORDER BY recorded_at ASC
`).all(hours);
+
+ // Real-time summary: sum from DB positions directly (includes closed legs)
+ const liveOpen = db.prepare(`
+ SELECT COALESCE(SUM(unrealised_pnl),0) as u,
+ COALESCE(SUM(realised_pnl),0) as r,
+ COUNT(*) as cnt
+ FROM positions WHERE is_closed = 0 AND netqty != 0
+ `).get() as any;
+
+ // Realised from fully-closed positions (netqty=0, is_closed=1) — booked today
+ const closedRealised = db.prepare(`
+ SELECT COALESCE(SUM(realised_pnl),0) as r
+ FROM positions
+ WHERE (is_closed = 1 OR netqty = 0) AND realised_pnl != 0
+ AND updated_at >= date('now')
+ `).get() as any;
+
+ const totalUnrealised = liveOpen.u;
+ const totalRealised = liveOpen.r + closedRealised.r;
+ const totalPnl = totalUnrealised + totalRealised;
+
const latest = rows[rows.length - 1] as any;
res.json({
ok: true,
- summary: latest ? {
- totalUnrealised: latest.total_unrealised,
- totalRealised: latest.total_realised,
- totalPnl: latest.total_pnl,
- openPositions: latest.open_positions,
- asOf: latest.recorded_at,
- } : null,
+ summary: {
+ totalUnrealised,
+ totalRealised,
+ totalPnl,
+ openPositions: liveOpen.cnt,
+ bookedPnl: closedRealised.r,
+ asOf: latest?.recorded_at ?? new Date().toISOString(),
+ },
history: rows,
});
});
@@ -115,12 +137,17 @@ export function createServer(): express.Application {
`SELECT error, occurred_at FROM poll_errors ORDER BY occurred_at DESC LIMIT 1`
).get() as { error: string; occurred_at: string } | undefined;
- const posCount = (db.prepare(`SELECT COUNT(*) as n FROM positions WHERE is_closed = 0`).get() as { n: number }).n;
+ const posCount = (db.prepare(`SELECT COUNT(*) as n FROM positions WHERE is_closed = 0 AND netqty != 0`).get() as { n: number }).n;
+ const bookedRealised = (db.prepare(`
+ SELECT COALESCE(SUM(realised_pnl),0) as r FROM positions
+ WHERE (is_closed=1 OR netqty=0) AND realised_pnl!=0 AND updated_at>=date('now')
+ `).get() as { r: number }).r;
res.json({
ok: true,
marketOpen: isMarketOpen(),
openPositions: posCount,
+ bookedPnl: bookedRealised,
lastError: lastError ?? null,
uptime: Math.floor(process.uptime()),
});