### Fetching Wallet Data and Initializing Chart.js Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/TradingStats.html Performs an AJAX GET request to /api/statistics/wallet to retrieve wallet balance data. Upon successful retrieval, it formats the dates using Moment.js and initializes a Chart.js line graph to visualize the balances over time on the #canvas-1 element. ```JavaScript $.ajax({ url: "/api/statistics/wallet", type: "GET", dataType: 'json', success: function (rtnData) { console.log(rtnData); var arr = jQuery.map(rtnData.stat.dates, function (value, i) { return (moment(value).format("YYYY-MM-DD HH:mm:ss")); }); var config = { type: 'line', data: { datasets: [{ label: 'Balances', backgroundColor: 'rgba(220, 220, 220, 0.2)', borderColor: 'rgba(220, 220, 220, 1)', pointBackgroundColor: 'rgba(220, 220, 220, 1)', pointBorderColor: '#fff', data: rtnData.stat.balances }], labels: arr }, options: { responsive: true } }; var lineChart = new Chart($('#canvas-1'), config); }, error: function (rtnData) { alert('error' + rtnData); } }); ``` -------------------------------- ### Selling a Trade Position - JavaScript Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/Trades.html Prompts the user for confirmation using `bootbox.confirm` before sending an AJAX GET request to `/api/trading/sellNow/{tradeId}` to execute a sell order for the specified trade. ```JavaScript function sellPosition(tradeId) { bootbox.confirm("Sell this position now ?", function (result) { if (result === true) { $.get("/api/trading/sellNow/" + tradeId, function () { }); }; }); } ``` -------------------------------- ### Loading Trade Details Modal - JavaScript Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/Trades.html Fetches HTML content for a trade details modal from a specified URL using an AJAX GET request, populates the `#modal-content` div, and then displays the `#tradeModal`. ```JavaScript function loadTradeModal(url, tradeIdVal, tradeActiveVal) { tradeId = tradeIdVal; tradeActive = tradeActiveVal $.get(url, function (data) { $('#modal-content').html(data); $('#tradeModal').modal('show'); }); } ``` -------------------------------- ### Cancelling a Trade Order - JavaScript Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/Trades.html Confirms with the user via `bootbox.confirm` and then sends an AJAX GET request to `/api/trading/cancelOrder/{tradeId}` to cancel the specified trade order. ```JavaScript function cancelPosition(tradeId) { bootbox.confirm("Cancel this position now ?", function (result) { if (result === true) { $.get("/api/trading/cancelOrder/" + tradeId, function () { }); }; }); } ``` -------------------------------- ### Initializing Exchange and Market Parameters - JavaScript Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/TradingViewWidget.html This snippet initializes `exchange` and `market` variables. It first checks if the variables are already defined, then attempts to retrieve them from URL parameters using `getParam()`. If neither is available, it defaults to 'BINANCE' for exchange and 'BTCUSDT' for market. It also includes a commented-out section for a Coinbase-specific fix and ensures the market string is formatted correctly. ```JavaScript if (typeof (exchange) != "undefined") { exchange = exchange; } else if (getParam('exchange') != null) { exchange = getParam('exchange'); } else { exchange = "BINANCE"; } if (typeof (market) != "undefined") { market = market; } else if (getParam('market') != null) { market = getParam('market'); } else { market = "BTCUSDT"; } //fast fix for coinbase -> ToDo -> This function always return COINBASE even on valid exchanges /*if (exchange.localeCompare('GDAX') || exchange.localeCompare('ExchangeGdaxSimulationApi')) exchange = 'COINBASE'; */ market = market.replace('-', ''); ``` -------------------------------- ### Initializing Trading Parameters in JavaScript Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/SignalsWidget.html This JavaScript code block initializes critical trading parameters such as exchange, market, candle size, and trading strategy. It prioritizes existing variable values, falls back to URL parameters if available via `getParam()`, and defaults to an empty string if neither source provides a value. These parameters are essential for configuring subsequent trading operations. ```JavaScript if (typeof (exchange) != "undefined") { exchange = exchange; } else if (getParam('exchange') != null) { exchange = getParam('exchange'); } else { exchange = ""; } if (typeof (market) != "undefined") { market = market; } else if (getParam('market') != null) { market = getParam('market'); } else { market = ""; } if (typeof (candleSize) != "undefined") { candleSize = candleSize; } else if (getParam('candleSize') != null) { candleSize = getParam('candleSize'); } else { candleSize = ""; } if (typeof (tradingStrategy) != "undefined") { tradingStrategy = tradingStrategy; } else if (getParam('tradingStrategy') != null) { tradingStrategy = getParam('tradingStrategy'); } else { tradingStrategy = ""; } ``` -------------------------------- ### Initializing Vue.js Instance for Trade Data (JavaScript) Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/Trades.html This snippet initializes a Vue.js instance named 'myntTrades'. It manages active and closed trade data, connects to SignalR upon creation, fetches initial data, and provides utility methods for data updates and date formatting. ```JavaScript var myntTrades = new Vue({ el: '#myntTrades', parent: vueMain, data: { activeTradesData: null, closedTradesData: null }, created: function () { this.connectSignalr(); this.fetchData(); }, mounted: function () { }, methods: { connectSignalr: function () { var self = this; let hubRoute = "/signalr/HubTraders"; let protocol = new signalR.JsonHubProtocol(); var options = {}; var connection = new signalR.HubConnectionBuilder() //.configureLogging(signalR.LogLevel.Trace) .withUrl(hubRoute, options) .withHubProtocol(protocol) .build(); var connectSignalr = function () { connection.start().then(function () { //Make sure to register this signalr client - Needed for disconnect on page change addSignalrClient(hubRoute, connection); }).catch(function (err) { console.log(err); }); }; var reconnectSignalr = function () { console.log(signalrConnections); if (signalrConnections[hubRoute] != null) { setTimeout(function () { console.log("reconnnect"); connectSignalr(); }, 5000); } } connection.on('Send', function (msg) { console.log("Msg from signalR: " + msg); table.ajax.url('/api/trading/activeTrades').load(); tableClosedTrades.ajax.url('/api/trading/closedTrades').load(); //self.updateData(); }); connection.onclose(function (e) { if (e) { console.log('Connection closed with error: ' + e); } else { console.log('Disconnected'); } //Reconnect -> This connection should never be offline reconnectSignalr(); }); connectSignalr(); }, fetchData: function () { var self = this; $.get("/api/trading/activeTrades", function (activeTradeData) { self.activeTradesData = activeTradeData; $.get("/api/trading/closedTrades", function (closedTradeData) { self.closedTradesData = closedTradeData; self.$nextTick(function () { pagefunction(); }); }); }); }, updateData: function () { $.get("/api/trading/activeTrades", function (activeTradeData) { self.activeTradesData = activeTradeData; $.get("/api/trading/closedTrades", function (closedTradeData) { self.closedTradesData = closedTradeData; }); }); }, moment: function (data) { return moment(data).format("YYYY-MM-DD HH:mm:ss"); } } }); ``` -------------------------------- ### Initializing D3.js and Techan.js Chart Components Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/SignalsWidget.html This snippet initializes the D3.js and Techan.js charting components, including margins, scales, axes, and various financial indicators (candlestick, volume, SMA, EMA, Bollinger, MACD, trade arrows, crosshair). It sets up the SVG container and defines clip paths for rendering the main and context charts. ```JavaScript $(document).ready(function () { var margin = { top: 20, right: 20, bottom: 100, left: 80 }, margin2 = { top: 620, right: 20, bottom: 20, left: 80 }, width = 1000 - margin.left - margin.right, height = 700 - margin.top - margin.bottom, height2 = 700 - margin2.top - margin2.bottom; var parseDate = d3.timeParse("%Y-%m-%dT%H:%M:%S"); var x = techan.scale.financetime().range([0, width]); var y = d3.scaleLinear().range([height, 0]); var x2 = techan.scale.financetime().range([0, width]); var y2 = d3.scaleLinear().range([height2, 0]); var yVolume = d3.scaleLinear().range([y(0), y(0.3)]); var brush = d3.brushX().extent([[0, 0], [width, height2]]).on("end", brushed); var candlestick = techan.plot.candlestick().xScale(x).yScale(y); var volume = techan.plot.volume().xScale(x).yScale(yVolume); var close = techan.plot.close().xScale(x2).yScale(y2); var sma0 = techan.plot.sma().xScale(x).yScale(y); var sma1 = techan.plot.sma().xScale(x).yScale(y); var ema2 = techan.plot.ema().xScale(x).yScale(y); var ema3 = techan.plot.ema().xScale(x).yScale(y); var plotLine1 = d3.line() .defined(function (d) { return !isNaN(d.open); }) .x(function (d) { return x(d.date); }) .y(function (d) { return y(d.line1); }); var xAxis = d3.axisBottom(x); var yAxis = d3.axisLeft(y); var xAxis2 = d3.axisBottom(x2); var yAxis2 = d3.axisLeft(y2).ticks(0); var tradearrow = techan.plot.tradearrow() .xScale(x) .yScale(y) .orient(function (d) { if (d.type === 'buy') return "right"; if (d.type === 'sell') return "left"; }); var ohlcAnnotation = techan.plot.axisannotation().axis(yAxis).orient('left').format(d3.format(',.8')); var timeAnnotation = techan.plot.axisannotation() .axis(xAxis) .orient('bottom') .format(d3.timeFormat('%Y-%m-%dT%H:%M:%S')) .width(65) .translate([0, height]); var crosshair = techan.plot.crosshair().xScale(x).yScale(y).xAnnotation(timeAnnotation).yAnnotation(ohlcAnnotation); var bollinger = techan.plot.bollinger().xScale(x).yScale(y); var macd = techan.plot.macd().xScale(x).yScale(y); d3.select("svg").remove(); var svg = d3.select("#charts").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom); var focus = svg.append("g") .attr("class", "focus") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); focus.append("clipPath") .attr("id", "clip") .append("rect") .attr("x", 0) .attr("y", y(1)) .attr("width", width) .attr("height", y(0) - y(1)); focus.append("g") .attr("class", "bollinger") .attr("clip-path", "url(#clip)"); focus.append("g") .attr("class", "volume") .attr("clip-path", "url(#clip)"); focus.append("g") .attr("class", "candlestick") .attr("clip-path", "url(#clip)"); focus.append("g") .attr("class", "tradearrow") .attr("clip-path", "url(#clip)"); focus.append("g") .attr("class", "macd") .attr("clip-path", "url(#clip)"); focus.append("g") .attr("class", "indicator sma ma-0") .attr("clip-path", "url(#clip)"); focus.append("g") .attr("class", "indicator sma ma-1") .attr("clip-path", "url(#clip)"); focus.append("g") .attr("class", "indicator ema ma-2") .attr("clip-path", "url(#clip)"); focus.append("g") .attr("class", "indicator ema ma-3") .attr("clip-path", "url(#clip)"); focus.append("g") .attr("id", "data_line1") .append("path") .attr("clip-path", "url(#clip)") .attr("class", "line"); focus.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")"); focus.append('g') .attr("class", "crosshair") .call(crosshair); //focus.append("g") // .attr("class", "y axis") // .append("text") // .attr("transform", "rotate(-90)") // .attr("y", 6) // .attr("x", -56) // .attr("dy", ".71em") // .style("text-anchor", "end") // .text("MACD"); focus.append("g") .attr("class", "y axis") .append("text") .attr("y", 0) .attr("x", 50) .attr("dy", ".71em") .style("text-anchor", "end") .style("fill", "#1f77b4") .text("SMA10"); focus.append("g") .attr("class", "y axis") .append("text") .attr("y", 0) .attr("x", 100) .attr("dy", ".71em") .style("text-anchor", "end") .style("fill", "#aec7e8") .text("SMA20"); focus.append("g ``` -------------------------------- ### Initializing DataTables for Coin Performance Statistics Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/TradingStats.html Initializes a jQuery DataTables instance for displaying coin performance data fetched from /api/statistics/overview. It configures responsiveness, column definitions, custom rendering for performance percentages and trade counts, and applies CSS classes to rows based on LogState for visual warnings. ```JavaScript Vue.config.devtools = true; var pagefunction = function () { }; $(document).ready(function () { table = $('#statisticTableId').DataTable({ ajax: { url: '/api/statistics/overview', dataSrc: 'stat.coinPerformances' }, responsive: true, "autoWidth": false, "iDisplayLength": 100, 'columnDefs': [{ 'targets': 0, 'searchable': true, 'orderable': true, 'className': 'dt-body-center' }], 'order': [2, 'desc'], "createdRow": function (row, data, dataIndex) { if (data.LogState === "Warning") $(row).addClass('orangeCell'); if (data.LogState === "Danger") $(row).addClass('redCell'); }, "columns": [ { "title": "Coin", "mDataProp": "coin", "sWidth": "200px", "sType": "alt-string", "sClass": "center", responsivePriority: 1, mRender: function (data, type, full, meta) { var formatted = full.coin; return formatted; } }, { "title": "Performance BTC", "mDataProp": "performance", "sWidth": "150px", "sType": "alt-string", "sClass": "center", responsivePriority: 2, mRender: function (data, type, full, meta) { var formatted = parseFloat(full.performance).toFixed(8); return formatted; } }, { "title": "PerformancePercentage", "mDataProp": "performancePercentage", "sWidth": "1000px", "sType": "alt-string", "sClass": "center", responsivePriority: 2, mRender: function (data, type, full, meta) { var formatted = parseFloat(full.performancePercentage).toFixed(1) + ' %'; return formatted; } }, { "title": "Trades", "mDataProp": "trades", "sWidth": "1000px", "sType": "alt-string", "sClass": "center", responsivePriority: 2, mRender: function (data, type, full, meta) { var posT = full.positiveTrades; var posN = full.negativeTrade; var formatted = '' + posT + ' ' + '' + posN + ' '; return formatted; } } ] }); ``` -------------------------------- ### Initializing Open Trades DataTables - JavaScript Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/Trades.html Initializes a DataTables instance for `#openTradesTableId`, fetching data from `/api/trading/openTrades`. It configures responsive behavior, column definitions, and applies `greenCell` or `redCell` classes to rows based on trade profit/loss. ```JavaScript $(document).ready(function () { tableOpenTrades = $('#openTradesTableId').DataTable({ ajax: { url: '/api/trading/openTrades', dataSrc: '' }, responsive: true, "autoWidth": false, "iDisplayLength": 100, 'columnDefs': [{ 'targets': 0, 'searchable': true, 'orderable': true, 'className': 'dt-body-center' }], 'order': [0, 'asc'], "createdRow": function (row, data, dataIndex) { if (parseFloat(((100 * data.tickerLast.last) / data.openRate) - ``` -------------------------------- ### Initializing TradingView Technical Analysis Widget - JavaScript Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/TradingViewWidget.html This code initializes a TradingView widget for technical analysis. It configures the widget to display data for the dynamically determined `exchange` and `market`, sets display properties like interval, theme, and toolbar, and includes specific studies (ROC, StochasticRSI, MASimple). The widget is rendered into the HTML element with `container_id` 'technical-analysis'. ```JavaScript new TradingView.widget({ "container_id": 'technical-analysis', "autosize": true, "symbol": exchange + ":" + market, "interval": "D", "timezone": Intl.DateTimeFormat().resolvedOptions().timeZone, "interval": "5", //"timezone": "exchange", "theme": "Light", "style": "1", "toolbar_bg": "#f1f3f6", "withdateranges": true, "hide_side_toolbar": false, "allow_symbol_change": true, "save_image": false, "hideideas": true, "studies": ["ROC@tv-basicstudies", "StochasticRSI@tv-basicstudies", "MASimple@tv-basicstudies"], "show_popup_button": true }); ``` -------------------------------- ### Initializing Vue.js TradingView Modal Component - JavaScript Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/TradingViewWidget.html This snippet initializes a Vue.js instance for a modal component, linking it to the HTML element `#widgetTradingViewModal`. It passes the dynamically determined `market` and `exchange` data to the component. The component includes a `fetchData` method, which is called during its creation lifecycle hook, although the method itself is currently empty. ```JavaScript var widgetTradingViewModal = new Vue({ el: '#widgetTradingViewModal', parent: vueMain, data: { market: market, exchange: exchange }, created: function () { this.fetchData(); }, methods: { fetchData: function () { var self = this; } } }); ``` -------------------------------- ### Loading TradingView Widget Modal - JavaScript Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/Trades.html Retrieves the TradingView widget HTML from a given URL via AJAX, inserts it into `#tradingViewModalContent`, and then shows the `#tradingViewModal`. ```JavaScript function loadTradingViewModal(url, exchangeVal, marketVal) { exchange = exchangeVal; market = marketVal; $.get(url, function (data) { $('#tradingViewModalContent').html(data); $('#tradingViewModal').modal('show'); }); } ``` -------------------------------- ### Client-Side Configuration Management with Vue.js and jQuery (JavaScript) Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/Configuration.html This JavaScript code manages the client-side configuration for MachinaTrader, handling UI interactions, form serialization, and data fetching. It initializes UI components like Select2 and cron pickers, dynamically adjusts database settings visibility, and uses Vue.js to bind and update configuration data fetched from the API. ```JavaScript var initialBuyTimerCron = null; var initialSellTimerCron = null; var pagefunction = function () { $(document).ready(function () { var t = document.getElementById("database"); if (t.value === 'LiteDB') { $('#databaseSettings').css("display", "none"); } }); document.getElementById("database").onchange = function (e) { if (this.value === 'MongoDB') { $('#databaseSettings').removeAttr("style"); } if (this.value === 'LiteDB') { $('#databaseSettings').css("display", "none"); } }; /*$('#apiMainConfig').find(':input').each(function () { $(this).on("propertychange, change, keyup, paste, input", function () { event.preventDefault(); postFormData("apiMainConfig", "/api/config/mainConfig", false); }); $(this).on('ifChanged', function (event) { event.preventDefault(); postFormData("apiMainConfig", "/api/config/mainConfig", false); }); }); $('#apiMainConfig').find(':input\[type=checkbox\]').each(function () { $(this).change(function () { event.preventDefault(); postFormData("apiMainConfig", "/api/config/mainConfig", false); }); });*/ $('.qTip').on('mouseover', function (event) { $(this).qtip({ content: { title: $(this).attr('title'), text: $(this).next('div').clone() }, position: { my: 'top center', at: 'bottom center' }, style: { classes: 'qtip-shadow qtip-bootstrap', tip: { corner: true, width: 25, height: 10, offset: 10 } }, prerender: false, overwrite: true, show: { event: event.type, ready: true }, hide: { event: 'mouseout' }, events: { hidden: function (event, api) { $(this).qtip('destroy', true); } } }, event); }); $('#buyTimerCron').cron({ initial: initialBuyTimerCron, onChange: function () { $('#buyTimerCronInput').val($(this).cron("value")); } }); $('#sellTimerCron').cron({ initial: initialSellTimerCron, onChange: function () { $('#sellTimerCronInput').val($(this).cron("value")); } }); $(".select2").select2({ theme: "bootstrap", templateResult: selectPickerImage, templateSelection: selectPickerImage, width: "100%" }); $('.select2-multiple').select2({ placeholder: 'Select Currencies', multiple: true, tags: true, theme: "bootstrap", width: "100%", createTag: function (item) { return { id: item.term, text: item.term }; } }); }; var apiMainConfig = new Vue({ el: '#apiMainConfig', parent: vueMain, data: { apiMainConfigData: null, allStrategiesData: null, exchangeCoinsData: null }, created: function () { this.fetchData(); }, methods: { serializeForm: function () { postFormData("apiMainConfig", "/api/config/mainConfig", true); }, isBool: function (data) { if ((typeof (data) === "boolean")) { return true; } return false; }, updateSymbols: function () { var self = this; //Todo //$.get('/api/trading/getExchangePairs?exchange=' + $("#exchangeSelect").val(), function (data) { // self.exchangeCoinsData = data; //}); }, getTopCurrencies: function () { var self = this; $.get('/api/trading/topVolumeCurrencies?limit=' + $('#amountOfTopCurrenciesToAdd').val(), function (data) { self.apiMainConfigData['tradeOptions']['onlyTradeList'] = data; self.apiMainConfigData['tradeOptions']['alwaysTradeList'] = data; //Workaround to get new Items $("#OnlyTradeList").append(new Option("dummy", "dummy")); $("#OnlyTradeList").trigger("change"); $("#OnlyTradeList option\[value='dummy'\]").remove(); $("#AlwaysTradeList").append(new Option("dummy", "dummy")); $("#AlwaysTradeList").trigger("change"); $("#AlwaysTradeList option\[value='dummy'\]").remove(); }); }, fetchData: function () { var self = this; $.get('/api/config/mainConfig', function (data) { self.apiMainConfigData = data; $.get('/api/backtester/backtesterStrategy', function (data) { self.allStrategiesData = data; $.get('/api/trading/exchangePairsExchangeSymbols?exchange=Binance', function (data) { self.exchangeCoinsData = data; self.$nextTick(function () { initialBuyTimerCron = self.apiMainConfigData['tradeOptions']['buyTimer']; initialSellTimerCron = self.apiMainConfigData['tradeOptions']['sellTimer']; pagefunction(); //self.updateSymbols(); }); }); }); }); } } }); ``` -------------------------------- ### Initializing Percentage Profit TouchSpin - JavaScript Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/TradesTradeModal.html This 'pagefunction' initializes a Bootstrap TouchSpin component on the input field with the ID 'percentage_profit'. It configures the spinner's minimum, maximum, step, decimal places, boost behavior, and adds a '%' postfix. Additionally, it attaches a 'change' event listener to trigger a recalculation of the percentage via the 'tradesModalEdit' Vue instance when the input value changes. ```JavaScript var pagefunction = function () { $("#percentage_profit").TouchSpin({ min: 0, max: 100, step: 0.01, decimals: 2, boostat: 5, maxboostedstep: 10, postfix: '%' }); $('#percentage_profit').on('change', function () { tradesModalEdit.recalculatePercentage($("#percentage_profit").val()); }); }; ``` -------------------------------- ### Initializing Page Function - JavaScript Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/Trades.html Declares an empty `pagefunction` variable, likely a placeholder for page-specific initialization logic or a legacy pattern. ```JavaScript var pagefunction = function () { }; ``` -------------------------------- ### Initializing DataTables for Account Balances Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/Accounts.html This JavaScript snippet initializes a jQuery DataTables instance for the '#accountsTableId' element. It fetches account balance data from '/api/account/balance' via AJAX, configures responsiveness, column definitions, and custom rendering functions for market, total coins, and USD/display currency values. It displays a custom message if the table is empty. ```JavaScript var pagefunction = function () { }; $(document).ready(function () { table = $('#accountsTableId').DataTable({ ajax: { url: '/api/account/balance', dataSrc: '' }, "oLanguage": { "sEmptyTable": "Check your API keys under configuration page." }, responsive: true, "autoWidth": false, "iDisplayLength": 100, 'columnDefs': [{ 'targets': 0, 'searchable': true, 'orderable': true, 'className': 'dt-body-center' }], 'order': [0, 'desc'], "columns": [ { "title": "Market", "mDataProp": "market", "sWidth": "200px", "sType": "alt-string", "sClass": "center", responsivePriority: 1, mRender: function (data, type, full, meta) { var formatted = full.market; formatted = '' + formatted + ' '; return formatted; } }, { "title": "Total Coins", "sWidth": "150px", "sType": "alt-string", "sClass": "center", responsivePriority: 2, mRender: function (data, type, full, meta) { var formatted = parseFloat(full.totalCoins).toFixed(8); return formatted; } }, { "title": "Value in Usd", "sWidth": "1000px", "sType": "alt-string", "sClass": "center", responsivePriority: 2, mRender: function (data, type, full, meta) { var formatted = parseFloat(full.balanceInUsd).toFixed(3); formatted = 'USD ' + formatted; return formatted; } }, { "title": "Value in DisplayCurrency", "sWidth": "1000px", "sType": "alt-string", "sClass": "center", responsivePriority: 2, mRender: function (data, type, full, meta) { if (full.balanceInDisplayCurrency === 0) { formatted = '' + full.displayCurrency + ' not available ' ; } if (full.balanceInDisplayCurrency > 0) { var formatted = parseFloat(full.balanceInDisplayCurrency).toFixed(8); formatted = '' + full.displayCurrency + ' ' + formatted; } return formatted; } } ] }); }); ``` -------------------------------- ### Initializing Trade ID and Active Status - JavaScript Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/TradesTradeModal.html This JavaScript code block initializes the 'tradeId' and 'tradeActive' variables. It first checks if these variables are already defined, then attempts to retrieve their values from URL parameters using a 'getParam' function, and finally assigns default fallback values if neither source provides a definition. ```JavaScript if (typeof (tradeId) != "undefined") { tradeId = tradeId; } else if (getParam('tradeId') != null) { tradeId = getParam('tradeId'); } else { tradeId = "7b3b883255274e609c9de77d19eb989c"; } if (typeof (tradeActive) != "undefined") { tradeActive = tradeActive; } else if (getParam('tradeActive') != null) { tradeActive = getParam('tradeActive'); } else { tradeActive = false; } ``` -------------------------------- ### Initializing DataTables for Log Display (JavaScript) Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/Logging.html Initializes a jQuery DataTables instance for the '#logsTableId' element, configuring it to fetch log data from '/api/logging/logs'. It sets up responsive behavior, column definitions, sorting, and applies CSS classes ('orangeCell', 'redCell') to rows based on the 'LogState' property, providing visual cues for log severity. ```JavaScript var pagefunction = function () { }; $(document).ready(function () { table = $('#logsTableId').DataTable({ ajax: { url: '/api/logging/logs', dataSrc: '' }, responsive: true, "autoWidth": false, "iDisplayLength": 100, 'columnDefs': [{ 'targets': 0, 'searchable': true, 'orderable': true, 'className': 'dt-body-center' }], 'order': [0, 'desc'], "createdRow": function (row, data, dataIndex) { if (data.LogState === "Warning") $(row).addClass('orangeCell'); if (data.LogState === "Danger") $(row).addClass('redCell'); }, "columns": [ { "title": "Date", "mDataProp": "date", "sWidth": "200px", "sType": "alt-string", "sClass": "center", responsivePriority: 1, mRender: function (data, type, full, meta) { var now = moment(); var formatted = moment(full.date).format("YYYY-MM-DD HH:mm:ss"); return formatted; } }, { "title": "State", "mDataProp": "state", "sWidth": "150px", "sType": "alt-string", "sClass": "center", responsivePriority: 2, mRender: function (data, type, full, meta) { var formatted = full.logState; return formatted; } }, { "title": "Message", "mDataProp": "message", "sWidth": "1000px", "sType": "alt-string", "sClass": "center", responsivePriority: 2, mRender: function (data, type, full, meta) { var formatted = full.msg; return formatted; } } ] }); }); ``` -------------------------------- ### Initializing jQuery UI Sortable for Dashboard Cards - JavaScript Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/main.html This function initializes jQuery UI's sortable functionality for dashboard cards. It allows users to drag and drop elements matching `[class*=col]` by their `.card-header`, enabling a customizable layout for the dashboard with a visual placeholder. ```JavaScript var pagefunction = function () { $(function () { var element = "\\[class\\*=col\\]"; var handle = ".card-header"; var connect = "\\[class\\*=col\\]"; $(element).sortable({ handle: handle, connectWith: connect, tolerance: 'pointer', forcePlaceholderSize: true, opacity: 0.8, placeholder: 'card-placeholder' }) .disableSelection(); }); }; ``` -------------------------------- ### Defining API Endpoint for Home Dashboard - JavaScript Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/main.html This snippet defines a JavaScript variable `homeDashBoard` to store the API endpoint URL for fetching core plugin data. It serves as a configuration variable for subsequent AJAX requests made by the Vue.js component. ```JavaScript var homeDashBoard = '/api/core/plugins'; ``` -------------------------------- ### Vue.js Component for Home Dashboard Data Fetching - JavaScript Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/main.html This Vue.js component, mounted on `#homeDashBoard`, is responsible for fetching dashboard data from the API endpoint defined by `homeDashBoard`. Upon successful data retrieval, it updates the component's data and then calls `pagefunction` to initialize the sortable UI elements, ensuring the dashboard is interactive after data loads. ```JavaScript var homeDashBoard = new Vue({ el: '#homeDashBoard', parent: vueMain, data: { homeDashBoardData: null }, created: function () { this.fetchData(); }, methods: { fetchData: function () { var self = this; $.get(homeDashBoard, function (data) { self.homeDashBoardData = data; self.$nextTick(function () { pagefunction(); }); }); } } }); ``` -------------------------------- ### Displaying Performance Statistics with Vue.js Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/TradingStats.html Uses Vue.js template syntax to dynamically display various performance metrics such as quote currency, profit in quote currency, profit percentage, and the default strategy. These values are bound to the myntStatisticsData object, which is populated by the Vue instance. ```HTML #### {{myntStatisticsData.tradeOptions.quoteCurrency}} #### Profit in {{myntStatisticsData.tradeOptions.quoteCurrency}} #### {{parseFloat(myntStatisticsData.stat.profitLoss).toFixed(7)}} {{myntStatisticsData.tradeOptions.quoteCurrency}} #### Profit in % #### {{parseFloat(myntStatisticsData.stat.profitLossPercentage).toFixed(3)}}% #### Used Stategy #### {{myntStatisticsData.tradeOptions.defaultStrategy}} ``` -------------------------------- ### Initializing Vue.js Signals Modal Component Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/SignalsWidget.html This JavaScript code initializes a Vue.js instance for a 'widgetSignalsModalModal' component. It binds to the HTML element with ID '#widgetSignalsModalModal' and inherits from a parent Vue instance (`vueMain`). The component's data properties are populated with the previously initialized trading parameters, and it includes a `fetchData` method called on creation, likely to retrieve signal data relevant to the configured parameters. ```JavaScript var widgetSignalsModalModal = new Vue({ el: '#widgetSignalsModalModal', parent: vueMain, data: { exchange: exchange, market: market, candleSize: candleSize, tradingStrategy: tradingStrategy }, created: function () { this.fetchData(); }, methods: { fetchData: function () { var self = this; }, }, }); ``` -------------------------------- ### Vue.js Component for Real-time Log Updates with SignalR (JavaScript) Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/Logging.html Defines a Vue.js instance ('#myntLogs') that connects to a SignalR hub ('/signalr/HubLogs') for real-time log updates. It includes methods for establishing and re-establishing the SignalR connection, fetching initial log data via AJAX, and updating the DataTables instance when new log messages are received from the hub. ```JavaScript var myntLogs = new Vue({ el: '#myntLogs', parent: vueMain, data: { myntLogsData: null }, created: function () { this.connectSignalr(); this.fetchData(); }, mounted: function () { }, methods: { connectSignalr: function () { var self = this; let hubRoute = "/signalr/HubLogs"; let protocol = new signalR.JsonHubProtocol(); var options = {}; var connection = new signalR.HubConnectionBuilder() //.configureLogging(signalR.LogLevel.Trace) .withUrl(hubRoute, options) .withHubProtocol(protocol) .build(); var connectSignalr = function () { connection.start().then(function () { //Make sure to register this signalr client - Needed for disconnect on page change addSignalrClient(hubRoute, connection); }).catch(function (err) { console.log(err); }); }; var reconnectSignalr = function () { console.log(signalrConnections); if (signalrConnections[hubRoute] != null) { setTimeout(function () { console.log("reconnnect"); connectSignalr(); }, 5000); } } connection.on('Send', function (msg) { console.log("Msg from signalR: " + msg); table.ajax.url('/api/logging/logs').load(); //self.updateData(); }); connection.onclose(function (e) { if (e) { console.log('Connection closed with error: ' + e); } else { console.log('Disconnected'); } //Reconnect -> This connection should never be offline reconnectSignalr(); }); connectSignalr(); }, fetchData: function () { var self = this; $.get("/api/logging/logs", function (data) { self.myntLogsData = data; self.$nextTick(function () { pagefunction(); }); }); }, updateData: function () { $.get("/api/logging/logs", function (data) { self.myntLogsData = data; }); }, moment: function (data) { return moment(data).format("YYYY-MM-DD HH:mm:ss"); } } }); ``` -------------------------------- ### Styling Cron Timer Select Elements (CSS) Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/Configuration.html These CSS rules ensure that select elements within `.cron-period` and `.cron-block` containers are displayed inline and have their width set to initial, preventing them from taking full width and allowing them to align properly with other elements. ```CSS .cron-period > select { display: inline; width: initial; } .cron-block > select { display: inline; width: initial; } ``` -------------------------------- ### Displaying Trade Details - Vue.js Template Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/TradesTradeModal.html This HTML snippet utilizes Vue.js data binding to dynamically display various attributes of a 'trade' object. It shows the trade ID, open date (formatted using a 'moment' helper), market, quantity, calculated cost, buy rate, and the strategy used for the trade. ```HTML Trade Id: {{trade.tradeId}} Open Date: {{moment(trade.openDate)}} Market: {{trade.market}} Quantity: {{trade.quantity}} Cost: {{parseFloat(trade.openRate \* trade.quantity).toFixed(8)}} Buy Rate: {{trade.openRate}} Strategy: {{trade.strategyUsed}} ``` -------------------------------- ### Styling Header and TouchSpin Elements - CSS Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/TradesTradeModal.html This CSS snippet defines styling rules for header columns, setting font weight, letter spacing, line height, and bottom margin. It also specifies a color for the second header column and resets padding and border for the append group of the Bootstrap TouchSpin component. ```CSS .header-title > .col-4, .col-8 { font-weight: 600; letter-spacing: .04em; line-height: 16px; margin-bottom: 12px; } .header-title > .col-8 { color: #797979; } .bootstrap-touchspin > .input-group-append { padding: 0; border: 0; } ``` -------------------------------- ### Configuring DataTables Details Column (JavaScript) Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/Trades.html This snippet defines a DataTables column that provides a clickable "Info" button. Clicking this button opens a modal ('TradesTradeModal.html') to display detailed information about a specific trade using its 'tradeId'. ```JavaScript mRender: function (data, type, full, meta) { var formatted = 'Info'; return formatted; } ``` -------------------------------- ### Configuring DataTables Market Column (JavaScript) Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/Trades.html This snippet defines a DataTables column for displaying market information. It formats the market symbol as a clickable link that opens a TradingView widget modal, showing the exchange and market. ```JavaScript mRender: function (data, type, full, meta) { var formatted = ' ' + full.globalSymbol + ''; return formatted; } ``` -------------------------------- ### Configuring DataTables Result Column (JavaScript) Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/Trades.html This snippet defines a DataTables column to display the percentage profit/loss of a trade. If 'tickerLast' and 'sellOrderId' are present, it calculates the percentage difference between 'closeRate' and 'openRate'; otherwise, it defaults to "0%". ```JavaScript mRender: function (data, type, full, meta) { var formatted = ''; if (full.tickerLast !== null && full.sellOrderId !== null) { var formatted = parseFloat(((100 * full.closeRate) / full.openRate) - 100).toFixed(2) + " %"; } else { var formatted = "0%"; } return formatted; } ``` -------------------------------- ### Vue.js Instance for Real-time Statistics with SignalR Source: https://github.com/mobileguru1013/machinatrader/blob/master/MachinaTrader/wwwroot/views/TradingStats.html Defines a Vue.js instance that manages myntStatisticsData, connecting to a SignalR hub (/signalr/HubStatistics) for real-time updates. It fetches initial data, registers the client with SignalR, and reloads DataTables and updates Vue data upon receiving 'Send' messages or reconnecting after a disconnection. ```JavaScript var myntStatistics = new Vue({ el: '#myntStatistics', parent: vueMain, data: { myntStatisticsData: null }, created: function () { this.connectSignalr(); this.fetchData(); }, methods: { connectSignalr: function () { var self = this; let hubRoute = "/signalr/HubStatistics"; let protocol = new signalR.JsonHubProtocol(); var options = {}; var connection = new signalR.HubConnectionBuilder() //.configureLogging(signalR.LogLevel.Trace) .withUrl(hubRoute, options) .withHubProtocol(protocol) .build(); var connectSignalr = function () { connection.start().then(function () { //Make sure to register this signalr client - Needed for disconnect on page change addSignalrClient(hubRoute, connection); }).catch(function (err) { console.log(err); }); }; var reconnectSignalr = function () { console.log(signalrConnections); if (signalrConnections[hubRoute] != null) { setTimeout(function () { console.log("reconnnect"); connectSignalr(); }, 5000); } } connection.on('Send', function (msg) { console.log("Msg from signalR: " + msg); table.ajax.url('/api/statistics/overview').load(); self.updateData(); }); connection.onclose(function (e) { if (e) { console.log('Connection closed with error: ' + e); } else { console.log('Disconnected'); } //Reconnect -> This connection should never be offline reconnectSignalr(); }); connectSignalr(); }, fetchData: function () { var self = this; $.get("/api/statistics/overview", function (data) { self.myntStatisticsData = data; self.$nextTick(function () { pagefunction(); }); }); }, updateData: function () { var self = this; $.get("/api/statistics/overview", function (data) { self.myntStatisticsData = data; }); } } ```