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
+48 -5
View File
@@ -132,7 +132,7 @@ def _roll_preview_response(cfg: dict, data: dict, json_mode: bool = False) -> di
if not mon:
conn.close()
return {"ok": False, "msg": "未找到该币种同向的下单监控持仓,请先在「实盘下单」开仓"}
rg, legs_done = _get_or_create_roll_group_meta(conn, mon)
rg, legs_done, _is_new = _get_or_create_roll_group_meta(conn, mon)
conn.close()
pos = cfg["get_position"](ex_sym, direction)
qty = float(pos.get("contracts") or 0)
@@ -217,7 +217,7 @@ def _roll_execute(cfg: dict, data: dict) -> tuple[bool, str]:
mon = _get_active_monitor(conn, cfg, symbol, direction)
if not mon:
return False, "监控单已不存在"
rg, legs_done = _get_or_create_roll_group_meta(conn, mon)
rg, legs_done, roll_is_new = _get_or_create_roll_group_meta(conn, mon)
new_sl = float(preview["new_stop_loss"])
tp0 = float(preview["initial_take_profit"])
if add_mode == "market":
@@ -253,6 +253,21 @@ def _roll_execute(cfg: dict, data: dict) -> tuple[bool, str]:
(legs_done + 1, cfg["app_now_str"](), rg["id"]),
)
conn.commit()
if roll_is_new:
try:
from strategy_wechat_notify import notify_roll_group_started
notify_roll_group_started(
cfg,
group_id=int(rg["id"]),
symbol=symbol,
direction=direction,
order_monitor_id=int(mon["id"]),
initial_take_profit=tp0,
initial_stop_loss=float(mon.get("stop_loss") or new_sl),
)
except Exception:
pass
return True, f"已挂限价加仓单 #{oid},成交后请在页面点「同步持仓并更新止损」"
cfg["replace_tpsl"](ex_sym, direction, new_sl, tp0, mon)
conn.execute(
@@ -284,6 +299,23 @@ def _roll_execute(cfg: dict, data: dict) -> tuple[bool, str]:
(new_sl, mon["id"]),
)
conn.commit()
try:
from strategy_wechat_notify import (
notify_roll_group_started,
)
if roll_is_new:
notify_roll_group_started(
cfg,
group_id=int(rg["id"]),
symbol=symbol,
direction=direction,
order_monitor_id=int(mon["id"]),
initial_take_profit=tp0,
initial_stop_loss=new_sl,
)
except Exception:
pass
return True, f"滚仓第 {legs_done + 1} 腿已市价成交,交易所止损已更新,止盈仍为首仓 {tp0}"
except Exception as e:
fe = cfg.get("friendly_error")
@@ -304,14 +336,14 @@ def _get_active_monitor(conn, cfg: dict, symbol: str, direction: str) -> Optiona
return _row_to_dict(row) if row else None
def _get_or_create_roll_group_meta(conn, mon: dict) -> tuple[dict, int]:
def _get_or_create_roll_group_meta(conn, mon: dict) -> tuple[dict, int, bool]:
row = conn.execute(
"SELECT * FROM roll_groups WHERE order_monitor_id=? AND status='active' ORDER BY id DESC LIMIT 1",
(mon["id"],),
).fetchone()
if row:
d = _row_to_dict(row)
return d, int(d.get("leg_count") or 0)
return d, int(d.get("leg_count") or 0), False
now = mon.get("created_at") or ""
cur = conn.execute(
"""INSERT INTO roll_groups (
@@ -335,6 +367,17 @@ def _get_or_create_roll_group_meta(conn, mon: dict) -> tuple[dict, int]:
),
)
gid = int(cur.lastrowid)
return {"id": gid, "leg_count": 0, "initial_take_profit": mon.get("take_profit")}, 0
return (
{
"id": gid,
"leg_count": 0,
"initial_take_profit": mon.get("take_profit"),
"initial_stop_loss": mon.get("stop_loss"),
"symbol": mon.get("symbol"),
"direction": mon.get("direction"),
},
0,
True,
)