SciChart.js JavaScript 2D Charts API > 2D Chart Types > The Candlestick Series type
The Candlestick Series type

Candlestick Series or JavaScript Stock Charts can be created using the FastCandlestickRenderableSeries type.

The JavaScript Candlestick Chart Example can be found in the SciChart.Js Examples Suite on Github, or our live demo at demo.scichart.com

Above: The JavaScript Candlestick Chart example from the SciChart.js Demo.

Create a Candlestick Series

To create a Javascript Candlestick Chart with SciChart.js, use the following code:

// Demonstrates how to create a Candlestick chart with SciChart.js
const {
  SciChartSurface,
  CategoryAxis,
  NumericAxis,
  FastCandlestickRenderableSeries,
  OhlcDataSeries,
  SciChartJsNavyTheme
} = SciChart;

// or, for npm, import { SciChartSurface, ... } from "scichart"

const { wasmContext, sciChartSurface } = await SciChartSurface.create(divElementId, {
  theme: new SciChartJsNavyTheme()
});
sciChartSurface.xAxes.add(new CategoryAxis(wasmContext));
sciChartSurface.yAxes.add(new NumericAxis(wasmContext, { labelPrefix: "$", labelPrecision: 2 }));

// Data format is { dateValues[], openValues[], highValues[], lowValues[], closeValues[] }
const { dateValues, openValues, highValues, lowValues, closeValues, volumeValues }
    = await getCandles("BTCUSDT", "1h", 100);

// Create a OhlcDataSeries with open, high, low, close values
const dataSeries = new OhlcDataSeries(wasmContext, {
  xValues: dateValues,
  openValues,
  highValues,
  lowValues,
  closeValues,
});

// Create and add the Candlestick series
const candlestickSeries = new FastCandlestickRenderableSeries(wasmContext, {
  strokeThickness: 1,
  dataSeries,
  dataPointWidth: 0.7,
  brushUp: "#33ff3377",
  brushDown: "#ff333377",
  strokeUp: "#77ff77",
  strokeDown: "#ff7777",
});
sciChartSurface.renderableSeries.add(candlestickSeries);
// Demonstrates how to create a line chart with SciChart.js using the Builder API
const {
  chartBuilder,
  ESeriesType,
  EThemeProviderType,
  EAxisType
} = SciChart;

// or, for npm, import { chartBuilder, ... } from "scichart"

// Data format is { dateValues[], openValues[], highValues[], lowValues[], closeValues[] }
const { dateValues, openValues, highValues, lowValues, closeValues, volumeValues }
    = await getCandles("BTCUSDT", "1h", 100);

const { wasmContext, sciChartSurface } = await chartBuilder.build2DChart(divElementId, {
  surface: { theme: { type: EThemeProviderType.Dark } },
  xAxes: [{ type: EAxisType.CategoryAxis }],
  yAxes: [{ type: EAxisType.NumericAxis, options: { labelPrefix: "$", labelPrecision: 2 } }],
  series: [
    {
      type: ESeriesType.CandlestickSeries,
      ohlcData: {
        xValues: dateValues,
        openValues,
        highValues,
        lowValues,
        closeValues
      },
      options: {
        dataPointWidth: 0.7,
        brushUp: "#33ff3377",
        brushDown: "#ff333377",
        strokeUp: "#77ff77",
        strokeDown: "#ff7777",
        strokeThickness: 1,
      }
    }
  ]
});

This results in the following output:

<div id="scichart-root" ></div>
  
body { margin: 0; }
#scichart-root { width: 100%; height: 100vh; }
  
// Helper class to fetch candlestick data from Binance via Rest API
const getCandles = async (
    symbol,
    interval,
    limit = 300
) => {
  let url = `https://api.binance.com/api/v3/klines?symbol=${symbol}&interval=${interval}`;
  if (limit) {
    url += `&limit=${limit}`;
  }
  try {
    console.log(`SimpleBinanceClient: Fetching ${limit} candles of ${symbol} ${interval}`);
    const response = await fetch(url);
    // Returned data format is [ { date, open, high, low, close, volume }, ... ]
    const data = await response.json();
    // Map to { dateValues[], openValues[], highValues[], lowValues[], closeValues[] } expected by scichart.js
    const dateValues = [];
    const openValues = [];
    const highValues = [];
    const lowValues = [];
    const closeValues = [];
    const volumeValues = [];
    data.forEach(candle => {
      const [timestamp, open, high, low, close, volume] = candle;
      dateValues.push(timestamp / 1000); // SciChart expects Unix Timestamp / 1000
      openValues.push(parseFloat(open));
      highValues.push(parseFloat(high));
      lowValues.push(parseFloat(low));
      closeValues.push(parseFloat(close));
      volumeValues.push(parseFloat(volume));
    });
    return { dateValues, openValues, highValues, lowValues, closeValues, volumeValues };
  } catch (err) {
    console.error(err);
    return [];
  }
};

