npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

scichart-scitrader

v0.0.4

Published

SciTrader: trading charts, studies, drawing tools and market depth for SciChart.js. Framework-agnostic.

Readme

SciTrader SDK - Financial Trading Charts in JavaScript

The SciTrader demo app, built with the SciTrader SDK, Desktop and Mobile Ready Financial Trading Charts in JS

scichart-scitrader is the SciTrader SDK: a complete toolkit for building financial trading and crypto charting apps in JavaScript and TypeScript. It gives you GPU-accelerated candlestick charts with linked multi-pane layouts, 30 technical indicators, about 35 drawing tools, a market-depth ladder, live exchange connectors, CSV data, themes, and the toolbars and settings forms that go around a chart.

It is the engine behind the SciTrader app: everything you see there is built from this package.

  • See it running: scitrader.io -> Menu -> Web App
  • Built on SciChart.js. SciTrader depends on SciChart.js, the high-performance WebGL and WebAssembly charting library, and on scichart-financial-tools.
  • Framework-agnostic. It works in plain TypeScript or JavaScript, and with any framework. For React, add scichart-scitrader-react.

License

Deployment of scichart-scitrader to commercial applications requires a SciChart Advanced License, and ships under the same license terms as SciChart.js. For non-commercial, or personal use, community license terms apply.

Contents

What's in the SDK

Financial charts

Candlestick, OHLC, line, mountain, Heikin-Ashi, Renko and point & figure charts

Candlesticks, OHLC bars, line, mountain and Heikin-Ashi candles, plus Renko and point & figure. Price, volume and indicator panes pan and zoom together. Users scroll to zoom, drag to pan, drag an axis to rescale it, and pan left to load older history, which is fetched in the background. A legend and crosshair follow the mouse.

Technical indicators

Moving averages, Bollinger Bands, RSI and MACD on a SciTrader chart

30 studies: moving averages, bands and channels, Ichimoku, oscillators such as RSI, MACD, Stochastic and ADX, volume studies, volume profile, and order-book studies. Every input and colour can be edited at runtime from a ready-made settings form, and you can write your own studies. See the full list.

Drawing tools

Fibonacci retracement, pitchfork and trend lines drawn on a chart

About 35 tools: lines, channels, pitchforks, Fibonacci tools, cycles, harmonic and Elliott wave patterns, measure, stop-loss / take-profit, freehand pen and highlighter. They come with a toolbar, a list of drawings, a floating quick-edit toolbar, keyboard shortcuts and touch support. See the full list.

Layout

Panes stacked vertically or side by side. Each pane has a control bar to resize, lock, maximise, hide, reorder and close it, with a touch layout for phones and tablets. Loading states, a skeleton placeholder and progress dots are built in.

Market depth

The market-depth ladder beside a chart

MarketDepthPanel draws a live order book as a price ladder, with depth bars, price grouping, flashes for pulled liquidity and a slippage readout on hover or long press.

Toolbars and UI components

Interval, period, candle-type and follow / anchored pickers, study settings forms, a colour picker, a study list, a drawings list, a candle counter, UI icons, and watchlist prices and sparklines. All plain DOM, styled by one stylesheet. See the full list.

Themes

The same chart in the dark, light and Ocean themes

Dark, light and Ocean themes are built in. One theme object sets every colour of the chart, its studies, its drawings and its UI, and switching theme restyles a live chart in place.

Data

Built-in connectors for Binance and Coinbase (history plus live updates, no API key), a CSV connector for your own files, and one interface to implement for any other source. Downloaded candles are cached in IndexedDB.

State

Save a chart, with its studies, settings, panes and drawings, to JSON, and restore it later.

Installation

npm install scichart-scitrader scichart scichart-financial-tools rxjs

scichart, scichart-financial-tools and rxjs are peer dependencies: your app installs them, and the SDK uses your copy. An app must have exactly one copy of SciChart, because SciChart keeps global state (the licence, the WebAssembly engine, and the registry used to save and restore charts).

| Package | Version | | -------------------------- | ------------------ | | scichart | 6.0.14 or later 6.x | | scichart-financial-tools | 6.0.14 or later 6.x | | rxjs | 7.5.5 or later |

The SDK's own dependencies (idb, technicalindicators) install automatically.

You need a bundler, such as webpack, Vite, esbuild, Rollup or Parcel. The package ships ES modules (esm/), CommonJS (cjs/) and TypeScript types (types/).

Import the stylesheet once, next to your first import of the SDK. It gives the toolbars, pane controls, menus and overlays their look:

import "scichart-scitrader/scitrader.css";

Without a bundler, link node_modules/scichart-scitrader/styles/scitrader.css from your page.

Serving SciChart's WebAssembly

SciChart draws with a WebAssembly engine. Your bundler bundles SciChart's JavaScript, but the browser downloads the engine as a separate file when the first chart is created, so your app has to serve it. The files are in node_modules/scichart/_wasm/:

| File | Loaded | | ---------------------- | -------------------------------------------------------------------- | | scichart.wasm | Always, in browsers with WebAssembly SIMD (every browser since 2023) | | scichart-nosimd.wasm | Instead of scichart.wasm, in older browsers |

Then tell SciChart the file's absolute URL, before the first chart is created. By default SciChart looks relative to the page's URL, which breaks on nested routes such as /charts/btc.

webpack, with copy-webpack-plugin:

// webpack.config.js
const CopyWebpackPlugin = require("copy-webpack-plugin");
const path = require("path");

const scichartWasm = path.join(path.dirname(require.resolve("scichart/package.json")), "_wasm");

module.exports = {
    // …
    plugins: [new CopyWebpackPlugin({ patterns: [{ from: scichartWasm, to: "" }] })],
};
import { SciChartSurface } from "scichart";

SciChartSurface.configure({ wasmUrl: "/scichart.wasm" });

Vite needs no copy step. Import each file's URL; Vite copies the file into the build and returns its hashed URL:

import { SciChartSurface } from "scichart";
import wasmUrl from "scichart/_wasm/scichart.wasm?url";
import wasmNoSimdUrl from "scichart/_wasm/scichart-nosimd.wasm?url";

SciChartSurface.configure({ wasmUrl, wasmNoSimdUrl });

Anything else: copy the folder to where your server publishes static files as part of your build, and call configure with the URL of scichart.wasm. Serve it with the application/wasm content type.

From a CDN, with no copy step. Your users then need to reach cdn.jsdelivr.net:

SciChartSurface.loadWasmFromCDN();

Notes for other bundlers:

  • Rollup also needs @rollup/plugin-replace to define process.env.NODE_ENV, which SciChart reads.
  • Parcel needs "@parcel/resolver-default": { "packageExports": true } in your package.json to find scichart-scitrader/scitrader.css.

If the file can't be loaded, chart creation fails with "Could not load SciChart WebAssembly module". Look for a 404 on scichart.wasm in the browser's network tab: its URL is where SciChart looked.

Getting started

A chart gets its candles from an exchange, looked up by name. This example charts your own CSV file, so it runs without network access to a live exchange.

1. A CSV file, served with your app at /data/crypto-1h.csv. One row per candle; a symbol column lets one file hold several symbols:

symbol,time,open,high,low,close,volume
BTCUSDT,2026-07-01 12:00,58622.02,58676,58326,58538.01,1716.61
BTCUSDT,2026-07-01 13:00,58538,59508,58536,59498.03,2321.79
ETHUSDT,2026-07-01 12:00,3402.11,3410.50,3391.02,3399.87,10234.5

2. A container with a size. The chart fills it and follows it when it resizes:

<div id="chart" style="height: 600px"></div>

3. The chart:

import "scichart-scitrader/scitrader.css";
import { SciChartSurface } from "scichart";
import {
    CandleInterval,
    CSVExchange,
    defaultExchangeProvider,
    ECandleType,
    OHLCStudy,
    registerCSVExchange,
    RSIStudy,
    SciFinanceChartPanel,
    SMAStudy,
    VolumeStudy,
} from "scichart-scitrader";

SciChartSurface.configure({ wasmUrl: "/scichart.wasm" });

// Register your data once, at startup, under the name charts will ask for.
const csv = await CSVExchange.fromUrl("/data/crypto-1h.csv", { name: "MyData" });
registerCSVExchange(defaultExchangeProvider, csv);

const panel = await SciFinanceChartPanel.create(document.getElementById("chart") as HTMLDivElement, {
    exchangeName: "MyData",
    symbol: "BTCUSDT",
    interval: CandleInterval.FOUR_HOURS, // resampled from the hourly rows
    period: "3M",
    studies: [new OHLCStudy(), new VolumeStudy(), new SMAStudy({ length: 50 }), new RSIStudy()],
});

SciFinanceChartPanel.create builds the layout, the price pane, a data feed for the symbol, and a pane for each study that needs one. It resolves with the panel's API:

| Member | Use | | -------------- | ---------------------------------------------------------------------------------------------------- | | financeApi | The chart (SciFinanceChart): studies, data feeds, interval, period, candle type, theme and events. | | paneGroupApi | The layout: pane order, sizes, visibility. | | toJSON() | The chart's state as JSON. | | cleanup() | Destroys the chart and its feeds. Call it when the element goes away. |

await panel.financeApi.changeInterval(CandleInterval.ONE_DAY, "1Y");
panel.financeApi.setCandleType(ECandleType.HeikinAshi);
panel.cleanup();

To chart live crypto data instead, register an exchange connector: see Data sources.

Chart configuration

SciFinanceChartPanel.create(container, config) takes an ISciFinanceChartPanelConfig:

| Option | Default | Meaning | | ------------------------------------ | ------------------------- | ----------------------------------------------------------------------------------------------------------- | | exchangeName, symbol, interval | required | The data to chart. | | studies | required | What to draw, in order: Studies. | | period | none | How much time to show at first: "1D", "5D", "1W", "1M", "3M", "6M", "YTD", "1Y", "ALL", … | | lockPeriodWidth | true | Whether period also caps how far the user can zoom out. | | liveTipMode | "follow" | Whether the view scrolls with new candles ("follow") or stays put ("anchored"). | | useSubCharts | true | Draw all panes on one surface (true, fastest), or give each pane its own surface (false). | | direction | "column" | Stack panes vertically ("column") or side by side ("row"). | | maxPanes | 6 | Most panes allowed. A study that would add more is refused, and paneLimitReached is raised. | | paneSizing | price 3 : indicator 1 | Size hints per pane id, e.g. { [PaneId.DEFAULT.value]: { grow: 4 } }. | | paneControls | all buttons, mouse layout | Each pane's control bar and the dividers: { visible, touch, buttons }. | | loading | skeleton and overlay | What panes show while they load. | | theme | SCITRADER_DARK_THEME | Every colour the chart draws with: Themes. | | axisDefaults | none | SciChart axis options applied to every axis, over the theme's. | | surfaceConfig | none | A function run on each pane's SciChartSurface as it is created. | | services | global | Data services private to this chart, e.g. its own exchange registry. |

Examples

Each example assumes the CSV exchange from Getting started is registered as "MyData", and container is a sized element. Everything is imported from scichart-scitrader unless shown otherwise.

Indicators with custom settings

A chart with SMA, EMA, Bollinger Bands, RSI and MACD

Overlays (moving averages, bands, channels) share the price pane. Oscillators each get a pane of their own. Constructor options set a study's inputs and styles; anything left out takes its default.

const panel = await SciFinanceChartPanel.create(container, {
    exchangeName: "MyData",
    symbol: "ETHUSDT",
    interval: CandleInterval.ONE_DAY,
    period: "6M",
    studies: [
        new OHLCStudy(),
        new VolumeStudy({ volumeUpColor: "#26A69A80", volumeDownColor: "#EF535080" }),
        new SMAStudy({ length: 50 }),
        new EMAStudy({ length: 20, renderOptions: { stroke: "#FFB74D", strokeThickness: 2 } }),
        new BollingerBandsStudy({ period: 20, stdDev: 2 }),
        new RSIStudy({ length: 14, overbought: 70, oversold: 30 }),
        new MACDStudy({ fast: 12, slow: 26, signal: 9 }),
    ],
    paneSizing: { [PaneId.DEFAULT.value]: { grow: 4 } },
});

// Add and remove studies later. A study's pane goes with it.
const stoch = new StochasticStudy({ length: 14, signalPeriod: 3 });
await panel.financeApi.attachStudy(stoch);
panel.financeApi.detachStudy(stoch);

Light theme, side-by-side panes, line chart

A light-themed chart with price and indicator panes side by side

const panel = await SciFinanceChartPanel.create(container, {
    exchangeName: "MyData",
    symbol: "SOLUSDT",
    interval: CandleInterval.ONE_HOUR,
    period: "1W",
    theme: SCITRADER_LIGHT_THEME,
    direction: "row", // panes side by side
    useSubCharts: false, // each pane its own SciChartSurface
    liveTipMode: "anchored",
    studies: [new OHLCStudy({ candleType: ECandleType.Line }), new IchimokuCloudStudy(), new ATRStudy({ length: 14 })],
    axisDefaults: { drawMinorGridLines: false, labelStyle: { fontSize: 12 } },
});

Touch layout, a trimmed control bar, and a pane limit

A chart on a phone with the touch control-bar drawer

const isPhone = window.matchMedia("(max-width: 600px)").matches;

const panel = await SciFinanceChartPanel.create(container, {
    exchangeName: "MyData",
    symbol: "BTCUSDT",
    interval: CandleInterval.FIFTEEN_MINUTES,
    period: "1D",
    maxPanes: 3,
    paneControls: {
        touch: isPhone, // control bar in a drawer, wider dividers
        buttons: { close: false, lockSize: false },
    },
    studies: [new OHLCStudy(), new VolumeStudy(), new StochasticStudy()],
});

panel.financeApi.paneLimitReached.subscribe(({ max, studyType }) =>
    showMessage(`${studyType} needs a new pane, and the chart has its maximum of ${max}`)
);

// The chart doesn't detect touch screens: switch a live chart when your layout changes.
panel.setPaneControls({ touch: true });

Drawing tools, with a toolbar and a list

A chart with the drawing toolbar on the left and the drawings list on the right

import { DrawingList, DrawingToolbar, DrawingToolsController } from "scichart-scitrader";
import { ETradingAnnotationType } from "scichart-financial-tools";

const panel = await SciFinanceChartPanel.create(container, {
    exchangeName: "MyData",
    symbol: "BTCUSDT",
    interval: CandleInterval.FOUR_HOURS,
    studies: [new OHLCStudy(), new VolumeStudy()],
});

const drawing = DrawingToolsController.attach(panel.financeApi, { touch: true });
DrawingToolbar.create(document.getElementById("tools"), drawing, { orientation: "vertical" });
DrawingList.create(document.getElementById("drawings"), { controller: drawing });

// Start a tool from your own button or shortcut, too.
drawing.selectTool(ETradingAnnotationType.FibonacciRetracementAnnotation);

Toolbar controls wired to the chart

import { CandleTypeSelector, IntervalSelector, LiveTipToggle, PeriodSelector } from "scichart-scitrader";

const chart = panel.financeApi;
const toolbar = document.getElementById("toolbar");

IntervalSelector.create(toolbar, {
    value: CandleInterval.FOUR_HOURS,
    intervals: [CandleInterval.ONE_HOUR, CandleInterval.FOUR_HOURS, CandleInterval.ONE_DAY, CandleInterval.ONE_WEEK],
    onChange: (interval) => chart.changeInterval(interval),
});
PeriodSelector.create(toolbar, {
    value: "3M",
    currentInterval: CandleInterval.FOUR_HOURS, // disables periods that don't suit the interval
    onChange: (period) => chart.setPeriod(period),
});
CandleTypeSelector.create(toolbar, { value: ECandleType.Candlestick, onChange: (t) => chart.setCandleType(t) });
LiveTipToggle.create(toolbar, { value: chart.liveTipMode, onChange: (mode) => (chart.liveTipMode = mode) });

Two files, one symbol: detailed intraday and long daily history

// Each interval comes from an exact match if there is one, else it is resampled from the coarsest
// file that divides it. Dates move forward so the last candle is now; pass alignToNow: false
// for data that is already current.
const csv = await CSVExchange.fromUrl(
    [
        { url: "/data/aapl-1h.csv", symbol: "AAPL" },
        { url: "/data/aapl-1d.csv", symbol: "AAPL" },
    ],
    { name: "Stocks", alignToNow: false }
);
registerCSVExchange(defaultExchangeProvider, csv);

Studies and indicators

Everything a chart draws is a study: OHLCStudy draws price, VolumeStudy draws volume, and every indicator is a study too. Pass them in studies, or add them later with financeApi.attachStudy(study). To create a study by type, for a picker or a saved chart, use studyProvider.getStudy(EStudyType.RSI).

