Skip to main content

Documentation Index

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

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

This guide walks you through every step needed to go from a fresh clone to a running backtest: launching the MinIO and Redis infrastructure containers, configuring credentials in .env, building the compiled strategy bundle, and running the runner in backtest, live, or paper mode. The entire flow — infrastructure up through first execution — takes under 5 minutes.
1

Clone the repository and verify prerequisites

Before you begin, make sure the following are installed on your machine:
  • Node.js 18 or later — the CLI and build toolchain require the native parseArgs API introduced in Node 18.
  • Docker and Docker Compose — used to run the MinIO and Redis infrastructure containers.
Clone the repository and install dependencies:
git clone https://github.com/theonetrade/backtest-kit-minio-s3-docker.git
cd backtest-kit-minio-s3-docker
npm install
The project uses Rollup to bundle your strategy into a single CommonJS file at ./build/index.cjs. The @backtest-kit/cli package is the runner that the npm scripts delegate to.
2

Start MinIO

MinIO provides the S3-compatible object store that all 16 persist adapters write to. Start it with the dedicated Compose file under docker/minio/:
docker-compose -f docker/minio/docker-compose.yaml up -d
This launches the following service:
services:
  minio:
    image: docker.io/tripolskypetr/minio:2022
    ports:
      - '9000:9000'   # S3 API endpoint
      - '9001:9001'   # MinIO web console
    volumes:
      - './minio_data:/data'
    environment:
      - MINIO_ROOT_USER=minioadmin
      - MINIO_ROOT_PASSWORD=minioadmin
      - MINIO_DEFAULT_BUCKETS=backtest-kit
    restart: always
volumes:
  minio_data:
MinIO exposes:
  • :9000 — the S3 API endpoint consumed by the adapters.
  • :9001 — the browser-based MinIO Console for inspecting buckets and objects.
The MINIO_DEFAULT_BUCKETS=backtest-kit environment variable pre-creates the backtest-kit bucket on first boot. All 16 persist adapters share this single bucket using folder prefixes (e.g. candle-items/, log-items/), so no manual bucket creation is required. You can browse and inspect all stored objects at http://localhost:9001 using the credentials minioadmin / minioadmin.
3

Start Redis

Redis maintains the time-ordered minute-bucket index for the three entities that require newest-first listings: Log, Notification, and Storage. Start it with the dedicated Compose file under docker/redis/:
docker-compose -f docker/redis/docker-compose.yaml up -d
This launches the following service:
version: '3.8'

services:
  redis:
    image: redis:7.4.1
    container_name: redis
    ports:
      - "6379:6379"
    environment:
      - REDIS_PASSWORD=mysecurepassword
    command: ["redis-server", "--requirepass", "mysecurepassword"]
    volumes:
      - ./redis_data:/data
    restart: always

volumes:
  redis_data:
Redis is started with password authentication (mysecurepassword). The Redis data is persisted to ./redis_data on the host, so the minute-bucket index survives container restarts. If the index is lost (e.g. after redis-cli FLUSHALL), the adapters fall back automatically to S3 prefix listings and re-warm the index in the same pass.
4

Configure environment variables

Copy the example file and edit the values to match your local setup:
cp .env.example .env
The .env.example file contains:
# Infrastructure endpoints as seen from the backtest-kit container
# (docker-compose.yaml maps host.docker.internal to the host gateway).
# For a host-node run replace host.docker.internal with 127.0.0.1.

# MinIO (S3) — source of truth, see docker/minio/docker-compose.yaml
CC_MINIO_ENDPOINT=host.docker.internal
CC_MINIO_PORT=9000
CC_MINIO_ACCESSKEY=minioadmin
CC_MINIO_SECRETKEY=minioadmin

# Redis — time-ordered index, see docker/redis/docker-compose.yaml
CC_REDIS_HOST=host.docker.internal
CC_REDIS_PORT=6379
CC_REDIS_USER=default
CC_REDIS_PASSWORD=mysecurepassword
VariableDefaultDescription
CC_MINIO_ENDPOINThost.docker.internalHostname or IP of the MinIO S3 API. Use host.docker.internal inside Docker; use 127.0.0.1 for host-node runs.
CC_MINIO_PORT9000S3 API port exposed by the MinIO container.
CC_MINIO_ACCESSKEYminioadminMinIO root user (matches MINIO_ROOT_USER in the MinIO Compose file).
CC_MINIO_SECRETKEYminioadminMinIO root password (matches MINIO_ROOT_PASSWORD).
CC_REDIS_HOSThost.docker.internalHostname of the Redis instance.
CC_REDIS_PORT6379Redis port.
CC_REDIS_USERdefaultRedis ACL username (use default for password-only auth).
CC_REDIS_PASSWORDmysecurepasswordRedis password (matches --requirepass in the Redis Compose file).
If you are running the Node.js process directly on the host (not inside Docker), change CC_MINIO_ENDPOINT and CC_REDIS_HOST from host.docker.internal to 127.0.0.1. The host.docker.internal alias is only resolvable inside a Docker container.
5

Build the strategy bundle

Rollup compiles your TypeScript strategy into a single CommonJS bundle at ./build/index.cjs:
npm run build
The build step is also run automatically by the start and start:docker npm scripts, so you only need to run it manually if you want to separate the compile step from execution (e.g. in CI).
If you need to inspect the compiled output interactively, use the REPL script:
npm run start:repl
This loads environment variables from .env via dotenv-cli, builds the bundle, then starts an interactive Node.js session with the strategy module already require()d — useful for ad-hoc inspection of adapter state or exported strategy values.
6

