Compare commits
21
Commits
No files matched your search
+27
-36
@@ -810,7 +810,7 @@
|
||||
"disableIfPropertyIsDefined": true,
|
||||
"propertyToCheckFor": "javascriptCode",
|
||||
"label": "Add Code",
|
||||
"relatedUiObject": "Javascript Code",
|
||||
"relatedUiObject": "Condition",
|
||||
"actionFunction": "payload.onMenuItemClick"
|
||||
},
|
||||
{
|
||||
@@ -1245,7 +1245,7 @@
|
||||
"config": true
|
||||
},
|
||||
"initialValues": {
|
||||
"code": "{ \n\"ipAddress\": \"\", \n\"webPort\": \"\", \n\"webSocketsPort\": \"\"\n}"
|
||||
"code": "{ \n\"host\": \"localhost\", \n\"webPort\": \"34247\", \n\"webSocketsPort\": \"8080\"\n}"
|
||||
},
|
||||
"isTitleAllwaysVisible": true,
|
||||
"addLeftIcons": true,
|
||||
@@ -1322,7 +1322,6 @@
|
||||
"actionFunction": "payload.onMenuItemClick"
|
||||
}
|
||||
],
|
||||
"isTitleAllwaysVisible": true,
|
||||
"addLeftIcons": true,
|
||||
"level": 1,
|
||||
"chainAttachesTo": {
|
||||
@@ -1360,6 +1359,16 @@
|
||||
"iconPathOff": "paper-plane",
|
||||
"actionFunction": "payload.onMenuItemClick"
|
||||
},
|
||||
{
|
||||
"action": "Debug Task",
|
||||
"label": "Debug",
|
||||
"workingLabel": "Debugging",
|
||||
"workDoneLabel": "Debug Request Sent",
|
||||
"workFailedLabel": "Task Cannot be Debugged",
|
||||
"iconPathOn": "status-dependency",
|
||||
"iconPathOff": "status-dependency",
|
||||
"actionFunction": "payload.onMenuItemClick"
|
||||
},
|
||||
{
|
||||
"action": "Add UI Object",
|
||||
"disableIfPropertyIsDefined": true,
|
||||
@@ -2208,7 +2217,7 @@
|
||||
"compatibleTypes": "->Trading System->"
|
||||
},
|
||||
"chainAttachesTo": {
|
||||
"compatibleTypes": "->Process Instance->"
|
||||
"compatibleTypes": "->Trading Process Instance->"
|
||||
},
|
||||
"icon": "session-paper-trading",
|
||||
"properties": [
|
||||
@@ -2293,7 +2302,7 @@
|
||||
"compatibleTypes": "->Trading System->"
|
||||
},
|
||||
"chainAttachesTo": {
|
||||
"compatibleTypes": "->Process Instance->"
|
||||
"compatibleTypes": "->Trading Process Instance->"
|
||||
},
|
||||
"icon": "session-forward-testing",
|
||||
"properties": [
|
||||
@@ -2403,7 +2412,7 @@
|
||||
"compatibleTypes": "->Trading System->"
|
||||
},
|
||||
"chainAttachesTo": {
|
||||
"compatibleTypes": "->Process Instance->"
|
||||
"compatibleTypes": "->Trading Process Instance->"
|
||||
},
|
||||
"icon": "session-live-trading",
|
||||
"properties": [
|
||||
@@ -4011,12 +4020,14 @@
|
||||
{
|
||||
"name": "positionSize",
|
||||
"type": "node",
|
||||
"childType": "Position Size"
|
||||
"childType": "Position Size",
|
||||
"autoAdd": true
|
||||
},
|
||||
{
|
||||
"name": "positionRate",
|
||||
"type": "node",
|
||||
"childType": "Position Rate"
|
||||
"childType": "Position Rate",
|
||||
"autoAdd": true
|
||||
}
|
||||
],
|
||||
"propertyNameAtParent": "initialDefinition"
|
||||
@@ -4370,7 +4381,8 @@
|
||||
{
|
||||
"name": "formula",
|
||||
"type": "node",
|
||||
"childType": "Formula"
|
||||
"childType": "Formula",
|
||||
"autoAdd": true
|
||||
}
|
||||
],
|
||||
"propertyNameAtParent": "positionSize"
|
||||
@@ -4407,7 +4419,8 @@
|
||||
{
|
||||
"name": "formula",
|
||||
"type": "node",
|
||||
"childType": "Formula"
|
||||
"childType": "Formula",
|
||||
"autoAdd": true
|
||||
}
|
||||
],
|
||||
"propertyNameAtParent": "positionRate"
|
||||
@@ -4809,7 +4822,7 @@
|
||||
{
|
||||
"action": "Send Webhook Test Message",
|
||||
"label": "Send Test Message",
|
||||
"workingLabel": "Seinding Message",
|
||||
"workingLabel": "Sending Message",
|
||||
"workDoneLabel": "Message Sent",
|
||||
"workFailedLabel": "Message not Delived",
|
||||
"iconPathOn": "paper-plane",
|
||||
@@ -6095,7 +6108,7 @@
|
||||
"compatibleTypes": "->Crypto Exchange->"
|
||||
},
|
||||
"chainAttachesTo": {
|
||||
"compatibleTypes": "->Data Mining->Testing Environmnet->Production Environment->Template Structure->"
|
||||
"compatibleTypes": "->Data Mining->Testing Environment->Production Environment->Template Structure->"
|
||||
},
|
||||
"alternativeIcons": "Use Reference Parent",
|
||||
"title": [
|
||||
@@ -6164,7 +6177,6 @@
|
||||
"name": "exchangeTasks",
|
||||
"type": "array",
|
||||
"childType": "Exchange Tasks",
|
||||
"autoAdd": true,
|
||||
"monitorChildrenRunning": true
|
||||
}
|
||||
]
|
||||
@@ -6217,17 +6229,10 @@
|
||||
},
|
||||
"propertyNameAtParent": "testingEnvironment",
|
||||
"properties": [
|
||||
{
|
||||
"name": "taskManagers",
|
||||
"type": "array",
|
||||
"childType": "Task Manager",
|
||||
"autoAdd": true
|
||||
},
|
||||
{
|
||||
"name": "exchangeTasks",
|
||||
"type": "array",
|
||||
"childType": "Exchange Tasks",
|
||||
"autoAdd": true,
|
||||
"monitorChildrenRunning": true
|
||||
}
|
||||
]
|
||||
@@ -6280,17 +6285,10 @@
|
||||
},
|
||||
"propertyNameAtParent": "productionEnvironment",
|
||||
"properties": [
|
||||
{
|
||||
"name": "taskManagers",
|
||||
"type": "array",
|
||||
"childType": "Task Manager",
|
||||
"autoAdd": true
|
||||
},
|
||||
{
|
||||
"name": "exchangeTasks",
|
||||
"type": "array",
|
||||
"childType": "Exchange Tasks",
|
||||
"autoAdd": true,
|
||||
"monitorChildrenRunning": true
|
||||
}
|
||||
]
|
||||
@@ -6403,7 +6401,7 @@
|
||||
"compatibleTypes": "->Crypto Exchange->"
|
||||
},
|
||||
"chainAttachesTo": {
|
||||
"compatibleTypes": "->Data Storage->"
|
||||
"compatibleTypes": "->Session Based Data->"
|
||||
},
|
||||
"propertyNameAtParent": "exchangeSessions",
|
||||
"properties": [
|
||||
@@ -6442,17 +6440,10 @@
|
||||
},
|
||||
"propertyNameAtParent": "sessionBasedData",
|
||||
"properties": [
|
||||
{
|
||||
"name": "sessionReferences",
|
||||
"type": "array",
|
||||
"childType": "Session Reference",
|
||||
"autoAdd": true
|
||||
},
|
||||
{
|
||||
"name": "exchangeSessions",
|
||||
"type": "array",
|
||||
"childType": "Exchange Sessions",
|
||||
"autoAdd": true
|
||||
"childType": "Exchange Sessions"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -94,6 +94,7 @@ function newAppLoader() {
|
||||
'FloatingSpace/ConfigEditor.js',
|
||||
'FloatingSpace/ConditionEditor.js',
|
||||
'FloatingSpace/FormulaEditor.js',
|
||||
'FloatingSpace/Picker.js',
|
||||
|
||||
'Scales/RateScale.js',
|
||||
'Scales/TimeScale.js',
|
||||
|
||||
@@ -51,17 +51,17 @@
|
||||
//console.log('[INFO] BackendServers -> Task Manager Server -> runTask -> Entering function.')
|
||||
|
||||
if (message.event === undefined) {
|
||||
console.log('[WARN] BackendServers -> Task Manager Server -> runTask -> Message Received Without Event -> message = ' + JSON.stringify(message))
|
||||
console.log('[WARN] BackendServers -> Task Manager Server -> runTask -> Message Received Without Event -> message = ' + JSON.stringify(message).substring(0, 1000))
|
||||
return
|
||||
}
|
||||
|
||||
if (message.event.taskId === undefined) {
|
||||
console.log('[WARN] BackendServers -> Task Manager Server -> runTask -> Message Received Without taskId -> message = ' + JSON.stringify(message))
|
||||
console.log('[WARN] BackendServers -> Task Manager Server -> runTask -> Message Received Without taskId -> message = ' + JSON.stringify(message).substring(0, 1000))
|
||||
return
|
||||
}
|
||||
|
||||
if (message.event.definition === undefined) {
|
||||
console.log('[WARN] BackendServers -> Task Manager Server -> runTask -> Message Received Without Definition -> message = ' + JSON.stringify(message))
|
||||
if (message.event.taskDefinition === undefined) {
|
||||
console.log('[WARN] BackendServers -> Task Manager Server -> runTask -> Message Received Without taskDefinition -> message = ' + JSON.stringify(message).substring(0, 1000))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -116,12 +116,12 @@
|
||||
//console.log('[INFO] BackendServers -> Task Manager Server -> stopTask -> Entering function.')
|
||||
|
||||
if (message.event === undefined) {
|
||||
console.log('[WARN] BackendServers -> Task Manager Server -> stopTask -> Message Received Without Event -> message = ' + JSON.stringify(message))
|
||||
console.log('[WARN] BackendServers -> Task Manager Server -> stopTask -> Message Received Without Event -> message = ' + JSON.stringify(message).substring(0, 1000))
|
||||
return
|
||||
}
|
||||
|
||||
if (message.event.taskId === undefined) {
|
||||
console.log('[WARN] BackendServers -> Task Manager Server -> stopTask -> Message Received Without taskId -> message = ' + JSON.stringify(message))
|
||||
console.log('[WARN] BackendServers -> Task Manager Server -> stopTask -> Message Received Without taskId -> message = ' + JSON.stringify(message).substring(0, 1000))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
try {
|
||||
if (LOG_INFO === true) {
|
||||
console.log('Message Received: ' + message)
|
||||
console.log('Message Received: ' + message.substring(0, 1000))
|
||||
}
|
||||
|
||||
let messageArray = message.split('|*|')
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
if (origin === 'Web Browser') {
|
||||
if (isNaN(nonce) || nonce === "") {
|
||||
console.log('[ERROR] BackendServers -> Web Sockets Server -> run -> setUpWebSocketServer -> Nonce is not a Number. message = ' + message)
|
||||
console.log('[ERROR] BackendServers -> Web Sockets Server -> run -> setUpWebSocketServer -> Nonce is not a Number. message = ' + message.substring(0, 1000))
|
||||
console.log('[ERROR] BackendServers -> Web Sockets Server -> run -> setUpWebSocketServer -> Nonce is not a Number. nonce = ' + nonce)
|
||||
return
|
||||
}
|
||||
@@ -68,7 +68,7 @@
|
||||
}
|
||||
|
||||
if (Number(nonce) < Number(lastNonce)) {
|
||||
console.log('[ERROR] BackendServers -> Web Sockets Server -> run -> setUpWebSocketServer -> Nonce received is less than Last Nonce. message = ' + message)
|
||||
console.log('[ERROR] BackendServers -> Web Sockets Server -> run -> setUpWebSocketServer -> Nonce received is less than Last Nonce. message = ' + message.substring(0, 1000))
|
||||
console.log('[ERROR] BackendServers -> Web Sockets Server -> run -> setUpWebSocketServer -> Nonce received is less than Last Nonce. nonce = ' + nonce)
|
||||
console.log('[ERROR] BackendServers -> Web Sockets Server -> run -> setUpWebSocketServer -> Nonce received is less than Last Nonce. lastNonce = ' + lastNonce)
|
||||
return
|
||||
@@ -79,7 +79,7 @@
|
||||
try {
|
||||
let jsonCheck = JSON.parse(messageToEventServer)
|
||||
} catch (err) {
|
||||
console.log('[ERROR] BackendServers -> Web Sockets Server -> run -> setUpWebSocketServer -> Message received from the browser is not a valid JSON. message = ' + message)
|
||||
console.log('[ERROR] BackendServers -> Web Sockets Server -> run -> setUpWebSocketServer -> Message received from the browser is not a valid JSON. message = ' + message.substring(0, 1000))
|
||||
console.log('[ERROR] BackendServers -> Web Sockets Server -> run -> setUpWebSocketServer -> Message received from the browser is not a valid JSON. messageToEventServer = ' + messageToEventServer)
|
||||
return
|
||||
}
|
||||
@@ -106,7 +106,7 @@
|
||||
|
||||
console.log('Web Sockets Server Started.')
|
||||
} catch (err) {
|
||||
console.log('[ERROR] BackendServers -> Web Sockets Server -> run -> setUpWebSocketServer -> err.message = ' + err.message)
|
||||
console.log('[ERROR] BackendServers -> Web Sockets Server -> run -> setUpWebSocketServer -> err.message = ' + err.message.substring(0, 1000))
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -4,7 +4,7 @@ We are thrilled you are interested in contributing to this project. Your help ma
|
||||
|
||||
Superalgos is a collective project, currently at a very early stage. We not only welcome contributions but may even choose to incentivize relevant contributions via the project's native crypto token, to be deployed in the near future.
|
||||
|
||||
Please read the [Join the Dev Team]( https://superalgos.org/developers-join-dev-team.shtml) page in our website to learn more about how you may become a relevant member of the Superalgos Project and even make a living of contributing code.
|
||||
|
||||
|
||||
Contributions are deemed _voluntary work_, irrespective of the incentives that may be in place, and are subject to the conditions described in the software [LICENSE](LICENSE).
|
||||
|
||||
|
||||
@@ -130,8 +130,6 @@ function newCanvas () {
|
||||
animation.initialize()
|
||||
|
||||
thisObject.animation = animation
|
||||
/* Low Level Infraestructure First */
|
||||
animation.addCallBackFunction('System Event Handler Physics', eventsServerClient.physics)
|
||||
|
||||
/* Spcaces Physics */
|
||||
animation.addCallBackFunction('CockpitSpace Physics', thisObject.cockpitSpace.physics)
|
||||
|
||||
@@ -146,6 +146,13 @@ function newPlottersManager () {
|
||||
}
|
||||
}
|
||||
|
||||
let host = layer.networkNode.code.host
|
||||
let webPort = layer.networkNode.code.webPort
|
||||
if (host === undefined) { host = 'localhost' }
|
||||
if (webPort === undefined) { webPort = window.location.port }
|
||||
|
||||
let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(layer.networkNode.id)
|
||||
|
||||
storage.initialize(
|
||||
dataMine,
|
||||
bot,
|
||||
@@ -155,6 +162,9 @@ function newPlottersManager () {
|
||||
market,
|
||||
datetime,
|
||||
timeFrame,
|
||||
host,
|
||||
webPort,
|
||||
eventsServerClient,
|
||||
onProductStorageInitialized
|
||||
)
|
||||
|
||||
|
||||
@@ -24,23 +24,19 @@ function newProtocolNode () {
|
||||
|
||||
/* Children Nodes */
|
||||
if (nodeDefinition.properties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
for (let i = 0; i < nodeDefinition.properties.length; i++) {
|
||||
let property = nodeDefinition.properties[i]
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (node[property.name] !== undefined) {
|
||||
if (property.name !== previousPropertyName) {
|
||||
if (lightingPath === undefined) {
|
||||
object[property.name] = getProtocolNode(node[property.name], removePersonalData, parseCode, includeIds, includeReferencesInSavedPayload, includePayload)
|
||||
} else {
|
||||
let newLightingPath = getNewLightingPath(lightingPath, node.type, property.childType)
|
||||
if (newLightingPath !== undefined) {
|
||||
object[property.name] = getProtocolNode(node[property.name], removePersonalData, parseCode, includeIds, includePayload, includeReferencesInSavedPayload, newLightingPath)
|
||||
}
|
||||
if (lightingPath === undefined) {
|
||||
object[property.name] = getProtocolNode(node[property.name], removePersonalData, parseCode, includeIds, includeReferencesInSavedPayload, includePayload)
|
||||
} else {
|
||||
let newLightingPath = getNewLightingPath(lightingPath, node.type, property.childType)
|
||||
if (newLightingPath !== undefined) {
|
||||
object[property.name] = getProtocolNode(node[property.name], removePersonalData, parseCode, includeIds, includePayload, includeReferencesInSavedPayload, newLightingPath)
|
||||
}
|
||||
previousPropertyName = property.name
|
||||
}
|
||||
}
|
||||
break
|
||||
|
||||
@@ -7,26 +7,15 @@ function newSessionFunctions () {
|
||||
return thisObject
|
||||
|
||||
function runSession (node, functionLibraryProtocolNode, functionLibraryDependenciesFilter, callBackFunction) {
|
||||
/* We can not run a sessionif its parent process is not running. Less if it does not have a parent. */
|
||||
if (node.payload.parentNode === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Session needs a Process Instance parent to be able to run.')
|
||||
if (validations(node) !== true) {
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
return
|
||||
}
|
||||
|
||||
if (node.payload.parentNode.payload.uiObject.isRunning !== true) {
|
||||
node.payload.uiObject.setErrorMessage('Session needs a Process Instance parent to be running to be able to run.')
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
return
|
||||
}
|
||||
let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode
|
||||
let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id)
|
||||
|
||||
if (node.payload.referenceParent === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Session needs to reference a Trading System.')
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
return
|
||||
}
|
||||
|
||||
node.payload.uiObject.run(callBackFunction)
|
||||
node.payload.uiObject.run(eventsServerClient, callBackFunction)
|
||||
|
||||
let key = node.name + '-' + node.type + '-' + node.id
|
||||
|
||||
@@ -77,9 +66,65 @@ function newSessionFunctions () {
|
||||
}
|
||||
|
||||
function stopSession (node, functionLibraryProtocolNode, callBackFunction) {
|
||||
if (validations(node) !== true) {
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
return
|
||||
}
|
||||
|
||||
let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode
|
||||
let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id)
|
||||
|
||||
let key = node.name + '-' + node.type + '-' + node.id
|
||||
eventsServerClient.raiseEvent(key, 'Stop Session')
|
||||
|
||||
node.payload.uiObject.stop(callBackFunction)
|
||||
}
|
||||
|
||||
function validations (node) {
|
||||
if (node.payload.parentNode === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Session needs a Process Instance parent to be able to run.')
|
||||
return
|
||||
}
|
||||
|
||||
if (node.payload.parentNode.payload.parentNode === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Session needs to be inside a Trading Process Instance.')
|
||||
return
|
||||
}
|
||||
|
||||
if (node.payload.parentNode.payload.parentNode.payload.parentNode === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Session needs to be inside a Task.')
|
||||
return
|
||||
}
|
||||
|
||||
if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Session needs to be inside a Task Manager.')
|
||||
return
|
||||
}
|
||||
|
||||
if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Session needs to be inside Exchange Tasks.')
|
||||
return
|
||||
}
|
||||
|
||||
if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Session needs to be inside a Testing or Production Environment.')
|
||||
return
|
||||
}
|
||||
|
||||
if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Session needs to be inside a Network Node.')
|
||||
return
|
||||
}
|
||||
|
||||
if (node.payload.parentNode.payload.uiObject.isRunning !== true) {
|
||||
node.payload.uiObject.setErrorMessage('Session needs a Process Instance parent to be running.')
|
||||
return
|
||||
}
|
||||
|
||||
if (node.payload.referenceParent === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Session needs to reference a Trading System.')
|
||||
return
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -12,23 +12,21 @@ function newTaskFunctions () {
|
||||
|
||||
return thisObject
|
||||
|
||||
function runTask (node, functionLibraryProtocolNode, callBackFunction) {
|
||||
/* Check if it is possible to Run or not */
|
||||
if (node.bot === undefined) {
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
return
|
||||
}
|
||||
if (node.bot.processes.length === 0) {
|
||||
function runTask (node, functionLibraryProtocolNode, isDebugging, callBackFunction) {
|
||||
if (validations(node) !== true) {
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
return
|
||||
}
|
||||
|
||||
let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode
|
||||
let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id)
|
||||
|
||||
for (let i = 0; i < node.bot.processes.length; i++) {
|
||||
let process = node.bot.processes[i]
|
||||
process.payload.uiObject.run()
|
||||
process.payload.uiObject.run(eventsServerClient)
|
||||
}
|
||||
|
||||
let lightingPath = '->Task->' +
|
||||
let taskLightingPath = '->Task->' +
|
||||
'Sensor Bot Instance->' +
|
||||
'Indicator Bot Instance->' +
|
||||
'Trading Bot Instance->' +
|
||||
@@ -58,25 +56,48 @@ function newTaskFunctions () {
|
||||
'Trading Bot->' +
|
||||
'Data Mine->'
|
||||
|
||||
let definition = functionLibraryProtocolNode.getProtocolNode(node, false, true, true, false, false, lightingPath)
|
||||
let taskDefinition = functionLibraryProtocolNode.getProtocolNode(node, false, true, true, false, false, taskLightingPath)
|
||||
|
||||
let networkLightingPath = '->Network->Network Node->' +
|
||||
'Data Storage->Session Independent Data->Exchange Data Products->' +
|
||||
'Single Market Data->Data Product->Product Definition->' +
|
||||
'Data Mining->Testing Environment->Production Environment->' +
|
||||
'Exchange Tasks->Crypto Exchange->' +
|
||||
'Task Manager->Task->' +
|
||||
'Indicator Bot Instance->Sensor Bot Instance->Trading Bot Instance->' +
|
||||
'Indicator Process Instance->Sensor Process Instance->Trading Process Instance->' +
|
||||
'Paper Trading Session->Forward Testing Session->Backtesting Session->Live Trading Session->' +
|
||||
'Market Reference->Market->' +
|
||||
'Process Definition->'
|
||||
|
||||
let networkDefinition = functionLibraryProtocolNode.getProtocolNode(networkNode.payload.parentNode, false, true, true, false, false, networkLightingPath)
|
||||
|
||||
let event = {
|
||||
taskId: node.id,
|
||||
taskName: node.name,
|
||||
definition: JSON.stringify(definition) // <- We need to do this workaround in order no to send unescaped charactars to the taskManager.
|
||||
taskDefinition: JSON.stringify(taskDefinition),
|
||||
networkDefinition: JSON.stringify(networkDefinition)
|
||||
}
|
||||
|
||||
if (node.payload.parentNode === undefined) {
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
if (isDebugging === true) {
|
||||
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE)
|
||||
eventsServerClient.raiseEvent('Task Server', 'Debug Task Started', event)
|
||||
return
|
||||
}
|
||||
|
||||
node.payload.uiObject.run(callBackFunction)
|
||||
node.payload.uiObject.run(eventsServerClient, callBackFunction)
|
||||
eventsServerClient.raiseEvent('Task Manager', 'Run Task', event)
|
||||
}
|
||||
|
||||
function stopTask (node, functionLibraryProtocolNode, callBackFunction) {
|
||||
if (validations(node) !== true) {
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
return
|
||||
}
|
||||
|
||||
let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode
|
||||
let eventsServerClient = canvas.designSpace.workspace.eventsServerClients.get(networkNode.id)
|
||||
|
||||
let event = {
|
||||
taskId: node.id,
|
||||
taskName: node.name
|
||||
@@ -94,6 +115,60 @@ function newTaskFunctions () {
|
||||
}
|
||||
}
|
||||
|
||||
function validations (node) {
|
||||
if (node.bot === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Task needs to have a Bot Instance.')
|
||||
return
|
||||
}
|
||||
if (node.bot.processes.length === 0) {
|
||||
node.payload.uiObject.setErrorMessage('Task Bot Instance needs to have al least once Process Instance.')
|
||||
return
|
||||
}
|
||||
|
||||
if (node.payload.parentNode === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Task needs to be inside a Task Manager.')
|
||||
return
|
||||
}
|
||||
|
||||
if (node.payload.parentNode.payload.parentNode === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Task needs to be inside Exchange Tasks.')
|
||||
return
|
||||
}
|
||||
|
||||
if (node.payload.parentNode.payload.parentNode.payload.parentNode === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Task needs to be inside a Testing or Production Environment or a Data Mining node.')
|
||||
return
|
||||
}
|
||||
|
||||
if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Task needs to be inside a Network Node.')
|
||||
return
|
||||
}
|
||||
|
||||
if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Task needs to be inside a Network.')
|
||||
return
|
||||
}
|
||||
|
||||
let networkNode = node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode
|
||||
if (loadPropertyFromNodeConfig(networkNode.payload, 'host') === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Network Node needs to have a valid Host property at its config.')
|
||||
return
|
||||
}
|
||||
|
||||
if (loadPropertyFromNodeConfig(networkNode.payload, 'webPort') === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Network Node needs to have a valid webPort property at its config.')
|
||||
return
|
||||
}
|
||||
|
||||
if (loadPropertyFromNodeConfig(networkNode.payload, 'webSocketsPort') === undefined) {
|
||||
node.payload.uiObject.setErrorMessage('Network Node needs to have a valid webSocketsPort property at its config.')
|
||||
return
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
function runAllTasks (taskManager, functionLibraryProtocolNode) {
|
||||
for (let i = 0; i < taskManager.tasks.length; i++) {
|
||||
let node = taskManager.tasks[i]
|
||||
|
||||
@@ -37,7 +37,7 @@ function newUiObjectsFromNodes () {
|
||||
|
||||
for (let i = 0; i < includeDataMines.length; i++) {
|
||||
let name = includeDataMines[i]
|
||||
blobService.getBlobToText('DataMines' + '/' + name, undefined, onFileReceived, true)
|
||||
blobService.getFileFromHost('DataMines' + '/' + name, onFileReceived, true)
|
||||
function onFileReceived (err, text, response) {
|
||||
if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
|
||||
console.log('Cannot load included Data Mine ' + name + '. The workspace can not be loaded.')
|
||||
@@ -66,7 +66,7 @@ function newUiObjectsFromNodes () {
|
||||
|
||||
for (let i = 0; i < includeTradingSystems.length; i++) {
|
||||
let name = includeTradingSystems[i]
|
||||
blobService.getBlobToText('TradingSystems' + '/' + name, undefined, onFileReceived, true)
|
||||
blobService.getFileFromHost('TradingSystems' + '/' + name, onFileReceived, true)
|
||||
function onFileReceived (err, text, response) {
|
||||
if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
|
||||
console.log('Cannot load included Data Mine ' + name + '. The workspace can not be loaded.')
|
||||
@@ -95,7 +95,7 @@ function newUiObjectsFromNodes () {
|
||||
|
||||
for (let i = 0; i < includeSuperScripts.length; i++) {
|
||||
let name = includeSuperScripts[i]
|
||||
blobService.getBlobToText('SuperScripts' + '/' + name, undefined, onFileReceived, true)
|
||||
blobService.getFileFromHost('SuperScripts' + '/' + name, onFileReceived, true)
|
||||
function onFileReceived (err, text, response) {
|
||||
if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
|
||||
console.log('Cannot load included Data Mine ' + name + '. The workspace can not be loaded.')
|
||||
|
||||
@@ -10,6 +10,7 @@ function newWorkspace () {
|
||||
container: undefined,
|
||||
enabled: false,
|
||||
nodeChildren: undefined,
|
||||
eventsServerClients: new Map(),
|
||||
save: saveWorkspace,
|
||||
getHierarchyHeads: getHierarchyHeads,
|
||||
getNodeThatIsOnFocus: getNodeThatIsOnFocus,
|
||||
@@ -93,6 +94,7 @@ function newWorkspace () {
|
||||
thisObject.workspaceNode = JSON.parse(savedWorkspace)
|
||||
}
|
||||
functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode)
|
||||
setupEventsServerClients()
|
||||
thisObject.enabled = true
|
||||
|
||||
setInterval(saveWorkspace, 60000)
|
||||
@@ -101,6 +103,38 @@ function newWorkspace () {
|
||||
}
|
||||
}
|
||||
|
||||
function setupEventsServerClients () {
|
||||
for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) {
|
||||
let rootNode = thisObject.workspaceNode.rootNodes[i]
|
||||
|
||||
if (rootNode.type === 'Network') {
|
||||
for (let j = 0; j < rootNode.networkNodes.length; j++) {
|
||||
let networkNode = rootNode.networkNodes[j]
|
||||
|
||||
let host
|
||||
let webSocketsPort
|
||||
/* At this point the node does not have the payload property yet, that is why we have to do this manually */
|
||||
try {
|
||||
let code = JSON.parse(networkNode.code)
|
||||
host = code.host
|
||||
webSocketsPort = code.webSocketsPort
|
||||
} catch (err) {
|
||||
console.log('[ERROR] networkNode ' + networkNode.name + ' has an invalid configuration. Cannot know the host name and webSocketsPort.')
|
||||
return
|
||||
}
|
||||
|
||||
if (host === undefined) { host = 'localhost' }
|
||||
if (webSocketsPort === undefined) { webSocketsPort = '8080' }
|
||||
|
||||
let eventsServerClient = newEventsServerClient(host, webSocketsPort, networkNode.name)
|
||||
eventsServerClient.initialize()
|
||||
|
||||
thisObject.eventsServerClients.set(networkNode.id, eventsServerClient)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function chainDetachNode (node) {
|
||||
functionLibraryChainAttachDetach.chainDetachNode(node, thisObject.workspaceNode.rootNodes)
|
||||
}
|
||||
@@ -118,6 +152,17 @@ function newWorkspace () {
|
||||
}
|
||||
|
||||
function saveWorkspace () {
|
||||
/* When there is an exception while loading the app, the rootNodes of the workspace get into null value. To avoid saving a corrupt staate we are going to verufy we are not in that situation before saving. */
|
||||
let workspace = canvas.designSpace.workspace.workspaceNode
|
||||
|
||||
for (let i = 0; i < workspace.rootNodes.length; i++) {
|
||||
let rootNode = workspace.rootNodes[i]
|
||||
if (rootNode === null) {
|
||||
canvas.cockpitSpace.setStatus('Could not save the Workspace. The state of the workspace in memory is corrupt, please reload the App.', 150, canvas.cockpitSpace.statusTypes.WARNING)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
let savedSessionTimestamp = window.localStorage.getItem('Session Timestamp')
|
||||
if (Number(savedSessionTimestamp) !== sessionTimestamp) {
|
||||
canvas.cockpitSpace.setStatus('Could not save the Workspace. You have more that one instance of the Superlagos User Interface open at the same time. Plese close this instance as it is older than the others.', 150, canvas.cockpitSpace.statusTypes.WARNING)
|
||||
@@ -130,6 +175,19 @@ function newWorkspace () {
|
||||
}
|
||||
|
||||
function physics () {
|
||||
eventsServerClientsPhysics()
|
||||
replacingWorkspacePhysics()
|
||||
}
|
||||
|
||||
function eventsServerClientsPhysics () {
|
||||
thisObject.eventsServerClients.forEach(applyPhysics)
|
||||
|
||||
function applyPhysics (eventServerClient) {
|
||||
eventServerClient.physics()
|
||||
}
|
||||
}
|
||||
|
||||
function replacingWorkspacePhysics () {
|
||||
if (thisObject.enabled !== true) { return }
|
||||
|
||||
if (workingAtTask > 0) {
|
||||
@@ -151,6 +209,7 @@ function newWorkspace () {
|
||||
break
|
||||
case 4:
|
||||
functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode, true)
|
||||
setupEventsServerClients()
|
||||
workingAtTask++
|
||||
break
|
||||
case 5:
|
||||
@@ -358,10 +417,15 @@ function newWorkspace () {
|
||||
downloadText(fileName, text)
|
||||
}
|
||||
|
||||
break
|
||||
case 'Debug Task':
|
||||
{
|
||||
functionLibraryTaskFunctions.runTask(payload.node, functionLibraryProtocolNode, true, callBackFunction)
|
||||
}
|
||||
break
|
||||
case 'Run Task':
|
||||
{
|
||||
functionLibraryTaskFunctions.runTask(payload.node, functionLibraryProtocolNode, callBackFunction)
|
||||
functionLibraryTaskFunctions.runTask(payload.node, functionLibraryProtocolNode, false, callBackFunction)
|
||||
}
|
||||
break
|
||||
case 'Stop Task':
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
function newEventsServerClient () {
|
||||
function newEventsServerClient (host, port, hostName) {
|
||||
/* Web Sockets Connection */
|
||||
|
||||
const MODULE_NAME = 'System Event Handler'
|
||||
@@ -8,7 +8,10 @@ function newEventsServerClient () {
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
const WEB_SOCKETS_URL = 'ws://localhost:8080'
|
||||
if (host === '' || host === undefined) { host = 'localhost' }
|
||||
if (port === '' || port === undefined) { port = '8080' }
|
||||
|
||||
const WEB_SOCKETS_URL = 'ws://' + host + ':' + port + ''
|
||||
let WEB_SOCKETS_CONNECTION
|
||||
|
||||
let thisObject = {
|
||||
@@ -56,12 +59,7 @@ function newEventsServerClient () {
|
||||
responseWaiters.set(command.callerId, responseCallBack)
|
||||
}
|
||||
|
||||
if (WEB_SOCKETS_CONNECTION.readyState === 1) {
|
||||
// 1 means connected and ready.
|
||||
sendToWebSocketServer(command)
|
||||
} else {
|
||||
console.log('WebSocket message could not be sent because the connection was not ready. Message = ' + JSON.stringify(command))
|
||||
}
|
||||
sendToWebSocketServer(command)
|
||||
}
|
||||
|
||||
function sendToWebSocketServer (command) {
|
||||
@@ -72,7 +70,12 @@ function newEventsServerClient () {
|
||||
commandsSentByTimestamp.set(stringNonce, timestamp)
|
||||
|
||||
let messageToWebSocketServer = 'Web Browser' + '|*|' + stringNonce + '|*|' + JSON.stringify(command)
|
||||
WEB_SOCKETS_CONNECTION.send(messageToWebSocketServer)
|
||||
|
||||
if (WEB_SOCKETS_CONNECTION.readyState === 1) {
|
||||
WEB_SOCKETS_CONNECTION.send(messageToWebSocketServer)
|
||||
} else {
|
||||
console.log('WebSocket message could not be sent because the connection was not ready. Will retry soon. Message = ' + JSON.stringify(command))
|
||||
}
|
||||
}
|
||||
|
||||
function createEventHandler (eventHandlerName, callerId, responseCallBack) {
|
||||
@@ -153,7 +156,7 @@ function newEventsServerClient () {
|
||||
}
|
||||
|
||||
if (thisObject.isConnected() !== true) {
|
||||
canvas.cockpitSpace.setStatus('Connection with the local backend lost. Please check that all localhost servers are running.', 100, canvas.cockpitSpace.statusTypes.WARNING)
|
||||
canvas.cockpitSpace.setStatus('Connecting to ' + hostName + ' Network Node. Please wait until the connection is established.', 100, canvas.cockpitSpace.statusTypes.WARNING)
|
||||
} else {
|
||||
retryCommandsPhysics()
|
||||
}
|
||||
|
||||
@@ -22,27 +22,35 @@ function newCircularProgressBar () {
|
||||
thisObject.container.frame.position.y = 0
|
||||
|
||||
let opacityCounters = []
|
||||
|
||||
let eventSubscriptionIdHeartbeat
|
||||
|
||||
let needToDrawRing = true
|
||||
let eventsServerClient
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
|
||||
if (eventSubscriptionIdHeartbeat !== undefined) {
|
||||
eventsServerClient.stopListening(key, eventSubscriptionIdHeartbeat)
|
||||
}
|
||||
finalizeEventsServerClient()
|
||||
|
||||
thisObject.container = undefined
|
||||
thisObject.payload = undefined
|
||||
thisObject.fitFunction = undefined
|
||||
}
|
||||
|
||||
function initialize (payload) {
|
||||
function finalizeEventsServerClient () {
|
||||
if (eventsServerClient !== undefined) {
|
||||
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
|
||||
if (eventSubscriptionIdHeartbeat !== undefined) {
|
||||
eventsServerClient.stopListening(key, eventSubscriptionIdHeartbeat)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function initialize (payload, pEventsServerClient) {
|
||||
thisObject.payload = payload
|
||||
|
||||
finalizeEventsServerClient()
|
||||
eventsServerClient = pEventsServerClient
|
||||
|
||||
for (let i = 0; i < 60; i++) {
|
||||
opacityCounters.push(0)
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ function newCodeEditor () {
|
||||
|
||||
let thisObject = {
|
||||
isVisibleFunction: undefined,
|
||||
iconOK: undefined,
|
||||
iconNOT_OK: undefined,
|
||||
visible: false,
|
||||
imagePathOK: undefined,
|
||||
imagePathNOT_OK: undefined,
|
||||
@@ -41,29 +39,12 @@ function newCodeEditor () {
|
||||
function finalize () {
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
thisObject.iconOK = undefined
|
||||
thisObject.iconNOT_OK = undefined
|
||||
thisObject.payload = undefined
|
||||
thisObject.isVisibleFunction = undefined
|
||||
}
|
||||
|
||||
function initialize () {
|
||||
/* Load Images */
|
||||
|
||||
thisObject.iconOK = new Image()
|
||||
thisObject.iconOK.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
thisObject.iconNOT_OK = new Image()
|
||||
thisObject.iconNOT_OK.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
thisObject.canDrawIcon = true
|
||||
}
|
||||
thisObject.iconNOT_OK.src = window.canvasApp.urlPrefix + thisObject.imagePathNOT_OK
|
||||
}
|
||||
// thisObject.iconOK.src = window.canvasApp.urlPrefix + thisObject.imagePathOK
|
||||
// thisObject.icon = thisObject.iconOK // The default value is ON.
|
||||
}
|
||||
|
||||
function deactivate () {
|
||||
|
||||
@@ -4,14 +4,9 @@ function newConditionEditor () {
|
||||
|
||||
let thisObject = {
|
||||
isVisibleFunction: undefined,
|
||||
iconOK: undefined,
|
||||
iconNOT_OK: undefined,
|
||||
visible: false,
|
||||
imagePathOK: undefined,
|
||||
imagePathNOT_OK: undefined,
|
||||
rawRadius: undefined,
|
||||
targetRadius: undefined,
|
||||
currentRadius: undefined,
|
||||
container: undefined,
|
||||
payload: undefined,
|
||||
deactivate: deactivate,
|
||||
@@ -25,93 +20,620 @@ function newConditionEditor () {
|
||||
}
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME)
|
||||
thisObject.container.initialize(MODULE_NAME, 'Circle')
|
||||
thisObject.container.isClickeable = false
|
||||
thisObject.container.isDraggeable = false
|
||||
thisObject.container.detectMouseOver = false
|
||||
thisObject.container.frame.radius = 0
|
||||
thisObject.container.frame.position.x = 0
|
||||
thisObject.container.frame.position.y = 0
|
||||
thisObject.container.frame.radius = 750
|
||||
thisObject.container.frame.containerName = MODULE_NAME
|
||||
|
||||
let isMouseOver = false
|
||||
let conditionStructure
|
||||
let scanResult
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
thisObject.iconOK = undefined
|
||||
thisObject.iconNOT_OK = undefined
|
||||
thisObject.payload = undefined
|
||||
thisObject.isVisibleFunction = undefined
|
||||
|
||||
conditionStructure = undefined
|
||||
scanResult = undefined
|
||||
}
|
||||
|
||||
function initialize () {
|
||||
/* Load Images */
|
||||
|
||||
thisObject.iconOK = new Image()
|
||||
thisObject.iconOK.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
thisObject.iconNOT_OK = new Image()
|
||||
thisObject.iconNOT_OK.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
thisObject.canDrawIcon = true
|
||||
}
|
||||
thisObject.iconNOT_OK.src = window.canvasApp.urlPrefix + thisObject.imagePathNOT_OK
|
||||
}
|
||||
// thisObject.iconOK.src = window.canvasApp.urlPrefix + thisObject.imagePathOK
|
||||
// thisObject.icon = thisObject.iconOK // The default value is ON.
|
||||
}
|
||||
|
||||
function deactivate () {
|
||||
if (thisObject.visible === true) {
|
||||
thisObject.visible = false
|
||||
let textArea = document.getElementById('textArea')
|
||||
textArea.style.display = 'none'
|
||||
thisObject.payload.node.code = textArea.value
|
||||
}
|
||||
EDITOR_ON_FOCUS = false
|
||||
}
|
||||
|
||||
function activate (payload) {
|
||||
thisObject.visible = true
|
||||
thisObject.payload = payload
|
||||
thisObject.rawRadius = 8
|
||||
thisObject.targetRadius = thisObject.container.frame.radius
|
||||
thisObject.currentRadius = 0
|
||||
thisObject.payload.uiObject.setErrorMessage('', 0)
|
||||
|
||||
let textArea = document.getElementById('textArea')
|
||||
textArea.value = payload.node.code
|
||||
textArea.style = 'resize: none;' +
|
||||
' border: none;' +
|
||||
' outline: none;' +
|
||||
'box-shadow: none;' +
|
||||
'overflow:hidden;' +
|
||||
'font-family: ' + UI_FONT.PRIMARY + ';' +
|
||||
'font-size: 14px;' +
|
||||
'background-color: rgb(' + UI_COLOR.GREEN + ');' +
|
||||
'color:rgb(255, 255, 255);' +
|
||||
'width: ' + thisObject.container.frame.width + 'px;' +
|
||||
'height: ' + thisObject.container.frame.height + 'px'
|
||||
textArea.style.display = 'block'
|
||||
textArea.focus()
|
||||
conditionStructure = {
|
||||
code: thisObject.payload.node.code,
|
||||
orOperands: []
|
||||
}
|
||||
|
||||
scanDataMines()
|
||||
loadFromCode()
|
||||
EDITOR_ON_FOCUS = true
|
||||
}
|
||||
|
||||
function deactivate () {
|
||||
convertToCode()
|
||||
finalizePickers()
|
||||
|
||||
conditionStructure = undefined
|
||||
|
||||
if (thisObject.visible === true) {
|
||||
thisObject.visible = false
|
||||
}
|
||||
EDITOR_ON_FOCUS = false
|
||||
}
|
||||
|
||||
function loadFromCode () {
|
||||
if (thisObject.payload.node.code === undefined || thisObject.payload.node.code === '') { return }
|
||||
|
||||
/* LOGICAL ORs */
|
||||
let orArray = conditionStructure.code.split(' || ')
|
||||
for (let j = 0; j < orArray.length; j++) {
|
||||
let logicOperand = {
|
||||
code: orArray[j],
|
||||
index: j,
|
||||
comparison: {}
|
||||
}
|
||||
checkComparison(logicOperand, j)
|
||||
conditionStructure.orOperands.push(logicOperand)
|
||||
}
|
||||
|
||||
function checkComparison (logicOperand) {
|
||||
/* We are going to decompose the code into 2 comparison operators */
|
||||
logicOperand.comparison.operandA = { index: 0}
|
||||
logicOperand.comparison.operandB = { index: 1}
|
||||
|
||||
if (logicOperand.code.indexOf(' > ') > 0) {
|
||||
let codeArray = logicOperand.code.split(' > ')
|
||||
logicOperand.comparison.operandA.code = codeArray[0]
|
||||
logicOperand.comparison.operandB.code = codeArray[1]
|
||||
logicOperand.comparison.operator = ' > '
|
||||
logicOperand.comparison.operatorIndex = 0
|
||||
}
|
||||
|
||||
if (logicOperand.code.indexOf(' < ') > 0) {
|
||||
let codeArray = logicOperand.code.split(' < ')
|
||||
logicOperand.comparison.operandA.code = codeArray[0]
|
||||
logicOperand.comparison.operandB.code = codeArray[1]
|
||||
logicOperand.comparison.operator = ' < '
|
||||
logicOperand.comparison.operatorIndex = 1
|
||||
}
|
||||
|
||||
if (logicOperand.code.indexOf(' >= ') > 0) {
|
||||
let codeArray = logicOperand.code.split(' >= ')
|
||||
logicOperand.comparison.operandA.code = codeArray[0]
|
||||
logicOperand.comparison.operandB.code = codeArray[1]
|
||||
logicOperand.comparison.operator = ' >= '
|
||||
logicOperand.comparison.operatorIndex = 2
|
||||
}
|
||||
|
||||
if (logicOperand.code.indexOf(' <= ') > 0) {
|
||||
let codeArray = logicOperand.code.split(' <= ')
|
||||
logicOperand.comparison.operandA.code = codeArray[0]
|
||||
logicOperand.comparison.operandB.code = codeArray[1]
|
||||
logicOperand.comparison.operator = ' <= '
|
||||
logicOperand.comparison.operatorIndex = 3
|
||||
}
|
||||
|
||||
if (logicOperand.code.indexOf(' === ') > 0) {
|
||||
let codeArray = logicOperand.code.split(' === ')
|
||||
logicOperand.comparison.operandA.code = codeArray[0]
|
||||
logicOperand.comparison.operandB.code = codeArray[1]
|
||||
logicOperand.comparison.operator = ' === '
|
||||
logicOperand.comparison.operatorIndex = 4
|
||||
}
|
||||
|
||||
logicOperand.comparison.picker = newPicker()
|
||||
let picker = logicOperand.comparison.picker
|
||||
picker.name = 'Comparison'
|
||||
picker.container.connectToParent(thisObject.container)
|
||||
picker.container.frame.position.x = 0 - picker.container.frame.width / 2
|
||||
picker.container.frame.position.y = 0 - picker.container.frame.height / 2
|
||||
let optionsList = ['Greater Than', 'Less Than', 'Greater or Equal Than', 'Less or Equal Than', 'Equal To']
|
||||
picker.initialize(optionsList)
|
||||
|
||||
picker.eventSuscriptionId = picker.container.eventHandler.listenToEvent('onParentChanged', onParentChanged)
|
||||
|
||||
/* Each comparison code may have one or more algebraic operators */
|
||||
checkAlgebra(logicOperand, logicOperand.comparison.operandA)
|
||||
checkAlgebra(logicOperand, logicOperand.comparison.operandB)
|
||||
}
|
||||
|
||||
function checkAlgebra (logicOperand, comparisonOperand) {
|
||||
comparisonOperand.algebra = {
|
||||
operandA: { index: 0},
|
||||
operandB: { index: 1}
|
||||
}
|
||||
|
||||
/* The default situation is that there is no Algebraic operation, meaning we will setup a Algebraic operation only with operandA */
|
||||
comparisonOperand.algebra.operandA.code = comparisonOperand.code
|
||||
comparisonOperand.algebra.operandB.code = ''
|
||||
comparisonOperand.algebra.operator = ' ... '
|
||||
comparisonOperand.algebra.operatorIndex = 0
|
||||
|
||||
if (comparisonOperand.code.indexOf(' + ') > 0) {
|
||||
let codeArray = logicOperand.code.split(' + ')
|
||||
comparisonOperand.algebra.operandA.code = codeArray[0]
|
||||
comparisonOperand.algebra.operandB.code = codeArray[1]
|
||||
comparisonOperand.algebra.operator = ' + '
|
||||
comparisonOperand.algebra.operatorIndex = 1
|
||||
}
|
||||
|
||||
if (comparisonOperand.code.indexOf(' - ') > 0) {
|
||||
let codeArray = logicOperand.code.split(' - ')
|
||||
comparisonOperand.algebra.operandA.code = codeArray[0]
|
||||
comparisonOperand.algebra.operandB.code = codeArray[1]
|
||||
comparisonOperand.algebra.operator = ' - '
|
||||
comparisonOperand.algebra.operatorIndex = 2
|
||||
}
|
||||
|
||||
if (comparisonOperand.code.indexOf(' * ') > 0) {
|
||||
let codeArray = logicOperand.code.split(' * ')
|
||||
comparisonOperand.algebra.operandA.code = codeArray[0]
|
||||
comparisonOperand.algebra.operandB.code = codeArray[1]
|
||||
comparisonOperand.algebra.operator = ' * '
|
||||
comparisonOperand.algebra.operatorIndex = 3
|
||||
}
|
||||
|
||||
if (comparisonOperand.code.indexOf(' / ') > 0) {
|
||||
let codeArray = logicOperand.code.split(' / ')
|
||||
comparisonOperand.algebra.operandA.code = codeArray[0]
|
||||
comparisonOperand.algebra.operandB.code = codeArray[1]
|
||||
comparisonOperand.algebra.operator = ' / '
|
||||
comparisonOperand.algebra.operatorIndex = 4
|
||||
}
|
||||
|
||||
initializePickersSet(logicOperand, comparisonOperand, comparisonOperand.algebra.operandA)
|
||||
initializePickersSet(logicOperand, comparisonOperand, comparisonOperand.algebra.operandA)
|
||||
updatePickers(logicOperand, comparisonOperand, comparisonOperand.algebra.operandA)
|
||||
updatePickers(logicOperand, comparisonOperand, comparisonOperand.algebra.operandA)
|
||||
}
|
||||
|
||||
function initializePickersSet (logicOperand, comparisonOperand, algebraOperand) {
|
||||
/* Get the ySign */
|
||||
let ySign
|
||||
if (algebraOperand.index === 0) {
|
||||
ySign = -1
|
||||
}
|
||||
if (algebraOperand.index === 1) {
|
||||
ySign = 1
|
||||
}
|
||||
|
||||
let properties
|
||||
let parent
|
||||
let current
|
||||
|
||||
algebraOperand.whenPicker = newPicker()
|
||||
algebraOperand.whenPicker.name = 'When'
|
||||
algebraOperand.whenPicker.container.connectToParent(thisObject.container)
|
||||
algebraOperand.whenPicker.container.frame.position.x = 0 - algebraOperand.whenPicker.container.frame.width / 2 - algebraOperand.whenPicker.container.frame.width * 1.0
|
||||
algebraOperand.whenPicker.container.frame.position.y = 0 - algebraOperand.whenPicker.container.frame.height / 2 + algebraOperand.whenPicker.container.frame.height * ySign
|
||||
current = ['Current', '1 Previous', '2 Previous', '3 Previous', '4 Previous', '5 Previous']
|
||||
algebraOperand.whenPicker.initialize(current, current)
|
||||
algebraOperand.whenPicker.visible = true
|
||||
|
||||
algebraOperand.algebraicPicker = newPicker()
|
||||
algebraOperand.algebraicPicker.name = 'Algebraic'
|
||||
algebraOperand.algebraicPicker.container.connectToParent(thisObject.container)
|
||||
algebraOperand.algebraicPicker.container.frame.position.x = 0 - algebraOperand.algebraicPicker.container.frame.width / 2 + algebraOperand.algebraicPicker.container.frame.width * 3.0
|
||||
algebraOperand.algebraicPicker.container.frame.position.y = 0 - algebraOperand.algebraicPicker.container.frame.height / 2 + algebraOperand.algebraicPicker.container.frame.height * ySign
|
||||
current = ['+ - * /', 'Plus', 'Minus', 'Times', 'Divided by']
|
||||
algebraOperand.algebraicPicker.initialize(current, current)
|
||||
algebraOperand.algebraicPicker.visible = true
|
||||
|
||||
algebraOperand.dataMinePicker = newPicker()
|
||||
algebraOperand.dataMinePicker.name = 'Data Mine'
|
||||
algebraOperand.dataMinePicker.container.connectToParent(thisObject.container)
|
||||
algebraOperand.dataMinePicker.container.frame.position.x = 0 - algebraOperand.dataMinePicker.container.frame.width / 2 - algebraOperand.dataMinePicker.container.frame.width * 3.0
|
||||
algebraOperand.dataMinePicker.container.frame.position.y = 0 - algebraOperand.dataMinePicker.container.frame.height / 2 + algebraOperand.dataMinePicker.container.frame.height * ySign
|
||||
current = scanResult
|
||||
properties = Object.keys(current)
|
||||
algebraOperand.dataMinePicker.initialize(properties, current)
|
||||
parent = current
|
||||
algebraOperand.dataMinePicker.visible = true
|
||||
|
||||
algebraOperand.botPicker = newPicker()
|
||||
algebraOperand.botPicker.name = 'Bot'
|
||||
algebraOperand.botPicker.container.connectToParent(thisObject.container)
|
||||
algebraOperand.botPicker.container.frame.position.x = 0 - algebraOperand.botPicker.container.frame.width / 2 - algebraOperand.botPicker.container.frame.width * 2.0
|
||||
algebraOperand.botPicker.container.frame.position.y = 0 - algebraOperand.botPicker.container.frame.height / 2 + algebraOperand.dataMinePicker.container.frame.height * ySign
|
||||
current = parent[properties[0]]
|
||||
properties = Object.keys(current)
|
||||
algebraOperand.botPicker.initialize(properties, current, parent)
|
||||
parent = current
|
||||
algebraOperand.botPicker.visible = true
|
||||
|
||||
algebraOperand.productPicker = newPicker()
|
||||
algebraOperand.productPicker.name = 'Product'
|
||||
algebraOperand.productPicker.container.connectToParent(thisObject.container)
|
||||
algebraOperand.productPicker.container.frame.position.x = 0 - algebraOperand.productPicker.container.frame.width / 2 + algebraOperand.productPicker.container.frame.width * 0.0
|
||||
algebraOperand.productPicker.container.frame.position.y = 0 - algebraOperand.productPicker.container.frame.height / 2 + algebraOperand.dataMinePicker.container.frame.height * ySign
|
||||
current = parent[properties[0]]
|
||||
properties = Object.keys(current)
|
||||
algebraOperand.productPicker.initialize(properties, current, parent)
|
||||
parent = current
|
||||
algebraOperand.productPicker.visible = true
|
||||
|
||||
let productParent = parent
|
||||
let productProperties = properties
|
||||
|
||||
algebraOperand.propertyPicker = newPicker()
|
||||
algebraOperand.propertyPicker.name = 'Property'
|
||||
algebraOperand.propertyPicker.container.connectToParent(thisObject.container)
|
||||
algebraOperand.propertyPicker.container.frame.position.x = 0 - algebraOperand.propertyPicker.container.frame.width / 2 + algebraOperand.propertyPicker.container.frame.width * 1.0
|
||||
algebraOperand.propertyPicker.container.frame.position.y = 0 - algebraOperand.propertyPicker.container.frame.height / 2 + algebraOperand.dataMinePicker.container.frame.height * ySign
|
||||
current = productParent[productProperties[0]]
|
||||
current = current.properties
|
||||
properties = Object.keys(current)
|
||||
algebraOperand.propertyPicker.initialize(properties, current, productParent, 'properties')
|
||||
parent = current
|
||||
algebraOperand.propertyPicker.visible = true
|
||||
|
||||
algebraOperand.valuePicker = newPicker()
|
||||
algebraOperand.valuePicker.name = 'Value'
|
||||
algebraOperand.valuePicker.container.connectToParent(thisObject.container)
|
||||
algebraOperand.valuePicker.container.frame.position.x = 0 - algebraOperand.valuePicker.container.frame.width / 2
|
||||
algebraOperand.valuePicker.container.frame.position.y = 0 - algebraOperand.valuePicker.container.frame.height / 2 + algebraOperand.valuePicker.container.frame.height * 1
|
||||
current = parent[properties[0]]
|
||||
properties = current.possibleValues
|
||||
algebraOperand.valuePicker.initialize(properties, current, parent, 'possibleValues')
|
||||
parent = current
|
||||
algebraOperand.valuePicker.visible = false
|
||||
|
||||
algebraOperand.timeFramePicker = newPicker()
|
||||
algebraOperand.timeFramePicker.name = 'Time Frame'
|
||||
algebraOperand.timeFramePicker.container.connectToParent(thisObject.container)
|
||||
algebraOperand.timeFramePicker.container.frame.position.x = 0 - algebraOperand.timeFramePicker.container.frame.width / 2 + algebraOperand.timeFramePicker.container.frame.width * 2.0
|
||||
algebraOperand.timeFramePicker.container.frame.position.y = 0 - algebraOperand.timeFramePicker.container.frame.height / 2 + algebraOperand.timeFramePicker.container.frame.height * ySign
|
||||
current = productParent[productProperties[0]]
|
||||
properties = current.validTimeFrames
|
||||
algebraOperand.timeFramePicker.initialize(properties, current, productParent, 'validTimeFrames')
|
||||
parent = current
|
||||
algebraOperand.timeFramePicker.visible = true
|
||||
|
||||
algebraOperand.botPicker.eventSuscriptionId = algebraOperand.dataMinePicker.container.eventHandler.listenToEvent('onParentChanged', algebraOperand.botPicker.onParentChanged)
|
||||
algebraOperand.productPicker.eventSuscriptionId = algebraOperand.botPicker.container.eventHandler.listenToEvent('onParentChanged', algebraOperand.productPicker.onParentChanged)
|
||||
algebraOperand.propertyPicker.eventSuscriptionId = algebraOperand.productPicker.container.eventHandler.listenToEvent('onParentChanged', algebraOperand.propertyPicker.onParentChanged)
|
||||
algebraOperand.valuePicker.eventSuscriptionId = algebraOperand.propertyPicker.container.eventHandler.listenToEvent('onParentChanged', algebraOperand.valuePicker.onParentChanged)
|
||||
algebraOperand.timeFramePicker.eventSuscriptionId = algebraOperand.productPicker.container.eventHandler.listenToEvent('onParentChanged', algebraOperand.timeFramePicker.onParentChanged)
|
||||
}
|
||||
|
||||
function updatePickers (logicOperand, comparisonOperand, algebraOperand) {
|
||||
let codeArray = algebraOperand.code.split('.')
|
||||
|
||||
let codeTimeFrame = codeArray[1].substring(2, 4) + '-' + codeArray[1].substring(4, 7)
|
||||
let codeProduct = codeArray[2]
|
||||
|
||||
/* Parse When */
|
||||
let propertyDisplacement = 0
|
||||
let codeWhen = 'Current'
|
||||
if (codeArray[3] === 'previous') {
|
||||
propertyDisplacement++
|
||||
codeWhen = '1 Previous'
|
||||
}
|
||||
if (codeArray[4] === 'previous') {
|
||||
propertyDisplacement++
|
||||
codeWhen = '2 Previous'
|
||||
}
|
||||
if (codeArray[5] === 'previous') {
|
||||
propertyDisplacement++
|
||||
codeWhen = '3 Previous'
|
||||
}
|
||||
if (codeArray[6] === 'previous') {
|
||||
propertyDisplacement++
|
||||
codeWhen = '4 Previous'
|
||||
}
|
||||
if (codeArray[7] === 'previous') {
|
||||
propertyDisplacement++
|
||||
codeWhen = '5 Previous'
|
||||
}
|
||||
algebraOperand.whenPicker.setSelected(undefined, undefined, undefined, propertyDisplacement)
|
||||
|
||||
let codeProperty = codeArray[3 + propertyDisplacement]
|
||||
let codeValue = comparisonOperand.algebra.operandB.code.replace('"', '').replace('"', '')
|
||||
|
||||
let dataMines = Object.keys(scanResult)
|
||||
for (let i = 0; i < dataMines.length; i++) {
|
||||
let dataMine = dataMines[i]
|
||||
let dataMineObject = scanResult[dataMine]
|
||||
let bots = Object.keys(dataMineObject)
|
||||
for (let j = 0; j < bots.length; j++) {
|
||||
let bot = bots[j]
|
||||
let botObject = dataMineObject[bot]
|
||||
let products = Object.keys(botObject)
|
||||
for (let k = 0; k < products.length; k++) {
|
||||
let product = products[k]
|
||||
let productObject = botObject[product]
|
||||
if (codeProduct === product) {
|
||||
algebraOperand.dataMinePicker.setSelected(dataMines, scanResult, undefined, i)
|
||||
algebraOperand.botPicker.setSelected(bots, dataMineObject, scanResult, j)
|
||||
algebraOperand.productPicker.setSelected(products, botObject, dataMineObject, k)
|
||||
let properties = Object.keys(productObject.properties)
|
||||
for (let m = 0; m < properties.length; m++) {
|
||||
let property = properties[m]
|
||||
let propertyObject = productObject.properties[property]
|
||||
if (codeProperty === property) {
|
||||
algebraOperand.propertyPicker.setSelected(properties, productObject.properties, botObject, m)
|
||||
let values = propertyObject.possibleValues
|
||||
for (let n = 0; n < values.length; n++) {
|
||||
let value = values[n]
|
||||
let valueObject = propertyObject[value]
|
||||
if (codeValue === value) {
|
||||
algebraOperand.valuePicker.setSelected(values, propertyObject, productObject, n)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let timeFrames = productObject.validTimeFrames
|
||||
for (let m = 0; m < timeFrames.length; m++) {
|
||||
let timeFrame = timeFrames[m]
|
||||
let timeFrameObject = productObject.validTimeFrames[timeFrame]
|
||||
if (codeTimeFrame === timeFrame) {
|
||||
algebraOperand.timeFramePicker.setSelected(timeFrames, productObject, botObject, m)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function scanDataMines () {
|
||||
let selector = {}
|
||||
|
||||
let workspace = canvas.designSpace.workspace.workspaceNode
|
||||
|
||||
for (let i = 0; i < workspace.rootNodes.length; i++) {
|
||||
let rootNode = workspace.rootNodes[i]
|
||||
if (rootNode.type !== 'Data Mine') { continue }
|
||||
let dataMine = rootNode
|
||||
let dataMineName = loadPropertyFromNodeConfig(dataMine.payload, 'codeName')
|
||||
selector[dataMineName] = {}
|
||||
let bots = dataMine.sensorBots.concat(dataMine.indicatorBots)
|
||||
for (let j = 0; j < bots.length; j++) {
|
||||
let bot = bots[j]
|
||||
let botName = loadPropertyFromNodeConfig(bot.payload, 'codeName')
|
||||
let selectorDataMine = selector[dataMineName]
|
||||
selectorDataMine[botName] = {}
|
||||
for (let k = 0; k < bot.products.length; k++) {
|
||||
let product = bot.products[k]
|
||||
let productName = loadPropertyFromNodeConfig(product.payload, 'singularVariableName')
|
||||
if (productName === undefined) { continue }
|
||||
let selectorProduct = selectorDataMine[botName]
|
||||
selectorProduct[productName] = {
|
||||
properties: {}
|
||||
}
|
||||
if (product.record === undefined) { continue }
|
||||
for (let m = 0; m < product.record.properties.length; m++) {
|
||||
let property = product.record.properties[m]
|
||||
let propertyName = loadPropertyFromNodeConfig(property.payload, 'codeName')
|
||||
let selectorProperty = selectorProduct[productName]
|
||||
selectorProperty = selectorProperty.properties
|
||||
selectorProperty[propertyName] = {}
|
||||
let possibleValues = loadPropertyFromNodeConfig(property.payload, 'possibleValues')
|
||||
if (possibleValues === undefined) { possibleValues = [] }
|
||||
let selectorPossibleValue = selectorProperty[propertyName]
|
||||
selectorPossibleValue.possibleValues = possibleValues
|
||||
}
|
||||
let allPossibleTimeFrames = []
|
||||
for (let m = 0; m < product.datasets.length; m++) {
|
||||
let dataset = product.datasets[m]
|
||||
let validTimeFrames = loadPropertyFromNodeConfig(dataset.payload, 'validTimeFrames')
|
||||
if (validTimeFrames !== undefined) {
|
||||
allPossibleTimeFrames = allPossibleTimeFrames.concat(validTimeFrames)
|
||||
}
|
||||
}
|
||||
let selectorValidTimeFrames = selectorProduct[productName]
|
||||
selectorValidTimeFrames.validTimeFrames = allPossibleTimeFrames
|
||||
|
||||
let productKeys = Object.keys(selectorProduct[productName])
|
||||
if (productKeys.length === 0) {
|
||||
selectorProduct[productName] = undefined
|
||||
}
|
||||
}
|
||||
let botKeys = Object.keys(selectorDataMine[botName])
|
||||
if (botKeys.length === 0) {
|
||||
selectorDataMine[botName] = undefined
|
||||
}
|
||||
}
|
||||
let dataMineKeys = Object.keys(selector[dataMineName])
|
||||
if (dataMineKeys.length === 0) {
|
||||
selector[dataMineName] = undefined
|
||||
}
|
||||
}
|
||||
scanResult = JSON.parse(JSON.stringify(selector))
|
||||
}
|
||||
|
||||
function convertToCode () {
|
||||
// if (comparisonOperatorA === undefined || comparisonOperatorB === undefined || comparisonPicker === undefined) { return }
|
||||
|
||||
// chart.at01hs.bollingerSubChannel.previous.previous.slope=== "Extreme"
|
||||
/*
|
||||
let code = ''
|
||||
|
||||
code = code + 'chart.at' + comparisonOperatorA.timeFramePicker.getSelected().replace('-', '')
|
||||
code = code + '.' + comparisonOperatorA.productPicker.getSelected()
|
||||
insertWhen(comparisonOperatorA)
|
||||
code = code + '.' + comparisonOperatorA.propertyPicker.getSelected()
|
||||
|
||||
switch (comparisonPicker.getSelected()) {
|
||||
case 'Greater Than': {
|
||||
code = code + ' > '
|
||||
break
|
||||
}
|
||||
case 'Less Than': {
|
||||
code = code + ' < '
|
||||
break
|
||||
}
|
||||
case 'Greater or Equal Than': {
|
||||
code = code + ' >= '
|
||||
break
|
||||
}
|
||||
case 'Less or Equal Than': {
|
||||
code = code + ' <= '
|
||||
break
|
||||
}
|
||||
case 'Equal To': {
|
||||
code = code + ' === '
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (comparisonPicker.getSelected() === 'Equal To') {
|
||||
code = code + '"' + comparisonOperatorA.valuePicker.getSelected() + '"'
|
||||
} else {
|
||||
code = code + 'chart.at' + comparisonOperatorB.timeFramePicker.getSelected().replace('-', '')
|
||||
code = code + '.' + comparisonOperatorB.productPicker.getSelected()
|
||||
insertWhen(comparisonOperatorB)
|
||||
code = code + '.' + comparisonOperatorB.propertyPicker.getSelected()
|
||||
}
|
||||
|
||||
thisObject.payload.node.code = code
|
||||
|
||||
function insertWhen (operator) {
|
||||
switch (operator.whenPicker.getSelected()) {
|
||||
case 'Current': {
|
||||
return
|
||||
}
|
||||
case '1 Previous': {
|
||||
code = code + '.previous'
|
||||
return
|
||||
}
|
||||
case '2 Previous': {
|
||||
code = code + '.previous.previous'
|
||||
return
|
||||
}
|
||||
case '3 Previous': {
|
||||
code = code + '.previous.previous.previous'
|
||||
return
|
||||
}
|
||||
case '4 Previous': {
|
||||
code = code + '.previous.previous.previous.previous'
|
||||
return
|
||||
}
|
||||
case '5 Previous': {
|
||||
code = code + '.previous.previous.previous.previous.previous'
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
function finalizePickers () {
|
||||
if (conditionStructure === undefined) { return }
|
||||
for (let i = 0; i < conditionStructure.orOperands.length; i++) {
|
||||
let logicOperand = conditionStructure.orOperands[i]
|
||||
finalizeOperator(logicOperand.comparison.operandA.algebra.operandA)
|
||||
finalizeOperator(logicOperand.comparison.operandA.algebra.operandB)
|
||||
finalizeOperator(logicOperand.comparison.operandB.algebra.operandA)
|
||||
finalizeOperator(logicOperand.comparison.operandB.algebra.operandB)
|
||||
}
|
||||
}
|
||||
|
||||
function finalizeOperator (operand) {
|
||||
if (operand === undefined) { return }
|
||||
|
||||
if (operand.whenPicker !== undefined) {
|
||||
operand.whenPicker.finalize()
|
||||
operand.whenPicker = undefined
|
||||
}
|
||||
|
||||
if (operand.algebraicPicker !== undefined) {
|
||||
operand.algebraicPicker.finalize()
|
||||
operand.algebraicPicker = undefined
|
||||
}
|
||||
|
||||
if (operand.dataMinePicker !== undefined) {
|
||||
operand.dataMinePicker.container.eventHandler.stopListening(operand.botPicker.eventSuscriptionId)
|
||||
operand.dataMinePicker.finalize()
|
||||
operand.dataMinePicker = undefined
|
||||
}
|
||||
|
||||
if (operand.botPicker !== undefined) {
|
||||
operand.botPicker.container.eventHandler.stopListening(operand.productPicker.eventSuscriptionId)
|
||||
operand.botPicker.finalize()
|
||||
operand.botPicker = undefined
|
||||
}
|
||||
|
||||
if (operand.productPicker !== undefined) {
|
||||
operand.productPicker.container.eventHandler.stopListening(operand.propertyPicker.eventSuscriptionId)
|
||||
operand.productPicker.container.eventHandler.stopListening(operand.timeFramePicker.eventSuscriptionId)
|
||||
operand.productPicker.finalize()
|
||||
operand.productPicker = undefined
|
||||
}
|
||||
|
||||
if (operand.propertyPicker !== undefined) {
|
||||
operand.propertyPicker.container.eventHandler.stopListening(operand.valuePicker.eventSuscriptionId)
|
||||
operand.propertyPicker.finalize()
|
||||
operand.propertyPicker = undefined
|
||||
}
|
||||
|
||||
if (operand.valuePicker !== undefined) {
|
||||
operand.valuePicker.finalize()
|
||||
operand.valuePicker = undefined
|
||||
}
|
||||
|
||||
if (operand.timeFramePicker !== undefined) {
|
||||
operand.timeFramePicker.finalize()
|
||||
operand.timeFramePicker = undefined
|
||||
}
|
||||
}
|
||||
|
||||
function onParentChanged (event) {
|
||||
if (event.selected === 4) {
|
||||
// this means Equal To
|
||||
|
||||
comparisonOperatorA.valuePicker.visible = true
|
||||
comparisonOperatorB.whenPicker.visible = false
|
||||
comparisonOperatorB.algebraicPicker.visible = false
|
||||
comparisonOperatorB.dataMinePicker.visible = false
|
||||
comparisonOperatorB.botPicker.visible = false
|
||||
comparisonOperatorB.productPicker.visible = false
|
||||
comparisonOperatorB.propertyPicker.visible = false
|
||||
comparisonOperatorB.timeFramePicker.visible = false
|
||||
} else {
|
||||
comparisonOperatorA.valuePicker.visible = false
|
||||
comparisonOperatorB.whenPicker.visible = true
|
||||
comparisonOperatorB.algebraicPicker.visible = true
|
||||
comparisonOperatorB.dataMinePicker.visible = true
|
||||
comparisonOperatorB.botPicker.visible = true
|
||||
comparisonOperatorB.productPicker.visible = true
|
||||
comparisonOperatorB.propertyPicker.visible = true
|
||||
comparisonOperatorB.timeFramePicker.visible = true
|
||||
}
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
let container
|
||||
if (thisObject.visible === true) {
|
||||
if (point.x === VERY_LARGE_NUMBER) {
|
||||
/* The the mouse leaves the canvas, and event of mouse over with a ridiculous coordinate is triggered so that
|
||||
anyone can react. In our case, the code editor has a text area that is not part of the canvas, so the event is
|
||||
triggered. We compensate recognizing this coordinate and returning our container. */
|
||||
return thisObject.container
|
||||
if (conditionStructure === undefined) { return }
|
||||
|
||||
for (let i = 0; i < conditionStructure.orOperands.length; i++) {
|
||||
let logicOperand = conditionStructure.orOperands[i]
|
||||
container = operandGetContainer(point, logicOperand.comparison.operandA.algebra.operandA)
|
||||
if (container !== undefined) { return container }
|
||||
container = operandGetContainer(point, logicOperand.comparison.operandA.algebra.operandB)
|
||||
if (container !== undefined) { return container }
|
||||
container = operandGetContainer(point, logicOperand.comparison.operandB.algebra.operandA)
|
||||
if (container !== undefined) { return container }
|
||||
container = operandGetContainer(point, logicOperand.comparison.operandB.algebra.operandB)
|
||||
if (container !== undefined) { return container }
|
||||
}
|
||||
|
||||
if (thisObject.container.frame.isThisPointHere(point, true, false) === true) {
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
@@ -119,43 +641,139 @@ function newConditionEditor () {
|
||||
}
|
||||
}
|
||||
|
||||
function physics () {
|
||||
if (Math.abs(thisObject.currentRadius - thisObject.targetRadius) >= 0.5) {
|
||||
if (thisObject.currentRadius < thisObject.targetRadius) {
|
||||
thisObject.currentRadius = thisObject.currentRadius + 0.5
|
||||
} else {
|
||||
thisObject.currentRadius = thisObject.currentRadius - 0.5
|
||||
function operandGetContainer (point, operand) {
|
||||
let container
|
||||
if (operand.whenPicker !== undefined) {
|
||||
if (operand.whenPicker.visible === true) {
|
||||
container = operand.whenPicker.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
}
|
||||
}
|
||||
|
||||
thisObject.container.frame.position.x = 0
|
||||
thisObject.container.frame.position.y = 0
|
||||
|
||||
thisObject.container.frame.width = thisObject.container.frame.radius * 1.8 * 2
|
||||
thisObject.container.frame.height = thisObject.container.frame.radius * 1 * 2
|
||||
|
||||
let textAreaPosition = {
|
||||
x: 0 - thisObject.container.frame.width / 2,
|
||||
y: 0 - thisObject.container.frame.height * 3 / 7 + CURRENT_TOP_MARGIN
|
||||
}
|
||||
|
||||
textAreaPosition = thisObject.container.frame.frameThisPoint(textAreaPosition)
|
||||
if (thisObject.visible === true) {
|
||||
let checkPosition = {
|
||||
x: textAreaPosition.x,
|
||||
y: textAreaPosition.y - CURRENT_TOP_MARGIN
|
||||
}
|
||||
if (thisObject.isVisibleFunction(checkPosition) === false) {
|
||||
deactivate()
|
||||
if (operand.algebraicPicker !== undefined) {
|
||||
if (operand.algebraicPicker.visible === true) {
|
||||
container = operand.algebraicPicker.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
}
|
||||
}
|
||||
if (thisObject.visible === true) {
|
||||
let textAreaDiv = document.getElementById('textAreaDiv')
|
||||
textAreaDiv.style = 'position:fixed; top:' + textAreaPosition.y + 'px; left:' + textAreaPosition.x + 'px; z-index:1; '
|
||||
|
||||
if (operand.dataMinePicker !== undefined) {
|
||||
if (operand.dataMinePicker.visible === true) {
|
||||
container = operand.dataMinePicker.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.botPicker !== undefined) {
|
||||
if (operand.botPicker.visible === true) {
|
||||
container = operand.botPicker.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.productPicker !== undefined) {
|
||||
if (operand.productPicker.visible === true) {
|
||||
container = operand.productPicker.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.propertyPicker !== undefined) {
|
||||
if (operand.propertyPicker.visible === true) {
|
||||
container = operand.propertyPicker.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.valuePicker !== undefined) {
|
||||
if (operand.valuePicker.visible === true) {
|
||||
container = operand.valuePicker.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.timeFramePicker !== undefined) {
|
||||
if (operand.timeFramePicker.visible === true) {
|
||||
container = operand.timeFramePicker.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function physics () {
|
||||
|
||||
}
|
||||
|
||||
function drawBackground () {
|
||||
thisObjectDrawBackground()
|
||||
childrenDrawBackground()
|
||||
}
|
||||
|
||||
function childrenDrawBackground () {
|
||||
if (conditionStructure === undefined) { return }
|
||||
|
||||
for (let i = 0; i < conditionStructure.orOperands.length; i++) {
|
||||
let logicOperand = conditionStructure.orOperands[i]
|
||||
operandDrawBackground(logicOperand.comparison.operandA.algebra.operandA)
|
||||
operandDrawBackground(logicOperand.comparison.operandA.algebra.operandB)
|
||||
operandDrawBackground(logicOperand.comparison.operandB.algebra.operandA)
|
||||
operandDrawBackground(logicOperand.comparison.operandB.algebra.operandB)
|
||||
}
|
||||
}
|
||||
|
||||
function operandDrawBackground (operand) {
|
||||
if (operand === undefined) { return }
|
||||
|
||||
if (operand.whenPicker !== undefined) {
|
||||
if (operand.whenPicker.visible === true) {
|
||||
operand.whenPicker.drawBackground()
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.algebraicPicker !== undefined) {
|
||||
if (operand.algebraicPicker.visible === true) {
|
||||
operand.algebraicPicker.drawBackground()
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.dataMinePicker !== undefined) {
|
||||
if (operand.dataMinePicker.visible === true) {
|
||||
operand.dataMinePicker.drawBackground()
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.botPicker !== undefined) {
|
||||
if (operand.botPicker.visible === true) {
|
||||
operand.botPicker.drawBackground()
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.productPicker !== undefined) {
|
||||
if (operand.productPicker.visible === true) {
|
||||
operand.productPicker.drawBackground()
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.propertyPicker !== undefined) {
|
||||
if (operand.propertyPicker.visible === true) {
|
||||
operand.propertyPicker.drawBackground()
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.valuePicker !== undefined) {
|
||||
if (operand.valuePicker.visible === true) {
|
||||
operand.valuePicker.drawBackground()
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.timeFramePicker !== undefined) {
|
||||
if (operand.timeFramePicker.visible === true) {
|
||||
operand.timeFramePicker.drawBackground()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function thisObjectDrawBackground () {
|
||||
if (thisObject.visible === true) {
|
||||
let position = {
|
||||
x: 0,
|
||||
@@ -164,54 +782,92 @@ function newConditionEditor () {
|
||||
|
||||
position = thisObject.container.frame.frameThisPoint(position)
|
||||
|
||||
let radius = thisObject.container.frame.radius * 2
|
||||
let radius = thisObject.container.frame.radius
|
||||
|
||||
if (radius > 0.5) {
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(position.x, position.y, radius * 1.3 + 3, 0, Math.PI * 2, true)
|
||||
browserCanvasContext.closePath()
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')'
|
||||
browserCanvasContext.fill()
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(position.x, position.y, radius + 3, 0, Math.PI * 2, true)
|
||||
browserCanvasContext.closePath()
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')'
|
||||
browserCanvasContext.fill()
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(position.x, position.y, radius * 1.3, 0, Math.PI * 2, true)
|
||||
browserCanvasContext.closePath()
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + 1 + ')'
|
||||
browserCanvasContext.fill()
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(position.x, position.y, radius, 0, Math.PI * 2, true)
|
||||
browserCanvasContext.closePath()
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREY + ', ' + 1 + ')'
|
||||
browserCanvasContext.fill()
|
||||
}
|
||||
}
|
||||
|
||||
function drawForeground () {
|
||||
thisObjectDrawForeground()
|
||||
childrenDrawForeground()
|
||||
}
|
||||
|
||||
function childrenDrawForeground () {
|
||||
if (conditionStructure === undefined) { return }
|
||||
|
||||
for (let i = 0; i < conditionStructure.orOperands.length; i++) {
|
||||
let logicOperand = conditionStructure.orOperands[i]
|
||||
operandDrawForeground(logicOperand.comparison.operandA.algebra.operandA)
|
||||
operandDrawForeground(logicOperand.comparison.operandA.algebra.operandB)
|
||||
operandDrawForeground(logicOperand.comparison.operandB.algebra.operandA)
|
||||
operandDrawForeground(logicOperand.comparison.operandB.algebra.operandB)
|
||||
}
|
||||
}
|
||||
|
||||
function operandDrawForeground (operand) {
|
||||
if (operand === undefined) { return }
|
||||
|
||||
if (operand.whenPicker !== undefined) {
|
||||
if (operand.whenPicker.visible === true) {
|
||||
operand.whenPicker.drawForeground()
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.algebraicPicker !== undefined) {
|
||||
if (operand.algebraicPicker.visible === true) {
|
||||
operand.algebraicPicker.drawForeground()
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.dataMinePicker !== undefined) {
|
||||
if (operand.dataMinePicker.visible === true) {
|
||||
operand.dataMinePicker.drawForeground()
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.botPicker !== undefined) {
|
||||
if (operand.botPicker.visible === true) {
|
||||
operand.botPicker.drawForeground()
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.productPicker !== undefined) {
|
||||
if (operand.productPicker.visible === true) {
|
||||
operand.productPicker.drawForeground()
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.propertyPicker !== undefined) {
|
||||
if (operand.propertyPicker.visible === true) {
|
||||
operand.propertyPicker.drawForeground()
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.valuePicker !== undefined) {
|
||||
if (operand.valuePicker.visible === true) {
|
||||
operand.valuePicker.drawForeground()
|
||||
}
|
||||
}
|
||||
|
||||
if (operand.timeFramePicker !== undefined) {
|
||||
if (operand.timeFramePicker.visible === true) {
|
||||
operand.timeFramePicker.drawForeground()
|
||||
}
|
||||
}
|
||||
}
|
||||
function drawForeground () {
|
||||
let iconPosition = {
|
||||
x: 0,
|
||||
y: thisObject.currentRadius * 1.5
|
||||
}
|
||||
|
||||
iconPosition = thisObject.container.frame.frameThisPoint(iconPosition)
|
||||
function thisObjectDrawForeground () {
|
||||
|
||||
/* Menu Item */
|
||||
|
||||
if (thisObject.canDrawIcon === true && thisObject.currentRadius > 1) {
|
||||
browserCanvasContext.drawImage(thisObject.icon, iconPosition.x - thisObject.currentRadius, iconPosition.y - thisObject.currentRadius, thisObject.currentRadius * 2, thisObject.currentRadius * 2)
|
||||
|
||||
/* Menu Label */
|
||||
|
||||
let label = 'Code looks good!'
|
||||
let labelPoint
|
||||
let fontSize = 10
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
|
||||
if (label !== undefined && thisObject.currentRadius >= thisObject.targetRadius) {
|
||||
labelPoint = {
|
||||
x: iconPosition.x + thisObject.currentRadius + 10,
|
||||
y: iconPosition.y + fontSize * FONT_ASPECT_RATIO
|
||||
}
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,6 @@ function newConfigEditor () {
|
||||
|
||||
let thisObject = {
|
||||
isVisibleFunction: undefined,
|
||||
iconOK: undefined,
|
||||
iconNOT_OK: undefined,
|
||||
visible: false,
|
||||
imagePathOK: undefined,
|
||||
imagePathNOT_OK: undefined,
|
||||
@@ -41,29 +39,12 @@ function newConfigEditor () {
|
||||
function finalize () {
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
thisObject.iconOK = undefined
|
||||
thisObject.iconNOT_OK = undefined
|
||||
thisObject.payload = undefined
|
||||
thisObject.isVisibleFunction = undefined
|
||||
}
|
||||
|
||||
function initialize () {
|
||||
/* Load Images */
|
||||
|
||||
thisObject.iconOK = new Image()
|
||||
thisObject.iconOK.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
thisObject.iconNOT_OK = new Image()
|
||||
thisObject.iconNOT_OK.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
thisObject.canDrawIcon = true
|
||||
}
|
||||
thisObject.iconNOT_OK.src = window.canvasApp.urlPrefix + thisObject.imagePathNOT_OK
|
||||
}
|
||||
// thisObject.iconOK.src = window.canvasApp.urlPrefix + thisObject.imagePathOK
|
||||
// thisObject.icon = thisObject.iconOK // The default value is ON.
|
||||
}
|
||||
|
||||
function deactivate () {
|
||||
|
||||
@@ -4,8 +4,6 @@ function newFormulaEditor () {
|
||||
|
||||
let thisObject = {
|
||||
isVisibleFunction: undefined,
|
||||
iconOK: undefined,
|
||||
iconNOT_OK: undefined,
|
||||
visible: false,
|
||||
imagePathOK: undefined,
|
||||
imagePathNOT_OK: undefined,
|
||||
@@ -41,29 +39,12 @@ function newFormulaEditor () {
|
||||
function finalize () {
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
thisObject.iconOK = undefined
|
||||
thisObject.iconNOT_OK = undefined
|
||||
thisObject.payload = undefined
|
||||
thisObject.isVisibleFunction = undefined
|
||||
}
|
||||
|
||||
function initialize () {
|
||||
/* Load Images */
|
||||
|
||||
thisObject.iconOK = new Image()
|
||||
thisObject.iconOK.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
thisObject.iconNOT_OK = new Image()
|
||||
thisObject.iconNOT_OK.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
thisObject.canDrawIcon = true
|
||||
}
|
||||
thisObject.iconNOT_OK.src = window.canvasApp.urlPrefix + thisObject.imagePathNOT_OK
|
||||
}
|
||||
// thisObject.iconOK.src = window.canvasApp.urlPrefix + thisObject.imagePathOK
|
||||
// thisObject.icon = thisObject.iconOK // The default value is ON.
|
||||
}
|
||||
|
||||
function deactivate () {
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
|
||||
function newPicker () {
|
||||
const MODULE_NAME = 'Picker'
|
||||
|
||||
let thisObject = {
|
||||
container: undefined,
|
||||
selectedItem: 0,
|
||||
onParentChanged: onParentChanged,
|
||||
getSelected: getSelected,
|
||||
setSelected: setSelected,
|
||||
physics: physics,
|
||||
drawBackground: drawBackground,
|
||||
drawForeground: drawForeground,
|
||||
getContainer: getContainer,
|
||||
finalize: finalize,
|
||||
initialize: initialize
|
||||
}
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME)
|
||||
thisObject.container.isClickeable = false
|
||||
thisObject.container.isDraggeable = false
|
||||
thisObject.container.isWheelable = true
|
||||
thisObject.container.detectMouseOver = true
|
||||
thisObject.container.frame.radius = 0
|
||||
thisObject.container.frame.position.x = 0
|
||||
thisObject.container.frame.position.y = 0
|
||||
thisObject.container.frame.width = 200
|
||||
thisObject.container.frame.height = 120
|
||||
|
||||
let isMouseOver
|
||||
let optionsList
|
||||
let parent
|
||||
let current
|
||||
let parentSelected = 0
|
||||
let propertyName
|
||||
let selected = 0
|
||||
let lastSelected = 0
|
||||
let onMouseWheelEventSubscriptionId
|
||||
let onMouseOverEventSubscriptionId
|
||||
let onMouseNotOverEventSubscriptionId
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
thisObject.container.eventHandler.stopListening(onMouseWheelEventSubscriptionId)
|
||||
thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId)
|
||||
thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId)
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
optionsList = undefined
|
||||
parent = undefined
|
||||
current = undefined
|
||||
}
|
||||
|
||||
function initialize (pOptionsList, pCurrent, pParent, pPropertyName) {
|
||||
optionsList = pOptionsList
|
||||
current = pCurrent
|
||||
parent = pParent
|
||||
propertyName = pPropertyName
|
||||
onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
|
||||
onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
|
||||
onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
|
||||
}
|
||||
|
||||
function onMouseOver (event) {
|
||||
isMouseOver = true
|
||||
}
|
||||
|
||||
function onMouseNotOver () {
|
||||
isMouseOver = false
|
||||
}
|
||||
|
||||
function getSelected () {
|
||||
return optionsList[selected]
|
||||
}
|
||||
|
||||
function setSelected (pOptionsList, pCurrent, pParent, pSelected) {
|
||||
if (pOptionsList !== undefined) {
|
||||
optionsList = pOptionsList
|
||||
}
|
||||
if (pCurrent !== undefined) {
|
||||
current = pCurrent
|
||||
}
|
||||
if (pParent !== undefined) {
|
||||
parent = pParent
|
||||
}
|
||||
if (pSelected !== undefined) {
|
||||
selected = pSelected
|
||||
}
|
||||
raiseEventParentChanged()
|
||||
}
|
||||
|
||||
function onParentChanged (event) {
|
||||
if (event.parent !== undefined) {
|
||||
parent = event.parent
|
||||
}
|
||||
parentSelected = event.selected
|
||||
|
||||
selected = 0
|
||||
let parentKeys
|
||||
|
||||
parentKeys = Object.keys(parent)
|
||||
checkPropertyName()
|
||||
|
||||
function checkPropertyName () {
|
||||
if (propertyName === undefined) {
|
||||
current = parent[parentKeys[parentSelected]]
|
||||
checkArray()
|
||||
} else {
|
||||
current = parent[parentKeys[parentSelected]]
|
||||
current = current[propertyName]
|
||||
checkArray()
|
||||
}
|
||||
}
|
||||
|
||||
function checkArray () {
|
||||
if (Array.isArray(current) === false) {
|
||||
optionsList = Object.keys(current)
|
||||
} else {
|
||||
optionsList = current
|
||||
}
|
||||
}
|
||||
|
||||
raiseEventParentChanged()
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
let container
|
||||
|
||||
if (thisObject.container.frame.isThisPointHere(point, true, false) === true) {
|
||||
return thisObject.container
|
||||
}
|
||||
}
|
||||
|
||||
function getSelected () {
|
||||
return optionsList[selected]
|
||||
}
|
||||
|
||||
function onMouseWheel () {
|
||||
delta = event.wheelDelta
|
||||
if (delta > 0) {
|
||||
delta = -1
|
||||
} else {
|
||||
delta = 1
|
||||
}
|
||||
|
||||
selected = selected + delta
|
||||
if (selected < 0) { selected = 0 }
|
||||
if (selected > optionsList.length - 1) {
|
||||
selected = optionsList.length - 1
|
||||
}
|
||||
|
||||
if (selected !== lastSelected) {
|
||||
lastSelected = selected
|
||||
raiseEventParentChanged()
|
||||
}
|
||||
}
|
||||
|
||||
function raiseEventParentChanged () {
|
||||
let event = {
|
||||
selected: selected,
|
||||
parent: current,
|
||||
propertyName: propertyName
|
||||
}
|
||||
thisObject.container.eventHandler.raiseEvent('onParentChanged', event)
|
||||
}
|
||||
|
||||
function physics () {
|
||||
|
||||
}
|
||||
|
||||
function drawBackground () {
|
||||
|
||||
}
|
||||
|
||||
function drawForeground () {
|
||||
const FONT_SIZE = 20
|
||||
const VISIBLE_LABELS = 5
|
||||
let fontSize
|
||||
let fontColor
|
||||
let opacity
|
||||
|
||||
for (let i = 0; i < VISIBLE_LABELS; i++) {
|
||||
let index = i - 2 + selected
|
||||
let label = ''
|
||||
if (index >= 0 && index < optionsList.length) {
|
||||
label = optionsList[index]
|
||||
}
|
||||
fontColor = UI_COLOR.LIGHT_GREY
|
||||
switch (i) {
|
||||
case 0:
|
||||
fontSize = FONT_SIZE - 10
|
||||
opacity = 0.4
|
||||
break
|
||||
case 1:
|
||||
fontSize = FONT_SIZE - 5
|
||||
opacity = 0.5
|
||||
break
|
||||
case 2:
|
||||
fontSize = FONT_SIZE - 0
|
||||
fontColor = UI_COLOR.BLACK
|
||||
opacity = 1
|
||||
break
|
||||
case 3:
|
||||
fontSize = FONT_SIZE - 5
|
||||
opacity = 0.5
|
||||
break
|
||||
case 4:
|
||||
fontSize = FONT_SIZE - 10
|
||||
opacity = 0.4
|
||||
break
|
||||
}
|
||||
|
||||
if (i === 2 || isMouseOver === true) {
|
||||
drawLabel(label, 1 / 2, i / VISIBLE_LABELS, 0, 0, fontSize, thisObject.container, fontColor, undefined, undefined, opacity)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,17 +117,12 @@ function newUiObject () {
|
||||
let referenceLineCounter = 0
|
||||
let chainLineCounter = 0
|
||||
|
||||
let eventsServerClient
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
|
||||
|
||||
if (eventSubscriptionIdOnRunning !== undefined) {
|
||||
eventsServerClient.stopListening(key, eventSubscriptionIdOnRunning, 'UiObject')
|
||||
}
|
||||
if (eventSubscriptionIdOnStopped !== undefined) {
|
||||
eventsServerClient.stopListening(key, eventSubscriptionIdOnStopped, 'UiObject')
|
||||
}
|
||||
finalizeEventsServerClient()
|
||||
|
||||
thisObject.container.eventHandler.stopListening(selfFocusEventSubscriptionId)
|
||||
thisObject.container.eventHandler.stopListening(selfNotFocusEventSubscriptionId)
|
||||
@@ -173,6 +168,19 @@ function newUiObject () {
|
||||
onRunningCallBackFunction = undefined
|
||||
}
|
||||
|
||||
function finalizeEventsServerClient () {
|
||||
if (eventsServerClient !== undefined) {
|
||||
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
|
||||
|
||||
if (eventSubscriptionIdOnRunning !== undefined) {
|
||||
eventsServerClient.stopListening(key, eventSubscriptionIdOnRunning, 'UiObject')
|
||||
}
|
||||
if (eventSubscriptionIdOnStopped !== undefined) {
|
||||
eventsServerClient.stopListening(key, eventSubscriptionIdOnStopped, 'UiObject')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function initialize (payload, menuItemsInitialValues) {
|
||||
thisObject.payload = payload
|
||||
|
||||
@@ -257,7 +265,7 @@ function newUiObject () {
|
||||
if (container !== undefined) { return container }
|
||||
}
|
||||
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
if (thisObject.container.frame.isThisPointHere(point, true, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
@@ -750,14 +758,17 @@ function newUiObject () {
|
||||
}
|
||||
}
|
||||
|
||||
function run (callBackFunction) {
|
||||
function run (pEventsServerClient, callBackFunction) {
|
||||
finalizeEventsServerClient()
|
||||
eventsServerClient = pEventsServerClient
|
||||
|
||||
/* We setup the circular progress bar. */
|
||||
if (thisObject.circularProgressBar !== undefined) {
|
||||
thisObject.circularProgressBar.finalize()
|
||||
}
|
||||
|
||||
thisObject.circularProgressBar = newCircularProgressBar()
|
||||
thisObject.circularProgressBar.initialize(thisObject.payload)
|
||||
thisObject.circularProgressBar.initialize(thisObject.payload, eventsServerClient)
|
||||
thisObject.circularProgressBar.fitFunction = thisObject.fitFunction
|
||||
thisObject.circularProgressBar.container = thisObject.container
|
||||
|
||||
@@ -1413,7 +1424,7 @@ function newUiObject () {
|
||||
let label
|
||||
|
||||
if (radius > 6) {
|
||||
const MAX_LABEL_LENGTH = 65
|
||||
const MAX_LABEL_LENGTH = 100
|
||||
|
||||
label = currentStatus
|
||||
|
||||
|
||||
@@ -157,6 +157,17 @@ function newUiObjectConstructor () {
|
||||
}
|
||||
}
|
||||
|
||||
/* Default Values in case there was no way to set a value previous to this. */
|
||||
if (floatingObject.angleToParent === undefined) {
|
||||
floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_360
|
||||
}
|
||||
if (floatingObject.distanceToParent === undefined) {
|
||||
floatingObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_100X
|
||||
}
|
||||
if (floatingObject.arrangementStyle === undefined) {
|
||||
floatingObject.arrangementStyle = ARRANGEMENT_STYLE.CONCAVE
|
||||
}
|
||||
|
||||
let uiObject = newUiObject()
|
||||
payload.uiObject = uiObject
|
||||
uiObject.fitFunction = canvas.floatingSpace.fitIntoVisibleArea
|
||||
@@ -243,7 +254,7 @@ function newUiObjectConstructor () {
|
||||
)
|
||||
menuItemsInitialValues.push(
|
||||
{
|
||||
action: 'change Distance to Paarent',
|
||||
action: 'Change Distance to Paarent',
|
||||
actionFunction: floatingObject.distanceToParentToggle,
|
||||
actionStatus: floatingObject.getDistanceToParent,
|
||||
currentStatus: true,
|
||||
@@ -258,7 +269,7 @@ function newUiObjectConstructor () {
|
||||
)
|
||||
menuItemsInitialValues.push(
|
||||
{
|
||||
action: 'change Arrangement Style',
|
||||
action: 'Change Arrangement Style',
|
||||
actionFunction: floatingObject.arrangementStyleToggle,
|
||||
actionStatus: floatingObject.getArrangementStyle,
|
||||
currentStatus: true,
|
||||
@@ -401,26 +412,26 @@ function newUiObjectConstructor () {
|
||||
if (nodeDefinition.editors.config === true) {
|
||||
uiObject.configEditor = newConfigEditor()
|
||||
uiObject.configEditor.isVisibleFunction = uiObject.isVisibleFunction
|
||||
uiObject.configEditor.initialize()
|
||||
uiObject.configEditor.container.connectToParent(uiObject.container, false, false, true, true, false, false, false, false)
|
||||
uiObject.configEditor.initialize()
|
||||
}
|
||||
if (nodeDefinition.editors.code === true) {
|
||||
uiObject.codeEditor = newCodeEditor()
|
||||
uiObject.codeEditor.isVisibleFunction = uiObject.isVisibleFunction
|
||||
uiObject.codeEditor.initialize()
|
||||
uiObject.codeEditor.container.connectToParent(uiObject.container, false, false, true, true, false, false, false, false)
|
||||
uiObject.codeEditor.initialize()
|
||||
}
|
||||
if (nodeDefinition.editors.formula === true) {
|
||||
uiObject.formulaEditor = newFormulaEditor()
|
||||
uiObject.formulaEditor.isVisibleFunction = uiObject.isVisibleFunction
|
||||
uiObject.formulaEditor.initialize()
|
||||
uiObject.formulaEditor.container.connectToParent(uiObject.container, false, false, true, true, false, false, false, false)
|
||||
uiObject.formulaEditor.initialize()
|
||||
}
|
||||
if (nodeDefinition.editors.condition === true) {
|
||||
uiObject.conditionEditor = newConditionEditor()
|
||||
uiObject.conditionEditor.isVisibleFunction = uiObject.isVisibleFunction
|
||||
uiObject.conditionEditor.container.connectToParent(uiObject.container, false, false, false, true, false, false, false, false)
|
||||
uiObject.conditionEditor.initialize()
|
||||
uiObject.conditionEditor.container.connectToParent(uiObject.container, false, false, true, true, false, false, false, false)
|
||||
}
|
||||
}
|
||||
if (nodeDefinition.addLeftIcons === true) {
|
||||
|
||||
+1
-1
@@ -211,7 +211,7 @@ function newFrame () {
|
||||
/* Now we check if the resulting point is whin the current Frame. */
|
||||
if (isNaN(checkPoint.x) || isNaN(checkPoint.y)) { return false }
|
||||
if (thisObject.type === 'Circle') {
|
||||
let distance = Math.sqrt(Math.pow(thisObject.position.x - point.x, 2) + Math.pow(thisObject.position.y - point.y, 2))
|
||||
let distance = Math.sqrt(Math.pow(thisObject.position.x - checkPoint.x, 2) + Math.pow(thisObject.position.y - checkPoint.y, 2))
|
||||
|
||||
if (distance < thisObject.radius) {
|
||||
return true
|
||||
|
||||
@@ -20,6 +20,7 @@ function newLayer () {
|
||||
plotterTypeIcon: undefined,
|
||||
baseAssetIcon: undefined,
|
||||
quotedAssetIcon: undefined,
|
||||
networkNode: undefined,
|
||||
checkStatusAtShutDown: checkStatusAtShutDown,
|
||||
physics: physics,
|
||||
draw: draw,
|
||||
@@ -128,6 +129,7 @@ function newLayer () {
|
||||
thisObject.plotterTypeIcon = undefined
|
||||
thisObject.baseAssetIcon = undefined
|
||||
thisObject.quotedAssetIcon = undefined
|
||||
thisObject.networkNode = undefined
|
||||
}
|
||||
|
||||
function initialize (callBackFunction) {
|
||||
@@ -151,9 +153,10 @@ function newLayer () {
|
||||
let functionLibraryProtocolNode = newProtocolNode()
|
||||
let lightingPath =
|
||||
'->Layer->' +
|
||||
'Data Product->Single Market Data->' +
|
||||
'Session Independent Data->Session Based Data->' +
|
||||
'Session Reference->Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' +
|
||||
'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->' +
|
||||
'Market->Market Base Asset->Asset->' +
|
||||
'Market Quoted Asset->Asset->' +
|
||||
'Exchange Markets->Crypto Exchange->' +
|
||||
@@ -186,6 +189,10 @@ function newLayer () {
|
||||
if (thisObject.definition.referenceParent.referenceParent === undefined) { return }
|
||||
if (thisObject.definition.referenceParent.referenceParent.parentNode === undefined) { return }
|
||||
if (thisObject.definition.referenceParent.referenceParent.parentNode.parentNode === undefined) { return }
|
||||
if (thisObject.definition.referenceParent.parentNode.parentNode === undefined) { return }
|
||||
if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode === undefined) { return }
|
||||
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 */
|
||||
onMouseClickEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
|
||||
@@ -226,6 +233,12 @@ function newLayer () {
|
||||
thisObject.baseAssetIcon = getIcon(thisObject.baseAsset)
|
||||
thisObject.quotedAssetIcon = getIcon(thisObject.quotedAsset)
|
||||
|
||||
if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.type === 'Data Storage') {
|
||||
thisObject.networkNode = thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode
|
||||
} else {
|
||||
thisObject.networkNode = thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode
|
||||
}
|
||||
|
||||
function getIcon (node) {
|
||||
let nodeDefinition = APP_SCHEMA_MAP.get(node.type)
|
||||
let iconName
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
let canvas
|
||||
let markets
|
||||
let eventsServerClient
|
||||
|
||||
let APP_SCHEMA_MAP = new Map()
|
||||
let APP_SCHEMA_ARRAY = []
|
||||
@@ -23,9 +22,7 @@ function newDashboard () {
|
||||
function start () {
|
||||
try {
|
||||
setBrowserEvents()
|
||||
|
||||
eventsServerClient = newEventsServerClient()
|
||||
eventsServerClient.initialize(setUpAppSchema)
|
||||
setUpAppSchema()
|
||||
|
||||
function setUpAppSchema () {
|
||||
APP_SCHEMA_ARRAY = getAppSchema()
|
||||
|
||||
@@ -74,7 +74,7 @@ function newProductStorage (name) {
|
||||
}
|
||||
}
|
||||
|
||||
function initialize (dataMine, bot, session, product, exchange, market, pDatetime, pTimeFrame, callBackFunction) {
|
||||
function initialize (dataMine, bot, session, product, exchange, market, pDatetime, pTimeFrame, host, port, eventsServerClient, callBackFunction) {
|
||||
try {
|
||||
datetime = pDatetime
|
||||
timeFrame = pTimeFrame
|
||||
@@ -90,7 +90,7 @@ function newProductStorage (name) {
|
||||
dataSetsToLoad++
|
||||
|
||||
let marketFiles = newMarketFiles()
|
||||
marketFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, onMarketFileReady)
|
||||
marketFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, eventsServerClient, onMarketFileReady)
|
||||
thisObject.marketFiles.push(marketFiles)
|
||||
}
|
||||
break
|
||||
@@ -99,7 +99,7 @@ function newProductStorage (name) {
|
||||
dataSetsToLoad++
|
||||
|
||||
let dailyFiles = newDailyFiles()
|
||||
dailyFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, pDatetime, pTimeFrame, onDailyFileReady)
|
||||
dailyFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, pDatetime, pTimeFrame, host, port, eventsServerClient, onDailyFileReady)
|
||||
thisObject.dailyFiles.push(dailyFiles)
|
||||
}
|
||||
break
|
||||
@@ -108,7 +108,7 @@ function newProductStorage (name) {
|
||||
dataSetsToLoad++
|
||||
|
||||
let singleFile = newSingleFile()
|
||||
singleFile.initialize(dataMine, bot, session, product, dataset, exchange, market, onSingleFileReady)
|
||||
singleFile.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, eventsServerClient, onSingleFileReady)
|
||||
thisObject.singleFile.push(singleFile)
|
||||
}
|
||||
break
|
||||
@@ -117,7 +117,7 @@ function newProductStorage (name) {
|
||||
dataSetsToLoad++
|
||||
|
||||
let fileSequences = newFileSequence()
|
||||
fileSequences.initialize(dataMine, bot, session, product, dataset, exchange, market, onFileSequenceReady)
|
||||
fileSequences.initialize(dataMine, bot, session, product, dataset, exchange, market, host, port, eventsServerClient, onFileSequenceReady)
|
||||
thisObject.fileSequences.push(fileSequences)
|
||||
}
|
||||
break
|
||||
|
||||
@@ -122,7 +122,7 @@ function newSplashScreen () {
|
||||
|
||||
fontSize = 35
|
||||
|
||||
title = 'Beta'
|
||||
title = 'Beta 4'
|
||||
|
||||
titlePoint = {
|
||||
x: thisObject.container.frame.width / 2 - title.length / 2 * fontSize * FONT_ASPECT_RATIO - 20,
|
||||
|
||||
@@ -105,10 +105,11 @@ function roundedCornersBackground (params) {
|
||||
browserCanvasContext.stroke()
|
||||
}
|
||||
|
||||
function drawLabel (label, xFactor, yFactor, xOffset, yOffset, fontSize, container, fontColor, noFrameX, noFrameY) {
|
||||
function drawLabel (label, xFactor, yFactor, xOffset, yOffset, fontSize, container, fontColor, noFrameX, noFrameY, opacity) {
|
||||
if (label === undefined) { return }
|
||||
if (fontColor === undefined) { fontColor = UI_COLOR.WHITE }
|
||||
let fontOffset = label.length * fontSize * FONT_ASPECT_RATIO + 10
|
||||
if (opacity === undefined) { opacity = 1 }
|
||||
|
||||
let labelPoint = {
|
||||
x: container.frame.width * xFactor + xOffset - fontOffset / 2,
|
||||
@@ -126,7 +127,7 @@ function drawLabel (label, xFactor, yFactor, xOffset, yOffset, fontSize, contain
|
||||
}
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(' + fontColor + ', 1)'
|
||||
browserCanvasContext.fillStyle = 'rgba(' + fontColor + ', ' + opacity + ')'
|
||||
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
}
|
||||
|
||||
@@ -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","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
|
||||
@@ -45,14 +45,14 @@ function newDailyFiles () {
|
||||
}
|
||||
}
|
||||
|
||||
function initialize (pDataMine, pBot, pSession, pProduct, pDataset, pExchange, pMarket, pDatetime, pTimeFrame, callBackFunction) {
|
||||
function initialize (pDataMine, pBot, pSession, pProduct, pDataset, pExchange, pMarket, pDatetime, pTimeFrame, pHost, pPort, pEventsServerClient, callBackFunction) {
|
||||
try {
|
||||
callBackWhenFileReceived = callBackFunction
|
||||
|
||||
let exchange = pExchange
|
||||
|
||||
fileCloud = newFileCloud()
|
||||
fileCloud.initialize(pBot)
|
||||
fileCloud.initialize(pBot, pHost, pPort)
|
||||
|
||||
/* Some Validations */
|
||||
if (pDataset.code.validTimeFrames === undefined) {
|
||||
@@ -114,7 +114,7 @@ function newDailyFiles () {
|
||||
if (pDataset.code.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, onInitialized)
|
||||
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) {
|
||||
|
||||
@@ -17,12 +17,12 @@ function newFileCloud () {
|
||||
initialize: initialize
|
||||
}
|
||||
|
||||
let blobService
|
||||
let fileStorage
|
||||
|
||||
return thisObject
|
||||
|
||||
function initialize (pBot) {
|
||||
blobService = newFileStorage()
|
||||
function initialize (pBot, pHost, pPort) {
|
||||
fileStorage = newFileStorage(pHost, pPort)
|
||||
}
|
||||
|
||||
function getFile (pDataMine, pBot, pSession, pProduct, pDataset, pExchange, pMarket, pPeriodName, pDatetime, pSequence, pDataRange, callBackFunction) {
|
||||
@@ -121,7 +121,7 @@ function newFileCloud () {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] getFile -> getFileRecursively -> filePath = ' + filePath) }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] getFile -> getFileRecursively -> fileName = ' + fileName) }
|
||||
|
||||
blobService.getBlobToText(filePath + '/' + fileName, undefined, onFileReceived)
|
||||
fileStorage.getFileFromHost(filePath + '/' + fileName, onFileReceived)
|
||||
|
||||
function onFileReceived (err, text, response) {
|
||||
try {
|
||||
|
||||
@@ -34,6 +34,7 @@ function newFileCursor () {
|
||||
let timeFrame
|
||||
let beginDateRange
|
||||
let endDateRange
|
||||
let eventsServerClient
|
||||
|
||||
let finalized = false
|
||||
|
||||
@@ -61,6 +62,7 @@ function newFileCursor () {
|
||||
timeFrame = undefined
|
||||
beginDateRange = undefined
|
||||
endDateRange = undefined
|
||||
eventsServerClient = undefined
|
||||
|
||||
thisObject.files = undefined
|
||||
cursorDate = undefined
|
||||
@@ -73,7 +75,23 @@ function newFileCursor () {
|
||||
}
|
||||
}
|
||||
|
||||
function initialize (pFileCloud, pDataMine, pBot, pSession, pProduct, pDataset, pExchange, pMarket, pPeriodName, pTimeFrame, pCursorDate, pCurrentTimeFrame, pBeginDateRange, pEndDateRange, callBackFunction) {
|
||||
function initialize (
|
||||
pFileCloud,
|
||||
pDataMine,
|
||||
pBot,
|
||||
pSession,
|
||||
pProduct,
|
||||
pDataset,
|
||||
pExchange,
|
||||
pMarket,
|
||||
pPeriodName,
|
||||
pTimeFrame,
|
||||
pCursorDate,
|
||||
pCurrentTimeFrame,
|
||||
pBeginDateRange,
|
||||
pEndDateRange,
|
||||
pEventsServerClient,
|
||||
callBackFunction) {
|
||||
try {
|
||||
market = pMarket
|
||||
exchange = pExchange
|
||||
@@ -88,6 +106,7 @@ function newFileCursor () {
|
||||
timeFrame = pTimeFrame
|
||||
beginDateRange = pBeginDateRange
|
||||
endDateRange = pEndDateRange
|
||||
eventsServerClient = pEventsServerClient
|
||||
|
||||
let key = dataMine.code.codeName + '-' + bot.code.codeName + '-' + product.code.codeName + '-' + dataset.code.codeName + '-' + exchange.name + '-' + market.baseAsset + '/' + market.quotedAsset
|
||||
let callerId = key + '-' + periodName + newUniqueId()
|
||||
|
||||
@@ -32,6 +32,7 @@ function newFileSequence () {
|
||||
|
||||
let eventSubscriptionIdDatasetUpdated
|
||||
let callerId
|
||||
let eventsServerClient
|
||||
|
||||
return thisObject
|
||||
|
||||
@@ -52,6 +53,7 @@ function newFileSequence () {
|
||||
session = undefined
|
||||
dataset = undefined
|
||||
product = undefined
|
||||
eventsServerClient = undefined
|
||||
|
||||
finalized = true
|
||||
} catch (err) {
|
||||
@@ -59,7 +61,18 @@ function newFileSequence () {
|
||||
}
|
||||
}
|
||||
|
||||
function initialize (pDataMine, pBot, pSession, pProduct, pDataset, pExchange, pMarket, callBackFunction) {
|
||||
function initialize (
|
||||
pDataMine,
|
||||
pBot,
|
||||
pSession,
|
||||
pProduct,
|
||||
pDataset,
|
||||
pExchange,
|
||||
pMarket,
|
||||
pHost,
|
||||
pPort,
|
||||
pEventsServerClient,
|
||||
callBackFunction) {
|
||||
try {
|
||||
exchange = pExchange
|
||||
market = pMarket
|
||||
@@ -68,9 +81,10 @@ function newFileSequence () {
|
||||
session = pSession
|
||||
dataset = pDataset
|
||||
product = pProduct
|
||||
eventsServerClient = pEventsServerClient
|
||||
|
||||
fileCloud = newFileCloud()
|
||||
fileCloud.initialize(bot)
|
||||
fileCloud.initialize(bot, pHost, pPort)
|
||||
|
||||
callerId = newUniqueId()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
function newFileStorage () {
|
||||
function newFileStorage (host, port) {
|
||||
const MODULE_NAME = 'File Storage'
|
||||
const INFO_LOG = false
|
||||
const logger = newWebDebugLog()
|
||||
@@ -24,20 +24,28 @@ function newFileStorage () {
|
||||
]
|
||||
|
||||
let thisObject = {
|
||||
getBlobToText: getBlobToText
|
||||
getFileFromHost: getFileFromHost
|
||||
}
|
||||
|
||||
if (host === '' || host === undefined) { host = 'localhost' }
|
||||
if (port === '' || port === undefined) { port = '34247' }
|
||||
|
||||
return thisObject
|
||||
|
||||
async function getBlobToText (filePath, host, callBackFunction, pathComplete) {
|
||||
async function getFileFromHost (filePath, callBackFunction, pathComplete) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] getBlobToText -> Entering function.') }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] getFileFromHost -> Entering function.') }
|
||||
|
||||
let folder = ''
|
||||
if (pathComplete === false || pathComplete === undefined) {
|
||||
folder = 'Storage/'
|
||||
}
|
||||
callServer(undefined, folder + filePath, (response, fileContent) => {
|
||||
let url = folder + filePath
|
||||
if (host !== undefined) {
|
||||
url = 'http://' + host + ':' + port + '/' + folder + filePath
|
||||
}
|
||||
|
||||
callServer(undefined, url, (response, fileContent) => {
|
||||
if (response.result === GLOBAL.DEFAULT_OK_RESPONSE.result) {
|
||||
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, fileContent)
|
||||
} else {
|
||||
@@ -48,7 +56,7 @@ function newFileStorage () {
|
||||
if (verifyRetry(err.code) && currentRetry < MAX_RETRY) {
|
||||
currentRetry++
|
||||
if (INFO_LOG === true) { console.log('[INFO] getTextFile -> Retrying connection to the server because received error: ' + err.code + '. Retry #: ' + currentRetry) }
|
||||
getBlobToText(filePath, host, callBackFunction)
|
||||
getFileFromHost(filePath, callBackFunction)
|
||||
} else if (err.message === 'Request aborted') {
|
||||
let err = { code: 'The specified key does not exist.' }
|
||||
callBackFunction(err)
|
||||
|
||||
@@ -37,6 +37,7 @@ function newMarketFiles () {
|
||||
let finalized = false
|
||||
|
||||
let eventSubscriptionIdDatasetUpdated = []
|
||||
let eventsServerClient
|
||||
|
||||
return thisObject
|
||||
|
||||
@@ -60,6 +61,7 @@ function newMarketFiles () {
|
||||
dataset = undefined
|
||||
product = undefined
|
||||
periodName = undefined
|
||||
eventsServerClient = undefined
|
||||
|
||||
finalized = true
|
||||
} catch (err) {
|
||||
@@ -67,7 +69,18 @@ function newMarketFiles () {
|
||||
}
|
||||
}
|
||||
|
||||
function initialize (pDataMine, pBot, pSession, pProduct, pDataset, pExchange, pMarket, callBackFunction) {
|
||||
function initialize (
|
||||
pDataMine,
|
||||
pBot,
|
||||
pSession,
|
||||
pProduct,
|
||||
pDataset,
|
||||
pExchange,
|
||||
pMarket,
|
||||
pHost,
|
||||
pPort,
|
||||
pEventsServerClient,
|
||||
callBackFunction) {
|
||||
try {
|
||||
exchange = pExchange
|
||||
market = pMarket
|
||||
@@ -76,9 +89,10 @@ function newMarketFiles () {
|
||||
session = pSession
|
||||
dataset = pDataset
|
||||
product = pProduct
|
||||
eventsServerClient = pEventsServerClient
|
||||
|
||||
fileCloud = newFileCloud()
|
||||
fileCloud.initialize(pBot)
|
||||
fileCloud.initialize(pBot, pHost, pPort)
|
||||
|
||||
/* Some Validations */
|
||||
if (dataset.code.validTimeFrames === undefined) {
|
||||
|
||||
@@ -16,7 +16,18 @@ function newSingleFile () {
|
||||
|
||||
return thisObject
|
||||
|
||||
function initialize (pDataMine, pBot, pSession, pProduct, pDataset, pExchange, pMarket, callBackFunction) {
|
||||
function initialize (
|
||||
pDataMine,
|
||||
pBot,
|
||||
pSession,
|
||||
pProduct,
|
||||
pDataset,
|
||||
pExchange,
|
||||
pMarket,
|
||||
pHost,
|
||||
pPort,
|
||||
pEventsServerClient,
|
||||
callBackFunction) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> Entering function.') }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> key = ' + pDataMine.code.codeName + '-' + pBot.code.codeName + '-' + pProduct.code.codeName) }
|
||||
@@ -24,7 +35,7 @@ function newSingleFile () {
|
||||
let exchange = pExchange
|
||||
|
||||
fileCloud = newFileCloud()
|
||||
fileCloud.initialize(pBot)
|
||||
fileCloud.initialize(pBot, pHost, pPort)
|
||||
|
||||
/* Now we will get the file */
|
||||
|
||||
|
||||
+8
-4
@@ -385,8 +385,10 @@
|
||||
record.maximunBalanceB = dailyFile[i][32];
|
||||
record.baseAsset = dailyFile[i][33];
|
||||
record.quotedAsset = dailyFile[i][34];
|
||||
record.positionPeriods = dailyFile[i][35];
|
||||
record.positionDays = dailyFile[i][36];
|
||||
record.marketBaseAsset = dailyFile[i][35];
|
||||
record.marketQuotedAsset = dailyFile[i][36];
|
||||
record.positionPeriods = dailyFile[i][37];
|
||||
record.positionDays = dailyFile[i][38];
|
||||
|
||||
if (
|
||||
(record.begin >= farLeftDate.valueOf() && record.end <= farRightDate.valueOf()) &&
|
||||
@@ -477,8 +479,10 @@
|
||||
record.maximunBalanceB = marketFile[i][32];
|
||||
record.baseAsset = marketFile[i][33];
|
||||
record.quotedAsset = marketFile[i][34];
|
||||
record.positionPeriods = marketFile[i][35];
|
||||
record.positionDays = marketFile[i][36];
|
||||
record.marketBaseAsset = marketFile[i][35];
|
||||
record.marketQuotedAsset = marketFile[i][36];
|
||||
record.positionPeriods = marketFile[i][37];
|
||||
record.positionDays = marketFile[i][38];
|
||||
|
||||
if (
|
||||
(record.begin >= leftDate.valueOf() && record.end <= rightDate.valueOf()) &&
|
||||
|
||||
+55
-24
@@ -154,33 +154,64 @@ function newTradingEnginesPlottersTradingSimulationTradingSimulationTradingSimul
|
||||
return
|
||||
}
|
||||
|
||||
params = {}
|
||||
params.VALUE = currentRecord.balanceA;
|
||||
params.INIT_VALUE = currentRecord.initialBalanceA
|
||||
params.MIN_VALUE = currentRecord.minimunBalanceA
|
||||
params.MAX_VALUE = currentRecord.maximunBalanceA
|
||||
params.ASSET_LABEL = 'Asset A'
|
||||
params.ASSET_NAME = currentRecord.baseAsset
|
||||
params.LEFT_OFFSET = X_AXIS
|
||||
params.POSITION_TAKEN = positionTaken
|
||||
params.BASE_ASSET = currentRecord.baseAsset
|
||||
params.DECIMALS = 4
|
||||
if (currentRecord.baseAsset === currentRecord.marketBaseAsset) {
|
||||
params = {}
|
||||
params.VALUE = currentRecord.balanceA;
|
||||
params.INIT_VALUE = currentRecord.initialBalanceA
|
||||
params.MIN_VALUE = currentRecord.minimunBalanceA
|
||||
params.MAX_VALUE = currentRecord.maximunBalanceA
|
||||
params.ASSET_LABEL = 'Base'
|
||||
params.ASSET_NAME = currentRecord.baseAsset
|
||||
params.LEFT_OFFSET = X_AXIS
|
||||
params.POSITION_TAKEN = positionTaken
|
||||
params.BASE_ASSET = currentRecord.baseAsset
|
||||
params.DECIMALS = 4
|
||||
|
||||
paramsArray.push(params)
|
||||
paramsArray.push(params)
|
||||
|
||||
params = {}
|
||||
params.VALUE = currentRecord.balanceB;
|
||||
params.MIN_VALUE = currentRecord.minimunBalanceB
|
||||
params.INIT_VALUE = currentRecord.initialBalanceB
|
||||
params.MAX_VALUE = currentRecord.maximunBalanceB
|
||||
params.ASSET_LABEL = 'Asset B'
|
||||
params.ASSET_NAME = currentRecord.quotedAsset
|
||||
params.LEFT_OFFSET = X_AXIS
|
||||
params.POSITION_TAKEN = positionTaken
|
||||
params.BASE_ASSET = currentRecord.baseAsset
|
||||
params.DECIMALS = 2
|
||||
params = {}
|
||||
params.VALUE = currentRecord.balanceB;
|
||||
params.MIN_VALUE = currentRecord.minimunBalanceB
|
||||
params.INIT_VALUE = currentRecord.initialBalanceB
|
||||
params.MAX_VALUE = currentRecord.maximunBalanceB
|
||||
params.ASSET_LABEL = 'Quoted'
|
||||
params.ASSET_NAME = currentRecord.quotedAsset
|
||||
params.LEFT_OFFSET = X_AXIS
|
||||
params.POSITION_TAKEN = positionTaken
|
||||
params.BASE_ASSET = currentRecord.baseAsset
|
||||
params.DECIMALS = 2
|
||||
|
||||
paramsArray.push(params)
|
||||
} else {
|
||||
params = {}
|
||||
params.VALUE = currentRecord.balanceB;
|
||||
params.INIT_VALUE = currentRecord.initialBalanceB
|
||||
params.MIN_VALUE = currentRecord.minimunBalanceB
|
||||
params.MAX_VALUE = currentRecord.maximunBalanceB
|
||||
params.ASSET_LABEL = 'Base'
|
||||
params.ASSET_NAME = currentRecord.baseAsset
|
||||
params.LEFT_OFFSET = X_AXIS
|
||||
params.POSITION_TAKEN = positionTaken
|
||||
params.BASE_ASSET = currentRecord.baseAsset
|
||||
params.DECIMALS = 4
|
||||
|
||||
paramsArray.push(params)
|
||||
|
||||
params = {}
|
||||
params.VALUE = currentRecord.balanceA;
|
||||
params.MIN_VALUE = currentRecord.minimunBalanceA
|
||||
params.INIT_VALUE = currentRecord.initialBalanceA
|
||||
params.MAX_VALUE = currentRecord.maximunBalanceA
|
||||
params.ASSET_LABEL = 'Quoted'
|
||||
params.ASSET_NAME = currentRecord.quotedAsset
|
||||
params.LEFT_OFFSET = X_AXIS
|
||||
params.POSITION_TAKEN = positionTaken
|
||||
params.BASE_ASSET = currentRecord.baseAsset
|
||||
params.DECIMALS = 2
|
||||
|
||||
paramsArray.push(params)
|
||||
}
|
||||
|
||||
paramsArray.push(params)
|
||||
|
||||
thisObject.assetBalances.setParamsArray(paramsArray)
|
||||
thisObject.assetBalances.draw()
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Contact Us
|
||||
|
||||
Please join our Telegram Community to contact us there: https://t.me/superalgoscommunity
|
||||
|
||||
# Superalgos
|
||||
|
||||
Superalgos provides a toolbox with many integrated tools that could help you research crypto markets and design / automate trading strategies. You can use Superalgos to download market data from crypto exchanges, make arbitrary calculations with it (including indicators), plot the results of your calculations, design, test and automate trading strategies, and more.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{"type":"Workspace","name":"Simple Workspace","rootNodes":[{"type":"Network","name":"Superalgos","networkNodes":[{"type":"Network Node","name":"My Computer","code":"{ \n\"host\": \"localhost\", \n\"webPort\": \"34247\", \n\"webSocketsPort\": \"8080\"\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":"New Exchange Data Products","singleMarketData":[{"type":"Single Market Data","name":"","dataProducts":[{"type":"Data Product","name":"Candles","id":"cc7f62f2-0aa8-498c-861c-85060dd70522","savedPayload":{"position":{"x":39641.333811210454,"y":28936.98413868935},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"70e3b1ab-65d9-4c9e-8489-35d6852e7ef5","savedPayload":{"position":{"x":39612.59634583407,"y":28848.5110343909},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"eebb207f-6a7e-405a-9bed-2ff3afdd12af","savedPayload":{"position":{"x":39594.15352768551,"y":28758.904338266497},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"09706013-dc8f-4e40-8a71-129191aa521d","savedPayload":{"position":{"x":39585.513470979095,"y":28668.600155855387},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"d81b957c-4a39-4c15-8158-c05a0e63e591","savedPayload":{"position":{"x":39586.515890435076,"y":28578.275802249987},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"dd2bbd8b-0c18-4cc2-b176-ad3b177a98a7","savedPayload":{"position":{"x":39597.01323868843,"y":28488.759535006342},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"c2f6e67c-b1b1-47d3-9600-cf18be037620","savedPayload":{"position":{"x":39616.82107043368,"y":28400.936525998834},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"074c15c8-317c-4358-963f-4186f245bb25","savedPayload":{"position":{"x":39645.70528040039,"y":28315.720626172813},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"c4a5297a-6f84-4337-8cd8-4ebde8fa1ae5","savedPayload":{"position":{"x":39683.34058679891,"y":28234.020419812852},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollaLine truncated
|
||||
@@ -1 +1 @@
|
||||
{"type":"Super Scripts","name":"Masters","code":"{ \n\"codeName\": \"Masters\"\n}","scriptsLibrary":{"type":"Scripts Library","name":"New Scripts Library","masterScripts":[{"type":"Master Script","name":"Setup Market","templateScripts":[{"type":"Template Script","name":"Install Single Market Data","templateStructure":{"type":"Template Structure","name":"New Template Structure","singleMarketData":{"type":"Single Market Data","name":"","dataProducts":[{"type":"Data Product","name":"Candles","id":"24c5f795-acf3-43c3-99ee-ddb521b082f4","savedPayload":{"position":{"x":39933.49393163037,"y":29046.10981068428},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"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":"204ec959-0861-486a-aa2a-276dbf48f775","savedPayload":{"position":{"x":39908.11948414529,"y":28963.262354549173},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"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":"90ee9733-ab7e-41a0-ac78-4a7661a27017","savedPayload":{"position":{"x":39895.18349066973,"y":28880.38336833146},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"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":"9ade8e93-9071-422b-8cce-7a50d6dad739","savedPayload":{"position":{"x":39893.27964669049,"y":28797.90081457585},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"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":"b5ef2cf7-3d35-45ec-848c-31970b59c04e","savedPayload":{"position":{"x":39901.90265885927,"y":28716.54731001258},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"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":"1c3881ca-24b3-4cc9-b16b-9db7aa2b4c24","savedPayload":{"position":{"x":39920.664403351046,"y":28637.27326471363},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"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":"92eec33b-86be-4b73-899f-e9550f7b0df3","savedPayload":{"position":{"x":39949.20152839712,"y":28561.15482568263},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"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":"4b69df71-9091-4d22-9b0d-571304297033","savedPayload":{"position":{"x":39987.032994167246,"y":28489.298406726437},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"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":"8a5f7e27-9ca5-4d6e-b6b9-2d6cbdda8040","savedPayload":{"position":{"x":40033.55648252736,"y":28422.790182572182},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"tLine truncated
|
||||
{"type":"Super Scripts","name":"Masters","code":"{ \n\"codeName\": \"Masters\"\n}","scriptsLibrary":{"type":"Scripts Library","name":"New Scripts Library","masterScripts":[{"type":"Master Script","name":"Setup Market","templateScripts":[{"type":"Template Script","name":"Install Single Market Data","templateStructure":{"type":"Template Structure","name":"New Template Structure","singleMarketData":{"type":"Single Market Data","name":"","dataProducts":[{"type":"Data Product","name":"Candles","id":"24c5f795-acf3-43c3-99ee-ddb521b082f4","savedPayload":{"position":{"x":39641.333811210454,"y":28936.98413868935},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"204ec959-0861-486a-aa2a-276dbf48f775","savedPayload":{"position":{"x":39612.59634583407,"y":28848.5110343909},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"90ee9733-ab7e-41a0-ac78-4a7661a27017","savedPayload":{"position":{"x":39594.15352768551,"y":28758.904338266497},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"9ade8e93-9071-422b-8cce-7a50d6dad739","savedPayload":{"position":{"x":39585.513470979095,"y":28668.600155855387},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"b5ef2cf7-3d35-45ec-848c-31970b59c04e","savedPayload":{"position":{"x":39586.515890435076,"y":28578.275802249987},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"1c3881ca-24b3-4cc9-b16b-9db7aa2b4c24","savedPayload":{"position":{"x":39597.01323868843,"y":28488.759535006342},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"92eec33b-86be-4b73-899f-e9550f7b0df3","savedPayload":{"position":{"x":39616.82107043368,"y":28400.936525998834},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"4b69df71-9091-4d22-9b0d-571304297033","savedPayload":{"position":{"x":39645.70528040039,"y":28315.720626172813},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"8a5f7e27-9ca5-4d6e-b6b9-2d6cbdda8040","savedPayload":{"position":{"x":39683.34058679891,"y":28234.020419812852},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":Line truncated
|
||||
@@ -10,7 +10,8 @@
|
||||
nodeArray: undefined,
|
||||
dataSetsModulesArray: [],
|
||||
isItADepenency: isItADepenency,
|
||||
initialize: initialize
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
};
|
||||
|
||||
let filter = new Map()
|
||||
@@ -69,7 +70,7 @@
|
||||
function onInitilized(err) {
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> onInitilized -> err = "+ err.stack);
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> onInitilized -> err = "+ JSON.stringify(err));
|
||||
|
||||
alreadyCalledBack = true;
|
||||
callBackFunction(err);
|
||||
@@ -103,6 +104,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
function finalize() {
|
||||
for (let i = 0; i < thisObject.dataSetsModulesArray.length; i++) {
|
||||
let dataSetModule = thisObject.dataSetsModulesArray[i]
|
||||
dataSetModule.finalize()
|
||||
}
|
||||
thisObject.dataSetsModulesArray = undefined
|
||||
filter = undefined
|
||||
bot = undefined
|
||||
}
|
||||
|
||||
function isItADepenency(timeFrame, product) {
|
||||
let key = timeFrame + '-' + product
|
||||
|
||||
|
||||
+85
-2
@@ -6,7 +6,9 @@ exports.newDataSet = function newDataSet(BOT, logger) {
|
||||
|
||||
let thisObject = {
|
||||
node: undefined,
|
||||
networkNode: undefined,
|
||||
initialize: initialize,
|
||||
finalize: finalize,
|
||||
getTextFile: getTextFile,
|
||||
createTextFile: createTextFile
|
||||
};
|
||||
@@ -14,7 +16,7 @@ exports.newDataSet = function newDataSet(BOT, logger) {
|
||||
/* Storage account to be used here. */
|
||||
|
||||
const FILE_STORAGE = require('./FileStorage.js');
|
||||
let fileStorage = FILE_STORAGE.newFileStorage(logger);
|
||||
let fileStorage
|
||||
|
||||
return thisObject;
|
||||
|
||||
@@ -76,7 +78,81 @@ exports.newDataSet = function newDataSet(BOT, logger) {
|
||||
return
|
||||
}
|
||||
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
/* Now we will see where do we need to fetch this data from. */
|
||||
let network = global.TASK_NETWORK
|
||||
let datasetProductDefinition = thisObject.node.parentNode
|
||||
|
||||
for (let i = 0; i < network.networkNodes.length; i++) {
|
||||
let networkNode = network.networkNodes[i]
|
||||
if (networkNode.dataStorage !== undefined) {
|
||||
if (networkNode.dataStorage.sessionIndependentData !== undefined) {
|
||||
for (let j = 0; j < networkNode.dataStorage.sessionIndependentData.exchangeDataProducts.length; j++) {
|
||||
let exchangeDataProduct = networkNode.dataStorage.sessionIndependentData.exchangeDataProducts[j]
|
||||
for (let k = 0; k < exchangeDataProduct.singleMarketData.length; k++) {
|
||||
let singleMarketData = exchangeDataProduct.singleMarketData[k]
|
||||
if (singleMarketData.referenceParent !== undefined) {
|
||||
let market = singleMarketData.referenceParent
|
||||
let currentProcessMarket = bot.processNode.marketReference.referenceParent
|
||||
|
||||
if (currentProcessMarket.id === market.id) {
|
||||
for (let m = 0; m < singleMarketData.dataProducts.length; m++) {
|
||||
let dataProduct = singleMarketData.dataProducts[m]
|
||||
if (dataProduct.referenceParent !== undefined) {
|
||||
let productDefinition = dataProduct.referenceParent
|
||||
if (datasetProductDefinition.id === productDefinition.id) {
|
||||
|
||||
/* We found where the data is located on the network. */
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Retrieving data from " + networkNode.name + " -> host = " + networkNode.code.host + ' -> port = ' + networkNode.code.webPort + '.'); }
|
||||
|
||||
fileStorage = FILE_STORAGE.newFileStorage(logger, networkNode.code.host, networkNode.code.webPort);
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (networkNode.dataStorage.sessionBasedData !== undefined) {
|
||||
for (let j = 0; j < networkNode.dataStorage.sessionBasedData.exchangeDataProducts.length; j++) {
|
||||
let exchangeDataProduct = networkNode.dataStorage.sessionBasedData.exchangeDataProducts[j]
|
||||
for (let s = 0; s < exchangeDataProduct.sessionReferences.length; s++) {
|
||||
let sessionReference = exchangeDataProduct.sessionReferences[s]
|
||||
let singleMarketData = sessionReference.singleMarketData
|
||||
if (singleMarketData.referenceParent !== undefined) {
|
||||
let market = singleMarketData.referenceParent
|
||||
let currentProcessMarket = bot.processNode.marketReference.referenceParent
|
||||
|
||||
if (currentProcessMarket.id === market.id) {
|
||||
for (let m = 0; m < singleMarketData.dataProducts.length; m++) {
|
||||
let dataProduct = singleMarketData.dataProducts[m]
|
||||
if (dataProduct.referenceParent !== undefined) {
|
||||
let productDefinition = dataProduct.referenceParent
|
||||
if (datasetProductDefinition.id === productDefinition.id) {
|
||||
|
||||
/* We found where the data is located on the network. */
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Retrieving data from " + networkNode.name + " -> host = " + networkNode.code.host + ' -> port = ' + networkNode.code.webPort + '.'); }
|
||||
|
||||
fileStorage = FILE_STORAGE.newFileStorage(logger, networkNode.code.host, networkNode.code.webPort);
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Initialization Failed because we could not find where the data of this dataset is located within the network. Check the logs for more info.");
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Could not find where " + datasetProductDefinition.name + " for " + bot.exchange + " " + bot.market.baseAsset + "/" + bot.market.quotedAsset + " is stored within the network.");
|
||||
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> err = "+ err.stack);
|
||||
@@ -84,6 +160,13 @@ exports.newDataSet = function newDataSet(BOT, logger) {
|
||||
}
|
||||
}
|
||||
|
||||
function finalize() {
|
||||
fileStorage = undefined
|
||||
thisObject.networkNode = undefined
|
||||
bot = undefined
|
||||
thisObject = undefined
|
||||
}
|
||||
|
||||
function getTextFile(pFolderPath, pFileName, callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
@@ -17,7 +17,8 @@ exports.newDebugLog = function newDebugLog() {
|
||||
write: write,
|
||||
newInternalLoop: newInternalLoop,
|
||||
persist: persist, // This method is executed at the end of each Main Loop.
|
||||
initialize: initialize
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
};
|
||||
|
||||
let accumulatedLog = "[";
|
||||
@@ -37,6 +38,10 @@ exports.newDebugLog = function newDebugLog() {
|
||||
}
|
||||
}
|
||||
|
||||
function finalize() {
|
||||
persist()
|
||||
}
|
||||
|
||||
function newInternalLoop(pBot, pProcess, date, percentage) {
|
||||
if (percentage === undefined) {
|
||||
percentage = ""
|
||||
@@ -64,6 +69,7 @@ exports.newDebugLog = function newDebugLog() {
|
||||
/* Here we actually write the content of the in-memory log to a file */
|
||||
|
||||
try {
|
||||
if (accumulatedLog === "[") {return} // nothing to persist at the moment.
|
||||
|
||||
internalLoopCounter++;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
exports.newEventsServerClient = function newEventsServerClient() {
|
||||
exports.newEventsServerClient = function newEventsServerClient(host, port) {
|
||||
|
||||
const MODULE = "Task Server "
|
||||
const ERROR_LOG = true
|
||||
@@ -19,7 +19,14 @@
|
||||
|
||||
let WEB_SOCKETS_CLIENT
|
||||
const WEB_SOCKET = require('ws')
|
||||
let port = process.env.WEB_SOCKETS_SERVER_PORT
|
||||
|
||||
if (host === undefined) {
|
||||
host = 'localhost'
|
||||
}
|
||||
if (port === undefined) {
|
||||
port = process.env.WEB_SOCKETS_SERVER_PORT
|
||||
}
|
||||
|
||||
|
||||
return thisObject
|
||||
|
||||
@@ -32,7 +39,7 @@
|
||||
function setuptWebSockets(callBackFunction) {
|
||||
try {
|
||||
|
||||
WEB_SOCKETS_CLIENT = new WEB_SOCKET('ws://localhost:' + port )
|
||||
WEB_SOCKETS_CLIENT = new WEB_SOCKET('ws://' + host + ':' + port )
|
||||
|
||||
WEB_SOCKETS_CLIENT.onerror = error => {
|
||||
console.log('[ERROR] Task Server -> Event Server Client -> setuptWebSockets -> On connection error -> error = ' + JSON.stringify(error))
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
'secret': secret,
|
||||
'timeout': 30000,
|
||||
'enableRateLimit': true,
|
||||
verbose: true,
|
||||
verbose: false,
|
||||
options: options
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
const path = require('path')
|
||||
|
||||
exports.newFileStorage = function newFileStorage(logger) {
|
||||
exports.newFileStorage = function newFileStorage(logger, host, port) {
|
||||
|
||||
const MODULE_NAME = 'FileStorage'
|
||||
const MAX_RETRY = 30
|
||||
@@ -51,9 +51,15 @@ exports.newFileStorage = function newFileStorage(logger) {
|
||||
|
||||
logger.write(MODULE_NAME, '[INFO] FileStorage -> getTextFile -> fileLocation: ' + fileLocation)
|
||||
|
||||
/* Here we actually write the file. */
|
||||
const fs = require('fs')
|
||||
fs.readFile(fileLocation, onFileRead)
|
||||
/* Here we actually reaad the file. */
|
||||
if (host === undefined || host === 'localhost') {
|
||||
/* We read the file from the local file system. */
|
||||
const fs = require('fs')
|
||||
fs.readFile(fileLocation, onFileRead)
|
||||
} else {
|
||||
/* We read the file via a web server over http */
|
||||
getFileViaHTTP(fileLocation, onFileRead, callBackFunction)
|
||||
}
|
||||
|
||||
function onFileRead(err, text) {
|
||||
let retryTimeToUse = FAST_RETRY_TIME_IN_MILISECONDS
|
||||
@@ -118,7 +124,14 @@ exports.newFileStorage = function newFileStorage(logger) {
|
||||
if (canUsePrevious === true) {
|
||||
logger.write(MODULE_NAME, '[WARN] FileStorage -> getTextFile -> onFileRead -> Could read the file, but could not parse it as it is not a valid JSON. Will try to read the PREVIOUS version instead. -> file = ' + fileLocation)
|
||||
|
||||
fs.readFile(fileLocation + '.Previous.json', onPreviousFileRead)
|
||||
if (host === undefined || host === 'localhost') {
|
||||
/* We read the file from the local file system. */
|
||||
const fs = require('fs')
|
||||
fs.readFile(fileLocation + '.Previous.json', onPreviousFileRead)
|
||||
} else {
|
||||
/* We read the file via a web server over http */
|
||||
getFileViaHTTP(fileLocation + '.Previous.json', onPreviousFileRead, callBackFunction)
|
||||
}
|
||||
|
||||
function onPreviousFileRead(err, text) {
|
||||
|
||||
@@ -136,6 +149,7 @@ exports.newFileStorage = function newFileStorage(logger) {
|
||||
} else {
|
||||
logger.write(MODULE_NAME, '[WARN] FileStorage -> getTextFile -> onFileRead -> Could read the file, but could not parse it as it is not a valid JSON.')
|
||||
logger.write(MODULE_NAME, '[WARN] FileStorage -> getTextFile -> onFileRead -> err = ' + err.stack)
|
||||
logger.write(MODULE_NAME, '[WARN] FileStorage -> getTextFile -> onFileRead -> text.toString() = ' + text.toString())
|
||||
setTimeout(retry, retryTimeToUse)
|
||||
return
|
||||
}
|
||||
@@ -390,9 +404,8 @@ exports.newFileStorage = function newFileStorage(logger) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to create folders of missing folders at any path. */
|
||||
|
||||
function mkDirByPathSync(targetDir, { isRelativeToScript = false } = {}) {
|
||||
/* Function to create folders of missing folders at any path. */
|
||||
function mkDirByPathSync(targetDir, { isRelativeToScript = false } = {}) {
|
||||
const sep = '/';
|
||||
const initDir = path.isAbsolute(targetDir) ? sep : '';
|
||||
const baseDir = isRelativeToScript ? __dirname : '.';
|
||||
@@ -420,5 +433,63 @@ exports.newFileStorage = function newFileStorage(logger) {
|
||||
|
||||
return curDir;
|
||||
}, initDir);
|
||||
}
|
||||
}
|
||||
|
||||
function getFileViaHTTP(filePath, callback, callBackFunction) {
|
||||
try {
|
||||
|
||||
/* The filePath received is the one that is needed to fetch data from with fs. To do it via http we need to remove the prefix that includes this: ./Data-Storage/ */
|
||||
filePath = filePath.substring(15, filePath.length)
|
||||
|
||||
let http = require('http');
|
||||
let url = 'http://' + host +
|
||||
':' + port +
|
||||
'/Storage/' +
|
||||
filePath
|
||||
|
||||
logger.write(MODULE_NAME, '[INFO] FileStorage -> getFileViaHTTP -> url = ' + url)
|
||||
|
||||
let request = http.get(url, onResponse);
|
||||
|
||||
request.on('error', function (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] getFileViaHTTP -> onError -> err = " + err.stack);
|
||||
logger.write(MODULE_NAME, "[ERROR] getFileViaHTTP -> onError -> Failed to fetch file via HTTP. Will retry later. ");
|
||||
callBackFunction(global.DEFAULT_RETRY_RESPONSE);
|
||||
})
|
||||
|
||||
function onResponse(response) {
|
||||
|
||||
try {
|
||||
const chunks = []
|
||||
|
||||
response.on('data', onMessegesArrived)
|
||||
response.on('end', onEnd)
|
||||
|
||||
function onMessegesArrived(chunk) {
|
||||
chunks.push(chunk)
|
||||
}
|
||||
|
||||
function onEnd() {
|
||||
let fileContent = Buffer.concat(chunks).toString('utf8')
|
||||
let err = null
|
||||
if (fileContent.indexOf('does not exist') >= 0) {
|
||||
err = {
|
||||
code: "ENOENT" // This is how fs would have returned upon this situation.
|
||||
}
|
||||
fileContent = undefined
|
||||
}
|
||||
callback(err, fileContent)
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] getFileViaHTTP -> onResponse -> err = " + err.stack);
|
||||
logger.write(MODULE_NAME, "[ERROR] getFileViaHTTP -> onResponse -> Failed to fetch file via HTTP. Will retry later. ");
|
||||
callBackFunction(global.DEFAULT_RETRY_RESPONSE);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] getFileViaHTTP -> err = " + err.stack);
|
||||
logger.write(MODULE_NAME, "[ERROR] getFileViaHTTP -> Failed to fetch file via HTTP. Will retry later. ");
|
||||
callBackFunction(global.DEFAULT_RETRY_RESPONSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,7 +116,11 @@
|
||||
|
||||
/* For each loop we want to create a new log file. */
|
||||
|
||||
if (logger !== undefined) {
|
||||
logger.finalize()
|
||||
}
|
||||
logger = DEBUG_MODULE.newDebugLog();
|
||||
global.LOGGER_MAP.set(MODULE_NAME, logger)
|
||||
logger.bot = bot;
|
||||
logger.initialize();
|
||||
|
||||
@@ -252,6 +256,12 @@
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessExecutionEvents -> onStarted -> Execution finished well.");
|
||||
|
||||
if (global.STOP_TASK_GRACEFULLY === true) {
|
||||
loopControl()
|
||||
return
|
||||
}
|
||||
|
||||
initializeStatusDependencies();
|
||||
return;
|
||||
}
|
||||
@@ -776,10 +786,13 @@
|
||||
function onFinished(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessFramework -> onFinished -> Entering function."); }
|
||||
processFramework.finalize()
|
||||
processFramework = undefined
|
||||
dataDependencies.finalize()
|
||||
dataDependencies = undefined
|
||||
statusDependencies.finalize()
|
||||
statusDependencies = undefined
|
||||
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
@@ -876,11 +889,12 @@
|
||||
processExecutionEvents.finish(onFinished);
|
||||
|
||||
function onFinished(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> finishProcessExecutionEvents -> onFinished -> Entering function."); }
|
||||
|
||||
processExecutionEvents.finalize()
|
||||
processExecutionEvents = undefined
|
||||
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> finishProcessExecutionEvents -> onFinished -> Execution finished well.");
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
thisReport = statusReport.file;
|
||||
|
||||
if (thisReport.lastFile === undefined) {
|
||||
logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> Undefined Last File. -> reportKey = " + reportKey);
|
||||
logger.write(MODULE_NAME, "[WARN] start -> getContextVariables -> Undefined Last File. -> thisReport = " + JSON.stringify(thisReport));
|
||||
|
||||
let customOK = {
|
||||
result: global.CUSTOM_OK_RESPONSE.result,
|
||||
|
||||
@@ -8,57 +8,137 @@
|
||||
*/
|
||||
|
||||
const MODULE_NAME = "Process Execution Events";
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
let bot = BOT;
|
||||
|
||||
let thisObject = {
|
||||
networkNode: undefined,
|
||||
initialize, initialize,
|
||||
finalize: finalize,
|
||||
start: start,
|
||||
finish: finish
|
||||
};
|
||||
|
||||
let processThisDependsOn; // This is the process this process needs to wait for it to finishes in order to start.
|
||||
|
||||
let currentProcessKey
|
||||
|
||||
let EVENT_SERVER_CLIENT = require('./EventServerClient.js');
|
||||
let eventServerClient
|
||||
|
||||
return thisObject;
|
||||
|
||||
function initialize(callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
|
||||
|
||||
let name = 'Not Depends on any Process'
|
||||
logger.fileName = MODULE_NAME + "." + name;
|
||||
|
||||
if (bot.processNode.referenceParent !== undefined) {
|
||||
if (bot.processNode.referenceParent === undefined) {
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Initialization Failed because the Process Instance needs to have a Reference Parent.");
|
||||
return
|
||||
}
|
||||
|
||||
let market = bot.market.baseAsset + '/' + bot.market.quotedAsset
|
||||
currentProcessKey = bot.processNode.referenceParent.name + "-" + bot.processNode.referenceParent.type + "-" + bot.processNode.referenceParent.id + "-" + bot.exchange + "-" + market
|
||||
let market = bot.market.baseAsset + '/' + bot.market.quotedAsset
|
||||
currentProcessKey = bot.processNode.referenceParent.name + "-" + bot.processNode.referenceParent.type + "-" + bot.processNode.referenceParent.id + "-" + bot.exchange + "-" + market
|
||||
|
||||
if (bot.processNode.referenceParent.executionStartedEvent !== undefined) {
|
||||
if (bot.processNode.referenceParent.executionStartedEvent.referenceParent !== undefined) {
|
||||
if (bot.processNode.referenceParent.executionStartedEvent.referenceParent.parentNode !== undefined) {
|
||||
processThisDependsOn = bot.processNode.referenceParent.executionStartedEvent.referenceParent.parentNode
|
||||
if (bot.processNode.referenceParent.executionStartedEvent !== undefined) {
|
||||
if (bot.processNode.referenceParent.executionStartedEvent.referenceParent !== undefined) {
|
||||
if (bot.processNode.referenceParent.executionStartedEvent.referenceParent.parentNode !== undefined) {
|
||||
processThisDependsOn = bot.processNode.referenceParent.executionStartedEvent.referenceParent.parentNode
|
||||
|
||||
name = processThisDependsOn.name
|
||||
if (processThisDependsOn.code.monthlyInstances === true) {
|
||||
logger.fileName = MODULE_NAME + "." + name;
|
||||
}
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> " + currentProcessKey + " depends on " + name); }
|
||||
name = processThisDependsOn.name
|
||||
if (processThisDependsOn.code.monthlyInstances === true) {
|
||||
logger.fileName = MODULE_NAME + "." + name;
|
||||
}
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> " + currentProcessKey + " depends on " + name); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.fileName = MODULE_NAME + "." + name;
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
|
||||
if (processThisDependsOn !== undefined) {
|
||||
|
||||
/* We need to find at which network node is running the process that we need to hear from when it finished. */
|
||||
let network = global.TASK_NETWORK
|
||||
|
||||
for (let i = 0; i < network.networkNodes.length; i++) {
|
||||
let networkNode = network.networkNodes[i]
|
||||
if (networkNode.dataMining !== undefined) {
|
||||
for (let j = 0; j < networkNode.dataMining.exchangeTasks.length; j++) {
|
||||
let exchangeTasks = networkNode.dataMining.exchangeTasks[j]
|
||||
for (let k = 0; k < exchangeTasks.taskManagers.length; k++) {
|
||||
let taskManager = exchangeTasks.taskManagers[k]
|
||||
for (let m = 0; m < taskManager.tasks.length; m++) {
|
||||
let task = taskManager.tasks[m]
|
||||
if (task.bot !== undefined) {
|
||||
for (let n = 0; n < task.bot.processes.length; n++) {
|
||||
let process = task.bot.processes[n]
|
||||
if (process.marketReference !== undefined) {
|
||||
if (process.marketReference.referenceParent !== undefined) {
|
||||
let market = process.marketReference.referenceParent
|
||||
let currentProcessMarket = bot.processNode.marketReference.referenceParent
|
||||
|
||||
if (currentProcessMarket.id === market.id) {
|
||||
if (process.referenceParent !== undefined) {
|
||||
let processDefinition = process.referenceParent
|
||||
if (processThisDependsOn.id === processDefinition.id) {
|
||||
|
||||
/* We found where the task that runs the process definition we are waiting for is located on the network. */
|
||||
|
||||
thisObject.networkNode = networkNode
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Connecting to Websockets Server " + networkNode.name + " -> host = " + networkNode.code.host + ' -> port = ' + networkNode.code.webSocketsPort + '.'); }
|
||||
|
||||
eventServerClient = EVENT_SERVER_CLIENT.newEventsServerClient(networkNode.code.host, networkNode.code.webSocketsPort)
|
||||
eventServerClient.initialize(onConnected)
|
||||
|
||||
function onConnected() {
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Connected to Websockets Server " + networkNode.name + " -> host = " + networkNode.code.host + ' -> port = ' + networkNode.code.webSocketsPort + '.'); }
|
||||
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Initialization Failed because we could not find where the task that runs the Process Definition we are waiting for is located within the network. Check the logs for more info.");
|
||||
return
|
||||
}
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
function finalize() {
|
||||
if (eventServerClient !== undefined) {
|
||||
eventServerClient.finalize()
|
||||
eventServerClient = undefined
|
||||
}
|
||||
|
||||
processThisDependsOn = undefined
|
||||
currentProcessKey = undefined
|
||||
thisObject.networkNode = undefined
|
||||
bot = undefined
|
||||
thisObject = undefined
|
||||
}
|
||||
|
||||
function start(callBackFunction) {
|
||||
|
||||
try {
|
||||
@@ -81,9 +161,9 @@
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] start -> waitForDependantProcess -> key = " + key); }
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] start -> waitForDependantProcess -> callerId = " + callerId); }
|
||||
|
||||
global.EVENT_SERVER_CLIENT.listenToEvent(key, 'Process Execution Finished', undefined, callerId, responseCallBack, eventsCallBack)
|
||||
eventServerClient.listenToEvent(key, 'Process Execution Finished', undefined, callerId, responseCallBack, eventsCallBack)
|
||||
|
||||
bot.processHeartBeat(undefined, undefined, "Waiting for " + processThisDependsOn.parentNode.parentNode.name + "->" + processThisDependsOn.parentNode.code.codeName + "->" + processThisDependsOn.code.codeName)
|
||||
bot.processHeartBeat(undefined, undefined, "Waiting for " + thisObject.networkNode.name + "->" + processThisDependsOn.parentNode.parentNode.name + "->" + processThisDependsOn.parentNode.code.codeName + "->" + processThisDependsOn.code.codeName)
|
||||
|
||||
function responseCallBack(message) {
|
||||
if (message.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
@@ -102,7 +182,7 @@
|
||||
/* We continue the normal flow after we learn the dependent process has finished its execution. */
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] start -> eventsCallBack -> stopListening to Process Execution Finished. "); }
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] start -> eventsCallBack -> subscriptionId = " + subscriptionId); }
|
||||
global.EVENT_SERVER_CLIENT.stopListening(key, 'Process Execution Finished', subscriptionId)
|
||||
eventServerClient.stopListening(key, 'Process Execution Finished', subscriptionId)
|
||||
|
||||
if (message.event.err.result === global.DEFAULT_OK_RESPONSE.result) {
|
||||
/* We emit our own event that the process started. */
|
||||
|
||||
@@ -391,6 +391,7 @@
|
||||
let logger;
|
||||
|
||||
logger = DEBUG_MODULE.newDebugLog();
|
||||
global.LOGGER_MAP.set('runSensorBot', logger)
|
||||
logger.bot = pBotConfig;
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runSensorBot -> Entering function."); }
|
||||
@@ -455,6 +456,7 @@
|
||||
let logger;
|
||||
|
||||
logger = DEBUG_MODULE.newDebugLog();
|
||||
global.LOGGER_MAP.set('runIndicatorBot', logger)
|
||||
logger.bot = pBotConfig;
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runIndicatorBot -> Entering function."); }
|
||||
@@ -517,6 +519,7 @@
|
||||
let logger;
|
||||
|
||||
logger = DEBUG_MODULE.newDebugLog();
|
||||
global.LOGGER_MAP.set('runTradingBot', logger)
|
||||
logger.bot = pBotConfig;
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> bootingBot -> runTradingBot -> Entering function."); }
|
||||
|
||||
@@ -121,7 +121,11 @@
|
||||
|
||||
/* For each loop we want to create a new log file. */
|
||||
|
||||
if (logger !== undefined) {
|
||||
logger.finalize()
|
||||
}
|
||||
logger = DEBUG_MODULE.newDebugLog();
|
||||
global.LOGGER_MAP.set(MODULE_NAME, logger)
|
||||
logger.bot = bot;
|
||||
logger.initialize();
|
||||
|
||||
@@ -254,6 +258,12 @@
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessExecutionEvents -> onStarted -> Execution finished well.");
|
||||
|
||||
if (global.STOP_TASK_GRACEFULLY === true) {
|
||||
loopControl()
|
||||
return
|
||||
}
|
||||
|
||||
initializeStatusDependencies();
|
||||
return;
|
||||
}
|
||||
@@ -584,11 +594,12 @@
|
||||
processExecutionEvents.finish(onFinished);
|
||||
|
||||
function onFinished(err) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> finishProcessExecutionEvents -> onFinished -> Entering function."); }
|
||||
|
||||
processExecutionEvents.finalize()
|
||||
processExecutionEvents = undefined
|
||||
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> finishProcessExecutionEvents -> onFinished -> Execution finished well.");
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
/* Listen to event to start or stop the session. */
|
||||
bot.sessionKey = bot.processNode.session.name + '-' + bot.processNode.session.type + '-' + bot.processNode.session.id
|
||||
global.SESSION_MAP.set(bot.sessionKey, bot.sessionKey)
|
||||
|
||||
global.EVENT_SERVER_CLIENT.listenToEvent(bot.sessionKey, 'Run Session', undefined, bot.sessionKey, undefined, runSession)
|
||||
global.EVENT_SERVER_CLIENT.listenToEvent(bot.sessionKey, 'Stop Session', undefined, bot.sessionKey, undefined, stopSession)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
statusReports: new Map(),
|
||||
reportsByMainUtility: new Map(),
|
||||
initialize: initialize,
|
||||
finalize: finalize,
|
||||
keys: []
|
||||
};
|
||||
|
||||
@@ -165,4 +166,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
function finalize() {
|
||||
thisObject.statusReports.forEach(forEachStatusDependency)
|
||||
function forEachStatusDependency(statusDependency) {
|
||||
statusDependency.finalize()
|
||||
}
|
||||
thisObject.statusReports = undefined
|
||||
bot = undefined
|
||||
thisObject = undefined
|
||||
}
|
||||
};
|
||||
+79
-13
@@ -13,9 +13,11 @@
|
||||
let bot = BOT;
|
||||
|
||||
let thisObject = {
|
||||
networkNode: undefined,
|
||||
mainUtility: undefined,
|
||||
file: undefined, // Here we have the JSON object representing the file content.
|
||||
initialize: initialize,
|
||||
finalize: finalize,
|
||||
load: load,
|
||||
save: save,
|
||||
status: undefined
|
||||
@@ -30,7 +32,7 @@
|
||||
/* Storage account to be used here. */
|
||||
|
||||
const FILE_STORAGE = require('./FileStorage.js');
|
||||
let fileStorage = FILE_STORAGE.newFileStorage(logger);
|
||||
let fileStorage
|
||||
|
||||
let sessionPath = ''
|
||||
|
||||
@@ -93,17 +95,6 @@
|
||||
statusDependencyNode.bottype = statusDependencyNode.referenceParent.parentNode.parentNode.type
|
||||
statusDependencyNode.dataMine = statusDependencyNode.referenceParent.parentNode.parentNode.parentNode.code.codeName
|
||||
|
||||
/* Let's see if the process is run monthly or not. */
|
||||
if (statusDependencyNode.referenceParent.parentNode.code.startMode !== undefined) {
|
||||
if (statusDependencyNode.referenceParent.parentNode.code.startMode.allMonths !== undefined) {
|
||||
if (statusDependencyNode.referenceParent.parentNode.code.startMode.oneMonth !== undefined) {
|
||||
if (statusDependencyNode.referenceParent.parentNode.code.startMode.allMonths.run === "true" || statusDependencyNode.referenceParent.parentNode.code.startMode.oneMonth.run === "true") {
|
||||
statusDependencyNode.processRunMonthly = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We retrieve the report main utility */
|
||||
if (statusDependencyNode.code !== undefined) {
|
||||
if (statusDependencyNode.code.mainUtility !== undefined) {
|
||||
@@ -122,7 +113,74 @@
|
||||
sessionPath = bot.SESSION.folderName + "/"
|
||||
}
|
||||
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
/* Now we will see where do we need to fetch this status report from. */
|
||||
let network = global.TASK_NETWORK
|
||||
let processThisDependsOn = statusDependencyNode.referenceParent.parentNode
|
||||
|
||||
for (let i = 0; i < network.networkNodes.length; i++) {
|
||||
let networkNode = network.networkNodes[i]
|
||||
|
||||
if (checkThisBranch(networkNode.dataMining) === true) { return }
|
||||
if (checkThisBranch(networkNode.testingEnvironment) === true) {return}
|
||||
if (checkThisBranch(networkNode.productionEnvironment) === true) { return }
|
||||
|
||||
function checkThisBranch(branch) {
|
||||
if (branch === undefined) {return}
|
||||
for (let j = 0; j < branch.exchangeTasks.length; j++) {
|
||||
let exchangeTasks = branch.exchangeTasks[j]
|
||||
for (let k = 0; k < exchangeTasks.taskManagers.length; k++) {
|
||||
let taskManager = exchangeTasks.taskManagers[k]
|
||||
for (let m = 0; m < taskManager.tasks.length; m++) {
|
||||
let task = taskManager.tasks[m]
|
||||
if (task.bot !== undefined) {
|
||||
for (let n = 0; n < task.bot.processes.length; n++) {
|
||||
let process = task.bot.processes[n]
|
||||
if (process.marketReference !== undefined) {
|
||||
if (process.marketReference.referenceParent !== undefined) {
|
||||
let market = process.marketReference.referenceParent
|
||||
let currentProcessMarket = bot.processNode.marketReference.referenceParent
|
||||
if (currentProcessMarket.id === market.id) {
|
||||
if (process.referenceParent !== undefined) {
|
||||
let processDefinition = process.referenceParent
|
||||
if (processThisDependsOn.id === processDefinition.id) {
|
||||
if (process.type === 'Trading Process Instance') {
|
||||
if (process.session !== undefined) {
|
||||
if (bot.processNode.session.id !== process.session.id) {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
/* We found where the task that runs the process definition this status report depends on and where it is located on the network. */
|
||||
|
||||
thisObject.networkNode = networkNode
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Retrieving status report from " + networkNode.name + " -> host = " + networkNode.code.host + ' -> port = ' + networkNode.code.webPort + '.'); }
|
||||
|
||||
fileStorage = FILE_STORAGE.newFileStorage(logger, networkNode.code.host, networkNode.code.webPort);
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> Initialization Failed because we could not find where the data of this status report is located within the network. Check the logs for more info.");
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> bot = " + statusDependencyNode.bot);
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> process = " + statusDependencyNode.process);
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> bottype = " + statusDependencyNode.bottype);
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> dataMine = " + statusDependencyNode.dataMine);
|
||||
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> err = "+ err.stack);
|
||||
@@ -130,6 +188,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
function finalize() {
|
||||
fileStorage = undefined
|
||||
thisObject.networkNode = undefined
|
||||
bot = undefined
|
||||
thisObject = undefined
|
||||
}
|
||||
|
||||
function load(callBackFunction) {
|
||||
|
||||
try {
|
||||
@@ -212,6 +277,7 @@
|
||||
*/
|
||||
|
||||
logger.write(MODULE_NAME, "[ERROR] load -> onFileReceived -> Error Parsing the Status report. -> Err = " + err.message);
|
||||
logger.write(MODULE_NAME, "[WARN] load -> onFileReceived -> Error Parsing the Status report. -> text = " + text);
|
||||
|
||||
let customFail = {
|
||||
result: global.CUSTOM_FAIL_RESPONSE.result,
|
||||
|
||||
@@ -213,6 +213,8 @@
|
||||
record.maximumBalanceB + "," +
|
||||
record.baseAsset + "," +
|
||||
record.quotedAsset + "," +
|
||||
record.marketBaseAsset + "," +
|
||||
record.marketQuotedAsset + "," +
|
||||
record.positionPeriods + "," +
|
||||
record.positionDays + "," +
|
||||
record.distanceToLastTriggerOn + "," +
|
||||
@@ -559,8 +561,14 @@
|
||||
record.maximumBalanceB + "," +
|
||||
record.baseAsset + "," +
|
||||
record.quotedAsset + "," +
|
||||
record.marketBaseAsset + "," +
|
||||
record.marketQuotedAsset + "," +
|
||||
record.positionPeriods + "," +
|
||||
record.positionDays + "]";
|
||||
record.positionDays + "," +
|
||||
record.distanceToLastTriggerOn + "," +
|
||||
record.distanceToLastTriggerOff + "," +
|
||||
record.distanceToLastTakePosition + "," +
|
||||
record.distanceToLastClosePosition + "]";
|
||||
|
||||
if (separator === "") { separator = ","; }
|
||||
|
||||
@@ -664,8 +672,14 @@
|
||||
record.maximumBalanceB + "," +
|
||||
record.baseAsset + "," +
|
||||
record.quotedAsset + "," +
|
||||
record.marketBaseAsset + "," +
|
||||
record.marketQuotedAsset + "," +
|
||||
record.positionPeriods + "," +
|
||||
record.positionDays + "]";
|
||||
record.positionDays + "," +
|
||||
record.distanceToLastTriggerOn + "," +
|
||||
record.distanceToLastTriggerOff + "," +
|
||||
record.distanceToLastTakePosition + "," +
|
||||
record.distanceToLastClosePosition + "]";
|
||||
|
||||
if (separator === "") { separator = ","; }
|
||||
|
||||
|
||||
@@ -124,8 +124,11 @@
|
||||
}
|
||||
|
||||
/* For each loop we want to create a new log file. */
|
||||
|
||||
if (logger !== undefined) {
|
||||
logger.finalize()
|
||||
}
|
||||
logger = DEBUG_MODULE.newDebugLog();
|
||||
global.LOGGER_MAP.set(MODULE_NAME, logger)
|
||||
logger.bot = bot;
|
||||
logger.initialize();
|
||||
|
||||
@@ -288,6 +291,12 @@
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessExecutionEvents -> onStarted -> Execution finished well.");
|
||||
|
||||
if (global.STOP_TASK_GRACEFULLY === true) {
|
||||
loopControl()
|
||||
return
|
||||
}
|
||||
|
||||
initializeStatusDependencies();
|
||||
return;
|
||||
}
|
||||
@@ -694,6 +703,10 @@
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessFramework -> onFinished -> Entering function."); }
|
||||
processFramework.finalize()
|
||||
processFramework = undefined
|
||||
dataDependencies.finalize()
|
||||
dataDependencies = undefined
|
||||
statusDependencies.finalize()
|
||||
statusDependencies = undefined
|
||||
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
@@ -792,8 +805,9 @@
|
||||
processExecutionEvents.finish(onFinished);
|
||||
|
||||
function onFinished(err) {
|
||||
|
||||
try {
|
||||
processExecutionEvents.finalize()
|
||||
processExecutionEvents = undefined
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> finishProcessExecutionEvents -> onFinished -> Entering function."); }
|
||||
|
||||
|
||||
@@ -2798,6 +2798,8 @@
|
||||
maximumBalanceB: bot.VALUES_TO_USE.maximumBalanceB,
|
||||
baseAsset: quotedBaseAsset,
|
||||
quotedAsset: quotedQuotedAsset,
|
||||
marketBaseAsset: '"' + bot.market.baseAsset + '"',
|
||||
marketQuotedAsset: '"' + bot.market.quotedAsset + '"' ,
|
||||
positionPeriods: positionPeriods,
|
||||
positionDays: positionDays,
|
||||
distanceToLastTriggerOn: distanceToLast.triggerOn,
|
||||
|
||||
+35
-6
@@ -26,19 +26,37 @@ global.CUSTOM_FAIL_RESPONSE = {
|
||||
};
|
||||
|
||||
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000;
|
||||
global.LOGGER_MAP = new Map()
|
||||
global.SESSION_MAP = new Map()
|
||||
|
||||
process.on('uncaughtException', function (err) {
|
||||
console.log('[ERROR] Task Server -> server -> uncaughtException -> err.message = ' + err.message)
|
||||
console.log('[ERROR] Task Server -> server -> uncaughtException -> err.stack = ' + err.stack)
|
||||
process.exit(1)
|
||||
global.EXIT_NODE_PROCESS()
|
||||
})
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('[ERROR] Task Server -> server -> unhandledRejection -> reason = ' + JSON.stringify(reason))
|
||||
console.log('[ERROR] Task Server -> server -> unhandledRejection -> p = ' + JSON.stringify(p))
|
||||
process.exit(1)
|
||||
global.EXIT_NODE_PROCESS()
|
||||
})
|
||||
|
||||
function finalizeLoggers() {
|
||||
global.LOGGER_MAP.forEach(forEachLogger)
|
||||
|
||||
function forEachLogger(logger) {
|
||||
logger.finalize()
|
||||
}
|
||||
}
|
||||
|
||||
function finalizeSessions() {
|
||||
global.SESSION_MAP.forEach(forEachSession)
|
||||
|
||||
function forEachSession(session) {
|
||||
global.EVENT_SERVER_CLIENT.raiseEvent(session, 'Stopped')
|
||||
}
|
||||
}
|
||||
|
||||
process.on('exit', function (code) {
|
||||
|
||||
if (global.TASK_NODE !== undefined) {
|
||||
@@ -69,8 +87,16 @@ process.on('message', message => {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
let shuttingDownProcess = false
|
||||
global.EXIT_NODE_PROCESS = function exitProcess() {
|
||||
|
||||
if (shuttingDownProcess === true) { return }
|
||||
shuttingDownProcess = true
|
||||
|
||||
/* Signal that all sessions are stopping. */
|
||||
finalizeSessions()
|
||||
|
||||
/* Cleaning Before Exiting. */
|
||||
clearInterval(global.HEARTBEAT_INTERVAL_HANDLER)
|
||||
|
||||
@@ -82,6 +108,7 @@ global.EXIT_NODE_PROCESS = function exitProcess() {
|
||||
global.EVENT_SERVER_CLIENT.raiseEvent(key, 'Stopped') // Meaning Process Stopped
|
||||
}
|
||||
|
||||
finalizeLoggers()
|
||||
//console.log("[INFO] Task Server -> " + global.TASK_NODE.name + " -> EXIT_NODE_PROCESS -> Task Server will stop in 10 seconds.");
|
||||
|
||||
setTimeout(process.exit, 10000) // We will give 10 seconds to logs be written on file
|
||||
@@ -125,12 +152,13 @@ function preLoader() {
|
||||
global.EVENT_SERVER_CLIENT.raiseEvent('Task Manager - ' + taskId, 'Nodejs Process Ready for Task')
|
||||
function eventReceived(message) {
|
||||
global.TASK_NODE = message
|
||||
global.TASK_NODE = JSON.parse(message.event.definition)
|
||||
global.TASK_NODE = JSON.parse(message.event.taskDefinition)
|
||||
global.TASK_NETWORK = JSON.parse(message.event.networkDefinition)
|
||||
bootLoader()
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('[ERROR] Task Server -> server -> preLoader -> global.TASK_NODE -> ' + err.stack)
|
||||
console.log('[ERROR] Task Server -> server -> preLoader -> global.TASK_NODE = ' + JSON.stringify(global.TASK_NODE))
|
||||
console.log('[ERROR] Task Server -> server -> preLoader -> global.TASK_NODE = ' + JSON.stringify(global.TASK_NODE).substring(0, 1000))
|
||||
}
|
||||
}
|
||||
else { /* This process was started not by the Task Manager, but independently (most likely for debugging purposes). In this case we listen to an event with the Task Info that should be emitted at the UI */
|
||||
@@ -139,12 +167,13 @@ function preLoader() {
|
||||
global.EVENT_SERVER_CLIENT.listenToEvent('Task Server', 'Debug Task Started', undefined, 'Task Server', undefined, startDebugging)
|
||||
function startDebugging(message) {
|
||||
global.TASK_NODE = message
|
||||
global.TASK_NODE = JSON.parse(message.event.definition)
|
||||
global.TASK_NODE = JSON.parse(message.event.taskDefinition)
|
||||
global.TASK_NETWORK = JSON.parse(message.event.networkDefinition)
|
||||
bootLoader()
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('[ERROR] Task Server -> server -> preLoader -> global.TASK_NODE -> ' + err.stack)
|
||||
console.log('[ERROR] Task Server -> server -> preLoader -> global.TASK_NODE = ' + JSON.stringify(global.TASK_NODE))
|
||||
console.log('[ERROR] Task Server -> server -> preLoader -> global.TASK_NODE = ' + JSON.stringify(global.TASK_NODE).substring(0, 1000))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"type":"Trading System","name":"Bull Run Rider for BTC/USDT","code":"{ \n\"codeName\": \"Sparta-BRR-BTC-USDT\"\n}","strategies":[{"type":"Strategy","name":"My Strategy","triggerStage":{"type":"Trigger Stage","triggerOn":{"type":"Trigger On Event","situations":[{"type":"Situation","name":"New Situation","conditions":[{"type":"Condition","name":"New Condition","javascriptCode":{"type":"Javascript Code","code":"chart.at01hs.candle.max > chart.at01hs.bollingerBand.movingAverage + chart.at01hs.bollingerBand.deviation","id":"1e07e38a-c469-4f3f-b7e8-dccd9f94c546","savedPayload":{"position":{"x":39365.82836640363,"y":18024.168218963674},"targetPosition":{"x":39580.43309418583,"y":18013.241510980984},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"a1c434c4-5787-4906-8157-1e355999bba8","savedPayload":{"position":{"x":39580.43309418583,"y":18013.241510980984},"targetPosition":{"x":39795.82183026887,"y":18002.339607729755},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Condition","name":"New Condition","javascriptCode":{"type":"Javascript Code","code":"chart.at01hs.candle.previous.max > chart.at01hs.bollingerBand.previous.movingAverage + chart.at01hs.bollingerBand.previous.deviation\n","id":"3fb95a71-efe8-45cf-be43-8b0d94d2f420","savedPayload":{"position":{"x":39560.74976017509,"y":17641.37546255235},"targetPosition":{"x":39677.97500609048,"y":17821.555824077757},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"f69f2608-49bd-4b04-b8f8-497675f819fe","savedPayload":{"position":{"x":39677.97500609048,"y":17821.555824077757},"targetPosition":{"x":39795.82183026887,"y":18002.339607729755},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"1dfb0689-df0c-4184-9c09-683d012c9dfe","savedPayload":{"position":{"x":39795.82183026887,"y":18002.339607729755},"targetPosition":{"x":39987.61800165299,"y":18099.825253218787},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"announcements":[],"id":"32d2ee8c-71bd-4e4c-8671-04bbc4a16734","savedPayload":{"position":{"x":39987.61800165299,"y":18099.825253218787},"targetPosition":{"x":40369.80868599963,"y":18293.946872397046},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"triggerOff":{"type":"Trigger Off Event","situations":[{"type":"Situation","name":"New Situation","conditions":[{"type":"Condition","name":"New Condition","javascriptCode":{"type":"Javascript Code","code":"chart.at01hs.candle.close < chart.at01hs.bollingerBand.movingAverage","id":"a1dd4467-b96b-4084-bd9b-056c6495de95","savedPayload":{"position":{"x":40036.90604970189,"y":17272.087105877887},"targetPosition":{"x":40103.63478212326,"y":17476.753747464914},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"b527026c-4be3-4baf-bbde-83ebfd17e567","savedPayload":{"position":{"x":40103.63478212326,"y":17476.753747464914},"targetPosition":{"x":40170.46021986034,"y":17681.58479868604},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"41cbb7ba-020c-4e96-a6a7-c3ef8c25b6fd","savedPayload":{"position":{"x":40170.46021986034,"y":17681.58479868604},"targetPosition":{"x":40237.14613497818,"y":17886.475906641663},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"announcements":[],"id":"1af9fdb8-7316-4374-84f2-1b946741b5c6","savedPayload":{"position":{"x":40237.14613497818,"y":17886.475906641663},"targetPosition":{"x":40369.80868599963,"y":18293.946872397046},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"takePosition":{"type":"Take Position Event","situations":[{"type":"Situation","name":"New Situation","conditions":[{"type":"Condition","name":"New Condition","javascriptCode":{"type":"Javascript Code","code":"chart.at01hs.candle.previous.max > chart.at01hs.bollingerBand.previous.movingAverage + chart.at01hs.bollingerBand.previous.deviation\n","id":"0c15bd8b-b59c-4a2c-b65a-b063aec45216","savedPayload":{"position":{"x":40373.57878568003,"y":17396.87030065395},"targetPosition":{"x":40513.12406224243,"yLine truncated
|
||||
{"type":"Trading System","name":"Bull Run Rider for BTC/USDT","code":"{ \n\"codeName\": \"Sparta-BRR-BTC-USDT\"\n}","strategies":[{"type":"Strategy","name":"My Strategy","triggerStage":{"type":"Trigger Stage","triggerOn":{"type":"Trigger On Event","situations":[{"type":"Situation","name":"New Situation","conditions":[{"type":"Condition","name":"New Condition","javascriptCode":{"type":"Javascript Code","code":"chart.at01hs.candle.max > chart.at01hs.bollingerBand.movingAverage + chart.at01hs.bollingerBand.deviation","id":"1e07e38a-c469-4f3f-b7e8-dccd9f94c546","savedPayload":{"position":{"x":32136.28636024774,"y":18006.129040560536},"targetPosition":{"x":32356.411078541598,"y":17994.8611316122},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"a1c434c4-5787-4906-8157-1e355999bba8","savedPayload":{"position":{"x":32356.411078541598,"y":17994.8611316122},"targetPosition":{"x":32576.81076551354,"y":17983.560786264006},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Condition","name":"New Condition","javascriptCode":{"type":"Javascript Code","code":"chart.at01hs.candle.previous.max > chart.at01hs.bollingerBand.previous.movingAverage + chart.at01hs.bollingerBand.previous.deviation\n","id":"3fb95a71-efe8-45cf-be43-8b0d94d2f420","savedPayload":{"position":{"x":32336.278054047183,"y":17613.80662251148},"targetPosition":{"x":32456.46036116711,"y":17798.592583814658},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"f69f2608-49bd-4b04-b8f8-497675f819fe","savedPayload":{"position":{"x":32456.46036116711,"y":17798.592583814658},"targetPosition":{"x":32576.81076551354,"y":17983.560786264006},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"1dfb0689-df0c-4184-9c09-683d012c9dfe","savedPayload":{"position":{"x":32576.81076551354,"y":17983.560786264006},"targetPosition":{"x":32773.13118473049,"y":18083.48293309789},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"announcements":[],"id":"32d2ee8c-71bd-4e4c-8671-04bbc4a16734","savedPayload":{"position":{"x":32773.13118473049,"y":18083.48293309789},"targetPosition":{"x":33165.111331477776,"y":18282.94927462636},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"triggerOff":{"type":"Trigger Off Event","situations":[{"type":"Situation","name":"New Situation","conditions":[{"type":"Condition","name":"New Condition","javascriptCode":{"type":"Javascript Code","code":"chart.at01hs.candle.close < chart.at01hs.bollingerBand.movingAverage","id":"a1dd4467-b96b-4084-bd9b-056c6495de95","savedPayload":{"position":{"x":32824.239213958535,"y":17235.66806596493},"targetPosition":{"x":32892.45262811099,"y":17445.325022978603},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"b527026c-4be3-4baf-bbde-83ebfd17e567","savedPayload":{"position":{"x":32892.45262811099,"y":17445.325022978603},"targetPosition":{"x":32960.82113677954,"y":17655.21646975055},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"41cbb7ba-020c-4e96-a6a7-c3ef8c25b6fd","savedPayload":{"position":{"x":32960.82113677954,"y":17655.21646975055},"targetPosition":{"x":33029.05799170436,"y":17864.75284364219},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"announcements":[],"id":"1af9fdb8-7316-4374-84f2-1b946741b5c6","savedPayload":{"position":{"x":33029.05799170436,"y":17864.75284364219},"targetPosition":{"x":33165.111331477776,"y":18282.94927462636},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"takePosition":{"type":"Take Position Event","situations":[{"type":"Situation","name":"New Situation","conditions":[{"type":"Condition","name":"New Condition","javascriptCode":{"type":"Javascript Code","code":"chart.at01hs.candle.previous.max > chart.at01hs.bollingerBand.previous.movingAverage + chart.at01hs.bollingerBand.previous.deviation\n","id":"0c15bd8b-b59c-4a2c-b65a-b063aec45216","savedPayload":{"position":{"x":33171.57121687983,"y":17363.232196850764},"targetPosition":{"x":33314.699085071785,"y":1Line truncated
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"type":"Workspace","name":"My Workspace","rootNodes":[{"type":"Network","name":"Superalgos","networkNodes":[{"type":"Network Node","name":"My Computer","code":"{ \n\"ipAddress\": \"\", \n\"webPort\": \"\", \n\"webSocketsPort\": \"\"\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":"24c141e4-1ed2-48ac-a034-7356312e82f9","savedPayload":{"position":{"x":39933.49393163037,"y":29046.10981068428},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"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":"130cba4c-0c21-4955-88b9-e66d2b9abed0","savedPayload":{"position":{"x":39908.11948414529,"y":28963.262354549173},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"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":"e0e5315b-d9a1-4763-80ac-649932acb5b0","savedPayload":{"position":{"x":39895.18349066973,"y":28880.38336833146},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"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":"f9d97733-0919-4cbe-9e9e-b622ff629bc1","savedPayload":{"position":{"x":39893.27964669049,"y":28797.90081457585},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"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":"97e49713-d0ba-4678-8703-aafc343c7972","savedPayload":{"position":{"x":39901.90265885927,"y":28716.54731001258},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"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":"8169b2ef-9761-4bf7-9059-258f579a35c5","savedPayload":{"position":{"x":39920.664403351046,"y":28637.27326471363},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"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":"2629ed65-1f0b-4a39-89b6-5f4492439363","savedPayload":{"position":{"x":39949.20152839712,"y":28561.15482568263},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"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":"a536f2a1-6474-490b-a62b-724cc404acbd","savedPayload":{"position":{"x":39987.032994167246,"y":28489.298406726437},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"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":"36245c8b-614d-4bea-8e92-fe45babcb936","savedPayload":{"position":{"x":40033.55648252736,"y":28422.790182572182},"targetPosition":{"x":40538.49727374207,"y":28825.59791579029},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"anLine truncated
|
||||
{"type":"Workspace","name":"My Workspace","rootNodes":[{"type":"Network","name":"Superalgos","networkNodes":[{"type":"Network Node","name":"My Computer","code":"{ \n\"host\": \"localhost\", \n\"webPort\": \"34247\", \n\"webSocketsPort\": \"8080\"\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":"431ea989-085b-40ae-aa2a-d371d7cb68c6","savedPayload":{"position":{"x":39641.333811210454,"y":28936.98413868935},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"cc76acbb-9fd2-43f0-95de-dc78e1aaa2b5","savedPayload":{"position":{"x":39612.59634583407,"y":28848.5110343909},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"683e24f7-010a-412e-ba21-f280e63a0f1d","savedPayload":{"position":{"x":39594.15352768551,"y":28758.904338266497},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"210b7e14-a6f0-4c56-b5e4-108f57ebb4c6","savedPayload":{"position":{"x":39585.513470979095,"y":28668.600155855387},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"ddd34b26-4fa8-4d7c-b76d-f671c92a6181","savedPayload":{"position":{"x":39586.515890435076,"y":28578.275802249987},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"302bfaf2-6466-4aa0-9924-33999366b774","savedPayload":{"position":{"x":39597.01323868843,"y":28488.759535006342},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"10142313-9ac8-4f4c-8105-88aec7bb7ce9","savedPayload":{"position":{"x":39616.82107043368,"y":28400.936525998834},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"80ed873e-8017-45ec-b211-fc4604f5aaf6","savedPayload":{"position":{"x":39645.70528040039,"y":28315.720626172813},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"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":"6635502b-5366-430e-8dc1-4edaa21c2a7f","savedPayload":{"position":{"x":39683.34058679891,"y":28234.020419812852},"targetPosition":{"x":40443.285556188,"y":28633.794640045882},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":fLine truncated
|
||||
Reference in new issue
Block a user