From 64a4ce7bdc2bef64a302513bb9f8784b8a4179d3 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 14 Jul 2019 13:46:15 +0200 Subject: [PATCH] All kind of improvements on pannels, including extended simulation panel --- Project.njsproj | 3 + SimulationExecution.js | 673 +++++++++++++++++++----------------- SimulationExecutionPanel.js | 452 ++++++++++++++++++++++++ TradingSimulation.js | 10 +- TradingSimulationPanel.js | 150 +++++--- this.plotter.config.json | 5 + 6 files changed, 935 insertions(+), 358 deletions(-) create mode 100644 SimulationExecutionPanel.js diff --git a/Project.njsproj b/Project.njsproj index 15b8f293a..3551d717d 100644 --- a/Project.njsproj +++ b/Project.njsproj @@ -23,6 +23,9 @@ Code + + Code + Code diff --git a/SimulationExecution.js b/SimulationExecution.js index a0e3fb0ff..b21c05248 100644 --- a/SimulationExecution.js +++ b/SimulationExecution.js @@ -17,16 +17,7 @@ setTimePeriod: setTimePeriod, setDatetime: setDatetime, recalculateScale: recalculateScale, - draw: draw, - payload: { - profile: { - position: { - x: 0, - y: 0 - }, - visible: false - } - } + draw: draw }; /* this is part of the module template */ @@ -173,7 +164,7 @@ const ONE_MIN_IN_MILISECONDS = 60 * 1000; let step = timePeriod / ONE_MIN_IN_MILISECONDS; - step = 1; // For now we dont discard records depending on the zoom level. + step = 1; // For now we dont discard records depending on the zoom level. let i = 0; let lastRecordPushed = 0; @@ -198,7 +189,8 @@ profitsAssetA: file[i][11], profitsAssetB: file[i][12], combinedProfitsA: file[i][13], - combinedProfitsB: file[i][14] + combinedProfitsB: file[i][14], + datetime: file[i][0] }; /* Finally we add this History Record to the Array */ @@ -208,40 +200,40 @@ /* Here we build the lines. */ - if (timePeriod <= 1 * 60 * 1000) { + //if (timePeriod <= 1 * 60 * 1000) { - if (newHistoryRecord.lastSellRate > 0) { - lastSellRate = newHistoryRecord.lastSellRate; - lastSellDate = newHistoryRecord.date; - } - - if (newHistoryRecord.sellExecRate > 0) { - let newLine = { - type: "sell", - x1: lastSellDate, - y1: lastSellRate, - x2: newHistoryRecord.date, - y2: newHistoryRecord.sellExecRate - }; - lines.push(newLine); - } - - if (newHistoryRecord.lastBuyRate > 0) { - lastBuyRate = newHistoryRecord.lastBuyRate; - lastBuyDate = newHistoryRecord.date; - } - - if (newHistoryRecord.buyExecRate > 0) { - let newLine = { - type: "buy", - x1: lastBuyDate, - y1: lastBuyRate, - x2: newHistoryRecord.date, - y2: newHistoryRecord.buyExecRate - }; - lines.push(newLine); - } + if (newHistoryRecord.lastSellRate > 0) { + lastSellRate = newHistoryRecord.lastSellRate; + lastSellDate = newHistoryRecord.date; } + + if (newHistoryRecord.sellExecRate > 0) { + let newLine = { + type: "sell", + x1: lastSellDate, + y1: lastSellRate, + x2: newHistoryRecord.date, + y2: newHistoryRecord.sellExecRate + }; + lines.push(newLine); + } + + if (newHistoryRecord.lastBuyRate > 0) { + lastBuyRate = newHistoryRecord.lastBuyRate; + lastBuyDate = newHistoryRecord.date; + } + + if (newHistoryRecord.buyExecRate > 0) { + let newLine = { + type: "buy", + x1: lastBuyDate, + y1: lastBuyRate, + x2: newHistoryRecord.date, + y2: newHistoryRecord.buyExecRate + }; + lines.push(newLine); + } + //} } /* We allways want to put the last record of the file on the filterd dataset, so as to allways show the latest advance of the bot. */ @@ -276,8 +268,6 @@ } - /* Second we process the text */ - for (let i = 0; i < file.length; i++) { let newHistoryRecord = { @@ -343,11 +333,16 @@ } function draw() { - plotChart(); + plotChart(); } function plotChart() { try { + + let userPosition = getUserPosition() + let userPositionDate = userPosition.point.x + let currentRecord + let point = { x: 0, y: 0 @@ -362,8 +357,9 @@ for (let i = 0; i < history.length; i++) { record = history[i]; + currentRecord = record - let timestamp = Math.trunc(record.date / timePeriod) * timePeriod + timePeriod / 2; + let timestamp = record.date // Math.trunc(record.date / timePeriod) * timePeriod + timePeriod / 2; point = { x: timestamp, @@ -379,30 +375,323 @@ let isCurrentRecord = false; - if (datetime !== undefined) { - let dateValue = datetime.valueOf(); - if (dateValue >= record.date - timePeriod / 2 && dateValue <= record.date + timePeriod / 2 - 1) { - isCurrentRecord = true; - } + if (userPositionDate >= record.date - 30000 && userPositionDate <= record.date + 30000 - 1) { + isCurrentRecord = true; } - let radius = 3; + let opacity = '1'; + let currentRadius = 10 - let opacity = '0.2'; + /* Draw a red inverted triangle on exec sell */ + if (record.sellExecRate > 0) { - browserCanvasContext.lineWidth = 1; + opacity = '1'; + + let normalSize = 5 + let extraSize = 0 + if (isCurrentRecord) { extraSize = 5 } + + let point1 = { + x: record.date, + y: record.sellExecRate + }; + + let point2 = { + x: record.date + timePeriod / 7 * (normalSize + extraSize), + y: record.sellExecRate + }; + + let point3 = { + x: record.date - timePeriod / 7 * (normalSize + extraSize), + y: record.sellExecRate + }; + + point1 = timeLineCoordinateSystem.transformThisPoint(point1); + point1 = transformThisPoint(point1, thisObject.container); + point1 = viewPort.fitIntoVisibleArea(point1); + + point2 = timeLineCoordinateSystem.transformThisPoint(point2); + point2 = transformThisPoint(point2, thisObject.container); + point2 = viewPort.fitIntoVisibleArea(point2); + + point3 = timeLineCoordinateSystem.transformThisPoint(point3); + point3 = transformThisPoint(point3, thisObject.container); + point3 = viewPort.fitIntoVisibleArea(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y - diff; + point3.y = point3.y - diff; + + currentRecord.timePeriod = diff + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')'; + + if (isCurrentRecord === false) { + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + opacity + ')'; + } else { + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */ + } + + browserCanvasContext.fill(); + + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.stroke(); + + } + + /* Draw a green triangle on exec buy */ + if (record.buyExecRate > 0) { + + opacity = '1'; + + let normalSize = 5 + let extraSize = 0 + if (isCurrentRecord) { extraSize = 5 } + + let point1 = { + x: record.date, + y: record.buyExecRate + }; + + let point2 = { + x: record.date + timePeriod / 7 * (normalSize + extraSize), + y: record.buyExecRate + }; + + let point3 = { + x: record.date - timePeriod / 7 * (normalSize + extraSize), + y: record.buyExecRate + }; + + point1 = timeLineCoordinateSystem.transformThisPoint(point1); + point1 = transformThisPoint(point1, thisObject.container); + point1 = viewPort.fitIntoVisibleArea(point1); + + point2 = timeLineCoordinateSystem.transformThisPoint(point2); + point2 = transformThisPoint(point2, thisObject.container); + point2 = viewPort.fitIntoVisibleArea(point2); + + point3 = timeLineCoordinateSystem.transformThisPoint(point3); + point3 = transformThisPoint(point3, thisObject.container); + point3 = viewPort.fitIntoVisibleArea(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y + diff; + point3.y = point3.y + diff; + + currentRecord.timePeriod = diff + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + opacity + ')'; + + if (isCurrentRecord === false) { + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + opacity + ')'; + } else { + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */ + } + + browserCanvasContext.fill(); + + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.stroke(); + } + + /* Draw a red inverted triangle on sell */ + if (record.lastSellRate > 0) { + opacity = '1'; + + let normalSize = 5 + let extraSize = 0 + if (isCurrentRecord) { extraSize = 5 } + + let point1 = { + x: record.date, + y: record.lastSellRate + }; + + let point2 = { + x: record.date + timePeriod / 7 * (normalSize + extraSize), + y: record.lastSellRate + }; + + let point3 = { + x: record.date - timePeriod / 7 * (normalSize + extraSize), + y: record.lastSellRate + }; + + point1 = timeLineCoordinateSystem.transformThisPoint(point1); + point1 = transformThisPoint(point1, thisObject.container); + point1 = viewPort.fitIntoVisibleArea(point1); + + point2 = timeLineCoordinateSystem.transformThisPoint(point2); + point2 = transformThisPoint(point2, thisObject.container); + point2 = viewPort.fitIntoVisibleArea(point2); + + point3 = timeLineCoordinateSystem.transformThisPoint(point3); + point3 = transformThisPoint(point3, thisObject.container); + point3 = viewPort.fitIntoVisibleArea(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y - diff; + point3.y = point3.y - diff; + + currentRecord.timePeriod = diff + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + if (isCurrentRecord === false) { + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ')'; + } else { + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */ + } + + browserCanvasContext.fill(); + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + opacity + ')'; + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.stroke(); + } + + /* Draw a green triangle on buy */ + if (record.lastBuyRate > 0) { + + opacity = '1'; + + let normalSize = 5 + let extraSize = 0 + if (isCurrentRecord) { extraSize = 5 } + + let point1 = { + x: record.date, + y: record.lastBuyRate + }; + + let point2 = { + x: record.date + timePeriod / 7 * (normalSize + extraSize), + y: record.lastBuyRate + }; + + let point3 = { + x: record.date - timePeriod / 7 * (normalSize + extraSize), + y: record.lastBuyRate + }; + + point1 = timeLineCoordinateSystem.transformThisPoint(point1); + point1 = transformThisPoint(point1, thisObject.container); + point1 = viewPort.fitIntoVisibleArea(point1); + + point2 = timeLineCoordinateSystem.transformThisPoint(point2); + point2 = transformThisPoint(point2, thisObject.container); + point2 = viewPort.fitIntoVisibleArea(point2); + + point3 = timeLineCoordinateSystem.transformThisPoint(point3); + point3 = transformThisPoint(point3, thisObject.container); + point3 = viewPort.fitIntoVisibleArea(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y + diff; + point3.y = point3.y + diff; + + currentRecord.timePeriod = diff + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + if (isCurrentRecord === false) { + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ')'; + } else { + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */ + } + + browserCanvasContext.fill(); + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + opacity + ')'; + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.stroke(); + } + + /* Send the current record to the panel */ + + if (userPositionDate >= record.date - 30000 && userPositionDate < record.date + 30000) { + thisObject.container.eventHandler.raiseEvent("Current Record Changed", currentRecord); + } + + /* Circles */ + + let radius = 2; + currentRadius = 10 + + browserCanvasContext.lineWidth = 0.25; /* Outer Circle */ + if (isCurrentRecord === true) { + + browserCanvasContext.beginPath(); + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')'; + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */ + + browserCanvasContext.arc(point.x, point.y, currentRadius, 0, Math.PI * 2, true); + browserCanvasContext.closePath(); + + if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { + browserCanvasContext.fill(); + } + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.stroke(); + } + + /* Inner Circle */ + browserCanvasContext.beginPath(); - browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', ' + opacity + ')'; + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')'; - if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.LIGHT + ', ' + opacity + ')'; - } else { - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */ - } + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + opacity + ')'; browserCanvasContext.arc(point.x, point.y, radius, 0, Math.PI * 2, true); browserCanvasContext.closePath(); @@ -410,252 +699,9 @@ if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { browserCanvasContext.fill(); } - + browserCanvasContext.setLineDash([0, 0]) browserCanvasContext.stroke(); - /* Draw a red inverted triangle on exec sell */ - - if (record.sellExecRate > 0) { - - opacity = '0.5'; - - let point1 = { - x: record.date, - y: record.sellExecRate - }; - - let point2 = { - x: record.date + timePeriod / 7 * 2, - y: record.sellExecRate - }; - - let point3 = { - x: record.date - timePeriod / 7 * 2, - y: record.sellExecRate - }; - - point1 = timeLineCoordinateSystem.transformThisPoint(point1); - point1 = transformThisPoint(point1, thisObject.container); - point1 = viewPort.fitIntoVisibleArea(point1); - - point2 = timeLineCoordinateSystem.transformThisPoint(point2); - point2 = transformThisPoint(point2, thisObject.container); - point2 = viewPort.fitIntoVisibleArea(point2); - - point3 = timeLineCoordinateSystem.transformThisPoint(point3); - point3 = transformThisPoint(point3, thisObject.container); - point3 = viewPort.fitIntoVisibleArea(point3); - - let diff = point2.x - point3.x; - point2.y = point2.y - diff; - point3.y = point3.y - diff; - - point2 = viewPort.fitIntoVisibleArea(point2); - point3 = viewPort.fitIntoVisibleArea(point3); - - browserCanvasContext.beginPath(); - - browserCanvasContext.moveTo(point1.x, point1.y); - browserCanvasContext.lineTo(point2.x, point2.y); - browserCanvasContext.lineTo(point3.x, point3.y); - browserCanvasContext.lineTo(point1.x, point1.y); - - browserCanvasContext.closePath(); - - if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(219, 18, 18, ' + opacity + ')'; - } else { - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ - } - - browserCanvasContext.fill(); - - browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, ' + opacity + ')'; - browserCanvasContext.stroke(); - - } - - /* Draw a green triangle on exec buy */ - - if (record.buyExecRate > 0) { - - opacity = '0.5'; - - let point1 = { - x: record.date, - y: record.buyExecRate - }; - - let point2 = { - x: record.date + timePeriod / 7 * 2, - y: record.buyExecRate - }; - - let point3 = { - x: record.date - timePeriod / 7 * 2, - y: record.buyExecRate - }; - - point1 = timeLineCoordinateSystem.transformThisPoint(point1); - point1 = transformThisPoint(point1, thisObject.container); - point1 = viewPort.fitIntoVisibleArea(point1); - - point2 = timeLineCoordinateSystem.transformThisPoint(point2); - point2 = transformThisPoint(point2, thisObject.container); - point2 = viewPort.fitIntoVisibleArea(point2); - - point3 = timeLineCoordinateSystem.transformThisPoint(point3); - point3 = transformThisPoint(point3, thisObject.container); - point3 = viewPort.fitIntoVisibleArea(point3); - - let diff = point2.x - point3.x; - point2.y = point2.y + diff; - point3.y = point3.y + diff; - - point2 = viewPort.fitIntoVisibleArea(point2); - point3 = viewPort.fitIntoVisibleArea(point3); - - browserCanvasContext.beginPath(); - - browserCanvasContext.moveTo(point1.x, point1.y); - browserCanvasContext.lineTo(point2.x, point2.y); - browserCanvasContext.lineTo(point3.x, point3.y); - browserCanvasContext.lineTo(point1.x, point1.y); - - browserCanvasContext.closePath(); - - if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(64, 217, 26, ' + opacity + ')'; - } else { - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ - } - - browserCanvasContext.fill(); - - browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; - browserCanvasContext.stroke(); - } - - /* Draw a red inverted triangle on sell */ - if (record.lastSellRate > 0) { - opacity = '0.5'; - - let point1 = { - x: record.date, - y: record.lastSellRate - }; - - let point2 = { - x: record.date + timePeriod / 7 * 2, - y: record.lastSellRate - }; - - let point3 = { - x: record.date - timePeriod / 7 * 2, - y: record.lastSellRate - }; - - point1 = timeLineCoordinateSystem.transformThisPoint(point1); - point1 = transformThisPoint(point1, thisObject.container); - point1 = viewPort.fitIntoVisibleArea(point1); - - point2 = timeLineCoordinateSystem.transformThisPoint(point2); - point2 = transformThisPoint(point2, thisObject.container); - point2 = viewPort.fitIntoVisibleArea(point2); - - point3 = timeLineCoordinateSystem.transformThisPoint(point3); - point3 = transformThisPoint(point3, thisObject.container); - point3 = viewPort.fitIntoVisibleArea(point3); - - let diff = point2.x - point3.x; - point2.y = point2.y - diff; - point3.y = point3.y - diff; - - point2 = viewPort.fitIntoVisibleArea(point2); - point3 = viewPort.fitIntoVisibleArea(point3); - - browserCanvasContext.beginPath(); - - browserCanvasContext.moveTo(point1.x, point1.y); - browserCanvasContext.lineTo(point2.x, point2.y); - browserCanvasContext.lineTo(point3.x, point3.y); - browserCanvasContext.lineTo(point1.x, point1.y); - - browserCanvasContext.closePath(); - - if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(255, 255, 255, ' + opacity + ')'; - } else { - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ - } - - browserCanvasContext.fill(); - - browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, ' + opacity + ')'; - browserCanvasContext.stroke(); - - } - - /* Draw a green triangle on buy */ - if (record.lastBuyRate > 0) { - - opacity = '0.5'; - - let point1 = { - x: record.date, - y: record.lastBuyRate - }; - - let point2 = { - x: record.date + timePeriod / 7 * 2, - y: record.lastBuyRate - }; - - let point3 = { - x: record.date - timePeriod / 7 * 2, - y: record.lastBuyRate - }; - - point1 = timeLineCoordinateSystem.transformThisPoint(point1); - point1 = transformThisPoint(point1, thisObject.container); - point1 = viewPort.fitIntoVisibleArea(point1); - - point2 = timeLineCoordinateSystem.transformThisPoint(point2); - point2 = transformThisPoint(point2, thisObject.container); - point2 = viewPort.fitIntoVisibleArea(point2); - - point3 = timeLineCoordinateSystem.transformThisPoint(point3); - point3 = transformThisPoint(point3, thisObject.container); - point3 = viewPort.fitIntoVisibleArea(point3); - - let diff = point2.x - point3.x; - point2.y = point2.y + diff; - point3.y = point3.y + diff; - - point2 = viewPort.fitIntoVisibleArea(point2); - point3 = viewPort.fitIntoVisibleArea(point3); - - browserCanvasContext.beginPath(); - - browserCanvasContext.moveTo(point1.x, point1.y); - browserCanvasContext.lineTo(point2.x, point2.y); - browserCanvasContext.lineTo(point3.x, point3.y); - browserCanvasContext.lineTo(point1.x, point1.y); - - browserCanvasContext.closePath(); - - if (isCurrentRecord === false) { - browserCanvasContext.fillStyle = 'rgba(255, 255, 255, ' + opacity + ')'; - } else { - browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */ - } - - browserCanvasContext.fill(); - - browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; - browserCanvasContext.stroke(); - - } } /* Draw the lines connecting plot elements. */ @@ -665,7 +711,7 @@ let line = lines[i]; - opacity = '0.2'; + opacity = '1'; let point1 = { x: line.x1, @@ -693,12 +739,14 @@ browserCanvasContext.closePath(); if (line.type === "sell") { - browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, ' + opacity + ')'; + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + opacity + ')'; } else { - browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + opacity + ')'; + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + opacity + ')'; } browserCanvasContext.stroke(); } + + } } catch (err) { if (ERROR_LOG === true) { logger.write("[ERROR] ' + MODULE_NAME + ' -> plotChart -> err = " + err.stack); } @@ -706,3 +754,10 @@ } } + + + + + + + diff --git a/SimulationExecutionPanel.js b/SimulationExecutionPanel.js new file mode 100644 index 000000000..8dd3cc1f1 --- /dev/null +++ b/SimulationExecutionPanel.js @@ -0,0 +1,452 @@ + +function newAAMastersPlottersTradingSimulationSimulationExecutionSimulationExecutionPanel() { + + + let thisObject = { + fitFunction: undefined, + container: undefined, + onEventRaised: onEventRaised, + draw: draw, + getContainer: getContainer, + initialize: initialize + }; + + let container = newContainer(); + container.initialize(); + thisObject.container = container; + + container.displacement.containerName = "Trading Execution"; + container.frame.containerName = "Trading Execution"; + + let currentRecord; + let panelTabButton + + return thisObject; + + function initialize() { + + thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL; + thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL * 2; + + thisObject.container.frame.position.x = viewPort.visibleArea.topLeft.x + thisObject.container.frame.width * 4; + thisObject.container.frame.position.y = viewPort.visibleArea.topRight.y; + + panelTabButton = newPanelTabButton() + panelTabButton.parentContainer = thisObject.container + panelTabButton.container.frame.parentFrame = thisObject.container.frame + panelTabButton.fitFunction = thisObject.fitFunction + panelTabButton.initialize() + } + + function getContainer(point) { + + let container; + + container = panelTabButton.getContainer(point) + if (container !== undefined) { return container } + + if (thisObject.container.frame.isThisPointHere(point, true) === true) { + + let checkPoint = { + x: point.x, + y: point.y + } + + checkPoint = thisObject.fitFunction(checkPoint) + + if (point.x === checkPoint.x && point.y === checkPoint.y) { + return thisObject.container; + } + } + } + + + function onEventRaised(lastCurrentCandle) { + + currentRecord = lastCurrentCandle; + + } + + + function draw() { + + thisObject.container.frame.draw(false, false, true, thisObject.fitFunction); + + plot(); + + panelTabButton.draw() + + } + + + function plot() { + + if (currentRecord === undefined) { return; } + + const frameBodyHeight = thisObject.container.frame.getBodyHeight(); + const frameTitleHeight = thisObject.container.frame.height - frameBodyHeight; + + const X_AXIS = thisObject.container.frame.width / 2; + const Y_AXIS = frameTitleHeight + frameBodyHeight / 2; + + record = currentRecord + + point = { + x: X_AXIS, + y: Y_AXIS + }; + + point = thisObject.container.frame.frameThisPoint(point); + point = thisObject.fitFunction(point); + + let isCurrentRecord = true; + + let radius = 2; + let currentRadius = 10 + let opacity = '1'; + + /* Draw a red inverted triangle on exec sell */ + if (record.sellExecRate > 0) { + + opacity = '1'; + + let point1 = { + x: X_AXIS, + y: Y_AXIS + }; + + let point2 = { + x: X_AXIS + record.timePeriod / 4, + y: Y_AXIS + }; + + let point3 = { + x: X_AXIS - record.timePeriod / 4, + y: Y_AXIS + }; + + point1 = thisObject.container.frame.frameThisPoint(point1); + point1 = thisObject.fitFunction(point1); + + point2 = thisObject.container.frame.frameThisPoint(point2); + point2 = thisObject.fitFunction(point2); + + point3 = thisObject.container.frame.frameThisPoint(point3); + point3 = thisObject.fitFunction(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y - diff; + point3.y = point3.y - diff; + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')'; + + if (isCurrentRecord === false) { + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + opacity + ')'; + } else { + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */ + } + + browserCanvasContext.fill(); + + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.stroke(); + + } + + /* Draw a green triangle on exec buy */ + if (record.buyExecRate > 0) { + + opacity = '1'; + + let point1 = { + x: X_AXIS, + y: Y_AXIS + }; + + let point2 = { + x: X_AXIS + record.timePeriod / 4, + y: Y_AXIS + }; + + let point3 = { + x: X_AXIS - record.timePeriod / 4, + y: Y_AXIS + }; + + point1 = thisObject.container.frame.frameThisPoint(point1); + point1 = thisObject.fitFunction(point1); + + point2 = thisObject.container.frame.frameThisPoint(point2); + point2 = thisObject.fitFunction(point2); + + point3 = thisObject.container.frame.frameThisPoint(point3); + point3 = thisObject.fitFunction(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y + diff; + point3.y = point3.y + diff; + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + opacity + ')'; + + if (isCurrentRecord === false) { + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + opacity + ')'; + } else { + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */ + } + + browserCanvasContext.fill(); + + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.stroke(); + } + + /* Draw a red inverted triangle on sell */ + if (record.lastSellRate > 0) { + opacity = '1'; + + let point1 = { + x: X_AXIS, + y: Y_AXIS + }; + + let point2 = { + x: X_AXIS + record.timePeriod / 4, + y: Y_AXIS + }; + + let point3 = { + x: X_AXIS - record.timePeriod / 4, + y: Y_AXIS + }; + + point1 = thisObject.container.frame.frameThisPoint(point1); + point1 = thisObject.fitFunction(point1); + + point2 = thisObject.container.frame.frameThisPoint(point2); + point2 = thisObject.fitFunction(point2); + + point3 = thisObject.container.frame.frameThisPoint(point3); + point3 = thisObject.fitFunction(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y - diff; + point3.y = point3.y - diff; + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + if (isCurrentRecord === false) { + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ')'; + } else { + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */ + } + + browserCanvasContext.fill(); + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + opacity + ')'; + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.stroke(); + } + + /* Draw a green triangle on buy */ + if (record.lastBuyRate > 0) { + + opacity = '1'; + + let point1 = { + x: X_AXIS, + y: Y_AXIS + }; + + let point2 = { + x: X_AXIS + record.timePeriod / 4, + y: Y_AXIS + }; + + let point3 = { + x: X_AXIS - record.timePeriod / 4, + y: Y_AXIS + }; + + point1 = thisObject.container.frame.frameThisPoint(point1); + point1 = thisObject.fitFunction(point1); + + point2 = thisObject.container.frame.frameThisPoint(point2); + point2 = thisObject.fitFunction(point2); + + point3 = thisObject.container.frame.frameThisPoint(point3); + point3 = thisObject.fitFunction(point3); + + let diff = point2.x - point3.x; + point2.y = point2.y + diff; + point3.y = point3.y + diff; + + point2 = viewPort.fitIntoVisibleArea(point2); + point3 = viewPort.fitIntoVisibleArea(point3); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(point1.x, point1.y); + browserCanvasContext.lineTo(point2.x, point2.y); + browserCanvasContext.lineTo(point3.x, point3.y); + browserCanvasContext.lineTo(point1.x, point1.y); + + browserCanvasContext.closePath(); + + if (isCurrentRecord === false) { + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ')'; + } else { + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */ + } + + browserCanvasContext.fill(); + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + opacity + ')'; + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.stroke(); + } + + browserCanvasContext.lineWidth = 0.25; + + /* Outer Circle */ + + if (isCurrentRecord === true) { + + browserCanvasContext.beginPath(); + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')'; + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */ + + browserCanvasContext.arc(point.x, point.y, currentRadius, 0, Math.PI * 2, true); + browserCanvasContext.closePath(); + + if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { + browserCanvasContext.fill(); + } + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.stroke(); + } + + /* Inner Circle */ + + browserCanvasContext.beginPath(); + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')'; + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + opacity + ')'; + + browserCanvasContext.arc(point.x, point.y, radius, 0, Math.PI * 2, true); + browserCanvasContext.closePath(); + + if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else { + browserCanvasContext.fill(); + } + browserCanvasContext.setLineDash([0, 0]) + browserCanvasContext.stroke(); + + /* put the labels */ + + browserCanvasContext.beginPath(); + + let y; + let recordDate = new Date(currentRecord.datetime) + + printLabel('Market Rate', X_AXIS, frameTitleHeight + frameBodyHeight * 0.05 / 2, '1'); + printLabel(currentRecord.marketRate, X_AXIS, frameTitleHeight + frameBodyHeight * 0.10 / 2, '0.50'); + + printLabel('Sell Rate', X_AXIS, frameTitleHeight + frameBodyHeight * 0.15 / 2, '1'); + printLabel(currentRecord.lastSellRate, X_AXIS, frameTitleHeight + frameBodyHeight * 0.20 / 2, '0.50'); + + printLabel('Sell Executed Rate', X_AXIS, frameTitleHeight + frameBodyHeight * 0.25 / 2, '1'); + printLabel(currentRecord.sellExecRate, X_AXIS, frameTitleHeight + frameBodyHeight * 0.30 / 2, '0.50'); + + printLabel('Buy Rate', X_AXIS, frameTitleHeight + frameBodyHeight * 0.35 / 2, '1'); + printLabel(currentRecord.lastBuyRate, X_AXIS, frameTitleHeight + frameBodyHeight * 0.40 / 2, '0.40'); + + printLabel('Buy Executed Rate', X_AXIS, frameTitleHeight + frameBodyHeight * 0.45 / 2, '1'); + printLabel(currentRecord.buyExecRate, X_AXIS, frameTitleHeight + frameBodyHeight * 0.50 / 2, '0.50'); + + printLabel('ROI Asset A', X_AXIS, frameTitleHeight + frameBodyHeight * (1 - 0.25 / 2), '1'); + printLabel((currentRecord.combinedProfitsA).toFixed(2) + '%', X_AXIS, frameTitleHeight + frameBodyHeight * (1 - 0.30 / 2), '0.50'); + + printLabel('ROI Asset B', X_AXIS, frameTitleHeight + frameBodyHeight * (1 - 0.15 / 2), '1'); + printLabel((currentRecord.combinedProfitsB).toFixed(2) + '%', X_AXIS, frameTitleHeight + frameBodyHeight * (1 - 0.20 / 2), '0.50'); + + printLabel('Datetime', X_AXIS, frameTitleHeight + frameBodyHeight * (1 - 0.05 / 2), '1'); + printLabel(recordDate.toUTCString(), X_AXIS, frameTitleHeight + frameBodyHeight * (1 - 0.1 / 2), '0.50'); + + + function printLabel(labelToPrint, x, y, opacity) { + + let labelPoint; + let fontSize = 10; + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.SECONDARY + ' Saira'; + + let label = '' + labelToPrint; + if (isNaN(label) === false) { + label = Number(label).toLocaleString(); + } + let xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO; + + labelPoint = { + x: x - xOffset, + y: y + }; + + labelPoint = thisObject.container.frame.frameThisPoint(labelPoint); + labelPoint = thisObject.fitFunction(labelPoint) + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', ' + opacity + ')'; + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y); + + } + + browserCanvasContext.closePath(); + browserCanvasContext.fill(); + + } + + +} + + + + + + + diff --git a/TradingSimulation.js b/TradingSimulation.js index b87de89c5..3182189b1 100644 --- a/TradingSimulation.js +++ b/TradingSimulation.js @@ -513,10 +513,11 @@ if (userPositionDate >= record.begin && userPositionDate <= record.end) { - let currentRecord = { - innerRecord: record + let eventRecords = { + currentRecord: record, + lastRecord: records[records.length - 1] }; - thisObject.container.eventHandler.raiseEvent("Current Record Changed", currentRecord); + thisObject.container.eventHandler.raiseEvent("Current Record Changed", eventRecords); } let stopLossPhase = 0; @@ -549,7 +550,7 @@ let recordPoint4 = { x: record.begin + timePeriod / 7 * 1.5, - y: thisObject.container.frame.height * 3 + y: thisObject.container.frame.height * 100 }; let recordPoint5 = { @@ -851,5 +852,6 @@ + diff --git a/TradingSimulationPanel.js b/TradingSimulationPanel.js index b44a9760b..1f3d5431e 100644 --- a/TradingSimulationPanel.js +++ b/TradingSimulationPanel.js @@ -15,10 +15,11 @@ function newAAMastersPlottersTradingSimulationTradingSimulationTradingSimulation container.initialize(); thisObject.container = container; - container.displacement.containerName = "Simulation"; - container.frame.containerName = "Simulation"; + container.displacement.containerName = "Trading Simulation"; + container.frame.containerName = "Trading Simulation"; let currentRecord; + let lastRecord; let panelTabButton @@ -26,10 +27,10 @@ function newAAMastersPlottersTradingSimulationTradingSimulationTradingSimulation function initialize() { - thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL; + thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL * 2; thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL * 2; - thisObject.container.frame.position.x = viewPort.visibleArea.topRight.x - thisObject.container.frame.width * 1; + thisObject.container.frame.position.x = viewPort.visibleArea.topLeft.x + thisObject.container.frame.width * 1; thisObject.container.frame.position.y = viewPort.visibleArea.topRight.y; panelTabButton = newPanelTabButton() @@ -67,9 +68,10 @@ function newAAMastersPlottersTradingSimulationTradingSimulationTradingSimulation } - function onEventRaised(lastCurrentRecord) { + function onEventRaised(records) { - currentRecord = lastCurrentRecord; + currentRecord = records.currentRecord; + lastRecord = records.lastRecord } @@ -87,7 +89,7 @@ function newAAMastersPlottersTradingSimulationTradingSimulationTradingSimulation function plotCurrentRecordInfo() { if (currentRecord === undefined) { return; } - if (currentRecord.innerRecord === undefined) { return; } + if (lastRecord === undefined) { return; } const frameBodyHeight = thisObject.container.frame.getBodyHeight(); const frameTitleHeight = thisObject.container.frame.height - frameBodyHeight; @@ -105,92 +107,149 @@ function newAAMastersPlottersTradingSimulationTradingSimulationTradingSimulation y = y + increment; y = y + increment; - printLabel('Current Trade', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', 12); + printLabel('Current Trade', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1', 14); y = y + increment; printLabel('Size', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60'); y = y + increment; - printLabel(currentRecord.innerRecord.positionSize, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + printLabel(currentRecord.positionSize, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); y = y + increment; printLabel('Rate', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60'); y = y + increment; - printLabel(currentRecord.innerRecord.sellRate, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + printLabel(currentRecord.sellRate, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); y = y + increment; printLabel('Stop', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60'); y = y + increment; - printLabel(currentRecord.innerRecord.stopLoss, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + printLabel(currentRecord.stopLoss, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); y = y + increment; printLabel('Take Profit', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60'); y = y + increment; - printLabel(currentRecord.innerRecord.takeProfit, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + printLabel(currentRecord.takeProfit, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); y = y + increment; y = y + increment; - printLabel('Latest Trade', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', 12); + printLabel('Latest Trade', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1', 14); y = y + increment; printLabel('Profit / Loss', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60'); y = y + increment; - printLabel(currentRecord.innerRecord.lastTradeProfitLoss, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + printLabel(currentRecord.lastTradeProfitLoss, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); y = y + increment; printLabel('ROI', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60'); y = y + increment; - printLabel((currentRecord.innerRecord.lastTradeROI).toFixed(2) + ' % ', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + printLabel((currentRecord.lastTradeROI).toFixed(2) + ' % ', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + + + let bifurcationLevel = y + y = y + increment; + y = y + increment; + printLabel('Partial Results', X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1', 14); + + y = y + increment; + printLabel('Profit / Loss', X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); + y = y + increment; + printLabel(currentRecord.profit, X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + + y = y + increment; + printLabel('Trades', X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); + y = y + increment; + printLabel(currentRecord.roundtrips, X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + + y = y + increment; + printLabel('Hits', X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); + y = y + increment; + printLabel(currentRecord.hits, X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + + y = y + increment; + printLabel('Fails', X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); + y = y + increment; + printLabel(currentRecord.fails, X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + + y = y + increment; + printLabel('Hit Ratio', X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); + y = y + increment; + printLabel((currentRecord.hitRatio * 100).toFixed(2) + ' %', X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + + y = y + increment; + printLabel('ROI', X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); + y = y + increment; + printLabel((currentRecord.ROI * 100).toFixed(2) + ' %', X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + + y = y + increment; + printLabel('Periods', X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); + y = y + increment; + printLabel(currentRecord.periods, X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + + y = y + increment; + printLabel('Days', X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); + y = y + increment; + printLabel(currentRecord.days, X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + + y = y + increment; + printLabel('Anualized Rate of Return', X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); + y = y + increment; + printLabel((currentRecord.anualizedRateOfReturn * 100).toFixed(2) + ' %', X_AXIS - thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + + + y = bifurcationLevel + y = y + increment; y = y + increment; - printLabel('Totals Accumulated', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', 12); + printLabel('Final Results', X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1', 14); y = y + increment; - printLabel('Profit / Loss', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60'); + printLabel('Profit / Loss', X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); y = y + increment; - printLabel(currentRecord.innerRecord.profit, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + printLabel(lastRecord.profit, X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); y = y + increment; - printLabel('Trades', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60'); + printLabel('Trades', X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); y = y + increment; - printLabel(currentRecord.innerRecord.roundtrips, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + printLabel(lastRecord.roundtrips, X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); y = y + increment; - printLabel('Hits', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60'); + printLabel('Hits', X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); y = y + increment; - printLabel(currentRecord.innerRecord.hits, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + printLabel(lastRecord.hits, X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); y = y + increment; - printLabel('Fails', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60'); + printLabel('Fails', X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); y = y + increment; - printLabel(currentRecord.innerRecord.fails, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + printLabel(lastRecord.fails, X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); y = y + increment; - printLabel('Hit Ratio', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60'); + printLabel('Hit Ratio', X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); y = y + increment; - printLabel((currentRecord.innerRecord.hitRatio * 100).toFixed(2) + ' %', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + printLabel((lastRecord.hitRatio * 100).toFixed(2) + ' %', X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); y = y + increment; - printLabel('ROI', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60'); + printLabel('ROI', X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); y = y + increment; - printLabel((currentRecord.innerRecord.ROI * 100).toFixed(2) + ' %', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + printLabel((lastRecord.ROI * 100).toFixed(2) + ' %', X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); y = y + increment; - printLabel('Periods', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60'); + printLabel('Periods', X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); y = y + increment; - printLabel(currentRecord.innerRecord.periods, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + printLabel(lastRecord.periods, X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); y = y + increment; - printLabel('Days', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60'); + printLabel('Days', X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); y = y + increment; - printLabel(currentRecord.innerRecord.days, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + printLabel(lastRecord.days, X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); y = y + increment; - printLabel('Anualized Rate of Return', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60'); + printLabel('Anualized Rate of Return', X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '0.60'); y = y + increment; - printLabel((currentRecord.innerRecord.anualizedRateOfReturn * 100).toFixed(2) + ' %', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + printLabel((lastRecord.anualizedRateOfReturn * 100).toFixed(2) + ' %', X_AXIS + thisObject.container.frame.width / 4, frameTitleHeight + frameBodyHeight * y, '1.00', 14); + + function printLabel(labelToPrint, x, y, opacity, fontSize) { @@ -226,34 +285,34 @@ function newAAMastersPlottersTradingSimulationTradingSimulationTradingSimulation let paramsArray = [] let positionTaken = false - if (currentRecord.innerRecord.positionSize > 0) { + if (currentRecord.positionSize > 0) { positionTaken = true } params = {} - params.VALUE = currentRecord.innerRecord.balanceA; - params.INIT_VALUE = currentRecord.innerRecord.initialBalanceA - params.MIN_VALUE = currentRecord.innerRecord.minimunBalanceA - params.MAX_VALUE = currentRecord.innerRecord.maximunBalanceA + params.VALUE = currentRecord.balanceA; + params.INIT_VALUE = currentRecord.initialBalanceA + params.MIN_VALUE = currentRecord.minimunBalanceA + params.MAX_VALUE = currentRecord.maximunBalanceA params.ASSET_LABEL = 'Asset A' params.ASSET_NAME = DEFAULT_MARKET.assetB params.LEFT_OFFSET = 100 params.POSITION_TAKEN = positionTaken - params.BASE_ASSET = currentRecord.innerRecord.baseAsset + params.BASE_ASSET = currentRecord.baseAsset params.DECIMALS = 4 paramsArray.push(params) params = {} - params.VALUE = currentRecord.innerRecord.balanceB; - params.MIN_VALUE = currentRecord.innerRecord.minimunBalanceB - params.INIT_VALUE = currentRecord.innerRecord.initialBalanceB - params.MAX_VALUE = currentRecord.innerRecord.maximunBalanceB + params.VALUE = currentRecord.balanceB; + params.MIN_VALUE = currentRecord.minimunBalanceB + params.INIT_VALUE = currentRecord.initialBalanceB + params.MAX_VALUE = currentRecord.maximunBalanceB params.ASSET_LABEL = 'Asset B' params.ASSET_NAME = DEFAULT_MARKET.assetA params.LEFT_OFFSET = 220 params.POSITION_TAKEN = positionTaken - params.BASE_ASSET = currentRecord.innerRecord.baseAsset + params.BASE_ASSET = currentRecord.baseAsset params.DECIMALS = 2 paramsArray.push(params) @@ -281,5 +340,6 @@ function newAAMastersPlottersTradingSimulationTradingSimulationTradingSimulation + diff --git a/this.plotter.config.json b/this.plotter.config.json index 19447d29e..9505e5005 100644 --- a/this.plotter.config.json +++ b/this.plotter.config.json @@ -45,6 +45,11 @@ "description": "Plots Simulation Execution.", "profilePicture": "SimulationExecution.png", "panels": [ + { + "codeName": "SimulationExecutionPanel", + "moduleName": "SimulationExecutionPanel", + "event": "Current Record Changed" + } ] } ]