ox-charts

Implementing IDatafeed

Two required calls, history and a live subscription, plus symbol search with filters and the per-symbol instrument spec.

A datafeed pours bars into the chart. The shell asks for history once per cell and symbol, then subscribes for live updates.

import type { IDatafeed, OhlcBar } from "@option-x-tech/ox-charts";

export const feed: IDatafeed = {
  // Up to `countback` bars ending at (and including) `to`, oldest first.
  async getHistory({ symbol, resolution, to, countback }) {
    const rows = await api.history(symbol, resolution, to, countback);
    return rows.map((r): OhlcBar => ({ time: r.t, open: r.o, high: r.h, low: r.l, close: r.c, volume: r.v }));
  },
  // One full bar per tick. Same time = update the live bar; newer time = append.
  subscribe(symbol, resolution, onBar) {
    const off = socket.on(symbol, resolution, (bar) => onBar(bar));
    return () => off();
  },
  // Optional: the symbol search dialog. Its category tab and exchange row arrive as `filter`.
  async searchSymbols(query, filter) { return api.search(query, filter?.type, filter?.exchange); },
  // The readable name and the instrument spec, per symbol. Trading needs it.
  async resolveSymbol(symbol) {
    const c = await api.contract(symbol);
    return c ? { symbol, name: c.displayName, exchange: c.exchange, type: c.kind, tickSize: c.tick, decimals: c.decimals, lotSize: c.lot } : null;
  },
  exchanges: ["NSE", "NFO", "BSE"],                          // optional: the dialog's exchange row
  symbolTypes: ["index", "stock", "future", "option"],       // optional: its category tabs
};
Symbol callWhat the chart does with it
searchSymbols(query, filter)Shows exactly what you return; filter server-side. An empty query asks for the selected category's defaults.
resolveSymbol(symbol)Cached per symbol. name is what every surface shows instead of the id; tickSize, decimals and lotSize drive that symbol's axis, ticket, order lines and lot maths.
NeitherThe id is shown as-is, and the symbol cannot be traded: there is no lot size to size an order with.
RuleWhy
time is a UTC timestamp in seconds, the bar's openEvery layer maps bars by time
Emit a whole bar snapshot, not a trade printThe engine replaces the last bar when the time matches
Return the unsubscribe functionCells unsubscribe on symbol, interval or layout changes
Resolutions are 1 3 5 10 15 30 60 1DThe interval menu offers exactly these

Order flow is opt-in

A feed that also implements the footprint interface (IFootprintDatafeed) unlocks the Order flow button, the footprint modes and exact delta. A depth feed (IDepthDatafeed) unlocks the order-book heatmap. Without them those controls are greyed out with a reason.