ScottPlot.NET
Finance charts represent price over a binned time range using OHLC (open, high, low, close) data format.
  • This page contains recipes for the Finance category.
  • Visit the Cookbook Home Page to view all cookbook recipes.
  • Generated by ScottPlot 4.1.45 on 5/9/2022

Candlestick Chart

ScottPlot can draw some financial indicators on plots in X/Y space, but users looking to develop robust financial charts should probably look at other libraries designed specifically for financial charting. The biggest limitations are (1) lack of mouse interaction and (2) the horizontal axis is strictly numeric Cartesian space and is not ideal for plotting dates. That said, some financial charting is possible with ScottPlot, and this cookbook demonstrates common use cases.

var plt = new ScottPlot.Plot(600, 400);

// OHLCs are open, high, low, and closing prices for a time range.
OHLC[] prices = DataGen.RandomStockPrices(null, 60);
plt.AddCandlesticks(prices);

plt.SaveFig("finance_quickstart.png");

OHLC Chart

OHLC charts are an alternative to candlestick charts. They show high and low prices as a vertical line, and indicate open and close prices with little ticks to the left and to the right.

var plt = new ScottPlot.Plot(600, 400);

OHLC[] prices = DataGen.RandomStockPrices(null, 60);
plt.AddOHLCs(prices);

plt.SaveFig("finance_ohlc.png");

Using a DateTime Axis

You probably never want to do this… but OHLCs have an X value you can customize to be a DateTime (converted to a double using DateTime.ToOATime()). The advantage is that you can use the native DateTime axis support on the horizontal axis. The disadvantage is that gaps in time appear as gaps in the candlesticks. Weekends without trading will appear as gaps. The alternative to this method is to plot a series of OHLCs using sequential numbers, then manually define the axis tick labels.

var plt = new ScottPlot.Plot(600, 400);

OHLC[] prices = DataGen.RandomStockPrices(null, 60, TimeSpan.FromDays(1));

// add the OHLCs to the plot and the horizontal axis to display DateTime tick labels
plt.AddCandlesticks(prices);
plt.XAxis.DateTimeFormat(true);

plt.SaveFig("finance_dateTimeAxis.png");

Candlesticks with Custom Tick Labels

A better way to represent time on the horizontal axis is to use traditional Cartesian coordinates so each candlestick is placed at X positions (0, 1, 2, etc.), then manually define the locations and label text of important positions on the plot. This is clunky, but possible. This inelegance is why financial charting is probably best done with real financial charting libraries, not a scientific charting library like ScottPlot…

var plt = new ScottPlot.Plot(600, 400);

OHLC[] prices = DataGen.RandomStockPrices(null, 30);
plt.AddCandlesticks(prices);

// manually indicate where axis ticks should be and what their labels should say
double[] tickPositions = { 0, 6, 13, 20, 27 };
string[] tickLabels = { "Sep 23", "Sep 30", "Oct 7", "Oct 14", "Oct 21" };
plt.XTicks(tickPositions, tickLabels);

plt.SaveFig("finance_tickLabels.png");

Simple Moving Average (SMA)

A simple moving average (SMA) technical indicator can be calculated and drawn as a scatter plot.

var plt = new ScottPlot.Plot(600, 400);

OHLC[] ohlcs = DataGen.RandomStockPrices(null, 75);
var candlePlot = plt.AddCandlesticks(ohlcs);

var sma8 = candlePlot.GetSMA(8);
plt.AddScatterLines(sma8.xs, sma8.ys, Color.Blue, 2);

var sma20 = candlePlot.GetSMA(20);
plt.AddScatterLines(sma20.xs, sma20.ys, Color.Navy, 2);

plt.SaveFig("finance_sma.png");

Bollinger Bands

Bollinger bands are a common technical indicator that show the average +/- two times the standard deviation of a given time range preceeding it.

var plt = new ScottPlot.Plot(600, 400);

OHLC[] ohlcs = DataGen.RandomStockPrices(null, 100);
var candlePlot = plt.AddCandlesticks(ohlcs);

var bol = candlePlot.GetBollingerBands(20);
plt.AddScatterLines(bol.xs, bol.sma, Color.Blue);
plt.AddScatterLines(bol.xs, bol.lower, Color.Blue, lineStyle: LineStyle.Dash);
plt.AddScatterLines(bol.xs, bol.upper, Color.Blue, lineStyle: LineStyle.Dash);

