Skip to main content

Documentation Index

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

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

The @backtest-kit/mongo package replaces backtest-kit’s default file-based ./dump/ storage with MongoDB as the source of truth and Redis as an O(1) lookup cache. During backtests, the engine performs thousands of context-keyed reads per second — Redis eliminates per-request B-tree traversal and makes repeated reads effectively free. MongoDB provides durability, atomic upserts, and a queryable signal history that survives process restarts. All 15 IPersist*Instance contracts from the core library are fully implemented, so strategy code requires absolutely no changes.

Key Features

MongoDB Backend

All 15 persistence adapters implemented with Mongoose and unique compound indexes. Covers Candle, Signal, Schedule, Risk, Partial, Breakeven, Storage, Notification, Log, Measure, Interval, Memory, Recent, State, and Session.

O(1) Redis Reads

Every context-key lookup goes through ioredis — one GET plus one findById. No B-tree scans for hot-path reads during high-frequency backtests.

Atomic Writes

findOneAndUpdate with upsert: true guarantees read-after-write correctness with no race conditions under concurrent writes.

Look-Ahead Bias Protection

Adapters that affect signal logic store the simulation timestamp in a when field so backtest-kit can enforce strict temporal correctness.

Soft Delete

Measure, Interval, and Memory records carry a removed flag instead of being physically deleted — history is preserved for auditing and replay.

Zero Strategy Changes

Drop setup() into your entry point and everything else stays the same. Strategy files, risk rules, and runners are completely unaffected.

Getting Started

1

Install the package and its peers

npm install @backtest-kit/mongo backtest-kit mongoose ioredis
2

Configure connection strings in your environment

# .env
CC_MONGO_CONNECTION_STRING=mongodb://localhost:27017/backtest
CC_REDIS_HOST=localhost
CC_REDIS_PORT=6379
3

Call setup() in your entry point

Add a single setup() call at the top of your runner or entry file, before any strategy schemas are registered:
import { setup } from '@backtest-kit/mongo';

// Drop this in before addStrategySchema, addExchangeSchema, etc.
await setup();
That is the only change required. All 15 persistence adapters are registered automatically.
4

Run as normal

Start your backtest or live bot exactly as before. @backtest-kit/mongo intercepts all reads and writes transparently.
Strategy code, risk rules, exchange adapters, and runner scripts stay completely unchanged. The only addition to your project is the setup() call in the entry point. No imports, no wiring, and no refactoring are needed inside strategy files.

When to Use MongoDB Persistence

File-based ./dump/ storage works well for single-symbol backtests and development. Switch to @backtest-kit/mongo when:
  • Large datasets: Backtesting months of 1m candles across many symbols exhausts file system performance
  • Concurrent writes: Running multiple symbols in parallel creates write contention that MongoDB’s atomic upserts handle cleanly
  • Containerized deployments: Docker and Kubernetes environments benefit from external, durable storage that survives container restarts
  • Live trading: Production bots need crash-safe persistence and instant recovery without replaying state from files
  • Signal auditing: MongoDB’s queryable collections make it easy to inspect historical signals, risk rejections, and partial fills
In live trading, always use durable MongoDB persistence. File-based storage is not suitable for production — a process crash can leave signal state in an inconsistent state on disk.

Architecture

Strategy getSignal()


backtest-kit engine  ──read──▶  Redis (O(1) key lookup)
                                    │ miss

                               MongoDB (findById)

                                    └──▶ Redis (backfill cache)

backtest-kit engine  ──write─▶  MongoDB (findOneAndUpdate upsert)

                                    └──▶  Redis (invalidate / update cache)
The read path is a single Redis GET. On a cache miss the adapter falls back to MongoDB and backfills the cache entry automatically. The write path is always a single atomic MongoDB upsert — Redis is updated in the same operation to keep the cache consistent.

Build docs developers (and LLMs) love