diff --git a/TradingSimulation.js b/TradingSimulation.js index f6b6c2a61..e61f1d813 100644 --- a/TradingSimulation.js +++ b/TradingSimulation.js @@ -557,6 +557,16 @@ for (let i = 1; i < records.length; i++) { // We do not start in 0 so as to be able to read the previous record i - 1 record = records[i]; + + /* Send the current record to the panel */ + + if (userPositionDate >= record.begin && userPositionDate <= record.end) { + + let currentRecord = { + innerRecord: record + }; + thisObject.container.eventHandler.raiseEvent("Current Record Changed", currentRecord); + } let stopLossPhase = 0; let buyOrderPhase = 0; @@ -728,15 +738,6 @@ printLabel(buyOrderPhase, recordPoint9.x - imageSize * 1 / 3, recordPoint9.y + imageSize * 1.9, '0.9', 8); } - /* Send the current record to the panel */ - - if (userPositionDate >= record.begin && userPositionDate <= record.end) { - - let currentRecord = { - innerRecord: record - }; - thisObject.container.eventHandler.raiseEvent("Current Record Changed", currentRecord); - } } diff --git a/TradingSimulationPanel.js b/TradingSimulationPanel.js index 307922662..0d1bd24f1 100644 --- a/TradingSimulationPanel.js +++ b/TradingSimulationPanel.js @@ -1,7 +1,7 @@  -function newAAMastersPlottersTradingSimulationTradingSimulationTradingSimulationPanel () { +function newAAMastersPlottersTradingSimulationTradingSimulationTradingSimulationPanel() { - var thisObject = { + let thisObject = { onEventRaised: onEventRaised, container: undefined, draw: draw, @@ -9,7 +9,7 @@ function newAAMastersPlottersTradingSimulationTradingSimulationTradingSimulation initialize: initialize }; - var container = newContainer(); + let container = newContainer(); container.initialize(); thisObject.container = container; @@ -18,6 +18,7 @@ function newAAMastersPlottersTradingSimulationTradingSimulationTradingSimulation let currentRecord; let panelTabButton + let controlHandler return thisObject; @@ -33,6 +34,9 @@ function newAAMastersPlottersTradingSimulationTradingSimulationTradingSimulation panelTabButton.parentContainer = thisObject.container panelTabButton.container.frame.parentFrame = thisObject.container.frame panelTabButton.initialize() + + controlHandler = canvas.bottomSpace.createNewControl('Over The Line', drawAssetBalanceUI, 'Global') + } function getContainer(point) { @@ -94,86 +98,76 @@ function newAAMastersPlottersTradingSimulationTradingSimulationTradingSimulation let y = 0; let increment = 0.025; - y = y + increment; - printLabel('Balance A', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1'); - y = y + increment; - printLabel(currentRecord.innerRecord.balanceA, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50',16); - - y = y + increment; - printLabel('Balance B', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1'); - y = y + increment; - printLabel(currentRecord.innerRecord.balanceB, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50',16); - y = y + increment; printLabel('Profit', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1'); y = y + increment; - printLabel(currentRecord.innerRecord.profit, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50',16); + printLabel(currentRecord.innerRecord.profit, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50', 16); y = y + increment; printLabel('Last Profit', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1'); y = y + increment; - printLabel(currentRecord.innerRecord.lastProfit, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50',16); + printLabel(currentRecord.innerRecord.lastProfit, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50', 16); y = y + increment; printLabel('Last Profit %', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1'); y = y + increment; - printLabel((currentRecord.innerRecord.lastProfitPercent).toFixed(2) + ' % ', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50',16); + printLabel((currentRecord.innerRecord.lastProfitPercent).toFixed(2) + ' % ', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50', 16); y = y + increment; printLabel('Rate', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1'); y = y + increment; - printLabel(currentRecord.innerRecord.sellRate, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50',16); + printLabel(currentRecord.innerRecord.sellRate, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50', 16); y = y + increment; printLabel('Stop', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1'); y = y + increment; - printLabel(currentRecord.innerRecord.stopLoss, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50',16); + printLabel(currentRecord.innerRecord.stopLoss, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50', 16); y = y + increment; printLabel('Take Profit', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1'); y = y + increment; - printLabel(currentRecord.innerRecord.buyOrder, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50',16); + printLabel(currentRecord.innerRecord.buyOrder, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50', 16); y = y + increment; printLabel('Trades', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1'); y = y + increment; - printLabel(currentRecord.innerRecord.roundtrips, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50',16); + printLabel(currentRecord.innerRecord.roundtrips, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50', 16); y = y + increment; printLabel('Hits', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1'); y = y + increment; - printLabel(currentRecord.innerRecord.hits, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50',16); + printLabel(currentRecord.innerRecord.hits, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50', 16); y = y + increment; printLabel('Fails', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1'); y = y + increment; - printLabel(currentRecord.innerRecord.fails, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50',16); + printLabel(currentRecord.innerRecord.fails, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50', 16); y = y + increment; printLabel('Hit Ratio', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1'); y = y + increment; - printLabel((currentRecord.innerRecord.hitRatio * 100).toFixed(2) + ' %', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50',16); + printLabel((currentRecord.innerRecord.hitRatio * 100).toFixed(2) + ' %', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50', 16); y = y + increment; printLabel('ROI', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1'); y = y + increment; - printLabel((currentRecord.innerRecord.ROI * 100).toFixed(2) + ' %', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50',16); + printLabel((currentRecord.innerRecord.ROI * 100).toFixed(2) + ' %', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50', 16); y = y + increment; printLabel('Periods', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1'); y = y + increment; - printLabel(currentRecord.innerRecord.periods, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50',16); + printLabel(currentRecord.innerRecord.periods, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50', 16); y = y + increment; printLabel('Days', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1'); y = y + increment; - printLabel(currentRecord.innerRecord.days, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50',16); + printLabel(currentRecord.innerRecord.days, X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50', 16); y = y + increment; printLabel('Anualized Rate of Return', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1'); y = y + increment; - printLabel((currentRecord.innerRecord.anualizedRateOfReturn * 100).toFixed(2) + ' %', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50',16); - + printLabel((currentRecord.innerRecord.anualizedRateOfReturn * 100).toFixed(2) + ' %', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.50', 16); + function printLabel(labelToPrint, x, y, opacity, fontSize) { let labelPoint; @@ -202,8 +196,254 @@ function newAAMastersPlottersTradingSimulationTradingSimulationTradingSimulation browserCanvasContext.closePath(); browserCanvasContext.fill(); + /* Parameters */ + let params + let paramsArray = [] + + params = {} + params.VALUE = currentRecord.innerRecord.balanceA; + params.MIN_VALUE = 0.5 + params.MAX_VALUE = 1 + params.ASSET_LABEL = 'Asset A' + params.ASSET_NAME = DEFAULT_MARKET.assetB + ' ' + params.LEFT_OFFSET = 100 + + paramsArray.push(params) + + params = {} + params.VALUE = currentRecord.innerRecord.balanceB; + params.MIN_VALUE = 0 + params.MAX_VALUE = 6000 + params.ASSET_LABEL = 'Asset B' + params.ASSET_NAME = DEFAULT_MARKET.assetA + ' ' + params.LEFT_OFFSET = 220 + + paramsArray.push(params) + + let control = canvas.bottomSpace.getControl(controlHandler, 'Global') + control.paramsArray = paramsArray + } + function drawAssetBalanceUI(paramsArray) { + drawAssetCircle(paramsArray[0]) + drawAssetCircle(paramsArray[1]) + + let fontSize + let label + let xOffset + let yOffset + + const OPACITY = 1; + + /* We put the params.VALUE in the middle */ + + fontSize = 15; + + browserCanvasContext.font = "bold " + fontSize + 'px ' + UI_FONT.WHITE + ' Saira'; + + label = 'ASSET BALANCES' + + + xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO; + yOffset = -40 + + labelPoint = { + x: viewPort.visibleArea.bottomLeft.x - xOffset + (paramsArray[1].LEFT_OFFSET - paramsArray[0].LEFT_OFFSET) / 2 + paramsArray[0].LEFT_OFFSET - 20, + y: viewPort.visibleArea.bottomLeft.y - yOffset + }; + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')'; + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y); + } + + function drawAssetCircle(params) { + + /* We draw the circle container */ + + const RED_LINE_HIGHT = 5; + const RADIOUS = 50; + const OPACITY = 1; + + let centerPoint = { + x: viewPort.visibleArea.bottomLeft.x + params.LEFT_OFFSET, + y: viewPort.visibleArea.bottomLeft.y + } + + browserCanvasContext.beginPath(); + browserCanvasContext.arc(centerPoint.x, centerPoint.y, RADIOUS + RED_LINE_HIGHT, 0.9 * Math.PI, 2.1 * Math.PI) + browserCanvasContext.closePath(); + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + OPACITY + ')' + browserCanvasContext.fill() + + browserCanvasContext.beginPath(); + browserCanvasContext.arc(centerPoint.x, centerPoint.y, RADIOUS, 0.0 * Math.PI, 2.0 * Math.PI) + browserCanvasContext.closePath(); + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', ' + OPACITY + ')' + browserCanvasContext.fill() + + + /* We draw the circle bar */ + + const DEFAULT_THICKNESS = 2; + const VALUE_THICKNESS = 4; + const BAR_RADIOUS = RADIOUS * 0.9; + const BAR_START_ANGLE = 0.9 * Math.PI; + const BAR_END_ANGLE = 2.1 * Math.PI; + const CURRENT_VALUE_ANGLE = params.VALUE * (BAR_END_ANGLE - BAR_START_ANGLE) / params.MAX_VALUE + BAR_START_ANGLE + const MIN_VALUE_ANGLE = params.MIN_VALUE * (BAR_END_ANGLE - BAR_START_ANGLE) / params.MAX_VALUE + BAR_START_ANGLE + let PROFIT_VALUE_ANGLE = (params.VALUE - params.MAX_VALUE) * (BAR_END_ANGLE - BAR_START_ANGLE) / params.MAX_VALUE + BAR_START_ANGLE + + if (PROFIT_VALUE_ANGLE > BAR_END_ANGLE) { PROFIT_VALUE_ANGLE = BAR_END_ANGLE } + + browserCanvasContext.setLineDash([0, 0]) + + browserCanvasContext.beginPath(); + browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, BAR_START_ANGLE, MIN_VALUE_ANGLE) + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = DEFAULT_THICKNESS + browserCanvasContext.stroke() + browserCanvasContext.closePath(); + + browserCanvasContext.beginPath(); + browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, MIN_VALUE_ANGLE, BAR_END_ANGLE) + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = DEFAULT_THICKNESS + browserCanvasContext.stroke() + browserCanvasContext.closePath(); + + if (params.VALUE > 0 && params.VALUE <= params.MAX_VALUE) { + + browserCanvasContext.beginPath(); + browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, BAR_START_ANGLE, MIN_VALUE_ANGLE) + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = VALUE_THICKNESS + browserCanvasContext.stroke() + browserCanvasContext.closePath(); + + browserCanvasContext.beginPath(); + browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, MIN_VALUE_ANGLE, CURRENT_VALUE_ANGLE) + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = VALUE_THICKNESS + browserCanvasContext.stroke() + browserCanvasContext.closePath(); + + browserCanvasContext.beginPath(); + browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, CURRENT_VALUE_ANGLE, BAR_END_ANGLE) + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = DEFAULT_THICKNESS + browserCanvasContext.stroke() + browserCanvasContext.closePath(); + + } + + if (params.VALUE > params.MAX_VALUE) { + + browserCanvasContext.beginPath(); + browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, BAR_START_ANGLE, BAR_END_ANGLE) + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = DEFAULT_THICKNESS + browserCanvasContext.stroke() + browserCanvasContext.closePath(); + + browserCanvasContext.beginPath(); + browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, BAR_START_ANGLE, PROFIT_VALUE_ANGLE) + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + OPACITY + ')' + browserCanvasContext.lineWidth = VALUE_THICKNESS + browserCanvasContext.stroke() + browserCanvasContext.closePath(); + + } + + /* Common Variables */ + + let fontSize + let label + let xOffset + let yOffset + + /* We put the params.VALUE in the middle */ + + fontSize = 25; + + browserCanvasContext.font = "bold " + fontSize + 'px ' + UI_FONT.WHITE + ' Saira'; + + label = params.VALUE; + if (isNaN(label) === false) { + label = Number(label); + label = label.toLocaleString(); + } + + label = label.substring(0, 5); + + + xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO; + + labelPoint = { + x: centerPoint.x - xOffset, + y: centerPoint.y + }; + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')'; + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y); + + /* We put the top label */ + + fontSize = 15; + + browserCanvasContext.font = "bold " + fontSize + 'px ' + UI_FONT.WHITE + ' Saira'; + + label = params.ASSET_LABEL; + + xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO; + yOffset = 22 + + labelPoint = { + x: centerPoint.x - xOffset, + y: centerPoint.y - yOffset + }; + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')'; + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y); + + /* We put the bottom label */ + + fontSize = 15; + + browserCanvasContext.font = "bold " + fontSize + 'px ' + UI_FONT.WHITE + ' Saira'; + + label = params.ASSET_NAME; + + xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO; + yOffset = - 15 + + labelPoint = { + x: centerPoint.x - xOffset, + y: centerPoint.y - yOffset + }; + + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')'; + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y); + + } } + + + + + + + + +