feat: strategy builder
This commit is contained in:
@@ -146,6 +146,38 @@ def chain(
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
|
||||
|
||||
@router.get("/presets")
|
||||
def presets(
|
||||
symbol: str = Query(...),
|
||||
horizon_days: int = Query(8),
|
||||
dte_min: Optional[int] = Query(None),
|
||||
dte_max: Optional[int] = Query(None),
|
||||
):
|
||||
"""The full strategy catalog (services.backtest_strategies.STRATEGIES) built from the
|
||||
REAL current chain instead of Backtest's synthetic grid — so a preset click here seeds
|
||||
the leg editor with actually-quoted strikes/expiries, ready to price or replay as-is.
|
||||
n_expiries=5 (vs. Strategy Builder's own default of 3) so calendar/diagonal presets,
|
||||
which need two distinct expiries, reliably have a second one to draw from."""
|
||||
from services.backtest_strategies import STRATEGIES, build_legs
|
||||
try:
|
||||
chain_slice = get_chain_slice(symbol, horizon_days, 5, dte_min=dte_min, dte_max=dte_max)
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
|
||||
expiries = chain_slice["expiries"]
|
||||
if not expiries:
|
||||
raise HTTPException(status_code=404, detail=f"Aucune échéance exploitable pour '{symbol}'.")
|
||||
near, far = expiries[0], expiries[1] if len(expiries) > 1 else None
|
||||
|
||||
out = []
|
||||
for key, label, n_legs in STRATEGIES:
|
||||
legs = build_legs(key, chain_slice["spot"], 0.05, near, far)
|
||||
if not legs:
|
||||
continue # e.g. calendar/diagonal with only one real expiry available right now
|
||||
out.append({"key": key, "label": label, "n_legs": n_legs, "legs": legs})
|
||||
return out
|
||||
|
||||
|
||||
@router.post("/price")
|
||||
def price(req: PriceRequest):
|
||||
if not req.legs:
|
||||
|
||||
Reference in New Issue
Block a user