ClientId 0 与主客户端 ID
clientId 是 API 客户端连接 TWS 时使用的编号。订单管理里很多“能不能看见订单、能不能接管订单”的问题,都和 clientId 有关。
普通程序建议使用非 0 的 clientId,例如 100、98300。clientId=0 有特殊含义,主要用于绑定 TWS 手工订单。
三种常见角色
Section titled “三种常见角色”| 角色 | 中文说明 |
|---|---|
普通 clientId | 只能自动接收自己这个客户端提交的订单状态。 |
clientId=0 | 可以配合 reqAutoOpenOrders(True) 绑定 TWS 手工订单。 |
| 主客户端 ID | 在 TWS 设置中配置,用来把其它客户端订单状态推送给指定客户端。 |
为什么不要随便用 clientId 0
Section titled “为什么不要随便用 clientId 0”clientId=0 可以和 TWS 手工订单产生绑定关系。绑定后,API 端可能收到这些订单的 openOrder()、orderStatus()、orderBound() 回调。
这对订单管理工具很有用,但对新手脚本可能很危险:你以为只是在查询,实际已经让程序接管了手工订单的可见范围。
主客户端 ID 是什么
Section titled “主客户端 ID 是什么”主客户端 ID 是 TWS / IB Gateway API 设置里的一个配置项。配置后,指定 clientId 的 API 客户端可以接收其它客户端的订单状态消息。
它常见于“订单监控中心”这类程序:一个客户端不负责下单,只负责观察多个 API 客户端提交的订单状态。
| 场景 | 说明 |
|---|---|
| 普通策略脚本 | 不需要配置主客户端 ID。 |
| 一个程序监控多个策略 | 可以考虑把这个程序的 clientId 设为主客户端 ID。 |
| 需要接管 TWS 手工订单 | 重点看 clientId=0 和 reqAutoOpenOrders(True)。 |
| 只想看自己下的单 | 不需要主客户端 ID,也不需要 clientId=0。 |
| 场景 | 建议 |
|---|---|
| 普通策略程序 | 使用固定非 0 clientId。 |
| 只查询自己提交的订单 | 用 reqOpenOrders()。 |
| 查询所有 API 订单 | 用 reqAllOpenOrders(),但仍不要绑定手工订单。 |
| 接管 TWS 手工订单 | 明确使用 clientId=0,并理解 reqAutoOpenOrders(True)。 |
app.connect("127.0.0.1", 7497, clientId=98300)这里 98300 是普通 API 客户端编号,不会主动绑定 TWS 手工订单。
和订单 ID 的关系
Section titled “和订单 ID 的关系”clientId 不是 orderId。clientId 表示“哪个 API 客户端”,orderId 表示“这张订单的编号”。
同一个订单状态里可能同时出现:
orderId=12clientId=98300permId=771998447其中 permId 是 IB 系统级永久订单编号,跨客户端和会话更稳定。
使用普通非 0 clientId=98300 查询订单管理接口时,连接成功,但没有未完成订单,也没有手工订单绑定记录:
CONNECTED=TrueOPEN_ORDERS_END=TrueALL_OPEN_ORDERS_END=TrueOPEN_ORDER_ROWS=0ORDER_STATUS_ROWS=0ORDER_BOUND_ROWS=0NON_INFO_ERROR_COUNT=0这说明普通 clientId 能正常连接并查询订单状态;没有返回订单行,只代表查询时账户里没有该客户端可见的未完成订单。
新手判断顺序
Section titled “新手判断顺序”排查“为什么看不到订单”时,按这个顺序更清楚:
| 问题 | 应看什么 |
|---|---|
| 这张单是不是 API 程序自己提交的 | 如果是,用提交时的 clientId 连接并调用 reqOpenOrders()。 |
| 是否想看其它 API 客户端的订单 | 需要理解 reqAllOpenOrders() 或主客户端 ID。 |
| 是否想接管 TWS 手工订单 | 需要 clientId=0 和 reqAutoOpenOrders(True)。 |
| 是否只是想查历史成交 | 不看 open order,应该用 reqExecutions()。 |