增加关键位人工输入

This commit is contained in:
dekun
2026-05-22 22:15:46 +08:00
parent 593f8fcff5
commit ac762b540c
20 changed files with 1541 additions and 42 deletions
+114
View File
@@ -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();