跳转到内容

接收管理账户

managedAccounts()reqManagedAccts() 的返回回调。它接收一个逗号分隔的账户字符串:

def managedAccounts(self, accountsList):
...

accountsList 里是这个 TWS 会话可见的真实账户号。公开输出前必须脱敏。

字段中文含义说明
accountsList账户列表字符串多个账户用逗号分隔

解析方式:

accounts = [item for item in accountsList.split(",") if item]

if item 过滤空字符串,可以避免某些环境下尾部逗号造成空账户项。

下面示例会保存真实账户列表,但输出时只显示脱敏别名。

import threading
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
INFO_CODES = {2100, 2104, 2106, 2158}
class ReceiveManagedAccountsApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
self.ready = threading.Event()
self.managed_ready = threading.Event()
self.accounts_list_raw = ""
self.accounts = []
self.info_codes = []
self.errors_seen = []
def nextValidId(self, orderId):
self.ready.set()
def managedAccounts(self, accountsList):
self.accounts_list_raw = accountsList or ""
self.accounts = [item for item in self.accounts_list_raw.split(",") if item]
self.managed_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 = ReceiveManagedAccountsApp()
try:
app.connect("127.0.0.1", 7497, clientId=983)
thread = threading.Thread(target=app.run, daemon=True)
thread.start()
if not app.ready.wait(8):
raise RuntimeError("等待 nextValidId 超时")
app.reqManagedAccts()
if not app.managed_ready.wait(8):
raise RuntimeError("等待 managedAccounts 回调超时")
finally:
if app.isConnected():
app.disconnect()
aliases = [f"ACCOUNT_{index}" for index, _ in enumerate(app.accounts, 1)]
print(f"MANAGED_CALLBACK_RECEIVED={app.managed_ready.is_set()}")
print(f"ACCOUNT_COUNT={len(app.accounts)}")
print("ACCOUNT_ALIASES=" + (",".join(aliases) if aliases else "NONE"))
print(f"RAW_LIST_HAS_TRAILING_COMMA={app.accounts_list_raw.endswith(',')}")
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)}")
MANAGED_CALLBACK_RECEIVED=True
ACCOUNT_COUNT=1
ACCOUNT_ALIASES=ACCOUNT_1
RAW_LIST_HAS_TRAILING_COMMA=False
INFO_CODES=2104,2106,2158
NON_INFO_ERROR_COUNT=0

这个环境返回 1 个可见账户,并且原始字符串没有尾部逗号。

如果返回多个账户,不要默认使用第一个账户做所有操作。更稳妥的方式是:

  • 在配置里保存用户选择的目标账户。
  • 每次启动后用 reqManagedAccts() 验证该账户仍在可见列表里。
  • 日志里输出脱敏别名,不输出真实账户号。

示例:

target_account = "DU1234567"
if target_account not in accounts:
raise RuntimeError("目标账户不在这个 TWS 会话可见账户列表中")

公开日志可写成:

TARGET_ACCOUNT_ALIAS=ACCOUNT_2
TARGET_ACCOUNT_VISIBLE=True

不是。Python API 回调里它是字符串,需要自己 split(",")

先确认是否收到回调。如果收到空字符串,说明这个会话没有返回可见账户;检查 TWS 登录状态、账户权限和 API 连接。普通模拟账户正常情况下应至少返回一个账户。

可以把 accountsList 直接传给账户更新接口吗?

Section titled “可以把 accountsList 直接传给账户更新接口吗?”

不建议。accountsList 可能包含多个账户。应先解析成列表,再选择一个明确账户传给账户类接口。

IBKR Campus: TWS API Documentation