断开并停止
disconnect_and_stop() 用来关闭 TWSSyncWrapper 与 TWS / IB Gateway 的连接,并等待后台消息线程结束。同步封装虽然让请求看起来像普通函数调用,但底层仍然有一个 app.run() 线程在处理 TWS 返回的消息。
如果脚本退出前不主动断开,常见后果是:
- Python 进程短时间内没有正常退出。
- TWS 中还保留旧 API 客户端连接状态。
- 下次运行脚本时
clientId冲突。 - 后台线程还在处理旧回调,影响调试判断。
本地官方源码中的定义如下:
def disconnect_and_stop(self): ...这个方法的清理逻辑很简单:
- 调用
self.disconnect()关闭 socket。 - 如果存在
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=TrueCURRENT_TIME=1781421671IS_CONNECTED_AFTER_STOP=FalseIS_CONNECTED_AFTER_STOP=False 表示 API 客户端已经不再连接 TWS。
断开前要考虑什么
Section titled “断开前要考虑什么”| 状态 | 建议 |
|---|---|
| 行情订阅 | 长连接或流式订阅应先取消,例如 cancelMktData() |
| 账户订阅 | 同步方法通常会取消对应订阅,但自定义请求要自己处理 |
| 持仓订阅 | 如果使用 reqPositions(),退出前应 cancelPositions() |
| 未完成订单 | 断开 API 不等于取消订单,必须单独管理订单生命周期 |
| 未处理异常 | 不要吞掉异常,至少写日志方便排查 |
特别注意:断开 API 连接不会自动撤单。已经提交到 TWS / IBKR 后端的订单,仍可能继续工作。订单章节会单独解释提交、取消和状态恢复。
| 误区 | 正确理解 |
|---|---|
disconnect_and_stop() 会关闭 TWS | 它只断开 API socket,不关闭 TWS 客户端 |
| 断开连接会取消所有订单 | 不会,订单需要用订单接口取消 |
脚本结束就一定释放 clientId | 最好主动调用断开方法 |
join(timeout=1) 能保证所有业务状态保存 | 它只等待线程结束,不负责业务持久化 |
如果脚本频繁调试,主动断开可以减少 TWS 端残留连接和 clientId 冲突。