refactor(BT-001C): share historical fixture provider
This commit is contained in:
@@ -13,13 +13,7 @@ from app.models.backtest import (
|
||||
ProviderRef,
|
||||
TemplateRef,
|
||||
)
|
||||
from app.services.backtesting.historical_provider import (
|
||||
DailyClosePoint,
|
||||
HistoricalOptionMark,
|
||||
HistoricalOptionPosition,
|
||||
SyntheticHistoricalProvider,
|
||||
SyntheticOptionQuote,
|
||||
)
|
||||
from app.services.backtesting.fixture_source import bind_fixture_source, build_backtest_ui_fixture_source
|
||||
from app.services.backtesting.input_normalization import normalize_historical_scenario_inputs
|
||||
from app.services.backtesting.service import BacktestService
|
||||
from app.services.strategy_templates import StrategyTemplateService
|
||||
@@ -37,29 +31,6 @@ def _validate_initial_collateral(underlying_units: float, entry_spot: float, loa
|
||||
)
|
||||
|
||||
|
||||
DETERMINISTIC_UI_FIXTURE_HISTORY: tuple[DailyClosePoint, ...] = (
|
||||
DailyClosePoint(date=date(2024, 1, 2), close=100.0),
|
||||
DailyClosePoint(date=date(2024, 1, 3), close=96.0),
|
||||
DailyClosePoint(date=date(2024, 1, 4), close=92.0),
|
||||
DailyClosePoint(date=date(2024, 1, 5), close=88.0),
|
||||
DailyClosePoint(date=date(2024, 1, 8), close=85.0),
|
||||
)
|
||||
|
||||
|
||||
class DeterministicBacktestFixtureSource:
|
||||
def load_daily_closes(self, symbol: str, start_date: date, end_date: date) -> list[DailyClosePoint]:
|
||||
normalized_symbol = symbol.strip().upper()
|
||||
if (
|
||||
normalized_symbol != SUPPORTED_BACKTEST_PAGE_SYMBOL
|
||||
or start_date != date(2024, 1, 2)
|
||||
or end_date != date(2024, 1, 8)
|
||||
):
|
||||
raise ValueError(
|
||||
"BT-001A deterministic fixture data only supports GLD on the seeded 2024-01-02 through 2024-01-08 window"
|
||||
)
|
||||
return list(DETERMINISTIC_UI_FIXTURE_HISTORY)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class BacktestPageRunResult:
|
||||
scenario: BacktestScenario
|
||||
@@ -67,40 +38,6 @@ 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)
|
||||
|
||||
def open_position(self, **kwargs: object) -> HistoricalOptionPosition:
|
||||
return self.base_provider.open_position(**kwargs)
|
||||
|
||||
def mark_position(self, position: HistoricalOptionPosition, **kwargs: object) -> HistoricalOptionMark:
|
||||
return self.base_provider.mark_position(position, **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,
|
||||
@@ -112,7 +49,7 @@ class BacktestPageService:
|
||||
provider=None,
|
||||
)
|
||||
self.template_service = template_service or base_service.template_service
|
||||
fixture_provider = FixtureBoundHistoricalProvider(base_service.provider)
|
||||
fixture_provider = bind_fixture_source(base_service.provider, build_backtest_ui_fixture_source())
|
||||
self.backtest_service = copy(base_service)
|
||||
self.backtest_service.provider = fixture_provider
|
||||
self.backtest_service.template_service = self.template_service
|
||||
|
||||
Reference in New Issue
Block a user