Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| from dataclasses import dataclass | |
| from datetime import datetime | |
| from typing import Any | |
| import pandas as pd | |
| class OIPDConfig: | |
| risk_free_rate: float = 0.04 | |
| method: str = "svi" | |
| pricing_engine: str = "black76" | |
| price_method: str = "mid" | |
| max_staleness_days: int = 3 | |
| class OIPDDistributionResult: | |
| density: pd.DataFrame | |
| metadata: dict[str, Any] | |
| def prepare_oipd_chain(options: pd.DataFrame, expiry: datetime) -> pd.DataFrame: | |
| s = options[pd.to_datetime(options["expiry"]) == pd.to_datetime(expiry)].copy() | |
| if s.empty: | |
| raise ValueError(f"No option rows for expiry={expiry}") | |
| s["option_type"] = ( | |
| s["option_type"] | |
| .astype(str) | |
| .str.lower() | |
| .map({"call": "C", "put": "P"}) | |
| .fillna(s["option_type"]) | |
| ) | |
| s["last_price"] = s["mid"].astype(float) | |
| s["expiry"] = pd.to_datetime(s["expiry"]).dt.tz_localize(None) | |
| needed_cols = ["strike", "option_type", "bid", "ask", "last_price", "expiry"] | |
| for col in ["bid", "ask"]: | |
| if col not in s.columns: | |
| s[col] = pd.NA | |
| out = s[needed_cols].copy() | |
| out = out.dropna(subset=["strike", "last_price", "option_type"]).reset_index( | |
| drop=True | |
| ) | |
| if out.empty: | |
| raise ValueError("No valid rows after OIPD chain preparation") | |
| return out | |
| def fit_oipd_distribution( | |
| chain: pd.DataFrame, | |
| spot: float, | |
| valuation_time: datetime, | |
| config: OIPDConfig, | |
| ) -> OIPDDistributionResult: | |
| try: | |
| from oipd import MarketInputs, VolCurve | |
| except ImportError as exc: | |
| raise RuntimeError("oipd is not installed. Run: uv sync --extra v2") from exc | |
| market = MarketInputs( | |
| risk_free_rate=float(config.risk_free_rate), | |
| valuation_date=valuation_time.date(), | |
| underlying_price=float(spot), | |
| ) | |
| vc = VolCurve( | |
| method=config.method, | |
| pricing_engine=config.pricing_engine, | |
| price_method=config.price_method, | |
| max_staleness_days=int(config.max_staleness_days), | |
| ) | |
| vc.fit(chain, market) | |
| prob = vc.implied_distribution() | |
| df = prob.density_results() | |
| density = df.rename(columns={"price": "strike", "pdf": "density"})[ | |
| ["strike", "density", "cdf"] | |
| ].copy() | |
| metadata = { | |
| "method": config.method, | |
| "pricing_engine": config.pricing_engine, | |
| "price_method": config.price_method, | |
| "diagnostics": vc.diagnostics, | |
| } | |
| return OIPDDistributionResult(density=density, metadata=metadata) | |