在 TWS 中接受 API 连接
当一个 API 程序第一次连接 TWS 时,TWS 可能会弹出确认窗口,要求用户明确接受这个连接。这个窗口不是每次都会出现:如果你已经允许过同一台电脑的连接,或者 TWS 已经记住可信来源,之后连接可能直接通过。
所以不要把“有没有弹窗”当作唯一判断标准。更可靠的连接链路是:
Socket 打开 -> TWS 接受 API 客户端 -> 收到 nextValidId -> 可以发送业务请求connect() 只代表程序尝试打开 socket。真正适合开始发请求的信号,是 TWS 返回 nextValidId()。如果首次连接确认没有通过,程序端经常表现为一直等不到 nextValidId()。
首次连接要核对什么
Section titled “首次连接要核对什么”如果 TWS 弹出 API 连接确认窗口,先核对这些信息:
| 项目 | 说明 |
|---|---|
| 来源地址 | 同一台电脑运行时通常应为 127.0.0.1 或电脑名。 |
| Socket 端口 | 应与 TWS API 设置里的 Socket port 一致。 |
| 账户模式 | 模拟账户通常用 7497,真实账户通常用 7496,以界面显示为准。 |
| 是否可信 | 只接受自己正在运行的脚本,不接受陌生来源。 |
如果程序和 TWS 在同一台电脑,常见来源是:
127.0.0.1如果程序在另一台机器,来源可能是局域网 IP,例如:
192.168.1.31远程连接要更谨慎,必须配合可信 IP、防火墙、端口访问控制和日志记录。
没有弹窗也可能正常
Section titled “没有弹窗也可能正常”没有看到确认窗口,常见原因有三种:
| 情况 | 说明 |
|---|---|
| 已经允许过同一台电脑的连接 | TWS 可能记住了之前的选择。 |
| 连接来源是同一台电脑且设置允许 | 只允许本地连接时,同一台电脑上的脚本可能直接通过。 |
| 弹窗被其他窗口挡住 | 程序一直等不到 nextValidId() 时,要切回 TWS 检查。 |
因此验证连接时,应以程序输出和回调为准:
| 信号 | 含义 |
|---|---|
nextValidId(orderId) | 初始握手完成,可以开始发送请求。 |
currentTime(time_) | 简单请求已经成功返回。 |
error() 中的连接通知 | TWS API 可能把通知和警告也放在 error 回调里。 |
最小等待方式
Section titled “最小等待方式”不要把 connect() 当作连接完成。建议用 threading.Event 等待 nextValidId():
import threading
from ibapi.client import EClientfrom 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")和 API 设置的关系
Section titled “和 API 设置的关系”| 设置 | 影响 |
|---|---|
Enable ActiveX and Socket Clients 未勾选 | TWS 不接受 API Socket 连接。 |
Read-Only API 勾选 | 连接可以建立,但下单、改单等请求会受限。 |
Allow connections from localhost only 勾选 | 只接受本地连接,远程机器会被挡住。 |
Trusted IPs 未包含远程程序 IP | 远程程序可能无法被接受。 |
| Socket 端口写错 | 程序连不到正确的 TWS API 端口。 |
常见卡住现象
Section titled “常见卡住现象”| 现象 | 常见原因 | 处理方式 |
|---|---|---|
程序一直等待 nextValidId() | TWS 弹窗未确认,或弹窗被挡住 | 切到 TWS 界面检查确认窗口。 |
| 没有弹窗但连接成功 | 之前已经允许过同一台电脑的连接 | 以 nextValidId() 和 currentTime() 为准。 |
| 连接后马上断开 | clientId 冲突、TWS 重启或网络中断 | 换独立 clientId,检查日志。 |
第一次调试时,只做 reqCurrentTime() 这类安全请求。等连接确认逻辑稳定后,再进入行情、账户和订单接口。