From 6c35efde0f7739eac3c99f130a4737d85a81accb Mon Sep 17 00:00:00 2001 From: Bu5hm4nn Date: Fri, 3 Apr 2026 20:34:21 +0200 Subject: [PATCH] fix: use selected data source for backtest historical prices The backtest engine was always using fixture data (limited to 2024-01-02 through 2024-01-08) regardless of the data_source selection. The fix fetches historical prices using the specified data source (Databento, Yahoo Finance, or synthetic) and passes them directly to the engine. --- app/services/backtesting/ui_service.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/app/services/backtesting/ui_service.py b/app/services/backtesting/ui_service.py index f7cd5b7..ccf4ee9 100644 --- a/app/services/backtesting/ui_service.py +++ b/app/services/backtesting/ui_service.py @@ -323,15 +323,20 @@ class BacktestPageService: margin_call_ltv=normalized_inputs.margin_call_ltv, ) - # CRITICAL: The backtest engine uses a fixture provider (synthetic_v1), - # regardless of the data_source used for price fetching. - # We must use the fixture provider's ID for the scenario, not the data source's ID. - # The data_source parameter only affects price data fetching, not the backtest engine. + # Fetch historical prices using the specified data source + history = self.get_historical_prices(normalized_symbol, start_date, end_date, data_source) + if not history: + raise ValueError("No historical prices found for scenario window") + if history[0].date != start_date: + raise ValueError( + "Scenario start date must match the first available historical close for entry-at-start backtests" + ) + + # Use the fixture provider's ID for the scenario (for pricing mode) + # The actual price data comes from the specified data_source provider_id = self.backtest_service.provider.provider_id pricing_mode = self.backtest_service.provider.pricing_mode - # For now, always use the synthetic engine (which uses fixture data for demo) - # In a full implementation, we would create different engines for different providers scenario = BacktestScenario( scenario_id=( f"{normalized_symbol.lower()}-{start_date.isoformat()}-{end_date.isoformat()}-{template.slug}" @@ -353,9 +358,14 @@ class BacktestPageService: if data_source == "databento": data_cost_usd = self.get_cost_estimate(normalized_symbol, start_date, end_date, data_source) + # Run the backtest engine directly with pre-fetched history + # This bypasses the fixture provider in BacktestService.run_scenario + template_result = self.backtest_service.engine.run_template(scenario, template, history) + run_result = BacktestRunResult(scenario_id=scenario.scenario_id, template_results=(template_result,)) + return BacktestPageRunResult( scenario=scenario, - run_result=self.backtest_service.run_scenario(scenario), + run_result=run_result, entry_spot=entry_spot, data_source=data_source, data_cost_usd=data_cost_usd,