feat: strategy builder

This commit is contained in:
OpenSquared
2026-07-27 18:58:02 +02:00
parent ce09159bfb
commit 568414ca0c
18 changed files with 1315 additions and 63 deletions

View File

@@ -43,7 +43,13 @@ class Surface:
class ScenarioSurface:
"""Shocked surface at the scenario horizon: parametric shifts + manual overrides."""
"""Shocked surface at the scenario horizon: parametric shifts + manual overrides.
`iv_level_shift` is already the "parallel" component (applies to every strike/expiry
uniformly) — `term_slope_shift` is the term-structure *slope* (zero at days=0, growing
linearly per 30 days), so between the two the surface already has the "parallel vs.
slope" split a term-structure model needs; a third "curvature" term is deliberately
not modeled yet (see project memory: Strategy Builder Greeks plan, Phase 1)."""
def __init__(
self,
@@ -51,14 +57,14 @@ class ScenarioSurface:
scenario_spot: float,
iv_level_shift: float,
skew_tilt: float,
term_shift: float,
term_slope_shift: float,
manual_overrides: Optional[Dict[Tuple[int, float], float]] = None,
):
self.base = base
self.spot = scenario_spot
self.iv_level_shift = iv_level_shift
self.skew_tilt = skew_tilt
self.term_shift = term_shift
self.term_slope_shift = term_slope_shift
self.manual_overrides = manual_overrides or {}
def iv_at(self, strike: float, days: float) -> float:
@@ -71,7 +77,7 @@ class ScenarioSurface:
base_iv
+ self.iv_level_shift
+ self.skew_tilt * moneyness
+ self.term_shift * (days / 30.0)
+ self.term_slope_shift * (days / 30.0)
)
return max(0.01, shocked)
@@ -137,7 +143,7 @@ def apply_scenario(
spot_shock_pct: float = 0.0,
iv_level_shift: float = 0.0,
skew_tilt: float = 0.0,
term_shift: float = 0.0,
term_slope_shift: float = 0.0,
manual_grid: Optional[List[Dict[str, Any]]] = None,
) -> ScenarioSurface:
"""
@@ -149,4 +155,4 @@ def apply_scenario(
for cell in (manual_grid or []):
if cell.get("iv") is not None:
overrides[(int(cell["days_to_expiry"]), float(cell["strike_pct"]))] = float(cell["iv"])
return ScenarioSurface(surface, scenario_spot, iv_level_shift, skew_tilt, term_shift, overrides)
return ScenarioSurface(surface, scenario_spot, iv_level_shift, skew_tilt, term_slope_shift, overrides)