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 call | What 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. |
| Neither | The id is shown as-is, and the symbol cannot be traded: there is no lot size to size an order with. |
| Rule | Why |
|---|---|
time is a UTC timestamp in seconds, the bar's open | Every layer maps bars by time |
| Emit a whole bar snapshot, not a trade print | The engine replaces the last bar when the time matches |
| Return the unsubscribe function | Cells unsubscribe on symbol, interval or layout changes |
Resolutions are 1 3 5 10 15 30 60 1D | The 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.