brighter-trading/static/trade.js

184 lines
9.2 KiB
JavaScript

class Trade {
constructor() {
// A list of all the open trades.
this.trades = [];
/* HTML elements that interact with this class. */
// The html element that displays the quote value to execute the trade at.
this.priceInput_el = null;
// The html element that displays the actual quote value of the base asset.
this.currentPrice_el = null;
// The html element that displays the quantity to executed the trade at.
this.qtyInput_el = null;
// The html element that displays the value of the trade. (quantity * price)
this.tradeValue_el = null;
// The html element that displays the orderType of the trade. (Market|Limit)
this.orderType_el = null;
// The html element that displays the target for the trade ['binance'|'test_exchange'].
this.target_el = null;
// The html element that displays the side to trade. [buy|sell]
this.side_el = null;
// The html element that displays the form dialog for a new trade.
this.formDialog_el = null;
// The html element that displays the active trades.
this.activeTLst_el = null;
}
connectElements({price='price', currentPrice='currentPrice', quantity='quantity',
tradeValue='tradeValue', orderType='orderType', target='tradeTarget',
side='side', ntf='new_trade_form', atl='activeTradesLst'}={}){
/*
Sets a reference to the dom elements that interact with this class.
Overwriting the default id's allows for instance specific binding.
*/
this.priceInput_el = document.getElementById(price);
this.currentPrice_el = document.getElementById(currentPrice);
this.qtyInput_el = document.getElementById(quantity);
this.tradeValue_el = document.getElementById(tradeValue);
this.orderType_el = document.getElementById(orderType);
this.target_el = document.getElementById(target);
this.side_el = document.getElementById(side);
this.formDialog_el = document.getElementById(ntf);
this.activeTLst_el = document.getElementById(atl);
}
initialize(){
/* Set the values and behavior of elements this class interacts with. */
// Bind this instance with the html element ment to interact with it.
this.connectElements();
// Store this object pointer for referencing inside callbacks and event handlers.
var that = this;
// Assign the quote value of the asset to the current price display element.
window.UI.data.price_history.then((ph) => {
// Assign the last closing price in the price history to the price input element.
that.priceInput_el.value = ph[ph.length-1].close;
// Set the current price display to the same value.
that.currentPrice_el.value = that.priceInput_el.value;
});
// Set the trade value to zero. This will update when price and quantity inputs are received.
this.tradeValue_el.value = 0;
// Toggle current price or input-field for value updates depending on orderType.
function update_tradeValue(){
if ( that.orderType_el.value == 'MARKET')
{that.tradeValue_el.value = that.qtyInput_el.value * that.currentPrice_el.value;}
else
{that.tradeValue_el.value = that.qtyInput_el.value * that.priceInput_el.value;}
}
// Market orders are executed at the current price. To avoid confusion.
// Grey out this price input when orderType is set to Market.
this.orderType_el.addEventListener('change', function(){
if(this.value == 'MARKET')
{
that.currentPrice_el.style.display = "inline-block";
that.priceInput_el.style.display = "none";
}
else if(this.value == 'LIMIT')
{
that.currentPrice_el.style.display = "none";
that.priceInput_el.style.display = "inline-block";
}
update_tradeValue();
});
// Update the trade value display everytime the price input changes.
this.priceInput_el.addEventListener('change', update_tradeValue);
// Update the trade value display everytime the quantity input changes.
this.qtyInput_el.addEventListener('change', update_tradeValue);
// Send a request to the server for any loaded data.
window.UI.data.comms.sendToApp('request', 'trades');
}
// Call to display the 'Create new trade' dialog.
open_tradeForm() { this.formDialog_el.style.display = "grid"; }
// Call to hide the 'Create new signal' dialog.
close_tradeForm() { this.formDialog_el.style.display = "none"; }
// Call to display the 'Trade details' dialog.
open_tradeDetails_Form() { document.getElementById("trade_details_form").style.display = "grid"; }
// Call to hide the 'Create new signal' dialog.
close_tradeDetails_Form() { document.getElementById("trade_details_form").style.display = "none"; }
submitNewTrade(){
// Collect all the input fields.
var target = this.target_el.value; // The target to trade ['binance'|'test_exchange'].
var symbol = window.UI.data.trading_pair; // The symbol to trade at.
var price = this.priceInput_el.value; // The price to trade at this is ignored in a market trade.
var side = this.side_el.value; // The side to trade at.
var orderType = this.orderType_el.value; // The orderType for the trade.
var quantity = this.qtyInput_el.value; // The base quantity to trade.
var data = {
target, symbol, price, side, orderType, quantity
};
window.UI.data.comms.sendToApp( "new_trade", data);
this.close_tradeForm();
}
set_data(trades){
console.log('incoming trades!!!');
console.log(trades);
// Create a list item for every trade and add it to a UL element.
var ul = this.activeTLst_el;
// loop through a provided list of trades and attributes.
for (let trade in trades){
// Create a Json object from each trade.
if (typeof(trades[trade]) == 'string')
// During initialization the object received from the server is in string form.
var obj = JSON.parse(trades[trade]);
else
// When trades are created this function receives a javascript object.
var obj=trades[trade];
// Keep a local record of the trade.
this.trades.push(obj);
// Define the function that is called when closing an individual trade.
let click_func = "window.UI.trade.closeTrade('" + obj.unique_id + "')";
// Create a close button for every individual trade.
let close_btn = '<button onclick="' + click_func + '" style="color:red;width:32;height:22;margin-right:18;">&#10008;</button>';
// Format some markup to display the attributes of the trade.
//let trade_id = " <span>" + obj.unique_id + ": </span>";
let trade_qty = "<span id='" + obj.unique_id + "_qty'>" + obj.stats.qty_filled + "</span>";
let trade_profit = "<span id='" + obj.unique_id + "_profit'>" + obj.stats.profit + "</span>";
let trade_pct = "<span id='" + obj.unique_id + "_pct'>" + obj.stats.profit_pct + "</span>";
let trade_icon = "<button class='trade_details' onclick='UI.trade.open_tradeDetails_Form()'>" + "</button>";
// Stick all the html together.
let html = trade_icon;
html += "<span>QTY:" + trade_qty + "</span>";
html += "<span>P/L:" + trade_profit + "</span>";
html += "<span>P/L %:" + trade_pct + "</span>";
html += close_btn;
// Put it in a div.
html = "<div class='trade_cont'>" + html + "</div>"
// Create the list item.
let li = document.createElement("li");
// Give it an id.
li.id = obj.unique_id + '_item';
// Inject the html.
li.innerHTML= html;
// And add it the the UL we created earlier.
ul.appendChild(li);
}
console.log('pushed trades!!!');
console.log(this.trades);
}
closeTrade(tradeId){
// Requests that the server close a specific trade.
window.UI.data.comms.sendToApp('close_trade', tradeId);
// Get the trade element from the UI
let child = document.getElementById(tradeId + '_item');
// Ask the parent of the trade element to remove its child(trade) from the document.
child.parentNode.removeChild(child);
}
update_received(trade_updts){
// if ( 'cmd' in trade_updts) {
// let alert =
// window.UI.alerts.publish_alerts('trade', trade_updts);
// this.executeCmd(trade_updts.cmd);
// }
console.log('Received trade update.');
console.log('Updating trade updating local list.');
this.trades = trade_updts;
for (let trade in this.trades){
console.log('dont forget to update the html.');
console.log(trade);
}
}
}