The UZSE Backtest App builds OHLCV candlestick series in 11 timeframes simultaneously, ranging from 1-minute granularity up to a full trading day. All higher timeframes are derived from the same 1-minute base series, which is itself aggregated directly from raw trade records. Every timeframe is produced in a single pass over each day’s trades and written to theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/theonetrade/uzse-backtest-app/llms.txt
Use this file to discover all available pages before exploring further.
candle-items collection in one batch, making the build process efficient even for multi-year histories.
Supported Timeframes
| Interval | Minutes | Step (ms) | Description |
|---|---|---|---|
1m | 1 | 60,000 | 1-minute — base timeframe, directly aggregated from trades |
3m | 3 | 180,000 | 3-minute |
5m | 5 | 300,000 | 5-minute |
15m | 15 | 900,000 | 15-minute |
30m | 30 | 1,800,000 | 30-minute |
1h | 60 | 3,600,000 | 1-hour |
2h | 120 | 7,200,000 | 2-hour |
4h | 240 | 14,400,000 | 4-hour |
6h | 360 | 21,600,000 | 6-hour |
8h | 480 | 28,800,000 | 8-hour |
1d | 1440 | 86,400,000 | Daily |
CandleInterval type exported from backtest-kit constrains valid interval values to this exact set. The same values are enforced at the database layer via the Mongoose enum constraint on the interval field in CandleSchema.
Aggregation Algorithm
The candle builder follows a four-step process, derived directly from thebuild-candles.ts source:
Aggregate trades into 1-minute buckets
All trades for a given day are loaded from the Within each bucket, OHLCV values are accumulated:
trade-results collection (queried by ISIN and UTC day boundaries). Each trade is placed into a 1-minute bucket by flooring its timestamp:open—tradePriceof the first trade in the buckethigh— maximumtradePriceacross all trades in the bucketlow— minimumtradePriceacross all trades in the bucketclose—tradePriceof the last trade in the bucketvolume— sum ofquantity(share count) across all trades in the bucket
Fill intraday gaps
A continuous minute-by-minute series is generated from
00:00:00 to 23:59:00 UTC for each calendar day. For any minute that has no real trade activity, a synthetic candle is inserted:open = high = low = close=closeof the most recent real candlevolume = 0
Fill non-trading days
Weekends and exchange holidays are days that have no trades at all. The builder detects these implicitly — when the
trade-results query for a day returns zero rows, all 1440 minutes of that day are gap-filled using the last known closing price from the most recent trading day:open = high = low = close=closeof the last candle from the previous trading dayvolume = 0
Aggregate higher timeframes from the filled 1m series
After the full-day 1-minute series (including gap-filled candles) is built in memory, all 11 timeframes are accumulated in a single forward pass over the 1440-minute array. Each higher timeframe N is computed by flooring each 1m timestamp to the nearest N-minute boundary:Within each N-minute period:
open— taken from the first 1m candle falling in the periodhigh— maximumhighacross all 1m candles in the periodlow— minimumlowacross all 1m candles in the periodclose— taken from the last 1m candle in the periodvolume— sum of all 1m candlevolumevalues in the period
candle-items collection in a single insertMany call at the end of each day.Gap-Fill Reference
| Scenario | OHLC Values | Volume |
|---|---|---|
| Minute with real trade(s) | Derived from trade prices | Sum of quantity |
| Minute with no trades (intraday gap) | = previous candle close | 0 |
| Non-trading day (weekend / holiday) | = last trading day close | 0 |
Idempotency
The{ symbol: 1, interval: 1, timestamp: 1 } unique index on candle-items guarantees that re-running build-candles.ts for an already-processed symbol and date range is safe. The script calls insertMany with { ordered: false }, so existing candles generate write errors that are caught and counted as skipped rather than causing the process to abort.
Using Timeframes with the Exchange Module
When thebacktest-kit editor calls getCandles, it passes one of the 11 interval strings along with the symbol and a since date. The exchange module translates this directly into a MongoDB query:
Related Pages
Candle Schema
Full field reference for the
candle-items collection including types and indexes.Build Candles
How to run
build-candles.ts to populate all 11 timeframes for a symbol.Exchange Module
How
getCandles() queries the candle-items collection for Pine Script analysis.Data Model
End-to-end overview of how trades become candles and reach the editor.