From 1aeb6e85874f104d12a8a034171e0e63733c4840 Mon Sep 17 00:00:00 2001 From: Viktor Barzin Date: Wed, 27 May 2026 18:00:48 +0000 Subject: [PATCH] fix(dashboard): Strategy page crashed on undefined fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User reported UI error. Root cause: API GET /api/meet-kevin/strategy/ performance returns {trade_count, closed_trade_count, total_pnl_usd, win_rate_pct, wins, losses} but the dashboard's StrategyPerformance type expected {total_return_pct, sharpe_ratio, max_drawdown_pct, open_positions, alpha_vs_spy_pct, ...}. So performance.open_positions was undefined and .toString() crashed the whole page render. Fix: update StrategyPerformance to match the actual API shape and rewrite the 6-card headline grid to show the metrics the API actually computes (trade count, closed count, total P&L, win rate, wins, losses). Defensive ?? 0 fallbacks everywhere so future schema drift doesn't crash again. Long-term: extend the API to compute sharpe/max-dd/alpha vs SPY etc. once there are real Kevin trades to compute them on (currently 0 trades — all 13 emitted signals fired outside market hours and were correctly rejected by RiskManager). --- dashboard/src/pages/meetKevin/Strategy.tsx | 41 +++++++++++----------- dashboard/src/types/meetKevin.ts | 15 ++++---- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/dashboard/src/pages/meetKevin/Strategy.tsx b/dashboard/src/pages/meetKevin/Strategy.tsx index 6ee8197..16ead54 100644 --- a/dashboard/src/pages/meetKevin/Strategy.tsx +++ b/dashboard/src/pages/meetKevin/Strategy.tsx @@ -123,36 +123,35 @@ export default function MeetKevinStrategy() { {/* Headline metrics */} {performance && ( -
+
= 0 ? 'text-green-400' : 'text-red-400'} + label="Total Trades" + value={(performance.trade_count ?? 0).toString()} /> = 0 ? 'text-green-400' : 'text-red-400'} + label="Closed Trades" + value={(performance.closed_trade_count ?? 0).toString()} /> = 1 ? 'text-green-400' : 'text-yellow-400'} + label="Total P&L" + value={`${(performance.total_pnl_usd ?? 0) >= 0 ? '+' : ''}$${(performance.total_pnl_usd ?? 0).toFixed(2)}`} + color={(performance.total_pnl_usd ?? 0) >= 0 ? 'text-green-400' : 'text-red-400'} /> = 50 ? 'text-green-400' : 'text-yellow-400'} + /> + + - = 0 ? 'text-green-400' : 'text-red-400'} - /> -
)} diff --git a/dashboard/src/types/meetKevin.ts b/dashboard/src/types/meetKevin.ts index 3c04ef4..0982e15 100644 --- a/dashboard/src/types/meetKevin.ts +++ b/dashboard/src/types/meetKevin.ts @@ -199,13 +199,12 @@ export interface StrategyEquityCurve { } export interface StrategyPerformance { - total_return_pct: number; - annualized_return_pct: number | null; - sharpe_ratio: number | null; - max_drawdown_pct: number | null; - win_rate: number | null; + // Live-path metrics — current shape from + // GET /api/meet-kevin/strategy/performance. trade_count: number; - alpha_vs_spy_pct: number | null; - open_positions: number; - last_backtest_at: string | null; + closed_trade_count: number; + total_pnl_usd: number; + win_rate_pct: number; + wins: number; + losses: number; }