feat: option lab

This commit is contained in:
OpenSquared
2026-07-28 14:33:25 +02:00
parent 06db653c46
commit 61e120a8c5

View File

@@ -77,9 +77,21 @@ def analyze_option_pricing(ticker: str, date_a: str, date_b: str, target_dte: Op
expiry = chain_a["expiries"][0] expiry = chain_a["expiries"][0]
expiry_date = expiry["expiry_date"] expiry_date = expiry["expiry_date"]
spot_a = chain_a["spot"] spot_a = chain_a["spot"]
strikes_a = sorted({row["strike"] for row in expiry["calls"]} | {row["strike"] for row in expiry["puts"]}) if spot_a is None:
if not strikes_a or spot_a is None: return {"available": False, "reason": "Spot manquant dans l'historique Saxo à la date de départ."}
return {"available": False, "reason": "Aucun strike/spot exploitable dans le chain à cette date."}
# Many rows in the accumulated history are spot-tracking placeholders with no real
# bid/ask (Saxo doesn't actively quote every strike) — only strikes with an actual
# tradeable mid (call OR put) are candidates for the hindsight pick below, otherwise
# the "closest to the outcome" strike could be one that was never really quoted at all.
strikes_a = sorted({
row["strike"] for row in (expiry["calls"] + expiry["puts"]) if row.get("mid", 0) > 0
})
if not strikes_a:
return {
"available": False,
"reason": f"Aucun strike avec une cotation réelle (bid/ask) dans l'historique Saxo au {date_a} pour l'échéance {expiry_date} — essayez un autre DTE cible ou une autre date.",
}
rows_b = get_snapshot_rows_asof(saxo_symbol, date_b) rows_b = get_snapshot_rows_asof(saxo_symbol, date_b)
if not rows_b: if not rows_b: