加 Telegram 通知,并修好一道死掉的闸
接 Telegram 时查出 Guard.realized() 定义了但全仓库没有调用点——pnl_day 恒为 0,MAX_DAY_LOSS 完全不生效。三条硬约束里最重要的一条是死的。 根因是止损与止盈都挂在交易所侧成交,本进程收不到通知,而 sweep 只在 48 分钟到点才查持仓。连带第二个后果:execs 条目不清,MAX_OPEN 把已出场的 仓位继续算在场,新信号被白挡到截止时刻。 补 watch() 循环(10s):持仓消失即判出场,去 history-position 取 netProfit(= pnl + 资金费 + 开平手续费)记回闸并释放名额。盈亏取交易所的 数而不自己按标记价估——估会漏掉费用且方向总偏乐观。历史未落库时留到下轮, 不会漏记。字段名按文档与官方 TS 类型的差异同时兼容 ctime/cTime。 Telegram(live/tg.py,stdlib + aiohttp):推开仓、平仓带已实现盈亏、被硬 约束挡住、报错、对账平仓、跨日结算、启动与停机。不推信号过期跳过(常态, 搬运重连会重放旧信号)与心跳,否则真事会被淹掉。启动那条兼作通道自检。 研究侧 tg_notify.send 改为复用生产的传输层,方向与 signal_bus 一致。 status.sh 增加一条判读:开过仓但 pnl 仍为 0 就是 watch() 出了问题。 实测:8 类消息渲染、_match_hist 的过早/方向不符/币不符/驼峰字段/取最近 五种情形、100 USDT 下 SOL 与 ADA 的端到端空跑(两腿等量,50/50 精确)。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+12
-14
@@ -185,20 +185,18 @@ def build(sym: str, direction: int, entry: float, atr_pct: float,
|
||||
|
||||
|
||||
async def send(text: str) -> None:
|
||||
"""推一条。任何失败都只打日志——推送挂了不能连坐采集。"""
|
||||
if not ENABLED:
|
||||
return
|
||||
try:
|
||||
import aiohttp
|
||||
url = f"https://api.telegram.org/bot{TOKEN}/sendMessage"
|
||||
async with aiohttp.ClientSession() as s:
|
||||
async with s.post(url, json={"chat_id": CHAT, "text": text},
|
||||
timeout=aiohttp.ClientTimeout(total=10)) as r:
|
||||
if r.status != 200:
|
||||
print(f" [TG] 推送失败 HTTP {r.status} "
|
||||
f"{(await r.text())[:200]}", flush=True)
|
||||
except Exception as e:
|
||||
print(f" [TG] 推送异常 {type(e).__name__}: {e}", flush=True)
|
||||
"""推一条。传输层复用生产侧的 `live/tg.py`,这里不再维护第二份。
|
||||
|
||||
方向与 `signal_bus` 一致:**生产持有实现,研究侧反过来 import**。反过来
|
||||
写成生产 import 研究侧,就等于把研究侧的依赖树绑到实盘进程上。
|
||||
"""
|
||||
from pathlib import Path
|
||||
import sys
|
||||
p = str(Path(__file__).resolve().parents[2] / "live")
|
||||
if p not in sys.path:
|
||||
sys.path.insert(0, p)
|
||||
import tg
|
||||
await tg.send(text)
|
||||
|
||||
|
||||
async def push_signal(sym: str, direction: int, entry: float, atr_pct: float,
|
||||
|
||||
Reference in New Issue
Block a user