feat-rotation-llm-driven

This commit is contained in:
xxm
2026-08-26 13:55:10 +08:00
parent 73e0780434
commit 050c397e17
2 changed files with 18 additions and 1185 deletions
File diff suppressed because it is too large Load Diff
+17 -33
View File
@@ -1876,39 +1876,23 @@ def flush_rec_digest(max_items=5):
+ (f"(合计≈{cum:.0f}%" if buys else ""))
# ── 换仓策略:有排队推荐时,找可减的弱持仓来腾挪 ──
if queued:
weak = conn.execute("""
SELECT hs.code, hs.name, hs.timing_signal, h.position_pct, h.cost, lp.price, lp.change_pct
FROM holding_strategies hs
JOIN holdings h ON hs.code = h.code AND h.is_active = 1
LEFT JOIN live_prices lp ON hs.code = lp.code
WHERE hs.status='active' AND h.shares > 0
AND hs.timing_signal IN ('弱势持有','观望','持有')
""").fetchall()
# ── v7.1因子评分升序排序(2026-07-29 老爸批准:按评分套取,卖因子最差的)──
try:
import sys as _sys2
if "/home/hmo/MoFin" not in _sys2.path:
_sys2.path.insert(0, "/home/hmo/MoFin")
from backtest_framework import prepare_bars as _pb, compute_single_score as _cs
from datetime import datetime as _dt2, timedelta as _td2
_end2 = _dt2.now().strftime('%Y-%m-%d')
_start2 = (_dt2.now() - _td2(days=150)).strftime('%Y-%m-%d')
_scored = []
for w in weak:
_sc = 0
try:
_bars = _pb(w['code'], _start2, _end2)
if _bars and len(_bars) >= 25:
_r = _cs(_bars)
_sc = _r[0] if _r else 0
except Exception:
pass
_scored.append((_sc, w))
_scored.sort(key=lambda x: x[0]) # 评分最低 = 优先套取
weak = [w for _, w in _scored]
print(" [换仓] 因子评分排序: " + ", ".join(f"{w['name']}({s})" for s, w in _scored[:5]), flush=True)
except Exception as _se:
print(f" [换仓] 评分排序失败(回退信号排序): {_se}", flush=True)
weak = []
# 2026-08-26: LLM rotation
for item in items:
sj = item.get('signal_json') or {}
rc = sj.get('rotation_candidate') or {}
if rc.get('code') and rc.get('reason'):
_rot = conn.execute(
"SELECT code, name, timing_signal, position_pct, cost FROM holding_strategies hs "
"JOIN holdings h ON hs.code = h.code AND h.is_active = 1 "
"WHERE hs.code = ? AND h.shares > 0", (rc['code'],)
).fetchone()
if _rot:
_d = dict(_rot)
_d['_rotation_reason'] = rc.get('reason', '')
weak.append(_d)
if weak:
print(f" [换仓] LLM推荐 {len(weak)}", flush=True)
weak = sorted(weak, key=lambda w: ({'弱势持有': 0, '观望': 1}.get(w['timing_signal'], 2),
-(w['position_pct'] or 0)))
if weak: