Skip to main content

Documentation Index

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

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

The Candle adapter is the only insert-only adapter in the stack. Rather than overwriting existing candle data, it uses a $setOnInsert strategy so that historical OHLCV bars written during a backtest run are never clobbered by a subsequent run over the same time range. Reads reconstruct a contiguous candle array by stepping through timestamps at the correct interval cadence and returning null if any bar in the requested window is missing.

Constructor

class implements IPersistCandleInstance {
  constructor(
    readonly symbol: string,
    readonly interval: CandleInterval,
    readonly exchangeName: string,
  ) {}
}
symbol
string
required
The trading pair symbol, e.g. "BTCUSDT".
interval
CandleInterval
required
The candle timeframe. Must be one of the supported values listed below.
exchangeName
string
required
The exchange identifier. In the default implementation the value "ccxt_binance" is hardcoded inside CandleDbService and is used as part of the Redis cache key.

Supported Intervals

The adapter resolves each CandleInterval to a millisecond step size using the following map:
const INTERVAL_MINUTES: Record<CandleInterval, number> = {
  "1m": 1,   "3m": 3,   "5m": 5,   "15m": 15,  "30m": 30,
  "1h": 60,  "2h": 120, "4h": 240, "6h": 360,  "8h": 480,
  "1d": 1440,
};
const MS_PER_MINUTE = 60_000;
Each interval’s step in milliseconds is INTERVAL_MINUTES[interval] * MS_PER_MINUTE.

Methods

writeCandlesData

Persists an array of CandleData objects to the candle-items collection. Each candle is written individually with an insert-only upsert — if a document already exists for the (symbol, interval, timestamp) triple, the write is a no-op.
async writeCandlesData(candles: CandleData[]): Promise<void> {
  for (const candle of candles) {
    await ioc.candleDbService.create({
      symbol: this.symbol,
      interval: this.interval,
      ...candle,
    });
  }
}
candles
CandleData[]
required
Array of candle objects. Each entry must include timestamp, open, high, low, close, and volume.
candleDbService.create uses MongoDB’s $setOnInsert operator under the hood. Duplicate (symbol, interval, timestamp) entries are silently skipped rather than overwritten.

readCandlesData

Reconstructs a contiguous window of candles starting at sinceTimestamp by fetching exactly limit bars, each separated by the interval step size. If any bar in the window is absent from MongoDB, the method returns null immediately.
async readCandlesData(limit: number, sinceTimestamp: number): Promise<CandleData[] | null> {
  const stepMs = INTERVAL_MINUTES[this.interval] * MS_PER_MINUTE;
  const result: CandleData[] = [];
  for (let i = 0; i < limit; i++) {
    const ts = sinceTimestamp + i * stepMs;
    const row = await ioc.candleDbService.findBySymbolIntervalTimestamp(
      this.symbol, this.interval, ts,
    );
    if (!row) return null;
    result.push({
      timestamp: row.timestamp,
      open: row.open,
      high: row.high,
      low: row.low,
      close: row.close,
      volume: row.volume,
    });
  }
  return result;
}
limit
number
required
The number of candles to retrieve. Must be a positive integer.
sinceTimestamp
number
required
Unix timestamp in milliseconds for the first candle in the window.
Returns: CandleData[] when all limit bars are present, or null if any bar is missing.
A null return does not indicate an error — it means the requested candle window is not fully populated in the database. Callers should treat null as a cache-miss signal and either skip the bar or fetch from the upstream exchange.

Redis Cache Key Format

Each candle lookup is backed by a Redis key with the following structure:
candle_cache:<exchangeName>:<symbol>:<interval>:<timestamp>
For example, a 1-hour BTC/USDT candle at timestamp 1700000000000 maps to:
candle_cache:ccxt_binance:BTCUSDT:1h:1700000000000
Because candles are insert-only, the Redis cache entry never becomes stale after it is written. Cache entries can be set with a long TTL or even no expiry.

Collection

FieldValue
Collection namecandle-items
Context key(symbol, interval, timestamp)
Write strategyInsert-only ($setOnInsert)
Soft deleteNo

Build docs developers (and LLMs) love