| Name | Class | EStudyType | Category | Pane | | ------------------------------------------------------ | ------------------------- | -------------------- | ------------------- | ----- | | Price (candlestick, OHLC, line, mountain, Heikin-Ashi) | OHLCStudy | OHLC | Price & Chart Types | price | | Renko | RenkoStudy | Renko | Price & Chart Types | own | | Point & Figure | PointAndFigureStudy | PointAndFigure | Price & Chart Types | own | | Simple Moving Average (SMA) | SMAStudy | SMA | Trend | price | | Exponential Moving Average (EMA) | EMAStudy | EMA | Trend | price | | Weighted Moving Average (WMA) | WMAStudy | WMA | Trend | price | | Parabolic SAR (PSAR) | PSARStudy | PSAR | Trend | price | | Ichimoku Cloud | IchimokuCloudStudy | Ichimoku | Trend | price | | Average Directional Index (ADX) | ADXStudy | ADX | Trend | own | | Relative Strength Index (RSI) | RSIStudy | RSI | Momentum | own | | Moving Average Convergence / Divergence (MACD) | MACDStudy | MACD | Momentum | own | | Stochastic Oscillator | StochasticStudy | Stochastic | Momentum | own | | Commodity Channel Index (CCI) | CCIStudy | CCI | Momentum | own | | Williams Percent Range (Williams %R) | WilliamsRStudy | WilliamsR | Momentum | own | | Rate of Change (ROC) | ROCStudy | ROC | Momentum | own | | Triple EMA Oscillator (TRIX) | TRIXStudy | TRIX | Momentum | own | | Awesome Oscillator (AO) | AwesomeOscillatorStudy | AO | Momentum | own | | Bollinger Bands | BollingerBandsStudy | BBANDS | Volatility | price | | Keltner Channels | KeltnerChannelsStudy | Keltner | Volatility | price | | Donchian Channels | DonchianChannelsStudy | Donchian | Volatility | price | | Average True Range (ATR) | ATRStudy | ATR | Volatility | own | | Volume | VolumeStudy | Volume | Volume | price | | Volume Profile (volume traded by price) | VolumeProfileStudy | VolumeProfile | Volume | price | | Volume Weighted Average Price (VWAP) | VWAPStudy | VWAP | Volume | price | | On Balance Volume (OBV) | OBVStudy | OBV | Volume | own | | Money Flow Index (MFI) | MFIStudy | MFI | Volume | own | | Force Index | ForceIndexStudy | ForceIndex | Volume | own | | Order Book Heatmap (historical resting liquidity) | OrderBookHeatmapStudy | OrderBookHeatmap | Order Book | price | | Order Book Imbalance (bid vs ask depth) | OrderBookImbalanceStudy | OrderBookImbalance | Order Book | own |

The order-book studies need an order-book data source (IOrderBookSource, registered with setOrderBookSources). The Binance, Coinbase and CSV connectors don't provide one.

Candle types. The price study draws ECandleType.Candlestick, OhlcBars, Line, Mountain or HeikinAshi. Set it with new OHLCStudy({ candleType }), and change it on a live chart with financeApi.setCandleType(type). Renko and point & figure plot price movement rather than time, so they are studies with their own pane and an index axis.

Building a study picker. STUDY_MENU_ITEMS lists every study with its type, label, description and category. filterStudyMenuItems(items, { query, category }) searches it, and groupStudyMenuItems groups the result by category.

Settings forms. Every study describes its settings as a descriptor (study.getDescriptor(), study.applyDescriptor(d)). StudySettingsForm.create(container, { study }) renders it as a form whose edits apply to the chart live, with "Reset to defaults". StudyList.create(container, { chart: panel.financeApi }) lists the chart's studies, each with its form and a remove button.

Your own study. Extend StudyBase<T>, implement createInputOutputIds, createDataSeries, createAxes, createRenderableSeries and onDataChanged, and register it with studyProvider.registerStudy(...) so it can be created by type and restored from JSON.

Drawing tools

DrawingToolsController.attach(panel.financeApi) adds the drawing tools to every pane, shows a floating quick-edit toolbar on the selected drawing, and reports drawings as they change. Start a tool with selectTool(toolId). Drawings are saved with the chart.

Most tool ids are values of ETradingAnnotationType from scichart-financial-tools; the rest are EDrawingToolVariantId values from this package. DRAWING_TOOLS lists them all, with labels, icons and groups.

