Commercial
API mapping
Concept by concept, from Lightweight Charts, Highcharts Stock, Advanced Charts or ChartIQ.
Read this page as Markdown, or take the whole documentation in one file.
How to Read This Page
If you have not decided yet, start with moving from TradingView or Highcharts: it is organised by how products actually embed a chart, and it says what the move costs from each shape. This page is the concept-by-concept mapping you want open while you do it.
Four libraries, four honest comparisons. Each section maps the concepts that line up, then states plainly what that library does which ORTEX Charts does not. The second half is the part that matters when you are deciding, so it is not buried.
Competitor APIs change between major versions. The mappings below are written against Lightweight Charts 5, Highcharts Stock 13, TradingView Advanced Charts 20-era and ChartIQ 8; check the exact names against the version you are on.
One thing is common to all four migrations: timestamps in ORTEX Charts are milliseconds since the Unix epoch, in UTC, everywhere. Not seconds, not business-day objects, not local dates. That single conversion is most of the work in a mechanical port.
The Translators Do the Mechanical Half
For the two libraries most people arrive from, you do not have to do the mapping by hand.
@ortex-charts/migrate takes what you already have — a TradingView datafeed and widget
options, or a Highcharts options object — and returns a working chart plus a list of what
did not carry over, so the port is a checklist rather than a guess.
npm install @ortex-charts/migrate
import { tradingViewWidget, tradingViewDatafeed, fromHighcharts } from "@ortex-charts/migrate";
// Drop-in for `new TradingView.widget({...})`
const shell = tradingViewWidget({ container_id: "chart", datafeed, symbol: "NASDAQ:AAPL", interval: "D", theme: "Dark" });
// Or keep your own shell and wrap only the datafeed
createChartShell(el, { datafeed: tradingViewDatafeed(myDatafeed), symbol: "NASDAQ:AAPL", resolution: "1D" });
// Highcharts and Highcharts Stock, options object and all
const { chart, series, indicators, markers, unsupported } = fromHighcharts(el, highchartsOptions);
if (unsupported.length) console.info("Look at:", unsupported);
The inputs are typed to accept the vendors' own objects as they are: a
ChartingLibraryWidgetOptions with its IBasicDataFeed, or a Highcharts.Options, without
a cast. Two pages port one real chart each, end to end: moving from
Highcharts and moving from TradingView.
The TradingView wrapper turns the callback interface into the promise one: onReady is
awaited once, resolveSymbol is resolved once per symbol and cached, getBars is converted
from seconds to milliseconds, subscribeBars returns an unsubscribe function, and
resolutions map both ways (D ↔ 1D). pricescale and minmov become priceFormat, and
the first entry of logo_urls becomes the legend logo. supportedResolutions() on the
wrapped feed answers with what the symbol, else onReady, declared, and
tradingViewWidgetAsync waits for it so the toolbar offers only those.
The Highcharts translator reads the series types (line, spline, area, areaspline,
column, bar, candlestick, ohlc, scatter), every point shape Highcharts accepts,
y-axes placed with top and height as panes, the column on the second axis under a
candlestick as the volume, sma, ema, wma, rsi, atr, bb, macd and stochastic
series as indicators with their periods, flags as markers, plotLines as price lines
(once per axis), a left axis, and dashStyle, lineWidth, fillOpacity and visible.
fromHighchartsCategory and fromHighchartsPie do the same for column, bar and pie charts.
Anything without a counterpart is reported rather than silently dropped, and nothing is
emitted for it: the Highcharts translator lists series types, yAxis.min/max, percent
stacking and the modules the shell replaces (navigator, rangeSelector, scrollbar,
exporting, annotations, stockTools) in unsupported; the TradingView translator lists
every widget key, disabled_features or enabled_features flag and overrides path it did
not read in ignored, on the shell it returns. translateHighcharts,
translateHighchartsCategory, translateHighchartsPie and fromTVWidgetOptions return the
translation without creating anything, which is what you want in a test or a gradual move.
The rest of this page is the conceptual mapping, which you still want to read: the translators get a chart on the screen, not a finished port.
From TradingView Lightweight Charts
This is the easiest migration of the four. The mental models are close: one chart, series you add to it, data you set and update, a time scale you drive.
API Mapping
| Lightweight Charts | ORTEX Charts |
|---|---|
createChart(el, options) |
createChart(el, options), or createFinancialChart(el, options) for a chart with a volume pane |
chart.addSeries(CandlestickSeries, o) |
chart.addSeries("candlestick", o) |
chart.addSeries(LineSeries, o) |
chart.addSeries("line", o) |
chart.addSeries(AreaSeries, o) |
chart.addSeries("area", o) |
chart.addSeries(BaselineSeries, o) |
chart.addSeries("baseline", o) |
chart.addSeries(HistogramSeries, o) |
chart.addSeries("histogram", o) |
chart.addSeries(BarSeries, o) |
chart.addSeries("bar", o) |
series.setData(data) |
series.setData(data) |
series.update(bar) |
series.update(bar) |
series.applyOptions(o) |
series.applyOptions(o) |
chart.removeSeries(series) |
chart.removeSeries(series.id) |
chart.applyOptions(o) |
chart.applyOptions(o) |
chart.timeScale().fitContent() |
chart.timeScale.fitContent() |
chart.timeScale().setVisibleLogicalRange({from, to}) |
chart.timeScale.setVisibleRange(from, to) |
chart.timeScale().scrollToRealTime() |
chart.timeScale.scrollToRealtime() |
chart.subscribeCrosshairMove(cb) |
chart.subscribeCrosshairMove(cb) |
chart.subscribeClick(cb) |
chart.subscribeClick(cb) |
chart.addPane() |
chart.addPane({ heightRatio }) |
createSeriesMarkers(series, markers) |
addSeriesMarkers(chart, series, markers), or fc.setMarkers(markers) |
series.createPriceLine(o) |
chart.addPriceLine(series.id, o) |
chart.remove() |
chart.remove() |
| Custom series plugin | registerSeriesType(name, def) |
| Pane primitive plugin | chart.addPrimitive(primitive, paneId) |
The Differences That Bite
timeScaleis a property, not a method.chart.timeScale.fitContent().- Times are milliseconds. Lightweight Charts takes Unix seconds or a business-day
object. Multiply by 1,000; convert
{ year, month, day }to a UTC midnight timestamp. - Series are removed by id, not by reference:
chart.removeSeries(series.id). - Series types are strings, not imported constructors.
- Colors default from the theme. Where you set
upColoranddownColoron every series, you can set them once in the theme instead. - A series declares how it aligns to the main timeline. Lightweight Charts requires every
series to share a time axis; here a daily series on an intraday chart is
align: "forwardFill"rather than a data-preparation problem.
What Lightweight Charts Has That ORTEX Charts Does Not
- It is open source, Apache 2.0. No license key, no mark, no contract, no cost. If that is the deciding factor, it decides.
- It is about 5 KB smaller for the subset it covers.
- It has a longer public track record and a larger body of community examples.
What You Gain
A toolbar, symbol search, 32 drawing tools, 51 indicators, event markers, order flow, bar replay, alerts, host-managed layouts, an adapter layer, and a faster first paint at large data sizes — for about 5 KB more.
From Highcharts Stock
The mental model is further away. Highcharts is declarative: you describe a whole chart as
one options object and call update to change it. ORTEX Charts is imperative: you create
objects and call methods on them.
API Mapping
| Highcharts Stock | ORTEX Charts |
|---|---|
Highcharts.stockChart(el, options) |
createFinancialChart(el, options) |
series: [{ type: "candlestick", data }] |
chart.addSeries("candlestick").setData(data) |
data: [[x, o, h, l, c]] |
[{ time, open, high, low, close, volume }] |
series: [{ type: "line", data: [[x, y]] }] |
chart.addSeries("line").setData([[time, value]]) |
yAxis: [{ …}, { … }] with height and top |
chart.addPane({ heightRatio }) plus priceScaleId |
yAxis.type: "logarithmic" |
chart.priceScale("right").applyOptions({ mode: "logarithmic" }) |
series[i].addPoint(point, redraw, shift) |
series.update(point) |
series[i].setData(data) |
series.setData(data) |
chart.update(options) |
chart.applyOptions(options) |
series[i].update({ color }) |
series.applyOptions({ color }) |
series: [{ type: "sma", linkedTo: "main", params: { period } }] |
chart.addIndicator("sma", { length }) |
series: [{ type: "flags", data }] |
chart.setEvents(events) or chart.setMarkers(markers) |
chart.setSize(w, h) |
chart.resize(w, h), or leave autoSize on |
Highcharts.setOptions({ colors }) |
chart.setTheme({ ...darkTheme, palette }) |
chart.destroy() |
chart.remove() |
exporting module |
chart.takeScreenshot(), shell.exportCsv(), downloadPNG, downloadCSV |
The Differences That Bite
- There is no global options object. Nothing is configured for the page; every chart carries its own options and its own theme.
- Panes are not y-axes with pixel offsets. A pane is a real container with a relative height weight, and a scale lives inside it.
- Indicators are not linked series. They are a separate concept with their own registration, inputs and outputs.
- Rendering is Canvas, not SVG. There is no DOM node per point to style with CSS or select with a query, and no SVG export. Styling is options and theme tokens.
- Redrawing is automatic. There is no
redrawflag on mutators; the chart schedules a frame. - Times are milliseconds here as well, which Highcharts also uses, so this is the one migration where timestamps need no conversion.
What Highcharts Stock Has That ORTEX Charts Does Not
- A navigator strip and range-selector buttons (1m, 3m, YTD, 1y, All) as built-in
components. Range presets are the shell's period buttons, or a few lines on
setVisibleTimeRange; a navigator mini-chart is not built in. The "All" button is nottimeScale.fitContent()on a long history: Highcharts groups daily bars into weekly points to fit ten years in one view, whilefitContentstops atminBarSpacing, half a pixel per bar by default, so 2,500 daily bars do not fit in 1,100 pixels and the view opens on the most recent bars that do. LowertimeScale.minBarSpacing, or open on a year. - An accessibility module: screen-reader descriptions of the data, a focusable data table, and keyboard navigation of points. See The toolbar for what is and is not implemented here.
- A server-side export server producing PNG, PDF and SVG from a running service.
- SVG rendering, if per-point DOM matters to you for styling or testing.
- A boost module for very large point counts.
What You Gain
About a fifth of the payload, a financial toolbar and drawing tools that Highcharts Stock does not include, an index-based time axis that removes closed periods without configuration, order flow, bar replay, and per-product rather than per-developer licensing.
From TradingView Advanced Charts
This is the migration with the largest gap in both directions, because Advanced Charts is a complete application delivered as a widget rather than a library you compose.
API Mapping
| Advanced Charts | ORTEX Charts |
|---|---|
new TradingView.widget({ … }) |
createChartShell(el, { … }) |
datafeed with onReady, resolveSymbol, getBars, subscribeBars, searchSymbols |
Datafeed with resolveSymbol, getBars, subscribeBars, searchSymbols; no onReady |
LibrarySymbolInfo |
SymbolInfo |
resolution as "1", "60", "1D" |
The same notation |
widget.setSymbol(symbol, interval, cb) |
shell.setSymbol(s) and shell.setResolution(r) |
widget.activeChart().createStudy(name, …) |
shell.addIndicator(id, inputs) |
widget.activeChart().createShape(point, o) |
tools.add({ kind, points, style }) |
widget.activeChart().createMultipointShape(points, o) |
The same |
widget.activeChart().setChartType(n) |
shell.setSeriesType("candlestick") |
widget.activeChart().setVisibleRange({from, to}) |
chart.timeScale.setVisibleTimeRange(from, to) |
widget.save(cb) and widget.load(state) |
shell.getLayout() and shell.setLayout(layout) |
disabled_features and enabled_features |
toolbar, drawings, indicators, drawingTools switches |
overrides |
Theme tokens and series options |
widget.onChartReady(cb) |
The shell is ready when createChartShell returns |
| Timescale marks | chart.setEvents(events) with style: "lane" |
| Compare study | The built-in price overlay for another symbol |
Datafeed shapes are deliberately close, so a port is usually mechanical: drop onReady,
return { bars, noMoreData } instead of calling onHistoryCallback, and return bars with
millisecond time rather than second time.
The Differences That Bite
- Callbacks become promises.
getBarsreturns a promise instead of callingonHistoryCallbackandonErrorCallback. - Times are milliseconds, not seconds.
- There is no iframe. The chart is in your DOM, so your CSS, your fonts and your developer tools all apply — and so do your layout bugs.
- State is yours. There is no
save/loadserver contract and no chart storage service;getLayoutgives you JSON and you decide where it lives. - Feature flags become option switches. The
disabled_featuresstring list is replaced by typed options on the shell.
What Advanced Charts Has That ORTEX Charts Does Not
- Around 110 built-in studies against 51. The long tail there is mostly variations on what is here.
- The TradingView platform behind it: the interface users already recognize, and the Pine Script ecosystem that comes with the platform rather than with the library. Custom studies in Advanced Charts itself are JavaScript, as they are here.
- Around 90 drawing tools against 32.
- Multi-chart layouts (two-by-two and the rest) as a built-in container, with symbol and
interval synchronization.
linkChartssynchronizes time and crosshair here, but the grid container is your CSS. - Around 30 interface languages. The chrome here is English only.
- A broker and order-management integration — order tickets, positions, depth of market, an account panel — in the Trading Platform edition.
- The brand recognition. Users know the interface.
What You Gain
89.9 KB in one file instead of 4.8 MB across 154. A chart you can style, extend and debug. No attribution requirement on a licensed build, and no restriction to services offered free of charge: the free Advanced Charts agreement requires the TradingView mark and a service the public can use without paying, which rules out a subscription product and an internal desk tool outright.
From ChartIQ
ChartIQ is the closest competitor on feature depth and the furthest away on API style. It is also the most expensive of the four, sold as an annual enterprise contract.
API Mapping
| ChartIQ | ORTEX Charts |
|---|---|
new CIQ.ChartEngine({ container }) |
createFinancialChart(el, options) |
stxx.loadChart(symbol, { periodicity, masterData }) |
chart.bind(datafeed, { symbol, resolution }) |
quotefeed with fetchInitialData, fetchPaginationData, fetchUpdateData |
Datafeed with getBars and subscribeBars |
stxx.setPeriodicity({ period, interval }) |
binding.setResolution("15") |
stxx.setChartType("candle") |
fc.setSeriesType("candlestick") |
stxx.setChartScale("log") |
chart.priceScale("right").applyOptions({ mode: "logarithmic" }) |
CIQ.Studies.addStudy(stxx, "rsi", inputs, outputs) |
fc.addIndicator("rsi", inputs, options) |
stxx.addSeries(symbol, params) |
chart.addSeries(type, options).setData(data) |
stxx.createDrawing(kind, params) |
tools.add({ kind, points, style }) |
stxx.exportDrawings() and importDrawings() |
tools.getDrawings() and setDrawings() |
stxx.append/updateChartData |
series.update(bar) |
| Themes as CSS | Theme tokens on the chart |
stxx.destroy() |
chart.remove() |
The Differences That Bite
- Styling is options, not CSS. ChartIQ is styled with stylesheets over its own class names; here every color is a theme token or a series option.
- There is no periodicity object. A resolution is a string.
- There is no
masterDataconcept; series own their own data and alignment.
What ChartIQ Has That ORTEX Charts Does Not
- A much deeper indicator and study library, with study editing, comparison studies and a study browser.
- Term structure, options chains, cross-section and time-span event charts as first-class chart types.
- A trading and order-management integration, and a market-depth component.
- Multi-chart layouts and workspace management as products in their own right.
- A managed data service and a signature integration ecosystem.
- An accessibility story, including screen-reader support.
What You Gain
The demo transfers 4.4 MB and reaches DOMContentLoaded at 3.4 seconds. The full ORTEX chart is 89.9 KB in one file. Order flow — footprint bars, exact volume and market profiles, real delta from aggressor data — is included rather than a platform tier. And the price is public.
A Migration Checklist
Whichever library you are coming from:
- Convert timestamps to milliseconds, UTC. Multiply seconds by 1,000, convert business-day objects to a UTC midnight, and drop local-date parsing.
- Set
timeZoneto the exchange zone, not to the browser zone, or daily bars will land on the wrong day for a third of your users. - Set
sessionif you draw intraday bars, so hourly candles start at the open. See Time, sessions and resolutions. - Move colors into a theme rather than onto every series, so the theme switch works.
- Replace per-series time alignment work with
align. Data that does not share the price timeline is a series option here, not a pre-processing step. - Replace
setData-per-tick withupdate. This is the single biggest performance difference between a good port and a bad one. - Decide where layouts and drawings live, because the library will not decide for you. See The shell and layouts.
- Audit your indicator list against the 51 built-ins and budget for the ones you have to write. This is the most common source of unplanned work in a migration.
The Honest Summary
| If you need | Choose |
|---|---|
| Open source with no license at all | Lightweight Charts |
| 110 studies, 90 drawing tools, 30 interface languages | TradingView Advanced Charts |
| A navigator, an accessibility module, a server-side export service, SVG | Highcharts Stock |
| The deepest study library, term structure, order management, an enterprise contract | ChartIQ |
| Millions of points on screen at 60 Hz | SciChart |
| A small, fast, extensible financial chart with a toolbar, drawings, order flow and replay, that you can white-label, priced per product | ORTEX Charts |