跳转到内容

在 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