Auto-cancel stale option close limits after pending TTL.
Default 10m via OKX_OPTIONS_PENDING_TTL_SECONDS; show age/countdown in pending panel; monitor loop cancels sell closes. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
let positionsRefreshSeq = 0;
|
||||
let refreshAllTimer = null;
|
||||
let pendingRefreshTimer = null;
|
||||
let pendingTtlSeconds = 600;
|
||||
const POSITIONS_STALE_MS = 45000;
|
||||
const PENDING_POLL_MS = 8000;
|
||||
|
||||
@@ -123,8 +124,30 @@
|
||||
startPendingOrdersPoll();
|
||||
}
|
||||
|
||||
function paintPendingOrders(orders) {
|
||||
function fmtPendingAge(sec) {
|
||||
if (sec == null || Number.isNaN(Number(sec))) return "—";
|
||||
let s = Math.max(0, Math.round(Number(sec)));
|
||||
if (s < 60) return s + "秒";
|
||||
const m = Math.floor(s / 60);
|
||||
const rs = s % 60;
|
||||
if (m < 60) return rs ? m + "分" + rs + "秒" : m + "分";
|
||||
const h = Math.floor(m / 60);
|
||||
const rm = m % 60;
|
||||
return rm ? h + "时" + rm + "分" : h + "时";
|
||||
}
|
||||
|
||||
function paintPendingOrders(orders, ttlSec) {
|
||||
const host = document.getElementById("opt-pending-list");
|
||||
const hint = document.getElementById("opt-pending-ttl-hint");
|
||||
if (ttlSec != null && !Number.isNaN(Number(ttlSec))) {
|
||||
pendingTtlSeconds = Number(ttlSec);
|
||||
}
|
||||
if (hint) {
|
||||
const ttl = pendingTtlSeconds;
|
||||
hint.textContent = ttl > 0
|
||||
? ("平仓限价超 " + fmtPendingAge(ttl) + " 未成交将自动撤销")
|
||||
: "平仓超时自动撤单已关闭";
|
||||
}
|
||||
if (!host) return;
|
||||
const rows = Array.isArray(orders) ? orders : [];
|
||||
if (!rows.length) {
|
||||
@@ -136,10 +159,17 @@
|
||||
const sideCls = side === "buy" ? "is-buy" : side === "sell" ? "is-sell" : "";
|
||||
const remain = (o.sz != null && o.fill_sz != null) ? Math.max(0, Number(o.sz) - Number(o.fill_sz)) : o.sz;
|
||||
const pxTxt = o.px != null ? fmtOptionPx(o.px, null) : "—";
|
||||
const kind = o.is_close_order ? "平仓" : "开仓";
|
||||
let ttlTxt = "";
|
||||
if (o.auto_cancel_enabled) {
|
||||
if (o.stale) ttlTxt = " · 超时待撤";
|
||||
else if (o.expire_in_sec != null) ttlTxt = " · 剩 " + fmtPendingAge(o.expire_in_sec) + " 自动撤";
|
||||
}
|
||||
const ageTxt = o.age_sec != null ? ("已挂 " + fmtPendingAge(o.age_sec)) : "";
|
||||
return (
|
||||
'<div class="opt-pending-item" data-ord="' + (o.ord_id || "") + '" data-inst="' + (o.inst_id || "") + '">' +
|
||||
'<div class="opt-pending-item-top">' +
|
||||
'<span class="opt-pending-side ' + sideCls + '">' + (o.side_label || side || "—") + "</span>" +
|
||||
'<span class="opt-pending-side ' + sideCls + '">' + kind + " · " + (o.side_label || side || "—") + "</span>" +
|
||||
'<button type="button" class="btn-secondary opt-pending-cancel" data-ord="' + (o.ord_id || "") +
|
||||
'" data-inst="' + (o.inst_id || "") + '">撤销</button>' +
|
||||
"</div>" +
|
||||
@@ -148,6 +178,8 @@
|
||||
" · 张数 " + (o.sz != null ? o.sz : "—") +
|
||||
(o.fill_sz != null && Number(o.fill_sz) > 0 ? " · 已成 " + o.fill_sz : "") +
|
||||
(remain != null && o.fill_sz != null && Number(o.fill_sz) > 0 ? " · 剩余 " + remain : "") +
|
||||
(ageTxt ? " · " + ageTxt : "") +
|
||||
ttlTxt +
|
||||
"</div></div>"
|
||||
);
|
||||
}).join("");
|
||||
@@ -167,7 +199,7 @@
|
||||
host.innerHTML = '<div class="muted opt-pending-empty">' + (d.msg || "获取委托失败") + "</div>";
|
||||
return;
|
||||
}
|
||||
paintPendingOrders(d.orders || []);
|
||||
paintPendingOrders(d.orders || [], d.pending_ttl_seconds);
|
||||
} catch (e) {
|
||||
host.innerHTML = '<div class="muted opt-pending-empty">获取委托失败</div>';
|
||||
}
|
||||
@@ -176,8 +208,7 @@
|
||||
function startPendingOrdersPoll() {
|
||||
stopPendingOrdersPoll();
|
||||
pendingRefreshTimer = setInterval(function () {
|
||||
const panel = orderPanel();
|
||||
if (!panel || panel.style.display === "none") {
|
||||
if (!document.getElementById("options-root")) {
|
||||
stopPendingOrdersPoll();
|
||||
return;
|
||||
}
|
||||
@@ -1709,6 +1740,8 @@
|
||||
syncMoneyFilterButtons();
|
||||
syncChainViewUI();
|
||||
updateUnderlyingLabel();
|
||||
refreshPendingOrders();
|
||||
startPendingOrdersPoll();
|
||||
const hasCache =
|
||||
panelCache.chain &&
|
||||
panelCache.underlying === state.underlying &&
|
||||
|
||||
Reference in New Issue
Block a user