Trading API
On this page
Trading API
Backtest market orders execute after the strategy decision against the current real completed-bar close logical BBO, plus configured slippage and fees; an unseen next open is never used. Paper uses completed bars as decision triggers but prices a submitted market order from a fresh OnePort BBO. If that quote is missing, stale or invalid, the Paper order is rejected without changing the account.
Order methods#
Submit an order in Backtest, Paper or Live. qty is normally a positive coin quantity; side carries direction. A finite exact zero returns a terminal Rejected/PRECISION result with no provider call or position change. Limit requires price, while Market does not accept one. The framework requires exact quantity and price-step alignment and never silently resizes or reprices an order. Minimum quantity, minimum notional and per-order maximums are reference fields rather than OPR admission rules; a Live venue remains authoritative. reduce_only applies only to UPERP: a valid request that is flat, same-direction or crosses zero returns terminal Rejected/REDUCE_ONLY and the strategy continues. These local rejections consume one decision intent but no active-order slot. With multiple accounts, pass the configured account key.
Round a calculated non-negative coin quantity down to the active execution context's qty_step. Backtest uses the run-frozen step; Paper/Live use one cached current OnePort snapshot bound before the callback. A value below one step returns 0; normally skip it. If submitted, zero is a local terminal Rejected/PRECISION audit result and does not abort the callback.
Round a calculated Limit price to the active execution context's price_step: down for Buy and up for Sell. Backtest uses frozen precision; Paper/Live use the callback-bound current snapshot. The gateway never requantizes or retries.
Return whether the execution source confirmed the cancel request. This does not prove that the order is cancelled or terminal; query order_status later.
Read only the latest durable local view. Known orders, including completed ones, remain queryable throughout the generation; this form never reads a venue.
Explicitly query one known, exactly owned native order identity. Live performs exactly one provider read per call, with no scan, retry or background polling; Backtest and Paper use native ID = local ID as a string.
Return local orders not explicitly terminal=true. It reads only the local ledger; Live terminal=null means the last observation did not provide that field, not that OPR is confirming it in the background.
Page immutable PLACE/CANCEL command receipts from the generation-local cursor. Reading does not query, consume or acknowledge a receipt; persist the processed cursor in ctx.state.
Order status is exactly New, PartiallyFilled, Filled, Cancelled, Rejected, Expired or Unknown. Live transport ambiguity is returned without retry or a global freeze. The scheduler never polls, resubmits, cancels or flattens an order; the SDK has no order-event DTO or callback.
instrument = "binance:UPERP:BTCUSDT"
side = "Buy"
market_price = float(bars[instrument].close)
equity = ctx.accounts["alpha"].equity
if equity is None or equity <= 0 or market_price <= 0:
return
limit_price = ctx.quantize_price(
instrument, market_price * 0.995, side=side,
)
if limit_price <= 0:
return
raw_qty = 0.10 * equity / limit_price
qty = ctx.quantize_qty(instrument, raw_qty)
if qty <= 0:
return
result = ctx.place_order(
instrument, side, "Limit", qty, account="alpha", price=limit_price,
)
ctx.state.pending_order_id = result.local_order_id
ctx.state.submit_success = result.success
ctx.state.submit_status = result.status
view = ctx.order_status(ctx.state.pending_order_id)
if view is not None and view.terminal is True:
ctx.state.pending_order_id = NoneAccount & positions#
ctx.portfolio.nav # unitless capital-flow-adjusted NAV | None
account = ctx.accounts["main"] # account-scoped facts and multi-account orders use an explicit key
account.base_coin # USD/BTC/ETH/SOL/XRP denomination
account.cash # float | None; missing wallet fact stays None
account.equity # float | None; base-coin amount for sizing/risk
account.wallet_balance # float | None; never inferred from equity
account.available_to_trade # float | None
account.initial_margin # float | None
account.maintenance_margin # float | None
account.uni_mmr # float | None
account.as_of_ms / as_of_semantics
account.complete / availability / completeness
account.balances[asset].balance # asset quantity used consistently in every mode
account.leverage # (debt value + derivative gross notional) / equity
account.realized_pnl # float | None; may be unavailable in Live
account.funding_pnl # float | None; may be unavailable in Live
account.fees_paid # float | None; unavailable values stay None
account.nav # Live: None/unavailable; deployment NAV is ctx.portfolio.nav
account.positions # dict[instrument, Position]
pos = account.positions.get("binance:UPERP:BTCUSDT")
if pos:
pos.qty # signed quantity (negative = short)
pos.avg_price # float | None; average entry price when available
pos.last_price # float | None; latest mark when available
pos.unrealized_pnl # float | None; requires avg + mark
pos.notional # float | None; requires mark
pos.side # "LONG" / "SHORT"
