连接并启动
connect_and_start() 是 TWSSyncWrapper 的连接入口。它把普通 TWS API 里常见的三步合并成一个方法:
connect() -> 启动 app.run() 消息线程 -> 等待 nextValidId()只有这三步都完成后,同步方法才有机会正常等待返回值。否则 get_current_time()、get_contract_details() 等方法会发出请求,但没有消息线程处理 TWS 返回的回调。
官方 Python API 包中的定义如下:
def connect_and_start(self, host, port, client_id): ...参数含义:
| 参数 | 含义 | 常见值 |
|---|---|---|
host | TWS / IB Gateway 所在地址 | 同一台电脑运行时用 127.0.0.1 |
port | API Socket 端口 | TWS 模拟账户常见 7497 |
client_id | API 客户端编号 | 每个脚本使用独立编号 |
端口不要写死。最终以 TWS / IB Gateway 的 API -> Settings -> Socket Port 为准。
最小连接示例
Section titled “最小连接示例”from ibapi.sync_wrapper import TWSSyncWrapper
app = TWSSyncWrapper(timeout=5)
try: connected = app.connect_and_start("127.0.0.1", 7497, 941) if not connected: raise RuntimeError("TWS API 连接未完成")
print(f"NEXT_VALID_ID={app.next_valid_id_value}")
finally: app.disconnect_and_stop()这段代码只验证连接和 nextValidId(),不请求行情、不读账户、不下单。它适合用来确认同步封装是否能正常启动。
使用 TWS 模拟账户、127.0.0.1:7497、clientId=941 检查连接时,常见输出类似:
CONNECTED=TrueNEXT_VALID_ID=1IS_CONNECTED_AFTER_STOP=False看到 CONNECTED=True,说明:
- TWS / IB Gateway 已接受 socket 连接。
TWSSyncWrapper已启动后台消息线程。- 初始握手已收到
nextValidId()。 - 其他同步方法可以在这个连接上发起请求。
connect_and_start 做了什么
Section titled “connect_and_start 做了什么”从官方源码看,它的核心逻辑是:
- 调用
self.connect(host, port, client_id)。 - 最多等待约 5 秒,看
isConnected()是否为真。 - 创建后台线程执行
self.run()。 - 最多等待约 5 秒,看
next_valid_id_value是否已经返回。 - 返回连接状态。
这里有一个细节:connect_and_start() 等待的是连接和 nextValidId(),不是等待所有业务数据都准备好。账户、行情、合约、历史 K 线等请求仍然要在各自同步方法中单独等待。
常见失败原因
Section titled “常见失败原因”| 现象 | 常见原因 | 处理方式 |
|---|---|---|
返回 False | TWS 未启动、API 未启用、端口不对 | 回到连接设置检查 |
| 卡住后超时 | TWS 弹出 API 连接确认但未接受 | 切到 TWS 接受连接 |
报 502 | 客户端无法连接 TWS 端口 | 检查 TWS 是否正在监听该端口 |
报 326 | clientId 已被使用 | 换一个独立 clientId |
| 其他同步方法超时 | 没有真正收到回调,或请求本身没有返回 | 先用 get_current_time() 做最小请求 |
调试顺序建议是:先让 connect_and_start() 成功,再测试 get_current_time(),最后再进入合约、行情、账户和订单接口。
不要重复启动同一个对象
Section titled “不要重复启动同一个对象”不要对同一个 TWSSyncWrapper 实例反复调用 connect_and_start()。如果连接断开,建议:
- 调用
disconnect_and_stop()。 - 创建新的
TWSSyncWrapper实例。 - 使用新的
client_id或确认旧连接已释放。 - 再次连接并恢复业务状态。
这样更容易避免旧线程、旧事件和旧响应数据影响新连接。