diff --git a/static/cond_orders.js b/static/cond_orders.js
index 702c068..9361ab4 100644
--- a/static/cond_orders.js
+++ b/static/cond_orders.js
@@ -1,333 +1,395 @@
-(function (global) {
- function escapeHtml(s) {
- return String(s)
- .replace(/&/g, "&")
- .replace(//g, ">")
- .replace(/"/g, """);
- }
-
- function leftTriggerSide(optType) {
- return String(optType || "P").toUpperCase() === "C" ? "lte" : "gte";
- }
-
- function triggerHintText(optType, px) {
- const put = String(optType || "P").toUpperCase() !== "C";
- const price = px && String(px).trim() !== "" ? String(px) : "触发价";
- if (put) {
- return "看跌左侧单:指数上穿 " + price + " 后,在偏离区内开最近实值 Put。";
- }
- return "看涨左侧单:指数下穿 " + price + " 后,在偏离区内开最近实值 Call。";
- }
-
- function syncTriggerHint() {
- const hint = document.getElementById("cf-trigger-hint");
- const typeEl = document.getElementById("cf-opt-type");
- const pxEl = document.getElementById("cf-trigger-px");
- if (!hint || !typeEl) return;
- hint.textContent = triggerHintText(typeEl.value, pxEl && pxEl.value);
- hint.className = "cond-trigger-hint " + (typeEl.value === "C" ? "is-call" : "is-put");
- }
-
- function statusLabel(o) {
- const st = o.status || "";
- const reason = o.end_reason || "";
- if (st === "done") {
- const map = {
- leave_up: "结束·上破",
- leave_down: "结束·下破",
- cancel: "已取消",
- closed: "已完成",
- };
- return map[reason] || "已结束";
- }
- const map2 = { armed: "待命", triggering: "触发中", open: "持仓中" };
- return map2[st] || st || "—";
- }
-
- function statusClass(o) {
- const st = o.status || "";
- if (st === "open") return "st-open";
- if (st === "triggering") return "st-trig";
- if (st === "armed") return "st-armed";
- return "st-done";
- }
-
- function instanceMode(it) {
- const m = String((it && it.mode) || "").toLowerCase();
- return m === "sim" || m === "live" ? m : "";
- }
-
- function renderCandidateCard(it, checkedIds) {
- const disabled = !it.selectable;
- const tip = disabled
- ? it.has_position
- ? "已有持仓"
- : it.cond_order_locked
- ? "条件单占用"
- : it.online
- ? "不可选"
- : "离线"
- : "可选";
- const id = String(it.id);
- const checked = !disabled && checkedIds.indexOf(id) >= 0;
- return (
- '"
- );
- }
-
- function renderCandidateGroup(mode, items, checkedIds) {
- if (!items.length) return "";
- const label =
- mode === "sim" || mode === "live"
- ? '
' +
- mode +
- "
"
- : "";
- return (
- '' +
- label +
- '
' +
- items
- .map(function (it) {
- return renderCandidateCard(it, checkedIds);
- })
- .join("") +
- "
"
- );
- }
-
- async function loadCandidates() {
- const box = document.getElementById("cf-instances");
- if (!box) return;
- const checkedIds = Array.prototype.slice
- .call(box.querySelectorAll('input[name="cf-inst"]:checked'))
- .map(function (el) {
- return decodeURIComponent(el.value || "");
- });
- const r = await fetch("/api/cond_orders/candidates");
- const d = await r.json();
- const list = d.instances || [];
- if (!list.length) {
- box.innerHTML = '暂无启用实例';
- return;
- }
- const sim = [];
- const live = [];
- const other = [];
- list.forEach(function (it) {
- const m = instanceMode(it);
- if (m === "sim") sim.push(it);
- else if (m === "live") live.push(it);
- else other.push(it);
- });
- box.innerHTML =
- renderCandidateGroup("sim", sim, checkedIds) +
- renderCandidateGroup("live", live, checkedIds) +
- renderCandidateGroup("", other, checkedIds);
- }
-
- async function loadOrders() {
- const box = document.getElementById("cond-list");
- if (!box) return;
- const r = await fetch("/api/cond_orders");
- const d = await r.json();
- const list = d.orders || [];
- if (!list.length) {
- box.innerHTML = '暂无条件单
';
- return;
- }
- box.innerHTML =
- '' +
- "| 客户端 | 状态 | 标的 | 触发 | 偏离 | 到期h | 出场 | 说明 | 操作 | " +
- "
" +
- list
- .map(function (o) {
- const side = o.trigger_side === "lte" ? "下穿 ≤" : "上穿 ≥";
- const exit =
- (o.profit_exit_enabled ? "翻倍×" + (o.profit_exit_mult || "") : "") +
- (o.target_index != null ? " 目标" + o.target_index : "");
- const canCancel = o.status === "armed" || o.status === "triggering";
- const canExit = o.status === "open";
- let actions = "";
- if (canCancel) {
- actions +=
- '';
- }
- if (canExit) {
- actions +=
- '';
- }
- return (
- "" +
- "| " +
- escapeHtml(o.instance_name || "") +
- " | " +
- '' +
- escapeHtml(statusLabel(o)) +
- " | " +
- "" +
- escapeHtml((o.underlying || "") + " " + (o.opt_type || "")) +
- " | " +
- "" +
- escapeHtml(side + " " + (o.trigger_px != null ? o.trigger_px : "")) +
- " | " +
- "" +
- escapeHtml(o.deviation_pct != null ? o.deviation_pct + "%" : "—") +
- " | " +
- "" +
- escapeHtml(o.min_expiry_hours != null ? String(o.min_expiry_hours) : "—") +
- " | " +
- "" +
- escapeHtml(exit || "—") +
- " | " +
- '' +
- escapeHtml(o.message || "") +
- " | " +
- '' +
- actions +
- " | " +
- "
"
- );
- })
- .join("") +
- "
";
-
- box.querySelectorAll("[data-cancel]").forEach(function (btn) {
- btn.addEventListener("click", async function () {
- if (!confirm("确认取消该条件单?")) return;
- const oid = decodeURIComponent(btn.getAttribute("data-cancel") || "");
- const iid = decodeURIComponent(btn.getAttribute("data-iid") || "");
- const rr = await fetch("/api/cond_orders/" + encodeURIComponent(oid) + "/cancel", {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({ instance_id: Number(iid) }),
- });
- const dd = await rr.json();
- alert(dd.msg || (dd.ok ? "已取消" : "失败"));
- refresh();
- });
- });
- box.querySelectorAll("[data-exit]").forEach(function (btn) {
- btn.addEventListener("click", async function () {
- const oid = decodeURIComponent(btn.getAttribute("data-exit") || "");
- const iid = decodeURIComponent(btn.getAttribute("data-iid") || "");
- const curT = decodeURIComponent(btn.getAttribute("data-target") || "");
- const curM = decodeURIComponent(btn.getAttribute("data-mult") || "1");
- const pe = btn.getAttribute("data-pe") === "1";
- const t = prompt("目标指数(留空清除)", curT);
- if (t === null) return;
- const peOn = confirm("是否启用翻倍出场?\n当前:" + (pe ? "开" : "关"));
- let mult = curM;
- if (peOn) {
- const m = prompt("翻倍倍数", curM);
- if (m === null) return;
- mult = m;
- }
- const rr = await fetch("/api/cond_orders/" + encodeURIComponent(oid) + "/exit", {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({
- instance_id: Number(iid),
- target_index: t === "" ? "" : t,
- profit_exit_enabled: peOn,
- profit_exit_mult: mult,
- }),
- });
- const dd = await rr.json();
- alert(dd.msg || (dd.ok ? "已更新" : "失败"));
- refresh();
- });
- });
- }
-
- async function createOrder() {
- const status = document.getElementById("cf-status");
- const ids = Array.prototype.slice
- .call(document.querySelectorAll('input[name="cf-inst"]:checked'))
- .map(function (el) {
- return Number(decodeURIComponent(el.value));
- });
- if (!ids.length) {
- alert("请选择至少一台可选客户端");
- return;
- }
- const optType = document.getElementById("cf-opt-type").value;
- const body = {
- instance_ids: ids,
- underlying: document.getElementById("cf-underlying").value,
- opt_type: optType,
- trigger_side: leftTriggerSide(optType),
- trigger_px: document.getElementById("cf-trigger-px").value,
- deviation_pct: document.getElementById("cf-deviation").value,
- min_expiry_hours: document.getElementById("cf-expiry-h").value,
- target_index: document.getElementById("cf-target").value,
- profit_exit_enabled: document.getElementById("cf-pe").checked,
- profit_exit_mult: document.getElementById("cf-pe-mult").value,
- };
- if (status) status.textContent = "下发中…";
- const r = await fetch("/api/cond_orders", {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify(body),
- });
- const d = await r.json();
- if (status) status.textContent = d.msg || "";
- alert(d.msg || (d.ok ? "已下发" : "失败"));
- refresh();
- }
-
- async function refresh() {
- await Promise.all([loadCandidates(), loadOrders()]);
- }
-
- function boot() {
- const btn = document.getElementById("btn-cond-refresh");
- if (btn) btn.addEventListener("click", refresh);
- const create = document.getElementById("btn-cond-create");
- if (create) create.addEventListener("click", createOrder);
- const typeEl = document.getElementById("cf-opt-type");
- const pxEl = document.getElementById("cf-trigger-px");
- if (typeEl) typeEl.addEventListener("change", syncTriggerHint);
- if (pxEl) pxEl.addEventListener("input", syncTriggerHint);
- syncTriggerHint();
- refresh();
- setInterval(refresh, 10000);
- }
-
- global.HubCondOrders = { boot: boot, refresh: refresh };
-})(window);
+(function (global) {
+ function escapeHtml(s) {
+ return String(s)
+ .replace(/&/g, "&")
+ .replace(//g, ">")
+ .replace(/"/g, """);
+ }
+
+ function leftTriggerSide(optType) {
+ return String(optType || "P").toUpperCase() === "C" ? "lte" : "gte";
+ }
+
+ function triggerHintText(optType, px) {
+ const put = String(optType || "P").toUpperCase() !== "C";
+ const price = px && String(px).trim() !== "" ? String(px) : "触发价";
+ if (put) {
+ return "看跌左侧单:指数上穿 " + price + " 后,在偏离区内开最近实值 Put。";
+ }
+ return "看涨左侧单:指数下穿 " + price + " 后,在偏离区内开最近实值 Call。";
+ }
+
+ function syncTriggerHint() {
+ const hint = document.getElementById("cf-trigger-hint");
+ const typeEl = document.getElementById("cf-opt-type");
+ const pxEl = document.getElementById("cf-trigger-px");
+ if (!hint || !typeEl) return;
+ hint.textContent = triggerHintText(typeEl.value, pxEl && pxEl.value);
+ hint.className = "cond-trigger-hint " + (typeEl.value === "C" ? "is-call" : "is-put");
+ }
+
+ function statusLabel(o) {
+ const st = o.status || "";
+ const reason = o.end_reason || "";
+ if (st === "done") {
+ const map = {
+ leave_up: "结束·上破",
+ leave_down: "结束·下破",
+ cancel: "已取消",
+ closed: "已完成",
+ };
+ return map[reason] || "已结束";
+ }
+ const map2 = { armed: "待命", triggering: "触发中", open: "持仓中" };
+ return map2[st] || st || "—";
+ }
+
+ function statusClass(o) {
+ const st = o.status || "";
+ if (st === "open") return "st-open";
+ if (st === "triggering") return "st-trig";
+ if (st === "armed") return "st-armed";
+ return "st-done";
+ }
+
+ function isHubPhone() {
+ return (
+ document.documentElement.classList.contains("hub-phone-html") ||
+ !!(document.body && document.body.classList.contains("hub-phone"))
+ );
+ }
+
+ function orderTriggerText(o) {
+ const side = o.trigger_side === "lte" ? "下穿≤" : "上穿≥";
+ const px = o.trigger_px != null ? String(o.trigger_px) : "";
+ return side + px;
+ }
+
+ function orderExitText(o) {
+ const bits = [];
+ if (o.profit_exit_enabled) bits.push("翻倍×" + (o.profit_exit_mult || ""));
+ if (o.target_index != null) bits.push("目标" + o.target_index);
+ return bits.join(" · ");
+ }
+
+ function orderActionHtml(o) {
+ const canCancel = o.status === "armed" || o.status === "triggering";
+ const canExit = o.status === "open";
+ let actions = "";
+ if (canCancel) {
+ actions +=
+ '';
+ }
+ if (canExit) {
+ actions +=
+ '';
+ }
+ return actions;
+ }
+
+ function bindOrderActions(box) {
+ if (!box) return;
+ box.querySelectorAll("[data-cancel]").forEach(function (btn) {
+ btn.addEventListener("click", async function () {
+ if (!confirm("确认取消该条件单?")) return;
+ const oid = decodeURIComponent(btn.getAttribute("data-cancel") || "");
+ const iid = decodeURIComponent(btn.getAttribute("data-iid") || "");
+ const rr = await fetch("/api/cond_orders/" + encodeURIComponent(oid) + "/cancel", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ instance_id: Number(iid) }),
+ });
+ const dd = await rr.json();
+ alert(dd.msg || (dd.ok ? "已取消" : "失败"));
+ refresh();
+ });
+ });
+ box.querySelectorAll("[data-exit]").forEach(function (btn) {
+ btn.addEventListener("click", async function () {
+ const oid = decodeURIComponent(btn.getAttribute("data-exit") || "");
+ const iid = decodeURIComponent(btn.getAttribute("data-iid") || "");
+ const curT = decodeURIComponent(btn.getAttribute("data-target") || "");
+ const curM = decodeURIComponent(btn.getAttribute("data-mult") || "1");
+ const pe = btn.getAttribute("data-pe") === "1";
+ const t = prompt("目标指数(留空清除)", curT);
+ if (t === null) return;
+ const peOn = confirm("是否启用翻倍出场?\n当前:" + (pe ? "开" : "关"));
+ let mult = curM;
+ if (peOn) {
+ const m = prompt("翻倍倍数", curM);
+ if (m === null) return;
+ mult = m;
+ }
+ const rr = await fetch("/api/cond_orders/" + encodeURIComponent(oid) + "/exit", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({
+ instance_id: Number(iid),
+ target_index: t === "" ? "" : t,
+ profit_exit_enabled: peOn,
+ profit_exit_mult: mult,
+ }),
+ });
+ const dd = await rr.json();
+ alert(dd.msg || (dd.ok ? "已更新" : "失败"));
+ refresh();
+ });
+ });
+ }
+
+ function renderPhoneOrderCard(o) {
+ const exit = orderExitText(o);
+ const meta = [];
+ if (o.deviation_pct != null) meta.push("偏离 " + o.deviation_pct + "%");
+ if (o.min_expiry_hours != null) meta.push("到期 " + o.min_expiry_hours + "h");
+ if (exit) meta.push(exit);
+ const actions = orderActionHtml(o);
+ return (
+ '' +
+ '' +
+ "" +
+ escapeHtml(o.instance_name || "") +
+ "" +
+ '' +
+ escapeHtml(statusLabel(o)) +
+ "
" +
+ '' +
+ escapeHtml((o.underlying || "") + " " + (o.opt_type === "C" ? "Call" : "Put")) +
+ " · " +
+ escapeHtml(orderTriggerText(o)) +
+ "
" +
+ (meta.length ? '' + escapeHtml(meta.join(" · ")) + "
" : "") +
+ (o.message ? '' + escapeHtml(o.message) + "
" : "") +
+ (actions ? '' + actions + "
" : "") +
+ ""
+ );
+ }
+
+ function instanceMode(it) {
+ const m = String((it && it.mode) || "").toLowerCase();
+ return m === "sim" || m === "live" ? m : "";
+ }
+
+ function renderCandidateCard(it, checkedIds) {
+ const disabled = !it.selectable;
+ const tip = disabled
+ ? it.has_position
+ ? "已有持仓"
+ : it.cond_order_locked
+ ? "条件单占用"
+ : it.online
+ ? "不可选"
+ : "离线"
+ : "可选";
+ const id = String(it.id);
+ const checked = !disabled && checkedIds.indexOf(id) >= 0;
+ return (
+ '"
+ );
+ }
+
+ function renderCandidateGroup(mode, items, checkedIds) {
+ if (!items.length) return "";
+ const label =
+ mode === "sim" || mode === "live"
+ ? '' +
+ mode +
+ "
"
+ : "";
+ return (
+ '' +
+ label +
+ '
' +
+ items
+ .map(function (it) {
+ return renderCandidateCard(it, checkedIds);
+ })
+ .join("") +
+ "
"
+ );
+ }
+
+ async function loadCandidates() {
+ const box = document.getElementById("cf-instances");
+ if (!box) return;
+ const checkedIds = Array.prototype.slice
+ .call(box.querySelectorAll('input[name="cf-inst"]:checked'))
+ .map(function (el) {
+ return decodeURIComponent(el.value || "");
+ });
+ const r = await fetch("/api/cond_orders/candidates");
+ const d = await r.json();
+ const list = d.instances || [];
+ if (!list.length) {
+ box.innerHTML = '暂无启用实例';
+ return;
+ }
+ const sim = [];
+ const live = [];
+ const other = [];
+ list.forEach(function (it) {
+ const m = instanceMode(it);
+ if (m === "sim") sim.push(it);
+ else if (m === "live") live.push(it);
+ else other.push(it);
+ });
+ box.innerHTML =
+ renderCandidateGroup("sim", sim, checkedIds) +
+ renderCandidateGroup("live", live, checkedIds) +
+ renderCandidateGroup("", other, checkedIds);
+ }
+
+ async function loadOrders() {
+ const box = document.getElementById("cond-list");
+ if (!box) return;
+ const r = await fetch("/api/cond_orders");
+ const d = await r.json();
+ const list = d.orders || [];
+ if (!list.length) {
+ box.innerHTML = '暂无条件单
';
+ return;
+ }
+ if (isHubPhone()) {
+ box.innerHTML =
+ '' +
+ list.map(renderPhoneOrderCard).join("") +
+ "
";
+ bindOrderActions(box);
+ return;
+ }
+ box.innerHTML =
+ '' +
+ "| 客户端 | 状态 | 标的 | 触发 | 偏离 | 到期h | 出场 | 说明 | 操作 | " +
+ "
" +
+ list
+ .map(function (o) {
+ return (
+ "" +
+ "| " +
+ escapeHtml(o.instance_name || "") +
+ " | " +
+ '' +
+ escapeHtml(statusLabel(o)) +
+ " | " +
+ "" +
+ escapeHtml((o.underlying || "") + " " + (o.opt_type || "")) +
+ " | " +
+ "" +
+ escapeHtml(orderTriggerText(o).replace("≤", " ≤ ").replace("≥", " ≥ ")) +
+ " | " +
+ "" +
+ escapeHtml(o.deviation_pct != null ? o.deviation_pct + "%" : "—") +
+ " | " +
+ "" +
+ escapeHtml(o.min_expiry_hours != null ? String(o.min_expiry_hours) : "—") +
+ " | " +
+ "" +
+ escapeHtml(orderExitText(o) || "—") +
+ " | " +
+ '' +
+ escapeHtml(o.message || "") +
+ " | " +
+ '' +
+ orderActionHtml(o) +
+ " | " +
+ "
"
+ );
+ })
+ .join("") +
+ "
";
+ bindOrderActions(box);
+ }
+
+ async function createOrder() {
+ const status = document.getElementById("cf-status");
+ const ids = Array.prototype.slice
+ .call(document.querySelectorAll('input[name="cf-inst"]:checked'))
+ .map(function (el) {
+ return Number(decodeURIComponent(el.value));
+ });
+ if (!ids.length) {
+ alert("请选择至少一台可选客户端");
+ return;
+ }
+ const optType = document.getElementById("cf-opt-type").value;
+ const body = {
+ instance_ids: ids,
+ underlying: document.getElementById("cf-underlying").value,
+ opt_type: optType,
+ trigger_side: leftTriggerSide(optType),
+ trigger_px: document.getElementById("cf-trigger-px").value,
+ deviation_pct: document.getElementById("cf-deviation").value,
+ min_expiry_hours: document.getElementById("cf-expiry-h").value,
+ target_index: document.getElementById("cf-target").value,
+ profit_exit_enabled: document.getElementById("cf-pe").checked,
+ profit_exit_mult: document.getElementById("cf-pe-mult").value,
+ };
+ if (status) status.textContent = "下发中…";
+ const r = await fetch("/api/cond_orders", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify(body),
+ });
+ const d = await r.json();
+ if (status) status.textContent = d.msg || "";
+ alert(d.msg || (d.ok ? "已下发" : "失败"));
+ refresh();
+ }
+
+ async function refresh() {
+ await Promise.all([loadCandidates(), loadOrders()]);
+ }
+
+ function boot() {
+ const btn = document.getElementById("btn-cond-refresh");
+ if (btn) btn.addEventListener("click", refresh);
+ const create = document.getElementById("btn-cond-create");
+ if (create) create.addEventListener("click", createOrder);
+ const typeEl = document.getElementById("cf-opt-type");
+ const pxEl = document.getElementById("cf-trigger-px");
+ if (typeEl) typeEl.addEventListener("change", syncTriggerHint);
+ if (pxEl) pxEl.addEventListener("input", syncTriggerHint);
+ syncTriggerHint();
+ refresh();
+ setInterval(refresh, 10000);
+ }
+
+ global.HubCondOrders = { boot: boot, refresh: refresh };
+})(window);
diff --git a/static/hub.css b/static/hub.css
index 5fe72b6..b2db34b 100644
--- a/static/hub.css
+++ b/static/hub.css
@@ -1979,6 +1979,80 @@ html.hub-phone-html .table-wrap {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
+html.hub-phone-html body.page-cond-orders .cond-lead {
+ display: none;
+}
+html.hub-phone-html body.page-cond-orders .cond-layout {
+ display: flex;
+ flex-direction: column;
+ gap: 14px;
+}
+html.hub-phone-html body.page-cond-orders .cond-layout > .cond-card:last-child {
+ order: -1;
+}
+html.hub-phone-html body.page-cond-orders .cond-card {
+ padding: 14px;
+ border-radius: 14px;
+}
+html.hub-phone-html body.page-cond-orders .cond-card-head {
+ margin-bottom: 10px;
+}
+html.hub-phone-html body.page-cond-orders .cond-grid {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 10px 12px;
+}
+html.hub-phone-html body.page-cond-orders .cond-switch {
+ min-height: 0;
+ grid-column: 1 / -1;
+}
+html.hub-phone-html body.page-cond-orders .cond-inst-grid {
+ grid-template-columns: 1fr;
+}
+html.hub-phone-html body.page-cond-orders .cond-actions {
+ flex-direction: column;
+ align-items: stretch;
+}
+html.hub-phone-html body.page-cond-orders .cond-actions .btn {
+ width: 100%;
+}
+.hub-phone-cond-list {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+.hub-phone-cond {
+ padding: 12px 12px 10px;
+ border-radius: 12px;
+ border: 1px solid rgba(56, 189, 248, 0.18);
+ background: rgba(8, 16, 30, 0.72);
+}
+.hub-phone-cond-head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 8px;
+ margin-bottom: 6px;
+}
+.hub-phone-cond-head strong {
+ font-size: 0.95rem;
+}
+.hub-phone-cond-main {
+ font-size: 0.98rem;
+ font-weight: 600;
+ line-height: 1.4;
+}
+.hub-phone-cond-meta,
+.hub-phone-cond-msg {
+ margin-top: 4px;
+ font-size: 0.78rem;
+ line-height: 1.4;
+}
+.hub-phone-cond-actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-top: 10px;
+}
html.hub-phone-html .login-wrap {
padding: 48px 16px 24px;
}
diff --git a/templates/base.html b/templates/base.html
index 18ae60e..a8d9ca1 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -11,7 +11,7 @@
-
+
-
-{% endblock %}
+{% extends "base.html" %}
+{% block title %}条件单 · 期权中控{% endblock %}
+{% block body %}
+
+
+
左侧条件开仓
+
中控只下发;盯盘、买币、开平仓都在客户端。有仓或已占用的机器不可选。
+
+
+
+
+
+
+
+
新建条件单
+ 左侧单
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{% endblock %}
+{% block scripts %}
+
+
+{% endblock %}