跳转到内容

请求白标用户信息

reqUserInfo() 用来请求登录用户关联的白标信息。

app.reqUserInfo(reqId)

这个接口只有一个参数 reqId。它不需要传账户号,也不需要传合约、模型代码或订阅参数。

def reqUserInfo(self, reqId: int):
...
参数中文含义说明
reqId请求编号自己分配,用来匹配 userInfo() 回调

reqId 只是本次请求的编号,不是账户号、订单号或会话号。建议每类请求使用不同编号,方便日志里区分来源。

请求成功后,TWS 会通过 userInfo(reqId, whiteBrandingId) 返回结果。普通个人账户可能返回空字符串;如果用户名没有关联白标实体,也可能在超时时间内没有收到回调。

检查项原因
TWS 或 IB Gateway 已登录接口读取登录用户的信息
API Socket 已启用程序需要连接本地 API 端口
已收到 nextValidId()说明基础连接已建立
TWS / API 版本足够新老版本不支持 user info 请求
import threading
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
INFO_CODES = {2103, 2104, 2105, 2106, 2107, 2108, 2158}
class RequestUserInfoApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
self.ready = threading.Event()
self.user_info_ready = threading.Event()
self.rows = []
self.info_codes = []
self.errors_seen = []
def nextValidId(self, orderId):
self.ready.set()
def userInfo(self, reqId, whiteBrandingId):
self.rows.append({
"reqId": reqId,
"whiteBrandingId_empty": whiteBrandingId == "",
"whiteBrandingId_length": len(whiteBrandingId or ""),
})
self.user_info_ready.set()
def error(self, reqId, errorTime, errorCode, errorString, advancedOrderRejectJson=""):
if errorCode in INFO_CODES:
self.info_codes.append(errorCode)
else:
self.errors_seen.append((reqId, errorCode, errorString))
app = RequestUserInfoApp()
req_id = 9401
try:
app.connect("127.0.0.1", 7497, clientId=126)
thread = threading.Thread(target=app.run, daemon=True)
thread.start()
if not app.ready.wait(8):
raise RuntimeError("等待 nextValidId 超时")
app.reqUserInfo(req_id)
callback_received = app.user_info_ready.wait(8)
finally:
if app.isConnected():
app.disconnect()
print(f"REQUEST_SENT=True")
print(f"USER_INFO_CALLBACK_RECEIVED={callback_received}")
print(f"USER_INFO_ROW_COUNT={len(app.rows)}")
print("ROWS=" + (str(app.rows) if app.rows else "EMPTY"))
if app.rows:
print(f"WHITE_BRANDING_ID_EMPTY={app.rows[0]['whiteBrandingId_empty']}")
print(f"WHITE_BRANDING_ID_LENGTH={app.rows[0]['whiteBrandingId_length']}")
else:
print("WHITE_BRANDING_ID_EMPTY=UNKNOWN")
print("WHITE_BRANDING_ID_LENGTH=UNKNOWN")
print("INFO_CODES=" + (",".join(map(str, sorted(set(app.info_codes)))) if app.info_codes else "NONE"))
print(f"NON_INFO_ERROR_COUNT={len(app.errors_seen)}")
print(f"IS_CONNECTED_AFTER_DISCONNECT={app.isConnected()}")
CONNECTED=True
REQUEST_SENT=True
USER_INFO_CALLBACK_RECEIVED=True
USER_INFO_ROW_COUNT=1
ROWS=[{'reqId': 9401, 'whiteBrandingId_empty': True, 'whiteBrandingId_length': 0}]
WHITE_BRANDING_ID_EMPTY=True
WHITE_BRANDING_ID_LENGTH=0
INFO_CODES=2104,2106,2158
NON_INFO_ERROR_COUNT=0
IS_CONNECTED_AFTER_DISCONNECT=False

TWS 模拟账户收到回调,但 whiteBrandingId 为空。这个结果并不表示请求失败,只表示用户没有可返回的白标 ID。

不需要。reqUserInfo() 查询的是登录用户的白标信息,不是某个账户的资产或持仓。

这个接口能查用户名或邮箱吗?

Section titled “这个接口能查用户名或邮箱吗?”

不能。它只返回 whiteBrandingId

不需要。它不是持续订阅接口,官方 Python API 中也没有对应的 cancelUserInfo()

先看是否有非信息类错误。如果没有错误,且连接握手正常,通常可以按“用户没有可返回的白标信息”处理。这个接口不适合作为判断 TWS 连接是否健康的唯一依据。

IBKR Campus: TWS API Documentation