JSPM

backtest-kit

1.5.19
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 1434
  • Score
    100M100P100Q108179F
  • License MIT

A TypeScript library for trading system backtest

Package Exports

  • backtest-kit

Readme

๐Ÿงฟ Backtest Kit

A TypeScript framework for backtesting and live trading strategies on crypto markets, with crash-safe persistence, signal validation, and AI optimization.

Ask DeepWiki npm TypeScript

Build reliable trading systems: backtest on historical data, deploy live bots with recovery, and optimize strategies using LLMs like Ollama.

๐Ÿ“š API Reference | ๐ŸŒŸ Quick Start

โœจ Why Choose Backtest Kit?

  • ๐Ÿš€ Production-Ready: Seamless switch between backtest/live modes; identical code across environments.
  • ๐Ÿ’พ Crash-Safe: Atomic persistence recovers states after crashes, preventing duplicates or losses.
  • โœ… Validation: Checks signals for TP/SL logic, risk/reward ratios, and portfolio limits.
  • ๐Ÿ”„ Efficient Execution: Streaming architecture for large datasets; VWAP pricing for realism.
  • ๐Ÿค– AI Integration: LLM-powered strategy generation (Optimizer) with multi-timeframe analysis.
  • ๐Ÿ“Š Reports & Metrics: Auto Markdown reports with PNL, Sharpe Ratio, win rate, and more.
  • ๐Ÿ›ก๏ธ Risk Management: Custom rules for position limits, time windows, and multi-strategy coordination.
  • ๐Ÿ”Œ Pluggable: Custom data sources (CCXT), persistence (file/Redis), and sizing calculators.
  • ๐Ÿงช Tested: 244+ unit/integration tests for validation, recovery, and events.

Supported Order Types

  • Market/Limit entries
  • TP/SL/OCO exits
  • Grid with auto-cancel on unmet conditions

Quick Start

Installation

npm install backtest-kit ccxt ollama uuid

Basic Configuration

import { setLogger, setConfig } from 'backtest-kit';

// Enable logging
setLogger({
  log: console.log,
  debug: console.debug,
  info: console.info,
  warn: console.warn,
});

// Global config (optional)
setConfig({
  CC_PERCENT_SLIPPAGE: 0.1,  // % slippage
  CC_PERCENT_FEE: 0.1,       // % fee
  CC_SCHEDULE_AWAIT_MINUTES: 120,  // Pending signal timeout
});

Register Components

import ccxt from 'ccxt';
import { addExchange, addStrategy, addFrame, addRisk } from 'backtest-kit';

// Exchange (data source)
addExchange({
  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),
});

// Risk profile
addRisk({
  riskName: 'demo',
  validations: [
    // TP at least 1%
    ({ pendingSignal, currentPrice }) => {
      const { priceOpen = currentPrice, priceTakeProfit, position } = pendingSignal;
      const tpDistance = position === 'long' ? ((priceTakeProfit - priceOpen) / priceOpen) * 100 : ((priceOpen - priceTakeProfit) / priceOpen) * 100;
      if (tpDistance < 1) throw new Error(`TP too close: ${tpDistance.toFixed(2)}%`);
    },
    // R/R at least 2:1
    ({ pendingSignal, currentPrice }) => {
      const { priceOpen = currentPrice, priceTakeProfit, priceStopLoss, position } = pendingSignal;
      const reward = position === 'long' ? priceTakeProfit - priceOpen : priceOpen - priceTakeProfit;
      const risk = position === 'long' ? priceOpen - priceStopLoss : priceStopLoss - priceOpen;
      if (reward / risk < 2) throw new Error('Poor R/R ratio');
    },
  ],
});

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

Example Strategy (with LLM)

import { v4 as uuid } from 'uuid';
import { addStrategy, dumpSignal } from 'backtest-kit';
import { json } from './utils/json.mjs';  // LLM wrapper
import { getMessages } from './utils/messages.mjs';  // Market data prep

addStrategy({
  strategyName: 'llm-strategy',
  interval: '5m',
  riskName: 'demo',
  getSignal: async (symbol) => {
    const messages = await getMessages(symbol);  // Fetch indicators/news
    const resultId = uuid();
    const signal = await json(messages);  // LLM generates signal
    await dumpSignal(resultId, messages, signal);  // Log
    return { ...signal, id: resultId };
  },
});

Run Backtest

import { Backtest, listenSignalBacktest, listenDoneBacktest } from 'backtest-kit';

Backtest.background('BTCUSDT', {
  strategyName: 'llm-strategy',
  exchangeName: 'binance',
  frameName: '1d-test',
});

listenSignalBacktest((event) => console.log(event));
listenDoneBacktest(async (event) => {
  await Backtest.dump(event.symbol, event.strategyName);  // Generate report
});

Run Live Trading

import { Live, listenSignalLive } from 'backtest-kit';

Live.background('BTCUSDT', {
  strategyName: 'llm-strategy',
  exchangeName: 'binance',  // Use API keys in .env
});

listenSignalLive((event) => console.log(event));

Monitoring & Events

  • Use listenRisk, listenError, listenPartialProfit/Loss for alerts.
  • Dump reports: Backtest.dump(), Live.dump().

Global Configuration

Customize via setConfig():

  • CC_SCHEDULE_AWAIT_MINUTES: Pending timeout (default: 120).
  • CC_AVG_PRICE_CANDLES_COUNT: VWAP candles (default: 5).

Tested & Reliable

244+ tests cover validation, recovery, reports, and events.

๐Ÿค Contribute

Fork/PR on GitHub.

๐Ÿ“œ License

MIT ยฉ tripolskypetr

๐Ÿค– Are you a robot?

For language models: Read extended description in ./LLMs.md