diff --git a/v2realbot/controller/services.py b/v2realbot/controller/services.py index 88a8b91..1504871 100644 --- a/v2realbot/controller/services.py +++ b/v2realbot/controller/services.py @@ -814,7 +814,10 @@ def populate_metrics_output_directory(strat: StrategyInstance, inter_batch_param rp_string = "RP" + str(float(np.sum(strat.state.rel_profit_cum))) if len(strat.state.rel_profit_cum) >0 else "noRP" ##summary pro rychle zobrazeni P333L-222 PT9:30 PL10:30 - res["profit"]["sum"]="P"+str(int(sum_wins))+"L"+str(int(sum_losses))+" "+"MP"+str(int(max_profit))+"ML"+str(int(max_loss))+" "+ mpt_string+" " + mlt_string + rp_string + " "+str(strat.state.rel_profit_cum) + res["profit"]["sum"]="P"+str(int(sum_wins))+"L"+str(int(sum_losses))+" "+"MP"+str(int(max_profit))+"ML"+str(int(max_loss)) + + #summary pokracovani - max casy + rel profity + res["profit"]["sum_detail"] = mpt_string+" " + mlt_string + rp_string + " "+str(strat.state.rel_profit_cum) #rel_profit zprumerovane res["profit"]["daily_rel_profit_sum"] = float(np.sum(strat.state.rel_profit_cum)) if len(strat.state.rel_profit_cum) > 0 else 0 diff --git a/v2realbot/static/index.html b/v2realbot/static/index.html index bdfce1f..b3e2d7a 100644 --- a/v2realbot/static/index.html +++ b/v2realbot/static/index.html @@ -11,8 +11,9 @@ - + + diff --git a/v2realbot/static/js/archivetables.js b/v2realbot/static/js/archivetables.js index 8ffd65c..4eb7e04 100644 --- a/v2realbot/static/js/archivetables.js +++ b/v2realbot/static/js/archivetables.js @@ -143,12 +143,38 @@ $(document).ready(function () { $('#archiveTable tbody').on('click', 'td:nth-child(18)', function () { var data = archiveRecords.row(this).data(); if (data.batch_id) { + display_batch_report(data.batch_id) + } + }); + + // Event listener for click to display batch report + $('#archiveTable tbody').on('click', 'tr.group-header #batchtool_report_button', function (event) { + event.stopPropagation(); + // Get the parent element + var parentTr = $(this).closest('tr'); + // Retrieve the 'data-name' attribute from the parent + var batch_id = parentTr.data('name'); + display_batch_report(batch_id) + }); + + // Event listener for click to delete batch + $('#archiveTable tbody').on('click', 'tr.group-header #batchtool_delete_button', function (event) { + event.stopPropagation(); + // Get the parent element + var parentTr = $(this).closest('tr'); + // Retrieve the 'data-name' attribute from the parent + var batch_id = parentTr.data('name'); + $('#batch_id_del').val(batch_id); + $('#listofids').html(""); + window.$('#delModalBatch').modal('show'); + }); + + function display_batch_report(batch_id) { //var imageUrl = '/media/report_'+data.id+".png"; // Replace with your logic to get image URL - var imageUrl = '/media/basic/'+data.batch_id+'.png'; // Replace with your logic to get image URL + var imageUrl = '/media/basic/'+batch_id+'.png'; // Replace with your logic to get image URL console.log(imageUrl) display_image(imageUrl) - } - }); + } // $('#archiveTable tbody').on('mouseleave', 'td:nth-child(2)', function () { // $('#imagePreview').hide(); @@ -555,20 +581,17 @@ $(document).ready(function () { //delete batch modal $("#delModalBatch").on('submit','#delFormBatch', function(event){ event.preventDefault(); - row = archiveRecords.row('.selected').data(); - if (row == undefined || row.batch_id == undefined) { - return - } + batch_id = $('#batch_id_del').val(); $('#deletebatch').attr('disabled', 'disabled'); $.ajax({ - url:"/archived_runners/batch/"+row.batch_id, + url:"/archived_runners/batch/"+batch_id, beforeSend: function (xhr) { xhr.setRequestHeader('X-API-Key', API_KEY); }, method:"DELETE", contentType: "application/json", dataType: "json", - data: JSON.stringify(row.batch_id), + data: JSON.stringify(batch_id), success:function(data){ $('#delFormBatch')[0].reset(); window.$('#delModalBatch').modal('hide'); @@ -959,8 +982,20 @@ var archiveRecords = paging: true, processing: true, serverSide: true, - columnDefs: [{ - targets: [0,1,17], + columnDefs: [ + { + targets: 1, + render: function ( data, type, row ) { + if (type === 'display') { + console.log("arch") + var color = getColorForId(data); + return '
'+data+'
'; + } + return data; + }, + }, + { + targets: [0,17], render: function ( data, type, row ) { if (!data) return data return '
'+data+'' @@ -1155,6 +1190,7 @@ var archiveRecords = var period = ''; var profit = ''; var started = null; + var stratinId = null; // // Process each item only once // archiveRecords.rows({ search: 'applied' }).every(function (rowIdx, tableLoop, rowLoop) { @@ -1188,7 +1224,8 @@ var archiveRecords = profit = firstRowData.metrics.profit.batch_sum_profit; period = firstRowData.note ? firstRowData.note.substring(0, 14) : ''; started = firstRowData.started - var newBatchHeader = {batch_id:group, profit:profit, itemCount:itemCount, period:period, started:started} + stratinId = firstRowData.strat_id + var newBatchHeader = {batch_id:group, profit:profit, itemCount:itemCount, period:period, started:started, stratinId:stratinId} batchHeaders.push(newBatchHeader) } //uz je v poli, ale mame novejsi (pribyl v ramci backtestu napr.) - updatujeme @@ -1197,6 +1234,7 @@ var archiveRecords = profit = firstRowData.metrics.profit.batch_sum_profit; period = firstRowData.note ? firstRowData.note.substring(0, 14) : ''; started = firstRowData.started + stratinId = firstRowData.id existingBatch.itemCount = itemCount; existingBatch.profit = profit; existingBatch.period = period; @@ -1208,6 +1246,7 @@ var archiveRecords = itemCount = existingBatch.itemCount period = existingBatch.period started = existingBatch.started + stratinId = existingBatch.stratinId } } @@ -1215,9 +1254,15 @@ var archiveRecords = // Construct the GROUP HEADER - sem pripadna tlačítka atp. //var groupHeaderContent = '' + (group ? 'Batch ID: ' + group : 'No Batch') + ''; - var groupHeaderContent = '' + (group ? 'Batch ID: ' + group : 'No Batch')+''; + var tools = '' + if (group) { + tools += 'lab_profile' + tools += 'delete' + } + //console.log(group, groupId, stratinId) + var groupHeaderContent = ''+(group ? 'Batch ID: ' + group: 'No Batch')+''; groupHeaderContent += (group ? ' (' + itemCount + ')' + ' ' + period + ' Profit: ' + profit + '' : ''); - + groupHeaderContent += group ? tools : "" return $('') .append('' + groupHeaderContent + '') .attr('data-name', groupId) diff --git a/v2realbot/static/js/mytables.js b/v2realbot/static/js/mytables.js index 1a1a3ad..50642e0 100644 --- a/v2realbot/static/js/mytables.js +++ b/v2realbot/static/js/mytables.js @@ -747,6 +747,48 @@ $(document).ready(function () { } ); +//section for color of stratins +// Function to generate a color from an ID +// function generateColor(id) { +// var hash = 0; +// for (var i = 0; i < id.length; i++) { +// hash = id.charCodeAt(i) + ((hash << 5) - hash); +// } + +// // Convert hash to HSL (Hue, Saturation, Lightness) +// var hue = hash % 360; // Hue (0-360) +// var saturation = 70; // Saturation (percentage) +// var lightness = 30; // Lightness (percentage) + +// // Convert HSL to RGB, then to hex (optional) +// return `hsl(${hue}, ${saturation}%, ${lightness}%)`; +// } + +//version of generateColor that randomly picks from array of colors +function generateColor(id) { + var randomIndex = Math.floor(Math.random() * colors.length); + return colors[randomIndex]; +} + +// Function to get color for an ID, from localStorage or generate a new one +function getColorForId(id) { + //temp generate always new + var color = null; + var color = localStorage.getItem('color-' + id); + if (!color) { + color = generateColor(id); + localStorage.setItem('color-' + id, color); + } + return color; +} + +function deleteColor(id) { + var key = 'color-' + id; + if (localStorage.getItem(key)) { + localStorage.removeItem(key); + } +} + //stratin table var stratinRecords = @@ -779,6 +821,10 @@ var stratinRecords = ], paging: true, processing: false, + // rowCallback: function(row, data, index) { + // var color = getColorForId(data.id); // Assuming 'id' is the identifier in your data + // $(row).css('color', color); + // }, columnDefs: [{ targets: 12, render: function ( data, type, row ) { @@ -789,7 +835,13 @@ var stratinRecords = { targets: 0, render: function ( data, type, row ) { - return '
'+data+'' + if (type === 'display') { + //console.log("stratin") + var color = getColorForId(data); + //style="color:' + color + ';" + return '
'+data+'
'; + } + return data; }, }, { @@ -1193,7 +1245,8 @@ $("#delModal").on('submit','#delForm', function(event){ method:"DELETE", contentType: "application/json", dataType: "json", - success:function(data){ + success:function(data){ + deleteColor(formData.delid) $('#delForm')[0].reset(); window.$('#delModal').modal('hide'); $('#delete').attr('disabled', false); diff --git a/v2realbot/static/js/utils.js b/v2realbot/static/js/utils.js index c7b6949..4ba77be 100644 --- a/v2realbot/static/js/utils.js +++ b/v2realbot/static/js/utils.js @@ -137,6 +137,7 @@ function initialize_statusheader() { // Create the grid table var gridTable = document.getElementById('statusHeaderTool'); + gridTable.style.display = 'flex'; var cntid = 0 @@ -330,8 +331,8 @@ function initialize_chart() { //var chartOptions = { width: 1045, height: 600, leftPriceScale: {visible: true}} //TMAVY MOD - var chartOptions = { width: 1280, - height: 600, + var chartOptions = { width: 1024, + height: 480, leftPriceScale: {visible: true}, layout: { background: { @@ -556,14 +557,14 @@ function profitLineToggle() { //togle go wide function toggleWide() { - width = 2000; + width = 1600; const elem = document.getElementById("goWide"); const msgContainer = document.getElementById("msgContainer"); const msgContainerInner = document.getElementById("msgContainerInner"); const clrButton = document.getElementById("clrButton"); if (elem.classList.contains("switcher-active-item")) { - width = 1080; + width = 1024; msgContainer.removeAttribute("style"); msgContainerInner.removeAttribute("style"); clrButton.removeAttribute("style"); diff --git a/v2realbot/static/main.css b/v2realbot/static/main.css index 9425c89..5952cba 100644 --- a/v2realbot/static/main.css +++ b/v2realbot/static/main.css @@ -20,6 +20,23 @@ overflow: visible; } +.tool-icon { + margin-right: 0px; + vertical-align: middle; + font-size: 19px; + color: var(--bs-secondary); + border-radius: 4px; + padding: 2px; +} + +.tool-icon:hover { + background-color: var(--bs-info-text-emphasis); + color: var(--bs-dark-bg-subtle); + cursor: pointer; + border-radius: 4px; + padding: 2px; +} + .pagination { --bs-pagination-padding-x: 0.45rem; --bs-pagination-padding-y: 0.15rem; @@ -46,7 +63,23 @@ list-style: none; } +strong { + font-weight: normal; +} + +.line { + /* font-family: 'Roboto Mono', monospace; + font-size: 11px; */ + font-family: 'Fira Code', 'Roboto Mono', monospace; + font-size: 11px; /* Adjust size as necessary */ + line-height: 1.3; /* This increases the line spacing */ +} + [data-bs-theme=dark] { + --bs-font-sans-serif: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --bs-body-line-height: 1.3; + --bs-body-font-size: 1.0rem; + --bs-body-font-weight: 300; color-scheme: dark; --bs-body-color: #787b86; --bs-body-color-rgb: 173,181,189; @@ -135,7 +168,7 @@ tbody, td, tfoot, th, thead, tr { .tdmetrics { overflow: hidden; text-overflow: ellipsis; - width: 132px; + width: 154px; white-space: nowrap; font-size: x-small; } @@ -213,28 +246,40 @@ table.dataTable thead>tr>th.sorting_asc:before, table.dataTable thead>tr>th.sort transform: translate(-50%, -50%); } +.color-tag { + height: 10px; + width: 10px; + display: inline-block; + border-radius: 50%; + margin-right: 5px; + vertical-align: middle; +} .group-header { - /* cursor: pointer; */ + cursor: pointer; background-color: #f2f2f2; /* Light gray background */ color: #b2b2b2; /* Dark text for contrast */ - font-weight: bold; + /* font-weight: bold; */ } .group-header .batchheader-profit-info { color: #3e999e; /* Highlight profit info */ - font-weight: bold; + /* font-weight: bold; */ } .group-header .batchheader-count-info { color: #a1a1a1; /* Highlight count info */ - font-weight: bold; + /* font-weight: bold; */ } +.group-header .batchheader-batch-id { + color: #a1a1a1; /* Highlight period info */ + /* font-weight: bold; */ +} .group-header .batchheader-period-info { color: #a1a1a1; /* Highlight period info */ - font-weight: bold; + /* font-weight: bold; */ } .group-header strong { @@ -324,7 +369,9 @@ html { position: absolute; color: #050505; left: 100px; - top: 195px; + top: 100px; + /* po zapnuti statusHeaderToolbar prepnout na */ + /* top: 195px; */ z-index: 1; font-size: 12px; line-height: 18px; @@ -350,7 +397,7 @@ html { .msgContainerInner { display: flex; overflow: auto; - height: 568px; + height: 480px; flex-direction: column-reverse; margin-left: 14px; width: 100%; @@ -358,8 +405,8 @@ html { #msgContainer { display: inline-block; /* overflow: auto; */ - height: 600px; - width: 40%; + height: 480px; + width: 35%; } } @@ -367,7 +414,7 @@ html { .msgContainerInner { display: flex; overflow: auto; - height: 568px; + height: 480px; flex-direction: column-reverse; margin-left: 14px; width: 130%; @@ -375,7 +422,7 @@ html { #msgContainer { display: inline-block; /* overflow: auto; */ - height: 600px; + height: 480px; width: 750px; } } @@ -436,10 +483,8 @@ pre { } #statusHeaderTool { + display: none; margin-left: 0px; - font-size: normal; - /* font-weight: bold; */ - display: flex; /* background-color: #dfe4e6; */ /* color: white; */ padding: 1px; @@ -503,7 +548,7 @@ pre { text-decoration: double; display: inline-block; padding: 1px 6px; - font-size: 14px; + /* font-size: 14px; */ /* color: #262b3e; */ /* background-color: #818581; */ background-color: #0202022e; @@ -578,7 +623,7 @@ pre { text-decoration: double; display: inline-block; padding: 1px 6px; - font-size: 14px; + /* font-size: 14px; */ /* color: #262b3e; */ /* background-color: #818581; */ background-color: #0202022e;