Skip to main content

Realtime Bars

Realtime subscriptions keep the active symbol and interval live once historical bars have loaded. Three behaviors define a correct subscription: the last candle ticks in place, a new candle appears when the interval rolls over, and a correction reloads without leaving a stale bar behind.

Who owns what

  • The chart calls subscribeRealTimeBars(subscription, callback) once per active symbol/interval and later calls the returned Unsubscribe function when the symbol, interval, or chart goes away.
  • Your feed owns the transport (WebSocket, SSE, polling) and pushes complete Bar objects through callback.
  • The SDK decides update-vs-append purely from bar.time — there is no separate "update" API.

Minimal working path

datafeed.ts
const datafeed: MarketDataFeed = {
async loadBars(symbol, interval, request) {
return fetchBars(symbol, interval, request);
},

subscribeRealTimeBars(subscription, callback) {
const socket = connectBarStream(
subscription.symbol.ticker,
subscription.interval,
);
socket.onBar((bar) => callback(bar)); // complete Bar, ms timestamp

return () => socket.close(); // Unsubscribe
},
};

Advertise the capability with supportsRealTime: true from onReady().

Checkpoint: with the feed connected to a live source, the last candle's close/high/low/volume change in place between interval boundaries, and exactly one new candle appears at each boundary.

Update vs. append, with concrete values

Suppose the last chart bar is the 1m bar for 13:30:00Z:

{ time: Date.parse('2026-07-09T13:30:00Z'),
open: 187.2, high: 187.4, low: 187.1, close: 187.3, volume: 1200 }

Same timestamp → update in place. A trade prints inside the same minute; emit the whole bar again with the same time:

callback({ time: Date.parse('2026-07-09T13:30:00Z'),
open: 187.2, high: 187.5, low: 187.1, close: 187.5, volume: 1450 });
FieldBeforeAfter
high187.4187.5
close187.3187.5
volume12001450
Bar countnn (unchanged)

Newer timestamp → append. The minute rolls over; emit the next bar:

callback({ time: Date.parse('2026-07-09T13:31:00Z'),
open: 187.5, high: 187.6, low: 187.4, close: 187.6, volume: 300 });

Bar count becomes n + 1. If the user is at the right edge, the viewport stays locked to the latest bar; if they have scrolled back, the viewport does not jump.

Older timestamp → not a realtime update. A bar older than the last chart bar is an out-of-order correction. Do not emit it through callback; call subscription.onResetCacheNeeded?.() and let the SDK clear cached bars and refetch visible history.

Subscription lifecycle

On unsubscribe, stop emitting immediately: callbacks after unsubscribe are a bug in the feed. On reconnect, if the stream may have dropped ticks, prefer onResetCacheNeeded over guessing — the SDK refetches through loadBars, so the repaired history comes from your source of truth.

Corrections and cache reset

Use same-timestamp realtime bars for edits to the currently open bar. Use onResetCacheNeeded for corrections to older bars, vendor reconnect repairs, split adjustments, or any event where the visible history may no longer match the feed's source of truth.

onResetCacheNeeded clears SDK-held cache entries for the subscribed symbol/interval and asks the chart to reload. If the feed owns additional history caches, implement resetCache(request) as well so host calls such as chart.resetCache() clear both SDK and feed-side state.

Full contract

RealTimeBarSubscription and callback types
export interface RealTimeBarSubscription {
id: string;
symbol: SymbolInfo;
interval: ChartInterval;
transport?: RealTimeTransportOptions;
metadata?: Record<string, unknown>;
onResetCacheNeeded?: () => void;
}

export type RealTimeBarCallback = (bar: Bar) => void;
export type Unsubscribe = () => void;

id is a stable subscription identifier assigned by the chart; use it to key feed-side subscription state. Bar.time is Unix milliseconds, matching historical bars.

Next steps

  • Session Filtering — drop bars outside included session states before they reach the chart.
  • Order Flow — depth and tape streams for microstructure views.