Build an authenticated account monitor that keeps exact funding and trading balances separate, tracks reservations and open orders, and uses revisions to reject stale balance updates.
Read and format the balance snapshot
from polyester import format_ledger_u128
balances = await client.balances.list()
for balance in balances.balances:
print(
balance.asset_id,
"available",
format_ledger_u128(balance.available),
"reserved",
format_ledger_u128(balance.reserved),
"trading_revision",
balance.trading_revision,
"funding_revision",
balance.funding_revision,
)funding is deposit/withdraw custody state. trading, reserved, and available are execution
state. Their revisions are independent; compare trading_revision only with trading-state updates
and funding_revision only with funding-state updates.
Reconcile open orders
open_orders = await client.orders.list_open(
include_attached_risk=True,
include_attached_risk_state=True,
)
for order in open_orders.orders:
print(
order.order_id,
order.client_order_id,
order.symbol_id,
order.status,
order.orig_qty,
order.cum_qty,
order.leaves_qty,
)Reserved balance and open-order leaves should move together eventually, but they are served by different read models and can lag briefly. Do not flag a mismatch until a bounded reconciliation window and a fresh read have both completed.
Subscribe for low-latency order changes
from polyester.models import PrivateOrdersReady, PrivateOrdersSnapshot, PrivateOrdersUnit
orders = {order.order_id: order for order in (await client.orders.list_open()).orders}
subscription = await client.orders.subscribe(account_id=account_id)
async with subscription:
async for event in subscription:
if isinstance(event, PrivateOrdersSnapshot):
orders = {order.order_id: order for order in event.orders}
elif isinstance(event, PrivateOrdersUnit):
for order in event.orders:
held = orders.get(order.order_id)
if held is None or order.version > held.version:
orders[order.order_id] = order
scale = client.catalogs.base_quantity_scale_for_symbol_id(order.symbol_id)
if scale is None:
raise RuntimeError(f"stream symbol {order.symbol_id} quantity scale is unavailable")
cum = order.cum_qty.format(scale=scale) if order.cum_qty else None
leaves = order.leaves_qty.format(scale=scale) if order.leaves_qty else None
print(order.order_id, order.status, cum, leaves)
for order_id in event.removed_order_ids:
orders.pop(order_id, None) # left the live view; not a cancel
elif isinstance(event, PrivateOrdersReady):
print("stream caught up with the read above")orders.subscribe yields private-stream events, not bare orders. Wait for PrivateOrdersReady before relying on the stream, and keep the higher version of each order. A failure that ends the
stream is raised from iteration. The private stream accelerates the UI; it does not replace
snapshots. On queue overflow, discard local assumptions and reconcile balances plus open orders
again. Stream quantities can omit scale, so resolve it from the hydrated catalog by symbol_id and
fail closed if unavailable; never invent a stream scale.
Resolve fills before computing inventory
from polyester.models import OrderId
details = await client.orders.wait_for_order_trades_complete(
key=OrderId("order-id-from-create"),
timeout=15.0,
)
if details.order:
print(details.order.cum_qty, len(details.trades))The order projection can show cumulative quantity before every related trade row is queryable.
Use the completed trade projection for fee-source-aware received inventory and realized execution
reporting. The wait completes only for an order that has ended (filled, canceled, or rejected); for
a working order it raises PolyesterTransportError at the timeout, so read a working order with orders.get instead.
Poll as a safety net
Poll slowly enough to respect rate limits, add jitter across replicas, and set one overall timeout per cycle. A useful cycle is balances → open orders → recent history. Publish the new dashboard state atomically only after all required reads succeed; otherwise retain the previous state and mark it stale.
Account-state API map
balances.list: Funding/trading snapshot and revisions. Inputs: account scope, subaccount.balances.get_balance_history: Auditable balance movement. Inputs: range, ledger, account codes.orders.list_open: Current reservation intent. Inputs: scope, pagination, attached-risk flags.orders.list_history: Terminal and recent order states. Inputs: symbol/ID, pagination.orders.get: One order plus related fills. Inputs:key.orders.subscribe: Low-latency private order events. Inputs: account ID.orders.wait_for_order_trades_complete: Complete fill projection of an ended order. Inputs:key, timeout.trades.list: User execution ledger. Inputs: account filters, pagination.
The snippets on this page are type-checked against polyester-sdk==0.11.0.