期货量化 wait_update 超时怎么办:天勤 TqTimeoutError 分级处理
前言
主循环里api.wait_update()偶尔抛出TqTimeoutError,有人一律重试、有人立刻平仓,都可能过度反应。我习惯把超时当成「分级事件」:偶发可退避重试,连续失败则暂停发单并核对持仓,与断线重连流程衔接但不混为一谈。
天勤TqSdk在reference/tqsdk.exceptions.rst中定义了异常类型。下面说明超时常见原因、重试与退避、和trading_enabled开关配合的写法。断线后持仓核对在另一篇有展开,此处只写超时本身。
一、超时不等于策略错了
可能原因包括:
- 网络抖动,下一帧就恢复
- 休市或品种无推送,
wait_update等待过久 - 订阅合约错误,长期无有效行情
- 服务器侧短暂繁忙
先记录日志(时间、合约、连续次数),再决定重试还是停机,不要无日志地pass。
二、分级处理表
| 级别 | 条件 | 动作 |
|---|---|---|
| L1 | 首次超时 | sleep 1~2 秒,continue |
| L2 | 连续 3~5 次 | 暂停新信号,继续wait_update |
| L3 | 连续 >5 次或伴其他异常 | 停发单,核对 position,通知人工 |
阈值按品种频率调整;Tick 策略比日线 K 线更严。
三、代码骨架
importloggingimporttimefromtqsdkimportTqApi,TqAuth,TqSimfromtqsdk.exceptionsimportTqTimeoutError log=logging.getLogger("tq")api=TqApi(TqSim(),auth=TqAuth("账户","密码"))trading_enabled=Truestreak=0whileTrue:try:api.wait_update()streak=0exceptTqTimeoutError:streak+=1log.warning("TqTimeoutError streak=%s",streak)ifstreak>=5:trading_enabled=Falselog.error("暂停发单,请核对行情与持仓")time.sleep(min(2*streak,30))continueexceptExceptionase:log.exception("wait_update: %s",e)trading_enabled=Falsetime.sleep(5)continueifnottrading_enabled:continue# 信号与下单恢复trading_enabled = True前,应人工或reconcile函数确认行情与持仓正常。
四、与行情订阅、交易时段
若超时集中在休市,应加交易时段过滤,而不是无限重试。检查quote.datetime是否推进;不推进时先查合约代码与权限。
交易类超时(若文档区分)与行情超时可分开计数,交易超时更保守,直接暂停下单。
五、不要和 close 泄漏混淆
超时后反复new TqApi而不close旧实例,会导致连接泄漏。正常应在一个 api 上重试;仅当文档建议或长期无法恢复时,才close后重建。
总结
TqTimeoutError应分级处理,不宜一律重试或一律平仓:偶发超时可在 1~2 秒退避后continue;连续 3~5 次宜置trading_enabled = False、暂停新信号但继续wait_update;更高 streak 或伴随其他异常时,停发单并核对position、挂单与行情是否在推进。每次超时都要打日志(时间、连续次数),便于与断线重连流程区分——超时可能是抖动,断线则可能需持仓核对。
休市、合约写错、长期无推送时,加交易时段与quote.datetime检查,比无限重试更有效。不要每次超时都new TqApi而不close旧实例,除非长期无法恢复。交易类超时(若与行情超时区分)应更保守。恢复自动发单前,宜人工或 reconcile 确认行情与持仓正常。
建议在模拟盘观察超时 streak 触发是否符合预期;把阈值、退避上限、是否暂停发单写进策略配置;与结构化日志、紧急停止流程一并纳入上线检查表。
FAQ
1)捕获后要不要 api.close()?
单次超时不必;进程要退出时在 finally 里 close。
2)超时能设置更长吗?
构造或文档参数以官方为准,过长会掩盖行情停滞。
3)和 KeyboardInterrupt?
单独 except,保证 close。
4)多合约都超时?
先查网络与 auth,再查是否休市。
风险提示
本文用于异常处理技术说明,不构成投资建议。
