跳转到内容

在 TWS 中接受 API 连接

当一个 API 程序第一次连接 TWS 时,TWS 可能会弹出确认窗口,要求用户明确接受这个连接。这个窗口不是每次都会出现:如果你已经允许过同一台电脑的连接,或者 TWS 已经记住可信来源,之后连接可能直接通过。

所以不要把“有没有弹窗”当作唯一判断标准。更可靠的连接链路是:

Socket 打开 -> TWS 接受 API 客户端 -> 收到 nextValidId -> 可以发送业务请求

connect() 只代表程序尝试打开 socket。真正适合开始发请求的信号,是 TWS 返回 nextValidId()。如果首次连接确认没有通过,程序端经常表现为一直等不到 nextValidId()

如果 TWS 弹出 API 连接确认窗口,先核对这些信息:

项目说明
来源地址同一台电脑运行时通常应为 127.0.0.1 或电脑名。
Socket 端口应与 TWS API 设置里的 Socket port 一致。
账户模式模拟账户通常用 7497,真实账户通常用 7496,以界面显示为准。
是否可信只接受自己正在运行的脚本,不接受陌生来源。

如果程序和 TWS 在同一台电脑,常见来源是:

127.0.0.1

如果程序在另一台机器,来源可能是局域网 IP,例如:

192.168.1.31

远程连接要更谨慎,必须配合可信 IP、防火墙、端口访问控制和日志记录。

没有看到确认窗口,常见原因有三种:

情况说明
已经允许过同一台电脑的连接TWS 可能记住了之前的选择。
连接来源是同一台电脑且设置允许只允许本地连接时,同一台电脑上的脚本可能直接通过。
弹窗被其他窗口挡住程序一直等不到 nextValidId() 时,要切回 TWS 检查。

因此验证连接时,应以程序输出和回调为准:

信号含义
nextValidId(orderId)初始握手完成,可以开始发送请求。
currentTime(time_)简单请求已经成功返回。
error() 中的连接通知TWS API 可能把通知和警告也放在 error 回调里。

不要把 connect() 当作连接完成。建议用 threading.Event 等待 nextValidId()

import threading
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
class App(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
self.connected_event = threading.Event()
def nextValidId(self, orderId: int):
print(f"连接已被 TWS 接受,下一个可用订单 ID: {orderId}")
self.connected_event.set()
def error(self, reqId, errorCode, errorString, advancedOrderRejectJson=""):
print(f"API message: reqId={reqId}, code={errorCode}, message={errorString}")
app = App()
app.connect("127.0.0.1", 7497, clientId=31)
thread = threading.Thread(target=app.run, daemon=True)
thread.start()
if not app.connected_event.wait(10):
app.disconnect()
raise TimeoutError("TWS 尚未接受 API 连接,或没有返回 nextValidId")
设置影响
Enable ActiveX and Socket Clients 未勾选TWS 不接受 API Socket 连接。
Read-Only API 勾选连接可以建立,但下单、改单等请求会受限。
Allow connections from localhost only 勾选只接受本地连接,远程机器会被挡住。
Trusted IPs 未包含远程程序 IP远程程序可能无法被接受。
Socket 端口写错程序连不到正确的 TWS API 端口。
现象常见原因处理方式
程序一直等待 nextValidId()TWS 弹窗未确认,或弹窗被挡住切到 TWS 界面检查确认窗口。
没有弹窗但连接成功之前已经允许过同一台电脑的连接nextValidId()currentTime() 为准。
连接后马上断开clientId 冲突、TWS 重启或网络中断换独立 clientId,检查日志。

第一次调试时,只做 reqCurrentTime() 这类安全请求。等连接确认逻辑稳定后,再进入行情、账户和订单接口。

IBKR Campus: TWS API Documentation