VeztaVezta
Architecture

Trading Engine

SmartRouter, exchange adapters, and order state machine

The trading engine handles order submission, routing, execution, and lifecycle management. It routes orders to the correct exchange, manages state transitions, and supports advanced order types including take-profit/stop-loss, sniper orders, and counter-trade automation.

Order Submission Flow

Client (web/mobile)


  Trading Controller
   POST /api/v1/trading/order


  ┌─────────────────┐
  │  SmartRouter     │  ← Selects exchange based on market source
  │  Service         │
  └────────┬────────┘

     ┌─────┴─────┐
     ▼           ▼
┌──────────┐ ┌──────────┐
│Polymarket│ │  Kalshi  │
│ Adapter  │ │ Adapter  │
└────┬─────┘ └────┬─────┘
     │             │
     └──────┬──────┘

   ┌────────────────┐
   │ OrderState      │
   │ Machine         │
   └────────────────┘

SmartRouter

The SmartRouterService determines which exchange adapter should handle an order. For markets that exist on a single exchange, the routing is straightforward. For markets available on both Polymarket and Kalshi, the router considers price and liquidity to find the best execution venue.

Exchange Adapters

Exchange-specific adapters live in src/modules/trading/adapters/ and implement a common interface:

AdapterExchangeDetails
Polymarket AdapterPolymarketSubmits orders via CLOB API using the user's sub-wallet CLOB credentials. Supports market and limit orders.
Kalshi AdapterKalshiSubmits orders via Trade API v2. Kalshi is custodial, so no wallet signature is needed per-trade.

Each adapter handles exchange-specific order formats, response parsing, and error mapping.

Order State Machine

The OrderStateMachine enforces valid state transitions for every order:

created ──▶ pending ──▶ partial ──▶ filled
                │          │
                │          └──▶ filled

                ├──▶ filled
                ├──▶ cancelled
                └──▶ failed

Terminal states: filled, cancelled, failed. Once an order reaches a terminal state, no further transitions are allowed.

StateDescription
createdOrder validated and saved to database
pendingOrder submitted to exchange, awaiting confirmation
partialPartially filled -- some quantity executed
filledFully filled -- all quantity executed
cancelledCancelled by user or system
failedSubmission or execution failed

The Prisma OrderStatus enum includes additional states (SUBMITTING, OPEN, PARTIALLY_FILLED, CANCELLING, REJECTED) that are not used by the OrderStateMachine. The state machine maps its own string states to a subset of the Prisma enum.

Take-Profit and Stop-Loss (TPSL)

Positions can have optional takeProfitPrice and stopLossPrice fields. When set, the system monitors market prices and automatically submits sell orders when the target price is reached:

  • Take-Profit -- Sell when currentPrice >= takeProfitPrice to lock in gains
  • Stop-Loss -- Sell when currentPrice <= stopLossPrice to limit losses

TPSL monitoring runs as part of the price-sync cycle.

Sniper Orders

Sniper orders are price-triggered buy orders managed by the SniperMonitorScheduler. Key fields:

FieldTypeDescription
triggerPriceDecimal(10,6)Price threshold that triggers execution
amountDecimal(18,6)Order size in USD
slippageDecimal(5,4)Maximum acceptable slippage (default 2%)
statusSniperStatusWATCHING, EXECUTING, FILLED, EXPIRED, CANCELLED, FAILED
expiresAtDateTimeExpiration timestamp
repeatBooleanWhether to re-arm after filling

The monitor checks active sniper orders against current market prices and triggers execution when conditions are met.

Counter-Trade Automation

The CounterTradeConfig model allows users to automatically trade inversely against a target wallet address:

FieldTypeDescription
targetWalletAddressStringWallet to counter-trade against
strategyStringinverse (default) -- take the opposite side
sizeMultiplierDecimal(5,2)Multiplier applied to the target's trade size
executionDelaySecIntDelay before executing the counter-trade
maxTradeSizeDecimal?Per-trade size cap
dailyStopLossDecimal?Daily loss limit before pausing
categoriesString[]Market categories to counter-trade in

The CounterTradeResetScheduler resets daily PnL and trade counts at midnight.

Order Fields Reference

Key fields on the Order model:

FieldTypeDescription
sideStringyes or no
typeStringmarket or limit
actionStringbuy or sell
priceDecimal(10,6)Order price
quantityDecimal(18,6)Requested quantity
filledQuantityDecimal(18,6)Quantity filled so far
avgFillPriceDecimal(10,6)?Average execution price
feeDecimal(18,6)Trading fee
exchangeStringpolymarket or kalshi
sourceStringmanual, copy-trade, sniper, counter-trade
copyTradeSubIdString?Link to copy trade subscription if applicable

On this page