4ffde8cc06
- Database migration 018 with 13 tables for trading engine state - Trading engine service (services/trading/) with 12 pure computation modules: position sizer, stop-loss manager, reserve pool, circuit breaker, risk tier controller, correlation matrix, tax lots, trading window, gradual entry, notifications, micro-trading, backtester - Core TradingEngine with pre-trade evaluation pipeline and integration wiring - FastAPI HTTP service with 14 endpoints (health, config, decisions, metrics, backtest) - Performance tracker with Sharpe ratio, drawdown, profit factor computation - 194 Python tests (165 property-based + 29 integration) - Frontend: 13 TanStack Query hooks, 7 dashboard panels, tabbed Trading Engine page - Helm chart entry, network policy, nginx proxy, ingress for trading-engine - Shared infrastructure: enums, Redis keys, TradingConfig in AppConfig
116 lines
3.5 KiB
Python
116 lines
3.5 KiB
Python
"""Backtester for the autonomous trading engine.
|
|
|
|
Pure computation module that assembles backtest results from
|
|
pre-computed trade data and daily returns. The actual replay logic
|
|
(fetching historical data, simulating decisions) requires DB access
|
|
and will be wired in the integration layer. This module provides
|
|
the pure computation for result assembly.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import uuid
|
|
from dataclasses import dataclass, field
|
|
from datetime import date
|
|
|
|
from services.trading.models import ClosedTrade
|
|
from services.trading.performance_tracker import PerformanceComputer
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Data classes
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
@dataclass
|
|
class BacktestConfig:
|
|
"""Configuration for a backtest run."""
|
|
|
|
start_date: date
|
|
end_date: date
|
|
initial_capital: float
|
|
risk_tier: str # conservative | moderate | aggressive
|
|
|
|
|
|
@dataclass
|
|
class BacktestResult:
|
|
"""Output of a completed backtest run."""
|
|
|
|
backtest_id: str
|
|
config: BacktestConfig
|
|
total_return: float
|
|
sharpe_ratio: float
|
|
max_drawdown: float
|
|
win_rate: float
|
|
profit_factor: float
|
|
trade_count: int
|
|
trade_log: list[dict] = field(default_factory=list)
|
|
equity_curve: list[dict] = field(default_factory=list)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Engine
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class BacktestEngine:
|
|
"""Assembles a BacktestResult from pre-computed trade data.
|
|
|
|
Uses :class:`PerformanceComputer` to derive metrics from closed
|
|
trades and daily returns, then packages everything into a
|
|
:class:`BacktestResult`.
|
|
"""
|
|
|
|
def __init__(self) -> None:
|
|
self._perf = PerformanceComputer()
|
|
|
|
def compute_result(
|
|
self,
|
|
config: BacktestConfig,
|
|
trades: list[ClosedTrade],
|
|
daily_returns: list[float],
|
|
equity_curve: list[dict],
|
|
) -> BacktestResult:
|
|
"""Build a :class:`BacktestResult` from raw simulation outputs.
|
|
|
|
Args:
|
|
config: The backtest configuration that was used.
|
|
trades: Closed trades produced by the simulation.
|
|
daily_returns: Daily return percentages for the simulated period.
|
|
equity_curve: List of ``{"date": ..., "portfolio_value": ...}``
|
|
dicts representing the equity curve.
|
|
|
|
Returns:
|
|
A fully populated :class:`BacktestResult`.
|
|
"""
|
|
metrics = self._perf.compute_metrics(
|
|
closed_trades=trades,
|
|
portfolio_value=config.initial_capital,
|
|
active_pool=config.initial_capital,
|
|
reserve_pool=0.0,
|
|
daily_pnl=0.0,
|
|
unrealized_pnl=0.0,
|
|
portfolio_heat=0.0,
|
|
daily_returns=daily_returns,
|
|
)
|
|
|
|
trade_log = [self._perf.compute_trade_metrics(t) for t in trades]
|
|
|
|
total_return = (
|
|
sum(t.pnl for t in trades) / config.initial_capital
|
|
if config.initial_capital > 0
|
|
else 0.0
|
|
)
|
|
|
|
return BacktestResult(
|
|
backtest_id=str(uuid.uuid4()),
|
|
config=config,
|
|
total_return=total_return,
|
|
sharpe_ratio=metrics.sharpe_ratio,
|
|
max_drawdown=metrics.max_drawdown,
|
|
win_rate=metrics.win_rate,
|
|
profit_factor=metrics.profit_factor,
|
|
trade_count=len(trades),
|
|
trade_log=trade_log,
|
|
equity_curve=equity_curve,
|
|
)
|