补上停机处理:SIGTERM 撤挂单平仓再退,并关掉 aiohttp 会话

README 里原先写「执行器收到 SIGINT 会先平掉在场仓位再退出」,但代码里
完全没有信号处理——asyncio.run 外面连 except KeyboardInterrupt 都没有。
断言了一个不存在的行为,现在把它实现。

为什么停机要平仓而崩溃不用:崩溃后 systemd/docker 几秒内重启,reconcile
接着清掉遗留仓位,空窗期有交易所侧止损兜着。而主动停机后没人重启,仓位会
一直挂到止损或止盈,48 分钟超时腿丢了,跑的就不是回测那个出场结构。

必须显式挂 SIGTERM:docker stop 与 systemd stop 默认发的都是它,而 Python
对 SIGTERM 不抛 KeyboardInterrupt,不挂就是直接消失、没有任何清理。挂上后
systemd 单元里 KillSignal=SIGINT 那个绕法也去掉了。

主循环因异常退出时同样走停机流程,不把仓位留给已经没人管的进程。
顺带修掉 "Unclosed client session"(bitget_rest 本有 close() 但没人调,
Restart=always 下会漏 socket)。

实测:发 SIGTERM 后走完停机流程、无泄漏警告。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jack
2026-08-28 17:12:41 +08:00
co-authored by Cursor
parent 335d891478
commit 1642b1bbfc
2 changed files with 55 additions and 3 deletions
+3 -2
View File
@@ -21,8 +21,9 @@ ExecStart=/opt/chan/.venv/bin/python /opt/chan/live/live_exec.py
Restart=always
RestartSec=5
# 收到 stop 时给足时间:执行器平掉在场仓位再退出
KillSignal=SIGINT
# 收到 stop 时给足时间:执行器接到 SIGTERM 会撤挂单 + 平掉在场仓位再退出
# live_exec.shutdown(),内部平仓上限 60s)。默认的 90s 停机窗口留了余量。
# 不需要 KillSignal=SIGINT——SIGTERM 已在代码里显式挂了处理器
TimeoutStopSec=90
StandardOutput=journal