| Name | Tool id | Group | | ------------------------------- | --------------------------------------------------------------- | -------------- | | Poly Line (trend line) | ETradingAnnotationType.PolyLineAnnotation | Lines | | Extended Line | ETradingAnnotationType.ExtendedLineAnnotation | Lines | | Horizontal Line | ETradingAnnotationType.HorizontalTrendLineAnnotation | Lines | | Vertical Line | ETradingAnnotationType.VerticalTrendLineAnnotation | Lines | | Cross Line | ETradingAnnotationType.CrossLineAnnotation | Lines | | Angle Line | ETradingAnnotationType.AngleLineAnnotation | Lines | | Channel | ETradingAnnotationType.ChannelAnnotation | Channels | | Flat Bottom Channel | ETradingAnnotationType.FlatBottomChannelAnnotation | Channels | | Disjoint Channel | ETradingAnnotationType.DisjointChannelAnnotation | Channels | | Pitchfork | ETradingAnnotationType.PitchforkAnnotation | Pitchforks | | Inside Pitchfork | ETradingAnnotationType.InsidePitchforkAnnotation | Pitchforks | | Schiff Pitchfork | ETradingAnnotationType.SchiffPitchforkAnnotation | Pitchforks | | Modified Schiff Pitchfork | ETradingAnnotationType.ModifiedSchiffPitchforkAnnotation | Pitchforks | | Fibonacci Retracement | ETradingAnnotationType.FibonacciRetracementAnnotation | Fibonacci | | Fibonacci Extension | ETradingAnnotationType.FibonacciExtensionAnnotation | Fibonacci | | Fibonacci Time Zone | ETradingAnnotationType.FibonacciTimeZoneAnnotation | Fibonacci | | Fibonacci Speed Resistance Arcs | ETradingAnnotationType.FibonacciSpeedResistanceArcsAnnotation | Fibonacci | | Fibonacci Circles | ETradingAnnotationType.FibonacciCirclesAnnotation | Fibonacci | | Fibonacci Wedge | ETradingAnnotationType.FibonacciWedgeAnnotation | Fibonacci | | Pitchfan | ETradingAnnotationType.PitchfanAnnotation | Fibonacci | | Cyclic Line | ETradingAnnotationType.CyclicLineAnnotation | Cycles & Time | | Cyclic Arc | ETradingAnnotationType.CyclicArcAnnotation | Cycles & Time | | Sector | ETradingAnnotationType.SectorAnnotation | Cycles & Time | | XABCD Pattern | EDrawingToolVariantId.PatternXabcd | Patterns | | Elliott Impulse Wave (12345) | EDrawingToolVariantId.PatternElliottImpulse | Patterns | | Elliott Correction Wave (ABC) | EDrawingToolVariantId.PatternElliottCorrection | Patterns | | Elliott Triangle Wave (ABCDE) | EDrawingToolVariantId.PatternElliottTriangle | Patterns | | Elliott Double Combo (WXY) | EDrawingToolVariantId.PatternElliottDoubleCombo | Patterns | | Elliott Triple Combo (WXYXZ) | EDrawingToolVariantId.PatternElliottTripleCombo | Patterns | | Measure | ETradingAnnotationType.MeasureAnnotation | Measure & Risk | | Stop Loss / Take Profit | ETradingAnnotationType.StopLossTakeProfitAnnotation | Measure & Risk | | Freehand | ETradingAnnotationType.FreehandDrawingAnnotation | Freehand | | Highlighter | EDrawingToolVariantId.Highlighter | Freehand | | Eraser | EDrawingToolVariantId.Eraser | Eraser |

const drawing = DrawingToolsController.attach(panel.financeApi);

drawing.selectTool(ETradingAnnotationType.PitchforkAnnotation);
drawing.activeToolChanged.subscribe((tool) => console.log("active tool:", tool)); // null once placed
drawing.drawingsChanged.subscribe((items) => console.log(items.length, "drawings"));

drawing.stop(); // cancel the active tool
drawing.remove(); // delete every drawing, or pass one
drawing.detach(); // remove the tools from the chart; drawings stay

attach options include touch (long press selects; drag to aim the placement cursor, tap to commit each point), selectFinishedDrawing, resumeGestures, and editorContainer to offer the full annotation editor from the quick-edit toolbar.

Keyboard. Add OnChartKeyboardZoomPanModifier (arrows pan, + / - zoom, 0 resets) and AnnotationKeyboardSelectionModifier (N / P step through drawings, Delete removes, Esc deselects) to a pane's surface. OnChartButtonsModifier adds a zoom / pan / reset strip.

Toolbars and UI components

Each component is plain DOM: Component.create(container, options) builds it, update(options) changes it, and destroy() removes it. Controls that hold a value take value and onChange. They take their look from scitrader.css and follow the chart's theme.

Toolbars

| Name | Type | What it is | | -------------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | Drawing toolbar | DrawingToolbar | A rail of drawing tools, vertical or horizontal, with an "all tools" flyout. Default tools: DEFAULT_DRAWING_TOOLBAR_TOOLS. | | Drawing quick-edit toolbar | InlineAnnotationToolbar | Floats on the selected drawing: stroke colour, line thickness, delete, and a button to open the full editor. Shown by DrawingToolsController. | | Pane control bar | built in, set up by paneControls | Per-pane buttons: lock size, Y-axis autorange, move, maximise, hide, close. In a swipe-out drawer in the touch layout. | | Hidden-pane restore strip | built in | A pill for each hidden pane, to bring it back. | | On-chart buttons | OnChartButtonsModifier | A zoom in / zoom out / pan / reset strip on the pane under the mouse. | | Interval buttons | IntervalSelector | Candle interval, from 1s to 1M. | | Period buttons | PeriodSelector | Time span shown, with "Free"; disables periods that don't suit the interval. | | Candle-type menu | CandleTypeSelector | Candlestick, OHLC bars, line, mountain, Heikin-Ashi. | | Follow / Anchored toggle | LiveTipToggle | Whether the view follows new candles. |

