Implementation Finished

This commit is contained in:
Luis Fernando Molina committed 2020-07-23 14:35:23 +02:00
1 parent e84f8a6ed1
commit 6ec5580cd4
32 files changed
+1335 -6639

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -1,799 +0,0 @@
function newTradingEnginesPlottersTradingSimulationSimulationExecution() {
const MODULE_NAME = "Simulation Execution Plotter";
const INTENSIVE_LOG = false;
const ERROR_LOG = true;
const logger = newWebDebugLog();
logger.fileName = MODULE_NAME;
let thisObject = {
// Main functions and properties.
initialize: initialize,
finalize: finalize,
container: undefined,
fitFunction: undefined,
getContainer: getContainer,
setTimeFrame: setTimeFrame,
setDatetime: setDatetime,
setCoordinateSystem: setCoordinateSystem,
draw: draw
};
/* this is part of the module template */
let container = newContainer(); // Do not touch this 3 lines, they are just needed.
container.initialize();
thisObject.container = container;
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.
/* these are module specific variables: */
let fileSequence;
let plotElements = []; // This is where the elements to be plotted are stored before plotting.
let plotLines = []; // Here we store the lines of open positions.
let previousNotesSetKey;
let onMouseOverEventSuscriptionId
let offsetChangedEventSubscriptionId
let filesUpdatedEventSubscriptionId
let dimmensionsChangedEventSubscriptionId
let scaleChangedEventSubscriptionId
let userPositionDate
return thisObject;
function finalize() {
try {
/* Stop listening to the necesary events. */
thisObject.container.eventHandler.stopListening(onMouseOverEventSuscriptionId)
canvas.chartingSpace.viewport.eventHandler.stopListening(offsetChangedEventSubscriptionId);
fileSequence.eventHandler.stopListening(filesUpdatedEventSubscriptionId);
thisObject.container.eventHandler.stopListening(dimmensionsChangedEventSubscriptionId)
/* Destroyd References */
datetime = undefined;
timeFrame = undefined;
fileSequence = undefined;
plotElements = undefined;
plotLines = undefined;
thisObject.fitFunction = undefined
finalizeCoordinateSystem()
coordinateSystem = undefined
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] ' + MODULE_NAME + ' -> finalize -> err = " + err.stack.stack); }
}
}
function initialize(pStorage, pDatetime, pTimeFrame, pCoordinateSystem, callBackFunction) {
try {
datetime = pDatetime;
timeFrame = pTimeFrame;
coordinateSystem = pCoordinateSystem
initializeCoordinateSystem()
fileSequence = pStorage.fileSequences[0];
recalculate();
filesUpdatedEventSubscriptionId = fileSequence.eventHandler.listenToEvent("Files Updated", onFilesUpdated); // Only the first sequence is supported right now.
offsetChangedEventSubscriptionId = canvas.chartingSpace.viewport.eventHandler.listenToEvent("Position Changed", onViewportPositionChanged);
onMouseOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
/* Ready for when dimmension changes. */
dimmensionsChangedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('Dimmensions Changed', function () {
recalculate();
})
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] ' + MODULE_NAME + ' -> initialize -> err = " + err.stack); }
callBackFunction(GLOBAL.CUSTOM_FAIL_RESPONSE);
}
}
function initializeCoordinateSystem() {
scaleChangedEventSubscriptionId = coordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged)
}
function finalizeCoordinateSystem() {
coordinateSystem.eventHandler.stopListening(scaleChangedEventSubscriptionId)
}
function onScaleChanged() {
recalculate();
}
function onMouseOver(event) {
let userPosition = 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 (this.container.frame.isThisPointHere(point) === true) {
return this.container;
} else {
/* This point does not belong to this space. */
return undefined;
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] ' + MODULE_NAME + ' -> initialize -> err = " + err.stack); }
}
}
function onFilesUpdated() {
recalculate();
}
function setTimeFrame(pTimeFrame) {
timeFrame = pTimeFrame;
recalculate();
}
function setDatetime(pDatetime) {
datetime = pDatetime;
}
function setCoordinateSystem(pCoordinateSystem) {
finalizeCoordinateSystem()
coordinateSystem = pCoordinateSystem
initializeCoordinateSystem()
}
function onViewportPositionChanged() {
if (Math.random() * 100 > 95) {
recalculate()
}
}
function recalculate() {
try {
if (fileSequence === undefined) { return; }
/*
We are going to filter the records depending on the Time Frame. We want that for a 1 min time peroid all the records appears on screen,
but for higher periods, we will filter out some records, so that they do not overlap ever.
*/
plotElements = [];
plotLines = [];
let lastSellRate;
let lastSellDate;
let sellExecRate;
let lastBuyRate;
let lastBuyDate;
let buyExecRate;
let maxSequence = fileSequence.getFilesLoaded();
for (let j = 0; j < maxSequence; j++) {
let file = fileSequence.getFile(j);
let history = [];
let lines = [];
/* First the small balls */
const ONE_MIN_IN_MILISECONDS = 60 * 1000;
let step = timeFrame / ONE_MIN_IN_MILISECONDS;
step = 1; // For now we dont discard records depending on the zoom level.
let i = 0;
let lastRecordPushed = 0;
for (i = 0; i < file.length; i = i + step) {
let newHistoryRecord = {
date: Math.trunc(file[i][0] / 60000) * 60000 + 30000,
buyAvgRate: file[i][1],
sellAvgRate: file[i][2],
lastSellRate: file[i][3],
sellExecRate: file[i][4],
lastBuyRate: file[i][5],
buyExecRate: file[i][6],
marketRate: file[i][7],
newPositions: file[i][8],
newTrades: file[i][9],
movedPositions: file[i][10],
profitsAssetA: file[i][11],
profitsAssetB: file[i][12],
combinedProfitsA: file[i][13],
combinedProfitsB: file[i][14],
datetime: file[i][0]
};
/* Finally we add this History Record to the Array */
history.push(newHistoryRecord);
lastRecordPushed = i;
/* Here we build the lines. */
//if (timeFrame <= 1 * 60 * 1000) {
if (newHistoryRecord.lastSellRate > 0) {
lastSellRate = newHistoryRecord.lastSellRate;
lastSellDate = newHistoryRecord.date;
}
if (newHistoryRecord.sellExecRate > 0) {
let newLine = {
type: "sell",
x1: lastSellDate,
y1: lastSellRate,
x2: newHistoryRecord.date,
y2: newHistoryRecord.sellExecRate
};
lines.push(newLine);
}
if (newHistoryRecord.lastBuyRate > 0) {
lastBuyRate = newHistoryRecord.lastBuyRate;
lastBuyDate = newHistoryRecord.date;
}
if (newHistoryRecord.buyExecRate > 0) {
let newLine = {
type: "buy",
x1: lastBuyDate,
y1: lastBuyRate,
x2: newHistoryRecord.date,
y2: newHistoryRecord.buyExecRate
};
lines.push(newLine);
}
//}
}
/* We allways want to put the last record of the file on the filterd dataset, so as to allways show the latest advance of the bot. */
i = file.length - 1;
if (lastRecordPushed !== i) {
let newHistoryRecord = {
date: Math.trunc(file[i][0] / 60000) * 60000 + 30000,
buyAvgRate: file[i][1],
sellAvgRate: file[i][2],
lastSellRate: file[i][3],
sellExecRate: file[i][4],
lastBuyRate: file[i][5],
buyExecRate: file[i][6],
marketRate: file[i][7],
newPositions: file[i][8],
newTrades: file[i][9],
movedPositions: file[i][10],
profitsAssetA: file[i][11],
profitsAssetB: file[i][12],
combinedProfitsA: file[i][13],
combinedProfitsB: file[i][14]
};
history.push(newHistoryRecord);
}
for (let i = 0; i < file.length; i++) {
let newHistoryRecord = {
date: Math.trunc(file[i][0] / 60000) * 60000 + 30000,
buyAvgRate: file[i][1],
sellAvgRate: file[i][2],
lastSellRate: file[i][3],
sellExecRate: file[i][4],
lastBuyRate: file[i][5],
buyExecRate: file[i][6],
marketRate: file[i][7],
newPositions: file[i][8],
newTrades: file[i][9],
movedPositions: file[i][10],
profitsAssetA: file[i][11],
profitsAssetB: file[i][12],
combinedProfitsA: file[i][13],
combinedProfitsB: file[i][14]
};
}
plotElements.push(history);
plotLines.push(lines);
}
thisObject.container.eventHandler.raiseEvent("History Changed", history);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] ' + MODULE_NAME + ' -> recalculate -> err = " + err.stack); }
}
}
function draw() {
plotChart();
}
function plotChart() {
try {
let record
let point = {
x: 0,
y: 0
};
let history;
for (let j = 0; j < plotElements.length; j++) {
let history = plotElements[j];
for (let i = 0; i < history.length; i++) {
record = history[i];
record = record
let timestamp = record.date // Math.trunc(record.date / timeFrame) * timeFrame + timeFrame / 2;
point = {
x: timestamp,
y: record.marketRate
};
point = coordinateSystem.transformThisPoint(point);
point = transformThisPoint(point, thisObject.container);
if (point.x < canvas.chartingSpace.viewport.visibleArea.bottomLeft.x || point.x > canvas.chartingSpace.viewport.visibleArea.bottomRight.x) { continue; }
point = canvas.chartingSpace.viewport.fitIntoVisibleArea(point);
point = thisObject.fitFunction(point);
let isCurrentRecord = false;
if (userPositionDate >= record.date - 30000 && userPositionDate <= record.date + 30000 - 1) {
isCurrentRecord = true;
}
let opacity = '1';
let currentRadius = 10
/* Draw a red inverted triangle on exec sell */
if (record.sellExecRate > 0) {
opacity = '1';
let normalSize = 5
let extraSize = 0
if (isCurrentRecord) { extraSize = 5 }
let point1 = {
x: record.date,
y: record.sellExecRate
};
let point2 = {
x: record.date + timeFrame / 7 * (normalSize + extraSize),
y: record.sellExecRate
};
let point3 = {
x: record.date - timeFrame / 7 * (normalSize + extraSize),
y: record.sellExecRate
};
point1 = coordinateSystem.transformThisPoint(point1);
point1 = transformThisPoint(point1, thisObject.container);
point1 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point1);
point1 = thisObject.fitFunction(point1);
point2 = coordinateSystem.transformThisPoint(point2);
point2 = transformThisPoint(point2, thisObject.container);
point2 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point2);
point2 = thisObject.fitFunction(point2);
point3 = coordinateSystem.transformThisPoint(point3);
point3 = transformThisPoint(point3, thisObject.container);
point3 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point3);
point3 = thisObject.fitFunction(point3);
let diff = point2.x - point3.x;
point2.y = point2.y - diff;
point3.y = point3.y - diff;
record.timeFrame = diff
point2 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point2);
point3 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point3);
point2 = thisObject.fitFunction(point2);
point3 = thisObject.fitFunction(point3);
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point1.x, point1.y);
browserCanvasContext.closePath();
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')';
if (isCurrentRecord === false) {
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + opacity + ')';
} else {
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */
}
browserCanvasContext.fill();
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.lineWidth = 0.25;
browserCanvasContext.stroke();
}
/* Draw a green triangle on exec buy */
if (record.buyExecRate > 0) {
opacity = '1';
let normalSize = 5
let extraSize = 0
if (isCurrentRecord) { extraSize = 5 }
let point1 = {
x: record.date,
y: record.buyExecRate
};
let point2 = {
x: record.date + timeFrame / 7 * (normalSize + extraSize),
y: record.buyExecRate
};
let point3 = {
x: record.date - timeFrame / 7 * (normalSize + extraSize),
y: record.buyExecRate
};
point1 = coordinateSystem.transformThisPoint(point1);
point1 = transformThisPoint(point1, thisObject.container);
point1 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point1);
point1 = thisObject.fitFunction(point1);
point2 = coordinateSystem.transformThisPoint(point2);
point2 = transformThisPoint(point2, thisObject.container);
point2 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point2);
point2 = thisObject.fitFunction(point2);
point3 = coordinateSystem.transformThisPoint(point3);
point3 = transformThisPoint(point3, thisObject.container);
point3 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point3);
point3 = thisObject.fitFunction(point3);
let diff = point2.x - point3.x;
point2.y = point2.y + diff;
point3.y = point3.y + diff;
record.timeFrame = diff
point2 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point2);
point3 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point3);
point2 = thisObject.fitFunction(point2);
point3 = thisObject.fitFunction(point3);
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point1.x, point1.y);
browserCanvasContext.closePath();
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + opacity + ')';
if (isCurrentRecord === false) {
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + opacity + ')';
} else {
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */
}
browserCanvasContext.fill();
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.lineWidth = 0.25;
browserCanvasContext.stroke();
}
/* Draw a red inverted triangle on sell */
if (record.lastSellRate > 0) {
opacity = '1';
let normalSize = 5
let extraSize = 0
if (isCurrentRecord) { extraSize = 5 }
let point1 = {
x: record.date,
y: record.lastSellRate
};
let point2 = {
x: record.date + timeFrame / 7 * (normalSize + extraSize),
y: record.lastSellRate
};
let point3 = {
x: record.date - timeFrame / 7 * (normalSize + extraSize),
y: record.lastSellRate
};
point1 = coordinateSystem.transformThisPoint(point1);
point1 = transformThisPoint(point1, thisObject.container);
point1 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point1);
point1 = thisObject.fitFunction(point1);
point2 = coordinateSystem.transformThisPoint(point2);
point2 = transformThisPoint(point2, thisObject.container);
point2 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point2);
point2 = thisObject.fitFunction(point2);
point3 = coordinateSystem.transformThisPoint(point3);
point3 = transformThisPoint(point3, thisObject.container);
point3 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point3);
point3 = thisObject.fitFunction(point3);
let diff = point2.x - point3.x;
point2.y = point2.y - diff;
point3.y = point3.y - diff;
record.timeFrame = diff
point2 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point2);
point3 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point3);
point2 = thisObject.fitFunction(point2);
point3 = thisObject.fitFunction(point3);
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point1.x, point1.y);
browserCanvasContext.closePath();
if (isCurrentRecord === false) {
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ')';
} else {
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */
}
browserCanvasContext.fill();
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + opacity + ')';
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.lineWidth = 0.25;
browserCanvasContext.stroke();
}
/* Draw a green triangle on buy */
if (record.lastBuyRate > 0) {
opacity = '1';
let normalSize = 5
let extraSize = 0
if (isCurrentRecord) { extraSize = 5 }
let point1 = {
x: record.date,
y: record.lastBuyRate
};
let point2 = {
x: record.date + timeFrame / 7 * (normalSize + extraSize),
y: record.lastBuyRate
};
let point3 = {
x: record.date - timeFrame / 7 * (normalSize + extraSize),
y: record.lastBuyRate
};
point1 = coordinateSystem.transformThisPoint(point1);
point1 = transformThisPoint(point1, thisObject.container);
point1 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point1);
point1 = thisObject.fitFunction(point1);
point2 = coordinateSystem.transformThisPoint(point2);
point2 = transformThisPoint(point2, thisObject.container);
point2 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point2);
point2 = thisObject.fitFunction(point2);
point3 = coordinateSystem.transformThisPoint(point3);
point3 = transformThisPoint(point3, thisObject.container);
point3 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point3);
point3 = thisObject.fitFunction(point3);
let diff = point2.x - point3.x;
point2.y = point2.y + diff;
point3.y = point3.y + diff;
record.timeFrame = diff
point2 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point2);
point3 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point3);
point2 = thisObject.fitFunction(point2);
point3 = thisObject.fitFunction(point3);
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point1.x, point1.y);
browserCanvasContext.closePath();
if (isCurrentRecord === false) {
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ')';
} else {
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */
}
browserCanvasContext.fill();
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + opacity + ')';
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.lineWidth = 0.25;
browserCanvasContext.stroke();
}
/* Send the current record to the panel */
if (userPositionDate >= record.date - 30000 && userPositionDate < record.date + 30000) {
thisObject.container.eventHandler.raiseEvent("Current Record Changed", record);
}
/* Circles */
let radius = 2;
currentRadius = 10
/* Outer Circle */
if (isCurrentRecord === true) {
browserCanvasContext.beginPath();
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')';
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */
browserCanvasContext.arc(point.x, point.y, currentRadius, 0, Math.PI * 2, true);
browserCanvasContext.closePath();
if (point.x < canvas.chartingSpace.viewport.visibleArea.topLeft.x + 50 || point.x > canvas.chartingSpace.viewport.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else {
browserCanvasContext.fill();
}
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.lineWidth = 0.25;
browserCanvasContext.stroke();
}
/* Inner Circle */
browserCanvasContext.beginPath();
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')';
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + opacity + ')';
browserCanvasContext.arc(point.x, point.y, radius, 0, Math.PI * 2, true);
browserCanvasContext.closePath();
if (point.x < canvas.chartingSpace.viewport.visibleArea.topLeft.x + 50 || point.x > canvas.chartingSpace.viewport.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else {
browserCanvasContext.fill();
}
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.lineWidth = 0.25;
browserCanvasContext.stroke();
}
/* Draw the lines connecting plot elements. */
let lines = plotLines[j];
for (let i = 0; i < lines.length; i++) {
let line = lines[i];
opacity = '1';
let point1 = {
x: line.x1,
y: line.y1
};
let point2 = {
x: line.x2,
y: line.y2
};
point1 = coordinateSystem.transformThisPoint(point1);
point1 = transformThisPoint(point1, thisObject.container);
point1 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point1);
point1 = thisObject.fitFunction(point1);
point2 = coordinateSystem.transformThisPoint(point2);
point2 = transformThisPoint(point2, thisObject.container);
point2 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point2);
point2 = thisObject.fitFunction(point2);
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.closePath();
if (line.type === "sell") {
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + opacity + ')';
} else {
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + opacity + ')';
}
browserCanvasContext.setLineDash([4, 1])
browserCanvasContext.lineWidth = 0.25;
browserCanvasContext.stroke();
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] ' + MODULE_NAME + ' -> plotChart -> err = " + err.stack); }
}
}
}
@@ -1,465 +0,0 @@
function newTradingEnginesPlottersTradingSimulationSimulationExecutionSimulationExecutionPanel() {
let thisObject = {
fitFunction: undefined,
container: undefined,
isVisible: true,
onRecordChange: onRecordChange,
draw: draw,
getContainer: getContainer,
initialize: initialize,
finalize: finalize
};
let container = newContainer();
container.initialize();
thisObject.container = container;
container.frame.containerName = "Trading Execution";
let record;
let upDownButton
return thisObject;
function finalize() {
thisObject.container.finalize()
thisObject.container = undefined
thisObject.fitFunction = undefined
thisObject.isVisible = undefined
record = undefined
upDownButton.finalize()
upDownButton = undefined
}
function initialize() {
thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL;
thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL * 2.5;
thisObject.container.frame.position.x = canvas.chartingSpace.viewport.visibleArea.topLeft.x + thisObject.container.frame.width * 4;
thisObject.container.frame.position.y = canvas.chartingSpace.viewport.visibleArea.topRight.y;
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) {
record = lastCurrentCandle;
}
function draw() {
if (thisObject.isVisible !== true) { return }
thisObject.container.frame.draw(false, false, true, thisObject.fitFunction);
plot();
upDownButton.draw()
}
function plot() {
if (record === undefined) { return; }
const frameBodyHeight = thisObject.container.frame.getBodyHeight();
const frameTitleHeight = thisObject.container.frame.height - frameBodyHeight;
const X_AXIS = thisObject.container.frame.width / 2;
const Y_AXIS = frameTitleHeight + frameBodyHeight / 2;
record = record
point = {
x: X_AXIS,
y: Y_AXIS
};
point = thisObject.container.frame.frameThisPoint(point);
point = thisObject.fitFunction(point);
let isCurrentRecord = true;
let radius = 2;
let currentRadius = 10
let opacity = '1';
/* Draw a red inverted triangle on exec sell */
if (record.sellExecRate > 0) {
opacity = '1';
let point1 = {
x: X_AXIS,
y: Y_AXIS
};
let point2 = {
x: X_AXIS + record.timeFrame / 4,
y: Y_AXIS
};
let point3 = {
x: X_AXIS - record.timeFrame / 4,
y: Y_AXIS
};
point1 = thisObject.container.frame.frameThisPoint(point1);
point1 = thisObject.fitFunction(point1);
point2 = thisObject.container.frame.frameThisPoint(point2);
point2 = thisObject.fitFunction(point2);
point3 = thisObject.container.frame.frameThisPoint(point3);
point3 = thisObject.fitFunction(point3);
let diff = point2.x - point3.x;
point2.y = point2.y - diff;
point3.y = point3.y - diff;
point2 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point2);
point3 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point3);
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point1.x, point1.y);
browserCanvasContext.closePath();
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')';
if (isCurrentRecord === false) {
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + opacity + ')';
} else {
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */
}
browserCanvasContext.fill();
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.stroke();
}
/* Draw a green triangle on exec buy */
if (record.buyExecRate > 0) {
opacity = '1';
let point1 = {
x: X_AXIS,
y: Y_AXIS
};
let point2 = {
x: X_AXIS + record.timeFrame / 4,
y: Y_AXIS
};
let point3 = {
x: X_AXIS - record.timeFrame / 4,
y: Y_AXIS
};
point1 = thisObject.container.frame.frameThisPoint(point1);
point1 = thisObject.fitFunction(point1);
point2 = thisObject.container.frame.frameThisPoint(point2);
point2 = thisObject.fitFunction(point2);
point3 = thisObject.container.frame.frameThisPoint(point3);
point3 = thisObject.fitFunction(point3);
let diff = point2.x - point3.x;
point2.y = point2.y + diff;
point3.y = point3.y + diff;
point2 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point2);
point3 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point3);
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point1.x, point1.y);
browserCanvasContext.closePath();
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + opacity + ')';
if (isCurrentRecord === false) {
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + opacity + ')';
} else {
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */
}
browserCanvasContext.fill();
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.stroke();
}
/* Draw a red inverted triangle on sell */
if (record.lastSellRate > 0) {
opacity = '1';
let point1 = {
x: X_AXIS,
y: Y_AXIS
};
let point2 = {
x: X_AXIS + record.timeFrame / 4,
y: Y_AXIS
};
let point3 = {
x: X_AXIS - record.timeFrame / 4,
y: Y_AXIS
};
point1 = thisObject.container.frame.frameThisPoint(point1);
point1 = thisObject.fitFunction(point1);
point2 = thisObject.container.frame.frameThisPoint(point2);
point2 = thisObject.fitFunction(point2);
point3 = thisObject.container.frame.frameThisPoint(point3);
point3 = thisObject.fitFunction(point3);
let diff = point2.x - point3.x;
point2.y = point2.y - diff;
point3.y = point3.y - diff;
point2 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point2);
point3 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point3);
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point1.x, point1.y);
browserCanvasContext.closePath();
if (isCurrentRecord === false) {
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ')';
} else {
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */
}
browserCanvasContext.fill();
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + opacity + ')';
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.stroke();
}
/* Draw a green triangle on buy */
if (record.lastBuyRate > 0) {
opacity = '1';
let point1 = {
x: X_AXIS,
y: Y_AXIS
};
let point2 = {
x: X_AXIS + record.timeFrame / 4,
y: Y_AXIS
};
let point3 = {
x: X_AXIS - record.timeFrame / 4,
y: Y_AXIS
};
point1 = thisObject.container.frame.frameThisPoint(point1);
point1 = thisObject.fitFunction(point1);
point2 = thisObject.container.frame.frameThisPoint(point2);
point2 = thisObject.fitFunction(point2);
point3 = thisObject.container.frame.frameThisPoint(point3);
point3 = thisObject.fitFunction(point3);
let diff = point2.x - point3.x;
point2.y = point2.y + diff;
point3.y = point3.y + diff;
point2 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point2);
point3 = canvas.chartingSpace.viewport.fitIntoVisibleArea(point3);
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point1.x, point1.y);
browserCanvasContext.closePath();
if (isCurrentRecord === false) {
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ')';
} else {
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */
}
browserCanvasContext.fill();
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + opacity + ')';
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.stroke();
}
browserCanvasContext.lineWidth = 0.25;
/* Outer Circle */
if (isCurrentRecord === true) {
browserCanvasContext.beginPath();
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')';
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')'; /* highlight the current record */
browserCanvasContext.arc(point.x, point.y, currentRadius, 0, Math.PI * 2, true);
browserCanvasContext.closePath();
if (point.x < canvas.chartingSpace.viewport.visibleArea.topLeft.x + 50 || point.x > canvas.chartingSpace.viewport.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else {
browserCanvasContext.fill();
}
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.stroke();
}
/* Inner Circle */
browserCanvasContext.beginPath();
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')';
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + opacity + ')';
browserCanvasContext.arc(point.x, point.y, radius, 0, Math.PI * 2, true);
browserCanvasContext.closePath();
if (point.x < canvas.chartingSpace.viewport.visibleArea.topLeft.x + 50 || point.x > canvas.chartingSpace.viewport.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else {
browserCanvasContext.fill();
}
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.stroke();
/* put the labels */
browserCanvasContext.beginPath();
let y;
let recordDate = new Date(record.datetime)
printLabel('Market Rate', X_AXIS, frameTitleHeight + frameBodyHeight * 0.05 / 2, '1');
printLabel(record.marketRate, X_AXIS, frameTitleHeight + frameBodyHeight * 0.10 / 2, '0.50');
printLabel('Sell Rate', X_AXIS, frameTitleHeight + frameBodyHeight * 0.15 / 2, '1');
printLabel(record.lastSellRate, X_AXIS, frameTitleHeight + frameBodyHeight * 0.20 / 2, '0.50');
printLabel('Sell Executed Rate', X_AXIS, frameTitleHeight + frameBodyHeight * 0.25 / 2, '1');
printLabel(record.sellExecRate, X_AXIS, frameTitleHeight + frameBodyHeight * 0.30 / 2, '0.50');
printLabel('Buy Rate', X_AXIS, frameTitleHeight + frameBodyHeight * 0.35 / 2, '1');
printLabel(record.lastBuyRate, X_AXIS, frameTitleHeight + frameBodyHeight * 0.40 / 2, '0.40');
printLabel('Buy Executed Rate', X_AXIS, frameTitleHeight + frameBodyHeight * 0.45 / 2, '1');
printLabel(record.buyExecRate, X_AXIS, frameTitleHeight + frameBodyHeight * 0.50 / 2, '0.50');
printLabel('ROI Asset A', X_AXIS, frameTitleHeight + frameBodyHeight * (1 - 0.25 / 2), '1');
printLabel((record.combinedProfitsB).toFixed(2) + '%', X_AXIS, frameTitleHeight + frameBodyHeight * (1 - 0.30 / 2), '0.50');
printLabel('ROI Asset B', X_AXIS, frameTitleHeight + frameBodyHeight * (1 - 0.15 / 2), '1');
printLabel((record.combinedProfitsA).toFixed(2) + '%', X_AXIS, frameTitleHeight + frameBodyHeight * (1 - 0.20 / 2), '0.50');
printLabel('Datetime', X_AXIS, frameTitleHeight + frameBodyHeight * (1 - 0.05 / 2), '1');
printLabel(recordDate.toUTCString(), X_AXIS, frameTitleHeight + frameBodyHeight * (1 - 0.1 / 2), '0.50');
function printLabel(labelToPrint, x, y, opacity) {
let labelPoint;
let fontSize = 10;
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.SECONDARY + ' Saira';
let label = '' + labelToPrint;
if (isNaN(label) === false) {
label = Number(label).toLocaleString();
}
let xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO;
labelPoint = {
x: x - xOffset,
y: y
};
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint);
labelPoint = thisObject.fitFunction(labelPoint)
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', ' + opacity + ')';
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
}
browserCanvasContext.closePath();
browserCanvasContext.fill();
}
}
@@ -1,718 +0,0 @@
function newTradingEnginesPlottersTradingSimulationStrategies() {
const MODULE_NAME = "Strategies Plotter";
const INFO_LOG = false;
const ERROR_LOG = true;
const INTENSIVE_LOG = false;
const logger = newWebDebugLog();
logger.fileName = MODULE_NAME;
let thisObject = {
// Main functions and properties.
initialize: initialize,
finalize: finalize,
container: undefined,
fitFunction: undefined,
getContainer: getContainer,
setTimeFrame: setTimeFrame,
setDatetime: setDatetime,
setCoordinateSystem: setCoordinateSystem,
draw: draw,
/* Events declared outside the plotter. */
onDailyFileLoaded: onDailyFileLoaded,
// Secondary functions and properties.
record: undefined
};
/* this is part of the module template */
let container = newContainer(); // Do not touch this 3 lines, they are just needed.
container.initialize();
thisObject.container = container;
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 strategies = [];
let strategyImages = [];
let onMouseOverEventSuscriptionId
let zoomChangedEventSubscriptionId
let offsetChangedEventSubscriptionId
let dragFinishedEventSubscriptionId
let dimmensionsChangedEventSubscriptionId
let marketFilesUpdatedEventSubscriptionId
let dailyFilesUpdatedEventSubscriptionId
let scaleChangedEventSubscriptionId
let userPositionDate
return thisObject;
function finalize() {
try {
if (INFO_LOG === true) { logger.write("[INFO] finalize -> Entering function."); }
/* Stop listening to the necesary events. */
thisObject.container.eventHandler.stopListening(onMouseOverEventSuscriptionId)
canvas.chartingSpace.viewport.eventHandler.stopListening(zoomChangedEventSubscriptionId);
canvas.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;
strategyImages = 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 {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
/* 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 = canvas.chartingSpace.viewport.eventHandler.listenToEvent("Zoom Changed", onViewportZoomChanged);
offsetChangedEventSubscriptionId = canvas.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();
/* Ready for when dimmension changes. */
dimmensionsChangedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('Dimmensions Changed', function () {
recalculate();
})
for (let i = 1; i < 15; i++) {
let strategyImage = canvas.designSpace.iconByUiObjectType.get('Strategy');
strategyImages.push(strategyImage);
}
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 = getDateFromPointAtBrowserCanvas(event, thisObject.container, coordinateSystem)
userPositionDate = userPosition.valueOf()
}
function getContainer(point) {
try {
if (INFO_LOG === true) { logger.write("[INFO] getContainer -> Entering function."); }
let container;
/* First we check if this point is inside this space. */
if (this.container.frame.isThisPointHere(point) === true) {
return this.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) {
marketFile = marketFiles.getFile(pTimeFrame);
recalculate();
} else {
let newFileCursor = dailyFiles.getFileCursor(pTimeFrame);
fileCursor = newFileCursor; // In this case, we explicitly want that if there is no valid cursor, we invalidate the data and show nothing.
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 (INFO_LOG === true) { logger.write("[INFO] onDailyFileLoaded -> Entering function."); }
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."); }
this.container.frame.draw();
plotChart();
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] draw -> err = " + err.stack); }
}
}
function recalculate() {
try {
strategies = []
if (timeFrame >= _1_HOUR_IN_MILISECONDS) {
recalculateUsingMarketFiles();
} else {
recalculateUsingDailyFiles();
}
thisObject.container.eventHandler.raiseEvent("Strategies Changed", strategies);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] recalculate -> err = " + err.stack); }
}
}
function recalculateUsingDailyFiles() {
try {
if (INFO_LOG === true) { logger.write("[INFO] recalculateUsingDailyFiles -> Entering function."); }
if (fileCursor === undefined) {
strategies = [];
return;
} // We need to wait
if (fileCursor.files.size === 0) {
strategies = [];
return;
} // We need to wait until there are files in the cursor
let daysOnSides = getSideDays(timeFrame);
let leftDate = getDateFromPointAtBrowserCanvas(canvas.chartingSpace.viewport.visibleArea.topLeft, thisObject.container, coordinateSystem);
let rightDate = getDateFromPointAtBrowserCanvas(canvas.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());
strategies = [];
while (currentDate.valueOf() <= farRightDate.valueOf() + ONE_DAY_IN_MILISECONDS) {
let stringDate = currentDate.getFullYear() + '-' + pad(currentDate.getMonth() + 1, 2) + '-' + pad(currentDate.getDate(), 2);
let dailyFile = fileCursor.files.get(stringDate);
if (dailyFile !== undefined) {
for (let i = 0; i < dailyFile.length; i++) {
let record = {
begin: undefined,
end: undefined,
status: undefined,
number: undefined,
beginRate: undefined,
endRate: undefined
};
record.begin = dailyFile[i][0];
record.end = dailyFile[i][1];
record.status = dailyFile[i][2];
record.number = dailyFile[i][3];
record.beginRate = dailyFile[i][4];
record.endRate = dailyFile[i][5];
record.situationName = dailyFile[i][6];
record.name = dailyFile[i][7];
if (
(record.begin >= farLeftDate.valueOf() && record.end <= farRightDate.valueOf()) &&
(record.begin >= coordinateSystem.min.x && record.end <= coordinateSystem.max.x)
) {
strategies.push(record);
if (datetime.valueOf() >= record.begin && datetime.valueOf() <= record.end) {
thisObject.record = record;
thisObject.container.eventHandler.raiseEvent("Current Strategy Changed", thisObject.record);
}
}
}
}
currentDate = new Date(currentDate.valueOf() + ONE_DAY_IN_MILISECONDS);
}
/* Lests check if all the visible screen is going to be covered by strategies. */
let lowerEnd = leftDate.valueOf();
let upperEnd = rightDate.valueOf();
setTimeout(recalculate, 2000);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] recalculateUsingDailyFiles -> err = " + err.stack); }
}
}
function recalculateUsingMarketFiles() {
try {
if (INFO_LOG === true) { logger.write("[INFO] recalculateUsingMarketFiles -> Entering function."); }
if (marketFile === undefined) { return; } // Initialization not complete yet.
let daysOnSides = getSideDays(timeFrame);
let leftDate = getDateFromPointAtBrowserCanvas(canvas.chartingSpace.viewport.visibleArea.topLeft, thisObject.container, coordinateSystem);
let rightDate = getDateFromPointAtBrowserCanvas(canvas.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);
strategies = [];
for (let i = 0; i < marketFile.length; i++) {
let record = {
begin: undefined,
end: undefined,
status: undefined,
number: undefined,
beginRate: undefined,
endRate: undefined
};
record.begin = marketFile[i][0];
record.end = marketFile[i][1];
record.status = marketFile[i][2];
record.number = marketFile[i][3];
record.beginRate = marketFile[i][4];
record.endRate = marketFile[i][5];
record.situationName = marketFile[i][6];
record.name = marketFile[i][7];
if (record.begin >= leftDate.valueOf() && record.end <= rightDate.valueOf()) {
strategies.push(record);
if (
(record.begin >= leftDate.valueOf() && record.end <= rightDate.valueOf()) &&
(record.begin >= coordinateSystem.min.x && record.end <= coordinateSystem.max.x)
) {
thisObject.record = record;
thisObject.container.eventHandler.raiseEvent("Current Strategy Changed", thisObject.record);
}
}
}
//console.log("Olivia > recalculateUsingMarketFiles > total strategies generated : " + strategies.length);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] recalculateUsingMarketFiles -> err = " + err.stack); }
}
}
function plotChart() {
try {
thisObject.container.eventHandler.raiseEvent("Current Strategy Record Changed", undefined);
let record;
for (let i = 0; i < strategies.length; i++) {
record = strategies[i];
let recordPoint1 = {
x: record.begin,
y: record.beginRate
};
let recordPoint2 = {
x: record.end,
y: record.endRate
};
let recordPoint3 = {
x: record.begin,
y: record.beginRate
};
let recordPoint4 = {
x: record.end,
y: record.endRate
};
recordPoint1 = coordinateSystem.transformThisPoint(recordPoint1);
recordPoint2 = coordinateSystem.transformThisPoint(recordPoint2);
recordPoint3 = coordinateSystem.transformThisPoint(recordPoint3);
recordPoint4 = coordinateSystem.transformThisPoint(recordPoint4);
recordPoint1 = transformThisPoint(recordPoint1, thisObject.container);
recordPoint2 = transformThisPoint(recordPoint2, thisObject.container);
recordPoint3 = transformThisPoint(recordPoint3, thisObject.container);
recordPoint4 = transformThisPoint(recordPoint4, thisObject.container);
if (recordPoint2.x < canvas.chartingSpace.viewport.visibleArea.bottomLeft.x || recordPoint1.x > canvas.chartingSpace.viewport.visibleArea.bottomRight.x) {
continue;
}
recordPoint3.y = recordPoint1.y + 2000;
recordPoint4.y = recordPoint1.y + 2000;
recordPoint1 = canvas.chartingSpace.viewport.fitIntoVisibleArea(recordPoint1);
recordPoint2 = canvas.chartingSpace.viewport.fitIntoVisibleArea(recordPoint2);
recordPoint3 = canvas.chartingSpace.viewport.fitIntoVisibleArea(recordPoint3);
recordPoint4 = canvas.chartingSpace.viewport.fitIntoVisibleArea(recordPoint4);
recordPoint1 = thisObject.fitFunction(recordPoint1, undefined, 30);
recordPoint2 = thisObject.fitFunction(recordPoint2, undefined, 30);
recordPoint3 = thisObject.fitFunction(recordPoint3, undefined, 30);
recordPoint4 = thisObject.fitFunction(recordPoint4, undefined, 30);
let imageSize = 20;
let imageToDraw = strategyImages[record.number];
/* Draw the line that represents the duration of closed strategy */
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(recordPoint3.x + imageSize / 2, recordPoint3.y);
browserCanvasContext.lineTo(recordPoint4.x - imageSize / 2, recordPoint4.y);
browserCanvasContext.closePath();
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.MANGANESE_PURPLE + ', 1)';
browserCanvasContext.lineWidth = 1
if (record.status === 1) {
browserCanvasContext.setLineDash([0, 0])
} else {
browserCanvasContext.setLineDash([2, 4])
}
browserCanvasContext.stroke()
/* Draw the Area */
/*
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(recordPoint1.x, recordPoint2.y);
browserCanvasContext.lineTo(recordPoint3.x, recordPoint3.y);
browserCanvasContext.lineTo(recordPoint4.x, recordPoint4.y);
browserCanvasContext.lineTo(recordPoint2.x, recordPoint2.y);
browserCanvasContext.closePath();
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + 0.5 + ')';
browserCanvasContext.fill();
*/
/* Situation Name */
let digit = record.begin.toFixed(0).substring(7,8)
let positionY = recordPoint3.y - (recordPoint3.y - recordPoint1.y) / 2 + (Number(digit) * 10 - 50)
if (canvas.chartingSpace.viewport.zoomLevel >= ZOOM_OUT_THRESHOLD_FOR_HIDDING_CHARTS_LABELS) {
if (record.name !== "New Strategy") {
printLabel(record.name, recordPoint1.x + 5, positionY - 15, '1', 12);
}
if (record.situationName !== "New Situation") {
printLabel(record.situationName, recordPoint1.x + 5, positionY, '1', 12);
}
}
/* Draw the Sticks */
drawStick(recordPoint1, recordPoint3);
drawStick(recordPoint2, recordPoint4);
if (imageToDraw.canDrawIcon === true) {
browserCanvasContext.drawImage(imageToDraw, recordPoint3.x - imageSize / 2, recordPoint3.y - imageSize / 2, imageSize, imageSize);
if (record.status === 1) {
browserCanvasContext.drawImage(imageToDraw, recordPoint4.x - imageSize / 2, recordPoint4.y - imageSize / 2, imageSize, imageSize);
}
}
/* Send the current record to the panel */
if (userPositionDate >= record.begin && userPositionDate <= record.end) {
let record = {
};
thisObject.container.eventHandler.raiseEvent("Current Strategy Record Changed", record);
}
function drawStick(point1, point2) {
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.closePath();
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', 0.25)';
if (userPositionDate >= record.begin && userPositionDate <= record.end) {
/* highlight the current record */
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 1)'; // Current record accroding to time
}
browserCanvasContext.setLineDash([4, 3])
browserCanvasContext.lineWidth = 0.5
browserCanvasContext.stroke()
browserCanvasContext.setLineDash([0, 0])
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] plotChart -> err = " + err.stack); }
}
}
function onViewportZoomChanged(event) {
try {
if (INFO_LOG === true) { logger.write("[INFO] onViewportZoomChanged -> Entering function."); }
recalculate();
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] onViewportZoomChanged -> err = " + err.stack); }
}
}
function onViewportPositionChanged(event) {
try {
if (INFO_LOG === true) { logger.write("[INFO] onViewportPositionChanged -> Entering function."); }
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 {
if (INFO_LOG === true) { logger.write("[INFO] onDragFinished -> Entering function."); }
recalculate();
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] onDragFinished -> err = " + err.stack); }
}
}
}
@@ -1,690 +0,0 @@
function newTradingEnginesPlottersTradingSimulationTrades() {
const MODULE_NAME = "Trades Plotter";
const INFO_LOG = false;
const ERROR_LOG = true;
const INTENSIVE_LOG = false;
const logger = newWebDebugLog();
logger.fileName = MODULE_NAME;
let thisObject = {
// Main functions and properties.
initialize: initialize,
finalize: finalize,
container: undefined,
fitFunction: undefined,
getContainer: getContainer,
setTimeFrame: setTimeFrame,
setDatetime: setDatetime,
setCoordinateSystem: setCoordinateSystem,
draw: draw,
/* Events declared outside the plotter. */
onDailyFileLoaded: onDailyFileLoaded,
// Secondary functions and properties.
record: undefined
};
/* this is part of the module template */
let container = newContainer(); // Do not touch this 3 lines, they are just needed.
container.initialize();
thisObject.container = container;
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 trades = [];
let headers;
let onMouseOverEventSuscriptionId
let zoomChangedEventSubscriptionId
let offsetChangedEventSubscriptionId
let dragFinishedEventSubscriptionId
let dimmensionsChangedEventSubscriptionId
let marketFilesUpdatedEventSubscriptionId
let dailyFilesUpdatedEventSubscriptionId
let scaleChangedEventSubscriptionId
let userPositionDate
return thisObject;
function finalize() {
try {
if (INFO_LOG === true) { logger.write("[INFO] finalize -> Entering function."); }
/* Stop listening to the necesary events. */
thisObject.container.eventHandler.stopListening(onMouseOverEventSuscriptionId)
canvas.chartingSpace.viewport.eventHandler.stopListening(zoomChangedEventSubscriptionId);
canvas.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 {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
/* 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 = canvas.chartingSpace.viewport.eventHandler.listenToEvent("Zoom Changed", onViewportZoomChanged);
offsetChangedEventSubscriptionId = canvas.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();
/* Ready for when dimmension changes. */
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 = getDateFromPointAtBrowserCanvas(event, thisObject.container, coordinateSystem)
userPositionDate = userPosition.valueOf()
}
function getContainer(point) {
try {
if (INFO_LOG === true) { logger.write("[INFO] getContainer -> Entering function."); }
let container;
/* First we check if this point is inside this space. */
if (this.container.frame.isThisPointHere(point) === true) {
return this.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) {
marketFile = marketFiles.getFile(pTimeFrame);
recalculate();
} else {
let newFileCursor = dailyFiles.getFileCursor(pTimeFrame);
fileCursor = newFileCursor; // In this case, we explicitly want that if there is no valid cursor, we invalidate the data and show nothing.
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 (INFO_LOG === true) { logger.write("[INFO] onDailyFileLoaded -> Entering function."); }
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."); }
this.container.frame.draw();
plotChart();
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] draw -> err = " + err.stack); }
}
}
function recalculate() {
try {
trades = []
if (timeFrame >= _1_HOUR_IN_MILISECONDS) {
recalculateUsingMarketFiles();
} else {
recalculateUsingDailyFiles();
}
thisObject.container.eventHandler.raiseEvent("Trades Changed", trades);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] recalculate -> err = " + err.stack); }
}
}
function recalculateUsingDailyFiles() {
try {
if (INFO_LOG === true) { logger.write("[INFO] recalculateUsingDailyFiles -> Entering function."); }
if (fileCursor === undefined) {
trades = [];
return;
} // We need to wait
if (fileCursor.files.size === 0) {
trades = [];
return;
} // We need to wait until there are files in the cursor
let daysOnSides = getSideDays(timeFrame);
let leftDate = getDateFromPointAtBrowserCanvas(canvas.chartingSpace.viewport.visibleArea.topLeft, thisObject.container, coordinateSystem);
let rightDate = getDateFromPointAtBrowserCanvas(canvas.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());
trades = [];
while (currentDate.valueOf() <= farRightDate.valueOf() + ONE_DAY_IN_MILISECONDS) {
let stringDate = currentDate.getFullYear() + '-' + pad(currentDate.getMonth() + 1, 2) + '-' + pad(currentDate.getDate(), 2);
let dailyFile = fileCursor.files.get(stringDate);
if (dailyFile !== undefined) {
for (let i = 0; i < dailyFile.length; i++) {
let record = {};
record.begin = dailyFile[i][0];
record.end = dailyFile[i][1];
record.status = dailyFile[i][2];
record.variable_last_position_ROI = dailyFile[i][3];
record.beginRate = dailyFile[i][4];
record.endRate = dailyFile[i][5];
record.exitType = dailyFile[i][6];
record.situationName = dailyFile[i][7];
if (
(record.begin >= farLeftDate.valueOf() && record.end <= farRightDate.valueOf()) &&
(record.begin >= coordinateSystem.min.x && record.end <= coordinateSystem.max.x)
) {
trades.push(record);
if (datetime.valueOf() >= record.begin && datetime.valueOf() <= record.end) {
thisObject.record = record;
thisObject.container.eventHandler.raiseEvent("Current Trade Changed", thisObject.record);
}
}
}
}
currentDate = new Date(currentDate.valueOf() + ONE_DAY_IN_MILISECONDS);
}
/* Lests check if all the visible screen is going to be covered by trades. */
let lowerEnd = leftDate.valueOf();
let upperEnd = rightDate.valueOf();
setTimeout(recalculate, 2000);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] recalculateUsingDailyFiles -> err = " + err.stack); }
}
}
function recalculateUsingMarketFiles() {
try {
if (INFO_LOG === true) { logger.write("[INFO] recalculateUsingMarketFiles -> Entering function."); }
if (marketFile === undefined) { return; } // Initialization not complete yet.
let daysOnSides = getSideDays(timeFrame);
let leftDate = getDateFromPointAtBrowserCanvas(canvas.chartingSpace.viewport.visibleArea.topLeft, thisObject.container, coordinateSystem);
let rightDate = getDateFromPointAtBrowserCanvas(canvas.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);
trades = [];
for (let i = 0; i < marketFile.length; i++) {
let record = {};
record.begin = marketFile[i][0];
record.end = marketFile[i][1];
record.status = marketFile[i][2];
record.variable_last_position_ROI = marketFile[i][3];
record.beginRate = marketFile[i][4];
record.endRate = marketFile[i][5];
record.exitType = marketFile[i][6];
record.situationName = marketFile[i][7];
if (
(record.begin >= leftDate.valueOf() && record.end <= rightDate.valueOf()) &&
(record.begin >= coordinateSystem.min.x && record.end <= coordinateSystem.max.x)
) {
trades.push(record);
if (datetime.valueOf() >= record.begin && datetime.valueOf() <= record.end) {
thisObject.record = record;
thisObject.container.eventHandler.raiseEvent("Current Trade Changed", thisObject.record);
}
}
}
//console.log("Olivia > recalculateUsingMarketFiles > total trades generated : " + trades.length);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] recalculateUsingMarketFiles -> err = " + err.stack); }
}
}
function plotChart() {
try {
thisObject.container.eventHandler.raiseEvent("Current Trade Record Changed", undefined);
let record;
for (let i = 0; i < trades.length; i++) {
record = trades[i];
/* Send the current record to the panel */
if (userPositionDate >= record.begin && userPositionDate <= record.end) {
let record = {
};
thisObject.container.eventHandler.raiseEvent("Current Trade Record Changed", record);
}
let recordPoint1 = {
x: record.begin,
y: record.beginRate
};
let recordPoint2 = {
x: record.end,
y: record.beginRate
};
let recordPoint3 = {
x: record.end,
y: record.endRate
};
recordPoint1 = coordinateSystem.transformThisPoint(recordPoint1);
recordPoint2 = coordinateSystem.transformThisPoint(recordPoint2);
recordPoint3 = coordinateSystem.transformThisPoint(recordPoint3);
recordPoint1 = transformThisPoint(recordPoint1, thisObject.container);
recordPoint2 = transformThisPoint(recordPoint2, thisObject.container);
recordPoint3 = transformThisPoint(recordPoint3, thisObject.container);
if (recordPoint2.x < canvas.chartingSpace.viewport.visibleArea.bottomLeft.x || recordPoint1.x > canvas.chartingSpace.viewport.visibleArea.bottomRight.x) {
continue;
}
recordPoint1 = canvas.chartingSpace.viewport.fitIntoVisibleArea(recordPoint1);
recordPoint2 = canvas.chartingSpace.viewport.fitIntoVisibleArea(recordPoint2);
recordPoint3 = canvas.chartingSpace.viewport.fitIntoVisibleArea(recordPoint3);
recordPoint1 = thisObject.fitFunction(recordPoint1);
recordPoint2 = thisObject.fitFunction(recordPoint2);
recordPoint3 = thisObject.fitFunction(recordPoint3);
let line0 = record.situationName
let line1 = '';
let line2 = '';
if (line0 === 'New Situation') {
line0 = ''
}
if (record.status === 1) {
switch (record.exitType) {
case 1: {
line1 = 'Stop Loss';
break;
}
case 2: {
line1 = 'Take Profit';
break;
}
}
} else {
line1 = 'Open Position';
}
if (record.variable_last_position_ROI < 0) {
line2 = 'ROI:' + (record.variable_last_position_ROI).toFixed(2) + ' %';
} else {
line2 = 'ROI:' + (record.variable_last_position_ROI).toFixed(2) + ' %';
}
/* Draw the triangle that represents the trade. */
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(recordPoint1.x, recordPoint1.y);
browserCanvasContext.lineTo(recordPoint2.x, recordPoint2.y);
browserCanvasContext.lineTo(recordPoint3.x, recordPoint3.y);
browserCanvasContext.closePath();
let opacity = '0.25';
if (record.variable_last_position_ROI > 0) {
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + opacity + ')';
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + opacity + ')';
} else {
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + opacity + ')';
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')';
}
if (userPositionDate >= record.begin && userPositionDate <= record.end) {
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + opacity + ')';
}
browserCanvasContext.fill();
browserCanvasContext.lineWidth = 1;
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.stroke();
let point = {}
if (record.beginRate > record.endRate) {
point.x = recordPoint3.x
point.y = recordPoint3.y + 100
} else {
point.x = recordPoint3.x
point.y = recordPoint3.y - 100
}
point = canvas.chartingSpace.viewport.fitIntoVisibleArea(point);
point = thisObject.fitFunction(point, undefined, 50);
if (
recordPoint3.x < canvas.chartingSpace.viewport.visibleArea.topLeft.x + 250
||
recordPoint3.x > canvas.chartingSpace.viewport.visibleArea.bottomRight.x - 250
||
recordPoint3.y > canvas.chartingSpace.viewport.visibleArea.bottomRight.y - 150
||
recordPoint3.y < canvas.chartingSpace.viewport.visibleArea.topLeft.y + 150
) {
// we do not write any text
} else {
if (canvas.chartingSpace.viewport.zoomLevel >= ZOOM_OUT_THRESHOLD_FOR_HIDDING_CHARTS_LABELS) {
printLabel(line0, recordPoint2.x - (recordPoint2.x - recordPoint1.x) / 2 - line1.length * FONT_ASPECT_RATIO, point.y - 15, '1', 12);
printLabel(line1, recordPoint2.x - (recordPoint2.x - recordPoint1.x) / 2 - line1.length * FONT_ASPECT_RATIO, point.y, '1', 12);
printLabel(line2, recordPoint2.x - (recordPoint2.x - recordPoint1.x) / 2 - line2.length * FONT_ASPECT_RATIO, point.y + 15, '1', 12);
}
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] plotChart -> err = " + err.stack); }
}
}
function onViewportZoomChanged(event) {
try {
if (INFO_LOG === true) { logger.write("[INFO] onViewportZoomChanged -> Entering function."); }
recalculate();
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] onViewportZoomChanged -> err = " + err.stack); }
}
}
function onViewportPositionChanged(event) {
try {
if (INFO_LOG === true) { logger.write("[INFO] onViewportPositionChanged -> Entering function."); }
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 {
if (INFO_LOG === true) { logger.write("[INFO] onDragFinished -> Entering function."); }
recalculate();
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] onDragFinished -> err = " + err.stack); }
}
}
}
@@ -1,864 +0,0 @@
function newTradingEnginesPlottersTradingSimulationTradingSimulation() {
const MODULE_NAME = "Simulation Plotter";
const ERROR_LOG = true;
const INTENSIVE_LOG = false;
const logger = newWebDebugLog();
logger.fileName = MODULE_NAME;
let thisObject = {
// Main functions and properties.
initialize: initialize,
finalize: finalize,
container: undefined,
fitFunction: undefined,
getContainer: getContainer,
setTimeFrame: setTimeFrame,
setDatetime: setDatetime,
setCoordinateSystem: setCoordinateSystem,
draw: draw,
/* Events declared outside the plotter. */
onDailyFileLoaded: onDailyFileLoaded,
// Secondary functions and properties.
record: undefined
};
/* this is part of the module template */
let container = newContainer(); // Do not touch this 3 lines, they are just needed.
container.initialize();
thisObject.container = container;
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 records = []; // Here we keep the records to be ploted every time the Draw() function is called by the AAWebPlatform.
let imageStopLossPhase;
let imageTakeProfitPhase;
let imageRecord;
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)
canvas.chartingSpace.viewport.eventHandler.stopListening(zoomChangedEventSubscriptionId);
canvas.chartingSpace.viewport.eventHandler.stopListening(offsetChangedEventSubscriptionId);
canvas.eventHandler.stopListening(dragFinishedEventSubscriptionId);
thisObject.container.eventHandler.stopListening(dimmensionsChangedEventSubscriptionId)
marketFiles.eventHandler.stopListening(marketFilesUpdatedEventSubscriptionId);
dailyFiles.eventHandler.stopListening(dailyFilesUpdatedEventSubscriptionId);
/* icons */
imageStopLossPhase = undefined;
imageTakeProfitPhase = undefined;
imageRecord = undefined;
/* Destroy 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 = canvas.chartingSpace.viewport.eventHandler.listenToEvent("Zoom Changed", onViewportZoomChanged);
offsetChangedEventSubscriptionId = canvas.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();
/* Ready for when dimmension changes. */
dimmensionsChangedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('Dimmensions Changed', function () {
recalculate();
})
/* Loading a few icons */
imageStopLossPhase = canvas.designSpace.iconByUiObjectType.get('Managed Stop Loss');
imageTakeProfitPhase = canvas.designSpace.iconByUiObjectType.get('Phase');
imageRecord = canvas.designSpace.iconByUiObjectType.get('Trading System');
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 = getDateFromPointAtBrowserCanvas(event, thisObject.container, coordinateSystem)
userPositionDate = userPosition.valueOf()
}
function getContainer(point) {
let container;
/* First we check if this point is inside this space. */
if (this.container.frame.isThisPointHere(point) === true) {
return this.container;
} else {
/* This point does not belong to this space. */
return undefined;
}
}
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) {
marketFile = marketFiles.getFile(pTimeFrame);
recalculate();
} else {
let newFileCursor = dailyFiles.getFileCursor(pTimeFrame);
fileCursor = newFileCursor; // In this case, we explicitly want that if there is no valid cursor, we invalidate the data and show nothing.
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."); }
this.container.frame.draw();
plotChart();
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] draw -> err = " + err.stack); }
}
}
function recalculate() {
try {
records = []
if (timeFrame >= _1_HOUR_IN_MILISECONDS) {
recalculateUsingMarketFiles();
} else {
recalculateUsingDailyFiles();
}
thisObject.container.eventHandler.raiseEvent("Records Changed", records);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] recalculate -> err = " + err.stack); }
}
}
function recalculateUsingDailyFiles() {
try {
if (fileCursor === undefined) {
records = [];
return;
} // We need to wait
if (fileCursor.files.size === 0) {
records = [];
return;
} // We need to wait until there are files in the cursor
let daysOnSides = getSideDays(timeFrame);
let leftDate = getDateFromPointAtBrowserCanvas(canvas.chartingSpace.viewport.visibleArea.topLeft, thisObject.container, coordinateSystem);
let rightDate = getDateFromPointAtBrowserCanvas(canvas.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());
records = [];
while (currentDate.valueOf() <= farRightDate.valueOf() + ONE_DAY_IN_MILISECONDS) {
let stringDate = currentDate.getFullYear() + '-' + pad(currentDate.getMonth() + 1, 2) + '-' + pad(currentDate.getDate(), 2);
let dailyFile = fileCursor.files.get(stringDate);
if (dailyFile !== undefined) {
for (let i = 0; i < dailyFile.length; i++) {
let record = {};
record.begin = dailyFile[i][0];
record.end = dailyFile[i][1];
record.variable_current_balance_baseAsset = dailyFile[i][2];
record.variable_current_balance_quotedAsset = dailyFile[i][3];
record.variable_episode_stat_profitLoss = dailyFile[i][4];
record.variable_last_position_profitLoss = dailyFile[i][5];
record.variable_current_position_stopLoss_value = dailyFile[i][6];
record.variable_episode_count_positions = dailyFile[i][7];
record.variable_episode_count_hits = dailyFile[i][8];
record.variable_episode_count_fails = dailyFile[i][9];
record.variable_episode_stat_hitRatio = dailyFile[i][10];
record.variable_episode_stat_ROI = dailyFile[i][11];
record.variable_episode_count_periods = dailyFile[i][12];
record.variable_episode_stat_days = dailyFile[i][13];
record.variable_episode_stat_anualizedRateOfReturn = dailyFile[i][14];
record.variable_current_position_rate = dailyFile[i][15];
record.variable_last_position_ROI = dailyFile[i][16];
record.strategy = dailyFile[i][17];
record.variable_current_position_takeProfit_value = dailyFile[i][18];
record.variable_current_position_stopLoss_phase = dailyFile[i][19];
record.variable_current_position_takeProfit_phase = dailyFile[i][20];
record.variable_current_position_size = dailyFile[i][21]; // 25 is the message for the executor
record.variable_episode_parameters_initial_balance_baseAsset = dailyFile[i][22];
record.variable_episode_parameters_minimum_balance_baseAsset = dailyFile[i][23];
record.variable_episode_parameters_maximum_balance_baseAsset = dailyFile[i][24];
record.variable_episode_parameters_initial_balance_quotedAsset = dailyFile[i][25];
record.variable_episode_parameters_minimum_balance_quotedAsset = dailyFile[i][26];
record.variable_episode_parameters_maximum_balance_quotedAsset = dailyFile[i][27];
record.variable_episode_parameters_baseAsset = dailyFile[i][28];
record.variable_episode_parameters_quotedAsset = dailyFile[i][29];
record.variable_episode_parameters_marketBaseAsset = dailyFile[i][30];
record.variable_episode_parameters_marketQuotedAsset = dailyFile[i][31];
record.variable_current_position_count_periods = dailyFile[i][32];
record.variable_current_position_stat_days = dailyFile[i][33];
if (
(record.begin >= farLeftDate.valueOf() && record.end <= farRightDate.valueOf()) &&
(record.begin >= coordinateSystem.min.x && record.end <= coordinateSystem.max.x)
) {
records.push(record);
if (datetime.valueOf() >= record.begin && datetime.valueOf() <= record.end) {
thisObject.record = record;
thisObject.container.eventHandler.raiseEvent("Current Record Changed", thisObject.record);
}
}
}
}
currentDate = new Date(currentDate.valueOf() + ONE_DAY_IN_MILISECONDS);
}
/* Lests check if all the visible screen is going to be covered by records. */
let lowerEnd = leftDate.valueOf();
let upperEnd = rightDate.valueOf();
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 = getDateFromPointAtBrowserCanvas(canvas.chartingSpace.viewport.visibleArea.topLeft, thisObject.container, coordinateSystem);
let rightDate = getDateFromPointAtBrowserCanvas(canvas.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);
records = [];
for (let i = 0; i < marketFile.length; i++) {
let record = {};
record.begin = marketFile[i][0];
record.end = marketFile[i][1];
record.variable_current_balance_baseAsset = marketFile[i][2];
record.variable_current_balance_quotedAsset = marketFile[i][3];
record.variable_episode_stat_profitLoss = marketFile[i][4];
record.variable_last_position_profitLoss = marketFile[i][5];
record.variable_current_position_stopLoss_value = marketFile[i][6];
record.variable_episode_count_positions = marketFile[i][7];
record.variable_episode_count_hits = marketFile[i][8];
record.variable_episode_count_fails = marketFile[i][9];
record.variable_episode_stat_hitRatio = marketFile[i][10];
record.variable_episode_stat_ROI = marketFile[i][11];
record.variable_episode_count_periods = marketFile[i][12];
record.variable_episode_stat_days = marketFile[i][13];
record.variable_episode_stat_anualizedRateOfReturn = marketFile[i][14];
record.variable_current_position_rate = marketFile[i][15];
record.variable_last_position_ROI = marketFile[i][16];
record.variable_current_position_takeProfit_value = marketFile[i][17];
record.variable_current_position_stopLoss_phase = marketFile[i][18];
record.variable_current_position_takeProfit_phase = marketFile[i][19];
record.variable_current_position_size = marketFile[i][20];
record.variable_episode_parameters_initial_balance_baseAsset = marketFile[i][21];
record.variable_episode_parameters_minimum_balance_baseAsset = marketFile[i][22];
record.variable_episode_parameters_maximum_balance_baseAsset = marketFile[i][23];
record.variable_episode_parameters_initial_balance_quotedAsset = marketFile[i][24];
record.variable_episode_parameters_minimum_balance_quotedAsset = marketFile[i][25];
record.variable_episode_parameters_maximum_balance_quotedAsset = marketFile[i][26];
record.variable_episode_parameters_baseAsset = marketFile[i][27];
record.variable_episode_parameters_quotedAsset = marketFile[i][28];
record.variable_episode_parameters_marketBaseAsset = marketFile[i][29];
record.variable_episode_parameters_marketQuotedAsset = marketFile[i][30];
record.variable_current_position_count_periods = marketFile[i][31];
record.variable_current_position_stat_days = marketFile[i][32];
if (
(record.begin >= leftDate.valueOf() && record.end <= rightDate.valueOf()) &&
(record.begin >= coordinateSystem.min.x && record.end <= coordinateSystem.max.x)
) {
records.push(record);
if (datetime.valueOf() >= record.begin && datetime.valueOf() <= record.end) {
thisObject.record = record;
thisObject.container.eventHandler.raiseEvent("Current Record Changed", thisObject.record);
}
}
}
//console.log("Olivia > recalculateUsingMarketFiles > total records generated : " + records.length);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] recalculateUsingMarketFiles -> err = " + err.stack); }
}
}
function plotChart() {
try {
let record;
/* Now we calculate and plot the records */
for (let i = 0; i < records.length; i++) { // We do not start in 0 so as to be able to read the previous record i - 1
record = records[i];
/* Contributing to Auto-Scale*/
if (record.variable_current_position_stopLoss_value !== 0) {
coordinateSystem.reportYValue(record.variable_current_position_stopLoss_value)
}
if (record.variable_current_position_takeProfit_value !== 0) {
coordinateSystem.reportYValue(record.variable_current_position_takeProfit_value)
}
/* Send the current record to the panel */
if (userPositionDate >= record.begin && userPositionDate <= record.end) {
let eventRecords = {
record: record
};
thisObject.container.eventHandler.raiseEvent("Current Record Changed", eventRecords);
}
let stopLossPhase = -1;
let takeProfitPhase = -1;
if (i > 0) {
if (record.variable_current_position_stopLoss_phase !== records[i - 1].variable_current_position_stopLoss_phase) {
stopLossPhase = record.variable_current_position_stopLoss_phase;
}
if (record.variable_current_position_takeProfit_phase !== records[i - 1].variable_current_position_takeProfit_phase) {
takeProfitPhase = record.variable_current_position_takeProfit_phase;
}
}
let recordPoint1 = {
x: record.begin + timeFrame / 7 * 1.5,
y: thisObject.container.frame.height
};
let recordPoint2 = {
x: record.end + timeFrame / 7 * 5.5,
y: thisObject.container.frame.height
};
let recordPoint3 = {
x: recordPoint1.x + (recordPoint2.x - recordPoint1.x) / 2,
y: 0
};
let recordPoint4 = {
x: record.begin + timeFrame / 7 * 1.5,
y: thisObject.container.frame.height * 100
};
let recordPoint5 = {
x: record.begin,
y: record.variable_current_position_stopLoss_value
};
let recordPoint6 = {
x: record.end,
y: record.variable_current_position_stopLoss_value
};
if (record.variable_current_position_stopLoss_value === 0) { // Put these points out of range if stopLoss is zero.
recordPoint5.x = 0;
recordPoint6.x = 0;
}
let recordPoint7 = {
x: record.begin,
y: record.variable_current_position_rate
};
let recordPoint8 = {
x: record.end,
y: record.variable_current_position_rate
};
if (record.variable_current_position_rate === 0) { // Put these points out of range if sellRate is zero.
recordPoint7.x = 0;
recordPoint8.x = 0;
}
let recordPoint9 = {
x: record.begin,
y: record.variable_current_position_takeProfit_value
};
let recordPoint10 = {
x: record.end,
y: record.variable_current_position_takeProfit_value
};
if (record.variable_current_position_takeProfit_value === 0) { // Put these points out of range if takeProfit is zero.
recordPoint9.x = 0;
recordPoint10.x = 0;
}
recordPoint1 = coordinateSystem.transformThisPoint(recordPoint1);
recordPoint2 = coordinateSystem.transformThisPoint(recordPoint2);
recordPoint3 = coordinateSystem.transformThisPoint(recordPoint3);
recordPoint4 = coordinateSystem.transformThisPoint(recordPoint4);
recordPoint5 = coordinateSystem.transformThisPoint(recordPoint5);
recordPoint6 = coordinateSystem.transformThisPoint(recordPoint6);
recordPoint7 = coordinateSystem.transformThisPoint(recordPoint7);
recordPoint8 = coordinateSystem.transformThisPoint(recordPoint8);
recordPoint9 = coordinateSystem.transformThisPoint(recordPoint9);
recordPoint10 = coordinateSystem.transformThisPoint(recordPoint10);
recordPoint1 = transformThisPoint(recordPoint1, thisObject.container);
recordPoint2 = transformThisPoint(recordPoint2, thisObject.container);
recordPoint3 = transformThisPoint(recordPoint3, thisObject.container);
recordPoint4 = transformThisPoint(recordPoint4, thisObject.container);
recordPoint5 = transformThisPoint(recordPoint5, thisObject.container);
recordPoint6 = transformThisPoint(recordPoint6, thisObject.container);
recordPoint7 = transformThisPoint(recordPoint7, thisObject.container);
recordPoint8 = transformThisPoint(recordPoint8, thisObject.container);
recordPoint9 = transformThisPoint(recordPoint9, thisObject.container);
recordPoint10 = transformThisPoint(recordPoint10, thisObject.container);
recordPoint1 = canvas.chartingSpace.viewport.fitIntoVisibleArea(recordPoint1);
recordPoint2 = canvas.chartingSpace.viewport.fitIntoVisibleArea(recordPoint2);
recordPoint3 = canvas.chartingSpace.viewport.fitIntoVisibleArea(recordPoint3);
recordPoint4 = canvas.chartingSpace.viewport.fitIntoVisibleArea(recordPoint4);
recordPoint5 = canvas.chartingSpace.viewport.fitIntoVisibleArea(recordPoint5);
recordPoint6 = canvas.chartingSpace.viewport.fitIntoVisibleArea(recordPoint6);
recordPoint7 = canvas.chartingSpace.viewport.fitIntoVisibleArea(recordPoint7);
recordPoint8 = canvas.chartingSpace.viewport.fitIntoVisibleArea(recordPoint8);
recordPoint9 = canvas.chartingSpace.viewport.fitIntoVisibleArea(recordPoint9);
recordPoint10 = canvas.chartingSpace.viewport.fitIntoVisibleArea(recordPoint10);
recordPoint1 = thisObject.fitFunction(recordPoint1);
recordPoint2 = thisObject.fitFunction(recordPoint2);
recordPoint3 = thisObject.fitFunction(recordPoint3);
recordPoint4 = thisObject.fitFunction(recordPoint4);
recordPoint5 = thisObject.fitFunction(recordPoint5);
recordPoint6 = thisObject.fitFunction(recordPoint6);
recordPoint7 = thisObject.fitFunction(recordPoint7);
recordPoint8 = thisObject.fitFunction(recordPoint8);
recordPoint9 = thisObject.fitFunction(recordPoint9);
recordPoint10 = thisObject.fitFunction(recordPoint10);
/* Image representing a Record */
let imageOffset = {
x: 0,
y: -30
}
let imageSize = (recordPoint2.x - recordPoint1.x) / 2;
let recordLabel = record.variable_episode_count_periods.toLocaleString()
if (imageSize < 8) {
if (recordLabel[recordLabel.length - 1] !== '0' || imageSize < 4)
recordLabel = ''
}
let labelOffset = {
x: 0 - imageSize / 2 + 3 + imageOffset.x,
y: -2 - imageOffset.y
}
let imagePosition = {
x: recordPoint4.x + imageOffset.x,
y: 0
}
imagePosition = canvas.chartingSpace.viewport.fitIntoVisibleArea(imagePosition)
imagePosition = thisObject.fitFunction(imagePosition, undefined, 0, 0, imageSize)
if (imageRecord.canDrawIcon === true) {
browserCanvasContext.drawImage(imageRecord, imagePosition.x, imagePosition.y, imageSize, imageSize);
browserCanvasContext.save();
browserCanvasContext.translate(recordPoint3.x + labelOffset.x, recordPoint3.y + labelOffset.y);
browserCanvasContext.rotate(-Math.PI / 2);
printLabel(recordLabel, 0, 0, '1', 8, undefined, undefined, undefined, undefined, true);
browserCanvasContext.restore();
}
if (recordPoint5.x < canvas.chartingSpace.viewport.visibleArea.bottomLeft.x || recordPoint5.x > canvas.chartingSpace.viewport.visibleArea.bottomRight.x) {
continue;
}
/* Next we are drawing the position Rate */
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(recordPoint7.x, recordPoint7.y);
browserCanvasContext.lineTo(recordPoint8.x, recordPoint8.y);
browserCanvasContext.closePath();
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.MANGANESE_PURPLE + ', 1)';
browserCanvasContext.lineWidth = 1
browserCanvasContext.setLineDash([1, 4])
if (userPositionDate >= record.begin && userPositionDate <= record.end) {
browserCanvasContext.lineWidth = 5
browserCanvasContext.setLineDash([3, 4])
/* highlight the current record */
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 1)'; // Current record accroding to time
}
browserCanvasContext.stroke()
browserCanvasContext.setLineDash([0, 0])
imageSize = 20;
let imageToDraw;
/* Depending on what is on top, it is also the text and image of the take accumulatedProfitLoss / stop loss */
let yOffset = 0
if (record.variable_current_position_takeProfit_value > record.variable_current_position_stopLoss_value) { yOffset = imageSize * 2 }
/* Next we are drawing the stopLoss floor / ceilling */
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(recordPoint5.x, recordPoint5.y);
browserCanvasContext.lineTo(recordPoint6.x, recordPoint6.y);
browserCanvasContext.closePath();
let opacity = 1
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + '';
if (userPositionDate >= record.begin && userPositionDate <= record.end) {
/* highlight the current record */
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 1)'; // Current record accroding to time
}
browserCanvasContext.lineWidth = 1
browserCanvasContext.stroke()
imagePosition = {
x: recordPoint6.x - imageSize,
y: recordPoint6.y - imageSize * 1.25 + yOffset
}
imagePosition = canvas.chartingSpace.viewport.fitIntoVisibleArea(imagePosition)
imagePosition = thisObject.fitFunction(imagePosition, undefined, 0, 0, imageSize)
let labelPosition = {
x: recordPoint6.x - imageSize / 2 - 3,
y: recordPoint6.y - imageSize * 1.5 + yOffset * 2
}
labelPosition = canvas.chartingSpace.viewport.fitIntoVisibleArea(labelPosition)
labelPosition = thisObject.fitFunction(labelPosition, undefined, 30)
if (imageStopLossPhase.canDrawIcon === true && stopLossPhase > -1) {
browserCanvasContext.drawImage(imageStopLossPhase, imagePosition.x, imagePosition.y, imageSize, imageSize);
printLabel(stopLossPhase, labelPosition.x, labelPosition.y, '1', 9);
}
/* Next we are drawing the Take Profit */
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(recordPoint9.x, recordPoint9.y);
browserCanvasContext.lineTo(recordPoint10.x, recordPoint10.y);
browserCanvasContext.closePath();
opacity = 1
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + opacity + '';
if (userPositionDate >= record.begin && userPositionDate <= record.end) {
/* highlight the current record */
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 1)'; // Current record accroding to time
}
browserCanvasContext.lineWidth = 1
browserCanvasContext.stroke()
imagePosition = {
x: recordPoint10.x - imageSize * 2 / 3,
y: recordPoint10.y + imageSize / 4 - yOffset
}
imagePosition = canvas.chartingSpace.viewport.fitIntoVisibleArea(imagePosition)
imagePosition = thisObject.fitFunction(imagePosition, undefined, 0, 0, imageSize)
labelPosition = {
x: recordPoint10.x - imageSize * 1 / 3,
y: recordPoint10.y + imageSize * 1.9 - yOffset * 2
}
labelPosition = canvas.chartingSpace.viewport.fitIntoVisibleArea(labelPosition)
labelPosition = thisObject.fitFunction(labelPosition, undefined, 30)
if (imageTakeProfitPhase.canDrawIcon === true && takeProfitPhase > -1) {
browserCanvasContext.drawImage(imageTakeProfitPhase, imagePosition.x, imagePosition.y, imageSize, imageSize);
printLabel(takeProfitPhase, labelPosition.x, labelPosition.y, '1', 9);
}
}
} 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); }
}
}
}
@@ -1,219 +0,0 @@
function newTradingEnginesPlottersTradingSimulationTradingSimulationTradingSimulationAssetBalancesPanel() {
let thisObject = {
fitFunction: undefined,
onRecordChange: onRecordChange,
container: undefined,
session: undefined,
isVisible: true,
draw: draw,
getContainer: getContainer,
initialize: initialize,
finalize: finalize
};
let container = newContainer();
container.initialize();
thisObject.container = container;
container.frame.containerName = "Simulation Asset Balances Panel";
let record;
let lastRecord;
let upDownButton
const HEIGHT_FACTOR = 1.25
return thisObject;
function initialize() {
thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL * 1;
thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL * HEIGHT_FACTOR;
thisObject.container.frame.position.x = canvas.chartingSpace.viewport.visibleArea.topRight.x - thisObject.container.frame.width * 1;
thisObject.container.frame.position.y = canvas.chartingSpace.viewport.visibleArea.topRight.y;
upDownButton = newUpDownButton()
upDownButton.parentContainer = thisObject.container
upDownButton.container.frame.parentFrame = thisObject.container.frame
upDownButton.fitFunction = thisObject.fitFunction
upDownButton.initialize()
thisObject.assetBalances = newAssetalances()
thisObject.assetBalances.container.connectToParent(thisObject.container, true, true)
thisObject.assetBalances.initialize()
}
function finalize() {
thisObject.session = undefined
thisObject.container.finalize()
thisObject.container = undefined
thisObject.fitFunction = undefined
thisObject.onRecordChange = undefined
thisObject.isVisible = undefined
record = undefined
lastRecord = undefined
upDownButton = undefined
thisObject.assetBalances.finalize()
thisObject.assetBalances = undefined
}
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(records) {
record = records.record;
lastRecord = records.lastRecord
}
function draw() {
if (thisObject.isVisible !== true) { return }
thisObject.container.frame.draw(false, false, true, thisObject.fitFunction);
plotCurrentRecordInfo();
upDownButton.draw()
/* Define panel name */
if (thisObject.session !== undefined) {
const MAX_LABEL_LENGTH = 25
if (thisObject.session.name.length > MAX_LABEL_LENGTH) {
container.frame.containerName = thisObject.session.name.substring(0, MAX_LABEL_LENGTH) + '...'
} else {
container.frame.containerName = thisObject.session.name
}
}
}
function plotCurrentRecordInfo() {
if (record === 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;
/* put the labels with the records values */
let y = 0;
let increment = 0.024 / HEIGHT_FACTOR * 2.5;
y = y + increment;
y = y + increment;
printLabel('Asset Balances', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
/* Parameters */
let params
let paramsArray = []
let positionTaken = false
if (record.variable_current_position_size > 0) {
positionTaken = true
}
let testPoint = {
x: 0,
y: thisObject.container.frame.height
}
testPoint = thisObject.container.frame.frameThisPoint(testPoint)
let fitPoint = thisObject.fitFunction(testPoint)
if (fitPoint.y !== testPoint.y) {
return
}
if (record.variable_episode_parameters_baseAsset === record.variable_episode_parameters_marketBaseAsset) {
params = {}
params.VALUE = record.variable_current_balance_baseAsset;
params.INIT_VALUE = record.variable_episode_parameters_initial_balance_baseAsset
params.MIN_VALUE = record.variable_episode_parameters_minimum_balance_baseAsset
params.MAX_VALUE = record.variable_episode_parameters_maximum_balance_baseAsset
params.ASSET_LABEL = 'Base'
params.ASSET_NAME = record.variable_episode_parameters_baseAsset
params.LEFT_OFFSET = X_AXIS
params.POSITION_TAKEN = positionTaken
params.BASE_ASSET = record.variable_episode_parameters_baseAsset
params.DECIMALS = 4
paramsArray.push(params)
params = {}
params.VALUE = record.variable_current_balance_quotedAsset;
params.MIN_VALUE = record.variable_episode_parameters_minimum_balance_quotedAsset
params.INIT_VALUE = record.variable_episode_parameters_initial_balance_quotedAsset
params.MAX_VALUE = record.variable_episode_parameters_maximum_balance_quotedAsset
params.ASSET_LABEL = 'Quoted'
params.ASSET_NAME = record.variable_episode_parameters_quotedAsset
params.LEFT_OFFSET = X_AXIS
params.POSITION_TAKEN = positionTaken
params.BASE_ASSET = record.variable_episode_parameters_baseAsset
params.DECIMALS = 2
paramsArray.push(params)
} else {
params = {}
params.VALUE = record.variable_current_balance_quotedAsset;
params.INIT_VALUE = record.variable_episode_parameters_initial_balance_quotedAsset
params.MIN_VALUE = record.variable_episode_parameters_minimum_balance_quotedAsset
params.MAX_VALUE = record.variable_episode_parameters_maximum_balance_quotedAsset
params.ASSET_LABEL = 'Base'
params.ASSET_NAME = record.variable_episode_parameters_baseAsset
params.LEFT_OFFSET = X_AXIS
params.POSITION_TAKEN = positionTaken
params.BASE_ASSET = record.variable_episode_parameters_baseAsset
params.DECIMALS = 4
paramsArray.push(params)
params = {}
params.VALUE = record.variable_current_balance_baseAsset;
params.MIN_VALUE = record.variable_episode_parameters_minimum_balance_baseAsset
params.INIT_VALUE = record.variable_episode_parameters_initial_balance_baseAsset
params.MAX_VALUE = record.variable_episode_parameters_maximum_balance_baseAsset
params.ASSET_LABEL = 'Quoted'
params.ASSET_NAME = record.variable_episode_parameters_quotedAsset
params.LEFT_OFFSET = X_AXIS
params.POSITION_TAKEN = positionTaken
params.BASE_ASSET = record.variable_episode_parameters_baseAsset
params.DECIMALS = 2
paramsArray.push(params)
}
thisObject.assetBalances.setParamsArray(paramsArray)
thisObject.assetBalances.draw()
}
}
@@ -1,178 +0,0 @@
function newTradingEnginesPlottersTradingSimulationTradingSimulationTradingSimulationCurrentPositionPanel() {
let thisObject = {
fitFunction: undefined,
onRecordChange: onRecordChange,
container: undefined,
session: undefined,
isVisible: true,
draw: draw,
getContainer: getContainer,
initialize: initialize,
finalize: finalize
};
let container = newContainer();
container.initialize();
thisObject.container = container;
container.frame.containerName = "Simulation Current Position Panel";
let record;
let lastRecord;
let upDownButton
const HEIGHT_FACTOR = 1.25
return thisObject;
function initialize() {
thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL * 1;
thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL * HEIGHT_FACTOR;
thisObject.container.frame.position.x = canvas.chartingSpace.viewport.visibleArea.topRight.x - thisObject.container.frame.width * 1;
thisObject.container.frame.position.y = canvas.chartingSpace.viewport.visibleArea.topRight.y;
upDownButton = newUpDownButton()
upDownButton.parentContainer = thisObject.container
upDownButton.container.frame.parentFrame = thisObject.container.frame
upDownButton.fitFunction = thisObject.fitFunction
upDownButton.initialize()
}
function finalize() {
thisObject.session = undefined
thisObject.container.finalize()
thisObject.container = undefined
thisObject.fitFunction = undefined
thisObject.onRecordChange = undefined
thisObject.isVisible = undefined
record = undefined
lastRecord = undefined
upDownButton = undefined
}
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(records) {
record = records.record;
lastRecord = records.lastRecord
}
function draw() {
if (thisObject.isVisible !== true) { return }
thisObject.container.frame.draw(false, false, true, thisObject.fitFunction);
plotCurrentRecordInfo();
upDownButton.draw()
/* Define panel name */
if (thisObject.session !== undefined) {
const MAX_LABEL_LENGTH = 25
if (thisObject.session.name.length > MAX_LABEL_LENGTH) {
container.frame.containerName = thisObject.session.name.substring(0, MAX_LABEL_LENGTH) + '...'
} else {
container.frame.containerName = thisObject.session.name
}
}
}
function plotCurrentRecordInfo() {
if (record === 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;
/* put the labels with the records values */
let y = 0;
let increment = 0.024 / HEIGHT_FACTOR * 2.5;
y = y + increment;
y = y + increment;
printLabel('Current Position', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel('Size', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel(record.variable_current_position_size, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel('Rate', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel(record.variable_current_position_rate, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel('Stop', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel(record.variable_current_position_stopLoss_value, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel('Take Profit', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel(record.variable_current_position_takeProfit_value, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel('Periods', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel((record.variable_current_position_count_periods), X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel('Days', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel((record.variable_current_position_stat_days).toFixed(2), X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
y = y + increment;
printLabel('Latest Position', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel('Profit / Loss', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel((record.variable_last_position_profitLoss), X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel('ROI', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel((record.variable_last_position_ROI).toFixed(2) + ' % ', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
}
}
@@ -1,177 +0,0 @@
function newTradingEnginesPlottersTradingSimulationTradingSimulationTradingSimulationEpisodePanel() {
let thisObject = {
fitFunction: undefined,
onRecordChange: onRecordChange,
container: undefined,
session: undefined,
isVisible: true,
draw: draw,
getContainer: getContainer,
initialize: initialize,
finalize: finalize
};
let container = newContainer();
container.initialize();
thisObject.container = container;
container.frame.containerName = "Simulation Episode Panel";
let record;
let lastRecord;
let upDownButton
const HEIGHT_FACTOR = 1.25
return thisObject;
function initialize() {
thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL * 1;
thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL * HEIGHT_FACTOR;
thisObject.container.frame.position.x = canvas.chartingSpace.viewport.visibleArea.topRight.x - thisObject.container.frame.width * 1;
thisObject.container.frame.position.y = canvas.chartingSpace.viewport.visibleArea.topRight.y;
upDownButton = newUpDownButton()
upDownButton.parentContainer = thisObject.container
upDownButton.container.frame.parentFrame = thisObject.container.frame
upDownButton.fitFunction = thisObject.fitFunction
upDownButton.initialize()
}
function finalize() {
thisObject.session = undefined
thisObject.container.finalize()
thisObject.container = undefined
thisObject.fitFunction = undefined
thisObject.onRecordChange = undefined
thisObject.isVisible = undefined
record = undefined
lastRecord = undefined
upDownButton = undefined
}
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(records) {
record = records.record;
lastRecord = records.lastRecord
}
function draw() {
if (thisObject.isVisible !== true) { return }
thisObject.container.frame.draw(false, false, true, thisObject.fitFunction);
plotCurrentRecordInfo();
upDownButton.draw()
/* Define panel name */
if (thisObject.session !== undefined) {
const MAX_LABEL_LENGTH = 25
if (thisObject.session.name.length > MAX_LABEL_LENGTH) {
container.frame.containerName = thisObject.session.name.substring(0, MAX_LABEL_LENGTH) + '...'
} else {
container.frame.containerName = thisObject.session.name
}
}
}
function plotCurrentRecordInfo() {
if (record === 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;
/* put the labels with the records values */
let y = 0;
let increment = 0.024 / HEIGHT_FACTOR * 2.5;
y = y + increment;
y = y + increment;
printLabel('Episode', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel('Profit / Loss', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel(record.variable_episode_stat_profitLoss, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel('Trades', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel(record.variable_episode_count_positions, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel('Hits', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel(record.variable_episode_count_hits, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel('Fails', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel(record.variable_episode_count_fails, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel('Hit Ratio', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel((record.variable_episode_stat_hitRatio * 100).toFixed(2) + ' %', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel('ROI', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel((record.variable_episode_stat_ROI * 100).toFixed(2) + ' %', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel('Periods', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel(record.variable_episode_count_periods, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel('Days', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel(record.variable_episode_stat_days, X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel('Anualized Rate of Return', X_AXIS, frameTitleHeight + frameBodyHeight * y, '0.60', undefined, undefined, true, thisObject.container, thisObject.fitFunction);
y = y + increment;
printLabel((record.variable_episode_stat_anualizedRateOfReturn * 100).toFixed(2) + ' %', X_AXIS, frameTitleHeight + frameBodyHeight * y, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction);
}
}
@@ -1,56 +0,0 @@
{
"displayName": "Plotters Trading Simulation",
"codeName": "PlottersTradingSimulation",
"dataMine": "Masters",
"modules": [
{
"codeName": "TradingSimulation",
"moduleName": "TradingSimulation",
"description": "Plots Bollinger Records.",
"profilePicture": "TradingSimulation.png",
"panels": [
{
"codeName": "TradingSimulationPanel",
"moduleName": "TradingSimulationPanel",
"event": "Current Record Changed"
}
]
},
{
"codeName": "Conditions",
"moduleName": "Conditions",
"description": "Plots Simulation Conditions.",
"profilePicture": "Conditions.png",
"panels": []
},
{
"codeName": "Strategies",
"moduleName": "Strategies",
"description": "Plots Strategies.",
"profilePicture": "Strategies.png",
"panels": [
]
},
{
"codeName": "Trades",
"moduleName": "Trades",
"description": "Plots Trades.",
"profilePicture": "Trades.png",
"panels": [
]
},
{
"codeName": "SimulationExecution",
"moduleName": "SimulationExecution",
"description": "Plots Simulation Execution.",
"profilePicture": "SimulationExecution.png",
"panels": [
{
"codeName": "SimulationExecutionPanel",
"moduleName": "SimulationExecutionPanel",
"event": "Current Record Changed"
}
]
}
]
}