Beta6 update: Time Frame Files

This commit is contained in:
Luis Fernando Molina committed 2020-07-28 13:28:14 +02:00
1 parent 6ec5580cd4
commit e90ccebe8f
31 files changed
+2632 -1382

No files matched your search

+2 -1
View File
@@ -35,4 +35,5 @@ PATH_TO_WEB_SERVER=./BackendServers/
APP_SCHEMA_PATH=./
WORKSPACE_PATH=./
MY_WORKSPACES_PATH=./My-Workspaces
MY_WORKSPACES_PATH=./My-Workspaces
PATH_TO_FONTS=./BackendServers/WebServer/Fonts
+47
View File
@@ -6980,6 +6980,40 @@
"icon": "settings",
"propertyNameAtParent": "userDefinedParameters"
},
{
"type": "Time Frames Filter",
"menuItems": [
{
"action": "Configure This",
"label": "Configure This",
"iconPathOn": "settings",
"iconPathOff": "settings",
"actionFunction": "uiObject.configEditor.activate"
},
{
"action": "Delete UI Object",
"askConfirmation": true,
"confirmationLabel": "Confirm to Delete",
"label": "Delete This",
"iconPathOn": "delete",
"iconPathOff": "delete",
"actionFunction": "payload.onMenuItemClick"
}
],
"initialValues": {
"config": "{ \n\"dailyTimeFrames\": [ \"45-min\", \"40-min\", \"30-min\", \"20-min\", \"15-min\", \"10-min\", \"05-min\", \"04-min\", \"03-min\", \"02-min\", \"01-min\" ],\n\"marketTimeFrames\": [ \"24-hs\", \"12-hs\", \"08-hs\", \"06-hs\", \"04-hs\", \"03-hs\", \"02-hs\", \"01-hs\"]\n}"
},
"addLeftIcons": true,
"editors": {
"config": true
},
"level": 3,
"chainAttachesTo": {
"compatibleTypes": "->Indicator Bot Instance->"
},
"icon": "time-period",
"propertyNameAtParent": "timeFramesFilter"
},
{
"type": "Paper Trading Session",
"docURL": "https://docs.superalgos.org/suite-hierarchy-network.html#paper-trading-session",
@@ -7379,6 +7413,14 @@
"dontShowAtFullscreen": true,
"actionFunction": "uiObject.configEditor.activate"
},
{
"action": "Add UI Object",
"disableIfPropertyIsDefined": true,
"propertyToCheckFor": "timeFramesFilter",
"label": "Add Time Frames Filter",
"relatedUiObject": "Time Frames Filter",
"actionFunction": "payload.onMenuItemClick"
},
{
"action": "Add UI Object",
"label": "Add Process Instance",
@@ -7414,6 +7456,11 @@
"type": "array",
"childType": "Indicator Process Instance",
"autoAdd": true
},
{
"name": "timeFramesFilter",
"type": "node",
"childType": "Time Frames Filter"
}
],
"propertyNameAtParent": "bot"
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,27 @@
<html lang="en">
<head>
<link rel="stylesheet" href="stylesheet.css" type="text/css" charset="utf-8" />
<style type="text/css">
body {
font-family: 'saira_condensedregular';
}
</style>
</head>
<body>
<div id="container">
<div id="header">
Saira Condensed Regular </div>
<ul class="tabs">
<li><a href="#specimen">Specimen</a></li>
<li><a href="#layout">Sample Layout</a></li>
<li><a href="#glyphs">Glyphs &amp; Languages</a></li>
<li><a href="#installing">Installing Webfonts</a></li>
</ul>
</div>
</body>
</html>
+14 -36
View File
@@ -1,45 +1,25 @@
<!doctype html>
<html lang="en">
<html lang="en">
<head>
<meta charset="utf-8">
<title>Superalgos</title>
<meta name="description"
content="Crypto Trading on an Industrial Scale">
<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&amp;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">
<meta name="description" content="Free and Open Source Crypto Trading Tools">
<link rel="stylesheet" href="main.css" type="text/css" charset="utf-8" />
<link rel="shortcut icon" type="image/png/ico" href="Images/favicon.ico" />
<script type="text/javascript" src="WebServer/require.js"></script>
<script type="text/javascript" src="WebServer/AppPreLoader.js"></script>
<script src="externalScripts/CCapture.all.min.js"></script>
<script type="text/javascript">
function loadCanvas() {
if (window.canvasApp.visible === undefined) {
window.canvasApp = {
version: '', // This is used to avoid catching problems at the browser level.
sessionToken: '',
visible: true,
topMargin: 0,
urlPrefix: 'http://localhost:WEB_SERVER_PORT/',
graphQL: {
masterAppApiUrl: 'https://demo-api-dev.superalgos.org/graphql',
},
context: {}
};
window.canvasApp = {
urlPrefix: 'http://localhost:WEB_SERVER_PORT/'
};
try {
loadSuperalgos();
} catch (err) {
console.log("[ERROR] CanvasApp can not be started. Please check that WebServer is running.", err);
}
try {
loadSuperalgos();
} catch (err) {
console.log("[ERROR] CanvasApp can not be started. Please check that WebServer is running.", err);
}
}
@@ -49,21 +29,19 @@
if (canvas.eventHandler === undefined) { return }
canvas.eventHandler.raiseEvent('Browser Resized')
} catch (err) {
console.log('Error Resizing. ' + err.stack)
}
}
</script>
</head>
<body id="body" onload="loadCanvas()"
style="overflow:hidden; background: url(Images/superalgos-platform.jpg); background-size: cover;"
onresize="onResize()">
style="overflow:hidden; background: url(Images/superalgos-platform.jpg); background-size: cover;"
onresize="onResize()">
<div id="masterApp"></div>
<div id="canvasApp"></div>
<div id="textAreaDiv"></div>
<div id="inputDiv" style="font-family:saira condensed;">&nbsp;</div>
</body>
</html>
</html>
+134 -76
View File
@@ -83,22 +83,6 @@ exports.newWebServer = function newWebServer(EVENTS_SERVER) {
let requestParameters = request.url.split('/')
if (requestParameters[1].indexOf('index.html') >= 0) {
/*
We use this to solve the problem when someone is arriving to the site with a sessionToken in the queryString. We extract here that
token, that will be sent later embedded into the HTML code, so that it can enter into the stardard circuit where any site can put
the sessionToken into their HTML code and from there the Browser app will log the user in.
*/
let queryString = requestParameters[1].split('?')
requestParameters[1] = ''
requestParameters[2] = queryString[1]
homePage()
return
}
requestParameters = request.url.split('?') // Remove version information
requestParameters = requestParameters[0].split('/')
@@ -185,58 +169,19 @@ exports.newWebServer = function newWebServer(EVENTS_SERVER) {
case 'Webhook':
{
switch (requestParameters[2]) { // switch by command
case 'Fetch-Messages': {
let exchange = requestParameters[3]
let market = requestParameters[4]
/* Some validations */
if (exchange === undefined) {
console.log('[WARN] webServer -> Webhook -> Fetch-Messages -> Message with no Exchange received -> messageReceived = ' + messageReceived)
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
return
}
if (market === undefined) {
console.log('[WARN] webServer -> Webhook -> Fetch-Messages -> Message with no market received -> messageReceived = ' + messageReceived)
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
return
}
let key = exchange + '-' + market
let webhookMessages = webhook.get(key)
if (webhookMessages === undefined) {
webhookMessages = []
}
respondWithContent(JSON.stringify(webhookMessages), response)
webhookMessages = []
webhook.set(key, webhookMessages)
break
}
case 'New-Message': {
getBody(processRequest)
function processRequest(messageReceived) {
let timestamp = (new Date()).valueOf()
let source = requestParameters[3]
let exchange = requestParameters[4]
let market = requestParameters[5]
switch (requestParameters[2]) { // switch by command
case 'Fetch-Messages': {
let exchange = requestParameters[3]
let market = requestParameters[4]
/* Some validations */
if (source === undefined) {
console.log('[WARN] webServer -> Webhook -> New-Message -> Message with no Source received -> messageReceived = ' + messageReceived)
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
return
}
if (exchange === undefined) {
console.log('[WARN] webServer -> Webhook -> New-Message -> Message with no Exchange received -> messageReceived = ' + messageReceived)
console.log('[WARN] webServer -> Webhook -> Fetch-Messages -> Message with no Exchange received -> messageReceived = ' + messageReceived)
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
return
}
if (market === undefined) {
console.log('[WARN] webServer -> Webhook -> New-Message -> Message with no market received -> messageReceived = ' + messageReceived)
console.log('[WARN] webServer -> Webhook -> Fetch-Messages -> Message with no market received -> messageReceived = ' + messageReceived)
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
return
}
@@ -248,17 +193,56 @@ exports.newWebServer = function newWebServer(EVENTS_SERVER) {
webhookMessages = []
}
webhookMessages.push([timestamp, source, messageReceived])
webhook.set(key, webhookMessages)
respondWithContent(JSON.stringify(webhookMessages), response)
webhookMessages = []
respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), response)
webhook.set(key, webhookMessages)
break
}
case 'New-Message': {
getBody(processRequest)
function processRequest(messageReceived) {
let timestamp = (new Date()).valueOf()
let source = requestParameters[3]
let exchange = requestParameters[4]
let market = requestParameters[5]
/* Some validations */
if (source === undefined) {
console.log('[WARN] webServer -> Webhook -> New-Message -> Message with no Source received -> messageReceived = ' + messageReceived)
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
return
}
if (exchange === undefined) {
console.log('[WARN] webServer -> Webhook -> New-Message -> Message with no Exchange received -> messageReceived = ' + messageReceived)
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
return
}
if (market === undefined) {
console.log('[WARN] webServer -> Webhook -> New-Message -> Message with no market received -> messageReceived = ' + messageReceived)
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
return
}
let key = exchange + '-' + market
let webhookMessages = webhook.get(key)
if (webhookMessages === undefined) {
webhookMessages = []
}
webhookMessages.push([timestamp, source, messageReceived])
webhook.set(key, webhookMessages)
respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), response)
}
break
}
break
}
break
}
break
}
break
case 'ResetLogsAndData':
{
@@ -429,6 +413,12 @@ exports.newWebServer = function newWebServer(EVENTS_SERVER) {
}
break
case 'Fonts':
{
respondWithFont(process.env.PATH_TO_FONTS + '/' + requestParameters[2], response)
}
break
case 'FloatingSpace':
{
respondWithFile(process.env.PATH_TO_CANVAS_APP + '/' + requestParameters[1] + '/' + requestParameters[2], response)
@@ -493,7 +483,7 @@ exports.newWebServer = function newWebServer(EVENTS_SERVER) {
case 'ListWorkspaces':
{
let dirPath = process.env.MY_WORKSPACES_PATH
let dirPath = process.env.MY_WORKSPACES_PATH
try {
let fs = require('fs')
@@ -516,7 +506,7 @@ exports.newWebServer = function newWebServer(EVENTS_SERVER) {
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
return
}
}
break
@@ -590,12 +580,41 @@ exports.newWebServer = function newWebServer(EVENTS_SERVER) {
}
break
case 'main.css':
{
mainCSS()
}
break
default:
{
homePage()
}
}
function mainCSS() {
let fs = require('fs')
try {
let fileName = process.env.PATH_TO_WEB_SERVER + 'WebServer/main.css'
fs.readFile(fileName, onFileRead)
function onFileRead(err, file) {
try {
let fileContent = file.toString()
fileContent = fileContent.replace('WEB_SERVER_PORT', process.env.WEB_SERVER_PORT)
fileContent = fileContent.replace('WEB_SERVER_PORT', process.env.WEB_SERVER_PORT)
fileContent = fileContent.replace('WEB_SERVER_PORT', process.env.WEB_SERVER_PORT)
respondWithContent(fileContent, response, 'text/css')
} catch (err) {
console.log('[ERROR] webServer -> mainCSS -> File Not Found: ' + fileName + ' or Error = ' + err.stack)
}
}
} catch (err) {
console.log(err)
}
}
function homePage() {
if (requestParameters[1] === '') {
let fs = require('fs')
@@ -604,15 +623,13 @@ exports.newWebServer = function newWebServer(EVENTS_SERVER) {
fs.readFile(fileName, onFileRead)
function onFileRead(err, file) {
if (CONSOLE_LOG === true) { console.log('[INFO] webServer -> onBrowserRequest -> onFileRead -> Entering function.') }
try {
let fileContent = file.toString()
fileContent = fileContent.replace('WEB_SERVER_PORT', process.env.WEB_SERVER_PORT)
respondWithContent(fileContent, response)
} catch (err) {
console.log('[ERROR] webServer -> onBrowserRequest -> File Not Found: ' + fileName + ' or Error = ' + err.stack)
console.log('[ERROR] webServer -> homePage -> File Not Found: ' + fileName + ' or Error = ' + err.stack)
}
}
} catch (err) {
@@ -649,7 +666,7 @@ exports.newWebServer = function newWebServer(EVENTS_SERVER) {
}
}
function respondWithContent(content, response) {
function respondWithContent(content, response, contentType) {
if (CONSOLE_LOG === true) { console.log('[INFO] webServer -> respondWithContent -> Entering function.') }
try {
@@ -659,7 +676,11 @@ exports.newWebServer = function newWebServer(EVENTS_SERVER) {
response.setHeader('Access-Control-Allow-Origin', '*') // Allows to access data from other domains.
if (content !== undefined) {
response.writeHead(200, { 'Content-Type': 'text/html' })
if (contentType !== undefined) {
response.writeHead(200, { 'Content-Type': contentType })
} else {
response.writeHead(200, { 'Content-Type': 'text/html' })
}
response.write(content)
} else {
response.writeHead(404, { 'Content-Type': 'text/html' })
@@ -679,8 +700,10 @@ exports.newWebServer = function newWebServer(EVENTS_SERVER) {
fs.readFile(fileName, onFileRead)
function onFileRead(err, file) {
if (CONSOLE_LOG === true) { console.log('[INFO] webServer -> respondWithImage -> onFileRead -> Entering function.') }
if (err) {
console.log('[ERROR] webServer -> respondWithImage -> onFileRead -> File Not Found: ' + fileName + ' or Error = ' + err.stack)
return
}
try {
response.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate') // HTTP 1.1.
response.setHeader('Pragma', 'no-cache') // HTTP 1.0.
@@ -698,6 +721,41 @@ exports.newWebServer = function newWebServer(EVENTS_SERVER) {
}
}
function respondWithFont(fileName, response) {
if (CONSOLE_LOG === true) { console.log('[INFO] webServer -> respondWithBinary -> Entering function.') }
let fs = require('fs')
try {
fs.readFile(fileName, onFileRead)
function onFileRead(err, file) {
if (CONSOLE_LOG === true) { console.log('[INFO] webServer -> respondWithBinary -> onFileRead -> Entering function.') }
try {
if (err) {
console.log('[ERROR] webServer -> respondWithBinary -> onFileRead -> File Not Found: ' + fileName + ' or Error = ' + err.stack)
return
}
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.
if (fileName.indexOf('2') < 0) {
response.writeHead(200, { 'Content-Type': 'font/woff' })
} else {
response.writeHead(200, { 'Content-Type': 'font/woff2' })
}
response.end(file, 'binary')
} catch (err) {
console.log('[ERROR] webServer -> respondWithBinary -> onFileRead -> File Not Found: ' + fileName + ' or Error = ' + err.stack)
}
}
} catch (err) {
console.log('[ERROR] webServer -> respondWithBinary -> err = ' + err.stack)
}
}
function returnEmptyArray(response) {
try {
if (CONSOLE_LOG === true) { console.log('[INFO] webServer -> respondWithFile -> returnEmptyArray -> Entering function.') }
+61 -70
View File
@@ -59,89 +59,80 @@ function newAnimation () {
function animationLoop () {
try {
if (window.canvasApp.visible === true) {
/* We set the canvas to its normal width and height */
// browserCanvas.width = window.innerWidth
// browserCanvas.height = window.innerHeight - CURRENT_TOP_MARGIN
/* First thing is to clear the actual canvas */
clearBrowserCanvas()
/* First thing is to clear the actual canvas */
clearBrowserCanvas()
/* We loop through the callback functions collections and execute them all. */
let performanceMap = new Map()
let totalTimeConsumed = 0
let totalElements = 0
let chanceToExecute
let randomNumber
let mustExecute
/* We loop through the callback functions collections and execute them all. */
let performanceMap = new Map()
let totalTimeConsumed = 0
let totalElements = 0
let chanceToExecute
let randomNumber
let mustExecute
// console.clear()
let row = 0
for (const [key, callBackFunction] of callBackFunctions.entries()) {
row++
switch (key) {
case 'Floating Space Physics':
chanceToExecute = 50
randomNumber = Math.random() * 100 * chanceToExecute
if (randomNumber > 100 - chanceToExecute) { mustExecute = true } else { mustExecute = false }
break
default: {
mustExecute = true
}
let row = 0
for (const [key, callBackFunction] of callBackFunctions.entries()) {
row++
switch (key) {
case 'Floating Space Physics':
chanceToExecute = 50
randomNumber = Math.random() * 100 * chanceToExecute
if (randomNumber > 100 - chanceToExecute) { mustExecute = true } else { mustExecute = false }
break
default: {
mustExecute = true
}
let timeConsumed = 0
if (mustExecute === true) {
let t0 = performance.now()
callBackFunction()
let t1 = performance.now()
timeConsumed = t1 - t0
if (key === 'Charting Space Draw') {
if (Math.random() * 100 > 99) {
totalConsumption = 0
totalCounter = 0
}
totalConsumption = totalConsumption + timeConsumed
totalCounter = totalCounter + 1
}
performanceMap.set(key, timeConsumed)
totalTimeConsumed = totalTimeConsumed + timeConsumed
totalElements++
}
}
let timeConsumed = 0
if (mustExecute === true) {
let t0 = performance.now()
callBackFunction()
let t1 = performance.now()
timeConsumed = t1 - t0
if (key === 'Charting Space Draw') {
if (Math.random() * 100 > 99) {
totalConsumption = 0
totalCounter = 0
}
totalConsumption = totalConsumption + timeConsumed
totalCounter = totalCounter + 1
}
performanceMap.set(key, timeConsumed)
totalTimeConsumed = totalTimeConsumed + timeConsumed
totalElements++
}
}
/* Frame per Seconds */
ANIMATION_FRAME_PER_SECONDS = Math.trunc(1000 / totalTimeConsumed)
ANIMATION_FRAME_PER_SECONDS = Math.trunc(1000 / totalTimeConsumed)
/* Performance Check */
if (SHOW_ANIMATION_PERFORMACE === true) {
row = 0
for (const [key, timeConsumed] of performanceMap.entries()) {
row++
labelToPrint = key + ' ' + timeConsumed.toFixed(4)
printLabel(labelToPrint, 10, 100 + row * 30, 1, 20, UI_COLOR.RED)
let percentage = timeConsumed * 100 / totalTimeConsumed
labelToPrint = key + ' ' + percentage.toFixed(1) + '%'
printLabel(labelToPrint, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
}
if (SHOW_ANIMATION_PERFORMACE === true) {
row = 0
for (const [key, timeConsumed] of performanceMap.entries()) {
row++
labelToPrint = key + ' ' + timeConsumed.toFixed(4)
printLabel(labelToPrint, 10, 100 + row * 30, 1, 20, UI_COLOR.RED)
let percentage = timeConsumed * 100 / totalTimeConsumed
labelToPrint = key + ' ' + percentage.toFixed(1) + '%'
printLabel(labelToPrint, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
}
/* Other Variables */
row++
printLabel(DEBUG.variable1, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
row++
printLabel(DEBUG.variable2, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
row++
printLabel(DEBUG.variable3, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
row++
printLabel(DEBUG.variable4, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
row++
printLabel('Animation Frame Per Seconds: ' + ANIMATION_FRAME_PER_SECONDS, 300, 100 + row * 30, 1, 20, UI_COLOR.TITANIUM_YELLOW)
}
} else {
browserCanvas.width = 1
browserCanvas.height = 1
row++
printLabel(DEBUG.variable1, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
row++
printLabel(DEBUG.variable2, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
row++
printLabel(DEBUG.variable3, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
row++
printLabel(DEBUG.variable4, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
row++
printLabel('Animation Frame Per Seconds: ' + ANIMATION_FRAME_PER_SECONDS, 300, 100 + row * 30, 1, 20, UI_COLOR.TITANIUM_YELLOW)
}
/* Video Recording */
+5 -10
View File
@@ -97,12 +97,11 @@ function newCanvas () {
function initialize () {
try {
browserResized()
initializeBrowserCanvas()
addCanvasEvents()
/* Instantiate all the children spaces of Canvas object */
/* Instantiate all the children spaces of Canvas object */
thisObject.floatingSpace = newFloatingSpace()
thisObject.floatingSpace.initialize()
@@ -199,14 +198,10 @@ function newCanvas () {
}
function browserResized () {
try {
browserCanvas = document.getElementById('canvas')
browserCanvas = document.getElementById('canvas')
browserCanvas.width = window.innerWidth
browserCanvas.height = window.innerHeight - CURRENT_TOP_MARGIN
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] browserResized -> err = ' + err.stack) }
}
browserCanvas.width = window.innerWidth
browserCanvas.height = window.innerHeight - CURRENT_TOP_MARGIN
}
function checkMediaRecording (event) {
+1 -1
View File
@@ -82,7 +82,7 @@ function newFullScreen () {
} else {
thisObject.status = 'Off'
goOutFullscreen()
CURRENT_TOP_MARGIN = window.canvasApp.topMargin
CURRENT_TOP_MARGIN = TOP_MARGIN
AT_FULL_SCREEN_MODE = false
}
}
@@ -28,7 +28,7 @@ function newTaskFunctions () {
let taskLightingPath = '->Task->' +
'Sensor Bot Instance->' +
'Indicator Bot Instance->' +
'Indicator Bot Instance->Time Frames Filter->' +
'Trading Bot Instance->' +
'Sensor Process Instance->Indicator Process Instance->Trading Process Instance->' +
'Market Reference->' +
+2 -1
View File
@@ -178,7 +178,8 @@ let INITIAL_ZOOM_LEVEL = -28.25 // This is the zoom level at the view port
let INITIAL_TIME_PERIOD = ONE_DAY_IN_MILISECONDS // This value will be overwritten at the canvas.chartingSpace.viewport.initialize if the user had a prevous session with this same browser.
let VERY_LARGE_NUMBER = 100000000000000
let CURRENT_TOP_MARGIN = window.canvasApp.topMargin
const TOP_MARGIN = 0
let CURRENT_TOP_MARGIN = TOP_MARGIN
let AT_FULL_SCREEN_MODE = false
let maxDate = new Date();
+83 -67
View File
@@ -1,4 +1,4 @@
function newLayer () {
function newLayer() {
const MODULE_NAME = 'Layer'
const ERROR_LOG = true
const logger = newWebDebugLog()
@@ -80,7 +80,7 @@ function newLayer () {
let timeFrame = INITIAL_TIME_PERIOD
let datetime = NEW_SESSION_INITIAL_DATE
/* Add an Event Handler */
/* Add an Event Handler */
thisObject.eventHandler = newEventHandler()
let imagesLoaded = 0
@@ -89,7 +89,7 @@ function newLayer () {
return thisObject
function finalize () {
function finalize() {
thisObject.container.eventHandler.stopListening(onMouseClickEventSuscriptionId)
thisObject.container.finalize()
@@ -132,15 +132,15 @@ function newLayer () {
thisObject.networkNode = undefined
}
function initialize (callBackFunction) {
/* Create this objects continer */
function initialize(callBackFunction) {
/* Create this objects continer */
try {
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME + ' ' + thisObject.payload.node.id)
thisObject.container.isDraggeable = false
thisObject.container.isClickeable = true
/* Lets set the basic dimensions of this thisObject. */
/* Lets set the basic dimensions of this thisObject. */
let position = {
x: 0,
y: 0
@@ -152,32 +152,32 @@ function newLayer () {
let functionLibraryProtocolNode = newProtocolNode()
let lightingPath =
'->Layer->' +
'Data Product->Single Market Data->Exchange Data Products->' +
'Session Reference->Session Independent Data->Session Based Data->Exchange Sessions->Session Based Data->Data Storage->Network Node->' +
'Data Storage->Network Node->' +
'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' +
'Trading System Reference->Trading Engine Reference->Trading System->Trading Engine->' +
'Market->Market Base Asset->Asset->' +
'Market Quoted Asset->Asset->' +
'Exchange Markets->Crypto Exchange->' +
'Product Definition->' +
'Sensor Bot->Indicator Bot->Trading Bot->' +
'Data Mine->' +
'Dataset Definition->' +
'Record Definition->Record Property->Formula->' +
'Data Building Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' +
'Calculations Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' +
'Plotter Module->Plotter->' +
'Shapes->' +
'Chart Points->Point->Point Formula->' +
'Polygon->Polygon Condition->Polygon Body->Style->Style Condition->Style->' +
'Polygon Border->Style->Style Condition->Style->' +
'Polygon Vertex->Point->' +
'Image->Image Condition->Image Position->Point->' +
'Text->Text Condition->Text Position->Point->Text Formula->Text Style->' +
'Plotter Panel->Javascript Code->Panel Data->Data Formula->' +
'Nodes Highlights->Nodes Values->Nodes Errors->Nodes Status->Nodes Progress->Nodes Running->Nodes Announcements->Record Values->'
'->Layer->' +
'Data Product->Single Market Data->Exchange Data Products->' +
'Session Reference->Session Independent Data->Session Based Data->Exchange Sessions->Session Based Data->Data Storage->Network Node->' +
'Data Storage->Network Node->' +
'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' +
'Trading System Reference->Trading Engine Reference->Trading System->Trading Engine->' +
'Market->Market Base Asset->Asset->' +
'Market Quoted Asset->Asset->' +
'Exchange Markets->Crypto Exchange->' +
'Product Definition->' +
'Sensor Bot->Indicator Bot->Trading Bot->' +
'Data Mine->' +
'Dataset Definition->' +
'Record Definition->Record Property->Formula->' +
'Data Building Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' +
'Calculations Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' +
'Plotter Module->Plotter->' +
'Shapes->' +
'Chart Points->Point->Point Formula->' +
'Polygon->Polygon Condition->Polygon Body->Style->Style Condition->Style->' +
'Polygon Border->Style->Style Condition->Style->' +
'Polygon Vertex->Point->' +
'Image->Image Condition->Image Position->Point->' +
'Text->Text Condition->Text Position->Point->Text Formula->Text Style->' +
'Plotter Panel->Javascript Code->Panel Data->Data Formula->' +
'Nodes Highlights->Nodes Values->Nodes Errors->Nodes Status->Nodes Progress->Nodes Running->Nodes Announcements->Record Values->'
thisObject.definition = functionLibraryProtocolNode.getProtocolNode(thisObject.payload.node, false, true, true, false, false, lightingPath)
/* Here we validate that we have all the needed information */
@@ -198,7 +198,7 @@ function newLayer () {
if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode === undefined) { return }
if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode === undefined) { return }
/* Lets listen to our own events to react when we have a Mouse Click */
/* Lets listen to our own events to react when we have a Mouse Click */
onMouseClickEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
/* Get ready to draw this layer */
@@ -242,7 +242,7 @@ function newLayer () {
thisObject.networkNode = thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode
}
function getIcon (node) {
function getIcon(node) {
let nodeDefinition = getNodeDefinition(node)
let iconName
if (nodeDefinition.alternativeIcons !== undefined) {
@@ -267,7 +267,7 @@ function newLayer () {
}
}
function checkStatusAtShutDown () {
function checkStatusAtShutDown() {
/* Mechanism to recover a layer that was left loading the last time the browser was shut dowm. */
let storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'status')
if (storedValue !== undefined) {
@@ -278,7 +278,7 @@ function newLayer () {
}
}
function getContainer (point) {
function getContainer(point) {
if (panelsVisibleButton !== undefined) {
let container = panelsVisibleButton.getContainer(point)
if (container !== undefined) {
@@ -290,11 +290,11 @@ function newLayer () {
}
}
function setDatetime (pDatetime) {
/*
When the datetime changes from one day to another, this forces cursors to potentially load more files, thus we reset this counter and
get ready to receive events on files loaded.
*/
function setDatetime(pDatetime) {
/*
When the datetime changes from one day to another, this forces cursors to potentially load more files, thus we reset this counter and
get ready to receive events on files loaded.
*/
let currentDate = Math.trunc(datetime.valueOf() / ONE_DAY_IN_MILISECONDS)
let newDate = Math.trunc(pDatetime.valueOf() / ONE_DAY_IN_MILISECONDS)
@@ -307,11 +307,11 @@ function newLayer () {
}
}
function setTimeFrame (pTimeFrame) {
/*
When the time period below or equal to 1 hour changes, this forces cursors to potentially load more files, thus we reset this counter and
get ready to receive events on files loaded.
*/
function setTimeFrame(pTimeFrame) {
/*
When the time period below or equal to 1 hour changes, this forces cursors to potentially load more files, thus we reset this counter and
get ready to receive events on files loaded.
*/
if (timeFrame !== pTimeFrame) {
timeFrame = pTimeFrame
@@ -321,15 +321,23 @@ function newLayer () {
}
}
function onMarketFileLoaded (event) {
marketFileProgressBar.value = Math.trunc(event.totalValue * 100 / event.totalValue)
function onMarketFileLoaded(event) {
if (event.totalValue === 0) {
marketFileProgressBar.value = 100
return
}
marketFileProgressBar.value = Math.trunc((event.currentValue + event.filesNotLoaded) * 100 / event.totalValue)
marketFileProgressBar.fillStyle = LOADING_FILL_STYLE
marketFileProgressBar.strokeStyle = LOADING_STROKE_STYLE
if (marketFileProgressBar.value > 100) { marketFileProgressBar.value = 100 }
}
function onDailyFileLoaded (event) {
function onDailyFileLoaded(event) {
if (event.totalValue === 0) {
dailyFileProgressBar.value = 100
return
}
dailyFileProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue)
dailyFileProgressBar.fillStyle = LOADING_FILL_STYLE
dailyFileProgressBar.strokeStyle = LOADING_STROKE_STYLE
@@ -337,7 +345,11 @@ function newLayer () {
if (dailyFileProgressBar.value > 100) { dailyFileProgressBar.value = 100 }
}
function onSingleFileLoaded (event) {
function onSingleFileLoaded(event) {
if (event.totalValue === 0) {
singleFileProgressBar.value = 100
return
}
singleFileProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue)
singleFileProgressBar.fillStyle = LOADING_FILL_STYLE
singleFileProgressBar.strokeStyle = LOADING_STROKE_STYLE
@@ -345,7 +357,11 @@ function newLayer () {
if (singleFileProgressBar.value > 100) { singleFileProgressBar.value = 100 }
}
function onFileSequenceLoaded (event) {
function onFileSequenceLoaded(event) {
if (event.totalValue === 0) {
fileSequenceProgressBar.value = 100
return
}
fileSequenceProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue)
fileSequenceProgressBar.fillStyle = LOADING_FILL_STYLE
fileSequenceProgressBar.strokeStyle = LOADING_STROKE_STYLE
@@ -353,21 +369,21 @@ function newLayer () {
if (fileSequenceProgressBar.value > 100) { fileSequenceProgressBar.value = 100 }
}
function turnOff () {
function turnOff() {
if (thisObject.status !== LAYER_STATUS.OFF) {
resetProgressBars()
changeStatusTo(LAYER_STATUS.OFF)
}
}
function turnOn () {
function turnOn() {
if (thisObject.status === LAYER_STATUS.OFF) {
resetProgressBars()
changeStatusTo(LAYER_STATUS.LOADING)
}
}
function onMouseClick (event) {
function onMouseClick(event) {
switch (thisObject.status) {
case LAYER_STATUS.ON:
resetProgressBars()
@@ -383,7 +399,7 @@ function newLayer () {
}
}
function resetProgressBars () {
function resetProgressBars() {
marketFileProgressBar.animatedValue = 0
marketFileProgressBar.value = 0
marketFileProgressBar.fillStyle = UNLOADED_FILL_STYLE
@@ -405,12 +421,12 @@ function newLayer () {
fileSequenceProgressBar.strokeStyle = UNLOADED_STROKE_STYLE
}
function physics () {
function physics() {
statusPhysics()
childrenPhysics()
}
function childrenPhysics () {
function childrenPhysics() {
/* Panels Visible Button Setup */
if (thisObject.status === LAYER_STATUS.ON) {
if (panelsVisibleButton === undefined) {
@@ -435,8 +451,8 @@ function newLayer () {
}
}
function statusPhysics () {
/* We retrieve the stored status at the config. */
function statusPhysics() {
/* We retrieve the stored status at the config. */
try {
let storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'status')
@@ -456,7 +472,7 @@ function newLayer () {
changeStatusTo(LAYER_STATUS.OFF)
}
} catch (err) {
// we ignore errors here since most likely they will be parsing errors.
// we ignore errors here since most likely they will be parsing errors.
}
/* Check when the loading finishes */
@@ -469,7 +485,7 @@ function newLayer () {
}
}
function changeStatusTo (newStatus) {
function changeStatusTo(newStatus) {
if (thisObject.status !== newStatus) {
thisObject.status = newStatus
@@ -486,18 +502,18 @@ function newLayer () {
}
}
function draw () {
function draw() {
drawLayer()
if (panelsVisibleButton !== undefined) {
panelsVisibleButton.draw()
}
}
function drawLayer () {
function drawLayer() {
drawLayerDisplay()
}
function drawProgressBar (progressBar, lineWidth, offsetY) {
function drawProgressBar(progressBar, lineWidth, offsetY) {
const ANIMATED_INCREMENT = 5
const OPACITY_INCREMENT = 0.01
const OPACITY_MIN = 1
@@ -510,7 +526,7 @@ function newLayer () {
return
}
/* Animate */
/* Animate */
if (progressBar.animatedValue < progressBar.value) {
progressBar.animatedValue = progressBar.animatedValue + ANIMATED_INCREMENT
progressBar.opacity = progressBar.opacity + OPACITY_INCREMENT
@@ -535,7 +551,7 @@ function newLayer () {
y: thisObject.container.frame.height + offsetY
}
/* Now the transformations. */
/* Now the transformations. */
point1 = thisObject.container.frame.frameThisPoint(point1)
point2 = thisObject.container.frame.frameThisPoint(point2)
@@ -555,7 +571,7 @@ function newLayer () {
browserCanvasContext.stroke()
}
function drawLayerDisplay () {
function drawLayerDisplay() {
let label1 = thisObject.payload.node.name
let label2 = thisObject.exchange.name.substring(0, 15) + ' - ' + thisObject.market
let label3 = thisObject.status.toUpperCase()
+65 -73
View File
@@ -1,4 +1,4 @@
function newPlotter () {
function newPlotter() {
const MODULE_NAME = 'Plotter'
const ERROR_LOG = true
const INTENSIVE_LOG = false
@@ -58,7 +58,7 @@ function newPlotter () {
let logged = false
return thisObject
function finalize () {
function finalize() {
try {
/* Stop listening to the necesary events. */
thisObject.container.eventHandler.stopListening(onMouseOverEventSuscriptionId)
@@ -92,7 +92,7 @@ function newPlotter () {
}
}
function initialize (pStorage, pDatetime, pTimeFrame, pCoordinateSystem, callBackFunction, pProductDefinition) {
function initialize(pStorage, pDatetime, pTimeFrame, pCoordinateSystem, callBackFunction, pProductDefinition) {
try {
/* Store the information received. */
marketFiles = pStorage.marketFiles[0]
@@ -134,20 +134,20 @@ function newPlotter () {
}
}
function initializeCoordinateSystem () {
function initializeCoordinateSystem() {
scaleChangedEventSubscriptionId = coordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged)
}
function finalizeCoordinateSystem () {
function finalizeCoordinateSystem() {
coordinateSystem.eventHandler.stopListening(scaleChangedEventSubscriptionId)
}
function onScaleChanged () {
function onScaleChanged() {
mustRecalculateDataPoints = true
recalculate()
}
function onMouseOver (event) {
function onMouseOver(event) {
let userPosition = getDateFromPointAtBrowserCanvas(event, thisObject.container, coordinateSystem)
userPositionDate = userPosition.valueOf()
@@ -164,7 +164,7 @@ function newPlotter () {
maxUserPositionRate = getRateFromPointAtBrowserCanvas(maxPositionPoint, thisObject.container, coordinateSystem)
}
function onMarketFilesUpdated () {
function onMarketFilesUpdated() {
try {
let newMarketFile = marketFiles.getFile(timeFrame)
if (newMarketFile !== undefined) {
@@ -177,7 +177,7 @@ function newPlotter () {
}
}
function onDailyFilesUpdated () {
function onDailyFilesUpdated() {
try {
let newFileCursor = dailyFiles.getFileCursor(timeFrame)
if (newFileCursor !== undefined) {
@@ -190,14 +190,14 @@ function newPlotter () {
}
}
function getContainer (point) {
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. */
/* This point does not belong to this space. */
return undefined
}
} catch (err) {
@@ -205,29 +205,15 @@ function newPlotter () {
}
}
function setTimeFrame (pTimeFrame) {
function setTimeFrame(pTimeFrame) {
try {
if (timeFrame !== pTimeFrame) {
timeFrame = pTimeFrame
mustRecalculateDataPoints = true
if (timeFrame >= _1_HOUR_IN_MILISECONDS) {
let newMarketFile = marketFiles.getFile(pTimeFrame)
if (newMarketFile !== undefined) {
marketFile = newMarketFile
recalculate()
} else {
logger.write('[WARN] setTimeFrame -> Could not change to market file for timeFrame = ' + pTimeFrame)
}
marketFile = marketFiles.getFile(pTimeFrame)
} else {
let newFileCursor = dailyFiles.getFileCursor(pTimeFrame)
if (newFileCursor !== undefined) {
fileCursor = newFileCursor
recalculate()
} else {
logger.write('[WARN] setTimeFrame -> Could not change to market file for timeFrame = ' + pTimeFrame)
}
fileCursor = dailyFiles.getFileCursor(pTimeFrame)
}
}
} catch (err) {
@@ -235,17 +221,17 @@ function newPlotter () {
}
}
function setDatetime (pDatetime) {
function setDatetime(pDatetime) {
datetime = pDatetime
}
function setCoordinateSystem (pCoordinateSystem) {
function setCoordinateSystem(pCoordinateSystem) {
finalizeCoordinateSystem()
coordinateSystem = pCoordinateSystem
initializeCoordinateSystem()
}
function onDailyFileLoaded (event) {
function onDailyFileLoaded(event) {
try {
if (event.currentValue === event.totalValue) {
/* This happens only when all of the files in the cursor have been loaded. */
@@ -256,7 +242,7 @@ function newPlotter () {
}
}
function draw () {
function draw() {
try {
thisObject.container.frame.draw()
plot()
@@ -265,7 +251,7 @@ function newPlotter () {
}
}
function recalculate () {
function recalculate() {
if (canvas.chartingSpace.visible !== true) { return }
try {
if (timeFrame >= _1_HOUR_IN_MILISECONDS) {
@@ -279,11 +265,11 @@ function newPlotter () {
}
}
function jsonifyDataFile (dataFile, recordDefinition, farLeftDate, farRightDate) {
/*
This function has as an input the raw data on files and creates with it an array of JSON objects
with not calculated properties for later being consumed by Formulas
*/
function jsonifyDataFile(dataFile, recordDefinition, farLeftDate, farRightDate) {
/*
This function has as an input the raw data on files and creates with it an array of JSON objects
with not calculated properties for later being consumed by Formulas
*/
let jsonifiedArray = []
let previous
@@ -298,9 +284,9 @@ function newPlotter () {
}
if (
(record.begin >= farLeftDate.valueOf() && record.end <= farRightDate.valueOf()) &&
(record.end >= coordinateSystem.min.x && record.begin <= coordinateSystem.max.x)
) {
(record.begin >= farLeftDate.valueOf() && record.end <= farRightDate.valueOf()) &&
(record.end >= coordinateSystem.min.x && record.begin <= coordinateSystem.max.x)
) {
record.previous = previous
jsonifiedArray.push(record)
previous = record
@@ -316,11 +302,11 @@ function newPlotter () {
return jsonifiedArray
}
function calculationsProcedure (jsonArray, recordDefinition, calculationsProcedure, timeFrame) {
/*
This function has as an input an array of JSON objects, and it adds calculated properties to
complete the set of properties that will be available.
*/
function calculationsProcedure(jsonArray, recordDefinition, calculationsProcedure, timeFrame) {
/*
This function has as an input an array of JSON objects, and it adds calculated properties to
complete the set of properties that will be available.
*/
let system = { // These are the available system variables to be used in User Code and Formulas
timeFrame: timeFrame,
@@ -387,9 +373,12 @@ function newPlotter () {
return results
}
function recalculateUsingDailyFiles () {
function recalculateUsingDailyFiles() {
try {
if (fileCursor === undefined) { return } // We need to wait until there is a fileCursor
if (fileCursor === undefined) {
records = []
return
} // We need to wait until there is a fileCursor available or maybe this indicator does not produce data for the current Time Frame
if (fileCursor.files.size === 0) { return } // We need to wait until there are files in the cursor
let daysOnSides = getSideDays(timeFrame)
@@ -441,9 +430,12 @@ function newPlotter () {
}
}
function recalculateUsingMarketFiles () {
function recalculateUsingMarketFiles() {
try {
if (marketFile === undefined) { return } // Initialization not complete yet.
if (marketFile === undefined) {
records = []
return
} // Initialization not complete yet or this indicator does not produce data for the current time frame
let daysOnSides = getSideDays(timeFrame)
@@ -480,7 +472,7 @@ function newPlotter () {
}
}
function recalculateScale () {
function recalculateScale() {
try {
if (coordinateSystem.maxValue > 0) { return } // Already calculated.
/* First we calculate the default scale */
@@ -495,17 +487,17 @@ function newPlotter () {
}
coordinateSystem.initialize(
minValue,
maxValue,
thisObject.container.frame.width,
thisObject.container.frame.height
)
minValue,
maxValue,
thisObject.container.frame.width,
thisObject.container.frame.height
)
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] recalculateScale -> err = ' + err.stack) }
}
}
function plot () {
function plot() {
try {
/* Clean the pannel at places where there is no record. */
thisObject.container.eventHandler.raiseEvent('Current Record Changed', undefined)
@@ -593,17 +585,17 @@ function newPlotter () {
y: y
}
/*
The information we store in files is independent from the charing system and its coordinate systems.
That means that the first thing we allways need to do is to trasform these points to the coordinate system of the timeline.
*/
/*
The information we store in files is independent from the charing system and its coordinate systems.
That means that the first thing we allways need to do is to trasform these points to the coordinate system of the timeline.
*/
let dataPoint
dataPoint = coordinateSystem.transformThisPoint(rawPoint)
dataPoint = transformThisPoint(dataPoint, thisObject.container)
dataPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(dataPoint)
dataPoint = thisObject.fitFunction(dataPoint)
/* Store the data point at the local map */
/* Store the data point at the local map */
dataPoint.rawPoint = rawPoint
dataPoints.set(point.id, dataPoint)
}
@@ -636,7 +628,7 @@ function newPlotter () {
}
calculatedStyle = record.fillStyle.get(polygon.id)
if (calculatedStyle !== undefined) {
/* We use the already calculated style */
/* We use the already calculated style */
fillStyle = calculatedStyle
} else {
/* Get the default style if exists */
@@ -691,7 +683,7 @@ function newPlotter () {
}
calculatedStyle = record.strokeStyle.get(polygon.id)
if (calculatedStyle !== undefined) {
/* We use the already calculated style */
/* We use the already calculated style */
strokeStyle = calculatedStyle
} else {
/* Get the default style if exists */
@@ -771,7 +763,7 @@ function newPlotter () {
}
browserCanvasContext.closePath()
/* Apply the fill style to the canvas object */
/* Apply the fill style to the canvas object */
if (polygon.polygonBody !== undefined) {
/* Replace the fill style if we are at mouse position */
if (atMousePosition === true) {
@@ -785,7 +777,7 @@ function newPlotter () {
browserCanvasContext.fill()
}
/* Apply the stroke style to the canvas object */
/* Apply the stroke style to the canvas object */
if (polygon.polygonBorder !== undefined) {
/* Replace the stroke style if we are at mouse position */
if (atMousePosition === true) {
@@ -815,7 +807,7 @@ function newPlotter () {
let imageSize = 0
let offsetX = 0
let offsetY = 0
let imagePosition = {x: 0, y: 0}
let imagePosition = { x: 0, y: 0 }
if (image.config.codeName !== undefined) { imageName = image.config.codeName }
if (image.config.size !== undefined) { imageSize = image.config.size }
if (image.imagePosition.config.offsetX !== undefined) { offsetX = image.imagePosition.config.offsetX }
@@ -853,7 +845,7 @@ function newPlotter () {
let paletteColor = UI_COLOR.GREY
let offsetX = 0
let offsetY = 0
let textPosition = {x: 0, y: 0}
let textPosition = { x: 0, y: 0 }
if (text.textStyle.config.fontSize !== undefined) { fontSize = text.textStyle.config.fontSize }
if (text.textStyle.config.opacity !== undefined) { opacity = text.textStyle.config.opacity }
if (text.textStyle.config.paletteColor !== undefined) { paletteColor = eval(text.textStyle.config.paletteColor) }
@@ -888,7 +880,7 @@ function newPlotter () {
}
}
function onViewportZoomChanged (event) {
function onViewportZoomChanged(event) {
try {
mustRecalculateDataPoints = true
recalculate()
@@ -897,19 +889,19 @@ function newPlotter () {
}
}
function onDragFinished () {
function onDragFinished() {
recalculate()
}
function onDisplace (event) {
function onDisplace(event) {
recalculateAll(event)
}
function onViewportPositionChanged (event) {
function onViewportPositionChanged(event) {
recalculateAll(event)
}
function recalculateAll (event) {
function recalculateAll(event) {
mustRecalculateDataPoints = true
if (event !== undefined) {
if (event.recalculate === true) {
+1 -1
View File
@@ -1 +1 @@
{"type":"Data Mine","name":"Masters-Trading","config":"{ \n\"codeName\": \"Masters-Trading\"\n}","sensorBots":[],"indicatorBots":[],"tradingBots":[{"type":"Trading Bot","name":"Low Frequency","config":"{\n\"codeName\": \"Low-Frequency\"\n}","processes":[{"type":"Process Definition","name":"Trading","config":"{\n \"codeName\": \"Trading\",\n \"liveTradingWaitTime\": 0,\n \"paperTradingWaitTime\": 0,\n \"fordwardTestingWaitTime\": 0,\n \"backtestingWaitTime\": 0,\n \"sessionRunWaitTime\": 5000,\n \"retryWaitTime\": 10000,\n \"framework\": {\n \"name\": \"Low-Frequency-Trading-Process\"\n }\n }","processOutput":{"type":"Process Output","name":"New Process Output","outputDatasets":[{"type":"Output Dataset","name":"Multi-Period-Market Episode Counters","id":"6fc3054e-5034-4fc7-bddf-02360e0a6acf","savedPayload":{"position":{"x":17450.068251326462,"y":15841.551559017382},"targetPosition":{"x":19639.44096944686,"y":14981.892188598802},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Market","id":"db063d7b-db05-4bf6-941f-999e1ccb38fc"}}},{"type":"Output Dataset","name":"Multi-Period-Daily Episode Counters","id":"c3c2240f-514b-40de-825f-674037117d0b","savedPayload":{"position":{"x":17408.574644476477,"y":15727.325552793509},"targetPosition":{"x":19639.44096944686,"y":14981.892188598802},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Daily","id":"0764aaaf-d970-4f23-9df8-55fe5b7dd273"}}},{"type":"Output Dataset","name":"Multi-Period-Market Episode Statistics","id":"1dfdfc0d-842f-4e63-a591-256ac8a06b0f","savedPayload":{"position":{"x":17373.12088415627,"y":15611.394883926749},"targetPosition":{"x":19639.44096944686,"y":14981.892188598802},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Market","id":"fc9dc0f7-35e0-4548-bb91-f920825d694f"}}},{"type":"Output Dataset","name":"Multi-Period-Daily Episode Statistics","id":"39360c55-5ba8-413b-b0bd-cac3789ebf5f","savedPayload":{"position":{"x":17343.701241214498,"y":15493.846491633021},"targetPosition":{"x":19639.44096944686,"y":14981.892188598802},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Daily","id":"91953362-8751-4440-a898-21245cd47c15"}}},{"type":"Output Dataset","name":"Multi-Period-Market Current Candle","id":"ba614415-6e4f-4979-97a5-34c72a59e67c","savedPayload":{"position":{"x":17320.378252589224,"y":15374.95820021913},"targetPosition":{"x":19639.44096944686,"y":14981.892188598802},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Market","id":"17fb41f5-61b5-4433-9a10-950ff8216a7e"}}},{"type":"Output Dataset","name":"Multi-Period-Daily Current Candle","id":"1a2e3461-33e6-45b1-bcc1-c56a8c5d275c","savedPayload":{"position":{"x":17303.209229100234,"y":15255.03551122105},"targetPosition":{"x":19639.44096944686,"y":14981.892188598802},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Daily","id":"bbc9467d-28bf-432b-9e49-582d1bcabfb9"}}},{"type":"Output Dataset","name":"Multi-Period-Market Current Balance","id":"567e4dc9-4deb-41e4-9ac9-dde943fb91ba","savedPayload":{"position":{"x":17292.23789362744,"y":15134.392617857315},"targetPosition":{"x":19639.44096944686,"y":14981.892188598802},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Market","id":"acddff59-b51b-4b45-b58f-71d4077755ee"}}},{"type":"Output Dataset","name":"Multi-Period-Daily Current Balance","id":"e94b9bb3-9f0c-4550-94e1-09de444780a8","savedPayload":{"position":{"x":17287.49247877813,"y":15013.347651781945},"targetPosition":{"x":19639.44096944686,"y":14981.892188598802},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Daily","id":"213b8fe8-f772-41ea-a3f5-97867be555f7"}}},{"type":"Output Dataset","name":"Multi-Period-Market Distance To Event","id":"a30e7306-7be9-41b6-a465-Line truncated
{"type":"Data Mine","name":"Masters-Trading","config":"{ \n\"codeName\": \"Masters-Trading\"\n}","sensorBots":[],"indicatorBots":[],"tradingBots":[{"type":"Trading Bot","name":"Low Frequency","config":"{\n\"codeName\": \"Low-Frequency\"\n}","processes":[{"type":"Process Definition","name":"Trading","config":"{\n \"codeName\": \"Trading\",\n \"liveTradingWaitTime\": 0,\n \"paperTradingWaitTime\": 0,\n \"fordwardTestingWaitTime\": 0,\n \"backtestingWaitTime\": 0,\n \"sessionRunWaitTime\": 5000,\n \"retryWaitTime\": 10000,\n \"framework\": {\n \"name\": \"Low-Frequency-Trading-Process\"\n }\n }","processOutput":{"type":"Process Output","name":"New Process Output","outputDatasets":[{"type":"Output Dataset","name":"Multi-Period-Market Episode Counters","id":"6fc3054e-5034-4fc7-bddf-02360e0a6acf","savedPayload":{"position":{"x":17450.068251326462,"y":15841.551559017382},"targetPosition":{"x":19639.44096944686,"y":14981.892188598802},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Market","id":"db063d7b-db05-4bf6-941f-999e1ccb38fc"}}},{"type":"Output Dataset","name":"Multi-Period-Daily Episode Counters","id":"c3c2240f-514b-40de-825f-674037117d0b","savedPayload":{"position":{"x":17408.574644476477,"y":15727.325552793509},"targetPosition":{"x":19639.44096944686,"y":14981.892188598802},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Daily","id":"0764aaaf-d970-4f23-9df8-55fe5b7dd273"}}},{"type":"Output Dataset","name":"Multi-Period-Market Episode Statistics","id":"1dfdfc0d-842f-4e63-a591-256ac8a06b0f","savedPayload":{"position":{"x":17373.12088415627,"y":15611.394883926749},"targetPosition":{"x":19639.44096944686,"y":14981.892188598802},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Market","id":"fc9dc0f7-35e0-4548-bb91-f920825d694f"}}},{"type":"Output Dataset","name":"Multi-Period-Daily Episode Statistics","id":"39360c55-5ba8-413b-b0bd-cac3789ebf5f","savedPayload":{"position":{"x":17343.701241214498,"y":15493.846491633021},"targetPosition":{"x":19639.44096944686,"y":14981.892188598802},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Daily","id":"91953362-8751-4440-a898-21245cd47c15"}}},{"type":"Output Dataset","name":"Multi-Period-Market Current Candle","id":"ba614415-6e4f-4979-97a5-34c72a59e67c","savedPayload":{"position":{"x":17320.378252589224,"y":15374.95820021913},"targetPosition":{"x":19639.44096944686,"y":14981.892188598802},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Market","id":"17fb41f5-61b5-4433-9a10-950ff8216a7e"}}},{"type":"Output Dataset","name":"Multi-Period-Daily Current Candle","id":"1a2e3461-33e6-45b1-bcc1-c56a8c5d275c","savedPayload":{"position":{"x":17303.209229100234,"y":15255.03551122105},"targetPosition":{"x":19639.44096944686,"y":14981.892188598802},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Daily","id":"bbc9467d-28bf-432b-9e49-582d1bcabfb9"}}},{"type":"Output Dataset","name":"Multi-Period-Market Current Balance","id":"567e4dc9-4deb-41e4-9ac9-dde943fb91ba","savedPayload":{"position":{"x":17292.23789362744,"y":15134.392617857315},"targetPosition":{"x":19639.44096944686,"y":14981.892188598802},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Market","id":"acddff59-b51b-4b45-b58f-71d4077755ee"}}},{"type":"Output Dataset","name":"Multi-Period-Daily Current Balance","id":"e94b9bb3-9f0c-4550-94e1-09de444780a8","savedPayload":{"position":{"x":17287.49247877813,"y":15013.347651781945},"targetPosition":{"x":19639.44096944686,"y":14981.892188598802},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Daily","id":"213b8fe8-f772-41ea-a3f5-97867be555f7"}}},{"type":"Output Dataset","name":"Multi-Period-Market Distance To Event","id":"a30e7306-7be9-41b6-a465-Line truncated
+1 -1
View File
@@ -1 +1 @@
{"type":"Data Mine","name":"Masters","code":"{\n\"codeName\": \"Masters\"\n}","sensorBots":[{"type":"Sensor Bot","name":"Exchange Raw Data","code":"{\n\"codeName\": \"Exchange-Raw-Data\",\n\"repo\": \"Exchange-Raw-Data-Sensor-Bot\"\n}","processes":[{"type":"Process Definition","name":"Historic-Trades","code":"{\n \"codeName\": \"Historic-Trades\",\n \"description\": \"Retrieves and saves the historical trades in batches going backwards from the current time until reaching the begining of the market.\",\n \"startMode\": {\n \"noTime\": {\n \"run\": \"true\"\n },\n \"fixedInterval\": {\n \"run\": \"false\",\n \"interval\": 0\n }\n },\n \"deadWaitTime\": 0,\n \"normalWaitTime\": 60000,\n \"retryWaitTime\": 10000\n}","processOutput":{"type":"Process Output","name":"New Process Output","outputDatasets":[],"id":"e3008f15-43ae-4452-9c28-bfbb6c1a5e84","savedPayload":{"position":{"x":13889.892304785908,"y":17976.7326423862},"targetPosition":{"x":13788.99537092664,"y":18353.285125876908},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":4,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"processDependencies":{"type":"Process Dependencies","name":"New Process Dependencies","statusDependencies":[{"type":"Status Dependency","name":"Self Reference","code":"{\n \"mainUtility\": \"Self Reference\"\n}","id":"f796022a-7871-4bde-bcc7-bcf2818f1eaf","savedPayload":{"position":{"x":14299.325525762739,"y":17993.12379366583},"targetPosition":{"x":13938.17907937083,"y":17993.12379366583},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"116834de-6646-4387-9f4b-4f711cea9235"}}}],"dataDependencies":[],"id":"1332b41e-7cd2-4e69-a40a-39ea47df67b5","savedPayload":{"position":{"x":13938.17907937083,"y":17993.12379366583},"targetPosition":{"x":13788.99537092664,"y":18353.285125876908},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":4,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"statusReport":{"type":"Status Report","name":"New Status Report","id":"116834de-6646-4387-9f4b-4f711cea9235","savedPayload":{"position":{"x":13983.913279342734,"y":18015.677405195172},"targetPosition":{"x":13788.99537092664,"y":18353.285125876908},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":4,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"executionStartedEvent":{"type":"Execution Started Event","name":"New Execution Started Event","id":"a9ea7169-fcd8-48c3-b0a9-b4e8941aa170","savedPayload":{"position":{"x":14026.312379860185,"y":18044.00757842793},"targetPosition":{"x":13788.99537092664,"y":18353.285125876908},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":4,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"executionFinishedEvent":{"type":"Execution Finished Event","name":"New Execution Finished Event","id":"51908884-c7a2-46ca-8a55-209070ae5fa6","savedPayload":{"position":{"x":14064.650920558077,"y":18077.62957624547},"targetPosition":{"x":13788.99537092664,"y":18353.285125876908},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":4,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"7a6a9399-474f-4a93-bcbd-28a594ef1943","savedPayload":{"position":{"x":14351.93363503598,"y":18425.400341491753},"targetPosition":{"x":13888.04337325749,"y":18696.024787447222},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":3,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Process Definition","name":"Historic-OHLCVs","code":"{\n \"codeName\": \"Historic-OHLCVs\",\n \"description\": \"Retrieves and saves historical maket data\",\n \"startMode\": {\n \"noTime\": {\n \"run\": \"true\"\n },\n \"fixedInterval\": {\n \"run\": \"false\",\n \"interval\": 0\n }\n },\n \"deadWaitTime\": 0,\n \"normalWaitTime\": 60000,\n \"retryWaitTime\": 10000\n}","processOutput":{"type":"Process Output","name":"New Process Output","outputDatasets":[],"id":"dfe2556e-a765-4e38-9d30-7f91090c0069","savedPayload":{"position":{"x":14546.018334597831,"y":18039.39680205973},"targetPosition":{"x":14407.127481538195,"y":18558.43550715096},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"processDependencies":{"type":"Process Dependencies","name":"New Process Dependencies","statusDependencies":[{"type":"Status Dependency","name":"Exchange Raw Data Historic-OHLCVs","code":"{\n \"mainUtility\": \"Self ReferencLine truncated
{"type":"Data Mine","name":"Masters","config":"{\n\"codeName\": \"Masters\"\n}","sensorBots":[{"type":"Sensor Bot","name":"Exchange Raw Data","config":"{\n\"codeName\": \"Exchange-Raw-Data\",\n\"repo\": \"Exchange-Raw-Data-Sensor-Bot\"\n}","processes":[{"type":"Process Definition","name":"Historic-Trades","config":"{\n \"codeName\": \"Historic-Trades\",\n \"description\": \"Retrieves and saves the historical trades in batches going backwards from the current time until reaching the begining of the market.\",\n \"startMode\": {\n \"noTime\": {\n \"run\": \"true\"\n },\n \"fixedInterval\": {\n \"run\": \"false\",\n \"interval\": 0\n }\n },\n \"deadWaitTime\": 0,\n \"normalWaitTime\": 60000,\n \"retryWaitTime\": 10000\n}","processOutput":{"type":"Process Output","name":"New Process Output","outputDatasets":[],"id":"e3008f15-43ae-4452-9c28-bfbb6c1a5e84","savedPayload":{"position":{"x":13889.892304785908,"y":17976.7326423862},"targetPosition":{"x":13788.99537092664,"y":18353.285125876908},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":4,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"processDependencies":{"type":"Process Dependencies","name":"New Process Dependencies","statusDependencies":[{"type":"Status Dependency","name":"Self Reference","config":"{\n \"mainUtility\": \"Self Reference\"\n}","id":"f796022a-7871-4bde-bcc7-bcf2818f1eaf","savedPayload":{"position":{"x":14299.325525762739,"y":17993.12379366583},"targetPosition":{"x":13938.17907937083,"y":17993.12379366583},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"116834de-6646-4387-9f4b-4f711cea9235"}}}],"dataDependencies":[],"id":"1332b41e-7cd2-4e69-a40a-39ea47df67b5","savedPayload":{"position":{"x":13938.17907937083,"y":17993.12379366583},"targetPosition":{"x":13788.99537092664,"y":18353.285125876908},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":4,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"statusReport":{"type":"Status Report","name":"New Status Report","id":"116834de-6646-4387-9f4b-4f711cea9235","savedPayload":{"position":{"x":13983.913279342734,"y":18015.677405195172},"targetPosition":{"x":13788.99537092664,"y":18353.285125876908},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":4,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"executionStartedEvent":{"type":"Execution Started Event","name":"New Execution Started Event","id":"a9ea7169-fcd8-48c3-b0a9-b4e8941aa170","savedPayload":{"position":{"x":14026.312379860185,"y":18044.00757842793},"targetPosition":{"x":13788.99537092664,"y":18353.285125876908},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":4,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"executionFinishedEvent":{"type":"Execution Finished Event","name":"New Execution Finished Event","id":"51908884-c7a2-46ca-8a55-209070ae5fa6","savedPayload":{"position":{"x":14064.650920558077,"y":18077.62957624547},"targetPosition":{"x":13788.99537092664,"y":18353.285125876908},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":4,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"7a6a9399-474f-4a93-bcbd-28a594ef1943","savedPayload":{"position":{"x":14351.93363503598,"y":18425.400341491753},"targetPosition":{"x":13888.04337325749,"y":18696.024787447222},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":3,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Process Definition","name":"Historic-OHLCVs","config":"{\n \"codeName\": \"Historic-OHLCVs\",\n \"description\": \"Retrieves and saves historical maket data\",\n \"startMode\": {\n \"noTime\": {\n \"run\": \"true\"\n },\n \"fixedInterval\": {\n \"run\": \"false\",\n \"interval\": 0\n }\n },\n \"deadWaitTime\": 0,\n \"normalWaitTime\": 60000,\n \"retryWaitTime\": 10000\n}","processOutput":{"type":"Process Output","name":"New Process Output","outputDatasets":[],"id":"dfe2556e-a765-4e38-9d30-7f91090c0069","savedPayload":{"position":{"x":14546.018334597831,"y":18039.39680205973},"targetPosition":{"x":14407.127481538195,"y":18558.43550715096},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"processDependencies":{"type":"Process Dependencies","name":"New Process Dependencies","statusDependencies":[{"type":"Status Dependency","name":"Exchange Raw Data Historic-OHLCVs","config":"{\n \"mainUtility\": \"SLine truncated
+123 -70
View File
@@ -1,5 +1,5 @@

function newDailyFiles () {
function newDailyFiles() {
const MODULE_NAME = 'Daily Files'
const ERROR_LOG = true
const logger = newWebDebugLog()
@@ -26,7 +26,7 @@ function newDailyFiles () {
return thisObject
function finalize () {
function finalize() {
try {
thisObject.eventHandler.finalize()
thisObject.eventHandler = undefined
@@ -37,7 +37,7 @@ function newDailyFiles () {
fileCursors.forEach(finalizeEach)
function finalizeEach (item, key, mapObj) {
function finalizeEach(item, key, mapObj) {
item.finalize()
}
} catch (err) {
@@ -45,45 +45,43 @@ function newDailyFiles () {
}
}
function initialize (pDataMine, pBot, pSession, pProduct, pDataset, pExchange, pMarket, pDatetime, pTimeFrame, pHost, pPort, pEventsServerClient, callBackFunction) {
function initialize(pDataMine, pBot, pSession, pProduct, pDataset, pExchange, pMarket, pDatetime, pTimeFrame, pHost, pPort, pEventsServerClient, callBackFunction) {
try {
callBackWhenFileReceived = callBackFunction
let exchange = pExchange
let beginDateRange
let endDateRange
let timeFrames
fileCloud = newFileCloud()
fileCloud.initialize(pBot, pHost, pPort)
/* Some Validations */
/* Config Validations */
if (pDataset.config.validTimeFrames === undefined) {
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = Can not initialize Market Files for bot ' + pBot.name) }
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = Can not initialize Daily Files for bot ' + pBot.name) }
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = You need to define validTimeFrames at the Dataset config. ') }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
return
}
/* First we will get the Data Range */
getDataRangeFile()
fileCloud.getFile(pDataMine, pBot, pSession, pProduct, pDataset, exchange, pMarket, undefined, undefined, undefined, true, onDataRangeReceived)
function onDataRangeReceived (err, pFile) {
try {
let beginDateRange
let endDateRange
function getDataRangeFile() {
/* First we will get the Data Range */
fileCloud.getFile(pDataMine, pBot, pSession, pProduct, pDataset, exchange, pMarket, undefined, undefined, undefined, true, undefined, onDataRangeReceived)
function onDataRangeReceived(err, pFile) {
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
beginDateRange = pFile.begin
endDateRange = pFile.end
break
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
return
}
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
if (err.message === 'File does not exist.') {
beginDateRange = new Date()
@@ -97,7 +95,6 @@ function newDailyFiles () {
endDateRange = new Date()
break
}
/* If none of the previous conditions are met, the we return the err to the caller. */
callBackFunction(err)
return
}
@@ -106,59 +103,115 @@ function newDailyFiles () {
return
}
}
/* Now we will get the daily files */
getTimeFramesFile()
}
}
function getTimeFramesFile() {
/* First we will get the Data Range */
fileCloud.getFile(pDataMine, pBot, pSession, pProduct, pDataset, exchange, pMarket, undefined, undefined, undefined, undefined, true, onTimeFramesReceived)
function onTimeFramesReceived(err, pFile) {
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
timeFrames = pFile
break
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
return
}
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
if (err.message === 'File does not exist.') {
/* It is ok, we will deal with this later */
break
}
if (err.message === 'Configured to not Support This.') {
/* It is ok, we will deal with this later */
break
}
if (err.message === 'Missing Configuration.') {
if (ERROR_LOG === true) { logger.write('[WARN] initialize -> onFileReceived -> The needed configuration to locate the timeFrames is missing at the dataSet.') }
if (ERROR_LOG === true) { logger.write('[WARN] initialize -> onFileReceived -> Time Frames Filters will be ignored -> Product = ' + pProduct.config.codeName) }
break
}
callBackFunction(err)
return
}
default: {
callBackFunction(err)
return
}
}
createFileCursors()
}
}
function createFileCursors() {
try {
/* Now we will get the daily files */
for (i = 0; i < dailyFilePeriods.length; i++) {
let periodTime = dailyFilePeriods[i][0]
let periodName = dailyFilePeriods[i][1]
if (pDataset.config.validTimeFrames.includes(periodName) === false) {
continue
}
if (timeFrames !== undefined) {
if (timeFrames.includes(periodName) === false) {
continue
}
}
let fileCursor = newFileCursor()
fileCursor.eventHandler = thisObject.eventHandler // We share our event handler with each file cursor, so that they can raise events there when files are changed.s
fileCursor.initialize(fileCloud, pDataMine, pBot, pSession, pProduct, pDataset, exchange, pMarket, periodName, periodTime, pDatetime, pTimeFrame, beginDateRange, endDateRange, pEventsServerClient, onInitialized)
function onInitialized(err) {
try {
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
break
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
callBackWhenFileReceived(GLOBAL.DEFAULT_FAIL_RESPONSE)
return
}
default: {
callBackWhenFileReceived(err)
return
}
}
fileCursors.set(periodTime, fileCursor)
expectedFiles = expectedFiles + fileCursor.getExpectedFiles()
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> onFileReceived -> onInitialized -> err = ' + err.stack) }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
}
}
}
loadThemAll()
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> createFileCursors -> err = ' + err.stack) }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
}
}
function loadThemAll() {
try {
for (i = 0; i < dailyFilePeriods.length; i++) {
let periodTime = dailyFilePeriods[i][0]
let periodName = dailyFilePeriods[i][1]
if (pDataset.config.validTimeFrames.includes(periodName) === true) {
let fileCursor = newFileCursor()
fileCursor.eventHandler = thisObject.eventHandler // We share our event handler with each file cursor, so that they can raise events there when files are changed.s
fileCursor.initialize(fileCloud, pDataMine, pBot, pSession, pProduct, pDataset, exchange, pMarket, periodName, periodTime, pDatetime, pTimeFrame, beginDateRange, endDateRange, pEventsServerClient, onInitialized)
function onInitialized (err) {
try {
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
break
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
callBackWhenFileReceived(GLOBAL.DEFAULT_FAIL_RESPONSE)
return
}
default: {
callBackWhenFileReceived(err)
return
}
}
fileCursors.set(periodTime, fileCursor)
expectedFiles = expectedFiles + fileCursor.getExpectedFiles()
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> onFileReceived -> onInitialized -> err = ' + err.stack) }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
}
let fileCursor = fileCursors.get(periodTime)
if (fileCursor !== undefined) {
fileCursor.reload(onFileReceived)
}
}
}
loadThemAll()
function loadThemAll () {
try {
for (i = 0; i < dailyFilePeriods.length; i++) {
let periodTime = dailyFilePeriods[i][0]
let periodName = dailyFilePeriods[i][1]
if (pDataset.config.validTimeFrames.includes(periodName) === true) {
let fileCursor = fileCursors.get(periodTime)
fileCursor.reload(onFileReceived)
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> onFileReceived -> loadThemAll -> err = ' + err.stack) }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
}
}
callBackWhenFileReceived(GLOBAL.DEFAULT_OK_RESPONSE, thisObject)
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> onFileReceived -> err = ' + err.stack) }
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> loadThemAll -> err = ' + err.stack) }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
}
}
@@ -168,7 +221,7 @@ function newDailyFiles () {
}
}
function onFileReceived (err) {
function onFileReceived(err) {
try {
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
@@ -195,7 +248,7 @@ function newDailyFiles () {
}
}
function getFileCursor (pPeriod) {
function getFileCursor(pPeriod) {
try {
return fileCursors.get(pPeriod)
} catch (err) {
@@ -203,13 +256,13 @@ function newDailyFiles () {
}
}
function setDatetime (pDatetime) {
function setDatetime(pDatetime) {
try {
filesLoaded = 0
expectedFiles = 0
fileCursors.forEach(setDatetimeToEach)
function setDatetimeToEach (fileCursor, key, map) {
function setDatetimeToEach(fileCursor, key, map) {
fileCursor.setDatetime(pDatetime)
expectedFiles = expectedFiles + fileCursor.getExpectedFiles()
fileCursor.reload(onFileReceived)
@@ -219,13 +272,13 @@ function newDailyFiles () {
}
}
function setTimeFrame (pTimeFrame, pDatetime) {
function setTimeFrame(pTimeFrame, pDatetime) {
try {
filesLoaded = 0
expectedFiles = 0
fileCursors.forEach(setTimeFrameToEach)
function setTimeFrameToEach (fileCursor, key, map) {
function setTimeFrameToEach(fileCursor, key, map) {
fileCursor.setTimeFrame(pTimeFrame, pDatetime)
expectedFiles = expectedFiles + fileCursor.getExpectedFiles()
fileCursor.reload(onFileReceived)
@@ -235,11 +288,11 @@ function newDailyFiles () {
}
}
function getExpectedFiles () {
function getExpectedFiles() {
return expectedFiles
}
function getFilesLoaded () {
function getFilesLoaded() {
return filesLoaded
}
}
+41 -40
View File
@@ -1,15 +1,12 @@
function newFileCloud () {
const MODULE_NAME = 'File Cloud'
const INFO_LOG = false
const ERROR_LOG = true
const logger = newWebDebugLog()
logger.fileName = MODULE_NAME
/*
This is the module in the system that actually connects to the cloud storage and grabs from there the needed files.
*/
let thisObject = {
@@ -18,47 +15,64 @@ function newFileCloud () {
}
let fileStorage
return thisObject
function initialize (pBot, pHost, pPort) {
fileStorage = newFileStorage(pHost, pPort)
}
function getFile (pDataMine, pBot, pSession, pProduct, pDataset, pExchange, pMarket, pPeriodName, pDatetime, pSequence, pDataRange, callBackFunction) {
function getFile (pDataMine, pBot, pSession, pProduct, pDataset, pExchange, pMarket, pPeriodName, pDatetime, pSequence, pDataRange, pTimeFrames, callBackFunction) {
try {
if (INFO_LOG === true) { logger.write('[INFO] getFile -> Entering function.') }
const MAX_RETRIES = 3
getFileRecursively(0, pDataMine, pBot, pSession, pProduct, pDataset, pExchange, pMarket, pPeriodName, pDatetime, pSequence, pDataRange, pTimeFrames, callBackFunction)
getFileRecursively(0, pDataMine, pBot, pSession, pProduct, pDataset, pExchange, pMarket, pPeriodName, pDatetime, pSequence, pDataRange, callBackFunction)
function getFileRecursively (pRetryCounter, pDataMine, pBot, pSession, pProduct, pDataset, pExchange, pMarket, pPeriodName, pDatetime, pSequence, pDataRange, callBackFunction) {
function getFileRecursively (pRetryCounter, pDataMine, pBot, pSession, pProduct, pDataset, pExchange, pMarket, pPeriodName, pDatetime, pSequence, pDataRange, pTimeFrames, callBackFunction) {
try {
if (INFO_LOG === true) { logger.write('[INFO] getFile -> getFileRecursively -> Entering function.') }
if (INFO_LOG === true) { logger.write('[INFO] getFile -> getFileRecursively -> key = ' + pDataMine.config.codeName + '-' + pBot.config.codeName + '-' + pDataset.config.filePath + '-' + pDataset.config.fileName) }
let fileName
let filePath
if (pDataRange === undefined) {
if (pDataRange === undefined && pTimeFrames === undefined) {
fileName = pDataset.config.fileName
filePath = pDataset.config.filePath
} else {
if (pDataset.config.dataRange !== undefined) {
fileName = pDataset.config.dataRange.fileName
filePath = pDataset.config.dataRange.filePath
} else {
let customErr = {
result: GLOBAL.CUSTOM_FAIL_RESPONSE.result,
message: 'Missing Configuration.'
if (pDataRange !== undefined) {
if (pDataset.config.dataRange !== undefined) {
fileName = pDataset.config.dataRange.fileName
filePath = pDataset.config.dataRange.filePath
} else {
let customErr = {
result: GLOBAL.CUSTOM_FAIL_RESPONSE.result,
message: 'Missing Configuration.'
}
if (ERROR_LOG === true) { logger.write('[WARN] getFile -> getFileRecursively -> onFileReceived -> customErr.message = ' + customErr.message) }
if (ERROR_LOG === true) { logger.write('[WARN] getFile -> getFileRecursively -> onFileReceived -> Data Range configuration could not be found at Dataset ' + pDataset.name) }
callBackFunction(customErr)
return
}
}
if (pTimeFrames !== undefined) {
if (pDataset.config.timeFrames !== undefined) {
if (pDataset.config.timeFrames.fileName !== '') {
fileName = pDataset.config.timeFrames.fileName
filePath = pDataset.config.timeFrames.filePath
} else {
let customErr = {
result: GLOBAL.CUSTOM_FAIL_RESPONSE.result,
message: 'Configured to not Support This.'
}
callBackFunction(customErr)
return
}
} else {
let customErr = {
result: GLOBAL.CUSTOM_FAIL_RESPONSE.result,
message: 'Missing Configuration.'
}
if (ERROR_LOG === true) { logger.write('[WARN] getFile -> getFileRecursively -> onFileReceived -> customErr.message = ' + customErr.message) }
if (ERROR_LOG === true) { logger.write('[WARN] getFile -> getFileRecursively -> onFileReceived -> Time Frames configuration could not be found at Dataset ' + pDataset.name) }
callBackFunction(customErr)
return
}
if (ERROR_LOG === true) { logger.write('[WARN] getFile -> getFileRecursively -> onFileReceived -> customErr.message = ' + customErr.message) }
if (ERROR_LOG === true) { logger.write('[WARN] getFile -> getFileRecursively -> onFileReceived -> Data Range configuration could not be found. ') }
callBackFunction(customErr)
return
}
}
@@ -118,17 +132,10 @@ function newFileCloud () {
fileName = fileName.replace('@Sequence', pSequence)
}
if (INFO_LOG === true) { logger.write('[INFO] getFile -> getFileRecursively -> filePath = ' + filePath) }
if (INFO_LOG === true) { logger.write('[INFO] getFile -> getFileRecursively -> fileName = ' + fileName) }
fileStorage.getFileFromHost(filePath + '/' + fileName, onFileReceived)
function onFileReceived (err, text, response) {
try {
if (INFO_LOG === true) { logger.write('[INFO] getFile -> getFileRecursively -> onFileReceived -> Entering function.') }
if (INFO_LOG === true) { logger.write('[INFO] getFile -> getFileRecursively -> onFileReceived -> filePath = ' + filePath) }
if (INFO_LOG === true) { logger.write('[INFO] getFile -> getFileRecursively -> onFileReceived -> fileName = ' + fileName) }
let data
if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
@@ -137,9 +144,6 @@ function newFileCloud () {
result: GLOBAL.CUSTOM_FAIL_RESPONSE.result,
message: 'File does not exist.'
}
if (INFO_LOG === true) { logger.write('[WARN] getFile -> getFileRecursively -> onFileReceived -> customErr.message = ' + customErr.message) }
callBackFunction(customErr)
return
}
@@ -171,9 +175,6 @@ function newFileCloud () {
} else {
try {
data = JSON.parse(text)
if (INFO_LOG === true) { logger.write('[INFO] getFile -> getFileRecursively -> onFileReceived -> Data received is valid JSON.') }
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, data)
return
} catch (err) {
+2 -2
View File
@@ -168,7 +168,7 @@ function newFileCursor () {
dateString = targetDate.getUTCFullYear() + '-' + pad(targetDate.getUTCMonth() + 1, 2) + '-' + pad(targetDate.getUTCDate(), 2)
fileCloud.getFile(dataMine, bot, session, product, dataset, exchange, market, periodName, targetDate, undefined, undefined, onFileReceived)
fileCloud.getFile(dataMine, bot, session, product, dataset, exchange, market, periodName, targetDate, undefined, undefined, undefined, onFileReceived)
function onFileReceived (err, file) {
try {
@@ -468,7 +468,7 @@ function newFileCursor () {
if (thisObject.files.get(dateString) === undefined) {
// We dont reload files we already have.
fileCloud.getFile(dataMine, bot, session, product, dataset, exchange, market, periodName, targetDate, undefined, undefined, onFileReceived)
fileCloud.getFile(dataMine, bot, session, product, dataset, exchange, market, periodName, targetDate, undefined, undefined, undefined, onFileReceived)
} else {
controlLoop()
}
+4 -4
View File
@@ -97,7 +97,7 @@ function newFileSequence () {
/* First we will get the sequence max number */
fileCloud.getFile(dataMine, bot, session, product, dataset, exchange, market, undefined, undefined, 'Sequence', undefined, onSequenceFileReceived)
fileCloud.getFile(dataMine, bot, session, product, dataset, exchange, market, undefined, undefined, 'Sequence', undefined, undefined, onSequenceFileReceived)
function onSequenceFileReceived (err, file) {
try {
@@ -142,7 +142,7 @@ function newFileSequence () {
/* Now we will get the sequence of files */
for (let i = 0; i <= maxSequence; i++) {
fileCloud.getFile(dataMine, bot, session, product, dataset, exchange, market, undefined, undefined, i, undefined, onFileReceived)
fileCloud.getFile(dataMine, bot, session, product, dataset, exchange, market, undefined, undefined, i, undefined, undefined, onFileReceived)
function onFileReceived (err, file) {
try {
@@ -207,7 +207,7 @@ function newFileSequence () {
let currentMaxSequence = maxSequence
fileCloud.getFile(dataMine, bot, session, product, dataset, exchange, market, undefined, undefined, 'Sequence', undefined, onSequenceFileReceived)
fileCloud.getFile(dataMine, bot, session, product, dataset, exchange, market, undefined, undefined, 'Sequence', undefined, undefined, onSequenceFileReceived)
function onSequenceFileReceived (err, sequenceFile) {
try {
@@ -243,7 +243,7 @@ function newFileSequence () {
/* Now we will get the sequence of files, but in this case only from the currentMaxSequence and above. */
for (let i = currentMaxSequence; i <= maxSequence; i++) {
fileCloud.getFile(dataMine, bot, session, product, dataset, exchange, market, undefined, undefined, i, undefined, onFileReceived)
fileCloud.getFile(dataMine, bot, session, product, dataset, exchange, market, undefined, undefined, i, undefined, undefined, onFileReceived)
function onFileReceived (err, file) {
try {
+91 -30
View File
@@ -1,5 +1,5 @@

function newMarketFiles () {
function newMarketFiles() {
const MODULE_NAME = 'Market Files'
const ERROR_LOG = true
const logger = newWebDebugLog()
@@ -17,6 +17,7 @@ function newMarketFiles () {
let filesLoaded = 0
let filesNotLoaded = 0
let filesExpected = 0
let fileCloud
@@ -41,7 +42,7 @@ function newMarketFiles () {
return thisObject
function finalize () {
function finalize() {
try {
for (let i = 0; i < eventSubscriptionIdDatasetUpdated.length; i++) {
eventsServerClient.stopListening('Dataset Updated', eventSubscriptionIdDatasetUpdated[i])
@@ -69,7 +70,7 @@ function newMarketFiles () {
}
}
function initialize (
function initialize(
pDataMine,
pBot,
pSession,
@@ -82,6 +83,8 @@ function newMarketFiles () {
pEventsServerClient,
callBackFunction) {
try {
let timeFrames
exchange = pExchange
market = pMarket
dataMine = pDataMine
@@ -102,16 +105,69 @@ function newMarketFiles () {
return
}
/* Now we will get the market files */
getTimeFramesFile()
for (let i = 0; i < marketFilesPeriods.length; i++) {
let periodTime = marketFilesPeriods[i][0]
let periodName = marketFilesPeriods[i][1]
function getTimeFramesFile() {
/* First we will get the Data Range */
fileCloud.getFile(pDataMine, pBot, pSession, pProduct, pDataset, exchange, pMarket, undefined, undefined, undefined, undefined, true, onTimeFramesReceived)
if (dataset.config.validTimeFrames.includes(periodName) === true) {
fileCloud.getFile(dataMine, bot, session, product, dataset, exchange, market, periodName, undefined, undefined, undefined, onFileReceived)
function onTimeFramesReceived(err, pFile) {
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
timeFrames = pFile
break
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
return
}
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
if (err.message === 'File does not exist.') {
/* It is ok, we will deal with this later */
break
}
if (err.message === 'Configured to not Support This.') {
/* It is ok, we will deal with this later */
break
}
if (err.message === 'Missing Configuration.') {
if (ERROR_LOG === true) { logger.write('[WARN] initialize -> onFileReceived -> The needed configuration to locate the timeFrames is missing at the dataSet.') }
if (ERROR_LOG === true) { logger.write('[WARN] initialize -> onFileReceived -> Time Frames Filters will be ignored -> Product = ' + pProduct.config.codeName) }
break
}
callBackFunction(err)
return
}
default: {
callBackFunction(err)
return
}
}
getMarketFiles()
}
}
function onFileReceived (err, file) {
function getMarketFiles() {
/* Now we will get the market files */
for (let i = 0; i < marketFilesPeriods.length; i++) {
let periodTime = marketFilesPeriods[i][0]
let periodName = marketFilesPeriods[i][1]
if (dataset.config.validTimeFrames.includes(periodName) === false) {
filesNotLoaded++
continue
}
if (timeFrames !== undefined) {
if (timeFrames.includes(periodName) === false) {
filesNotLoaded++
continue
}
}
filesExpected++
fileCloud.getFile(dataMine, bot, session, product, dataset, exchange, market, periodName, undefined, undefined, undefined, undefined, onFileReceived)
function onFileReceived(err, file) {
try {
if (finalized === true) { return }
if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) {
@@ -128,7 +184,7 @@ function newMarketFiles () {
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, thisObject)
function onResponse (message) {
function onResponse(message) {
eventSubscriptionIdDatasetUpdated.push(message.eventSubscriptionId)
}
}
@@ -138,6 +194,8 @@ function newMarketFiles () {
}
}
}
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, thisObject)
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) }
@@ -145,32 +203,35 @@ function newMarketFiles () {
}
}
function updateFiles () {
function updateFiles(message) {
try {
if (finalized === true) { return }
let updatedFiles = 0
if (message.event === undefined) { return }
/* Now we will get the market files */
/* Now we will get the market files */
for (let i = 0; i < marketFilesPeriods.length; i++) {
let periodTime = marketFilesPeriods[i][0]
let periodName = marketFilesPeriods[i][1]
if (dataset.config.validTimeFrames.includes(periodName) === true) {
fileCloud.getFile(dataMine, bot, session, product, dataset, exchange, market, periodName, undefined, undefined, undefined, onFileReceived)
if (dataset.config.validTimeFrames.includes(periodName) !== true) { continue }
if (message.event.timeFrames !== undefined) {
if (message.event.timeFrames.includes(periodName) !== true) { continue }
}
fileCloud.getFile(dataMine, bot, session, product, dataset, exchange, market, periodName, undefined, undefined, undefined, undefined, onFileReceived)
function onFileReceived (err, file) {
try {
if (finalized === true) { return }
files.set(periodTime, file)
updatedFiles++
function onFileReceived(err, file) {
try {
if (finalized === true) { return }
files.set(periodTime, file)
updatedFiles++
if (updatedFiles === marketFilesPeriods.length) {
thisObject.eventHandler.raiseEvent('Files Updated')
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] updateFiles -> onFileReceived -> err = ' + err.stack) }
if (updatedFiles === filesExpected) {
thisObject.eventHandler.raiseEvent('Files Updated')
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] updateFiles -> onFileReceived -> err = ' + err.stack) }
}
}
}
@@ -179,19 +240,19 @@ function newMarketFiles () {
}
}
function getFile (pPeriod) {
function getFile(pPeriod) {
return files.get(pPeriod)
}
function getExpectedFiles () {
function getExpectedFiles() {
return marketFilesPeriods.length
}
function getFilesLoaded () {
function getFilesLoaded() {
return filesLoaded
}
function getFilesNotLoaded () {
function getFilesNotLoaded() {
return filesNotLoaded
}
}
+1 -1
View File
@@ -39,7 +39,7 @@ function newSingleFile () {
/* Now we will get the file */
fileCloud.getFile(pDataMine, pBot, pSession, pProduct, pDataset, exchange, pMarket, undefined, undefined, undefined, undefined, onFileReceived)
fileCloud.getFile(pDataMine, pBot, pSession, pProduct, pDataset, exchange, pMarket, undefined, undefined, undefined, undefined, undefined, onFileReceived)
function onFileReceived (err, pFile) {
try {
@@ -0,0 +1 @@
// Nothing here to run
@@ -0,0 +1 @@
// Nothing here to run
+1 -1
View File
@@ -1 +1 @@
{"type":"Workspace","name":"Beta 6","rootNodes":[{"type":"Network","name":"Superalgos","networkNodes":[{"type":"Network Node","name":"My Computer","config":"{ \n\"host\": \"localhost\", \n\"webPort\": \"34248\", \n\"webSocketsPort\": \"8081\"\n}","dataStorage":{"type":"Data Storage","name":"New Data Storage","sessionIndependentData":{"type":"Session Independent Data","name":"New Session Independent Data","exchangeDataProducts":[{"type":"Exchange Data Products","name":"Binance","singleMarketData":[{"type":"Single Market Data","name":"Binance BTC/USDT","dataProducts":[{"type":"Data Product","name":"Candles","id":"dd7c8795-bb24-4438-9d77-b37a9000ad7f","savedPayload":{"position":{"x":23357.055360727853,"y":29739.13668562185},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Product Definition","name":"Candles","id":"fe6065ec-4d2d-47a0-bae0-8647f0e195d7"}}},{"type":"Data Product","name":"Volumes","id":"98e6c917-f4b7-4b71-9215-de3ccaf3dc0c","savedPayload":{"position":{"x":23291.030236843966,"y":29662.131374764274},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Product Definition","name":"Volumes","id":"1a366aef-efef-470e-88e0-2a6fbe4dd91f"}}},{"type":"Data Product","name":"Candles Channels","id":"1d7dd537-5f6f-4eb2-8e56-ddba0aef720f","savedPayload":{"position":{"x":23231.77091792585,"y":29579.512296539906},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Product Definition","name":"Candles Channels","id":"8c81d378-0947-4e9d-be25-58e69120152e"}}},{"type":"Data Product","name":"Candles Channels Objects","id":"221c8d22-8a7f-4014-a7ed-0bafc886b123","savedPayload":{"position":{"x":23179.942027683566,"y":29492.078725813997},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Product Definition","name":"Candles Channels Objects","id":"ba5dbb67-2030-42a0-9ff8-1ee80874f047"}}},{"type":"Data Product","name":"Bollinger Bands","id":"6929ebe7-6486-4299-add5-ed0282500d91","savedPayload":{"position":{"x":23135.872351370694,"y":29400.352192197388},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Product Definition","name":"Bollinger Bands","id":"29088877-8d63-4217-8d34-8742afc262f4"}}},{"type":"Data Product","name":"Percentage Bandwidth","id":"4a3ed8eb-a73e-4fb4-835a-681cf47d7373","savedPayload":{"position":{"x":23099.965969252025,"y":29305.112951112584},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Product Definition","name":"Percentage Bandwidth","id":"3b7885a0-cd72-4a3f-a38b-3dc8c47bd068"}}},{"type":"Data Product","name":"Bollinger Channels Objects","id":"5ffc6a67-e33b-422b-8e36-f9711f93c723","savedPayload":{"position":{"x":23072.49341713892,"y":29207.0453495464},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Product Definition","name":"Bollinger Channels Objects","id":"1f111f72-624f-4166-9f99-ab8d785d5267"}}},{"type":"Data Product","name":"Bollinger Sub-Channels Objects","id":"48f7953c-f62d-4292-b042-d1ac05f8f80f","savedPayload":{"position":{"x":23053.683458829226,"y":29106.890611883788},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Product Definition","name":"Bollinger Sub-Channels Objects","id":"080c87fc-4546-4482-ab11-180a33f6d9ab"}}},{"type":"Data Product","name":"Popular SMAs","id":"3b9a3c93-6d41-440e-89a2-2fd1b2dde603","savedPayload":{"position":{"x":23043.701100505998,"y":29005.50001492274},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollLine truncated
{"type":"Workspace","name":"Beta 6","rootNodes":[{"type":"Network","name":"Superalgos","networkNodes":[{"type":"Network Node","name":"My Computer","config":"{ \n\"host\": \"localhost\", \n\"webPort\": \"34248\", \n\"webSocketsPort\": \"8081\"\n}","dataStorage":{"type":"Data Storage","name":"New Data Storage","sessionIndependentData":{"type":"Session Independent Data","name":"New Session Independent Data","exchangeDataProducts":[{"type":"Exchange Data Products","name":"Binance","singleMarketData":[{"type":"Single Market Data","name":"Binance BTC/USDT","dataProducts":[{"type":"Data Product","name":"Candles","id":"dd7c8795-bb24-4438-9d77-b37a9000ad7f","savedPayload":{"position":{"x":23357.055360727853,"y":29739.13668562185},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Product Definition","name":"Candles","id":"fe6065ec-4d2d-47a0-bae0-8647f0e195d7"}}},{"type":"Data Product","name":"Volumes","id":"98e6c917-f4b7-4b71-9215-de3ccaf3dc0c","savedPayload":{"position":{"x":23291.030236843966,"y":29662.131374764274},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Product Definition","name":"Volumes","id":"1a366aef-efef-470e-88e0-2a6fbe4dd91f"}}},{"type":"Data Product","name":"Candles Channels","id":"1d7dd537-5f6f-4eb2-8e56-ddba0aef720f","savedPayload":{"position":{"x":23231.77091792585,"y":29579.512296539906},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Product Definition","name":"Candles Channels","id":"8c81d378-0947-4e9d-be25-58e69120152e"}}},{"type":"Data Product","name":"Candles Channels Objects","id":"221c8d22-8a7f-4014-a7ed-0bafc886b123","savedPayload":{"position":{"x":23179.942027683566,"y":29492.078725813997},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Product Definition","name":"Candles Channels Objects","id":"ba5dbb67-2030-42a0-9ff8-1ee80874f047"}}},{"type":"Data Product","name":"Bollinger Bands","id":"6929ebe7-6486-4299-add5-ed0282500d91","savedPayload":{"position":{"x":23135.872351370694,"y":29400.352192197388},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Product Definition","name":"Bollinger Bands","id":"29088877-8d63-4217-8d34-8742afc262f4"}}},{"type":"Data Product","name":"Percentage Bandwidth","id":"4a3ed8eb-a73e-4fb4-835a-681cf47d7373","savedPayload":{"position":{"x":23099.965969252025,"y":29305.112951112584},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Product Definition","name":"Percentage Bandwidth","id":"3b7885a0-cd72-4a3f-a38b-3dc8c47bd068"}}},{"type":"Data Product","name":"Bollinger Channels Objects","id":"5ffc6a67-e33b-422b-8e36-f9711f93c723","savedPayload":{"position":{"x":23072.49341713892,"y":29207.0453495464},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Product Definition","name":"Bollinger Channels Objects","id":"1f111f72-624f-4166-9f99-ab8d785d5267"}}},{"type":"Data Product","name":"Bollinger Sub-Channels Objects","id":"48f7953c-f62d-4292-b042-d1ac05f8f80f","savedPayload":{"position":{"x":23053.683458829226,"y":29106.890611883788},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Product Definition","name":"Bollinger Sub-Channels Objects","id":"080c87fc-4546-4482-ab11-180a33f6d9ab"}}},{"type":"Data Product","name":"Popular SMAs","id":"3b9a3c93-6d41-440e-89a2-2fd1b2dde603","savedPayload":{"position":{"x":23043.701100505998,"y":29005.50001492274},"targetPosition":{"x":24208.69903024272,"y":28943.27543890267},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollLine truncated
@@ -255,11 +255,11 @@
}
}
/*
We do market files first since if the simulation is run on daily files, there will be a loop to getch each daus files and we do not need
that loop to reload market files.
*/
function processMarketFiles() {
/*
We do market files first since if the simulation is run on daily files, there will be a loop to getch each daus files and we do not need
that loop to reload market files.
*/
let n;
timeFramesLoop();
@@ -603,22 +603,25 @@
bot.FIRST_EXECUTION = false // From here on, all other loops executions wont be the first execution.
if (currentTimeFrame > global.dailyFilePeriods[0][0]) {
writeMarketStatusReport(onMarketStatusReport)
} else {
writeDataRanges(currentTimeFrameLabel, onWritten);
writeTimeFramesFiles(currentTimeFrame, currentTimeFrameLabel, onTimeFrameFilesWritten)
function onTimeFrameFilesWritten() {
writeDataRanges(currentTimeFrameLabel, onDataRangesWritten);
}
function onWritten(err) {
function onDataRangesWritten(err) {
try {
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> processDailyFiles -> buildCharts -> onOutputGenerated -> onWritten -> err = " + err.stack);
callBackFunction(err);
return;
}
writeDailyStatusReport(bot.tradingProcessDate, onDailyStatusReport);
if (currentTimeFrame > global.dailyFilePeriods[0][0]) {
writeMarketStatusReport(onMarketStatusReport)
} else {
writeDailyStatusReport(bot.tradingProcessDate, onDailyStatusReport);
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> processDailyFiles -> buildCharts -> onOutputGenerated -> onWritten -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
@@ -727,6 +730,51 @@
thisReport.save(callBack);
}
function writeTimeFramesFiles(currentTimeFrame, currentTimeFrameLabel, callBack) {
let outputDatasetIndex = -1;
controlLoop()
function productLoopBody() {
let productCodeName = bot.processNode.referenceParent.processOutput.outputDatasets[outputDatasetIndex].referenceParent.parentNode.config.codeName;
writeTimeFramesFile(currentTimeFrame, currentTimeFrameLabel, productCodeName, 'Multi-Period-Daily', dailyFileWritten)
function dailyFileWritten() {
writeTimeFramesFile(currentTimeFrame, currentTimeFrameLabel, productCodeName, 'Multi-Period-Market', controlLoop)
}
}
function controlLoop() {
outputDatasetIndex++
if (outputDatasetIndex < bot.processNode.referenceParent.processOutput.outputDatasets.length) {
productLoopBody()
} else {
callBack()
}
}
}
function writeTimeFramesFile(currentTimeFrame, currentTimeFrameLabel, productCodeName, processType, callBack) {
let timeFramesArray = []
timeFramesArray.push(currentTimeFrameLabel)
let fileContent = JSON.stringify(timeFramesArray)
let fileName = '/Time.Frames.json';
let filePath = bot.filePathRoot + "/Output/" + bot.SESSION.folderName + "/" + productCodeName + "/" + processType + fileName;
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated)
function onFileCreated(err) {
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> writeTimeFramesFile -> onFileCreated -> err = " + err.stack)
callBack(err)
return
}
callBack()
}
}
function trimDataFile(dataFile, recordDefinition) {
/*
Here we will discard all the records in a file that are outside of the current time range.
@@ -272,8 +272,7 @@ exports.newTradingSystem = function newTradingSystem(bot, logger, tradingEngineM
*/
value = false
if (code.indexOf('previous') > -1 && err.message.indexOf('of undefined') > -1 ||
code.indexOf('chart') > -1 && err.message.indexOf('of undefined') > -1
if (code.indexOf('previous') > -1 && err.message.indexOf('of undefined') > -1
) {
/*
We are not going to set an error for the casess we are using previous and the error is that the indicator is undefined.
@@ -313,8 +312,7 @@ exports.newTradingSystem = function newTradingSystem(bot, logger, tradingEngineM
*/
value = 0
if (node.code.indexOf('previous') > -1 && err.message.indexOf('of undefined') > -1 ||
node.code.indexOf('chart') > -1 && err.message.indexOf('of undefined') > -1
if (node.code.indexOf('previous') > -1 && err.message.indexOf('of undefined') > -1
) {
/*
We are not going to set an error for the casess we are using previous and the error is that the indicator is undefined.
File diff suppressed because it is too large. Load diff
+171 -278
View File
@@ -1,52 +1,38 @@
exports.newMultiPeriodMarket = function newMultiPeriodMarket(bot, logger, UTILITIES, FILE_STORAGE) {
const FULL_LOG = true;
const LOG_FILE_CONTENT = false;
const MODULE_NAME = "Multi Period Market";
thisObject = {
initialize: initialize,
finalize: finalize,
start: start
};
let utilities = UTILITIES.newCloudUtilities(logger);
let utilities = UTILITIES.newCloudUtilities(logger)
let fileStorage = FILE_STORAGE.newFileStorage(logger)
let statusDependencies;
let dataDependenciesModule;
let dataFiles = new Map();
let dataFiles = new Map()
let indicatorOutputModule;
let processConfig;
return thisObject;
function initialize(pProcessConfig, pStatusDependencies, pDataDependencies, callBackFunction) {
logger.fileName = MODULE_NAME;
logger.initialize()
try {
statusDependencies = pStatusDependencies;
dataDependenciesModule = pDataDependencies;
processConfig = pProcessConfig;
logger.fileName = MODULE_NAME;
logger.initialize();
let INDICATOR_OUTPUT_MODULE = require("./IndicatorOutput")
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
statusDependencies = pStatusDependencies;
dataDependenciesModule = pDataDependencies;
processConfig = pProcessConfig;
let INDICATOR_OUTPUT_MODULE = require("./IndicatorOutput")
indicatorOutputModule = INDICATOR_OUTPUT_MODULE.newIndicatorOutput(bot, logger, UTILITIES, FILE_STORAGE);
indicatorOutputModule.initialize(callBackFunction);
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
indicatorOutputModule = INDICATOR_OUTPUT_MODULE.newIndicatorOutput(bot, logger, UTILITIES, FILE_STORAGE)
indicatorOutputModule.initialize(callBackFunction)
}
function finalize() {
fileStorage = undefined
dataFiles = undefined
statusDependencies = undefined
dataDependenciesModule = undefined
@@ -56,272 +42,179 @@
}
function start(callBackFunction) {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> Entering function."); }
let market = bot.market;
/* Context Variables */
let contextVariables = {
dateBeginOfMarket: undefined, // Datetime of the first trade file in the whole market history.
dateEndOfMarket: undefined // Datetime of the last file available to be used as an input of this process.
};
processTimeFrames();
processTimeFrames()
function processTimeFrames() {
let n;
timeFramesLoop()
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFrames -> Entering function."); }
try {
let n;
periodsLoop();
function periodsLoop() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFrames -> periodsLoop -> Entering function."); }
/*
We will iterate through all posible periods.
*/
n = 0 // loop Variable representing each possible period as defined at the periods array.
periodsLoopBody();
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> processTimeFrames -> periodsLoop -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function periodsLoopBody() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFrames -> periodsLoopBody -> Entering function."); }
const timeFrame = global.marketFilesPeriods[n][0];
const timeFrameLabel = global.marketFilesPeriods[n][1];
let dependencyIndex = 0;
dataFiles = new Map;
dependencyLoopBody();
function dependencyLoopBody() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFrames -> periodsLoopBody -> dependencyLoopBody -> Entering function."); }
let dependency = dataDependenciesModule.nodeArray[dependencyIndex];
let datasetModule = dataDependenciesModule.dataSetsModulesArray[dependencyIndex];
getFile();
function getFile() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFrames -> periodsLoopBody -> dependencyLoopBody -> getFile -> Entering function."); }
let dateForPath = bot.processDatetime.getUTCFullYear() + '/' + utilities.pad(bot.processDatetime.getUTCMonth() + 1, 2) + '/' + utilities.pad(bot.processDatetime.getUTCDate(), 2);
let fileName = "Data.json";
let filePath
if (dependency.referenceParent.config.codeName === "Multi-Period-Market") {
filePath = dependency.referenceParent.parentNode.config.codeName + '/' + dependency.referenceParent.config.codeName + "/" + timeFrameLabel;
} else {
filePath = dependency.referenceParent.parentNode.config.codeName + '/' + dependency.referenceParent.config.codeName + "/" + dateForPath;
}
datasetModule.getTextFile(filePath, fileName, onFileReceived);
function onFileReceived(err, text) {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFrames -> periodsLoopBody -> dependencyLoopBody -> getFile -> onFileReceived -> Entering function."); }
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFrames -> periodsLoopBody -> dependencyLoopBody -> getFile -> onFileReceived -> text = " + text); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> processTimeFrames -> periodsLoopBody -> dependencyLoopBody -> getFile -> onFileReceived -> err = " + err.stack);
callBackFunction(err);
return;
}
let dataFile = JSON.parse(text);
dataFiles.set(dependency.id, dataFile);
dependencyControlLoop();
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> processTimeFrames -> periodsLoopBody -> dependencyLoopBody -> getFile -> onFileReceived -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> processTimeFrames -> periodsLoopBody -> dependencyLoopBody -> getFile -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> processTimeFrames -> periodsLoop -> dependencyLoopBody -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function dependencyControlLoop() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFrames -> dependencyControlLoop -> Entering function."); }
dependencyIndex++;
if (dependencyIndex < dataDependenciesModule.nodeArray.length) {
dependencyLoopBody();
} else {
generateOutput();
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> processTimeFrames -> dependencyControlLoop -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function generateOutput() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFrames -> periodsLoopBody -> generateOutput -> Entering function."); }
const timeFrame = global.marketFilesPeriods[n][0];
const timeFrameLabel = global.marketFilesPeriods[n][1];
indicatorOutputModule.start(
dataFiles,
timeFrame,
timeFrameLabel,
undefined,
undefined,
onOutputGenerated);
function onOutputGenerated(err) {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFrames -> periodsLoopBody -> generateOutput -> onOutputGenerated -> Entering function."); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
callBackFunction(err);
return;
}
periodsControlLoop();
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> processTimeFrames -> periodsLoopBody -> generateOutput -> onOutputGenerated -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> processTimeFrames -> periodsLoopBody -> generateOutput -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> processTimeFrames -> periodsLoopBody -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function periodsControlLoop() {
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> processTimeFrames -> periodsControlLoop -> Entering function."); }
n++;
if (n < global.marketFilesPeriods.length) {
periodsLoopBody();
} else {
writeStatusReport(callBackFunction);
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> processTimeFrames -> periodsControlLoop -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function timeFramesLoop() {
/* We will iterate through all posible timeFrames.*/
n = 0 // loop Variable representing each possible period as defined at the timeFrames array.
timeFramesLoopBody()
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> processTimeFrames -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
function timeFramesLoopBody() {
const timeFrame = global.marketFilesPeriods[n][0]
const timeFrameLabel = global.marketFilesPeriods[n][1]
/* Check Time Frames Filter */
if (bot.marketTimeFrames !== undefined) {
if (bot.marketTimeFrames.includes(timeFrameLabel) === false) {
/* We are not going to process this Time Frame */
timeFramesControlLoop()
return
}
}
let dependencyIndex = 0;
dataFiles = new Map;
dependencyLoopBody()
function dependencyLoopBody() {
let dependency = dataDependenciesModule.nodeArray[dependencyIndex]
let datasetModule = dataDependenciesModule.dataSetsModulesArray[dependencyIndex]
getFile()
function getFile() {
let fileName = "Data.json";
let filePath = dependency.referenceParent.parentNode.config.codeName + '/' + dependency.referenceParent.config.codeName + "/" + timeFrameLabel;
datasetModule.getTextFile(filePath, fileName, onFileReceived)
function onFileReceived(err, text) {
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> processTimeFrames -> timeFramesLoopBody -> dependencyLoopBody -> getFile -> onFileReceived -> err = " + err.stack)
callBackFunction(err)
return;
}
let dataFile = JSON.parse(text)
dataFiles.set(dependency.id, dataFile)
dependencyControlLoop()
}
}
}
function dependencyControlLoop() {
dependencyIndex++;
if (dependencyIndex < dataDependenciesModule.nodeArray.length) {
dependencyLoopBody()
} else {
generateOutput()
}
function generateOutput() {
indicatorOutputModule.start(
dataFiles,
timeFrame,
timeFrameLabel,
undefined,
undefined,
onOutputGenerated)
function onOutputGenerated(err) {
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
callBackFunction(err)
return;
}
timeFramesControlLoop()
}
}
}
}
function timeFramesControlLoop() {
n++;
if (n < global.marketFilesPeriods.length) {
timeFramesLoopBody()
} else {
writeTimeFramesFiles(onTimeFrameFilesWritten)
function onTimeFrameFilesWritten() {
writeStatusReport(callBackFunction)
}
}
}
}
function writeTimeFramesFiles(callBack) {
let outputDatasetIndex = -1;
controlLoop()
function productLoopBody() {
let productCodeName = bot.processNode.referenceParent.processOutput.outputDatasets[outputDatasetIndex].referenceParent.parentNode.config.codeName;
writeTimeFramesFile(productCodeName, controlLoop)
}
function controlLoop() {
outputDatasetIndex++
if (outputDatasetIndex < bot.processNode.referenceParent.processOutput.outputDatasets.length) {
productLoopBody()
} else {
callBack()
}
}
}
function writeTimeFramesFile(productCodeName, callBack) {
let timeFramesArray = []
for (let n = 0; n < global.marketFilesPeriods.length; n++) {
let timeFrameLabel = global.marketFilesPeriods[n][1]
/* Check Time Frames Filter */
if (bot.marketTimeFrames !== undefined) {
if (bot.marketTimeFrames.includes(timeFrameLabel) === true) {
timeFramesArray.push(timeFrameLabel)
}
} else {
timeFramesArray.push(timeFrameLabel)
}
}
let fileContent = JSON.stringify(timeFramesArray)
let fileName = '/Time.Frames.json';
let filePath = bot.filePathRoot + "/Output/" + productCodeName + "/" + bot.process + fileName;
fileStorage.createTextFile(filePath, fileContent + '\n', onFileCreated)
function onFileCreated(err) {
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
logger.write(MODULE_NAME, "[ERROR] start -> writeTimeFramesFile -> onFileCreated -> err = " + err.stack)
callBack(err)
return
}
callBack()
}
}
function writeStatusReport(callBack) {
let reportKey = bot.dataMine + "-" + bot.codeName + "-" + "Multi-Period-Market"
let thisReport = statusDependencies.statusReports.get(reportKey)
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeStatusReport -> Entering function."); }
try {
let reportKey = bot.dataMine + "-" + bot.codeName + "-" + "Multi-Period-Market"
let thisReport = statusDependencies.statusReports.get(reportKey);
thisReport.file.lastExecution = bot.processDatetime;
thisReport.save(callBack);
if (global.areEqualDates(bot.processDatetime, new Date()) === false) {
logger.newInternalLoop(bot.codeName, bot.process, bot.processDatetime);
}
/* Telling the world we are alive and doing well */
let currentDateString = bot.processDatetime.getUTCFullYear() + '-' + utilities.pad(bot.processDatetime.getUTCMonth() + 1, 2) + '-' + utilities.pad(bot.processDatetime.getUTCDate(), 2);
let currentDate = new Date(bot.processDatetime)
let lastDate = new Date()
bot.processHeartBeat(currentDateString, global.getPercentage(currentDate, currentDate, lastDate))
thisReport.file.lastExecution = bot.processDatetime;
if (bot.marketTimeFrames !== undefined) {
thisReport.file.timeFrames = bot.marketTimeFrames
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> writeStatusReport -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
thisReport.save(callBack)
if (global.areEqualDates(bot.processDatetime, new Date()) === false) {
logger.newInternalLoop(bot.codeName, bot.process, bot.processDatetime)
}
/* Telling the world we are alive and doing well */
let currentDateString = bot.processDatetime.getUTCFullYear() + '-' + utilities.pad(bot.processDatetime.getUTCMonth() + 1, 2) + '-' + utilities.pad(bot.processDatetime.getUTCDate(), 2)
let currentDate = new Date(bot.processDatetime)
let lastDate = new Date()
bot.processHeartBeat(currentDateString, global.getPercentage(currentDate, currentDate, lastDate))
}
}
catch (err) {
logger.write(MODULE_NAME, "[ERROR] start -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
logger.write(MODULE_NAME, "[ERROR] start -> err = " + err.stack)
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
}
}
};
}
+3 -2
View File
@@ -14,7 +14,7 @@
return thisObject;
function raiseEvents(lastFile, callBackFunction) {
function raiseEvents(lastFile, timeFrames, callBackFunction) {
try {
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] raiseEvents -> Entering function."); }
@@ -83,7 +83,8 @@
key = dataMine + "-" + botName + "-" + product + "-" + dataset + "-" + bot.exchange + "-" + bot.market.baseAsset + '/' + bot.market.quotedAsset
let event = {
lastFile: lastFile
lastFile: lastFile,
timeFrames: timeFrames
}
global.EVENT_SERVER_CLIENT.createEventHandler(key, 'Dataset Updated')
global.EVENT_SERVER_CLIENT.raiseEvent(key, 'Dataset Updated', event)
+6
View File
@@ -225,6 +225,12 @@
/* Bot Type */
botConfig.type = global.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.type
/* Time Frame Filter */
if (global.TASK_NODE.bot.timeFramesFilter !== undefined) {
botConfig.dailyTimeFrames = global.TASK_NODE.bot.timeFramesFilter.config.dailyTimeFrames
botConfig.marketTimeFrames = global.TASK_NODE.bot.timeFramesFilter.config.marketTimeFrames
}
if (botConfig.processNode) {
if (botConfig.processNode.marketReference) {
if (botConfig.processNode.marketReference.keyReference !== undefined) {
+1 -1
View File
@@ -334,7 +334,7 @@
let processOutput = PROCESS_OUTPUT.newProcessOutput(bot, logger)
processOutput.raiseEvents(thisObject.file.lastFile, callBackFunction);
processOutput.raiseEvents(thisObject.file.lastFile, thisObject.file.timeFrames, callBackFunction);
return;
}