fix(pre-alpha): preserve injected template services

This commit is contained in:
Bu5hm4nn
2026-03-26 12:26:38 +01:00
parent d7117bb6a3
commit 52d943e614
2 changed files with 42 additions and 9 deletions

View File

@@ -11,7 +11,11 @@ from app.models.backtest import (
ProviderRef,
TemplateRef,
)
from app.services.backtesting.historical_provider import DailyClosePoint, SyntheticHistoricalProvider
from app.services.backtesting.historical_provider import (
DailyClosePoint,
SyntheticHistoricalProvider,
SyntheticOptionQuote,
)
from app.services.backtesting.service import BacktestService
from app.services.strategy_templates import StrategyTemplateService
@@ -58,22 +62,46 @@ class BacktestPageRunResult:
entry_spot: float
class FixtureBoundHistoricalProvider:
def __init__(self, base_provider: SyntheticHistoricalProvider) -> None:
self.base_provider = base_provider
self.source = DeterministicBacktestFixtureSource()
self.provider_id = base_provider.provider_id
self.pricing_mode = base_provider.pricing_mode
self.implied_volatility = base_provider.implied_volatility
self.risk_free_rate = base_provider.risk_free_rate
def load_history(self, symbol: str, start_date: date, end_date: date) -> list[DailyClosePoint]:
rows = self.source.load_daily_closes(symbol, start_date, end_date)
filtered = [row for row in rows if start_date <= row.date <= end_date]
return sorted(filtered, key=lambda row: row.date)
def validate_provider_ref(self, provider_ref: ProviderRef) -> None:
self.base_provider.validate_provider_ref(provider_ref)
def resolve_expiry(self, trading_days: list[DailyClosePoint], as_of_date: date, target_expiry_days: int) -> date:
return self.base_provider.resolve_expiry(trading_days, as_of_date, target_expiry_days)
def price_option(self, **kwargs: object) -> SyntheticOptionQuote:
return self.base_provider.price_option(**kwargs)
@staticmethod
def intrinsic_value(*, option_type: str, spot: float, strike: float) -> float:
return SyntheticHistoricalProvider.intrinsic_value(option_type=option_type, spot=spot, strike=strike)
class BacktestPageService:
def __init__(
self,
backtest_service: BacktestService | None = None,
template_service: StrategyTemplateService | None = None,
) -> None:
self.template_service = template_service or StrategyTemplateService()
base_service = backtest_service or BacktestService(
template_service=self.template_service,
template_service=template_service,
provider=None,
)
fixture_provider = SyntheticHistoricalProvider(
source=DeterministicBacktestFixtureSource(),
implied_volatility=base_service.provider.implied_volatility,
risk_free_rate=base_service.provider.risk_free_rate,
)
self.template_service = template_service or base_service.template_service
fixture_provider = FixtureBoundHistoricalProvider(base_service.provider)
self.backtest_service = BacktestService(
provider=fixture_provider,
template_service=self.template_service,

View File

@@ -230,7 +230,12 @@ def test_backtest_page_service_does_not_mutate_injected_backtest_service() -> No
)
injected_service = BacktestService(provider=provider)
BacktestPageService(backtest_service=injected_service)
page_service = BacktestPageService(backtest_service=injected_service)
history = injected_service.provider.load_history("GLD", date(2024, 1, 3), date(2024, 1, 3))
assert history[0].close == 123.0
assert page_service.template_service is injected_service.template_service
assert page_service.backtest_service.provider.implied_volatility == 0.2
assert page_service.backtest_service.provider.risk_free_rate == 0.01
seeded_history = page_service.backtest_service.provider.load_history("GLD", date(2024, 1, 2), date(2024, 1, 8))
assert seeded_history[0].close == 100.0