Fix stale pending orders after CTP rejection or cancel.
When the exchange rejects or cancels an order, close local pending monitors once the order leaves CTP active list instead of waiting for the full timeout. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -41,6 +41,7 @@ from ctp_fee_worker import start_ctp_fee_worker
|
||||
from order_pending import (
|
||||
cancel_pending_monitor,
|
||||
pending_auto_cancel_remaining,
|
||||
pending_monitor_has_live_order,
|
||||
reconcile_pending_orders,
|
||||
)
|
||||
from db_conn import execute_retry
|
||||
@@ -1305,11 +1306,23 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
|
||||
except Exception as exc:
|
||||
logger.warning("compose ctp order row failed: %s", exc)
|
||||
|
||||
ctp_active_map: dict[str, dict] = {}
|
||||
for o in ctp_orders or []:
|
||||
for key in (o.get("order_id"), o.get("vt_order_id")):
|
||||
if key:
|
||||
ctp_active_map[str(key)] = o
|
||||
|
||||
for r in conn.execute(
|
||||
"SELECT * FROM trade_order_monitors WHERE status='pending' ORDER BY id DESC"
|
||||
).fetchall():
|
||||
mon = dict(r)
|
||||
try:
|
||||
if not pending_monitor_has_live_order(
|
||||
mon,
|
||||
active_orders=ctp_active_map,
|
||||
active_order_list=ctp_orders or [],
|
||||
):
|
||||
continue
|
||||
prow = _compose_pending_row(
|
||||
mon, mode=mode, capital=capital, now_iso=now_iso,
|
||||
)
|
||||
@@ -2207,6 +2220,17 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
|
||||
"SELECT status FROM trade_order_monitors WHERE id=?", (mid,),
|
||||
).fetchone()
|
||||
filled = st_row and (st_row["status"] or "").strip().lower() == "active"
|
||||
rejected = st_row and (st_row["status"] or "").strip().lower() == "closed"
|
||||
if rejected:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
_push_position_snapshot_async(fast=False)
|
||||
return jsonify({
|
||||
"ok": False,
|
||||
"error": "委托已被柜台拒绝或撤销(请确认合约状态与交易时段)",
|
||||
"lots": lots,
|
||||
"filled": False,
|
||||
}), 400
|
||||
if not filled:
|
||||
try:
|
||||
get_bridge().refresh_positions()
|
||||
@@ -2217,6 +2241,17 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
|
||||
"SELECT status FROM trade_order_monitors WHERE id=?", (mid,),
|
||||
).fetchone()
|
||||
filled = st_row and (st_row["status"] or "").strip().lower() == "active"
|
||||
rejected = st_row and (st_row["status"] or "").strip().lower() == "closed"
|
||||
if rejected:
|
||||
conn.commit()
|
||||
conn.close()
|
||||
_push_position_snapshot_async(fast=False)
|
||||
return jsonify({
|
||||
"ok": False,
|
||||
"error": "委托已被柜台拒绝或撤销(请确认合约状态与交易时段)",
|
||||
"lots": lots,
|
||||
"filled": False,
|
||||
}), 400
|
||||
if filled:
|
||||
_sync_monitor_from_ctp(
|
||||
conn, mid, sym, direction, mode, capital=_capital(conn),
|
||||
|
||||
Reference in New Issue
Block a user