请求白标用户信息
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 请求 |
Python 请求示例
Section titled “Python 请求示例”import threading
from ibapi.client import EClientfrom 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=TrueREQUEST_SENT=TrueUSER_INFO_CALLBACK_RECEIVED=TrueUSER_INFO_ROW_COUNT=1ROWS=[{'reqId': 9401, 'whiteBrandingId_empty': True, 'whiteBrandingId_length': 0}]WHITE_BRANDING_ID_EMPTY=TrueWHITE_BRANDING_ID_LENGTH=0INFO_CODES=2104,2106,2158NON_INFO_ERROR_COUNT=0IS_CONNECTED_AFTER_DISCONNECT=FalseTWS 模拟账户收到回调,但 whiteBrandingId 为空。这个结果并不表示请求失败,只表示用户没有可返回的白标 ID。
需要传账户号吗?
Section titled “需要传账户号吗?”不需要。reqUserInfo() 查询的是登录用户的白标信息,不是某个账户的资产或持仓。
这个接口能查用户名或邮箱吗?
Section titled “这个接口能查用户名或邮箱吗?”不能。它只返回 whiteBrandingId。
需要取消请求吗?
Section titled “需要取消请求吗?”不需要。它不是持续订阅接口,官方 Python API 中也没有对应的 cancelUserInfo()。
超时没有回调怎么办?
Section titled “超时没有回调怎么办?”先看是否有非信息类错误。如果没有错误,且连接握手正常,通常可以按“用户没有可返回的白标信息”处理。这个接口不适合作为判断 TWS 连接是否健康的唯一依据。