DocumentationTimeframes & Tick Charts

Timeframes & tick charts

OpenAlgo Charts handles the full range of timeframes - from seconds and ticks up to weeks - because the time axis is a logical index, not a fixed grid.

Time labels default to IST (the Indian-market default). For other markets, pass a timeFormatter (UTC seconds -> string) to createChart, or call chart.setTimeFormatter(...) at runtime. For example, UTC time labels: createChart(el, { timeFormatter: (s) => new Date(s * 1000).toISOString().slice(11, 16) }). It drives both the time-axis ticks and the crosshair pill.

There are two sources of bars:

  1. Historical bars come from your data feed at a chosen interval (5s, 1m, 1h, D, W, …). The chart just draws them.
  2. Tick, volume, and sub-minute bars are aggregated live from a trade/quote stream using TickBarAggregator or CandleBuilder - OHLCV history alone cannot produce them.

History intervals

The OpenAlgo REST adapter passes the interval through verbatim, so any interval your broker supports works. Fetch the exact list at runtime instead of hard-coding it:

// OpenAlgo exposes the supported intervals per broker:
//   seconds:  5s, 10s, 15s, 30s, 45s, 60s ...
//   minutes:  1m, 3m, 5m, 10m, 15m, 30m ...
//   hours:    1h, 2h, 4h ...
//   days+:    D, W, M
const bars = await feed.getBars({
  symbol: 'RELIANCE', exchange: 'NSE', interval: '5s',
  from: dayStartUtcSeconds, to: nowUtcSeconds,
});
series.setData(bars);

The time axis automatically switches to HH:MM:SS labels when the visible bars are less than a minute apart, and the crosshair tag shows seconds on sub-minute bars - so a 5-second chart reads correctly without any configuration.

Second timeframes (live)

CandleBuilder buckets a tick stream into interval OHLC. intervalSec can be any number of seconds - here, 5-second candles. Pass a sessionAnchorSec so buckets align to the session open (09:15) rather than an arbitrary epoch floor.

const chart = lib.createChart(el);
const series = chart.addSeries('candlestick');

// Build 5-second candles from a simulated tick stream.
const builder = new lib.CandleBuilder({ intervalSec: 5, volumeMode: 'ltq-sum' });
const bars = [];
let t = 1700000000, p = 100, seed = 99;
for (let i = 0; i < 3000; i++) {
seed = (seed * 1103515245 + 12345) & 2147483647;
p = Math.max(1, p + (seed / 2147483647 - 0.5) * 0.4);
t += 1; // one tick per second
const u = builder.onTick({ time: t, price: p, ltq: 10 });
if (u) { if (u.isNew) bars.push(u.bar); else bars[bars.length - 1] = u.bar; }
}
series.setData(bars);
chart.timeScale.fitContent(bars.length);
return chart;
live
Rendering live chart…
5-second candles aggregated from a per-second tick stream. Note the HH:MM:SS axis.

Tick bars

TickBarAggregator makes bars from trade ticks by clock interval, tick count, or traded volume:

import { TickBarAggregator } from 'openalgo-charts';
 
const agg = new TickBarAggregator({ mode: 'ticks', count: 100 });   // 100-tick bars
// or { mode: 'volume', perBar: 5000 }   - constant-volume bars
// or { mode: 'interval', seconds: 30 }  - 30-second bars
 
ws.onTrade((t) => {
  const u = agg.onTick({ time: t.timeSec, price: t.price, qty: t.qty });
  if (u.isNew) series.setData([...bars, u.bar]);   // append
  else series.update(u.bar);                       // mutate the forming bar
});

Here is a 250-tick chart built from a simulated trade stream:

const chart = lib.createChart(el);
const series = chart.addSeries('candlestick');
const agg = new lib.TickBarAggregator({ mode: 'ticks', count: 250 });
const bars = [];
let t = 1700000000, p = 100, seed = 3;
for (let i = 0; i < 12000; i++) {
seed = (seed * 1103515245 + 12345) & 2147483647;
p = Math.max(1, p + (seed / 2147483647 - 0.5) * 0.6);
t += 1;
const u = agg.onTick({ time: t, price: p, qty: 1 });
if (u.isNew) bars.push(u.bar); else bars[bars.length - 1] = u.bar;
}
series.setData(bars);
chart.timeScale.fitContent(bars.length);
return chart;
live
Rendering live chart…
⚠️

Tick-count and volume bars require real trade ticks. A 1-minute OHLCV history cannot be re-bucketed into them - you need a tick feed (or a tick-recording backend). Bid/ask classification for footprint / order flow needs the same.