增加关键位显示
This commit is contained in:
@@ -206,11 +206,21 @@ async def api_monitor_board():
|
|||||||
snap = await _fetch_flask_json(client, ex, "/api/price_snapshot")
|
snap = await _fetch_flask_json(client, ex, "/api/price_snapshot")
|
||||||
if isinstance(snap, dict):
|
if isinstance(snap, dict):
|
||||||
key_prices = snap.get("key_prices")
|
key_prices = snap.get("key_prices")
|
||||||
|
flask_ok = isinstance(hub_mon, dict) and hub_mon.get("ok") is not False
|
||||||
|
flask_err = None
|
||||||
|
if isinstance(hub_mon, dict) and hub_mon.get("ok") is False:
|
||||||
|
flask_err = (
|
||||||
|
hub_mon.get("msg")
|
||||||
|
or hub_mon.get("error")
|
||||||
|
or (str(hub_mon.get("text") or "")[:200] or None)
|
||||||
|
)
|
||||||
out.append(
|
out.append(
|
||||||
{
|
{
|
||||||
**agent_row,
|
**agent_row,
|
||||||
"review_url": ex.get("review_url") or "",
|
"review_url": ex.get("review_url") or "",
|
||||||
"hub_monitor": hub_mon,
|
"hub_monitor": hub_mon,
|
||||||
|
"flask_ok": flask_ok,
|
||||||
|
"flask_error": flask_err,
|
||||||
"meta": (meta or {}).get("meta") if isinstance(meta, dict) else meta,
|
"meta": (meta or {}).get("meta") if isinstance(meta, dict) else meta,
|
||||||
"key_prices": key_prices,
|
"key_prices": key_prices,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,9 +97,10 @@
|
|||||||
const ag = row.agent || {};
|
const ag = row.agent || {};
|
||||||
const pos = Array.isArray(ag.positions) ? ag.positions : [];
|
const pos = Array.isArray(ag.positions) ? ag.positions : [];
|
||||||
const hm = row.hub_monitor || {};
|
const hm = row.hub_monitor || {};
|
||||||
const keys = hm.keys || [];
|
const flaskOk = row.flask_ok !== false && hm.ok !== false;
|
||||||
const orders = hm.orders || [];
|
const keys = flaskOk ? hm.keys || [] : [];
|
||||||
const trends = hm.trends || [];
|
const orders = flaskOk ? hm.orders || [] : [];
|
||||||
|
const trends = flaskOk ? hm.trends || [] : [];
|
||||||
const kmap = {};
|
const kmap = {};
|
||||||
(row.key_prices || []).forEach((k) => {
|
(row.key_prices || []).forEach((k) => {
|
||||||
kmap[k.id] = k;
|
kmap[k.id] = k;
|
||||||
@@ -129,12 +130,26 @@
|
|||||||
inner += `<div class="rule-tip">${esc(o.symbol)} ${o.direction} 成交${o.trigger_price}</div>`;
|
inner += `<div class="rule-tip">${esc(o.symbol)} ${o.direction} 成交${o.trigger_price}</div>`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if ((row.capabilities || []).includes("key") && keys.length) {
|
if ((row.capabilities || []).includes("key")) {
|
||||||
inner += `<div style="margin-top:8px;font-size:12px;color:#b8c4ff">关键位 ${keys.length} 条</div>`;
|
if (!flaskOk) {
|
||||||
keys.slice(0, 6).forEach((k) => {
|
inner += `<div style="margin-top:8px;font-size:12px;color:#f85149">关键位/机器人:策略 Flask 未连通</div>`;
|
||||||
const kp = kmap[k.id] || {};
|
inner += `<div class="rule-tip">${esc(row.flask_error || hm.msg || "请确认实例 app 已启动,且 HUB_BRIDGE_TOKEN 与实例一致或 APP_AUTH_DISABLED=true")}</div>`;
|
||||||
inner += `<div class="rule-tip">${esc(k.symbol)} ${esc(k.monitor_type)} 上${k.upper}/下${k.lower} 门控:${esc(kp.gate_summary || "-")}</div>`;
|
} else if (!keys.length) {
|
||||||
});
|
inner += `<div style="margin-top:8px;color:var(--muted);font-size:12px">关键位:当前无记录(在下单区或实例首页添加)</div>`;
|
||||||
|
} else {
|
||||||
|
inner += `<div style="margin-top:8px;font-size:12px;color:#b8c4ff">关键位 ${keys.length} 条</div>`;
|
||||||
|
keys.slice(0, 8).forEach((k) => {
|
||||||
|
const kp = kmap[k.id] || kmap[String(k.id)] || {};
|
||||||
|
const mt = k.monitor_type || k.type || "";
|
||||||
|
inner += `<div class="rule-tip">${esc(k.symbol)} ${esc(mt)} 上${k.upper}/下${k.lower}`;
|
||||||
|
if (kp.price_display != null || kp.price != null) {
|
||||||
|
inner += ` · 现价 ${esc(kp.price_display != null ? kp.price_display : kp.price)}`;
|
||||||
|
}
|
||||||
|
inner += ` · 门控 ${esc(kp.gate_summary || "-")}</div>`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if ((row.capabilities || []).includes("trend")) {
|
||||||
|
inner += `<div style="margin-top:6px;color:var(--muted);font-size:12px">该账户为趋势户,无关键位(见趋势计划或下单区)</div>`;
|
||||||
}
|
}
|
||||||
if (trends.length) {
|
if (trends.length) {
|
||||||
inner += `<div style="margin-top:8px;font-size:12px;color:#b8c4ff">趋势计划 ${trends.length} 个运行中</div>`;
|
inner += `<div style="margin-top:8px;font-size:12px;color:#b8c4ff">趋势计划 ${trends.length} 个运行中</div>`;
|
||||||
@@ -144,7 +159,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const review = row.review_url
|
const review = row.review_url
|
||||||
? `<a href="${esc(row.review_url)}" target="_blank" rel="noopener">复盘</a>`
|
? `<a href="${esc(row.review_url)}" target="_blank" rel="noopener" title="打开该实例的交易记录与复盘页(不在中控内操作)">交易复盘</a>`
|
||||||
: "";
|
: "";
|
||||||
return `<div class="card">
|
return `<div class="card">
|
||||||
<div class="card-head">
|
<div class="card-head">
|
||||||
|
|||||||
@@ -15,6 +15,10 @@
|
|||||||
|
|
||||||
<div id="page-monitor" class="page">
|
<div id="page-monitor" class="page">
|
||||||
<h1>监控区</h1>
|
<h1>监控区</h1>
|
||||||
|
<p class="rule-tip" style="margin-top:0">
|
||||||
|
持仓/余额来自子代理;关键位、机器人单来自各实例 Flask(须 PM2 跑着 crypto_*)。
|
||||||
|
卡片右上角「交易复盘」= 打开该所交易记录页,不在中控里做复盘。
|
||||||
|
</p>
|
||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<button type="button" id="btn-monitor-refresh">立即刷新</button>
|
<button type="button" id="btn-monitor-refresh">立即刷新</button>
|
||||||
<label style="color:var(--muted);font-size:12px;display:flex;align-items:center;gap:6px">
|
<label style="color:var(--muted);font-size:12px;display:flex;align-items:center;gap:6px">
|
||||||
|
|||||||
@@ -154,7 +154,8 @@ python hub.py
|
|||||||
| **机器人持仓** | 来自实例 `/api/hub/monitor` 的 `order_monitors`(active) |
|
| **机器人持仓** | 来自实例 `/api/hub/monitor` 的 `order_monitors`(active) |
|
||||||
| **关键位** | 仅 `capabilities` 含 `key` 的户;展示门控摘要(`/api/price_snapshot`) |
|
| **关键位** | 仅 `capabilities` 含 `key` 的户;展示门控摘要(`/api/price_snapshot`) |
|
||||||
| **趋势计划** | 仅 Gate 趋势户;`trend_pullback_plans` active |
|
| **趋势计划** | 仅 Gate 趋势户;`trend_pullback_plans` active |
|
||||||
| **复盘** | 新标签打开该户 `review_url`(各实例交易记录页) |
|
| **交易复盘** | 新标签打开该户 Flask 的 `/records`(交易记录、笔记、导出 CSV);**中控不做复盘**,仅跳转 |
|
||||||
|
| **关键位** | 来自实例 `/api/hub/monitor` + `/api/price_snapshot`(须 Flask 已启动);无记录或 Flask 未连通时卡片会提示原因;**Gate 趋势户**无关键位 |
|
||||||
| **该户全平** | `POST` 子代理 `/emergency/close-all`,仅平该 API Key 仓位 |
|
| **该户全平** | `POST` 子代理 `/emergency/close-all`,仅平该 API Key 仓位 |
|
||||||
| **全局紧急全平** | 对所有已启用户依次全平(不含 `HUB_DISABLED_IDS` 强制关闭的 id) |
|
| **全局紧急全平** | 对所有已启用户依次全平(不含 `HUB_DISABLED_IDS` 强制关闭的 id) |
|
||||||
| **自动刷新** | 默认每 5 秒请求 `/api/monitor/board` |
|
| **自动刷新** | 默认每 5 秒请求 `/api/monitor/board` |
|
||||||
|
|||||||
Reference in New Issue
Block a user