DocsBacktest Enginefills

Market Order Fills

Market orders are the simplest order type. They fill at the next bar's open.

Fill Price Calculation

Fill Price = Next Bar Open × (1 + slippage × direction)

Where:

  • direction = +1 for buys (slippage works against you)
  • direction = -1 for sells

Example

Configuration:

// Backtest settings { slippage: 0.001 // 0.1% }

Bar i+1 opens at 100:

  • Market buy fills at: 100 × 1.001 = 100.10
  • Market sell fills at: 100 × 0.999 = 99.90

Guaranteed Fill

Market orders always fill (assuming sufficient balance). They cannot:

  • Partially fill
  • Be rejected
  • Expire

Gap Handling

If the market gaps significantly, market orders still fill at the open:

Bar i: Close = 100
Bar i+1: Open = 110 (10% gap up)
→ Market buy placed on Bar i fills at 110 (plus slippage)

This models reality: market orders in gapping markets can have significant slippage.

Code Example

function onBar(ctx, i) { if (q.crossOver(ctx.ind.fastEma, ctx.ind.slowEma, i)) { // Order placed here... ctx.order.market('ASSET', 1, { signal: 'buy' }); // ...fills on bar i+1 at open ± slippage } }

Fill Confirmation

You can track fills using state:

function init(ctx) { ctx.state.prevQty = 0; } function onBar(ctx, i) { const pos = ctx.position('ASSET'); // Detect fill by comparing to previous bar if (pos.qty > 0 && ctx.state.prevQty === 0) { // Just entered a position ctx.state.entryBar = i; ctx.state.entryPrice = pos.avgPrice; } ctx.state.prevQty = pos.qty; }

Related

enginefillsmarketslippageqsl