From dc0a290219a765f28daee305a7fddea948708e60 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 18 Apr 2018 23:04:55 +0200 Subject: [PATCH] Candles Profile Picture --- .vs/Plotters-Candles-Volumes/v15/.suo | Bin 22016 -> 30720 bytes CandlePanel.js | 303 ++++++++++++++++++++++++++ Candles.png | Bin 0 -> 10842 bytes Project.njsproj | 5 + VolumePanel.js | 224 +++++++++++++++++++ this.plotter.config.json | 27 +++ 6 files changed, 559 insertions(+) create mode 100644 CandlePanel.js create mode 100644 Candles.png create mode 100644 VolumePanel.js create mode 100644 this.plotter.config.json diff --git a/.vs/Plotters-Candles-Volumes/v15/.suo b/.vs/Plotters-Candles-Volumes/v15/.suo index e96c3c5353c49ce3a5d00b274a676c26f4dac3c7..1408ec49f5e865da9fd52ea7ad9ee86a99962624 100644 GIT binary patch literal 30720 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 diff --git a/CandlePanel.js b/CandlePanel.js new file mode 100644 index 000000000..babd6f50d --- /dev/null +++ b/CandlePanel.js @@ -0,0 +1,303 @@ + +function newCandlePanel() { + + var currentCandlePanel = { + onCurrentCandleChanged: onCurrentCandleChanged, + container: undefined, + draw: draw, + getContainer: getContainer, + initialize: initialize + }; + + var container = newContainer(); + container.initialize(); + currentCandlePanel.container = container; + + container.displacement.containerName = "Current Candle Panel"; + container.zoom.containerName = "Current Candle Panel"; + container.frame.containerName = "Current Candle Panel"; + + let currentCandle; + + return currentCandlePanel; + + function initialize() { + + currentCandlePanel.container.frame.width = 250; + currentCandlePanel.container.frame.height = 300; + + currentCandlePanel.container.frame.position.x = viewPort.visibleArea.topRight.x - currentCandlePanel.container.frame.width - 180; + currentCandlePanel.container.frame.position.y = 0; + + + } + + + + function getContainer(point) { + + var container; + + /* First we check if this point is inside this space. */ + + if (this.container.frame.isThisPointHere(point, true) === true) { + + return this.container; + + } else { + + /* This point does not belong to this space. */ + + return undefined; + } + + } + + + function onCurrentCandleChanged(lastCurrentCandle) { + + currentCandle = lastCurrentCandle; + + } + + + function draw() { + + this.container.frame.draw(false, false, true); + + plotCurrentCandleInfo(); + + } + + + function plotCurrentCandleInfo() { + + if (currentCandle === undefined) { return; } + if (currentCandle.innerCandle === undefined) { return; } + + const frameBodyHeight = currentCandlePanel.container.frame.getBodyHeight(); + const frameTitleHeight = currentCandlePanel.container.frame.height - frameBodyHeight; + + const X_AXIS = currentCandlePanel.container.frame.width / 2; + const Y_AXIS = frameTitleHeight + frameBodyHeight / 2; + + var candlePoint1 = { + x: X_AXIS - currentCandle.bodyWidth / 2, + y: Y_AXIS - currentCandle.bodyHeight / 2 + }; + + var candlePoint2 = { + x: X_AXIS + currentCandle.bodyWidth / 2, + y: Y_AXIS - currentCandle.bodyHeight / 2 + }; + + var candlePoint3 = { + x: X_AXIS + currentCandle.bodyWidth / 2, + y: Y_AXIS + currentCandle.bodyHeight / 2 + }; + + var candlePoint4 = { + x: X_AXIS - currentCandle.bodyWidth / 2, + y: Y_AXIS + currentCandle.bodyHeight / 2 + }; + + + var stickPoint1 = { + x: X_AXIS - currentCandle.stickWidth / 2, + y: candlePoint1.y - currentCandle.stickStart + }; + + var stickPoint2 = { + x: X_AXIS + currentCandle.stickWidth / 2, + y: candlePoint1.y - currentCandle.stickStart + }; + + var stickPoint3 = { + x: X_AXIS + currentCandle.stickWidth / 2, + y: candlePoint1.y - currentCandle.stickStart + currentCandle.stickHeight + }; + + var stickPoint4 = { + x: X_AXIS - currentCandle.stickWidth / 2, + y: candlePoint1.y - currentCandle.stickStart + currentCandle.stickHeight + }; + + + /* Extra bounderies due to constrained space */ + + const upperLimit = frameTitleHeight + frameBodyHeight * 0.15; + const downLimit = frameTitleHeight + frameBodyHeight * 0.85; + + if (candlePoint1.y < upperLimit) { + + candlePoint1.y = upperLimit; + candlePoint2.y = upperLimit; + + } + + if (stickPoint1.y < upperLimit) { + + stickPoint1.y = upperLimit; + stickPoint2.y = upperLimit; + + } + + if (candlePoint3.y < upperLimit) { + + candlePoint3.y = upperLimit; + candlePoint4.y = upperLimit; + + } + + if (stickPoint3.y < upperLimit) { + + stickPoint3.y = upperLimit; + stickPoint4.y = upperLimit; + + } + + if (candlePoint1.y > downLimit) { + + candlePoint1.y = downLimit; + candlePoint2.y = downLimit; + + } + + if (stickPoint1.y > downLimit) { + + stickPoint1.y = downLimit; + stickPoint2.y = downLimit; + + } + + if (candlePoint3.y > downLimit) { + + candlePoint3.y = downLimit; + candlePoint4.y = downLimit; + + } + + if (stickPoint3.y > downLimit) { + + stickPoint3.y = downLimit; + stickPoint4.y = downLimit; + + } + + + candlePoint1 = currentCandlePanel.container.frame.frameThisPoint(candlePoint1); + candlePoint2 = currentCandlePanel.container.frame.frameThisPoint(candlePoint2); + candlePoint3 = currentCandlePanel.container.frame.frameThisPoint(candlePoint3); + candlePoint4 = currentCandlePanel.container.frame.frameThisPoint(candlePoint4); + + stickPoint1 = currentCandlePanel.container.frame.frameThisPoint(stickPoint1); + stickPoint2 = currentCandlePanel.container.frame.frameThisPoint(stickPoint2); + stickPoint3 = currentCandlePanel.container.frame.frameThisPoint(stickPoint3); + stickPoint4 = currentCandlePanel.container.frame.frameThisPoint(stickPoint4); + + + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(stickPoint1.x, stickPoint1.y); + browserCanvasContext.lineTo(stickPoint2.x, stickPoint2.y); + browserCanvasContext.lineTo(stickPoint3.x, stickPoint3.y); + browserCanvasContext.lineTo(stickPoint4.x, stickPoint4.y); + + browserCanvasContext.closePath(); + browserCanvasContext.fillStyle = 'rgba(54, 54, 54, 1)'; + browserCanvasContext.fill(); + + browserCanvasContext.lineWidth = 1; + browserCanvasContext.stroke(); + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(candlePoint1.x, candlePoint1.y); + browserCanvasContext.lineTo(candlePoint2.x, candlePoint2.y); + browserCanvasContext.lineTo(candlePoint3.x, candlePoint3.y); + browserCanvasContext.lineTo(candlePoint4.x, candlePoint4.y); + + browserCanvasContext.closePath(); + + const OPACITY = '1'; + + if (currentCandle.innerCandle.direction === 'up') { browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + OPACITY + ')'; } + if (currentCandle.innerCandle.direction === 'down') { browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, ' + OPACITY + ')'; } + if (currentCandle.innerCandle.direction === 'side') { browserCanvasContext.strokeStyle = 'rgba(27, 7, 105, ' + OPACITY + ')'; } + + if (currentCandle.innerCandle.direction === 'up') { browserCanvasContext.fillStyle = 'rgba(64, 217, 26, ' + OPACITY + ')'; } + if (currentCandle.innerCandle.direction === 'down') { browserCanvasContext.fillStyle = 'rgba(219, 18, 18, ' + OPACITY + ')'; } + if (currentCandle.innerCandle.direction === 'side') { browserCanvasContext.fillStyle = 'rgba(64, 26, 217, ' + OPACITY + ')'; } + + browserCanvasContext.fill(); + + browserCanvasContext.lineWidth = 1; + browserCanvasContext.stroke(); + + + browserCanvasContext.beginPath(); + + /* put the labels with the candles values */ + + + + + let y; + + printLabel('High', X_AXIS, frameTitleHeight + frameBodyHeight * 0.05, '1'); + printLabel(currentCandle.innerCandle.max, X_AXIS, frameTitleHeight + frameBodyHeight * 0.10, '0.50'); + + printLabel('Low', X_AXIS, frameTitleHeight + frameBodyHeight * 0.95, '1'); + printLabel(currentCandle.innerCandle.min, X_AXIS, frameTitleHeight + frameBodyHeight * 0.90, '0.50'); + + + y = Y_AXIS - currentCandle.bodyHeight / 2; + + if (y < frameTitleHeight + frameBodyHeight * 0.15) { y = frameTitleHeight + frameBodyHeight * 0.15; } + if (y > frameTitleHeight + frameBodyHeight * 0.80) { y = frameTitleHeight + frameBodyHeight * 0.80; } + + printLabel('Open', X_AXIS * 1 / 2, y , '1'); + printLabel(currentCandle.innerCandle.open, X_AXIS * 1 / 2, y + frameBodyHeight * 0.05, '0.50'); + + y = Y_AXIS + currentCandle.bodyHeight / 2; + + if (y < frameTitleHeight + frameBodyHeight * 0.15) { y = frameTitleHeight + frameBodyHeight * 0.15; } + if (y > frameTitleHeight + frameBodyHeight * 0.80) { y = frameTitleHeight + frameBodyHeight * 0.80; } + + printLabel('Close', X_AXIS * 3 / 2, y , '1'); + printLabel(currentCandle.innerCandle.close, X_AXIS * 3 / 2, y + frameBodyHeight * 0.05, '0.50'); + + + + function printLabel(labelToPrint, x, y, opacity) { + + let labelPoint; + let fontSize = 10; + + browserCanvasContext.font = fontSize + 'px Courier New'; + + let label = '' + labelToPrint; + + let xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO; + + labelPoint = { + x: x - xOffset, + y: y + }; + + labelPoint = currentCandlePanel.container.frame.frameThisPoint(labelPoint); + + browserCanvasContext.fillStyle = 'rgba(60, 60, 60, ' + opacity + ')'; + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y); + + } + + browserCanvasContext.closePath(); + browserCanvasContext.fill(); + + } + + +} + diff --git a/Candles.png b/Candles.png new file mode 100644 index 0000000000000000000000000000000000000000..f1e093cd521cba08bf6902c269febdbe7d9e7673 GIT binary patch literal 10842 zcmaL7cT`i&7dDEBQbeT*C=moh354EzFA2?r-a&eo-iu1F(go=d5a|IzlOjls^iBi> zM5H46Z=X_^�aG6DjEhY&R-I03<(O#HDK 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 + + Code + + + diff --git a/VolumePanel.js b/VolumePanel.js new file mode 100644 index 000000000..4a2d08eb6 --- /dev/null +++ b/VolumePanel.js @@ -0,0 +1,224 @@ + +function newVolumePanel() { + + var currentVolumePanel = { + onCurrentVolumeChanged: onCurrentVolumeChanged, + container: undefined, + draw: draw, + getContainer: getContainer, + initialize: initialize + }; + + var container = newContainer(); + container.initialize(); + currentVolumePanel.container = container; + + container.displacement.containerName = "Current Volume Panel"; + container.zoom.containerName = "Current Volume Panel"; + container.frame.containerName = "Current Volume Panel"; + + let currentVolume; + + return currentVolumePanel; + + function initialize() { + + currentVolumePanel.container.frame.width = 250; + currentVolumePanel.container.frame.height = 300; + + currentVolumePanel.container.frame.position.x = viewPort.visibleArea.topRight.x - currentVolumePanel.container.frame.width; + currentVolumePanel.container.frame.position.y = 0; + + + } + + + + function getContainer(point) { + + var container; + + /* First we check if this point is inside this space. */ + + if (this.container.frame.isThisPointHere(point, true) === true) { + + return this.container; + + } else { + + /* This point does not belong to this space. */ + + return undefined; + } + + } + + + function onCurrentVolumeChanged(lastCurrentVolume) { + + currentVolume = lastCurrentVolume; + + } + + + function draw() { + + this.container.frame.draw(false, false, true); + + plotCurrentVolumeInfo(); + + } + + + function plotCurrentVolumeInfo() { + + if (currentVolume === undefined) { return; } + if (currentVolume.innerVolumeBar === undefined) { return; } + + const frameBodyHeight = currentVolumePanel.container.frame.getBodyHeight(); + const frameTitleHeight = currentVolumePanel.container.frame.height - frameBodyHeight; + + const X_AXIS = currentVolumePanel.container.frame.width / 2; + const Y_AXIS_BUY = frameTitleHeight + frameBodyHeight * 0.85; + const Y_AXIS_SELL = frameTitleHeight + frameBodyHeight * 0.15; + + var buyVolumePoint1 = { + x: X_AXIS - currentVolume.buyInfo.baseWidth / 2, + y: Y_AXIS_BUY + }; + + var buyVolumePoint2 = { + x: X_AXIS - currentVolume.buyInfo.topWidth / 2, + y: Y_AXIS_BUY + currentVolume.buyInfo.height + }; + + var buyVolumePoint3 = { + x: X_AXIS + currentVolume.buyInfo.topWidth / 2, + y: Y_AXIS_BUY + currentVolume.buyInfo.height + }; + + var buyVolumePoint4 = { + x: X_AXIS + currentVolume.buyInfo.baseWidth / 2, + y: Y_AXIS_BUY + }; + + buyVolumePoint1 = currentVolumePanel.container.frame.fitIntoFrame(buyVolumePoint1); + buyVolumePoint2 = currentVolumePanel.container.frame.fitIntoFrame(buyVolumePoint2); + buyVolumePoint3 = currentVolumePanel.container.frame.fitIntoFrame(buyVolumePoint3); + buyVolumePoint4 = currentVolumePanel.container.frame.fitIntoFrame(buyVolumePoint4); + + buyVolumePoint1 = currentVolumePanel.container.frame.frameThisPoint(buyVolumePoint1); + buyVolumePoint2 = currentVolumePanel.container.frame.frameThisPoint(buyVolumePoint2); + buyVolumePoint3 = currentVolumePanel.container.frame.frameThisPoint(buyVolumePoint3); + buyVolumePoint4 = currentVolumePanel.container.frame.frameThisPoint(buyVolumePoint4); + + var sellVolumePoint1 = { + x: X_AXIS - currentVolume.buyInfo.baseWidth / 2, + y: Y_AXIS_SELL + }; + + var sellVolumePoint2 = { + x: X_AXIS - currentVolume.buyInfo.topWidth / 2, + y: Y_AXIS_SELL + currentVolume.sellInfo.height + }; + + var sellVolumePoint3 = { + x: X_AXIS + currentVolume.buyInfo.topWidth / 2, + y: Y_AXIS_SELL + currentVolume.sellInfo.height + }; + + var sellVolumePoint4 = { + x: X_AXIS + currentVolume.buyInfo.baseWidth / 2, + y: Y_AXIS_SELL + }; + + sellVolumePoint1 = currentVolumePanel.container.frame.fitIntoFrame(sellVolumePoint1); + sellVolumePoint2 = currentVolumePanel.container.frame.fitIntoFrame(sellVolumePoint2); + sellVolumePoint3 = currentVolumePanel.container.frame.fitIntoFrame(sellVolumePoint3); + sellVolumePoint4 = currentVolumePanel.container.frame.fitIntoFrame(sellVolumePoint4); + + sellVolumePoint1 = currentVolumePanel.container.frame.frameThisPoint(sellVolumePoint1); + sellVolumePoint2 = currentVolumePanel.container.frame.frameThisPoint(sellVolumePoint2); + sellVolumePoint3 = currentVolumePanel.container.frame.frameThisPoint(sellVolumePoint3); + sellVolumePoint4 = currentVolumePanel.container.frame.frameThisPoint(sellVolumePoint4); + + const OPACITY = '0.40'; + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(buyVolumePoint1.x, buyVolumePoint1.y); + browserCanvasContext.lineTo(buyVolumePoint2.x, buyVolumePoint2.y); + browserCanvasContext.lineTo(buyVolumePoint3.x, buyVolumePoint3.y); + browserCanvasContext.lineTo(buyVolumePoint4.x, buyVolumePoint4.y); + + browserCanvasContext.closePath(); + + browserCanvasContext.strokeStyle = 'rgba(27, 105, 7, ' + OPACITY + ')'; + browserCanvasContext.fillStyle = 'rgba(64, 217, 26, ' + OPACITY + ')'; + + browserCanvasContext.fill(); + + browserCanvasContext.lineWidth = 1; + browserCanvasContext.stroke(); + + + browserCanvasContext.beginPath(); + + browserCanvasContext.moveTo(sellVolumePoint1.x, sellVolumePoint1.y); + browserCanvasContext.lineTo(sellVolumePoint2.x, sellVolumePoint2.y); + browserCanvasContext.lineTo(sellVolumePoint3.x, sellVolumePoint3.y); + browserCanvasContext.lineTo(sellVolumePoint4.x, sellVolumePoint4.y); + + browserCanvasContext.closePath(); + + browserCanvasContext.strokeStyle = 'rgba(130, 9, 9, ' + OPACITY + ')'; + browserCanvasContext.fillStyle = 'rgba(219, 18, 18, ' + OPACITY + ')'; + + browserCanvasContext.fill(); + + browserCanvasContext.lineWidth = 1; + browserCanvasContext.stroke(); + + + /* put the labels with the volumes values */ + + browserCanvasContext.beginPath(); + + printLabel('Buy Volume', X_AXIS, frameTitleHeight + frameBodyHeight * 0.95, '1'); + printLabel(currentVolume.innerVolumeBar.amountBuy, X_AXIS, frameTitleHeight + frameBodyHeight * 0.90, '0.50'); + + printLabel('Sell Volume', X_AXIS, frameTitleHeight + frameBodyHeight * 0.05, '1'); + printLabel(currentVolume.innerVolumeBar.amountSell, X_AXIS, frameTitleHeight + frameBodyHeight * 0.10, '0.50'); + + + function printLabel(labelToPrint, x, y, opacity) { + + let labelPoint; + let fontSize = 10; + + browserCanvasContext.font = fontSize + 'px Courier New'; + + let label = '' + labelToPrint; + + let xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO; + + labelPoint = { + x: x - xOffset, + y: y + }; + + labelPoint = currentVolumePanel.container.frame.frameThisPoint(labelPoint); + + browserCanvasContext.fillStyle = 'rgba(60, 60, 60, ' + opacity + ')'; + browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y); + + } + + browserCanvasContext.closePath(); + browserCanvasContext.fill(); + + } + + +} + diff --git a/this.plotter.config.json b/this.plotter.config.json new file mode 100644 index 000000000..13724b2f2 --- /dev/null +++ b/this.plotter.config.json @@ -0,0 +1,27 @@ +{ + "modules": [ + { + "codeName": "Candles", + "moduleName": "Candles", + "description": "Plots traditional red and green candles.", + "profilePicture": "Candles.png", + "panels": [ + { + "codeName": "Current Candle", + "moduleName": "CandlePanel" + } + ] + }, + { + "codeName": "Volumes", + "description": "Plots volumes separated in buy and sell.", + "moduleName": "Volumes", + "panels": [ + { + "codeName": "Current Volume", + "moduleName": "VolumePanel" + } + ] + } + ] +} \ No newline at end of file