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é
- )}
)
})}