diff --git a/Configuration.py b/Configuration.py index a88ec8f..5b6a78a 100644 --- a/Configuration.py +++ b/Configuration.py @@ -28,20 +28,28 @@ class Configuration: # Call a static method from indicators that fills in a default list of indicators in config. self.signals_list = Signals.get_signals_defaults() + # list of strategies in config. + self.strategies_list = [] + # The data that will be saved and loaded from file . self.saved_data = None + def new_strategy(self, data): + # The strategies_list is modified by reference in strategies the loaded in config_and_states('save'). + # Save it to file. + self.config_and_states('save') + def new_signal(self, data): # Create a new signal. self.saved_data['signals'].append(data) # Save it to file. self.config_and_states('save') - def remove_signal(self, data): - print(f'removing {data}') - for sig in self.saved_data['signals']: - if sig['name'] == data: - self.saved_data['signals'].remove(sig) + def remove(self, what, name): + print(f'removing {what}:{name}') + for obj in self.saved_data[what]: + if obj['name'] == name: + self.saved_data[what].remove(obj) break # Save it to file. self.config_and_states('save') @@ -53,7 +61,8 @@ class Configuration: self.saved_data = { 'indicator_list': self.indicator_list, 'config': {'chart_interval': self.chart_interval, 'trading_pair': self.trading_pair}, - 'signals': self.signals_list + 'signals': self.signals_list, + 'strategies': self.strategies_list } def set_loaded_values(): @@ -62,6 +71,7 @@ class Configuration: self.chart_interval = self.saved_data['config']['chart_interval'] self.trading_pair = self.saved_data['config']['trading_pair'] self.signals_list = self.saved_data['signals'] + self.strategies_list = self.saved_data['strategies'] def load_configuration(filepath): """load file data""" diff --git a/Signals.py b/Signals.py index b236fb9..086fdbd 100644 --- a/Signals.py +++ b/Signals.py @@ -53,7 +53,7 @@ class Signal: class Signals: def __init__(self): self.signals = [] - self.set_signals_defaults() + # self.set_signals_defaults() def set_signals_defaults(self): """These defaults are loaded if the config file is not found.""" @@ -91,7 +91,6 @@ class Signals: prop1=sig['prop1'], operator=sig['operator'], source2=sig['source2'], prop2=sig['prop2'], state=sig['state'])) - print(self.signals) def get_signals(self): return self.signals diff --git a/Strategies.py b/Strategies.py new file mode 100644 index 0000000..d67d6d3 --- /dev/null +++ b/Strategies.py @@ -0,0 +1,15 @@ +class Strategies: + def __init__(self, loaded_strats): + self.strat_list = loaded_strats + + def new_strategy(self, data): + self.strat_list.append(data) + + def delete_strategy(self, name): + for obj in self.strat_list: + if obj['name'] == name: + self.strat_list.remove(obj) + break + + def get_strategies(self): + return self.strat_list diff --git a/app.py b/app.py index 006d5ad..f00aceb 100644 --- a/app.py +++ b/app.py @@ -61,6 +61,15 @@ def ws(sock): } resp = json.dumps(resp) sock.send(resp) + elif msg_obj['data'] == 'strategies': + strategies = bt.app_data.get_strategies() + if strategies: + resp = { + "reply": "strategies", + "data": strategies + } + resp = json.dumps(resp) + sock.send(resp) else: print('Warning: Unhandled request!') print(msg_obj['data']) @@ -68,6 +77,9 @@ def ws(sock): if msg_obj['message_type'] == 'delete_signal': bt.app_data.delete_signal(msg_obj['data']) + if msg_obj['message_type'] == 'delete_strategy': + bt.app_data.delete_strategy(msg_obj['data']) + if msg_obj['message_type'] == 'reply': print(msg_obj['rep']) print('Reply') @@ -83,6 +95,18 @@ def ws(sock): } resp = json.dumps(resp) sock.send(resp) + + if msg_obj['message_type'] == 'new_strategy': + # Send the data to the BrighterData_obj + # and forward any returned data to the client. + r_data = bt.app_data.received_new_strategy(msg_obj['data']) + if r_data: + resp = { + "reply": "strategy_created", + "data": r_data + } + resp = json.dumps(resp) + sock.send(resp) return # The rendered page connects to the exchange and relays the candle data back here diff --git a/data.py b/data.py index 506cddd..4fdbcc6 100644 --- a/data.py +++ b/data.py @@ -1,6 +1,7 @@ from binance.client import Client import config +from Strategies import Strategies from candles import Candles from Configuration import Configuration from exchange_info import ExchangeInfo @@ -36,6 +37,9 @@ class BrighterData: # Object that maintains exchange and account data self.exchange_info = ExchangeInfo(self.client) + # Object that maintains the strategies data + self.strategies = Strategies(self.config.strategies_list) + def get_js_init_data(self): """Returns a JSON object of initialization data for the javascript in the rendered HTML""" @@ -90,8 +94,26 @@ class BrighterData: self.signals.new_signal(data) # Forward the new signal data to config. So it can save it to file. self.config.new_signal(data) + # Send the data back to where it came from. return data + def received_new_strategy(self, data): + # Check the data. + if 'name' not in data: + return 'data.py:received_new_strategy() - The new strategy has no name. ' + # Forward the new strategy data to the strategy's instance. So it can create a new strategy. + self.strategies.new_strategy(data) + # Forward the new signal data to config. So it can save it to file. + self.config.new_strategy(data) + # Send the data back to where it came from. + return data + + def delete_strategy(self, strategy_name): + # Delete the signal from the signals instance. + self.strategies.delete_strategy(strategy_name) + # Delete the signal from the configuration file. + self.config.remove('strategies', strategy_name) + def get_signals(self): """ Return a JSON object of all the signals in the signals instance.""" sigs = self.signals.get_signals() @@ -100,11 +122,19 @@ class BrighterData: json_str.append(json.dumps(sig.__dict__)) return json_str + def get_strategies(self): + """ Return a JSON object of all the signals in the signals instance.""" + strats = self.strategies.get_strategies() + json_str = [] + for strat in strats: + json_str.append(json.dumps(strat)) + return json_str + def delete_signal(self, signal_name): # Delete the signal from the signals instance. self.signals.delete_signal(signal_name) # Delete the signal from the configuration file. - self.config.remove_signal(signal_name) + self.config.remove('signals', signal_name) app_data = BrighterData() diff --git a/indicators.py b/indicators.py index 1200a74..53c6fa2 100644 --- a/indicators.py +++ b/indicators.py @@ -359,13 +359,17 @@ class Indicators: """Set the default settings for each indicator""" indicator_list = { - 'SMA 21': {'type': 'SMA', 'period': 21, 'visible': True, 'color': f"#{random.randrange(0x1000000):06x}", + 'EMA 5': {'type': 'EMA', 'period': 5, 'visible': True, 'color': f"#{random.randrange(0x1000000):06x}", + 'value': 0}, + 'EMA 15': {'type': 'EMA', 'period': 15, 'visible': True, 'color': f"#{random.randrange(0x1000000):06x}", + 'value': 0}, + 'EMA 20': {'type': 'EMA', 'period': 20, 'visible': True, 'color': f"#{random.randrange(0x1000000):06x}", 'value': 0}, 'EMA 50': {'type': 'EMA', 'period': 50, 'visible': True, 'color': f"#{random.randrange(0x1000000):06x}", 'value': 0}, 'EMA 100': {'type': 'EMA', 'period': 100, 'visible': True, 'color': f"#{random.randrange(0x1000000):06x}", 'value': 0}, - 'SMA 200': {'type': 'SMA', 'period': 200, 'visible': True, 'color': f"#{random.randrange(0x1000000):06x}", + 'EMA 200': {'type': 'EMA', 'period': 200, 'visible': True, 'color': f"#{random.randrange(0x1000000):06x}", 'value': 0}, 'RSI 14': {'type': 'RSI', 'period': 14, 'visible': True, 'color': f"#{random.randrange(0x1000000):06x}", 'value': 0}, diff --git a/static/Strategies.js b/static/Strategies.js index 2c5e9ff..2e1401c 100644 --- a/static/Strategies.js +++ b/static/Strategies.js @@ -1,86 +1,35 @@ -class Strategy{ - constructor(strat_type, name, side, take_profit, stop_loss, conditions) { - // The type of alert. - this.type = strat_type; - // The source of the alert. - this.name = name; - // buy|sell: string - this.side = side; - // Conditions to exit trade in profit. {on: ('profit'|'condition'), trig_val: 999} - this.take_profit = take_profit; - // Conditions to exit trade in loss. {on: ('loss'|'condition'), trig_val: 999} - this.stop_loss = stop_loss; - // The conditions to evaluate. { on: (signal_name: str), trig_val: (true|false|changed) } - this.conditions = conditions; - // html formatted representation. - this.display_output = this.format_html(); - // any last results needed for comparison. - this.last_result = {}; - } - format_html(){ - let html ='
  • ' + '' + this.name + ''; - html +='' + this.type + ''; - html +='' + this.side + ''; - if (this.take_profit.on == 'profit'){ - if(this.side == 'buy') {var then_do ='sell';} - else if(this.side == 'sell') {var then_do ='buy';} - html += '' + 'If profit exceeds' + ': ' + this.take_profit.trig_val + ' '+ then_do + '.'; - } - if (this.stop_loss.on == 'loss'){ - if(this.side == 'buy') {var then_do ='sell';} - else if(this.side == 'sell') {var then_do ='buy';} - html +='' + 'If loss exceeds' + ': ' + this.stop_loss.trig_val + ' '+ then_do + '.'; - } - for(let cond of this.conditions){ - html += 'If ' + cond.on + ' is ' + cond.trig_val + ''; - } - html += '
  • '; - return html; - } - conditions_satisfied(signals){ - let result = true; - for(let cond of this.conditions){ - if (cond.trig_val == 'true'){ - if (signals[cond.on] == true){ - result = result && true; - }else{ - result = false; - } - } - else if (cond.trig_val == 'false'){ - if (signals[cond.on] == false){ - result = result && true; - }else{ - result = false; - } - } - else if (cond.trig_val == 'changed'){ - // If no last result exists for this trigger, create one. - if ( !this.last_results[cond.on] ){ - this.last_results[cond.on] = signals[cond.on]; - } - if (signals[cond.on] != this.last_results[cond.on]){ - result = result && true; - }else{ - result = false; - } - } - } - return result; - } - name(){ - return this.name; - } - type(){ - return this.type; - } - strategy(){ - return this.strategy; - } - print_html(){ - return this.display_output; - } -} +//TODO this func is unused left over for reference. +//conditions_satisfied(signals){ +// let result = true; +// for(let cond of this.conditions){ +// if (cond.trig_val == 'true'){ +// if (signals[cond.on] == true){ +// result = result && true; +// }else{ +// result = false; +// } +// } +// else if (cond.trig_val == 'false'){ +// if (signals[cond.on] == false){ +// result = result && true; +// }else{ +// result = false; +// } +// } +// else if (cond.trig_val == 'changed'){ +// // If no last result exists for this trigger, create one. +// if ( !this.last_results[cond.on] ){ +// this.last_results[cond.on] = signals[cond.on]; +// } +// if (signals[cond.on] != this.last_results[cond.on]){ +// result = result && true; +// }else{ +// result = false; +// } +// } +// } +// return result; +//} class Strategies { constructor(target_id) { // The list of strategies. @@ -95,21 +44,123 @@ class Strategies { open_form() { document.getElementById("new_strat_form").style.display = "grid"; } // Call to hide Create new signal dialog. close_form() { document.getElementById("new_strat_form").style.display = "none"; } - + submit(){ + /* + - Collect the data from the form fields and + create an object representing the strategy. + - Record the strategy in the an instance list. + - Update the display output. + - Send the strategy object to the server. + */ + let strat = {}; + strat.name = document.getElementById('stg_name').value; + if (strat.name == ''){ + alert('Please provide a name.'); + return; + } + strat.type = document.getElementById('strat_type').value; + strat.side = document.getElementById('trade_in_side').value; + strat.margin = document.getElementById('margin_select').value; + strat.trd_in_conds = {}; + let conds = Array.from(document.querySelectorAll('#trade_in_cond>li')); + for (let cond of conds){ + let json_obj = JSON.parse(cond.innerHTML); + strat.trd_in_conds[json_obj.Trigger] = json_obj.Value; + } + let take_profit = {}; + take_profit.typ = document.getElementById('prof_typ').value; + if (take_profit.typ == 'conditional'){ + take_profit.trig = document.getElementById('prof_trig').value; + take_profit.val = document.getElementById('prof_trigVal').value; + }else{ + take_profit.val = document.getElementById('prof_val').value; + } + strat.take_profit = take_profit; + let stop_loss = {}; + stop_loss.typ = document.getElementById('loss_typ').value; + if ( stop_loss.typ == 'conditional' ){ + stop_loss.trig = document.getElementById('loss_trig').value; + stop_loss.val = document.getElementById('loss_trigVal').value; + }else{ + stop_loss.val = document.getElementById('loss_val').value; + } + strat.stop_loss = stop_loss; + // Add the strategy to the instance list. + this.strategies.push(strat); + // Add the strategy to display. + this.update_html(); + // Send the new strategy to the server. + window.UI.data.comms.send_to_app( "new_strategy", strat); + this.close_form(); + } + set_data(strats){ + for (let strat of strats){ + // Add the strategy to the instance list. + this.strategies.push(JSON.parse(strat)); + } + // Add the strategy to display. + this.update_html(); + } open_stg_form(){ this.open_form(); this.fill_field('strat_opt', 'take_profit'); - // condition = { on: (signal_name: str), trig_val: (true|false|changed) } - let cond1 = {on: 'signal1', trig_val:'changed'} - // take_profit = {on: ('profit'|'condition'), trig_val: 999} - let take_profit = {on: 'signal2', trig_val: false} - // stop_loss = {on: ('loss'|'condition'), trig_val: 999} - let stop_loss = {on: 'loss', trig_val: '80%' } - let side='buy'; - let conditions = []; //_str = side + condition + take_profit - conditions.push(cond1); - this.strategies.push( new Strategy('take_profit', 'strategy_#1', side, take_profit, stop_loss, conditions) ); - this.update_html(); + } + clear_innerHTML(el){ + el.innerHTML=""; + } + dropDown(name, label, parent, options){ + /* Create a html selection element and append it to a parent element. + name: name and id of the element. + label: text displayed beside the selection list element. + parent: the html element to append to. + options: An array of selection options. + */ + let lbl = document.createElement("label"); + lbl.for = name; + lbl.id = name + '_lbl'; + lbl.innerHTML = label; + let select = document.createElement("select"); + select.id = name; + select.name = name; + for(let option of options){ + select.innerHTML += ''; + } + parent.appendChild(lbl); + parent.appendChild(select); + } + val_input(name, label, parent, min, max, i_val){ + /* Create an input element. + name: name and id of the element. + label: text displayed beside the element. + parent: the html element to append to. + min, max, i_val: Range and initialization values. + */ + let lbl = document.createElement("label"); + lbl.for = name; + lbl.id = name + '_lbl'; + lbl.innerHTML = label; + let input = document.createElement("input"); + input.name = name; + input.id = name; + input.type = 'number'; + input.min = min; + input.max = max; + input.value = i_val; + parent.appendChild(lbl); + parent.appendChild(input); + + } + hideShowTags(elements, cmd){ + /* Hides or shows 1 or many elements. + Receives either string or array of string. + */ + if (typeof(elements) == 'string'){ + elements = [elements]; + } + for(let el of elements){ + if(cmd== 'hide'){document.getElementById(el).style.display = 'none';} + if(cmd== 'show'){document.getElementById(el).style.display = 'inline-block';} + } } fill_field(field, value){ if (field == 'strat_opt'){ @@ -117,35 +168,17 @@ class Strategies { if (value == 'take_profit'){ // Clear previous content. - options.innerHTML=""; + this.clear_innerHTML(options); //Create a drop down for buy/sell option - let side_select_label = document.createElement("label"); - side_select_label.for = 'trade_in_side'; - side_select_label.innerHTML = 'Side:'; - let side_select = document.createElement("select"); - side_select.id = "trade_in_side"; - side_select.name = "trade_in_side"; - side_select.innerHTML = ''; - options.appendChild(side_select_label); - options.appendChild(side_select); + this.dropDown('trade_in_side','Side:', options, ['buy','sell']); - //Create an input for margin trading value. (1X-100X) - let margin_label = document.createElement("label"); - margin_label.for = 'margin'; - margin_label.innerHTML = 'Margin:'; - let margin_select = document.createElement("input"); - margin_select.name = 'margin'; - margin_select.type = 'number'; - margin_select.min = 1; - margin_select.max = 100; - margin_select.value = 1; - options.appendChild(margin_label); - options.appendChild(margin_select); + //Create an input for margin trading value. (1-100) + this.val_input('margin_select', 'Margin:', options, 1,100, 50); // Create a un ordered list to hold the conditions of trading in. let ul_in_cond = document.createElement('ul'); - ul_in_cond.id ='trade_in_conditions'; + ul_in_cond.id ='trade_in_cond'; // Create a submit button for the conditions. let add_cond_btn = document.createElement('button'); @@ -154,116 +187,108 @@ class Strategies { add_cond_btn.innerHTML = "Add Condition"; add_cond_btn.onclick = function () { let li = document.createElement('li'); - li.innerHTML = 'Trigger:'+ trigger.value+' Value:' + trigVal.value; + li.innerHTML = JSON.stringify({ Trigger: trigger.value, Value: trigVal.value }); ul_in_cond.appendChild(li); }; // Add a horizontal rule. - let element = document.createElement('hr'); - options.appendChild(element); + options.appendChild(document.createElement('hr')); //Create a drop down for trigger options - let trigger_label = document.createElement("label"); - trigger_label.for = 'trigger'; - trigger_label.innerHTML = 'Trigger Signal:'; - let trigger = document.createElement("select"); - trigger.id = "trigger"; - trigger.name = "trigger"; - // Populate the signal selector. - for (let signal in window.UI.signals.signals){ - let opt = document.createElement('option'); - opt.value = window.UI.signals.signals[signal].name; - opt.innerHTML = window.UI.signals.signals[signal].name; - trigger.appendChild(opt); - } - // Add it to the dom. - options.appendChild(trigger_label); - options.appendChild(trigger); + // Get the signal options from the signal instance. + let ops = []; + for (let signal of window.UI.signals.signals) {ops.push(signal.name);} + this.dropDown('trigger','Trigger Signal:', options, ops); + //Create a drop down for trigger value. - let trigVal_label = document.createElement("label"); - trigVal_label.for = 'trigVal'; - trigVal_label.innerHTML = 'Trigger Value:'; - let trigVal = document.createElement("select"); - trigVal.id = "trigVal"; - trigVal.name = "trigVal"; - - let opt = document.createElement('option'); - opt.value = true; - opt.innerHTML = 'true'; - trigVal.appendChild(opt); - - opt = document.createElement('option'); - opt.value = false; - opt.innerHTML = 'false'; - trigVal.appendChild(opt); - - opt = document.createElement('option'); - opt.value = 'changed'; - opt.innerHTML = 'changed'; - trigVal.appendChild(opt); - - // Add trigger Value select element to the dom. - options.appendChild(trigVal_label); - options.appendChild(trigVal); + this.dropDown('trigVal','Trigger Value:', options, ['true', 'false', 'changed']); // Add the submit btn and the list to the dom. options.appendChild(add_cond_btn); options.appendChild(ul_in_cond); // Add a horizontal rule. - element = document.createElement('hr'); - options.appendChild(element); - - //Create an input for take profit value. - let prof_value_lbl = document.createElement("label"); - prof_value_lbl.for = 'profit_val'; - prof_value_lbl.innerHTML = 'Profit %:'; - let profit_val = document.createElement("input"); - profit_val.type='number'; - profit_val.min=0; profit_val.max=100; profit_val.value = 50; + options.appendChild(document.createElement('hr')); //Create a drop down for take profit type. - let prof_typ_label = document.createElement("label"); - prof_typ_label.for = 'prof_typ'; - prof_typ_label.innerHTML = 'Profit type:'; - let prof_typ = document.createElement("select"); - prof_typ.id = "prof_typ"; - prof_typ.name = "prof_typ"; - prof_typ.onchange= function(){ + this.dropDown('prof_typ','Profit type:', options, ['value', 'conditional']); + // Add and onchange function to show and hide some options. + let that = this; + document.getElementById('prof_typ').onchange= function(){ if (this.value == 'value'){ - prof_value_lbl.style.display = 'inline-block'; - profit_val.style.display = 'inline-block'; - //profit_trig.style.display = 'none'; + that.hideShowTags(['prof_val_lbl','prof_val'], 'show'); + that.hideShowTags(['prof_trig_lbl', 'prof_trig', 'prof_trigVal_lbl', 'prof_trigVal'], 'hide'); } else if (this.value == 'conditional'){ - prof_value_lbl.style.display = 'none'; - profit_val.style.display = 'none'; - //profit_trig.style.display = 'block'; + that.hideShowTags(['prof_val_lbl','prof_val'], 'hide'); + that.hideShowTags(['prof_trig_lbl', 'prof_trig', 'prof_trigVal_lbl', 'prof_trigVal'], 'show'); } }; - opt = document.createElement('option'); - opt.value = 'value'; - opt.innerHTML = 'value'; - prof_typ.appendChild(opt); + // Add a line break. + options.appendChild(document.createElement('br')); - opt = document.createElement('option'); - opt.value = 'conditional'; - opt.innerHTML = 'conditional'; - prof_typ.appendChild(opt); + // Create an input for take profit value. + this.val_input('prof_val', 'Profit %:', options, 1,100, 50); + // Set display to visible. + this.hideShowTags(['prof_val_lbl','prof_val'], 'show'); - // Add profit_type select element to the dom. - options.appendChild(prof_typ_label); - options.appendChild(prof_typ); + // Create an input for take profit signal trigger. + // Get the signal options from the signal instance. + ops = []; for (let signal of window.UI.signals.signals) {ops.push(signal.name);} + this.dropDown('prof_trig','Profit trigger:', options, ops); + // Set display to hidden. + this.hideShowTags(['prof_trig_lbl','prof_trig'], 'hide'); - opt = document.createElement('br'); - options.appendChild(opt); + //Create a drop down for take profit trigger value. + this.dropDown('prof_trigVal','Trigger Value:', options, ['true', 'false', 'changed']); + // Set display to hidden. + this.hideShowTags(['prof_trigVal_lbl','prof_trigVal'], 'hide'); - // Add value input to the dom. - options.appendChild(prof_value_lbl); - options.appendChild(profit_val); + // Add a line break. + options.appendChild(document.createElement('br')); + // Add a horizontal rule. + options.appendChild(document.createElement('hr')); + //Create a drop down for Stop Loss type. + this.dropDown('loss_typ','Stop-Loss type:', options, ['value', 'conditional']); + // Add and onchange function to show and hide some options. + document.getElementById('loss_typ').onchange= function(){ + if (this.value == 'value'){ + that.hideShowTags(['loss_val_lbl','loss_val'], 'show'); + that.hideShowTags(['loss_trig_lbl', 'loss_trig', 'loss_trigVal_lbl', 'loss_trigVal'], 'hide'); + } + else if (this.value == 'conditional'){ + that.hideShowTags(['loss_val_lbl','loss_val'], 'hide'); + that.hideShowTags(['loss_trig_lbl', 'loss_trig', 'loss_trigVal_lbl', 'loss_trigVal'], 'show'); + } + }; + + // Add a line break. + options.appendChild( document.createElement('br') ); + + // Create an input for take profit value. + this.val_input('loss_val', 'Loss %:', options, 1,100, 50); + // Set display to visible. + this.hideShowTags(['loss_val_lbl','loss_val'], 'show'); + + // Create an input for take profit signal trigger. + // Get the signal options from the signal instance. + ops = []; for (let signal of window.UI.signals.signals) {ops.push(signal.name);} + this.dropDown('loss_trig','Stop-Loss trigger:', options, ops); + // Set display to hidden. + this.hideShowTags(['loss_trig_lbl','loss_trig'], 'hide'); + + //Create a drop down for take profit trigger value. + this.dropDown('loss_trigVal','Loss Value:', options, ['true', 'false', 'changed']); + // Set display to hidden. + this.hideShowTags(['loss_trigVal_lbl','loss_trigVal'], 'hide'); + + // Add a line break. + options.appendChild(document.createElement('br')); + // Add a horizontal rule. + options.appendChild(document.createElement('hr')); } if (value == 'incremental_profits'){ @@ -274,14 +299,25 @@ class Strategies { } } } - set_target(){ + initialize(){ // This is called after the html document has been parsed. this.target = document.getElementById(this.target_id); + // Send a request to the server for any loaded data. + window.UI.data.comms.send_to_app('request', 'strategies'); + } + del(name){ + window.UI.data.comms.send_to_app('delete_strategy', name); + // Get the child element node + let child = document.getElementById(name + '_item'); + // Remove the child element from the document + child.parentNode.removeChild(child); } update_html(){ let strats =''; + let on_click = " window.UI.strats.del(this.value);"; for (let strat of this.strategies){ - strats += strat.print_html(); + let button =""; + strats += "
  • " + button + "
    " + JSON.stringify(strat) + "
  • "; } this.target.innerHTML = strats; } diff --git a/static/communication.js b/static/communication.js index 31f8e64..6d42a4f 100644 --- a/static/communication.js +++ b/static/communication.js @@ -33,6 +33,7 @@ class Comms { return id; } send_to_app(message_type, data){ + console.log('window.UI.data.comms.send_to_app(): Sending->'); console.log( JSON.stringify({ message_type: message_type, data : data })); if (this.connection_open){ this.app_con.send( JSON.stringify({ message_type: message_type, data : data })); @@ -83,6 +84,10 @@ class Comms { /* On initialization the server will send a list of signals loaded from file. Forward this to the signals instance.*/ window.UI.signals.set_data(msg.data); + }else if (msg.reply == 'strategies'){ + /* On initialization the server will send a list of strategies loaded from file. + Forward this to the strategies instance.*/ + window.UI.strats.set_data(msg.data); } else if (msg.reply =='signal_created'){ /* After the server creates a new signal it will send the details here. diff --git a/static/general.js b/static/general.js index 8c0dbc8..0cc64da 100644 --- a/static/general.js +++ b/static/general.js @@ -85,8 +85,8 @@ class User_Interface{ window.UI.signals.request_signals(); // initialize the alerts instance. window.UI.alerts.set_target(); - // initialize the alerts instance. - window.UI.strats.set_target(); + // initialize the strategies instance. + window.UI.strats.initialize(); }); } diff --git a/static/signals.js b/static/signals.js index 841098f..d745fef 100644 --- a/static/signals.js +++ b/static/signals.js @@ -58,9 +58,9 @@ class Signals { // Keep a local record of the signals. this.signals.push(obj); // Define the function that is called when deleting an individual signal. - let click_func = "window.UI.signals.delete_signal('" + obj.name+ "')"; + let click_func = "window.UI.signals.delete_signal('" + obj.name + "')"; // create a delete button for every individual signal. - let delete_btn = ""; + let delete_btn = ''; // Put all the attributes into html elements. let signal_name = " " + obj.name + ": "; diff --git a/templates/index.html b/templates/index.html index 262be3e..c219be2 100644 --- a/templates/index.html +++ b/templates/index.html @@ -46,7 +46,7 @@
    - +