Skip to main content

Documentation Index

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

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

This page is the fastest path from zero to a working strategy. You will scaffold a project, register an exchange, define a time frame, wire up a strategy, and run your first backtest — all with real code and no boilerplate to write by hand. The CLI handles the infrastructure; you focus on the signal.
1

Scaffold the project

Run the CLI init command to generate a minimal project. All bootstrap wiring lives inside @backtest-kit/cli — your project only contains strategy files.
npx @backtest-kit/cli --init --output my-trading-bot
cd my-trading-bot
npm install
The generated directory contains a preconfigured package.json, an example strategy entry point under content/, utility scripts, and automatically fetched library documentation under docs/lib/.
You can override the output directory name with any value: --output my-algo-desk, --output btc-scalper, etc.
2

Register an exchange schema

Open (or create) your strategy entry point — for example src/index.ts. Register a data source using addExchangeSchema from backtest-kit. The example below connects to Binance via CCXT.
import ccxt from 'ccxt';
import { addExchangeSchema } from 'backtest-kit';

addExchangeSchema({
  exchangeName: 'binance',
  getCandles: async (symbol, interval, since, limit) => {
    const exchange = new ccxt.binance();
    const ohlcv = await exchange.fetchOHLCV(symbol, interval, since.getTime(), limit);
    return ohlcv.map(([timestamp, open, high, low, close, volume]) => ({
      timestamp, open, high, low, close, volume,
    }));
  },
  formatPrice: (symbol, price) => price.toFixed(2),
  formatQuantity: (symbol, quantity) => quantity.toFixed(8),
});
The getCandles adapter is the only integration point with your data source. In live mode it fetches from the exchange API; in backtest mode the CLI pre-warms the candle cache so no live calls are made during replay.
3

Register a frame and strategy

A FrameSchema defines the historical window for your backtest. A StrategySchema defines the interval your strategy ticks on and the getSignal function that produces trading signals.
import { addFrameSchema, addStrategySchema } from 'backtest-kit';

// Backtest window
addFrameSchema({
  frameName: '1d-test',
  interval: '1m',
  startDate: new Date('2025-12-01'),
  endDate: new Date('2025-12-02'),
});

// Strategy
addStrategySchema({
  strategyName: 'my-strategy',
  interval: '15m',
  getSignal: async (symbol) => {
    // Return a signal object or null to skip this tick.
    // Use getCandles(symbol, interval, limit) here to read market data.
    return null;
  },
});
getSignal runs inside an ambient temporal context powered by AsyncLocalStorage. Every call to getCandles inside this function automatically uses the current virtual time — look-ahead bias is structurally impossible.
4

Run the backtest

Point the CLI at your entry file and provide a symbol. The CLI pre-warms the candle cache, replays the frame, calls your getSignal on every tick, and writes a Markdown report when done.
npx @backtest-kit/cli --backtest ./src/index.ts --symbol BTCUSDT
You can also add these as package.json scripts for convenience:
{
  "scripts": {
    "backtest": "npx @backtest-kit/cli --backtest ./src/index.ts --symbol BTCUSDT",
    "paper":    "npx @backtest-kit/cli --paper    ./src/index.ts --symbol BTCUSDT",
    "start":    "npx @backtest-kit/cli --live     ./src/index.ts --symbol BTCUSDT"
  }
}
Add --ui to launch the interactive web dashboard at http://localhost:60050, and --telegram to receive formatted trade notifications with price charts in a Telegram channel.
5

View results and switch to live trading

After the backtest finishes, a Markdown report is written to ./dump/ containing PNL, Sharpe Ratio, win rate, Max Drawdown, and per-signal details. Inspect it directly or open the UI dashboard.When you’re ready to go live, change one flag:
# Paper trading — live prices, no real orders
npx @backtest-kit/cli --paper ./src/index.ts --symbol BTCUSDT

# Live trading — real orders via broker adapter
npx @backtest-kit/cli --live ./src/index.ts --symbol BTCUSDT
The same entry file, the same schemas, and the same getSignal function drive all three modes. For live order placement, drop a modules/live.module.ts file that calls Broker.useBrokerAdapter() — the CLI loads it automatically before starting the live run.

Complete Minimal Example

Here is the full minimal entry point that combines all the steps above into a single file — ready to run with the CLI.
import ccxt from 'ccxt';
import {
  addExchangeSchema,
  addFrameSchema,
  addStrategySchema,
} from 'backtest-kit';

// 1. Exchange — data source via CCXT
addExchangeSchema({
  exchangeName: 'binance',
  getCandles: async (symbol, interval, since, limit) => {
    const exchange = new ccxt.binance();
    const ohlcv = await exchange.fetchOHLCV(symbol, interval, since.getTime(), limit);
    return ohlcv.map(([timestamp, open, high, low, close, volume]) => ({
      timestamp, open, high, low, close, volume,
    }));
  },
  formatPrice: (symbol, price) => price.toFixed(2),
  formatQuantity: (symbol, quantity) => quantity.toFixed(8),
});

// 2. Frame — historical backtest window
addFrameSchema({
  frameName: '1d-test',
  interval: '1m',
  startDate: new Date('2025-12-01'),
  endDate: new Date('2025-12-02'),
});

// 3. Strategy — signal generation logic
addStrategySchema({
  strategyName: 'my-strategy',
  interval: '15m',
  getSignal: async (symbol) => {
    // Add your signal logic here.
    // Call getCandles(symbol, '15m', 60) to read recent candles.
    // Return a signal object with priceOpen, priceTakeProfit,
    // priceStopLoss, and position ('long' | 'short'), or null to skip.
    return null;
  },
});
Run it:
npx @backtest-kit/cli --backtest ./src/index.ts --symbol BTCUSDT
The reference implementation for a production-ready strategy is the AI news sentiment bot — a fully working system with LLM forecasting, multi-timeframe data, and a documented February 2026 backtest that achieved +16.99% during a -16.4% market month. Start from there when you’re ready to move beyond the minimal scaffold.

Next Steps

Signal Lifecycle

Understand how a signal moves from getSignal through validation, scheduling, activation, partial commits, and final close.

Running Backtests

Learn how to configure frames, warm candle caches, generate reports, and compare strategies with the Walker A/B tool.

Examples

Explore real strategy implementations: neural networks, Pine Script breakouts, LLM sentiment, DCA ladders, and more.

Build docs developers (and LLMs) love