Exchange nodes implemented

This commit is contained in:
Luis Fernando Molina committed 2020-03-04 20:36:47 +01:00
1 parent ba88b1a133
commit 6c86bdadda
11 files changed
+301 -71

No files matched your search

+217 -17
View File
@@ -1278,7 +1278,7 @@
"addLeftIcons": true,
"level": 1,
"chainAttachesTo": {
"compatibleTypes": "->Data Mining->Testing Environment->Production Environment->Template Structure->"
"compatibleTypes": "->Exchange Tasks->"
},
"icon": "task-manager",
"properties": [
@@ -5623,7 +5623,7 @@
]
},
{
"type": "Data Mining",
"type": "Exchange Tasks",
"menuItems": [
{
"action": "Run All Task Managers",
@@ -5651,6 +5651,69 @@
"relatedUiObject": "Task Manager",
"actionFunction": "payload.onMenuItemClick"
},
{
"action": "Delete UI Object",
"askConfirmation": true,
"confirmationLabel": "Confirm to Delete",
"label": "Delete Exchange Tasks",
"iconPathOn": "delete",
"iconPathOff": "delete",
"actionFunction": "payload.onMenuItemClick"
}
],
"addLeftIcons": true,
"level": 2,
"icon": "crypto-exchange",
"referenceAttachesTo": {
"compatibleTypes": "->Crypto Exchange->"
},
"chainAttachesTo": {
"compatibleTypes": "->Data Mining->Testing Environmnet->Production Environmnet->Template Structure->"
},
"alternativeIcons": "Use Reference Parent",
"title": [
"Use Reference Parent"
],
"isTitleAllwaysVisible": true,
"propertyNameAtParent": "exchangeTasks",
"properties": [
{
"name": "taskManagers",
"type": "array",
"childType": "Task Manager",
"monitorChildrenRunning": true
}
]
},
{
"type": "Data Mining",
"menuItems": [
{
"action": "Run All Exchange Tasks",
"label": "Run All Exchange Tasks",
"askConfirmation": true,
"confirmationLabel": "Confirm to Run",
"workDoneLabel": "Run Request Sent",
"iconPathOn": "paper-plane",
"iconPathOff": "paper-plane",
"actionFunction": "payload.onMenuItemClick"
},
{
"action": "Stop All Exchange Tasks",
"label": "Stop All Exchange Tasks",
"askConfirmation": true,
"confirmationLabel": "Confirm to Stop",
"workDoneLabel": "Stop Request Sent",
"iconPathOn": "stop",
"iconPathOff": "stop",
"actionFunction": "payload.onMenuItemClick"
},
{
"action": "Add UI Object",
"label": "Add Exchange Tasks",
"relatedUiObject": "Exchange Tasks",
"actionFunction": "payload.onMenuItemClick"
},
{
"action": "Delete UI Object",
"askConfirmation": true,
@@ -5670,9 +5733,9 @@
"propertyNameAtParent": "dataMining",
"properties": [
{
"name": "taskManagers",
"name": "exchangeTasks",
"type": "array",
"childType": "Task Manager",
"childType": "Exchange Tasks",
"autoAdd": true,
"monitorChildrenRunning": true
}
@@ -5681,10 +5744,30 @@
{
"type": "Testing Environment",
"menuItems": [
{
"action": "Run All Exchange Tasks",
"label": "Run All Exchange Tasks",
"askConfirmation": true,
"confirmationLabel": "Confirm to Run",
"workDoneLabel": "Run Request Sent",
"iconPathOn": "paper-plane",
"iconPathOff": "paper-plane",
"actionFunction": "payload.onMenuItemClick"
},
{
"action": "Stop All Exchange Tasks",
"label": "Stop All Exchange Tasks",
"askConfirmation": true,
"confirmationLabel": "Confirm to Stop",
"workDoneLabel": "Stop Request Sent",
"iconPathOn": "stop",
"iconPathOff": "stop",
"actionFunction": "payload.onMenuItemClick"
},
{
"action": "Add UI Object",
"label": "Add Task Manager",
"relatedUiObject": "Task Manager",
"label": "Add Exchange Tasks",
"relatedUiObject": "Exchange Tasks",
"actionFunction": "payload.onMenuItemClick"
},
{
@@ -5710,16 +5793,43 @@
"type": "array",
"childType": "Task Manager",
"autoAdd": true
},
{
"name": "exchangeTasks",
"type": "array",
"childType": "Exchange Tasks",
"autoAdd": true,
"monitorChildrenRunning": true
}
]
},
{
"type": "Production Environment",
"menuItems": [
{
"action": "Run All Exchange Tasks",
"label": "Run All Exchange Tasks",
"askConfirmation": true,
"confirmationLabel": "Confirm to Run",
"workDoneLabel": "Run Request Sent",
"iconPathOn": "paper-plane",
"iconPathOff": "paper-plane",
"actionFunction": "payload.onMenuItemClick"
},
{
"action": "Stop All Exchange Tasks",
"label": "Stop All Exchange Tasks",
"askConfirmation": true,
"confirmationLabel": "Confirm to Stop",
"workDoneLabel": "Stop Request Sent",
"iconPathOn": "stop",
"iconPathOff": "stop",
"actionFunction": "payload.onMenuItemClick"
},
{
"action": "Add UI Object",
"label": "Add Task Manager",
"relatedUiObject": "Task Manager",
"label": "Add Exchange Tasks",
"relatedUiObject": "Exchange Tasks",
"actionFunction": "payload.onMenuItemClick"
},
{
@@ -5745,6 +5855,55 @@
"type": "array",
"childType": "Task Manager",
"autoAdd": true
},
{
"name": "exchangeTasks",
"type": "array",
"childType": "Exchange Tasks",
"autoAdd": true,
"monitorChildrenRunning": true
}
]
},
{
"type": "Exchange Data Products",
"menuItems": [
{
"action": "Add UI Object",
"label": "Add Single Market Data",
"relatedUiObject": "Single Market Data",
"actionFunction": "payload.onMenuItemClick"
},
{
"action": "Delete UI Object",
"askConfirmation": true,
"confirmationLabel": "Confirm to Delete",
"label": "Delete Data Storage",
"iconPathOn": "delete",
"iconPathOff": "delete",
"actionFunction": "payload.onMenuItemClick"
}
],
"alternativeIcons": "Use Reference Parent",
"title": [
"Use Reference Parent"
],
"isTitleAllwaysVisible": true,
"addLeftIcons": true,
"level": 3,
"icon": "crypto-exchange",
"referenceAttachesTo": {
"compatibleTypes": "->Crypto Exchange->"
},
"chainAttachesTo": {
"compatibleTypes": "->Session Independent Data->"
},
"propertyNameAtParent": "exchangeDataProducts",
"properties": [
{
"name": "singleMarketData",
"type": "array",
"childType": "Single Market Data"
}
]
},
@@ -5753,8 +5912,8 @@
"menuItems": [
{
"action": "Add UI Object",
"label": "Add Single Market Data",
"relatedUiObject": "Single Market Data",
"label": "Add Exchange",
"relatedUiObject": "Exchange Data Products",
"actionFunction": "payload.onMenuItemClick"
},
{
@@ -5776,10 +5935,45 @@
"propertyNameAtParent": "sessionIndependentData",
"properties": [
{
"name": "singleMarketData",
"name": "exchangeDataProducts",
"type": "array",
"childType": "Single Market Data",
"autoAdd": true
"childType": "Exchange Data Products"
}
]
},
{
"type": "Exchange Sessions",
"menuItems": [
{
"action": "Delete UI Object",
"askConfirmation": true,
"confirmationLabel": "Confirm to Delete",
"label": "Delete Exchange Sessions",
"iconPathOn": "delete",
"iconPathOff": "delete",
"actionFunction": "payload.onMenuItemClick"
}
],
"alternativeIcons": "Use Reference Parent",
"title": [
"Use Reference Parent"
],
"isTitleAllwaysVisible": true,
"addLeftIcons": true,
"level": 3,
"icon": "crypto-exchange",
"referenceAttachesTo": {
"compatibleTypes": "->Crypto Exchange->"
},
"chainAttachesTo": {
"compatibleTypes": "->Data Storage->"
},
"propertyNameAtParent": "exchangeSessions",
"properties": [
{
"name": "sessionReferences",
"type": "array",
"childType": "Session Reference"
}
]
},
@@ -5788,8 +5982,8 @@
"menuItems": [
{
"action": "Add UI Object",
"label": "Add Session Reference",
"relatedUiObject": "Session Reference",
"label": "Add Exchange Sessions",
"relatedUiObject": "Exchange Sessions",
"actionFunction": "payload.onMenuItemClick"
},
{
@@ -5815,6 +6009,12 @@
"type": "array",
"childType": "Session Reference",
"autoAdd": true
},
{
"name": "exchangeSessions",
"type": "array",
"childType": "Exchange Sessions",
"autoAdd": true
}
]
},
@@ -5852,7 +6052,7 @@
"compatibleTypes": "->Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->"
},
"chainAttachesTo": {
"compatibleTypes": "->Session Based Data->Template Structure->"
"compatibleTypes": "->Exchange Sessions->Template Structure->"
},
"propertyNameAtParent": "sessionReferences",
"properties": [
@@ -5895,7 +6095,7 @@
"compatibleTypes": "->Market->"
},
"chainAttachesTo": {
"compatibleTypes": "->Session Independent Data->Session Reference->Template Structure->"
"compatibleTypes": "->Exchange Data Products->Session Reference->Template Structure->"
},
"propertyNameAtParent": "singleMarketData",
"properties": [
+3 -29
View File
@@ -48,8 +48,6 @@ function newTimeMachine () {
let syncWithDesignerLoop = 0
let timelineChartsMap = new Map()
let onViewportPositionChangedEventSuscriptionId
let onViewportZoomChangedEventSuscriptionId
let onMouseOverEventSuscriptionId
let onMouseNotOverEventSuscriptionId
let timeScaleMouseOverEventSuscriptionId
@@ -74,8 +72,6 @@ function newTimeMachine () {
}
function finalize () {
canvas.chartingSpace.viewport.eventHandler.stopListening(onViewportPositionChangedEventSuscriptionId)
canvas.chartingSpace.viewport.eventHandler.stopListening(onViewportZoomChangedEventSuscriptionId)
timeMachineCoordinateSystem.eventHandler.stopListening(onScaleChangedEventSubscriptionId)
if (thisObject.timeScale !== undefined) {
@@ -148,8 +144,6 @@ function newTimeMachine () {
onMouseOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
onMouseNotOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
onViewportPositionChangedEventSuscriptionId = canvas.chartingSpace.viewport.eventHandler.listenToEvent('Position Changed', onViewportPositionChanged)
onViewportZoomChangedEventSuscriptionId = canvas.chartingSpace.viewport.eventHandler.listenToEvent('Zoom Changed', onViewportZoomChanged)
onScaleChangedEventSubscriptionId = timeMachineCoordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged)
thisObject.edgeEditor = newEdgeEditor()
@@ -314,36 +308,17 @@ function newTimeMachine () {
}
}
function onViewportZoomChanged (event) {
if (thisObject.container.frame.isInViewPort()) {
recalculateCurrentDatetime()
}
}
function onViewportPositionChanged () {
if (thisObject.container.frame.isInViewPort()) {
recalculateCurrentDatetime()
}
}
function onScaleChanged () {
recalculateCurrentDatetime()
}
function recalculateCurrentDatetime () {
/*
The view port was moved or the view port zoom level was changed and the center of the screen points to a different datetime that we
must calculate.
*/
let center = {
x: (canvas.chartingSpace.viewport.visibleArea.bottomRight.x - canvas.chartingSpace.viewport.visibleArea.bottomLeft.x) / 2,
y: (canvas.chartingSpace.viewport.visibleArea.bottomRight.y - canvas.chartingSpace.viewport.visibleArea.topRight.y) / 2
x: thisObject.container.frame.width / 2,
y: thisObject.container.frame.height / 2
}
center = unTransformThisPoint(center, thisObject.container)
center = timeMachineCoordinateSystem.unInverseTransform(center, thisObject.container.frame.height)
datetime = new Date(center.x)
datetime = new Date(getDateFromPointAtContainer(center, thisObject.container, timeMachineCoordinateSystem))
for (let i = 0; i < thisObject.timelineCharts.length; i++) {
let timelineChart = thisObject.timelineCharts[i]
@@ -729,4 +704,3 @@ function newTimeMachine () {
)
}
}
@@ -10,11 +10,40 @@ function newSuperScriptsFunctions () {
let clone = functionLibraryNodeCloning.getNodeClone
let executionResult = true
function setup (templateClone, target) {
function setup (templateClone, target, exchange, exchangeNodeType, arrayPropertyName) {
spawnPosition.x = target.payload.position.x
spawnPosition.y = target.payload.position.y
functionLibraryUiObjectsFromNodes.createUiObjectFromNode(templateClone, target, target)
if (exchange === undefined) {
functionLibraryUiObjectsFromNodes.createUiObjectFromNode(templateClone, target, target)
} else {
let definition = APP_SCHEMA_MAP.get(target.type)
for (let i = 0; i < definition.properties.length; i++) {
let property = definition.properties[i]
if (property.childType === exchangeNodeType) {
let exchanges = target[property.name]
if (exchanges === undefined) {
exchanges = []
}
let targetExchange
for (let j = 0; j < exchanges.length; j++) {
let thisExchange = exchanges[j]
if (thisExchange.payload.referenceParent !== undefined) {
if (thisExchange.payload.referenceParent.id === exchange.id) {
targetExchange = thisExchange
}
}
}
if (targetExchange === undefined) {
targetExchange = functionLibraryUiObjectsFromNodes.addUIObject(target, exchangeNodeType)
targetExchange.payload.referenceParent = exchange
}
let nodesArray = targetExchange[arrayPropertyName]
nodesArray.push(templateClone)
functionLibraryUiObjectsFromNodes.createUiObjectFromNode(templateClone, targetExchange, targetExchange)
}
}
}
}
function deleteNode (node) {
@@ -5,7 +5,9 @@ function newTaskFunctions () {
runAllTasks: runAllTasks,
stopAllTasks: stopAllTasks,
runAllTaskManagers: runAllTaskManagers,
stopAllTaskManagers: stopAllTaskManagers
stopAllTaskManagers: stopAllTaskManagers,
runAllExchangeTasks: runAllExchangeTasks,
stopAllExchangeTasks: stopAllExchangeTasks
}
return thisObject
@@ -110,9 +112,9 @@ function newTaskFunctions () {
}
}
function runAllTaskManagers (dataMining, functionLibraryProtocolNode) {
for (let i = 0; i < dataMining.taskManagers.length; i++) {
let node = dataMining.taskManagers[i]
function runAllTaskManagers (parent, functionLibraryProtocolNode) {
for (let i = 0; i < parent.taskManagers.length; i++) {
let node = parent.taskManagers[i]
let menu = node.payload.uiObject.menu
menu.internalClick('Run All Tasks')
@@ -120,13 +122,32 @@ function newTaskFunctions () {
}
}
function stopAllTaskManagers (dataMining, functionLibraryProtocolNode) {
for (let i = 0; i < dataMining.taskManagers.length; i++) {
let node = dataMining.taskManagers[i]
function stopAllTaskManagers (parent, functionLibraryProtocolNode) {
for (let i = 0; i < parent.taskManagers.length; i++) {
let node = parent.taskManagers[i]
let menu = node.payload.uiObject.menu
menu.internalClick('Stop All Tasks')
menu.internalClick('Stop All Tasks')
}
}
function runAllExchangeTasks (parent, functionLibraryProtocolNode) {
for (let i = 0; i < parent.exchangeTasks.length; i++) {
let node = parent.exchangeTasks[i]
let menu = node.payload.uiObject.menu
menu.internalClick('Run All Task Managers')
menu.internalClick('Run All Task Managers')
}
}
function stopAllExchangeTasks (parent, functionLibraryProtocolNode) {
for (let i = 0; i < parent.exchangeTasks.length; i++) {
let node = parent.exchangeTasks[i]
let menu = node.payload.uiObject.menu
menu.internalClick('Stop All Task Managers')
menu.internalClick('Stop All Task Managers')
}
}
}
+16 -12
View File
@@ -183,22 +183,16 @@ function newWorkspace () {
for (let j = 0; j < rootNode.networkNodes.length; j++) {
let networkNode = rootNode.networkNodes[j]
if (networkNode.dataMining !== undefined) {
for (let i = 0; i < networkNode.dataMining.taskManagers.length; i++) {
let taskManager = networkNode.dataMining.taskManagers[i]
taskManager.payload.uiObject.menu.internalClick('Stop All Tasks')
}
networkNode.dataMining.payload.uiObject.menu.internalClick('Stop All Exchange Tasks')
networkNode.dataMining.payload.uiObject.menu.internalClick('Stop All Exchange Tasks')
}
if (networkNode.testingEnvironment !== undefined) {
for (let i = 0; i < networkNode.testingEnvironment.taskManagers.length; i++) {
let taskManager = networkNode.testingEnvironment.taskManagers[i]
taskManager.payload.uiObject.menu.internalClick('Stop All Tasks')
}
networkNode.testingEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Tasks')
networkNode.testingEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Tasks')
}
if (networkNode.productionEnvironment !== undefined) {
for (let i = 0; i < networkNode.productionEnvironment.taskManagers.length; i++) {
let taskManager = networkNode.productionEnvironment.taskManagers[i]
taskManager.payload.uiObject.menu.internalClick('Stop All Tasks')
}
networkNode.productionEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Tasks')
networkNode.productionEnvironment.payload.uiObject.menu.internalClick('Stop All Exchange Tasks')
}
}
}
@@ -366,6 +360,16 @@ function newWorkspace () {
functionLibraryTaskFunctions.stopAllTaskManagers(payload.node, functionLibraryProtocolNode)
}
break
case 'Run All Exchange Tasks':
{
functionLibraryTaskFunctions.runAllExchangeTasks(payload.node, functionLibraryProtocolNode)
}
break
case 'Stop All Exchange Tasks':
{
functionLibraryTaskFunctions.stopAllExchangeTasks(payload.node, functionLibraryProtocolNode)
}
break
case 'Run Session':
{
functionLibrarySessionFunctions.runSession(payload.node, functionLibraryProtocolNode, callBackFunction)
+1
View File
@@ -287,6 +287,7 @@ function newUiObject () {
let property = nodeDefinition.properties[i]
if (property.monitorChildrenRunning === true) {
let children = thisObject.payload.node[property.name]
if (children === undefined) { continue }
let totalRunning = 0
for (let j = 0; j < children.length; j++) {
let child = children[j]
+1
View File
@@ -42,6 +42,7 @@ function loadPropertyFromNodeConfig (payload, propertyName) {
}
function saveFrame (payload, frame) {
if (frame.position.x === 0 && frame.position.y === 0) { return }
payload.frame = {
position: {
x: frame.position.x,
@@ -20,7 +20,7 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt
const ONE_MIN = 60000
const ONE_DAY = ONE_MIN * 60 * 24
const MAX_OHLCVs_PER_EXECUTION = 500000
const MAX_OHLCVs_PER_EXECUTION = 1000000
const symbol = bot.market.baseAsset + '/' + bot.market.quotedAsset
const ccxt = require('ccxt')
@@ -694,7 +694,7 @@
elementsPlotted++
}
browserCanvasContext.closePath();
if (lowResolution === false) {
+1 -1
View File
@@ -177,7 +177,7 @@ function bootLoader() {
}
if (global.TASK_NODE.bot.processes[processIndex].marketReference.referenceParent === undefined) {
console.log("[WARN] Task Server -> server -> bootLoader -> Market Reference without a Reference Parent. This process will not be executed. -> Process Instance = " + JSON.stringify(global.TASK_NODE.bot.processes[processIndex].marketReference));
console.log("[WARN] Task Server -> server -> bootLoader -> Market Reference without a Reference Parent. This process will not be executed. -> Process Instance = " + JSON.stringify(global.TASK_NODE.bot.processes[processIndex].marketReference) + ", bot = " + global.TASK_NODE.bot.name);
continue
}
+1 -1
View File
@@ -1 +1 @@
{"type":"Workspace","name":"My Workspace","rootNodes":[{"type":"Network","name":"Superalgos","networkNodes":[{"type":"Network Node","name":"My Computer","dataStorage":{"type":"Data Storage","name":"New Data Storage","sessionIndependentData":{"type":"Session Independent Data","name":"New Session Independent Data","singleMarketData":[{"type":"Single Market Data","name":"Binance BTC/USDT","dataProducts":[{"type":"Data Product","name":"Candles","id":"592901f9-9d7e-4d02-9c3e-9941fd1cbc62","savedPayload":{"position":{"x":25077.92118083212,"y":30760.520078448346},"targetPosition":{"x":24832.704328476622,"y":30358.975810950342},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Candles","id":"fe6065ec-4d2d-47a0-bae0-8647f0e195d7"}}},{"type":"Data Product","name":"Volumes","id":"54e5d587-dae5-4901-8625-899f3b6eb361","savedPayload":{"position":{"x":24999.96233239647,"y":30798.741502613975},"targetPosition":{"x":24832.704328476622,"y":30358.975810950342},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Volumes","id":"1a366aef-efef-470e-88e0-2a6fbe4dd91f"}}},{"type":"Data Product","name":"Candle-Stairs","id":"7f5856c1-cf3a-4525-8036-69da93e57771","savedPayload":{"position":{"x":24916.307713241193,"y":30821.98723359081},"targetPosition":{"x":24832.704328476622,"y":30358.975810950342},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Candle-Stairs","id":"642474e9-da61-4168-97dc-7f7869bebc02"}}},{"type":"Data Product","name":"Volume-Stairs","id":"fad346d0-20f9-4cf4-9663-7eb54622b5f0","savedPayload":{"position":{"x":24829.80608108897,"y":30829.46566589062},"targetPosition":{"x":24832.704328476622,"y":30358.975810950342},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Volume-Stairs","id":"846e9572-c4d6-4c7e-942e-c82402c5ecea"}}},{"type":"Data Product","name":"Bollinger Bands","id":"2fc1f392-7d9b-409e-9cb7-85c14e1e7c07","savedPayload":{"position":{"x":24743.403145275464,"y":30820.922130470823},"targetPosition":{"x":24832.704328476622,"y":30358.975810950342},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Bollinger Bands","id":"29088877-8d63-4217-8d34-8742afc262f4"}}},{"type":"Data Product","name":"Percentage Bandwidth","id":"e7c4252c-3b6b-4b21-9f7a-6a6263739835","savedPayload":{"position":{"x":24660.04125415091,"y":30796.647567183296},"targetPosition":{"x":24832.704328476622,"y":30358.975810950342},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Percentage Bandwidth","id":"3b7885a0-cd72-4a3f-a38b-3dc8c47bd068"}}},{"type":"Data Product","name":"Bollinger Channels Objects","id":"3e9c58db-ca68-4089-9a02-d99f01428a41","savedPayload":{"position":{"x":24582.55919693599,"y":30757.468617166673},"targetPosition":{"x":24832.704328476622,"y":30358.975810950342},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Bollinger Channels Objects","id":"1f111f72-624f-4166-9f99-ab8d785d5267"}}},{"type":"Data Product","name":"Bollinger Sub-Channels Objects","id":"b47bf5eb-2f3e-462f-aa45-8e5c6ae784bc","savedPayload":{"position":{"x":24513.595532159667,"y":30704.71947257379},"targetPosition":{"x":24832.704328476622,"y":30358.975810950342},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Bollinger Sub-Channels Objects","id":"080c87fc-4546-4482-ab11-180a33f6d9ab"}}},{"type":"Data Product","name":"Popular SMAs","id":"67a989ee-e8da-4079-9b0a-8a7509db45a5","savedPayload":{"position":{"x":24455.498734713103,"y":30640.196442258137},"targetPosition":{"x":24832.704328476622,"y":30358.975810950342},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Popular SMAs","id":"4029d5bf-a8ad-4d80-b874-2af506e0ab34"}}},{"type":"Data Product","name":"Base7 SMAs","id":"763cde69-4a76-498f-a753-87baa3b227f3","savedPayload":{"position":{"x":24410.247221353908,"y":30566.09678063027},"targetPosition":{"x":24832.704328476622,"y":30358.975810950342},"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","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":"592901f9-9d7e-4d02-9c3e-9941fd1cbc62","savedPayload":{"position":{"x":25504.760548571518,"y":30474.545725692617},"targetPosition":{"x":25159.58206404965,"y":30546.012914365223},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Candles","id":"fe6065ec-4d2d-47a0-bae0-8647f0e195d7"}}},{"type":"Data Product","name":"Volumes","id":"54e5d587-dae5-4901-8625-899f3b6eb361","savedPayload":{"position":{"x":25512.0152903826,"y":30539.188970481562},"targetPosition":{"x":25159.58206404965,"y":30546.012914365223},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Volumes","id":"1a366aef-efef-470e-88e0-2a6fbe4dd91f"}}},{"type":"Data Product","name":"Candle-Stairs","id":"7f5856c1-cf3a-4525-8036-69da93e57771","savedPayload":{"position":{"x":25507.268341367977,"y":30604.064596495053},"targetPosition":{"x":25159.58206404965,"y":30546.012914365223},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Candle-Stairs","id":"642474e9-da61-4168-97dc-7f7869bebc02"}}},{"type":"Data Product","name":"Volume-Stairs","id":"fad346d0-20f9-4cf4-9663-7eb54622b5f0","savedPayload":{"position":{"x":25490.681353183005,"y":30666.963342098927},"targetPosition":{"x":25159.58206404965,"y":30546.012914365223},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Volume-Stairs","id":"846e9572-c4d6-4c7e-942e-c82402c5ecea"}}},{"type":"Data Product","name":"Bollinger Bands","id":"2fc1f392-7d9b-409e-9cb7-85c14e1e7c07","savedPayload":{"position":{"x":25462.819175816425,"y":30725.74326595038},"targetPosition":{"x":25159.58206404965,"y":30546.012914365223},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Bollinger Bands","id":"29088877-8d63-4217-8d34-8742afc262f4"}}},{"type":"Data Product","name":"Percentage Bandwidth","id":"e7c4252c-3b6b-4b21-9f7a-6a6263739835","savedPayload":{"position":{"x":25424.630622301454,"y":30778.402688241396},"targetPosition":{"x":25159.58206404965,"y":30546.012914365223},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Percentage Bandwidth","id":"3b7885a0-cd72-4a3f-a38b-3dc8c47bd068"}}},{"type":"Data Product","name":"Bollinger Channels Objects","id":"3e9c58db-ca68-4089-9a02-d99f01428a41","savedPayload":{"position":{"x":25377.416158025928,"y":30823.148355503872},"targetPosition":{"x":25159.58206404965,"y":30546.012914365223},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Bollinger Channels Objects","id":"1f111f72-624f-4166-9f99-ab8d785d5267"}}},{"type":"Data Product","name":"Bollinger Sub-Channels Objects","id":"b47bf5eb-2f3e-462f-aa45-8e5c6ae784bc","savedPayload":{"position":{"x":25322.783614943237,"y":30858.456507705698},"targetPosition":{"x":25159.58206404965,"y":30546.012914365223},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Bollinger Sub-Channels Objects","id":"080c87fc-4546-4482-ab11-180a33f6d9ab"}}},{"type":"Data Product","name":"Popular SMAs","id":"67a989ee-e8da-4079-9b0a-8a7509db45a5","savedPayload":{"position":{"x":25262.59343878355,"y":30883.1247680711},"targetPosition":{"x":25159.58206404965,"y":30546.012914365223},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3},"uiObject":{},"referenceParent":{"type":"Product Definition","name":"Popular SMAs","id":"4029d5bf-a8ad-4d80-b874-2af506e0ab34"}}},{"type":"Data Product","name":"Base7 SMAs","id":"763cde69-4a76-498f-a753-87baa3b227f3","savedPayload":{"position":{"x":25198.895333805827,"y":30896.31308857965},"targetPosition":{"x":25159.58206404965,"y":30546.012914365223},"floatingLine truncated