/** * Performance Metrics Panel * Displays comprehensive backtesting performance metrics */ import React from 'react'; import { ChartBarIcon, ArrowTrendingUpIcon, ArrowTrendingDownIcon, ScaleIcon, ClockIcon, FireIcon, ShieldCheckIcon, } from '@heroicons/react/24/solid'; import type { BacktestMetrics } from '../../../services/backtestService'; import { formatMetric, getMetricColor } from '../../../services/backtestService'; interface PerformanceMetricsPanelProps { metrics: BacktestMetrics; initialCapital: number; finalCapital: number; className?: string; } export const PerformanceMetricsPanel: React.FC = ({ metrics, initialCapital, finalCapital, className = '', }) => { const returnPercent = ((finalCapital - initialCapital) / initialCapital) * 100; return (

Performance Metrics

{/* Capital Summary */}

Initial Capital

{formatMetric(initialCapital, 'currency')}

Final Capital

{formatMetric(finalCapital, 'currency')}

Return

{formatMetric(returnPercent, 'percent')}

{/* Trade Statistics */}

Trade Statistics

} /> } />
{/* Profit/Loss */}

Profit & Loss

{/* Risk Metrics */}

Risk Metrics

{/* Streaks */}

Streaks & Timing

{/* Performance Grade */}
Overall Grade
); }; // Helper Components interface MetricCardProps { label: string; value: number | string; format: 'percent' | 'currency' | 'ratio' | 'number' | 'custom'; colorType?: 'pnl' | 'winrate' | 'drawdown' | 'ratio'; positive?: boolean; negative?: boolean; invertColor?: boolean; icon?: React.ReactNode; } const MetricCard: React.FC = ({ label, value, format, colorType, positive, negative, invertColor, icon, }) => { let displayValue: string; let colorClass = 'text-white'; if (format === 'custom') { displayValue = String(value); } else { displayValue = formatMetric(typeof value === 'number' ? value : parseFloat(String(value)), format); } if (colorType && typeof value === 'number') { colorClass = getMetricColor(invertColor ? -value : value, colorType); } else if (positive) { colorClass = 'text-green-400'; } else if (negative) { colorClass = 'text-red-400'; } return (
{label} {icon}

{displayValue}

); }; const PerformanceGrade: React.FC<{ metrics: BacktestMetrics }> = ({ metrics }) => { // Calculate grade based on multiple factors let score = 0; // Win rate (max 25 points) score += Math.min(25, (metrics.win_rate / 100) * 40); // Profit factor (max 25 points) score += Math.min(25, metrics.profit_factor * 10); // Sharpe ratio (max 25 points) score += Math.min(25, metrics.sharpe_ratio * 12.5); // Max drawdown penalty (max 25 points, lower is better) score += Math.max(0, 25 - metrics.max_drawdown_percent); let grade: string; let gradeColor: string; if (score >= 80) { grade = 'A'; gradeColor = 'bg-green-600'; } else if (score >= 65) { grade = 'B'; gradeColor = 'bg-blue-600'; } else if (score >= 50) { grade = 'C'; gradeColor = 'bg-yellow-600'; } else if (score >= 35) { grade = 'D'; gradeColor = 'bg-orange-600'; } else { grade = 'F'; gradeColor = 'bg-red-600'; } return (
{grade}
Score: {Math.round(score)}/100
); }; export default PerformanceMetricsPanel;