> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agg.market/llms.txt
> Use this file to discover all available pages before exploring further.

# Paper Trading

> Offer simulated trading with live market data for staging, QA, or user-facing paper portfolios

<Info>
  Live market data. Simulated funds. The same integration path your users will use in production.
</Info>

Paper trading can be a production user feature, a staging QA tool, or both. It
prices quotes against current market data and records simulated balances,
orders, and positions, while keeping live funds completely out of the flow.

## Choose The Right Surface

Use `mode: "paper"` when users should trade through the normal execution path
with a simulated account. Users sign in normally, request smart routes normally,
fill quotes normally, and read balances, positions, and orders from the same SDK
methods or API reference operations they use for live trading.

Use the [paper account management APIs](/recipes/paper-trading-accounts) when
your backend needs to create, seed, reset, or inspect server-side paper accounts
for user simulators, QA, or automated test runs.

<Warning>
  Paper trading never submits to venues and never runs bridges, custody transfers, deposits,
  withdrawals, or redemptions. Do not treat paper balances as prefunded wallets, live account
  balances, or venue funds.
</Warning>

## Product Patterns

Paper trading supports two common app patterns:

| Pattern                        | What users see                                                                                 | What your app sends                                                                                       |
| ------------------------------ | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| User-facing paper trading      | Users can switch between a real account and a paper account in the same production app.        | `mode: "paper"` for paper balances, quotes, fills, positions, and orders. Live mode for the real account. |
| Staging and QA execution tests | Test users exercise the same order entry, profile, and account surfaces without risking funds. | The same SDK/API calls as production, with `mode: "paper"` and test-only app chrome.                      |

Keep paper and live state visually separate. A user can have both a paper
portfolio and a live account, but those balances, orders, positions, and funding
surfaces should never be presented as interchangeable.

## How It Works

<Steps>
  <Step title="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.
  </Step>

  <Step title="AGG reads live market data">
    Smart routes and direct paper fills price against the current order book. The result is
    simulated, but the quote quality reflects current market depth.
  </Step>

  <Step title="Your app sends paper mode">
    Add `mode: "paper"` to custom SDK/API execution calls. For AGG UI surfaces, set
    `trading.executionMode` once in `AggProvider` config so hosted pages and order panels share
    the same paper account mode.
  </Step>

  <Step title="AGG writes paper state only">
    Paper fills update `PAPER_USD`, paper orders, and paper positions. Live managed wallets, venue
    accounts, and executor orders are not touched.
  </Step>
</Steps>

## UI Components

For AGG-hosted UI surfaces, set paper mode globally in `AggProvider` config.
`HomePage`, `EventMarketPage`, `PlaceOrder`, and `UserProfilePage` read this
provider setting when an explicit `executionMode` prop is not supplied.

```tsx theme={null}
import { AggProvider } from "@agg-build/ui";
import { HomePage } from "@agg-build/ui/pages";

export function App() {
  return (
    <AggProvider
      client={client}
      config={{
        trading: {
          executionMode: "paper",
        },
      }}
    >
      <HomePage />
    </AggProvider>
  );
}
```

This keeps hosted AGG pages, embedded order panels, profile balances, positions,
and orders on the same paper account mode without threading props through every
surface.

You can still pass `executionMode` directly when one surface must override the
provider default, for example a live-only panel inside a paper-mode app shell:

```tsx theme={null}
import { EventMarketPage } from "@agg-build/ui/pages";

export function LiveEventOverride({ eventId }: { eventId: string }) {
  return <EventMarketPage eventId={eventId} executionMode="live" />;
}
```

## SDK Flow

If you build your own order entry, pass `mode: "paper"` on each execution call.
The SDK methods below map to the same API reference operations used in live
mode:

| SDK method                                 | API reference                                                 |
| ------------------------------------------ | ------------------------------------------------------------- |
| `getManagedBalances({ mode: "paper" })`    | [Get balances](/api-reference/users/getmanagedbalances)       |
| `getSmartRoute({ mode: "paper" })`         | [Compute order route](/api-reference/orderbook/getsmartroute) |
| `executeManaged({ mode: "paper" })`        | [Execute quote](/api-reference/execution/fillmanaged)         |
| `getExecutionPositions({ mode: "paper" })` | [Get user positions](/api-reference/users/getpositions)       |
| `getExecutionOrders({ mode: "paper" })`    | [Get user orders](/api-reference/users/getorders)             |