plt.SaveFig("finance_bollinger.png");

Price on Right

Newer data appears on the ride side of the chart so financial charts are often displayed with the vertical axis label on the right side as well. This is possible by disabling the left vertical axis (YAxis) and enabling the right one (YAxis2). The left and right Y axes are index 0 and 1 (respectively), and the plottable has to be update to indicate which axis index it should render on.

var plt = new ScottPlot.Plot(600, 400);

OHLC[] prices = DataGen.RandomStockPrices(null, 30, TimeSpan.FromMinutes(5));
var candlePlot = plt.AddCandlesticks(prices);
candlePlot.YAxisIndex = 1;
plt.XAxis.DateTimeFormat(true);

plt.YAxis.Ticks(false);
plt.YAxis2.Ticks(true);
plt.YAxis2.Label("Price (USD)");

plt.SaveFig("finance_right.png");

Custom Wick Color

By default candle wicks are the same color as their bodies, but this can be customized.

var plt = new ScottPlot.Plot(600, 400);

OHLC[] prices = DataGen.RandomStockPrices(null, 30, TimeSpan.FromMinutes(5));
var fp = plt.AddCandlesticks(prices);
fp.WickColor = Color.Black;

plt.SaveFig("finance_wick.png");

Custom Colors

Candles that close below their open price are colored differently from candles which close at or above it. These colors can be customized. Combine this styling with a custom wick color (which also controls the candle border) to create a different visual style.

var plt = new ScottPlot.Plot(600, 400);

OHLC[] prices = DataGen.RandomStockPrices(null, 30, TimeSpan.FromMinutes(5));
var fp = plt.AddCandlesticks(prices);
fp.ColorDown = Color.Black;
fp.ColorUp = Color.White;
fp.WickColor = Color.Black;

plt.SaveFig("finance_color.png");

Dark Mode

A dark mode finance plot can be realized by customizing color options of the candles and figure. Colors in this example were chosen to mimic TC2000.

var plt = new ScottPlot.Plot(600, 400);

// add some random candles
OHLC[] prices = DataGen.RandomStockPrices(null, 100, TimeSpan.FromMinutes(5));
double[] xs = prices.Select(x => x.DateTime.ToOADate()).ToArray();
var candlePlot = plt.AddCandlesticks(prices);
candlePlot.YAxisIndex = 1;

plt.XAxis.DateTimeFormat(true);

// add SMA indicators for 8 and 20 days
var sma8 = candlePlot.GetSMA(8);
var sma20 = candlePlot.GetSMA(20);
var sma8plot = plt.AddScatterLines(sma8.xs, sma8.ys, Color.Cyan, 2, label: "8 day SMA");
var sma20plot = plt.AddScatterLines(sma20.xs, sma20.ys, Color.Yellow, 2, label: "20 day SMA");
sma8plot.YAxisIndex = 1;
sma20plot.YAxisIndex = 1;

// customize candle styling
candlePlot.ColorDown = ColorTranslator.FromHtml("#00FF00");
candlePlot.ColorUp = ColorTranslator.FromHtml("#FF0000");

// customize figure styling
plt.Layout(padding: 12);
plt.Style(figureBackground: Color.Black, dataBackground: Color.Black);
plt.Frameless();
plt.XAxis.TickLabelStyle(color: Color.White);
plt.XAxis.TickMarkColor(ColorTranslator.FromHtml("#333333"));
plt.XAxis.MajorGrid(color: ColorTranslator.FromHtml("#333333"));

// hide the left axis and show a right axis
plt.YAxis.Ticks(false);
plt.YAxis.Grid(false);
plt.YAxis2.Ticks(true);
plt.YAxis2.Grid(true);
plt.YAxis2.TickLabelStyle(color: ColorTranslator.FromHtml("#00FF00"));
plt.YAxis2.TickMarkColor(ColorTranslator.FromHtml("#333333"));
plt.YAxis2.MajorGrid(color: ColorTranslator.FromHtml("#333333"));

// customize the legend style
var legend = plt.Legend();
legend.FillColor = Color.Transparent;
legend.OutlineColor = Color.Transparent;
legend.Font.Color = Color.White;
legend.Font.Bold = true;

plt.SaveFig("finance_dark.png");