async function simpleCandlestickChart(divElementId) {
  // #region ExampleA
  // Demonstrates how to create a Candlestick chart with SciChart.js
  const {
    SciChartSurface,
    CategoryAxis,
    NumericAxis,
    FastCandlestickRenderableSeries,
    OhlcDataSeries,
    SciChartJsNavyTheme
  } = SciChart;

  // or, for npm, import { SciChartSurface, ... } from "scichart"

  const { wasmContext, sciChartSurface } = await SciChartSurface.create(divElementId, {
    theme: new SciChartJsNavyTheme()
  });
  sciChartSurface.xAxes.add(new CategoryAxis(wasmContext));
  sciChartSurface.yAxes.add(new NumericAxis(wasmContext, { labelPrefix: "$", labelPrecision: 2 }));

  // Data format is { dateValues[], openValues[], highValues[], lowValues[], closeValues[] }
  const { dateValues, openValues, highValues, lowValues, closeValues, volumeValues }
      = await getCandles("BTCUSDT", "1h", 100);

  // Create a OhlcDataSeries with open, high, low, close values
  const dataSeries = new OhlcDataSeries(wasmContext, {
    xValues: dateValues,
    openValues,
    highValues,
    lowValues,
    closeValues,
  });

  // Create and add the Candlestick series
  const candlestickSeries = new FastCandlestickRenderableSeries(wasmContext, {
    strokeThickness: 1,
    dataSeries,
    dataPointWidth: 0.7,
    brushUp: "#33ff3377",
    brushDown: "#ff333377",
    strokeUp: "#77ff77",
    strokeDown: "#ff7777",
  });
  sciChartSurface.renderableSeries.add(candlestickSeries);
  // #endregion

  // add interactivity for the example
  const { MouseWheelZoomModifier, ZoomPanModifier, ZoomExtentsModifier } = SciChart;
  sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier());
  sciChartSurface.chartModifiers.add(new ZoomPanModifier());
  sciChartSurface.chartModifiers.add(new ZoomExtentsModifier());
};

simpleCandlestickChart("scichart-root");





async function builderExample(divElementId) {
  // #region ExampleB
  // Demonstrates how to create a line chart with SciChart.js using the Builder API
  const {
    chartBuilder,
    ESeriesType,
    EThemeProviderType,
    EAxisType
  } = SciChart;

  // or, for npm, import { chartBuilder, ... } from "scichart"

  // Data format is { dateValues[], openValues[], highValues[], lowValues[], closeValues[] }
  const { dateValues, openValues, highValues, lowValues, closeValues, volumeValues }
      = await getCandles("BTCUSDT", "1h", 100);

  const { wasmContext, sciChartSurface } = await chartBuilder.build2DChart(divElementId, {
    surface: { theme: { type: EThemeProviderType.Dark } },
    xAxes: [{ type: EAxisType.CategoryAxis }],
    yAxes: [{ type: EAxisType.NumericAxis, options: { labelPrefix: "$", labelPrecision: 2 } }],
    series: [
      {
        type: ESeriesType.CandlestickSeries,
        ohlcData: {
          xValues: dateValues,
          openValues,
          highValues,
          lowValues,
          closeValues
        },
        options: {
          dataPointWidth: 0.7,
          brushUp: "#33ff3377",
          brushDown: "#ff333377",
          strokeUp: "#77ff77",
          strokeDown: "#ff7777",
          strokeThickness: 1,
        }
      }
    ]
  });
  // #endregion
};



// Uncomment this to use the builder example
//builderExample("scichart-root");

  
Note: The above example makes a web call to Binance to fetch Bitcoin/USD prices. If you see a blank chart, check the Js console as this web call may be blocked. You can always edit the Codepen to substitute your own data!

In the example above:

To learn more about the CategoryAxis see the page on Value Axis vs. CategoryAxis

CategoryAxis is necessary if you have Forex or Stock market data which includes weekend or overnight gaps, as this axis type measures by x-index, not by x-value. For CryptoCurrency data the DateTimeNumericAxis can be used as these are 24/7 markets.

