Add daily loss force-flatten at configurable equity limit

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-03 12:42:13 +08:00
parent b6c3266a9e
commit 2081bf2da9
17 changed files with 850 additions and 97 deletions
+1
View File
@@ -49,6 +49,7 @@
.trade-action-row .btn-open{padding:.65rem .75rem;font-size:.9rem;width:100%}
.trade-action-row .btn-open:disabled{opacity:.45;cursor:not-allowed;filter:grayscale(.25)}
.trade-action-row .btn-open.btn-session-off{background:var(--text-muted);border-color:var(--text-muted)}
.trade-action-row .btn-open.btn-risk-off{background:var(--text-muted);border-color:var(--text-muted);opacity:.72;cursor:not-allowed}
.trailing-be-toggle{display:flex;align-items:center;gap:.4rem;font-size:.78rem;color:var(--text-label);margin-bottom:.45rem;cursor:pointer;user-select:none}
.trailing-be-toggle input{width:auto;margin:0}
.trailing-be-hint{font-size:.72rem;margin:0;color:var(--text-muted)}
+14 -1
View File
@@ -453,9 +453,22 @@
var dailyRiskLim = lim.daily_trading_risk_pct_limit != null
? lim.daily_trading_risk_pct_limit
: st.daily_trading_risk_pct_limit;
var slipBuf = lim.daily_loss_slippage_buffer_pct != null
? lim.daily_loss_slippage_buffer_pct
: st.daily_loss_slippage_buffer_pct;
var dailyRiskCap = lim.daily_loss_total_cap_pct != null
? lim.daily_loss_total_cap_pct
: st.daily_loss_total_cap_pct;
var dailyRiskText = dailyRiskUsed != null ? fmtNum(dailyRiskUsed) + '%' : '—';
if (dailyRiskLim != null && dailyRiskUsed != null) {
dailyRiskText += ' / ' + fmtNum(dailyRiskLim) + '%';
if (slipBuf != null) {
dailyRiskText += '+滑点' + fmtNum(slipBuf) + '%';
if (dailyRiskCap != null) {
dailyRiskText += ',合计≤' + fmtNum(dailyRiskCap) + '%';
}
dailyRiskText += '';
}
} else if (dailyRiskLim != null) {
dailyRiskText += ' / ' + fmtNum(dailyRiskLim) + '%';
}
@@ -489,7 +502,7 @@
},
{ label: '持仓限制', value: active + ' / ' + (maxPos != null ? maxPos : '—') },
{ label: '日持仓限制', value: dailyOpens + ' / ' + (dailyPosLim != null ? dailyPosLim : '—') },
{ label: '日交易风险', value: dailyRiskText },
{ label: '日亏损风控', value: dailyRiskText },
{ label: '手动平仓次数', value: manualCnt + ' / ' + (manualLim != null ? manualLim : '—') },
{
label: '综合保证金占比',
+7 -1
View File
@@ -28,6 +28,7 @@
var lastCtpLoginBanAt = 0;
var ctpReconnecting = false;
var ctpConnectInflight = false;
var lastRiskStatus = null;
var isTradingSession = false;
var hasSlTpMonitoring = false;
var ctpConnected = false;
@@ -313,6 +314,7 @@
}
var riskBadge = document.getElementById('risk-badge');
if (riskBadge && data.risk_status) {
lastRiskStatus = data.risk_status;
riskBadge.textContent = data.risk_status.status_label || '';
riskBadge.className = 'badge ' + (data.risk_status.can_trade ? 'profit' : 'loss');
}
@@ -396,9 +398,13 @@
function updateSessionUi() {
var btnOpen = document.getElementById('btn-open');
var sessionHint = document.getElementById('session-hint');
var canTrade = !lastRiskStatus || lastRiskStatus.can_trade !== false;
if (btnOpen) {
btnOpen.disabled = !isTradingSession;
var blocked = !isTradingSession || !canTrade;
btnOpen.disabled = blocked;
btnOpen.classList.toggle('btn-session-off', !isTradingSession);
btnOpen.classList.toggle('btn-risk-off', isTradingSession && !canTrade);
btnOpen.textContent = (isTradingSession && !canTrade) ? '风控' : '开仓';
}
if (sessionHint) {
sessionHint.hidden = !!isTradingSession;