跳转到内容

账户摘要总览

账户摘要用于读取 TWS 账户窗口 Summary tab 中的账户级数据,例如账户类型、净清算值、现金、购买力、可用资金、超额流动性和 Cushion。

它适合回答这类问题:

  • 账户大概有多少净值?
  • 可用资金和购买力是多少?
  • 账户是否接近保证金压力?
  • 多账户或 FA 结构下,某个账户组的摘要字段是什么?

账户摘要不适合替代持仓、成交或订单状态。持仓要看 reqPositions(),组合市值和盈亏要看 reqAccountUpdates(),成交流水要看 reqExecutions()

账户摘要对应原始 TWS API 的这一组调用和回调:

reqAccountSummary(reqId, groupName, tags)
-> accountSummary(reqId, account, tag, value, currency)
-> accountSummaryEnd(reqId)
cancelAccountSummary(reqId)

核心含义如下:

名称中文解释
reqAccountSummary()请求并订阅账户摘要字段
accountSummary()每返回一个账户字段,就触发一次回调
accountSummaryEnd()本轮账户摘要初始数据已经发送完成
cancelAccountSummary()取消这个账户摘要订阅

reqAccountSummary() 不是一次普通函数返回,而是“请求 + 回调 + 结束信号 + 取消订阅”的模型。新手最容易漏掉的是最后的取消订阅。

reqAccountSummary(reqId, groupName, tags)
参数中文解释常见写法
reqId请求 ID,用来把回调和请求对应起来每次请求使用不同整数
groupName账户组名称普通单账户常用 "All"
tags逗号分隔的字段名"NetLiquidation,BuyingPower"

groupName="All" 可以返回所有可见账户的摘要。对于 Financial Advisor 或多账户结构,也可以传 TWS 中已经配置好的账户组名称。

def accountSummary(self, reqId, account, tag, value, currency):
...

每一条回调只代表一个字段。比如同一个账户请求了 7 个标签,就可能收到 7 次 accountSummary()

回调字段中文解释
reqId本次请求 ID
account账户代码,公开展示前必须脱敏
tag字段名,例如 NetLiquidation
value字段值,通常是字符串
currency币种;部分字段没有币种,可能为空

程序中一般会把回调整理成这种结构:

{
"ACCOUNT_CODE": {
"NetLiquidation": {
"value": "...",
"currency": "USD"
}
}
}
标签中文含义说明
AccountType账户类型例如现金账户、保证金账户等
NetLiquidation净清算值常用于估算账户总净值
TotalCashValue总现金价值包含现金相关余额
BuyingPower购买力可买入保证金证券的大致能力
AvailableFunds可用资金开新仓前常看的字段
ExcessLiquidity超额流动性保证金压力相关字段
CushionCushion 比例用于观察账户安全垫

标签数量很多,不建议一开始请求 $LEDGER:ALL 或全部字段。新手项目先请求少量关键字段,更容易排查,也更不容易把敏感账户信息打到日志里。

下面的示例使用 Python API 包中的 TWSSyncWrapper.get_account_summary()。它会完成请求、等待 accountSummaryEnd(),并在收到结果后调用 cancelAccountSummary()

from ibapi.sync_wrapper import TWSSyncWrapper, ResponseTimeout
TAGS = (
"AccountType,"
"NetLiquidation,"
"TotalCashValue,"
"BuyingPower,"
"AvailableFunds,"
"ExcessLiquidity,"
"Cushion"
)
app = TWSSyncWrapper(timeout=12)
try:
if not app.connect_and_start("127.0.0.1", 7497, 959):
raise RuntimeError("连接 TWS API 失败")
summary = app.get_account_summary(TAGS, group="All", timeout=8)
all_tags = sorted({
tag
for account_data in summary.values()
for tag in account_data.keys()
})
currencies = sorted({
data.get("currency") or "EMPTY"
for account_data in summary.values()
for data in account_data.values()
})
row_count = sum(len(account_data) for account_data in summary.values())
print(f"ACCOUNT_COUNT={len(summary)}")
print(f"ROW_COUNT={row_count}")
print("TAGS=" + ",".join(all_tags))
print("CURRENCIES=" + ",".join(currencies))
# 公开日志中不要打印真实账户号、净值、现金、购买力等值。
for index, account_data in enumerate(summary.values(), start=1):
print(f"ACCOUNT_ALIAS=ACCOUNT_{index}")
for tag in all_tags:
if tag in account_data:
currency = account_data[tag].get("currency") or "EMPTY"
print(f"FIELD={tag};CURRENCY={currency};VALUE=<redacted>")
except ResponseTimeout:
print("等待账户摘要回调超时,请确认 TWS API 连接正常。")
finally:
app.disconnect_and_stop()
print(f"IS_CONNECTED_AFTER_STOP={app.isConnected()}")

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

CONNECTED=True
ACCOUNT_COUNT=1
ROW_COUNT=7
TAGS=AccountType,AvailableFunds,BuyingPower,Cushion,ExcessLiquidity,NetLiquidation,TotalCashValue
CURRENCIES=EMPTY,USD
ACCOUNT_ALIAS=ACCOUNT_1
FIELD=AccountType;CURRENCY=EMPTY;VALUE=<redacted>
FIELD=AvailableFunds;CURRENCY=USD;VALUE=<redacted>
FIELD=BuyingPower;CURRENCY=USD;VALUE=<redacted>
FIELD=Cushion;CURRENCY=EMPTY;VALUE=<redacted>
FIELD=ExcessLiquidity;CURRENCY=USD;VALUE=<redacted>
FIELD=NetLiquidation;CURRENCY=USD;VALUE=<redacted>
FIELD=TotalCashValue;CURRENCY=USD;VALUE=<redacted>
IS_CONNECTED_AFTER_STOP=False

这里能看到 1 个账户、7 个字段。真实字段值没有写入文档,因为账户摘要属于敏感财务数据。

需求是否适合账户摘要
显示账户净值、现金、购买力适合
判断是否有足够资金开仓适合,但还要结合订单预检查
查看持仓数量不适合,用持仓接口
查看每个合约市值和盈亏不适合,用组合数据
查看订单是否成交不适合,用订单状态和成交接口
做长期对账报表不适合单独依赖,应结合报表或 Flex 服务

账户摘要适合做“账户级仪表盘”,不适合当作完整风控和对账系统的唯一数据源。

现象常见原因处理方式
ACCOUNT_COUNT=0账户组不可见,或请求没有返回数据先用 group="All" 测试,再检查账户权限
某些字段没有币种字段本身不是金额字段空币种可以显示为 EMPTY 或空字符串
字段值是字符串官方回调中 value 类型就是字符串需要计算时再按字段转成 Decimalfloat
结果迟迟不结束没收到 accountSummaryEnd()检查 TWS API 连接、TWS 弹窗和请求参数
日志泄露账户信息打印了 account 或真实金额公开日志和文档中必须脱敏

IBKR Campus: TWS API Documentation