refactor: 策略判断合并——失效=需更换(老莫:同一决策)。失效时必须给新归属(候选封闭集),给不出才停invalidated。三选一:维持/修改/策略失效需更换

This commit is contained in:
xxm
2026-08-18 21:37:39 +08:00
parent 4af4bda7b3
commit 62a0626141
2 changed files with 39 additions and 30 deletions
+28 -20
View File
@@ -459,12 +459,12 @@ PE={data.get('pe','?')}(最新财报) 市值={data.get('mcap','?')}亿
请严格按以下格式输出(注意节标题不可省略):
【策略判断】选一:维持原策略 / 修改参数 / 策略失效重定 / 更换策略归类
- 默认倾向「维持原策略」;只有情势体检命中红线、或重评侧重检查发现原入场逻辑不成立时,才选后三者
- 「策略失效重定」= 策略已不适用,按当前市场环境重新制定(新止损/止盈/持有期
- 「更换策略归类」= 该股当前更适合另一个策略,从【策略定义】候选中选择,禁止自创
【策略判断】选一:维持原策略 / 修改参数 / 策略失效需更换
- 默认倾向「维持原策略」;只有情势体检命中红线、或重评侧重检查发现原入场逻辑不成立时,才选「策略失效需更换」
- 「修改参数」= 策略框架仍适用,仅微调参数(止损/止盈/区间
- 「策略失效需更换」= 原策略在当前情势下已不适合(温区切换/黑天鹅/入场逻辑不成立),必须换一个策略来评估
【策略失效理由】(策略判断≠维持原策略时必填,逐条对照重评侧重说明哪条不成立;维持时写"无需修改"
【更换策略归类】(仅当策略判断=更换策略归类时填,写策略名)
【更换策略归类】策略失效需更换时【必须】从候选中选一个(禁止自创);若确实无合适策略,写"无合适策略"
【维持或修改】明确二选一判断:维持原策略 / 需要修改策略
【修改点及理由】
如果维持原策略 → 写"无需修改"
@@ -591,10 +591,11 @@ def parse_response(text):
break
# 2026-08-18 策略判断(只认【策略判断】节行)
# 老莫 2026-08-18:失效=需更换(同一决策),失效时必须给新归属;给不出才停在失效未归属
result["strategy_judge"] = ""
_sj = _section_line("策略判断")
if _sj:
_m = re.search(r'策略判断】\s*(维持原策略|修改参数|策略失效重定|更换策略归类)', _sj)
_m = re.search(r'策略判断】\s*(维持原策略|修改参数|策略失效更换|策略失效重定)', _sj)
if _m:
result["strategy_judge"] = _m.group(1)
# 策略失效理由
@@ -602,18 +603,19 @@ def parse_response(text):
_sr = _section_line("策略失效理由")
if _sr:
result["strategy_reason"] = re.sub(r'^\s*【策略失效理由】\s*', '', _sr).strip()[:200]
# 更换策略归类(封闭集校验:必须在候选列表内)
# 更换策略归类(封闭集校验:必须在候选列表内;失效和更换都解析
result["strategy_switch_to"] = ""
_CANDIDATES = ("accumulation", "b_td1_v3", "v_mr", "hk_pe_mom", "hk_pe_oversold", "p_oversold", "s2_panic", "leader", "v_next", "v8.1")
_st = _section_line("更换策略归类")
if _st:
_body = re.sub(r'^\s*【更换策略归类】\s*', '', _st).strip().lower()
for c in _CANDIDATES:
if c in _body:
result["strategy_switch_to"] = c
break
if not result["strategy_switch_to"] and result["strategy_judge"] == "更换策略归类":
result["strategy_judge"] = "策略失效重定" # 归因无效→降级
if "无合适策略" in _body or "无合适" in _body:
result["strategy_switch_to"] = "" # 明确无合适 → 失效未归属
else:
for c in _CANDIDATES:
if c in _body:
result["strategy_switch_to"] = c
break
return result
@@ -741,14 +743,20 @@ def save_result(code, full_text, parsed, ta_levels=None):
conn.execute(sql, params)
conn.commit()
# 2026-08-18 策略状态落库(strategy_judge/switch_to,老莫:策略切换决策)
# 2026-08-18 策略状态落库(strategy_judge/switch_to,老莫:失效=需更换,同一决策)
_j = parsed.get("strategy_judge", "")
if _j == "策略失效重定":
conn.execute("UPDATE holding_strategies SET strategy_state='invalidated' WHERE code=? AND status='active'", (code,))
conn.commit()
elif _j == "更换策略归类" and parsed.get("strategy_switch_to"):
conn.execute("UPDATE holding_strategies SET strategy_attributed=?, strategy_state='switched', strategy_provenance='llm_attributed' WHERE code=? AND status='active'", (parsed["strategy_switch_to"], code))
conn.commit()
_st = parsed.get("strategy_switch_to", "")
if _j in ("策略失效需更换", "策略失效重定"):
if _st:
# 失效+给归属 → 切换到新策略
conn.execute("UPDATE holding_strategies SET strategy_attributed=?, strategy_state='switched', strategy_provenance='llm_attributed' WHERE code=? AND status='active'", (_st, code))
conn.commit()
print(f" ✅ 策略切换: {_j} → 归属 {_st}strategy_state=switched")
else:
# 失效+无合适归属 → 标记失效
conn.execute("UPDATE holding_strategies SET strategy_state='invalidated' WHERE code=? AND status='active'", (code,))
conn.commit()
print(f" ✅ 策略失效: {_j} 无合适归属(strategy_state=invalidated")
# ── 信号以分析为唯一事实源(防信号/分析脱节)──
from mofin_db import reconcile_signal_from_analysis