Add daily loss force-flatten at configurable equity limit
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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)}
|
||||
|
||||
@@ -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: '综合保证金占比',
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -253,12 +253,21 @@
|
||||
<label>开仓挂单超时(分钟)</label>
|
||||
<input name="pending_order_timeout_min" type="number" step="1" min="1" max="60" value="{{ pending_order_timeout_min }}">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>日亏损强平线(%权益)</label>
|
||||
<input name="daily_loss_force_close_pct" type="number" step="0.1" min="0.1" max="50" value="{{ daily_loss_force_close_pct }}">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>强平滑点预留(%权益)</label>
|
||||
<input name="daily_loss_slippage_buffer_pct" type="number" step="0.1" min="0" max="20" value="{{ daily_loss_slippage_buffer_pct }}">
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn-primary" style="margin-top:.75rem">保存交易设置</button>
|
||||
<p class="hint" style="margin-top:.75rem;margin-bottom:0">
|
||||
单仓保证金上限(默认 30%)用于<strong>新开仓</strong>校验与最大手数估算;综合保证金上限(默认 50%)在单仓模式下为滚仓合计上限、多仓模式下为全部持仓合计上限。固定金额计仓时<strong>先按止损算手数,再按单仓上限收紧</strong>。
|
||||
<strong>移动保本</strong>:达 1R 后止损移至开仓价 ± N 跳。
|
||||
<strong>挂单超时</strong>:限价开仓未成交时,超过设定分钟数自动向柜台撤单(1~60 分钟)。
|
||||
<strong>日亏损强平</strong>:当日亏损(已实现+浮亏)达「强平线」占权益比例时,无条件平掉全部持仓并当日禁止开仓;「滑点预留」为强平执行额外允许的最大亏损占权益比例(默认 2%+1%=3% 合计上限)。
|
||||
<span class="text-muted">{{ small_account_margin_rec.label }}。</span>
|
||||
CTP 账号与前置在下方「CTP 连接」中配置。
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user