Appearance
Paper Trading
The UserPaperTradePortfolio Durable Object implements the full paper trading engine.
Balance & Margin
- Starting balance: $10,000
- Account failure: Disabled by default (ChallengeManager enables via
setBalanceForChallenge) - Margin modes: CROSS (default) and ISOLATED. CROSS includes unrealized PnL in available margin. Mode cannot be changed with open positions or limit orders.
- Available margin:
balance + unrealizedPnL - marginUsed - reservedMargin
Position Management
3-case netting algorithm:
- Same direction — adds to existing position
- Partial close — reduces position size
- Full reversal — closes and opens opposite
Explicit partial close: closePosition() accepts optional sizeUsd to close a specific amount. Remaining position keeps original entry price.
Validation Rules
- Integer leverage only, 1 to token-dependent max (see
apps/backend/src/constants/symbols/leverage.ts) - Minimum order size: $10 USD (configurable via
min_order_sizeaccount setting) - Required margin ≤ available balance
- Leverage can only increase (≥ existing position leverage), never decrease
- System auto-adjusts leverage before adding to position if higher leverage requested
- Adding to position must not cause immediate liquidation
Leverage Management
changeLeverage()RPC: Increase leverage for existing position (strictly increasing only)- Auto-adjustment: When opening with higher leverage, system increases existing position's leverage first
- Effects: Releases margin, updates liquidation price, re-registers liquidation alert
Fee System
7-tier volume-based fees tracked over a 14-day rolling window.
Pending Order State Machine
CREATED → PENDING → EXECUTED / FAILEDSurvives DO eviction. Margin is reserved at creation time for "eventually correct" execution.
BigNumber Serialization
Generic Serialized<T> type with serialize() and parseMonetary() helpers for safe monetary arithmetic.
Idempotency
24-hour TTL deduplication keys for: OPEN/CLOSE_POSITION, CLOSE_ALL_POSITIONS, LIMIT_ORDER, CANCEL_ALL_LIMIT_ORDERS, RESET, START_CHALLENGE. PROCESSING status prevents race conditions.