Merge remote-tracking branch 'PlotterCandlesVolumes/develop' into develop

This commit is contained in:
Luis Fernando Molina committed 2020-11-20 18:26:47 +01:00
commit 3affc5c1b5
13 files changed
+2341

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
+11
View File
@@ -0,0 +1,11 @@
.vs/*
obj/*
bin/*
*.config
*.log
*.cache
node_modules/*
+352
View File
@@ -0,0 +1,352 @@
function newMastersPlottersCandlesVolumesCandlesCandlePanel() {
let thisObject = {
fitFunction: undefined,
container: undefined,
isVisible: true,
onRecordChange: onRecordChange,
draw: draw,
getContainer: getContainer,
initialize: initialize,
finalize: finalize
};
thisObject.container = newContainer();
thisObject.container.initialize();
thisObject.container.frame.containerName = "Candle";
let currentCandle;
let upDownButton
return thisObject;
function finalize() {
thisObject.container.finalize()
thisObject.container = undefined
thisObject.fitFunction = undefined
thisObject.isVisible = undefined
currentCandle = undefined
upDownButton.finalize()
upDownButton = undefined
}
function initialize() {
thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL;
thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL;
thisObject.container.frame.position.x = UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.topRight.x - thisObject.container.frame.width * 2;
thisObject.container.frame.position.y = UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.bottomLeft.y - thisObject.container.frame.height;
upDownButton = newUpDownButton()
upDownButton.parentContainer = thisObject.container
upDownButton.container.frame.parentFrame = thisObject.container.frame
upDownButton.fitFunction = thisObject.fitFunction
upDownButton.initialize()
}
function getContainer(point) {
if (thisObject.isVisible !== true) { return }
let container;
container = upDownButton.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 onRecordChange(lastCurrentCandle) {
currentCandle = lastCurrentCandle;
}
function draw() {
if (thisObject.isVisible !== true) { return }
thisObject.container.frame.draw(false, false, true, thisObject.fitFunction);
plotCurrentCandleInfo();
upDownButton.draw()
}
function plotCurrentCandleInfo() {
if (currentCandle === undefined) { return; }
if (currentCandle.innerCandle === 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;
let candlePoint1 = {
x: X_AXIS - currentCandle.bodyWidth / 2,
y: Y_AXIS - currentCandle.bodyHeight / 2
};
let candlePoint2 = {
x: X_AXIS + currentCandle.bodyWidth / 2,
y: Y_AXIS - currentCandle.bodyHeight / 2
};
let candlePoint3 = {
x: X_AXIS + currentCandle.bodyWidth / 2,
y: Y_AXIS + currentCandle.bodyHeight / 2
};
let candlePoint4 = {
x: X_AXIS - currentCandle.bodyWidth / 2,
y: Y_AXIS + currentCandle.bodyHeight / 2
};
let stickPoint1 = {
x: X_AXIS - currentCandle.stickWidth / 2,
y: candlePoint1.y - currentCandle.stickStart
};
let stickPoint2 = {
x: X_AXIS + currentCandle.stickWidth / 2,
y: candlePoint1.y - currentCandle.stickStart
};
let stickPoint3 = {
x: X_AXIS + currentCandle.stickWidth / 2,
y: candlePoint1.y - currentCandle.stickStart + currentCandle.stickHeight
};
let 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;
}
const leftLimit = thisObject.container.frame.width * 0.42;
const rightLimit = thisObject.container.frame.width * 0.58;
if (candlePoint1.x < leftLimit) {
candlePoint1.x = leftLimit;
candlePoint4.x = leftLimit;
}
if (stickPoint1.x < leftLimit) {
stickPoint1.x = leftLimit;
stickPoint4.x = leftLimit;
}
if (candlePoint4.x < leftLimit) {
candlePoint4.x = leftLimit;
candlePoint1.x = leftLimit;
}
if (stickPoint4.x < leftLimit) {
stickPoint4.x = leftLimit;
stickPoint1.x = leftLimit;
}
if (candlePoint2.x > rightLimit) {
candlePoint2.x = rightLimit;
candlePoint3.x = rightLimit;
}
if (stickPoint2.x > rightLimit) {
stickPoint2.x = rightLimit;
stickPoint3.x = rightLimit;
}
if (candlePoint3.x > rightLimit) {
candlePoint3.x = rightLimit;
candlePoint2.x = rightLimit;
}
if (stickPoint3.x > rightLimit) {
stickPoint3.x = rightLimit;
stickPoint2.x = rightLimit;
}
candlePoint1 = thisObject.container.frame.frameThisPoint(candlePoint1);
candlePoint2 = thisObject.container.frame.frameThisPoint(candlePoint2);
candlePoint3 = thisObject.container.frame.frameThisPoint(candlePoint3);
candlePoint4 = thisObject.container.frame.frameThisPoint(candlePoint4);
candlePoint1 = thisObject.fitFunction(candlePoint1)
candlePoint2 = thisObject.fitFunction(candlePoint2)
candlePoint3 = thisObject.fitFunction(candlePoint3)
candlePoint4 = thisObject.fitFunction(candlePoint4)
stickPoint1 = thisObject.container.frame.frameThisPoint(stickPoint1);
stickPoint2 = thisObject.container.frame.frameThisPoint(stickPoint2);
stickPoint3 = thisObject.container.frame.frameThisPoint(stickPoint3);
stickPoint4 = thisObject.container.frame.frameThisPoint(stickPoint4);
stickPoint1 = thisObject.fitFunction(stickPoint1)
stickPoint2 = thisObject.fitFunction(stickPoint2)
stickPoint3 = thisObject.fitFunction(stickPoint3)
stickPoint4 = thisObject.fitFunction(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(' + UI_COLOR.DARK + ', 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(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + OPACITY + ')'; }
if (currentCandle.innerCandle.direction === 'down') { browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + OPACITY + ')'; }
if (currentCandle.innerCandle.direction === 'side') { browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', ' + OPACITY + ')'; }
if (currentCandle.innerCandle.direction === 'up') { browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + OPACITY + ')'; }
if (currentCandle.innerCandle.direction === 'down') { browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + OPACITY + ')'; }
if (currentCandle.innerCandle.direction === 'side') { browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', ' + OPACITY + ')'; }
browserCanvasContext.fill();
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
/* put the labels with the candles values */
let y;
UI.projects.superalgos.utilities.drawPrint.printLabel('Max', undefined, undefined, X_AXIS, frameTitleHeight + frameBodyHeight * 0.05, '0.60', undefined, undefined, 'Center', thisObject.container, thisObject.fitFunction);
UI.projects.superalgos.utilities.drawPrint.printLabel(currentCandle.innerCandle.max, undefined, undefined, X_AXIS, frameTitleHeight + frameBodyHeight * 0.10, '1.00', 15, undefined, 'Center', thisObject.container, thisObject.fitFunction);
UI.projects.superalgos.utilities.drawPrint.printLabel('Min', undefined, undefined, X_AXIS, frameTitleHeight + frameBodyHeight * 0.95, '0.60', undefined, undefined, 'Center', thisObject.container, thisObject.fitFunction);
UI.projects.superalgos.utilities.drawPrint.printLabel(currentCandle.innerCandle.min, undefined, undefined, X_AXIS, frameTitleHeight + frameBodyHeight * 0.90, '1.00', 15, undefined, 'Center', thisObject.container, thisObject.fitFunction);
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; }
UI.projects.superalgos.utilities.drawPrint.printLabel('Open', undefined, undefined, X_AXIS * 2 / 5, y, '0.60', undefined, undefined, 'Center', thisObject.container, thisObject.fitFunction);
UI.projects.superalgos.utilities.drawPrint.printLabel(currentCandle.innerCandle.open, undefined, undefined, X_AXIS * 2 / 5, y + frameBodyHeight * 0.05, '1.00', 15, undefined, 'Center', thisObject.container, thisObject.fitFunction);
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; }
UI.projects.superalgos.utilities.drawPrint.printLabel('Close', undefined, undefined, X_AXIS * 7 / 5, y, '0.60', undefined, undefined, 'Center', thisObject.container, thisObject.fitFunction);
UI.projects.superalgos.utilities.drawPrint.printLabel(currentCandle.innerCandle.close, undefined, undefined, X_AXIS * 7 / 5, y + frameBodyHeight * 0.05, '1.00', 15, undefined, 'Center', thisObject.container, thisObject.fitFunction);
}
}
+810
View File
@@ -0,0 +1,810 @@
function newMastersPlottersCandlesVolumesCandles() {
const MODULE_NAME = "Candles Plotter";
const ERROR_LOG = true;
const INTENSIVE_LOG = false;
const logger = newWebDebugLog();
logger.fileName = MODULE_NAME;
let thisObject = {
initialize: initialize,
finalize: finalize,
container: undefined,
fitFunction: undefined,
getContainer: getContainer,
setTimeFrame: setTimeFrame,
setDatetime: setDatetime,
setCoordinateSystem: setCoordinateSystem,
draw: draw,
onDailyFileLoaded: onDailyFileLoaded,
currentCandle: undefined
};
/* this is part of the module template */
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
let coordinateSystem
let timeFrame; // This will hold the current Time Frame the user is at.
let datetime; // This will hold the current Datetime the user is at.
let marketFile; // This is the current Market File being plotted.
let fileCursor; // This is the current File Cursor being used to retrieve Daily Files.
let marketFiles; // This object will provide the different Market Files at different Time Frames.
let dailyFiles; // This object will provide the different File Cursors at different Time Frames.
/* these are module specific variables: */
let candles = []; // Here we keep the candles to be ploted every time the Draw() function is called by the AAWebPlatform.
let onMouseOverEventSuscriptionId
let zoomChangedEventSubscriptionId
let offsetChangedEventSubscriptionId
let dragFinishedEventSubscriptionId
let dimmensionsChangedEventSubscriptionId
let marketFilesUpdatedEventSubscriptionId
let dailyFilesUpdatedEventSubscriptionId
let scaleChangedEventSubscriptionId
let userPositionDate
return thisObject;
function finalize() {
try {
/* Stop listening to the necesary events. */
thisObject.container.eventHandler.stopListening(onMouseOverEventSuscriptionId)
UI.projects.superalgos.spaces.chartingSpace.viewport.eventHandler.stopListening(zoomChangedEventSubscriptionId);
UI.projects.superalgos.spaces.chartingSpace.viewport.eventHandler.stopListening(offsetChangedEventSubscriptionId);
canvas.eventHandler.stopListening(dragFinishedEventSubscriptionId);
thisObject.container.eventHandler.stopListening(dimmensionsChangedEventSubscriptionId)
marketFiles.eventHandler.stopListening(marketFilesUpdatedEventSubscriptionId);
dailyFiles.eventHandler.stopListening(dailyFilesUpdatedEventSubscriptionId);
/* Destroyd References */
marketFiles = undefined;
dailyFiles = undefined;
datetime = undefined;
timeFrame = undefined;
marketFile = undefined;
fileCursor = undefined;
thisObject.fitFunction = undefined
finalizeCoordinateSystem()
coordinateSystem = undefined
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] finalize -> err = " + err.stack); }
}
}
function initialize(pStorage, pDatetime, pTimeFrame, pCoordinateSystem, callBackFunction) {
try {
/* Store the information received. */
marketFiles = pStorage.marketFiles[0];
dailyFiles = pStorage.dailyFiles[0];
datetime = pDatetime;
timeFrame = pTimeFrame;
coordinateSystem = pCoordinateSystem
initializeCoordinateSystem()
/* We need a Market File in order to calculate the Y scale, since this scale depends on actual data. */
marketFile = marketFiles.getFile(ONE_DAY_IN_MILISECONDS); // This file is the one processed faster.
/* Now we set the right files according to current Period. */
marketFile = marketFiles.getFile(pTimeFrame);
fileCursor = dailyFiles.getFileCursor(pTimeFrame);
/* Listen to the necesary events. */
zoomChangedEventSubscriptionId = UI.projects.superalgos.spaces.chartingSpace.viewport.eventHandler.listenToEvent("Zoom Changed", onViewportZoomChanged);
offsetChangedEventSubscriptionId = UI.projects.superalgos.spaces.chartingSpace.viewport.eventHandler.listenToEvent("Position Changed", onViewportPositionChanged);
dragFinishedEventSubscriptionId = canvas.eventHandler.listenToEvent("Drag Finished", onDragFinished);
marketFilesUpdatedEventSubscriptionId = marketFiles.eventHandler.listenToEvent("Files Updated", onMarketFilesUpdated);
dailyFilesUpdatedEventSubscriptionId = dailyFiles.eventHandler.listenToEvent("Files Updated", onDailyFilesUpdated);
onMouseOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
/* Get ready for plotting. */
recalculate();
dimmensionsChangedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('Dimmensions Changed', function () {
recalculate();
})
callBackFunction();
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err.stack); }
}
}
function initializeCoordinateSystem() {
scaleChangedEventSubscriptionId = coordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged)
}
function finalizeCoordinateSystem() {
coordinateSystem.eventHandler.stopListening(scaleChangedEventSubscriptionId)
}
function onScaleChanged() {
recalculate();
}
function onMouseOver(event) {
let userPosition = UI.projects.superalgos.utilities.dateRateTransformations.getDateFromPointAtBrowserCanvas(event, thisObject.container, coordinateSystem)
userPositionDate = userPosition.valueOf()
}
function getContainer(point) {
try {
let container;
/* First we check if this point is inside this space. */
if (thisObject.container.frame.isThisPointHere(point) === true) {
return thisObject.container;
} else {
/* This point does not belong to this space. */
return undefined;
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] getContainer -> err = " + err.stack); }
}
}
function onMarketFilesUpdated() {
try {
let newMarketFile = marketFiles.getFile(timeFrame);
if (newMarketFile !== undefined) {
marketFile = newMarketFile;
recalculate();
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] onMarketFilesUpdated -> err = " + err.stack); }
}
}
function onDailyFilesUpdated() {
try {
let newFileCursor = dailyFiles.getFileCursor(timeFrame);
if (newFileCursor !== undefined) {
fileCursor = newFileCursor;
recalculate();
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] onDailyFilesUpdated -> err = " + err.stack); }
}
}
function setTimeFrame(pTimeFrame) {
try {
if (timeFrame !== pTimeFrame) {
timeFrame = pTimeFrame;
if (timeFrame >= _1_HOUR_IN_MILISECONDS) {
let newMarketFile = marketFiles.getFile(pTimeFrame);
if (newMarketFile !== undefined) {
marketFile = newMarketFile;
recalculate();
}
} else {
let newFileCursor = dailyFiles.getFileCursor(pTimeFrame);
if (newFileCursor !== undefined) {
fileCursor = newFileCursor;
recalculate();
}
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] setTimeFrame -> err = " + err.stack); }
}
}
function setDatetime(pDatetime) {
datetime = pDatetime;
}
function setCoordinateSystem(pCoordinateSystem) {
finalizeCoordinateSystem()
coordinateSystem = pCoordinateSystem
initializeCoordinateSystem()
}
function onDailyFileLoaded(event) {
try {
if (event.currentValue === event.totalValue) {
/* This happens only when all of the files in the cursor have been loaded. */
recalculate();
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] onDailyFileLoaded -> err = " + err.stack); }
}
}
function draw() {
try {
if (INTENSIVE_LOG === true) { logger.write("[INFO] draw -> Entering function."); }
thisObject.container.frame.draw();
return plotChart();
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] draw -> err = " + err.stack); }
}
}
function recalculate() {
try {
if (timeFrame >= _1_HOUR_IN_MILISECONDS) {
recalculateUsingMarketFiles();
} else {
recalculateUsingDailyFiles();
}
thisObject.container.eventHandler.raiseEvent("Candles Changed", candles);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] recalculate -> err = " + err.stack); }
}
}
function recalculateUsingDailyFiles() {
try {
if (fileCursor === undefined) { return; } // We need to wait
if (fileCursor.files.size === 0) { return; } // We need to wait until there are files in the cursor
let daysOnSides = getSideDays(timeFrame);
let leftDate = UI.projects.superalgos.utilities.dateRateTransformations.getDateFromPointAtBrowserCanvas(UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.topLeft, thisObject.container, coordinateSystem);
let rightDate = UI.projects.superalgos.utilities.dateRateTransformations.getDateFromPointAtBrowserCanvas(UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.topRight, thisObject.container, coordinateSystem);
let dateDiff = rightDate.valueOf() - leftDate.valueOf();
let farLeftDate = new Date(leftDate.valueOf() - dateDiff * 1.5);
let farRightDate = new Date(rightDate.valueOf() + dateDiff * 1.5);
let currentDate = new Date(farLeftDate.valueOf());
candles = [];
while (currentDate.valueOf() <= farRightDate.valueOf() + ONE_DAY_IN_MILISECONDS) {
let stringDate = currentDate.getUTCFullYear() + '-' + pad(currentDate.getUTCMonth() + 1, 2) + '-' + pad(currentDate.getUTCDate(), 2);
let dailyFile = fileCursor.files.get(stringDate);
if (dailyFile !== undefined) {
for (let i = 0; i < dailyFile.length; i++) {
let candle = {
open: undefined,
close: undefined,
min: 10000000000000,
max: 0,
begin: undefined,
end: undefined,
direction: undefined
};
candle.min = dailyFile[i][0];
candle.max = dailyFile[i][1];
candle.open = dailyFile[i][2];
candle.close = dailyFile[i][3];
candle.begin = dailyFile[i][4];
candle.end = dailyFile[i][5];
if (candle.open > candle.close) { candle.direction = 'down'; }
if (candle.open < candle.close) { candle.direction = 'up'; }
if (candle.open === candle.close) { candle.direction = 'side'; }
/* Contributing to Auto-Scale*/
if (i === 0) {
coordinateSystem.reportXValue(candle.begin)
}
if (i === dailyFile.length - 1) {
coordinateSystem.reportXValue(candle.end)
}
if (
(candle.begin >= farLeftDate.valueOf() && candle.end <= farRightDate.valueOf()) &&
(candle.begin >= coordinateSystem.min.x && candle.end <= coordinateSystem.max.x)
) {
candles.push(candle);
if (datetime.valueOf() >= candle.begin && datetime.valueOf() <= candle.end) {
thisObject.currentCandle = candle;
thisObject.container.eventHandler.raiseEvent("Current Record Changed", thisObject.currentCandle);
}
}
}
}
currentDate = new Date(currentDate.valueOf() + ONE_DAY_IN_MILISECONDS);
}
/* Lests check if all the visible screen is going to be covered by candles. */
let lowerEnd = leftDate.valueOf();
let upperEnd = rightDate.valueOf();
if (candles.length > 0) {
if (candles[0].begin > lowerEnd || candles[candles.length - 1].end < upperEnd) {
setTimeout(recalculate, 2000);
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] recalculateUsingDailyFiles -> err = " + err.stack); }
}
}
function recalculateUsingMarketFiles() {
try {
if (marketFile === undefined) { return; } // Initialization not complete yet.
let daysOnSides = getSideDays(timeFrame);
let leftDate = UI.projects.superalgos.utilities.dateRateTransformations.getDateFromPointAtBrowserCanvas(UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.topLeft, thisObject.container, coordinateSystem);
let rightDate = UI.projects.superalgos.utilities.dateRateTransformations.getDateFromPointAtBrowserCanvas(UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.topRight, thisObject.container, coordinateSystem);
let dateDiff = rightDate.valueOf() - leftDate.valueOf();
leftDate = new Date(leftDate.valueOf() - dateDiff * 1.5);
rightDate = new Date(rightDate.valueOf() + dateDiff * 1.5);
candles = [];
for (let i = 0; i < marketFile.length; i++) {
let candle = {
open: undefined,
close: undefined,
min: 10000000000000,
max: 0,
begin: undefined,
end: undefined,
direction: undefined
};
candle.min = marketFile[i][0];
candle.max = marketFile[i][1];
candle.open = marketFile[i][2];
candle.close = marketFile[i][3];
candle.begin = marketFile[i][4];
candle.end = marketFile[i][5];
if (candle.open > candle.close) { candle.direction = 'down'; }
if (candle.open < candle.close) { candle.direction = 'up'; }
if (candle.open === candle.close) { candle.direction = 'side'; }
/* Contributing to Auto-Scale*/
if (i === 0) {
coordinateSystem.reportXValue(candle.begin)
}
if (i === marketFile.length - 1) {
coordinateSystem.reportXValue(candle.end)
}
if (
(candle.begin >= leftDate.valueOf() && candle.end <= rightDate.valueOf()) &&
(candle.begin >= coordinateSystem.min.x && candle.end <= coordinateSystem.max.x)
) {
candles.push(candle);
if (datetime.valueOf() >= candle.begin && datetime.valueOf() <= candle.end) {
thisObject.currentCandle = candle;
thisObject.container.eventHandler.raiseEvent("Current Record Changed", thisObject.currentCandle);
}
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] recalculateUsingMarketFiles -> err = " + err.stack); }
}
}
function plotChart() {
try {
let elementsPlotted = 0
let lowResolution = false
if (UI.projects.superalgos.spaces.chartingSpace.viewport.zoomTargetLevel < UI.projects.superalgos.globals.zoom.ZOOM_OUT_THRESHOLD_FOR_PLOTTING_IN_LOW_RESOLUTION) {
if (candles.length > 100) {
lowResolution = true
}
}
if (candles.length > 0) {
/* On screen candles */
let onScreenCandles = []
let mouseCandle
/* Now we calculate all the points. */
for (let i = 0; i < candles.length; i++) {
candle = candles[i];
candle.candlePoint1 = {
x: candle.begin + timeFrame / 7 * 1.5,
y: candle.open
};
candle.candlePoint2 = {
x: candle.begin + timeFrame / 7 * 5.5,
y: candle.open
};
candle.candlePoint3 = {
x: candle.begin + timeFrame / 7 * 5.5,
y: candle.close
};
candle.candlePoint4 = {
x: candle.begin + timeFrame / 7 * 1.5,
y: candle.close
};
candle.candlePoint1 = coordinateSystem.transformThisPoint(candle.candlePoint1);
candle.candlePoint2 = coordinateSystem.transformThisPoint(candle.candlePoint2);
candle.candlePoint3 = coordinateSystem.transformThisPoint(candle.candlePoint3);
candle.candlePoint4 = coordinateSystem.transformThisPoint(candle.candlePoint4);
candle.candlePoint1 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(candle.candlePoint1, thisObject.container);
candle.candlePoint2 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(candle.candlePoint2, thisObject.container);
candle.candlePoint3 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(candle.candlePoint3, thisObject.container);
candle.candlePoint4 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(candle.candlePoint4, thisObject.container);
/* Skip the first candle with zero at open */
if (candle.open === 0) { continue }
if (candle.candlePoint2.x < UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.bottomLeft.x || candle.candlePoint1.x > UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.bottomRight.x) {
continue
}
addToOnScreenCandles(candle)
candle.stickPoint1 = {
x: candle.begin + timeFrame / 7 * 3.2,
y: candle.max
};
candle.stickPoint2 = {
x: candle.begin + timeFrame / 7 * 3.8,
y: candle.max
};
candle.stickPoint3 = {
x: candle.begin + timeFrame / 7 * 3.8,
y: candle.min
};
candle.stickPoint4 = {
x: candle.begin + timeFrame / 7 * 3.2,
y: candle.min
};
candle.stickPoint1 = coordinateSystem.transformThisPoint(candle.stickPoint1);
candle.stickPoint2 = coordinateSystem.transformThisPoint(candle.stickPoint2);
candle.stickPoint3 = coordinateSystem.transformThisPoint(candle.stickPoint3);
candle.stickPoint4 = coordinateSystem.transformThisPoint(candle.stickPoint4);
candle.stickPoint1 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(candle.stickPoint1, thisObject.container);
candle.stickPoint2 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(candle.stickPoint2, thisObject.container);
candle.stickPoint3 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(candle.stickPoint3, thisObject.container);
candle.stickPoint4 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(candle.stickPoint4, thisObject.container);
if (UI.projects.superalgos.spaces.chartingSpace.viewport.zoomTargetLevel < UI.projects.superalgos.globals.zoom.ZOOM_OUT_THRESHOLD_FOR_PACKING_OBJECTS_AT_THE_BOTTOM_OR_TOP_OF_VIEWPORT) {
let diffA = candle.stickPoint3.y - UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.bottomLeft.y
if (diffA > 0) {
candle.candlePoint1.y = candle.candlePoint1.y - diffA
candle.candlePoint2.y = candle.candlePoint2.y - diffA
candle.candlePoint3.y = candle.candlePoint3.y - diffA
candle.candlePoint4.y = candle.candlePoint4.y - diffA
candle.stickPoint1.y = candle.stickPoint1.y - diffA
candle.stickPoint2.y = candle.stickPoint2.y - diffA
candle.stickPoint3.y = candle.stickPoint3.y - diffA
candle.stickPoint4.y = candle.stickPoint4.y - diffA
}
let diffB = candle.stickPoint1.y - UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.topLeft.y
if (diffB < 0) {
candle.candlePoint1.y = candle.candlePoint1.y - diffB
candle.candlePoint2.y = candle.candlePoint2.y - diffB
candle.candlePoint3.y = candle.candlePoint3.y - diffB
candle.candlePoint4.y = candle.candlePoint4.y - diffB
candle.stickPoint1.y = candle.stickPoint1.y - diffB
candle.stickPoint2.y = candle.stickPoint2.y - diffB
candle.stickPoint3.y = candle.stickPoint3.y - diffB
candle.stickPoint4.y = candle.stickPoint4.y - diffB
}
}
candle.candlePoint1 = UI.projects.superalgos.spaces.chartingSpace.viewport.fitIntoVisibleArea(candle.candlePoint1);
candle.candlePoint2 = UI.projects.superalgos.spaces.chartingSpace.viewport.fitIntoVisibleArea(candle.candlePoint2);
candle.candlePoint3 = UI.projects.superalgos.spaces.chartingSpace.viewport.fitIntoVisibleArea(candle.candlePoint3);
candle.candlePoint4 = UI.projects.superalgos.spaces.chartingSpace.viewport.fitIntoVisibleArea(candle.candlePoint4);
candle.candlePoint1 = thisObject.fitFunction(candle.candlePoint1);
candle.candlePoint2 = thisObject.fitFunction(candle.candlePoint2);
candle.candlePoint3 = thisObject.fitFunction(candle.candlePoint3);
candle.candlePoint4 = thisObject.fitFunction(candle.candlePoint4);
candle.stickPoint1 = UI.projects.superalgos.spaces.chartingSpace.viewport.fitIntoVisibleArea(candle.stickPoint1);
candle.stickPoint2 = UI.projects.superalgos.spaces.chartingSpace.viewport.fitIntoVisibleArea(candle.stickPoint2);
candle.stickPoint3 = UI.projects.superalgos.spaces.chartingSpace.viewport.fitIntoVisibleArea(candle.stickPoint3);
candle.stickPoint4 = UI.projects.superalgos.spaces.chartingSpace.viewport.fitIntoVisibleArea(candle.stickPoint4);
candle.stickPoint1 = thisObject.fitFunction(candle.stickPoint1);
candle.stickPoint2 = thisObject.fitFunction(candle.stickPoint2);
candle.stickPoint3 = thisObject.fitFunction(candle.stickPoint3);
candle.stickPoint4 = thisObject.fitFunction(candle.stickPoint4);
}
function addToOnScreenCandles(candle) {
/* Contributing to Auto-Scale*/
coordinateSystem.reportYValue(candle.max)
coordinateSystem.reportYValue(candle.min)
//if (onScreenCandles.length < 15000) {
onScreenCandles.push(candle)
//}
if (userPositionDate >= candle.begin && userPositionDate <= candle.end) {
mouseCandle = candle
}
}
/* We draw the sticks */
browserCanvasContext.beginPath();
for (let i = 0; i < onScreenCandles.length; i++) {
candle = onScreenCandles[i];
browserCanvasContext.moveTo(candle.stickPoint1.x, candle.stickPoint1.y);
browserCanvasContext.lineTo(candle.stickPoint2.x, candle.stickPoint2.y);
browserCanvasContext.lineTo(candle.stickPoint3.x, candle.stickPoint3.y);
browserCanvasContext.lineTo(candle.stickPoint4.x, candle.stickPoint4.y);
}
browserCanvasContext.closePath();
if (lowResolution === false) {
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', 1)';
browserCanvasContext.fill();
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.LIGHT + ', 1)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.stroke();
}
/* The stick at the mouse candle */
if (mouseCandle) {
browserCanvasContext.beginPath();
candle = mouseCandle
browserCanvasContext.moveTo(candle.stickPoint1.x, candle.stickPoint1.y);
browserCanvasContext.lineTo(candle.stickPoint2.x, candle.stickPoint2.y);
browserCanvasContext.lineTo(candle.stickPoint3.x, candle.stickPoint3.y);
browserCanvasContext.lineTo(candle.stickPoint4.x, candle.stickPoint4.y);
browserCanvasContext.closePath();
if (lowResolution === false) {
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', 1)';
browserCanvasContext.fill();
}
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 1)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.stroke();
}
/* We draw the candles. */
drawCandlesByDirection('up')
drawCandlesByDirection('down')
drawCandlesByDirection('side')
function drawCandlesByDirection(direction) {
browserCanvasContext.beginPath();
for (let i = 0; i < onScreenCandles.length; i++) {
candle = onScreenCandles[i];
if (candle.direction !== direction) { continue }
browserCanvasContext.moveTo(candle.candlePoint1.x, candle.candlePoint1.y);
browserCanvasContext.lineTo(candle.candlePoint2.x, candle.candlePoint2.y);
browserCanvasContext.lineTo(candle.candlePoint3.x, candle.candlePoint3.y);
browserCanvasContext.lineTo(candle.candlePoint4.x, candle.candlePoint4.y);
browserCanvasContext.lineTo(candle.candlePoint1.x, candle.candlePoint1.y);
elementsPlotted++
}
browserCanvasContext.closePath();
if (lowResolution === false) {
if (direction === 'up') { browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREEN + ', 1)'; }
if (direction === 'down') { browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', 1)'; }
if (direction === 'side') { browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', 1)'; }
browserCanvasContext.fill();
}
if (direction === 'up') { browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', 1)'; }
if (direction === 'down') { browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', 1)'; }
if (direction === 'side') { browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', 1)'; }
browserCanvasContext.lineWidth = 1;
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.stroke();
}
/* Draw mouse candel and Raise Event. */
if (mouseCandle) {
/* highlight the current candle */
browserCanvasContext.beginPath();
candle = mouseCandle
browserCanvasContext.moveTo(candle.candlePoint1.x, candle.candlePoint1.y);
browserCanvasContext.lineTo(candle.candlePoint2.x, candle.candlePoint2.y);
browserCanvasContext.lineTo(candle.candlePoint3.x, candle.candlePoint3.y);
browserCanvasContext.lineTo(candle.candlePoint4.x, candle.candlePoint4.y);
browserCanvasContext.closePath();
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 1)'; // Current candle accroding to time
browserCanvasContext.fill();
let currentCandle = {
bodyWidth: candle.candlePoint2.x - candle.candlePoint1.x,
bodyHeight: candle.candlePoint3.y - candle.candlePoint2.y,
stickHeight: candle.stickPoint4.y - candle.stickPoint2.y,
stickWidth: candle.stickPoint2.x - candle.stickPoint1.x,
stickStart: candle.candlePoint2.y - candle.stickPoint2.y,
period: timeFrame,
innerCandle: candle
};
thisObject.container.eventHandler.raiseEvent("Current Record Changed", currentCandle);
}
}
return elementsPlotted
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] plotChart -> err = " + err.stack); }
}
}
function onViewportZoomChanged(event) {
try {
recalculate();
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] onViewportZoomChanged -> err = " + err.stack); }
}
}
function onViewportPositionChanged(event) {
try {
if (event !== undefined) {
if (event.recalculate === true) {
recalculate()
return
}
}
if (Math.random() * 100 > 95) {
recalculate()
};
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] onViewportPositionChanged -> err = " + err.stack); }
}
}
function onDragFinished() {
try {
recalculate();
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] onDragFinished -> err = " + err.stack); }
}
}
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

