跳转到内容

家庭代码总览

家庭代码接口用来判断可见账户是否属于 IBKR 的 account family,并返回账户对应的 family code。它主要服务于顾问账户、IBroker、家庭账户结构或需要按账户家庭关系做分组的程序。

reqFamilyCodes()
-> familyCodes(familyCodes)

这组接口很小:没有请求参数,也没有取消方法。请求一次后,结果通过 familyCodes() 回调返回。

场景是否适合
判断账户是否属于 account family适合
顾问账户、IBroker、家庭账户结构分组适合
普通单账户入门开发通常不是必需
获取账户资金、保证金、购买力不适合,应看账户摘要或账户更新
获取持仓、盈亏、订单不适合,应看对应账户、持仓、订单接口

如果你只是开发普通模拟账户的行情、下单、账户余额展示,家庭代码不是第一优先级。它更像账户结构辅助信息。

名称类型中文含义说明
reqFamilyCodes()请求方法请求家庭代码没有参数
familyCodes()回调方法接收家庭代码列表返回 FamilyCode 对象列表
FamilyCode.accountID字段账户代码真实账户号,公开输出应脱敏
FamilyCode.familyCodeStr字段家庭代码字符串不属于 account family 时可能为空

本地 Python API 源码里的 FamilyCode 对象只有两个主要字段:

class FamilyCode:
accountID = ""
familyCodeStr = ""

家庭代码接口有一个容易误解的点:回调返回了账户行,但 familyCodeStr 可能是空字符串。

这通常表示:

  • 账户可以被 TWS API 看见。
  • 但这个账户没有归属于 account family,或者登录环境没有对应家庭代码。

所以,空 family code 不是一定失败。判断是否失败时,应同时看是否收到 familyCodes() 回调、是否有非信息类错误。

下面示例会连接TWS 模拟账户,请求家庭代码,并只输出脱敏后的结构:

import threading
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
INFO_CODES = {2100, 2104, 2106, 2158}
class FamilyCodesOverviewApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
self.ready = threading.Event()
self.family_ready = threading.Event()
self.family_codes = []
self.info_codes = []
self.errors_seen = []
def nextValidId(self, orderId):
self.ready.set()
def familyCodes(self, familyCodes):
# familyCodes 是 FamilyCode 对象列表,真实 accountID 不要直接打印到公开日志。
self.family_codes = list(familyCodes or [])
self.family_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 = FamilyCodesOverviewApp()
try:
app.connect("127.0.0.1", 7497, clientId=978)
thread = threading.Thread(target=app.run, daemon=True)
thread.start()
if not app.ready.wait(8):
raise RuntimeError("等待 nextValidId 超时")
app.reqFamilyCodes()
if not app.family_ready.wait(8):
raise RuntimeError("等待 familyCodes 回调超时")
finally:
if app.isConnected():
app.disconnect()
rows = []
for index, item in enumerate(app.family_codes, 1):
rows.append({
"alias": f"ACCOUNT_{index}",
"has_account_id": bool(item.accountID),
"family_code": item.familyCodeStr or "EMPTY",
})
print("FAMILY_CALLBACK_RECEIVED=True")
print(f"FAMILY_CODE_ROW_COUNT={len(app.family_codes)}")
print("ROWS=" + (str(rows) if rows else "EMPTY"))
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)}")

使用TWS 模拟账户、127.0.0.1:7497 和独立 clientId 检查时,脱敏输出如下:

CONNECTED=True
REQUEST_SENT=True
FAMILY_CALLBACK_RECEIVED=True
FAMILY_CODE_ROW_COUNT=1
ROWS=[{'alias': 'ACCOUNT_1', 'has_account_id': True, 'family_code': 'EMPTY'}]
INFO_CODES=2104,2106,2158
NON_INFO_ERROR_COUNT=0
IS_CONNECTED_AFTER_DISCONNECT=False

这次结果说明:接口调用成功,这个会话返回了 1 个可见账户行;账户号存在,但 family code 为空。对普通模拟账户来说,这是合理结果,不应当当成接口失败。

FamilyCode.accountID 是真实账户号,公开文档、日志和报错里建议统一脱敏。例如:

DU1234567 -> ACCOUNT_1

familyCodeStr 本身也可能暴露账户组织关系。如果你在团队系统里记录它,建议只在受控日志或后台页面中展示。

页面内容
请求家庭代码reqFamilyCodes() 的请求流程和请求前检查
接收家庭代码familyCodes() 回调、FamilyCode 字段和空 family code 的判断

IBKR Campus: TWS API Documentation