TWS API 连接超时
TWS API 连接超时,通常表现为:TWS 已经登录,端口看起来也开着,但程序一直收不到 nextValidId(),或者连接后没有任何回调。
这类问题要分清两层:
- TCP 端口能连上,只代表本机能访问这个端口。
- 收到
nextValidId(),才说明 TWS API 初始握手基本完成。
如果没有收到 nextValidId(),不要继续发送合约、行情或订单请求,先把连接链路排清楚。
| 现象 | 更可能的问题 |
|---|---|
Connection refused | TWS / IB Gateway 没启动,端口没监听,或端口填错。 |
端口已打开但没有 nextValidId() | API 设置、首次连接确认、客户端 ID、Python API 版本或消息循环问题。 |
收到 nextValidId() 但没有 currentTime() | 消息循环、请求发送时机或程序提前断开。 |
连接后只收到 2104/2106/2158 | 这些通常是连接状态信息,不代表错误。 |
行情请求返回 10089 | 连接已通,但账户缺少对应行情订阅或权限。 |
先检查 TWS 设置
Section titled “先检查 TWS 设置”在 TWS 中打开:
配置 -> API -> 设置重点确认:
| 设置项 | 常见建议 |
|---|---|
| 启用 ActiveX 和套接字客户端 | 必须勾选,否则 Socket API 不可用。 |
| 只读 API | 学习行情和账户查询可以勾选;模拟账户下单测试前需要取消勾选。 |
| 套接字端口 | TWS 模拟账户常见 7497,TWS 真实账户常见 7496。 |
| 仅允许从本地主机连接 | 本机开发建议保持勾选。 |
| 可信的 IP | 远程连接才需要谨慎配置,本机 127.0.0.1 通常不需要额外添加。 |
修改设置后点击 应用 和 确定。如果端口仍不生效,重启 TWS 再测试。
再检查 Python API 版本
Section titled “再检查 Python API 版本”连接超时有时不是 TWS 设置问题,而是 Python API 包太旧或装错环境。
用运行脚本的同一个 Python 查看:
python -c "import sys, ibapi; from ibapi import get_version_string; print(sys.executable); print(ibapi.__file__); print(get_version_string())"如果你使用虚拟环境,就调用虚拟环境里的 Python:
".venv\Scripts\python.exe" -c "import sys, ibapi; from ibapi import get_version_string; print(sys.executable); print(ibapi.__file__); print(get_version_string())"判断重点:
| 输出 | 怎么看 |
|---|---|
sys.executable | 是否是你真正运行脚本的 Python。 |
ibapi.__file__ | 是否来自这个 Python 的 site-packages。 |
get_version_string() | 是否接近你下载的官方 TWS API 包版本。 |
不建议优先使用 PyPI 上很旧的 ibapi 包。更稳妥的方式是从官方 TWS API 包里的 source/pythonclient 安装:
set "API_ROOT=C:\TWS API"cd /d "%API_ROOT%\source\pythonclient"python -m pip install .把 C:\TWS API 改成自己的实际 API 包目录。
检查消息循环
Section titled “检查消息循环”Python TWS API 必须持续运行消息循环,否则 TWS 返回的回调不会被处理。最小结构通常是:
app.connect("127.0.0.1", 7497, clientId=101)
thread = threading.Thread(target=app.run, daemon=True)thread.start()常见错误:
| 错误写法 | 结果 |
|---|---|
只调用 connect(),没有启动 app.run() | 程序连上后收不到回调。 |
启动线程后立刻 disconnect() | 回调还没来得及进入程序。 |
没有等待 nextValidId() | 后续请求可能发送得太早。 |
多个程序使用同一个 clientId | 订单和状态回调可能混乱。 |
最小验证顺序
Section titled “最小验证顺序”建议按这个顺序排查:
- 确认 TWS 或 IB Gateway 已登录。
- 确认 API Socket 已启用。
- 确认端口与当前环境一致。
- 确认 Python 能导入官方
ibapi。 - 启动消息循环。
- 等待
nextValidId()。 - 再请求
currentTime()。 - 最后再测试合约、行情、账户或订单。
成功输出长什么样
Section titled “成功输出长什么样”最小连接脚本成功时,通常能看到类似输出:
CONNECTED=TrueNEXT_VALID_ID=1SERVER_TIME=1781289125NON_INFO_ERROR_COUNT=0NEXT_VALID_ID 和 SERVER_TIME 的具体数字每个账户、每次运行都可能不同。关键是:程序收到回调,而不是固定数字一致。
| 错误码或消息 | 含义 |
|---|---|
502 Couldn't connect to TWS | TWS / IB Gateway 没启动、端口不对或网络不可达。 |
504 Not connected | 程序还没有建立 API 连接就发送请求。 |
2104 | 市场数据场连接正常,通常是状态信息。 |
2106 | 历史市场数据场连接正常,通常是状态信息。 |
2158 | Sec-def 数据场连接正常,通常是状态信息。 |
10089 | 请求的行情需要额外订阅或权限。 |
连接超时和行情权限不是一类问题。
- 没有
nextValidId():先查连接、端口、API 设置、Python 包和消息循环。 - 已经收到
nextValidId(),但行情失败:再查行情权限、合约、marketDataType和订阅。 - 已经能请求行情,但订单失败:再查只读模式、订单预防设置、交易权限和订单参数。
把这三层分开,能避免在同一个问题上反复试错。
- IBKR TWS API Documentation:官方连接流程要求 API 客户端连接 TWS / IB Gateway 后处理初始握手和回调;
nextValidId()是常用的连接就绪信号。