feat: strategy builder
This commit is contained in:
@@ -41,6 +41,12 @@ class ScenarioIn(BaseModel):
|
||||
# options (e.g. dte_min=20, dte_max=60) instead of horizon_days doing double duty.
|
||||
dte_min: Optional[int] = None
|
||||
dte_max: Optional[int] = None
|
||||
# "Dériver d'un historique" mode: reconstruct the chain (and every leg strike drawn
|
||||
# from it, including in /optimize) as it stood at/before this date instead of live —
|
||||
# e.g. so the optimizer searches over what was ACTUALLY quoted on the day a realized
|
||||
# scenario's window starts, not today's chain. None (default) = live, unchanged
|
||||
# behavior for the normal Construire flow.
|
||||
as_of: Optional[str] = None
|
||||
|
||||
@property
|
||||
def shocked_rate(self) -> float:
|
||||
@@ -118,7 +124,7 @@ class StrategySaveRequest(BaseModel):
|
||||
def _build_surfaces(scenario: ScenarioIn):
|
||||
chain_slice = get_chain_slice(
|
||||
scenario.symbol, scenario.horizon_days, scenario.n_expiries,
|
||||
dte_min=scenario.dte_min, dte_max=scenario.dte_max,
|
||||
dte_min=scenario.dte_min, dte_max=scenario.dte_max, as_of=scenario.as_of,
|
||||
)
|
||||
surface_now = build_surface(chain_slice)
|
||||
surface_scenario = apply_scenario(
|
||||
@@ -206,6 +212,20 @@ def price(req: PriceRequest):
|
||||
return result
|
||||
|
||||
|
||||
@router.get("/realized-scenario")
|
||||
def realized_scenario(symbol: str = Query(...), start_date: str = Query(...), end_date: str = Query(...)):
|
||||
""""Dériver d'un historique" mode: turns a real Du→Au window into scenario inputs
|
||||
(spot_shock_pct/iv_level_shift/horizon_days) computed from what actually happened —
|
||||
see services.realized_scenario. The frontend copies these into the normal scenario
|
||||
state (same one Construire/optimize use) rather than this being a separate pricing
|
||||
path of its own."""
|
||||
from services.realized_scenario import compute_realized_scenario
|
||||
try:
|
||||
return compute_realized_scenario(symbol, start_date, end_date)
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
|
||||
|
||||
@router.post("/suggested-profile")
|
||||
def suggested_profile(scenario: ScenarioIn):
|
||||
"""Mode 1 of the scenario/profile/constraints split: what Greek behavior this scenario
|
||||
|
||||
Reference in New Issue
Block a user