diff --git a/ChartsSpace/PlottersManager.js b/ChartsSpace/PlottersManager.js index 16ffb3acf..ef59d597b 100644 --- a/ChartsSpace/PlottersManager.js +++ b/ChartsSpace/PlottersManager.js @@ -142,6 +142,10 @@ function newPlottersManager () { function initializeCompetitionPlotters (callBack) { try { + /* Disabling this functionality since it is not currently available */ + callBack(GLOBAL.DEFAULT_OK_RESPONSE) + return + /* At this current version of the platform, we will support only one competition with only one plotter. */ const COMPETITION_HOST = 'AAMasters' @@ -214,7 +218,7 @@ function newPlottersManager () { let imageId = participant.devTeam + '.' + participant.profilePicture const TEAM = devTeam.codeName.toLowerCase() const BOT = bot.codeName.toLowerCase() - +/* let botAvatar = new Image() botAvatar.src = window.canvasApp.context.fbProfileImages.get(TEAM + '-' + BOT) competitionPlotter.plotter.payload[k].profile.title = bot.displayName @@ -225,6 +229,8 @@ function newPlottersManager () { function onProfileBallCreated (err, pProfileHandle) { competitionPlotter.plotter.payload[k].profile.handle = pProfileHandle } + +*/ } } callBack(GLOBAL.DEFAULT_OK_RESPONSE) diff --git a/CockpitSpace/FullScreen.js b/CockpitSpace/FullScreen.js index 2218de0c0..8f204e3b7 100644 --- a/CockpitSpace/FullScreen.js +++ b/CockpitSpace/FullScreen.js @@ -78,10 +78,12 @@ function newFullScreen () { thisObject.status = 'On' goFullscreen() CURRENT_TOP_MARGIN = 0 + AT_FULL_SCREEN_MODE = true } else { thisObject.status = 'Off' goOutFullscreen() CURRENT_TOP_MARGIN = window.canvasApp.topMargin + AT_FULL_SCREEN_MODE = false } } diff --git a/CockpitSpace/RestartSimulation.js b/CockpitSpace/RestartSimulation.js index 927f82c75..15fbf7fa8 100644 --- a/CockpitSpace/RestartSimulation.js +++ b/CockpitSpace/RestartSimulation.js @@ -196,7 +196,7 @@ function newRestartSimulation () { } function executionFocusPhysics () { - if (canvas.strategySpace.workspace.tradingSystem !== undefined) { + if (canvas.strategySpace.workspace.definition !== undefined) { executionFocusExists = true } else { executionFocusExists = false diff --git a/Dashboard.js b/Dashboard.js index 4e69b50cb..4811d2b5a 100644 --- a/Dashboard.js +++ b/Dashboard.js @@ -7,9 +7,9 @@ try { viewPort = newViewPort() } catch (e) { setTimeout(() => { - console.log("Loading deferred.") + console.log('Loading deferred.') viewPort = newViewPort() - }, 1000); + }, 1000) } function newDashboard () { @@ -36,19 +36,25 @@ function newDashboard () { if (canvas !== undefined) { canvas.finalize() } + /* Here we check where we are executing. In case we are Local we need to create a Local Dummy User and Team. */ + + if (window.canvasApp.executingAt === 'Local') { + window.localStorage.setItem(LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY, 'Local Access Token') // Dummy Access Token + window.localStorage.setItem(LOGGED_IN_USER_LOCAL_STORAGE_KEY, '{"authId":"x|x","alias":"user"}') // Dummy Local User + } + /* Here we will setup the global eventHandler that will enable the Canvas App to react to events happening outside its execution scope. */ window.canvasApp.eventHandler = newEventHandler() userProfileChangedEventSubscriptionId = window.canvasApp.eventHandler.listenToEvent('User Profile Changed', userProfileChanged) browserResizedEventSubscriptionId = window.canvasApp.eventHandler.listenToEvent('Browser Resized', browserResized) - loadImages(onImagesLoaded) + /* Here we used to have a call to the Teams Module to get the profile pictures. That was removed but to keep things working, we do this: */ - function onImagesLoaded () { - /* Next we start the App */ + window.canvasApp.context.teamProfileImages = new Map() + window.canvasApp.context.fbProfileImages = new Map() - setTimeout(delayedStart, DEBUG_START_UP_DELAY) - } + setTimeout(delayedStart, DEBUG_START_UP_DELAY) } catch (err) { if (ERROR_LOG === true) { logger.write('[ERROR] start -> err = ' + err.stack) } } @@ -95,115 +101,4 @@ function newDashboard () { if (ERROR_LOG === true) { logger.write('[ERROR] browserResized -> err = ' + err.stack) } } } - - function loadImages (callBack) { - try { - const accessToken = '' - // Soon, we will need to get images from the Financial Beings Module. - - const networkInterfaceTeams = Apollo.lib.createNetworkInterface({ - uri: window.canvasApp.graphQL.masterAppApiUrl - }) - - networkInterfaceTeams.use([{ - applyMiddleware (req, next) { - req.options.headers = { - authorization: `Bearer ${accessToken}` - } - next() - } - }]) - - const apolloClientTeams = new Apollo.lib.ApolloClient({ - networkInterface: networkInterfaceTeams, - connectToDevTools: true - }) - - const ALL_TEAMS_QUERY = Apollo.gql` - { - teams_Teams{ - edges{ - node{ - id - name - slug - profile { - avatar - banner - description - motto - updatedAt - } - fb { - id - name - slug - avatar - kind - status { - status - reason - createdAt - } - } - } - } - } - } - ` - - let teams - - const getTeams = () => { - return new Promise((resolve, reject) => { - apolloClientTeams.query({ - query: ALL_TEAMS_QUERY - }) - .then(response => { - teams = response.data.teams_Teams - //window.localStorage.setItem('Teams', JSON.stringify(response.data.teams_Teams)) - resolve({ teams: response.data.teams_Teams }) - }) - .catch(err => { - if (ERROR_LOG === true) { logger.write('[ERROR] loadImages -> getTeams -> Error fetching data from Teams Module.') } - if (ERROR_LOG === true) { logger.write('[ERROR] loadImages -> getTeams -> err = ' + err.stack) } - reject(err) - }) - }) - } - - // To avoid race conditions, add asynchronous fetches to array - let fetchDataPromises = [] - - fetchDataPromises.push(/* getUser(), */ getTeams()) // <-- Here we must add the function calll to the Financial Beings module. - - // When all asynchronous fetches resolve, authenticate user or throw error. - Promise.all(fetchDataPromises).then(result => { - /* All good, we will go through the results creating a map with all the Images URLs */ - - let teamProfileImages = new Map() - let fbProfileImages = new Map() - - for (let i = 0; i < teams.edges.length; i++) { - let team = teams.edges[i].node - - teamProfileImages.set(team.slug, team.profile.avatar) - - if (team.fb.length > 0) { - fbProfileImages.set(team.slug + '-' + team.fb[0].slug, team.fb[0].avatar) - } - } - - window.canvasApp.context.teamProfileImages = teamProfileImages - window.canvasApp.context.fbProfileImages = fbProfileImages - - callBack() - }, err => { - if (ERROR_LOG === true) { logger.write('[ERROR] loadImages -> Error fetching data from Teams Module.') } - if (ERROR_LOG === true) { logger.write('[ERROR] loadImages -> err = ' + err.stack) } - }) - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] loadImages -> err = ' + err.stack) } - } - } } diff --git a/FloatingSpace/CircularMenuItem.js b/FloatingSpace/CircularMenuItem.js index d969cdb74..40f87bfa0 100644 --- a/FloatingSpace/CircularMenuItem.js +++ b/FloatingSpace/CircularMenuItem.js @@ -93,7 +93,7 @@ function newCircularMenuItem () { } function getContainer (point) { - if (thisObject.dontShowAtFullscreen === true && CURRENT_TOP_MARGIN === 0) { return } + if (thisObject.dontShowAtFullscreen === true && AT_FULL_SCREEN_MODE === true) { return } let container if (thisObject.isDeployed === true) { @@ -106,7 +106,7 @@ function newCircularMenuItem () { } function physics () { - if (thisObject.dontShowAtFullscreen === true && CURRENT_TOP_MARGIN === 0) { return } + if (thisObject.dontShowAtFullscreen === true && AT_FULL_SCREEN_MODE === true) { return } const INCREASE_STEP = 2 @@ -206,7 +206,7 @@ function newCircularMenuItem () { } function drawBackground () { - if (thisObject.dontShowAtFullscreen === true && CURRENT_TOP_MARGIN === 0) { return } + if (thisObject.dontShowAtFullscreen === true && AT_FULL_SCREEN_MODE === true) { return } if (thisObject.container.frame.position.x > 0 && thisObject.isDeployed === true && thisObject.currentRadius >= thisObject.targetRadius) { if (thisObject.type === 'Icon & Text') { @@ -231,7 +231,7 @@ function newCircularMenuItem () { } function drawForeground () { - if (thisObject.dontShowAtFullscreen === true && CURRENT_TOP_MARGIN === 0) { return } + if (thisObject.dontShowAtFullscreen === true && AT_FULL_SCREEN_MODE === true) { return } let menuPosition = { x: thisObject.currentRadius * 1.5, diff --git a/FloatingSpace/CodeEditor.js b/FloatingSpace/CodeEditor.js index 9b910f842..5bfa65232 100644 --- a/FloatingSpace/CodeEditor.js +++ b/FloatingSpace/CodeEditor.js @@ -133,7 +133,7 @@ function newCodeEditor () { let textAreaPosition = { x: 0 - thisObject.container.frame.width / 2, - y: 0 + thisObject.container.frame.height * 2 / 7 + y: 0 - thisObject.container.frame.height * 3 / 7 } textAreaPosition = thisObject.container.frame.frameThisPoint(textAreaPosition) diff --git a/FloatingSpace/StrategyPart.js b/FloatingSpace/StrategyPart.js index 049de0b79..e8653f1ad 100644 --- a/FloatingSpace/StrategyPart.js +++ b/FloatingSpace/StrategyPart.js @@ -196,6 +196,26 @@ function newStrategyPart () { let compatibleType let compatibleSubType switch (thisObject.payload.node.type) { + case 'Trading System': + compatibleType = '->' + 'Definition' + compatibleSubType = undefined + break + case 'Personal Data': + compatibleType = '->' + 'Definition' + compatibleSubType = undefined + break + case 'Exchange Account': + compatibleType = '->' + 'Personal Data' + compatibleSubType = undefined + break + case 'Exchange Account Asset': + compatibleType = '->' + 'Exchange Account' + compatibleSubType = undefined + break + case 'Exchange Account Key': + compatibleType = '->' + 'Exchange Account' + compatibleSubType = undefined + break case 'Parameters': compatibleType = '->' + 'Trading System' compatibleSubType = undefined @@ -248,6 +268,14 @@ function newStrategyPart () { compatibleType = '->' + 'Open Stage' compatibleSubType = undefined break + case 'Open Execution': + compatibleType = '->' + 'Open Stage' + compatibleSubType = undefined + break + case 'Close Execution': + compatibleType = '->' + 'Close Stage' + compatibleSubType = undefined + break case 'Stop': compatibleType = '->' + 'Manage Stage' + '->' + 'Initial Definition' compatibleSubType = undefined @@ -294,6 +322,8 @@ function newStrategyPart () { let nearbyNode = floatingObject.payload.node if (compatibleType.indexOf('->' + nearbyNode.type) >= 0) { /* Discard objects with busy coonection ports */ + if (thisObject.payload.node.type === 'Trading System' && nearbyNode.tradingSystem !== undefined) { continue } + if (thisObject.payload.node.type === 'Personal Data' && nearbyNode.personalData !== undefined) { continue } if (thisObject.payload.node.type === 'Parameters' && nearbyNode.parameters !== undefined) { continue } if (thisObject.payload.node.type === 'Base Asset' && nearbyNode.baseAsset !== undefined) { continue } if (thisObject.payload.node.type === 'Trigger Stage' && nearbyNode.triggerStage !== undefined) { continue } @@ -306,6 +336,8 @@ function newStrategyPart () { if (thisObject.payload.node.type === 'Trigger Off Event' && nearbyNode.triggerOff !== undefined) { continue } if (thisObject.payload.node.type === 'Trigger On Event' && nearbyNode.triggerOn !== undefined) { continue } if (thisObject.payload.node.type === 'Initial Definition' && nearbyNode.initialDefinition !== undefined) { continue } + if (thisObject.payload.node.type === 'Open Execution' && nearbyNode.openExecution !== undefined) { continue } + if (thisObject.payload.node.type === 'Close Execution' && nearbyNode.closeExecution !== undefined) { continue } if (thisObject.payload.node.type === 'Stop' && nearbyNode.stopLoss !== undefined) { continue } if (thisObject.payload.node.type === 'Take Profit' && nearbyNode.takeProfit !== undefined) { continue } if (thisObject.payload.node.type === 'Formula' && nearbyNode.formula !== undefined) { continue } @@ -449,8 +481,8 @@ function newStrategyPart () { } function runningPhisycs () { - if (canvas.strategySpace.workspace.tradingSystem !== undefined) { - if (canvas.strategySpace.workspace.tradingSystem.id !== thisObject.payload.node.id) { + if (canvas.strategySpace.workspace.definition !== undefined) { + if (canvas.strategySpace.workspace.definition.id !== thisObject.payload.node.id) { runningCounter-- } } @@ -467,13 +499,13 @@ function newStrategyPart () { } function setRunningStatus () { - canvas.strategySpace.workspace.tradingSystem = thisObject.payload.node + canvas.strategySpace.workspace.definition = thisObject.payload.node thisObject.isRunning = true runningCounter = 30 } function setNotRunningStatus () { - canvas.strategySpace.workspace.tradingSystem = undefined + canvas.strategySpace.workspace.definition = undefined thisObject.isRunning = false } @@ -962,4 +994,3 @@ function newStrategyPart () { } } } - diff --git a/FloatingSpace/StrategyPartConstructor.js b/FloatingSpace/StrategyPartConstructor.js index 91d34379f..92288655f 100644 --- a/FloatingSpace/StrategyPartConstructor.js +++ b/FloatingSpace/StrategyPartConstructor.js @@ -70,7 +70,7 @@ function newStrategyPartConstructor () { if (payload.node.savedPayload !== undefined) { if (payload.node.savedPayload.uiObject.isRunning === true) { strategyPart.setRunningStatus() - canvas.strategySpace.workspace.tradingSystem = payload.node + canvas.strategySpace.workspace.definition = payload.node } } @@ -92,12 +92,12 @@ function newStrategyPartConstructor () { currentStatus: false, label: undefined, visible: false, - iconPathOn: 'target', - iconPathOff: 'security', + iconPathOn: 'menu-fix-pinned', + iconPathOff: 'menu-fix-unpinned', rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: -135 + angle: -130 } ) menuItemsInitialValues.push( @@ -109,11 +109,11 @@ function newStrategyPartConstructor () { label: undefined, visible: false, iconPathOn: 'compass', - iconPathOff: 'headphones', + iconPathOff: 'compass-bw', rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: -165 + angle: -155 } ) menuItemsInitialValues.push( @@ -124,12 +124,12 @@ function newStrategyPartConstructor () { currentStatus: true, label: undefined, visible: false, - iconPathOn: 'broken-link', - iconPathOff: 'targeting', + iconPathOn: 'menu-mobility-unfreeze', + iconPathOff: 'menu-mobility-freeze', rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: 165 + angle: 180 } ) menuItemsInitialValues.push( @@ -140,12 +140,26 @@ function newStrategyPartConstructor () { currentStatus: false, label: undefined, visible: false, - iconPathOn: 'tap', - iconPathOff: 'layout', + iconPathOn: 'menu-tree-plus', + iconPathOff: 'menu-tree-minus', rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: 135 + angle: 155 + } + ) + menuItemsInitialValues.push( + { + action: 'Backup', + actionFunction: floatingObject.payload.onMenuItemClick, + label: undefined, + visible: false, + iconPathOn: 'menu-backup', + iconPathOff: 'menu-backup', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 130 } ) } @@ -164,20 +178,32 @@ function newStrategyPartConstructor () { currentStatus: true, label: undefined, visible: false, - iconPathOn: 'target', - iconPathOff: 'security', + iconPathOn: 'menu-fix-unpinned', + iconPathOff: 'menu-fix-pinned', rawRadius: 8, targetRadius: 0, currentRadius: 0, angle: -135 }, { - action: 'Download Workspace', + action: 'Backup Workspace', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: undefined, visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'menu-backup', + iconPathOff: 'menu-backup', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 130 + }, + { + action: 'Share Workspace', + actionFunction: payload.onMenuItemClick, + label: 'Share', + visible: false, + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -185,7 +211,7 @@ function newStrategyPartConstructor () { }] break } - case 'Trading System': { + case 'Definition': { floatingObject.isPinned = true floatingObject.positionLocked = true addLeftIcons(menuItemsInitialValues, floatingObject) @@ -196,7 +222,7 @@ function newStrategyPartConstructor () { label: 'Run', visible: false, iconPathOn: 'paper-plane', - iconPathOff: 'upload', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -212,8 +238,8 @@ function newStrategyPartConstructor () { workDoneLabel: 'Saved', workFailedLabel: 'Not Saved', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'menu-backup', + iconPathOff: 'menu-backup', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -222,14 +248,14 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Delete Trading System', + action: 'Delete Definition', askConfirmation: true, confirmationLabel: 'Confirm to Delete', actionFunction: payload.onMenuItemClick, - label: 'Delete Trading System', + label: 'Delete Definition', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -238,17 +264,214 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'New Strategy', + action: 'Add Trading System', actionFunction: payload.onMenuItemClick, - label: 'New Strategy', + label: 'Add Trading System', + visible: false, + relatedStrategyPart: 'Trading System', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 10 + } + ) + menuItemsInitialValues.push( + { + action: 'Add Personal Data', + actionFunction: payload.onMenuItemClick, + label: 'Add Personal Data', + visible: false, + relatedStrategyPart: 'Personal Data', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 40 + } + ) + menuItemsInitialValues.push( + { + action: 'Share', + actionFunction: payload.onMenuItemClick, + label: 'Share', + visible: false, + iconPathOn: 'share', + iconPathOff: 'share', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 70 + } + ) + break + } + case 'Personal Data': { + addLeftIcons(menuItemsInitialValues, floatingObject) + menuItemsInitialValues.push( + { + action: 'Delete Personal Data', + askConfirmation: true, + confirmationLabel: 'Confirm to Delete', + actionFunction: payload.onMenuItemClick, + label: 'Delete Personal Data', + visible: false, + iconPathOn: 'delete', + iconPathOff: 'delete', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -20 + } + ) + menuItemsInitialValues.push( + { + action: 'Add Exchange Account', + actionFunction: payload.onMenuItemClick, + label: 'Add Exchange Account', + visible: false, + relatedStrategyPart: 'Exchange Account', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: +20 + } + ) + break + } + case 'Exchange Account': { + addLeftIcons(menuItemsInitialValues, floatingObject) + menuItemsInitialValues.push( + { + action: 'Delete Exchange Account', + askConfirmation: true, + confirmationLabel: 'Confirm to Delete', + actionFunction: payload.onMenuItemClick, + label: 'Delete This Account', + visible: false, + iconPathOn: 'delete', + iconPathOff: 'delete', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -40 + } + ) + menuItemsInitialValues.push( + { + action: 'Add Exchange Account Asset', + actionFunction: payload.onMenuItemClick, + label: 'Add Asset', + visible: false, + relatedStrategyPart: 'Exchange Account Asset', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 0 + } + ) + menuItemsInitialValues.push( + { + action: 'Add Exchange Account Key', + actionFunction: payload.onMenuItemClick, + label: 'Add Key', + visible: false, + relatedStrategyPart: 'Exchange Account Key', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 40 + } + ) + break + } + case 'Exchange Account Asset': { + addLeftIcons(menuItemsInitialValues, floatingObject) + menuItemsInitialValues.push( + { + action: 'Delete Exchange Account Asset', + askConfirmation: true, + confirmationLabel: 'Confirm to Delete', + actionFunction: payload.onMenuItemClick, + label: 'Delete This Asset', + visible: false, + iconPathOn: 'delete', + iconPathOff: 'delete', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 0 + } + ) + break + } + case 'Exchange Account Key': { + strategyPart.codeEditor = newCodeEditor() + strategyPart.codeEditor.isVisibleFunction = strategyPart.isVisibleFunction + strategyPart.codeEditor.initialize() + strategyPart.codeEditor.container.connectToParent(strategyPart.container, false, false, true, true, false, false, false, false) + + addLeftIcons(menuItemsInitialValues, floatingObject) + menuItemsInitialValues.push( + { + action: 'Edit Key Value', + actionFunction: strategyPart.codeEditor.activate, + label: 'Edit Key Value', + visible: false, + iconPathOn: 'html', + iconPathOff: 'html', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -20, + dontShowAtFullscreen: true + } + ) + menuItemsInitialValues.push( + { + action: 'Delete Exchange Account Key', + askConfirmation: true, + confirmationLabel: 'Confirm to Delete', + actionFunction: payload.onMenuItemClick, + label: 'Delete This Key', + visible: false, + iconPathOn: 'delete', + iconPathOff: 'delete', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 20 + } + ) + break + } + case 'Trading System': { + addLeftIcons(menuItemsInitialValues, floatingObject) + menuItemsInitialValues.push( + { + action: 'Delete Trading System', + askConfirmation: true, + confirmationLabel: 'Confirm to Delete', + actionFunction: payload.onMenuItemClick, + label: 'Delete Trading System', + visible: false, + iconPathOn: 'delete', + iconPathOff: 'delete', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -60 + } + ) + menuItemsInitialValues.push( + { + action: 'Add Strategy', + actionFunction: payload.onMenuItemClick, + label: 'Add Strategy', visible: false, - iconPathOn: 'quality', - iconPathOff: 'quality', relatedStrategyPart: 'Strategy', rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: +10 + angle: -20 } ) menuItemsInitialValues.push( @@ -257,27 +480,25 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Parameters', visible: false, - iconPathOn: 'quality', - iconPathOff: 'quality', relatedStrategyPart: 'Parameters', rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: 40 + angle: 20 } ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: 70 + angle: 60 } ) break @@ -292,8 +513,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete Parameters', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -306,8 +527,7 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Missing Params', visible: false, - iconPathOn: 'settings', - iconPathOff: 'settings', + relatedStrategyPart: 'Parameters', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -316,12 +536,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -340,8 +560,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete Base Asset', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -354,8 +574,6 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Formula', visible: false, - iconPathOn: 'pipette', - iconPathOff: 'pipette', relatedStrategyPart: 'Formula', rawRadius: 8, targetRadius: 0, @@ -365,12 +583,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -387,8 +605,7 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Missing Stages', visible: false, - iconPathOn: 'target', - iconPathOff: 'trash', + relatedStrategyPart: 'Strategy', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -403,8 +620,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete This Strategy', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -413,12 +630,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -428,61 +645,21 @@ function newStrategyPartConstructor () { break } case 'Trigger Stage': { - menuItemsInitialValues = [ - { - action: 'Pin / Unpin', - actionFunction: floatingObject.pinToggle, - actionStatus: floatingObject.getPinStatus, - currentStatus: false, - label: undefined, - visible: false, - iconPathOn: 'target', - iconPathOff: 'security', - rawRadius: 8, - targetRadius: 0, - currentRadius: 0, - angle: -135 - }, - { - action: 'Tense / Untense', - actionFunction: floatingObject.tensionToggle, - actionStatus: floatingObject.getTensionStatus, - currentStatus: false, - label: undefined, - visible: false, - iconPathOn: 'compass', - iconPathOff: 'headphones', - rawRadius: 8, - targetRadius: 0, - currentRadius: 0, - angle: 180 - }, - { - action: 'Freeze / Unfreeze', - actionFunction: floatingObject.freezeToggle, - actionStatus: floatingObject.getFreezeStatus, - currentStatus: true, - label: undefined, - visible: false, - iconPathOn: 'targeting', - iconPathOff: 'broken-link', - rawRadius: 8, - targetRadius: 0, - currentRadius: 0, - angle: 135 - }, + addLeftIcons(menuItemsInitialValues, floatingObject) + menuItemsInitialValues.push( { action: 'Add Missing Events', actionFunction: payload.onMenuItemClick, label: 'Add Missing Events', visible: false, - iconPathOn: 'target', - iconPathOff: 'trash', + relatedStrategyPart: 'Trigger Stage', rawRadius: 8, targetRadius: 0, currentRadius: 0, angle: -40 - }, + } + ) + menuItemsInitialValues.push( { action: 'Delete Trigger Stage', askConfirmation: true, @@ -490,25 +667,28 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete This Stage', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, angle: 0 - }, + } + ) + menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, angle: 40 - }] + } + ) break } case 'Open Stage': { @@ -519,12 +699,24 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Initial Definition', visible: false, - iconPathOn: 'target', - iconPathOff: 'trash', + relatedStrategyPart: 'Initial Definition', rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: -40 + angle: -60 + } + ) + menuItemsInitialValues.push( + { + action: 'Add Open Execution', + actionFunction: payload.onMenuItemClick, + label: 'Add Open Execution', + visible: false, + relatedStrategyPart: 'Open Execution', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -20 } ) menuItemsInitialValues.push( @@ -535,26 +727,26 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete This Stage', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: 0 + angle: 20 } ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: 40 + angle: 60 } ) break @@ -567,8 +759,7 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Missing Items', visible: false, - iconPathOn: 'target', - iconPathOff: 'trash', + relatedStrategyPart: 'Manage Stage', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -583,8 +774,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete This Stage', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -593,12 +784,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -609,6 +800,19 @@ function newStrategyPartConstructor () { } case 'Close Stage': { addLeftIcons(menuItemsInitialValues, floatingObject) + menuItemsInitialValues.push( + { + action: 'Add Close Execution', + actionFunction: payload.onMenuItemClick, + label: 'Add Close Execution', + visible: false, + relatedStrategyPart: 'Close Execution', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -40 + } + ) menuItemsInitialValues.push( { action: 'Delete Close Stage', @@ -617,26 +821,26 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete This Stage', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: -20 + angle: 0 } ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: 20 + angle: 40 } ) break @@ -651,8 +855,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete Position Size', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -665,8 +869,6 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Formula', visible: false, - iconPathOn: 'pipette', - iconPathOff: 'pipette', relatedStrategyPart: 'Formula', rawRadius: 8, targetRadius: 0, @@ -676,12 +878,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -700,8 +902,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete Position Rate', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -714,8 +916,6 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Formula', visible: false, - iconPathOn: 'pipette', - iconPathOff: 'pipette', relatedStrategyPart: 'Formula', rawRadius: 8, targetRadius: 0, @@ -725,12 +925,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -747,8 +947,6 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Situation', visible: false, - iconPathOn: 'pyramid', - iconPathOff: 'pyramid', relatedStrategyPart: 'Situation', rawRadius: 8, targetRadius: 0, @@ -764,8 +962,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete This Event', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -774,12 +972,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -796,8 +994,6 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Situation', visible: false, - iconPathOn: 'pyramid', - iconPathOff: 'pyramid', relatedStrategyPart: 'Situation', rawRadius: 8, targetRadius: 0, @@ -813,8 +1009,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete This Event', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -823,12 +1019,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -845,8 +1041,6 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Situation', visible: false, - iconPathOn: 'pyramid', - iconPathOff: 'pyramid', relatedStrategyPart: 'Situation', rawRadius: 8, targetRadius: 0, @@ -862,8 +1056,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete This Event', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -872,12 +1066,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -894,8 +1088,7 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Missing Items', visible: false, - iconPathOn: 'target', - iconPathOff: 'trash', + relatedStrategyPart: 'Initial Definition', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -910,8 +1103,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete This Definition', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -920,12 +1113,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -934,6 +1127,74 @@ function newStrategyPartConstructor () { ) break } + case 'Open Execution': { + addLeftIcons(menuItemsInitialValues, floatingObject) + menuItemsInitialValues.push( + { + action: 'Delete Open Execution', + askConfirmation: true, + confirmationLabel: 'Confirm to Delete', + actionFunction: payload.onMenuItemClick, + label: 'Delete This', + visible: false, + iconPathOn: 'delete', + iconPathOff: 'delete', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -20 + } + ) + menuItemsInitialValues.push( + { + action: 'Share', + actionFunction: payload.onMenuItemClick, + label: 'Share', + visible: false, + iconPathOn: 'share', + iconPathOff: 'share', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 20 + } + ) + break + } + case 'Close Execution': { + addLeftIcons(menuItemsInitialValues, floatingObject) + menuItemsInitialValues.push( + { + action: 'Delete Close Execution', + askConfirmation: true, + confirmationLabel: 'Confirm to Delete', + actionFunction: payload.onMenuItemClick, + label: 'Delete This', + visible: false, + iconPathOn: 'delete', + iconPathOff: 'delete', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -20 + } + ) + menuItemsInitialValues.push( + { + action: 'Share', + actionFunction: payload.onMenuItemClick, + label: 'Share', + visible: false, + iconPathOn: 'share', + iconPathOff: 'share', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 20 + } + ) + break + } case 'Stop': { addLeftIcons(menuItemsInitialValues, floatingObject) menuItemsInitialValues.push( @@ -942,8 +1203,6 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Phase', visible: false, - iconPathOn: 'placeholder', - iconPathOff: 'placeholder', relatedStrategyPart: 'Phase', rawRadius: 8, targetRadius: 0, @@ -959,8 +1218,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete This Item', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -969,12 +1228,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -991,8 +1250,6 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Phase', visible: false, - iconPathOn: 'placeholder', - iconPathOff: 'placeholder', relatedStrategyPart: 'Phase', rawRadius: 8, targetRadius: 0, @@ -1008,8 +1265,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete This Item', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -1018,12 +1275,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -1040,8 +1297,6 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Formula', visible: false, - iconPathOn: 'pipette', - iconPathOff: 'pipette', relatedStrategyPart: 'Formula', rawRadius: 8, targetRadius: 0, @@ -1055,8 +1310,6 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Next Phase Event', visible: false, - iconPathOn: 'pipette', - iconPathOff: 'pipette', relatedStrategyPart: 'Next Phase Event', rawRadius: 8, targetRadius: 0, @@ -1072,8 +1325,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete This Phase', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -1082,12 +1335,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -1126,8 +1379,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete This Formula', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -1136,12 +1389,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -1158,8 +1411,6 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Situation', visible: false, - iconPathOn: 'pyramid', - iconPathOff: 'pyramid', relatedStrategyPart: 'Situation', rawRadius: 8, targetRadius: 0, @@ -1175,8 +1426,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete This Event', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -1185,12 +1436,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -1207,8 +1458,6 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Condition', visible: false, - iconPathOn: 'testing', - iconPathOff: 'testing', relatedStrategyPart: 'Condition', rawRadius: 8, targetRadius: 0, @@ -1224,8 +1473,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete This Situation', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -1234,12 +1483,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -1256,8 +1505,6 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Add Code', visible: false, - iconPathOn: 'html', - iconPathOff: 'html', relatedStrategyPart: 'Code', rawRadius: 8, targetRadius: 0, @@ -1273,8 +1520,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete This Condition', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -1283,12 +1530,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -1327,8 +1574,8 @@ function newStrategyPartConstructor () { actionFunction: payload.onMenuItemClick, label: 'Delete This Code', visible: false, - iconPathOn: 'trash', - iconPathOff: 'trash', + iconPathOn: 'delete', + iconPathOff: 'delete', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -1337,12 +1584,12 @@ function newStrategyPartConstructor () { ) menuItemsInitialValues.push( { - action: 'Download', + action: 'Share', actionFunction: payload.onMenuItemClick, - label: 'Download', + label: 'Share', visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', + iconPathOn: 'share', + iconPathOff: 'share', rawRadius: 8, targetRadius: 0, currentRadius: 0, @@ -1368,10 +1615,30 @@ function newStrategyPartConstructor () { level_0() break } - case 'Trading System': { + case 'Definition': { level_0() break } + case 'Exchange Account': { + level_1() + break + } + case 'Exchange Account Asset': { + level_3() + break + } + case 'Exchange Account Key': { + level_3() + break + } + case 'Personal Data': { + level_1() + break + } + case 'Trading System': { + level_1() + break + } case 'Parameters': { level_3() break @@ -1424,6 +1691,14 @@ function newStrategyPartConstructor () { level_3() break } + case 'Open Execution': { + level_3() + break + } + case 'Close Execution': { + level_3() + break + } case 'Stop': { level_3() break diff --git a/FloatingSpace/StrategyPartTitle.js b/FloatingSpace/StrategyPartTitle.js index 27d0652d9..a47ec5402 100644 --- a/FloatingSpace/StrategyPartTitle.js +++ b/FloatingSpace/StrategyPartTitle.js @@ -48,6 +48,22 @@ function newStrategyPartTitle () { thisObject.payload = payload switch (payload.node.type) { + case 'Definition': { + thisObject.allwaysVisible = true + break + } + case 'Personal Data': { + break + } + case 'Exchange Account': { + break + } + case 'Exchange Account Asset': { + break + } + case 'Exchange Account Key': { + break + } case 'Workspace': { thisObject.allwaysVisible = true break @@ -96,6 +112,12 @@ function newStrategyPartTitle () { case 'Initial Definition': { break } + case 'Open Execution': { + break + } + case 'Close Execution': { + break + } case 'Stop': { break } diff --git a/Globals.js b/Globals.js index eebdfc073..564259e92 100644 --- a/Globals.js +++ b/Globals.js @@ -170,6 +170,7 @@ let INITIAL_TIME_PERIOD = ONE_DAY_IN_MILISECONDS // This value will be overwrit let VERY_LARGE_NUMBER = 100000000000 let CURRENT_TOP_MARGIN = window.canvasApp.topMargin +let AT_FULL_SCREEN_MODE = false let maxDate = new Date(); maxDate.setMilliseconds(0); diff --git a/Panels/ProductCard.js b/Panels/ProductCard.js index d25ca09d4..e66f90e3b 100644 --- a/Panels/ProductCard.js +++ b/Panels/ProductCard.js @@ -221,7 +221,7 @@ function newProductCard () { legacyBotAvatar.src = window.canvasApp.urlPrefix + 'Images/' + LEGACY_TEAM + '/' + REPO + '/' + PROFILE_PIC } else { /* - Here we will download the images of teams uploaded at the Teams Module. + Here we will download the images of teams shareed at the Teams Module. There might be Product Cards of bots beloging to teams not present currently at the Teams Module, in those cases nothing should happen. */ diff --git a/README.md b/README.md index 181a3e267..5acae3fca 100644 --- a/README.md +++ b/README.md @@ -284,3 +284,9 @@ In the example above, conditions A and B are mathematical comparison statements **periods:** The number of candles evaluated in the current execution. +## Maintainer + +[![Luis-Fernando-Molina](https://avatars1.githubusercontent.com/u/9479367?s=130&v=4)](https://github.com/Luis-Fernando-Molina) | +---| +[Luis-Fernando-Molina](https://github.com/jaredallard) | + diff --git a/Spaces/StrategySpace.js b/Spaces/StrategySpace.js index 848785951..c7650827d 100644 --- a/Spaces/StrategySpace.js +++ b/Spaces/StrategySpace.js @@ -39,22 +39,29 @@ function newStrategySpace () { function buildIconByPartTypeMap () { const relationshipArray = [ + ['Definition', 'text'], + ['Personal Data', 'security'], + ['Exchange Account', 'approve'], + ['Exchange Account Asset', 'paper-plane'], + ['Exchange Account Key', 'login'], ['Workspace', 'design-tool'], ['Trading System', 'analysis'], ['Parameters', 'settings'], ['Base Asset', 'sitemap'], ['Strategy', 'quality'], ['Trigger Stage', 'chronometer'], - ['Open Stage', 'photo-camera'], + ['Open Stage', 'stage-open'], ['Manage Stage', 'video-player'], - ['Close Stage', 'timeline'], + ['Close Stage', 'stage-close'], ['Position Size', 'responsive'], ['Position Rate', 'promotion'], ['Trigger On Event', 'startup'], ['Trigger Off Event', 'support'], ['Take Position Event', 'compass'], ['Initial Definition', 'task'], - ['Stop', 'pixel'], + ['Open Execution', 'piggy-bank'], + ['Close Execution', 'piggy-bank'], + ['Stop', 'stop'], ['Take Profit', 'competition'], ['Phase', 'placeholder'], ['Formula', 'pipette'], @@ -84,6 +91,7 @@ function newStrategySpace () { 'chat', 'chronometer', 'compass', + 'compass-bw', 'competition', 'content', 'design-tool', @@ -114,17 +122,27 @@ function newStrategySpace () { 'startup', 'support', 'tap', - 'target', + 'menu-fix-pinned', + 'menu-fix-unpinned', 'targeting', 'task', 'testing', 'text', 'timeline', 'tools', - 'trash', + 'delete', 'upload', 'vector', - 'video-player' + 'video-player', + 'menu-mobility-freeze', + 'menu-mobility-unfreeze', + 'menu-tree-minus', + 'menu-tree-plus', + 'menu-backup', + 'share', + 'stop', + 'stage-open', + 'stage-close' ] for (let i = 0; i < iconsNames.length; i++) { diff --git a/SplashScreen.js b/SplashScreen.js index da250bd39..a4c43f411 100644 --- a/SplashScreen.js +++ b/SplashScreen.js @@ -100,7 +100,7 @@ function newSplashScreen () { /* Second the % of Advance. */ let label = '' + Math.trunc(stepsInitializationCounter) + ' %' - stepsInitializationCounter = stepsInitializationCounter + 0.5 + stepsInitializationCounter = stepsInitializationCounter + 1.0 if (stepsInitializationCounter > 99) { splashScreenNeeded = false diff --git a/StrategySpace/StrategizerGateway.js b/StrategySpace/StrategizerGateway.js index 589ff517e..fa7fbfcad 100644 --- a/StrategySpace/StrategizerGateway.js +++ b/StrategySpace/StrategizerGateway.js @@ -46,40 +46,48 @@ function newStrategizerGateway () { } user = JSON.parse(user) - let fbSlug = 'simulator-bot-' + user.alias.replace('.', '') - graphQLServer = await axios({ - url: window.canvasApp.graphQL.masterAppApiUrl, - method: 'post', - data: { - query: - ` - query($fbSlug: String!){ - strategizer_TradingSystemByFb(fbSlug: $fbSlug){ - id - fbSlug - data - } - } - `, - - variables: { - fbSlug: fbSlug - } - }, - headers: { - authorization: 'Bearer ' + accessToken - } - }) - - if (graphQLServer.data.errors) { - logger.write('[ERROR] loadFromStrategyzer -> GraphQL Error: ' + JSON.stringify(graphQLServer.data.errors)) - return false - } else { - thisObject.strategizerData = JSON.parse(JSON.stringify(graphQLServer.data.data.strategizer_TradingSystemByFb.data)) - thisObject.idAtStrategizer = graphQLServer.data.data.strategizer_TradingSystemByFb.id - window.localStorage.setItem(CANVAS_APP_NAME + '.' + MODULE_NAME + '.' + user.alias, thisObject.idAtStrategizer) + if (window.canvasApp.executingAt === 'Local') { + window.localStorage.setItem(CANVAS_APP_NAME + '.' + MODULE_NAME + '.' + user.alias, 'Local File') + thisObject.strategizerData = JSON.parse('{"type":"Definition"}') + thisObject.idAtStrategizer = 'Local File' return true + } else { + let fbSlug = 'simulator-bot-' + user.alias.replace('.', '') + + graphQLServer = await axios({ + url: window.canvasApp.graphQL.masterAppApiUrl, + method: 'post', + data: { + query: + ` + query($fbSlug: String!){ + strategizer_TradingSystemByFb(fbSlug: $fbSlug){ + id + fbSlug + data + } + } + `, + + variables: { + fbSlug: fbSlug + } + }, + headers: { + authorization: 'Bearer ' + accessToken + } + }) + + if (graphQLServer.data.errors) { + logger.write('[ERROR] loadFromStrategyzer -> GraphQL Error: ' + JSON.stringify(graphQLServer.data.errors)) + return false + } else { + thisObject.strategizerData = JSON.parse(JSON.stringify(graphQLServer.data.data.strategizer_TradingSystemByFb.data)) + thisObject.idAtStrategizer = graphQLServer.data.data.strategizer_TradingSystemByFb.id + window.localStorage.setItem(CANVAS_APP_NAME + '.' + MODULE_NAME + '.' + user.alias, thisObject.idAtStrategizer) + return true + } } } catch (err) { logger.write('[ERROR] loadFromStrategyzer -> err = ' + err.stack) @@ -100,10 +108,6 @@ function newStrategizerGateway () { return } - user = JSON.parse(user) - - /* See if we need to update or create a new record at the strategizer */ - let tradingSystem = canvas.strategySpace.workspace.getProtocolTradingSystem() if (tradingSystem === undefined || tradingSystem === null) { logger.write('[ERROR] saveToStrategyzer -> Can not save when tradingSystem is null or undefined.') @@ -115,37 +119,53 @@ function newStrategizerGateway () { logger.write('[ERROR] saveToStrategyzer -> Can not save when idAtStrategizer is null or undefined.') return } - graphQLServer = await axios({ - url: window.canvasApp.graphQL.masterAppApiUrl, - method: 'post', - data: { - query: ` - mutation strategizer_EditTradingSystem - ( - $id: ID!, $data: strategizer_JSON! - ) - { - strategizer_EditTradingSystem(id: $id, tradingSystem: { data: $data }) - { - id - } - } - `, - variables: { - id: idAtStrategizer, - data: tradingSystem + + if (window.canvasApp.executingAt === 'Local') { + callServer(JSON.stringify(tradingSystem), 'SaveDefinition', onSaved) + function onSaved (err) { + if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { + return true + } else { + logger.write('[ERROR] saveToStrategyzer -> Can not save definition to local server. err = ' + err.messsage) + return false } - }, - headers: { - authorization: 'Bearer ' + accessToken } - }) + return true // TODO: Here we will always show that the saving works even if it does not. We need to fix this at some point in time. + } else { + user = JSON.parse(user) - if (graphQLServer.data.errors) { - logger.write('[ERROR] saveToStrategyzer -> GraphsQL Error -> graphQLServer.data.errors = ' + JSON.stringify(graphQLServer.data.errors)) + graphQLServer = await axios({ + url: window.canvasApp.graphQL.masterAppApiUrl, + method: 'post', + data: { + query: ` + mutation strategizer_EditTradingSystem + ( + $id: ID!, $data: strategizer_JSON! + ) + { + strategizer_EditTradingSystem(id: $id, tradingSystem: { data: $data }) + { + id + } + } + `, + variables: { + id: idAtStrategizer, + data: tradingSystem + } + }, + headers: { + authorization: 'Bearer ' + accessToken + } + }) + + if (graphQLServer.data.errors) { + logger.write('[ERROR] saveToStrategyzer -> GraphsQL Error -> graphQLServer.data.errors = ' + JSON.stringify(graphQLServer.data.errors)) + } + + return true } - - return true } catch (err) { logger.write('[ERROR] saveToStrategyzer -> err = ' + err.stack) } diff --git a/StrategySpace/Workspace/FunctionLibraries/AttachDetach.js b/StrategySpace/Workspace/FunctionLibraries/AttachDetach.js index b486bd0ea..107539f5f 100644 --- a/StrategySpace/Workspace/FunctionLibraries/AttachDetach.js +++ b/StrategySpace/Workspace/FunctionLibraries/AttachDetach.js @@ -8,11 +8,49 @@ function newAttachDetach () { function detachNode (node, rootNodes) { switch (node.type) { - case 'Trading System': { + case 'Definition': { return } - case 'Parameters': { - node.payload.parentNode.parameters = undefined + case 'Personal Data': { + node.payload.parentNode.personalData = undefined + completeDetachment(node, rootNodes) + return + } + case 'Exchange Account': { + let payload = node.payload + for (let i = 0; i < payload.parentNode.exchangeAccounts.length; i++) { + let strategy = payload.parentNode.exchangeAccounts[i] + if (strategy.id === node.id) { + payload.parentNode.exchangeAccounts.splice(i, 1) + } + } + completeDetachment(node, rootNodes) + return + } + case 'Exchange Account Asset': { + let payload = node.payload + for (let i = 0; i < payload.parentNode.assets.length; i++) { + let asset = payload.parentNode.assets[i] + if (asset.id === node.id) { + payload.parentNode.assets.splice(i, 1) + } + } + completeDetachment(node, rootNodes) + return + } + case 'Exchange Account Key': { + let payload = node.payload + for (let i = 0; i < payload.parentNode.keys.length; i++) { + let key = payload.parentNode.keys[i] + if (key.id === node.id) { + payload.parentNode.keys.splice(i, 1) + } + } + completeDetachment(node, rootNodes) + return + } + case 'Trading System': { + node.payload.parentNode.tradingSystem = undefined completeDetachment(node, rootNodes) return } @@ -28,10 +66,10 @@ function newAttachDetach () { if (strategy.id === node.id) { payload.parentNode.strategies.splice(i, 1) } - completeDetachment(node, rootNodes) } + completeDetachment(node, rootNodes) + return } - break case 'Trigger Stage': { node.payload.parentNode.triggerStage = undefined completeDetachment(node, rootNodes) @@ -82,6 +120,16 @@ function newAttachDetach () { completeDetachment(node, rootNodes) return } + case 'Open Execution': { + node.payload.parentNode.openExecution = undefined + completeDetachment(node, rootNodes) + return + } + case 'Close Execution': { + node.payload.parentNode.closeExecution = undefined + completeDetachment(node, rootNodes) + return + } case 'Stop': { node.payload.parentNode.stopLoss = undefined completeDetachment(node, rootNodes) @@ -116,8 +164,8 @@ function newAttachDetach () { } } completeDetachment(node, rootNodes) + return } - break case 'Situation': { let payload = node.payload for (let i = 0; i < payload.parentNode.situations.length; i++) { @@ -127,8 +175,8 @@ function newAttachDetach () { } } completeDetachment(node, rootNodes) + return } - break case 'Phase': { let payload = node.payload for (let i = 0; i < payload.parentNode.phases.length; i++) { @@ -148,12 +196,41 @@ function newAttachDetach () { return } } + return } } } function attachNode (node, attachToNode, rootNodes) { switch (node.type) { + case 'Personal Data': { + node.payload.parentNode = attachToNode + node.payload.chainParent = attachToNode + node.payload.parentNode.personalData = node + completeAttachment(node, rootNodes) + } + break + case 'Exchange Account': { + node.payload.parentNode = attachToNode + node.payload.chainParent = attachToNode + node.payload.parentNode.exchangeAccounts.push(node) + completeAttachment(node, rootNodes) + } + break + case 'Exchange Account Asset': { + node.payload.parentNode = attachToNode + node.payload.chainParent = attachToNode + node.payload.parentNode.assets.push(node) + completeAttachment(node, rootNodes) + } + break + case 'Exchange Account Key': { + node.payload.parentNode = attachToNode + node.payload.chainParent = attachToNode + node.payload.parentNode.keys.push(node) + completeAttachment(node, rootNodes) + } + break case 'Parameters': { node.payload.parentNode = attachToNode node.payload.chainParent = attachToNode @@ -168,6 +245,13 @@ function newAttachDetach () { completeAttachment(node, rootNodes) } break + case 'Trading System': { + node.payload.parentNode = attachToNode + node.payload.chainParent = attachToNode + node.payload.parentNode.tradingSystem = node + completeAttachment(node, rootNodes) + } + break case 'Strategy': { node.payload.parentNode = attachToNode node.payload.chainParent = attachToNode @@ -224,6 +308,20 @@ function newAttachDetach () { completeAttachment(node, rootNodes) } break + case 'Open Execution': { + node.payload.parentNode = attachToNode + node.payload.chainParent = attachToNode + node.payload.parentNode.openExecution = node + completeAttachment(node, rootNodes) + } + break + case 'Close Execution': { + node.payload.parentNode = attachToNode + node.payload.chainParent = attachToNode + node.payload.parentNode.closeExecution = node + completeAttachment(node, rootNodes) + } + break case 'Trigger On Event': { node.payload.parentNode = attachToNode node.payload.chainParent = attachToNode diff --git a/StrategySpace/Workspace/FunctionLibraries/NodeChildren.js b/StrategySpace/Workspace/FunctionLibraries/NodeChildren.js index 85d1664d9..9d57b1a87 100644 --- a/StrategySpace/Workspace/FunctionLibraries/NodeChildren.js +++ b/StrategySpace/Workspace/FunctionLibraries/NodeChildren.js @@ -8,6 +8,21 @@ function newNodeChildren () { function childrenCount (parentNode, childNode) { switch (parentNode.type) { + case 'Definition': { + return countChildrenDefinition(parentNode, childNode) + } + case 'Personal Data': { + return countChildrenPersonalData(parentNode, childNode) + } + case 'Exchange Account': { + return countChildrenExchangeAccount(parentNode, childNode) + } + case 'Exchange Account Asset': { + return countChildrenExchangeAccountAsset(parentNode, childNode) + } + case 'Exchange Account Key': { + return countChildrenExchangeAccountKey(parentNode, childNode) + } case 'Trading System': { return countChildrenTradingSystem(parentNode, childNode) } @@ -41,6 +56,12 @@ function newNodeChildren () { case 'Initial Definition': { return countChildrenInitialDefinition(parentNode, childNode) } + case 'Open Execution': { + return countChildrenOpenExecution(parentNode, childNode) + } + case 'Close Execution': { + return countChildrenCloseExecution(parentNode, childNode) + } case 'Next Phase Event': { return countChildrenEvent(parentNode, childNode) } @@ -80,6 +101,82 @@ function newNodeChildren () { } } + function countChildrenDefinition (parentNode, childNode) { + let response = { + childrenCount: 0, + childIndex: undefined + } + if (parentNode.tradingSystem !== undefined) { + response.childrenCount++ + if (parentNode.tradingSystem.id === childNode.id) { + response.childIndex = response.childrenCount + } + } + if (parentNode.personalData !== undefined) { + response.childrenCount++ + if (parentNode.personalData.id === childNode.id) { + response.childIndex = response.childrenCount + } + } + return response + } + + function countChildrenPersonalData (parentNode, childNode) { + let response = { + childrenCount: 0, + childIndex: undefined + } + + for (let i = 0; i < parentNode.exchangeAccounts.length; i++) { + let child = parentNode.exchangeAccounts[i] + response.childrenCount++ + if (child.id === childNode.id) { + response.childIndex = response.childrenCount + } + } + return response + } + + function countChildrenExchangeAccount (parentNode, childNode) { + let response = { + childrenCount: 0, + childIndex: undefined + } + + for (let i = 0; i < parentNode.assets.length; i++) { + let child = parentNode.assets[i] + response.childrenCount++ + if (child.id === childNode.id) { + response.childIndex = response.childrenCount + } + } + + for (let i = 0; i < parentNode.keys.length; i++) { + let child = parentNode.keys[i] + response.childrenCount++ + if (child.id === childNode.id) { + response.childIndex = response.childrenCount + } + } + return response + } + + function countChildrenExchangeAccountAsset (parentNode, childNode) { + let response = { + childrenCount: 0, + childIndex: undefined + } + return response + } + + function countChildrenExchangeAccountKey (parentNode, childNode) { + let response = { + childrenCount: 0, + childIndex: undefined + } + return response + } + function countChildrenTradingSystem (parentNode, childNode) { let response = { childrenCount: 0, @@ -200,6 +297,12 @@ function newNodeChildren () { response.childIndex = response.childrenCount } } + if (parentNode.openExecution !== undefined) { + response.childrenCount++ + if (parentNode.openExecution.id === childNode.id) { + response.childIndex = response.childrenCount + } + } return response } @@ -228,6 +331,12 @@ function newNodeChildren () { childrenCount: 0, childIndex: undefined } + if (parentNode.closeExecution !== undefined) { + response.childrenCount++ + if (parentNode.closeExecution.id === childNode.id) { + response.childIndex = response.childrenCount + } + } return response } @@ -291,6 +400,22 @@ function newNodeChildren () { return response } + function countChildrenOpenExecution (parentNode, childNode) { + let response = { + childrenCount: 0, + childIndex: undefined + } + return response + } + + function countChildrenCloseExecution (parentNode, childNode) { + let response = { + childrenCount: 0, + childIndex: undefined + } + return response + } + function countChildrenEvent (parentNode, childNode) { let response = { childrenCount: 0, diff --git a/StrategySpace/Workspace/FunctionLibraries/NodeDeleter.js b/StrategySpace/Workspace/FunctionLibraries/NodeDeleter.js index 51f9d84da..e4ded4e0b 100644 --- a/StrategySpace/Workspace/FunctionLibraries/NodeDeleter.js +++ b/StrategySpace/Workspace/FunctionLibraries/NodeDeleter.js @@ -1,5 +1,10 @@ function newNodeDeleter () { thisObject = { + deleteDefinition: deleteDefinition, + deletePersonalData: deletePersonalData, + deleteExchangeAccount: deleteExchangeAccount, + deleteExchangeAccountAsset: deleteExchangeAccountAsset, + deleteExchangeAccountKey: deleteExchangeAccountKey, deleteWorkspace: deleteWorkspace, deleteTradingSystem: deleteTradingSystem, deleteParameters: deleteParameters, @@ -12,6 +17,8 @@ function newNodeDeleter () { deletePositionSize: deletePositionSize, deletePositionRate: deletePositionRate, deleteInitialDefinition: deleteInitialDefinition, + deleteOpenExecution: deleteOpenExecution, + deleteCloseExecution: deleteCloseExecution, deleteEvent: deleteEvent, deleteManagedItem: deleteManagedItem, deletePhase: deletePhase, @@ -32,8 +39,28 @@ function newNodeDeleter () { let rootNode = node.rootNodes[0] switch (rootNode.type) { + case 'Definition': { + deleteDefinition(rootNode, rootNodes, true) + break + } + case 'Personal Data': { + deletePersonalData(rootNode, rootNodes) + break + } + case 'Exchange Account': { + deleteExchangeAccount(rootNode, rootNodes) + break + } + case 'Exchange Account Asset': { + deleteExchangeAccountAsset(rootNode, rootNodes) + break + } + case 'Exchange Account Key': { + deleteExchangeAccountKey(rootNode, rootNodes) + break + } case 'Trading System': { - deleteTradingSystem(rootNode, rootNodes, true) + deleteTradingSystem(rootNode, rootNodes) break } case 'Parameters': { @@ -76,6 +103,14 @@ function newNodeDeleter () { deleteInitialDefinition(rootNode, rootNodes) break } + case 'Open Execution': { + deleteOpenExecution(rootNode, rootNodes) + break + } + case 'Close Execution': { + deleteCloseExecution(rootNode, rootNodes) + break + } case 'Event': { deleteEvent(rootNode, rootNodes) break @@ -116,7 +151,9 @@ function newNodeDeleter () { cleanNode(node) } - function deleteTradingSystem (node, rootNodes, forced) { + function deleteDefinition (node, rootNodes, forced) { + let payload = node.payload + if (forced !== true) { /* Can not delete if it is the last one */ let counter = 0 @@ -133,6 +170,93 @@ function newNodeDeleter () { node.payload.uiObject.setNotRunningStatus() } + if (node.tradingSystem !== undefined) { + deleteTradingSystem(node.tradingSystem, rootNodes) + } + if (node.personalData !== undefined) { + deletePersonalData(node.personalData, rootNodes) + } + completeDeletion(node, rootNodes) + destroyPart(node) + cleanNode(node) + } + + function deletePersonalData (node, rootNodes) { + let payload = node.payload + + if (payload.parentNode !== undefined) { + payload.parentNode.personalData = undefined + } + + while (node.exchangeAccounts.length > 0) { + deleteExchangeAccount(node.exchangeAccounts[0], rootNodes) + } + + completeDeletion(node, rootNodes) + destroyPart(node) + cleanNode(node) + } + + function deleteExchangeAccount (node, rootNodes) { + let payload = node.payload + if (payload.parentNode !== undefined) { + for (let j = 0; j < payload.parentNode.exchangeAccounts.length; j++) { + let exchangeAccount = payload.parentNode.exchangeAccounts[j] + if (exchangeAccount.id === node.id) { + payload.parentNode.exchangeAccounts.splice(j, 1) + } + } + } + while (node.assets.length > 0) { + deleteExchangeAccountAsset(node.assets[0], rootNodes) + } + while (node.keys.length > 0) { + deleteExchangeAccountKey(node.keys[0], rootNodes) + } + completeDeletion(node, rootNodes) + destroyPart(node) + cleanNode(node) + } + + function deleteExchangeAccountAsset (node, rootNodes) { + let payload = node.payload + if (payload.parentNode !== undefined) { + for (let j = 0; j < payload.parentNode.assets.length; j++) { + let asset = payload.parentNode.assets[j] + if (asset.id === node.id) { + payload.parentNode.assets.splice(j, 1) + } + } + } else { + completeDeletion(node, rootNodes) + } + destroyPart(node) + cleanNode(node) + } + + function deleteExchangeAccountKey (node, rootNodes) { + let payload = node.payload + if (payload.parentNode !== undefined) { + for (let j = 0; j < payload.parentNode.keys.length; j++) { + let key = payload.parentNode.keys[j] + if (key.id === node.id) { + payload.parentNode.keys.splice(j, 1) + } + } + } else { + completeDeletion(node, rootNodes) + } + destroyPart(node) + cleanNode(node) + } + + function deleteTradingSystem (node, rootNodes) { + let payload = node.payload + + if (payload.parentNode !== undefined) { + payload.parentNode.tradingSystem = undefined + } + while (node.strategies.length > 0) { deleteStrategy(node.strategies[0], rootNodes) } @@ -232,6 +356,11 @@ function newNodeDeleter () { if (node.initialDefinition !== undefined) { deleteInitialDefinition(node.initialDefinition, rootNodes) } + + if (node.openExecution !== undefined) { + deleteOpenExecution(node.openExecution, rootNodes) + } + destroyPart(node) cleanNode(node) } @@ -260,6 +389,9 @@ function newNodeDeleter () { } else { completeDeletion(node, rootNodes) } + if (node.closeExecution !== undefined) { + deleteCloseExecution(node.closeExecution, rootNodes) + } destroyPart(node) cleanNode(node) } @@ -315,6 +447,28 @@ function newNodeDeleter () { cleanNode(node) } + function deleteOpenExecution (node, rootNodes) { + let payload = node.payload + if (payload.parentNode !== undefined) { + payload.parentNode.openExecution = undefined + } else { + completeDeletion(node, rootNodes) + } + destroyPart(node) + cleanNode(node) + } + + function deleteCloseExecution (node, rootNodes) { + let payload = node.payload + if (payload.parentNode !== undefined) { + payload.parentNode.closeExecution = undefined + } else { + completeDeletion(node, rootNodes) + } + destroyPart(node) + cleanNode(node) + } + function deleteEvent (node, rootNodes) { let payload = node.payload if (payload.parentNode !== undefined) { diff --git a/StrategySpace/Workspace/FunctionLibraries/PartsFromNodes.js b/StrategySpace/Workspace/FunctionLibraries/PartsFromNodes.js index 47f81f152..b37cdf60a 100644 --- a/StrategySpace/Workspace/FunctionLibraries/PartsFromNodes.js +++ b/StrategySpace/Workspace/FunctionLibraries/PartsFromNodes.js @@ -1,13 +1,20 @@ function newPartsFromNodes () { thisObject = { createPartFromNode: createPartFromNode, - newStrategy: newStrategy, + addTradingSystem: addTradingSystem, + addPersonalData: addPersonalData, + addExchangeAccount: addExchangeAccount, + addExchangeAccountAsset: addExchangeAccountAsset, + addExchangeAccountKey: addExchangeAccountKey, + addStrategy: addStrategy, addParameters: addParameters, addMissingParameters: addMissingParameters, addMissingStages: addMissingStages, addMissingEvents: addMissingEvents, addMissingItems: addMissingItems, addInitialDefinition: addInitialDefinition, + addOpenExecution: addOpenExecution, + addCloseExecution: addCloseExecution, addPhase: addPhase, addFormula: addFormula, addNextPhaseEvent: addNextPhaseEvent, @@ -102,6 +109,16 @@ function newPartsFromNodes () { } return } + case 'Open Execution': + { + createPart('Open Execution', node.name, node, parentNode, chainParent, 'Open Execution') + return + } + case 'Close Execution': + { + createPart('Close Execution', node.name, node, parentNode, chainParent, 'Close Execution') + return + } case 'Initial Definition': { createPart('Initial Definition', node.name, node, parentNode, chainParent, 'Initial Definition') @@ -182,6 +199,9 @@ function newPartsFromNodes () { if (node.initialDefinition !== undefined) { createPartFromNode(node.initialDefinition, stage, stage) } + if (node.openExecution !== undefined) { + createPartFromNode(node.openExecution, stage, stage) + } return } case 'Manage Stage': { @@ -199,6 +219,10 @@ function newPartsFromNodes () { case 'Close Stage': { let stage = node createPart('Close Stage', stage.name, stage, parentNode, chainParent, 'Close Stage') + + if (node.closeExecution !== undefined) { + createPartFromNode(node.closeExecution, stage, stage) + } return } case 'Strategy': { @@ -249,10 +273,96 @@ function newPartsFromNodes () { createPart('Workspace', workspace.name, workspace, parentNode, chainParent, 'Workspace') return } + case 'Personal Data': { + createPart('Personal Data', node.name, node, parentNode, chainParent, 'Personal Data') + for (let m = 0; m < node.exchangeAccounts.length; m++) { + let exchangeAccount = node.exchangeAccounts[m] + createPartFromNode(exchangeAccount, node, node) + } + return + } + case 'Exchange Account': { + createPart('Exchange Account', node.name, node, parentNode, chainParent, 'Exchange Account') + for (let m = 0; m < node.assets.length; m++) { + let asset = node.assets[m] + createPartFromNode(asset, node, node) + } + for (let m = 0; m < node.keys.length; m++) { + let key = node.keys[m] + createPartFromNode(key, node, node) + } + return + } + case 'Exchange Account Asset': { + createPart('Exchange Account Asset', node.name, node, parentNode, chainParent, 'Exchange Account Asset') + return + } + case 'Exchange Account Key': { + createPart('Exchange Account Key', node.name, node, parentNode, chainParent, 'Exchange Account Key') + return + } + case 'Definition': { + createPart('Definition', node.name, node, parentNode, chainParent, 'Definition') + if (node.tradingSystem !== undefined) { + createPartFromNode(node.tradingSystem, node, node) + } + if (node.personalData !== undefined) { + createPartFromNode(node.personalData, node, node) + } + return + } } } - function newStrategy (parentNode) { + function addTradingSystem (node) { + if (node.tradingSystem === undefined) { + node.tradingSystem = { + strategies: [] + } + createPart('Trading System', '', node.tradingSystem, node, node) + } + } + + function addPersonalData (node) { + if (node.personalData === undefined) { + node.personalData = { + exchangeAccounts: [] + } + createPart('Personal Data', '', node.personalData, node, node) + } + } + + function addExchangeAccount (parentNode) { + let personalData = parentNode + let exchangeAccount = { + name: 'New Account', + assets: [], + keys: [] + } + personalData.exchangeAccounts.push(exchangeAccount) + createPart('Exchange Account', exchangeAccount.name, exchangeAccount, personalData, personalData, 'Exchange Account') + } + + function addExchangeAccountAsset (parentNode) { + let exchangeAccount = parentNode + let asset = { + name: 'New Asset' + } + exchangeAccount.assets.push(asset) + createPart('Exchange Account Asset', asset.name, asset, exchangeAccount, exchangeAccount, 'Account Asset') + } + + function addExchangeAccountKey (parentNode) { + let exchangeAccount = parentNode + let key = { + name: 'New Key', + code: 'Paste your exchange API secret key here. Secret keys are filtered out and NOT exported when using the SHARE menu option on any object at your workspace. Secret keys ARE downloaded when using the download button.' + } + exchangeAccount.keys.push(key) + createPart('Exchange Account Key', key.name, key, exchangeAccount, exchangeAccount, 'Account Key') + } + + function addStrategy (parentNode) { let strategyParent = parentNode let strategy = { name: 'New Strategy', @@ -396,7 +506,9 @@ function newPartsFromNodes () { createPart('Stop', '', node.manageStage.stopLoss, node.manageStage, node.manageStage) createPart('Take Profit', '', node.manageStage.takeProfit, node.manageStage, node.manageStage) } - if (node.triggerStage === undefined) { + if (node.closeStage === undefined) { + node.closeStage = { + } createPart('Close Stage', '', node.closeStage, node, node, 'Close Stage') } } @@ -496,6 +608,20 @@ function newPartsFromNodes () { } } + function addOpenExecution (node) { + if (node.openExecution === undefined) { + node.openExecution = {} + createPart('Open Execution', '', node.openExecution, node, node) + } + } + + function addCloseExecution (node) { + if (node.closeExecution === undefined) { + node.closeExecution = {} + createPart('Close Execution', '', node.closeExecution, node, node) + } + } + function addFormula (node) { if (node.formula === undefined) { node.formula = { diff --git a/StrategySpace/Workspace/FunctionLibraries/ProtocolNode.js b/StrategySpace/Workspace/FunctionLibraries/ProtocolNode.js index 5e665b21d..c3eb4d943 100644 --- a/StrategySpace/Workspace/FunctionLibraries/ProtocolNode.js +++ b/StrategySpace/Workspace/FunctionLibraries/ProtocolNode.js @@ -4,7 +4,7 @@ function newProtocolNode () { } return thisObject - function getProtocolNode (node) { + function getProtocolNode (node, removePersonalData) { if (node === undefined) { return } switch (node.type) { case 'Code': @@ -23,7 +23,7 @@ function newProtocolNode () { type: node.type, subType: node.subType, name: node.name, - code: getProtocolNode(node.code) + code: getProtocolNode(node.code, removePersonalData) } return condition } @@ -36,7 +36,7 @@ function newProtocolNode () { } for (let m = 0; m < node.conditions.length; m++) { - let condition = getProtocolNode(node.conditions[m]) + let condition = getProtocolNode(node.conditions[m], removePersonalData) situation.conditions.push(condition) } return situation @@ -60,7 +60,7 @@ function newProtocolNode () { situations: [] } for (let m = 0; m < node.situations.length; m++) { - let situation = getProtocolNode(node.situations[m]) + let situation = getProtocolNode(node.situations[m], removePersonalData) event.situations.push(situation) } return event @@ -70,8 +70,8 @@ function newProtocolNode () { type: node.type, subType: node.subType, name: node.name, - formula: getProtocolNode(node.formula), - nextPhaseEvent: getProtocolNode(node.nextPhaseEvent) + formula: getProtocolNode(node.formula, removePersonalData), + nextPhaseEvent: getProtocolNode(node.nextPhaseEvent, removePersonalData) } return phase } @@ -84,7 +84,7 @@ function newProtocolNode () { } for (let m = 0; m < node.phases.length; m++) { - let phase = getProtocolNode(node.phases[m]) + let phase = getProtocolNode(node.phases[m], removePersonalData) stop.phases.push(phase) } return stop @@ -98,7 +98,7 @@ function newProtocolNode () { } for (let m = 0; m < node.phases.length; m++) { - let phase = getProtocolNode(node.phases[m]) + let phase = getProtocolNode(node.phases[m], removePersonalData) takeProfit.phases.push(phase) } return takeProfit @@ -112,7 +112,7 @@ function newProtocolNode () { } for (let m = 0; m < node.situations.length; m++) { - let situation = getProtocolNode(node.situations[m]) + let situation = getProtocolNode(node.situations[m], removePersonalData) event.situations.push(situation) } return event @@ -126,7 +126,7 @@ function newProtocolNode () { } for (let m = 0; m < node.situations.length; m++) { - let situation = getProtocolNode(node.situations[m]) + let situation = getProtocolNode(node.situations[m], removePersonalData) event.situations.push(situation) } return event @@ -140,7 +140,7 @@ function newProtocolNode () { } for (let m = 0; m < node.situations.length; m++) { - let situation = getProtocolNode(node.situations[m]) + let situation = getProtocolNode(node.situations[m], removePersonalData) event.situations.push(situation) } return event @@ -150,10 +150,26 @@ function newProtocolNode () { type: node.type, subType: node.subType, name: node.name, - stopLoss: getProtocolNode(node.stopLoss), - takeProfit: getProtocolNode(node.takeProfit), - positionSize: getProtocolNode(node.positionSize), - positionRate: getProtocolNode(node.positionRate) + stopLoss: getProtocolNode(node.stopLoss, removePersonalData), + takeProfit: getProtocolNode(node.takeProfit, removePersonalData), + positionSize: getProtocolNode(node.positionSize, removePersonalData), + positionRate: getProtocolNode(node.positionRate, removePersonalData) + } + return object + } + case 'Open Execution': { + let object = { + type: node.type, + subType: node.subType, + name: node.name + } + return object + } + case 'Close Execution': { + let object = { + type: node.type, + subType: node.subType, + name: node.name } return object } @@ -162,7 +178,7 @@ function newProtocolNode () { type: node.type, subType: node.subType, name: node.name, - formula: getProtocolNode(node.formula) + formula: getProtocolNode(node.formula, removePersonalData) } return object } @@ -171,7 +187,7 @@ function newProtocolNode () { type: node.type, subType: node.subType, name: node.name, - formula: getProtocolNode(node.formula) + formula: getProtocolNode(node.formula, removePersonalData) } return object } @@ -180,9 +196,9 @@ function newProtocolNode () { type: node.type, subType: node.subType, name: node.name, - triggerOn: getProtocolNode(node.triggerOn), - triggerOff: getProtocolNode(node.triggerOff), - takePosition: getProtocolNode(node.takePosition) + triggerOn: getProtocolNode(node.triggerOn, removePersonalData), + triggerOff: getProtocolNode(node.triggerOff, removePersonalData), + takePosition: getProtocolNode(node.takePosition, removePersonalData) } return stage } @@ -191,7 +207,8 @@ function newProtocolNode () { type: node.type, subType: node.subType, name: node.name, - initialDefinition: getProtocolNode(node.initialDefinition) + initialDefinition: getProtocolNode(node.initialDefinition, removePersonalData), + openExecution: getProtocolNode(node.openExecution, removePersonalData) } return stage } @@ -200,8 +217,8 @@ function newProtocolNode () { type: node.type, subType: node.subType, name: node.name, - stopLoss: getProtocolNode(node.stopLoss), - takeProfit: getProtocolNode(node.takeProfit) + stopLoss: getProtocolNode(node.stopLoss, removePersonalData), + takeProfit: getProtocolNode(node.takeProfit, removePersonalData) } return stage } @@ -209,7 +226,8 @@ function newProtocolNode () { let stage = { type: node.type, subType: node.subType, - name: node.name + name: node.name, + closeExecution: getProtocolNode(node.closeExecution, removePersonalData) } return stage } @@ -218,10 +236,10 @@ function newProtocolNode () { type: node.type, subType: node.subType, name: node.name, - triggerStage: getProtocolNode(node.triggerStage), - openStage: getProtocolNode(node.openStage), - manageStage: getProtocolNode(node.manageStage), - closeStage: getProtocolNode(node.closeStage) + triggerStage: getProtocolNode(node.triggerStage, removePersonalData), + openStage: getProtocolNode(node.openStage, removePersonalData), + manageStage: getProtocolNode(node.manageStage, removePersonalData), + closeStage: getProtocolNode(node.closeStage, removePersonalData) } return strategy } @@ -230,7 +248,7 @@ function newProtocolNode () { type: node.type, subType: node.subType, name: node.name, - formula: getProtocolNode(node.formula) + formula: getProtocolNode(node.formula, removePersonalData) } return object } @@ -239,7 +257,7 @@ function newProtocolNode () { type: node.type, subType: node.subType, name: node.name, - baseAsset: getProtocolNode(node.baseAsset) + baseAsset: getProtocolNode(node.baseAsset, removePersonalData) } return object } @@ -249,15 +267,79 @@ function newProtocolNode () { subType: node.subType, name: node.name, strategies: [], - parameters: getProtocolNode(node.parameters) + parameters: getProtocolNode(node.parameters, removePersonalData) } for (let m = 0; m < node.strategies.length; m++) { - let strategy = getProtocolNode(node.strategies[m]) + let strategy = getProtocolNode(node.strategies[m], removePersonalData) tradingSystem.strategies.push(strategy) } return tradingSystem } + case 'Personal Data': { + if (removePersonalData === true) { return } + let personalData = { + type: node.type, + subType: node.subType, + name: node.name, + exchangeAccounts: [] + } + + for (let m = 0; m < node.exchangeAccounts.length; m++) { + let exchangeAccount = getProtocolNode(node.exchangeAccounts[m], removePersonalData) + personalData.exchangeAccounts.push(exchangeAccount) + } + return personalData + } + case 'Exchange Account': { + if (removePersonalData === true) { return } + let exchangeAccount = { + type: node.type, + subType: node.subType, + name: node.name, + assets: [], + keys: [] + } + + for (let m = 0; m < node.assets.length; m++) { + let asset = getProtocolNode(node.assets[m], removePersonalData) + exchangeAccount.assets.push(asset) + } + for (let m = 0; m < node.keys.length; m++) { + let key = getProtocolNode(node.keys[m], removePersonalData) + exchangeAccount.keys.push(key) + } + return exchangeAccount + } + case 'Exchange Account Asset': { + if (removePersonalData === true) { return } + let asset = { + type: node.type, + subType: node.subType, + name: node.name + } + return asset + } + case 'Exchange Account Key': { + if (removePersonalData === true) { return } + let key = { + type: node.type, + subType: node.subType, + name: node.name, + code: node.code + } + return key + } + case 'Definition': { + let object = { + type: node.type, + subType: node.subType, + name: node.name, + tradingSystem: getProtocolNode(node.tradingSystem, removePersonalData), + personalData: getProtocolNode(node.personalData, removePersonalData) + } + return object + } } } } diff --git a/StrategySpace/Workspace/FunctionLibraries/StringifyNode.js b/StrategySpace/Workspace/FunctionLibraries/StringifyNode.js index 05039cebc..4191cacd0 100644 --- a/StrategySpace/Workspace/FunctionLibraries/StringifyNode.js +++ b/StrategySpace/Workspace/FunctionLibraries/StringifyNode.js @@ -4,7 +4,7 @@ function newStringifyNode () { } return thisObject - function prepareForStringify (node) { + function prepareForStringify (node, removePersonalData) { if (node === undefined) { return } switch (node.type) { case 'Code': @@ -26,7 +26,7 @@ function newStringifyNode () { type: node.type, subType: node.subType, name: node.name, - code: prepareForStringify(node.code), + code: prepareForStringify(node.code, removePersonalData), savedPayload: getSavedPayload(node) } return condition @@ -42,7 +42,7 @@ function newStringifyNode () { } for (let m = 0; m < node.conditions.length; m++) { - let condition = prepareForStringify(node.conditions[m]) + let condition = prepareForStringify(node.conditions[m], removePersonalData) situation.conditions.push(condition) } return situation @@ -70,7 +70,7 @@ function newStringifyNode () { savedPayload: getSavedPayload(node) } for (let m = 0; m < node.situations.length; m++) { - let situation = prepareForStringify(node.situations[m]) + let situation = prepareForStringify(node.situations[m], removePersonalData) event.situations.push(situation) } return event @@ -81,8 +81,8 @@ function newStringifyNode () { type: node.type, subType: node.subType, name: node.name, - formula: prepareForStringify(node.formula), - nextPhaseEvent: prepareForStringify(node.nextPhaseEvent), + formula: prepareForStringify(node.formula, removePersonalData), + nextPhaseEvent: prepareForStringify(node.nextPhaseEvent, removePersonalData), savedPayload: getSavedPayload(node) } return phase @@ -99,7 +99,7 @@ function newStringifyNode () { } for (let m = 0; m < node.phases.length; m++) { - let phase = prepareForStringify(node.phases[m]) + let phase = prepareForStringify(node.phases[m], removePersonalData) stop.phases.push(phase) } return stop @@ -116,7 +116,7 @@ function newStringifyNode () { } for (let m = 0; m < node.phases.length; m++) { - let phase = prepareForStringify(node.phases[m]) + let phase = prepareForStringify(node.phases[m], removePersonalData) takeProfit.phases.push(phase) } return takeProfit @@ -132,7 +132,7 @@ function newStringifyNode () { } for (let m = 0; m < node.situations.length; m++) { - let situation = prepareForStringify(node.situations[m]) + let situation = prepareForStringify(node.situations[m], removePersonalData) event.situations.push(situation) } return event @@ -148,7 +148,7 @@ function newStringifyNode () { } for (let m = 0; m < node.situations.length; m++) { - let situation = prepareForStringify(node.situations[m]) + let situation = prepareForStringify(node.situations[m], removePersonalData) event.situations.push(situation) } return event @@ -164,7 +164,7 @@ function newStringifyNode () { } for (let m = 0; m < node.situations.length; m++) { - let situation = prepareForStringify(node.situations[m]) + let situation = prepareForStringify(node.situations[m], removePersonalData) event.situations.push(situation) } return event @@ -175,10 +175,30 @@ function newStringifyNode () { type: node.type, subType: node.subType, name: node.name, - stopLoss: prepareForStringify(node.stopLoss), - takeProfit: prepareForStringify(node.takeProfit), - positionSize: prepareForStringify(node.positionSize), - positionRate: prepareForStringify(node.positionRate), + stopLoss: prepareForStringify(node.stopLoss, removePersonalData), + takeProfit: prepareForStringify(node.takeProfit, removePersonalData), + positionSize: prepareForStringify(node.positionSize, removePersonalData), + positionRate: prepareForStringify(node.positionRate, removePersonalData), + savedPayload: getSavedPayload(node) + } + return object + } + case 'Open Execution': { + let object = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + savedPayload: getSavedPayload(node) + } + return object + } + case 'Close Execution': { + let object = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, savedPayload: getSavedPayload(node) } return object @@ -189,7 +209,7 @@ function newStringifyNode () { type: node.type, subType: node.subType, name: node.name, - formula: prepareForStringify(node.formula), + formula: prepareForStringify(node.formula, removePersonalData), savedPayload: getSavedPayload(node) } return object @@ -200,7 +220,7 @@ function newStringifyNode () { type: node.type, subType: node.subType, name: node.name, - formula: prepareForStringify(node.formula), + formula: prepareForStringify(node.formula, removePersonalData), savedPayload: getSavedPayload(node) } return object @@ -211,9 +231,9 @@ function newStringifyNode () { type: node.type, subType: node.subType, name: node.name, - triggerOn: prepareForStringify(node.triggerOn), - triggerOff: prepareForStringify(node.triggerOff), - takePosition: prepareForStringify(node.takePosition), + triggerOn: prepareForStringify(node.triggerOn, removePersonalData), + triggerOff: prepareForStringify(node.triggerOff, removePersonalData), + takePosition: prepareForStringify(node.takePosition, removePersonalData), savedPayload: getSavedPayload(node) } return stage @@ -224,7 +244,8 @@ function newStringifyNode () { type: node.type, subType: node.subType, name: node.name, - initialDefinition: prepareForStringify(node.initialDefinition), + initialDefinition: prepareForStringify(node.initialDefinition, removePersonalData), + openExecution: prepareForStringify(node.openExecution, removePersonalData), savedPayload: getSavedPayload(node) } return stage @@ -235,8 +256,8 @@ function newStringifyNode () { type: node.type, subType: node.subType, name: node.name, - stopLoss: prepareForStringify(node.stopLoss), - takeProfit: prepareForStringify(node.takeProfit), + stopLoss: prepareForStringify(node.stopLoss, removePersonalData), + takeProfit: prepareForStringify(node.takeProfit, removePersonalData), savedPayload: getSavedPayload(node) } return stage @@ -247,6 +268,7 @@ function newStringifyNode () { type: node.type, subType: node.subType, name: node.name, + closeExecution: prepareForStringify(node.closeExecution, removePersonalData), savedPayload: getSavedPayload(node) } return stage @@ -257,10 +279,10 @@ function newStringifyNode () { type: node.type, subType: node.subType, name: node.name, - triggerStage: prepareForStringify(node.triggerStage), - openStage: prepareForStringify(node.openStage), - manageStage: prepareForStringify(node.manageStage), - closeStage: prepareForStringify(node.closeStage), + triggerStage: prepareForStringify(node.triggerStage, removePersonalData), + openStage: prepareForStringify(node.openStage, removePersonalData), + manageStage: prepareForStringify(node.manageStage, removePersonalData), + closeStage: prepareForStringify(node.closeStage, removePersonalData), savedPayload: getSavedPayload(node) } return strategy @@ -271,7 +293,7 @@ function newStringifyNode () { type: node.type, subType: node.subType, name: node.name, - formula: prepareForStringify(node.formula), + formula: prepareForStringify(node.formula, removePersonalData), savedPayload: getSavedPayload(node) } return object @@ -282,7 +304,7 @@ function newStringifyNode () { type: node.type, subType: node.subType, name: node.name, - baseAsset: prepareForStringify(node.baseAsset), + baseAsset: prepareForStringify(node.baseAsset, removePersonalData), savedPayload: getSavedPayload(node) } return object @@ -294,16 +316,91 @@ function newStringifyNode () { subType: node.subType, name: node.name, strategies: [], - parameters: prepareForStringify(node.parameters), + parameters: prepareForStringify(node.parameters, removePersonalData), savedPayload: getSavedPayload(node) } for (let m = 0; m < node.strategies.length; m++) { - let strategy = prepareForStringify(node.strategies[m]) + let strategy = prepareForStringify(node.strategies[m], removePersonalData) tradingSystem.strategies.push(strategy) } return tradingSystem } + case 'Personal Data': { + if (removePersonalData === true) { return } + let personalData = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + exchangeAccounts: [], + savedPayload: getSavedPayload(node) + } + + for (let m = 0; m < node.exchangeAccounts.length; m++) { + let exchangeAccount = prepareForStringify(node.exchangeAccounts[m]) + personalData.exchangeAccounts.push(exchangeAccount) + } + return personalData + } + case 'Exchange Account': { + if (removePersonalData === true) { return } + let exchangeAccount = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + assets: [], + keys: [], + savedPayload: getSavedPayload(node) + } + + for (let m = 0; m < node.assets.length; m++) { + let asset = prepareForStringify(node.assets[m], removePersonalData) + exchangeAccount.assets.push(asset) + } + + for (let m = 0; m < node.keys.length; m++) { + let key = prepareForStringify(node.keys[m], removePersonalData) + exchangeAccount.keys.push(key) + } + return exchangeAccount + } + case 'Exchange Account Asset': { + if (removePersonalData === true) { return } + let asset = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + savedPayload: getSavedPayload(node) + } + return asset + } + case 'Exchange Account Key': { + if (removePersonalData === true) { return } + let key = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + code: node.code, + savedPayload: getSavedPayload(node) + } + return key + } + case 'Definition': { + let object = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + tradingSystem: prepareForStringify(node.tradingSystem, removePersonalData), + personalData: prepareForStringify(node.personalData, removePersonalData), + savedPayload: getSavedPayload(node) + } + return object + } } } diff --git a/StrategySpace/Workspace/Workspace.js b/StrategySpace/Workspace/Workspace.js index 8ee674b5e..d850e3093 100644 --- a/StrategySpace/Workspace/Workspace.js +++ b/StrategySpace/Workspace/Workspace.js @@ -47,7 +47,7 @@ function newWorkspace () { return thisObject function finalize () { - thisObject.tradingSystem = undefined + thisObject.definition = undefined thisObject.container.finalize() thisObject.container = undefined } @@ -59,8 +59,8 @@ function newWorkspace () { } user = JSON.parse(user) - let idAtStrategizer = null - let savedWorkspace = null + let idAtStrategizer = window.localStorage.getItem(CANVAS_APP_NAME + '.' + 'Strategizer Gateway' + '.' + user.alias) + let savedWorkspace = window.localStorage.getItem(CANVAS_APP_NAME + '.' + 'Workspace' + '.' + user.alias) if (savedWorkspace === null || idAtStrategizer === null) { workspaceNode.type = 'Workspace' @@ -82,16 +82,16 @@ function newWorkspace () { async function initializeLoadingFromStrategizer () { let result = await canvas.strategySpace.strategizerGateway.loadFromStrategyzer() if (result === true) { - thisObject.tradingSystem = canvas.strategySpace.strategizerGateway.strategizerData - workspaceNode.rootNodes.push(thisObject.tradingSystem) - functionLibraryPartsFromNodes.createPartFromNode(thisObject.tradingSystem, undefined, undefined) - thisObject.tradingSystem.payload.uiObject.setRunningStatus() + thisObject.definition = canvas.strategySpace.strategizerGateway.strategizerData + workspaceNode.rootNodes.push(thisObject.definition) + functionLibraryPartsFromNodes.createPartFromNode(thisObject.definition, undefined, undefined) + thisObject.definition.payload.uiObject.setRunningStatus() thisObject.enabled = true } } function getProtocolTradingSystem () { - return functionLibraryProtocolNode.getProtocolNode(thisObject.tradingSystem) + return functionLibraryProtocolNode.getProtocolNode(thisObject.definition) } function detachNode (node) { @@ -115,11 +115,11 @@ function newWorkspace () { window.localStorage.setItem(CANVAS_APP_NAME + '.' + 'Workspace' + '.' + user.alias, textToSave) } - function stringifyWorkspace () { + function stringifyWorkspace (removePersonalData) { let stringifyReadyNodes = [] for (let i = 0; i < workspaceNode.rootNodes.length; i++) { let rootNode = workspaceNode.rootNodes[i] - let workspace = functionLibraryWorkspaceNodes.prepareForStringify(rootNode) + let workspace = functionLibraryWorkspaceNodes.prepareForStringify(rootNode, removePersonalData) stringifyReadyNodes.push(workspace) } let workspace = { @@ -127,6 +127,7 @@ function newWorkspace () { name: workspaceNode.name, rootNodes: stringifyReadyNodes } + return JSON.stringify(workspace) } @@ -154,13 +155,19 @@ function newWorkspace () { async function onMenuItemClick (payload, action) { switch (action) { - case 'Download Workspace': + case 'Share Workspace': { - let text = stringifyWorkspace() - let fileName = payload.node.type + ' - ' + payload.node.name + '.json' + let text = stringifyWorkspace(true) + let fileName = 'Share - ' + payload.node.type + ' - ' + payload.node.name + '.json' + download(fileName, text) + } + break + case 'Backup Workspace': + { + let text = stringifyWorkspace(false) + let fileName = 'Backup - ' + payload.node.type + ' - ' + payload.node.name + '.json' download(fileName, text) } - break case 'Save Trading System': { @@ -172,24 +179,37 @@ function newWorkspace () { case 'Edit Code': break - case 'Download': + case 'Share': { - let text = JSON.stringify(functionLibraryProtocolNode.getProtocolNode(payload.node)) + let text = JSON.stringify(functionLibraryProtocolNode.getProtocolNode(payload.node, true)) let nodeName = payload.node.name if (nodeName === undefined) { nodeName = '' } else { nodeName = '.' + nodeName } - let fileName = payload.node.type + ' - ' + nodeName + '.json' + let fileName = 'Share - ' + payload.node.type + ' - ' + nodeName + '.json' download(fileName, text) } break - - case 'New Strategy': + case 'Backup': { - functionLibraryPartsFromNodes.newStrategy(payload.node) + let text = JSON.stringify(functionLibraryProtocolNode.getProtocolNode(payload.node, false)) + let nodeName = payload.node.name + if (nodeName === undefined) { + nodeName = '' + } else { + nodeName = '.' + nodeName + } + let fileName = 'Backup - ' + payload.node.type + ' - ' + nodeName + '.json' + download(fileName, text) + } + + break + case 'Add Strategy': + { + functionLibraryPartsFromNodes.addStrategy(payload.node) } break case 'Add Parameters': @@ -222,6 +242,16 @@ function newWorkspace () { functionLibraryPartsFromNodes.addInitialDefinition(payload.node) } break + case 'Add Open Execution': + { + functionLibraryPartsFromNodes.addOpenExecution(payload.node) + } + break + case 'Add Close Execution': + { + functionLibraryPartsFromNodes.addCloseExecution(payload.node) + } + break case 'Add Phase': { functionLibraryPartsFromNodes.addPhase(payload.node) @@ -252,6 +282,31 @@ function newWorkspace () { functionLibraryPartsFromNodes.addCode(payload.node) } break + case 'Add Exchange Account': + { + functionLibraryPartsFromNodes.addExchangeAccount(payload.node) + } + break + case 'Add Exchange Account Asset': + { + functionLibraryPartsFromNodes.addExchangeAccountAsset(payload.node) + } + break + case 'Add Exchange Account Key': + { + functionLibraryPartsFromNodes.addExchangeAccountKey(payload.node) + } + break + case 'Add Trading System': + { + functionLibraryPartsFromNodes.addTradingSystem(payload.node) + } + break + case 'Add Personal Data': + { + functionLibraryPartsFromNodes.addPersonalData(payload.node) + } + break case 'Delete Trading System': { functionLibraryNodeDeleter.deleteTradingSystem(payload.node, workspaceNode.rootNodes) break @@ -296,6 +351,14 @@ function newWorkspace () { functionLibraryNodeDeleter.deleteInitialDefinition(payload.node, workspaceNode.rootNodes) break } + case 'Delete Open Execution': { + functionLibraryNodeDeleter.deleteOpenExecution(payload.node, workspaceNode.rootNodes) + break + } + case 'Delete Close Execution': { + functionLibraryNodeDeleter.deleteCloseExecution(payload.node, workspaceNode.rootNodes) + break + } case 'Delete Event': { functionLibraryNodeDeleter.deleteEvent(payload.node, workspaceNode.rootNodes) break @@ -324,6 +387,26 @@ function newWorkspace () { functionLibraryNodeDeleter.deleteCode(payload.node, workspaceNode.rootNodes) break } + case 'Delete Exchange Account': { + functionLibraryNodeDeleter.deleteExchangeAccount(payload.node, workspaceNode.rootNodes) + break + } + case 'Delete Exchange Account Asset': { + functionLibraryNodeDeleter.deleteExchangeAccountAsset(payload.node, workspaceNode.rootNodes) + break + } + case 'Delete Exchange Account Key': { + functionLibraryNodeDeleter.deleteExchangeAccountKey(payload.node, workspaceNode.rootNodes) + break + } + case 'Delete Personal Data': { + functionLibraryNodeDeleter.deletePersonalData(payload.node, workspaceNode.rootNodes) + break + } + case 'Delete Definition': { + functionLibraryNodeDeleter.deleteDefinition(payload.node, workspaceNode.rootNodes) + break + } default: } diff --git a/TopSpace/Login.js b/TopSpace/Login.js index b3964fbeb..79b09d25a 100644 --- a/TopSpace/Login.js +++ b/TopSpace/Login.js @@ -1,5 +1,5 @@ -function newLogin() { +function newLogin () { const MODULE_NAME = 'Login' const ERROR_LOG = true const logger = newWebDebugLog() @@ -27,8 +27,10 @@ function newLogin() { return thisObject - async function initialize(sharedStatus) { + async function initialize (sharedStatus) { try { + if (window.canvasApp.executingAt === 'Local') { return } + const accessToken = window.localStorage.getItem('access_token') if (accessToken) { @@ -37,14 +39,13 @@ function newLogin() { } thisObject.container.eventHandler.listenToEvent('onMouseClick', onClick) - } catch (err) { if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err) } if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err.stack = ' + err.stack) } } } - async function getEvents(accessToken, sharedStatus) { + async function getEvents (accessToken, sharedStatus) { var d = new Date() var nowSeconds = Math.round(d.getTime() / 1000) var twoWeeksAgoSeconds = nowSeconds - 1209600 @@ -72,7 +73,7 @@ function newLogin() { } } } - }`, + }` }, variables: { variables: { maxStartDate: nowSeconds, minEndDate: twoWeeksAgoSeconds } @@ -99,7 +100,7 @@ function newLogin() { } } - async function getClones(accessToken) { + async function getClones (accessToken) { let response = await axios({ url: window.canvasApp.graphQL.masterAppApiUrl, method: 'post', @@ -166,11 +167,11 @@ function newLogin() { } } - function onClick() { + function onClick () { } - function getContainer(point) { + function getContainer (point) { /* First we check if this point is inside this object UI. */ if (thisObject.container.frame.isThisPointHere(point, true) === true) { return this.container @@ -180,7 +181,7 @@ function newLogin() { } } - function draw() { + function draw () { return // nothing to show. } } diff --git a/WebDebugLog.js b/WebDebugLog.js index 3888b3b82..6a758304e 100644 --- a/WebDebugLog.js +++ b/WebDebugLog.js @@ -1,17 +1,21 @@ function newWebDebugLog () { - let thisObject = { - write: write, - fileName: 'undefined' - } + try { + let thisObject = { + write: write, + fileName: 'undefined' + } - return thisObject + return thisObject - function write (pText) { - console.log(spacePad(thisObject.fileName, 50) + ' : ' + pText) + function write (pText) { + console.log(spacePad(thisObject.fileName, 50) + ' : ' + pText) - function spacePad (str, max) { - str = str.toString() - return str.length < max ? spacePad(' ' + str, max) : str - } - } -} + function spacePad (str, max) { + str = str.toString() + return str.length < max ? spacePad(' ' + str, max) : str + } + } + } catch (err) { + console.log(spacePad(MODULE_NAME, 50) + ' : ' + '[ERROR] WebDebugLog --> err = ' + err.stack) + } + }