Show cancellable pending option orders beside the order form.

Fetch live OKX option hangs on the right after submit, with refresh and one-click cancel.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-15 21:22:29 +08:00
parent c2a0cea3f4
commit ab8b2a74e2
5 changed files with 364 additions and 33 deletions
+60
View File
@@ -766,6 +766,66 @@ def quote_option_contract(ex: ccxt.okx, inst_id: str) -> dict[str, Any]:
return {"ok": False, "msg": str(e)}
def fetch_option_pending_orders(ex: ccxt.okx, inst_id: str | None = None) -> list[dict[str, Any]]:
"""未成交期权委托(限价挂单)."""
params: dict[str, Any] = {"instType": "OPTION"}
inst = (inst_id or "").strip()
if inst:
params["instId"] = inst
try:
rows = ex.private_get_trade_orders_pending(params).get("data") or []
except Exception:
return []
out: list[dict[str, Any]] = []
for o in rows:
if not isinstance(o, dict):
continue
oid = str(o.get("ordId") or "").strip()
iid = str(o.get("instId") or "").strip()
if not oid or not iid:
continue
side = str(o.get("side") or "").lower()
px = _safe_float(o.get("px"))
sz = _safe_float(o.get("sz"))
fill_sz = _safe_float(o.get("fillSz")) or 0.0
acc_fill = _safe_float(o.get("accFillSz"))
if acc_fill is not None:
fill_sz = acc_fill
out.append(
{
"ord_id": oid,
"inst_id": iid,
"side": side,
"side_label": "买入" if side == "buy" else ("卖出" if side == "sell" else side or ""),
"px": px,
"sz": int(sz) if sz is not None else None,
"fill_sz": int(fill_sz) if fill_sz is not None else 0,
"state": str(o.get("state") or ""),
"ord_type": str(o.get("ordType") or ""),
"c_time": o.get("cTime"),
"u_time": o.get("uTime"),
"reduce_only": str(o.get("reduceOnly") or "").lower() in ("true", "1", "yes"),
}
)
out.sort(key=lambda x: int(float(x.get("c_time") or 0)), reverse=True)
return out
def cancel_option_order(ex: ccxt.okx, *, inst_id: str, ord_id: str) -> dict[str, Any]:
inst_id = (inst_id or "").strip()
ord_id = (ord_id or "").strip()
if not inst_id or not ord_id:
return {"ok": False, "msg": "缺少 inst_id 或 ord_id"}
try:
resp = ex.private_post_trade_cancel_order({"instId": inst_id, "ordId": ord_id})
data = (resp or {}).get("data") or []
if data and str(data[0].get("sCode")) == "0":
return {"ok": True, "data": data[0], "raw": resp}
return {"ok": False, "msg": _okx_trade_error_message(resp=resp), "raw": resp}
except Exception as e:
return {"ok": False, "msg": _okx_trade_error_message(e)}
def place_option_limit_order(
ex: ccxt.okx,
*,