feat(risk): add account cooldown and daily freeze after manual/external close
Implements shared account_risk_lib with 4h/1h cooloff and daily freeze rules, wires hooks into all four exchange apps and hub monitor UI, with tests and docs. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -20,6 +20,12 @@
|
||||
.header{display:flex;flex-direction:column;align-items:center;gap:8px;margin-bottom:12px}
|
||||
.header h1{font-size:1.75rem;color:#dbe4ff;text-align:center;line-height:1.25}
|
||||
.exchange-tag{font-size:.82rem;font-weight:600;color:#b8f5d0;background:#14241e;border:1px solid #2d6a4f;padding:5px 14px;border-radius:999px;letter-spacing:.06em}
|
||||
.header-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap;justify-content:center}
|
||||
.risk-status-badge{font-size:.78rem;font-weight:600;padding:4px 12px;border-radius:999px;border:1px solid transparent}
|
||||
.risk-status-normal{color:#b8f5d0;background:#14241e;border-color:#2d6a4f}
|
||||
.risk-status-freeze_1h{color:#ffd89a;background:#2a2210;border-color:#8a6a20}
|
||||
.risk-status-freeze_4h{color:#ffb4a0;background:#2a1410;border-color:#8a4020}
|
||||
.risk-status-freeze_daily{color:#ffb0c8;background:#2a1020;border-color:#8a3050}
|
||||
.top-nav{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin-bottom:12px}
|
||||
.top-nav a{padding:6px 10px;border:1px solid #304164;border-radius:8px;background:#151a2a;color:#8fc8ff;text-decoration:none}
|
||||
.top-nav a.active{background:#2a3f6c;color:#dbe4ff}
|
||||
@@ -262,6 +268,7 @@
|
||||
<h1>加密货币|交易监控 + AI复盘一体化</h1>
|
||||
<div class="header-row">
|
||||
<div class="exchange-tag">{{ exchange_display }}</div>
|
||||
<span class="risk-status-badge risk-status-{{ risk_status.status|default('normal') }}" id="account-risk-badge" title="{{ risk_status.reason|default('', true) }}">{{ risk_status.status_label|default('正常') }}</span>
|
||||
<div class="theme-toggle instance-theme-toggle" role="group" aria-label="界面主题">
|
||||
<button type="button" class="theme-toggle-btn is-active" data-theme-value="dark" aria-pressed="true" title="暗色主题">
|
||||
<svg class="theme-icon" viewBox="0 0 24 24" width="18" height="18" aria-hidden="true">
|
||||
@@ -2041,9 +2048,21 @@ function refreshAccountSnapshot(){
|
||||
if (typeof data.available_trading_usdt !== "undefined" && data.available_trading_usdt !== null) {
|
||||
latestAvailableUsdt = Number(data.available_trading_usdt);
|
||||
}
|
||||
if (data.risk_status) {
|
||||
const badge = document.getElementById("account-risk-badge");
|
||||
if (badge) {
|
||||
const st = data.risk_status.status || "normal";
|
||||
badge.className = "risk-status-badge risk-status-" + st;
|
||||
badge.innerText = data.risk_status.status_label || "正常";
|
||||
badge.title = data.risk_status.reason || "";
|
||||
}
|
||||
}
|
||||
let canTradeText = "可开仓";
|
||||
if (!data.can_trade) {
|
||||
const parts = [];
|
||||
if (data.risk_status && data.risk_status.can_trade === false && data.risk_status.reason) {
|
||||
parts.push(data.risk_status.reason);
|
||||
}
|
||||
const ac = Number(data.active_count || 0);
|
||||
const max = Number(data.max_active_positions || {{ max_active_positions }});
|
||||
if (ac >= max) parts.push(`持仓 ${ac}/${max}`);
|
||||
|
||||
Reference in New Issue
Block a user