fix: 代码级约束 —— 推荐前必须同步重评, 不输出无操作信号的信息
1. price_monitor: 区间突破后同步调reassess_with_context(), 明确信号推XMPP 2. stale_detector: 只输出有[PUSH]/[STRATEGY_STALE]标记的行, 静默无操作信号的买入区 3. mofin_collect: stale/无策略持仓同步重评, 不靠TODO异步
This commit is contained in:
@@ -30,13 +30,32 @@ except ImportError:
|
||||
# 策略重评依赖(技术面驱动,非机械百分比)
|
||||
sys.path.insert(0, "/home/hmo/web-dashboard")
|
||||
try:
|
||||
from strategy_lifecycle import reassess_strategy
|
||||
from strategy_lifecycle import reassess_strategy, reassess_with_context
|
||||
HAS_REASSESS = True
|
||||
except ImportError:
|
||||
HAS_REASSESS = False
|
||||
|
||||
UA = "Mozilla/5.0"
|
||||
|
||||
# ── XMPP推送 ──────────────────────────────────────────────────────────
|
||||
XMPP_USER = "hmo@yoin.fun"
|
||||
XMPP_BRIDGE = "http://127.0.0.1:5805/"
|
||||
|
||||
def push_to_xmpp(text):
|
||||
"""通过知微 HTTP bridge 推送到Dad私信"""
|
||||
if not text.strip():
|
||||
return
|
||||
try:
|
||||
payload = json.dumps({
|
||||
"to": XMPP_USER,
|
||||
"body": text.strip(),
|
||||
"type": "chat",
|
||||
}).encode("utf-8")
|
||||
req = urllib.request.Request(XMPP_BRIDGE, data=payload, headers={"Content-Type": "application/json"})
|
||||
urllib.request.urlopen(req, timeout=5)
|
||||
except Exception as e:
|
||||
print(f"[XMPP推送失败] {e}", file=sys.stderr)
|
||||
|
||||
# ── 批量拉取价格 ──────────────────────────────────────────────────────────
|
||||
|
||||
def fetch_all_prices(codes):
|
||||
@@ -350,6 +369,24 @@ def run_once(round_label=""):
|
||||
if key == "stop_loss":
|
||||
outputs.append(f"⚠️ {name}({code}) {price} → 跌破止损{hi}!")
|
||||
record_event(code, name, "stop_loss", price, str(hi))
|
||||
# 止损触发 → 立即重评并推送给Dad
|
||||
try:
|
||||
cost = d.get("cost", 0) or 0
|
||||
shares = d.get("shares", 0) or 0
|
||||
current_action = d.get("action", "")
|
||||
result = reassess_with_context(code, name, price, cost, shares, current_action)
|
||||
if result:
|
||||
timing_signal = result.get("timing_signal", "")
|
||||
action = result.get("action", "")
|
||||
if "买入" in timing_signal or "加仓" in timing_signal or "止损" in action:
|
||||
buy_lo = d.get("entry_low", 0)
|
||||
buy_hi = d.get("entry_high", 0)
|
||||
rr = result.get("rr_ratio", 0)
|
||||
msg = f"🛒 {name}({code}) 价{price} 买入区{buy_lo}~{buy_hi} RR={rr} 止损触发!"
|
||||
push_to_xmpp(msg)
|
||||
outputs.append(f" 📨 止损重评→已推送Dad: {action}")
|
||||
except Exception as e:
|
||||
outputs.append(f" ⚠️ 止损重评失败: {e}")
|
||||
else:
|
||||
extra = ""
|
||||
if "_price" in key:
|
||||
@@ -363,6 +400,22 @@ def run_once(round_label=""):
|
||||
extra = f"({act})"
|
||||
outputs.append(f"⚡ {name}({code}) {price} → 进入{label}{lo}~{hi}{extra}")
|
||||
record_event(code, name, "entry_zone", price, f"{lo}~{hi}", label)
|
||||
# 进入区间 → 立即重评并推送给Dad
|
||||
try:
|
||||
cost = d.get("cost", 0) or 0
|
||||
shares = d.get("shares", 0) or 0
|
||||
current_action = d.get("action", "")
|
||||
result = reassess_with_context(code, name, price, cost, shares, current_action)
|
||||
if result:
|
||||
timing_signal = result.get("timing_signal", "")
|
||||
action = result.get("action", "")
|
||||
if "买入" in timing_signal or "加仓" in timing_signal or "止损" in action:
|
||||
rr = result.get("rr_ratio", 0)
|
||||
msg = f"🛒 {name}({code}) 价{price} 买入区{lo}~{hi} RR={rr}"
|
||||
push_to_xmpp(msg)
|
||||
outputs.append(f" 📨 区间触发重评→已推送Dad: {action}")
|
||||
except Exception as e:
|
||||
outputs.append(f" ⚠️ 区间重评失败: {e}")
|
||||
state[code][key] = True
|
||||
state_updated = True
|
||||
|
||||
|
||||
@@ -183,11 +183,9 @@ def main():
|
||||
flags.append("[WL_IN]")
|
||||
if strategy_deficient:
|
||||
flags.append("[STRATEGY_STALE]")
|
||||
prefix = "⚠️仓位挤占 " if position_pct > 80 else ""
|
||||
issues.append(f"[STRATEGY_STALE] {prefix}价{price:.2f}在买入区{el}~{eh}但策略不完整({'RR='+f'{rr:.2f}<1.5' if rr_invalid else '无止盈位' if not tp else '非买入信号'}),买入区需重评")
|
||||
issues.append(f"[STRATEGY_STALE] 价{price:.2f}在买入区{el}~{eh}但策略不完整({'RR='+f'{rr:.2f}<1.5' if rr_invalid else '无止盈位' if not tp else '非买入信号'}),买入区需重评")
|
||||
else:
|
||||
prefix = "⚠️仓位挤占 " if position_pct > 80 else ""
|
||||
issues.append(f"[PUSH] {prefix}价{price:.2f}入买入区{el}~{eh}")
|
||||
issues.append(f"[PUSH] 价{price:.2f}入买入区{el}~{eh}")
|
||||
elif price > eh * 1.35:
|
||||
flags.append("[WL_HIGH]")
|
||||
issues.append(f"价{price:.2f}高出买入区+{((price/eh)-1)*100:.0f}%,买入区需重评")
|
||||
@@ -255,8 +253,11 @@ def main():
|
||||
pass
|
||||
|
||||
if issues:
|
||||
print(f"{' '.join(flags)} {tag} {name}({code}) 价{price:.2f}{chg} | 买入{el}~{eh} | {'; '.join(issues)}")
|
||||
found += 1
|
||||
# 仅输出有明确操作信号的行:[PUSH]=推荐买入, [STRATEGY_STALE]=需重评
|
||||
# 静默其他纯信息行(如仅"价XX高出/高于买入区"而无操作建议)
|
||||
if any("[PUSH]" in i or "[STRATEGY_STALE]" in i for i in issues):
|
||||
print(f"{' '.join(flags)} {tag} {name}({code}) 价{price:.2f}{chg} | 买入{el}~{eh} | {'; '.join(issues)}")
|
||||
found += 1
|
||||
|
||||
if found == 0:
|
||||
print("[SILENT] 所有策略正常")
|
||||
|
||||
Reference in New Issue
Block a user