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 uses sensible defaults for all configuration — override only what you need. The configuration is global and process-wide; values set with setConfig apply to every strategy, exchange, and frame registered in the same process.
Call setConfig and setLogger before registering any schemas (addStrategySchema, addExchangeSchema, etc.) and before calling Backtest.background() or Live.background(). Configuration values are read at runtime, but schema validation (e.g. ConfigValidationService) runs during schema registration and may reject invalid combinations.

setConfig(options)

Updates the global configuration. Accepts a partial object — only the keys you provide are changed; all others retain their defaults.
import { setConfig } from 'backtest-kit';

setConfig({
  CC_PERCENT_SLIPPAGE: 0.05,       // 0.05% slippage per side
  CC_PERCENT_FEE: 0.1,             // 0.10% fee per side
  CC_SCHEDULE_AWAIT_MINUTES: 60,   // 1 hour timeout for scheduled signals
});

Configuration Options

CC_PERCENT_SLIPPAGE
number
default:"0.1"
Slippage percentage applied to entry and exit prices, simulating market impact. Expressed as a percentage (e.g. 0.1 = 0.1%). Applied per side: once when the position opens and once when it closes. See the PnL formula below for how slippage affects the final result.
CC_PERCENT_FEE
number
default:"0.1"
Trading fee percentage applied to entry and exit prices. Expressed as a percentage (e.g. 0.1 = 0.1%). Applied per side like slippage. Represents the exchange maker/taker fee.
CC_SCHEDULE_AWAIT_MINUTES
number
default:"120"
Minutes before a scheduled signal (pending entry at a limit price) times out and is automatically cancelled. After this duration, the signal is discarded and the strategy returns to idle, free to generate a new signal. Set to a large value (e.g. 99999) for signals that should wait indefinitely.
CC_AVG_PRICE_CANDLES_COUNT
number
default:"5"
Number of 1-minute candles used to compute the VWAP price for all entry and exit decisions. Increasing this value smooths the VWAP over a longer window; decreasing it makes it more responsive to recent price action. Also used by getAveragePrice().
CC_ORDER_BOOK_TIME_OFFSET_MINUTES
number
Time window in minutes for order book alignment. getOrderBook() aligns the request to the nearest multiple of this value. For example, with CC_ORDER_BOOK_TIME_OFFSET_MINUTES = 10, a call at 00:12 UTC will align to the [00:00, 00:10) window.
CC_ORDER_BOOK_MAX_DEPTH_LEVELS
number
Default depth (number of bid/ask levels) passed to the exchange adapter’s getOrderBook implementation when depth is not explicitly provided to getOrderBook().
CC_AGGREGATED_TRADES_MAX_MINUTES
number
Time window in minutes for a single getAggregatedTrades fetch page. When paginating (with a limit argument), the function fetches in chunks of this width, going backwards until enough trades are collected.

setLogger(options)

Plugs in a custom logging implementation. The framework adds context (strategy name, exchange name, symbol) to each log message automatically. Calling setLogger before any other setup ensures all internal lifecycle messages are captured.
import { setLogger } from 'backtest-kit';

setLogger({
  log: console.log,
  debug: console.debug,
  info: console.info,
  warn: console.warn,
});
log
(...args: unknown[]) => void
required
General-purpose log function. Used for important state changes and lifecycle events (position opened, signal persisted, etc.).
debug
(...args: unknown[]) => void
required
Debug-level log function. Used for detailed internal events (candle alignment calculations, cache hits/misses, etc.). Safe to set to a no-op in production.
info
(...args: unknown[]) => void
required
Info-level log function. Used for successful high-level operations (schema registered, backtest started, etc.).
warn
(...args: unknown[]) => void
required
Warning-level log function. Used for recoverable anomalies (signal rejected by validation, missing data, deprecated usage patterns).

Environment Variables (CLI / Docker)

When using @backtest-kit/cli or the Docker deployment, the following environment variables configure optional integrations. These are read at CLI startup, not via setConfig.
# Telegram alerts — send trade notifications to a Telegram channel
CC_TELEGRAM_TOKEN=your-bot-token
CC_TELEGRAM_CHANNEL=@your_channel

# @backtest-kit/ui web dashboard
CC_WWWROOT_HOST=0.0.0.0
CC_WWWROOT_PORT=8080

# QuickChart server (used by @backtest-kit/ui for candlestick chart images)
CC_QUICKCHART_HOST=https://quickchart.io
CC_TELEGRAM_TOKEN
string
Telegram Bot API token. When set along with CC_TELEGRAM_CHANNEL, the CLI sends formatted trade notifications (opened, closed, PnL) to the specified channel.
CC_TELEGRAM_CHANNEL
string
Telegram channel username (e.g. @my_trading_alerts) or numeric chat ID.
CC_WWWROOT_HOST
string
Host to bind the @backtest-kit/ui dashboard server to. Defaults to 0.0.0.0.
CC_WWWROOT_PORT
number
Port for the @backtest-kit/ui dashboard server. Defaults to 8080.
CC_QUICKCHART_HOST
string
Base URL for the QuickChart service used to render candlestick chart images in Telegram notifications. Defaults to https://quickchart.io. Set to a self-hosted instance for air-gapped deployments.

PnL Calculation Formula

Backtest Kit applies slippage and fee to both entry and exit prices. The direction of slippage depends on the position side — slippage always works against the trader.
const slippage = CC_PERCENT_SLIPPAGE / 100;  // e.g. 0.001 for 0.1%
const fee      = CC_PERCENT_FEE / 100;        // e.g. 0.001 for 0.1%

// ── LONG position ──────────────────────────────────────────────────────────
// Entry: slippage pushes price UP (you pay more), fee is also a cost
priceOpenWithCosts  = priceOpen  * (1 + slippage + fee);

// Exit: slippage pushes price DOWN (you receive less), fee is also a cost
priceCloseWithCosts = priceClose * (1 - slippage - fee);

pnlPercent = (priceCloseWithCosts - priceOpenWithCosts) / priceOpenWithCosts * 100;

// ── SHORT position ──────────────────────────────────────────────────────────
// Entry: slippage pushes price DOWN (you sell for less), fee is a cost
priceOpenWithCosts  = priceOpen  * (1 - slippage + fee);

// Exit: slippage pushes price UP (you buy back for more), fee is also a cost
priceCloseWithCosts = priceClose * (1 + slippage + fee);

pnlPercent = (priceOpenWithCosts - priceCloseWithCosts) / priceOpenWithCosts * 100;
Example (LONG): Entry at 1000, exit at 1100, slippage 0.1%, fee 0.1%:
  • priceOpenWithCosts = 1000 * (1 + 0.001 + 0.001) = 1002.00
  • priceCloseWithCosts = 1100 * (1 - 0.001 - 0.001) = 1097.80
  • pnlPercent = (1097.80 - 1002.00) / 1002.00 * 100 ≈ +9.56%
The breakeven threshold — the minimum price move required to produce a positive PnL net of costs — is approximately 2 * (slippage + fee) = 0.4% with default settings. The getBreakeven(symbol, currentPrice) helper checks this threshold automatically.

getConfig() and getDefaultConfig()

Read the current configuration or retrieve a copy of the defaults:
import { getConfig, getDefaultConfig } from 'backtest-kit';

const current  = getConfig();          // current merged config
const defaults = getDefaultConfig();   // factory defaults (read-only copy)

console.log(current.CC_PERCENT_FEE);   // e.g. 0.1
Both functions return a copy — mutations to the returned object have no effect on the live configuration.

Build docs developers (and LLMs) love