class Indicator { constructor(name) { // The name of the indicator. this.name = name; this.lines=[]; this.hist=[]; } init(data){ console.log(this.name + ': init() unimplemented.'); } update(data){ console.log(this.name + ': update() unimplemented.'); } addHist(name, chart, color='#26a69a'){ this.hist[name] = chart.addHistogramSeries({ color: color, priceFormat: { type: 'price', }, priceScaleId: '', scaleMargins: { top: 0.0, bottom: 0, }, }); } addLine(name, chart, color, lineWidth){ this.lines[name] = chart.addLineSeries({ color: color, lineWidth: lineWidth }); } setLine(name, data, value_name){ // Initialize the data with the data object provided. this.lines[name].setData(data); // Isolate the last value provided and round to 2 decimals places. let priceValue = data.at(-1).value; this.updateDisplay(name, priceValue, value_name); } updateDisplay(name, priceValue, value_name){ let rounded_value = (Math.round(priceValue * 100) / 100).toFixed(2); // Update the data in the edit and view indicators panel document.getElementById(this.name + '_' + value_name).value = rounded_value; //Initialise the legend todo fix this //set_legend_text(rounded_value, i); } setHist(name, data){ this.hist[name].setData(data); } updateLine(name, data, value_name){ // Update the line-set data in the chart this.lines[name].update(data); // Update the data in the edit and view indicators panel this.updateDisplay(name, data, value_name); } updateHist(name,data){ this.hist[name].update(data); } } class SMA extends Indicator{ constructor(name, chart, color, lineWidth = 2) { // Call the inherited constructor. super(name); // Create a line series and append to the appropriate chart. this.addLine('line', chart, color, lineWidth); // todo: pass in indicator output or something? Regiyhhster crosshair movements to the indicators output panel //create_legend(name, chart); } init(data){ this.setLine('line',data, 'value'); } update(data){ this.updateLine('line', data, 'value'); } } class Linear_Regression extends SMA{ } class EMA extends SMA{ } class RSI extends Indicator{ constructor(name, charts, color, lineWidth = 2) { // Call the inherited constructor. super(name); // If the chart doesn't exsist create one. if( !charts.hasOwnProperty('chart2') ) { charts.create_RSI_chart(); } let chart = charts.chart2; // Create a line series and append to the appropriate chart. this.addLine('line', chart, color, lineWidth); // todo: pass in indicator output or somthing? Register crosshair movements to the indicators output panel //create_legend(name, chart); } init(data){ this.setLine('line',data, 'value'); } update(data){ this.updateLine('line', data, 'value'); } } class MACD extends Indicator{ constructor(name, charts, color_m, color_s, lineWidth = 2) { // Call the inherited constructor. super(name); // If the chart doesn't exsist create one. if( !charts.hasOwnProperty('chart3') ) { charts.create_MACD_chart(); } let chart = charts.chart3; // Create two line series and append to the chart. this.addLine('line_m', chart, color_m, lineWidth); this.addLine('line_s', chart, color_s, lineWidth); this.addHist(name, chart); // todo: pass in indicator output or somthing? Register crosshair movements to the indicators output panel //create_legend(name, chart); } init(data){ this.setLine('line_m',data[0], 'macd'); this.setLine('line_s',data[1], 'signal'); this.setHist(name, data[2]); } update(data){ this.updateLine('line_m', data[0], 'macd'); this.updateLine('line_s', data[1], 'signal'); this.addHist(name, data[3]); } } class ATR extends Indicator{ init(data) { this.updateDisplay(this.name, data.at(-1).value, 'value'); } update(data) { this.updateDisplay(this.name, data.value, 'value'); } } class Volume extends Indicator{ constructor(name, chart) { // Call the inherited constructor. super(name); this.addHist(name, chart); this.hist[name].applyOptions( { scaleMargins: { top: 0.8, bottom: 0.0} } ); } init(data){ this.setHist(this.name, data); } update(data){ this.updateHist(this.name, data); } } class Bolenger extends Indicator{ constructor(name, chart, color_u, color_m, color_l, lineWidth = 2) { // Call the inherited constructor. super(name); // Create three line series and append to the chart. this.addLine('line_u', chart, color_u, lineWidth); this.addLine('line_m', chart, color_u, lineWidth); this.addLine('line_l', chart, color_u, lineWidth); } init(data){ // Initialize the data with the data object provided. this.setLine('line_u',data[0],'value1'); this.setLine('line_m',data[1],'value2'); this.setLine('line_l',data[2],'value3'); } update(data){ // Update the line-set data in the chart this.line_u.update(data[0], 'value1'); // Update the line-set data in the chart this.line_m.update(data[1]), 'value2'; // Update the line-set data in the chart this.line_l.update(data[2], 'value3'); } } class Indicators { constructor(charts, idata) { // Create an array to hold all the created indicators. this.indicators = []; // Pass a list of indicators from received from the server // to a function that will create them. this.create_indicators(idata.indicators, charts); // Pass the initial indicator data to an initialize function for the indicators. idata.indicator_data.then( (data) => { this.init_indicators(data); } ); } create_indicators(indicators, charts){ // loop through all the indicators received from the // server and if the are enabled and create them. for (let name in indicators) { // If this indicator is hidden skip to the next one if (!indicators[name].visible) {continue;} // Get the type of indicator let i_type = indicators[name].type; // Call the indicator creation function if (i_type == 'SMA') { // The color of the line let color = indicators[name].color; this.indicators[name] = new SMA(name, charts.chart_1, color); } if (i_type == 'BOLBands') { // The color of three lines let color_u = bt_data.indicators[name].color_1; let color_m = bt_data.indicators[name].color_2; let color_l = bt_data.indicators[name].color_3; this.indicators[name] = new Bolenger(name, charts.chart_1, color_u, color_m, color_l); } if (i_type == 'MACD') { // The color of two lines let color_m = bt_data.indicators[name].color_1; let color_s = bt_data.indicators[name].color_2; this.indicators[name] = new MACD(name, charts, color_m, color_s); } if (i_type == 'Volume') { this.indicators[name] = new Volume(name, charts.chart_1); } if (i_type == 'ATR') { this.indicators[name] = new ATR(name); } if (i_type == 'LREG') { // The color of the line let color = indicators[name].color; this.indicators[name] = new Linear_Regression(name, charts.chart_1, color); } if (i_type == 'RSI') { let color = indicators[name].color; this.indicators[name] = new RSI(name, charts, color); } if (i_type == 'EMA') { // The color of the line let color = indicators[name].color; this.indicators[name] = new EMA(name, charts.chart_1, color); } } } init_indicators(data){ // Loop through all the indicators. for (name in data){ // Call the initialization function for each indicator. this.indicators[name].init(data[name]['data']); } } }