+24
View File
@@ -0,0 +1,24 @@
Financial Beings License
Collective Copyright by the Advanced Algos Community
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software including without limitation the rights to use, copy, modify,
merge, publish, distribute and sublicense copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the following
conditions:
1. Using, copying, modifying, publishing, distributing and sublicensing rights
are restricted to the Advanced Algos Platform, meaning the rights granted can
only be exercised through the Advanced Algos Service.
2. The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+25
View File
@@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2027
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "Project", "Project.njsproj", "{096B35AD-F86F-47B9-A99F-04CA93397DA8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{096B35AD-F86F-47B9-A99F-04CA93397DA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{096B35AD-F86F-47B9-A99F-04CA93397DA8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{096B35AD-F86F-47B9-A99F-04CA93397DA8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{096B35AD-F86F-47B9-A99F-04CA93397DA8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E75EDC9D-66A7-4C54-8EA1-5ADC148CACA8}
EndGlobalSection
EndGlobal
+72
View File
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{096b35ad-f86f-47b9-a99f-04ca93397da8}</ProjectGuid>
<ProjectHome />
<ProjectView>ShowAllFiles</ProjectView>
<StartupFile>Candles.js</StartupFile>
<WorkingDirectory>.</WorkingDirectory>
<OutputPath>.</OutputPath>
<ProjectTypeGuids>{3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{349c5851-65df-11da-9384-00065b846f21};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<Name>Project</Name>
</PropertyGroup>
<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" />
<Import Project="$(VSToolsPath)\Node.js Tools\Microsoft.NodejsTools.targets" />
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>0</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:48022/</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>True</UseCustomServer>
<CustomServerUrl>http://localhost:1337</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}" User="">
<WebProjectProperties>
<StartPageUrl>
</StartPageUrl>
<StartAction>CurrentPage</StartAction>
<AspNetDebugging>True</AspNetDebugging>
<SilverlightDebugging>False</SilverlightDebugging>
<NativeDebugging>False</NativeDebugging>
<SQLDebugging>False</SQLDebugging>
<ExternalProgram>
</ExternalProgram>
<StartExternalURL>
</StartExternalURL>
<StartCmdLineArguments>
</StartCmdLineArguments>
<StartWorkingDirectory>
</StartWorkingDirectory>
<EnableENC>False</EnableENC>
<AlwaysStartWebServerOnDebug>False</AlwaysStartWebServerOnDebug>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
</Project>
+1
View File
@@ -0,0 +1 @@
# AAOlivia-Plotter
+256
View File
@@ -0,0 +1,256 @@
function newMastersPlottersCandlesVolumesVolumesVolumePanel() {
let thisObject = {
fitFunction: undefined,
container: undefined,
isVisible: true,
onRecordChange: onRecordChange,
draw: draw,
getContainer: getContainer,
initialize: initialize,
finalize: finalize
};
thisObject.container = newContainer();
thisObject.container.initialize();
thisObject.container.frame.containerName = "Volume";
let currentVolume;
let upDownButton
return thisObject;
function finalize() {
thisObject.container.finalize()
thisObject.container = undefined
thisObject.fitFunction = undefined
thisObject.isVisible = undefined
currentVolume = undefined
upDownButton.finalize()
upDownButton = undefined
}
function initialize() {
thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL;
thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL;
thisObject.container.frame.position.x = UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.topRight.x - thisObject.container.frame.width;
thisObject.container.frame.position.y = UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.bottomLeft.y - thisObject.container.frame.height;
upDownButton = newUpDownButton()
upDownButton.parentContainer = thisObject.container
upDownButton.container.frame.parentFrame = thisObject.container.frame
upDownButton.fitFunction = thisObject.fitFunction
upDownButton.initialize()
}
function getContainer(point) {
if (thisObject.isVisible !== true) { return }
let container;
container = upDownButton.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 onRecordChange(lastCurrentVolume) {
currentVolume = lastCurrentVolume;
}
function draw() {
if (thisObject.isVisible !== true) { return }
thisObject.container.frame.draw(false, false, true, thisObject.fitFunction);
plotCurrentVolumeInfo();
upDownButton.draw()
}
function plotCurrentVolumeInfo() {
if (currentVolume === undefined) { return; }
if (currentVolume.innerVolumeBar === 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_BUY = frameTitleHeight + frameBodyHeight * 0.85;
const Y_AXIS_SELL = frameTitleHeight + frameBodyHeight * 0.15;
let buyVolumePoint1 = {
x: X_AXIS - currentVolume.buyInfo.baseWidth / 2,
y: Y_AXIS_BUY
};
let buyVolumePoint2 = {
x: X_AXIS - currentVolume.buyInfo.topWidth / 2,
y: Y_AXIS_BUY + currentVolume.buyInfo.height
};
let buyVolumePoint3 = {
x: X_AXIS + currentVolume.buyInfo.topWidth / 2,
y: Y_AXIS_BUY + currentVolume.buyInfo.height
};
let buyVolumePoint4 = {
x: X_AXIS + currentVolume.buyInfo.baseWidth / 2,
y: Y_AXIS_BUY
};
/* Extra bounderies due to constrained space */
const upperLimit = frameTitleHeight + frameBodyHeight * 0.15;
const downLimit = frameTitleHeight + frameBodyHeight * 0.85;
const leftLimit = thisObject.container.frame.width * 0.40;
const rightLimit = thisObject.container.frame.width * 0.60;
if (buyVolumePoint1.y < downLimit) { buyVolumePoint1.y = downLimit; }
if (buyVolumePoint4.y < downLimit) { buyVolumePoint4.y = downLimit; }
if (buyVolumePoint2.y < upperLimit) { buyVolumePoint2.y = upperLimit; }
if (buyVolumePoint3.y < upperLimit) { buyVolumePoint3.y = upperLimit; }
if (buyVolumePoint1.x < leftLimit) { buyVolumePoint1.x = leftLimit; }
if (buyVolumePoint2.x < leftLimit) { buyVolumePoint2.x = leftLimit; }
if (buyVolumePoint3.x > rightLimit) { buyVolumePoint3.x = rightLimit; }
if (buyVolumePoint4.x > rightLimit) { buyVolumePoint4.x = rightLimit; }
buyVolumePoint1 = thisObject.container.frame.fitIntoFrame(buyVolumePoint1);
buyVolumePoint2 = thisObject.container.frame.fitIntoFrame(buyVolumePoint2);
buyVolumePoint3 = thisObject.container.frame.fitIntoFrame(buyVolumePoint3);
buyVolumePoint4 = thisObject.container.frame.fitIntoFrame(buyVolumePoint4);
buyVolumePoint1 = thisObject.container.frame.frameThisPoint(buyVolumePoint1);
buyVolumePoint2 = thisObject.container.frame.frameThisPoint(buyVolumePoint2);
buyVolumePoint3 = thisObject.container.frame.frameThisPoint(buyVolumePoint3);
buyVolumePoint4 = thisObject.container.frame.frameThisPoint(buyVolumePoint4);
buyVolumePoint1 = thisObject.fitFunction(buyVolumePoint1)
buyVolumePoint2 = thisObject.fitFunction(buyVolumePoint2)
buyVolumePoint3 = thisObject.fitFunction(buyVolumePoint3)
buyVolumePoint4 = thisObject.fitFunction(buyVolumePoint4)
let sellVolumePoint1 = {
x: X_AXIS - currentVolume.buyInfo.baseWidth / 2,
y: Y_AXIS_SELL
};
let sellVolumePoint2 = {
x: X_AXIS - currentVolume.buyInfo.topWidth / 2,
y: Y_AXIS_SELL + currentVolume.sellInfo.height
};
let sellVolumePoint3 = {
x: X_AXIS + currentVolume.buyInfo.topWidth / 2,
y: Y_AXIS_SELL + currentVolume.sellInfo.height
};
let sellVolumePoint4 = {
x: X_AXIS + currentVolume.buyInfo.baseWidth / 2,
y: Y_AXIS_SELL
};
if (sellVolumePoint1.y < upperLimit) { sellVolumePoint1.y = upperLimit; }
if (sellVolumePoint4.y < upperLimit) { sellVolumePoint4.y = upperLimit; }
if (sellVolumePoint2.y > downLimit) { sellVolumePoint2.y = downLimit; }
if (sellVolumePoint3.y > downLimit) { sellVolumePoint3.y = downLimit; }
if (sellVolumePoint1.x < leftLimit) { sellVolumePoint1.x = leftLimit; }
if (sellVolumePoint2.x < leftLimit) { sellVolumePoint2.x = leftLimit; }
if (sellVolumePoint3.x > rightLimit) { sellVolumePoint3.x = rightLimit; }
if (sellVolumePoint4.x > rightLimit) { sellVolumePoint4.x = rightLimit; }
sellVolumePoint1 = thisObject.container.frame.fitIntoFrame(sellVolumePoint1);
sellVolumePoint2 = thisObject.container.frame.fitIntoFrame(sellVolumePoint2);
sellVolumePoint3 = thisObject.container.frame.fitIntoFrame(sellVolumePoint3);
sellVolumePoint4 = thisObject.container.frame.fitIntoFrame(sellVolumePoint4);
sellVolumePoint1 = thisObject.container.frame.frameThisPoint(sellVolumePoint1);
sellVolumePoint2 = thisObject.container.frame.frameThisPoint(sellVolumePoint2);
sellVolumePoint3 = thisObject.container.frame.frameThisPoint(sellVolumePoint3);
sellVolumePoint4 = thisObject.container.frame.frameThisPoint(sellVolumePoint4);
sellVolumePoint1 = thisObject.fitFunction(sellVolumePoint1)
sellVolumePoint2 = thisObject.fitFunction(sellVolumePoint2)
sellVolumePoint3 = thisObject.fitFunction(sellVolumePoint3)
sellVolumePoint4 = thisObject.fitFunction(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(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + OPACITY + ')';
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + 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(' + UI_COLOR.RED + ', ' + OPACITY + ')';
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + OPACITY + ')';
browserCanvasContext.fill();
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
/* put the labels with the volumes values */
UI.projects.superalgos.utilities.drawPrint.printLabel('Buy Volume', undefined, undefined, X_AXIS, frameTitleHeight + frameBodyHeight * 0.95, '0.60', undefined, undefined, 'Center', thisObject.container, thisObject.fitFunction);
UI.projects.superalgos.utilities.drawPrint.printLabel(currentVolume.innerVolumeBar.amountBuy, undefined, undefined, X_AXIS, frameTitleHeight + frameBodyHeight * 0.90, '1.00', 15, undefined, 'Center', thisObject.container, thisObject.fitFunction);
UI.projects.superalgos.utilities.drawPrint.printLabel('Sell Volume', undefined, undefined, X_AXIS, frameTitleHeight + frameBodyHeight * 0.05, '0.60', undefined, undefined, 'Center', thisObject.container, thisObject.fitFunction);
UI.projects.superalgos.utilities.drawPrint.printLabel(currentVolume.innerVolumeBar.amountSell, undefined, undefined, X_AXIS, frameTitleHeight + frameBodyHeight * 0.10, '1.00', 15, undefined, 'Center', thisObject.container, thisObject.fitFunction);
}
}
+755
View File
@@ -0,0 +1,755 @@
function newMastersPlottersCandlesVolumesVolumes() {
const MODULE_NAME = "Volumes Plotter";
const ERROR_LOG = true;
const INTENSIVE_LOG = false;
const logger = newWebDebugLog();
logger.fileName = MODULE_NAME;
let thisObject = {
/* Events declared outside the plotter. */
onDailyFileLoaded: onDailyFileLoaded,
// Main functions and properties.
initialize: initialize,
finalize: finalize,
container: undefined,
fitFunction: undefined,
getContainer: getContainer,
setTimeFrame: setTimeFrame,
setDatetime: setDatetime,
setCoordinateSystem: setCoordinateSystem,
recalculateScale: recalculateScale,
draw: draw
};
/* this is part of the module template */
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
let coordinateSystem
let timeFrame; // This will hold the current Time Frame the user is at.
let datetime; // This will hold the current Datetime the user is at.
let marketFile; // This is the current Market File being plotted.
let fileCursor; // This is the current File Cursor being used to retrieve Daily Files.
let marketFiles; // This object will provide the different Market Files at different Time Frames.
let dailyFiles; // This object will provide the different File Cursors at different Time Frames.
let scaleFile; // This file is used to calculate the scale.
/* these are module specific variables: */
let volumes = []; // Here we keep the volumes to be ploted every time the Draw() function is called by the AAWebPlatform.
let onMouseOverEventSuscriptionId
let zoomChangedEventSubscriptionId
let offsetChangedEventSubscriptionId
let dragFinishedEventSubscriptionId
let dimmensionsChangedEventSubscriptionId
let marketFilesUpdatedEventSubscriptionId
let dailyFilesUpdatedEventSubscriptionId
let scaleChangedEventSubscriptionId
let userPositionDate
return thisObject;
function finalize() {
try {
/* Stop listening to the necesary events. */
thisObject.container.eventHandler.stopListening(onMouseOverEventSuscriptionId)
UI.projects.superalgos.spaces.chartingSpace.viewport.eventHandler.stopListening(zoomChangedEventSubscriptionId);
UI.projects.superalgos.spaces.chartingSpace.viewport.eventHandler.stopListening(offsetChangedEventSubscriptionId);
canvas.eventHandler.stopListening(dragFinishedEventSubscriptionId);
thisObject.container.eventHandler.stopListening(dimmensionsChangedEventSubscriptionId)
marketFiles.eventHandler.stopListening(marketFilesUpdatedEventSubscriptionId);
dailyFiles.eventHandler.stopListening(dailyFilesUpdatedEventSubscriptionId);
/* Destroyd References */
marketFiles = undefined;
dailyFiles = undefined;
datetime = undefined;
timeFrame = undefined;
marketFile = undefined;
fileCursor = undefined;
thisObject.fitFunction = undefined
finalizeCoordinateSystem()
coordinateSystem = undefined
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] finalize -> err = " + err.stack); }
}
}
function initialize(pStorage, pDatetime, pTimeFrame, pCoordinateSystem, callBackFunction) {
try {
/* Store the information received. */
marketFiles = pStorage.marketFiles[0];
dailyFiles = pStorage.dailyFiles[0];
datetime = pDatetime;
timeFrame = pTimeFrame;
coordinateSystem = pCoordinateSystem
initializeCoordinateSystem()
/* We need a Market File in order to calculate the Y scale, since this scale depends on actual data. */
scaleFile = marketFiles.getFile(ONE_DAY_IN_MILISECONDS); // This file is the one processed faster.
/* Now we set the right files according to current Period. */
marketFile = marketFiles.getFile(pTimeFrame);
fileCursor = dailyFiles.getFileCursor(pTimeFrame);
/* Listen to the necesary events. */
zoomChangedEventSubscriptionId = UI.projects.superalgos.spaces.chartingSpace.viewport.eventHandler.listenToEvent("Zoom Changed", onViewportZoomChanged);
offsetChangedEventSubscriptionId = UI.projects.superalgos.spaces.chartingSpace.viewport.eventHandler.listenToEvent("Position Changed", onViewportPositionChanged);
dragFinishedEventSubscriptionId = canvas.eventHandler.listenToEvent("Drag Finished", onDragFinished);
marketFilesUpdatedEventSubscriptionId = marketFiles.eventHandler.listenToEvent("Files Updated", onMarketFilesUpdated);
dailyFilesUpdatedEventSubscriptionId = dailyFiles.eventHandler.listenToEvent("Files Updated", onDailyFilesUpdated);
onMouseOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
/* Get ready for plotting. */
recalculate();
dimmensionsChangedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('Dimmensions Changed', function () {
recalculate();
})
callBackFunction();
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err.stack); }
}
}
function initializeCoordinateSystem() {
scaleChangedEventSubscriptionId = coordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged)
}
function finalizeCoordinateSystem() {
coordinateSystem.eventHandler.stopListening(scaleChangedEventSubscriptionId)
}
function onScaleChanged() {
recalculate();
}
function onMouseOver(event) {
let userPosition = UI.projects.superalgos.utilities.dateRateTransformations.getDateFromPointAtBrowserCanvas(event, thisObject.container, coordinateSystem)
userPositionDate = userPosition.valueOf()
}
function recalculateScale() {
recalculate();
}
function getContainer(point) {
try {
let container;
/* First we check if this point is inside this space. */
if (thisObject.container.frame.isThisPointHere(point) === true) {
return thisObject.container;
} else {
/* This point does not belong to this space. */
return undefined;
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] getContainer -> err = " + err.stack); }
}
}
function onMarketFilesUpdated() {
try {
let newMarketFile = marketFiles.getFile(timeFrame);
if (newMarketFile !== undefined) {
marketFile = newMarketFile;
recalculate();
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] onMarketFilesUpdated -> err = " + err.stack); }
}
}
function onDailyFilesUpdated() {
try {
let newFileCursor = dailyFiles.getFileCursor(timeFrame);
if (newFileCursor !== undefined) {
fileCursor = newFileCursor;
recalculate();
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] onDailyFilesUpdated -> err = " + err.stack); }
}
}
function setTimeFrame(pTimeFrame) {
try {
if (timeFrame !== pTimeFrame) {
timeFrame = pTimeFrame;
if (timeFrame >= _1_HOUR_IN_MILISECONDS) {
let newMarketFile = marketFiles.getFile(pTimeFrame);
if (newMarketFile !== undefined) {
marketFile = newMarketFile;
recalculate();
}
} else {
let newFileCursor = dailyFiles.getFileCursor(pTimeFrame);
if (newFileCursor !== undefined) {
fileCursor = newFileCursor;
recalculate();
}
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] setTimeFrame -> err = " + err.stack); }
}
}
function setDatetime(pDatetime) {
datetime = pDatetime;
}
function setCoordinateSystem(pCoordinateSystem) {
finalizeCoordinateSystem()
coordinateSystem = pCoordinateSystem
initializeCoordinateSystem()
}
function onDailyFileLoaded(event) {
if (event.currentValue === event.totalValue) {
/* This happens only when all of the files in the cursor have been loaded. */
recalculate();
}
}
function draw() {
try {
if (INTENSIVE_LOG === true) { logger.write("[INFO] draw -> Entering function."); }
thisObject.container.frame.draw();
plotChart();
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] draw -> err = " + err.stack); }
}
}
function recalculate() {
if (timeFrame >= _1_HOUR_IN_MILISECONDS) {
recalculateUsingMarketFiles();
} else {
recalculateUsingDailyFiles();
}
thisObject.container.eventHandler.raiseEvent("Volumes Changed", volumes);
}
function recalculateUsingDailyFiles() {
try {
if (fileCursor === undefined) { return; } // We need to wait
if (fileCursor.files.size === 0) { return; } // We need to wait until there are files in the cursor
let leftDate = UI.projects.superalgos.utilities.dateRateTransformations.getDateFromPointAtBrowserCanvas(UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.topLeft, thisObject.container, coordinateSystem);
let rightDate = UI.projects.superalgos.utilities.dateRateTransformations.getDateFromPointAtBrowserCanvas(UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.topRight, thisObject.container, coordinateSystem);
let dateDiff = rightDate.valueOf() - leftDate.valueOf();
let farLeftDate = new Date(leftDate.valueOf() - dateDiff * 1.5);
let farRightDate = new Date(rightDate.valueOf() + dateDiff * 1.5);
let currentDate = new Date(farLeftDate.valueOf());
volumes = [];
while (currentDate.valueOf() <= farRightDate.valueOf() + ONE_DAY_IN_MILISECONDS) {
let stringDate = currentDate.getUTCFullYear() + '-' + pad(currentDate.getUTCMonth() + 1, 2) + '-' + pad(currentDate.getUTCDate(), 2);
let dailyFile = fileCursor.files.get(stringDate);
if (dailyFile !== undefined) {
for (let i = 0; i < dailyFile.length; i++) {
let volume = {
amountBuy: 0,
amountSell: 0,
begin: undefined,
end: undefined
};
volume.amountBuy = dailyFile[i][0];
volume.amountSell = dailyFile[i][1];
volume.begin = dailyFile[i][2];
volume.end = dailyFile[i][3];
if (
(volume.begin >= farLeftDate.valueOf() && volume.end <= farRightDate.valueOf()) &&
(volume.begin >= coordinateSystem.min.x && volume.end <= coordinateSystem.max.x)
) {
volumes.push(volume);
if (datetime.valueOf() >= volume.begin && datetime.valueOf() <= volume.end) {
thisObject.container.eventHandler.raiseEvent("Current Record Changed", thisObject.currentCandle);
}
}
}
}
currentDate = new Date(currentDate.valueOf() + ONE_DAY_IN_MILISECONDS);
}
/* Lests check if all the visible screen is going to be covered by volumes. */
let lowerEnd = leftDate.valueOf();
let upperEnd = rightDate.valueOf();
if (volumes.length > 0) {
if (volumes[0].begin > lowerEnd || volumes[volumes.length - 1].end < upperEnd) {
setTimeout(recalculate, 2000);
//console.log("File missing while calculating volumes, scheduling a recalculation in 2 seconds.");
}
}
//console.log("Olivia > recalculateUsingDailyFiles > total volumes generated : " + volumes.length);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] recalculateUsingDailyFiles -> err = " + err.stack); }
}
}
function recalculateUsingMarketFiles() {
try {
if (marketFile === undefined) { return; } // Initialization not complete yet.
let leftDate = UI.projects.superalgos.utilities.dateRateTransformations.getDateFromPointAtBrowserCanvas(UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.topLeft, thisObject.container, coordinateSystem);
let rightDate = UI.projects.superalgos.utilities.dateRateTransformations.getDateFromPointAtBrowserCanvas(UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.topRight, thisObject.container, coordinateSystem);
let dateDiff = rightDate.valueOf() - leftDate.valueOf();
leftDate = new Date(leftDate.valueOf() - dateDiff * 1.5);
rightDate = new Date(rightDate.valueOf() + dateDiff * 1.5);
volumes = [];
for (let i = 0; i < marketFile.length; i++) {
let volume = {
amountBuy: 0,
amountSell: 0,
begin: undefined,
end: undefined
};
volume.amountBuy = marketFile[i][0];
volume.amountSell = marketFile[i][1];
volume.begin = marketFile[i][2];
volume.end = marketFile[i][3];
if (
(volume.begin >= leftDate.valueOf() && volume.end <= rightDate.valueOf()) &&
(volume.begin >= coordinateSystem.min.x && volume.end <= coordinateSystem.max.x)
) {
volumes.push(volume);
if (datetime.valueOf() >= volume.begin && datetime.valueOf() <= volume.end) {
thisObject.container.eventHandler.raiseEvent("Current Record Changed", thisObject.currentCandle);
}
}
}
//console.log("Olivia > recalculateUsingMarketFiles > total volumes generated : " + volumes.length);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] recalculateUsingMarketFiles -> err = " + err.stack); }
}
}
function plotChart() {
try {
let lowResolution = false
if (UI.projects.superalgos.spaces.chartingSpace.viewport.zoomTargetLevel < UI.projects.superalgos.globals.zoom.ZOOM_OUT_THRESHOLD_FOR_PLOTTING_IN_LOW_RESOLUTION) {
if (volumes.length > 100) {
lowResolution = true
}
}
if (volumes.length > 0) {
/* Now we calculate and plot the volumes */
let visibleHeight = UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.bottomRight.y - UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.topLeft.y;
let frameCorner1 = {
x: 0,
y: 0
};
let frameCorner2 = {
x: thisObject.container.frame.width,
y: thisObject.container.frame.height
};
/* Now the transformations. */
frameCorner1 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(frameCorner1, thisObject.container.frame.container);
frameCorner2 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(frameCorner2, thisObject.container.frame.container);
let frameHeightInViewPort = frameCorner2.y - frameCorner1.y;
if (volumes.length > 0) {
for (let i = 0; i < volumes.length; i++) {
volume = volumes[i];
let volumePointA1;
let volumePointA2;
let volumePointA3;
let volumePointA4;
function calculateBuys(plot, height) {
volumePointA1 = {
x: volume.begin + timeFrame / 7 * 2,
y: 0
};
volumePointA2 = {
x: volume.begin + timeFrame / 7 * 2,
y: volume.amountBuy
};
volumePointA3 = {
x: volume.begin + timeFrame / 7 * 5,
y: volume.amountBuy
};
volumePointA4 = {
x: volume.begin + timeFrame / 7 * 5,
y: 0
};
volumePointA1 = plot.transformThisPoint(volumePointA1);
volumePointA2 = plot.transformThisPoint(volumePointA2);
volumePointA3 = plot.transformThisPoint(volumePointA3);
volumePointA4 = plot.transformThisPoint(volumePointA4);
volumePointA1 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(volumePointA1, thisObject.container);
volumePointA2 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(volumePointA2, thisObject.container);
volumePointA3 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(volumePointA3, thisObject.container);
volumePointA4 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(volumePointA4, thisObject.container);
let baseIncrement = (volumePointA3.x - volumePointA1.x) * WIDHTER_VOLUME_BAR_BASE_FACTOR;
volumePointA1.x = volumePointA1.x - baseIncrement;
volumePointA4.x = volumePointA4.x + baseIncrement;
if (volumePointA4.x < UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.bottomLeft.x || volumePointA1.x > UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.bottomRight.x) {
return false;
}
return true;
}
if (calculateBuys(coordinateSystem, thisObject.container.frame.height) === false) { continue; } // We try to see if it fits in the visible area.
let diffA = volumePointA1.y - UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.bottomLeft.y
if (diffA > 0) {
volumePointA1.y = volumePointA1.y - diffA
volumePointA2.y = volumePointA2.y - diffA
volumePointA3.y = volumePointA3.y - diffA
volumePointA4.y = volumePointA4.y - diffA
}
let volumePointB1;
let volumePointB2;
let volumePointB3;
let volumePointB4;
function calculateSells(plot, height) {
volumePointB1 = {
x: volume.begin + timeFrame / 7 * 2,
y: height
};
volumePointB2 = {
x: volume.begin + timeFrame / 7 * 2,
y: height - volume.amountSell
};
volumePointB3 = {
x: volume.begin + timeFrame / 7 * 5,
y: height - volume.amountSell
};
volumePointB4 = {
x: volume.begin + timeFrame / 7 * 5,
y: height
};
volumePointB1 = plot.transformThisPoint2(volumePointB1);
volumePointB2 = plot.transformThisPoint2(volumePointB2);
volumePointB3 = plot.transformThisPoint2(volumePointB3);
volumePointB4 = plot.transformThisPoint2(volumePointB4);
volumePointB1 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(volumePointB1, thisObject.container);
volumePointB2 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(volumePointB2, thisObject.container);
volumePointB3 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(volumePointB3, thisObject.container);
volumePointB4 = UI.projects.superalgos.utilities.coordinateTransformations.transformThisPoint(volumePointB4, thisObject.container);
}
calculateSells(coordinateSystem, thisObject.container.frame.height); // We try to see if it fits in the visible area.
let diffB = volumePointB1.y - UI.projects.superalgos.spaces.chartingSpace.viewport.visibleArea.topLeft.y
if (diffB < 0) {
volumePointB1.y = volumePointB1.y - diffB
volumePointB2.y = volumePointB2.y - diffB
volumePointB3.y = volumePointB3.y - diffB
volumePointB4.y = volumePointB4.y - diffB
}
/* We put a wider base */
let baseIncrement = (volumePointB3.x - volumePointB1.x) * WIDHTER_VOLUME_BAR_BASE_FACTOR;
volumePointB1.x = volumePointB1.x - baseIncrement;
volumePointB4.x = volumePointB4.x + baseIncrement;
/* We put a less wider top */
let baseDencrement = (volumePointA3.x - volumePointA2.x) * LESS_WIDHTER_VOLUME_BAR_TOP_FACTOR;
volumePointA2.x = volumePointA2.x + baseDencrement;
volumePointA3.x = volumePointA3.x - baseDencrement;
volumePointB2.x = volumePointB2.x + baseDencrement;
volumePointB3.x = volumePointB3.x - baseDencrement;
/* Everything must fit within the visible area */
volumePointA1 = UI.projects.superalgos.spaces.chartingSpace.viewport.fitIntoVisibleArea(volumePointA1);
volumePointA2 = UI.projects.superalgos.spaces.chartingSpace.viewport.fitIntoVisibleArea(volumePointA2);
volumePointA3 = UI.projects.superalgos.spaces.chartingSpace.viewport.fitIntoVisibleArea(volumePointA3);
volumePointA4 = UI.projects.superalgos.spaces.chartingSpace.viewport.fitIntoVisibleArea(volumePointA4);
volumePointB1 = UI.projects.superalgos.spaces.chartingSpace.viewport.fitIntoVisibleArea(volumePointB1);
volumePointB2 = UI.projects.superalgos.spaces.chartingSpace.viewport.fitIntoVisibleArea(volumePointB2);
volumePointB3 = UI.projects.superalgos.spaces.chartingSpace.viewport.fitIntoVisibleArea(volumePointB3);
volumePointB4 = UI.projects.superalgos.spaces.chartingSpace.viewport.fitIntoVisibleArea(volumePointB4);
volumePointA1 = thisObject.fitFunction(volumePointA1);
volumePointA2 = thisObject.fitFunction(volumePointA2);
volumePointA3 = thisObject.fitFunction(volumePointA3);
volumePointA4 = thisObject.fitFunction(volumePointA4);
volumePointB1 = thisObject.fitFunction(volumePointB1);
volumePointB2 = thisObject.fitFunction(volumePointB2);
volumePointB3 = thisObject.fitFunction(volumePointB3);
volumePointB4 = thisObject.fitFunction(volumePointB4);
/* Everything must fit within the Frame. We know that that is equivalent to say that each bar con not be higher than the base of the opposite . */
if (volumePointA2.y < volumePointB1.y) {
volumePointA2.y = volumePointB1.y;
volumePointA3.y = volumePointB1.y;
}
if (volumePointB2.y > volumePointA1.y) {
volumePointB2.y = volumePointA1.y;
volumePointB3.y = volumePointA1.y;
}
/* Now the drawing of the volume bars*/
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(volumePointA1.x, volumePointA1.y);
browserCanvasContext.lineTo(volumePointA2.x, volumePointA2.y);
browserCanvasContext.lineTo(volumePointA3.x, volumePointA3.y);
browserCanvasContext.lineTo(volumePointA4.x, volumePointA4.y);
browserCanvasContext.closePath();
if (lowResolution === false) {
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREEN + ', 0.40)';
if (userPositionDate >= volume.begin && userPositionDate <= volume.end) {
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 0.40)'; // Current bar accroding to time
}
}
browserCanvasContext.fill();
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', 0.40)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.stroke();
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(volumePointB1.x, volumePointB1.y);
browserCanvasContext.lineTo(volumePointB2.x, volumePointB2.y);
browserCanvasContext.lineTo(volumePointB3.x, volumePointB3.y);
browserCanvasContext.lineTo(volumePointB4.x, volumePointB4.y);
browserCanvasContext.closePath();
if (lowResolution === false) {
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', 0.40)';
if (userPositionDate >= volume.begin && userPositionDate <= volume.end) {
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 0.40)'; // Current volume accroding to time
}
browserCanvasContext.fill();
}
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', 0.40)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.stroke();
if (userPositionDate >= volume.begin && userPositionDate <= volume.end) {
let buyInfo = {
baseWidth: volumePointA4.x - volumePointA1.x,
topWidth: volumePointA3.x - volumePointA2.x,
height: volumePointA2.y - volumePointA1.y
};
let sellInfo = {
baseWidth: volumePointB4.x - volumePointB1.x,
topWidth: volumePointB3.x - volumePointB2.x,
height: volumePointB2.y - volumePointB1.y
};
let currentVolume = {
buyInfo: buyInfo,
sellInfo: sellInfo,
period: timeFrame,
innerVolumeBar: volume
};
thisObject.container.eventHandler.raiseEvent("Current Record Changed", currentVolume);
}
/* Contributing to Auto-Scale*/
coordinateSystem.reportYValue(volume.amountBuy * 5)
coordinateSystem.reportYValue(volume.amountSell * 5)
coordinateSystem.reportYValue(0)
}
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] plotChart -> err = " + err.stack); }
}
}
function onViewportZoomChanged(event) {
recalculate()
}
function onViewportPositionChanged(event) {
try {
if (event !== undefined) {
if (event.recalculate === true) {
recalculate();
return
}
}
if (Math.random() * 100 > 95) {
recalculate();
};
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] onViewportPositionChanged -> err = " + err.stack); }
}
}
function onDragFinished() {
recalculate();
}
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+33
View File
@@ -0,0 +1,33 @@
{
"displayName": "Plotters Candles & Volumes",
"codeName": "PlottersCandlesVolumes",
"dataMine": "Masters",
"modules": [
{
"codeName": "Candles",
"moduleName": "Candles",
"description": "Plots traditional red and green candles.",
"profilePicture": "Candles.png",
"panels": [
{
"codeName": "CandlePanel",
"moduleName": "CandlePanel",
"event": "Current Record Changed"
}
]
},
{
"codeName": "Volumes",
"description": "Plots volumes separated in buy and sell.",
"moduleName": "Volumes",
"profilePicture": "Volumes.png",
"panels": [
{
"codeName": "VolumePanel",
"moduleName": "VolumePanel",
"event": "Current Record Changed"
}
]
}
]
}