fix期权链 Delta 改为从 opt-summary 拉取。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-14 22:20:08 +08:00
parent 627c27a6f8
commit 4e14c92385
2 changed files with 52 additions and 5 deletions
+34 -4
View File
@@ -799,6 +799,37 @@ def fetch_option_tickers(ex: ccxt.okx, inst_family: str) -> dict[str, dict[str,
return out
def fetch_option_summaries(ex: ccxt.okx, inst_family: str) -> dict[str, dict[str, Any]]:
"""GET /api/v5/public/opt-summary — 含 delta / deltaBS 等希腊字母.
市场 tickers 不含 Delta,期权链展示必须走本接口.
"""
out: dict[str, dict[str, Any]] = {}
try:
rows = ex.public_get_public_opt_summary({"instFamily": inst_family}).get("data") or []
for r in rows:
if isinstance(r, dict) and r.get("instId"):
out[str(r["instId"])] = r
except Exception:
pass
return out
def option_delta_from_summary(
summary: dict[str, Any] | None = None,
*,
ticker: dict[str, Any] | None = None,
) -> float | None:
"""优先 Black-Scholes 单位 Delta(deltaBS),其次 delta;兼容 ticker 偶发字段."""
for src in (summary, ticker):
if not isinstance(src, dict):
continue
for key in ("deltaBS", "delta", "deltaBs", "delta_bs"):
v = _safe_float(src.get(key))
if v is not None:
return v
return None
def build_option_chain(
ex: ccxt.okx,
underlying: str,
@@ -847,6 +878,7 @@ def build_option_chain(
except Exception as e2:
instruments_err = str(e2) or e2.__class__.__name__
tickers = fetch_option_tickers(ex, family)
summaries = fetch_option_summaries(ex, family)
expiries: dict[str, list[dict[str, Any]]] = {}
skipped_no_index = 0
for meta in instruments:
@@ -872,6 +904,7 @@ def build_option_chain(
continue
inst_id = str(meta.get("instId") or "")
t = tickers.get(inst_id) or {}
s = summaries.get(inst_id) or {}
q = _resolve_chain_quote(
ticker=t,
meta=meta,
@@ -884,10 +917,7 @@ def build_option_chain(
mark = q["mark_px"]
ask_sz = q["ask_sz"]
bid_sz = q["bid_sz"]
# 行情 ticker:delta;兼容个别字段名
delta = _safe_float(t.get("delta"))
if delta is None:
delta = _safe_float(t.get("deltaBS"))
delta = option_delta_from_summary(s, ticker=t)
expiry_be = expiry_breakeven_from_ask(
opt_type=opt_type,
strike=strike,