前言国内期货策略在 Linux 服务器上 7×24 跑难免遇到机器重启、发版替换、内存 OOM 被系统杀掉、网络闪断后进程退出。进程一死内存里的变量全没你记的target_vol3、网格档位、上一根 K 线是否已处理、emergency标志都会消失。若新进程启动后默认“从空仓开始”再次set_target_volume(3)而期货公司柜台里其实已有 2 手就会变成超仓、重复开仓或与人工作出的仓位冲突。可靠原则只有一句柜台是真相同期本地文件是辅助。天勤在连接后通过wait_update()更新get_position、get_order、get_account业务状态上次处理到哪根 bar需自己用 JSON/SQLite 持久化。下面说明崩溃重启后恢复顺序、各英文字段指什么、如何避免重复开仓。一、什么必须从柜台读、什么可以写文件数据天勤接口重启后怎么用真实净持仓get_position(symbol).pos真相优先于文件在途委托get_order()status 为 ALIVE决定要不要撤单或同步 task资金get_account()风控与能否加仓上次处理的 bar 时间自建 state JSON防同一根 K 线重复下单策略阶段机、网格 level文件辅助与 pos 冲突以 pos 为准emergency 标志文件自定字段true 时应先平仓再交易ALIVE是委托 status 的一种表示单还在交易所有效、未完全成交也未撤完。FINISHED表示该委托生命周期结束。二、推荐启动恢复流程按顺序勿跳步apimake_api()stateload_state()# 本地 JSON可能过时for_inrange(20):api.wait_update()# 先收几帧让 position/order 有数forsinsymbols:posapi.get_position(s)actualpos.pos state.setdefault(targets,{})[s]actual tasks[s].set_target_volume(actual)# 让 TargetPosTask 与柜台一致# 打印 ALIVE 单决定是否人工处理foroid,oinapi.get_order().items():ifo.statusALIVE:log(alive order,oid,o.volume_left,o.last_msg)# 再进入主循环按 datetime 产生新信号含义不要一启动就按文件里的target3去 set要先wait_update读pos.pos。set_target_volume(actual)是让天勤内部 task 认为“目标就是当前仓”避免它立刻再报一单去追文件里的旧目标。若文件写target3但actual1必须打告警以 1 为起点由新信号决定是否加到 3勿直接 set 3。三、持久化写什么、何时写建议在 K 线datetime变新 bar且信号逻辑跑完后写文件state[last_bar_dt]str(kl.iloc[-2].datetime)state[targets][symbol]intended_target# 策略意图非柜台真相state[version]CONFIG_VERSION save_state_atomic(state)# 先写 .tmp 再 rename防写到一半崩溃datetime是 K 线表上的业务时间由行情服务写入。intended_target是策略想达到的目标柜台pos可能因部分成交滞后两者不一致时要走对账逻辑见部分成交专题。四、挂单与重复 insert_order重启后get_order()可能仍有ALIVE单。若策略不应保留挂单例如只用 task 调仓不要盲再insert_order应让set_target_volume驱动 task 撤旧挂新或按团队规范显式撤单。同一合约勿 task 与insert_order混用。五、emergency 与崩溃交叉若崩溃前已进入 emergency当日回撤超限文件应持久化emergencytrue。重启后应先读 position有仓则继续平到 0且禁止信号层新开仓直到人工复位emergencyfalse。否则会出现“风控已触发却又开仓”的严重事故。六、多策略、多环境多策略每策略独立 state 文件目录勿共用一个targets字典。TqKq与TqSim持仓体系不同重启后make_api()的 MODE 必须与崩溃前一致勿 sim 状态文件配 live API。指标缓存可持久化或启动后 warm-up 重算见冷启动专题勿用旧文件里的指标值当真相。七、演练纳入发布流程模拟盘对运行中进程kill -9再用 systemd 拉起检查是否重复开仓、ALIVE 单是否异常、日志里 pos 与 APP 是否一致。通过后再上实盘。这比真事故时改代码成本低得多。总结崩溃重启之后最重要的不是尽快恢复下单而是先恢复对‘当前真实状态’的认识柜台里到底有多少 pos、有哪些 ALIVE 单、资金是否可继续承受。可靠的顺序是 wait_update 先把真相读回来再把任务目标同步到实际 pos把文件中的 last_bar_dt 或策略阶段机作为辅助证据而不是用旧记忆直接开新仓。还要处理挂单不能在不清楚交易所状态时盲目重复 insert_order而是让 task/对账逻辑接管。若崩溃前已进入 emergency也要确保紧急状态能被持久化并在重启后继续执行“先平后启”。当这些边界写清楚系统才能从异常中平稳接续不会因为重启把正常风险再重跑一遍。FAQ1文件写 3、position 是 0以 position 为准改文件并查是否人工平仓或拒单。2重启后指标全是 nan新 session 要 warm-up或从文件恢复足够长的 last_bar_dt 后重算。3underlying_symbol 换月变了重启后重新读主连 quote 的 underlying_symbol更新 trade_sym 与 task 订阅。4容器自动重启太频繁先修 OOM 或断线勿让恢复逻辑在仓位未查清时高频 set。风险提示以上内容用于恢复流程参考不构成投资建议。
策略进程崩溃重启后避免重复开仓:状态恢复与柜台核对
前言国内期货策略在 Linux 服务器上 7×24 跑难免遇到机器重启、发版替换、内存 OOM 被系统杀掉、网络闪断后进程退出。进程一死内存里的变量全没你记的target_vol3、网格档位、上一根 K 线是否已处理、emergency标志都会消失。若新进程启动后默认“从空仓开始”再次set_target_volume(3)而期货公司柜台里其实已有 2 手就会变成超仓、重复开仓或与人工作出的仓位冲突。可靠原则只有一句柜台是真相同期本地文件是辅助。天勤在连接后通过wait_update()更新get_position、get_order、get_account业务状态上次处理到哪根 bar需自己用 JSON/SQLite 持久化。下面说明崩溃重启后恢复顺序、各英文字段指什么、如何避免重复开仓。一、什么必须从柜台读、什么可以写文件数据天勤接口重启后怎么用真实净持仓get_position(symbol).pos真相优先于文件在途委托get_order()status 为 ALIVE决定要不要撤单或同步 task资金get_account()风控与能否加仓上次处理的 bar 时间自建 state JSON防同一根 K 线重复下单策略阶段机、网格 level文件辅助与 pos 冲突以 pos 为准emergency 标志文件自定字段true 时应先平仓再交易ALIVE是委托 status 的一种表示单还在交易所有效、未完全成交也未撤完。FINISHED表示该委托生命周期结束。二、推荐启动恢复流程按顺序勿跳步apimake_api()stateload_state()# 本地 JSON可能过时for_inrange(20):api.wait_update()# 先收几帧让 position/order 有数forsinsymbols:posapi.get_position(s)actualpos.pos state.setdefault(targets,{})[s]actual tasks[s].set_target_volume(actual)# 让 TargetPosTask 与柜台一致# 打印 ALIVE 单决定是否人工处理foroid,oinapi.get_order().items():ifo.statusALIVE:log(alive order,oid,o.volume_left,o.last_msg)# 再进入主循环按 datetime 产生新信号含义不要一启动就按文件里的target3去 set要先wait_update读pos.pos。set_target_volume(actual)是让天勤内部 task 认为“目标就是当前仓”避免它立刻再报一单去追文件里的旧目标。若文件写target3但actual1必须打告警以 1 为起点由新信号决定是否加到 3勿直接 set 3。三、持久化写什么、何时写建议在 K 线datetime变新 bar且信号逻辑跑完后写文件state[last_bar_dt]str(kl.iloc[-2].datetime)state[targets][symbol]intended_target# 策略意图非柜台真相state[version]CONFIG_VERSION save_state_atomic(state)# 先写 .tmp 再 rename防写到一半崩溃datetime是 K 线表上的业务时间由行情服务写入。intended_target是策略想达到的目标柜台pos可能因部分成交滞后两者不一致时要走对账逻辑见部分成交专题。四、挂单与重复 insert_order重启后get_order()可能仍有ALIVE单。若策略不应保留挂单例如只用 task 调仓不要盲再insert_order应让set_target_volume驱动 task 撤旧挂新或按团队规范显式撤单。同一合约勿 task 与insert_order混用。五、emergency 与崩溃交叉若崩溃前已进入 emergency当日回撤超限文件应持久化emergencytrue。重启后应先读 position有仓则继续平到 0且禁止信号层新开仓直到人工复位emergencyfalse。否则会出现“风控已触发却又开仓”的严重事故。六、多策略、多环境多策略每策略独立 state 文件目录勿共用一个targets字典。TqKq与TqSim持仓体系不同重启后make_api()的 MODE 必须与崩溃前一致勿 sim 状态文件配 live API。指标缓存可持久化或启动后 warm-up 重算见冷启动专题勿用旧文件里的指标值当真相。七、演练纳入发布流程模拟盘对运行中进程kill -9再用 systemd 拉起检查是否重复开仓、ALIVE 单是否异常、日志里 pos 与 APP 是否一致。通过后再上实盘。这比真事故时改代码成本低得多。总结崩溃重启之后最重要的不是尽快恢复下单而是先恢复对‘当前真实状态’的认识柜台里到底有多少 pos、有哪些 ALIVE 单、资金是否可继续承受。可靠的顺序是 wait_update 先把真相读回来再把任务目标同步到实际 pos把文件中的 last_bar_dt 或策略阶段机作为辅助证据而不是用旧记忆直接开新仓。还要处理挂单不能在不清楚交易所状态时盲目重复 insert_order而是让 task/对账逻辑接管。若崩溃前已进入 emergency也要确保紧急状态能被持久化并在重启后继续执行“先平后启”。当这些边界写清楚系统才能从异常中平稳接续不会因为重启把正常风险再重跑一遍。FAQ1文件写 3、position 是 0以 position 为准改文件并查是否人工平仓或拒单。2重启后指标全是 nan新 session 要 warm-up或从文件恢复足够长的 last_bar_dt 后重算。3underlying_symbol 换月变了重启后重新读主连 quote 的 underlying_symbol更新 trade_sym 与 task 订阅。4容器自动重启太频繁先修 OOM 或断线勿让恢复逻辑在仓位未查清时高频 set。风险提示以上内容用于恢复流程参考不构成投资建议。