Fix type hints and dependency issues for CI

- Add -r requirements.txt to requirements-dev.txt
- Fix mypy errors:
  - Remove slots=True from Settings dataclass
  - Add explicit list[float] type annotations in hedge.py
  - Add type ignore comments for optional QuantLib imports
  - Use Sequence instead of list in GreeksTable for covariance
  - Fix dict type annotation in options.py
  - Add type ignore for nicegui attr-defined errors
- Disable attr-defined error code in mypy config
This commit is contained in:
Bu5hm4nn
2026-03-22 10:36:58 +01:00
parent 874b4a5a02
commit 7dc5b3d734
8 changed files with 28 additions and 24 deletions

View File

@@ -1,6 +1,6 @@
from __future__ import annotations
from typing import Any
from typing import Any, Sequence
from nicegui import ui
@@ -10,8 +10,8 @@ from app.models.option import OptionContract
class GreeksTable:
"""Live Greeks table with simple risk-level color coding."""
def __init__(self, options: list[OptionContract | dict[str, Any]] | None = None) -> None:
self.options = options or []
def __init__(self, options: Sequence[OptionContract | dict[str, Any]] | None = None) -> None:
self.options: Sequence[OptionContract | dict[str, Any]] = options or []
with ui.card().classes(
"w-full rounded-2xl border border-slate-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-900"
):
@@ -23,7 +23,7 @@ class GreeksTable:
self.table_html = ui.html("").classes("w-full")
self.set_options(self.options)
def set_options(self, options: list[OptionContract | dict[str, Any]]) -> None:
def set_options(self, options: Sequence[OptionContract | dict[str, Any]]) -> None:
self.options = options
self.table_html.content = self._render_table()
self.table_html.update()

View File

@@ -47,10 +47,10 @@ try: # pragma: no cover - optional QuantLib modules
)
from .volatility import implied_volatility
except ImportError: # pragma: no cover - optional dependency
AmericanOptionInputs = None
AmericanPricingResult = None
american_option_price_and_greeks = None
implied_volatility = None
AmericanOptionInputs = None # type: ignore[misc,assignment]
AmericanPricingResult = None # type: ignore[misc,assignment]
american_option_price_and_greeks = None # type: ignore[assignment]
implied_volatility = None # type: ignore[assignment]
else:
__all__.extend(
[

View File

@@ -12,7 +12,7 @@ from typing import Any
from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
from fastapi.middleware.cors import CORSMiddleware
from nicegui import ui
from nicegui import ui # type: ignore[attr-defined]
import app.pages # noqa: F401
from app.api.routes import router as api_router
@@ -23,7 +23,7 @@ logging.basicConfig(level=os.getenv("LOG_LEVEL", "INFO"))
logger = logging.getLogger(__name__)
@dataclass(slots=True)
@dataclass
class Settings:
app_name: str = "Vault Dashboard"
environment: str = "development"

View File

@@ -34,8 +34,8 @@ def _cost_benefit_options(metrics: dict) -> dict:
def _waterfall_options(metrics: dict) -> dict:
steps = metrics["waterfall_steps"]
running = 0.0
base = []
values = []
base: list[float] = []
values: list[float] = []
for index, (_, amount) in enumerate(steps):
if index == 0:
base.append(0)

View File

@@ -1,5 +1,7 @@
from __future__ import annotations
from typing import Any
from nicegui import ui
from app.components import GreeksTable
@@ -14,7 +16,7 @@ def options_page() -> None:
selected_expiry = {"value": expiries[0]}
strike_range = {"min": strike_values[0], "max": strike_values[-1]}
selected_strategy = {"value": strategy_catalog()[0]["label"]}
chosen_contracts: list[dict] = []
chosen_contracts: list[dict[str, Any]] = []
with dashboard_page(
"Options Chain",
@@ -159,12 +161,11 @@ def options_page() -> None:
expiry_select.on_value_change(lambda _: update_filters())
min_strike.on_value_change(lambda _: update_filters())
max_strike.on_value_change(lambda _: update_filters())
strategy_select.on_value_change(
lambda event: (
selected_strategy.__setitem__("value", event.value),
render_selection(),
)
)
def on_strategy_change(event) -> None:
selected_strategy["value"] = event.value # type: ignore[assignment]
render_selection()
strategy_select.on_value_change(on_strategy_change)
render_selection()
render_chain()

View File

@@ -30,7 +30,7 @@ class DataService:
cache_key = f"portfolio:{ticker}"
cached = await self.cache.get_json(cache_key)
if cached:
if cached and isinstance(cached, dict):
return cached
quote = await self.get_quote(ticker)
@@ -49,7 +49,7 @@ class DataService:
async def get_quote(self, symbol: str) -> dict[str, Any]:
cache_key = f"quote:{symbol}"
cached = await self.cache.get_json(cache_key)
if cached:
if cached and isinstance(cached, dict):
return cached
quote = await self._fetch_quote(symbol)
@@ -61,7 +61,7 @@ class DataService:
cache_key = f"options:{ticker}"
cached = await self.cache.get_json(cache_key)
if cached:
if cached and isinstance(cached, dict):
return cached
quote = await self.get_quote(ticker)
@@ -116,7 +116,8 @@ class DataService:
},
"strategies": engine.compare_all_strategies(),
"recommendations": {
profile: engine.recommend(profile) for profile in ("conservative", "balanced", "cost_sensitive")
profile: engine.recommend(profile) # type: ignore[arg-type]
for profile in ("conservative", "balanced", "cost_sensitive")
},
"sensitivity_analysis": engine.sensitivity_analysis(),
}