Paper Portfolio
On this page
Portfolio and accounts
Paper trading runs a frozen Strategy continuously in an isolated simulation. Choose the reporting currency, initial assets and up to 16 simulated accounts. It does not connect a OnePort trading credential or a real account, so it cannot submit a real order.
Choose strategy_memory_gb when preflighting and creating Paper. STANDARD/VIP1 can use 8 GiB, VIP2 can use 8/16, and VIP3/ADMIN can use 8/16/32/64. New Paper defaults to 8 when omitted. Existing legacy deployments without a stored value continue at the 2 GiB compatibility fallback, and memory choice does not add concurrency.
Each instrument is routed to one simulated account. Accounts may belong to different venues, and a Strategy may read a signal from one venue while placing its simulated order on another. With a dynamic universe, review the resolved instruments and account routes before creation; if the available universe changes, refresh the preview before continuing.
If the Paper universe includes UPERP, choose USD as base_coin. This keeps perpetual PnL, fees and funding in the same reporting currency without guessing a settlement asset. SPOT-only Paper may use any reporting currency offered by the creation form.
During a run, strategy callbacks use completed KLines from OnePort OpenAPI at the selected frequency. When the Strategy submits or reprices an order, Paper reads a fresh OnePort BBO and applies the result only to the isolated account. Historical Backtest continues to use its historical-bar execution model.
Orders and status
Every order call returns the same OrderSubmitResult shape in Backtest, Paper and Live. It includes a stable local_order_id, submission success, status, requested quantity, filled quantity and average fill price when available. Store the local ID when the Strategy needs to check or cancel the order on a later trigger.
Paper uses the same step contract as Backtest and Live: quantize every calculated quantity, and every calculated Limit price, before submission. A step mismatch is rejected instead of being silently rounded. Minimum quantity, minimum notional and per-order maximums are shown for reference and do not cause a local Paper rejection.
def handle_bar(self, ctx, bars):
pending = getattr(ctx.state, "pending_order_id", None)
if pending is not None:
order = ctx.order_status(pending)
if order and order.terminal is True:
ctx.state.pending_order_id = None
return
instrument = "okx:UPERP:BTC-USDT-SWAP"
qty = ctx.quantize_qty(instrument, 0.01)
if qty <= 0:
return
result = ctx.place_order(
instrument, "Buy", "Market", qty, account="okx-main",
)
if result.success is True:
ctx.state.pending_order_id = result.local_order_idPaper market orders complete immediately when a valid, current BBO is available. If the quote is missing or invalid, the order is rejected and the account is left unchanged. Limit orders and open orders remain visible through order status and the Paper dashboard.
Lifecycle
| Action | Result | What is retained |
|---|---|---|
| Start | Starts the deployment | Uses the selected frozen Strategy and account setup |
| Pause | Stops new strategy triggers temporarily | Accounts, positions and open orders |
| Resume | Continues the paused deployment | Resumes from the retained state |
| Stop | Ends the deployment | History remains available; positions are not closed automatically |
| Delete | Removes a stopped deployment from the workspace | Completed order and fill records are preserved |
The page checks that you are acting on the latest deployment state, so an older browser tab cannot overwrite a newer action. Pausing or stopping never submits a hidden close or cancel request.
Missing market data
Paper exposes every admitted boundary through ctx.data_quality. PARTIAL means bars contains only the instruments with real completed KLines. After initialization, an authoritative all-missing slot becomes a GAP_CLOCK and still calls the Strategy with {}; the first all-empty input does not initialize. EMPTY_SELECTION_CLOCK separately means the Strategy selected no active instruments.
Missing KLines are never filled with zero, copied forward, used as marks or used for KLine matching. Existing Paper working orders may still evolve from an independently observed fresh BBO. A Strategy can keep managing known orders or strictly reduce exposure during a gap, while the runtime rejects new, increased or reversing risk for an instrument missing at that boundary. The dashboard keeps the last real mark and its time, clearly labelled stale when appropriate.
Portfolio dashboard
The dashboard brings together Portfolio performance, account balances, positions, orders, fills, fees, strategy records and runtime health. Use the Portfolio view for the combined NAV and equity, then open an account to inspect its own activity.
Combined Portfolio values are shown only when all accounts can be valued consistently in the reporting currency. Otherwise the account views remain available and the missing aggregate is labelled unavailable instead of being estimated.
Values recorded with ctx.record appear as custom series. You can compare or normalize selected series in the dashboard; missing timestamps are left missing.

