Below Example shows adding & removing technical / financial indicators like SMA, EMA & MACD to StockChart. SMA, EMA & MACD calculations has been modularized such that you can easily customize it as required.
window.onload = function () { var dps1 = [], dps2= []; var stockChart = new CanvasJS.StockChart("chartContainer",{ title:{ text:"Technical Indicators" }, subtitles: [{ text: "Mouse over Technical Indicator Menu to Add SMA, EMA and MACD", fontSize: 12 }], theme: "light2", exportEnabled: true, charts: [{ axisY: { prefix: "$" }, legend: { verticalAlign: "top", horizontalAlign: "left", cursor: "pointer", itemclick: function (e) { if (typeof (e.dataSeries.visible) === "undefined" || e.dataSeries.visible) { e.dataSeries.visible = false; } else { e.dataSeries.visible = true; } e.chart.render(); } }, toolTip: { shared: true }, data: [{ type: "candlestick", showInLegend: true, name: "Stock Price", yValueFormatString: "$#,###.00", dataPoints : dps1 }], }], navigator: { data: [{ dataPoints: dps2 }], slider: { minimum: new Date(2018, 03, 01), maximum: new Date(2018, 05, 01) } } }); $.getJSON("https://canvasjs.com/data/docs/ethusd2018.json", function(data) { for(var i = 0; i < data.length; i++){ dps1.push({x: new Date(data[i].date), y: [Number(data[i].open), Number(data[i].high), Number(data[i].low), Number(data[i].close)]}); dps2.push({x: new Date(data[i].date), y: Number(data[i].close)}); } stockChart.render(); jQuery("#sma").on("change", function(){ for(var i=0; i<stockChart.charts[0].data.length; i++ ) { if(stockChart.charts[0].data[i].name === "Simple Moving Average") { stockChart.charts[0].data[i].remove(); return; } } var sma = calculateSMA(dps1, 7); stockChart.charts[0].addTo("data", { type: "line", dataPoints: sma, showInLegend: true, yValueFormatString: "$#,###.00", name: "Simple Moving Average"}) }); jQuery("#ema").on("change", function(){ for(var i=0; i<stockChart.charts[0].data.length; i++ ) { if(stockChart.charts[0].data[i].name === "EMA") { stockChart.charts[0].data[i].remove(); return; } } var ema = calculateEMA(dps1, 7); stockChart.charts[0].addTo("data", {type: "line", name: "EMA", showInLegend: true, yValueFormatString: "$#,###.##", dataPoints: ema}); }); jQuery("#macd").on("change", function(){ if(stockChart.charts.length > 1) { stockChart.options.charts.pop(); stockChart.render(); return; } var ema12 = calculateEMA(dps1, 12), ema26 = calculateEMA(dps1, 26), macd = [], ema9; for(var i = 0; i < ema12.length; i++) { macd.push({x: ema12[i].x, y: (ema12[i].y - ema26[i].y)}); } var ema9 = calculateEMA(macd, 9); stockChart.addTo("charts", {height: 100, data: [{type: "line", name: "MACD", showInLegend: true, yValueFormatString: "#,###.00", dataPoints: macd}], legend: {horizontalAlign: "left"}, toolTip: {shared: true}}); stockChart.charts[1].addTo("data", {type: "line", name: "Signal", showInLegend: true, yValueFormatString: "#,##0.00", dataPoints: ema9}); }); }); function calculateSMA(dps, count){ var avg = function(dps){ var sum = 0, count = 0, val; for (var i = 0; i < dps.length; i++) { val = dps[i].y[3]; sum += val; count++; } return sum / count; }; var result = [], val; count = count || 5; for (var i=0; i < count; i++) result.push({ x: dps[i].x , y: null}); for (var i=count - 1, len=dps.length; i < len; i++){ val = avg(dps.slice(i - count + 1, i)); if (isNaN(val)) result.push({ x: dps[i].x, y: null}); else result.push({ x: dps[i].x, y: val}); } return result; } function calculateEMA(dps,count) { var k = 2/(count + 1); var emaDps = [{x: dps[0].x, y: dps[0].y.length ? dps[0].y[3] : dps[0].y}]; for (var i = 1; i < dps.length; i++) { emaDps.push({x: dps[i].x, y: (dps[i].y.length ? dps[i].y[3] : dps[i].y) * k + emaDps[i - 1].y * (1 - k)}); } return emaDps; } }