Run your first backtest

With MinIO and Redis running and the bundle built, start the backtest runner:
npm run start -- --entry --backtest --ui ./build/index.cjs
The --entry flag gates execution in src/main/backtest.ts — without it the runner starts but no strategy is launched. --backtest selects backtest mode. --ui enables the web UI on port 60050.What happens on startup:
  1. The Redis service initialises and waits for the connection (ioc.redisService.waitForInit()).
  2. waitForReady(true) registers all 16 persist adapters and gates on first-touch infrastructure readiness.
  3. warmCandles(...) fetches historical OHLCV data from the exchange and stores it in the candle-items/ prefix in MinIO.
  4. Backtest.background(...) launches the strategy loop against the cached candles.
The web UI is available at http://localhost:60050 once the runner is ready. You can monitor positions, signals, logs, and notifications in real time without any additional setup.

Running in all three modes

Replays historical candle data against your strategy. warmCandles is called first to fetch and cache OHLCV data in MinIO, then Backtest.background drives the simulation.
npm run start -- --entry --backtest --ui ./build/index.cjs
The backtest mode entry point (src/main/backtest.ts) waits for Redis, warms candles for the configured date range, then runs the strategy against the cached data.

Additional CLI flags

The src/helpers/getArgs.ts wrapper parses four boolean flags locally (--entry, --backtest, --live, --paper) using Node’s built-in parseArgs with strict: false, which means any additional flags are forwarded transparently to the underlying @backtest-kit/cli runner. The following flags are consumed by that runner:
FlagDescription
--uiEnable the web UI on :60050. Pass the path to your bundle as the value (e.g. ./build/index.cjs).
--telegramEnable Telegram notifications (configure bot token in your strategy).
--verboseEmit verbose debug logging from the runner.
--no-cacheDisable the runner’s in-process key cache.
--no-flushSkip flushing internal state on shutdown.

Full Docker deploy

For a fully containerised deployment — strategy bundle, runner, and backtest-kit runtime all inside a single container — use the root docker-compose.yaml. It pulls the tripolskypetr/backtest-kit image, mounts the project directory as /workspace, and reads runtime configuration from environment variables and .env.

Main docker-compose.yaml

version: '3.8'

services:
  backtest:
    image: tripolskypetr/backtest-kit
    platform: linux/amd64
    extra_hosts:
      - "host.docker.internal:host-gateway"
    container_name: backtest-kit-minio-s3-docker
    ports:
      - "60050:60050"
    restart: unless-stopped
    volumes:
      - ./:/workspace
    working_dir: /workspace
    environment:
      - MODE
      - STRATEGY_FILE
      - SYMBOL
      - STRATEGY
      - EXCHANGE
      - FRAME
      - UI
      - TELEGRAM
      - VERBOSE
      - NO_CACHE
      - NO_FLUSH
      - ENTRY
    env_file:
      - .env
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:60050/api/v1/health/health_check"]
      interval: 30s
      timeout: 10s
      retries: 3
The extra_hosts: host.docker.internal:host-gateway mapping ensures the container can reach MinIO on :9000 and Redis on :6379 running on the host via the host.docker.internal hostname defined in .env.

Container environment variables

VariablePurpose
MODEbacktest | live | paper — selects the runner entrypoint.
STRATEGY_FILEPath to the compiled strategy bundle inside /workspace (default: ./build/index.cjs).
ENTRYSet to 1 to actually run the strategy (mirrors the --entry CLI flag).
SYMBOLOverride the trading symbol in the strategy context.
STRATEGYOverride the strategy name.
EXCHANGEOverride the exchange name.
FRAMEOverride the frame name.
UISet to 1 to enable the web UI on :60050.
TELEGRAMEnable Telegram notifications.
VERBOSEEnable verbose logging.
NO_CACHEDisable the in-process key cache.
NO_FLUSHSkip flushing the Redis index on shutdown.

Launch commands

MODE=backtest ENTRY=1 UI=1 STRATEGY_FILE=./build/index.cjs docker-compose up -d
docker-compose logs -f
The npm run start:docker script is equivalent to:
npm run build && cross-env MODE=backtest ENTRY=1 UI=1 STRATEGY_FILE=./build/index.cjs docker-compose up -d
It builds the strategy bundle first, then launches the container with MODE=backtest, ENTRY=1, and UI=1 pre-set.
After the container starts, the MinIO Console is available at http://localhost:9001 (credentials: minioadmin / minioadmin) for inspecting bucket contents and object metadata. The backtest-kit web UI — showing live positions, signals, logs, and notifications — is available at http://localhost:60050 once the runner reports healthy (the healthcheck pings /api/v1/health/health_check every 30 seconds).

Debugging

Use the start:debug script to attach a Node.js debugger (e.g. Chrome DevTools or VS Code) to the running strategy process:
npm run start:debug
This passes --inspect-brk to Node, which pauses execution at the first line until a debugger connects on port 9229.
The tripolskypetr/backtest-kit Docker image is built for linux/amd64. On Apple Silicon (M-series) Macs the image runs under Rosetta emulation. If you encounter performance issues, run the Node.js process directly on the host (npm run start) and keep only MinIO and Redis in Docker.

Build docs developers (and LLMs) love