diff --git a/Canvas.js b/Canvas.js index 19a14f60a..c99219890 100644 --- a/Canvas.js +++ b/Canvas.js @@ -82,6 +82,9 @@ function newCanvas () { /* Instantiate all the children spaces of Canvas object */ + thisObject.floatingSpace = newFloatingSpace() + thisObject.floatingSpace.initialize() + thisObject.topSpace = newTopSpace() await thisObject.topSpace.initialize() @@ -94,9 +97,6 @@ function newCanvas () { thisObject.panelsSpace = newPanelsSpace() thisObject.panelsSpace.initialize() - thisObject.floatingSpace = newFloatingSpace() - thisObject.floatingSpace.initialize() - thisObject.chartSpace = newChartSpace() thisObject.chartSpace.initialize(onCharSpaceInitialized) @@ -128,6 +128,7 @@ function newCanvas () { animation.addCallBackFunction('CockpitSpace Physics', thisObject.cockpitSpace.physics) animation.addCallBackFunction('Top Space Draw', thisObject.topSpace.draw) animation.addCallBackFunction('Strategy Space Draw', thisObject.strategySpace.draw) + animation.addCallBackFunction('Strategy Space Physics', thisObject.strategySpace.physics) animation.addCallBackFunction('Splash Screen Draw', splashScreen.draw) animation.start() } catch (err) { @@ -705,4 +706,3 @@ function newCanvas () { } } } - diff --git a/ChartsSpace/TimeMachine.js b/ChartsSpace/TimeMachine.js index 0f01ddf25..b56d543dd 100644 --- a/ChartsSpace/TimeMachine.js +++ b/ChartsSpace/TimeMachine.js @@ -346,6 +346,7 @@ function newTimeMachine () { } function thisBackground () { + return let params = { cornerRadius: 15, lineWidth: 5, diff --git a/CockpitSpace/RestartSimulation.js b/CockpitSpace/RestartSimulation.js index 97a494a7a..530dff1cb 100644 --- a/CockpitSpace/RestartSimulation.js +++ b/CockpitSpace/RestartSimulation.js @@ -6,6 +6,7 @@ function newRestartSimulation () { visible: true, container: undefined, status: undefined, + restart: restart, physics: physics, draw: draw, getContainer: getContainer, @@ -73,7 +74,11 @@ function newRestartSimulation () { isMouseOver = false } - async function onMouseClick (event) { + function onMouseClick (event) { + restart() + } + + async function restart () { let dateAtScreenCorner = new Date(window.localStorage.getItem('Date @ Screen Corner')) let currentTimePeriod = JSON.parse(window.localStorage.getItem('Current Time Period')) @@ -103,7 +108,7 @@ function newRestartSimulation () { } try { thisObject.status = 'Saving' - let result = await canvas.strategySpace.strategizerGateway.saveToStrategyzer(canvas.strategySpace.workspace.tradingSystem) + let result = await canvas.strategySpace.strategizerGateway.saveToStrategyzer() if (result === true) { thisObject.status = 'Restarting' await graphQlRestartSimulation(simulationParams) diff --git a/Dashboard.js b/Dashboard.js index 663c7cfa6..773606797 100644 --- a/Dashboard.js +++ b/Dashboard.js @@ -120,7 +120,6 @@ function newDashboard () { isTrader avatarHandle avatarChangeDate - sessionToken role { id } @@ -136,8 +135,6 @@ function newDashboard () { } }) .then(response => { - sessionToken = response.data.users_UserByAuthId.sessionToken; - window.localStorage.setItem('loggedInUser', JSON.stringify(response.data.users_UserByAuthId)); resolve({ user: response.data.users_UserByAuthId }) }) diff --git a/FloatingSpace/CircularMenu.js b/FloatingSpace/CircularMenu.js index 89113c067..5a6c96be7 100644 --- a/FloatingSpace/CircularMenu.js +++ b/FloatingSpace/CircularMenu.js @@ -52,6 +52,7 @@ function newCircularMenu () { menuItem.action = menuItemInitialValue.action menuItem.actionFunction = menuItemInitialValue.actionFunction + menuItem.actionStatus = menuItemInitialValue.actionStatus menuItem.label = menuItemInitialValue.label menuItem.workingLabel = menuItemInitialValue.workingLabel menuItem.workDoneLabel = menuItemInitialValue.workDoneLabel diff --git a/FloatingSpace/CircularMenuItem.js b/FloatingSpace/CircularMenuItem.js index b4f191322..cbda91bc9 100644 --- a/FloatingSpace/CircularMenuItem.js +++ b/FloatingSpace/CircularMenuItem.js @@ -10,6 +10,7 @@ function newCircularMenuItem () { currentIcon: undefined, action: undefined, actionFunction: undefined, + actionStatus: undefined, label: undefined, workingLabel: undefined, workDoneLabel: undefined, @@ -70,6 +71,7 @@ function newCircularMenuItem () { thisObject.currentIcon = undefined thisObject.payload = undefined thisObject.actionFunction = undefined + thisObject.actionStatus = undefined } function initialize (pPayload) { @@ -140,6 +142,12 @@ function newCircularMenuItem () { thisObject.iconOff = canvas.strategySpace.iconCollection.get(thisObject.iconPathOff) } + /* Current Status might be linked to some other object status */ + + if (thisObject.actionStatus !== undefined) { + thisObject.currentStatus = thisObject.actionStatus() + } + /* Current Status sets the icon to be used */ if (thisObject.currentStatus === true) { diff --git a/FloatingSpace/FloatingObject.js b/FloatingSpace/FloatingObject.js index 266a7cd0c..6bc85f59d 100644 --- a/FloatingSpace/FloatingObject.js +++ b/FloatingSpace/FloatingObject.js @@ -20,7 +20,9 @@ function newFloatingObject () { rawRadius: 0, // This is the radius of this floating object without zoom. targetRadius: 0, // This is the target radius of the floating object with zoom applied. It should be animated until reaching this value. isPinned: false, + getPinStatus: getPinStatus, nearbyFloatingObjects: [], + setPosition: setPosition, pinToggle: pinToggle, physics: physics, initializeMass: initializeMass, @@ -99,6 +101,10 @@ function newFloatingObject () { } } + function getPinStatus () { + return thisObject.isPinned + } + function pinToggle () { if (thisObject.isPinned !== true) { thisObject.isPinned = true @@ -267,8 +273,10 @@ function newFloatingObject () { y: Math.floor((Math.random() * (200) - 100)) + arroundPoint.y } - // thisObject.container.frame.position = thisObject.container.frame.frameThisPoint(position) + setPosition(position) + } + function setPosition (position) { thisObject.container.frame.position.x = position.x thisObject.container.frame.position.y = position.y @@ -309,4 +317,3 @@ function newFloatingObject () { function updateRadius () { } } - diff --git a/FloatingSpace/StrategyPart.js b/FloatingSpace/StrategyPart.js index 664ec9fc8..8076cb23c 100644 --- a/FloatingSpace/StrategyPart.js +++ b/FloatingSpace/StrategyPart.js @@ -17,6 +17,9 @@ function newStrategyPart () { codeEditor: undefined, partTitle: undefined, isExecuting: undefined, + isRunning: undefined, + run: run, + setRunningStatus: setRunningStatus, getReadyToAttach: getReadyToAttach, showAvailabilityToAttach: showAvailabilityToAttach, highlight: highlight, @@ -50,6 +53,7 @@ function newStrategyPart () { let isHighlighted let highlightCounter = 0 + let runningCounter = 0 let previousDistance @@ -160,6 +164,7 @@ function newStrategyPart () { } iconPhysics() + runningPhisycs() highlightPhisycs() detachingPhysics() attachingPhysics() @@ -292,6 +297,30 @@ function newStrategyPart () { // highlightCounter = 0 } + function runningPhisycs () { + if (canvas.strategySpace.workspace.tradingSystem !== undefined) { + if (canvas.strategySpace.workspace.tradingSystem.id !== thisObject.payload.node.id) { + runningCounter-- + } + } + + if (runningCounter < 0) { + runningCounter = 0 + thisObject.isRunning = false + } + } + + function run () { + canvas.strategySpace.workspace.tradingSystem = thisObject.payload.node + canvas.cockpitSpace.restartSimulation.restart() + setRunningStatus() + } + + function setRunningStatus () { + thisObject.isRunning = true + runningCounter = 30 + } + function iconPhysics () { icon = canvas.strategySpace.iconByPartType.get(thisObject.payload.node.type) executingIcon = canvas.strategySpace.iconCollection.get('attractive') @@ -453,7 +482,7 @@ function newStrategyPart () { labelPoint = { x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 5, - y: position.y + radius * 2 / 3 + fontSize * FONT_ASPECT_RATIO + 15 + y: position.y + radius * 4 / 5 + fontSize * FONT_ASPECT_RATIO + 15 } browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY @@ -556,6 +585,21 @@ function newStrategyPart () { browserCanvasContext.fill() + if (thisObject.isRunning === true) { + VISIBLE_RADIUS = thisObject.container.frame.radius * 2 + let OPACITY = runningCounter / 30 + + browserCanvasContext.beginPath() + browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) + browserCanvasContext.closePath() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + OPACITY + ')' + + browserCanvasContext.lineWidth = 10 + browserCanvasContext.setLineDash([4, 20]) + browserCanvasContext.stroke() + } + if (isHighlighted === true) { VISIBLE_RADIUS = thisObject.container.frame.radius let OPACITY = highlightCounter / 30 @@ -614,9 +658,6 @@ function newStrategyPart () { } } - if (thisObject.isExecuting === true) { - let a = 1 - } if (executingIcon !== undefined) { if (executingIcon.canDrawIcon === true) { if (thisObject.isExecuting === true) { @@ -633,3 +674,4 @@ function newStrategyPart () { } } } + diff --git a/FloatingSpace/StrategyPartConstructor.js b/FloatingSpace/StrategyPartConstructor.js index bbe0151e8..2ea714253 100644 --- a/FloatingSpace/StrategyPartConstructor.js +++ b/FloatingSpace/StrategyPartConstructor.js @@ -6,12 +6,10 @@ function newStrategyPartConstructor () { logger.fileName = MODULE_NAME let thisObject = { - createStrategyPart: createStrategyPart, destroyStrategyPart: destroyStrategyPart, initialize: initialize, finalize: finalize - } let floatingLayer @@ -36,13 +34,33 @@ function newStrategyPartConstructor () { floatingObject.initialize('Strategy Part', payload) payload.floatingObject = floatingObject + if (payload.node.savedPayload !== undefined) { + position = { + x: payload.node.savedPayload.position.x, + y: payload.node.savedPayload.position.y + } + floatingObject.setPosition(position) + payload.node.savedPayload.position = undefined + if (payload.node.savedPayload.floatingObject.isPinned === true) { + floatingObject.pinToggle() + } + } + let strategyPart = newStrategyPart() + payload.uiObject = strategyPart strategyPart.fitFunction = canvas.floatingSpace.fitIntoVisibleArea strategyPart.isVisibleFunction = canvas.floatingSpace.isThisPointVisible let menuItemsInitialValues = getMenuItemsInitialValues(strategyPart, floatingObject, payload) strategyPart.initialize(payload, menuItemsInitialValues) strategyPart.container.connectToParent(floatingObject.container, false, false, true, true, false, false, true, true, true, true, true) - payload.uiObject = strategyPart + + if (payload.node.savedPayload !== undefined) { + if (payload.node.savedPayload.uiObject.isRunning === true) { + strategyPart.setRunningStatus() + canvas.strategySpace.workspace.tradingSystem = payload.node + } + } + payload.node.savedPayload = undefined setFloatingObjectBasicProperties(floatingObject, payload) @@ -61,6 +79,7 @@ function newStrategyPartConstructor () { { action: 'Pin / Unpin', actionFunction: floatingObject.pinToggle, + actionStatus: floatingObject.getPinStatus, currentStatus: true, label: undefined, visible: false, @@ -71,6 +90,18 @@ function newStrategyPartConstructor () { currentRadius: 0, angle: -135 }, + { + action: 'Run Trading System', + actionFunction: payload.uiObject.run, + label: 'Run', + visible: false, + iconPathOn: 'paper-plane', + iconPathOff: 'upload', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -60 + }, { action: 'Save Trading System', actionFunction: payload.onMenuItemClick, @@ -84,7 +115,7 @@ function newStrategyPartConstructor () { rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: -40 + angle: -20 }, { action: 'New Strategy', @@ -97,7 +128,7 @@ function newStrategyPartConstructor () { rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: 0 + angle: 20 }, { action: 'Download', @@ -109,7 +140,7 @@ function newStrategyPartConstructor () { rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: 40 + angle: 60 }] break } @@ -118,6 +149,7 @@ function newStrategyPartConstructor () { { action: 'Pin / Unpin', actionFunction: floatingObject.pinToggle, + actionStatus: floatingObject.getPinStatus, currentStatus: false, label: undefined, visible: false, @@ -159,6 +191,7 @@ function newStrategyPartConstructor () { { action: 'Pin / Unpin', actionFunction: floatingObject.pinToggle, + actionStatus: floatingObject.getPinStatus, currentStatus: false, label: undefined, visible: false, @@ -201,6 +234,7 @@ function newStrategyPartConstructor () { { action: 'Pin / Unpin', actionFunction: floatingObject.pinToggle, + actionStatus: floatingObject.getPinStatus, currentStatus: false, label: undefined, visible: false, @@ -243,6 +277,7 @@ function newStrategyPartConstructor () { { action: 'Pin / Unpin', actionFunction: floatingObject.pinToggle, + actionStatus: floatingObject.getPinStatus, currentStatus: false, label: undefined, visible: false, @@ -285,6 +320,7 @@ function newStrategyPartConstructor () { { action: 'Pin / Unpin', actionFunction: floatingObject.pinToggle, + actionStatus: floatingObject.getPinStatus, currentStatus: false, label: undefined, visible: false, @@ -327,6 +363,7 @@ function newStrategyPartConstructor () { { action: 'Pin / Unpin', actionFunction: floatingObject.pinToggle, + actionStatus: floatingObject.getPinStatus, currentStatus: false, label: undefined, visible: false, @@ -374,6 +411,7 @@ function newStrategyPartConstructor () { { action: 'Pin / Unpin', actionFunction: floatingObject.pinToggle, + actionStatus: floatingObject.getPinStatus, currentStatus: false, label: undefined, visible: false, @@ -441,6 +479,7 @@ function newStrategyPartConstructor () { { action: 'Pin / Unpin', actionFunction: floatingObject.pinToggle, + actionStatus: floatingObject.getPinStatus, currentStatus: false, label: undefined, visible: false, @@ -500,6 +539,7 @@ function newStrategyPartConstructor () { { action: 'Pin / Unpin', actionFunction: floatingObject.pinToggle, + actionStatus: floatingObject.getPinStatus, currentStatus: false, label: undefined, visible: false, diff --git a/FloatingSpace/StrategyPartTitle.js b/FloatingSpace/StrategyPartTitle.js index 296b05772..865b1039b 100644 --- a/FloatingSpace/StrategyPartTitle.js +++ b/FloatingSpace/StrategyPartTitle.js @@ -49,6 +49,7 @@ function newStrategyPartTitle () { switch (payload.node.type) { case 'Trading System': { + thisObject.allwaysVisible = true break } case 'Strategy': { @@ -116,7 +117,7 @@ function newStrategyPartTitle () { const FRAME_HEIGHT = 25 const FRAME_WIDTH = title.length / 2 * thisObject.payload.floatingObject.currentFontSize * FONT_ASPECT_RATIO * 1.2 * 2 thisObject.container.frame.position.x = 0 - FRAME_WIDTH / 2 - thisObject.container.frame.position.y = 0 - thisObject.container.frame.radius * 1 / 2 - thisObject.payload.floatingObject.currentFontSize * FONT_ASPECT_RATIO - 10 - FRAME_HEIGHT + thisObject.container.frame.position.y = 0 - thisObject.container.frame.radius * 1 / 2 - thisObject.payload.floatingObject.currentFontSize * FONT_ASPECT_RATIO - 20 - FRAME_HEIGHT thisObject.container.frame.width = FRAME_WIDTH thisObject.container.frame.height = FRAME_HEIGHT diff --git a/Spaces/CockpitSpace.js b/Spaces/CockpitSpace.js index 92cb0e922..9de6a2eb1 100644 --- a/Spaces/CockpitSpace.js +++ b/Spaces/CockpitSpace.js @@ -47,7 +47,9 @@ thisObject.container.frame.position.x = 0 let INITIAL_POSITION - if (canvas.strategySpace.isInitialized === true) { + const accessToken = window.localStorage.getItem(LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY) + + if (accessToken !== null) { INITIAL_POSITION = 55 } else { INITIAL_POSITION = 100 diff --git a/Spaces/StrategySpace.js b/Spaces/StrategySpace.js index c24ffadbc..3685ae89b 100644 --- a/Spaces/StrategySpace.js +++ b/Spaces/StrategySpace.js @@ -8,8 +8,7 @@ function newStrategySpace () { iconCollection: undefined, iconByPartType: undefined, workspace: undefined, - isDeployed: false, - isInitialized: false, + physics: physics, draw: draw, getContainer: getContainer, makeVisible: makeVisible, @@ -29,17 +28,14 @@ function newStrategySpace () { return thisObject async function initialize () { - thisObject.strategizerGateway = newStrategizerGateway() - - thisObject.strategizerGateway.initialize() - await thisObject.strategizerGateway.loadFromStrategyzer() - loadIconCollection() buildIconByPartTypeMap() - if (thisObject.strategizerGateway.strategizerData !== undefined) { - thisObject.isInitialized = true - } + thisObject.strategizerGateway = newStrategizerGateway() + thisObject.strategizerGateway.initialize() + + thisObject.workspace = newWorkspace() + thisObject.workspace.initialize() } function buildIconByPartTypeMap () { @@ -138,20 +134,14 @@ function newStrategySpace () { } } - function makeVisible () { - if (thisObject.isDeployed !== true) { - deploydTradingSystem() - } - canvas.floatingSpace.makeVisible() - visible = true + function physics () { + if (visible !== true) { return } + thisObject.workspace.physics() } - function deploydTradingSystem () { - thisObject.workspace = newWorkspace() - if (thisObject.strategizerGateway.strategizerData !== undefined) { - thisObject.workspace.initialize(thisObject.strategizerGateway.strategizerData) - thisObject.isDeployed = true - } + function makeVisible () { + canvas.floatingSpace.makeVisible() + visible = true } function makeInvisible () { diff --git a/StrategySpace/StrategizerGateway.js b/StrategySpace/StrategizerGateway.js index 60d4cff73..1e06d799b 100644 --- a/StrategySpace/StrategizerGateway.js +++ b/StrategySpace/StrategizerGateway.js @@ -36,7 +36,7 @@ function newStrategizerGateway () { } - async function saveToStrategyzer (tradingSystem) { + async function saveToStrategyzer () { try { const accessToken = window.localStorage.getItem(LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY) @@ -73,6 +73,8 @@ function newStrategizerGateway () { } }]) + let tradingSystem = canvas.strategySpace.workspace.tradingSystem + let idAtStrategizer = canvas.strategySpace.workspace.idAtStrategizer let dataToSave = buildGraphQLDataToSave(tradingSystem) const updateStrategies = () => { @@ -80,7 +82,7 @@ function newStrategizerGateway () { apolloClient.mutate({ mutation: GRAPHQL_MUTATION_UPDATE_STRATEGIES, variables: { - id: thisObject.strategizerData.id, + id: idAtStrategizer, strategy: dataToSave.strategy } }) diff --git a/StrategySpace/Workspace.js b/StrategySpace/Workspace.js index f2c76368a..180c97dec 100644 --- a/StrategySpace/Workspace.js +++ b/StrategySpace/Workspace.js @@ -5,6 +5,8 @@ function newWorkspace () { let thisObject = { tradingSystem: undefined, container: undefined, + idAtStrategizer: undefined, + physics: physics, spawn: spawn, detachNode: detachNode, attachNode: attachNode, @@ -30,6 +32,8 @@ function newWorkspace () { y: canvas.floatingSpace.container.frame.height / 2 } + let rootNodes = [] + return thisObject function finalize () { @@ -38,18 +42,60 @@ function newWorkspace () { thisObject.container = undefined } - function initialize (tradingSystem) { - thisObject.tradingSystem = { - id: tradingSystem.id, - strategies: tradingSystem.subStrategies + async function initialize () { + let savedWorkspace = window.localStorage.getItem('workspace') + if (savedWorkspace === null) { + initializeLoadingFromStrategizer() + } else { + workspace = JSON.parse(savedWorkspace) + rootNodes = workspace.rootNodes + thisObject.idAtStrategizer = workspace.idAtStrategizer + if (thisObject.idAtStrategizer === undefined) { + initializeLoadingFromStrategizer() + } else { + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + createPartFromNode(rootNode, undefined, undefined) + } + } + } + } + + async function initializeLoadingFromStrategizer () { + await canvas.strategySpace.strategizerGateway.loadFromStrategyzer() + let tradingSystem = canvas.strategySpace.strategizerGateway.strategizerData + if (tradingSystem !== undefined) { + let adaptedTradingSystem = { + strategies: tradingSystem.subStrategies + } + thisObject.idAtStrategizer = tradingSystem.id + rootNodes.push(adaptedTradingSystem) + generateStrategyParts(adaptedTradingSystem) + thisObject.tradingSystem = adaptedTradingSystem + thisObject.tradingSystem.payload.uiObject.setRunningStatus() } - generateStrategyParts() } function getContainer (point) { } + function physics () { + /* Here we will save all the workspace related objects into the local storage */ + let stringifyReadyNodes = [] + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + let workspaceNode = getWorkspaceNode(rootNode) + stringifyReadyNodes.push(workspaceNode) + } + let workspace = { + idAtStrategizer: thisObject.idAtStrategizer, + rootNodes: stringifyReadyNodes + } + let textToSave = JSON.stringify(workspace) + window.localStorage.setItem('workspace', textToSave) + } + function spawn (nodeText, point) { point = canvas.floatingSpace.container.frame.unframeThisPoint(point) spawnPosition.x = point.x @@ -57,6 +103,7 @@ function newWorkspace () { let dirtyNode = JSON.parse(nodeText) let rootNode = getProtocolNode(dirtyNode) + rootNodes.push(rootNode) createPartFromNode(rootNode, undefined, undefined) } @@ -181,8 +228,7 @@ function newWorkspace () { if (strategy.id === node.id) { payload.parentNode.strategies.splice(i, 1) } - payload.parentNode = undefined - payload.chainParent = undefined + completeDetachment(node) } } break @@ -214,8 +260,7 @@ function newWorkspace () { payload.parentNode.conditions.splice(i, 1) } } - node.payload.chainParent = undefined - node.payload.parentNode = undefined + completeDetachment(node) } break case 'Situation': { @@ -226,8 +271,7 @@ function newWorkspace () { payload.parentNode.situations.splice(i, 1) } } - node.payload.chainParent = undefined - node.payload.parentNode = undefined + completeDetachment(node) } break case 'Phase': { @@ -245,8 +289,7 @@ function newWorkspace () { } } payload.parentNode.phases.splice(i, 1) - payload.parentNode = undefined - payload.chainParent = undefined + completeDetachment(node) return } } @@ -260,6 +303,7 @@ function newWorkspace () { node.payload.parentNode = attachToNode node.payload.chainParent = attachToNode node.payload.parentNode.strategies.push(node) + completeAttachment(node) } break case 'Phase': { @@ -273,6 +317,7 @@ function newWorkspace () { node.payload.chainParent = attachToNode } attachToNode.phases.push(node) + completeAttachment(node) } break case 'Take Profit': { @@ -284,6 +329,7 @@ function newWorkspace () { node.payload.chainParent = attachToNode } attachToNode.phases.push(node) + completeAttachment(node) } break case 'Phase': { @@ -294,11 +340,13 @@ function newWorkspace () { if (i === node.payload.parentNode.phases.length - 1) { node.payload.chainParent = attachToNode node.payload.parentNode.phases.push(node) + completeAttachment(node) } else { node.payload.chainParent = attachToNode let nextPhase = node.payload.parentNode.phases[i + 1] nextPhase.payload.chainParent = node node.payload.parentNode.phases.splice(i + 1, 0, node) + completeAttachment(node) return } } @@ -311,28 +359,56 @@ function newWorkspace () { node.payload.parentNode = attachToNode node.payload.chainParent = attachToNode node.payload.parentNode.situations.push(node) + completeAttachment(node) } break case 'Condition': { node.payload.parentNode = attachToNode node.payload.chainParent = attachToNode node.payload.parentNode.conditions.push(node) + completeAttachment(node) } break } } + function completeDetachment (node) { + node.payload.parentNode = undefined + node.payload.chainParent = undefined + rootNodes.push(node) + } + + function completeAttachment (node) { + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + if (rootNode.id === node.id) { + rootNodes.splice(i, 1) + return + } + } + } + function createPart (partType, name, node, parentNode, chainParent, title) { let payload = {} - if (chainParent === undefined) { + + if (name === '' || name === undefined) { name = 'My ' + partType } + if (node.savedPayload !== undefined) { payload.targetPosition = { - x: spawnPosition.x, - y: spawnPosition.y + x: node.savedPayload.targetPosition.x, + y: node.savedPayload.targetPosition.y } + node.savedPayload.targetPosition = undefined } else { - payload.targetPosition = { - x: chainParent.payload.position.x, - y: chainParent.payload.position.y + if (chainParent === undefined) { + payload.targetPosition = { + x: spawnPosition.x, + y: spawnPosition.y + } + } else { + payload.targetPosition = { + x: chainParent.payload.position.x, + y: chainParent.payload.position.y + } } } @@ -361,11 +437,11 @@ function newWorkspace () { canvas.floatingSpace.strategyPartConstructor.destroyStrategyPart(node.payload) } - function generateStrategyParts () { + function generateStrategyParts (node) { let lastPhase - let tradingSystem = thisObject.tradingSystem + let tradingSystem = node - createPart('Trading System', '', tradingSystem, undefined, undefined) + createPart('Trading System', tradingSystem.name, tradingSystem, undefined, undefined) for (m = 0; m < tradingSystem.strategies.length; m++) { let strategy = tradingSystem.strategies[m] @@ -457,7 +533,7 @@ function newWorkspace () { switch (action) { case 'Save Trading System': { - let result = await canvas.strategySpace.strategizerGateway.saveToStrategyzer(canvas.strategySpace.workspace.tradingSystem) + let result = await canvas.strategySpace.strategizerGateway.saveToStrategyzer() return result break } @@ -730,15 +806,16 @@ function newWorkspace () { { let condition = { type: node.type, + subType: node.subType, name: node.name, code: node.code } return condition - break } case 'Situation': { let situation = { type: node.type, + subType: node.subType, name: node.name, conditions: [] } @@ -748,7 +825,6 @@ function newWorkspace () { situation.conditions.push(condition) } return situation - break } case 'Phase': { let phase = { @@ -764,7 +840,6 @@ function newWorkspace () { phase.situations.push(situation) } return phase - break } case 'Stop': { let stop = { @@ -779,7 +854,6 @@ function newWorkspace () { stop.phases.push(phase) } return stop - break } case 'Take Profit': { let takeProfit = { @@ -794,7 +868,6 @@ function newWorkspace () { takeProfit.phases.push(phase) } return takeProfit - break } case 'Take Position Event': { let event = { @@ -809,7 +882,6 @@ function newWorkspace () { event.situations.push(situation) } return event - break } case 'Trigger On Event': { let event = { @@ -824,7 +896,6 @@ function newWorkspace () { event.situations.push(situation) } return event - break } case 'Trigger Off Event': { let event = { @@ -839,7 +910,6 @@ function newWorkspace () { event.situations.push(situation) } return event - break } case 'Strategy': { let strategy = { @@ -853,7 +923,6 @@ function newWorkspace () { buyOrder: getProtocolNode(node.buyOrder) } return strategy - break } case 'Trading System': { let tradingSystem = { @@ -868,8 +937,188 @@ function newWorkspace () { tradingSystem.strategies.push(strategy) } return tradingSystem - break } } } + + function getWorkspaceNode (node) { + switch (node.type) { + case 'Condition': + { + let condition = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + code: node.code, + savedPayload: getSavedPayload(node) + } + return condition + } + case 'Situation': { + let situation = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + conditions: [], + savedPayload: getSavedPayload(node) + } + + for (let m = 0; m < node.conditions.length; m++) { + let condition = getWorkspaceNode(node.conditions[m]) + situation.conditions.push(condition) + } + return situation + } + case 'Phase': { + let phase = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + code: node.code, + situations: [], + savedPayload: getSavedPayload(node) + } + + for (let m = 0; m < node.situations.length; m++) { + let situation = getWorkspaceNode(node.situations[m]) + phase.situations.push(situation) + } + return phase + } + case 'Stop': { + let stop = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + phases: [], + savedPayload: getSavedPayload(node) + } + + for (let m = 0; m < node.phases.length; m++) { + let phase = getWorkspaceNode(node.phases[m]) + stop.phases.push(phase) + } + return stop + } + case 'Take Profit': { + let takeProfit = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + phases: [], + savedPayload: getSavedPayload(node) + } + + for (let m = 0; m < node.phases.length; m++) { + let phase = getWorkspaceNode(node.phases[m]) + takeProfit.phases.push(phase) + } + return takeProfit + } + case 'Take Position Event': { + let event = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + situations: [], + savedPayload: getSavedPayload(node) + } + + for (let m = 0; m < node.situations.length; m++) { + let situation = getWorkspaceNode(node.situations[m]) + event.situations.push(situation) + } + return event + } + case 'Trigger On Event': { + let event = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + situations: [], + savedPayload: getSavedPayload(node) + } + + for (let m = 0; m < node.situations.length; m++) { + let situation = getWorkspaceNode(node.situations[m]) + event.situations.push(situation) + } + return event + } + case 'Trigger Off Event': { + let event = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + situations: [], + savedPayload: getSavedPayload(node) + } + + for (let m = 0; m < node.situations.length; m++) { + let situation = getWorkspaceNode(node.situations[m]) + event.situations.push(situation) + } + return event + } + case 'Strategy': { + let strategy = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + entryPoint: getWorkspaceNode(node.entryPoint), + exitPoint: getWorkspaceNode(node.exitPoint), + sellPoint: getWorkspaceNode(node.sellPoint), + stopLoss: getWorkspaceNode(node.stopLoss), + buyOrder: getWorkspaceNode(node.buyOrder), + savedPayload: getSavedPayload(node) + } + return strategy + } + case 'Trading System': { + let tradingSystem = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + strategies: [], + savedPayload: getSavedPayload(node) + } + + for (let m = 0; m < node.strategies.length; m++) { + let strategy = getWorkspaceNode(node.strategies[m]) + tradingSystem.strategies.push(strategy) + } + return tradingSystem + } + } + } + + function getSavedPayload (node) { + let savedPayload = { + position: { + x: node.payload.position.x, + y: node.payload.position.y + }, + targetPosition: { + x: node.payload.targetPosition.x, + y: node.payload.targetPosition.y + }, + floatingObject: { + isPinned: node.payload.floatingObject.isPinned + }, + uiObject: { + isRunning: node.payload.uiObject.isRunning + } + } + return savedPayload + } }