diff --git a/deploy/profile-scripts/batch_reassess.py b/deploy/profile-scripts/batch_reassess.py index 71d9b6a5..318985d5 100644 --- a/deploy/profile-scripts/batch_reassess.py +++ b/deploy/profile-scripts/batch_reassess.py @@ -576,6 +576,26 @@ def save_result(code, full_text, parsed, ta_levels=None): params.append(_tp) elif _tp > 0: print(f" ⚠️ 止盈{_tp}与区间/止损不一致,跳过写入(保留原值)", flush=True) + # 2026-08-18 修复:LLM 算的 entry 区间也写回 entry_low/entry_high(纠正 promote 错误区间) + # 例:promote 入库 entry 95~99 vs 现价 7.59 严重偏离,重评算正确 7.55~7.70 应覆盖 + _el_new = parsed.get("entry_low") or 0 + _eh_new = parsed.get("entry_high") or 0 + if _el_new > 0 and _eh_new > _el_new: + # 校验 entry 与现 stop_loss/take_profit 一致(sl < el < eh < tp) + _ok = True + if "stop_loss=?" in updates: + _cur_sl = params[updates.index("stop_loss=?")] + if _cur_sl >= _el_new: + _ok = False + if "take_profit=?" in updates: + _cur_tp = params[updates.index("take_profit=?")] + if _cur_tp <= _eh_new: + _ok = False + if _ok: + updates.append("entry_low=?") + params.append(_el_new) + updates.append("entry_high=?") + params.append(_eh_new) if parsed["position"]: updates.append("position_advice=?") params.append(parsed["position"]) diff --git a/deploy/profile-scripts/promote_candidates.py b/deploy/profile-scripts/promote_candidates.py index 9694fbf1..ea9ebba5 100644 --- a/deploy/profile-scripts/promote_candidates.py +++ b/deploy/profile-scripts/promote_candidates.py @@ -143,6 +143,40 @@ def main(): print(f" ⏭ {code} {name} 候选参数无效(区{el}~{eh} 损{sl} 盈{tp}),跳过") processed += 1 continue + # ── B. entry_range 与现价偏离>50% → 不直接用(标记需重评校准,防错误区间进自选)── + try: + import subprocess, json as _jj + _r2 = subprocess.run(["python3", "/home/hmo/.hermes/profiles/position-analyst/scripts/stock_quote.py", code], + capture_output=True, text=True, timeout=10) + _q = _jj.loads(_r2.stdout) + _cur_price = float(_q.get("price", 0)) + if _cur_price > 0: + _dev = abs((_cur_price - (el + eh) / 2) / _cur_price) * 100 + if _dev > 50: + print(f" ⏭ {code} {name} 买入区{el}~{eh} 偏离现价{_cur_price} {_dev:.0f}%(错误区间),标记重评校准不入自选") + processed += 1 + continue + except Exception: + pass + # ── C. 可执行性检查:止损距离≥2%、止盈空间≥3%、修正风报比(含成本)≥2 ── + _price_est = (el + eh) / 2 + _stop_dist = (_price_est - sl) / _price_est * 100 if sl > 0 else 0 + _tp_space = (tp - _price_est) / _price_est * 100 if tp > 0 else 0 + # 修正风报比:考虑交易成本(双边~0.2%) + _COST = 0.002 + _rr_exec = ((_tp_space / 100 - _COST) / (_stop_dist / 100 + _COST)) if _stop_dist > 0 else 0 + if _stop_dist < 2.0: + print(f" ⏭ {code} {name} 止损距离{_stop_dist:.1f}%<2%(不可执行,贴死技术位),跳过") + processed += 1 + continue + if _tp_space < 3.0: + print(f" ⏭ {code} {name} 止盈空间{_tp_space:.1f}%<3%(不可执行,覆盖不了成本),跳过") + processed += 1 + continue + if _rr_exec < 2.0: + print(f" ⏭ {code} {name} 修正风报比{_rr_exec:.1f}<2.0(含交易成本后不达标的阿猫阿狗),跳过") + processed += 1 + continue # 构建策略 now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")