Skip to main content
Paper trading prices quotes against current market data and records simulated balances, orders, and positions. Live funds never enter the flow. Use it as a production feature (a paper account next to a real one), as a testing and QA tool, or both. There are two surfaces:
Paper trading never submits to venues and never runs bridges, custody transfers, deposits, withdrawals, or redemptions. Do not treat paper balances as funded wallets or venue balances.

How it works

1

User signs in

Paper mode is user-scoped. A signed-in user gets a paper account for your app the first time they request paper balances, positions, quotes, or a fill.
2

AGG prices against live books

Quotes and paper fills price against the current order book. The result is simulated, but the quote reflects current market depth.
3

Your app sends paper mode

Add mode: "paper" to the paper-capable calls in SDK flow. For AGG UI components, set trading.executionMode once on AggProvider.
4

AGG writes paper state only

Paper fills update the PAPER_USD balance, paper orders, and paper positions. Live wallets, venue accounts, and live orders are not touched.
Keep paper and live state visually separate. A user can have both, but never show them as one balance or one portfolio.

SDK flow

Pass mode: "paper" on these calls. They, and only they, accept it:
Keep the mode the same from quote to fill. A paper quote must be filled with mode: "paper", and a live fill cannot execute a paper quote. Switching modes needs a fresh quote.
Place an order directly (POST /execution/orders) is live only. It has no mode field and rejects one with 400. Use a quote and fill with mode: "paper", or a paper account order from your backend.

UI components

Set paper mode once on AggProvider. HomePage, EventMarketPage, PlaceOrder, and UserProfilePage read it when no executionMode prop is passed.
Pass executionMode on one component when it must differ from the provider:
Hide deposit, withdrawal, and redemption controls in a paper-only experience.

Manage paper accounts from your backend

These endpoints need a server-side x-app-api-key (see Base URL, app IDs & API keys). Never call them from the browser.

Seed the account a user sees

Browser paper mode uses the account whose externalId is user:<aggUserId>. Create or reset that account from your backend and the signed-in user sees the seeded balance in the app.
externalId is unique per app, so creating an existing account returns a validation error. Look it up instead:

Reset or set cash

resetPaperTradingAccount clears open positions and sets cash. setPaperTradingBalance changes cash only.
Raw amounts use 6 decimals. initialBalance, balance, and spend also accept numbers, but raw strings are better for repeatable fixtures. Order history survives a reset.

Place a simulated order

Direct paper orders build known positions before a UI test. They price against the current book and come back filled or rejected.
On paper orders, clientOrderId is stored for traceability only. It is not an idempotency key.

Inspect state

Testing with paper mode

For pre-release checks or CI smoke tests:
  • Sign in a test user through the normal auth flow.
  • Read paper balances and check PAPER_USD is present.
  • Quote a current open market with mode: "paper", fill it, and poll status to a terminal state.
  • Read paper orders and positions and check the fill is there and cash changed.
Negative paths:
  • Fill a paper quote without mode: "paper" and expect a rejection.
  • Switch from paper to live and require a fresh quote before filling.
  • Check paper pages show no deposit, withdrawal, bridge, or redemption actions.
For repeatable runs, reset the user’s user:<aggUserId> account before the run, pick test outcomes from current discovery instead of hardcoding one that can close, and use scenario-owned clientOrderId values on backend orders so logs map fixtures to orders.

Launch checklist

  • Decide whether paper trading is for testing only, user-facing, or both.
  • Show a clear paper badge or account switcher.
  • Set config.trading.executionMode = "paper" on AggProvider while the paper account is selected.
  • Pass mode: "paper" on custom SDK calls for balances, quotes, fills, status, positions, and orders.
  • Never send mode: "paper" to POST /execution/orders.
  • Use live mode only after the user explicitly picks their real account.