fix(types): resolve all mypy type errors (CORE-003)

- Fix return type annotation for get_default_premium_for_product
- Add type narrowing for Weight|Money union using _as_money helper
- Add isinstance checks before float() calls for object types
- Add type guard for Decimal.exponent comparison
- Use _unit_typed and _currency_typed properties for type narrowing
- Cast option_type to OptionType Literal after validation
- Fix provider type hierarchy in backtesting services
- Add types-requests to dev dependencies
- Remove '|| true' from CI type-check job

All 36 mypy errors resolved across 15 files.
This commit is contained in:
Bu5hm4nn
2026-03-30 00:05:09 +02:00
parent 36ba8731e6
commit 887565be74
15 changed files with 193 additions and 55 deletions

View File

@@ -12,7 +12,11 @@ from app.models.backtest import (
TemplateRef,
)
from app.models.event_preset import EventPreset
from app.services.backtesting.historical_provider import DailyClosePoint, SyntheticHistoricalProvider
from app.services.backtesting.fixture_source import FixtureBoundSyntheticHistoricalProvider
from app.services.backtesting.historical_provider import (
DailyClosePoint,
SyntheticHistoricalProvider,
)
from app.services.backtesting.input_normalization import normalize_historical_scenario_inputs
from app.services.backtesting.service import BacktestService
from app.services.event_presets import EventPresetService
@@ -22,7 +26,7 @@ from app.services.strategy_templates import StrategyTemplateService
class EventComparisonService:
def __init__(
self,
provider: SyntheticHistoricalProvider | None = None,
provider: SyntheticHistoricalProvider | FixtureBoundSyntheticHistoricalProvider | None = None,
template_service: StrategyTemplateService | None = None,
event_preset_service: EventPresetService | None = None,
backtest_service: BacktestService | None = None,

View File

@@ -3,7 +3,7 @@ from __future__ import annotations
from dataclasses import dataclass
from datetime import date, timedelta
from math import isfinite
from typing import Protocol
from typing import Protocol, cast
from app.models.backtest import ProviderRef
@@ -12,7 +12,7 @@ try:
except ImportError: # pragma: no cover - optional in tests
yf = None
from app.core.pricing.black_scholes import BlackScholesInputs, black_scholes_price_and_greeks
from app.core.pricing.black_scholes import BlackScholesInputs, OptionType, black_scholes_price_and_greeks
from app.models.strategy_template import TemplateLeg
@@ -186,7 +186,10 @@ class YFinanceHistoricalPriceSource:
return None
if not hasattr(row_date, "date"):
raise TypeError(f"historical row date must support .date(), got {type(row_date)!r}")
normalized_close = float(close)
if isinstance(close, (int, float)):
normalized_close = float(close)
else:
raise TypeError(f"close must be numeric, got {type(close)!r}")
if not isfinite(normalized_close):
raise ValueError("historical close must be finite")
return DailyClosePoint(date=row_date.date(), close=normalized_close)
@@ -355,7 +358,7 @@ class SyntheticHistoricalProvider:
time_to_expiry=remaining_days / 365.0,
risk_free_rate=self.risk_free_rate,
volatility=self.implied_volatility,
option_type=option_type,
option_type=cast(OptionType, option_type),
valuation_date=valuation_date,
)
).price

View File

@@ -15,8 +15,16 @@ from app.models.backtest import (
TemplateRef,
)
from app.services.backtesting.databento_source import DatabentoHistoricalPriceSource, DatabentoSourceConfig
from app.services.backtesting.fixture_source import bind_fixture_source, build_backtest_ui_fixture_source
from app.services.backtesting.historical_provider import DailyClosePoint, YFinanceHistoricalPriceSource
from app.services.backtesting.fixture_source import (
FixtureBoundSyntheticHistoricalProvider,
SharedHistoricalFixtureSource,
build_backtest_ui_fixture_source,
)
from app.services.backtesting.historical_provider import (
DailyClosePoint,
SyntheticHistoricalProvider,
YFinanceHistoricalPriceSource,
)
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
@@ -98,7 +106,10 @@ class BacktestPageService:
)
self.template_service = template_service or base_service.template_service
self.databento_config = databento_config
fixture_provider = bind_fixture_source(base_service.provider, build_backtest_ui_fixture_source())
fixture_provider = FixtureBoundSyntheticHistoricalProvider(
base_provider=SyntheticHistoricalProvider(),
source=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
@@ -135,11 +146,9 @@ class BacktestPageService:
List of daily close points sorted by date
"""
if data_source == "databento":
provider = self._get_databento_provider()
return provider.load_daily_closes(symbol, start_date, end_date)
return self._get_databento_provider().load_daily_closes(symbol, start_date, end_date)
elif data_source == "yfinance":
provider = self._get_yfinance_provider()
return provider.load_daily_closes(symbol, start_date, end_date)
return self._get_yfinance_provider().load_daily_closes(symbol, start_date, end_date)
else:
# Use synthetic fixture data
return self.backtest_service.provider.load_history(symbol, start_date, end_date)