Merge remote-tracking branch 'upstream/develop' into develop
This commit is contained in:
commit
792a1067d0
21 files changed
+2301
-214
No files matched your search
+20
@@ -0,0 +1,20 @@
|
||||
NODE_ENV=production
|
||||
PORT=4101
|
||||
|
||||
VIRTUAL_HOST=charts-dev.superalgos.org
|
||||
LETSENCRYPT_HOST=charts-dev.superalgos.org
|
||||
LETSENCRYPT_EMAIL=ssl-certificates@advancedalgos.org
|
||||
VIRTUAL_PORT=4101
|
||||
|
||||
#Log options
|
||||
CONSOLE_LOG=true
|
||||
CONSOLE_ERROR_LOG=true
|
||||
LOG_FILE_CONTENT=false
|
||||
|
||||
# Server commands
|
||||
PATH_TO_CANVAS_APP=./dependency/CanvasApp
|
||||
PATH_TO_FILES_COMPONENT=./dependency/Files-Component/src
|
||||
|
||||
# GATEWAY_ENDPOINT=https://platform-api-dev.superalgos.org/graphql
|
||||
GATEWAY_ENDPOINT=http://localhost:4100/graphql
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
[submodule "Plotters/AAMasters/plotters/Plotters-Trading-Simulation"]
|
||||
path = Plotters/AAMasters/plotters/Plotters-Trading-Simulation
|
||||
url = https://github.com/AAMasters/Plotters-Trading-Simulation.git
|
||||
branch = develop
|
||||
[submodule "Plotters/AAMasters/plotters/Plotters-Candles-Volumes"]
|
||||
path = Plotters/AAMasters/plotters/Plotters-Candles-Volumes
|
||||
url = https://github.com/AAMasters/Plotters-Candles-Volumes.git
|
||||
branch = develop
|
||||
[submodule "Plotters/AAMasters/plotters/Plotters-Bollinger-Channels"]
|
||||
path = Plotters/AAMasters/plotters/Plotters-Bollinger-Channels
|
||||
url = https://github.com/AAMasters/Plotters-Bollinger-Channels.git
|
||||
branch = develop
|
||||
[submodule "Plotters/AAMasters/plotters/Plotters-Bollinger-Bands"]
|
||||
path = Plotters/AAMasters/plotters/Plotters-Bollinger-Bands
|
||||
url = https://github.com/AAMasters/Plotters-Bollinger-Bands.git
|
||||
branch = develop
|
||||
[submodule "Plotters/AAMasters/plotters/Plotters-Stairs-Patterns"]
|
||||
path = Plotters/AAMasters/plotters/Plotters-Stairs-Patterns
|
||||
url = https://github.com/AAMasters/Plotters-Stairs-Patterns.git
|
||||
branch = develop
|
||||
[submodule "Plotters/AAMasters/plotters/Plotters-Trading"]
|
||||
path = Plotters/AAMasters/plotters/Plotters-Trading
|
||||
url = https://github.com/AAMasters/Plotters-Trading.git
|
||||
branch = develop
|
||||
[submodule "Plotters/AAVikings/plotters/Plotters-Linear-Regression-Curve"]
|
||||
path = Plotters/AAVikings/plotters/Plotters-Linear-Regression-Curve
|
||||
url = https://github.com/AAVikings/Plotters-Linear-Regression-Curve.git
|
||||
branch = master
|
||||
[submodule "Files-Component"]
|
||||
path = Files-Component
|
||||
url = https://github.com/Superalgos/Files-Component.git
|
||||
branch = develop
|
||||
[submodule "CanvasApp"]
|
||||
path = CanvasApp
|
||||
url = https://github.com/Superalgos/CanvasApp.git
|
||||
branch = develop
|
||||
Submodule
+1
Submodule CanvasApp added at bdd9dce6a4.
@@ -18,6 +18,9 @@ function newEcosystem() {
|
||||
}
|
||||
|
||||
let ECOSYSTEM = JSON.parse(window.localStorage.getItem('ecosystem'));
|
||||
if (ECOSYSTEM === null || ECOSYSTEM === undefined) {
|
||||
ECOSYSTEM = getUserEcosystem()
|
||||
}
|
||||
|
||||
return thisObject;
|
||||
|
||||
|
||||
Submodule
+1
Submodule Files-Component added at df6c6050c7.
Binary file not shown.
|
After Width: | Height: | Size: 436 KiB |
+1
Submodule Plotters/AAMasters/plotters/Plotters-Bollinger-Bands added at b801eb222c.
Submodule Plotters/AAMasters/plotters/Plotters-Bollinger-Channels added at f1466c8b43.
+1
Submodule Plotters/AAMasters/plotters/Plotters-Candles-Volumes added at f2254b9a21.
@@ -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": []
|
||||
}
|
||||
]
|
||||
}
|
||||
+1
Submodule Plotters/AAMasters/plotters/Plotters-Stairs-Patterns added at f2c3d2ad39.
+1
Submodule Plotters/AAMasters/plotters/Plotters-Trading added at 316a2a8476.
Submodule Plotters/AAMasters/plotters/Plotters-Trading-Simulation added at 54f9c8d647.
Submodule Plotters/AAVikings/plotters/Plotters-Linear-Regression-Curve added at df092daaa2.
+63
-28
@@ -17,11 +17,20 @@ function newAppLoader() {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] loadModules -> Entering function.') }
|
||||
|
||||
let ecosystem = await loadEcosystem()
|
||||
window.localStorage.setItem('ecosystem', JSON.stringify(ecosystem))
|
||||
let plotters = getPlotters(ecosystem)
|
||||
window.localStorage.removeItem('ecosystem')
|
||||
|
||||
let modulesArray = [
|
||||
let plotters, modulesArray
|
||||
let ecosystem = await loadEcosystem()
|
||||
if (ecosystem) {
|
||||
window.localStorage.setItem('ecosystem', JSON.stringify(ecosystem))
|
||||
plotters = getPlotters(ecosystem)
|
||||
} else {
|
||||
plotters = defaultPlotters()
|
||||
modulesArray = ['UserEcosystem.js']
|
||||
}
|
||||
|
||||
modulesArray = modulesArray.concat([
|
||||
'ChartsSpace/ViewPort.js',
|
||||
|
||||
'Globals.js',
|
||||
'Ecosystem.js',
|
||||
@@ -31,7 +40,6 @@ function newAppLoader() {
|
||||
'ChartsSpace/PlottersManager.js',
|
||||
'ChartsSpace/TimelineChart.js',
|
||||
'ChartsSpace/TimeMachine.js',
|
||||
'ChartsSpace/ViewPort.js',
|
||||
'ChartsSpace/TimeLineCoordinateSystem.js',
|
||||
|
||||
'TopSpace/CurrentEvent.js',
|
||||
@@ -114,7 +122,7 @@ function newAppLoader() {
|
||||
|
||||
'Utilities.js',
|
||||
'Dashboard.js'
|
||||
]
|
||||
])
|
||||
|
||||
modulesArray = modulesArray.concat(plotters)
|
||||
|
||||
@@ -145,10 +153,11 @@ function newAppLoader() {
|
||||
|
||||
if (downloadedCounter === modulesArray.length) {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] loadModules -> onRequired -> Starting Advanced Algos Platform.') }
|
||||
setTimeout(() => {
|
||||
dashboard = newDashboard()
|
||||
dashboard.start()
|
||||
}, 500)
|
||||
|
||||
dashboard = newDashboard()
|
||||
|
||||
dashboard.start()
|
||||
}
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] loadModules -> onRequired -> err = ' + err.stack) }
|
||||
@@ -163,19 +172,13 @@ function newAppLoader() {
|
||||
async function loadEcosystem() {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] loadEcosystem -> Entering function.') }
|
||||
|
||||
let headers
|
||||
let accessToken = window.localStorage.getItem('access_token')
|
||||
if (accessToken !== null) {
|
||||
headers = {
|
||||
authorization: 'Bearer ' + accessToken
|
||||
}
|
||||
}
|
||||
|
||||
let response = await axios({
|
||||
url: window.canvasApp.graphQL.masterAppApiUrl,
|
||||
method: 'post',
|
||||
data: {
|
||||
query: `
|
||||
let response = await axios({
|
||||
url: window.canvasApp.graphQL.masterAppApiUrl,
|
||||
method: 'post',
|
||||
data: {
|
||||
query: `
|
||||
query {
|
||||
web_GetEcosystem {
|
||||
id
|
||||
@@ -295,22 +298,54 @@ function newAppLoader() {
|
||||
}
|
||||
}
|
||||
`
|
||||
},
|
||||
headers: headers
|
||||
})
|
||||
},
|
||||
headers: {
|
||||
authorization: 'Bearer ' + accessToken
|
||||
}
|
||||
})
|
||||
|
||||
if (response.data.errors) {
|
||||
if (ERROR_LOG === true) { console.log(spacePad(MODULE_NAME, 50) + ' : ' + '[ERROR] AppPreLoader -> loadEcosystem -> response.text = ' + JSON.stringify(res.data.errors)) }
|
||||
throw error
|
||||
if (response.data.errors) {
|
||||
if (ERROR_LOG === true) { console.log(spacePad(MODULE_NAME, 50) + ' : ' + '[ERROR] AppPreLoader -> loadEcosystem -> response.text = ' + JSON.stringify(response.data.errors)) }
|
||||
throw error
|
||||
}
|
||||
|
||||
return response.data.data.web_GetEcosystem
|
||||
}
|
||||
}
|
||||
|
||||
return response.data.data.web_GetEcosystem
|
||||
function defaultPlotters() {
|
||||
return [
|
||||
'Plotters/AAMasters/Plotters-Candles-Volumes/Candles.js',
|
||||
'PlotterPanels/AAMasters/Plotters-Candles-Volumes/CandlePanel.js',
|
||||
'Plotters/AAMasters/Plotters-Candles-Volumes/Volumes.js',
|
||||
'PlotterPanels/AAMasters/Plotters-Candles-Volumes/VolumePanel.js',
|
||||
'Plotters/AAMasters/Plotters-Stairs-Patterns/CandleStairs.js',
|
||||
'Plotters/AAMasters/Plotters-Stairs-Patterns/VolumeStairs.js',
|
||||
'Plotters/AAMasters/Plotters-Trading/Details.js',
|
||||
'Plotters/AAMasters/Plotters-Trading/History.js',
|
||||
'Plotters/AAMasters/Plotters-Bollinger-Bands/BollingerBands.js',
|
||||
'PlotterPanels/AAMasters/Plotters-Bollinger-Bands/BollingerBandsPanel.js',
|
||||
'Plotters/AAMasters/Plotters-Bollinger-Bands/PercentageBandwidth.js',
|
||||
'Plotters/AAMasters/Plotters-Trading-Simulation/TradingSimulation.js',
|
||||
'PlotterPanels/AAMasters/Plotters-Trading-Simulation/TradingSimulationPanel.js',
|
||||
'Plotters/AAMasters/Plotters-Trading-Simulation/Conditions.js',
|
||||
'Plotters/AAMasters/Plotters-Trading-Simulation/Strategies.js',
|
||||
'Plotters/AAMasters/Plotters-Trading-Simulation/Trades.js',
|
||||
'Plotters/AAMasters/Plotters-Trading-Simulation/SimulationExecution.js',
|
||||
'PlotterPanels/AAMasters/Plotters-Trading-Simulation/SimulationExecutionPanel.js',
|
||||
'Plotters/AAMasters/Plotters-Bollinger-Channels/BollingerChannels.js',
|
||||
'PlotterPanels/AAMasters/Plotters-Bollinger-Channels/ChannelPanel.js',
|
||||
'Plotters/AAMasters/Plotters-Bollinger-Channels/BollingerSubChannels.js',
|
||||
'PlotterPanels/AAMasters/Plotters-Bollinger-Channels/SubChannelPanel.js',
|
||||
'Plotters/AAVikings/Plotters-Linear-Regression-Curve/LRC.js',
|
||||
'PlotterPanels/AAVikings/Plotters-Linear-Regression-Curve/ChannelPanel.js',
|
||||
'Plotters/AAMasters/Plotters-ROI/CombinedProfits.js'
|
||||
]
|
||||
}
|
||||
|
||||
function getPlotters(ecosystem) {
|
||||
if (INFO_LOG === true) { console.log('[INFO] server -> onBrowserRequest -> onFileRead -> addPlotters -> Entering function.') }
|
||||
|
||||
|
||||
let plotters = []
|
||||
let devTeams = ecosystem.devTeams
|
||||
let hosts = ecosystem.hosts
|
||||
|
||||
+8
-19
@@ -26,9 +26,9 @@ GLOBAL.CUSTOM_OK_RESPONSE = {
|
||||
GLOBAL.CUSTOM_FAIL_RESPONSE = {
|
||||
result: "Fail Because",
|
||||
message: "Custom Message"
|
||||
};
|
||||
};
|
||||
|
||||
let browserCanvas; // This is the canvas object of the browser.
|
||||
let browserCanvas; // This is the canvas object of the browser.
|
||||
|
||||
function spacePad(str, max) {
|
||||
str = str.toString();
|
||||
@@ -136,39 +136,28 @@ function loadAdvancedAlgosPlatform() {
|
||||
}
|
||||
|
||||
function callServer(pContentToSend, pPath, callBackFunction) {
|
||||
|
||||
let xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function () {
|
||||
if (this.readyState === 4 && this.status === 200) {
|
||||
|
||||
callBackFunction(xhttp.responseText);
|
||||
|
||||
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, xhttp.responseText);
|
||||
return;
|
||||
} else if (this.readyState === 4 && this.status === 404) {
|
||||
callBackFunction({ result: "Fail", message: xhttp.responseText.trim(), code: xhttp.responseText.trim() });
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
if (pContentToSend === undefined) {
|
||||
|
||||
xhttp.open("GET", pPath, true);
|
||||
xhttp.send();
|
||||
|
||||
} else {
|
||||
|
||||
try {
|
||||
|
||||
let blob = new Blob([pContentToSend], { type: 'text/plain' });
|
||||
|
||||
xhttp.open("POST", pPath, true);
|
||||
xhttp.send(blob);
|
||||
|
||||
} catch (err) {
|
||||
|
||||
if (ERROR_LOG === true) { console.log(spacePad(MODULE_NAME, 50) + " : " + "[ERROR] callServer -> err.message = " & err.message); }
|
||||
|
||||
callBackFunction({ result: "Fail", message: err.message })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
exports.newFileCloud = function newFileCloud() {
|
||||
const MODULE_NAME = 'File Cloud'
|
||||
const INFO_LOG = false
|
||||
const ERROR_LOG = true
|
||||
const axios = require('axios')
|
||||
|
||||
let thisObject = {
|
||||
getBlobToText: getBlobToText
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
function getBlobToText(container, filePath, host, callBackFunction) {
|
||||
try {
|
||||
if (INFO_LOG === true) { console.log('[INFO] getBlobToText -> Entering function.' + filePath) }
|
||||
|
||||
let headers
|
||||
|
||||
axios({
|
||||
url: process.env.GATEWAY_ENDPOINT,
|
||||
method: 'post',
|
||||
data: {
|
||||
query: `
|
||||
query web_PlotterCode($file: web_FileInput){
|
||||
web_PlotterCode(file: $file)
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
file: {
|
||||
container: container.toLowerCase(),
|
||||
filePath: filePath,
|
||||
storage: '',
|
||||
accessKey: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
headers: headers
|
||||
}).then(res => {
|
||||
if (res.data.errors) {
|
||||
if (ERROR_LOG === true) { console.log(MODULE_NAME + ' : ' + '[ERROR] FileCloud -> getBlobToText -> response.text = ' + JSON.stringify(res.data.errors)) }
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE, '', '')
|
||||
}
|
||||
let response = res.data.data.web_PlotterCode
|
||||
if (response)
|
||||
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, response, '')
|
||||
else
|
||||
callBackFunction(GLOBAL.CUSTOM_FAIL_RESPONSE)
|
||||
}).catch(error => {
|
||||
if (ERROR_LOG === true) { console.log(MODULE_NAME + ' : ' + '[ERROR] FileCloud -> getBlobToText -> Invalid JSON received: ' + error.message, error.stack) }
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE, '', '')
|
||||
})
|
||||
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { console.log('[ERROR] FileCloud -> getBlobToText -> err = ' + err.message, err.stack) }
|
||||
}
|
||||
}
|
||||
}
|
||||
+1258
File diff suppressed because it is too large.
Load diff
+60
-35
@@ -1,42 +1,67 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<!-- This file is only used for local development. -->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Superalgos</title>
|
||||
<meta charset="utf-8">
|
||||
<title>Superalgos Platform</title>
|
||||
<meta name="description"
|
||||
content="The system enabling a collective of humans and machines to collaborate and compete while co-building trading algorithms.">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Saira+Condensed:300,600|Saira:300,600&subset=latin-ext,vietnamese"
|
||||
rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css"
|
||||
integrity="sha384-DNOHZ68U8hZfKXOrtjWvjxusGo9WQnrNx2sqG0tfsghAvtVlRW3tvkXWZh58N9jp" crossorigin="anonymous">
|
||||
<link rel="shortcut icon" type="image/png/ico" href="Images/favicon.ico" />
|
||||
|
||||
<script src="https://unpkg.com/apollo-client-browser@1.7.0"></script>
|
||||
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
|
||||
<script type="text/javascript" src="Scripts/require.js"></script>
|
||||
<script type="text/javascript" src="Scripts/AppPreLoader.js"></script>
|
||||
<link href="https://fonts.googleapis.com/css?family=Saira" rel="stylesheet">
|
||||
|
||||
<script src="https://unpkg.com/apollo-client-browser@1.7.0"></script>
|
||||
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="Scripts/require.js"></script>
|
||||
<script type="text/javascript" src="Scripts/AppPreLoader.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function loadCanvas() {
|
||||
if (window.canvasApp.visible === undefined) {
|
||||
window.canvasApp = {
|
||||
version: '1.0.0', // This is used to avoid catching problems at the browser level.
|
||||
sessionToken: '',
|
||||
executingAt: 'Master App',
|
||||
visible: true,
|
||||
topMargin: 1,
|
||||
urlPrefix: 'http://localhost:1337/',
|
||||
graphQL: {
|
||||
masterAppApiUrl: 'https://demo-api-dev.superalgos.org/graphql',
|
||||
},
|
||||
context: {}
|
||||
};
|
||||
|
||||
try {
|
||||
loadAdvancedAlgosPlatform();
|
||||
} catch (err) {
|
||||
console.log("[ERROR] CanvasApp can not be started. Please check that AAWeb is running.", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onResize() {
|
||||
if (window.canvasApp === undefined) { return }
|
||||
if (window.canvasApp.eventHandler === undefined) { return }
|
||||
window.canvasApp.eventHandler.raiseEvent('Browser Resized')
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body id="body" style="margin: 0px; padding: 0px; border: 0px; background-image: url(/Images/superalgos-platform-y.jpg); background-size: cover; " onresize="window.canvasApp.eventHandler.raiseEvent('Browser Resized');" onload="
|
||||
window.canvasApp={
|
||||
version: '1.0.0' , // This is used to avoid catching problems at the browser level.
|
||||
executingAt: 'Master App',
|
||||
visible: true,
|
||||
topMargin: 35,
|
||||
urlPrefix: 'http://localhost:1337/',
|
||||
graphQL: {
|
||||
masterAppApiUrl: 'https://demo-api-dev.superalgos.org/graphql/',
|
||||
},
|
||||
context: {}
|
||||
};
|
||||
|
||||
|
||||
loadAdvancedAlgosPlatform();
|
||||
|
||||
">
|
||||
|
||||
<div id="masterApp"></div>
|
||||
<div id="canvasApp"></div>
|
||||
<div id="textAreaDiv"></div>
|
||||
<div id="inputDiv"></div>
|
||||
|
||||
<body id="body" onload="loadCanvas()"
|
||||
style="overflow:hidden; background: url(Images/superalgos-platform.jpg)"
|
||||
onresize="onResize()">
|
||||
<div id="masterApp"></div>
|
||||
<div id="canvasApp"></div>
|
||||
<div id="textAreaDiv"></div>
|
||||
<div id="inputDiv"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -34,12 +34,9 @@ let http = require('http')
|
||||
let port = process.env.PORT || 1337
|
||||
let isHttpServerStarted = false
|
||||
|
||||
const FILE_CLOUD = require('./Server/FileCloud')
|
||||
let fileCloud = FILE_CLOUD.newFileCloud()
|
||||
|
||||
startHtttpServer()
|
||||
|
||||
function startHtttpServer () {
|
||||
function startHtttpServer() {
|
||||
if (CONSOLE_LOG === true) { console.log('[INFO] server -> startHtttpServer -> Entering function.') }
|
||||
|
||||
try {
|
||||
@@ -52,7 +49,7 @@ function startHtttpServer () {
|
||||
}
|
||||
}
|
||||
|
||||
function onBrowserRequest (request, response) {
|
||||
function onBrowserRequest(request, response) {
|
||||
if (CONSOLE_LOG === true && request.url.indexOf('NO-LOG') === -1) { console.log('[INFO] server -> onBrowserRequest -> request.url = ' + request.url) }
|
||||
|
||||
let requestParameters = request.url.split('/')
|
||||
@@ -148,15 +145,15 @@ function onBrowserRequest (request, response) {
|
||||
|
||||
{
|
||||
if (requestParameters[3] === undefined) {
|
||||
respondWithFile(process.env.PATH_TO_CANVAS_APP + '/StrategySpace/' + requestParameters[2], response)
|
||||
respondWithFile(process.env.PATH_TO_CANVAS_APP + '/StrategySpace/' + requestParameters[2], response)
|
||||
return
|
||||
}
|
||||
if (requestParameters[4] === undefined) {
|
||||
respondWithFile(process.env.PATH_TO_CANVAS_APP + '/StrategySpace/' + requestParameters[2] + '/' + requestParameters[3], response)
|
||||
respondWithFile(process.env.PATH_TO_CANVAS_APP + '/StrategySpace/' + requestParameters[2] + '/' + requestParameters[3], response)
|
||||
return
|
||||
}
|
||||
if (requestParameters[5] === undefined) {
|
||||
respondWithFile(process.env.PATH_TO_CANVAS_APP + '/StrategySpace/' + requestParameters[2] + '/' + requestParameters[3] + '/' + requestParameters[4], response)
|
||||
respondWithFile(process.env.PATH_TO_CANVAS_APP + '/StrategySpace/' + requestParameters[2] + '/' + requestParameters[3] + '/' + requestParameters[4], response)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -182,13 +179,21 @@ function onBrowserRequest (request, response) {
|
||||
|
||||
case 'Plotters': // This means the plotter folder, not to be confused with the Plotters script!
|
||||
{
|
||||
respondWithSourceCode(requestParameters, response)
|
||||
let devTeam = requestParameters[2]
|
||||
let codeName = requestParameters[3]
|
||||
let moduleName = requestParameters[4]
|
||||
let filePath = './Plotters/' + devTeam + '/plotters/' + codeName + '/' + moduleName
|
||||
respondWithFile(filePath, response)
|
||||
}
|
||||
break
|
||||
|
||||
case 'PlotterPanels': // This means the PlotterPanels folder, not to be confused with the Plotter Panels scripts!
|
||||
{
|
||||
respondWithSourceCode(requestParameters, response)
|
||||
let devTeam = requestParameters[2]
|
||||
let codeName = requestParameters[3]
|
||||
let moduleName = requestParameters[4]
|
||||
let filePath = './Plotters/' + devTeam + '/plotters/' + codeName + '/' + moduleName
|
||||
respondWithFile(filePath, response)
|
||||
}
|
||||
break
|
||||
case 'Panels':
|
||||
@@ -233,20 +238,87 @@ function onBrowserRequest (request, response) {
|
||||
}
|
||||
break
|
||||
|
||||
case 'UserEcosystem.js':
|
||||
{
|
||||
let fs = require('fs')
|
||||
|
||||
try {
|
||||
let filePath = process.env.CONFIG_PATH + '/ecosystem.json'
|
||||
fs.readFile(filePath, onFileRead)
|
||||
} catch (e) {
|
||||
console.log('[ERROR] Error reading the user ecosystem.', e)
|
||||
}
|
||||
|
||||
function onFileRead(err, userEcosystem) {
|
||||
if (err) {
|
||||
respondWithContent(undefined, response)
|
||||
} else {
|
||||
let responseContent = 'function getUserEcosystem(){ return ' + userEcosystem + '}'
|
||||
respondWithContent(responseContent, response)
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
|
||||
case 'Storage':
|
||||
{
|
||||
respondWithFile(process.env.STORAGE_PATH + '/' + request.url.substring(9), response)
|
||||
}
|
||||
break
|
||||
|
||||
case 'ReadUserConfig':
|
||||
{
|
||||
respondWithFile(process.env.CONFIG_PATH + '/userConfig.json', response)
|
||||
}
|
||||
break
|
||||
|
||||
case 'WriteUserConfig':
|
||||
{
|
||||
let fs = require('fs')
|
||||
let body = '';
|
||||
|
||||
request.on('data', function (data) {
|
||||
body += data;
|
||||
// Too much POST data
|
||||
if (body.length > 1e6)
|
||||
request.connection.destroy();
|
||||
});
|
||||
|
||||
request.on('end', function () {
|
||||
try {
|
||||
let filePath = process.env.CONFIG_PATH + '/userConfig.json'
|
||||
fs.writeFile(filePath, body, onFileWrite)
|
||||
} catch (e) {
|
||||
console.log('[ERROR] Error writing user config.', e)
|
||||
respondWithContent(undefined, response)
|
||||
}
|
||||
|
||||
function onFileWrite(err) {
|
||||
if (err) {
|
||||
respondWithContent(undefined, response)
|
||||
} else {
|
||||
let responseContent = 'User config updated.'
|
||||
respondWithContent(responseContent, response)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
break
|
||||
|
||||
default:
|
||||
{
|
||||
homePage()
|
||||
}
|
||||
}
|
||||
|
||||
function homePage () {
|
||||
function homePage() {
|
||||
if (requestParameters[1] === '') {
|
||||
let fs = require('fs')
|
||||
try {
|
||||
let fileName = 'index.html'
|
||||
fs.readFile(fileName, onFileRead)
|
||||
|
||||
function onFileRead (err, file) {
|
||||
function onFileRead(err, file) {
|
||||
if (CONSOLE_LOG === true) { console.log('[INFO] server -> onBrowserRequest -> onFileRead -> Entering function.') }
|
||||
|
||||
try {
|
||||
@@ -272,7 +344,32 @@ function onBrowserRequest (request, response) {
|
||||
}
|
||||
}
|
||||
|
||||
function respondWithContent (content, response) {
|
||||
function respondWithFile(fileName, response) {
|
||||
if (CONSOLE_LOG === true) { console.log('[INFO] server -> respondWithFile -> Entering function.') }
|
||||
|
||||
let fs = require('fs')
|
||||
if (fileName.indexOf('undefined') > 0) {
|
||||
console.log('[WRN] server -> respondWithFile -> Received request for undefined file. ')
|
||||
respondWithContent(undefined, response)
|
||||
} else {
|
||||
try {
|
||||
fs.readFile(fileName, onFileRead)
|
||||
|
||||
function onFileRead(err, file) {
|
||||
if (CONSOLE_LOG === true) { console.log('[INFO] server -> respondWithFile -> onFileRead -> Entering function.') }
|
||||
if (!err) {
|
||||
respondWithContent(file.toString(), response)
|
||||
} else {
|
||||
respondWithContent(undefined, response)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
returnEmptyArray()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function respondWithContent(content, response) {
|
||||
if (CONSOLE_LOG === true) { console.log('[INFO] server -> respondWithContent -> Entering function.') }
|
||||
|
||||
try {
|
||||
@@ -281,61 +378,27 @@ function respondWithContent (content, response) {
|
||||
response.setHeader('Expires', '0') // Proxies.
|
||||
response.setHeader('Access-Control-Allow-Origin', '*') // Allows to access data from other domains.
|
||||
|
||||
response.writeHead(200, { 'Content-Type': 'text/html' })
|
||||
response.write(content)
|
||||
if (content !== undefined) {
|
||||
response.writeHead(200, { 'Content-Type': 'text/html' })
|
||||
response.write(content)
|
||||
} else {
|
||||
response.writeHead(404, { 'Content-Type': 'text/html' });
|
||||
response.write('The specified key does not exist.')
|
||||
}
|
||||
response.end('\n')
|
||||
// console.log("Content Sent: " + content);
|
||||
} catch (err) {
|
||||
returnEmptyArray(response)
|
||||
}
|
||||
}
|
||||
|
||||
function respondWithFile (fileName, response) {
|
||||
if (CONSOLE_LOG === true) { console.log('[INFO] server -> respondWithFile -> Entering function.') }
|
||||
|
||||
let fs = require('fs')
|
||||
try {
|
||||
if (fileName.indexOf('undefined') > 0) {
|
||||
console.log('[WRN] server -> respondWithFile -> Received request for undefined file. ')
|
||||
return
|
||||
}
|
||||
|
||||
fs.readFile(fileName, onFileRead)
|
||||
|
||||
function onFileRead (err, file) {
|
||||
if (CONSOLE_LOG === true) { console.log('[INFO] server -> respondWithFile -> onFileRead -> Entering function.') }
|
||||
|
||||
try {
|
||||
let htmlResponse = file.toString()
|
||||
|
||||
response.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate') // HTTP 1.1.
|
||||
response.setHeader('Pragma', 'no-cache') // HTTP 1.0.
|
||||
response.setHeader('Expires', '0') // Proxies.
|
||||
response.setHeader('Access-Control-Allow-Origin', '*') // Allows to access data from other domains.
|
||||
|
||||
// response.writeHead(200, { 'Content-Type': 'text/html' });
|
||||
response.write(htmlResponse)
|
||||
response.end('\n')
|
||||
// console.log("File Sent: " + fileName);
|
||||
//
|
||||
} catch (err) {
|
||||
console.log('[ERROR] server -> respondWithFile -> onFileRead -> File Not Found: ' + fileName + ' or Error = ' + err.stack)
|
||||
returnEmptyArray()
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
returnEmptyArray()
|
||||
}
|
||||
}
|
||||
|
||||
function respondWithImage (fileName, response) {
|
||||
function respondWithImage(fileName, response) {
|
||||
if (CONSOLE_LOG === true) { console.log('[INFO] server -> respondWithImage -> Entering function.') }
|
||||
|
||||
let fs = require('fs')
|
||||
try {
|
||||
fs.readFile(fileName, onFileRead)
|
||||
|
||||
function onFileRead (err, file) {
|
||||
function onFileRead(err, file) {
|
||||
if (CONSOLE_LOG === true) { console.log('[INFO] server -> respondWithImage -> onFileRead -> Entering function.') }
|
||||
|
||||
try {
|
||||
@@ -355,7 +418,7 @@ function respondWithImage (fileName, response) {
|
||||
}
|
||||
}
|
||||
|
||||
function returnEmptyArray (response) {
|
||||
function returnEmptyArray(response) {
|
||||
try {
|
||||
if (CONSOLE_LOG === true) { console.log('[INFO] server -> respondWithFile -> returnEmptyArray -> Entering function.') }
|
||||
|
||||
@@ -370,21 +433,3 @@ function returnEmptyArray (response) {
|
||||
console.log('[ERROR] server -> returnEmptyArray -> err.message ' + err.message)
|
||||
}
|
||||
}
|
||||
|
||||
function respondWithSourceCode (requestParameters, response) {
|
||||
let devTeam = requestParameters[2]
|
||||
let codeName = requestParameters[3]
|
||||
let moduleName = requestParameters[4]
|
||||
|
||||
let filePath = devTeam + '/plotters/' + codeName + '/' + moduleName
|
||||
|
||||
fileCloud.getBlobToText(devTeam.toLowerCase(), filePath, null, onDataArrived)
|
||||
|
||||
function onDataArrived (err, pData) {
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
console.log('[ERROR] server -> onBrowserRequest -> respondWithSourceCode -> Could not read a file -> err.message = ' + err.message, err.stack)
|
||||
pData = ''
|
||||
}
|
||||
respondWithContent(pData, response)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user