```ts theme={null}
import { createAggClient } from "@agg-build/sdk";

const client = createAggClient({
  baseUrl: process.env.AGG_API_BASE_URL!,
  appId: "your-app-id",
});

// After the user authenticates...
const balances = await client.getManagedBalances({ mode: "paper" });

const route = await client.getSmartRoute({
  venueMarketOutcomeId: "vmo_...",
  tradeSide: "buy",
  maxSpend: 25,
  mode: "paper",
});

await client.executeManaged({
  quoteId: route.quoteId,
  mode: "paper",
  fallbackToLatest: {
    outcomeId: "vmo_...",
    side: "buy",
    maxSpend: 25,
  },
});

const [positions, orders] = await Promise.all([
  client.getExecutionPositions({ mode: "paper", status: "active", limit: 25 }),
  client.getExecutionOrders({ mode: "paper", limit: 25 }),
]);
```

<Warning>
  Keep the mode consistent from quote to fill. A quote created with `mode: "paper"` must be filled
  with `mode: "paper"`. A live fill cannot execute a paper quote, and a paper fill cannot execute a
  live quote.
</Warning>

## Funding UI

Hide deposit, withdrawal, and redemption controls anywhere your user is in a
paper-only experience. Paper accounts expose `PAPER_USD` and simulated
positions; they do not need wallet funding, bridge setup, venue account funding,
or settlement redemption.

## Execution Testing Strategies

Paper trading is the recommended way to test your execution UX because it uses
the same route, fill, order, position, and balance surfaces as live trading.

For staging or CI smoke tests:

* Sign in a test user through the normal auth flow.
* Read paper balances and assert `PAPER_USD` is present.
* Quote a current open market with `mode: "paper"`.
* Fill the quote with `mode: "paper"` and assert order IDs are returned.
* Read paper orders and active paper positions and assert the fill is visible.
* Assert the paper cash balance changed after the fill.

For negative-path coverage:

* Attempt to fill a paper quote without `mode: "paper"` and expect rejection.
* Switch from paper to live mode and require a fresh quote before fill.
* Verify paper pages do not show deposit, withdrawal, bridge, or redemption actions.
* Verify live balances and paper balances are never combined in one total.

For repeatable QA scenarios:

* Seed or reset the user paper account from your backend before the run.
* Use current market discovery when selecting test outcomes instead of hardcoding
  a single outcome ID that can age out.
* Store scenario-owned `clientOrderId` values when placing direct paper orders
  from your backend, so test logs can correlate fixtures to AGG orders.

## Launch Checklist

* Decide whether paper trading is staging-only, production user-facing, or both.
* Render a clear paper account badge or account switcher in your app shell.
* Set `config.trading.executionMode = "paper"` on `AggProvider` when the paper account is selected.
* Use component-level `executionMode` props only for intentional per-surface overrides.
* Pass `mode: "paper"` to custom SDK calls for paper balances, routes, fills, positions, and orders.
* Use live mode only after the user has explicitly selected their real account.
* Do not show deposit, withdrawal, or redemption flows as part of the paper account experience.
* Reset or seed account balances from your backend when a QA run needs a known starting state.

## FAQ

### Can I quote in paper mode and fill in live mode?

No. Quote and fill modes must match. This prevents a paper account flow from
accidentally turning a simulated quote into a live venue submission.

### When is a user paper account created?

AGG creates the user-scoped paper account lazily the first time a signed-in user
requests paper balances, positions, quotes, or a paper fill for your app.

### How do I reset or seed the paper balance?

Use the backend-only account management surface in
[Manage Paper Trading Accounts](/recipes/paper-trading-accounts). Normal browser
paper mode uses the `user:<aggUserId>` external ID, so your backend can reset
the same account the user sees in the app.

### Should I show funding, withdrawals, or redemptions?

No. Hide those controls in a paper-only experience. Paper trading uses simulated
funds and does not perform deposits, withdrawals, bridges, custody transfers, or
redemptions.
