"""Kevin-extension tests for compute_metrics (alpha/beta/winners/losers/best/worst).""" from datetime import datetime, timedelta, timezone from decimal import Decimal import pandas as pd from backtester.metrics import compute_metrics def _ts(day): return datetime(2026, 5, 15, tzinfo=timezone.utc) + timedelta(days=day) def test_compute_metrics_returns_alpha_and_beta_with_benchmark(): spy = pd.DataFrame( { "open": [500, 500, 510, 510, 520], "high": [500] * 5, "low": [500] * 5, "close": [500, 500, 510, 510, 520], "volume": [0] * 5, }, index=pd.date_range("2026-05-15", periods=5, freq="D", tz="UTC"), ) trades = [ { "symbol": "NVDA", "source_mention_id": 1, "entry_at": _ts(0), "entry_price": Decimal("100"), "exit_at": _ts(4), "exit_price": Decimal("110"), "qty": Decimal("10"), "pnl_usd": Decimal("100"), "pnl_pct": Decimal("10"), "holding_days_actual": 4, } ] curve = [(_ts(i), Decimal(str(100000 + 25 * i))) for i in range(5)] result = compute_metrics( trade_log=trades, equity_curve=curve, initial_capital=Decimal("100000"), benchmark_bars=spy, ) assert result.alpha_vs_spy_pct is not None assert result.beta_vs_spy is not None def test_compute_metrics_returns_winners_losers_best_worst(): trades = [ { "symbol": "NVDA", "source_mention_id": 1, "entry_at": _ts(0), "entry_price": Decimal("100"), "exit_at": _ts(5), "exit_price": Decimal("110"), "qty": Decimal("10"), "pnl_usd": Decimal("100"), "pnl_pct": Decimal("10"), "holding_days_actual": 5, }, { "symbol": "INTC", "source_mention_id": 2, "entry_at": _ts(0), "entry_price": Decimal("50"), "exit_at": _ts(5), "exit_price": Decimal("45"), "qty": Decimal("20"), "pnl_usd": Decimal("-100"), "pnl_pct": Decimal("-10"), "holding_days_actual": 5, }, ] result = compute_metrics( trade_log=trades, equity_curve=[(_ts(0), Decimal("100000"))], initial_capital=Decimal("100000"), ) assert result.avg_winner_pct == Decimal("10") assert result.avg_loser_pct == Decimal("-10") assert result.best_trade == {"symbol": "NVDA", "pnl_pct": Decimal("10")} assert result.worst_trade == {"symbol": "INTC", "pnl_pct": Decimal("-10")} def test_compute_metrics_no_benchmark_omits_alpha_beta(): result = compute_metrics( trade_log=[], equity_curve=[(_ts(0), Decimal("100000"))], initial_capital=Decimal("100000"), ) assert result.alpha_vs_spy_pct is None assert result.beta_vs_spy is None