Skip to main content
Order execution handles the placement of market orders on the Lighter exchange (live mode) or against simulated order books (simulation mode), with robust fill tracking to verify actual execution prices and quantities.

Execution Flow

1

Order Placement

Create order on exchange or simulator with market order type
2

Transaction Tracking

Poll transaction status until executed, failed, or rejected
3

Fill Verification

Query order status API to get actual filled quantity and average price
4

Database Persistence

Save position to Orders table with real fill details
5

SL/TP Placement

Place stop-loss and take-profit orders if specified in exit plan

Live Order Execution

Creating Orders

Orders are placed via the Lighter SignerClient with Immediate-Or-Cancel (IOC) time-in-force.
Location: src/server/features/trading/createPosition.ts:456 Key Parameters:
  • baseAmount: Quantity scaled by market decimals (e.g., 1.5 BTC → 150000000)
  • price: Limit price with 1% buffer for market orders (prevents rejection)
  • isAsk: false for LONG (buy), true for SHORT (sell)
  • orderType: ORDER_TYPE_MARKET (0) for immediate execution
  • timeInForce: IMMEDIATE_OR_CANCEL fills immediately or cancels unfilled portion

Fill Tracking

The trackFill function uses exponential backoff polling to verify order execution and extract actual fill details.
Location: src/server/features/trading/fillTracker.ts:72 Transaction Status Codes:
Fill Verification Steps:
  1. waitForTransaction(): Poll transaction until status is EXECUTED (3)
  2. checkOrderStatus(): Query OrderAPI for fill amount and average price
  3. Fallback: If order status unavailable, fetch recent trades from AccountAPI
  4. Conservative assumption: If all else fails, assume full fill (logged as warning)
The fallback assumes full fill to prevent stuck workflows, but logs a warning. In production, you should monitor these cases and investigate API issues.

Partial Fills

Partial fills occur when order book depth is insufficient to fill the entire order.
Handling:
  • System accepts partial fills and creates position with actual filled quantity
  • Logs warning: Partial fill: requested=X, filled=Y
  • Database stores actual filled quantity, not requested quantity

Simulated Execution

The simulator matches orders against cached order book snapshots using a realistic matching engine.
Location: src/server/features/simulator/orderMatching.ts:21 Matching Algorithm:
  1. Identify aggressing side (buy → asks, sell → bids)
  2. Walk order book levels from best price
  3. Fill against each level until quantity exhausted or book empty
  4. Calculate weighted average price from all fills
  5. Return partial fill if remaining quantity > 0
Realism Features:
  • Actual order book depth from Lighter API
  • Partial fills when liquidity insufficient
  • Volume-weighted average price calculation
  • Slippage modeling through multi-level fills

Position Scaling

When opening a position for a symbol with an existing OPEN position of the same side, the system scales into the position rather than creating a new one.
Location: src/server/features/trading/createPosition.ts:569 Weighted Average Entry Price:
Example:
  • Existing position: 1.0 BTC @ $50,000
  • New execution: 0.5 BTC @ $51,000
  • Result: 1.5 BTC @ $50,333 (weighted average)
When scaling in, SL/TP orders are cancelled and replaced with new orders reflecting the updated quantity and average entry price.

Closing Positions

Closing a position places a reverse order (LONG → sell, SHORT → buy) with reduceOnly: true.
Location: src/server/features/trading/closePosition.ts:226 Close Flow:
  1. Cancel any existing SL/TP orders
  2. Place reverse market order with reduceOnly: true
  3. Track fill to get actual exit price
  4. Calculate realized P&L
  5. Update Orders table: set status=CLOSED, exitPrice, realizedPnl, closedAt

Error Handling

Causes:
  • Invalid market parameters
  • Insufficient account balance
  • Exchange connectivity issues
Handling:
  • Return error in PositionResult
  • Log error message
  • Do not persist to database
  • Agent receives error and can retry with different parameters
Causes:
  • Network congestion
  • Exchange processing delays
  • Transaction stuck in pending state
Handling:
  • waitForTransaction() times out after 30 seconds
  • Return error: “Transaction tracking failed: timeout”
  • Position creation aborted
  • Agent can retry in next invocation
Causes:
  • Order API unavailable
  • Order not indexed yet
  • Authentication token issues
Handling:
  • Try fallback: fetch recent trades from AccountAPI
  • If fallback fails: assume full fill (logged as warning)
  • Position persisted with conservative assumption
  • Monitor logs for frequent fallback usage
Causes:
  • Insufficient order book depth
  • Large order size relative to liquidity
Handling:
  • Accept partial fill
  • Create position with actual filled quantity
  • Log warning for monitoring
  • Database stores actual quantity, not requested

Best Practices

Always Track Fills

Never assume order execution succeeded. Always use trackFill() to verify actual filled quantity and average price.

Handle Partial Fills

Design your system to gracefully handle partial fills. Store actual filled quantities, not requested amounts.

Use Reduce-Only for Closes

Always set reduceOnly: true when closing positions to prevent accidental position flips.

Cancel SL/TP Before Close

Always cancel existing SL/TP orders before manually closing a position to prevent race conditions.

Next Steps

Position Management

Learn about position tracking and exit plans

Risk Controls

Explore risk management and position sizing