账户值字段 key
updateAccountValue(key, val, currency, accountName) 里的 key 是账户字段名。它决定了 val 应该怎么解释:有些是金额,有些是比例,有些是文本状态,还有一些是按币种拆分的 Ledger 字段。
写账户面板、资金检查或风控提示时,不要只保存 key -> val。更稳妥的唯一键是:
(accountName, key, currency)这样可以避免同一个字段在不同币种、不同账户或不同账户分段里互相覆盖。
官方后缀规则
Section titled “官方后缀规则”官方文档把账户值 key 分成三类:
| key 形式 | 中文含义 | 例子 |
|---|---|---|
| 无后缀 | 总计口径 | NetLiquidation、AvailableFunds |
-S | Securities,证券分段 | NetLiquidation-S、AvailableFunds-S |
-C | Commodities,商品分段 | NetLiquidation-C、AvailableFunds-C |
实际 TWS 版本和账户类型还可能返回其他扩展后缀,例如这次验证里出现了 -P。程序不要因为没见过某个后缀就丢弃字段;建议保留原始 key,同时把已知后缀解析成更友好的显示名称。
def split_account_value_key(key): if key.endswith("-S"): return key[:-2], "证券分段" if key.endswith("-C"): return key[:-2], "商品分段" if key.endswith("-P"): return key[:-2], "TWS 扩展分段" return key, "总计或未分段"重要状态字段
Section titled “重要状态字段”| key | 中文含义 | 说明 |
|---|---|---|
AccountCode | 账户代码 | 真实账户号,公开输出必须脱敏。 |
AccountType | 账户类型 | 例如模拟、现金、保证金等账户类型信息,按实际返回为准。 |
AccountReady | 账户是否就绪 | 官方提醒:如果返回 false,表示 IB 服务器可能正在重置账户数据,这批值之后的数据可能过期或不准确。 |
ColumnPrio | TWS 账户窗口列优先级 | 多用于 TWS 展示,不常作为交易逻辑判断。 |
SegmentTitle | 账户分段标题 | 常和 -S、-C 等分段字段一起出现。 |
TradingType | 交易类型/分段类型 | 可能随账户结构返回,不建议写死枚举。 |
WhatIfPMEnabled | 是否启用组合保证金 What-If 相关能力 | 用于判断部分保证金预估能力。 |
NLVAndMarginInReview | 净清算值与保证金是否复核中 | 如果为复核状态,账户风控展示要更谨慎。 |
AccountReady 是这一组里最值得重点处理的字段。新手容易只看金额字段,但当 AccountReady=false 时,后面的金额字段可能并不适合直接用于下单前判断。
资金与净值字段
Section titled “资金与净值字段”| key | 中文含义 | 常见用途 |
|---|---|---|
NetLiquidation | 净清算值 | 账户总权益核心字段之一。 |
TotalCashValue | 总现金价值 | 观察现金余额。 |
SettledCashByDate | 按日期结算的现金 | 结算资金相关展示。 |
AccruedCash | 应计现金 | 利息、费用等应计现金口径。 |
AccruedDividend | 应计股息 | 股息相关应计值。 |
EquityWithLoanValue | 含借贷价值的权益 | 保证金账户常用权益口径。 |
GrossPositionValue | 总持仓市值 | 观察持仓规模。 |
PASharesValue | 投资组合分析股份价值 | 账户窗口可能返回的组合分析相关值。 |
这些字段很多都会出现无后缀、-S、-C 或其他扩展后缀。展示时最好把“总计”和“证券/商品分段”分开,不要把它们直接加总。
保证金与购买力字段
Section titled “保证金与购买力字段”| key | 中文含义 | 常见用途 |
|---|---|---|
BuyingPower | 购买力 | 粗略判断账户还能买入多少保证金证券。 |
AvailableFunds | 可用资金 | 下单前资金余量检查常用字段。 |
ExcessLiquidity | 超额流动性 | 保证金压力观察,过低时要警惕。 |
Cushion | 安全垫比例 | 通常用于观察账户离保证金压力的距离。 |
InitMarginReq | 初始保证金要求 | 该口径下开仓需要的初始保证金。 |
MaintMarginReq | 维持保证金要求 | 持仓需要维持的保证金。 |
SMA | Special Memorandum Account | 美股保证金账户常见字段。 |
RegTEquity | Reg T 权益 | Reg T 保证金口径相关。 |
RegTMargin | Reg T 保证金 | Reg T 保证金要求相关。 |
FullInitMarginReq | 完整口径初始保证金要求 | 完整保证金口径下的初始保证金。 |
FullMaintMarginReq | 完整口径维持保证金要求 | 完整保证金口径下的维持保证金。 |
FullAvailableFunds | 完整口径可用资金 | 完整保证金口径下的可用资金。 |
FullExcessLiquidity | 完整口径超额流动性 | 完整保证金口径下的超额流动性。 |
下单前不要只看一个字段。更稳妥的做法是同时观察 AvailableFunds、ExcessLiquidity、BuyingPower、订单预检查和真实订单回调。
前瞻保证金字段
Section titled “前瞻保证金字段”| key | 中文含义 | 说明 |
|---|---|---|
LookAheadNextChange | 下一次前瞻值生效时间 | 未来保证金口径发生变化的时间。 |
LookAheadInitMarginReq | 前瞻初始保证金要求 | 未来口径下的初始保证金要求。 |
LookAheadMaintMarginReq | 前瞻维持保证金要求 | 未来口径下的维持保证金要求。 |
LookAheadAvailableFunds | 前瞻可用资金 | 未来口径下的可用资金。 |
LookAheadExcessLiquidity | 前瞻超额流动性 | 未来口径下的超额流动性。 |
这些字段适合做风险提示,不适合单独作为“能不能下单”的最终判断。
Ledger 字段
Section titled “Ledger 字段”以 $LEDGER- 开头的字段通常表示按币种或账户账本口径拆分的值。常见 Ledger key 包括:
| key | 中文含义 |
|---|---|
$LEDGER-AccountOrGroup | 账本对应的账户或分组 |
$LEDGER-Currency | 账本币种 |
$LEDGER-RealCurrency | 真实币种 |
$LEDGER-ExchangeRate | 汇率 |
$LEDGER-CashBalance | 现金余额 |
$LEDGER-TotalCashBalance | 总现金余额 |
$LEDGER-AccruedCash | 应计现金 |
$LEDGER-FxCashBalance | 外汇现金余额 |
$LEDGER-NetLiquidationByCurrency | 按币种计算的净清算值 |
$LEDGER-StockMarketValue | 股票市值 |
$LEDGER-OptionMarketValue | 期权市值 |
$LEDGER-FutureOptionValue | 期货期权价值 |
$LEDGER-FundValue | 基金价值 |
$LEDGER-MutualFundValue | 共同基金价值 |
$LEDGER-MoneyMarketFundValue | 货币市场基金价值 |
$LEDGER-CorporateBondValue | 公司债价值 |
$LEDGER-TBillValue | 国库券价值 |
$LEDGER-TBondValue | 国债价值 |
$LEDGER-WarrantValue | 权证价值 |
$LEDGER-Cryptocurrency | 加密货币价值 |
$LEDGER-RealizedPnL | 已实现盈亏 |
$LEDGER-UnrealizedPnL | 未实现盈亏 |
$LEDGER-FuturesPNL | 期货盈亏 |
$LEDGER-NetDividend | 净股息 |
Ledger 字段经常和 currency 一起使用。保存时不要只用 $LEDGER-CashBalance 当唯一键,否则不同币种的现金余额可能互相覆盖。
其他账户窗口字段
Section titled “其他账户窗口字段”| key | 中文含义 | 说明 |
|---|---|---|
Billable | 可计费值 | 账户窗口相关字段,是否有用取决于账户类型。 |
Guarantee | 担保/保证相关值 | 常见于账户窗口分段字段。 |
IndianStockHaircut | 印度股票折扣/扣减 | 特定市场或账户场景才可能有意义。 |
IncentiveCoupons | 激励券 | 特定账户活动或优惠相关。 |
PhysicalCertificateValue | 实物凭证价值 | 很少用于自动交易判断。 |
PostExpirationExcess | 到期后超额流动性 | 衍生品到期相关风险字段。 |
PostExpirationMargin | 到期后保证金 | 衍生品到期相关保证金字段。 |
TotalDebitCardPendingCharges | 借记卡待处理费用 | 账户资金相关辅助字段。 |
Leverage | 杠杆 | 可能以分段后缀出现。 |
这些字段不一定每个账户都会返回。程序应该按“看到什么 key 就保存什么 key”设计,而不是假设字段全集固定。
Python 示例:统计 key
Section titled “Python 示例:统计 key”下面示例订阅一次账户更新,只统计 updateAccountValue() 里的 key、币种和类型,不打印真实金额。
import threadingfrom collections import Counterfrom decimal import Decimal, InvalidOperation
from ibapi.client import EClientfrom ibapi.wrapper import EWrapper
INFO_CODES = {2100, 2104, 2106, 2158}
class AccountValueKeysApp(EWrapper, EClient): def __init__(self): EClient.__init__(self, self) self.ready = threading.Event() self.managed_ready = threading.Event() self.download_end = threading.Event() self.managed_accounts = [] self.rows = [] self.errors_seen = []
def nextValidId(self, orderId): self.ready.set()
def managedAccounts(self, accountsList): self.managed_accounts = [item for item in accountsList.split(",") if item] self.managed_ready.set()
def updateAccountValue(self, key, val, currency, accountName): value_type = "empty" if val: try: Decimal(val) value_type = "decimal" except InvalidOperation: value_type = "text"
self.rows.append((key, currency or "EMPTY", value_type))
def accountDownloadEnd(self, accountName): self.download_end.set()
def error(self, reqId, errorTime, errorCode, errorString, advancedOrderRejectJson=""): if errorCode not in INFO_CODES: self.errors_seen.append((reqId, errorCode, errorString))
app = AccountValueKeysApp()
try: app.connect("127.0.0.1", 7497, clientId=972) 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 超时")
account = app.managed_accounts[0] app.reqAccountUpdates(True, account)
if not app.download_end.wait(8): raise RuntimeError("等待 accountDownloadEnd 超时")
app.reqAccountUpdates(False, account)
finally: if app.isConnected(): app.disconnect()
keys = sorted(set(key for key, _, _ in app.rows))currency_counts = Counter(currency for _, currency, _ in app.rows)type_counts = Counter(value_type for _, _, value_type in app.rows)
print(f"ROW_COUNT={len(app.rows)}")print(f"UNIQUE_KEY_COUNT={len(keys)}")print("CURRENCIES=" + ",".join(f"{key}:{value}" for key, value in sorted(currency_counts.items())))print("VALUE_TYPES=" + ",".join(f"{key}:{value}" for key, value in sorted(type_counts.items())))print("LEDGER_KEY_COUNT=" + str(sum(1 for key in keys if key.startswith("$LEDGER-"))))print("NON_INFO_ERROR_COUNT=" + str(len(app.errors_seen)))使用 TWS 模拟账户检查时,脱敏后的输出如下:
ROW_COUNT=183UNIQUE_KEY_COUNT=158CURRENCIES=BASE:25,EMPTY:19,USD:139VALUE_TYPES=decimal:164,text:19LEDGER_KEY_COUNT=25NON_INFO_ERROR_COUNT=0这次验证里,updateAccountValue() 返回 183 行、158 个去重 key。其中 25 个 key 以 $LEDGER- 开头,说明账户更新流不仅返回普通账户窗口字段,也会返回按账本或币种拆分的字段。
| 问题 | 建议 |
|---|---|
| 同一个字段有多个币种 | 用 (accountName, key, currency) 保存。 |
key 带 -S 或 -C | 按证券分段、商品分段展示,不要和总计字段混在一起。 |
| key 带未识别后缀 | 保留原始 key,先展示为扩展分段,不要丢弃。 |
val 是数字字符串 | 用 Decimal 解析,不建议用 float 做资金计算。 |
val 是文本 | 原样保存,例如账户类型、状态、币种等。 |
AccountReady=false | 不要立即用这批金额做下单判断,等待账户数据恢复稳定。 |