Other components

| Name | Type | | --------------------------------------------------- | -------------------------------------------------------- | | Study settings form | StudySettingsForm | | List of the chart's studies, each with its form | StudyList | | Colour field with opacity | ColorPicker | | Gradient ramp editor | GradientRampEditor | | List of drawings | DrawingList | | Market-depth ladder | MarketDepthPanel (headless model: MarketDepthLadder) | | Candle counts (visible / loaded / total) | CandleCounter | | Loading progress dots | createPaneProgressDots, paneProgressDotsLoading | | UI icons as SVG | SCITRADER_ICONS, sciTraderIconSvg | | Watchlist prices, 24-hour change and sparkline data | WatchListDataManager | | Sparkline chart | SparkLineChart |

Data sources and exchanges

A chart asks for data by exchange name. Register each exchange once, at startup, with defaultExchangeProvider. It starts empty.

| Exchange | Export | Name | Live updates | Notes | | --------- | ------------------ | ----------------------------- | ------------ | ---------------------------------------------------------------------------------------------------- | | Binance | BinanceExchange | "Binance" | yes | Symbols like BTCUSDT. No API key. Binance refuses connections from some regions, including the US. | | Coinbase | CoinbaseExchange | "Coinbase" | yes | Symbols like BTC-USD. No API key. Fewer intervals than Binance. | | CSV files | CSVExchange | your choice (default "CSV") | no | Your own data. Serves the file's interval and every coarser one. |

import { BinanceExchange, CoinbaseExchange, defaultExchangeProvider, idbPriceStore } from "scichart-scitrader";

// idbPriceStore caches candles in IndexedDB, so a reload draws at once and fetches only what's new.
defaultExchangeProvider.registerExchange(BinanceExchange, idbPriceStore);
defaultExchangeProvider.registerExchange(CoinbaseExchange, idbPriceStore);

await SciFinanceChartPanel.create(container, {
    exchangeName: "Binance",
    symbol: "BTCUSDT",
    interval: CandleInterval.ONE_MINUTE,
    period: "1H",
    studies: [new OHLCStudy(), new VolumeStudy()],
});

mapSymbol("BTCUSDT", "Binance", "Coinbase") converts a symbol between exchanges.

CSV options. Columns are found by their usual names (time / date / timestamp, open, high, low, close, volume, symbol), or mapped with columns: { time: "Date", close: 4 }. Times may be epoch seconds, epoch milliseconds or date strings (UTC). Also: delimiter, hasHeader, timeUnit, symbol, alignToNow, candleLimit. Pass CSV text to new CSVExchange(text, options) instead of fromUrl if you already have it.

A custom exchange

To chart data from your own API, implement IRemoteExchange and register it:

import { EMPTY, Observable } from "rxjs";
import { CandleInterval, ExchangeRestCandle, IRemoteExchange, SciTraderCandle } from "scichart-scitrader";

class MyExchange implements IRemoteExchange {
    readonly name = "MyExchange";
    candleLimit = 1000; // most candles per getCandles call
    readonly hasCompleteCandleStream = true; // getCandleStream emits whole candles

    async getInstruments() {
        return ["ALPHA", "BETA"];
    }
    getSupportedIntervals() {
        return [CandleInterval.ONE_MINUTE, CandleInterval.ONE_HOUR, CandleInterval.ONE_DAY];
    }
    async getListingDate() {
        return { openTime: Date.UTC(2024, 0, 1) };
    } // or null if unknown

    // History: candles with start <= openTime <= end, oldest first, at most `limit`.
    // Times in epoch ms, closeTime = openTime + interval - 1; prices and volume as strings.
    async getCandles(
        symbol: string,
        interval: CandleInterval,
        start: number,
        end: number,
        limit: number
    ): Promise<ExchangeRestCandle[]> {
        const res = await fetch(
            `/api/candles?symbol=${symbol}&interval=${interval}&start=${start}&end=${end}&limit=${limit}`
        );
        return res.json();
    }

    // Live: emit the whole forming candle whenever it changes. EMPTY for history only.
    getCandleStream(symbol: string | string[], interval: CandleInterval): Observable<SciTraderCandle> {
        return EMPTY;
    }

