adding plotter that doesn't exist on git

This commit is contained in:
Matias committed 2019-07-27 07:28:41 -03:00
1 parent 1fbef45bf5
commit 8b6966a5be
3 files changed
+725 -1

No files matched your search

@@ -0,0 +1,711 @@
function newAAMastersPlottersROICombinedProfits() {
const MODULE_NAME = "AAArena Plotters ROI Combined Profits";
const ERROR_LOG = true;
const INTENSIVE_LOG = false;
const logger = newWebDebugLog();
logger.fileName = MODULE_NAME;
let thisObject = {
// Main functions and properties.
initialize: initialize,
container: undefined,
getContainer: getContainer,
setTimePeriod: setTimePeriod,
setDatetime: setDatetime,
recalculateScale: recalculateScale,
draw: draw,
payload: []
};
/* this is part of the module template */
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
let timeLineCoordinateSystem = newTimeLineCoordinateSystem(); // Needed to be able to plot on the timeline, otherwise not.
let timePeriod; // This will hold the current Time Period the user is at.
let datetime; // This will hold the current Datetime the user is at.
/* these are module specific variables: */
let competition;
let competitorsSequences;
let updatedFilesEventsReceived = 0;
let fileStyles = [];
let offsetChangedEventSubscriptionId
let filesUpdatedEventSubscriptionId
let dimmensionsChangedEventSubscriptionId
return thisObject;
function finalize() {
try {
/* Stop listening to the necesary events. */
viewPort.eventHandler.stopListening(offsetChangedEventSubscriptionId);
fileSequence.eventHandler.stopListening(filesUpdatedEventSubscriptionId);
thisObject.container.eventHandler.stopListening(dimmensionsChangedEventSubscriptionId)
/* Destroyd References */
datetime = undefined;
timePeriod = undefined;
fileSequence = undefined;
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] finalize -> err = " + err.stack); }
}
}
function initialize(pCompetition, pStorage, pDatetime, pTimePeriod, callBackFunction) {
try {
competition = pCompetition;
competitorsSequences = pStorage.competitorsSequences;
datetime = pDatetime;
timePeriod = pTimePeriod;
recalculate();
recalculateScale();
offsetChangedEventSubscriptionId = viewPort.eventHandler.listenToEvent("Offset Changed", onOffsetChanged);
/* Create the Payload structure */
for (let k = 0; k < competition.participants.length; k++) {
let participant = competition.participants[k];
let payload = {
profile: {
position: {
x: 0,
y: 0
},
visible: false,
plot: true
}
}
thisObject.payload.push(payload);
}
for (let k = 0; k < competition.participants.length; k++) {
let fileSequence = competitorsSequences[0][k]; // Only the first dataSet is considered for now.
filesUpdatedEventSubscriptionId = fileSequence.eventHandler.listenToEvent("Files Updated", onFilesUpdated); // Only the first sequence is supported right now.
}
/* Here we will choose the colors of each participants path. */
for (let k = 0; k < competition.participants.length; k++) {
let red = Math.trunc(Math.random() * 5) * 50;
let green = Math.trunc(Math.random() * 5) * 50;
let blue = Math.trunc(Math.random() * 5) * 50;
let fillStyle = " " + red + "," + green + "," + blue;
fileStyles.push(fillStyle);
}
dimmensionsChangedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('Dimmensions Changed', function () {
recalculateScale()
recalculate();
})
recalculate();
recalculateScale();
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err.stack); }
}
}
function getContainer(point) {
try {
let container;
/* First we check if this point is inside this space. */
if (thisObject.container.frame.isThisPointHere(point) === true) {
return thisObject.container;
} else {
/* This point does not belong to this space. */
return undefined;
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] getContainer -> err = " + err.stack); }
}
}
function onFilesUpdated() {
try {
updatedFilesEventsReceived++;
if (updatedFilesEventsReceived === competition.participants.length) {
recalculate();
updatedFilesEventsReceived = 0;
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] onFilesUpdated -> err = " + err.stack); }
}
}
function setTimePeriod(pTimePeriod) {
try {
timePeriod = pTimePeriod;
recalculate();
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] setTimePeriod -> err = " + err.stack); }
}
}
function setDatetime(newDatetime) {
try {
datetime = newDatetime;
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] setDatetime -> err = " + err.stack); }
}
}
function draw() {
try {
return; // This plotter is currently disabled.
if (INTENSIVE_LOG === true) { logger.write("[INFO] setDatetime -> Entering function."); }
plotStartFinishLines();
plotChart();
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] draw -> err = " + err.stack); }
}
}
function onOffsetChanged() {
try {
if (Math.random() * 100 > 95) {
recalculate()
};
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] onOffsetChanged -> err = " + err.stack); }
}
}
function recalculate() {
try {
if (competitorsSequences === undefined) { return; }
/*
We are going to filter the records depending on the Time Period. 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.
*/
for (let k = 0; k < competition.participants.length; k++) {
let fileSequence = competitorsSequences[0][k]; // Only the first dataSet is considered for now.
competition.participants[k].plotElements = [];
let maxSequence = fileSequence.getFilesLoaded();
for (let j = 0; j < maxSequence; j++) {
let file = fileSequence.getFile(j);
/* First the small balls */
const ONE_MIN_IN_MILISECONDS = 60 * 1000;
let step = timePeriod / ONE_MIN_IN_MILISECONDS;
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],
messageRelevance: file[i][15],
messageTitle: file[i][16],
messageBody: file[i][17]
};
competition.participants[k].plotElements.push(newHistoryRecord);
lastRecordPushed = i;
}
/* 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],
messageRelevance: file[i][15],
messageTitle: file[i][16],
messageBody: file[i][17]
};
competition.participants[k].plotElements.push(newHistoryRecord);
}
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] recalculate -> err = " + err.stack); }
}
}
function recalculateScale() {
try {
if (competitorsSequences === undefined) { return; } // We need the market file to be loaded to make the calculation.
if (timeLineCoordinateSystem.maxValue > 0) { return; } // Already calculated.
let minValue = {
x: MIN_PLOTABLE_DATE.valueOf(),
y: 0
};
let maxValue = {
x: MAX_PLOTABLE_DATE.valueOf(),
y: 200 * 100
};
timeLineCoordinateSystem.initialize(
minValue,
maxValue,
thisObject.container.frame.width,
thisObject.container.frame.height
);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] recalculateScale -> err = " + err.stack); }
}
}
function plotStartFinishLines() {
try {
let startDatetime = new Date(competition.startDatetime);
let finishDatetime = new Date(competition.finishDatetime);
let startPointDown = {
x: startDatetime.valueOf(),
y: 0
};
let startPointUp = {
x: startDatetime.valueOf(),
y: 0
};
startPointDown = timeLineCoordinateSystem.transformThisPoint(startPointDown);
startPointDown = transformThisPoint(startPointDown, thisObject.container);
startPointUp = timeLineCoordinateSystem.transformThisPoint(startPointUp);
startPointUp.y = startPointUp.y - thisObject.container.frame.height;
startPointUp = transformThisPoint(startPointUp, thisObject.container);
if (startPointUp.x > viewPort.visibleArea.bottomLeft.x && startPointUp.x < viewPort.visibleArea.bottomRight.x) {
startPointDown = viewPort.fitIntoVisibleArea(startPointDown);
startPointUp = viewPort.fitIntoVisibleArea(startPointUp);
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(startPointDown.x, startPointDown.y);
browserCanvasContext.lineTo(startPointUp.x, startPointUp.y);
browserCanvasContext.closePath();
browserCanvasContext.strokeStyle = 'rgba(100, 10, 10, 0.5)';
browserCanvasContext.lineWidth = 2;
browserCanvasContext.stroke();
}
/* Here we draw the finish line. */
let SQUARE_SIDE_REDUCTION_FACTOR = 4;
if (timePeriod <= _1_HOUR_IN_MILISECONDS) { SQUARE_SIDE_REDUCTION_FACTOR = 2; }
if (timePeriod <= _10_MINUTES_IN_MILISECONDS) { SQUARE_SIDE_REDUCTION_FACTOR = 1; }
if (timePeriod < _5_MINUTES_IN_MILISECONDS) { SQUARE_SIDE_REDUCTION_FACTOR = 0.5; }
const TOTAL_SQUARES_TALL = ONE_DAY_IN_MILISECONDS / timePeriod * (timePeriod / _1_MINUTE_IN_MILISECONDS) / SQUARE_SIDE_REDUCTION_FACTOR;
const SQUARE_SIDE = thisObject.container.frame.height / TOTAL_SQUARES_TALL;
let paintThis = true;
for (i = 0; i < 3; i++) {
for (j = 0; j < TOTAL_SQUARES_TALL; j++) {
let finishPointDown = {
x: finishDatetime.valueOf(),
y: 0
};
let finishPointUp = {
x: finishDatetime.valueOf(),
y: 0
};
finishPointDown = timeLineCoordinateSystem.transformThisPoint(finishPointDown);
finishPointDown.x = finishPointDown.x + SQUARE_SIDE * i;
finishPointDown.y = finishPointDown.y - SQUARE_SIDE * j;
finishPointDown = transformThisPoint(finishPointDown, thisObject.container);
finishPointUp = timeLineCoordinateSystem.transformThisPoint(finishPointUp);
finishPointUp.x = finishPointUp.x + SQUARE_SIDE * i + SQUARE_SIDE;
finishPointUp.y = finishPointUp.y - SQUARE_SIDE * j - SQUARE_SIDE;
finishPointUp = transformThisPoint(finishPointUp, thisObject.container);
if (finishPointUp.x < viewPort.visibleArea.bottomLeft.x || finishPointDown.x > viewPort.visibleArea.bottomRight.x) { continue; }
finishPointDown = viewPort.fitIntoVisibleArea(finishPointDown);
finishPointUp = viewPort.fitIntoVisibleArea(finishPointUp);
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(finishPointDown.x, finishPointDown.y);
browserCanvasContext.lineTo(finishPointUp.x, finishPointDown.y);
browserCanvasContext.lineTo(finishPointUp.x, finishPointUp.y);
browserCanvasContext.lineTo(finishPointDown.x, finishPointUp.y);
browserCanvasContext.closePath();
/*
browserCanvasContext.strokeStyle = 'rgba(100, 100, 100, 1)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
*/
if (paintThis === true) {
browserCanvasContext.fillStyle = 'rgba(100, 100, 100, ' + (0.6 - i / 5) + ')';
browserCanvasContext.fill();
}
if (paintThis === true) { paintThis = false; } else { paintThis = true; }
}
if (paintThis === true) { paintThis = false; } else { paintThis = true; }
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] plotStartFinishLines -> err = " + err.stack); }
}
}
function plotChart() {
try {
let userPosition = getUserPosition()
let userPositionDate = userPosition.point.x
for (let k = 0; k < competition.participants.length; k++) {
let point = {
x: 0,
y: 0
};
let upLabel = "";
let participant = competition.participants[k];
let plotElements = participant.plotElements;
if (plotElements !== undefined) {
let profileIntervalCounter = 0;
let previousPoint;
for (let i = 0; i < plotElements.length; i++) {
record = plotElements[i];
point = {
x: record.date,
y: record.combinedProfitsB * 100
};
upLabel = "ROI: " + Math.trunc(record.combinedProfitsB * 10000) / 10000 + " %";
point = timeLineCoordinateSystem.transformThisPoint(point);
point.y = point.y - thisObject.container.frame.height / 2;
point = transformThisPoint(point, thisObject.container);
if (point.x < viewPort.visibleArea.bottomLeft.x || point.x > viewPort.visibleArea.bottomRight.x) { continue; }
point = viewPort.fitIntoVisibleArea(point);
let isCurrentRecord = false;
if (userPositionDate >= record.date - timePeriod / 2 && userPositionDate <= record.date + timePeriod / 2 - 1) {
isCurrentRecord = true;
}
let opacity = '0.2';
let radius = 2;
browserCanvasContext.lineWidth = 1;
/* Circles */
if (thisObject.payload[k].profile.plot === true) {
browserCanvasContext.beginPath();
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', ' + opacity + ')';
if (isCurrentRecord === false) {
browserCanvasContext.fillStyle = 'rgba(' + fileStyles[k] + ', ' + opacity + ')';
} else {
browserCanvasContext.fillStyle = 'rgba(255, 233, 31, ' + opacity + ')'; /* highlight the current record */
}
browserCanvasContext.arc(point.x, point.y, radius, 0, Math.PI * 2, true);
browserCanvasContext.closePath();
if (point.x < viewPort.visibleArea.topLeft.x + 50 || point.x > viewPort.visibleArea.bottomRight.x - 50) {/*we leave this history without fill. */ } else {
browserCanvasContext.fill();
}
browserCanvasContext.stroke();
}
/* Since there is at least some point plotted, then the profile should be visible. */
thisObject.payload[k].profile.visible = true;
/* Line */
if (previousPoint !== undefined && thisObject.payload[k].profile.plot === true) {
browserCanvasContext.strokeStyle = 'rgba(' + fileStyles[k] + ', ' + opacity + ')';
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(previousPoint.x, previousPoint.y);
browserCanvasContext.lineTo(point.x, point.y);
browserCanvasContext.closePath();
browserCanvasContext.stroke();
}
previousPoint = {
x: point.x,
y: point.y
};
/* Image */
if (thisObject.payload[k].profile.plot === true) {
profileIntervalCounter++;
if (profileIntervalCounter === 25) {
profileIntervalCounter = 0;
if (participant.profilePicture !== undefined) {
let imageId = participant.devTeam + "." + participant.profilePicture;
imageSize = 15;
if (imageId !== undefined) {
let image = document.getElementById(imageId);
if (image !== null) {
let offset = imageSize * 1.5;
if (point.y > viewPort.visibleArea.bottomLeft.y / 2) { offset = - offset; }
/* The line */
browserCanvasContext.lineWidth = 0.3;
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', ' + opacity + ')';
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point.x, point.y + offset);
browserCanvasContext.lineTo(point.x, point.y);
browserCanvasContext.closePath();
browserCanvasContext.stroke();
/* The Image */
browserCanvasContext.drawImage(image, point.x - imageSize / 2, point.y - imageSize / 2 + offset, imageSize, imageSize);
/* Now the border */
browserCanvasContext.beginPath();
opacity = '0.5';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', ' + opacity + ')';
let radius = imageSize / 2 + 2;
browserCanvasContext.arc(point.x, point.y + offset, radius, 0, Math.PI * 2, true);
browserCanvasContext.closePath();
browserCanvasContext.stroke();
}
}
}
}
}
}
/*
We replace the coordinate of the profile point so that whoever has a reference to it, gets the new position.
We will use the last point plotted on screen as the profilePoint.
*/
thisObject.payload[k].profile.position.x = point.x;
thisObject.payload[k].profile.position.y = point.y;
thisObject.payload[k].profile.upLabel = upLabel;
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] plotChart -> err = " + err.stack); }
}
}
}
@@ -0,0 +1,13 @@
{
"displayName": "Plotters ROI",
"codeName": "PlottersROI",
"devTeam": "AAMasters",
"modules": [
{
"codeName": "CombinedProfits",
"moduleName": "CombinedProfits",
"description": "Plots participants of a competition by the ROI each one had over time.",
"panels": []
}
]
}