feat-rotation-llm-driven
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user