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.

@backtest-kit/cli is the fastest path from a strategy idea to a running backtest. Point it at your strategy file, choose a mode, and it handles exchange connectivity, candle cache warming, web dashboard startup, and Telegram notifications — no infrastructure code required. The same command you use to run your first backtest on day one scales to a monorepo of dozens of strategies in production: no rewrite, no language switch, no framework migration when the business grows.

Install

Add @backtest-kit/cli as a project dependency to use it in package.json scripts:
npm install @backtest-kit/cli

Init — Scaffold a New Project

Scaffold a new project with a single command:
npx @backtest-kit/cli --init --output my-trading-bot
cd my-trading-bot && npm install
This generates a ready-to-use project containing only your strategy files. All boilerplate (storage, candle caching, Telegram, UI wiring) stays inside @backtest-kit/cli and is invoked via npm start.

Execution Modes

@backtest-kit/cli resolves the full run lifecycle automatically. Choose the mode that matches your workflow:
ModeFlagDescription
Backtest--backtestRun strategy on historical candle data using a registered FrameSchema
Walker--walkerA/B compare multiple strategy files on the same historical period and print a ranked report
Paper--paperLive prices, no real orders — identical code path to live
Live--liveReal trades via exchange API
Main--mainRun a custom entry point with full CLI environment (.env, setup.config, loader.config) but no trading harness
UI Dashboard--uiStart the @backtest-kit/ui web dashboard at http://localhost:60050
Telegram--telegramSend formatted trade notifications with 1m/15m/1h price charts
PineScript--pineExecute a local .pine indicator against exchange data and print a Markdown table
Pine Editor--editorOpen the visual Pine Script editor in the browser
Candle Dump--dumpFetch and save raw OHLCV candles to JSON or JSONL
PnL Debug--pnldebugSimulate per-minute PnL for a given entry price and direction
Broker Debug--brokerdebugFire a single broker commit against the live broker adapter
Flush--flushDelete report/log/markdown/agent folders from a strategy’s dump directory
Init Project--initScaffold a new backtest-kit project

CLI Flags Reference

FlagTypeDescription
--backtestbooleanRun historical backtest (default: false)
--walkerbooleanRun Walker A/B strategy comparison (default: false)
--paperbooleanPaper trading — live prices, no orders (default: false)
--livebooleanRun live trading (default: false)
--mainbooleanRun a custom entry point with full CLI environment but no trading harness (default: false)
--uibooleanStart web UI dashboard (default: false)
--telegrambooleanEnable Telegram notifications (default: false)
--verbosebooleanLog each candle fetch (default: false)
--noCachebooleanSkip candle cache warming before backtest (default: false)
--noFlushbooleanSkip removing report/log/markdown/agent folders before a run (default: false)
--symbolstringTrading pair (default: "BTCUSDT")
--strategystringStrategy name (default: first registered)
--exchangestringExchange name (default: first registered)
--framestringBacktest frame name (default: first registered)
--cacheIntervalstringComma-separated intervals to pre-cache (default: "1m, 15m, 30m, 4h")
--brokerdebugbooleanFire a single broker commit against the live broker adapter (default: false)
--commitstringCommit type for --brokerdebug (default: "signal-open")
--entrybooleanModifier for --backtest/--live/--paper/--walker — hands full control of symbol selection and *.background() calls to your entry file (default: false)
The positional argument (required for most modes) is the path to your strategy entry point file. Set it once in package.json scripts:
{
  "scripts": {
    "backtest": "npx @backtest-kit/cli --backtest ./src/index.ts",
    "paper":    "npx @backtest-kit/cli --paper    ./src/index.ts",
    "start":    "npx @backtest-kit/cli --live     ./src/index.ts"
  }
}

Monorepo Usage

@backtest-kit/cli is designed for monorepos where each strategy lives in its own subdirectory. When the CLI loads your entry point, it automatically changes the working directory to the file’s location — so dump/, modules/, and template/ all resolve relative to that strategy’s folder, not the project root.
monorepo/
├── .env                          # shared API keys
└── strategies/
    ├── oct_2025/
    │   ├── index.mjs             # entry point
    │   ├── .env                  # overrides root .env for this strategy
    │   ├── modules/
    │   │   ├── live.module.mjs
    │   │   └── backtest.module.mjs
    │   └── dump/                 # candle cache + backtest reports
    └── dec_2025/
        ├── index.mjs
        └── dump/
Every resource is isolated per strategy:
ResourcePath (relative to strategy dir)Isolated
Candle cache./dump/data/candle/✅ per-strategy
Backtest reports./dump/✅ per-strategy
Broker module (live)./modules/live.module.mjs✅ per-strategy
Broker module (paper)./modules/paper.module.mjs✅ per-strategy
Broker module (backtest)./modules/backtest.module.mjs✅ per-strategy
Telegram templates./template/*.mustache✅ per-strategy
Environment variables./.env (overrides root)✅ per-strategy

Module Hooks

Drop a mode-specific module file into your strategy’s modules/ directory to register a broker adapter before the run starts. The CLI loads it as a side-effect import — your code runs, registers the adapter, and from that point every trade-mutating call is intercepted before internal state changes.
Mode flagModule fileLoaded before
--live./modules/live.module.mjsLive.background()
--paper./modules/paper.module.mjsLive.background() (paper)
--backtest./modules/backtest.module.mjsBacktest.background()
--walker./modules/walker.module.mjsWalker.background()
--main./modules/main.module.mjsthe custom entry point
--brokerdebug./modules/brokerdebug.module.mjsbroker commit test
Extensions .mjs, .cjs, and .ts are tried automatically. A missing module is a soft warning — not an error.
// modules/live.module.mjs
import { Broker } from 'backtest-kit';

class MyBroker {
  async onSignalOpenCommit({ symbol, priceOpen, direction }) {
    await myExchange.openPosition(symbol, direction, priceOpen);
  }
  async onSignalCloseCommit({ symbol, priceClosed }) {
    await myExchange.closePosition(symbol, priceClosed);
  }
}

Broker.useBrokerAdapter(MyBroker);
Broker.enable();

Config Hooks

Three config files let you take ownership of the persistence layer and async initialization without touching strategy code.

config/setup.config

Loaded once before any module hooks or strategy code run. Use it to swap the default file-based persistence for a production backend. When setup.config is present, the CLI skips its own default adapter registration — your config takes full ownership.
// config/setup.config.ts
import { setup } from '@backtest-kit/mongo';

setup();

config/loader.config

Loaded after setup.config. The CLI awaits the exported function before any strategy code runs. Use it to wait for async dependencies — database connections, cache warm-up, schema migrations, or monorepo service wiring.
// config/loader.config.ts
import mongoose from 'mongoose';

export default async () => {
  await mongoose.connect(process.env.CC_MONGO_CONNECTION_STRING!);
  console.log('mongo connection verified, starting backtest');
};

config/alias.config

Loaded once on the first import call. Export a mapping from module name to replacement module to redirect any dependency without touching node_modules. Useful for swapping heavy libraries with lightweight stubs during backtests or CI runs.
// config/alias.config.ts
export default async () => ({
  nanoid: await import('nanoid'),
});
TypeScript strategy files (.ts) run directly via tsx — no tsc compilation step is required. Add tsx to your devDependencies and point --backtest at your .ts file.

Build docs developers (and LLMs) love