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:
@@ -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():
|
||||
|
||||
@@ -66,39 +66,52 @@
|
||||
</div>
|
||||
<div id="opt-order-panel-host" class="opt-order-panel-host" hidden aria-hidden="true">
|
||||
<div id="opt-order-panel" class="opt-order-panel-inner" style="display:none">
|
||||
<h3 class="opt-order-title">下单</h3>
|
||||
<div id="opt-order-inst" class="options-order-inst"></div>
|
||||
<div class="options-order-grid">
|
||||
<div><span class="k">卖一/张</span><span id="opt-order-ask" class="v">—</span></div>
|
||||
<div><span class="k">买一/张</span><span id="opt-order-bid" class="v">—</span></div>
|
||||
<div><span class="k">张数</span><span id="opt-order-sheets" class="v">—</span></div>
|
||||
<div><span class="k" id="opt-order-eth-label">ETH 数量</span><span id="opt-order-eth" class="v">—</span></div>
|
||||
<div><span class="k">预估权利金</span><span id="opt-order-premium" class="v">—</span></div>
|
||||
<div><span class="k">合约杠杆</span><span id="opt-order-leverage" class="v" title="名义价值÷权利金,测算用">—</span></div>
|
||||
<div><span class="k">到期平衡</span><span id="opt-order-expiry-be" class="v">—</span></div>
|
||||
<div><span class="k">距平衡</span><span id="opt-order-dist-be" class="v">—</span></div>
|
||||
<div class="opt-order-layout">
|
||||
<div class="opt-order-main">
|
||||
<h3 class="opt-order-title">下单</h3>
|
||||
<div id="opt-order-inst" class="options-order-inst"></div>
|
||||
<div class="options-order-grid">
|
||||
<div><span class="k">卖一/张</span><span id="opt-order-ask" class="v">—</span></div>
|
||||
<div><span class="k">买一/张</span><span id="opt-order-bid" class="v">—</span></div>
|
||||
<div><span class="k">张数</span><span id="opt-order-sheets" class="v">—</span></div>
|
||||
<div><span class="k" id="opt-order-eth-label">ETH 数量</span><span id="opt-order-eth" class="v">—</span></div>
|
||||
<div><span class="k">预估权利金</span><span id="opt-order-premium" class="v">—</span></div>
|
||||
<div><span class="k">合约杠杆</span><span id="opt-order-leverage" class="v" title="名义价值÷权利金,测算用">—</span></div>
|
||||
<div><span class="k">到期平衡</span><span id="opt-order-expiry-be" class="v">—</span></div>
|
||||
<div><span class="k">距平衡</span><span id="opt-order-dist-be" class="v">—</span></div>
|
||||
</div>
|
||||
<div class="options-estimate-row">
|
||||
<label class="opt-est-label" for="opt-target-idx">目标位(指数)</label>
|
||||
<input type="number" id="opt-target-idx" class="opt-target-idx" step="0.1" min="0" placeholder="达价限价平仓">
|
||||
<span class="k">预计价值</span>
|
||||
<span id="opt-est-value" class="v">—</span>
|
||||
<span class="k">盈利</span>
|
||||
<span id="opt-est-profit" class="v">—</span>
|
||||
<span class="k">目标杠杆</span>
|
||||
<span id="opt-est-leverage" class="v" title="目标位名义价值÷权利金">—</span>
|
||||
<span class="muted opt-est-note">目标价=监控指数;到位后按买一限价平仓;无止损,到期即止损</span>
|
||||
</div>
|
||||
<div class="form-row options-order-mode-row">
|
||||
<label><input type="radio" name="opt-size-mode" value="sheets" checked> 指定张数</label>
|
||||
<input type="number" id="opt-sheets-amount" min="1" step="1" value="1" placeholder="张数">
|
||||
<label><input type="radio" name="opt-size-mode" value="budget_full"> 按可用余额打满</label>
|
||||
<label><input type="radio" name="opt-size-mode" value="eth_amount"> 指定币数量</label>
|
||||
<input type="number" id="opt-eth-amount" min="0.01" step="0.01" placeholder="如 0.5" style="display:none">
|
||||
<input type="text" id="opt-signal-note" placeholder="备注(关键位说明)">
|
||||
<button type="button" class="btn-primary" id="opt-open-btn">限价买入 @ 卖一</button>
|
||||
</div>
|
||||
<div id="opt-order-msg" class="muted"></div>
|
||||
</div>
|
||||
<aside class="opt-order-pending" aria-label="未成交委托">
|
||||
<div class="opt-order-pending-head">
|
||||
<h4 class="opt-order-pending-title">委托</h4>
|
||||
<button type="button" class="btn-secondary" id="opt-pending-refresh">刷新</button>
|
||||
</div>
|
||||
<div id="opt-pending-list" class="opt-pending-list">
|
||||
<div class="muted opt-pending-empty">暂无未成交委托</div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
<div class="options-estimate-row">
|
||||
<label class="opt-est-label" for="opt-target-idx">目标位(指数)</label>
|
||||
<input type="number" id="opt-target-idx" class="opt-target-idx" step="0.1" min="0" placeholder="达价限价平仓">
|
||||
<span class="k">预计价值</span>
|
||||
<span id="opt-est-value" class="v">—</span>
|
||||
<span class="k">盈利</span>
|
||||
<span id="opt-est-profit" class="v">—</span>
|
||||
<span class="k">目标杠杆</span>
|
||||
<span id="opt-est-leverage" class="v" title="目标位名义价值÷权利金">—</span>
|
||||
<span class="muted opt-est-note">目标价=监控指数;到位后按买一限价平仓;无止损,到期即止损</span>
|
||||
</div>
|
||||
<div class="form-row options-order-mode-row">
|
||||
<label><input type="radio" name="opt-size-mode" value="sheets" checked> 指定张数</label>
|
||||
<input type="number" id="opt-sheets-amount" min="1" step="1" value="1" placeholder="张数">
|
||||
<label><input type="radio" name="opt-size-mode" value="budget_full"> 按可用余额打满</label>
|
||||
<label><input type="radio" name="opt-size-mode" value="eth_amount"> 指定币数量</label>
|
||||
<input type="number" id="opt-eth-amount" min="0.01" step="0.01" placeholder="如 0.5" style="display:none">
|
||||
<input type="text" id="opt-signal-note" placeholder="备注(关键位说明)">
|
||||
<button type="button" class="btn-primary" id="opt-open-btn">限价买入 @ 卖一</button>
|
||||
</div>
|
||||
<div id="opt-order-msg" class="muted"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user