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
+59
View File
@@ -87,6 +87,8 @@ def _build_cfg(app_module: Any) -> dict[str, Any]:
fetch_options_balances,
format_position_row,
options_api_ready,
cancel_option_order,
fetch_option_pending_orders,
place_option_limit_order,
place_option_market_order,
quote_option_contract,
@@ -119,6 +121,8 @@ def _build_cfg(app_module: Any) -> dict[str, Any]:
"fetch_option_book_depth": fetch_option_book_depth,
"place_option_limit_order": place_option_limit_order,
"place_option_market_order": place_option_market_order,
"fetch_option_pending_orders": fetch_option_pending_orders,
"cancel_option_order": cancel_option_order,
"fetch_option_positions": fetch_option_positions,
"fetch_options_balances": fetch_options_balances,
"format_position_row": format_position_row,
@@ -531,6 +535,61 @@ def register_options_routes(app: Flask, cfg: dict[str, Any]) -> None:
}
)
@app.route("/api/options/orders/pending")
@lr
def api_options_orders_pending():
ex, err = _require_options_ex(cfg)
if ex is None:
return jsonify({"ok": False, "msg": err})
inst_id = (request.args.get("inst_id") or "").strip() or None
try:
orders = cfg["fetch_option_pending_orders"](ex, inst_id)
except Exception as e:
return jsonify({"ok": False, "msg": f"获取委托失败: {e}"})
return jsonify({"ok": True, "orders": orders, "count": len(orders)})
@app.route("/api/options/orders/cancel", methods=["POST"])
@lr
def api_options_orders_cancel():
ex, err = _require_options_ex(cfg)
if ex is None:
return jsonify({"ok": False, "msg": err})
data = request.get_json(silent=True) or {}
inst_id = (data.get("inst_id") or "").strip()
ord_id = (data.get("ord_id") or "").strip()
if not inst_id or not ord_id:
return jsonify({"ok": False, "msg": "缺少 inst_id 或 ord_id"})
out = cfg["cancel_option_order"](ex, inst_id=inst_id, ord_id=ord_id)
if out.get("ok"):
from lib.exchange.okx_options_lib import invalidate_option_positions_cache
invalidate_option_positions_cache()
# 本地未成交开仓记录标记取消,避免假 open
try:
conn = cfg["get_db"]()
try:
init_options_tables(conn)
conn.execute(
"""
UPDATE options_trades
SET status = 'cancelled',
signal_note = CASE
WHEN signal_note IS NULL OR TRIM(signal_note) = '' THEN '委托撤销'
ELSE signal_note
END,
closed_at = CURRENT_TIMESTAMP
WHERE inst_id = ? AND exchange_ord_id = ? AND status = 'open'
""",
(inst_id, ord_id),
)
conn.commit()
finally:
conn.close()
except Exception:
pass
_sync_options_trades(cfg, force=True)
return jsonify(out), (200 if out.get("ok") else 400)
@app.route("/api/options/positions")
@lr
def api_options_positions():