feat: add per-account daily open hard limit across all exchanges

Enforce optional DAILY_OPEN_HARD_LIMIT in precheck_risk and can_trade, keep AI alerts at DAILY_OPEN_ALERT_THRESHOLD, and document env setup for all four instances.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-09 15:46:18 +08:00
parent f7d94f67d7
commit 24a86a710c
17 changed files with 698 additions and 77 deletions
+22 -3
View File
@@ -443,7 +443,8 @@
</div>
<div class="rule-tip" id="order-rule-tip">
规则:最多 {{ max_active_positions }} 仓;BTC {{ btc_leverage }}x / 山寨 {{ alt_leverage }}x
{% if can_trade %}可开仓{% else %}不可开仓(持仓已满或未到北京时间 {{ reset_hour }}:00{% endif %}
本交易日开仓 {{ opens_today }}{% if daily_open_hard_limit > 0 %} / 硬上限 {{ daily_open_hard_limit }}{% endif %}AI 提醒 {{ daily_open_alert_threshold }}
{% if can_trade %}可开仓{% else %}不可开仓(持仓已满、单日开仓达上限,或未到北京时间 {{ reset_hour }}:00{% endif %}
人工开仓盈亏比不得低于 {{ manual_min_planned_rr }}:1
</div>
<div class="rule-tip">
@@ -2042,11 +2043,29 @@ function refreshAccountSnapshot(){
if (typeof data.available_trading_usdt !== "undefined" && data.available_trading_usdt !== null) {
latestAvailableUsdt = Number(data.available_trading_usdt);
}
const canTradeText = data.can_trade ? "可开仓" : `不可开仓(持仓 ${data.active_count||0}/${data.max_active_positions||{{ max_active_positions }}} 或未到北京时间 {{ reset_hour }}:00`;
let canTradeText = "可开仓";
if (!data.can_trade) {
const parts = [];
const ac = Number(data.active_count || 0);
const max = Number(data.max_active_positions || {{ max_active_positions }});
if (ac >= max) parts.push(`持仓 ${ac}/${max}`);
const hard = Number(data.daily_open_hard_limit != null ? data.daily_open_hard_limit : {{ daily_open_hard_limit }});
const opens = Number(data.opens_today);
if (hard > 0 && !Number.isNaN(opens) && opens >= hard) parts.push(`本交易日开仓 ${opens}/${hard} 已达上限`);
if (!parts.length) parts.push(`未到北京时间 {{ reset_hour }}:00`);
else parts.push(`或未到北京时间 {{ reset_hour }}:00`);
canTradeText = `不可开仓(${parts.join("")}`;
}
const opensToday = Number(data.opens_today);
const hardLim = Number(data.daily_open_hard_limit != null ? data.daily_open_hard_limit : {{ daily_open_hard_limit }});
const alertLim = Number(data.daily_open_alert_threshold != null ? data.daily_open_alert_threshold : {{ daily_open_alert_threshold }});
const openCntTxt = !Number.isNaN(opensToday)
? `本交易日开仓 ${opensToday}${hardLim > 0 ? ` / 硬上限 ${hardLim}` : ""}AI 提醒 ${alertLim}`
: "";
const tip = document.getElementById("order-rule-tip");
const avail = (latestAvailableUsdt !== null && !Number.isNaN(latestAvailableUsdt)) ? `;交易账户可用约${latestAvailableUsdt.toFixed(2)}U` : "";
if(tip){
tip.innerText = `规则:最多 ${data.max_active_positions || {{ max_active_positions }}} 仓;BTC {{ btc_leverage }}x / 山寨 {{ alt_leverage }}x${canTradeText}${avail}`;
tip.innerText = `规则:最多 ${data.max_active_positions || {{ max_active_positions }}} 仓;BTC {{ btc_leverage }}x / 山寨 {{ alt_leverage }}x${openCntTxt ? openCntTxt + "" : ""}${canTradeText}${avail};人工开仓盈亏比不得低于 {{ manual_min_planned_rr }}:1`;
}
}).catch(()=>{});
}