Fix options select UI and false contract-missing quotes.
Keep the order host out of tbody wipes, sync pick-button labels, and retry/fallback OKX meta under rate limits so live contracts are not reported as missing. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -370,24 +370,62 @@ def normalize_option_exp_ms(exp_time: Any, inst_id: str = "") -> int | None:
|
||||
return expiry_ms_from_inst_id(inst_id)
|
||||
|
||||
|
||||
def _is_okx_rate_limit(err: BaseException) -> bool:
|
||||
text = str(err) or ""
|
||||
name = err.__class__.__name__
|
||||
return "50011" in text or "Too Many Requests" in text or "RateLimit" in name
|
||||
|
||||
|
||||
def _meta_from_inst_id_fallback(inst_id: str) -> dict[str, Any]:
|
||||
"""行情在但 instruments 限频时,用合约 ID 拼最小 meta,避免误报「合约不存在」."""
|
||||
family = inst_family_from_inst_id(inst_id) or ""
|
||||
opt_type, strike = option_fields_from_inst_id(inst_id)
|
||||
uly = family.replace("_UM", "") if family else ""
|
||||
return {
|
||||
"instId": inst_id,
|
||||
"instFamily": family,
|
||||
"uly": uly,
|
||||
"optType": opt_type,
|
||||
"stk": strike,
|
||||
"ctMult": 0.01,
|
||||
"minSz": "1",
|
||||
"tickSz": "0.0001",
|
||||
"state": "live",
|
||||
}
|
||||
|
||||
|
||||
def fetch_option_instrument_meta(ex: ccxt.okx, inst_id: str) -> dict[str, Any] | None:
|
||||
family = inst_family_from_inst_id(inst_id)
|
||||
if not family:
|
||||
return None
|
||||
try:
|
||||
rows = ex.public_get_public_instruments(
|
||||
{"instType": "OPTION", "instFamily": family, "instId": inst_id}
|
||||
).get("data") or []
|
||||
if rows and isinstance(rows[0], dict):
|
||||
return rows[0]
|
||||
rows = ex.public_get_public_instruments(
|
||||
{"instType": "OPTION", "instFamily": family}
|
||||
).get("data") or []
|
||||
for r in rows:
|
||||
if isinstance(r, dict) and str(r.get("instId")) == inst_id:
|
||||
return r
|
||||
except Exception:
|
||||
return None
|
||||
last_err: BaseException | None = None
|
||||
for attempt in range(3):
|
||||
try:
|
||||
rows = ex.public_get_public_instruments(
|
||||
{"instType": "OPTION", "instFamily": family, "instId": inst_id}
|
||||
).get("data") or []
|
||||
if rows and isinstance(rows[0], dict):
|
||||
return rows[0]
|
||||
rows = ex.public_get_public_instruments(
|
||||
{"instType": "OPTION", "instFamily": family}
|
||||
).get("data") or []
|
||||
for r in rows:
|
||||
if isinstance(r, dict) and str(r.get("instId")) == inst_id:
|
||||
return r
|
||||
return None
|
||||
except Exception as e:
|
||||
last_err = e
|
||||
if _is_okx_rate_limit(e) and attempt < 2:
|
||||
time.sleep(0.45 * (attempt + 1))
|
||||
continue
|
||||
break
|
||||
if last_err is not None and _is_okx_rate_limit(last_err):
|
||||
try:
|
||||
t_rows = ex.public_get_market_ticker({"instId": inst_id}).get("data") or []
|
||||
if t_rows:
|
||||
return _meta_from_inst_id_fallback(inst_id)
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
@@ -747,9 +785,25 @@ def quote_option_contract(ex: ccxt.okx, inst_id: str) -> dict[str, Any]:
|
||||
return {"ok": False, "msg": "缺少 inst_id"}
|
||||
try:
|
||||
meta = fetch_option_instrument_meta(ex, inst_id)
|
||||
t_rows: list[Any] = []
|
||||
ticker_err: BaseException | None = None
|
||||
for attempt in range(3):
|
||||
try:
|
||||
t_rows = ex.public_get_market_ticker({"instId": inst_id}).get("data") or []
|
||||
ticker_err = None
|
||||
break
|
||||
except Exception as e:
|
||||
ticker_err = e
|
||||
if _is_okx_rate_limit(e) and attempt < 2:
|
||||
time.sleep(0.45 * (attempt + 1))
|
||||
continue
|
||||
break
|
||||
if not meta and t_rows:
|
||||
meta = _meta_from_inst_id_fallback(inst_id)
|
||||
if not meta:
|
||||
if ticker_err is not None and _is_okx_rate_limit(ticker_err):
|
||||
return {"ok": False, "msg": "行情限频,请稍后重试"}
|
||||
return {"ok": False, "msg": "合约不存在"}
|
||||
t_rows = ex.public_get_market_ticker({"instId": inst_id}).get("data") or []
|
||||
t = t_rows[0] if t_rows else {}
|
||||
ask = _safe_float(t.get("askPx"))
|
||||
bid = _safe_float(t.get("bidPx"))
|
||||
|
||||
Reference in New Issue
Block a user