fix(rec): RR系统自算落库+卖出不占买入预算+RR>=1.5门槛

- mofin_db.recompute_rr: 用现价+止损止盈重算RR, sync_recommend_tag入口统一调用
  (根治: prompt没让LLM输出RR, parse不解析, save不落库 → rr_ratio永远0)
- flush_rec_digest: 卖出/止盈单独一组排最前, 不占现金预算; 买入加RR>=1.5可执行门槛
- server.py/api/watch: 卖出永远可执行; 买入RR>=1.5才给可执行徽章
  (根治: 卖出默认吃8%预算被排队, RR=0的5%仓位反而挤进预算)
This commit is contained in:
hmo
2026-07-22 20:31:47 +08:00
parent dabef038db
commit 9bcf3e5e63
2 changed files with 58 additions and 9 deletions
+14 -5
View File
@@ -227,18 +227,27 @@ def get_watch():
pass
return 8.0
_SELL_SIGS = ("卖出", "止盈")
_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)
# 现金预算内标记"可执行",预算外标记"排队"(不再降级隐藏)
# 卖出类永远可执行(释放现金,不占买入预算),排最前;买入类按 RR 降序
_sells = [d for d in _cands if (d.get('timing_signal') or '') in _SELL_SIGS]
_buys = [d for d in _cands if (d.get('timing_signal') or '') not in _SELL_SIGS]
_buys.sort(key=lambda x: x.get('rr_ratio') or 0, reverse=True)
for d in _sells:
d['rec_exec'] = True # 卖出不需要现金,永远可执行
d['suggested_position_pct'] = 0.0
# 买入:RR≥1.5 才有可执行资格(prompt 自己的纪律:RR<1.5→不推荐);
# 达标者贪心装入现金预算,预算外/不达标标记"排队"(不再降级隐藏)
_cum = 0.0
for d in _cands:
for d in _buys:
pct = _sugg_pct(d)
d['suggested_position_pct'] = pct
if _cum + pct <= _budget_pct + 1e-9:
rr = d.get('rr_ratio') or 0
if rr >= 1.5 and _cum + pct <= _budget_pct + 1e-9:
d['rec_exec'] = True # 可执行
_cum += pct
else:
d['rec_exec'] = False # 排队(现金不足)
d['rec_exec'] = False # 排队(现金不足或RR不达标
# 落选(tag 但非新鲜)仍降回自然分组;新鲜者全部留在推荐区
for d in results:
if d['sort_group'] == 0 and not _is_fresh(d):