    // Trades and tickers feed the trade studies and the watchlist. Empty if you have none.
    async getTrades() {
        return [];
    }
    getTradeStream() {
        return EMPTY;
    }
    getTickerStream() {
        return EMPTY;
    }
    getAllTickerStream() {
        return EMPTY;
    }
}

defaultExchangeProvider.registerExchange(new MyExchange(), idbPriceStore);
  • getCandles is all a historical chart needs. The SDK pages through long ranges in chunks of candleLimit, caches them, and stops at the listing date.
  • Without hasCompleteCandleStream, the SDK builds the live candle from getTradeStream instead.
  • Build Observables with the app's single copy of rxjs: two copies don't interoperate.
  • Use nullCandleStore instead of idbPriceStore for data that isn't stable between sessions, such as generated data.
  • To keep an exchange private to one chart, register it on createExchangeProvider() and pass services: { dataFeedManager: new DataFeedManager(provider) } in the chart's config.

Themes and styling

One theme object, ISciTraderTheme, sets every colour: the chart surface, axes, legend and crosshair, each study's defaults, drawings, the market-depth ladder, and the UI components. Three are built in:

| Theme | Export | | -------------- | ----------------------- | | Dark (default) | SCITRADER_DARK_THEME | | Light | SCITRADER_LIGHT_THEME | | Ocean | SCITRADER_OCEAN_THEME |

SCITRADER_THEMES (keyed dark, light, ocean) and SCITRADER_THEME_LIST list them, for a theme picker.

Your own theme. createSciTraderTheme(base, overrides) copies a theme and changes only the colours you list, so a custom theme stays complete as the SDK adds colours:

import { createSciTraderTheme, SCITRADER_DARK_THEME } from "scichart-scitrader";

const myTheme = createSciTraderTheme(SCITRADER_DARK_THEME, {
    name: "Midnight",
    chart: { background: "#0B1D2E", axisBackground: "#0F2438", gridLine: "#16324A", axisLabel: "#8FB3D1" },
    studies: {
        OHLC: { brushUp: "#26A69AB2", brushDown: "#EF5350B2", strokeUp: "#26A69A", strokeDown: "#EF5350" },
        EMA: { strokeColor: "#FFD54F" },
    },
    ui: { accent: "#4FC3F7" },
});

const panel = await SciFinanceChartPanel.create(container, { /* … */ theme: myTheme });

The groups are chart, candles, market, studies (keyed by EStudyType, then by the setting's name in the study's form), ui and drawing.

Switching a live chart. panel.financeApi.setTheme(SCITRADER_LIGHT_THEME) restyles everything in place. Colours set explicitly (a study constructor's colours, axisDefaults, a user's edits in a settings form) are kept.

Overriding the CSS. The HTML parts (toolbars, control bars, menus, forms, dialogs) are styled by scitrader.css, through st-* classes and CSS variables that follow the theme. Override them in your own CSS, loaded after it. Scoping under a class of your own keeps a change to one chart and wins whichever stylesheet loads first:

.my-chart .st-on-chart-buttons__button {
    border-radius: 4px;
}
.my-chart .st-drawing-toolbar__button[aria-pressed="true"] {
    border-width: 2px;
}

/* Your own elements can use the theme's variables */
.my-panel {
    background: var(--st-ui-panel, #262334);
    color: var(--st-ui-text-muted, #9da2bc);
}

States use attributes rather than extra classes: aria-pressed on toggles, aria-checked on menu items, aria-expanded, :disabled. applyThemeCssVariables(element, theme) writes a theme's variables onto any element, and themeToCssVariables(theme) lists them.

Axes and surfaces. Charts are drawn with WebGL, not CSS. axisDefaults sets any SciChart axis option on every axis, financeApi.applyAxisStyle(partial) changes them later, and surfaceConfig runs on each pane's SciChartSurface as it is created.

Saving and restoring

const state = panel.toJSON(); // studies, settings, panes, drawings, symbol, interval, period
localStorage.setItem("my-chart", JSON.stringify(state));

// Later
const saved: ISciFinanceChartPanelState = JSON.parse(localStorage.getItem("my-chart"));
const restored = await SciFinanceChartPanel.fromJSON(container, saved, { useSubCharts: saved.useSubCharts });

Custom studies must be registered with studyProvider before a state that uses them is restored. The zoom position isn't restored: the chart opens on its period.

The package

CommonJS is in cjs/, ES modules in esm/, types in types/, and the stylesheet in styles/scitrader.css. Deep imports such as scichart-scitrader/studies/RSIStudy resolve, but only the package entry point is the supported API.

Support