跳转到内容

TWS API 文档介绍

TWS API 是 Interactive Brokers 提供给开发者连接 Trader Workstation(TWS) 或 IB Gateway 的本地 Socket API。它不是直接访问云端的 REST 接口,而是让你的程序先连到已经登录的 TWS / IB Gateway,再由 TWS / IB Gateway 代表你的账户和 IBKR 后端通信。

官方入口:IBKR Campus - TWS API Documentation

旧版官方文档已经标注为 deprecated,但里面对 EClient、EWrapper、连接流程和示例项目的解释仍然有参考价值。本站会以新版目录为准,同时结合旧版说明、Python 实测结果和中文开发者常见问题重新整理。

TWS API 适合把交易、行情和账户数据接入自己的程序,例如:

  • 查询账户摘要、持仓、盈亏和成交。
  • 查询合约详情,确认股票、期权、期货、外汇等金融工具的唯一标识。
  • 请求实时行情、延迟行情、历史 K 线和逐笔数据。
  • 在模拟账户或真实账户中提交、修改、取消订单。
  • 接收订单状态、成交回报、佣金费用和错误消息。

TWS API 最大的难点不是“怎么发一个请求”,而是要理解它的 请求 / 回调模型:程序通过 EClient 发请求,再由 EWrapper 中的回调函数接收结果。后面的示例都会围绕这个模型展开。

你的 Python / Java / C++ / C# 程序
↓ 发送请求:EClient
TWS / IB Gateway
↑ 接收回调:EWrapper

例如请求历史 K 线时,程序调用的是 reqHistoricalData(),但结果不是这个函数直接返回,而是从 historicalData()、historicalDataEnd() 等回调里陆续回来。下单也是一样,placeOrder() 只是发出订单,真正的订单状态要看 openOrder()、orderStatus()、execDetails() 和 error()。

概念中文解释新手要记住什么
EClient请求发送端调用 reqMktData()、reqHistoricalData()、placeOrder() 等方法。
EWrapper回调接收端实现 tickPrice()、historicalData()、orderStatus() 等回调来接结果。
EReader消息读取线程负责从 Socket 读取 TWS 返回的消息,并触发对应回调。Python 里通常由 API 包自动处理读取线程,但仍然需要调用 app.run() 处理消息队列。
clientId客户端编号同一个 TWS 可以接多个 API 客户端,clientId 用来区分它们。不要让两个程序随便共用同一个编号。
nextValidId下一个可用订单 ID也是常用的“连接已经准备好”信号。收到它以后再发请求更稳。
reqId请求编号行情、合约、历史数据等请求常用它把请求和回调配对。

使用 TWS API 前,需要先满足这些条件:

项目说明
TWS 或 IB Gateway必须至少运行一个,并且已经登录账户。
API 设置需要在 TWS / IB Gateway 中启用 Socket API,并确认端口。
账户环境新手和调试阶段建议使用 Paper Account(模拟账户)。
本地网络默认连接 127.0.0.1,远程连接需要额外设置可信 IP 和安全边界。
API 包Python、Java、C++、C# 等语言需要安装对应 TWS API 包。Python 用户通常需要安装官方 ibapi 包。
行情权限模拟账户可以下模拟单,但不代表一定有全部实时行情、逐笔数据或新闻权限。

这些前提应分开排查:下载、安装、TWS 设置、连接测试、行情权限和订单风控不要混在一起看。

常见端口如下:

运行环境默认端口说明
TWS 模拟账户7497本地开发最常见。
TWS 实盘账户7496真实交易环境,必须额外加风控。
IB Gateway 模拟账户4002更适合服务器常驻。
IB Gateway 实盘账户4001常见服务器实盘端口,风险最高。

如果你是第一次做 IBKR 自动化交易,建议按这个顺序读:

  1. 先读本页和 注意事项与限制,知道 TWS API 能做什么、不能做什么。
  2. 再读 下载 TWS 或 IB Gateway、下载 TWS API 和 TWS 设置,把本机模拟账户环境准备好。
  3. 接着读 连接机制,理解 connect()、nextValidId、EReader 和断线处理。
  4. 然后读 合约 / 金融工具,先学会构造正确的 Contract。
  5. 最后进入 市场数据、账户与投资组合数据、订单 和 订单管理。

这个顺序能避免一个常见错误:还没有搞清楚合约、端口、权限和回调,就直接复制下单代码。

本文档会尽量提供 Python 示例,因为 Python 对新手更友好,也更适合快速验证 TWS API 的请求和回调。但示例必须遵守一个规则:

可复制示例优先使用已经在本机 TWS / IB Gateway 模拟账户环境验证过的 Python 代码。

如果某个接口受行情订阅、账户权限、地区限制或产品权限影响,页面会写清楚可能出现的真实错误码和处理方向。例如逐笔数据、市场深度、新闻和部分期权数据,经常不是“代码错了”,而是账户权限或数据源限制。

示例代码会尽量遵守这些约定:

约定说明
API 名保持英文reqHistoricalData、Contract、Order 等不翻译,避免和官方资料脱节。
注释使用中文让中文读者知道每一步为什么这样写。
参数表尽量完整不只解释最小示例里的参数,也解释常见可选参数和默认写法。
输出写真实形态能实测的写真实输出;受权限影响的写真实错误和原因。
不跳过回调请求函数和回调函数成对解释,避免只会发请求不会收结果。

下面这段代码展示的是 TWS API 最基础的结构:继承 EWrapper 接收回调,继承 EClient 发送请求,连接本机模拟账户端口 7497,收到 nextValidId 后请求服务器时间。

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
class DemoApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
def nextValidId(self, orderId: int):
# 收到 nextValidId 通常表示连接握手已经完成,可以开始发送请求。
print("下一个可用订单 ID:", orderId)
self.reqCurrentTime()
def currentTime(self, time_: int):
# 服务器时间是 Unix 时间戳。收到这个回调,说明请求和回调链路已经通了。
print("服务器时间:", time_)
self.disconnect()
app = DemoApp()
app.connect("127.0.0.1", 7497, clientId=901)
app.run()

这段代码里最重要的不是 reqCurrentTime() 本身,而是整个消息流程:

connect()
-> TWS 接受连接
-> nextValidId()
-> reqCurrentTime()
-> currentTime()
-> disconnect()

如果连接失败,优先检查 TWS 是否已登录、API 是否启用、端口是否正确、是否允许本机连接。

本站有两个不同层次的 TWS API 内容:

内容用途
TWS API Documentation 主线按实际开发流程解释:设置、连接、账户、合约、行情、订单。
TWS API Reference 类参考按类和字段查资料,例如 Contract、Order、Bar、EWrapper。

写程序时通常先看主线教程,遇到字段不理解时再查类参考。这样既能知道“该调用哪个接口”,也能知道“字段为什么要这样填”。

本站也包含 Client Portal Gateway、Client Portal Web API、WebSocket 和 Flex Web Service 相关页面。它们和 TWS API 不要混用:

类型通信方式典型写法
TWS APITCP Socket + 回调app.connect()、reqMktData()、EWrapper.tickPrice()
Client Portal Web APIHTTP / WebSocketGET /iserver/accounts、POST /iserver/auth/status
Flex Web ServiceHTTP 报表下载生成报表、轮询报表、下载 XML/CSV

如果示例里出现 EClient、EWrapper、Contract、Order,通常是在讲 TWS API。如果示例里出现 URL endpoint、curl、requests.get() 或 WebSocket topic,通常是在讲 Client Portal / Web API。