Datafeeds
MarketDataFeed is the single boundary between the chart and your market data,
whether that data arrives over REST, a WebSocket, a broker, an exchange, or your
own application state. One method makes the chart render candles. Every other
method is a deliberate decision to light up one more surface.
loadBars is the only required method. A bars-only feed is a complete,
supported integration. Add other capabilities only when the product needs them.
How the chart talks to your feed
The chart drives every request; the feed only answers. You own transport, authentication, and vendor caching. The SDK owns chart-side bar memory, deduplication, and the viewport.
Optional methods follow the same pattern: the chart calls them only when the
feed both implements the method and advertises the matching supports* flag.
1. Implement historical bars
This is the smallest useful REST-backed datafeed:
import type { MarketDataFeed } from '@tradescript/pro/sdk/core';
export const datafeed: MarketDataFeed = {
async loadBars(symbol, interval, request) {
const query = new URLSearchParams({
symbol: symbol.ticker,
interval,
from: String(request.startTime),
to: String(request.endTime),
count: String(request.barCount),
});
const response = await fetch(`/api/bars?${query}`);
if (!response.ok) {
throw new Error(`Bars request failed: ${response.status}`);
}
return response.json();
},
};
Return bars in ascending timestamp order. See Historical Bars for the response shape, pagination, timestamps, and cache ownership rules.
Verify before continuing:
- The chart renders candles for the mounted symbol and interval.
- Scrolling left triggers another
loadBarscall for an older range and the chart extends without gaps or duplicated timestamps. - A failing endpoint rejects the request (throw); it does not resolve with invented bars.
2. Choose the next capability
Pick the row your product needs next, implement its methods, advertise its flag, and stop. Partial feeds are first-class — bars-only, bars plus realtime, and full order-flow feeds are all valid production shapes.
| Product capability | Implement | Configure | Guide |
|---|---|---|---|
| Realtime bars | subscribeRealTimeBars | supportsRealTime | Realtime Bars |
| Symbol search | searchSymbols, resolveSymbol | supportsSearch | Symbol Search |
| Quotes | getQuotes, subscribeQuotes | supportsQuotes | Quotes and Watchlists |
| Sessions | resolveSessionInfo, subscribeSessionInfo, resolveSessionCalendar | supportsSessionInfo, supportsSessionCalendar | Session Schedules |
| Depth and tape | getDepth, subscribeDepth, getTimeAndSales, subscribeTimeAndSales | supportsDepth, supportsTimeAndSales | Order Flow |
| Marks, events, and news | getMarks, getTimescaleMarks, getEvents, subscribeEvents, getNews | Matching flags; events also require eventCatalog | Market Events |
| Instrument and watchlist UI | getInstrumentDetails, watchlist read/write methods | supportsDetails, supportsWatchlist | Quotes and Watchlists |
| Options and data window | getOptionContracts, getOptionQuotes, getDataWindow | Matching supports* flags | Option Chains |
See the MarketDataFeed API
for every current method and exact signature.
Configure intervals
The chart uses this default interval list when the feed does not provide one:
[
'1m', '2m', '3m', '5m', '10m', '15m', '30m',
'1H', '2H', '4H', '1D', '1W', '1M',
]
Use supportedIntervals for intervals the user may select and
providedIntervals for intervals loadBars can return directly:
onReady() {
return {
supportedIntervals: ['1m', '5m', '15m', '1H', '1D'],
providedIntervals: ['1m', '5m', '1D'],
resolutionRebuildPolicy: 'aggregate',
};
}
With resolutionRebuildPolicy: 'aggregate', createCachingDatafeed may build a
selected interval from a smaller provided interval. See
Resolutions for ticks, seconds, custom intervals, and
aggregation rules.
Keep capabilities aligned
Advertise only the surfaces the feed is ready to serve:
onReady() {
return {
supportsSearch: true,
supportsRealTime: true,
supportsQuotes: true,
supportsSessionCalendar: true,
emptyBars: true,
};
}
The chart intersects declared support with implemented methods. Events also
require an exact, non-empty eventCatalog.
resolveSessionCalendar supplies the historical trading windows used by
synthetic aggregation and empty-bar generation, including half-days and
corrections.
Production concerns
Cache invalidation
Implement resetCache(request) when the feed owns history caches outside the
SDK. chart.resetCache() and widget.resetCache() call it before clearing
SDK-held bar memory and reloading the mounted chart.
Quotes and events
Quote methods power legend quote fields, market status, and bid, ask, and previous-close price lines. Event methods power semantic timeline events such as earnings, dividends, filings, halts, and economic releases. See Market Events for the event contract.
Currency and unit conversion
Currency and unit conversion is feed-owned. The SDK does not multiply prices, volumes, or units after bars arrive. A price-scale target change re-enters symbol resolution, and the feed returns a symbol whose future history and realtime requests are already converted.
Use onReady().currencyCodes and onReady().units to advertise available
targets. The feed receives the requested target through resolveSymbol:
resolveSymbol(currentSymbol, { currencyCode: 'EUR', unitId: 'lot' });
A converted symbol should include display metadata and a stable identity that distinguishes converted and unconverted history:
{
ticker: 'AAPL',
canonicalSymbol: 'AAPL|EUR|lot',
currency: 'EUR',
originalCurrency: 'USD',
unitId: 'lot',
originalUnitId: 'share',
}
The canonicalSymbol shape is only an example. If the public ticker must stay
unchanged, include currency and unit fields in the feed's internal cache key.
Browser security
The chart runs in your page, so fetch and WebSocket requests originate from the application's origin. Cross-origin providers must allow that origin and any custom authentication headers. See Deployment and CSP for the production checklist.
Next steps
- Historical Bars — the exact
loadBarsrequest and response contract, pagination, and timestamp rules. - Realtime Bars —
subscribeRealTimeBars, and when a tick updates the last bar versus appends a new one. - Resolutions — which intervals you serve natively, which the SDK derives, and how unsupported intervals surface.
- Symbol Search —
searchSymbolsandresolveSymbolbehind the symbol picker. - Order Flow — depth, tape, derivatives series, and book history for the ladder, heatmap, footprint, and market profile.