diff --git a/Animation.js b/Animation.js index c5a53041d..400efe5c9 100644 --- a/Animation.js +++ b/Animation.js @@ -25,6 +25,9 @@ function newAnimation () { finalize: finalize } + let totalConsumption = 0 + let totalCounter = 0 + return thisObject function finalize () { @@ -69,15 +72,63 @@ function newAnimation () { /* We loop through the callback functions collections and execute them all. */ - callBackFunctions.forEach(function (callBackFunction) { - callBackFunction() - }) + let performanceMap = new Map() + let totalTimeConsumed = 0 + let totalElements = 0 + let chanceToExecute + let randomNumber + let mustExecute + + // console.clear() + + for (const [key, callBackFunction] of callBackFunctions.entries()) { + switch (key) { + case 'Floating Space Physics': + chanceToExecute = 50 + randomNumber = Math.random() * 100 * chanceToExecute + if (randomNumber > 100 - chanceToExecute) { mustExecute = true } else { mustExecute = false } + break + default: { + mustExecute = true + } + + } + if (mustExecute === true) { + let t0 = performance.now() + callBackFunction() + let t1 = performance.now() + let timeConsumed = t1 - t0 + if (key === 'Chart Space Draw') { + // console.log(key, (totalConsumption / totalCounter).toFixed(1)) + + if (Math.random() * 100 > 99) { + totalConsumption = 0 + totalCounter = 0 + } + + totalConsumption = totalConsumption + timeConsumed + totalCounter = totalCounter + 1 + } + performanceMap.set(key, timeConsumed) + totalTimeConsumed = totalTimeConsumed + timeConsumed + totalElements++ + } + } + + /* Performance Check */ + + for (const [key, timeConsumed] of performanceMap.entries()) { + let percentage = timeConsumed * 100 / totalTimeConsumed + if (key === 'Chart Space Draw') { + // console.log(key, percentage.toFixed(0)) + } + } } else { browserCanvas.width = 1 browserCanvas.height = 1 } - /* We request the next frame to be drawn, and stablishing a loop */ + /* We request the next frame to be drawn, and stablishing a loop */ /* Use this code for full animation speed. */ animationLoopHandle = window.requestAnimationFrame(animationLoop) @@ -104,3 +155,4 @@ function newAnimation () { browserCanvasContext.fill() } } + diff --git a/CockpitSpace/RestartSimulation.js b/CockpitSpace/RestartSimulation.js deleted file mode 100644 index 26f44c099..000000000 --- a/CockpitSpace/RestartSimulation.js +++ /dev/null @@ -1,332 +0,0 @@ - -function newRestartSimulation () { - const MODULE_NAME = 'Restart Simulation' - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME - - let thisObject = { - visible: true, - container: undefined, - status: undefined, - startOrStop: startOrStop, - physics: physics, - draw: draw, - getContainer: getContainer, - initialize: initialize, - finalize: finalize - } - - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) - - thisObject.container.isDraggeable = false - thisObject.container.isWheelable = false - thisObject.container.isClickeable = true - thisObject.container.detectMouseOver = true - - let selfMouseOverEventSubscriptionId - let selfMouseClickEventSubscriptionId - let selfMouseNotOverEventSubscriptionId - - let isMouseOver = false - let counterTillNextState = 0 - - let productCardsToTurnOn = [] - - let executionFocusExists = false - let idleLabel = '' - let isRunning = false - - let eventSubscriptionIdProcessStopped - - return thisObject - - function finalize () { - thisObject.container.eventHandler.stopListening(selfMouseOverEventSubscriptionId) - thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId) - thisObject.container.eventHandler.stopListening(selfMouseNotOverEventSubscriptionId) - - systemEventHandler.stopListening('Jason-Multi-Period', eventSubscriptionIdProcessStopped) - systemEventHandler.deleteEventHandler('Cockpit-Restart-Button') - - thisObject.container.finalize() - thisObject.container = undefined - } - - function initialize () { - thisObject.container.frame.width = 250 - thisObject.container.frame.height = COCKPIT_SPACE_HEIGHT - 12 - - selfMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) - selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) - selfMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) - - thisObject.status = 'Ready' - - systemEventHandler.createEventHandler('Cockpit-Restart-Button') - - systemEventHandler.listenToEvent('Jason-Multi-Period', 'Process Stopped', undefined, 'Cockpit-Restart-Button', onResponse, onProcessStopped) - - function onResponse (message) { - eventSubscriptionIdProcessStopped = message.eventSubscriptionId - } - - function onProcessStopped (message) { - thisObject.status = 'Ready' - isRunning = false - } - } - - function getContainer (point, purpose) { - if ( - thisObject.visible !== true || - (thisObject.status !== 'Ready' && thisObject.status !== 'Backtesting' && thisObject.status !== 'Live Trading') || - executionFocusExists === false) { return } - - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container - } else { - return undefined - } - } - - function onMouseOver (point) { - if (thisObject.container.frame.isThisPointHere(point, true, false) === true) { - isMouseOver = true - } else { - isMouseOver = false - } - } - - function onMouseNotOver (point) { - isMouseOver = false - } - - function onMouseClick (event) { - startOrStop() - } - - async function startOrStop () { - try { - if (isRunning === false) { - thisObject.status = 'Saving' - let result = await canvas.strategySpace.strategizerGateway.saveToStrategyzer(getSimulationParams()) - if (result === false) { - thisObject.status = 'Error' - counterTillNextState = 500 - } else { - callServer('', 'ResetLogsAndData', onSaved) - function onSaved (err) { - if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - logger.write('[ERROR] Restart Simulation -> Can not delete Logs and Simulation data. err = ' + err.messsage) - } - } - if (idleLabel === 'START LIVE TRADING') { - let event = { - definition: getDefinition() - } - systemEventHandler.raiseEvent('Cockpit-Restart-Button', 'Live-Trading Started', event) - thisObject.status = 'Live Trading' - } else { - let event = { - definition: getDefinition() - } - systemEventHandler.raiseEvent('Cockpit-Restart-Button', 'Backstesting Started', event) - thisObject.status = 'Backtesting' - } - - isRunning = true - } - } else { - /* isRunning === true */ - systemEventHandler.raiseEvent('Cockpit-Restart-Button', 'Stop Requested') - isRunning = false - thisObject.status = 'Stopping' - } - } catch (err) { - thisObject.status = 'Error' - counterTillNextState = 500 - } - } - - function getDefinition () { - let definitionNode = canvas.strategySpace.workspace.getProtocolDefinitionNode() - definitionNode.simulationParams = getSimulationParams() - return JSON.stringify(definitionNode) - } - - function turnOffProductCards () { - let productCardsToTurnOff = ['Trading-Simulation', 'Simulation-Conditions', 'Simulation-Strategies', 'Simulation-Trades', 'Live Trading History'] - for (let i = 0; i < canvas.panelsSpace.panels.length; i++) { - let panel = canvas.panelsSpace.panels[i] - if (panel.name === 'Products Panel') { - for (j = 0; j < panel.productCards.length; j++) { - let productCard = panel.productCards[j] - if (productCardsToTurnOff.includes(productCard.product.codeName) && productCard.status !== PRODUCT_CARD_STATUS.OFF) { - productCard.turnOff() - productCardsToTurnOn.push(productCard) - } - } - } - } - } - - function turnOnProductCards () { - for (let i = 0; i < productCardsToTurnOn.length; i++) { - let productCard = productCardsToTurnOn[i] - productCard.turnOn() - } - productCardsToTurnOn = [] - } - - function physics () { - labelPhysics() - - if (counterTillNextState > 0) { - counterTillNextState-- - - if (counterTillNextState === 0) { - switch (thisObject.status) { - case 'Ready': - - break - case 'Saving': - - break - case 'Stopping': - - break - case 'Error': - thisObject.status = 'Ready' - break - } - } - } - - positionPhysics() - executionFocusPhysics() - } - - function labelPhysics () { - idleLabel = 'START BACKTESTING' - if (canvas.strategySpace.workspace.definition) { - let definition = canvas.strategySpace.workspace.definition - if (definition.personalData) { - if (definition.personalData.exchangeAccounts) { - if (definition.personalData.exchangeAccounts.length > 0) { - let exchangeAccount = definition.personalData.exchangeAccounts[0] - if (exchangeAccount.keys) { - if (exchangeAccount.keys.length > 0) { - let key = exchangeAccount.keys[0] - idleLabel = 'START LIVE TRADING' - } - } - } - } - } - } - } - - function executionFocusPhysics () { - if (canvas.strategySpace.workspace.definition !== undefined) { - executionFocusExists = true - } else { - executionFocusExists = false - } - } - - function positionPhysics () { - thisObject.container.frame.position.x = thisObject.container.parentContainer.frame.width - thisObject.container.frame.width - 50 - thisObject.container.frame.position.y = 6 - } - - function draw () { - if (thisObject.visible !== true || executionFocusExists === false) { return } - drawBackground() - drawText() - } - - function drawBackground () { - let params = { - cornerRadius: 3, - lineWidth: 0.01, - container: thisObject.container, - borderColor: UI_COLOR.DARK, - castShadow: false, - opacity: 1 - } - - switch (thisObject.status) { - case 'Ready': { - if (isMouseOver === true) { - params.backgroundColor = UI_COLOR.TURQUOISE - } else { - params.backgroundColor = UI_COLOR.DARK_TURQUOISE - } - break - } - case 'Saving': - params.backgroundColor = UI_COLOR.GREY - break - case 'Backtesting': - params.backgroundColor = UI_COLOR.GREEN - break - case 'Live Trading': - params.backgroundColor = UI_COLOR.TITANIUM_YELLOW - break - case 'Stopping': - params.backgroundColor = UI_COLOR.GOLDEN_ORANGE - break - case 'Error': - params.backgroundColor = UI_COLOR.RUSTED_RED - break - } - - roundedCornersBackground(params) - } - - function drawText () { - let fontSize - let label - let xOffset - let yOffset - - const OPACITY = 1 - - /* We put the params.VALUE in the middle */ - - fontSize = 15 - - browserCanvasContext.font = 'bold ' + fontSize + 'px ' + UI_FONT.PRIMARY - - switch (thisObject.status) { - case 'Ready': - label = idleLabel - break - case 'Saving': - label = 'SAVING STRATEGIES CHANGES...' - break - case 'Backtesting': - label = 'STOP BACKTESTING' - break - case 'Live Trading': - label = 'STOP LIVE TRADING' - break - case 'Stopping': - label = 'STOPPING...' - break - case 'Error': - label = 'ERROR, RETRY LATER' - break - } - - let labelPoint = { - x: thisObject.container.frame.width / 2 - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 25, - y: thisObject.container.frame.height - 9 - } - labelPoint = thisObject.container.frame.frameThisPoint(labelPoint) - - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')' - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) - } -} diff --git a/Dashboard.js b/Dashboard.js index 61142d631..f6d435b22 100644 --- a/Dashboard.js +++ b/Dashboard.js @@ -25,6 +25,7 @@ function newDashboard () { function start () { try { setBrowserEvents() + viewPort = newViewPort() systemEventHandler = newSystemEventHandler() @@ -105,15 +106,8 @@ function newDashboard () { function setBrowserEvents () { window.onbeforeunload = onBrowserClosed function onBrowserClosed () { - stopAllRunningTasks() + canvas.strategySpace.workspace.stopAllRunningTasks() } } } -function stopAllRunningTasks () { - let definition = canvas.strategySpace.workspace.definition - for (let i = 0; i < definition.taskManagers.length; i++) { - taskManager = definition.taskManagers[i] - taskManager.payload.uiObject.menu.internalClick('Stop All Tasks') - } -} diff --git a/FloatingSpace/CircularMenuItem.js b/FloatingSpace/CircularMenuItem.js index 9fb252e8b..38bd97bd6 100644 --- a/FloatingSpace/CircularMenuItem.js +++ b/FloatingSpace/CircularMenuItem.js @@ -259,7 +259,16 @@ function newCircularMenuItem () { return } - function onPrimaryCallBack (err) { + function onPrimaryCallBack (err, event) { + /* While the primary action is being executed some event might have happen. Following we process the ones we can */ + + if (event !== undefined) { + if (event.type === 'Secondary Action Already Executed') { + setStatus(thisObject.secondaryWorkDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 250, STATUS_SECONDARY_WORK_DONE) + return + } + } + /* If there is a secondary action we will act different that if there is not */ if (thisObject.secondaryAction === undefined) { // This means there are no more possible actions. if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) { diff --git a/FloatingSpace/CircularProgressBar.js b/FloatingSpace/CircularProgressBar.js index a28c0ea68..613441a30 100644 --- a/FloatingSpace/CircularProgressBar.js +++ b/FloatingSpace/CircularProgressBar.js @@ -52,6 +52,7 @@ function newCircularProgressBar () { function onHeartBeat (message) { opacityCounters[message.event.seconds] = 2000 + thisObject.payload.uiObject.setValue(message.event.processingDate) } function getContainer (point) { diff --git a/FloatingSpace/StrategyPart.js b/FloatingSpace/StrategyPart.js index fb3761428..fb700c195 100644 --- a/FloatingSpace/StrategyPart.js +++ b/FloatingSpace/StrategyPart.js @@ -18,12 +18,9 @@ function newStrategyPart () { partTitle: undefined, circularProgressBar: undefined, isExecuting: undefined, - isDefault: undefined, - setAsDefault: setAsDefault, + isRunning: undefined, run: run, stop: stop, - setDefaultStatus: setDefaultStatus, - setNotRunningStatus: setNotRunningStatus, getReadyToAttach: getReadyToAttach, showAvailabilityToAttach: showAvailabilityToAttach, highlight: highlight, @@ -64,7 +61,6 @@ function newStrategyPart () { let hasValue let valueCounter = 0 - let runningCounter = 0 let previousDistance @@ -81,7 +77,7 @@ function newStrategyPart () { let attachToNode let errorMessage = '' - let formulaValue = 0 + let currentValue = 0 let rightDragging = false return thisObject @@ -210,6 +206,14 @@ function newStrategyPart () { compatibleType = '->' + 'Definition' + '->' compatibleSubType = undefined break + case 'Network': + compatibleType = '->' + 'Definition' + '->' + compatibleSubType = undefined + break + case 'Network Node': + compatibleType = '->' + 'Network' + '->' + compatibleSubType = undefined + break case 'Exchange Account': compatibleType = '->' + 'Personal Data' + '->' compatibleSubType = undefined @@ -223,8 +227,24 @@ function newStrategyPart () { compatibleSubType = undefined break case 'Parameters': - compatibleType = '->' + 'Trading System' + '->' - compatibleSubType = undefined + compatibleType = '->' + 'Trading System' + '->' + 'Backtesting Session' + '->' + 'Live Trading Session' + '->' + 'Paper Trading Session' + '->' + 'Fordward Testing Session' + '->' + compatibleSubType = '->' + 'Trading Engine Process' + '->' + break + case 'Backtesting Session': + compatibleType = '->' + 'Process' + '->' + compatibleSubType = '->' + 'Trading Engine Process' + '->' + break + case 'Live Trading Session': + compatibleType = '->' + 'Process' + '->' + compatibleSubType = '->' + 'Trading Engine Process' + '->' + break + case 'Paper Trading Session': + compatibleType = '->' + 'Process' + '->' + compatibleSubType = '->' + 'Trading Engine Process' + '->' + break + case 'Fordward Testing Session': + compatibleType = '->' + 'Process' + '->' + compatibleSubType = '->' + 'Trading Engine Process' + '->' break case 'Base Asset': compatibleType = '->' + 'Parameters' + '->' @@ -234,6 +254,10 @@ function newStrategyPart () { compatibleType = '->' + 'Parameters' + '->' compatibleSubType = undefined break + case 'Time Period': + compatibleType = '->' + 'Parameters' + '->' + compatibleSubType = undefined + break case 'Slippage': compatibleType = '->' + 'Parameters' + '->' compatibleSubType = undefined @@ -243,7 +267,7 @@ function newStrategyPart () { compatibleSubType = undefined break case 'Task Manager': - compatibleType = '->' + 'Definition' + '->' + compatibleType = '->' + 'Network Node' + '->' compatibleSubType = undefined break case 'Task': @@ -263,7 +287,20 @@ function newStrategyPart () { compatibleSubType = undefined break case 'Process': - compatibleType = '->' + 'Sensor' + '->' + 'Indicator' + '->' + 'Trading Engine' + '->' + switch (thisObject.payload.node.subType) { + case 'Sensor Process': { + compatibleType = '->' + 'Sensor' + '->' + break + } + case 'Indicator Process': { + compatibleType = '->' + 'Indicator' + '->' + break + } + case 'Trading Engine Process': { + compatibleType = '->' + 'Trading Engine' + '->' + break + } + } compatibleSubType = undefined break case 'Strategy': @@ -372,8 +409,13 @@ function newStrategyPart () { 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 === 'Backtesting Session' && nearbyNode.session !== undefined) { continue } + if (thisObject.payload.node.type === 'Live Trading Session' && nearbyNode.session !== undefined) { continue } + if (thisObject.payload.node.type === 'Fordward Testing Session' && nearbyNode.session !== undefined) { continue } + if (thisObject.payload.node.type === 'Paper Trading Session' && nearbyNode.session !== undefined) { continue } if (thisObject.payload.node.type === 'Base Asset' && nearbyNode.baseAsset !== undefined) { continue } if (thisObject.payload.node.type === 'Time Range' && nearbyNode.timeRange !== undefined) { continue } + if (thisObject.payload.node.type === 'Time Period' && nearbyNode.timePeriod !== undefined) { continue } if (thisObject.payload.node.type === 'Slippage' && nearbyNode.slippage !== undefined) { continue } if (thisObject.payload.node.type === 'Fee Structure' && nearbyNode.feeStructure !== undefined) { continue } if (thisObject.payload.node.type === 'Trigger Stage' && nearbyNode.triggerStage !== undefined) { continue } @@ -393,6 +435,12 @@ function newStrategyPart () { if (thisObject.payload.node.type === 'Formula' && nearbyNode.formula !== undefined) { continue } if (thisObject.payload.node.type === 'Next Phase Event' && nearbyNode.nextPhaseEvent !== undefined) { continue } if (thisObject.payload.node.type === 'Code' && nearbyNode.code !== undefined) { continue } + /* Here we check if the subtypes are compatible. */ + if (nearbyNode.subType !== undefined && compatibleSubType !== undefined) { + if (compatibleSubType.indexOf('->' + nearbyNode.subType + '->') < 0) { + continue + } + } /* Discard Phases without partent */ if (thisObject.payload.node.type === 'Phase' && nearbyNode.type === 'Phase' && nearbyNode.payload.parentNode === undefined) { continue } /* Control maxPhases */ @@ -524,9 +572,9 @@ function newStrategyPart () { function setValue (value) { if (value !== undefined) { - formulaValue = value + currentValue = value hasValue = true - valueCounter = 5 + valueCounter = 500 } } @@ -541,50 +589,53 @@ function newStrategyPart () { thisObject.circularProgressBar.fitFunction = thisObject.fitFunction thisObject.circularProgressBar.container = thisObject.container - /* We will wait to the event that the task was terminated in order to call back the menu item */ + /* We will wait to the event that the execution was terminated in order to call back the menu item */ let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id - systemEventHandler.listenToEvent(key, 'Running', undefined, key, undefined, onTaskTerminated) + systemEventHandler.listenToEvent(key, 'Running', undefined, key, undefined, onRunning) - function onTaskTerminated () { + function onRunning () { if (callBackFunction !== undefined) { callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) } } + + /* + While it is running, it can happen that it naturally stops or is stopped not from the UI but from other means. + In those cases, the stop function would never be called (from the UI). So what we will do is to call it from + here with and event, and passing our own callBackFunction. In case there is an external source stopping this, + this will produce an execution of the callback with our event, which will produce that the menu item is restored + to its default stage. + + If on the other side, it is executed from the UI, then we will be processing the Stopped event twice, which in + both cases will reset the menu item to its default state. + */ + + let event = { + type: 'Secondary Action Already Executed' + } + stop(callBackFunction, event) + + thisObject.isRunning = true } - function stop (callBackFunction) { - /* We will wait to the event that the task was terminated in order to call back the menu item */ + function stop (callBackFunction, event) { + /* We will wait to the event that the execution was terminated in order to call back the menu item */ let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id - let eventSubscriptionId = systemEventHandler.listenToEvent(key, 'Stopped', undefined, key, undefined, onTaskTerminated) + systemEventHandler.listenToEvent(key, 'Stopped', undefined, key, undefined, onStopped) - function onTaskTerminated () { + function onStopped () { if (callBackFunction !== undefined) { - callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) + callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, event) } if (thisObject.circularProgressBar !== undefined) { thisObject.circularProgressBar.finalize() thisObject.circularProgressBar = undefined } + thisObject.isRunning = false } } - function setAsDefault () { - setDefaultStatus() - canvas.cockpitSpace.restartSimulation.restart() - } - - function setDefaultStatus () { - canvas.strategySpace.workspace.definition = thisObject.payload.node - thisObject.isDefault = true - runningCounter = 30 - } - - function setNotRunningStatus () { - canvas.strategySpace.workspace.definition = undefined - thisObject.isDefault = false - } - function iconPhysics () { icon = canvas.strategySpace.iconByPartType.get(thisObject.payload.node.type) executingIcon = canvas.strategySpace.iconCollection.get('attractive') @@ -760,7 +811,7 @@ function newStrategyPart () { let label if (radius > 6) { - const MAX_LABEL_LENGTH = 20 + const MAX_LABEL_LENGTH = 30 label = thisObject.payload.subTitle label = addIndexNumber(label) @@ -832,7 +883,7 @@ function newStrategyPart () { position = thisObject.container.frame.frameThisPoint(position) - let radius = thisObject.container.frame.radius + let radius = thisObject.container.frame.radius * 1.5 /* Label Text */ let labelPoint let fontSize = thisObject.payload.floatingObject.currentFontSize * 6 / 4 @@ -841,7 +892,10 @@ function newStrategyPart () { if (radius > 6) { const MAX_LABEL_LENGTH = 30 - label = formulaValue.toFixed(2) + label = currentValue + if (!isNaN(label)) { + label = currentValue.toFixed(2) + } if (label !== undefined) { if (label.length > MAX_LABEL_LENGTH) { @@ -959,9 +1013,9 @@ function newStrategyPart () { browserCanvasContext.fill() - if (thisObject.isDefault === true) { + if (thisObject.payload.node.type === 'Definition') { VISIBLE_RADIUS = thisObject.container.frame.radius * 2 - let OPACITY = runningCounter / 30 + let OPACITY = 1 browserCanvasContext.beginPath() browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true) diff --git a/FloatingSpace/StrategyPartConstructor.js b/FloatingSpace/StrategyPartConstructor.js index 90f802865..8fb172f92 100644 --- a/FloatingSpace/StrategyPartConstructor.js +++ b/FloatingSpace/StrategyPartConstructor.js @@ -67,13 +67,6 @@ function newStrategyPartConstructor () { strategyPart.initialize(payload, menuItemsInitialValues) strategyPart.container.connectToParent(floatingObject.container, false, false, true, true, false, false, true, true, true, true, true) - if (payload.node.savedPayload !== undefined) { - if (payload.node.savedPayload.uiObject.isDefault === true) { - strategyPart.setDefaultStatus() - canvas.strategySpace.workspace.definition = payload.node - } - } - setFloatingObjectBasicProperties(floatingObject, payload) payload.node.savedPayload = undefined @@ -197,6 +190,17 @@ function newStrategyPartConstructor () { currentRadius: 0, angle: 130 }, + { + action: 'Add Definition', + actionFunction: payload.onMenuItemClick, + label: 'Add Definition', + visible: true, + relatedStrategyPart: 'Definition', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -10 + }, { action: 'Share Workspace', actionFunction: payload.onMenuItemClick, @@ -207,7 +211,7 @@ function newStrategyPartConstructor () { rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: 0 + angle: 10 }] break } @@ -215,37 +219,6 @@ function newStrategyPartConstructor () { floatingObject.isPinned = true floatingObject.positionLocked = true addLeftIcons(menuItemsInitialValues, floatingObject) - menuItemsInitialValues.push( - { - action: 'Set as Default', - actionFunction: payload.uiObject.setAsDefault, - label: 'Set as Default', - visible: true, - iconPathOn: 'paper-plane', - iconPathOff: 'paper-plane', - rawRadius: 8, - targetRadius: 0, - currentRadius: 0, - angle: -75 - } - ) - menuItemsInitialValues.push( - { - action: 'Save Trading System', - actionFunction: payload.onMenuItemClick, - label: 'Save Changes', - workingLabel: 'Saving...', - workDoneLabel: 'Saved', - workFailedLabel: 'Not Saved', - visible: true, - iconPathOn: 'menu-backup', - iconPathOff: 'menu-backup', - rawRadius: 8, - targetRadius: 0, - currentRadius: 0, - angle: -40 - } - ) menuItemsInitialValues.push( { action: 'Add Trading System', @@ -256,7 +229,7 @@ function newStrategyPartConstructor () { rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: -20 + angle: -40 } ) menuItemsInitialValues.push( @@ -269,20 +242,20 @@ function newStrategyPartConstructor () { rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: 0 + angle: -20 } ) menuItemsInitialValues.push( { - action: 'Add Task Manager', + action: 'Add Network', actionFunction: payload.onMenuItemClick, - label: 'Add Task Manager', + label: 'Add Network', visible: true, - relatedStrategyPart: 'Task Manager', + relatedStrategyPart: 'Network', rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: 20 + angle: 0 } ) menuItemsInitialValues.push( @@ -298,7 +271,7 @@ function newStrategyPartConstructor () { rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: 40 + angle: 20 } ) menuItemsInitialValues.push( @@ -312,7 +285,101 @@ function newStrategyPartConstructor () { rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: 75 + angle: 40 + } + ) + break + } + case 'Network': { + addLeftIcons(menuItemsInitialValues, floatingObject) + menuItemsInitialValues.push( + { + action: 'Add Network Node', + actionFunction: payload.onMenuItemClick, + label: 'Add Network Node', + visible: true, + relatedStrategyPart: 'Network Node', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -40 + } + ) + menuItemsInitialValues.push( + { + action: 'Delete Network', + askConfirmation: true, + confirmationLabel: 'Confirm to Delete', + actionFunction: payload.onMenuItemClick, + label: 'Delete Network', + visible: true, + iconPathOn: 'delete', + iconPathOff: 'delete', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 0 + } + ) + menuItemsInitialValues.push( + { + action: 'Share', + actionFunction: payload.onMenuItemClick, + label: 'Share', + visible: true, + iconPathOn: 'menu-share', + iconPathOff: 'menu-share', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 40 + } + ) + break + } + case 'Network Node': { + addLeftIcons(menuItemsInitialValues, floatingObject) + menuItemsInitialValues.push( + { + action: 'Add Task Manager', + actionFunction: payload.onMenuItemClick, + label: 'Add Task Manager', + visible: true, + relatedStrategyPart: 'Task Manager', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -40 + } + ) + menuItemsInitialValues.push( + { + action: 'Delete Network Node', + askConfirmation: true, + confirmationLabel: 'Confirm to Delete', + actionFunction: payload.onMenuItemClick, + label: 'Delete Network Node', + visible: true, + iconPathOn: 'delete', + iconPathOff: 'delete', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 0 + } + ) + menuItemsInitialValues.push( + { + action: 'Share', + actionFunction: payload.onMenuItemClick, + label: 'Share', + visible: true, + iconPathOn: 'menu-share', + iconPathOff: 'menu-share', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 40 } ) break @@ -462,7 +529,7 @@ function newStrategyPartConstructor () { askConfirmation: true, confirmationLabel: 'Confirm to Delete', actionFunction: payload.onMenuItemClick, - label: 'Delete Process', + label: 'Delete Task', visible: true, iconPathOn: 'delete', iconPathOff: 'delete', @@ -635,29 +702,192 @@ function newStrategyPartConstructor () { strategyPart.codeEditor.initialize() strategyPart.codeEditor.container.connectToParent(strategyPart.container, false, false, true, true, false, false, false, false) + addLeftIcons(menuItemsInitialValues, floatingObject) + + switch (payload.node.subType) { + case 'Trading Engine Process': { + menuItemsInitialValues.push( + { + action: 'Add Backtesting Session', + actionFunction: payload.onMenuItemClick, + label: 'Add Backtesting', + visible: true, + relatedStrategyPart: 'Backtesting Session', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -75 + } + ) + menuItemsInitialValues.push( + { + action: 'Add Live Trading Session', + actionFunction: payload.onMenuItemClick, + label: 'Add Live Trading', + visible: true, + relatedStrategyPart: 'Live Trading Session', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -40 + } + ) + menuItemsInitialValues.push( + { + action: 'Add Fordward Testing Session', + actionFunction: payload.onMenuItemClick, + label: 'Add Fordward Testing', + visible: true, + relatedStrategyPart: 'Fordward Testing Session', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -20 + } + ) + menuItemsInitialValues.push( + { + action: 'Add Paper Trading Session', + actionFunction: payload.onMenuItemClick, + label: 'Add Paper Trading', + visible: true, + relatedStrategyPart: 'Paper Trading Session', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 0 + } + ) + menuItemsInitialValues.push( + { + action: 'Edit Process', + actionFunction: strategyPart.codeEditor.activate, + label: 'Edit Process', + visible: true, + iconPathOn: 'html', + iconPathOff: 'html', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 20, + dontShowAtFullscreen: true + } + ) + menuItemsInitialValues.push( + { + action: 'Delete Process', + askConfirmation: true, + confirmationLabel: 'Confirm to Delete', + actionFunction: payload.onMenuItemClick, + label: 'Delete Process', + visible: true, + iconPathOn: 'delete', + iconPathOff: 'delete', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 40 + } + ) + menuItemsInitialValues.push( + { + action: 'Share', + actionFunction: payload.onMenuItemClick, + label: 'Share', + visible: true, + iconPathOn: 'menu-share', + iconPathOff: 'menu-share', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 75 + } + ) + break + } + default: { + menuItemsInitialValues.push( + { + action: 'Edit Process', + actionFunction: strategyPart.codeEditor.activate, + label: 'Edit Process', + visible: true, + iconPathOn: 'html', + iconPathOff: 'html', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -40, + dontShowAtFullscreen: true + } + ) + menuItemsInitialValues.push( + { + action: 'Delete Process', + askConfirmation: true, + confirmationLabel: 'Confirm to Delete', + actionFunction: payload.onMenuItemClick, + label: 'Delete Process', + visible: true, + iconPathOn: 'delete', + iconPathOff: 'delete', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 0 + } + ) + menuItemsInitialValues.push( + { + action: 'Share', + actionFunction: payload.onMenuItemClick, + label: 'Share', + visible: true, + iconPathOn: 'menu-share', + iconPathOff: 'menu-share', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 40 + } + ) + break + } + } + break + } + case 'Backtesting Session': { addLeftIcons(menuItemsInitialValues, floatingObject) menuItemsInitialValues.push( { - action: 'Edit Process', - actionFunction: strategyPart.codeEditor.activate, - label: 'Edit Process', + action: 'Run Session', + actionFunction: payload.onMenuItemClick, + label: 'Run', + workingLabel: 'Runing...', + workDoneLabel: 'Session Running', + workFailedLabel: 'Session Cannot be Run', + secondaryAction: 'Stop Session', + secondaryLabel: 'Stop', + secondaryWorkingLabel: 'Stopping...', + secondaryWorkDoneLabel: 'Session Stopped', + secondaryWorkFailedLabel: 'Session Cannot be Stopped', + secondaryIcon: 'stop', visible: true, - iconPathOn: 'html', - iconPathOff: 'html', + iconPathOn: 'paper-plane', + iconPathOff: 'paper-plane', rawRadius: 8, targetRadius: 0, currentRadius: 0, - angle: -40, - dontShowAtFullscreen: true + angle: -40 } ) menuItemsInitialValues.push( { - action: 'Delete Process', + action: 'Delete Backtesting Session', askConfirmation: true, confirmationLabel: 'Confirm to Delete', actionFunction: payload.onMenuItemClick, - label: 'Delete Process', + label: 'Delete Session', visible: true, iconPathOn: 'delete', iconPathOff: 'delete', @@ -680,7 +910,178 @@ function newStrategyPartConstructor () { currentRadius: 0, angle: 40 } - ) + ) + break + } + case 'Live Trading Session': { + addLeftIcons(menuItemsInitialValues, floatingObject) + menuItemsInitialValues.push( + { + action: 'Run Session', + actionFunction: payload.onMenuItemClick, + label: 'Run', + workingLabel: 'Stop', + workDoneLabel: 'Session Running', + workFailedLabel: 'Session Cannot be Run', + secondaryAction: 'Stop Session', + secondaryLabel: 'Stop', + secondaryWorkingLabel: 'Stopping...', + secondaryWorkDoneLabel: 'Session Stopped', + secondaryWorkFailedLabel: 'Session Cannot be Stopped', + secondaryIcon: 'stop', + visible: true, + iconPathOn: 'paper-plane', + iconPathOff: 'paper-plane', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -40 + } + ) + menuItemsInitialValues.push( + { + action: 'Delete Live Trading Session', + askConfirmation: true, + confirmationLabel: 'Confirm to Delete', + actionFunction: payload.onMenuItemClick, + label: 'Delete Session', + visible: true, + iconPathOn: 'delete', + iconPathOff: 'delete', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 0 + } + ) + menuItemsInitialValues.push( + { + action: 'Share', + actionFunction: payload.onMenuItemClick, + label: 'Share', + visible: true, + iconPathOn: 'menu-share', + iconPathOff: 'menu-share', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 40 + } + ) + break + } + case 'Fordward Testing Session': { + addLeftIcons(menuItemsInitialValues, floatingObject) + menuItemsInitialValues.push( + { + action: 'Run Session', + actionFunction: payload.onMenuItemClick, + label: 'Run', + workingLabel: 'Stop', + workDoneLabel: 'Session Running', + workFailedLabel: 'Session Cannot be Run', + secondaryAction: 'Stop Session', + secondaryLabel: 'Stop', + secondaryWorkingLabel: 'Stopping...', + secondaryWorkDoneLabel: 'Session Stopped', + secondaryWorkFailedLabel: 'Session Cannot be Stopped', + secondaryIcon: 'stop', + visible: true, + iconPathOn: 'paper-plane', + iconPathOff: 'paper-plane', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -40 + } + ) + menuItemsInitialValues.push( + { + action: 'Delete Fordward Testing Session', + askConfirmation: true, + confirmationLabel: 'Confirm to Delete', + actionFunction: payload.onMenuItemClick, + label: 'Delete Session', + visible: true, + iconPathOn: 'delete', + iconPathOff: 'delete', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 0 + } + ) + menuItemsInitialValues.push( + { + action: 'Share', + actionFunction: payload.onMenuItemClick, + label: 'Share', + visible: true, + iconPathOn: 'menu-share', + iconPathOff: 'menu-share', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 40 + } + ) + break + } + case 'Paper Trading Session': { + addLeftIcons(menuItemsInitialValues, floatingObject) + menuItemsInitialValues.push( + { + action: 'Run Session', + actionFunction: payload.onMenuItemClick, + label: 'Run', + workingLabel: 'Stop', + workDoneLabel: 'Session Running', + workFailedLabel: 'Session Cannot be Run', + secondaryAction: 'Stop Session', + secondaryLabel: 'Stop', + secondaryWorkingLabel: 'Stopping...', + secondaryWorkDoneLabel: 'Session Stopped', + secondaryWorkFailedLabel: 'Session Cannot be Stopped', + secondaryIcon: 'stop', + visible: true, + iconPathOn: 'paper-plane', + iconPathOff: 'paper-plane', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -40 + } + ) + menuItemsInitialValues.push( + { + action: 'Delete Paper Trading Session', + askConfirmation: true, + confirmationLabel: 'Confirm to Delete', + actionFunction: payload.onMenuItemClick, + label: 'Delete Session', + visible: true, + iconPathOn: 'delete', + iconPathOff: 'delete', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 0 + } + ) + menuItemsInitialValues.push( + { + action: 'Share', + actionFunction: payload.onMenuItemClick, + label: 'Share', + visible: true, + iconPathOn: 'menu-share', + iconPathOff: 'menu-share', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 40 + } + ) break } case 'Personal Data': { @@ -1035,6 +1436,59 @@ function newStrategyPartConstructor () { ) break } + case 'Time Period': { + 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 Time Period', + actionFunction: strategyPart.codeEditor.activate, + label: 'Edit Time Period', + visible: true, + iconPathOn: 'settings', + iconPathOff: 'settings', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: -40 + } + ) + menuItemsInitialValues.push( + { + action: 'Delete Time Period', + askConfirmation: true, + confirmationLabel: 'Confirm to Delete', + actionFunction: payload.onMenuItemClick, + label: 'Delete Time Period', + visible: true, + iconPathOn: 'delete', + iconPathOff: 'delete', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 0 + } + ) + menuItemsInitialValues.push( + { + action: 'Share', + actionFunction: payload.onMenuItemClick, + label: 'Share', + visible: true, + iconPathOn: 'menu-share', + iconPathOff: 'menu-share', + rawRadius: 8, + targetRadius: 0, + currentRadius: 0, + angle: 40 + } + ) + break + } case 'Slippage': { strategyPart.codeEditor = newCodeEditor() strategyPart.codeEditor.isVisibleFunction = strategyPart.isVisibleFunction @@ -2163,12 +2617,20 @@ function newStrategyPartConstructor () { level_0() break } + case 'Network': { + level_1() + break + } + case 'Network Node': { + level_1() + break + } case 'Task Manager': { level_1() break } case 'Task': { - level_1() + level_3() break } case 'Sensor': { @@ -2184,6 +2646,22 @@ function newStrategyPartConstructor () { break } case 'Process': { + level_2() + break + } + case 'Backtesting Session': { + level_4() + break + } + case 'Live Trading Session': { + level_4() + break + } + case 'Fordward Testing Session': { + level_4() + break + } + case 'Paper Trading Session': { level_4() break } @@ -2219,6 +2697,10 @@ function newStrategyPartConstructor () { level_3() break } + case 'Time Period': { + level_3() + break + } case 'Slippage': { level_3() break diff --git a/FloatingSpace/StrategyPartTitle.js b/FloatingSpace/StrategyPartTitle.js index 4d859608d..792bb88cf 100644 --- a/FloatingSpace/StrategyPartTitle.js +++ b/FloatingSpace/StrategyPartTitle.js @@ -52,6 +52,13 @@ function newStrategyPartTitle () { thisObject.allwaysVisible = true break } + case 'Network': { + thisObject.allwaysVisible = true + break + } + case 'Network Node': { + break + } case 'Task Manager': { break } @@ -72,6 +79,18 @@ function newStrategyPartTitle () { case 'Process': { break } + case 'Backtesting Session': { + break + } + case 'Live Trading Session': { + break + } + case 'Fordward Testing Session': { + break + } + case 'Paper Trading Session': { + break + } case 'Personal Data': { break } @@ -101,6 +120,9 @@ function newStrategyPartTitle () { case 'Time Range': { break } + case 'Time Period': { + break + } case 'Slippage': { break } diff --git a/Spaces/CockpitSpace.js b/Spaces/CockpitSpace.js index 86fc1c821..dbf34cfef 100644 --- a/Spaces/CockpitSpace.js +++ b/Spaces/CockpitSpace.js @@ -6,7 +6,6 @@ container: undefined, status: 'BOTTOM', assetBalances: undefined, - restartSimulation: undefined, fullscreen: undefined, toTop: toTop, toBottom: toBottom, @@ -39,7 +38,6 @@ thisObject.container.finalize() thisObject.container = undefined thisObject.assetBalances = undefined - thisObject.restartSimulation = undefined thisObject.fullscreen = undefined } @@ -67,10 +65,6 @@ thisObject.assetBalances = newAssetBalances() thisObject.assetBalances.initialize() - thisObject.restartSimulation = newRestartSimulation() - thisObject.restartSimulation.container.connectToParent(thisObject.container) - thisObject.restartSimulation.initialize() - thisObject.fullscreen = newFullScreen() thisObject.fullscreen.container.connectToParent(thisObject.container) thisObject.fullscreen.initialize() @@ -99,9 +93,6 @@ } function childrenPhysics () { - if (canvas.strategySpace.workspace.enabled === true) { - thisObject.restartSimulation.physics() - } thisObject.fullscreen.physics() } function thisObjectPhysics () { @@ -119,8 +110,10 @@ thisObject.container.frame.position.y = browserCanvas.height - COCKPIT_SPACE_HEIGHT thisObject.status = 'BOTTOM' canvas.strategySpace.makeInvisible() + canvas.floatingSpace.makeInvisible() } else { canvas.strategySpace.makeVisible() + canvas.floatingSpace.makeVisible() } if (thisObject.container.frame.position.y < browserCanvas.height * 0.5 / 100) { @@ -142,11 +135,6 @@ function getContainer (point) { let container - if (canvas.strategySpace.workspace.enabled === true) { - container = thisObject.restartSimulation.getContainer(point) - if (container !== undefined) { return container } - } - container = thisObject.fullscreen.getContainer(point) if (container !== undefined) { return container } @@ -163,9 +151,6 @@ drawBackground() thisObject.assetBalances.draw() - if (canvas.strategySpace.workspace.enabled === true) { - thisObject.restartSimulation.draw() - } thisObject.fullscreen.draw() } diff --git a/Spaces/FloatingSpace.js b/Spaces/FloatingSpace.js index 1deab5a25..e6a5d4cd3 100644 --- a/Spaces/FloatingSpace.js +++ b/Spaces/FloatingSpace.js @@ -137,8 +137,10 @@ function newFloatingSpace () { } function physics () { - browserZoomPhysics() - thisObject.floatingLayer.physics() + if (visible === true) { + browserZoomPhysics() + thisObject.floatingLayer.physics() + } } function browserZoomPhysics () { @@ -153,9 +155,8 @@ function newFloatingSpace () { function draw () { if (visible === true) { drawBackground() + thisObject.floatingLayer.draw() } - - thisObject.floatingLayer.draw() } function drawBackground () { @@ -168,3 +169,4 @@ function newFloatingSpace () { browserCanvasContext.fill() } } + diff --git a/Spaces/StrategySpace.js b/Spaces/StrategySpace.js index d940f2325..93bc631c5 100644 --- a/Spaces/StrategySpace.js +++ b/Spaces/StrategySpace.js @@ -40,12 +40,18 @@ function newStrategySpace () { function buildIconByPartTypeMap () { const relationshipArray = [ ['Definition', 'text'], + ['Network', 'network'], + ['Network Node', 'network-node'], ['Task Manager', 'task'], ['Task', 'timeline'], ['Sensor', 'pipette'], ['Indicator', 'vector'], ['Trading Engine', 'brainstorming'], ['Process', 'grid'], + ['Backtesting Session', 'session-backtesting'], + ['Live Trading Session', 'session-live-trading'], + ['Fordward Testing Session', 'session-forward-testing'], + ['Paper Trading Session', 'session-paper-trading'], ['Personal Data', 'security'], ['Exchange Account', 'approve'], ['Exchange Account Asset', 'paper-plane'], @@ -55,6 +61,7 @@ function newStrategySpace () { ['Parameters', 'settings'], ['Base Asset', 'loading'], ['Time Range', 'chronometer'], + ['Time Period', 'schedule'], ['Slippage', 'support'], ['Fee Structure', 'sitemap'], ['Strategy', 'quality'], @@ -74,7 +81,7 @@ function newStrategySpace () { ['Take Profit', 'stage-open-take-profit'], ['Phase', 'placeholder'], ['Formula', 'pipette'], - ['Next Phase Event', 'schedule'], + ['Next Phase Event', 'pantone'], ['Situation', 'pyramid'], ['Condition', 'testing'], ['Code', 'html'] @@ -159,7 +166,13 @@ function newStrategySpace () { 'menu-tensor-free-angles', 'stage-open-position-size', 'stage-open-take-profit', - 'stage-open-postion-rate' + 'stage-open-postion-rate', + 'session-live-trading', + 'session-paper-trading', + 'session-backtesting', + 'session-forward-testing', + 'network', + 'network-node' ] for (let i = 0; i < iconsNames.length; i++) { @@ -187,7 +200,6 @@ function newStrategySpace () { } function makeVisible () { - canvas.floatingSpace.makeVisible() visible = true } diff --git a/StrategySpace/StrategizerGateway.js b/StrategySpace/StrategizerGateway.js index b623990b4..bcf8644bb 100644 --- a/StrategySpace/StrategizerGateway.js +++ b/StrategySpace/StrategizerGateway.js @@ -8,8 +8,7 @@ function newStrategizerGateway () { idAtStrategizer: undefined, strategizerData: undefined, container: undefined, - loadFromStrategyzer: loadFromStrategyzer, - saveToStrategyzer: saveToStrategyzer + loadFromStrategyzer: loadFromStrategyzer } let colletionItems = [] @@ -92,77 +91,5 @@ function newStrategizerGateway () { } catch (err) { logger.write('[ERROR] loadFromStrategyzer -> err = ' + err.stack) } - } - - async function saveToStrategyzer (simulationParams) { - try { - const accessToken = window.localStorage.getItem(LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY) - if (accessToken === null) { - logger.write('[ERROR] saveToStrategyzer -> Can not save because the accessToken is missing.') - return - } - - let user = window.localStorage.getItem(LOGGED_IN_USER_LOCAL_STORAGE_KEY) - if (user === null) { - logger.write('[ERROR] saveToStrategyzer -> Can not save because user is not logged in. ') - return - } - - let tradingSystem = canvas.strategySpace.workspace.getProtocolDefinitionNode() - if (tradingSystem === undefined || tradingSystem === null) { - logger.write('[ERROR] saveToStrategyzer -> Can not save when tradingSystem is null or undefined.') - return - } - - if (window.canvasApp.executingAt === 'Local') { - tradingSystem.simulationParams = simulationParams - 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 - } - } - 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) - - 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 - } - } catch (err) { - logger.write('[ERROR] saveToStrategyzer -> err = ' + err.stack) - } - } + } } diff --git a/StrategySpace/Workspace/FunctionLibraries/AttachDetach.js b/StrategySpace/Workspace/FunctionLibraries/AttachDetach.js index 82fe0caf0..9f4183811 100644 --- a/StrategySpace/Workspace/FunctionLibraries/AttachDetach.js +++ b/StrategySpace/Workspace/FunctionLibraries/AttachDetach.js @@ -11,6 +11,22 @@ function newAttachDetach () { case 'Definition': { return } + case 'Network': { + node.payload.parentNode.network = undefined + completeDetachment(node, rootNodes) + return + } + case 'Network Node': { + let payload = node.payload + for (let i = 0; i < payload.parentNode.networkNodes.length; i++) { + let networkNode = payload.parentNode.networkNodes[i] + if (networkNode.id === node.id) { + payload.parentNode.networkNodes.splice(i, 1) + } + } + completeDetachment(node, rootNodes) + return + } case 'Personal Data': { node.payload.parentNode.personalData = undefined completeDetachment(node, rootNodes) @@ -86,8 +102,34 @@ function newAttachDetach () { completeDetachment(node, rootNodes) return } + case 'Backtesting Session': { + node.payload.parentNode.session = undefined + completeDetachment(node, rootNodes) + return + } + case 'Live Trading Session': { + node.payload.parentNode.session = undefined + completeDetachment(node, rootNodes) + return + } + case 'Fordward Testing Session': { + node.payload.parentNode.session = undefined + completeDetachment(node, rootNodes) + return + } + case 'Paper Trading Session': { + node.payload.parentNode.session = undefined + completeDetachment(node, rootNodes) + return + } case 'Process': { - node.payload.parentNode.process = undefined + let payload = node.payload + for (let i = 0; i < payload.parentNode.processes.length; i++) { + let process = payload.parentNode.processes[i] + if (process.id === node.id) { + payload.parentNode.processes.splice(i, 1) + } + } completeDetachment(node, rootNodes) return } @@ -106,6 +148,11 @@ function newAttachDetach () { completeDetachment(node, rootNodes) return } + case 'Time Period': { + node.payload.parentNode.timePeriod = undefined + completeDetachment(node, rootNodes) + return + } case 'Slippage': { node.payload.parentNode.slippage = undefined completeDetachment(node, rootNodes) @@ -265,6 +312,20 @@ function newAttachDetach () { function attachNode (node, attachToNode, rootNodes) { switch (node.type) { + case 'Network': { + node.payload.parentNode = attachToNode + node.payload.chainParent = attachToNode + node.payload.parentNode.network = node + completeAttachment(node, rootNodes) + } + break + case 'Network Node': { + node.payload.parentNode = attachToNode + node.payload.chainParent = attachToNode + node.payload.parentNode.networkNodes.push(node) + completeAttachment(node, rootNodes) + } + break case 'Task Manager': { node.payload.parentNode = attachToNode node.payload.chainParent = attachToNode @@ -307,6 +368,34 @@ function newAttachDetach () { completeAttachment(node, rootNodes) } break + case 'Backtesting Session': { + node.payload.parentNode = attachToNode + node.payload.chainParent = attachToNode + node.payload.parentNode.session = node + completeAttachment(node, rootNodes) + } + break + case 'Live Trading Session': { + node.payload.parentNode = attachToNode + node.payload.chainParent = attachToNode + node.payload.parentNode.session = node + completeAttachment(node, rootNodes) + } + break + case 'Fordward Testing Session': { + node.payload.parentNode = attachToNode + node.payload.chainParent = attachToNode + node.payload.parentNode.session = node + completeAttachment(node, rootNodes) + } + break + case 'Paper Trading Session': { + node.payload.parentNode = attachToNode + node.payload.chainParent = attachToNode + node.payload.parentNode.session = node + completeAttachment(node, rootNodes) + } + break case 'Personal Data': { node.payload.parentNode = attachToNode node.payload.chainParent = attachToNode @@ -356,6 +445,13 @@ function newAttachDetach () { completeAttachment(node, rootNodes) } break + case 'Time Period': { + node.payload.parentNode = attachToNode + node.payload.chainParent = attachToNode + node.payload.parentNode.timePeriod = node + completeAttachment(node, rootNodes) + } + break case 'Slippage': { node.payload.parentNode = attachToNode node.payload.chainParent = attachToNode diff --git a/StrategySpace/Workspace/FunctionLibraries/NodeChildren.js b/StrategySpace/Workspace/FunctionLibraries/NodeChildren.js index 5c6c2b311..7212cb830 100644 --- a/StrategySpace/Workspace/FunctionLibraries/NodeChildren.js +++ b/StrategySpace/Workspace/FunctionLibraries/NodeChildren.js @@ -11,6 +11,12 @@ function newNodeChildren () { case 'Definition': { return countChildrenDefinition(parentNode, childNode) } + case 'Network': { + return countChildrenNetwork(parentNode, childNode) + } + case 'Network Node': { + return countChildrenNetworkNode(parentNode, childNode) + } case 'Task Manager': { return countChildrenTaskManager(parentNode, childNode) } @@ -29,6 +35,18 @@ function newNodeChildren () { case 'Process': { return countChildrenProcess(parentNode, childNode) } + case 'Backtesting Session': { + return countBacktestingSession(parentNode, childNode) + } + case 'Live Trading Session': { + return countLiveTradingSession(parentNode, childNode) + } + case 'Fordward Testing Session': { + return countFordwardTestingSession(parentNode, childNode) + } + case 'Paper Trading Session': { + return countPaperTradingSession(parentNode, childNode) + } case 'Personal Data': { return countChildrenPersonalData(parentNode, childNode) } @@ -53,6 +71,9 @@ function newNodeChildren () { case 'Time Range': { return countChildrenTimeRange(parentNode, childNode) } + case 'Time Period': { + return countChildrenTimePeriod(parentNode, childNode) + } case 'Slippage': { return countChildrenSlippage(parentNode, childNode) } @@ -145,6 +166,37 @@ function newNodeChildren () { response.childIndex = response.childrenCount } } + if (parentNode.network !== undefined) { + response.childrenCount++ + if (parentNode.network.id === childNode.id) { + response.childIndex = response.childrenCount + } + } + return response + } + + function countChildrenNetwork (parentNode, childNode) { + let response = { + childrenCount: 0, + childIndex: undefined + } + if (parentNode.networkNodes !== undefined) { + for (let i = 0; i < parentNode.networkNodes.length; i++) { + let child = parentNode.networkNodes[i] + response.childrenCount++ + if (child.id === childNode.id) { + response.childIndex = response.childrenCount + } + } + } + return response + } + + function countChildrenNetworkNode (parentNode, childNode) { + let response = { + childrenCount: 0, + childIndex: undefined + } if (parentNode.taskManagers !== undefined) { for (let i = 0; i < parentNode.taskManagers.length; i++) { let child = parentNode.taskManagers[i] @@ -240,6 +292,68 @@ function newNodeChildren () { childrenCount: 0, childIndex: undefined } + if (parentNode.session !== undefined) { + response.childrenCount++ + if (parentNode.session.id === childNode.id) { + response.childIndex = response.childrenCount + } + } + return response + } + + function countBacktestingSession (parentNode, childNode) { + let response = { + childrenCount: 0, + childIndex: undefined + } + if (parentNode.parameters !== undefined) { + response.childrenCount++ + if (parentNode.parameters.id === childNode.id) { + response.childIndex = response.childrenCount + } + } + return response + } + + function countLiveTradingSession (parentNode, childNode) { + let response = { + childrenCount: 0, + childIndex: undefined + } + if (parentNode.parameters !== undefined) { + response.childrenCount++ + if (parentNode.parameters.id === childNode.id) { + response.childIndex = response.childrenCount + } + } + return response + } + + function countFordwardTestingSession (parentNode, childNode) { + let response = { + childrenCount: 0, + childIndex: undefined + } + if (parentNode.parameters !== undefined) { + response.childrenCount++ + if (parentNode.parameters.id === childNode.id) { + response.childIndex = response.childrenCount + } + } + return response + } + + function countPaperTradingSession (parentNode, childNode) { + let response = { + childrenCount: 0, + childIndex: undefined + } + if (parentNode.parameters !== undefined) { + response.childrenCount++ + if (parentNode.parameters.id === childNode.id) { + response.childIndex = response.childrenCount + } + } return response } @@ -339,6 +453,12 @@ function newNodeChildren () { response.childIndex = response.childrenCount } } + if (parentNode.timePeriod !== undefined) { + response.childrenCount++ + if (parentNode.timePeriod.id === childNode.id) { + response.childIndex = response.childrenCount + } + } if (parentNode.slippage !== undefined) { response.childrenCount++ if (parentNode.slippage.id === childNode.id) { @@ -370,6 +490,14 @@ function newNodeChildren () { return response } + function countChildrenTimePeriod (parentNode, childNode) { + let response = { + childrenCount: 0, + childIndex: undefined + } + return response + } + function countChildrenSlippage (parentNode, childNode) { let response = { childrenCount: 0, diff --git a/StrategySpace/Workspace/FunctionLibraries/NodeDeleter.js b/StrategySpace/Workspace/FunctionLibraries/NodeDeleter.js index 46dbd37a7..f761a7fd8 100644 --- a/StrategySpace/Workspace/FunctionLibraries/NodeDeleter.js +++ b/StrategySpace/Workspace/FunctionLibraries/NodeDeleter.js @@ -1,6 +1,8 @@ function newNodeDeleter () { thisObject = { deleteDefinition: deleteDefinition, + deleteNetwork: deleteNetwork, + deleteNetworkNode: deleteNetworkNode, deleteTaskManager: deleteTaskManager, deleteTask: deleteTask, deleteSensor: deleteBot, @@ -13,9 +15,14 @@ function newNodeDeleter () { deleteExchangeAccountKey: deleteExchangeAccountKey, deleteWorkspace: deleteWorkspace, deleteTradingSystem: deleteTradingSystem, + deleteBacktestingSession: deleteBacktestingSession, + deleteLiveTradingSession: deleteLiveTradingSession, + deleteFordwardTestingSession: deleteFordwardTestingSession, + deletePaperTradingSession: deletePaperTradingSession, deleteParameters: deleteParameters, deleteBaseAsset: deleteBaseAsset, deleteTimeRange: deleteTimeRange, + deleteTimePeriod: deleteTimePeriod, deleteSlippage: deleteSlippage, deleteFeeStructure: deleteFeeStructure, deleteStrategy: deleteStrategy, @@ -53,6 +60,14 @@ function newNodeDeleter () { deleteDefinition(rootNode, rootNodes, true) break } + case 'Network': { + deleteNetwork(rootNode, rootNodes) + break + } + case 'Network Node': { + deleteNetworkNode(rootNode, rootNodes) + break + } case 'Task Manager': { deleteTaskManager(rootNode, rootNodes) break @@ -97,6 +112,22 @@ function newNodeDeleter () { deleteTradingSystem(rootNode, rootNodes) break } + case 'Backtesting Session': { + deleteBacktestingSession(rootNode, rootNodes) + break + } + case 'Live Trading Session': { + deleteLiveTradingSession(rootNode, rootNodes) + break + } + case 'Fordward Testing Session': { + deleteFordwardTestingSession(rootNode, rootNodes) + break + } + case 'Paper Trading Session': { + deletePaperTradingSession(rootNode, rootNodes) + break + } case 'Parameters': { deleteParameters(rootNode, rootNodes) break @@ -109,6 +140,10 @@ function newNodeDeleter () { deleteTimeRange(rootNode, rootNodes) break } + case 'Time Period': { + deleteTimePeriod(rootNode, rootNodes) + break + } case 'Slippage': { deleteSlippage(rootNode, rootNodes) break @@ -225,16 +260,51 @@ function newNodeDeleter () { if (counter <= 1) { return } } - if (node.payload.uiObject.isDefault === true) { - node.payload.uiObject.setNotRunningStatus() - } - if (node.tradingSystem !== undefined) { deleteTradingSystem(node.tradingSystem, rootNodes) } if (node.personalData !== undefined) { deletePersonalData(node.personalData, rootNodes) } + if (node.network !== undefined) { + deleteNetwork(node.network, rootNodes) + } + + completeDeletion(node, rootNodes) + destroyPart(node) + cleanNode(node) + } + + function deleteNetwork (node, rootNodes, forced) { + let payload = node.payload + + if (payload.parentNode !== undefined) { + payload.parentNode.network = undefined + } + + if (node.networkNodes !== undefined) { + while (node.networkNodes.length > 0) { + deleteNetworkNode(node.networkNodes[0], rootNodes) + } + } + + completeDeletion(node, rootNodes) + destroyPart(node) + cleanNode(node) + } + + function deleteNetworkNode (node, rootNodes, forced) { + let payload = node.payload + + if (payload.parentNode !== undefined) { + for (let j = 0; j < payload.parentNode.networkNodes.length; j++) { + let networkNode = payload.parentNode.networkNodes[j] + if (networkNode.id === node.id) { + payload.parentNode.networkNodes.splice(j, 1) + } + } + } + if (node.taskManagers !== undefined) { while (node.taskManagers.length > 0) { deleteTaskManager(node.taskManagers[0], rootNodes) @@ -310,6 +380,88 @@ function newNodeDeleter () { } } } + + if (node.session !== undefined) { + switch (node.session.type) { + case 'Backtesting Session': { + deleteBacktestingSession(node.session, rootNodes) + break + } + case 'Live Trading Session': { + deleteLiveTradingSession(node.session, rootNodes) + break + } + case 'Fordward Testing Session': { + deleteFordwardTestingSession(node.session, rootNodes) + break + } + case 'Paper Trading Session': { + deletePaperTradingSession(node.session, rootNodes) + break + } + } + } + + completeDeletion(node, rootNodes) + destroyPart(node) + cleanNode(node) + } + + function deleteBacktestingSession (node, rootNodes) { + let payload = node.payload + + if (payload.parentNode !== undefined) { + payload.parentNode.session = undefined + } + + if (node.parameters !== undefined) { + deleteParameters(node.parameters, rootNodes) + } + completeDeletion(node, rootNodes) + destroyPart(node) + cleanNode(node) + } + + function deleteLiveTradingSession (node, rootNodes) { + let payload = node.payload + + if (payload.parentNode !== undefined) { + payload.parentNode.session = undefined + } + + if (node.parameters !== undefined) { + deleteParameters(node.parameters, rootNodes) + } + completeDeletion(node, rootNodes) + destroyPart(node) + cleanNode(node) + } + + function deleteFordwardTestingSession (node, rootNodes) { + let payload = node.payload + + if (payload.parentNode !== undefined) { + payload.parentNode.session = undefined + } + + if (node.parameters !== undefined) { + deleteParameters(node.parameters, rootNodes) + } + completeDeletion(node, rootNodes) + destroyPart(node) + cleanNode(node) + } + + function deletePaperTradingSession (node, rootNodes) { + let payload = node.payload + + if (payload.parentNode !== undefined) { + payload.parentNode.session = undefined + } + + if (node.parameters !== undefined) { + deleteParameters(node.parameters, rootNodes) + } completeDeletion(node, rootNodes) destroyPart(node) cleanNode(node) @@ -426,6 +578,9 @@ function newNodeDeleter () { if (node.timeRange !== undefined) { deleteTimeRange(node.timeRange, rootNodes) } + if (node.timePeriod !== undefined) { + deleteTimePeriod(node.timePeriod, rootNodes) + } if (node.slippage !== undefined) { deleteSlippage(node.slippage, rootNodes) } @@ -458,6 +613,17 @@ function newNodeDeleter () { cleanNode(node) } + function deleteTimePeriod (node, rootNodes) { + let payload = node.payload + if (payload.parentNode !== undefined) { + payload.parentNode.timePeriod = undefined + } else { + completeDeletion(node, rootNodes) + } + destroyPart(node) + cleanNode(node) + } + function deleteSlippage (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 183843041..a5a9a9902 100644 --- a/StrategySpace/Workspace/FunctionLibraries/PartsFromNodes.js +++ b/StrategySpace/Workspace/FunctionLibraries/PartsFromNodes.js @@ -1,12 +1,19 @@ function newPartsFromNodes () { thisObject = { createPartFromNode: createPartFromNode, + addDefinition: addDefinition, + addNetwork: addNetwork, + addNetworkNode: addNetworkNode, addTaskManager: addTaskManager, addTask: addTask, addSensor: addSensor, addIndicator: addIndicator, addTradingEngine: addTradingEngine, addProcess: addProcess, + addBacktestingSession: addBacktestingSession, + addLiveTradingSession: addLiveTradingSession, + addFordwardTestingSession: addFordwardTestingSession, + addPaperTradingSession: addPaperTradingSession, addTradingSystem: addTradingSystem, addPersonalData: addPersonalData, addExchangeAccount: addExchangeAccount, @@ -256,6 +263,10 @@ function newPartsFromNodes () { createPart('Time Range', node.name, node, parentNode, chainParent, 'Time Range') return } + case 'Time Period': { + createPart('Time Period', node.name, node, parentNode, chainParent, 'Time Period') + return + } case 'Slippage': { createPart('Slippage', node.name, node, parentNode, chainParent, 'Slippage') return @@ -272,6 +283,9 @@ function newPartsFromNodes () { if (node.timeRange !== undefined) { createPartFromNode(node.timeRange, node, node) } + if (node.timePeriod !== undefined) { + createPartFromNode(node.timePeriod, node, node) + } if (node.slippage !== undefined) { createPartFromNode(node.slippage, node, node) } @@ -333,6 +347,23 @@ function newPartsFromNodes () { if (node.personalData !== undefined) { createPartFromNode(node.personalData, node, node) } + if (node.network !== undefined) { + createPartFromNode(node.network, node, node) + } + return + } + case 'Network': { + createPart('Network', node.name, node, parentNode, chainParent, 'Network') + if (node.networkNodes !== undefined) { + for (let m = 0; m < node.networkNodes.length; m++) { + let networkNode = node.networkNodes[m] + createPartFromNode(networkNode, node, node) + } + } + return + } + case 'Network Node': { + createPart('Network Node', node.name, node, parentNode, chainParent, 'Network Node') if (node.taskManagers !== undefined) { for (let m = 0; m < node.taskManagers.length; m++) { let taskManager = node.taskManagers[m] @@ -381,15 +412,87 @@ function newPartsFromNodes () { return } case 'Process': { + if (parentNode !== undefined) { + switch (parentNode.type) { + case 'Sensor': { + node.subType = 'Sensor Process' + break + } + case 'Indicator': { + node.subType = 'Indicator Process' + break + } + case 'Trading Engine': { + node.subType = 'Trading Engine Process' + break + } + } + } createPart('Process', node.name, node, parentNode, chainParent, 'Process') + if (node.session !== undefined) { + createPartFromNode(node.session, node, node) + } + return + } + case 'Backtesting Session': { + createPart('Backtesting Session', node.name, node, parentNode, chainParent, 'Backtesting Session') + if (node.parameters !== undefined) { + createPartFromNode(node.parameters, node, node) + } + return + } + case 'Live Trading Session': { + createPart('Live Trading Session', node.name, node, parentNode, chainParent, 'Live Trading Session') + if (node.parameters !== undefined) { + createPartFromNode(node.parameters, node, node) + } + return + } + case 'Fordward Testing Session': { + createPart('Fordward Testing Session', node.name, node, parentNode, chainParent, 'Fordward Testing Session') + if (node.parameters !== undefined) { + createPartFromNode(node.parameters, node, node) + } + return + } + case 'Paper Trading Session': { + createPart('Paper Trading Session', node.name, node, parentNode, chainParent, 'Paper Trading Session') + if (node.parameters !== undefined) { + createPartFromNode(node.parameters, node, node) + } return } } } + function addNetwork (node) { + if (node.network === undefined) { + node.network = { + name: 'Superalgos' + } + createPart('Network', node.network.name, node.network, node, node, 'Network') + } + + return node.network + } + + function addNetworkNode (node) { + let networkNode = { + name: 'New Network Node' + } + if (node.networkNodes === undefined) { + node.networkNodes = [] + } + node.networkNodes.push(networkNode) + createPart('Network Node', networkNode.name, networkNode, node, node, 'Network Node') + + return networkNode + } + function addTaskManager (node) { let taskManager = { - name: 'New Task Manager' + name: 'New Task Manager', + tasks: [] } if (node.taskManagers === undefined) { node.taskManagers = [] @@ -442,8 +545,25 @@ function newPartsFromNodes () { function addProcess (node) { let process = { - name: 'New Process', - code: '// Write the configuration here.' + code: '{}' + } + + switch (node.type) { + case 'Sensor': { + process.subType = 'Sensor Process' + process.name = 'Sensor Process' + break + } + case 'Indicator': { + process.subType = 'Indicator Process' + process.name = 'Indicator Process' + break + } + case 'Trading Engine': { + process.subType = 'Trading Engine Process' + process.name = 'Trading Engine Process' + break + } } node.processes.push(process) createPart('Process', process.name, process, node, node, 'Process') @@ -451,6 +571,60 @@ function newPartsFromNodes () { return process } + function addBacktestingSession (node) { + if (node.session === undefined) { + node.session = { + name: 'New Backtesting Session' + } + createPart('Backtesting Session', '', node.session, node, node) + } + + return node.session + } + + function addLiveTradingSession (node) { + if (node.session === undefined) { + node.session = { + name: 'New Live Trading Session' + } + createPart('Live Trading Session', '', node.session, node, node) + } + + return node.session + } + + function addFordwardTestingSession (node) { + if (node.session === undefined) { + node.session = { + name: 'New Fordward Testing Session' + } + createPart('Fordward Testing Session', '', node.session, node, node) + } + + return node.session + } + + function addPaperTradingSession (node) { + if (node.session === undefined) { + node.session = { + name: 'New Paper Trading Session' + } + createPart('Paper Trading Session', '', node.session, node, node) + } + + return node.session + } + + function addDefinition (node) { + let definition = { + name: 'New Definition' + } + node.rootNodes.push(definition) + createPart('Definition', definition.name, definition, node, undefined, 'Definition') + + return definition + } + function addTradingSystem (node) { if (node.tradingSystem === undefined) { node.tradingSystem = { @@ -601,6 +775,13 @@ function newPartsFromNodes () { } createPart('Time Range', '', node.timeRange, node, node) } + if (node.timePeriod === undefined) { + node.timePeriod = { + name: 'Time Period', + code: DEFAULT_CONFIG_TEXT + } + createPart('Time Period', '', node.timePeriod, node, node) + } if (node.slippage === undefined) { node.slippage = { name: 'Slippage', diff --git a/StrategySpace/Workspace/FunctionLibraries/ProtocolNode.js b/StrategySpace/Workspace/FunctionLibraries/ProtocolNode.js index 9ee0774ed..1e1bdb1fc 100644 --- a/StrategySpace/Workspace/FunctionLibraries/ProtocolNode.js +++ b/StrategySpace/Workspace/FunctionLibraries/ProtocolNode.js @@ -15,6 +15,9 @@ function newProtocolNode () { name: node.name, code: node.code } + if (includeIds) { + code.id = node.id + } return code } case 'Condition': @@ -25,6 +28,9 @@ function newProtocolNode () { name: node.name, code: getProtocolNode(node.code, removePersonalData, parseJSONStrings, includeIds) } + if (includeIds) { + condition.id = node.id + } return condition } case 'Situation': { @@ -39,6 +45,9 @@ function newProtocolNode () { let condition = getProtocolNode(node.conditions[m], removePersonalData, parseJSONStrings, includeIds) situation.conditions.push(condition) } + if (includeIds) { + situation.id = node.id + } return situation } case 'Formula': @@ -49,6 +58,9 @@ function newProtocolNode () { name: node.name, code: node.code } + if (includeIds) { + formula.id = node.id + } return formula } case 'Next Phase Event': @@ -63,6 +75,9 @@ function newProtocolNode () { let situation = getProtocolNode(node.situations[m], removePersonalData, parseJSONStrings, includeIds) event.situations.push(situation) } + if (includeIds) { + event.id = node.id + } return event } case 'Phase': { @@ -73,6 +88,9 @@ function newProtocolNode () { formula: getProtocolNode(node.formula, removePersonalData, parseJSONStrings, includeIds), nextPhaseEvent: getProtocolNode(node.nextPhaseEvent, removePersonalData, parseJSONStrings, includeIds) } + if (includeIds) { + phase.id = node.id + } return phase } case 'Stop': { @@ -87,6 +105,9 @@ function newProtocolNode () { let phase = getProtocolNode(node.phases[m], removePersonalData, parseJSONStrings, includeIds) stop.phases.push(phase) } + if (includeIds) { + stop.id = node.id + } return stop } case 'Take Profit': { @@ -101,6 +122,9 @@ function newProtocolNode () { let phase = getProtocolNode(node.phases[m], removePersonalData, parseJSONStrings, includeIds) takeProfit.phases.push(phase) } + if (includeIds) { + takeProfit.id = node.id + } return takeProfit } case 'Take Position Event': { @@ -115,6 +139,9 @@ function newProtocolNode () { let situation = getProtocolNode(node.situations[m], removePersonalData, parseJSONStrings, includeIds) event.situations.push(situation) } + if (includeIds) { + event.id = node.id + } return event } case 'Trigger On Event': { @@ -129,6 +156,9 @@ function newProtocolNode () { let situation = getProtocolNode(node.situations[m], removePersonalData, parseJSONStrings, includeIds) event.situations.push(situation) } + if (includeIds) { + event.id = node.id + } return event } case 'Trigger Off Event': { @@ -143,6 +173,9 @@ function newProtocolNode () { let situation = getProtocolNode(node.situations[m], removePersonalData, parseJSONStrings, includeIds) event.situations.push(situation) } + if (includeIds) { + event.id = node.id + } return event } case 'Initial Definition': { @@ -155,6 +188,9 @@ function newProtocolNode () { positionSize: getProtocolNode(node.positionSize, removePersonalData, parseJSONStrings, includeIds), positionRate: getProtocolNode(node.positionRate, removePersonalData, parseJSONStrings, includeIds) } + if (includeIds) { + object.id = node.id + } return object } case 'Open Execution': { @@ -163,6 +199,9 @@ function newProtocolNode () { subType: node.subType, name: node.name } + if (includeIds) { + object.id = node.id + } return object } case 'Close Execution': { @@ -171,6 +210,9 @@ function newProtocolNode () { subType: node.subType, name: node.name } + if (includeIds) { + object.id = node.id + } return object } case 'Position Size': { @@ -180,6 +222,9 @@ function newProtocolNode () { name: node.name, formula: getProtocolNode(node.formula, removePersonalData, parseJSONStrings, includeIds) } + if (includeIds) { + object.id = node.id + } return object } case 'Position Rate': { @@ -189,6 +234,9 @@ function newProtocolNode () { name: node.name, formula: getProtocolNode(node.formula, removePersonalData, parseJSONStrings, includeIds) } + if (includeIds) { + object.id = node.id + } return object } case 'Trigger Stage': { @@ -200,6 +248,9 @@ function newProtocolNode () { triggerOff: getProtocolNode(node.triggerOff, removePersonalData, parseJSONStrings, includeIds), takePosition: getProtocolNode(node.takePosition, removePersonalData, parseJSONStrings, includeIds) } + if (includeIds) { + stage.id = node.id + } return stage } case 'Open Stage': { @@ -210,6 +261,9 @@ function newProtocolNode () { initialDefinition: getProtocolNode(node.initialDefinition, removePersonalData, parseJSONStrings, includeIds), openExecution: getProtocolNode(node.openExecution, removePersonalData, parseJSONStrings, includeIds) } + if (includeIds) { + stage.id = node.id + } return stage } case 'Manage Stage': { @@ -220,6 +274,9 @@ function newProtocolNode () { stopLoss: getProtocolNode(node.stopLoss, removePersonalData, parseJSONStrings, includeIds), takeProfit: getProtocolNode(node.takeProfit, removePersonalData, parseJSONStrings, includeIds) } + if (includeIds) { + stage.id = node.id + } return stage } case 'Close Stage': { @@ -229,6 +286,9 @@ function newProtocolNode () { name: node.name, closeExecution: getProtocolNode(node.closeExecution, removePersonalData, parseJSONStrings, includeIds) } + if (includeIds) { + stage.id = node.id + } return stage } case 'Strategy': { @@ -241,6 +301,9 @@ function newProtocolNode () { manageStage: getProtocolNode(node.manageStage, removePersonalData, parseJSONStrings, includeIds), closeStage: getProtocolNode(node.closeStage, removePersonalData, parseJSONStrings, includeIds) } + if (includeIds) { + strategy.id = node.id + } return strategy } case 'Base Asset': { @@ -250,6 +313,9 @@ function newProtocolNode () { name: node.name, code: node.code } + if (includeIds) { + object.id = node.id + } return object } case 'Time Range': { @@ -259,6 +325,21 @@ function newProtocolNode () { name: node.name, code: node.code } + if (includeIds) { + object.id = node.id + } + return object + } + case 'Time Period': { + let object = { + type: node.type, + subType: node.subType, + name: node.name, + code: node.code + } + if (includeIds) { + object.id = node.id + } return object } case 'Slippage': { @@ -268,6 +349,9 @@ function newProtocolNode () { name: node.name, code: node.code } + if (includeIds) { + object.id = node.id + } return object } case 'Fee Structure': { @@ -277,6 +361,9 @@ function newProtocolNode () { name: node.name, code: node.code } + if (includeIds) { + object.id = node.id + } return object } case 'Parameters': { @@ -286,9 +373,13 @@ function newProtocolNode () { name: node.name, baseAsset: getProtocolNode(node.baseAsset, removePersonalData, parseJSONStrings, includeIds), timeRange: getProtocolNode(node.timeRange, removePersonalData, parseJSONStrings, includeIds), + timePeriod: getProtocolNode(node.timePeriod, removePersonalData, parseJSONStrings, includeIds), slippage: getProtocolNode(node.slippage, removePersonalData, parseJSONStrings, includeIds), feeStructure: getProtocolNode(node.feeStructure, removePersonalData, parseJSONStrings, includeIds) } + if (includeIds) { + object.id = node.id + } return object } case 'Trading System': { @@ -304,6 +395,9 @@ function newProtocolNode () { let strategy = getProtocolNode(node.strategies[m], removePersonalData, parseJSONStrings, includeIds) tradingSystem.strategies.push(strategy) } + if (includeIds) { + tradingSystem.id = node.id + } return tradingSystem } case 'Personal Data': { @@ -319,6 +413,9 @@ function newProtocolNode () { let exchangeAccount = getProtocolNode(node.exchangeAccounts[m], removePersonalData, parseJSONStrings, includeIds) personalData.exchangeAccounts.push(exchangeAccount) } + if (includeIds) { + personalData.id = node.id + } return personalData } case 'Exchange Account': { @@ -339,6 +436,9 @@ function newProtocolNode () { let key = getProtocolNode(node.keys[m], removePersonalData, parseJSONStrings, includeIds) exchangeAccount.keys.push(key) } + if (includeIds) { + exchangeAccount.id = node.id + } return exchangeAccount } case 'Exchange Account Asset': { @@ -348,6 +448,9 @@ function newProtocolNode () { subType: node.subType, name: node.name } + if (includeIds) { + asset.id = node.id + } return asset } case 'Exchange Account Key': { @@ -358,6 +461,9 @@ function newProtocolNode () { name: node.name, code: node.code } + if (includeIds) { + key.id = node.id + } return key } case 'Task Manager': { @@ -372,6 +478,9 @@ function newProtocolNode () { let task = getProtocolNode(node.tasks[m], removePersonalData, parseJSONStrings, includeIds) taskManager.tasks.push(task) } + if (includeIds) { + taskManager.id = node.id + } return taskManager } case 'Task': { @@ -384,6 +493,9 @@ function newProtocolNode () { if (includeIds) { object.id = node.id } + if (includeIds) { + object.id = node.id + } return object } case 'Sensor': { @@ -398,6 +510,9 @@ function newProtocolNode () { let process = getProtocolNode(node.processes[m], removePersonalData, parseJSONStrings, includeIds) bot.processes.push(process) } + if (includeIds) { + bot.id = node.id + } return bot } case 'Indicator': { @@ -412,6 +527,9 @@ function newProtocolNode () { let process = getProtocolNode(node.processes[m], removePersonalData, parseJSONStrings, includeIds) bot.processes.push(process) } + if (includeIds) { + bot.id = node.id + } return bot } case 'Trading Engine': { @@ -426,6 +544,9 @@ function newProtocolNode () { let process = getProtocolNode(node.processes[m], removePersonalData, parseJSONStrings, includeIds) bot.processes.push(process) } + if (includeIds) { + bot.id = node.id + } return bot } case 'Process': { @@ -433,7 +554,8 @@ function newProtocolNode () { type: node.type, subType: node.subType, name: node.name, - code: node.code + code: node.code, + session: getProtocolNode(node.session, removePersonalData, parseJSONStrings, includeIds) } if (parseJSONStrings) { object.code = JSON.parse(object.code) @@ -443,6 +565,98 @@ function newProtocolNode () { } return object } + + case 'Backtesting Session': { + let object = { + type: node.type, + subType: node.subType, + name: node.name, + parameters: getProtocolNode(node.parameters, removePersonalData, parseJSONStrings, includeIds) + } + if (includeIds) { + object.id = node.id + } + return object + } + + case 'Live Trading Session': { + let object = { + type: node.type, + subType: node.subType, + name: node.name, + parameters: getProtocolNode(node.parameters, removePersonalData, parseJSONStrings, includeIds) + } + if (includeIds) { + object.id = node.id + } + return object + } + + case 'Fordward Testing Session': { + let object = { + type: node.type, + subType: node.subType, + name: node.name, + parameters: getProtocolNode(node.parameters, removePersonalData, parseJSONStrings, includeIds) + } + if (includeIds) { + object.id = node.id + } + return object + } + + case 'Paper Trading Session': { + let object = { + type: node.type, + subType: node.subType, + name: node.name, + parameters: getProtocolNode(node.parameters, removePersonalData, parseJSONStrings, includeIds) + } + if (includeIds) { + object.id = node.id + } + if (includeIds) { + object.id = node.id + } + return object + } + + case 'Network Node': { + let object = { + type: node.type, + subType: node.subType, + name: node.name, + taskManagers: [] + } + if (node.taskManagers !== undefined) { + for (let m = 0; m < node.taskManagers.length; m++) { + let taskManager = getProtocolNode(node.taskManagers[m], removePersonalData, parseJSONStrings, includeIds) + object.taskManagers.push(taskManager) + } + } + if (includeIds) { + object.id = node.id + } + return object + } + case 'Network': { + let object = { + type: node.type, + subType: node.subType, + name: node.name, + networkNodes: [] + } + if (node.networkNodes !== undefined) { + for (let m = 0; m < node.networkNodes.length; m++) { + let networkNode = getProtocolNode(node.networkNodes[m], removePersonalData, parseJSONStrings, includeIds) + object.networkNodes.push(networkNode) + } + } + if (includeIds) { + object.id = node.id + } + return object + } case 'Definition': { let object = { type: node.type, @@ -450,11 +664,10 @@ function newProtocolNode () { name: node.name, tradingSystem: getProtocolNode(node.tradingSystem, removePersonalData, parseJSONStrings, includeIds), personalData: getProtocolNode(node.personalData, removePersonalData, parseJSONStrings, includeIds), - taskManagers: [] + network: getProtocolNode(node.network, removePersonalData, parseJSONStrings, includeIds) } - for (let m = 0; m < node.taskManagers.length; m++) { - let taskManager = getProtocolNode(node.taskManagers[m], removePersonalData, parseJSONStrings, includeIds) - object.taskManagers.push(taskManager) + if (includeIds) { + object.id = node.id } return object } diff --git a/StrategySpace/Workspace/FunctionLibraries/SessionFunctions.js b/StrategySpace/Workspace/FunctionLibraries/SessionFunctions.js new file mode 100644 index 000000000..790fe292b --- /dev/null +++ b/StrategySpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -0,0 +1,73 @@ +function newSessionFunctions () { + thisObject = { + runSession: runSession, + stopSession: stopSession + } + + return thisObject + + function runSession (node, functionLibraryProtocolNode, callBackFunction) { + /* We can not run a sessionif its parent process is not running. Less if it does not have a parent. */ + if (node.payload.parentNode === undefined) { + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + return + } + + if (node.payload.parentNode.payload.uiObject.isRunning !== true) { + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + return + } + + node.payload.uiObject.run(callBackFunction) + + let key = node.name + '-' + node.type + '-' + node.id + + let thisNodeDefinition = getDefinition(node) + if (thisNodeDefinition === undefined) { return } + + /* Raise event to run the session */ + let event = { + session: JSON.stringify(functionLibraryProtocolNode.getProtocolNode(node, false, false, true)), + definition: JSON.stringify(functionLibraryProtocolNode.getProtocolNode(thisNodeDefinition, false, true, true)), + uiCurrentValues: getUICurrentValues() + } + + systemEventHandler.raiseEvent(key, 'Run Session', event) + + function getDefinition (node) { + if (node.type === 'Definition') { + return node + } + + if (node.payload.parentNode !== undefined) { + return getDefinition(node.payload.parentNode) + } else { + return + } + } + + function getUICurrentValues () { + let dateAtScreenCorner = new Date(window.localStorage.getItem('Date @ Screen Corner')) + let currentTimePeriod = JSON.parse(window.localStorage.getItem('Current Time Period')) + + let timePeriodsMasterArray = [marketFilesPeriods, dailyFilePeriods] + let timePeriodArray = timePeriodsMasterArray[currentTimePeriod.filePeriodIndex] + let timePeriod = timePeriodArray[currentTimePeriod.timePeriodIndex][1] + + let uiCurrentValues = { + initialDatetime: dateAtScreenCorner, + timePeriod: timePeriod, + timestamp: (new Date()).valueOf() + } + + return uiCurrentValues + } + } + + function stopSession (node, functionLibraryProtocolNode, callBackFunction) { + let key = node.name + '-' + node.type + '-' + node.id + systemEventHandler.raiseEvent(key, 'Stop Session') + + node.payload.uiObject.stop(callBackFunction) + } +} diff --git a/StrategySpace/Workspace/FunctionLibraries/StringifyNode.js b/StrategySpace/Workspace/FunctionLibraries/StringifyNode.js index 6cdf0dbea..f2a8e485e 100644 --- a/StrategySpace/Workspace/FunctionLibraries/StringifyNode.js +++ b/StrategySpace/Workspace/FunctionLibraries/StringifyNode.js @@ -309,6 +309,17 @@ function newStringifyNode () { } return object } + case 'Time Period': { + let object = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + code: node.code, + savedPayload: getSavedPayload(node) + } + return object + } case 'Slippage': { let object = { id: node.id, @@ -339,6 +350,7 @@ function newStringifyNode () { name: node.name, baseAsset: prepareForStringify(node.baseAsset, removePersonalData), timeRange: prepareForStringify(node.timeRange, removePersonalData), + timePeriod: prepareForStringify(node.timePeriod, removePersonalData), slippage: prepareForStringify(node.slippage, removePersonalData), feeStructure: prepareForStringify(node.feeStructure, removePersonalData), savedPayload: getSavedPayload(node) @@ -512,10 +524,89 @@ function newStringifyNode () { subType: node.subType, name: node.name, code: node.code, + session: prepareForStringify(node.session, removePersonalData), savedPayload: getSavedPayload(node) } return object } + case 'Backtesting Session': { + let object = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + parameters: prepareForStringify(node.parameters, removePersonalData), + savedPayload: getSavedPayload(node) + } + return object + } + case 'Live Trading Session': { + let object = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + parameters: prepareForStringify(node.parameters, removePersonalData), + savedPayload: getSavedPayload(node) + } + return object + } + case 'Fordward Testing Session': { + let object = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + parameters: prepareForStringify(node.parameters, removePersonalData), + savedPayload: getSavedPayload(node) + } + return object + } + case 'Paper Trading Session': { + let object = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + parameters: prepareForStringify(node.parameters, removePersonalData), + savedPayload: getSavedPayload(node) + } + return object + } + case 'Network Node': { + let object = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + taskManagers: [], + savedPayload: getSavedPayload(node) + } + if (node.taskManagers !== undefined) { + for (let m = 0; m < node.taskManagers.length; m++) { + let taskManager = prepareForStringify(node.taskManagers[m], removePersonalData) + object.taskManagers.push(taskManager) + } + } + return object + } + case 'Network': { + let object = { + id: node.id, + type: node.type, + subType: node.subType, + name: node.name, + networkNodes: [], + savedPayload: getSavedPayload(node) + } + if (node.networkNodes !== undefined) { + for (let m = 0; m < node.networkNodes.length; m++) { + let networkNode = prepareForStringify(node.networkNodes[m], removePersonalData) + object.networkNodes.push(networkNode) + } + } + return object + } case 'Definition': { let object = { id: node.id, @@ -524,15 +615,9 @@ function newStringifyNode () { name: node.name, tradingSystem: prepareForStringify(node.tradingSystem, removePersonalData), personalData: prepareForStringify(node.personalData, removePersonalData), - taskManagers: [], + network: prepareForStringify(node.network, removePersonalData), savedPayload: getSavedPayload(node) } - if (node.taskManagers !== undefined) { - for (let m = 0; m < node.taskManagers.length; m++) { - let taskManager = prepareForStringify(node.taskManagers[m], removePersonalData) - object.taskManagers.push(taskManager) - } - } return object } } @@ -558,7 +643,7 @@ function newStringifyNode () { isTensed: (node.payload.floatingObject.isTensed && node.payload.floatingObject.tensedManually) }, uiObject: { - isDefault: node.payload.uiObject.isDefault + isRunning: node.payload.uiObject.isRunning } } return savedPayload diff --git a/StrategySpace/Workspace/Workspace.js b/StrategySpace/Workspace/Workspace.js index 0dd9e4c87..0e2515055 100644 --- a/StrategySpace/Workspace/Workspace.js +++ b/StrategySpace/Workspace/Workspace.js @@ -6,12 +6,13 @@ function newWorkspace () { logger.fileName = MODULE_NAME let thisObject = { + workspaceNode: undefined, tradingSystem: undefined, container: undefined, enabled: false, nodeChildren: undefined, + stopAllRunningTasks: stopAllRunningTasks, onMenuItemClick: onMenuItemClick, - getProtocolDefinitionNode: getProtocolDefinitionNode, physics: physics, spawn: spawn, detachNode: detachNode, @@ -37,8 +38,8 @@ function newWorkspace () { y: canvas.floatingSpace.container.frame.height / 2 } - let workspaceNode = {} - workspaceNode.rootNodes = [] + thisObject.workspaceNode = {} + thisObject.workspaceNode.rootNodes = [] let functionLibraryAttachDetach = newAttachDetach() let functionLibraryNodeDeleter = newNodeDeleter() @@ -46,6 +47,7 @@ function newWorkspace () { let functionLibraryProtocolNode = newProtocolNode() let functionLibraryWorkspaceNodes = newStringifyNode() let functionLibraryTaskFunctions = newTaskFunctions() + let functionLibrarySessionFunctions = newSessionFunctions() thisObject.nodeChildren = newNodeChildren() return thisObject @@ -54,6 +56,7 @@ function newWorkspace () { thisObject.definition = undefined thisObject.container.finalize() thisObject.container = undefined + thisObject.workspaceNode = undefined } async function initialize () { @@ -68,16 +71,16 @@ function newWorkspace () { let savedWorkspace = window.localStorage.getItem(CANVAS_APP_NAME + '.' + 'Workspace' + '.' + user.alias) if (savedWorkspace === null || idAtStrategizer === null) { - workspaceNode.type = 'Workspace' - workspaceNode.name = 'My Workspace' - functionLibraryPartsFromNodes.createPartFromNode(workspaceNode, undefined, undefined) + thisObject.workspaceNode.type = 'Workspace' + thisObject.workspaceNode.name = 'My Workspace' + functionLibraryPartsFromNodes.createPartFromNode(thisObject.workspaceNode, undefined, undefined) spawnPosition.y = spawnPosition.y + 250 initializeLoadingFromStrategizer() } else { - workspaceNode = JSON.parse(savedWorkspace) - functionLibraryPartsFromNodes.createPartFromNode(workspaceNode, undefined, undefined) - for (let i = 0; i < workspaceNode.rootNodes.length; i++) { - let rootNode = workspaceNode.rootNodes[i] + thisObject.workspaceNode = JSON.parse(savedWorkspace) + functionLibraryPartsFromNodes.createPartFromNode(thisObject.workspaceNode, undefined, undefined) + for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) { + let rootNode = thisObject.workspaceNode.rootNodes[i] functionLibraryPartsFromNodes.createPartFromNode(rootNode, undefined, undefined) } thisObject.enabled = true @@ -91,23 +94,19 @@ function newWorkspace () { let result = await canvas.strategySpace.strategizerGateway.loadFromStrategyzer() if (result === true) { thisObject.definition = canvas.strategySpace.strategizerGateway.strategizerData - workspaceNode.rootNodes.push(thisObject.definition) + thisObject.workspaceNode.rootNodes.push(thisObject.definition) functionLibraryPartsFromNodes.createPartFromNode(thisObject.definition, undefined, undefined) - thisObject.definition.payload.uiObject.setDefaultStatus() + thisObject.enabled = true } } - function getProtocolDefinitionNode () { - return functionLibraryProtocolNode.getProtocolNode(thisObject.definition, false, true, true) // <- We need to do this workaround in order no to send unescaped charactars through a system event. - } - function detachNode (node) { - functionLibraryAttachDetach.detachNode(node, workspaceNode.rootNodes) + functionLibraryAttachDetach.detachNode(node, thisObject.workspaceNode.rootNodes) } function attachNode (node, attachToNode) { - functionLibraryAttachDetach.attachNode(node, attachToNode, workspaceNode.rootNodes) + functionLibraryAttachDetach.attachNode(node, attachToNode, thisObject.workspaceNode.rootNodes) } function physics () { @@ -125,8 +124,8 @@ function newWorkspace () { function stringifyWorkspace (removePersonalData) { let stringifyReadyNodes = [] - for (let i = 0; i < workspaceNode.rootNodes.length; i++) { - let rootNode = workspaceNode.rootNodes[i] + for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) { + let rootNode = thisObject.workspaceNode.rootNodes[i] let node = functionLibraryWorkspaceNodes.prepareForStringify(rootNode, removePersonalData) if (node) { stringifyReadyNodes.push(node) @@ -134,13 +133,33 @@ function newWorkspace () { } let workspace = { type: 'Workspace', - name: workspaceNode.name, + name: thisObject.workspaceNode.name, rootNodes: stringifyReadyNodes } return JSON.stringify(workspace) } + function stopAllRunningTasks () { + for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) { + let rootNode = thisObject.workspaceNode.rootNodes[i] + if (rootNode.type === 'Definition') { + let definition = rootNode + if (definition.network !== undefined) { + if (definition.network.networkNodes !== undefined) { + for (let j = 0; j < definition.network.networkNodes.length; j++) { + let networkNode = definition.network.networkNodes[j] + for (let i = 0; i < networkNode.taskManagers.length; i++) { + taskManager = networkNode.taskManagers[i] + taskManager.payload.uiObject.menu.internalClick('Stop All Tasks') + } + } + } + } + } + } + } + function spawn (nodeText, point) { try { point = canvas.floatingSpace.container.frame.unframeThisPoint(point) @@ -151,16 +170,16 @@ function newWorkspace () { if (droppedNode.type === 'Workspace') { stopAllRunningTasks() - functionLibraryNodeDeleter.deleteWorkspace(workspaceNode, workspaceNode.rootNodes) - workspaceNode = droppedNode - functionLibraryPartsFromNodes.createPartFromNode(workspaceNode, undefined, undefined) - for (let i = 0; i < workspaceNode.rootNodes.length; i++) { - let rootNode = workspaceNode.rootNodes[i] + functionLibraryNodeDeleter.deleteWorkspace(thisObject.workspaceNode, thisObject.workspaceNode.rootNodes) + thisObject.workspaceNode = droppedNode + functionLibraryPartsFromNodes.createPartFromNode(thisObject.workspaceNode, undefined, undefined) + for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) { + let rootNode = thisObject.workspaceNode.rootNodes[i] functionLibraryPartsFromNodes.createPartFromNode(rootNode, undefined, undefined) } } else { let rootNode = functionLibraryProtocolNode.getProtocolNode(droppedNode) - workspaceNode.rootNodes.push(rootNode) + thisObject.workspaceNode.rootNodes.push(rootNode) functionLibraryPartsFromNodes.createPartFromNode(rootNode, undefined, undefined) } } catch (err) { @@ -184,17 +203,6 @@ function newWorkspace () { download(fileName, text) } break - case 'Save Trading System': - { - let result = await canvas.strategySpace.strategizerGateway.saveToStrategyzer(getSimulationParams()) - if (result === true) { - callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) - } else { - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - } - break - } - case 'Edit Code': break @@ -246,6 +254,31 @@ function newWorkspace () { functionLibraryTaskFunctions.stopAllTasks(payload.node, functionLibraryProtocolNode) } break + case 'Run Session': + { + functionLibrarySessionFunctions.runSession(payload.node, functionLibraryProtocolNode, callBackFunction) + } + break + case 'Stop Session': + { + functionLibrarySessionFunctions.stopSession(payload.node, functionLibraryProtocolNode, callBackFunction) + } + break + case 'Add Definition': + { + functionLibraryPartsFromNodes.addDefinition(payload.node) + } + break + case 'Add Network': + { + functionLibraryPartsFromNodes.addNetwork(payload.node) + } + break + case 'Add Network Node': + { + functionLibraryPartsFromNodes.addNetworkNode(payload.node) + } + break case 'Add Task Manager': { functionLibraryPartsFromNodes.addTaskManager(payload.node) @@ -276,6 +309,26 @@ function newWorkspace () { functionLibraryPartsFromNodes.addProcess(payload.node) } break + case 'Add Backtesting Session': + { + functionLibraryPartsFromNodes.addBacktestingSession(payload.node) + } + break + case 'Add Live Trading Session': + { + functionLibraryPartsFromNodes.addLiveTradingSession(payload.node) + } + break + case 'Add Fordward Testing Session': + { + functionLibraryPartsFromNodes.addFordwardTestingSession(payload.node) + } + break + case 'Add Paper Trading Session': + { + functionLibraryPartsFromNodes.addPaperTradingSession(payload.node) + } + break case 'Add Strategy': { functionLibraryPartsFromNodes.addStrategy(payload.node) @@ -376,140 +429,168 @@ function newWorkspace () { functionLibraryPartsFromNodes.addPersonalData(payload.node) } break + case 'Delete Network': { + functionLibraryNodeDeleter.deleteNetwork(payload.node, thisObject.workspaceNode.rootNodes) + break + } + case 'Delete Network Node': { + functionLibraryNodeDeleter.deleteNetworkNode(payload.node, thisObject.workspaceNode.rootNodes) + break + } case 'Delete Task Manager': { - functionLibraryNodeDeleter.deleteTaskManager(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteTaskManager(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Task': { - functionLibraryNodeDeleter.deleteTask(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteTask(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Sensor': { - functionLibraryNodeDeleter.deleteSensor(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteSensor(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Indicator': { - functionLibraryNodeDeleter.deleteIndicator(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteIndicator(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Trading Engine': { - functionLibraryNodeDeleter.deleteTradingEngine(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteTradingEngine(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Process': { - functionLibraryNodeDeleter.deleteProcess(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteProcess(payload.node, thisObject.workspaceNode.rootNodes) + break + } + case 'Delete Backtesting Session': { + functionLibraryNodeDeleter.deleteBacktestingSession(payload.node, thisObject.workspaceNode.rootNodes) + break + } + case 'Delete Live Trading Session': { + functionLibraryNodeDeleter.deleteLiveTradingSession(payload.node, thisObject.workspaceNode.rootNodes) + break + } + case 'Delete Fordward Testing Session': { + functionLibraryNodeDeleter.deleteFordwardTestingSession(payload.node, thisObject.workspaceNode.rootNodes) + break + } + case 'Delete Paper Trading Session': { + functionLibraryNodeDeleter.deletePaperTradingSession(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Trading System': { - functionLibraryNodeDeleter.deleteTradingSystem(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteTradingSystem(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Parameters': { - functionLibraryNodeDeleter.deleteParameters(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteParameters(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Base Asset': { - functionLibraryNodeDeleter.deleteBaseAsset(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteBaseAsset(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Time Range': { - functionLibraryNodeDeleter.deleteTimeRange(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteTimeRange(payload.node, thisObject.workspaceNode.rootNodes) + break + } + case 'Delete Time Period': { + functionLibraryNodeDeleter.deleteTimePeriod(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Slippage': { - functionLibraryNodeDeleter.deleteSlippage(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteSlippage(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Fee Structure': { - functionLibraryNodeDeleter.deleteFeeStructure(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteFeeStructure(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Strategy': { - functionLibraryNodeDeleter.deleteStrategy(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteStrategy(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Trigger Stage': { - functionLibraryNodeDeleter.deleteTriggerStage(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteTriggerStage(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Open Stage': { - functionLibraryNodeDeleter.deleteOpenStage(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteOpenStage(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Manage Stage': { - functionLibraryNodeDeleter.deleteManageStage(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteManageStage(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Close Stage': { - functionLibraryNodeDeleter.deleteCloseStage(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteCloseStage(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Position Size': { - functionLibraryNodeDeleter.deletePositionSize(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deletePositionSize(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Position Rate': { - functionLibraryNodeDeleter.deletePositionSize(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deletePositionSize(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Initial Definition': { - functionLibraryNodeDeleter.deleteInitialDefinition(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteInitialDefinition(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Open Execution': { - functionLibraryNodeDeleter.deleteOpenExecution(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteOpenExecution(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Close Execution': { - functionLibraryNodeDeleter.deleteCloseExecution(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteCloseExecution(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Event': { - functionLibraryNodeDeleter.deleteEvent(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteEvent(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Managed Item': { - functionLibraryNodeDeleter.deleteManagedItem(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteManagedItem(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Phase': { - functionLibraryNodeDeleter.deletePhase(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deletePhase(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Formula': { - functionLibraryNodeDeleter.deleteFormula(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteFormula(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Situation': { - functionLibraryNodeDeleter.deleteSituation(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteSituation(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Condition': { - functionLibraryNodeDeleter.deleteCondition(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteCondition(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Code': { - functionLibraryNodeDeleter.deleteCode(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteCode(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Exchange Account': { - functionLibraryNodeDeleter.deleteExchangeAccount(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteExchangeAccount(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Exchange Account Asset': { - functionLibraryNodeDeleter.deleteExchangeAccountAsset(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteExchangeAccountAsset(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Exchange Account Key': { - functionLibraryNodeDeleter.deleteExchangeAccountKey(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteExchangeAccountKey(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Personal Data': { - functionLibraryNodeDeleter.deletePersonalData(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deletePersonalData(payload.node, thisObject.workspaceNode.rootNodes) break } case 'Delete Definition': { - functionLibraryNodeDeleter.deleteDefinition(payload.node, workspaceNode.rootNodes) + functionLibraryNodeDeleter.deleteDefinition(payload.node, thisObject.workspaceNode.rootNodes) break } default: diff --git a/Utilities.js b/Utilities.js index 7325e599f..a72310054 100644 --- a/Utilities.js +++ b/Utilities.js @@ -1,21 +1,4 @@ -function getSimulationParams () { - let dateAtScreenCorner = new Date(window.localStorage.getItem('Date @ Screen Corner')) - let currentTimePeriod = JSON.parse(window.localStorage.getItem('Current Time Period')) - - let timePeriodsMasterArray = [marketFilesPeriods, dailyFilePeriods] - let timePeriodArray = timePeriodsMasterArray[currentTimePeriod.filePeriodIndex] - let timePeriod = timePeriodArray[currentTimePeriod.timePeriodIndex][1] - - let simulationParams = { - beginDatetime: dateAtScreenCorner, - timePeriod: timePeriod, - timestamp: (new Date()).valueOf() - } - - return simulationParams -} - function transformThisPoint (point, container) { /* We make the point relative to the current frame */