Beta6 update: Time Frame Files
This commit is contained in:
1 parent
6ec5580cd4
commit
e90ccebe8f
31 files changed
+2632
-1382
No files matched your search
@@ -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
|
||||
@@ -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 & Languages</a></li>
|
||||
<li><a href="#installing">Installing Webfonts</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -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&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;"> </div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
+134
-76
@@ -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
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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->' +
|
||||
|
||||
@@ -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
@@ -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()
|
||||
|
||||
@@ -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 @@
|
||||
{"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 @@
|
||||
{"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
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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 @@
|
||||
{"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.
|
||||
|
||||
+365
-600
File diff suppressed because it is too large.
Load diff
+171
-278
@@ -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)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user