账户摘要总览
账户摘要用于读取 TWS 账户窗口 Summary tab 中的账户级数据,例如账户类型、净清算值、现金、购买力、可用资金、超额流动性和 Cushion。
它适合回答这类问题:
- 账户大概有多少净值?
- 可用资金和购买力是多少?
- 账户是否接近保证金压力?
- 多账户或 FA 结构下,某个账户组的摘要字段是什么?
账户摘要不适合替代持仓、成交或订单状态。持仓要看 reqPositions(),组合市值和盈亏要看 reqAccountUpdates(),成交流水要看 reqExecutions()。
官方调用模型
Section titled “官方调用模型”账户摘要对应原始 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 | 超额流动性 | 保证金压力相关字段 |
Cushion | Cushion 比例 | 用于观察账户安全垫 |
标签数量很多,不建议一开始请求 $LEDGER:ALL 或全部字段。新手项目先请求少量关键字段,更容易排查,也更不容易把敏感账户信息打到日志里。
Python 同步封装示例
Section titled “Python 同步封装示例”下面的示例使用 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=TrueACCOUNT_COUNT=1ROW_COUNT=7TAGS=AccountType,AvailableFunds,BuyingPower,Cushion,ExcessLiquidity,NetLiquidation,TotalCashValueCURRENCIES=EMPTY,USDACCOUNT_ALIAS=ACCOUNT_1FIELD=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 类型就是字符串 | 需要计算时再按字段转成 Decimal 或 float |
| 结果迟迟不结束 | 没收到 accountSummaryEnd() | 检查 TWS API 连接、TWS 弹窗和请求参数 |
| 日志泄露账户信息 | 打印了 account 或真实金额 | 公开日志和文档中必须脱敏 |