fix: 推送质量门禁+损盈一致性门禁(根治垃圾信号)

1. XMPP推送门禁(_validate_buy_alert): 实时价>0(live_prices)、
   区间有效、现价不超上沿5%、损<下沿且在(0.5x~1.0x)现价内、
   盈>上沿>损 —— 任一不过不推只记日志
2. DB损盈一致性门禁: 损必须在下沿之下、盈必须在上沿之上且损<盈,
   不一致字段跳过写入保留原值(浩辰 区2~3损25.11 类污染根治)
3. 推送价格源改 live_prices(不再用 holding_strategies.price 的0值)
4. 浩辰脏行已从快照恢复(区25.93~27.84 损25.11 盈31.38)
This commit is contained in:
hmo
2026-07-22 08:16:40 +08:00
parent c27388681c
commit 04284e5187
+40 -11
View File
@@ -352,12 +352,18 @@ def save_result(code, full_text, parsed):
params.append(_eh)
elif _el > 0 or _eh > 0:
print(f" ⚠️ 买入区解析异常({_el}~{_eh}),跳过区间写入(保留原值)", flush=True)
if parsed["stop_loss"] > 0:
# 止损/止盈一致性门禁:损>0 时必须在区间下沿之下(0.5x~1.0x),盈>0 时必须在区间上沿之上
_sl, _tp = parsed["stop_loss"], parsed["take_profit"]
if _sl > 0 and (not _el or _sl < _el) and (not _tp or _sl < _tp):
updates.append("stop_loss=?")
params.append(parsed["stop_loss"])
if parsed["take_profit"] > 0:
params.append(_sl)
elif _sl > 0:
print(f" ⚠️ 止损{_sl}与区间/止盈不一致,跳过写入(保留原值)", flush=True)
if _tp > 0 and (not _eh or _tp > _eh) and (not _sl or _tp > _sl):
updates.append("take_profit=?")
params.append(parsed["take_profit"])
params.append(_tp)
elif _tp > 0:
print(f" ⚠️ 止盈{_tp}与区间/止损不一致,跳过写入(保留原值)", flush=True)
if parsed["position"]:
updates.append("position_advice=?")
params.append(parsed["position"])
@@ -370,26 +376,49 @@ def save_result(code, full_text, parsed):
# ── 推荐操作 tag 同步(与 XMPP 动作级信号同源)──
sync_recommend_tag(conn, code, parsed.get("signal", ""))
# 买入信号→推XMPP通知(在conn close前执行)
# 买入信号→推XMPP通知(在conn close前执行)——推送质量门禁:
# 价格必须>0(live_prices实时价)、区间有效(下沿<上沿<下沿x3)、现价不超过上沿5%、
# 损<下沿、盈>上沿、损在(0.5x~1.0x)现价内。任何一项不过 → 不推,只记日志。
if parsed.get("signal") == "买入":
try:
_nr = conn.execute("SELECT name, price FROM holding_strategies WHERE code=? AND status='active'", (code,)).fetchone()
_nr = conn.execute("SELECT name FROM holding_strategies WHERE code=? AND status='active'", (code,)).fetchone()
_lp = conn.execute("SELECT price FROM live_prices WHERE code=?", (code,)).fetchone()
_name = _nr[0] if _nr else code
_p = _nr[1] if _nr else 0
_p = _lp[0] if _lp and _lp[0] else 0
_el = parsed.get("entry_low", 0)
_eh = parsed.get("entry_high", 0)
_sl = parsed.get("stop_loss", 0)
_tp = parsed.get("take_profit", 0)
_pos = parsed.get("position", "")
_msg = f"📈 {_name}({code}) 价{_p}→12维分析生成买入信号!区间{_el}~{_eh}{_sl}{_tp} 仓位{_pos}"
from alert_helper import notify as _notify, ACTION as _ACT
_notify("买入信号", _msg, _ACT)
print(f" \U0001f4e8 XMPP推送成功: {_msg[:60]}")
_ok, _why = _validate_buy_alert(_p, _el, _eh, _sl, _tp)
if _ok:
_msg = f"📈 {_name}({code}) 价{_p}→12维分析生成买入信号!区间{_el}~{_eh}{_sl}{_tp} 仓位{_pos}"
from alert_helper import notify as _notify, ACTION as _ACT
_notify("买入信号", _msg, _ACT)
print(f" \U0001f4e8 XMPP推送成功: {_msg[:60]}")
else:
print(f" ⚠️ 买入信号未过推送门禁({_why}),仅记日志不推送", flush=True)
except Exception as _e:
print(f" \u26a0\ufe0f XMPP推送失败: {_e}")
conn.close()
def _validate_buy_alert(price, el, eh, sl, tp):
"""买入信号推送门禁(垃圾信号不发)。
返回 (ok, reason)"""
if not price or price <= 0:
return False, f"无实时价格({price})"
if not (el > 0 and eh > el and eh < el * 3):
return False, f"区间无效({el}~{eh})"
if price > eh * 1.05:
return False, f"现价{price}高于区间上沿{eh}超5%(追高信号不推)"
if not (sl > 0 and sl < el and price * 0.5 <= sl <= price):
return False, f"止损{sl}不合理(需0.5x~1.0x现价且<下沿{el})"
if not (tp > eh and tp > sl):
return False, f"止盈{tp}需>上沿{eh}且>止损{sl}"
return True, ""
def process_stock(code, force_today=False):
"""处理单只股票"""
print(f"\n{'='*50}")