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:
@@ -30,6 +30,13 @@ def _money_to_float(value: Money) -> float:
|
||||
return float(value.amount)
|
||||
|
||||
|
||||
def _as_money(value: Weight | Money) -> Money:
|
||||
"""Narrow Weight | Money to Money after multiplication."""
|
||||
if isinstance(value, Money):
|
||||
return value
|
||||
raise TypeError(f"Expected Money, got {type(value).__name__}")
|
||||
|
||||
|
||||
def _decimal_to_float(value: Decimal) -> float:
|
||||
return float(value)
|
||||
|
||||
@@ -48,7 +55,12 @@ def _gold_weight(gold_ounces: float) -> Weight:
|
||||
|
||||
def _safe_quote_price(value: object) -> float:
|
||||
try:
|
||||
parsed = float(value)
|
||||
if isinstance(value, (int, float)):
|
||||
parsed = float(value)
|
||||
elif isinstance(value, str):
|
||||
parsed = float(value.strip())
|
||||
else:
|
||||
return 0.0
|
||||
except (TypeError, ValueError):
|
||||
return 0.0
|
||||
if parsed <= 0:
|
||||
@@ -121,7 +133,7 @@ def _strategy_option_payoff_per_unit(
|
||||
return sum(
|
||||
weight * max(strike_price - scenario_spot, _DECIMAL_ZERO)
|
||||
for weight, strike_price in _strategy_downside_put_legs(strategy, current_spot)
|
||||
)
|
||||
) or Decimal("0")
|
||||
|
||||
|
||||
def _strategy_upside_cap_effect_per_unit(
|
||||
@@ -233,7 +245,7 @@ def portfolio_snapshot_from_config(
|
||||
config: PortfolioConfig | None = None,
|
||||
*,
|
||||
runtime_spot_price: float | None = None,
|
||||
) -> dict[str, float]:
|
||||
) -> dict[str, float | str]:
|
||||
"""Build portfolio snapshot with display-mode-aware calculations.
|
||||
|
||||
In GLD mode:
|
||||
@@ -294,7 +306,7 @@ def portfolio_snapshot_from_config(
|
||||
margin_call_ltv = decimal_from_float(float(config.margin_threshold))
|
||||
hedge_budget = Money(amount=decimal_from_float(float(config.monthly_budget)), currency=BaseCurrency.USD)
|
||||
|
||||
gold_value = gold_weight * spot
|
||||
gold_value = _as_money(gold_weight * spot)
|
||||
net_equity = gold_value - loan_amount
|
||||
ltv_ratio = _decimal_ratio(loan_amount.amount, gold_value.amount)
|
||||
margin_call_price = loan_amount.amount / (margin_call_ltv * gold_weight.amount)
|
||||
@@ -334,7 +346,7 @@ def build_alert_context(
|
||||
gold_weight = _gold_weight(float(config.gold_ounces or 0.0))
|
||||
|
||||
live_spot = _spot_price(spot_price)
|
||||
gold_value = gold_weight * live_spot
|
||||
gold_value = _as_money(gold_weight * live_spot)
|
||||
loan_amount = Money(amount=decimal_from_float(float(config.loan_amount)), currency=BaseCurrency.USD)
|
||||
margin_call_ltv = decimal_from_float(float(config.margin_threshold))
|
||||
margin_call_price = (
|
||||
@@ -377,12 +389,12 @@ def strategy_metrics_from_snapshot(
|
||||
]
|
||||
|
||||
scenario_price = spot * _pct_factor(scenario_pct)
|
||||
scenario_gold_value = gold_weight * PricePerWeight(
|
||||
scenario_gold_value = _as_money(gold_weight * PricePerWeight(
|
||||
amount=scenario_price,
|
||||
currency=BaseCurrency.USD,
|
||||
per_unit=WeightUnit.OUNCE_TROY,
|
||||
)
|
||||
current_gold_value = gold_weight * current_spot
|
||||
))
|
||||
current_gold_value = _as_money(gold_weight * current_spot)
|
||||
unhedged_equity = scenario_gold_value - loan_amount
|
||||
scenario_payoff_per_unit = _strategy_option_payoff_per_unit(strategy, spot, scenario_price)
|
||||
capped_upside_per_unit = _strategy_upside_cap_effect_per_unit(strategy, spot, scenario_price)
|
||||
|
||||
Reference in New Issue
Block a user