Before running backtests or live trading, every component of Backtest Kit must be registered through schema functions. These functions populate the internal registries that the execution engine queries on every tick. Registration is stateful and global — schemas registered once are available for the lifetime of the process. Call them at startup, before anyDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/backtest-kit/backtest-kit-docs/llms.txt
Use this file to discover all available pages before exploring further.
Backtest.background() or Live.background() invocations.
addStrategySchema
Registers a trading strategy with the engine. The strategy’sgetSignal function is the primary entry point for signal generation. It is called on every tick (subject to interval throttling), validated automatically for TP/SL logic, and persisted to disk in live mode for crash recovery.
Parameters
Unique identifier for this strategy. Used as the key in the schema registry and in all reports, dumps, and persistence files.
The signal generation function. Called on every tick while no position is active. Return a signal object to open a position or
null to stay idle. Signals are validated automatically — invalid TP/SL relationships or negative prices cause the signal to be silently rejected (logged to listenError).Throttle interval for
getSignal. When set, getSignal is not called more frequently than this interval. Useful for strategies that rely on LLM inference or expensive computations. Defaults to calling on every available tick.Name of a risk schema registered via
addRiskSchema. If provided, every candidate signal is passed through the risk validations before being accepted. Rejected signals emit a listenRisk event instead of opening a position.Lifecycle callback. Invoked once before the first tick for a given symbol. Use for one-time setup such as loading ML models, warming caches, or opening database connections.
Lifecycle callback. Invoked once after the last tick — when a backtest completes or a live session is stopped. Use for cleanup such as flushing buffers or closing connections.
Called immediately after a position is opened. Receives the full signal row, including the effective entry price.
Called immediately after a position is closed for any reason (take-profit, stop-loss, time expiry, or manual close). Receives the closing price and the final signal row.
Called when the position reaches a new peak unrealized profit (new high watermark). Use for trailing-take or alerting logic.
Called when the position reaches a new maximum drawdown (new low watermark). Use for DCA or risk-reduction logic.
Called on every tick while a signal is in the scheduled (pending entry at limit price) state. Fires approximately once per minute.
Called on every tick while a position is active (open, monitoring TP/SL). Use for DCA, partial profit-taking, trailing stops, and breakeven adjustments.
Called on every tick while no position is active and no signal is scheduled. Use for pre-market analysis or idle monitoring.
Signal Object Shape
getSignal must return either null or an object conforming to ISignalDto:
Direction of the trade.
Desired entry price. If omitted, the engine uses the current VWAP as the entry price (market-style entry). If provided and the current price is not yet at
priceOpen, the signal is placed in scheduled state until the price is reached.Take-profit price. Must be above
priceOpen for longs and below for shorts — validated automatically.Stop-loss price. Must be below
priceOpen for longs and above for shorts — validated automatically.Maximum lifetime of the trade in minutes. Set to
Infinity to hold until TP or SL is hit with no timeout. This value determines how many candles are fetched during backtesting for fast forward-simulation.Dollar amount allocated to the initial entry. This same amount is used for each subsequent DCA entry via
commitAverageBuy.Optional stable identifier for the signal. Useful for correlating signals across logs, reports, and external systems. Auto-generated if not provided.
Optional human-readable annotation. Appears in reports and notification payloads. Useful for recording LLM reasoning, indicator values, or the trigger condition.
Position Helper Functions
ThePosition class provides convenience constructors for common TP/SL configurations. Both methods calculate prices as percentages relative to currentPrice and respect the position direction.
ISignalDto (without cost or minuteEstimatedTime) that you merge with the rest of your signal fields.
addExchangeSchema
Registers a data source (exchange) with the engine. ThegetCandles function is the critical adapter — it must fetch OHLCV data from your data provider and return it in the framework’s canonical format. All candle fetching inside strategies (via getCandles, getNextCandles, getRawCandles) is routed through this adapter.
Unique identifier for this exchange. Referenced by
Backtest.background(), Live.background(), and addStrategySchema.getCandles
(symbol, interval, since: Date, limit: number, backtest: boolean) => Promise<ICandleData[]>
required
Adapter function that fetches OHLCV candles. The engine guarantees that
since is aligned to the interval boundary and that exactly limit candles are expected in return. The backtest flag is true during backtesting and false during live trading — useful for routing to historical vs. live data endpoints.Formats a price value to the exchange’s required precision. Used in reports and broker adapter payloads. Defaults to
price.toFixed(2) if not provided.Formats a quantity value to the exchange’s required precision. Used in broker adapter payloads. Defaults to
quantity.toFixed(8) if not provided.Optional. Fetches an order book snapshot. Called by
getOrderBook() inside strategies. If not provided, calling getOrderBook() throws a runtime error. The from/to window is aligned to CC_ORDER_BOOK_TIME_OFFSET_MINUTES boundaries — live implementations may ignore the time range and return the current snapshot.getAggregatedTrades
(symbol, from: Date, to: Date, backtest: boolean) => Promise<IAggregatedTradeData[]>
Optional. Fetches aggregated trade records. Called by
getAggregatedTrades() inside strategies. If not provided, calling getAggregatedTrades() throws a runtime error. Live implementations may ignore from/to and return the most recent trades.addFrameSchema
Registers a time frame for backtesting. The frame defines the date range and candle interval that the engine iterates over. EachDate in the generated timeframe array becomes one execution tick — the engine calls your strategy’s getSignal (and checks TP/SL) once per tick.
Unique identifier for this frame. Referenced by
Backtest.background() and Backtest.run().Candle interval for the backtest timeframe. Determines the spacing between ticks and the step size used when aligning candle requests. Supported values:
1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M.Inclusive start of the backtest window. The engine generates ticks starting at this date, aligned to the interval boundary.
Exclusive end of the backtest window. The engine stops generating ticks at this date.
addRiskSchema
Registers a risk profile. A risk profile is a named collection of validation functions. When a strategy references ariskName, every candidate signal is passed through all validations in sequence before being accepted. Any validation that throws (or returns a rejection object) causes the signal to be silently discarded — the rejection details are emitted to listenRisk subscribers.
Unique identifier for this risk profile. Referenced by
addStrategySchema via the riskName field.Array of validation functions. Each function receives an
IRiskValidationPayload and must either return normally (signal accepted) or throw an Error (signal rejected with the error message as the rejection note).The payload contains:pendingSignal— the candidate signalcurrentPrice— VWAP at the time of the checkactivePositionCount— total number of open positions across all strategies sharing this risk profile
addSizingSchema
Registers a position sizing strategy. Sizing schemas are referenced by action handlers and advanced position management code to compute the dollar amount (cost) dynamically based on account balance and risk parameters.
Unique identifier for this sizing schema.
Sizing algorithm.
fixed-percentage allocates a fixed percentage of account balance. kelly uses the Kelly Criterion scaled by kellyMultiplier. atr-based sizes position relative to the Average True Range for volatility-adjusted risk.For
fixed-percentage and atr-based: maximum percentage of account balance to risk per trade (0–100).Minimum position size in dollars. Acts as a floor after the sizing calculation.
Maximum position size in dollars. Acts as a ceiling after the sizing calculation.
Maximum percentage of account balance for a single position, regardless of sizing calculation.