import type { BacktestResult } from '../types/backtest.types'; interface ExtendedMetrics { // Core metrics totalReturn?: number; sharpeRatio?: number; maxDrawdown?: number; winRate?: number; totalProfit?: number; profitFactor?: number; totalTrades?: number; avgWin?: number; avgLoss?: number; expectancy?: number; sortinoRatio?: number; calmarRatio?: number; profitableTrades?: number; // Extended metrics from orchestrator annualizedReturn?: number; volatility?: number; avgHoldingPeriod?: number; maxConsecutiveLosses?: number; maxConsecutiveWins?: number; payoffRatio?: number; largestWin?: number; largestLoss?: number; avgWinLoss?: number; skewness?: number; kurtosis?: number; tailRatio?: number; kellyFraction?: number; informationRatio?: number; avgTradesPerDay?: number; } interface CompactPerformanceMetricsProps { result: any | null; isLoading: boolean; } export function CompactPerformanceMetrics({ result, isLoading }: CompactPerformanceMetricsProps) { if (isLoading || !result) { return null; } const metrics = result.metrics as ExtendedMetrics; const analytics = result.analytics || {}; // Merge metrics from both sources const allMetrics = { ...metrics, ...analytics, // Override with metrics values if they exist ...metrics }; // Calculate totalProfit if not provided const totalProfit = allMetrics.totalProfit ?? (allMetrics.totalReturn && result.config?.initialCapital ? allMetrics.totalReturn * result.config.initialCapital : undefined); const formatValue = (value: number | undefined, format: 'percent' | 'number' | 'currency', decimals = 2) => { if (value === undefined || value === null) return '-'; switch (format) { case 'percent': return `${(value * 100).toFixed(decimals)}%`; case 'currency': const prefix = value < 0 ? '-$' : '$'; return `${prefix}${Math.abs(value).toFixed(decimals)}`; case 'number': return value.toFixed(decimals); } }; const getColorClass = (value: number | undefined, thresholds: { good: number; warning?: number }) => { if (value === undefined || value === null) return 'text-text-secondary'; if (thresholds.warning !== undefined) { if (value >= thresholds.good) return 'text-success'; if (value >= thresholds.warning) return 'text-warning'; return 'text-error'; } return value >= thresholds.good ? 'text-success' : 'text-error'; }; return (

Performance Analytics

{/* Column 1 - Return Metrics */}
Total Return {formatValue(allMetrics.totalReturn, 'percent')}
Sharpe Ratio {formatValue(allMetrics.sharpeRatio, 'number')}
Max Drawdown {formatValue(allMetrics.maxDrawdown, 'percent')}
Win Rate {formatValue(allMetrics.winRate, 'percent', 1)}
Total Profit {formatValue(totalProfit, 'currency')}
{/* Column 2 - Risk Metrics */}
Profit Factor {formatValue(allMetrics.profitFactor, 'number')}
Total Trades {allMetrics.totalTrades ?? '-'}
Avg Win/Loss {formatValue(allMetrics.avgWin, 'currency')} / {formatValue(allMetrics.avgLoss, 'currency')}
Expectancy {formatValue(allMetrics.expectancy, 'currency')}
Sortino Ratio {formatValue(allMetrics.sortinoRatio, 'number')}
{/* Column 3 - Additional Metrics */}
Annual Return {formatValue(allMetrics.annualizedReturn, 'percent')}
Volatility {formatValue(allMetrics.volatility ? allMetrics.volatility / 100 : undefined, 'percent', 1)}
Avg Holding {allMetrics.avgHoldingPeriod ? `${(allMetrics.avgHoldingPeriod / 60).toFixed(1)}h` : '-'}
Max Consec Loss 5 ? 'text-error' : 'text-text-primary'}`}> {allMetrics.maxConsecutiveLosses ?? '-'}
Payoff Ratio {formatValue(allMetrics.payoffRatio, 'number')}
{/* Advanced Metrics - Show only if available */} {(allMetrics.skewness !== undefined || allMetrics.kurtosis !== undefined || allMetrics.informationRatio !== undefined || allMetrics.kellyFraction !== undefined) && (
{allMetrics.informationRatio !== undefined && (
Info Ratio
{formatValue(allMetrics.informationRatio, 'number')}
)} {allMetrics.skewness !== undefined && (
Skewness
{formatValue(allMetrics.skewness, 'number')}
)} {allMetrics.kurtosis !== undefined && (
Kurtosis
{formatValue(allMetrics.kurtosis, 'number')}
)} {allMetrics.kellyFraction !== undefined && (
Kelly %
{formatValue(allMetrics.kellyFraction, 'percent')}
)}
)} {/* Additional Metrics Row */}
Calmar
{formatValue(allMetrics.calmarRatio, 'number')}
Profitable
{allMetrics.profitableTrades ?? '-'}/{allMetrics.totalTrades ?? '-'}
Exposure
{result.analytics?.exposureTime ? formatValue(result.analytics.exposureTime, 'percent', 1) : '-'}
Largest Win
{formatValue(allMetrics.largestWin, 'currency')}
Largest Loss
{formatValue(allMetrics.largestLoss, 'currency')}
); }