Documentation Index
Fetch the complete documentation index at: https://mintlify.com/backtest-kit/uzse-backtest-app/llms.txt
Use this file to discover all available pages before exploring further.
build-candles.ts reads raw trade records from the trade-results MongoDB collection and aggregates them into OHLCV (Open, High, Low, Close, Volume) candlestick documents across 11 timeframes simultaneously. The script processes trades one calendar day at a time, fills every minute of each day with gap candles (carrying the previous close forward at zero volume), and writes the resulting documents to the candle-items collection. Re-running the script is safe — the unique compound index {symbol, interval, timestamp} causes duplicate candles to be silently skipped.
Synopsis
Parameters
Display ticker written into the
candle-items collection, e.g. HMKB. This is the human-readable name used by charting consumers and does not need to match the ISIN.ISIN code used to look up trade records in
trade-results, e.g. UZ7011340005. Must match the symbol field stored by import-trades.ts.Supported Timeframes
All 11 timeframes from theTIMEFRAMES constant are built in a single pass per day:
| Interval | Minutes |
|---|---|
1m | 1 |
3m | 3 |
5m | 5 |
15m | 15 |
30m | 30 |
1h | 60 |
2h | 120 |
4h | 240 |
6h | 360 |
8h | 480 |
1d | 1440 |
Algorithm
The script processes data day by day from the first to the last trade date:- Load trades — queries
trade-resultsfor all records matching the given ISIN within the current day’s UTC boundary (00:00:00to23:59:59), sorted bytimeascending. - Build 1m buckets — aggregates all trades into a
minuteMapkeyed by the UTC minute timestamp produced byfloorToMin(ts, 1). - Walk every minute — iterates every millisecond-aligned minute from
dayStartMstodayStartMs + DAY_MS(1 440 steps). For each minute:- If a real trade bucket exists, uses its OHLCV and updates
lastClose. - Otherwise emits a gap candle:
open = high = low = close = lastClose,volume = 0.
- If a real trade bucket exists, uses its OHLCV and updates
- Accumulate higher timeframes — each 1m candle is simultaneously folded into all 11 timeframe accumulators using
floorToMin(ts, minutes)to align bucket boundaries. - Insert batch — flattens all accumulated candle documents for the day and calls
CandleModel.insertManywithordered: false, allowing partial inserts when some candles already exist.
OHLCV Aggregation Rules
| Field | Rule |
|---|---|
open | Price of the first trade in the period |
high | Maximum trade price in the period |
low | Minimum trade price in the period |
close | Price of the last trade in the period |
volume | Sum of all trade quantities |
Gap candles (minutes with no trades) carry
open = high = low = close = lastClose and volume = 0. This ensures every timeframe has fully contiguous series with no missing bars, which is required by most charting libraries.MongoDB
| Setting | Value |
|---|---|
| Database | backtest |
| Source collection | trade-results |
| Target collection | candle-items |
| Unique index | { symbol, interval, timestamp } — re-runs skip existing candles |
| Insert mode | insertMany with ordered: false (partial inserts on duplicates) |