diff options
Diffstat (limited to 'services/backtester/src')
| -rw-r--r-- | services/backtester/src/backtester/metrics.py | 2 | ||||
| -rw-r--r-- | services/backtester/src/backtester/simulator.py | 8 | ||||
| -rw-r--r-- | services/backtester/src/backtester/walk_forward.py | 17 |
3 files changed, 14 insertions, 13 deletions
diff --git a/services/backtester/src/backtester/metrics.py b/services/backtester/src/backtester/metrics.py index 5b43afd..239cb6f 100644 --- a/services/backtester/src/backtester/metrics.py +++ b/services/backtester/src/backtester/metrics.py @@ -207,7 +207,7 @@ def compute_detailed_metrics( # Sortino (downside deviation of excess returns) downside = [min(r - daily_rf, 0.0) for r in daily_returns] - downside_var = sum(d ** 2 for d in downside) / len(downside) + downside_var = sum(d**2 for d in downside) / len(downside) downside_std = math.sqrt(downside_var) sortino = (mean_excess / downside_std * math.sqrt(365)) if downside_std > 0 else 0.0 else: diff --git a/services/backtester/src/backtester/simulator.py b/services/backtester/src/backtester/simulator.py index 1e37740..64c88dd 100644 --- a/services/backtester/src/backtester/simulator.py +++ b/services/backtester/src/backtester/simulator.py @@ -89,9 +89,7 @@ class OrderSimulator: if triggered and exit_price is not None: # Close the position - close_side = ( - OrderSide.SELL if pos.side == OrderSide.BUY else OrderSide.BUY - ) + close_side = OrderSide.SELL if pos.side == OrderSide.BUY else OrderSide.BUY fee = self._calculate_fee(exit_price, pos.quantity) if pos.side == OrderSide.BUY: @@ -198,9 +196,7 @@ class OrderSimulator: ) return True - def _close_open_position( - self, symbol: str, side: OrderSide, quantity: Decimal - ) -> None: + def _close_open_position(self, symbol: str, side: OrderSide, quantity: Decimal) -> None: """Remove closed quantity from open positions (FIFO).""" remaining_qty = quantity new_positions: list[OpenPosition] = [] diff --git a/services/backtester/src/backtester/walk_forward.py b/services/backtester/src/backtester/walk_forward.py index fe6d020..c7b7fd8 100644 --- a/services/backtester/src/backtester/walk_forward.py +++ b/services/backtester/src/backtester/walk_forward.py @@ -1,4 +1,5 @@ """Walk-forward analysis for strategy parameter optimization.""" + from dataclasses import dataclass, field from decimal import Decimal from typing import Callable @@ -10,6 +11,7 @@ from backtester.engine import BacktestEngine, BacktestResult, StrategyProtocol @dataclass class WalkForwardWindow: """Result for a single in-sample/out-of-sample window.""" + window_index: int in_sample_result: BacktestResult out_of_sample_result: BacktestResult @@ -19,6 +21,7 @@ class WalkForwardWindow: @dataclass class WalkForwardResult: """Aggregated walk-forward analysis results.""" + strategy_name: str symbol: str num_windows: int @@ -130,12 +133,14 @@ class WalkForwardEngine: engine = BacktestEngine(strategy, self._initial_balance) oos_result = engine.run(out_of_sample) - windows.append(WalkForwardWindow( - window_index=i, - in_sample_result=best_is_result, - out_of_sample_result=oos_result, - best_params=best_params, - )) + windows.append( + WalkForwardWindow( + window_index=i, + in_sample_result=best_is_result, + out_of_sample_result=oos_result, + best_params=best_params, + ) + ) return WalkForwardResult( strategy_name=strategy_name, |
