前言
个人做国内期货量化时,常把天勤策略先跑在办公笔记本上:Python 进程里TqApi连上行情,主循环wait_update()推进,螺纹钢 5 分钟均线信号触发后TargetPosTask调仓。合盖午休后唤醒,任务管理器里进程还在,屏幕也没报错,但可能半小时没有新成交、本地记的目标仓和get_position().pos对不上,甚至重连后重复发单。
原因是休眠挂起网卡,天勤与行情服务器的连接已断,而 Python 进程未必退出;若不检测断连、不close重建TqApi、不按 account-position-order 全量对账,这种故障比进程直接崩溃更隐蔽。下面给笔记本场景下的检测、重连与对账流程,核心看quote.datetime是否还在走。
一、休眠后常见异常表现
| 现象 | 可能原因 |
|---|---|
quote.datetime长时间不变 | 行情断流 |
wait_update(deadline)频繁超时 | 链路半死不活 |
| 委托 status 卡在 ALIVE | 断线期间单在交易所,本地未更新 |
| 重复开仓 | 本地 target 与柜台 pos 脱节 |
二、断连检测怎么做
交易时段内监控:
importtime last_seen={}defmark_quote(api,symbol):q=api.get_quote(symbol)ifapi.is_changing(q,"datetime"):last_seen[symbol]=time.time()defcheck_stale(symbols,threshold_sec=300):now=time.time()stale=[sforsinsymbolsifnow-last_seen.get(s,0)>threshold_sec]returnstale配合quote.trading_time或自有交易日历,休市时段不报 stale。也可用wait_update(deadline=time.time()+60)返回 False 作为心跳超时信号。
三、重连流程
天勤没有单独的 reconnect 按钮,标准做法是:
- 记录断连原因与时间到日志。
api.close()关闭当前实例。- 重新构造
TqApi(...),重建TargetPosTask(参数须与之前一致或故意升级版本)。 - 先
wait_update()收齐账户、持仓、委托。 - 全量对账:account → position → order,再
set_target_volume对齐真实世界。
切忌不 close 就再TqApi()叠第二个连接,内存与回报会乱。
四、唤醒后的对账顺序
与断线重连专题一致:
get_account()看权益是否跳变。- 各品种
get_position().pos。 get_order()清理认知外的 ALIVE 单(是否撤单由策略决定)。- 用柜台 pos 重置本地 target,再交给 task。
五、工程习惯
- 笔记本策略尽量用
TqSim/TqKq或小额实盘,并设系统「合盖不休眠」若必须无人值守。 - 生产环境用服务器 + systemd 守护,笔记本只作开发。
- 外部 watchdog:进程在但 stale 超阈值则 kill 重启整个 Python。
六、外层重启壳子示意
whileTrue:api=Nonetry:api=TqApi(...)task=TargetPosTask(api,SYMBOL)run_strategy(api,task)exceptExceptionase:log("fatal",e)finally:ifapi:api.close()time.sleep(5)# 仅在外层重启间隔,不在 wait 循环内内层策略循环里仍禁止 sleep。
七、唤醒后首分钟别急着加仓
重连后对账完成前,设reconcile_grace=True,忽略 K 线开仓信号,只允许减仓。防止本地 target 旧值导致重复加仓。
八、与 TqNotify 配合
若订阅TqNotify,断线类通知在唤醒后可能批量涌出,应对disconnect类 key 做 5 分钟限频,避免钉钉刷屏。
总结
笔记本休眠导致的不是策略公式失效,而是天勤连接静默断开而进程仍在空转。用quote.datetime或wait_update超时做交易时段内的心跳,触发 close、重建TqApi、按 account-position-order 全量对账,再恢复TargetPosTask,才能把合盖唤醒后的隐患压下去。个人研发若必须本地跑,关闭合盖休眠或改用服务器,比事后补救更省事。
FAQ
1)能否自动 api.close 后无缝续跑?
可以写在外层 while 里,但 task 必须重建,state 要从柜台拉。
2)休眠时挂单会怎样?
交易所仍有效,唤醒后对账以get_order为准。
3)TqTimeoutError 和 deadline False 区别?
前者多来自等数据接口异常阻塞,后者是正常超时返回;处理层级不同。
4)Wi-Fi 切换算断连吗?
算,检测逻辑相同。
本文基于天勤 TqSdk 公开 API 整理,不构成投资建议。