feat: option lab
This commit is contained in:
@@ -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_date = expiry["expiry_date"]
|
||||
spot_a = chain_a["spot"]
|
||||
strikes_a = sorted({row["strike"] for row in expiry["calls"]} | {row["strike"] for row in expiry["puts"]})
|
||||
if not strikes_a or spot_a is None:
|
||||
return {"available": False, "reason": "Aucun strike/spot exploitable dans le chain à cette date."}
|
||||
if spot_a is None:
|
||||
return {"available": False, "reason": "Spot manquant dans l'historique Saxo à la date de départ."}
|
||||
|
||||
# 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)
|
||||
if not rows_b:
|
||||
|
||||
Reference in New Issue
Block a user