extends layout block content script. $(document).ready(function() { if ('#{settings.markets_page.page_header.show_last_updated}' == 'true') { var lastUpdatedDate = #{(last_updated == null || last_updated == '0' ? 0 : last_updated)}; if (lastUpdatedDate != 0) { $('span#lastUpdatedDate').html(' ' + format_unixtime(lastUpdatedDate)); if (#{settings.shared_pages.date_time.enable_alt_timezone_tooltips} == true) { $('span#lastUpdatedDate').attr('data-bs-toggle', 'tooltip').attr('data-bs-placement', 'auto').attr('title', format_unixtime(lastUpdatedDate, true)); enableTooltips(); } } else $('span#lastUpdatedDate').html(' N/A'); } if (#{settings.shared_pages.page_header.page_title_image.enable_animation} == true && #{settings.markets_page.page_header.show_img} == true) startRotateElement('img#header-img'); }); - var theadClasses = []; if settings.shared_pages.table_header_bgcolor != null && settings.shared_pages.table_header_bgcolor != '' - theadClasses.push('table-' + settings.shared_pages.table_header_bgcolor); if marketdata.data != null && ((marketdata.data.buys != null && marketdata.data.buys.length > 0) || (marketdata.data.sells != null && marketdata.data.sells.length > 0) || (marketdata.data.history != null && marketdata.data.history.length > 0)) script. $(document).ready(function() { $('.summary-table').dataTable({ info: false, paging: false, searching: false, ordering: false, autowidth: true, responsive: true, scrollX: true, fnDrawCallback: function(settings) { fixDataTableColumns(); } }); $('.order-table').dataTable({ info: false, paging: false, searching: false, ordering: false, scrollY: '250px', scrollCollapse: true, autowidth: true, responsive: true, scrollX: true, fnDrawCallback: function(settings) { fixDataTableColumns(); } }); $('#history-table').dataTable({ searching: false, ordering: false, responsive: true, scrollX: true, language: { paginate: { previous: '<', next: '>' } }, fnDrawCallback: function(settings) { if ($('#history-table > tbody > tr > td > span.timestampCol').length > 0) { $('#history-table > tbody > tr > td > span.timestampCol').each(function() { if ($.isNumeric($(this).text())) { if (#{settings.shared_pages.date_time.enable_alt_timezone_tooltips} == true) $(this).attr('data-bs-toggle', 'tooltip').attr('data-bs-placement', 'auto').attr('title', format_unixtime(parseInt($(this).text()), true)); $(this).html(format_unixtime(parseInt($(this).text()))); } }); if (#{settings.shared_pages.date_time.enable_alt_timezone_tooltips} == true) enableTooltips(); } fixDataTableColumns(); } }); }); .col-xs-12.col-md-12 if settings.markets_page.page_header.show_img == true || settings.markets_page.page_header.show_title == true || settings.markets_page.page_header.show_last_updated == true || (settings.markets_page.page_header.show_exchange_url == true && marketdata.url != null && marketdata.url != '') || settings.markets_page.page_header.show_description == true #page-header-container(style='align-items:' + (settings.markets_page.page_header.show_img == true && settings.markets_page.page_header.show_title == true && ((settings.markets_page.page_header.show_last_updated == true && settings.markets_page.page_header.show_description == true) || ((settings.markets_page.page_header.show_exchange_url == true && marketdata.url != null && marketdata.url != '') && settings.markets_page.page_header.show_description == true) || ((settings.markets_page.page_header.show_exchange_url == true && marketdata.url != null && marketdata.url != '') && settings.markets_page.page_header.show_last_updated == true)) ? 'flex-start' : 'center')) if settings.markets_page.page_header.show_img == true #header-img-container img#header-img(src=(settings.shared_pages.page_header.page_title_image == null || settings.shared_pages.page_header.page_title_image.image_path == null || settings.shared_pages.page_header.page_title_image.image_path == '' ? '/img/page-title-img.png' : settings.shared_pages.page_header.page_title_image.image_path)) #page-title-container if settings.markets_page.page_header.show_title == true h3#page-title !{settings.localization.mkt_title.replace('{1}', marketdata.market_name + ' (' + marketdata.coin + '/' + marketdata.exchange + ')')} if settings.markets_page.page_header.show_last_updated == true if settings.markets_page.page_header.show_title != true && settings.markets_page.page_header.show_description != true && (settings.markets_page.page_header.show_exchange_url != true && marketdata.url != null && marketdata.url != '') #page-title-container .sub-page-header span.fw-bold=settings.localization.last_updated + ':' span.text-muted#lastUpdatedDate else .sub-page-header(style='margin-bottom:' + (settings.markets_page.page_header.show_description == true || (settings.markets_page.page_header.show_exchange_url == true && marketdata.url != null && marketdata.url != '') ? '5' : '0') + 'px') span.fw-bold=settings.localization.last_updated + ':' span.text-muted#lastUpdatedDate if settings.markets_page.page_header.show_exchange_url == true && marketdata.url != null && marketdata.url != '' if settings.markets_page.page_header.show_title != true && settings.markets_page.page_header.show_last_updated != true && settings.markets_page.page_header.show_description != true #page-title-container .sub-page-header span.fw-bold='Link to Exchange:' a.sub-page-header(title='Link to Exchange', target='_blank', href=marketdata.url) span !{' Trade (' + marketdata.coin + '/' + marketdata.exchange + ')'} else .sub-page-header(style='margin-bottom:' + (settings.markets_page.page_header.show_description == true ? '5' : '0') + 'px') span.fw-bold='Link to Exchange:' a.sub-page-header(title='Link to Exchange', target='_blank', href=marketdata.url) span !{' Trade (' + marketdata.coin + '/' + marketdata.exchange + ')'} if settings.markets_page.page_header.show_description == true if settings.markets_page.page_header.show_title != true && settings.markets_page.page_header.show_last_updated != true && (settings.markets_page.page_header.show_exchange_url != true && marketdata.url != null && marketdata.url != '') #page-title-container .sub-page-header.text-muted=settings.localization.mkt_description.replace('{1}', marketdata.coin + '/' + marketdata.exchange).replace('{2}', marketdata.market_name) else .sub-page-header.text-muted=settings.localization.mkt_description.replace('{1}', marketdata.coin + '/' + marketdata.exchange).replace('{2}', marketdata.market_name) .cardSpacer.clearfix if settings.markets_page.show_market_select == true && settings.market_count > 1 .row .col-md-12.cardSpacer .card.card-default.border-0 .card-header strong #{settings.localization.mkt_select} .card-body ul.nav.nav-pills each mkt in settings.market_data if mkt != null && mkt.id != null each pair in mkt.trading_pairs if market == mkt.id && marketdata.coin.toLowerCase() + '/' + marketdata.exchange.toLowerCase() == pair.pair.toLowerCase() li.nav-item a.nav-link.active(href='/markets/' + mkt.id + '/' + pair.pair) if pair.isAlt == true if mkt.alt_logo != null && mkt.alt_logo != '' img.align-top.market-logo(src='data:image/png;base64,' + mkt.alt_logo, title=mkt.alt_name + ' (' + pair.pair + ')', alt=mkt.alt_name + ' (' + pair.pair + ')') else i.market-logo.fa-solid.fa-circle-question span #{mkt.alt_name} span.small.fw-normal (#{pair.pair}) else if mkt.logo != null && mkt.logo != '' img.align-top.market-logo(src='data:image/png;base64,' + mkt.logo, title=mkt.name + ' (' + pair.pair + ')', alt=mkt.name + ' (' + pair.pair + ')') else i.market-logo.fa-solid.fa-circle-question span #{mkt.name} span.small.fw-normal (#{pair.pair}) else li.nav-item a.nav-link(href='/markets/' + mkt.id + '/' + pair.pair) if pair.isAlt == true if mkt.alt_logo != null && mkt.alt_logo != '' img.align-top.market-logo(src='data:image/png;base64,' + mkt.alt_logo, title=mkt.alt_name + ' (' + pair.pair + ')', alt=mkt.alt_name + ' (' + pair.pair + ')') else i.market-logo.fa-solid.fa-circle-question span #{mkt.alt_name} span.small.fw-normal (#{pair.pair}) else if mkt.logo != null && mkt.logo != '' img.align-top.market-logo(src='data:image/png;base64,' + mkt.logo, title=mkt.name + ' (' + pair.pair + ')', alt=mkt.name + ' (' + pair.pair + ')') else i.market-logo.fa-solid.fa-circle-question span #{mkt.name} span.small.fw-normal (#{pair.pair}) if marketdata.data != null && ((marketdata.data.buys != null && marketdata.data.buys.length > 0) || (marketdata.data.sells != null && marketdata.data.sells.length > 0) || (marketdata.data.history != null && marketdata.data.history.length > 0)) block market_view script. $(document).ready(function() { var chartData = !{(marketdata.data.chartdata == null || marketdata.data.chartdata == 'null' || marketdata.data.chartdata == '' || marketdata.data.chartdata == '[]' ? 'null' : marketdata.data.chartdata)}; if (chartData != null) { chartData = chartData.map(function(item) { return { x: item[0], o: item[1], h: item[2], l: item[3], c: item[4] }; }); const backgroundPlugin = { id: 'backgroundFill', beforeDraw(chart) { const ctx = chart.ctx; ctx.save(); ctx.fillStyle = '#FFFFFF'; // Change chart background color const chartArea = chart.chartArea; ctx.fillRect(chartArea.left, chartArea.top, chartArea.right - chartArea.left, chartArea.bottom - chartArea.top); ctx.restore(); } }; Chart.register(backgroundPlugin); var ohlcvChart = new Chart('chart', { type: 'candlestick', data: { datasets: [{ label: 'Market Data', data: chartData, borderColor: { up: 'rgba(80, 160, 115, 1)', down: 'rgba(215, 85, 65, 1)', unchanged: 'rgba(90, 90, 90, 1)' }, color: { up: 'rgba(80, 160, 115, 1)', down: 'rgba(215, 85, 65, 1)', unchanged: 'rgba(90, 90, 90, 1)' } }] }, options: { maintainAspectRatio: true, aspectRatio: 3, scales: { x: { type: 'time', offset: true, ticks: { padding: 10 } }, y: { position: 'right', grace: '10%', ticks: { callback: function(value, index, values) { return parseFloat(value).toFixed(8); } } } }, plugins: { legend: { display: false }, tooltip: { mode: 'nearest', callbacks: { title: function(context) { return format_unixtime(context[0].raw.x / 1000); }, beforeBody: function(context) { const dataset = context[0].dataset; const data = dataset.data[context[0].dataIndex]; return [ 'Open: ' + data.o.toFixed(8), 'High: ' + data.h.toFixed(8), 'Low: ' + data.l.toFixed(8), 'Close: ' + data.c.toFixed(8) ]; }, label: function(context) { // Suppress the default body content return null; } } }, crosshair: { line: { color: '#000000', width: 1 }, sync: { enabled: false }, zoom: { enabled: false } } } } }); } }); .row .col-md-12.cardSpacer .card.card-default.border-0 .card-header if marketdata.market_logo != null && marketdata.market_logo != '' img.align-top.market-logo(src='data:image/png;base64,' + marketdata.market_logo, title=marketdata.market_name + ' Logo', alt=marketdata.market_name + ' Logo') strong #{marketdata.market_name} span.small.fw-normal (#{marketdata.coin}/#{marketdata.exchange}) strong - #{settings.localization.mkt_hours} if marketdata.data.chartdata == null || marketdata.data.chartdata == 'null' || marketdata.data.chartdata == '' || marketdata.data.chartdata == '[]' span.fa-solid.fa-chart-line.float-end.view-chart-disabled.market-toggle(style='cursor: pointer;color: var(--bs-body-color);', data-bs-toggle='tooltip', data-bs-placement='bottom', title=settings.localization.mkt_no_chart) table#market-summary.table.table-bordered.bottom-border-0.summary-table.single-row-table(style='border-top:0;margin-top:0 !important;') thead tr(class=theadClasses) if marketdata.data.summary != null if marketdata.data.summary.high != null th.text-center #{settings.localization.mkt_high} if marketdata.data.summary.low != null th.text-center #{settings.localization.mkt_low} if marketdata.data.summary.volume != null th.text-center #{settings.localization.mkt_volume} span.small.fw-normal (#{marketdata.coin}) if marketdata.data.summary.volume_btc != null th.text-center #{settings.localization.mkt_volume} span.small.fw-normal (#{marketdata.exchange}) if marketdata.data.summary.bid != null th.text-center #{settings.localization.mkt_top_bid} if marketdata.data.summary.ask != null th.text-center #{settings.localization.mkt_top_ask} if marketdata.data.summary.last != null th.text-center #{settings.localization.mkt_last} if marketdata.data.summary.prev != null th.text-center #{settings.localization.mkt_yesterday} if marketdata.data.summary.change != null || (marketdata.data.summary.last != null && marketdata.data.summary.prev != null) th.text-center #{settings.localization.mkt_change} else th.text-center #{settings.localization.mkt_high} th.text-center #{settings.localization.mkt_low} th.text-center #{settings.localization.mkt_volume} span.small.fw-normal (#{marketdata.coin}) th.text-center #{settings.localization.mkt_volume} span.small.fw-normal (#{marketdata.exchange}) th.text-center #{settings.localization.mkt_top_bid} th.text-center #{settings.localization.mkt_top_ask} th.text-center #{settings.localization.mkt_last} th.text-center #{settings.localization.mkt_yesterday} th.text-center #{settings.localization.mkt_change} tbody tr if marketdata.data.summary != null if marketdata.data.summary.high != null - var highValue = Number(marketdata.data.summary.high).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); - var splitHigh = highValue.split("."); td.text-center #{splitHigh[0]}. span.decimal #{splitHigh[1]} if marketdata.data.summary.low != null - var lowValue = Number(marketdata.data.summary.low).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); - var splitLow = lowValue.split("."); td.text-center #{splitLow[0]}. span.decimal #{splitLow[1]} if marketdata.data.summary.volume != null - var volumeValue = Number(marketdata.data.summary.volume).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); - var splitVolume = volumeValue.split("."); td.text-center #{splitVolume[0]}. span.decimal #{splitVolume[1]} if marketdata.data.summary.volume_btc != null - var volumeBTCValue = Number(marketdata.data.summary.volume_btc).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); - var splitVolumeBTC = volumeBTCValue.split("."); td.text-center #{splitVolumeBTC[0]}. span.decimal #{splitVolumeBTC[1]} if marketdata.data.summary.bid != null - var bidValue = Number(marketdata.data.summary.bid).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); - var splitBid = bidValue.split("."); td.text-center #{splitBid[0]}. span.decimal #{splitBid[1]} if marketdata.data.summary.ask != null - var askValue = Number(marketdata.data.summary.ask).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); - var splitAsk = askValue.split("."); td.text-center #{splitAsk[0]}. span.decimal #{splitAsk[1]} if marketdata.data.summary.last != null - var lastValue = Number(marketdata.data.summary.last).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); - var splitLast = lastValue.split("."); td.text-center #{splitLast[0]}. span.decimal #{splitLast[1]} if marketdata.data.summary.prev != null - var prevValue = Number(marketdata.data.summary.prev).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); - var splitPrev = prevValue.split("."); td.text-center #{splitPrev[0]}. span.decimal #{splitPrev[1]} if marketdata.data.summary.change != null || (marketdata.data.summary.last != null && marketdata.data.summary.prev != null) if marketdata.data.summary.change != null if marketdata.data.summary.change == '' || marketdata.data.summary.change == '-' - var price_change = "0.00"; else - var price_change = Number(marketdata.data.summary.change).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':2,'useGrouping':true}); else if marketdata.data.summary.last != 0 - var price_change = Number((100 - ((parseFloat(marketdata.data.summary.prev) / parseFloat(marketdata.data.summary.last)) * 100))).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':2,'useGrouping':true}); else - var price_change = Number(0).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':2,'useGrouping':true}); - var splitChange = price_change.split("."); if price_change > 0 td.text-center.text-success.fw-bold +#{splitChange[0]}. span.decimal #{splitChange[1]} span % else if price_change < 0 td.text-center.text-danger.fw-bold #{splitChange[0]}. span.decimal #{splitChange[1]} span % else td.text-center.fw-bold #{splitChange[0]}. span.decimal #{splitChange[1]} span % else td.text-center - td.text-center - td.text-center - td.text-center - td.text-center - td.text-center - td.text-center - td.text-center - td.text-center - if marketdata.data.chartdata != null && marketdata.data.chartdata != 'null' && marketdata.data.chartdata != '' && marketdata.data.chartdata != '[]' #marketChart.row .col-md-12.cardSpacer .card.card-default.border-0 .card-header if marketdata.market_logo != null && marketdata.market_logo != '' img.align-top.market-logo(src='data:image/png;base64,' + marketdata.market_logo, title=marketdata.market_name + ' Logo', alt=marketdata.market_name + ' Logo') strong #{marketdata.market_name} - #{marketdata.coin}/#{marketdata.exchange} - #{settings.localization.mkt_hours} .card-body canvas#chart(style='height:300px;') .row .col-md-6.col-xs-12.cardSpacer .card.card-default.border-0.wrapper-border-0(class=theadClasses) .card-header(style='border-bottom-width:1px;') if marketdata.market_logo != null && marketdata.market_logo != '' img.align-top.market-logo(src='data:image/png;base64,' + marketdata.market_logo, title=marketdata.market_name + ' Logo', alt=marketdata.market_name + ' Logo') strong(style='color:var(--bs-body-color)') #{settings.localization.mkt_buy_orders} table#buy-orders.table.table-striped.table-bordered.table-hover.order-table.bottom-border-0 thead tr(class=theadClasses) th.text-center #{settings.localization.mkt_price} span.small.fw-normal (#{marketdata.exchange}) th.text-center #{settings.localization.mkt_amount} span.small.fw-normal (#{marketdata.coin}) th.text-center #{settings.localization.mkt_total} span.small.fw-normal (#{marketdata.exchange}) tbody if marketdata.data.buys != null each buy in marketdata.data.buys - var price = Number(buy.price).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); - var splitPrice = price.split("."); - var quantity = Number(buy.quantity).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); - var splitQuantity = quantity.split("."); if buy.total != null - var total = Number(buy.total).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); else - var total = Number(parseFloat(buy.price).toFixed(8) * parseFloat(buy.quantity).toFixed(8)).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); - var splitTotal = total.split("."); tr td.text-center.text-success.fw-bold #{splitPrice[0]}. span.decimal #{splitPrice[1]} td.text-center #{splitQuantity[0]}. span.decimal #{splitQuantity[1]} td.text-center #{splitTotal[0]}. span.decimal #{splitTotal[1]} .col-md-6.col-xs-12.cardSpacer .card.card-default.border-0.wrapper-border-0(class=theadClasses) .card-header(style='border-bottom-width:1px;') if marketdata.market_logo != null && marketdata.market_logo != '' img.align-top.market-logo(src='data:image/png;base64,' + marketdata.market_logo, title=marketdata.market_name + ' Logo', alt=marketdata.market_name + ' Logo') strong(style='color:var(--bs-body-color)') #{settings.localization.mkt_sell_orders} table#sell-orders.table.table-striped.table-bordered.table-hover.order-table.bottom-border-0 thead tr(class=theadClasses) th.text-center #{settings.localization.mkt_price} span.small.fw-normal (#{marketdata.exchange}) th.text-center #{settings.localization.mkt_amount} span.small.fw-normal (#{marketdata.coin}) th.text-center #{settings.localization.mkt_total} span.small.fw-normal (#{marketdata.exchange}) tbody if marketdata.data.sells != null each sell in marketdata.data.sells - var price = Number(sell.price).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); - var splitPrice = price.split("."); - var quantity = Number(sell.quantity).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); - var splitQuantity = quantity.split("."); if sell.total != null - var total = Number(sell.total).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); else - var total = Number(parseFloat(sell.price).toFixed(8) * parseFloat(sell.quantity).toFixed(8)).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); - var splitTotal = total.split("."); tr td.text-center.text-danger.fw-bold #{splitPrice[0]}. span.decimal #{splitPrice[1]} td.text-center #{splitQuantity[0]}. span.decimal #{splitQuantity[1]} td.text-center #{splitTotal[0]}. span.decimal #{splitTotal[1]} .row .col-md-12 .card.card-default.border-0 .card-header if marketdata.market_logo != null && marketdata.market_logo != '' img.align-top.market-logo(src='data:image/png;base64,' + marketdata.market_logo, title=marketdata.market_name + ' Logo', alt=marketdata.market_name + ' Logo') strong #{settings.localization.mkt_trade_history} table#history-table.table.table-hover.table-bordered.table-striped.table-paging(cellspacing='0') thead tr(class=theadClasses) th.text-center #{settings.localization.mkt_price} span.small.fw-normal (#{marketdata.exchange}) th.text-center #{settings.localization.mkt_amount} span.small.fw-normal (#{marketdata.coin}) th.text-center #{settings.localization.mkt_total} span.small.fw-normal (#{marketdata.exchange}) th.text-center #{settings.localization.mkt_time_stamp} tbody if marketdata.data.history != null each order in marketdata.data.history if order.ordertype != null - var price = Number(order.price).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); - var splitPrice = price.split("."); - var quantity = Number(order.quantity).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); - var splitQuantity = quantity.split("."); if order.total != null - var total = Number(order.total).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); else - var total = Number(parseFloat(order.price).toFixed(8) * parseFloat(order.quantity).toFixed(8)).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); - var splitTotal = total.split("."); if order.ordertype.toUpperCase() == 'BUY' tr td.text-center.text-success.fw-bold #{splitPrice[0]}. span.decimal #{splitPrice[1]} td.text-center #{splitQuantity[0]}. span.decimal #{splitQuantity[1]} td.text-center #{splitTotal[0]}. span.decimal #{splitTotal[1]} td.text-center span.timestampCol=order.timestamp else tr td.text-center.text-danger.fw-bold #{splitPrice[0]}. span.decimal #{splitPrice[1]} td.text-center #{splitQuantity[0]}. span.decimal #{splitQuantity[1]} td.text-center #{splitTotal[0]}. span.decimal #{splitTotal[1]} td.text-center span.timestampCol=order.timestamp else .alert.alert-danger.alert-dismissible.fade.show(role='alert') button.btn-close(type='button', data-bs-dismiss='alert') .cardSpacer span.fa-solid.fa-circle-exclamation(style='margin-right:5px') strong #{marketdata.market_name} #{settings.localization.ex_error} div This market has no data to display.