Data Format (OHLCV)

Every ApexStock chart is driven by an array of OHLC(V) candles. Each candle packs the four prices into a single y tuple, which is different from passing separate open/high/low/close keys.

The candle shape

A single data point looks like this:

{
  x: 1706745600000,        // timestamp (epoch ms), date string, or Date
  y: [150, 155, 148, 153], // [open, high, low, close] — in that order
  v: 1200000,              // optional volume
}
FieldTypeRequiredDescription
xnumber | string | DateYesCategory or timestamp for the candle. Epoch milliseconds, an ISO date string, or a Date.
y[number, number, number, number]YesThe four prices as [open, high, low, close]. Most indicators read the close (y[3]).
vnumberNoVolume for the candle. Required for volume-based indicators (Volumes, PVT, Chaikin).

The four prices live in one y array, not as separate o/h/l/c keys.

A full series

Candles are supplied as the data of the first series:

const chartOptions = {
  chart: { height: 400 },
  series: [
    {
      name: 'ACME',
      data: [
        { x: '2024-01-01', y: [100, 101.05, 96.53, 98], v: 363305 },
        { x: '2024-01-02', y: [98, 98.39, 95.55, 97.51], v: 612318 },
        { x: '2024-01-03', y: [97.51, 98.14, 97.29, 97.63], v: 915487 },
      ],
    },
  ],
}

const apexStock = new ApexStock(document.querySelector('#chart'), chartOptions)
apexStock.render()

Ordering

Supply candles in ascending order by x (oldest first). Indicators, the x-axis, and streaming appends all assume a chronologically ordered buffer.

Timestamps vs categories

  • Timestamps (x: 1706745600000 or a Date) give a true time axis where gaps between bars reflect real elapsed time, including weekends and market holidays.
  • Date strings / categories (x: '2024-01-01') place bars at even intervals regardless of the calendar distance between them, which is useful for session-based views that should not show weekend gaps.

Malformed points are dropped

A point missing a valid x, or whose y is not a 4-number array, is discarded rather than throwing. This applies both to the constructor and to streaming appends. If a chart renders with fewer bars than expected, check that every point has a numeric x (or parseable date) and a complete four-value y.

Working with volume

Volume is optional, but several indicators need it. When v is present on your candles you can enable the Volumes pane and volume-based oscillators:

const chartOptions = {
  chart: { height: 500 },
  series: [{ name: 'ACME', data: candlesWithVolume }],
  plotOptions: {
    stockChart: {
      indicators: {
        volumes: { enabled: true },
        'price volume trend': { enabled: false },
      },
    },
  },
}

See Technical Indicators for the full list and Options for the complete option reference.