Subscription.balances
读取私有订阅根据推送维护的最新余额,仅适用于channel为private的订阅。
balances()示例
订阅私有流,在快照就绪时及每次余额变化时输出USDT的可用数量与冻结数量。
javascript
function main() {
var acct = ctx.subscribe(exchange, {channel: "private"})
while (true) {
var ev = ctx.poll([], 1000)
if (!ev || ev.stream !== acct.id) {
continue
}
var ready = ev.kind === 35 && ev.prefillStatus === 1
if (!ready && ev.channel !== "balance") {
continue
}
var balances = acct.balances()
if (balances === null) {
continue // 账户快照尚未就绪
}
var usdt = balances.find(function(b) { return b.asset === "USDT" })
Log("USDT free:", usdt ? usdt.free : 0, "frozen:", usdt ? usdt.frozen : 0)
}
}
python
def main():
acct = ctx.subscribe(exchange, {"channel": "private"})
while True:
ev = ctx.poll([], 1000)
if ev is None or ev.stream != acct.id:
continue
ready = ev.kind == 35 and ev.prefillStatus == 1
if not ready and ev.channel != "balance":
continue
balances = acct.balances()
if balances is None:
continue # 账户快照尚未就绪
usdt = next((b for b in balances if b.asset == "USDT"), None)
Log("USDT free:", usdt.free if usdt else 0, "frozen:", usdt.frozen if usdt else 0)
rust
use sdk::ctx::EventExt;
fn main() {
let acct = ctx::subscribe(exchange, ctx::SubOpts::private()).unwrap();
loop {
match ctx::poll(&[], Some(1000)) {
ctx::Polled::Event(ev) if ev.stream() == acct.id() => {
if ev.channel() != "private" && ev.channel() != "balance" {
continue;
}
if let Ok(Some(rows)) = acct.balances() {
if let Some(u) = rows.iter().find(|b| b.asset == "USDT") {
Log!("USDT free:", u.free, "frozen:", u.frozen);
}
}
}
ctx::Polled::Stopped => break,
_ => {}
}
}
}返回值
| 类型 | 描述 |
array / 空值 | 余额数组,每个元素为某种资产当前的完整余额,按资产名排序;账户快照尚未就绪时返回空值。 |
参考
备注
数组元素的字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| asset | string | 资产名,与exchange.GetAssets返回的资产名一致 |
| free | number | 可用数量 |
| frozen | number | 冻结数量 |
| equity、upnl、margin | number | 权益、未实现盈亏、保证金占用;交易所未推送时不包含这些字段 |
| time | number | 交易所更新时间(毫秒);交易所未提供时不包含该字段 |
可用数量与冻结数量均为0的资产不包含在数组中。
返回空值表示状态未知,而不是没有余额:订阅后,需要等到该事件流上出现channel为private、prefillStatus为1的初始化状态事件,之后才有数据;最近一次快照失败时也返回空值,直到下一次快照就绪。
托管者根据推送的余额事件(kind为18)更新此状态,因此需要持续调用ctx.poll获取事件。各交易所推送余额的方式不同(有的交易所在余额变动后由连接器重新请求REST接口再推送,有的只提供快照),详见各交易所页面的说明。exchange.GetAssets、exchange.GetAccount始终请求REST接口,与推送无关。
对非私有订阅或已退订的订阅对象调用时会抛出异常。
Rust中为sub.balances() -> Result<Option<Vec<ctx::BalanceRow>>, String>,Ok(None)表示快照尚未就绪;BalanceRow的字段为asset、free、frozen、equity、upnl、margin、time(后四个为Option)。Python中为sub.balances(),返回字典列表(字段同上,也可以用属性方式访问),快照尚未就绪时返回None。