Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/theonetrade/backtest-kit/llms.txt

Use this file to discover all available pages before exploring further.

getOrderBook fetches the current or historical order book for a trading pair from the registered exchange adapter. Like the candle functions, it uses AsyncLocalStorage to read the current execution context and aligns the request time to a configured offset boundary so that backtest runs see a deterministically reproducible snapshot window. In live mode the from/to parameters are passed to the adapter but most exchanges (including Binance GET /api/v3/depth) only expose the current order book, so they are typically ignored by the live implementation.

IOrderBookData

interface IOrderBookData {
  symbol: string;
  bids: IBidData[]; // buy orders, highest price first
  asks: IBidData[]; // sell orders, lowest price first
}

interface IBidData {
  price: string;    // price level (string for precision)
  quantity: string; // quantity at this level (string for precision)
}
Bids and asks are returned as strings to preserve exchange-native precision without floating-point rounding.

getOrderBook

getOrderBook(symbol: string, depth?: number): Promise<IOrderBookData>
symbol
string
required
Trading pair symbol (e.g., "BTCUSDT").
depth
number
Maximum number of price levels to return for both bids and asks. Defaults to CC_ORDER_BOOK_MAX_DEPTH_LEVELS (default: 20).

Time-Range Alignment

The function computes a time window by aligning the execution context when to CC_ORDER_BOOK_TIME_OFFSET_MINUTES boundaries:
offsetMs   = CC_ORDER_BOOK_TIME_OFFSET_MINUTES * 60_000
alignedTo  = Math.floor(when / offsetMs) * offsetMs
to         = alignedTo
from       = alignedTo - offsetMs
Example with CC_ORDER_BOOK_TIME_OFFSET_MINUTES = 10 and when = 00:12:00 UTC:
FieldValue
alignedTo00:10:00 UTC
to00:10:00 UTC
from00:00:00 UTC
The computed (symbol, depth, from, to, backtest) are forwarded to the exchange adapter’s getOrderBook implementation.

Configuration Options

CC_ORDER_BOOK_TIME_OFFSET_MINUTES
number
Minutes used as the alignment window size. Controls how from and to are calculated for the order book request. Default: 10.
CC_ORDER_BOOK_MAX_DEPTH_LEVELS
number
Default depth levels for both bids and asks when depth is not explicitly passed to getOrderBook. Default: 20.
Set these via setConfig:
import { setConfig } from 'backtest-kit';

setConfig({
  CC_ORDER_BOOK_TIME_OFFSET_MINUTES: 5,  // 5-minute alignment windows
  CC_ORDER_BOOK_MAX_DEPTH_LEVELS: 50,    // request 50 levels
});

Exchange Adapter Contract

The exchange adapter receives:
getOrderBook(
  symbol: string,
  depth: number,
  from: Date,
  to: Date,
  backtest: boolean
): Promise<IOrderBookData>
from
Date
Start of the aligned time window. May be ignored in live implementations.
to
Date
End of the aligned time window (aligned down). May be ignored in live implementations.
backtest
boolean
true during backtest execution. Use this flag to switch between a historical snapshot database and the live exchange API.

Backtest vs Live

Most exchanges only expose the current order book with no historical query API. For backtest mode you must implement your own snapshot storage — typically a time-series database that captures order book state on a regular schedule — and return the closest snapshot to the requested [from, to] window.
A typical adapter pattern:
import { addExchangeSchema } from 'backtest-kit';

addExchangeSchema({
  exchangeName: 'binance',
  getCandles: async (symbol, interval, since, limit) => { /* ... */ },
  getOrderBook: async (symbol, depth, from, to, backtest) => {
    if (backtest) {
      // Return closest stored snapshot from your database
      return await db.getOrderBookSnapshot(symbol, depth, from, to);
    }
    // Live: fetch current book from exchange
    return await exchange.fetchOrderBook(symbol, depth);
  },
});
If getOrderBook is not provided in the exchange schema, calling getOrderBook() from a strategy will throw an error.

Usage Example

import { addStrategySchema, getOrderBook } from 'backtest-kit';

addStrategySchema({
  strategyName: 'order-book-strategy',
  interval: '1m',
  getSignal: async (symbol) => {
    const book = await getOrderBook(symbol, 10);

    const topBid = parseFloat(book.bids[0].price);
    const topAsk = parseFloat(book.asks[0].price);
    const spread = topAsk - topBid;
    const midPrice = (topBid + topAsk) / 2;

    const bidLiquidity = book.bids
      .slice(0, 5)
      .reduce((sum, b) => sum + parseFloat(b.quantity), 0);

    const askLiquidity = book.asks
      .slice(0, 5)
      .reduce((sum, a) => sum + parseFloat(a.quantity), 0);

    // Open long when bid-side liquidity dominates
    if (bidLiquidity / askLiquidity > 2) {
      return {
        position: 'long',
        priceTakeProfit: midPrice * 1.01,
        priceStopLoss: midPrice * 0.99,
      };
    }

    return null;
  },
});

Build docs developers (and LLMs) love