You can format the date labels on the XAxis by following the instructions on the Axis Label Formatting page.

Adding Volume Bars to a Candlestick Chart

In the SciChart.js demo - Candlestick Charts - volume bars are docked to the bottom of the chart. Here's how to do this with SciChart.js.

// Add a secondary axis for the volume bars
sciChartSurface.yAxes.add(new NumericAxis(wasmContext, { id: "VolumeAxisId", isVisible: false, growBy: new NumberRange(0, 4) }));

// Fetch data. Format is { dates[], opens[], highs[], lows[], closes[], volumes[] }
const { dateValues, openValues, highValues, lowValues, closeValues, volumeValues }
    = await getCandles("BTCUSDT", "4h", 100);

// Add a column series to render the volume bars
sciChartSurface.renderableSeries.add(new FastColumnRenderableSeries(wasmContext, {
  dataSeries: new XyDataSeries(wasmContext, { xValues: dateValues, yValues: volumeValues }),
  yAxisId: "VolumeAxisId",
  strokeThickness: 0,
  dataPointWidth: 0.7,
  opacity: 0.47
}));

// continue to add the candlestick series to the chart...
const { wasmContext, sciChartSurface } = await chartBuilder.build2DChart(divElementId, {
  surface: { theme: { type: EThemeProviderType.Dark } },
  xAxes: [{ type: EAxisType.CategoryAxis }],
  yAxes: [
      { type: EAxisType.NumericAxis, options: { labelPrefix: "$", labelPrecision: 2 } },
      { type: EAxisType.NumericAxis, options: { isVisible: false, id: "VolumeAxisId", growBy: new NumberRange(0, 4) } },
  ],
  series: [
    {
      type: ESeriesType.CandlestickSeries,
      ohlcData: {
        xValues: dateValues,
        openValues,
        highValues,
        lowValues,
        closeValues
      },
      options: {
        dataPointWidth: 0.7,
        brushUp: "#33ff3377",
        brushDown: "#ff333377",
        strokeUp: "#77ff77",
        strokeDown: "#ff7777",
        strokeThickness: 1,
      }
    },
    {
      type: ESeriesType.ColumnSeries,
      xyData: {
        xValues: dateValues,
        yValues: volumeValues,
      },
      options: {
        yAxisId: "VolumeAxisId",
        strokeThickness: 0,
        dataPointWidth: 0.7,
        opacity: 0.47
      }
    }
  ]
});

Here's how the example looks now:

<div id="scichart-root" ></div>
  
body { margin: 0; }
#scichart-root { width: 100%; height: 100vh; }
  
const getCandles = async (
    symbol,
    interval,
    limit = 300
) => {
  let url = `https://api.binance.com/api/v3/klines?symbol=${symbol}&interval=${interval}`;
  if (limit) {
    url += `&limit=${limit}`;
  }
  try {
    console.log(`SimpleBinanceClient: Fetching ${limit} candles of ${symbol} ${interval}`);
    const response = await fetch(url);
    // Returned data format is [ { date, open, high, low, close, volume }, ... ]
    const data = await response.json();
    // Map to { dateValues[], openValues[], highValues[], lowValues[], closeValues[] } expected by scichart.js
    const dateValues = [];
    const openValues = [];
    const highValues = [];
    const lowValues = [];
    const closeValues = [];
    const volumeValues = [];
    data.forEach(candle => {
      const [timestamp, open, high, low, close, volume] = candle;
      dateValues.push(timestamp / 1000); // SciChart expects Unix Timestamp / 1000
      openValues.push(parseFloat(open));
      highValues.push(parseFloat(high));
      lowValues.push(parseFloat(low));
      closeValues.push(parseFloat(close));
      volumeValues.push(parseFloat(volume));
    });
    return { dateValues, openValues, highValues, lowValues, closeValues, volumeValues };
  } catch (err) {
    console.error(err);
    return [];
  }
};

