From 38c9aadb6b5ced65c2015a6701d7a93b3edd7042 Mon Sep 17 00:00:00 2001 From: OpenSquared Date: Fri, 19 Jun 2026 22:27:27 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20PnL=20montant=20via=20entry=5Fprice=20fa?= =?UTF-8?q?llback,=20Trades=20du=20cycle=20restructur=C3=A9,=20Dernier=20C?= =?UTF-8?q?ycle=20trades=20ajout=C3=A9s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PnL simulated: Investi ~ et P&L € calculés avec entry_price quand capital_invested est null (label ~ pour indiquer estimation) - Dernier Cycle: rename trades loggés -> trades ajoutés + mini mention des non-loggés quand patternsAdded > tradesLogged - Trades du cycle: supprime le grand header +N Trades (info déplacée dans Dernier Cycle); layout inversé — trade en primaire, pattern en secondaire petit en dessous; trades non loggés affichés en gris Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/pages/Dashboard.tsx | 86 +++++++++++++++++--------------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/frontend/src/pages/Dashboard.tsx b/frontend/src/pages/Dashboard.tsx index d656d55..fd225b0 100644 --- a/frontend/src/pages/Dashboard.tsx +++ b/frontend/src/pages/Dashboard.tsx @@ -314,9 +314,12 @@ export default function Dashboard() { const losers = withPnl.filter((t: any) => t.pnl_pct < 0).length const closedTrades = trades.filter((t: any) => t.status === 'closed') const openTrades = trades.filter((t: any) => t.status !== 'closed') - const totalCapital = trades.reduce((s: number, t: any) => s + (t.capital_invested ?? 0), 0) + // Use capital_invested if set, otherwise entry_price as proxy cost + const totalCapital = trades.reduce((s: number, t: any) => + s + (t.capital_invested ?? t.entry_price ?? 0), 0) const totalProfit = withPnl.reduce((s: number, t: any) => - s + ((t.capital_invested ?? 0) * t.pnl_pct / 100), 0) + s + ((t.capital_invested ?? t.entry_price ?? 0) * t.pnl_pct / 100), 0) + const isEstimated = trades.some((t: any) => t.capital_invested == null && t.entry_price != null) const targetHit = trades.filter((t: any) => t.alert_type === 'target_reached').length const stopHit = trades.filter((t: any) => t.alert_type === 'stop_loss').length @@ -356,7 +359,9 @@ export default function Dashboard() {
-
Investi
+
+ Investi{isEstimated ? ' ~' : ''} +
{totalCapital > 0 ? `${totalCapital.toFixed(0)}€` : '—'}
@@ -467,6 +472,7 @@ export default function Dashboard() { const patternsAdded: number = last?.patterns_added ?? 0 const patternsScored: number = last?.patterns_scored ?? 0 const tradesLogged: number = cycleTrades.length + const tradesNotLogged: number = Math.max(0, patternsAdded - tradesLogged) const tradesClosed = cycleTrades.filter((t: any) => t.status === 'closed').length const commentary = last?.commentary ? (() => { try { return typeof last.commentary === 'string' ? JSON.parse(last.commentary) : last.commentary } catch { return null } })() @@ -486,8 +492,11 @@ export default function Dashboard() {
patterns ajoutés
-
{tradesLogged}
-
trades loggés
+
+{tradesLogged}
+
trades ajoutés
+ {tradesNotLogged > 0 && ( +
{tradesNotLogged} non-loggé{tradesNotLogged > 1 ? 's' : ''}
+ )}
{patternsScored}
@@ -591,7 +600,6 @@ export default function Dashboard() { {/* Trades du dernier cycle — détaillé */} {(() => { - const tradeCount = cycleTrades.length // Build a map: pattern_id → trade for quick lookup const tradeByPattern: Record = {} for (const t of cycleTrades) { @@ -607,11 +615,8 @@ export default function Dashboard() { 📥 Trades du cycle
-
- {tradeCount > 0 ? `+${tradeCount} Trade${tradeCount > 1 ? 's' : ''}` : lastCycle ? '+0 Trades' : '—'} -
{rows.length > 0 ? ( -
+
{rows.slice(0, 3).map((p: any, i: number) => { const t = tradeByPattern[p.id] const logged = !!t @@ -620,38 +625,41 @@ export default function Dashboard() { const pnl: number | null = t?.pnl_pct ?? null const isBear = t?.strategy?.toLowerCase().includes('put') || t?.strategy?.toLowerCase().includes('bear') return ( -
- {/* Pattern name (origin) */} -
- - {logged ? '✓' : '○'} - - {p.name} - {score !== null && ( - {score} - )} -
- {/* Trade details if logged */} - {logged && ( -
- {isBear ? '🐻' : '🐂'} - {t.underlying ?? '—'} - {t.strategy ?? ''} - {ev !== null && ( - = 0.5 ? 'text-emerald-400' : ev >= 0 ? 'text-yellow-400' : 'text-red-400')}> - EV{ev >= 0 ? '+' : ''}{ev.toFixed(2)} - - )} - {pnl !== null && ( - = 0 ? 'text-emerald-400' : 'text-red-400')}> - {pnl >= 0 ? '+' : ''}{pnl.toFixed(1)}% - +
+ {logged ? ( + <> + {/* Trade row — primary */} +
+ {isBear ? '🐻' : '🐂'} + {t.underlying ?? '—'} + {t.strategy ?? ''} + {ev !== null && ( + = 0.5 ? 'text-emerald-400' : ev >= 0 ? 'text-yellow-400' : 'text-red-400')}> + EV{ev >= 0 ? '+' : ''}{ev.toFixed(2)} + + )} + {score !== null && ( + {score} + )} + {pnl !== null && ( + = 0 ? 'text-emerald-400' : 'text-red-400')}> + {pnl >= 0 ? '+' : ''}{pnl.toFixed(1)}% + + )} +
+ {/* Pattern name — secondary */} +
{p.name}
+ + ) : ( +
+ + {p.name} + {score !== null && ( + {score} )} + non loggé
)} - {!logged && ( -
score insuffisant — non loggé
- )}
) })}