跳转到内容

断开并停止

disconnect_and_stop() 用来关闭 TWSSyncWrapper 与 TWS / IB Gateway 的连接,并等待后台消息线程结束。同步封装虽然让请求看起来像普通函数调用,但底层仍然有一个 app.run() 线程在处理 TWS 返回的消息。

如果脚本退出前不主动断开,常见后果是:

  • Python 进程短时间内没有正常退出。
  • TWS 中还保留旧 API 客户端连接状态。
  • 下次运行脚本时 clientId 冲突。
  • 后台线程还在处理旧回调,影响调试判断。

本地官方源码中的定义如下:

def disconnect_and_stop(self):
...

这个方法的清理逻辑很简单:

  1. 调用 self.disconnect() 关闭 socket。
  2. 如果存在 api_thread 并且仍然存活,就 join(timeout=1) 等待线程结束。

它不会自动清空你的业务缓存,也不会保存订单状态。订单、持仓、行情订阅这些状态需要你的程序自己管理。

用同步封装时,建议把连接放进 try/finally

from ibapi.sync_wrapper import TWSSyncWrapper
app = TWSSyncWrapper(timeout=5)
try:
connected = app.connect_and_start("127.0.0.1", 7497, 942)
print(f"CONNECTED={connected}")
if not connected:
raise RuntimeError("连接 TWS API 失败")
server_time = app.get_current_time(timeout=5)
print(f"CURRENT_TIME={server_time}")
finally:
app.disconnect_and_stop()
print(f"IS_CONNECTED_AFTER_STOP={app.isConnected()}")

无论中间请求成功、超时还是抛异常,finally 都会执行断开逻辑。

使用 TWS 模拟账户检查断开流程时,断开后连接状态应为 False

CONNECTED=True
CURRENT_TIME=1781421671
IS_CONNECTED_AFTER_STOP=False

IS_CONNECTED_AFTER_STOP=False 表示 API 客户端已经不再连接 TWS。

状态建议
行情订阅长连接或流式订阅应先取消,例如 cancelMktData()
账户订阅同步方法通常会取消对应订阅,但自定义请求要自己处理
持仓订阅如果使用 reqPositions(),退出前应 cancelPositions()
未完成订单断开 API 不等于取消订单,必须单独管理订单生命周期
未处理异常不要吞掉异常,至少写日志方便排查

特别注意:断开 API 连接不会自动撤单。已经提交到 TWS / IBKR 后端的订单,仍可能继续工作。订单章节会单独解释提交、取消和状态恢复。

误区正确理解
disconnect_and_stop() 会关闭 TWS它只断开 API socket,不关闭 TWS 客户端
断开连接会取消所有订单不会,订单需要用订单接口取消
脚本结束就一定释放 clientId最好主动调用断开方法
join(timeout=1) 能保证所有业务状态保存它只等待线程结束,不负责业务持久化

如果脚本频繁调试,主动断开可以减少 TWS 端残留连接和 clientId 冲突。

IBKR Campus: TWS API Documentation