import { CommonModule } from '@angular/common'; import { Component, Input } from '@angular/core'; import { MatCardModule } from '@angular/material/card'; import { MatDividerModule } from '@angular/material/divider'; import { MatGridListModule } from '@angular/material/grid-list'; import { MatTooltipModule } from '@angular/material/tooltip'; import { BacktestResult } from '../../../services/strategy.service'; @Component({ selector: 'app-performance-metrics', standalone: true, imports: [CommonModule, MatCardModule, MatGridListModule, MatDividerModule, MatTooltipModule], template: ` Performance Metrics

Returns

Total Return
{{ formatPercent(backtestResult?.totalReturn || 0) }}
Annualized Return
{{ formatPercent(backtestResult?.annualizedReturn || 0) }}
CAGR
{{ formatPercent(backtestResult?.cagr || 0) }}

Risk Metrics

Max Drawdown
{{ formatPercent(backtestResult?.maxDrawdown || 0) }}
Max DD Duration
{{ formatDays(backtestResult?.maxDrawdownDuration || 0) }}
Volatility
{{ formatPercent(backtestResult?.volatility || 0) }}
Ulcer Index
{{ (backtestResult?.ulcerIndex || 0).toFixed(4) }}

Risk-Adjusted Returns

Sharpe Ratio
{{ (backtestResult?.sharpeRatio || 0).toFixed(2) }}
Sortino Ratio
{{ (backtestResult?.sortinoRatio || 0).toFixed(2) }}
Calmar Ratio
{{ (backtestResult?.calmarRatio || 0).toFixed(2) }}
Omega Ratio
{{ (backtestResult?.omegaRatio || 0).toFixed(2) }}

Trade Statistics

Total Trades
{{ backtestResult?.totalTrades || 0 }}
Win Rate
{{ formatPercent(backtestResult?.winRate || 0) }}
Avg Win
{{ formatPercent(backtestResult?.averageWinningTrade || 0) }}
Avg Loss
{{ formatPercent(backtestResult?.averageLosingTrade || 0) }}
Profit Factor
{{ (backtestResult?.profitFactor || 0).toFixed(2) }}
`, styles: ` .metrics-card { margin-bottom: 20px; } .metrics-grid { display: flex; flex-direction: column; gap: 16px; } .metric-group { padding: 10px 0; } .metric-group h3 { margin-top: 0; margin-bottom: 16px; font-size: 16px; font-weight: 500; color: #555; } .metrics-row { display: flex; flex-wrap: wrap; gap: 24px; } .metric { min-width: 120px; margin-bottom: 16px; } .metric-name { font-size: 12px; color: #666; margin-bottom: 4px; } .metric-value { font-size: 16px; font-weight: 500; } .positive { color: #4caf50; } .negative { color: #f44336; } .neutral { color: #ffa000; } mat-divider { margin: 8px 0; } `, }) export class PerformanceMetricsComponent { @Input() backtestResult?: BacktestResult; // Formatting helpers formatPercent(value: number): string { return new Intl.NumberFormat('en-US', { style: 'percent', minimumFractionDigits: 2, maximumFractionDigits: 2, }).format(value); } formatDays(days: number): string { return `${days} days`; } // Conditional classes getReturnClass(value: number): string { if (value > 0) { return 'positive'; } if (value < 0) { return 'negative'; } return ''; } getRatioClass(value: number): string { if (value >= 1.5) { return 'positive'; } if (value >= 1) { return 'neutral'; } if (value < 0) { return 'negative'; } return ''; } getWinRateClass(value: number): string { if (value >= 0.55) { return 'positive'; } if (value >= 0.45) { return 'neutral'; } return 'negative'; } getProfitFactorClass(value: number): string { if (value >= 1.5) { return 'positive'; } if (value >= 1) { return 'neutral'; } return 'negative'; } }