From deb5327e42c2f93f1e63ed21ef944f2c04bbe292 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 27 Jul 2019 22:08:38 +0200 Subject: [PATCH] Definition Added, with Personal Data and Trading System as children --- FloatingSpace/StrategyPart.js | 10 ++ FloatingSpace/StrategyPartConstructor.js | 140 +++++++++++++----- FloatingSpace/StrategyPartTitle.js | 4 + Spaces/StrategySpace.js | 1 + .../FunctionLibraries/AttachDetach.js | 21 +++ .../FunctionLibraries/NodeChildren.js | 23 +++ .../FunctionLibraries/NodeDeleter.js | 71 ++++++--- .../FunctionLibraries/PartsFromNodes.js | 30 ++++ .../FunctionLibraries/ProtocolNode.js | 10 ++ .../FunctionLibraries/StringifyNode.js | 12 ++ StrategySpace/Workspace/Workspace.js | 18 +++ 11 files changed, 283 insertions(+), 57 deletions(-) diff --git a/FloatingSpace/StrategyPart.js b/FloatingSpace/StrategyPart.js index 9986c3647..ba474fdd6 100644 --- a/FloatingSpace/StrategyPart.js +++ b/FloatingSpace/StrategyPart.js @@ -196,6 +196,14 @@ 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 @@ -314,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 } diff --git a/FloatingSpace/StrategyPartConstructor.js b/FloatingSpace/StrategyPartConstructor.js index 37c82ae39..c3c94205c 100644 --- a/FloatingSpace/StrategyPartConstructor.js +++ b/FloatingSpace/StrategyPartConstructor.js @@ -153,9 +153,105 @@ function newStrategyPartConstructor () { function getMenuItemsInitialValues (strategyPart, floatingObject, payload) { let menuItemsInitialValues = [] switch (payload.node.type) { - case 'Personal Data': { + case 'Workspace': { floatingObject.isPinned = true floatingObject.positionLocked = true + menuItemsInitialValues = [ + { + action: 'Pin / Unpin', + actionFunction: floatingObject.pinToggle, + actionStatus: floatingObject.getPinStatus, + currentStatus: true, + label: undefined, + visible: false, + iconPathOn: 'target', + iconPathOff: 'security', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -135 + }, + { + action: 'Download Workspace', + actionFunction: payload.onMenuItemClick, + label: 'Download', + visible: false, + iconPathOn: 'upload', + iconPathOff: 'upload', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 0 + }] + break + } + case 'Definition': { + floatingObject.isPinned = true + floatingObject.positionLocked = true + addLeftIcons(menuItemsInitialValues, floatingObject) + menuItemsInitialValues.push( + { + action: 'Delete Definition', + askConfirmation: true, + confirmationLabel: 'Confirm to Delete', + actionFunction: payload.onMenuItemClick, + label: 'Delete Definition', + visible: false, + iconPathOn: 'trash', + iconPathOff: 'trash', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -60 + } + ) + menuItemsInitialValues.push( + { + action: 'Add Trading System', + actionFunction: payload.onMenuItemClick, + label: 'Add Trading System', + visible: false, + iconPathOn: 'approve', + iconPathOff: 'approve', + relatedStrategyPart: 'Trading System', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -20 + } + ) + menuItemsInitialValues.push( + { + action: 'Add Personal Data', + actionFunction: payload.onMenuItemClick, + label: 'Add Personal Data', + visible: false, + iconPathOn: 'approve', + iconPathOff: 'approve', + relatedStrategyPart: 'Personal Data', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 20 + } + ) + menuItemsInitialValues.push( + { + action: 'Download', + actionFunction: payload.onMenuItemClick, + label: 'Download', + visible: false, + iconPathOn: 'upload', + iconPathOff: 'upload', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 60 + } + ) + break + } + case 'Personal Data': { addLeftIcons(menuItemsInitialValues, floatingObject) menuItemsInitialValues.push( { @@ -336,41 +432,7 @@ function newStrategyPartConstructor () { ) break } - case 'Workspace': { - floatingObject.isPinned = true - floatingObject.positionLocked = true - menuItemsInitialValues = [ - { - action: 'Pin / Unpin', - actionFunction: floatingObject.pinToggle, - actionStatus: floatingObject.getPinStatus, - currentStatus: true, - label: undefined, - visible: false, - iconPathOn: 'target', - iconPathOff: 'security', - rawRadius: 8, - targetRadius: 0, - currentRadius: 0, - angle: -135 - }, - { - action: 'Download Workspace', - actionFunction: payload.onMenuItemClick, - label: 'Download', - visible: false, - iconPathOn: 'upload', - iconPathOff: 'upload', - rawRadius: 8, - targetRadius: 0, - currentRadius: 0, - angle: 0 - }] - break - } case 'Trading System': { - floatingObject.isPinned = true - floatingObject.positionLocked = true addLeftIcons(menuItemsInitialValues, floatingObject) menuItemsInitialValues.push( { @@ -1647,6 +1709,10 @@ function newStrategyPartConstructor () { level_0() break } + case 'Definition': { + level_0() + break + } case 'Exchange Account': { level_1() break @@ -1660,11 +1726,11 @@ function newStrategyPartConstructor () { break } case 'Personal Data': { - level_0() + level_1() break } case 'Trading System': { - level_0() + level_1() break } case 'Parameters': { diff --git a/FloatingSpace/StrategyPartTitle.js b/FloatingSpace/StrategyPartTitle.js index 7ad6c9f90..a47ec5402 100644 --- a/FloatingSpace/StrategyPartTitle.js +++ b/FloatingSpace/StrategyPartTitle.js @@ -48,6 +48,10 @@ function newStrategyPartTitle () { thisObject.payload = payload switch (payload.node.type) { + case 'Definition': { + thisObject.allwaysVisible = true + break + } case 'Personal Data': { break } diff --git a/Spaces/StrategySpace.js b/Spaces/StrategySpace.js index 30d47d29d..8d78281af 100644 --- a/Spaces/StrategySpace.js +++ b/Spaces/StrategySpace.js @@ -39,6 +39,7 @@ function newStrategySpace () { function buildIconByPartTypeMap () { const relationshipArray = [ + ['Definition', 'text'], ['Personal Data', 'security'], ['Exchange Account', 'approve'], ['Exchange Account Asset', 'paper-plane'], diff --git a/StrategySpace/Workspace/FunctionLibraries/AttachDetach.js b/StrategySpace/Workspace/FunctionLibraries/AttachDetach.js index 7e9af0cf0..107539f5f 100644 --- a/StrategySpace/Workspace/FunctionLibraries/AttachDetach.js +++ b/StrategySpace/Workspace/FunctionLibraries/AttachDetach.js @@ -8,7 +8,12 @@ function newAttachDetach () { function detachNode (node, rootNodes) { switch (node.type) { + case 'Definition': { + return + } case 'Personal Data': { + node.payload.parentNode.personalData = undefined + completeDetachment(node, rootNodes) return } case 'Exchange Account': { @@ -45,6 +50,8 @@ function newAttachDetach () { return } case 'Trading System': { + node.payload.parentNode.tradingSystem = undefined + completeDetachment(node, rootNodes) return } case 'Base Asset': { @@ -196,6 +203,13 @@ function newAttachDetach () { 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 @@ -231,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 diff --git a/StrategySpace/Workspace/FunctionLibraries/NodeChildren.js b/StrategySpace/Workspace/FunctionLibraries/NodeChildren.js index e408852c1..9d57b1a87 100644 --- a/StrategySpace/Workspace/FunctionLibraries/NodeChildren.js +++ b/StrategySpace/Workspace/FunctionLibraries/NodeChildren.js @@ -8,6 +8,9 @@ function newNodeChildren () { function childrenCount (parentNode, childNode) { switch (parentNode.type) { + case 'Definition': { + return countChildrenDefinition(parentNode, childNode) + } case 'Personal Data': { return countChildrenPersonalData(parentNode, childNode) } @@ -98,6 +101,26 @@ 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, diff --git a/StrategySpace/Workspace/FunctionLibraries/NodeDeleter.js b/StrategySpace/Workspace/FunctionLibraries/NodeDeleter.js index 6a4e00449..e4ded4e0b 100644 --- a/StrategySpace/Workspace/FunctionLibraries/NodeDeleter.js +++ b/StrategySpace/Workspace/FunctionLibraries/NodeDeleter.js @@ -1,5 +1,6 @@ function newNodeDeleter () { thisObject = { + deleteDefinition: deleteDefinition, deletePersonalData: deletePersonalData, deleteExchangeAccount: deleteExchangeAccount, deleteExchangeAccountAsset: deleteExchangeAccountAsset, @@ -38,24 +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, true) + deletePersonalData(rootNode, rootNodes) break } case 'Exchange Account': { - deleteExchangeAccount(rootNode, rootNodes, true) + deleteExchangeAccount(rootNode, rootNodes) break } case 'Exchange Account Asset': { - deleteExchangeAccountAsset(rootNode, rootNodes, true) + deleteExchangeAccountAsset(rootNode, rootNodes) break } case 'Exchange Account Key': { - deleteExchangeAccountKey(rootNode, rootNodes, true) + deleteExchangeAccountKey(rootNode, rootNodes) break } case 'Trading System': { - deleteTradingSystem(rootNode, rootNodes, true) + deleteTradingSystem(rootNode, rootNodes) break } case 'Parameters': { @@ -146,9 +151,45 @@ function newNodeDeleter () { cleanNode(node) } + function deleteDefinition (node, rootNodes, forced) { + let payload = node.payload + + if (forced !== true) { + /* Can not delete if it is the last one */ + let counter = 0 + for (let i = 0; i < rootNodes.length; i++) { + let rootNode = rootNodes[i] + if (rootNode.type === node.type) { + counter++ + } + } + if (counter <= 1) { return } + } + + if (node.payload.uiObject.isRunning === true) { + 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) { - deleteStrategy(node.exchangeAccounts[0], rootNodes) + deleteExchangeAccount(node.exchangeAccounts[0], rootNodes) } completeDeletion(node, rootNodes) @@ -209,21 +250,11 @@ function newNodeDeleter () { cleanNode(node) } - function deleteTradingSystem (node, rootNodes, forced) { - if (forced !== true) { - /* Can not delete if it is the last one */ - let counter = 0 - for (let i = 0; i < rootNodes.length; i++) { - let rootNode = rootNodes[i] - if (rootNode.type === node.type) { - counter++ - } - } - if (counter <= 1) { return } - } + function deleteTradingSystem (node, rootNodes) { + let payload = node.payload - if (node.payload.uiObject.isRunning === true) { - node.payload.uiObject.setNotRunningStatus() + if (payload.parentNode !== undefined) { + payload.parentNode.tradingSystem = undefined } while (node.strategies.length > 0) { diff --git a/StrategySpace/Workspace/FunctionLibraries/PartsFromNodes.js b/StrategySpace/Workspace/FunctionLibraries/PartsFromNodes.js index 411c4c038..717496d2d 100644 --- a/StrategySpace/Workspace/FunctionLibraries/PartsFromNodes.js +++ b/StrategySpace/Workspace/FunctionLibraries/PartsFromNodes.js @@ -1,6 +1,8 @@ function newPartsFromNodes () { thisObject = { createPartFromNode: createPartFromNode, + addTradingSystem: addTradingSystem, + addPersonalData: addPersonalData, addExchangeAccount: addExchangeAccount, addExchangeAccountAsset: addExchangeAccountAsset, addExchangeAccountKey: addExchangeAccountKey, @@ -299,6 +301,34 @@ function newPartsFromNodes () { 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 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) } } diff --git a/StrategySpace/Workspace/FunctionLibraries/ProtocolNode.js b/StrategySpace/Workspace/FunctionLibraries/ProtocolNode.js index e9f84014f..7f569fc43 100644 --- a/StrategySpace/Workspace/FunctionLibraries/ProtocolNode.js +++ b/StrategySpace/Workspace/FunctionLibraries/ProtocolNode.js @@ -325,6 +325,16 @@ function newProtocolNode () { } return key } + case 'Definition': { + let object = { + type: node.type, + subType: node.subType, + name: node.name, + tradingSystem: getProtocolNode(node.tradingSystem), + personalData: getProtocolNode(node.personalData) + } + return object + } } } } diff --git a/StrategySpace/Workspace/FunctionLibraries/StringifyNode.js b/StrategySpace/Workspace/FunctionLibraries/StringifyNode.js index f3e1a5cbd..ffb8723cd 100644 --- a/StrategySpace/Workspace/FunctionLibraries/StringifyNode.js +++ b/StrategySpace/Workspace/FunctionLibraries/StringifyNode.js @@ -384,6 +384,18 @@ function newStringifyNode () { } return key } + case 'Definition': { + let object = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + tradingSystem: prepareForStringify(node.tradingSystem), + personalData: prepareForStringify(node.personalData), + savedPayload: getSavedPayload(node) + } + return object + } } } diff --git a/StrategySpace/Workspace/Workspace.js b/StrategySpace/Workspace/Workspace.js index 9d8c36038..a75374aa5 100644 --- a/StrategySpace/Workspace/Workspace.js +++ b/StrategySpace/Workspace/Workspace.js @@ -277,6 +277,16 @@ function newWorkspace () { 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 @@ -369,6 +379,14 @@ function newWorkspace () { 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: }