Appearance
Prop Trading Module
Overview
The prop-trading module owns synthetic account truth. It receives proposed actions, applies account policy and safety gates, simulates fills, updates positions/balances, writes ledger events, and exposes snapshots.
It does not own AI prompt/model logic, race settlement, ticket ownership, creator payouts, or payment verification.
Responsibilities
- Create, start, complete, liquidate, pause, resume, and lock prop accounts.
- Store execution policy snapshots on accounts.
- Accept AI-proposed decision actions idempotently.
- Run safety gates before execution.
- Simulate paper fills using latest market prices.
- Update balances, positions, orders, fills, and ledger rows.
- Mark active accounts to market on a cadence.
- Auto-liquidate accounts that breach drawdown thresholds.
- Provide snapshots and decision context to AI Trading.
- Provide admin audit controls for operational correction.
Boundary Rules
- Prop Trading is the only writer of
prop_*execution truth. - AI Trading can submit proposed actions but cannot mutate account balances or fills.
- Lifecycle creates/consumes prop accounts through services, not direct table writes.
- Data Ingestion owns source clients and price storage; Prop Trading reads prices.
- Backtesting can reuse fill/position math without writing production prop tables.
Runtime Flow
Account lifecycle:
text
create pending account
-> write account_created ledger event
-> start account
-> initialize balance
-> active account accepts decisions and mark-to-market
-> complete or liquidate terminal stateDecision action execution:
text
AI Trading submits action batch
-> idempotency check by account/run/action
-> reject unsupported hold/cancel/no-price/gate failures
-> create prop decision action
-> create validated order
-> simulate fill at latest mark price
-> update position math
-> update balance and ledger
-> link result back to AI decision actionMark-to-market:
text
List active accounts
-> fetch latest quote for open positions
-> reprice unrealized PnL/equity
-> update balance/high watermark
-> write mark_to_market ledger event
-> auto-liquidate if equity breaches thresholdMain Code Paths
| Path | Purpose |
|---|---|
backend/src/modules/prop-trading/account-service.ts | Prop account create/start/complete/liquidate lifecycle. |
backend/src/modules/prop-trading/decision-actions-service.ts | Validates and executes AI-proposed action requests. |
backend/src/modules/prop-trading/mark-to-market-service.ts | Reprices active accounts and auto-liquidates when needed. |
backend/src/modules/prop-trading/snapshot-service.ts | Account snapshots and AI decision context. |
backend/src/modules/prop-trading/admin-service.ts | Pause/resume/lock/liquidate/void/recompute controls. |
backend/src/modules/prop-trading/execution/safety-gates.ts | Runtime account/action policy gates. |
backend/src/modules/prop-trading/execution/fill-simulator.ts | Paper fill simulation and fee application. |
backend/src/modules/prop-trading/execution/position-math.ts | Position average price, realized/unrealized PnL, size math. |
backend/src/modules/prop-trading/execution/mid-price-source.ts | Latest price reads from Data Ingestion tables. |
backend/src/modules/prop-trading/repositories/* | Account, order, fill, position, balance, ledger, action, and audit persistence. |
backend/src/workers/mark-to-market.ts | Mark-to-market worker. |
State And Tables
| Migration | Tables |
|---|---|
0007_prop_accounts.sql | prop_accounts, prop_ledger_events |
0008_prop_orders_fills_positions.sql | prop_account_balances, prop_orders, prop_fills, prop_positions, prop_decision_actions |
0010_prop_admin_audit.sql | prop_admin_audit_log |
| Table | Technical significance |
|---|---|
prop_accounts | Account status, owner/clone/parent, mode, starting balance, execution policy snapshot. |
prop_account_balances | Cash, equity, realized/unrealized PnL, fees, high watermark. |
prop_orders | Validated paper order records. |
prop_fills | Paper execution records. |
prop_positions | Open/closed synthetic positions by symbol and side. |
prop_decision_actions | Idempotent intake and execution status for AI-proposed actions. |
prop_ledger_events | Audit trail for account lifecycle, validations, fills, positions, mark-to-market, liquidation. |
prop_admin_audit_log | Service-token/admin operational actions. |
Legacy clone_execution_* tables still exist for older debug paths. The prop runtime source of truth is the prop_* table family.
Routes And Workers
All /api/v1/prop/* and /api/v1/admin/prop/* routes are service-token guarded.
| Surface | Purpose |
|---|---|
POST /api/v1/prop/accounts | Create prop account. |
GET /api/v1/prop/accounts/:id | Read account. |
GET /api/v1/prop/clones/:cloneId/accounts | List clone prop accounts. |
POST /api/v1/prop/accounts/:id/start | Start pending account. |
POST /api/v1/prop/accounts/:id/complete | Complete active/paused/locked account. |
POST /api/v1/prop/accounts/:id/liquidate | Liquidate active/paused/locked account. |
GET /api/v1/prop/accounts/:id/{ledger,snapshot,decision-context,orders,fills,positions} | Account reads. |
POST /api/v1/prop/accounts/:id/decision-actions | Submit AI-proposed actions. |
POST /api/v1/prop/accounts/:id/mark-to-market | Reprice one account. |
POST /api/v1/prop/mark-to-market-all | Reprice active accounts. |
GET /api/v1/prop/decision-actions/:id | Read submitted decision action. |
/api/v1/admin/prop/accounts/:id/* | Pause/resume/lock/liquidate/void-order/void-fill/recompute/audit-log. |
npm run prop:mark-to-market:worker | Long-running mark-to-market worker. |
npm run prop:mark-to-market:once | One-shot mark-to-market. |
Execution Policy
Default audition-created accounts use:
| Policy | Default |
|---|---|
| Starting balance | 100,000 USDC |
| Max leverage | 5x |
| Max notional | 50,000 |
| Max open positions | 5 |
| Max open orders | 10 |
| Allowed directions | Long and short |
| Fee | 10 bps |
| Slippage model | mid_price |
Safety gates reject unsupported actions, inactive accounts, disallowed assets, missing execution prices, disallowed directions, notional/leverage breaches, aggregate leverage breaches, position-equity breaches, insufficient margin, and open position/order policy breaches.
Failure Behavior
- Account creation is idempotent by
idempotencyKey. - Starting an already-active account is idempotent.
- Terminal accounts block repeated complete/liquidate transitions.
- Decision action submission is idempotent by
(prop_account_id, decision_run_id, decision_action_id). - Duplicate decision action ids in the same batch are rejected.
- Retrying an already-submitted decision action returns the existing prop action instead of rerunning gates.
- Missing execution price rejects the action instead of using stale/guessed data.
- Mark-to-market catches per-account failures and records failure ledger/audit context where possible.
- Auto-liquidation threshold defaults to 50% drawdown from starting balance.
Debugging Notes
- For missing execution, check
prop_decision_actionsbefore orders/fills. - For rejected action, inspect gate metadata and latest Data Ingestion price rows.
- For balance mismatch, follow
prop_ledger_eventsin timestamp order. - For stale account snapshots, check the mark-to-market worker heartbeat and latest quote availability.
- If AI shows a proposed action but Prop Trading has no action, inspect AI action status/link fields first.
Tests
bash
cd backend
npm run typecheck
node --import tsx --test test/api-prop-trading.test.ts test/prop-*.test.ts test/safety-gates-extended.test.tsKnown Gaps
- Race-mode result snapshot consumption for Lifecycle.
- Operational reconciliation and incident runbooks.
- Final decision on how long to support legacy clone execution tables.