增加关键位人工输入
This commit is contained in:
@@ -400,6 +400,7 @@ async function refresh() {
|
||||
windowHours: funnelWindowApplied,
|
||||
});
|
||||
renderDailyReport(dailyReport);
|
||||
loadKeyMonitors();
|
||||
try {
|
||||
const oe = await fetchJson("/api/order-executors");
|
||||
renderOrderExecutors(oe);
|
||||
@@ -621,6 +622,117 @@ async function patchOrderExecutor(id, body) {
|
||||
});
|
||||
}
|
||||
|
||||
function syncKeySlTpFields() {
|
||||
const mode = getInputText("keySlTpModeInput") || "standard";
|
||||
const tpEl = document.getElementById("keyManualTpInput");
|
||||
if (tpEl) tpEl.style.display = mode === "trend_manual" ? "" : "none";
|
||||
}
|
||||
|
||||
function renderKeyMonitors(data) {
|
||||
const rule = document.getElementById("keyMonitorRule");
|
||||
if (rule && data.rule_text) rule.textContent = `// ${data.rule_text}`;
|
||||
|
||||
const active = data.active || [];
|
||||
renderItems("keyMonitorActive", active, (row) => {
|
||||
const prev = row.preview || {};
|
||||
const checks = prev.checks || {};
|
||||
const gateOk = prev.gate_ok ? '<span style="color:#4cd97f">门控通过</span>' : '<span style="color:#8892b0">门控未过</span>';
|
||||
const dir = row.direction === "long" ? "做多" : "做空";
|
||||
const modeLabel = row.sl_tp_mode === "trend_manual" ? "趋势突破" : "标准突破";
|
||||
return `
|
||||
<div class="matrix-list-item-head"><strong>${row.symbol}</strong> ${dir} · ${row.monitor_type} · ${modeLabel}</div>
|
||||
<div class="matrix-dim">上 ${row.upper} / 下 ${row.lower} · 保本 ${row.breakeven_enabled ? "开" : "关"}</div>
|
||||
<div class="matrix-dim">${gateOk} · 确认收盘 ${checks.confirm_close != null ? checks.confirm_close : "—"}</div>
|
||||
<button type="button" class="matrix-btn ghost key-del-btn" data-id="${row.id}" style="margin-top:6px">删除并归档</button>
|
||||
`;
|
||||
});
|
||||
if (!active.length) {
|
||||
const t = document.getElementById("keyMonitorActive");
|
||||
if (t) t.innerHTML = '<div class="matrix-dim">暂无监控中的关键位</div>';
|
||||
}
|
||||
|
||||
const hist = data.history || [];
|
||||
renderItems("keyMonitorHistory", hist.slice(0, 80), (h) => {
|
||||
const dir = h.direction === "long" ? "多" : "空";
|
||||
const modeLabel = h.sl_tp_mode === "trend_manual" ? "趋势" : "标准";
|
||||
return `
|
||||
<div><strong>${h.symbol}</strong> ${dir} · ${h.monitor_type} · ${modeLabel}</div>
|
||||
<div class="matrix-dim">${h.close_reason} · RR ${h.planned_rr != null ? Number(h.planned_rr).toFixed(2) : "—"} · ${formatIsoToBeijing(h.closed_at)}</div>
|
||||
`;
|
||||
});
|
||||
if (!hist.length) {
|
||||
const t = document.getElementById("keyMonitorHistory");
|
||||
if (t) t.innerHTML = '<div class="matrix-dim">暂无历史</div>';
|
||||
}
|
||||
}
|
||||
|
||||
async function loadKeyMonitors() {
|
||||
try {
|
||||
const data = await fetchJson("/api/key-monitors");
|
||||
renderKeyMonitors(data);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
async function addKeyMonitor() {
|
||||
const msg = document.getElementById("keyMonitorSaveMsg");
|
||||
const symbol = getInputText("keySymbolInput");
|
||||
const direction = getInputText("keyDirectionInput");
|
||||
const monitor_type = getInputText("keyMonitorTypeInput");
|
||||
const sl_tp_mode = getInputText("keySlTpModeInput") || "standard";
|
||||
if (!symbol || !direction) {
|
||||
if (msg) msg.textContent = "// 请填写币种与方向";
|
||||
return;
|
||||
}
|
||||
const body = {
|
||||
symbol,
|
||||
direction,
|
||||
monitor_type,
|
||||
sl_tp_mode,
|
||||
upper: getInputNumber("keyUpperInput"),
|
||||
lower: getInputNumber("keyLowerInput"),
|
||||
breakeven_enabled: getInputCheck("keyBreakevenInput"),
|
||||
};
|
||||
if (sl_tp_mode === "trend_manual") {
|
||||
body.manual_take_profit = getInputNumber("keyManualTpInput");
|
||||
}
|
||||
try {
|
||||
await fetchJson("/api/key-monitors", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
if (msg) msg.textContent = "// 已添加,开始 5m 门控轮询";
|
||||
loadKeyMonitors();
|
||||
} catch (error) {
|
||||
if (msg) msg.textContent = `// 失败 ${error}`;
|
||||
}
|
||||
}
|
||||
|
||||
function wireKeyMonitorPanel() {
|
||||
const modeSel = document.getElementById("keySlTpModeInput");
|
||||
if (modeSel) modeSel.addEventListener("change", syncKeySlTpFields);
|
||||
syncKeySlTpFields();
|
||||
const addBtn = document.getElementById("keyAddBtn");
|
||||
if (addBtn) addBtn.addEventListener("click", addKeyMonitor);
|
||||
const active = document.getElementById("keyMonitorActive");
|
||||
if (active) {
|
||||
active.addEventListener("click", async (ev) => {
|
||||
const btn = ev.target.closest && ev.target.closest(".key-del-btn");
|
||||
if (!btn) return;
|
||||
const id = btn.getAttribute("data-id");
|
||||
if (!id || !confirm("删除该关键位?将写入历史。")) return;
|
||||
try {
|
||||
await fetchJson(`/api/key-monitors/${encodeURIComponent(id)}`, { method: "DELETE" });
|
||||
loadKeyMonitors();
|
||||
} catch (error) {
|
||||
alert(String(error));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function wireOrderExecutorsPanel() {
|
||||
const saveG = document.getElementById("oeSaveGlobalBtn");
|
||||
if (saveG) saveG.addEventListener("click", saveOrderExecutorsGlobal);
|
||||
@@ -662,8 +774,10 @@ const saveDailyBtn = document.getElementById("saveDailyReportBtn");
|
||||
if (saveDailyBtn) saveDailyBtn.addEventListener("click", saveDailyReportSettings);
|
||||
loadIntradaySettings().catch(console.error);
|
||||
loadDailyReportSettings().catch(console.error);
|
||||
wireKeyMonitorPanel();
|
||||
wireOrderExecutorsPanel();
|
||||
loadOrderExecutors().catch(console.error);
|
||||
loadKeyMonitors().catch(console.error);
|
||||
tickClock();
|
||||
setInterval(tickClock, 1000);
|
||||
initMatrixRain();
|
||||
|
||||
Reference in New Issue
Block a user