Skip to main content

Documentation 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.

The CandleModel is the central output of the UZSE Backtest App pipeline. Every candle produced by build-candles.ts — across all 11 supported timeframes — lands in the candle-items MongoDB collection and conforms to the shape described on this page. The schema is intentionally minimal: eight required fields plus auto-managed timestamps, protected by a unique composite index that guarantees idempotent re-runs.

Collection Details

PropertyValue
MongoDB collectioncandle-items
Mongoose modelCandleModel
TypeScript interfaceICandleDto
Databasebacktest (configured via MONGO_URI)

Fields

symbol
String
required
Display symbol identifier for the security (e.g. HMKB). This is the human-readable ticker, not the ISIN. The build-candles.ts script accepts both the display symbol and the ISIN as separate CLI arguments and uses the display symbol when writing candle documents.Indexed individually ({ symbol: 1 }) and as part of the unique composite index.
interval
String
required
Candlestick timeframe. Must be one of the 11 values in the INTERVAL_ENUM: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 1d. Validated at the Mongoose schema level via the enum constraint. See Timeframes for aggregation details.Indexed individually ({ interval: 1 }) and as part of the unique composite index.
timestamp
Number
required
Unix timestamp in milliseconds representing the start (open) of the candle period. For example, a 1h candle covering 10:00–10:59 UTC has timestamp = 1704106800000. Computed by flooring the trade time to the nearest interval boundary using floor(tsMs, minutes * 60_000).Indexed individually ({ timestamp: 1 }) and as part of the unique composite index.
open
Number
required
Opening price of the period. For the 1-minute base series this is the tradePrice of the first trade in that minute. For higher timeframes it is the open of the first 1m candle in the aggregated period.
high
Number
required
Highest price reached during the period. For the 1-minute series this is the maximum tradePrice across all trades in that minute. For higher timeframes it is the maximum high across all contributing 1m candles.
low
Number
required
Lowest price reached during the period. For the 1-minute series this is the minimum tradePrice across all trades in that minute. For higher timeframes it is the minimum low across all contributing 1m candles.
close
Number
required
Closing price of the period. For the 1-minute series this is the tradePrice of the last trade in that minute. For higher timeframes it is the close of the last 1m candle in the aggregated period.
volume
Number
required
Total number of securities traded during the period — the sum of the quantity field from all contributing trade records. Note that this is share count, not monetary value. Gap-filled candles (minutes or days with no real trades) have volume = 0.
createDate
Date
Creation timestamp managed automatically by Mongoose via timestamps: { createdAt: "createDate" }. Set once when the document is first inserted; never updated.
updatedDate
Date
Last-updated timestamp managed automatically by Mongoose via timestamps: { updatedAt: "updatedDate" }. Updated on every subsequent save or findOneAndUpdate.

Indexes

IndexTypePurpose
{ symbol: 1, interval: 1, timestamp: 1 }Unique compositePrevents duplicate candles; enables idempotent re-runs of build-candles.ts
{ symbol: 1 }StandardFast lookups by ticker across all timeframes
{ interval: 1 }StandardEfficient filtering by timeframe
{ timestamp: 1 }StandardRange queries over time
The unique composite index is the most important constraint in the collection. When build-candles.ts runs insertMany with { ordered: false }, any candle that already exists for a given (symbol, interval, timestamp) triplet is silently skipped, making repeated runs safe.

TypeScript Interface

interface ICandleDto {
  symbol: string;
  interval: CandleInterval;
  timestamp: number;
  open: number;
  high: number;
  low: number;
  close: number;
  volume: number;
}
CandleInterval is imported from backtest-kit and constrains the interval field to the same 11-value union used in the Mongoose INTERVAL_ENUM. Two additional interfaces extend ICandleDto:
  • CandleDocument — extends both ICandleDto and Mongoose Document; used for typed Mongoose operations.
  • ICandleRow — adds id: string, createDate: Date, and updatedDate: Date; used when reading fully-hydrated documents (e.g. in the editor module).

Mongoose Schema Definition

const INTERVAL_ENUM = [
  "1m", "3m", "5m", "15m", "30m",
  "1h", "2h", "4h", "6h", "8h", "1d",
] as const;

const CandleSchema: Schema<CandleDocument> = new Schema(
  {
    symbol:    { type: String, required: true, index: true },
    interval:  { type: String, required: true, enum: INTERVAL_ENUM, index: true },
    timestamp: { type: Number, required: true, index: true },
    open:      { type: Number, required: true },
    high:      { type: Number, required: true },
    low:       { type: Number, required: true },
    close:     { type: Number, required: true },
    volume:    { type: Number, required: true },
  },
  { timestamps: { createdAt: "createDate", updatedAt: "updatedDate" } }
);

CandleSchema.index({ symbol: 1, interval: 1, timestamp: 1 }, { unique: true });

const CandleModel = mongoose.model<CandleDocument>("candle-items", CandleSchema);

Exchange Module Query

The editor.module.ts registers a mongo-exchange adapter with backtest-kit by providing a getCandles function that queries this collection:
addExchangeSchema({
  exchangeName: "mongo-exchange",
  getCandles: async (symbol, interval, since, limit) => {
    const candles = await CandleModel.find(
      { symbol, interval, timestamp: { $gte: since.getTime() } },
      { timestamp: 1, open: 1, high: 1, low: 1, close: 1, volume: 1, _id: 0 }
    )
      .sort({ timestamp: 1 })
      .limit(limit)
      .lean();

    return candles.map(({ timestamp, open, high, low, close, volume }) => ({
      timestamp, open, high, low, close, volume,
    }));
  },
});
This query uses the { symbol, interval, timestamp } composite index for optimal performance.
symbol vs isin: Candle documents store the display symbol (e.g. HMKB), while trade documents in trade-results store the ISIN (e.g. UZ7011340005). The build-candles.ts script bridges these two namespaces — it reads trades by ISIN from the trade-results collection and writes candles with the display symbol into candle-items. Always pass both values when running the script: npx tsx scripts/build-candles.ts HMKB UZ7011340005.

Trade Schema

Raw UZSE trade records in the trade-results collection, including the SHA1 deduplication hash.

Timeframes

All 11 supported OHLCV intervals and the gap-fill aggregation algorithm.

Data Model

End-to-end data flow from UZSE HTML pages to candles in MongoDB.

Build Candles

How to run build-candles.ts to populate the candle-items collection.

Build docs developers (and LLMs) love