Timeframes

A timeframe is the duration of one bar. You set it by label, and two things follow: the viewport snaps to a span wide enough to hold a good number of those bars, and the data engine fetches at that resolution.

That's pretty much it. The rest of this page is which labels exist, which ones you're allowed to use, and how to change them.

The shape

Internally a timeframe is an object (not a string). You'll see this shape whenever one is handed to you - on the timeframe:change event, in a plugin callback, in a serialized layout:

PropTypeDefaultDescription
labelstring-"1m", "4h", "213s" - its what gets serialized and what you pass back in
barNsbigint-Duration of one bar in nanoseconds. A bigint instead of a number, because nanosecond timestamps overflow a JS number.
defaultBarsnumber-Deprecated. Every timeframe defaults to ~300 bars.
isPresetboolean-false means the user typed it in rather than picking it from the list.

The presets

Thirteen ship built in:

None, Seconds: 1s 5s 15s 30s, Minutes: 1m 3m 5m 15m 30m, Hours: 1h 4h, Days: 1d

None is the orderflow-style "don't aggregate" option. Currently it's in practice a 1ms bar, which at any realistic zoom level means you're looking at individual events rather than candles - but its in the works to actually make it 'none'

Six of these are pinned to the toolbar by default - 1m, 5m, 15m, 1h, 4h, 1d. Which ones are pinned is a user preference and persists in localStorage, as do any custom timeframes they create.

The rules

Custom labels parse from <number><unit>, where unit is one of s m h d w. So 213m, 2h, 45s, and 3d all work. The number has to be between 1 and 100,000. Anything else fails to parse.

Currently there is no sub-second timeframe you can ask for. The engine keeps every timestamp in nanoseconds, and internally it can build bars at any duration you like - but the public api only accepts the units above for the moment. So the finest thing you can actually select is 1s or 'none' (at 1ms). The nanosecond precision is real and it matters for playback and event ordering; it just isn't reachable as a timeframe right now.

Warning

An unknown label behaves differently depending on where you pass it. In the constructor (options.timeframe) it throws. Via chart.setTimeframe() it logs a warning and leaves the current timeframe alone. So a typo in your setup code fails loudly, and a typo at runtime fails quietly - check your console if a switch seems to do nothing.

Bars align to the Unix epoch, not to your data. A 5m bar always starts on a 5-minute boundary, so gridlines stay put no matter where you pan. You don't have to do anything for this, but it does mean the first bar of your dataset could be partial.

Gating

If you're embedding Depth in a product with paid tiers, you can restrict which timeframes are available:

const { chart, element } = useDepthChart({
    dataAdapter: myAdapter,
    symbol: '/NQ1',
    features: {
        timeframe: {
            timeframes: ['1m', '5m', '15m', '1h'], // or 'any'
            allowCustom: false,
        },
    },
});
typescript

When a user tries something outside that set, the chart emits timeframe:add-failed rather than switching:

TIMEFRAME_NOT_ALLOWED: The label isn't in your timeframes list
NO_CUSTOM_TIMEFRAMES: They typed a custom one and allowCustom is false

chart.eventBus.on('timeframe:add-failed', ({ code, label }) => {
    if (code === 'NO_CUSTOM_TIMEFRAMES') {
        showUpgradeModal(`Custom timeframes like ${label} are a Pro feature.`);
    }
});
typescript

Important

This gate is presentation only. chart.setTimeframe() does not check it - it switches regardless, because your own code is trusted. The gate covers the ui paths that a user can reach. Anything actually worth money has to be enforced by whatever serves the data, like an api route, since a client can always be patched.

Setting a timeframe

chart.setTimeframe('5m');
chart.getTimeframe(); // "5m"

// Widen the allowed set at runtime, e.g. after granting a trial/taste.
// Emits features:change, so locks in the ui update immediately.
chart.allowTimeframes(['4h', '1d']);
chart.allowTimeframes('any');

// Check before offering something
if (chart.isTimeframeAllowed('1d')) { /* ... */ }

// React to changes, wherever they came from
const off = chart.eventBus.on('timeframe:change', ({ tf }) => {
    console.log(tf.label, tf.barNs);
});
typescript

You can't add to the preset list - it isn't exported. If you want a timeframe that isn't in there, it's a custom one, and allowCustom is what decides whether users can make their own.

Note

In a multi-chart layout every pane owns its timeframe independently, so two panes on the same instrument can sit at different resolutions. chart.setTimeframe() acts on the focused pane. If you want to set the timeframe of a specific chart, call chart.getChart(idx).setTimeframe(). See Multiple Charts.

Was this page helpful?