async function candlestickAndVolumeChart(divElementId) {
  // Demonstrates how to create a Candlestick chart with SciChart.js
  const {
    SciChartSurface,
    CategoryAxis,
    NumericAxis,
    FastCandlestickRenderableSeries,
    FastColumnRenderableSeries,
    XyDataSeries,
    OhlcDataSeries,
    NumberRange,
    SciChartJsNavyTheme
  } = SciChart;

  // or, for npm, import { SciChartSurface, ... } from "scichart"

  const { wasmContext, sciChartSurface } = await SciChartSurface.create(divElementId, {
    theme: new SciChartJsNavyTheme()
  });
  sciChartSurface.xAxes.add(new CategoryAxis(wasmContext));
  sciChartSurface.yAxes.add(new NumericAxis(wasmContext, { labelPrefix: "$", labelPrecision: 2 }));

  // #region ExampleA
  // Add a secondary axis for the volume bars
  sciChartSurface.yAxes.add(new NumericAxis(wasmContext, { id: "VolumeAxisId", isVisible: false, growBy: new NumberRange(0, 4) }));

  // Fetch data. Format is { dates[], opens[], highs[], lows[], closes[], volumes[] }
  const { dateValues, openValues, highValues, lowValues, closeValues, volumeValues }
      = await getCandles("BTCUSDT", "4h", 100);

  // Add a column series to render the volume bars
  sciChartSurface.renderableSeries.add(new FastColumnRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, { xValues: dateValues, yValues: volumeValues }),
    yAxisId: "VolumeAxisId",
    strokeThickness: 0,
    dataPointWidth: 0.7,
    opacity: 0.47
  }));

  // continue to add the candlestick series to the chart...
  // #endregion

  const candlestickSeries = new FastCandlestickRenderableSeries(wasmContext, {
    dataSeries: new OhlcDataSeries(wasmContext, {
      xValues: dateValues,
      openValues,
      highValues,
      lowValues,
      closeValues,
    }),
    strokeThickness: 1,
    dataPointWidth: 0.7,
    brushUp: "#33ff3377",
    brushDown: "#ff333377",
    strokeUp: "#77ff77",
    strokeDown: "#ff7777",
  });
  sciChartSurface.renderableSeries.add(candlestickSeries);

  // add interactivity for the example
  const { MouseWheelZoomModifier, ZoomPanModifier, ZoomExtentsModifier } = SciChart;
  sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier({ excludedYAxisIds: ["VolumeAxisId"]}));
  sciChartSurface.chartModifiers.add(new ZoomPanModifier({ excludedYAxisIds: ["VolumeAxisId"]}));
  sciChartSurface.chartModifiers.add(new ZoomExtentsModifier());
};

candlestickAndVolumeChart("scichart-root");





async function builderExample(divElementId) {
  // Demonstrates how to create a line chart with SciChart.js using the Builder API
  const {
    chartBuilder,
    ESeriesType,
    EAxisType,
    EThemeProviderType,
    NumberRange
  } = SciChart;

  // or, for npm, import { chartBuilder, ... } from "scichart"

  // Data format is { dateValues[], openValues[], highValues[], lowValues[], closeValues[] }
  const { dateValues, openValues, highValues, lowValues, closeValues, volumeValues }
      = await getCandles("BTCUSDT", "1h", 100);

  // #region ExampleB
  const { wasmContext, sciChartSurface } = await chartBuilder.build2DChart(divElementId, {
    surface: { theme: { type: EThemeProviderType.Dark } },
    xAxes: [{ type: EAxisType.CategoryAxis }],
    yAxes: [
        { type: EAxisType.NumericAxis, options: { labelPrefix: "$", labelPrecision: 2 } },
        { type: EAxisType.NumericAxis, options: { isVisible: false, id: "VolumeAxisId", growBy: new NumberRange(0, 4) } },
    ],
    series: [
      {
        type: ESeriesType.CandlestickSeries,
        ohlcData: {
          xValues: dateValues,
          openValues,
          highValues,
          lowValues,
          closeValues
        },
        options: {
          dataPointWidth: 0.7,
          brushUp: "#33ff3377",
          brushDown: "#ff333377",
          strokeUp: "#77ff77",
          strokeDown: "#ff7777",
          strokeThickness: 1,
        }
      },
      {
        type: ESeriesType.ColumnSeries,
        xyData: {
          xValues: dateValues,
          yValues: volumeValues,
        },
        options: {
          yAxisId: "VolumeAxisId",
          strokeThickness: 0,
          dataPointWidth: 0.7,
          opacity: 0.47
        }
      }
    ]
  });
  // #endregion
};



// Uncomment this to use the builder example
//builderExample("scichart-root");

  

Painting Candles with Different Colors

It is possible to define the colour of specific OHLC Bars using the PaletteProvider API.

For more info on how to do this, see the PaletteProvider - Per-point colouring of Candlestick/Ohlc Charts documentation page.

See Also