diff --git a/server.py b/server.py
index d9432395..e0c5c4d5 100644
--- a/server.py
+++ b/server.py
@@ -229,17 +229,19 @@ def get_watch():
_cands = [d for d in results if d['sort_group'] == 0 and _is_fresh(d)]
_cands.sort(key=lambda x: x.get('rr_ratio') or 0, reverse=True)
- _selected, _cum = [], 0.0
+ # 现金预算内标记"可执行",预算外标记"排队"(不再降级隐藏)
+ _cum = 0.0
for d in _cands:
pct = _sugg_pct(d)
- if len(_selected) < 5 and _cum + pct <= _budget_pct + 1e-9:
- d['suggested_position_pct'] = pct
+ d['suggested_position_pct'] = pct
+ if _cum + pct <= _budget_pct + 1e-9:
+ d['rec_exec'] = True # 可执行
_cum += pct
- _selected.append(d)
- _sel_codes = {d['code'] for d in _selected}
+ else:
+ d['rec_exec'] = False # 排队(现金不足)
+ # 落选(tag 但非新鲜)仍降回自然分组;新鲜者全部留在推荐区
for d in results:
- if d['sort_group'] == 0 and d['code'] not in _sel_codes:
- # 落选:降回自然分组
+ if d['sort_group'] == 0 and not _is_fresh(d):
d['sort_group'] = 1 if d['decision_type'] == '持仓策略' else 2
# 排序:group → signal_rank → group-internal (持仓按position_pct desc, 自选按rr desc)
diff --git a/static/index.html b/static/index.html
index 2f763e1d..03623f30 100644
--- a/static/index.html
+++ b/static/index.html
@@ -1519,9 +1519,18 @@ async function renderWatch() {
// 当前操作策略摘要
const strat = fmtStrategy(s);
- // 推荐行高亮
+ // 推荐行高亮 + 可执行/排队徽章
const rowCls = isRec ? 'bg-amber-900/15 border-l-2 border-l-amber-400' : 'border-b border-slate-800/30 hover:bg-slate-800/20';
- const recBadge = isRec ? '🔥推荐' : '';
+ let recBadge = '';
+ if (isRec) {
+ if (s.rec_exec === true) {
+ recBadge = '💰可执行';
+ } else if (s.rec_exec === false) {
+ recBadge = '⏳排队';
+ } else {
+ recBadge = '🔥推荐';
+ }
+ }
// 推荐行策略文本加粗醒目
const stratCls = isRec ? 'font-semibold text-amber-200' : 'text-slate-300';