import type { BacktestStatus } from '../types'; import type { BacktestResult } from '../services/backtestApi'; import { MetricsCard } from './MetricsCard'; import { PositionsTable } from './PositionsTable'; import { Chart } from '../../../components/charts'; import { useState, useMemo } from 'react'; interface BacktestResultsProps { status: BacktestStatus; results: BacktestResult | null; currentTime: number | null; } export function BacktestResults({ status, results, currentTime }: BacktestResultsProps) { if (status === 'idle') { return (

Configure Your Backtest

Set up your strategy parameters and click "Configure Backtest" to begin.

); } if (status === 'configured') { return (

Ready to Start

Click the "Start" button to begin backtesting your strategy.

); } if (status === 'running' && !results) { return (

Running Backtest...

Processing historical data and executing trades.

); } if (!results) { return (

No Results Yet

Results will appear here once the backtest is complete.

); } return (
{/* Metrics Overview */}
= 0 ? '+' : ''}${results.metrics.totalReturn.toFixed(2)}%`} trend={results.metrics.totalReturn >= 0 ? 'up' : 'down'} /> = 1 ? 'up' : 'down'} /> = 50 ? 'up' : 'down'} /> {results.metrics.profitFactor && ( = 1 ? 'up' : 'down'} /> )}
{/* Performance Chart */}

Portfolio Performance

{(() => { const hasOhlcData = results.ohlcData && Object.keys(results.ohlcData).length > 0; const hasEquityData = results.equity && results.equity.length > 0; if (hasOhlcData) { const firstSymbol = Object.keys(results.ohlcData)[0]; const ohlcData = results.ohlcData[firstSymbol]; return ( ({ time: Math.floor(new Date(point.date).getTime() / 1000), value: point.value })), color: '#10b981', lineWidth: 3 } ] : []} className="rounded" /> ); } else if (hasEquityData) { return ( ({ time: Math.floor(new Date(point.date).getTime() / 1000), value: point.value }))} height={400} type="area" showVolume={false} theme="dark" className="rounded" /> ); } else { return (

No data available

); } })()}
{/* Trade History Table */} {results.trades && results.trades.length > 0 && (

Trade History ({results.trades.length} trades)

{results.trades.slice().reverse().map((trade) => { const formatDate = (dateStr: string) => { const date = new Date(dateStr); return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: '2-digit' }); }; const formatDuration = (ms: number) => { const days = Math.floor(ms / (1000 * 60 * 60 * 24)); if (days > 0) return `${days}d`; const hours = Math.floor(ms / (1000 * 60 * 60)); if (hours > 0) return `${hours}h`; return '<1h'; }; return ( ); })}
Date Symbol Side Qty Entry Exit P&L Return Duration
{formatDate(trade.entryDate)} {trade.symbol} {trade.side.toUpperCase()} {trade.quantity} ${trade.entryPrice.toFixed(2)} ${trade.exitPrice.toFixed(2)} = 0 ? 'text-success' : 'text-error' }`}> {trade.pnl >= 0 ? '+' : ''}${trade.pnl.toFixed(2)} = 0 ? 'text-success' : 'text-error' }`}> {trade.pnlPercent >= 0 ? '+' : ''}{trade.pnlPercent.toFixed(2)}% {formatDuration(trade.duration)}
Total sum + t.pnl, 0) >= 0 ? 'text-success' : 'text-error' }`}> ${results.trades.reduce((sum, t) => sum + t.pnl, 0).toFixed(2)} Avg: {(results.trades.reduce((sum, t) => sum + t.pnlPercent, 0) / results.trades.length).toFixed(2)}%
)}
); }