Candles Profile Picture
This commit is contained in:
1 parent
c6e242ea00
commit
dc0a290219
6 files changed
+559
No files matched your search
Binary file not shown.
+303
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@@ -17,11 +17,16 @@
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'" />
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'" />
|
||||
<ItemGroup>
|
||||
<Compile Include="CandlePanel.js" />
|
||||
<Compile Include="Candles.js" />
|
||||
<Compile Include="VolumePanel.js" />
|
||||
<Compile Include="Volumes.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="this.plotter.config.json" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<!--Do not delete the following Import Project. While this appears to do nothing it is a marker for setting TypeScript properties before our import that depends on them.-->
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" Condition="False" />
|
||||
|
||||
+224
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user