feat(strategy): WeChat notify on trend and roll plan start/end

Add shared strategy_wechat_notify helpers; hook trend execute/finalize and roll group open/close across four exchanges and Gate bot.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-04 13:35:21 +08:00
parent 3b4120a36e
commit 52d97482f2
5 changed files with 373 additions and 6 deletions
+78
View File
@@ -79,8 +79,33 @@ def build_trend_config(app_module: Any = None, **kw) -> dict[str, Any]:
except Exception:
return None
def send_wechat(content):
fn = getattr(m, "send_wechat_msg", None)
if callable(fn):
fn(content)
def wechat_account_label():
fn = getattr(m, "_wechat_account_label", None)
if callable(fn):
try:
return fn()
except Exception:
pass
return getattr(m, "EXCHANGE_DISPLAY_NAME", "") or ""
def wechat_direction_text(direction):
fn = getattr(m, "_wechat_direction_text", None)
if callable(fn):
try:
return fn(direction)
except Exception:
pass
d = (direction or "long").strip().lower()
return "做多" if d == "long" else "做空"
return {
"app_module": m,
"exchange_display": getattr(m, "EXCHANGE_DISPLAY_NAME", ""),
"login_required": m.login_required,
"get_db": m.get_db,
"row_to_dict": m.row_to_dict,
@@ -93,6 +118,10 @@ def build_trend_config(app_module: Any = None, **kw) -> dict[str, Any]:
"max_active_positions": int(getattr(m, "MAX_ACTIVE_POSITIONS", 1)),
"reset_hour": int(getattr(m, "TRADING_DAY_RESET_HOUR", 8)),
"monitor_type_trend": MONITOR_TYPE_TREND,
"send_wechat": send_wechat,
"format_price": getattr(m, "format_price_for_symbol", None),
"wechat_account_label": wechat_account_label,
"wechat_direction_text": wechat_direction_text,
}
@@ -504,6 +533,21 @@ def _finalize_plan(cfg: dict, conn, row, result_label: str, exit_price: float) -
if not getattr(cur, "rowcount", 0):
return
conn.commit()
try:
from strategy_wechat_notify import notify_trend_plan_ended
notify_trend_plan_ended(
cfg,
plan_id=plan_id,
symbol=sym,
direction=direction,
end_type=result_label,
result_label=res,
exit_price=float(exit_price) if exit_price is not None else None,
pnl_amount=float(pnl_amount) if pnl_amount is not None else None,
)
except Exception:
pass
try:
closed = conn.execute(
"SELECT * FROM trend_pullback_plans WHERE id=?", (plan_id,)
@@ -945,6 +989,20 @@ def apply_manual_breakeven(cfg: dict, conn, row, offset_pct=None) -> tuple[bool,
send = getattr(m, "send_wechat_msg", None)
pf = getattr(m, "format_price_for_symbol", None)
fmt = (lambda s, p: pf(s, p)) if callable(pf) else (lambda _s, p: str(p))
try:
from strategy_wechat_notify import notify_trend_plan_ended
notify_trend_plan_ended(
cfg,
plan_id=plan_id,
symbol=sym,
direction=direction,
end_type="保本移交",
result_label=TREND_HANDOFF_TRADE_NOTE,
extra=f"已移交下单监控 #{mon_id};止损 {fmt(sym, new_sl)} 止盈 {fmt(sym, tp)}",
)
except Exception:
pass
if callable(send):
lines = [
f"# ✅ {sym} 趋势回调保本移交",
@@ -1213,6 +1271,26 @@ def register_trend_routes(app: Flask, cfg: dict) -> None:
)
conn.execute("DELETE FROM trend_pullback_previews WHERE id=?", (pid,))
conn.commit()
try:
from strategy_wechat_notify import notify_trend_plan_started
notify_trend_plan_started(
cfg,
plan_id=new_id,
symbol=symbol,
direction=direction,
leverage=leverage,
stop_loss=stop_loss,
take_profit=float(pr["take_profit"]),
add_upper=float(pr["add_upper"]),
risk_percent=float(pr["risk_percent"] or 5),
dca_legs=int(pr["dca_legs"] or 0),
first_order_amount=first_amt,
avg_entry=fill1,
snapshot_usdt=float(snap_now),
)
except Exception:
pass
conn.close()
flash("趋势回调已执行:首仓已成交并挂交易所止损,止盈由程序监控。")
return _redirect_trend()