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.

addFrameSchema defines the time window and tick granularity for a backtest run. Every call to Backtest.run or Walker.run requires a registered frame. The frame schema tells Backtest Kit how to generate the sequence of timestamps it iterates over—one tick per interval step from startDate through endDate. Live mode does not use frames; the engine produces ticks by reading the system clock.

Function Signature

addFrameSchema(frameSchema: IFrameSchema): void

Parameters

frameName
string
required
A unique string identifier for this frame. Referenced as frameName in Backtest.run and Walker.run context objects. Duplicate names throw at registration.
interval
FrameInterval
required
The spacing between consecutive ticks in the backtest. Each tick represents one point in simulated time at which the strategy is evaluated.Accepted values: "1m" | "3m" | "5m" | "15m" | "30m" | "1h" | "2h" | "4h" | "6h" | "8h" | "12h" | "1d"
startDate
Date
required
Inclusive start of the backtest period. The first tick is generated at alignToInterval(startDate, interval).
endDate
Date
required
Inclusive end of the backtest period. No ticks are generated beyond this date.
note
string
Optional developer note for documentation or introspection.
callbacks
Partial<IFrameCallbacks>
Optional lifecycle callbacks:
  • onTimeframe(timeframe, startDate, endDate, interval) — called once after the timestamp array is generated. Useful for logging the number of ticks or validating the configured period.

Example

import { addFrameSchema } from 'backtest-kit';

// Single-day backtest at 1-minute tick resolution
addFrameSchema({
  frameName: '2025-dec-01',
  interval: '1m',
  startDate: new Date('2025-12-01T00:00:00Z'),
  endDate:   new Date('2025-12-02T00:00:00Z'),
  callbacks: {
    onTimeframe: (timeframe, startDate, endDate, interval) => {
      console.log(
        `Frame 2025-dec-01: ${timeframe.length} ticks ` +
        `(${interval} from ${startDate.toISOString()} to ${endDate.toISOString()})`
      );
    },
  },
});

// Multi-month walk-forward period at hourly tick resolution
addFrameSchema({
  frameName: 'q1-2026',
  interval: '1h',
  startDate: new Date('2026-01-01T00:00:00Z'),
  endDate:   new Date('2026-04-01T00:00:00Z'),
  note: 'Q1 2026 hourly walk-forward window',
});
Then use the frame in a backtest:
import { Backtest } from 'backtest-kit';

for await (const result of Backtest.run('BTCUSDT', {
  strategyName: 'rsi-trend',
  exchangeName: 'binance',
  frameName:    '2025-dec-01',
})) {
  if (result.action === 'closed') {
    console.log('PNL:', result.pnl.pnlPercentage.toFixed(2) + '%');
  }
}
The interval in the frame schema controls backtest tick granularity—it determines how frequently the strategy is evaluated and how finely time advances through the historical period. It is independent of the interval in addStrategySchema, which controls signal-generation throttling. A frame with interval: "1m" and a strategy with interval: "5m" will step every minute but call getSignal at most every 5 minutes.

Build docs developers (and LLMs) love