From 4fd57ad93c207cb808097cffa342762b963be24b Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 2 Sep 2021 18:15:51 +0200 Subject: [PATCH 01/11] Governance Bug Fixed: Flashing status and values --- .../UI/Function-Libraries/AirdropProgram.js | 23 ++++++++--- .../UI/Function-Libraries/Assets.js | 15 +++++-- .../UI/Function-Libraries/ClaimsProgram.js | 22 ++++++---- .../Function-Libraries/DelegationProgram.js | 25 ++++++++---- .../UI/Function-Libraries/GithubProgram.js | 23 ++++++++--- .../UI/Function-Libraries/PluginsFunctions.js | 25 +++++++++--- .../Function-Libraries/ProfileConstructor.js | 40 +++++++++++++++---- .../UI/Function-Libraries/StakingProgram.js | 18 ++++++--- .../UI/Function-Libraries/TokenMining.js | 4 +- .../UI/Function-Libraries/TokenPower.js | 23 ++++++++--- .../UI/Function-Libraries/Tokens.js | 4 +- .../UI/Function-Libraries/VotingProgram.js | 30 +++++++++----- Projects/Governance/UI/Globals/Designer.js | 11 +++++ .../Spaces/User-Profile-Space/UserProfile.js | 18 +++++++-- .../Governance/UI/Utilities/BonusProgram.js | 14 +++++-- .../UI/Utilities/DecendentProgram.js | 36 ++++++++++++----- .../Governance/UI/Utilities/Validations.js | 5 ++- Projects/ProjectsSchema.json | 5 +++ 18 files changed, 256 insertions(+), 85 deletions(-) create mode 100644 Projects/Governance/UI/Globals/Designer.js diff --git a/Projects/Governance/UI/Function-Libraries/AirdropProgram.js b/Projects/Governance/UI/Function-Libraries/AirdropProgram.js index ec5bb3a57..8b36e5fb7 100644 --- a/Projects/Governance/UI/Function-Libraries/AirdropProgram.js +++ b/Projects/Governance/UI/Function-Libraries/AirdropProgram.js @@ -106,8 +106,13 @@ function newGovernanceFunctionLibraryAirdropProgram() { userProfile.payload.blockchainTokens === undefined ) { node.payload.airdropProgram.isActive = false - userProfile.payload.uiObject.setErrorMessage("You need to setup this profile with the Profile Constructor, to access the Token Power of your account at the Blockchain.") + userProfile.payload.uiObject.setErrorMessage( + "Airdrop Program: You need to setup this profile with the Profile Constructor, to access the Token Power of your account at the Blockchain.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return + } else { + userProfile.payload.uiObject.resetErrorMessage() } /* Next thing to do is to validate if the airdrop user profile has a star at the Superalgos repository. @@ -117,7 +122,10 @@ function newGovernanceFunctionLibraryAirdropProgram() { profileSignature === undefined ) { node.payload.airdropProgram.isActive = false - userProfile.payload.uiObject.setErrorMessage("You need to setup this profile with the Profile Constructor, and produce a signature of your Airdrop Username.") + userProfile.payload.uiObject.setErrorMessage( + "You need to setup this profile with the Profile Constructor, and produce a signature of your Airdrop Username.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } @@ -154,7 +162,10 @@ function newGovernanceFunctionLibraryAirdropProgram() { if (totalPowerRewardRatio < 1) { totalPowerRewardRatio = 1 } if (programNode.tokensAwarded === undefined || programNode.tokensAwarded.payload === undefined) { - programNode.payload.uiObject.setErrorMessage("Tokens Awarded Node is needed in order for this Program to get Tokens from the Program Pool.") + programNode.payload.uiObject.setErrorMessage( + "Tokens Awarded Node is needed in order for this Program to get Tokens from the Program Pool.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } programNode.payload.airdropProgram.awarded.tokens = programNode.payload.airdropProgram.ownPower / totalPowerRewardRatio @@ -170,7 +181,7 @@ function newGovernanceFunctionLibraryAirdropProgram() { node.payload.uiObject.statusAngleOffset = 0 node.payload.uiObject.statusAtAngle = false - node.payload.uiObject.setStatus(ownPowerText + ' Airdrop Power') + node.payload.uiObject.setStatus(ownPowerText + ' Airdrop Power', UI.projects.governance.globals.designer.SET_STATUS_COUNTER) } if (node.tokensAwarded !== undefined && node.tokensAwarded.payload !== undefined) { @@ -180,12 +191,12 @@ function newGovernanceFunctionLibraryAirdropProgram() { node.tokensAwarded.payload.uiObject.valueAngleOffset = 0 node.tokensAwarded.payload.uiObject.valueAtAngle = false - node.tokensAwarded.payload.uiObject.setValue(tokensAwardedText + ' SA Tokens' + tokensAwardedBTC) + node.tokensAwarded.payload.uiObject.setValue(tokensAwardedText + ' SA Tokens' + tokensAwardedBTC, UI.projects.governance.globals.designer.SET_VALUE_COUNTER) node.tokensAwarded.payload.uiObject.statusAngleOffset = 0 node.tokensAwarded.payload.uiObject.statusAtAngle = false - node.tokensAwarded.payload.uiObject.setStatus('For creating your Superalgos profile!') + node.tokensAwarded.payload.uiObject.setStatus('For creating your Superalgos profile!', UI.projects.governance.globals.designer.SET_STATUS_COUNTER) } } } diff --git a/Projects/Governance/UI/Function-Libraries/Assets.js b/Projects/Governance/UI/Function-Libraries/Assets.js index 64be554bf..d9e629570 100644 --- a/Projects/Governance/UI/Function-Libraries/Assets.js +++ b/Projects/Governance/UI/Function-Libraries/Assets.js @@ -12,10 +12,16 @@ function newGovernanceFunctionLibraryAssets() { let folderPath = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(node.payload, 'folderPath') if (folderPath === undefined || folderPath === "") { - node.payload.uiObject.setErrorMessage("folderPath Config Property undefined.") + node.payload.uiObject.setErrorMessage( + "folderPath Config Property undefined.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } - node.payload.uiObject.setInfoMessage("Hold on while we install all the assets inside the this path: " + folderPath + ". This might take a minute or two.") + node.payload.uiObject.setInfoMessage( + "Hold on while we install all the assets inside the this path: " + folderPath + ". This might take a minute or two.", + UI.projects.governance.globals.designer.SET_INFO_COUNTER_FACTOR + ) httpRequest(undefined, 'DirContent' + '/' + folderPath, onResponse) function onResponse(err, data) { @@ -32,7 +38,10 @@ function newGovernanceFunctionLibraryAssets() { totalAssets++ createNodesFromPath(node, foldersArray) } - node.payload.uiObject.setInfoMessage("A total of : " + totalAssets + " assets have been installed.") + node.payload.uiObject.setInfoMessage( + "A total of : " + totalAssets + " assets have been installed.", + UI.projects.governance.globals.designer.SET_INFO_COUNTER_FACTOR + ) } function removeFirstFromArray(array) { diff --git a/Projects/Governance/UI/Function-Libraries/ClaimsProgram.js b/Projects/Governance/UI/Function-Libraries/ClaimsProgram.js index eb70f7fba..6ec856aa8 100644 --- a/Projects/Governance/UI/Function-Libraries/ClaimsProgram.js +++ b/Projects/Governance/UI/Function-Libraries/ClaimsProgram.js @@ -350,7 +350,10 @@ function newGovernanceFunctionLibraryClaimsProgram() { } } if (totalPercentage > 100) { - node.payload.uiObject.setErrorMessage('Claim Power Switching Error. Total Percentage of children nodes is grater that 100.') + node.payload.uiObject.setErrorMessage( + 'Claim Power Switching Error. Total Percentage of children nodes is grater that 100.', + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } let defaultPercentage = 0 @@ -446,7 +449,7 @@ function newGovernanceFunctionLibraryClaimsProgram() { 'Shared Between: ' + node.payload.claimsProgram.share.count + ' claims' + ' - ' + 'Share of Claims: ' + node.payload.claimsProgram.share.percentage.toFixed(2) + '%' - node.payload.uiObject.setStatus(status) + node.payload.uiObject.setStatus(status, UI.projects.governance.globals.designer.SET_STATUS_COUNTER) } function drawProgram(node) { @@ -457,7 +460,7 @@ function newGovernanceFunctionLibraryClaimsProgram() { node.payload.uiObject.statusAngleOffset = 0 node.payload.uiObject.statusAtAngle = false - node.payload.uiObject.setStatus(ownPowerText + ' Claim Power') + node.payload.uiObject.setStatus(ownPowerText + ' Claim Power', UI.projects.governance.globals.designer.SET_STATUS_COUNTER) } } @@ -472,8 +475,8 @@ function newGovernanceFunctionLibraryClaimsProgram() { node.tokensAwarded.payload.uiObject.statusAngleOffset = 0 node.tokensAwarded.payload.uiObject.statusAtAngle = true - node.tokensAwarded.payload.uiObject.setValue(tokensAwardedText + ' SA Tokens' + tokensAwardedBTC) - node.tokensAwarded.payload.uiObject.setStatus('From ' + node.payload.claimsProgram.count + ' Claims.') + node.tokensAwarded.payload.uiObject.setValue(tokensAwardedText + ' SA Tokens' + tokensAwardedBTC, UI.projects.governance.globals.designer.SET_VALUE_COUNTER) + node.tokensAwarded.payload.uiObject.setStatus('From ' + node.payload.claimsProgram.count + ' Claims.', UI.projects.governance.globals.designer.SET_STATUS_COUNTER) } } @@ -489,7 +492,9 @@ function newGovernanceFunctionLibraryClaimsProgram() { node.payload.uiObject.setValue(programPowerText) if (percentage !== undefined) { - node.payload.uiObject.setPercentage(percentage.toFixed(2)) + node.payload.uiObject.setPercentage(percentage.toFixed(2), + UI.projects.governance.globals.designer.SET_PERCENTAGE_COUNTER + ) } } } @@ -498,7 +503,10 @@ function newGovernanceFunctionLibraryClaimsProgram() { function installMissingClaims(node, rootNodes) { if (node.payload === undefined) { return } if (node.payload.referenceParent === undefined) { - node.payload.uiObject.setErrorMessage('To Install Missing Claims you need a Reference Parent') + node.payload.uiObject.setErrorMessage( + 'To Install Missing Claims you need a Reference Parent', + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } scanNodeBranch(node, node.payload.referenceParent) diff --git a/Projects/Governance/UI/Function-Libraries/DelegationProgram.js b/Projects/Governance/UI/Function-Libraries/DelegationProgram.js index 764efd923..b429ed4a0 100644 --- a/Projects/Governance/UI/Function-Libraries/DelegationProgram.js +++ b/Projects/Governance/UI/Function-Libraries/DelegationProgram.js @@ -211,7 +211,10 @@ function newGovernanceFunctionLibraryDelegationProgram() { } } if (totalPercentage > 100) { - node.payload.uiObject.setErrorMessage('Delegate Power Switching Error. Total Percentage of children nodes is grater that 100.') + node.payload.uiObject.setErrorMessage( + 'Delegate Power Switching Error. Total Percentage of children nodes is grater that 100.', + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } let defaultPercentage = 0 @@ -278,7 +281,9 @@ function newGovernanceFunctionLibraryDelegationProgram() { drawProgram(node) if (percentage !== undefined) { - node.payload.uiObject.setPercentage(percentage.toFixed(2)) + node.payload.uiObject.setPercentage(percentage.toFixed(2), + UI.projects.governance.globals.designer.SET_PERCENTAGE_COUNTER + ) } return } @@ -294,10 +299,12 @@ function newGovernanceFunctionLibraryDelegationProgram() { let powerType = 'Delegate Power' const programPowerText = parseFloat(programPower.toFixed(0)).toLocaleString('en') + ' ' + powerType - node.payload.uiObject.setValue(programPowerText) + node.payload.uiObject.setValue(programPowerText, UI.projects.governance.globals.designer.SET_VALUE_COUNTER) if (percentage !== undefined) { - node.payload.uiObject.setPercentage(percentage.toFixed(2)) + node.payload.uiObject.setPercentage(percentage.toFixed(2), + UI.projects.governance.globals.designer.SET_PERCENTAGE_COUNTER + ) } } } @@ -310,18 +317,20 @@ function newGovernanceFunctionLibraryDelegationProgram() { node.payload.uiObject.valueAngleOffset = 180 node.payload.uiObject.valueAtAngle = true - node.payload.uiObject.setValue(outgoingPowerText + ' Delegate Power') + node.payload.uiObject.setValue(outgoingPowerText + ' Delegate Power', UI.projects.governance.globals.designer.SET_VALUE_COUNTER) node.payload.uiObject.percentageAngleOffset = 180 node.payload.uiObject.percentageAtAngle = true - node.payload.uiObject.setPercentage(percentage) + node.payload.uiObject.setPercentage(percentage, + UI.projects.governance.globals.designer.SET_PERCENTAGE_COUNTER + ) if (node.payload.referenceParent !== undefined) { node.payload.uiObject.statusAngleOffset = 0 node.payload.uiObject.statusAtAngle = true - node.payload.uiObject.setStatus(outgoingPowerText + ' ' + ' Outgoing Power') + node.payload.uiObject.setStatus(outgoingPowerText + ' ' + ' Outgoing Power', UI.projects.governance.globals.designer.SET_STATUS_COUNTER) } } } @@ -334,7 +343,7 @@ function newGovernanceFunctionLibraryDelegationProgram() { node.payload.uiObject.statusAngleOffset = 0 node.payload.uiObject.statusAtAngle = false - node.payload.uiObject.setStatus(ownPowerText + ' Delegate Power') + node.payload.uiObject.setStatus(ownPowerText + ' Delegate Power', UI.projects.governance.globals.designer.SET_STATUS_COUNTER) } } } diff --git a/Projects/Governance/UI/Function-Libraries/GithubProgram.js b/Projects/Governance/UI/Function-Libraries/GithubProgram.js index 30b919aa0..92711ecd4 100644 --- a/Projects/Governance/UI/Function-Libraries/GithubProgram.js +++ b/Projects/Governance/UI/Function-Libraries/GithubProgram.js @@ -106,8 +106,13 @@ function newGovernanceFunctionLibraryGithubProgram() { userProfile.payload.blockchainTokens === undefined ) { node.payload.githubProgram.isActive = false - userProfile.payload.uiObject.setErrorMessage("You need to setup this profile with the Profile Constructor, to access the Token Power of your account at the Blockchain.") + userProfile.payload.uiObject.setErrorMessage( + "Github Program: You need to setup this profile with the Profile Constructor, to access the Token Power of your account at the Blockchain.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return + } else { + userProfile.payload.uiObject.resetErrorMessage() } /* Next thing to do is to validate if the github user profile has a star at the Superalgos repository. @@ -117,7 +122,10 @@ function newGovernanceFunctionLibraryGithubProgram() { profileSignature === undefined ) { node.payload.githubProgram.isActive = false - userProfile.payload.uiObject.setErrorMessage("You need to setup this profile with the Profile Constructor, and produce a signature of your Github Username.") + userProfile.payload.uiObject.setErrorMessage( + "You need to setup this profile with the Profile Constructor, and produce a signature of your Github Username.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } let githubUsername = profileSignature.message @@ -168,7 +176,10 @@ function newGovernanceFunctionLibraryGithubProgram() { if (totalPowerRewardRatio < 1) { totalPowerRewardRatio = 1 } if (programNode.tokensAwarded === undefined || programNode.tokensAwarded.payload === undefined) { - programNode.payload.uiObject.setErrorMessage("Tokens Awarded Node is needed in order for this Program to get Tokens from the Program Pool.") + programNode.payload.uiObject.setErrorMessage( + "Tokens Awarded Node is needed in order for this Program to get Tokens from the Program Pool.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } const MAX_ENGAGEMENT = 3 @@ -185,7 +196,7 @@ function newGovernanceFunctionLibraryGithubProgram() { node.payload.uiObject.statusAngleOffset = 0 node.payload.uiObject.statusAtAngle = false - node.payload.uiObject.setStatus(ownPowerText + ' Github Power') + node.payload.uiObject.setStatus(ownPowerText + ' Github Power', UI.projects.governance.globals.designer.SET_STATUS_COUNTER) } if (node.tokensAwarded !== undefined && node.tokensAwarded.payload !== undefined) { @@ -195,7 +206,7 @@ function newGovernanceFunctionLibraryGithubProgram() { node.tokensAwarded.payload.uiObject.valueAngleOffset = 0 node.tokensAwarded.payload.uiObject.valueAtAngle = false - node.tokensAwarded.payload.uiObject.setValue(tokensAwardedText + ' SA Tokens' + tokensAwardedBTC) + node.tokensAwarded.payload.uiObject.setValue(tokensAwardedText + ' SA Tokens' + tokensAwardedBTC, UI.projects.governance.globals.designer.SET_VALUE_COUNTER) node.tokensAwarded.payload.uiObject.statusAngleOffset = 0 node.tokensAwarded.payload.uiObject.statusAtAngle = false @@ -211,7 +222,7 @@ function newGovernanceFunctionLibraryGithubProgram() { extraText = extraText + ' + 1 Fork' } - node.tokensAwarded.payload.uiObject.setStatus('From' + extraText) + node.tokensAwarded.payload.uiObject.setStatus('From' + extraText, UI.projects.governance.globals.designer.SET_STATUS_COUNTER) } } } diff --git a/Projects/Governance/UI/Function-Libraries/PluginsFunctions.js b/Projects/Governance/UI/Function-Libraries/PluginsFunctions.js index c31b3a2b7..e8a4a29e5 100644 --- a/Projects/Governance/UI/Function-Libraries/PluginsFunctions.js +++ b/Projects/Governance/UI/Function-Libraries/PluginsFunctions.js @@ -12,7 +12,10 @@ function newGovernanceFunctionLibraryPluginsFunctions() { let projectName = UI.projects.foundations.utilities.plugins.getProjectName(node) if (projectName === "" || projectName === undefined) { if (node.payload.parentNode !== undefined) { - node.payload.parentNode.payload.uiObject.setErrorMessage("Config codeName must have the name of the project.") + node.payload.parentNode.payload.uiObject.setErrorMessage( + "Config codeName must have the name of the project.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } } @@ -28,7 +31,10 @@ function newGovernanceFunctionLibraryPluginsFunctions() { let projectName = UI.projects.foundations.utilities.plugins.getProjectName(node) if (projectName === "" || projectName === undefined) { if (node.payload.parentNode !== undefined) { - node.payload.parentNode.payload.uiObject.setErrorMessage("Config codeName must have the name of the project.") + node.payload.parentNode.payload.uiObject.setErrorMessage( + "Config codeName must have the name of the project.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } } @@ -44,7 +50,10 @@ function newGovernanceFunctionLibraryPluginsFunctions() { let projectName = UI.projects.foundations.utilities.plugins.getProjectName(node) if (projectName === "" || projectName === undefined) { if (node.payload.parentNode !== undefined) { - node.payload.parentNode.payload.uiObject.setErrorMessage("Config codeName must have the name of the project.") + node.payload.parentNode.payload.uiObject.setErrorMessage( + "Config codeName must have the name of the project.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } } @@ -60,7 +69,10 @@ function newGovernanceFunctionLibraryPluginsFunctions() { let projectName = UI.projects.foundations.utilities.plugins.getProjectName(node) if (projectName === "" || projectName === undefined) { if (node.payload.parentNode !== undefined) { - node.payload.parentNode.payload.uiObject.setErrorMessage("Config codeName must have the name of the project.") + node.payload.parentNode.payload.uiObject.setErrorMessage( + "Config codeName must have the name of the project.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } } @@ -76,7 +88,10 @@ function newGovernanceFunctionLibraryPluginsFunctions() { let projectName = UI.projects.foundations.utilities.plugins.getProjectName(node) if (projectName === "" || projectName === undefined) { if (node.payload.parentNode !== undefined) { - node.payload.parentNode.payload.uiObject.setErrorMessage("Config codeName must have the name of the project.") + node.payload.parentNode.payload.uiObject.setErrorMessage( + "Config codeName must have the name of the project.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } } diff --git a/Projects/Governance/UI/Function-Libraries/ProfileConstructor.js b/Projects/Governance/UI/Function-Libraries/ProfileConstructor.js index 54eb74f35..eb09d4f6f 100644 --- a/Projects/Governance/UI/Function-Libraries/ProfileConstructor.js +++ b/Projects/Governance/UI/Function-Libraries/ProfileConstructor.js @@ -16,7 +16,10 @@ function newGovernanceFunctionLibraryProfileConstructor() { let mnemonic = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(node.payload, 'mnemonic') if (githubUsername === undefined || githubUsername === "") { - node.payload.uiObject.setErrorMessage("githubUsername config property missing.") + node.payload.uiObject.setErrorMessage( + "githubUsername config property missing.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } @@ -48,7 +51,10 @@ function newGovernanceFunctionLibraryProfileConstructor() { function onResponse(err, data) { /* Lets check the result of the call through the http interface */ if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - node.payload.uiObject.setErrorMessage('Call via HTTP Interface failed.') + node.payload.uiObject.setErrorMessage( + 'Call via HTTP Interface failed.', + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } @@ -58,11 +64,17 @@ function newGovernanceFunctionLibraryProfileConstructor() { if (response.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { if (mnemonic === undefined || mnemonic === "") { - node.payload.uiObject.setErrorMessage('Call to WEB3 Server failed. ' + response.error) + node.payload.uiObject.setErrorMessage( + 'Call to WEB3 Server failed. ' + response.error, + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) console.log('Call to WEB3 Server failed. ' + response.error) return } else { - node.payload.uiObject.setErrorMessage('Call to WEB3 Server failed. Most likely the Mnemonic provided is not correct or you need to run node setup because a dependency is missing. ' + response.error) + node.payload.uiObject.setErrorMessage( + 'Call to WEB3 Server failed. Most likely the Mnemonic provided is not correct or you need to run node setup because a dependency is missing. ' + response.error, + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) console.log('Call to WEB3 Server failed. Most likely the Mnemonic provided is not correct or you need to run node setup because a dependency is missing. ' + response.error) return } @@ -88,7 +100,10 @@ function newGovernanceFunctionLibraryProfileConstructor() { function onResponse(err, data) { /* Lets check the result of the call through the http interface */ if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - node.payload.uiObject.setErrorMessage('Call via HTTP Interface failed.') + node.payload.uiObject.setErrorMessage( + 'Call via HTTP Interface failed.', + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } @@ -96,7 +111,10 @@ function newGovernanceFunctionLibraryProfileConstructor() { /* Lets check the result of the method call */ if (response.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - node.payload.uiObject.setErrorMessage('Call to WEB3 Server failed. ' + response.error) + node.payload.uiObject.setErrorMessage( + 'Call to WEB3 Server failed. ' + response.error, + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) console.log('Call to WEB3 Server failed. ' + response.error) return } @@ -124,9 +142,15 @@ function newGovernanceFunctionLibraryProfileConstructor() { Show nice message. */ if (mnemonic === undefined || mnemonic === "") { - node.payload.uiObject.setInfoMessage("Profile Private Key has been successfully created. User Profile installed as a plugin and saved. Use the Private Key at a crypto wallet and delete this node once done.", 10000) + node.payload.uiObject.setInfoMessage( + "Profile Private Key has been successfully created. User Profile installed as a plugin and saved. Use the Private Key at a crypto wallet and delete this node once done.", + UI.projects.governance.globals.designer.SET_INFO_COUNTER_FACTOR + ) } else { - node.payload.uiObject.setInfoMessage("Mnemonic successfully imported. User Profile installed as a plugin and saved. Your external wallet was sucessfully linked to your profile.", 10000) + node.payload.uiObject.setInfoMessage( + "Mnemonic successfully imported. User Profile installed as a plugin and saved. Your external wallet was sucessfully linked to your profile.", + UI.projects.governance.globals.designer.SET_INFO_COUNTER_FACTOR + ) } } } diff --git a/Projects/Governance/UI/Function-Libraries/StakingProgram.js b/Projects/Governance/UI/Function-Libraries/StakingProgram.js index 46c3f8338..4e8b94db5 100644 --- a/Projects/Governance/UI/Function-Libraries/StakingProgram.js +++ b/Projects/Governance/UI/Function-Libraries/StakingProgram.js @@ -106,10 +106,15 @@ function newGovernanceFunctionLibraryStakingProgram() { userProfile.payload.blockchainTokens === undefined ) { node.payload.stakingProgram.isActive = false - userProfile.payload.uiObject.setErrorMessage("You need to setup this profile with the Profile Constructor, to access the Token Power of your account at the Blockchain.") + userProfile.payload.uiObject.setErrorMessage( + "Staking Program: You need to setup this profile with the Profile Constructor, to access the Token Power of your account at the Blockchain.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return + } else { + userProfile.payload.uiObject.resetErrorMessage() + node.payload.stakingProgram.isActive = true } - node.payload.stakingProgram.isActive = true } function distributeProgram(programNode) { @@ -142,7 +147,10 @@ function newGovernanceFunctionLibraryStakingProgram() { if (totalPowerRewardRatio < 1) { totalPowerRewardRatio = 1 } if (programNode.tokensAwarded === undefined || programNode.tokensAwarded.payload === undefined) { - programNode.payload.uiObject.setErrorMessage("Tokens Awarded Node is needed in order for this Program to get Tokens from the Program Pool.") + programNode.payload.uiObject.setErrorMessage( + "Tokens Awarded Node is needed in order for this Program to get Tokens from the Program Pool.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } programNode.payload.stakingProgram.awarded.tokens = programNode.payload.stakingProgram.ownPower / totalPowerRewardRatio @@ -158,7 +166,7 @@ function newGovernanceFunctionLibraryStakingProgram() { node.payload.uiObject.statusAngleOffset = 0 node.payload.uiObject.statusAtAngle = false - node.payload.uiObject.setStatus(ownPowerText + ' Staking Power') + node.payload.uiObject.setStatus(ownPowerText + ' Staking Power', UI.projects.governance.globals.designer.SET_STATUS_COUNTER) } if (node.tokensAwarded !== undefined && node.tokensAwarded.payload !== undefined) { @@ -168,7 +176,7 @@ function newGovernanceFunctionLibraryStakingProgram() { node.tokensAwarded.payload.uiObject.valueAngleOffset = 0 node.tokensAwarded.payload.uiObject.valueAtAngle = false - node.tokensAwarded.payload.uiObject.setValue(tokensAwardedText + ' SA Tokens' + tokensAwardedBTC) + node.tokensAwarded.payload.uiObject.setValue(tokensAwardedText + ' SA Tokens' + tokensAwardedBTC, UI.projects.governance.globals.designer.SET_VALUE_COUNTER) } } } diff --git a/Projects/Governance/UI/Function-Libraries/TokenMining.js b/Projects/Governance/UI/Function-Libraries/TokenMining.js index 7db6b6595..68abe13c7 100644 --- a/Projects/Governance/UI/Function-Libraries/TokenMining.js +++ b/Projects/Governance/UI/Function-Libraries/TokenMining.js @@ -174,8 +174,8 @@ function newGovernanceFunctionLibraryTokenMining() { userProfile.tokensMined.payload.uiObject.valueAngleOffset = 0 userProfile.tokensMined.payload.uiObject.valueAtAngle = true - userProfile.tokensMined.payload.uiObject.setStatus(awarded + ' Awarded + ' + bonus + ' Bonus') - userProfile.tokensMined.payload.uiObject.setValue(total + ' SA Tokens' + tokensAwardedBTC) + userProfile.tokensMined.payload.uiObject.setStatus(awarded + ' Awarded + ' + bonus + ' Bonus', UI.projects.governance.globals.designer.SET_STATUS_COUNTER) + userProfile.tokensMined.payload.uiObject.setValue(total + ' SA Tokens' + tokensAwardedBTC, UI.projects.governance.globals.designer.SET_VALUE_COUNTER) } } } \ No newline at end of file diff --git a/Projects/Governance/UI/Function-Libraries/TokenPower.js b/Projects/Governance/UI/Function-Libraries/TokenPower.js index 7e38746ad..d588bc777 100644 --- a/Projects/Governance/UI/Function-Libraries/TokenPower.js +++ b/Projects/Governance/UI/Function-Libraries/TokenPower.js @@ -96,7 +96,10 @@ function newGovernanceFunctionLibraryTokenPower() { Before we start we will do some validations: */ if (userProfile.tokenPowerSwitch === undefined) { - userProfile.payload.uiObject.setErrorMessage("You need to have a Token Power Switch child node.") + userProfile.payload.uiObject.setErrorMessage( + "You need to have a Token Power Switch child node.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } distributeTokenPower( @@ -119,7 +122,10 @@ function newGovernanceFunctionLibraryTokenPower() { Before we start we will do some validations: */ if (userProfile.tokenPowerSwitch === undefined) { - userProfile.payload.uiObject.setErrorMessage("You need to have a Token Power Switch child node.") + userProfile.payload.uiObject.setErrorMessage( + "You need to have a Token Power Switch child node.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } distributeTokenPower( @@ -213,7 +219,10 @@ function newGovernanceFunctionLibraryTokenPower() { } } if (totalPercentage > 100) { - node.payload.uiObject.setErrorMessage('Token Power Switching Error. Total Percentage of children nodes is grater that 100.') + node.payload.uiObject.setErrorMessage( + 'Token Power Switching Error. Total Percentage of children nodes is grater that 100.', + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } let defaultPercentage = 0 @@ -287,7 +296,7 @@ function newGovernanceFunctionLibraryTokenPower() { node.payload.uiObject.valueAngleOffset = 0 node.payload.uiObject.valueAtAngle = false - node.payload.uiObject.setStatus(ownPowerText + ' + ' + incomingPowerText) + node.payload.uiObject.setStatus(ownPowerText + ' + ' + incomingPowerText, UI.projects.governance.globals.designer.SET_STATUS_COUNTER) return } @@ -297,12 +306,14 @@ function newGovernanceFunctionLibraryTokenPower() { node.payload.uiObject.valueAngleOffset = 180 node.payload.uiObject.valueAtAngle = true - node.payload.uiObject.setValue(tokenPowerText) + node.payload.uiObject.setValue(tokenPowerText, UI.projects.governance.globals.designer.SET_VALUE_COUNTER) if (percentage !== undefined) { node.payload.uiObject.percentageAngleOffset = 180 node.payload.uiObject.percentageAtAngle = true - node.payload.uiObject.setPercentage(percentage.toFixed(2)) + node.payload.uiObject.setPercentage(percentage.toFixed(2), + UI.projects.governance.globals.designer.SET_PERCENTAGE_COUNTER + ) } } } diff --git a/Projects/Governance/UI/Function-Libraries/Tokens.js b/Projects/Governance/UI/Function-Libraries/Tokens.js index 4d30f56b0..2810130be 100644 --- a/Projects/Governance/UI/Function-Libraries/Tokens.js +++ b/Projects/Governance/UI/Function-Libraries/Tokens.js @@ -173,7 +173,7 @@ function newGovernanceFunctionLibraryTokens() { node.payload.uiObject.statusAngleOffset = 0 node.payload.uiObject.statusAtAngle = true - node.payload.uiObject.setStatus(status) + node.payload.uiObject.setStatus(status, UI.projects.governance.globals.designer.SET_STATUS_COUNTER) } else { status = 'Reward: ' + tokens.toLocaleString('en') + ' ' + 'SA' + ' ≃ ' + UI.projects.governance.utilities.conversions.estimateSATokensInBTC(tokens | 0) + ' BTC ' @@ -181,7 +181,7 @@ function newGovernanceFunctionLibraryTokens() { node.payload.uiObject.statusAngleOffset = 0 node.payload.uiObject.statusAtAngle = false - node.payload.uiObject.setStatus(status) + node.payload.uiObject.setStatus(status, UI.projects.governance.globals.designer.SET_STATUS_COUNTER) } } } \ No newline at end of file diff --git a/Projects/Governance/UI/Function-Libraries/VotingProgram.js b/Projects/Governance/UI/Function-Libraries/VotingProgram.js index e69bbe127..1ab72bf36 100644 --- a/Projects/Governance/UI/Function-Libraries/VotingProgram.js +++ b/Projects/Governance/UI/Function-Libraries/VotingProgram.js @@ -334,7 +334,10 @@ function newGovernanceFunctionLibraryVotingProgram() { } } if (totalPercentage > 100) { - node.payload.uiObject.setErrorMessage('Voting Power Switching Error. Total Percentage of children nodes is grater that 100.') + node.payload.uiObject.setErrorMessage( + 'Voting Power Switching Error. Total Percentage of children nodes is grater that 100.', + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } let defaultPercentage = 0 @@ -406,7 +409,9 @@ function newGovernanceFunctionLibraryVotingProgram() { drawProgram(node, userProfile) if (percentage !== undefined) { - node.payload.uiObject.setPercentage(percentage.toFixed(2)) + node.payload.uiObject.setPercentage(percentage.toFixed(2), + UI.projects.governance.globals.designer.SET_PERCENTAGE_COUNTER + ) } return } @@ -457,10 +462,12 @@ function newGovernanceFunctionLibraryVotingProgram() { node.payload.uiObject.valueAngleOffset = 0 node.payload.uiObject.valueAtAngle = true - node.payload.uiObject.setValue(votesText) + node.payload.uiObject.setValue(votesText, UI.projects.governance.globals.designer.SET_VALUE_COUNTER) if (percentage !== undefined) { - node.payload.uiObject.setPercentage(percentage.toFixed(2)) + node.payload.uiObject.setPercentage(percentage.toFixed(2), + UI.projects.governance.globals.designer.SET_PERCENTAGE_COUNTER + ) } } @@ -472,18 +479,20 @@ function newGovernanceFunctionLibraryVotingProgram() { node.payload.uiObject.valueAngleOffset = 180 node.payload.uiObject.valueAtAngle = true - node.payload.uiObject.setValue(outgoingPowerText + ' Voting Power') + node.payload.uiObject.setValue(outgoingPowerText + ' Voting Power', UI.projects.governance.globals.designer.SET_VALUE_COUNTER) node.payload.uiObject.percentageAngleOffset = 180 node.payload.uiObject.percentageAtAngle = true - node.payload.uiObject.setPercentage(percentage) + node.payload.uiObject.setPercentage(percentage, + UI.projects.governance.globals.designer.SET_PERCENTAGE_COUNTER + ) if (node.payload.referenceParent !== undefined) { node.payload.uiObject.statusAngleOffset = 0 node.payload.uiObject.statusAtAngle = true - node.payload.uiObject.setStatus(outgoingPowerText + ' ' + ' Outgoing Power') + node.payload.uiObject.setStatus(outgoingPowerText + ' ' + ' Outgoing Power', UI.projects.governance.globals.designer.SET_STATUS_COUNTER) } } } @@ -502,7 +511,7 @@ function newGovernanceFunctionLibraryVotingProgram() { node.payload.uiObject.statusAngleOffset = 0 node.payload.uiObject.statusAtAngle = false - node.payload.uiObject.setStatus(ownPowerText + ' Own Power' + ' + ' + incomingPowerText + ' Incoming Voting Power' + ' + ' + reputationPowerText + ' Reputation Power') + node.payload.uiObject.setStatus(ownPowerText + ' Own Power' + ' + ' + incomingPowerText + ' Incoming Voting Power' + ' + ' + reputationPowerText + ' Reputation Power', UI.projects.governance.globals.designer.SET_STATUS_COUNTER) } } } @@ -510,7 +519,10 @@ function newGovernanceFunctionLibraryVotingProgram() { function installMissingVotes(node, rootNodes) { if (node.payload === undefined) { return } if (node.payload.referenceParent === undefined) { - node.payload.uiObject.setErrorMessage('To install votes you need a Reference Parent') + node.payload.uiObject.setErrorMessage( + 'To install votes you need a Reference Parent', + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } scanNodeBranch(node, node.payload.referenceParent) diff --git a/Projects/Governance/UI/Globals/Designer.js b/Projects/Governance/UI/Globals/Designer.js new file mode 100644 index 000000000..9be7ea241 --- /dev/null +++ b/Projects/Governance/UI/Globals/Designer.js @@ -0,0 +1,11 @@ +function newGovernanceGlobalsDesigner() { + let thisObject = { + SET_VALUE_COUNTER: 1000, + SET_STATUS_COUNTER: 1000, + SET_ERROR_COUNTER_FACTOR: 10, + SET_INFO_COUNTER_FACTOR: 10, + SET_WARNING_COUNTER: 1000, + SET_PERCENTAGE_COUNTER: 1000 + } + return thisObject +} \ No newline at end of file diff --git a/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js b/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js index 8aa24af72..d37d0f684 100644 --- a/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js +++ b/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js @@ -365,7 +365,10 @@ function newGovernanceUserProfileSpace() { function onResponse(err, data) { /* Lets check the result of the call through the http interface */ if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - userProfile.payload.uiObject.setErrorMessage('Call via HTTP Interface failed.') + userProfile.payload.uiObject.setErrorMessage( + 'Call via HTTP Interface failed.', + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } @@ -373,7 +376,10 @@ function newGovernanceUserProfileSpace() { /* Lets check the result of the method call */ if (response.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - userProfile.payload.uiObject.setErrorMessage('Call to WEB3 Server failed. ' + response.error) + userProfile.payload.uiObject.setErrorMessage( + 'Call to WEB3 Server failed. ' + response.error, + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) console.log('Call to WEB3 Server failed. ' + response.error) return } @@ -403,7 +409,9 @@ function newGovernanceUserProfileSpace() { if (data.result === "Max rate limit reached, please use API Key for higher rate limit") { userProfile.payload.blockchainTokens = undefined // This enables this profile to query the blockchain again. } else { - userProfile.payload.uiObject.setInfoMessage(data) + userProfile.payload.uiObject.setInfoMessage(data, + UI.projects.governance.globals.designer.SET_INFO_COUNTER_FACTOR + ) userProfile.payload.blockchainTokens = Number(data.result) / 1000000000000000000 userProfile.payload.reputation = Math.min(reputationByAddress.get(blockchainAccount.toLowerCase()) | 0, userProfile.payload.blockchainTokens) } @@ -412,7 +420,9 @@ function newGovernanceUserProfileSpace() { const message = err.message + ' - ' + 'Can not access BSC SCAN servers.' console.log(message) if (userProfile.payload !== undefined) { - userProfile.payload.uiObject.setErrorMessage(message, 1000) + userProfile.payload.uiObject.setErrorMessage(message, + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) } waitingForResponses-- }); diff --git a/Projects/Governance/UI/Utilities/BonusProgram.js b/Projects/Governance/UI/Utilities/BonusProgram.js index e89450c32..97c3c3659 100644 --- a/Projects/Governance/UI/Utilities/BonusProgram.js +++ b/Projects/Governance/UI/Utilities/BonusProgram.js @@ -101,8 +101,13 @@ function newGovernanceUtilitiesBonusProgram() { userProfile.payload.blockchainTokens === undefined ) { node.payload[programPropertyName].isActive = false - userProfile.payload.uiObject.setErrorMessage("You need to setup this profile with the Profile Constructor, to access the Token Power of your account at the Blockchain.") + userProfile.payload.uiObject.setErrorMessage( + "Bonus Program: You need to setup this profile with the Profile Constructor, to access the Token Power of your account at the Blockchain.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return + } else { + userProfile.payload.uiObject.resetErrorMessage() } } @@ -135,7 +140,10 @@ function newGovernanceUtilitiesBonusProgram() { if (totalPowerRewardRatio < 1) { totalPowerRewardRatio = 1 } if (programNode.tokensBonus === undefined || programNode.tokensBonus.payload === undefined) { - programNode.payload.uiObject.setErrorMessage("Tokens Bonus Node is needed in order for this Program to get Tokens from the Bonus Program Pool.") + programNode.payload.uiObject.setErrorMessage( + "Tokens Bonus Node is needed in order for this Program to get Tokens from the Bonus Program Pool.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } programNode.payload[programPropertyName].bonus.tokens = programNode.payload[programPropertyName].bonusPower / totalPowerRewardRatio @@ -152,7 +160,7 @@ function newGovernanceUtilitiesBonusProgram() { node.tokensBonus.payload.uiObject.valueAngleOffset = 0 node.tokensBonus.payload.uiObject.valueAtAngle = true - node.tokensBonus.payload.uiObject.setValue(tokensBonusText + ' SA Tokens' + tokensAwardedBTC) + node.tokensBonus.payload.uiObject.setValue(tokensBonusText + ' SA Tokens' + tokensAwardedBTC, UI.projects.governance.globals.designer.SET_VALUE_COUNTER) } } } diff --git a/Projects/Governance/UI/Utilities/DecendentProgram.js b/Projects/Governance/UI/Utilities/DecendentProgram.js index b38ce2397..7b0b57a30 100644 --- a/Projects/Governance/UI/Utilities/DecendentProgram.js +++ b/Projects/Governance/UI/Utilities/DecendentProgram.js @@ -168,8 +168,13 @@ function newGovernanceUtilitiesDecendentProgram() { userProfile.payload.blockchainTokens === undefined ) { node.payload[programPropertyName].isActive = false - userProfile.payload.uiObject.setErrorMessage("You need to setup this profile with the Profile Constructor, to access the Token Power of your account at the Blockchain.") + userProfile.payload.uiObject.setErrorMessage( + "Decendent Program: You need to setup this profile with the Profile Constructor, to access the Token Power of your account at the Blockchain.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return + } else { + userProfile.payload.uiObject.resetErrorMessage() } /* As per the system rules, the Program will not give tokens @@ -182,7 +187,10 @@ function newGovernanceUtilitiesDecendentProgram() { (node[usersArrayPropertyName] === undefined || hasUsersDefined(node[usersArrayPropertyName]) === false) ) { node.payload[programPropertyName].isActive = false - node.payload.uiObject.setErrorMessage("In order to enable this program you need to add " + userNodeType + " nodes and reference a User Profile from each one.") + node.payload.uiObject.setErrorMessage( + "In order to enable this program you need to add " + userNodeType + " nodes and reference a User Profile from each one.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) } else { node.payload[programPropertyName].isActive = true } @@ -282,7 +290,10 @@ function newGovernanceUtilitiesDecendentProgram() { } } if (totalPercentage > 100) { - node.payload.uiObject.setErrorMessage('Program Power Switching Error. Total Percentage of children nodes is grater that 100.') + node.payload.uiObject.setErrorMessage( + 'Program Power Switching Error. Total Percentage of children nodes is grater that 100.', + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } let defaultPercentage = 0 @@ -371,7 +382,10 @@ function newGovernanceUtilitiesDecendentProgram() { if (totalPowerRewardRatio < 1) { totalPowerRewardRatio = 1 } if (programNode.tokensAwarded === undefined || programNode.tokensAwarded.payload === undefined) { - programNode.payload.uiObject.setErrorMessage("Tokens Awarded Node is needed in order for this Program to get Tokens from the Program Pool.") + programNode.payload.uiObject.setErrorMessage( + "Tokens Awarded Node is needed in order for this Program to get Tokens from the Program Pool.", + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } programNode.payload[programPropertyName].awarded.tokens = programNode.payload[programPropertyName].incomingPower / totalPowerRewardRatio @@ -387,17 +401,19 @@ function newGovernanceUtilitiesDecendentProgram() { node.payload.uiObject.valueAngleOffset = 180 node.payload.uiObject.valueAtAngle = true - node.payload.uiObject.setValue(outgoingPowerText + ' ' + programPowerName) + node.payload.uiObject.setValue(outgoingPowerText + ' ' + programPowerName, UI.projects.governance.globals.designer.SET_VALUE_COUNTER) node.payload.uiObject.percentageAngleOffset = 180 node.payload.uiObject.percentageAtAngle = true - node.payload.uiObject.setPercentage(percentage) + node.payload.uiObject.setPercentage(percentage, + UI.projects.governance.globals.designer.SET_PERCENTAGE_COUNTER + ) node.payload.uiObject.statusAngleOffset = 0 node.payload.uiObject.statusAtAngle = true - node.payload.uiObject.setStatus(outgoingPowerText + ' ' + ' Outgoing Power') + node.payload.uiObject.setStatus(outgoingPowerText + ' ' + ' Outgoing Power', UI.projects.governance.globals.designer.SET_STATUS_COUNTER) } } @@ -410,7 +426,7 @@ function newGovernanceUtilitiesDecendentProgram() { node.payload.uiObject.statusAngleOffset = 0 node.payload.uiObject.statusAtAngle = false - node.payload.uiObject.setStatus(ownPowerText + ' Own Power' + ' + ' + incomingPowerText + ' Incoming ' + programPowerName) + node.payload.uiObject.setStatus(ownPowerText + ' Own Power' + ' + ' + incomingPowerText + ' Incoming ' + programPowerName, UI.projects.governance.globals.designer.SET_STATUS_COUNTER) } if (node.tokensAwarded !== undefined && node.tokensAwarded.payload !== undefined) { @@ -422,8 +438,8 @@ function newGovernanceUtilitiesDecendentProgram() { node.tokensAwarded.payload.uiObject.valueAngleOffset = 0 node.tokensAwarded.payload.uiObject.valueAtAngle = true - node.tokensAwarded.payload.uiObject.setValue(tokensAwardedText + ' SA Tokens' + tokensAwardedBTC) - node.tokensAwarded.payload.uiObject.setStatus('From ' + node.payload[programPropertyName].count + ' Descendants.') + node.tokensAwarded.payload.uiObject.setValue(tokensAwardedText + ' SA Tokens' + tokensAwardedBTC, UI.projects.governance.globals.designer.SET_VALUE_COUNTER) + node.tokensAwarded.payload.uiObject.setStatus('From ' + node.payload[programPropertyName].count + ' Descendants.', UI.projects.governance.globals.designer.SET_STATUS_COUNTER) } } } diff --git a/Projects/Governance/UI/Utilities/Validations.js b/Projects/Governance/UI/Utilities/Validations.js index 4b23c27ce..6abe955b3 100644 --- a/Projects/Governance/UI/Utilities/Validations.js +++ b/Projects/Governance/UI/Utilities/Validations.js @@ -12,7 +12,10 @@ function newGovernanceUtilitiesValidations () { let programs = UI.projects.foundations.utilities.branches.nodeBranchToArray(userProfile, programNodeType) if (programs !== undefined) { if (programs.length > 1) { - userProfile.payload.uiObject.setErrorMessage('Only one ' + programNodeType + ' is allowed.') + userProfile.payload.uiObject.setErrorMessage( + 'Only one ' + programNodeType + ' is allowed.', + UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR + ) return } if (programs.length === 1) { diff --git a/Projects/ProjectsSchema.json b/Projects/ProjectsSchema.json index 7858df6f8..9f9fd3da6 100644 --- a/Projects/ProjectsSchema.json +++ b/Projects/ProjectsSchema.json @@ -1079,6 +1079,11 @@ "propertyName": "governance", "UI": { "globals": [ + { + "name": "Designer", + "propertyName": "designer", + "functionName": "newGovernanceGlobalsDesigner" + }, { "name": "Reports", "propertyName": "reports", From 622bdebb8003446dbe5f01d27f3a805569584205 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 2 Sep 2021 18:36:58 +0200 Subject: [PATCH 02/11] Governance final touches --- Projects/Governance/UI/Function-Libraries/AirdropProgram.js | 2 +- Projects/Governance/UI/Function-Libraries/ClaimsProgram.js | 2 +- Projects/Governance/UI/Function-Libraries/GithubProgram.js | 2 +- Projects/Governance/UI/Function-Libraries/StakingProgram.js | 2 +- Projects/Governance/UI/Utilities/BonusProgram.js | 2 +- Projects/Governance/UI/Utilities/DecendentProgram.js | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Projects/Governance/UI/Function-Libraries/AirdropProgram.js b/Projects/Governance/UI/Function-Libraries/AirdropProgram.js index 8b36e5fb7..f87c72699 100644 --- a/Projects/Governance/UI/Function-Libraries/AirdropProgram.js +++ b/Projects/Governance/UI/Function-Libraries/AirdropProgram.js @@ -107,7 +107,7 @@ function newGovernanceFunctionLibraryAirdropProgram() { ) { node.payload.airdropProgram.isActive = false userProfile.payload.uiObject.setErrorMessage( - "Airdrop Program: You need to setup this profile with the Profile Constructor, to access the Token Power of your account at the Blockchain.", + "Waiting for blockchain balance. It takes 6 seconds to load the balance of each profile, bacause you are using a free API provided by BSC Scan.", UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR ) return diff --git a/Projects/Governance/UI/Function-Libraries/ClaimsProgram.js b/Projects/Governance/UI/Function-Libraries/ClaimsProgram.js index 6ec856aa8..80b03c473 100644 --- a/Projects/Governance/UI/Function-Libraries/ClaimsProgram.js +++ b/Projects/Governance/UI/Function-Libraries/ClaimsProgram.js @@ -489,7 +489,7 @@ function newGovernanceFunctionLibraryClaimsProgram() { node.payload.uiObject.percentageAngleOffset = 180 node.payload.uiObject.percentageAtAngle = true - node.payload.uiObject.setValue(programPowerText) + node.payload.uiObject.setValue(programPowerText, UI.projects.governance.globals.designer.SET_VALUE_COUNTER) if (percentage !== undefined) { node.payload.uiObject.setPercentage(percentage.toFixed(2), diff --git a/Projects/Governance/UI/Function-Libraries/GithubProgram.js b/Projects/Governance/UI/Function-Libraries/GithubProgram.js index 92711ecd4..8ff7a84d8 100644 --- a/Projects/Governance/UI/Function-Libraries/GithubProgram.js +++ b/Projects/Governance/UI/Function-Libraries/GithubProgram.js @@ -107,7 +107,7 @@ function newGovernanceFunctionLibraryGithubProgram() { ) { node.payload.githubProgram.isActive = false userProfile.payload.uiObject.setErrorMessage( - "Github Program: You need to setup this profile with the Profile Constructor, to access the Token Power of your account at the Blockchain.", + "Waiting for blockchain balance. It takes 6 seconds to load the balance of each profile, bacause you are using a free API provided by BSC Scan.", UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR ) return diff --git a/Projects/Governance/UI/Function-Libraries/StakingProgram.js b/Projects/Governance/UI/Function-Libraries/StakingProgram.js index 4e8b94db5..d3b8a0263 100644 --- a/Projects/Governance/UI/Function-Libraries/StakingProgram.js +++ b/Projects/Governance/UI/Function-Libraries/StakingProgram.js @@ -107,7 +107,7 @@ function newGovernanceFunctionLibraryStakingProgram() { ) { node.payload.stakingProgram.isActive = false userProfile.payload.uiObject.setErrorMessage( - "Staking Program: You need to setup this profile with the Profile Constructor, to access the Token Power of your account at the Blockchain.", + "Waiting for blockchain balance. It takes 6 seconds to load the balance of each profile, bacause you are using a free API provided by BSC Scan.", UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR ) return diff --git a/Projects/Governance/UI/Utilities/BonusProgram.js b/Projects/Governance/UI/Utilities/BonusProgram.js index 97c3c3659..5ef959426 100644 --- a/Projects/Governance/UI/Utilities/BonusProgram.js +++ b/Projects/Governance/UI/Utilities/BonusProgram.js @@ -102,7 +102,7 @@ function newGovernanceUtilitiesBonusProgram() { ) { node.payload[programPropertyName].isActive = false userProfile.payload.uiObject.setErrorMessage( - "Bonus Program: You need to setup this profile with the Profile Constructor, to access the Token Power of your account at the Blockchain.", + "Waiting for blockchain balance. It takes 6 seconds to load the balance of each profile, bacause you are using a free API provided by BSC Scan.", UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR ) return diff --git a/Projects/Governance/UI/Utilities/DecendentProgram.js b/Projects/Governance/UI/Utilities/DecendentProgram.js index 7b0b57a30..3f604e612 100644 --- a/Projects/Governance/UI/Utilities/DecendentProgram.js +++ b/Projects/Governance/UI/Utilities/DecendentProgram.js @@ -169,7 +169,7 @@ function newGovernanceUtilitiesDecendentProgram() { ) { node.payload[programPropertyName].isActive = false userProfile.payload.uiObject.setErrorMessage( - "Decendent Program: You need to setup this profile with the Profile Constructor, to access the Token Power of your account at the Blockchain.", + "Waiting for blockchain balance. It takes 6 seconds to load the balance of each profile, bacause you are using a free API provided by BSC Scan.", UI.projects.governance.globals.designer.SET_ERROR_COUNTER_FACTOR ) return From a0a7e52edcffca7e1fddf41417731543991bb52f Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 2 Sep 2021 19:00:21 +0200 Subject: [PATCH 03/11] Governance Bug Fixed: No resizing Docs and Gov tab. --- .../Foundations/UI/Spaces/Charting-Space/ChartingSpace.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Projects/Foundations/UI/Spaces/Charting-Space/ChartingSpace.js b/Projects/Foundations/UI/Spaces/Charting-Space/ChartingSpace.js index 3fe3f38f4..4694622d6 100644 --- a/Projects/Foundations/UI/Spaces/Charting-Space/ChartingSpace.js +++ b/Projects/Foundations/UI/Spaces/Charting-Space/ChartingSpace.js @@ -186,7 +186,9 @@ function newFoundationsChartingSpace() { } function resize() { - thisObject.viewport.resize() + if (thisObject.viewport !== undefined) { + thisObject.viewport.resize() + } thisObject.container.frame.width = browserCanvas.width thisObject.container.frame.height = COCKPIT_SPACE_POSITION } From 433addd020b21e54af01f78f8c8181c4c22a730e Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 2 Sep 2021 19:54:35 +0200 Subject: [PATCH 04/11] Governance Tab Bug fixed --- .../UI/Spaces/Reports-Space/ReportsSpace.js | 46 +++++++++++++------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/Projects/Governance/UI/Spaces/Reports-Space/ReportsSpace.js b/Projects/Governance/UI/Spaces/Reports-Space/ReportsSpace.js index 3487a3c57..af136f4fe 100644 --- a/Projects/Governance/UI/Spaces/Reports-Space/ReportsSpace.js +++ b/Projects/Governance/UI/Spaces/Reports-Space/ReportsSpace.js @@ -46,6 +46,8 @@ function newGobernanceReportsSpace() { if (isInitialized === false) { return } + hidAppDiv() + thisObject.container.finalize() thisObject.container = undefined @@ -215,22 +217,38 @@ function newGobernanceReportsSpace() { if (isInitialized === false) { return } docsAppDivPhysics() + } - function docsAppDivPhysics() { - let docsSpaceDiv = document.getElementById('governance-reports-space-div') - docsAppDivPosition = { - x: 0, - y: 0 - } - docsAppDivPosition = thisObject.container.frame.frameThisPoint(docsAppDivPosition) - docsSpaceDiv.style = ' ' + - 'overflow-y: scroll;' + - 'overflow-x: hidden;' + - 'position:fixed; top:' + docsAppDivPosition.y + 'px; ' + - 'left:' + docsAppDivPosition.x + 'px; z-index:1; ' + - 'width: ' + thisObject.container.frame.width + 'px;' + - 'height: ' + thisObject.container.frame.height + 'px' + function docsAppDivPhysics() { + let docsSpaceDiv = document.getElementById('governance-reports-space-div') + docsAppDivPosition = { + x: 0, + y: 0 } + docsAppDivPosition = thisObject.container.frame.frameThisPoint(docsAppDivPosition) + docsSpaceDiv.style = ' ' + + 'overflow-y: scroll;' + + 'overflow-x: hidden;' + + 'position:fixed; top:' + docsAppDivPosition.y + 'px; ' + + 'left:' + docsAppDivPosition.x + 'px; z-index:1; ' + + 'width: ' + thisObject.container.frame.width + 'px;' + + 'height: ' + thisObject.container.frame.height + 'px' + } + + function hidAppDiv() { + let docsSpaceDiv = document.getElementById('governance-reports-space-div') + docsAppDivPosition = { + x: 100000000000, + y: 0 + } + docsAppDivPosition = thisObject.container.frame.frameThisPoint(docsAppDivPosition) + docsSpaceDiv.style = ' ' + + 'overflow-y: scroll;' + + 'overflow-x: hidden;' + + 'position:fixed; top:' + docsAppDivPosition.y + 'px; ' + + 'left:' + docsAppDivPosition.x + 'px; z-index:1; ' + + 'width: ' + thisObject.container.frame.width + 'px;' + + 'height: ' + thisObject.container.frame.height + 'px' } function getContainer(point, purpose) { From f519ad7e9fdb265e6b0496c4edc952bb8bf84796 Mon Sep 17 00:00:00 2001 From: quantum8 Date: Fri, 3 Sep 2021 11:30:46 +1000 Subject: [PATCH 05/11] Update sparta-data-mine-004-relative-strenght-index-rsi-sparta-indicator.json Spelling fix --- ...ne-004-relative-strenght-index-rsi-sparta-indicator.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Projects/Foundations/Schemas/Docs-Topics/S/Sparta/Sparta-Data-Mine/sparta-data-mine-004-relative-strenght-index-rsi-sparta-indicator.json b/Projects/Foundations/Schemas/Docs-Topics/S/Sparta/Sparta-Data-Mine/sparta-data-mine-004-relative-strenght-index-rsi-sparta-indicator.json index c6ce769d1..73b0ca493 100644 --- a/Projects/Foundations/Schemas/Docs-Topics/S/Sparta/Sparta-Data-Mine/sparta-data-mine-004-relative-strenght-index-rsi-sparta-indicator.json +++ b/Projects/Foundations/Schemas/Docs-Topics/S/Sparta/Sparta-Data-Mine/sparta-data-mine-004-relative-strenght-index-rsi-sparta-indicator.json @@ -1,9 +1,9 @@ { "topic": "Sparta Data Mine", "pageNumber": 4, - "type": "Relative Strenght Index (RSI) - Sparta Indicator", + "type": "Relative Strength Index (RSI) - Sparta Indicator", "definition": { - "text": "The indicator produces the standard 14 setting of the Relative Strenght Index.", + "text": "The indicator produces the standard 14 setting of the Relative Strength Index.", "updated": 1611662214310 }, "paragraphs": [ @@ -59,4 +59,4 @@ "text": "How’s the trend going at the 24-hours chart?" } ] -} \ No newline at end of file +} From 243f2ec1d8940473bdfd6e8b041e171b517c4dd0 Mon Sep 17 00:00:00 2001 From: quantum8 Date: Fri, 3 Sep 2021 11:31:47 +1000 Subject: [PATCH 06/11] Update sparta-data-mine-001-sparta-by-@julian-molina.json Spelling fix --- .../sparta-data-mine-001-sparta-by-@julian-molina.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Projects/Foundations/Schemas/Docs-Topics/S/Sparta/Sparta-Data-Mine/sparta-data-mine-001-sparta-by-@julian-molina.json b/Projects/Foundations/Schemas/Docs-Topics/S/Sparta/Sparta-Data-Mine/sparta-data-mine-001-sparta-by-@julian-molina.json index a5601801e..b17b60e2e 100644 --- a/Projects/Foundations/Schemas/Docs-Topics/S/Sparta/Sparta-Data-Mine/sparta-data-mine-001-sparta-by-@julian-molina.json +++ b/Projects/Foundations/Schemas/Docs-Topics/S/Sparta/Sparta-Data-Mine/sparta-data-mine-001-sparta-by-@julian-molina.json @@ -3,7 +3,7 @@ "pageNumber": 1, "type": "Sparta By @julian-molina", "definition": { - "text": "The set of indicators built in the Sparta data mine include Simple Moving Average (SMA), Exponential Moving Averege (EMA), Relative Strenght Index (RSI), and Moving Average convergence Divergence (MACD).", + "text": "The set of indicators built in the Sparta data mine include Simple Moving Average (SMA), Exponential Moving Averege (EMA), Relative Strength Index (RSI), and Moving Average convergence Divergence (MACD).", "updated": 1611685345604 }, "paragraphs": [ @@ -22,4 +22,4 @@ "text": "Collaborate with this data mine and report issues directly at the Superalgos repository." } ] -} \ No newline at end of file +} From 0fc22b5f56f8eb6944b348b826dfb1e238210ab3 Mon Sep 17 00:00:00 2001 From: quantum8 Date: Fri, 3 Sep 2021 11:33:27 +1000 Subject: [PATCH 07/11] Update Delta.json spelling fix --- Projects/Foundations/Plugins/Data-Mines/Delta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/Foundations/Plugins/Data-Mines/Delta.json b/Projects/Foundations/Plugins/Data-Mines/Delta.json index 4e8498d9b..2e11f0d13 100644 --- a/Projects/Foundations/Plugins/Data-Mines/Delta.json +++ b/Projects/Foundations/Plugins/Data-Mines/Delta.json @@ -1 +1 @@ -{"type":"Data Mine","name":"Delta","config":"{\n \"codeName\": \"Delta\"\n}","project":"Foundations","sensorBots":[],"indicatorBots":[{"type":"Indicator Bot","name":"Relative Strenght Index - Wilder Method (RSI-W)","config":"{\n \"codeName\": \"RSI-W\"\n}","project":"Foundations","processes":[{"type":"Process Definition","name":"Multi-Time-Frame-Market","config":"{\n \"codeName\": \"Multi-Time-Frame-Market\",\n \"description\": \"Calculates Wilder RSI.\",\n \"deadWaitTime\": 0,\n \"normalWaitTime\": 0,\n \"retryWaitTime\": 10000,\n \"sleepWaitTime\": 3600000,\n \"comaWaitTime\": 86400000,\n \"framework\": {\n \"name\": \"Multi-Time-Frame-Market\"\n }\n}","project":"Foundations","processOutput":{"type":"Process Output","name":"New Process Output","project":"Foundations","outputDatasets":[{"type":"Output Dataset","name":"Multi-Time-Frame-Market RSI-W14","project":"Foundations","id":"75881553-ec60-4954-9404-052ba11904f4","savedPayload":{"position":{"x":19646.18251638588,"y":17789.2053813897},"targetPosition":{"x":19675.299658959913,"y":17897.87203684722},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Market","id":"a94722c3-a453-4f46-931f-aeb244e7cb66"}}}],"outputDatasetFolders":[],"id":"ffb59a7e-565a-4588-bd44-999a7cb66122","savedPayload":{"position":{"x":19675.299658959913,"y":17897.87203684722},"targetPosition":{"x":19704.416801533946,"y":18006.53869230474},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"processDependencies":{"type":"Process Dependencies","name":"New Process Dependencies","project":"Foundations","statusDependencies":[{"type":"Status Dependency","name":"Candles Volumes Multi-Time-Frame-Market","config":"{\n \"mainUtility\": \"Market Ending Point\"\n}","project":"Foundations","id":"b0af9801-ba4e-4bfd-a605-98d9ac121b5f","savedPayload":{"position":{"x":19650.151086682014,"y":17594.3496655382},"targetPosition":{"x":19762.651086682014,"y":17789.2053813897},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"a0a61ba9-91cb-4ec7-92fe-134ff079de2d"}}},{"type":"Status Dependency","name":"Relative Strenght Index - Wilder Method (RSI-W) Multi-Time-Frame-Market","config":"{\n \"mainUtility\": \"Self Reference\"\n}","project":"Foundations","id":"02d64b4a-7c3c-4c89-918d-b3697b5955b2","savedPayload":{"position":{"x":19820.88537183008,"y":17571.87207047466},"targetPosition":{"x":19762.651086682014,"y":17789.2053813897},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"2b961dac-9f41-4eed-a495-4e55f26714c3"}}}],"dataDependencies":[{"type":"Data Dependency","name":"Candles Multi-Time-Frame-Market","project":"Foundations","id":"25315413-2e01-4a7d-83bc-1257d43f8fe6","savedPayload":{"position":{"x":19957.506802533513,"y":17676.7053813897},"targetPosition":{"x":19762.651086682014,"y":17789.2053813897},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Market","id":"2b03494a-67d6-47f1-89b6-53fc4c9116a8"}}}],"dataMineDataDependencies":[],"id":"b14516a1-e5cc-48f8-ab0f-0e46faf6c41c","savedPayload":{"position":{"x":19762.651086682014,"y":17789.2053813897},"targetPosition":{"x":19704.416801533946,"y":18006.53869230474},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"statusReport":{"type":"Status Report","name":"New Status Report","project":"Foundations","id":"2b961dac-9f41-4eed-a495-4e55f26714c3","savedPayload":{"position":{"x":19863.51582730092,"y":17847.439666537768},"targetPosition":{"x":19704.416801533946,"y":18006.53869230474},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},"executionStartedEvent":{"type":"Execution Started Event","name":"Candles Volumes Multi-Time-Frame-Market","project":"Foundations","id":"c1598823-e0b3-4036-8ad6-669ae0e3f638","savedPayload":{"position":{"x":19921.750112448986,"y":17948.304407156673},"targetPosition":{"x":19704.416801533946,"y":18006.53869230474},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Execution Finished Event","name":"New Execution Finished Event","id":"1824fa00-dd30-4cdc-acc0-01c2f29056c5"}}},"executionFinishedEvent":{"type":"Execution Finished Event","name":"New Execution Finished Event","project":"Foundations","id":"b317c309-4677-4a2a-ba2a-801fccd01b1d","savedPayload":{"position":{"x":19921.750112448986,"y":18064.77297745281},"targetPosition":{"x":19704.416801533946,"y":18006.53869230474},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},"id":"279a9122-7f94-47b4-bf09-999fa889104b","savedPayload":{"position":{"x":19690.416801533946,"y":18018.53869230474},"targetPosition":{"x":19372.21875,"y":18336.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Process Definition","name":"Multi-Time-Frame-Daily","config":"{\n \"codeName\": \"Multi-Time-Frame-Daily\",\n \"description\": \"Calculates Wilder RSI\",\n \"deadWaitTime\": 0,\n \"normalWaitTime\": 0,\n \"retryWaitTime\": 10000,\n \"sleepWaitTime\": 3600000,\n \"comaWaitTime\": 86400000,\n \"framework\": {\n \"name\": \"Multi-Time-Frame-Daily\"\n }\n}","project":"Foundations","processOutput":{"type":"Process Output","name":"New Process Output","project":"Foundations","outputDatasets":[{"type":"Output Dataset","name":"Multi-Time-Frame-Daily RSI-W14","project":"Foundations","id":"a902a032-dbcc-4f7f-8495-70f0f5da03f8","savedPayload":{"position":{"x":19167.963077267068,"y":19583.111743838686},"targetPosition":{"x":19081.360536888624,"y":19533.111743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Daily","id":"f6e7a28d-d3d8-4d05-b90f-40bbe5f59b8a"}}}],"outputDatasetFolders":[],"id":"02da2e0b-9593-485a-ae0d-3f4ff131c813","savedPayload":{"position":{"x":19081.360536888624,"y":19533.111743838686},"targetPosition":{"x":18935.21875,"y":19448.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"processDependencies":{"type":"Process Dependencies","name":"New Process Dependencies","project":"Foundations","statusDependencies":[{"type":"Status Dependency","name":"Candles Volumes Multi-Time-Frame-Daily","config":"{\"mainUtility\": \"Market Ending Point\"}","project":"Foundations","id":"3173726e-99f5-4153-acbd-17e0ca4c6dac","savedPayload":{"position":{"x":19608.369889686794,"y":20068.582247746013},"targetPosition":{"x":19272.71875,"y":20033.30389139318},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"2a021da8-9feb-475e-90ab-1586968c17c7"}}},{"type":"Status Dependency","name":"Exchange Raw Data Historic-OHLCVs","config":"{\n \"mainUtility\": \"Market Starting Point\"\n}","project":"Foundations","id":"56d255fa-7193-431f-a3c5-f98e6d28a508","savedPayload":{"position":{"x":19523.53012859862,"y":20259.135471039295},"targetPosition":{"x":19272.71875,"y":20033.30389139318},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"181c7c34-7243-497a-9ddb-1b0067c6d66e"}}},{"type":"Status Dependency","name":"Relative Strenght Index - Wilder Method (RSI-W) Multi-Time-Frame-Daily","config":"{\n \"mainUtility\": \"Self Reference\"\n}","project":"Foundations","id":"b96ab1d1-3bdc-429d-921a-0aab94741d29","savedPayload":{"position":{"x":19342.888945650993,"y":20363.42870664084},"targetPosition":{"x":19272.71875,"y":20033.30389139318},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"8c1c40cf-dd93-4f61-b3f0-9344707b196d"}}}],"dataDependencies":[{"type":"Data Dependency","name":"Candles Multi-Time-Frame-Daily","project":"Foundations","id":"756f850b-7e37-4fc8-8031-b7c8458bc8c3","savedPayload":{"position":{"x":19135.44513296192,"y":20341.625483347558},"targetPosition":{"x":19272.71875,"y":20033.30389139318},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Daily","id":"678a567c-f08d-49b9-813b-4e54fd6afadb"}}}],"dataMineDataDependencies":[],"id":"c42ac621-a7d7-499a-84a0-76bd99ef3fa4","savedPayload":{"position":{"x":19272.71875,"y":20033.30389139318},"targetPosition":{"x":18935.21875,"y":19448.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"statusReport":{"type":"Status Report","name":"New Status Report","project":"Foundations","id":"8c1c40cf-dd93-4f61-b3f0-9344707b196d","savedPayload":{"position":{"x":18935.21875,"y":19786.236743838686},"targetPosition":{"x":18935.21875,"y":19448.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},"executionStartedEvent":{"type":"Execution Started Event","name":"Candles Volumes Multi-Time-Frame-Daily","project":"Foundations","id":"1bf32fba-af6a-43eb-b0bb-2ac855bb5820","savedPayload":{"position":{"x":18766.46875,"y":19741.020317615934},"targetPosition":{"x":18935.21875,"y":19448.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Execution Finished Event","name":"New Execution Finished Event","id":"f29d08f9-e7c8-490c-8fca-14851a0d3dc3"}}},"executionFinishedEvent":{"type":"Execution Finished Event","name":"New Execution Finished Event","project":"Foundations","id":"ffcd3bc1-44f3-4e21-9f33-fc2f818494b5","savedPayload":{"position":{"x":18642.935176222752,"y":19617.486743838686},"targetPosition":{"x":18935.21875,"y":19448.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},"id":"a5c6c183-7b68-4e7c-82c2-27ac439b098d","savedPayload":{"position":{"x":20047.21875,"y":18336.736743838686},"targetPosition":{"x":19372.21875,"y":18336.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":4,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"products":[{"type":"Product Definition","name":"RSI-W14","config":"{\n \"codeName\": \"RSI-W14\",\n \"singularVariableName\": \"rsiw14\",\n \"pluralVariableName\": \"rsiw14s\"\n}","project":"Foundations","datasets":[{"type":"Dataset Definition","name":"Multi-Time-Frame-Daily","config":"{\n \"codeName\": \"Multi-Time-Frame-Daily\",\n \"type\": \"Daily Files\",\n \"validTimeFrames\": [\n \"45-min\",\n \"40-min\",\n \"30-min\",\n \"20-min\",\n \"15-min\",\n \"10-min\",\n \"05-min\",\n \"04-min\",\n \"03-min\",\n \"02-min\",\n \"01-min\"\n ],\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset/@TimeFrame/@Year/@Month/@Day\",\n \"fileName\": \"Data.json\",\n \"dataRange\": {\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset\",\n \"fileName\": \"Data.Range.json\"\n },\n \"timeFrames\": {\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset\",\n \"fileName\": \"Time.Frames.json\"\n }\n}","project":"Foundations","id":"f6e7a28d-d3d8-4d05-b90f-40bbe5f59b8a","savedPayload":{"position":{"x":19912.64667816785,"y":18619.73704073858},"targetPosition":{"x":19690.416801533946,"y":18654.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},{"type":"Dataset Definition","name":"Multi-Time-Frame-Market","config":"{\n \"codeName\": \"Multi-Time-Frame-Market\",\n \"type\": \"Market Files\",\n \"validTimeFrames\": [\n \"24-hs\",\n \"12-hs\",\n \"08-hs\",\n \"06-hs\",\n \"04-hs\",\n \"03-hs\",\n \"02-hs\",\n \"01-hs\"\n ],\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset/@TimeFrame\",\n \"fileName\": \"Data.json\",\n \"timeFrames\" : {\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset\",\n \"fileName\": \"Time.Frames.json\"\n }\n}","project":"Foundations","id":"a94722c3-a453-4f46-931f-aeb244e7cb66","savedPayload":{"position":{"x":19890.893269476328,"y":18757.08265781403},"targetPosition":{"x":19690.416801533946,"y":18654.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}}],"record":{"type":"Record Definition","name":"New Record Definition","project":"Foundations","properties":[{"type":"Record Property","name":"Begin","config":"{\n \"codeName\": \"begin\",\n \"isString\": false\n}","project":"Foundations","recordFormula":{"type":"Record Formula","name":"Begin","code":"record.current.begin","project":"Foundations","id":"5f2981e4-5b9a-4867-9bf4-79dd2b9c19f0","savedPayload":{"position":{"x":20108.700242583152,"y":19125.41655499176},"targetPosition":{"x":20001.706384499947,"y":19090.65214312458},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"a7c379ea-fc2f-4526-9a5f-fcdc272f6a02","savedPayload":{"position":{"x":20001.706384499947,"y":19090.65214312458},"targetPosition":{"x":19894.71252641674,"y":19055.887731257397},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Record Property","name":"End","config":"{\n \"codeName\": \"end\",\n \"isString\": false\n}","project":"Foundations","recordFormula":{"type":"Record Formula","code":"record.current.end","project":"Foundations","id":"ad4e0d6b-e7ce-4e09-88a6-a3f44d7c0c08","savedPayload":{"position":{"x":19996.860388858142,"y":19256.36419919978},"targetPosition":{"x":19945.78645763744,"y":19156.125965228588},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"a859a2ce-cd0a-43ae-995b-6140402a9f1a","savedPayload":{"position":{"x":19945.78645763744,"y":19156.125965228588},"targetPosition":{"x":19894.71252641674,"y":19055.887731257397},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Record Property","name":"Value","config":"{\n \"codeName\": \"value\",\n \"isString\": false\n}","project":"Foundations","recordFormula":{"type":"Record Formula","code":"variable.value","project":"Foundations","id":"43595088-af8f-4ad5-8bfe-3b04a5168681","savedPayload":{"position":{"x":19825.183702682378,"y":19269.87544742381},"targetPosition":{"x":19859.94811454956,"y":19162.881589340603},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"3cd01f28-dd1a-45bc-8c68-29bdbf4be84b","savedPayload":{"position":{"x":19859.94811454956,"y":19162.881589340603},"targetPosition":{"x":19894.71252641674,"y":19055.887731257397},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"ee7e6fb0-984c-410b-9ba7-241deddcd7ad","savedPayload":{"position":{"x":19894.71252641674,"y":19055.887731257397},"targetPosition":{"x":19690.416801533946,"y":18654.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"dataBuilding":{"type":"Data Building Procedure","name":"New Data Building Procedure","project":"Foundations","loop":{"type":"Procedure Loop","name":"New Procedure Loop","project":"Foundations","procedureJavascriptCode":{"type":"Procedure Javascript Code","code":"/* Loop Code */\n\n/* \nCalculation method credit: https://www.macroption.com/rsi-calculation/\n*/\n\n/* Calculating Up Moves and Down Moves */\n\n//let candle = record.current // Our main dependencies are candles \n//let candlePrevious = record.previous\n\nif (record.previous !== undefined) {\n if (record.current.close > record.previous.close) {\n variable.last14U.push(record.current.close - record.previous.close) // Add win to last 14 array.\n } else {\n variable.last14U.push(0) // Add 0 to keep proper count of records in the last 14 array.\n }\n \n if (record.current.close < record.previous.close) {\n variable.last14D.push(record.previous.close - record.current.close) // Add win to last 14 array.\n } else {\n variable.last14D.push(0) // Add 0 to keep proper count of records in the last 14 array.\n }\n \n if (variable.last14U.length > 14) {\n variable.last14U.splice(0, 1) // Remove the first element of the array to keep it at a maximun of 14 elements.\n }\n \n if (variable.last14D.length > 14) {\n variable.last14D.splice(0, 1) // Remove the first element of the array to keep it at a maximun of 14 elements.\n }\n \n /* Calculating Averages of Up Moves and Down Moves */\n\n variable.avgU = calculateRMAU(14)\n variable.avgD = calculateRMAD(14)\n\n /* Keep track of average moves */\n variable.rma14U.push(variable.avgU)\n variable.rma14D.push(variable.avgD)\n \n if (variable.rma14U.length > 14) {\n variable.rma14U.splice(0, 1) // Remove the first element of the array to keep it at a maximun of 14 elements.\n }\n \n if (variable.rma14D.length > 14) {\n variable.rma14D.splice(0, 1) // Remove the first element of the array to keep it at a maximun of 14 elements.\n }\n\n /* Calculating Relative Strength */\n \n if (variable.avgD > 0) {\n relativeStrength = variable.avgU / variable.avgD\n } else {\n relativeStrength = 0\n }\n\n /* Calculating RSI */\n\n relativeStrengthIndex = 100 - 100 / ( 1 + relativeStrength)\n\n if (relativeStrengthIndex !== undefined) {\n variable.value = relativeStrengthIndex.toFixed(2)\n } else {\n variable.value = 0\n }\n} else {\n variable.value = 0\n}\n\n// Statistics\n\nfunction calculateWMA(source, rmas, periods) { // Having a function avoids us to repeat code.\n /* We check we have enough values to make the calculation */\n if (source.length < periods) { return 0 } // If we dont, we define the value is zero.\n\n let alpha = 1 / periods\n let avg = source[source.length - 1] * alpha + rmas[rmas.length - 1] * (1 - alpha)\n return avg;\n}\n\nfunction calculateRMAU(periods) {\n return calculateWMA(variable.last14U, variable.rma14U, periods)\n}\n\nfunction calculateRMAD(periods) {\n return calculateWMA(variable.last14D, variable.rma14D, periods)\n}","project":"Foundations","id":"91eb76f0-617c-4397-9135-beca294a6481","savedPayload":{"position":{"x":19781.28686956123,"y":19519.505740564182},"targetPosition":{"x":19700.654080913537,"y":19309.450144602313},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"6957916d-b353-4b19-8b8f-cf7fb97024b3","savedPayload":{"position":{"x":19700.654080913537,"y":19309.450144602313},"targetPosition":{"x":19620.021292265843,"y":19099.394548640445},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"initialization":{"type":"Procedure Initialization","name":"New Procedure Initialization","project":"Foundations","procedureJavascriptCode":{"type":"Procedure Javascript Code","code":"/* Initialization Code*/\n\n/* \nWe keep two separate arrays to store last 14 price increments or losses.\n*/\n\nvariable.last14U = []\nvariable.last14D = []\nvariable.rma14U = []\nvariable.rma14D = []\n","project":"Foundations","id":"7b8d4dd2-2dde-47fe-8340-efd0f93fe435","savedPayload":{"position":{"x":19336.827116293414,"y":19449.110231296083},"targetPosition":{"x":19478.42420427963,"y":19274.252389968264},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"076ef281-1c67-4117-8168-a5beba487ffc","savedPayload":{"position":{"x":19478.42420427963,"y":19274.252389968264},"targetPosition":{"x":19620.021292265843,"y":19099.394548640445},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"id":"a1ef81d6-c2c9-46c4-aaed-366b31b2d639","savedPayload":{"position":{"x":19620.021292265843,"y":19099.394548640445},"targetPosition":{"x":19690.416801533946,"y":18654.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"id":"fbe3d4ba-bcfd-4cb1-91d1-64d7d381a21c","savedPayload":{"position":{"x":19690.416801533946,"y":18654.934795372632},"targetPosition":{"x":19372.21875,"y":18336.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Plotter Module","name":"RSI-W14","id":"4045dbb5-77d9-46ed-837d-e05caded1a29"}}}],"id":"1b49e818-f9f9-4ecc-bdbd-708f5641fb66","savedPayload":{"position":{"x":19372.21875,"y":18336.736743838686},"targetPosition":{"x":18922.21875,"y":18336.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Indicator Bot","name":"Money Flow Index (MFI)","config":"{\n \"codeName\": \"MFI\"\n}","project":"Foundations","processes":[{"type":"Process Definition","name":"Multi-Time-Frame-Daily","config":"{\n \"codeName\": \"Multi-Time-Frame-Daily\",\n \"description\": \"Calculates MFI\",\n \"deadWaitTime\": 0,\n \"normalWaitTime\": 0,\n \"retryWaitTime\": 10000,\n \"sleepWaitTime\": 3600000,\n \"comaWaitTime\": 86400000,\n \"framework\": {\n \"name\": \"Multi-Time-Frame-Daily\"\n }\n}","project":"Foundations","processOutput":{"type":"Process Output","name":"New Process Output","project":"Foundations","outputDatasets":[{"type":"Output Dataset","name":"Multi-Time-Frame-Daily MFI","project":"Foundations","id":"48a07111-4122-4d5c-a3ef-df4b138b6af7","savedPayload":{"position":{"x":19445.67603962037,"y":19049.935748288346},"targetPosition":{"x":19349.083456991466,"y":19075.8176527986},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Daily","id":"22edf2c6-b165-4b9e-b6ac-0cfefd9ee01b"}}}],"outputDatasetFolders":[],"id":"3c9355dd-ecf6-4604-b7f7-f6f1f8e784d6","savedPayload":{"position":{"x":19349.083456991466,"y":19075.8176527986},"targetPosition":{"x":19240.416801533946,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"processDependencies":{"type":"Process Dependencies","name":"New Process Dependencies","project":"Foundations","statusDependencies":[{"type":"Status Dependency","name":"Candles Volumes Multi-Time-Frame-Daily","config":"{\"mainUtility\": \"Market Ending Point\"}","project":"Foundations","id":"7867d355-9cd6-434e-90de-cd1f5f9ba32a","savedPayload":{"position":{"x":19537.299625332475,"y":19083.61956763721},"targetPosition":{"x":19457.750112448986,"y":19163.1690805207},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"2a021da8-9feb-475e-90ab-1586968c17c7"}}},{"type":"Status Dependency","name":"Exchange Raw Data Historic-OHLCVs","config":"{\n \"mainUtility\": \"Market Starting Point\"\n}","project":"Foundations","id":"bdf2cbd7-2cd6-4945-96b3-0609b3969d37","savedPayload":{"position":{"x":19566.416767906507,"y":19134.051937946668},"targetPosition":{"x":19457.750112448986,"y":19163.1690805207},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"181c7c34-7243-497a-9ddb-1b0067c6d66e"}}},{"type":"Status Dependency","name":"Money Flow Index (MFI) Multi-Time-Frame-Daily","config":"{\n \"mainUtility\": \"Self Reference\"\n}","project":"Foundations","id":"25380d29-c370-4b34-bcb6-55d94cab4a11","savedPayload":{"position":{"x":19566.416767906507,"y":19192.286223094732},"targetPosition":{"x":19457.750112448986,"y":19163.1690805207},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"218ce270-08fe-45a0-90ef-7189fffd72dd"}}}],"dataDependencies":[{"type":"Data Dependency","name":"Candles Multi-Time-Frame-Daily","project":"Foundations","id":"afdb16be-1eba-4ab0-aceb-9695b25ef435","savedPayload":{"position":{"x":19537.299625332475,"y":19242.718593404188},"targetPosition":{"x":19457.750112448986,"y":19163.1690805207},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Daily","id":"678a567c-f08d-49b9-813b-4e54fd6afadb"}}},{"type":"Data Dependency","name":"Volumes Multi-Time-Frame-Daily","project":"Foundations","id":"f26fa862-f8e1-480b-b9a3-fb8e001e3b8d","savedPayload":{"position":{"x":19486.86725502302,"y":19271.83573597822},"targetPosition":{"x":19457.750112448986,"y":19163.1690805207},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Daily","id":"2e683057-f911-4105-bc77-16f2706d1915"}}}],"dataMineDataDependencies":[],"id":"4704cf1b-133a-4e6e-8b97-bfece022354e","savedPayload":{"position":{"x":19457.750112448986,"y":19163.1690805207},"targetPosition":{"x":19240.416801533946,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"statusReport":{"type":"Status Report","name":"New Status Report","project":"Foundations","id":"218ce270-08fe-45a0-90ef-7189fffd72dd","savedPayload":{"position":{"x":19399.51582730092,"y":19264.033821139605},"targetPosition":{"x":19240.416801533946,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},"executionStartedEvent":{"type":"Execution Started Event","name":"Candles Volumes Multi-Time-Frame-Daily","project":"Foundations","id":"30fcca1f-f72d-46cf-bd17-99f8e2e1cd10","savedPayload":{"position":{"x":19298.651086682014,"y":19322.268106287673},"targetPosition":{"x":19240.416801533946,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Execution Finished Event","name":"New Execution Finished Event","id":"f29d08f9-e7c8-490c-8fca-14851a0d3dc3"}}},"executionFinishedEvent":{"type":"Execution Finished Event","name":"New Execution Finished Event","project":"Foundations","id":"91f10f62-3cad-4709-8b90-31daceb01bd2","savedPayload":{"position":{"x":19182.182516385878,"y":19322.268106287673},"targetPosition":{"x":19240.416801533946,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},"id":"6be015e8-abd8-4c91-bc44-ed0dbe4401bf","savedPayload":{"position":{"x":19240.416801533946,"y":19104.934795372632},"targetPosition":{"x":18922.21875,"y":18786.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Process Definition","name":"Multi-Time-Frame-Market","config":"{\n \"codeName\": \"Multi-Time-Frame-Market\",\n \"description\": \"Calculates MFI.\",\n \"deadWaitTime\": 0,\n \"normalWaitTime\": 0,\n \"retryWaitTime\": 10000,\n \"sleepWaitTime\": 3600000,\n \"comaWaitTime\": 86400000,\n \"framework\": {\n \"name\": \"Multi-Time-Frame-Market\"\n }\n}","project":"Foundations","processOutput":{"type":"Process Output","name":"New Process Output","project":"Foundations","outputDatasets":[{"type":"Output Dataset","name":"Multi-Time-Frame-Market MFI","project":"Foundations","id":"c5c02f93-dacc-4e97-803b-45f1d3d7756c","savedPayload":{"position":{"x":19130.074465851496,"y":19336.236743838686},"targetPosition":{"x":19032.646607925748,"y":19279.986743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Market","id":"f5f04930-c2a3-48b7-ade9-f98e148344f1"}}}],"outputDatasetFolders":[],"id":"a78ac5ae-14c4-4928-968b-604d5c78521c","savedPayload":{"position":{"x":19032.646607925748,"y":19279.986743838686},"targetPosition":{"x":18935.21875,"y":19223.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"processDependencies":{"type":"Process Dependencies","name":"New Process Dependencies","project":"Foundations","statusDependencies":[{"type":"Status Dependency","name":"Candles Volumes Multi-Time-Frame-Market","config":"{\n \"mainUtility\": \"Market Ending Point\"\n}","project":"Foundations","id":"226234a8-bb22-4f31-9446-ffee286446b4","savedPayload":{"position":{"x":19271.48617645786,"y":19442.111363925407},"targetPosition":{"x":19047.71875,"y":19418.592459690186},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"a0a61ba9-91cb-4ec7-92fe-134ff079de2d"}}},{"type":"Status Dependency","name":"Money Flow Index (MFI) Multi-Time-Frame-Market","config":"{\n \"mainUtility\": \"Self Reference\"\n}","project":"Foundations","id":"319ba4b4-77dc-412f-be3f-6fdb088f317c","savedPayload":{"position":{"x":19214.926335732413,"y":19569.14684612093},"targetPosition":{"x":19047.71875,"y":19418.592459690186},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"f4b09884-97e4-44e6-b0cf-3025c4cc44f9"}}}],"dataDependencies":[{"type":"Data Dependency","name":"Candles Multi-Time-Frame-Market","project":"Foundations","id":"39802ca4-ee03-42f3-a5a4-e805f787520b","savedPayload":{"position":{"x":19094.498880433996,"y":19638.675669855293},"targetPosition":{"x":19047.71875,"y":19418.592459690186},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Market","id":"2b03494a-67d6-47f1-89b6-53fc4c9116a8"}}},{"type":"Data Dependency","name":"Volumes Multi-Time-Frame-Market","project":"Foundations","id":"9580ee4c-eb61-4133-91be-b9b8065cc74e","savedPayload":{"position":{"x":18956.203005307943,"y":19624.14018765977},"targetPosition":{"x":19047.71875,"y":19418.592459690186},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Market","id":"9bf0483c-4825-4a46-9cf4-1b5262579fc1"}}}],"dataMineDataDependencies":[],"id":"871fab7f-2e97-4a8a-a771-0f4769c7b82d","savedPayload":{"position":{"x":19047.71875,"y":19418.592459690186},"targetPosition":{"x":18935.21875,"y":19223.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"statusReport":{"type":"Status Report","name":"New Status Report","project":"Foundations","id":"f4b09884-97e4-44e6-b0cf-3025c4cc44f9","savedPayload":{"position":{"x":18935.21875,"y":19448.736743838686},"targetPosition":{"x":18935.21875,"y":19223.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},"executionStartedEvent":{"type":"Execution Started Event","name":"Candles Volumes Multi-Time-Frame-Market","project":"Foundations","id":"6319139b-bbb9-4250-831c-e57d8f8575c7","savedPayload":{"position":{"x":18822.71875,"y":19418.592459690186},"targetPosition":{"x":18935.21875,"y":19223.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Execution Finished Event","name":"New Execution Finished Event","id":"1824fa00-dd30-4cdc-acc0-01c2f29056c5"}}},"executionFinishedEvent":{"type":"Execution Finished Event","name":"New Execution Finished Event","project":"Foundations","id":"adadc3e2-074c-4429-b3d7-84592d6fd73a","savedPayload":{"position":{"x":18740.3630341485,"y":19336.236743838686},"targetPosition":{"x":18935.21875,"y":19223.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},"id":"b2d41186-2875-4058-8949-8acd8e5e8218","savedPayload":{"position":{"x":18922.21875,"y":19236.736743838686},"targetPosition":{"x":18922.21875,"y":18786.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"products":[{"type":"Product Definition","name":"MFI","config":"{\n \"codeName\": \"MFI\",\n \"singularVariableName\": \"mfi\",\n \"pluralVariableName\": \"mfis\"\n}","project":"Foundations","datasets":[{"type":"Dataset Definition","name":"Multi-Time-Frame-Daily","config":"{\n \"codeName\": \"Multi-Time-Frame-Daily\",\n \"type\": \"Daily Files\",\n \"validTimeFrames\": [\n \"45-min\",\n \"40-min\",\n \"30-min\",\n \"20-min\",\n \"15-min\",\n \"10-min\",\n \"05-min\",\n \"04-min\",\n \"03-min\",\n \"02-min\",\n \"01-min\"\n ],\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset/@TimeFrame/@Year/@Month/@Day\",\n \"fileName\": \"Data.json\",\n \"dataRange\": {\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset\",\n \"fileName\": \"Data.Range.json\"\n },\n \"timeFrames\": {\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset\",\n \"fileName\": \"Time.Frames.json\"\n }\n}","project":"Foundations","id":"22edf2c6-b165-4b9e-b6ac-0cfefd9ee01b","savedPayload":{"position":{"x":18639.218453100108,"y":19327.164672006536},"targetPosition":{"x":18604.020698466054,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},{"type":"Dataset Definition","name":"Multi-Time-Frame-Market","config":"{\n \"codeName\": \"Multi-Time-Frame-Market\",\n \"type\": \"Market Files\",\n \"validTimeFrames\": [\n \"24-hs\",\n \"12-hs\",\n \"08-hs\",\n \"06-hs\",\n \"04-hs\",\n \"03-hs\",\n \"02-hs\",\n \"01-hs\"\n ],\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset/@TimeFrame\",\n \"fileName\": \"Data.json\",\n \"timeFrames\" : {\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset\",\n \"fileName\": \"Time.Frames.json\"\n }\n}","project":"Foundations","id":"f5f04930-c2a3-48b7-ade9-f98e148344f1","savedPayload":{"position":{"x":18501.872836024657,"y":19305.411263315014},"targetPosition":{"x":18604.020698466054,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}}],"record":{"type":"Record Definition","name":"New Record Definition","project":"Foundations","properties":[{"type":"Record Property","name":"Begin","config":"{\n \"codeName\": \"begin\",\n \"isString\": false\n}","project":"Foundations","recordFormula":{"type":"Record Formula","name":"Begin","code":"record.current.begin","project":"Foundations","id":"3e93fd4c-c8d1-46f2-9097-409c0ae93699","savedPayload":{"position":{"x":18133.538938846927,"y":19523.21823642184},"targetPosition":{"x":18168.303350714108,"y":19416.224378338633},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"c1daf05e-b41f-4b76-9a2c-ce190c623b86","savedPayload":{"position":{"x":18168.303350714108,"y":19416.224378338633},"targetPosition":{"x":18203.06776258129,"y":19309.230520255427},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Record Property","name":"End","config":"{\n \"codeName\": \"end\",\n \"isString\": false\n}","project":"Foundations","recordFormula":{"type":"Record Formula","code":"record.current.end","project":"Foundations","id":"453226d1-0bef-4df3-93ed-68c914f8c5b5","savedPayload":{"position":{"x":18002.591294638907,"y":19411.37838269683},"targetPosition":{"x":18102.8295286101,"y":19360.304451476128},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"6326c213-145f-42f5-beb9-30b0426208da","savedPayload":{"position":{"x":18102.8295286101,"y":19360.304451476128},"targetPosition":{"x":18203.06776258129,"y":19309.230520255427},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Record Property","name":"Value","config":"{\n \"codeName\": \"value\",\n \"isString\": false\n}","project":"Foundations","recordFormula":{"type":"Record Formula","code":"variable.value","project":"Foundations","id":"f88be3cc-cb81-43db-8ee9-5eab5dc3833d","savedPayload":{"position":{"x":17989.080046414878,"y":19239.701696521064},"targetPosition":{"x":18096.073904498084,"y":19274.466108388246},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"ed8d0a42-0423-4c07-95dd-2453f6e49b83","savedPayload":{"position":{"x":18096.073904498084,"y":19274.466108388246},"targetPosition":{"x":18203.06776258129,"y":19309.230520255427},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"42782833-c816-4069-9d20-55cea2597ac0","savedPayload":{"position":{"x":18203.06776258129,"y":19309.230520255427},"targetPosition":{"x":18604.020698466054,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"dataBuilding":{"type":"Data Building Procedure","name":"New Data Building Procedure","project":"Foundations","loop":{"type":"Procedure Loop","name":"New Procedure Loop","project":"Foundations","procedureJavascriptCode":{"type":"Procedure Javascript Code","name":"New Procedure Javascript Code","code":"/* Loop Code */\nlet candle = record.current // This is the primary dependency\nlet volume = getElement('volumes', candle) // Here I get the volume bar corresponding to the current candle\nlet totalVolume = volume.buy + volume.sell // Candles Volumes split the volume received from the exchange evenly betwen buy and sell because it does not know how much of it there is.\n\nlet hlc3 = (candle.max + candle.min + candle.close) / 3\nlet lastHlc3 = variable.lastHlc3\n\nif (record.previous !== undefined) {\n\n let change = hlc3 - variable.lastHlc3\n\n variable.last14U.push(totalVolume * (change <= 0 ? 0 : hlc3))\n variable.last14D.push(totalVolume * (change >= 0 ? 0 : hlc3))\n \n if (variable.last14U.length > 14) {\n variable.last14U.splice(0, 1) // Remove the first element of the array to keep it at a maximun of 14 elements.\n }\n \n if (variable.last14D.length > 14) {\n variable.last14D.splice(0, 1) // Remove the first element of the array to keep it at a maximun of 14 elements.\n }\n\n let upper = variable.last14U.reduce(function(a, b){return a + b;}, 0);\n let lower = variable.last14D.reduce(function(a, b){return a + b;}, 0);\n\n let mfi\n\n if(lower == 0)\n mfi = 100\n else if(upper == 0)\n mfi = 0\n else // RSI\n mfi = 100 - (100 / (1 + upper / lower))\n\n if (mfi !== undefined) {\n variable.value = mfi.toFixed(2)\n } else {\n variable.value = 0\n }\n\n/*\n // Printing values to console to check\n console.log(\"HLC3: \", hlc3)\n console.log(\"Last HLC3: \", lastHlc3)\n console.log(\"Change: \", change)\n console.log(\"Upper: \", upper)\n console.log(\"Lower: \", lower)\n console.log(\"MFI: \", mfi)\n */\n\n} else {\n variable.value = 0\n}\n\nvariable.lastHlc3 = hlc3","project":"Foundations","id":"086b666c-f4d1-4167-a103-76b9d3eddf5f","savedPayload":{"position":{"x":17319.33856135076,"y":19357.070440695297},"targetPosition":{"x":17739.4497532745,"y":19195.804863399913},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"f29a8156-18e0-48cf-b0ee-0d54a1296dc4","savedPayload":{"position":{"x":17739.4497532745,"y":19195.804863399913},"targetPosition":{"x":18159.560945198242,"y":19034.53928610453},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"initialization":{"type":"Procedure Initialization","name":"New Procedure Initialization","project":"Foundations","procedureJavascriptCode":{"type":"Procedure Javascript Code","name":"New Procedure Javascript Code","code":"/* Initialization Code*/\n\nvariable.lastHlc3 = 0\nvariable.last14U = []\nvariable.last14D = []\n","project":"Foundations","id":"0255406d-ebc4-4841-aeb2-69bf3783a328","savedPayload":{"position":{"x":17460.129579886965,"y":18468.150934159672},"targetPosition":{"x":17809.845262542603,"y":18751.3451101321},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"8e1fc1c7-4306-4151-b4e7-cd155b4d7218","savedPayload":{"position":{"x":17809.845262542603,"y":18751.3451101321},"targetPosition":{"x":18159.560945198242,"y":19034.53928610453},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"id":"7e8031b3-b8cb-43bd-8103-14e14e7be3a6","savedPayload":{"position":{"x":18159.560945198242,"y":19034.53928610453},"targetPosition":{"x":18604.020698466054,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"id":"019b29d1-0227-4185-aee7-aaba499cdf93","savedPayload":{"position":{"x":18604.020698466054,"y":19104.934795372632},"targetPosition":{"x":18922.21875,"y":18786.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Plotter Module","name":"MFI","id":"d10cdbe9-9416-490a-904e-ace49d0dfbf7"}}}],"id":"c43b88dc-4ad9-4321-976d-374f98e2434b","savedPayload":{"position":{"x":18922.21875,"y":18786.736743838686},"targetPosition":{"x":18922.21875,"y":18336.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"plotters":[{"type":"Plotter","name":"Relative Strenght Index - Wilder Method (RSI-W)","config":"{\n \"codeName\": \"Plotter RSI-W\"\n}","project":"Foundations","modules":[{"type":"Plotter Module","name":"RSI-W14","config":"{\n \"codeName\": \"RSI-W14\"\n}","project":"Foundations","panels":[{"type":"Plotter Panel","name":"RSI-W 14","config":"{\n \"codeName\": \"\"\n}","project":"Foundations","panelData":[{"type":"Panel Data","name":"RSI-W14","config":"{\n \"valueDecimals\": 2\n}","project":"Foundations","dataFormula":{"type":"Data Formula","name":"New Data Formula","code":"record.value","project":"Foundations","id":"e65f0b5b-4579-4584-b58b-897c7c9c7aad","savedPayload":{"position":{"x":17960.21875,"y":18323.736743838686},"targetPosition":{"x":18060.21875,"y":18323.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"b0a1f908-aad9-4e31-95b7-fecf08315b68","savedPayload":{"position":{"x":18060.21875,"y":18323.736743838686},"targetPosition":{"x":18160.21875,"y":18323.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"534848ee-8d03-4555-8370-1df9044d283f","savedPayload":{"position":{"x":18160.21875,"y":18323.736743838686},"targetPosition":{"x":18260.21875,"y":18323.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"4045dbb5-77d9-46ed-837d-e05caded1a29","savedPayload":{"position":{"x":18260.21875,"y":18323.736743838686},"targetPosition":{"x":18485.21875,"y":18323.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false,"shortcutKey":""}}}],"id":"31f1c7cf-fbde-446f-9921-793346e30c29","savedPayload":{"position":{"x":18472.21875,"y":18336.736743838686},"targetPosition":{"x":18922.21875,"y":18336.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Plotter","name":"Money Flow Index (MFI)","config":"{\n \"codeName\": \"Plotter MFI\"\n}","project":"Foundations","modules":[{"type":"Plotter Module","name":"MFI","config":"{ \n \"codeName\": \"Module-Name\", \n \"icon\": \"histogram|band|moving-average|oscillator|trend\"\n}","project":"Foundations","shapes":{"type":"Shapes","name":"New Shapes","project":"Foundations","chartPoints":[{"type":"Chart Points","name":"New Chart Points","project":"Foundations","points":[{"type":"Point","name":"New Point","project":"Foundations","pointFormula":{"type":"Point Formula","name":"New Point Formula","code":"x = record.begin\ny = record.property","project":"Foundations","id":"5e00d61b-c357-40dd-a0cf-a6d2fa76233d","savedPayload":{"position":{"x":18545.507318297008,"y":17873.736743838686},"targetPosition":{"x":18642.935176222756,"y":17817.486743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"a3fb852b-0aef-4518-a691-b6e9997a53e1","savedPayload":{"position":{"x":18642.935176222756,"y":17817.486743838686},"targetPosition":{"x":18740.363034148504,"y":17761.236743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"ca38b15d-e145-42c8-98a8-b0dbffc04720","savedPayload":{"position":{"x":18740.363034148504,"y":17761.236743838686},"targetPosition":{"x":18837.790892074252,"y":17704.986743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"polygons":[{"type":"Polygon","name":"New Polygon","project":"Foundations","polygonBody":{"type":"Polygon Body","name":"New Polygon Body","project":"Foundations","style":{"type":"Style","name":"New Style","config":" { \"default\": { \"opacity\": 0.2, \"lineWidth\": 1, \"lineDash\": [0,0], \"paletteColor\": \"UI_COLOR.DARK_TURQUOISE\" }, \"atMousePosition\": { \"opacity\": 0.3, \"lineWidth\": 2, \"lineDash\": [0,0], \"paletteColor\": \"UI_COLOR.RUSTED_RED\" }}","project":"Foundations","id":"bbc148c5-cfec-4cba-909c-29402cda8fb2","savedPayload":{"position":{"x":18612.790892074252,"y":17592.486743838686},"targetPosition":{"x":18725.290892074252,"y":17592.486743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"styleConditions":[],"id":"0d741cbf-553b-43e2-866c-414a637ac298","savedPayload":{"position":{"x":18725.290892074252,"y":17592.486743838686},"targetPosition":{"x":18837.790892074252,"y":17592.486743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"polygonBorder":{"type":"Polygon Border","name":"New Polygon Border","project":"Foundations","style":{"type":"Style","name":"New Style","config":" { \"default\": { \"opacity\": 0.2, \"lineWidth\": 1, \"lineDash\": [0,0], \"paletteColor\": \"UI_COLOR.DARK_TURQUOISE\" }, \"atMousePosition\": { \"opacity\": 0.3, \"lineWidth\": 2, \"lineDash\": [0,0], \"paletteColor\": \"UI_COLOR.RUSTED_RED\" }}","project":"Foundations","id":"06e0d64e-179d-4c28-a834-ac4cafba7147","savedPayload":{"position":{"x":18837.790892074252,"y":17367.486743838686},"targetPosition":{"x":18837.790892074252,"y":17479.986743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"styleConditions":[],"id":"da3b36a0-f339-4b35-b707-1e994704e0da","savedPayload":{"position":{"x":18837.790892074252,"y":17479.986743838686},"targetPosition":{"x":18837.790892074252,"y":17592.486743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"polygonVertexes":[{"type":"Polygon Vertex","name":"","project":"Foundations","id":"5ff95619-2158-48de-8c43-30a5009e4f47","savedPayload":{"position":{"x":18950.290892074252,"y":17592.486743838686},"targetPosition":{"x":18837.790892074252,"y":17592.486743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}}],"id":"915083b5-99cf-4abb-ac67-764bf1a9f26b","savedPayload":{"position":{"x":18837.790892074252,"y":17592.486743838686},"targetPosition":{"x":18837.790892074252,"y":17704.986743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"images":[],"texts":[],"id":"7afeb4e8-a789-4cfc-8394-a4253714891d","savedPayload":{"position":{"x":18837.790892074252,"y":17704.986743838686},"targetPosition":{"x":18935.21875,"y":17761.236743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"panels":[{"type":"Plotter Panel","name":"MFI","config":"{\n \"codeName\": \"\",\n \"isLegacy\": false\n}","project":"Foundations","panelData":[{"type":"Panel Data","name":"MFI","config":"{\n \"valueDecimals\": 2\n}","project":"Foundations","dataFormula":{"type":"Data Formula","name":"New Data Formula","code":"record.value","project":"Foundations","id":"53378fbb-eee0-4b7d-b771-ca2f9b813cde","savedPayload":{"position":{"x":19227.502323777244,"y":17592.486743838686},"targetPosition":{"x":19130.074465851496,"y":17648.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"8813ea4c-b38a-47f9-ae3e-d6c719246810","savedPayload":{"position":{"x":19130.074465851496,"y":17648.736743838686},"targetPosition":{"x":19032.646607925748,"y":17704.986743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"a4b4753e-e713-4bb2-9daa-cb7602e16e87","savedPayload":{"position":{"x":19032.646607925748,"y":17704.986743838686},"targetPosition":{"x":18935.21875,"y":17761.236743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"d10cdbe9-9416-490a-904e-ace49d0dfbf7","savedPayload":{"position":{"x":18935.21875,"y":17761.236743838686},"targetPosition":{"x":18935.21875,"y":17873.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"691c8481-d970-4eb0-a631-639bd1d53dd9","savedPayload":{"position":{"x":18922.21875,"y":17886.736743838686},"targetPosition":{"x":18922.21875,"y":18336.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"63655ecf-cd7d-4d65-a367-e976c00631d3","savedPayload":{"position":{"x":18922.21875,"y":18336.736743838686},"targetPosition":{"x":18922.21875,"y":18336.736743838686},"floatingObject":{"isPinned":true,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":4,"arrangementStyle":0},"uiObject":{"isRunning":false,"shortcutKey":"s"}}} \ No newline at end of file +{"type":"Data Mine","name":"Delta","config":"{\n \"codeName\": \"Delta\"\n}","project":"Foundations","sensorBots":[],"indicatorBots":[{"type":"Indicator Bot","name":"Relative Strength Index - Wilder Method (RSI-W)","config":"{\n \"codeName\": \"RSI-W\"\n}","project":"Foundations","processes":[{"type":"Process Definition","name":"Multi-Time-Frame-Market","config":"{\n \"codeName\": \"Multi-Time-Frame-Market\",\n \"description\": \"Calculates Wilder RSI.\",\n \"deadWaitTime\": 0,\n \"normalWaitTime\": 0,\n \"retryWaitTime\": 10000,\n \"sleepWaitTime\": 3600000,\n \"comaWaitTime\": 86400000,\n \"framework\": {\n \"name\": \"Multi-Time-Frame-Market\"\n }\n}","project":"Foundations","processOutput":{"type":"Process Output","name":"New Process Output","project":"Foundations","outputDatasets":[{"type":"Output Dataset","name":"Multi-Time-Frame-Market RSI-W14","project":"Foundations","id":"75881553-ec60-4954-9404-052ba11904f4","savedPayload":{"position":{"x":19646.18251638588,"y":17789.2053813897},"targetPosition":{"x":19675.299658959913,"y":17897.87203684722},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Market","id":"a94722c3-a453-4f46-931f-aeb244e7cb66"}}}],"outputDatasetFolders":[],"id":"ffb59a7e-565a-4588-bd44-999a7cb66122","savedPayload":{"position":{"x":19675.299658959913,"y":17897.87203684722},"targetPosition":{"x":19704.416801533946,"y":18006.53869230474},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"processDependencies":{"type":"Process Dependencies","name":"New Process Dependencies","project":"Foundations","statusDependencies":[{"type":"Status Dependency","name":"Candles Volumes Multi-Time-Frame-Market","config":"{\n \"mainUtility\": \"Market Ending Point\"\n}","project":"Foundations","id":"b0af9801-ba4e-4bfd-a605-98d9ac121b5f","savedPayload":{"position":{"x":19650.151086682014,"y":17594.3496655382},"targetPosition":{"x":19762.651086682014,"y":17789.2053813897},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"a0a61ba9-91cb-4ec7-92fe-134ff079de2d"}}},{"type":"Status Dependency","name":"Relative Strength Index - Wilder Method (RSI-W) Multi-Time-Frame-Market","config":"{\n \"mainUtility\": \"Self Reference\"\n}","project":"Foundations","id":"02d64b4a-7c3c-4c89-918d-b3697b5955b2","savedPayload":{"position":{"x":19820.88537183008,"y":17571.87207047466},"targetPosition":{"x":19762.651086682014,"y":17789.2053813897},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"2b961dac-9f41-4eed-a495-4e55f26714c3"}}}],"dataDependencies":[{"type":"Data Dependency","name":"Candles Multi-Time-Frame-Market","project":"Foundations","id":"25315413-2e01-4a7d-83bc-1257d43f8fe6","savedPayload":{"position":{"x":19957.506802533513,"y":17676.7053813897},"targetPosition":{"x":19762.651086682014,"y":17789.2053813897},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Market","id":"2b03494a-67d6-47f1-89b6-53fc4c9116a8"}}}],"dataMineDataDependencies":[],"id":"b14516a1-e5cc-48f8-ab0f-0e46faf6c41c","savedPayload":{"position":{"x":19762.651086682014,"y":17789.2053813897},"targetPosition":{"x":19704.416801533946,"y":18006.53869230474},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"statusReport":{"type":"Status Report","name":"New Status Report","project":"Foundations","id":"2b961dac-9f41-4eed-a495-4e55f26714c3","savedPayload":{"position":{"x":19863.51582730092,"y":17847.439666537768},"targetPosition":{"x":19704.416801533946,"y":18006.53869230474},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},"executionStartedEvent":{"type":"Execution Started Event","name":"Candles Volumes Multi-Time-Frame-Market","project":"Foundations","id":"c1598823-e0b3-4036-8ad6-669ae0e3f638","savedPayload":{"position":{"x":19921.750112448986,"y":17948.304407156673},"targetPosition":{"x":19704.416801533946,"y":18006.53869230474},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Execution Finished Event","name":"New Execution Finished Event","id":"1824fa00-dd30-4cdc-acc0-01c2f29056c5"}}},"executionFinishedEvent":{"type":"Execution Finished Event","name":"New Execution Finished Event","project":"Foundations","id":"b317c309-4677-4a2a-ba2a-801fccd01b1d","savedPayload":{"position":{"x":19921.750112448986,"y":18064.77297745281},"targetPosition":{"x":19704.416801533946,"y":18006.53869230474},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},"id":"279a9122-7f94-47b4-bf09-999fa889104b","savedPayload":{"position":{"x":19690.416801533946,"y":18018.53869230474},"targetPosition":{"x":19372.21875,"y":18336.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Process Definition","name":"Multi-Time-Frame-Daily","config":"{\n \"codeName\": \"Multi-Time-Frame-Daily\",\n \"description\": \"Calculates Wilder RSI\",\n \"deadWaitTime\": 0,\n \"normalWaitTime\": 0,\n \"retryWaitTime\": 10000,\n \"sleepWaitTime\": 3600000,\n \"comaWaitTime\": 86400000,\n \"framework\": {\n \"name\": \"Multi-Time-Frame-Daily\"\n }\n}","project":"Foundations","processOutput":{"type":"Process Output","name":"New Process Output","project":"Foundations","outputDatasets":[{"type":"Output Dataset","name":"Multi-Time-Frame-Daily RSI-W14","project":"Foundations","id":"a902a032-dbcc-4f7f-8495-70f0f5da03f8","savedPayload":{"position":{"x":19167.963077267068,"y":19583.111743838686},"targetPosition":{"x":19081.360536888624,"y":19533.111743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Daily","id":"f6e7a28d-d3d8-4d05-b90f-40bbe5f59b8a"}}}],"outputDatasetFolders":[],"id":"02da2e0b-9593-485a-ae0d-3f4ff131c813","savedPayload":{"position":{"x":19081.360536888624,"y":19533.111743838686},"targetPosition":{"x":18935.21875,"y":19448.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"processDependencies":{"type":"Process Dependencies","name":"New Process Dependencies","project":"Foundations","statusDependencies":[{"type":"Status Dependency","name":"Candles Volumes Multi-Time-Frame-Daily","config":"{\"mainUtility\": \"Market Ending Point\"}","project":"Foundations","id":"3173726e-99f5-4153-acbd-17e0ca4c6dac","savedPayload":{"position":{"x":19608.369889686794,"y":20068.582247746013},"targetPosition":{"x":19272.71875,"y":20033.30389139318},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"2a021da8-9feb-475e-90ab-1586968c17c7"}}},{"type":"Status Dependency","name":"Exchange Raw Data Historic-OHLCVs","config":"{\n \"mainUtility\": \"Market Starting Point\"\n}","project":"Foundations","id":"56d255fa-7193-431f-a3c5-f98e6d28a508","savedPayload":{"position":{"x":19523.53012859862,"y":20259.135471039295},"targetPosition":{"x":19272.71875,"y":20033.30389139318},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"181c7c34-7243-497a-9ddb-1b0067c6d66e"}}},{"type":"Status Dependency","name":"Relative Strength Index - Wilder Method (RSI-W) Multi-Time-Frame-Daily","config":"{\n \"mainUtility\": \"Self Reference\"\n}","project":"Foundations","id":"b96ab1d1-3bdc-429d-921a-0aab94741d29","savedPayload":{"position":{"x":19342.888945650993,"y":20363.42870664084},"targetPosition":{"x":19272.71875,"y":20033.30389139318},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"8c1c40cf-dd93-4f61-b3f0-9344707b196d"}}}],"dataDependencies":[{"type":"Data Dependency","name":"Candles Multi-Time-Frame-Daily","project":"Foundations","id":"756f850b-7e37-4fc8-8031-b7c8458bc8c3","savedPayload":{"position":{"x":19135.44513296192,"y":20341.625483347558},"targetPosition":{"x":19272.71875,"y":20033.30389139318},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Daily","id":"678a567c-f08d-49b9-813b-4e54fd6afadb"}}}],"dataMineDataDependencies":[],"id":"c42ac621-a7d7-499a-84a0-76bd99ef3fa4","savedPayload":{"position":{"x":19272.71875,"y":20033.30389139318},"targetPosition":{"x":18935.21875,"y":19448.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"statusReport":{"type":"Status Report","name":"New Status Report","project":"Foundations","id":"8c1c40cf-dd93-4f61-b3f0-9344707b196d","savedPayload":{"position":{"x":18935.21875,"y":19786.236743838686},"targetPosition":{"x":18935.21875,"y":19448.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},"executionStartedEvent":{"type":"Execution Started Event","name":"Candles Volumes Multi-Time-Frame-Daily","project":"Foundations","id":"1bf32fba-af6a-43eb-b0bb-2ac855bb5820","savedPayload":{"position":{"x":18766.46875,"y":19741.020317615934},"targetPosition":{"x":18935.21875,"y":19448.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Execution Finished Event","name":"New Execution Finished Event","id":"f29d08f9-e7c8-490c-8fca-14851a0d3dc3"}}},"executionFinishedEvent":{"type":"Execution Finished Event","name":"New Execution Finished Event","project":"Foundations","id":"ffcd3bc1-44f3-4e21-9f33-fc2f818494b5","savedPayload":{"position":{"x":18642.935176222752,"y":19617.486743838686},"targetPosition":{"x":18935.21875,"y":19448.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},"id":"a5c6c183-7b68-4e7c-82c2-27ac439b098d","savedPayload":{"position":{"x":20047.21875,"y":18336.736743838686},"targetPosition":{"x":19372.21875,"y":18336.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":4,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"products":[{"type":"Product Definition","name":"RSI-W14","config":"{\n \"codeName\": \"RSI-W14\",\n \"singularVariableName\": \"rsiw14\",\n \"pluralVariableName\": \"rsiw14s\"\n}","project":"Foundations","datasets":[{"type":"Dataset Definition","name":"Multi-Time-Frame-Daily","config":"{\n \"codeName\": \"Multi-Time-Frame-Daily\",\n \"type\": \"Daily Files\",\n \"validTimeFrames\": [\n \"45-min\",\n \"40-min\",\n \"30-min\",\n \"20-min\",\n \"15-min\",\n \"10-min\",\n \"05-min\",\n \"04-min\",\n \"03-min\",\n \"02-min\",\n \"01-min\"\n ],\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset/@TimeFrame/@Year/@Month/@Day\",\n \"fileName\": \"Data.json\",\n \"dataRange\": {\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset\",\n \"fileName\": \"Data.Range.json\"\n },\n \"timeFrames\": {\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset\",\n \"fileName\": \"Time.Frames.json\"\n }\n}","project":"Foundations","id":"f6e7a28d-d3d8-4d05-b90f-40bbe5f59b8a","savedPayload":{"position":{"x":19912.64667816785,"y":18619.73704073858},"targetPosition":{"x":19690.416801533946,"y":18654.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},{"type":"Dataset Definition","name":"Multi-Time-Frame-Market","config":"{\n \"codeName\": \"Multi-Time-Frame-Market\",\n \"type\": \"Market Files\",\n \"validTimeFrames\": [\n \"24-hs\",\n \"12-hs\",\n \"08-hs\",\n \"06-hs\",\n \"04-hs\",\n \"03-hs\",\n \"02-hs\",\n \"01-hs\"\n ],\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset/@TimeFrame\",\n \"fileName\": \"Data.json\",\n \"timeFrames\" : {\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset\",\n \"fileName\": \"Time.Frames.json\"\n }\n}","project":"Foundations","id":"a94722c3-a453-4f46-931f-aeb244e7cb66","savedPayload":{"position":{"x":19890.893269476328,"y":18757.08265781403},"targetPosition":{"x":19690.416801533946,"y":18654.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}}],"record":{"type":"Record Definition","name":"New Record Definition","project":"Foundations","properties":[{"type":"Record Property","name":"Begin","config":"{\n \"codeName\": \"begin\",\n \"isString\": false\n}","project":"Foundations","recordFormula":{"type":"Record Formula","name":"Begin","code":"record.current.begin","project":"Foundations","id":"5f2981e4-5b9a-4867-9bf4-79dd2b9c19f0","savedPayload":{"position":{"x":20108.700242583152,"y":19125.41655499176},"targetPosition":{"x":20001.706384499947,"y":19090.65214312458},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"a7c379ea-fc2f-4526-9a5f-fcdc272f6a02","savedPayload":{"position":{"x":20001.706384499947,"y":19090.65214312458},"targetPosition":{"x":19894.71252641674,"y":19055.887731257397},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Record Property","name":"End","config":"{\n \"codeName\": \"end\",\n \"isString\": false\n}","project":"Foundations","recordFormula":{"type":"Record Formula","code":"record.current.end","project":"Foundations","id":"ad4e0d6b-e7ce-4e09-88a6-a3f44d7c0c08","savedPayload":{"position":{"x":19996.860388858142,"y":19256.36419919978},"targetPosition":{"x":19945.78645763744,"y":19156.125965228588},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"a859a2ce-cd0a-43ae-995b-6140402a9f1a","savedPayload":{"position":{"x":19945.78645763744,"y":19156.125965228588},"targetPosition":{"x":19894.71252641674,"y":19055.887731257397},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Record Property","name":"Value","config":"{\n \"codeName\": \"value\",\n \"isString\": false\n}","project":"Foundations","recordFormula":{"type":"Record Formula","code":"variable.value","project":"Foundations","id":"43595088-af8f-4ad5-8bfe-3b04a5168681","savedPayload":{"position":{"x":19825.183702682378,"y":19269.87544742381},"targetPosition":{"x":19859.94811454956,"y":19162.881589340603},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"3cd01f28-dd1a-45bc-8c68-29bdbf4be84b","savedPayload":{"position":{"x":19859.94811454956,"y":19162.881589340603},"targetPosition":{"x":19894.71252641674,"y":19055.887731257397},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"ee7e6fb0-984c-410b-9ba7-241deddcd7ad","savedPayload":{"position":{"x":19894.71252641674,"y":19055.887731257397},"targetPosition":{"x":19690.416801533946,"y":18654.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"dataBuilding":{"type":"Data Building Procedure","name":"New Data Building Procedure","project":"Foundations","loop":{"type":"Procedure Loop","name":"New Procedure Loop","project":"Foundations","procedureJavascriptCode":{"type":"Procedure Javascript Code","code":"/* Loop Code */\n\n/* \nCalculation method credit: https://www.macroption.com/rsi-calculation/\n*/\n\n/* Calculating Up Moves and Down Moves */\n\n//let candle = record.current // Our main dependencies are candles \n//let candlePrevious = record.previous\n\nif (record.previous !== undefined) {\n if (record.current.close > record.previous.close) {\n variable.last14U.push(record.current.close - record.previous.close) // Add win to last 14 array.\n } else {\n variable.last14U.push(0) // Add 0 to keep proper count of records in the last 14 array.\n }\n \n if (record.current.close < record.previous.close) {\n variable.last14D.push(record.previous.close - record.current.close) // Add win to last 14 array.\n } else {\n variable.last14D.push(0) // Add 0 to keep proper count of records in the last 14 array.\n }\n \n if (variable.last14U.length > 14) {\n variable.last14U.splice(0, 1) // Remove the first element of the array to keep it at a maximun of 14 elements.\n }\n \n if (variable.last14D.length > 14) {\n variable.last14D.splice(0, 1) // Remove the first element of the array to keep it at a maximun of 14 elements.\n }\n \n /* Calculating Averages of Up Moves and Down Moves */\n\n variable.avgU = calculateRMAU(14)\n variable.avgD = calculateRMAD(14)\n\n /* Keep track of average moves */\n variable.rma14U.push(variable.avgU)\n variable.rma14D.push(variable.avgD)\n \n if (variable.rma14U.length > 14) {\n variable.rma14U.splice(0, 1) // Remove the first element of the array to keep it at a maximun of 14 elements.\n }\n \n if (variable.rma14D.length > 14) {\n variable.rma14D.splice(0, 1) // Remove the first element of the array to keep it at a maximun of 14 elements.\n }\n\n /* Calculating Relative Strength */\n \n if (variable.avgD > 0) {\n relativeStrength = variable.avgU / variable.avgD\n } else {\n relativeStrength = 0\n }\n\n /* Calculating RSI */\n\n relativeStrengthIndex = 100 - 100 / ( 1 + relativeStrength)\n\n if (relativeStrengthIndex !== undefined) {\n variable.value = relativeStrengthIndex.toFixed(2)\n } else {\n variable.value = 0\n }\n} else {\n variable.value = 0\n}\n\n// Statistics\n\nfunction calculateWMA(source, rmas, periods) { // Having a function avoids us to repeat code.\n /* We check we have enough values to make the calculation */\n if (source.length < periods) { return 0 } // If we dont, we define the value is zero.\n\n let alpha = 1 / periods\n let avg = source[source.length - 1] * alpha + rmas[rmas.length - 1] * (1 - alpha)\n return avg;\n}\n\nfunction calculateRMAU(periods) {\n return calculateWMA(variable.last14U, variable.rma14U, periods)\n}\n\nfunction calculateRMAD(periods) {\n return calculateWMA(variable.last14D, variable.rma14D, periods)\n}","project":"Foundations","id":"91eb76f0-617c-4397-9135-beca294a6481","savedPayload":{"position":{"x":19781.28686956123,"y":19519.505740564182},"targetPosition":{"x":19700.654080913537,"y":19309.450144602313},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"6957916d-b353-4b19-8b8f-cf7fb97024b3","savedPayload":{"position":{"x":19700.654080913537,"y":19309.450144602313},"targetPosition":{"x":19620.021292265843,"y":19099.394548640445},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"initialization":{"type":"Procedure Initialization","name":"New Procedure Initialization","project":"Foundations","procedureJavascriptCode":{"type":"Procedure Javascript Code","code":"/* Initialization Code*/\n\n/* \nWe keep two separate arrays to store last 14 price increments or losses.\n*/\n\nvariable.last14U = []\nvariable.last14D = []\nvariable.rma14U = []\nvariable.rma14D = []\n","project":"Foundations","id":"7b8d4dd2-2dde-47fe-8340-efd0f93fe435","savedPayload":{"position":{"x":19336.827116293414,"y":19449.110231296083},"targetPosition":{"x":19478.42420427963,"y":19274.252389968264},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"076ef281-1c67-4117-8168-a5beba487ffc","savedPayload":{"position":{"x":19478.42420427963,"y":19274.252389968264},"targetPosition":{"x":19620.021292265843,"y":19099.394548640445},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"id":"a1ef81d6-c2c9-46c4-aaed-366b31b2d639","savedPayload":{"position":{"x":19620.021292265843,"y":19099.394548640445},"targetPosition":{"x":19690.416801533946,"y":18654.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"id":"fbe3d4ba-bcfd-4cb1-91d1-64d7d381a21c","savedPayload":{"position":{"x":19690.416801533946,"y":18654.934795372632},"targetPosition":{"x":19372.21875,"y":18336.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Plotter Module","name":"RSI-W14","id":"4045dbb5-77d9-46ed-837d-e05caded1a29"}}}],"id":"1b49e818-f9f9-4ecc-bdbd-708f5641fb66","savedPayload":{"position":{"x":19372.21875,"y":18336.736743838686},"targetPosition":{"x":18922.21875,"y":18336.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Indicator Bot","name":"Money Flow Index (MFI)","config":"{\n \"codeName\": \"MFI\"\n}","project":"Foundations","processes":[{"type":"Process Definition","name":"Multi-Time-Frame-Daily","config":"{\n \"codeName\": \"Multi-Time-Frame-Daily\",\n \"description\": \"Calculates MFI\",\n \"deadWaitTime\": 0,\n \"normalWaitTime\": 0,\n \"retryWaitTime\": 10000,\n \"sleepWaitTime\": 3600000,\n \"comaWaitTime\": 86400000,\n \"framework\": {\n \"name\": \"Multi-Time-Frame-Daily\"\n }\n}","project":"Foundations","processOutput":{"type":"Process Output","name":"New Process Output","project":"Foundations","outputDatasets":[{"type":"Output Dataset","name":"Multi-Time-Frame-Daily MFI","project":"Foundations","id":"48a07111-4122-4d5c-a3ef-df4b138b6af7","savedPayload":{"position":{"x":19445.67603962037,"y":19049.935748288346},"targetPosition":{"x":19349.083456991466,"y":19075.8176527986},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Daily","id":"22edf2c6-b165-4b9e-b6ac-0cfefd9ee01b"}}}],"outputDatasetFolders":[],"id":"3c9355dd-ecf6-4604-b7f7-f6f1f8e784d6","savedPayload":{"position":{"x":19349.083456991466,"y":19075.8176527986},"targetPosition":{"x":19240.416801533946,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"processDependencies":{"type":"Process Dependencies","name":"New Process Dependencies","project":"Foundations","statusDependencies":[{"type":"Status Dependency","name":"Candles Volumes Multi-Time-Frame-Daily","config":"{\"mainUtility\": \"Market Ending Point\"}","project":"Foundations","id":"7867d355-9cd6-434e-90de-cd1f5f9ba32a","savedPayload":{"position":{"x":19537.299625332475,"y":19083.61956763721},"targetPosition":{"x":19457.750112448986,"y":19163.1690805207},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"2a021da8-9feb-475e-90ab-1586968c17c7"}}},{"type":"Status Dependency","name":"Exchange Raw Data Historic-OHLCVs","config":"{\n \"mainUtility\": \"Market Starting Point\"\n}","project":"Foundations","id":"bdf2cbd7-2cd6-4945-96b3-0609b3969d37","savedPayload":{"position":{"x":19566.416767906507,"y":19134.051937946668},"targetPosition":{"x":19457.750112448986,"y":19163.1690805207},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"181c7c34-7243-497a-9ddb-1b0067c6d66e"}}},{"type":"Status Dependency","name":"Money Flow Index (MFI) Multi-Time-Frame-Daily","config":"{\n \"mainUtility\": \"Self Reference\"\n}","project":"Foundations","id":"25380d29-c370-4b34-bcb6-55d94cab4a11","savedPayload":{"position":{"x":19566.416767906507,"y":19192.286223094732},"targetPosition":{"x":19457.750112448986,"y":19163.1690805207},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"218ce270-08fe-45a0-90ef-7189fffd72dd"}}}],"dataDependencies":[{"type":"Data Dependency","name":"Candles Multi-Time-Frame-Daily","project":"Foundations","id":"afdb16be-1eba-4ab0-aceb-9695b25ef435","savedPayload":{"position":{"x":19537.299625332475,"y":19242.718593404188},"targetPosition":{"x":19457.750112448986,"y":19163.1690805207},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Daily","id":"678a567c-f08d-49b9-813b-4e54fd6afadb"}}},{"type":"Data Dependency","name":"Volumes Multi-Time-Frame-Daily","project":"Foundations","id":"f26fa862-f8e1-480b-b9a3-fb8e001e3b8d","savedPayload":{"position":{"x":19486.86725502302,"y":19271.83573597822},"targetPosition":{"x":19457.750112448986,"y":19163.1690805207},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Daily","id":"2e683057-f911-4105-bc77-16f2706d1915"}}}],"dataMineDataDependencies":[],"id":"4704cf1b-133a-4e6e-8b97-bfece022354e","savedPayload":{"position":{"x":19457.750112448986,"y":19163.1690805207},"targetPosition":{"x":19240.416801533946,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"statusReport":{"type":"Status Report","name":"New Status Report","project":"Foundations","id":"218ce270-08fe-45a0-90ef-7189fffd72dd","savedPayload":{"position":{"x":19399.51582730092,"y":19264.033821139605},"targetPosition":{"x":19240.416801533946,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},"executionStartedEvent":{"type":"Execution Started Event","name":"Candles Volumes Multi-Time-Frame-Daily","project":"Foundations","id":"30fcca1f-f72d-46cf-bd17-99f8e2e1cd10","savedPayload":{"position":{"x":19298.651086682014,"y":19322.268106287673},"targetPosition":{"x":19240.416801533946,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Execution Finished Event","name":"New Execution Finished Event","id":"f29d08f9-e7c8-490c-8fca-14851a0d3dc3"}}},"executionFinishedEvent":{"type":"Execution Finished Event","name":"New Execution Finished Event","project":"Foundations","id":"91f10f62-3cad-4709-8b90-31daceb01bd2","savedPayload":{"position":{"x":19182.182516385878,"y":19322.268106287673},"targetPosition":{"x":19240.416801533946,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},"id":"6be015e8-abd8-4c91-bc44-ed0dbe4401bf","savedPayload":{"position":{"x":19240.416801533946,"y":19104.934795372632},"targetPosition":{"x":18922.21875,"y":18786.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Process Definition","name":"Multi-Time-Frame-Market","config":"{\n \"codeName\": \"Multi-Time-Frame-Market\",\n \"description\": \"Calculates MFI.\",\n \"deadWaitTime\": 0,\n \"normalWaitTime\": 0,\n \"retryWaitTime\": 10000,\n \"sleepWaitTime\": 3600000,\n \"comaWaitTime\": 86400000,\n \"framework\": {\n \"name\": \"Multi-Time-Frame-Market\"\n }\n}","project":"Foundations","processOutput":{"type":"Process Output","name":"New Process Output","project":"Foundations","outputDatasets":[{"type":"Output Dataset","name":"Multi-Time-Frame-Market MFI","project":"Foundations","id":"c5c02f93-dacc-4e97-803b-45f1d3d7756c","savedPayload":{"position":{"x":19130.074465851496,"y":19336.236743838686},"targetPosition":{"x":19032.646607925748,"y":19279.986743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Market","id":"f5f04930-c2a3-48b7-ade9-f98e148344f1"}}}],"outputDatasetFolders":[],"id":"a78ac5ae-14c4-4928-968b-604d5c78521c","savedPayload":{"position":{"x":19032.646607925748,"y":19279.986743838686},"targetPosition":{"x":18935.21875,"y":19223.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"processDependencies":{"type":"Process Dependencies","name":"New Process Dependencies","project":"Foundations","statusDependencies":[{"type":"Status Dependency","name":"Candles Volumes Multi-Time-Frame-Market","config":"{\n \"mainUtility\": \"Market Ending Point\"\n}","project":"Foundations","id":"226234a8-bb22-4f31-9446-ffee286446b4","savedPayload":{"position":{"x":19271.48617645786,"y":19442.111363925407},"targetPosition":{"x":19047.71875,"y":19418.592459690186},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"a0a61ba9-91cb-4ec7-92fe-134ff079de2d"}}},{"type":"Status Dependency","name":"Money Flow Index (MFI) Multi-Time-Frame-Market","config":"{\n \"mainUtility\": \"Self Reference\"\n}","project":"Foundations","id":"319ba4b4-77dc-412f-be3f-6fdb088f317c","savedPayload":{"position":{"x":19214.926335732413,"y":19569.14684612093},"targetPosition":{"x":19047.71875,"y":19418.592459690186},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"f4b09884-97e4-44e6-b0cf-3025c4cc44f9"}}}],"dataDependencies":[{"type":"Data Dependency","name":"Candles Multi-Time-Frame-Market","project":"Foundations","id":"39802ca4-ee03-42f3-a5a4-e805f787520b","savedPayload":{"position":{"x":19094.498880433996,"y":19638.675669855293},"targetPosition":{"x":19047.71875,"y":19418.592459690186},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Market","id":"2b03494a-67d6-47f1-89b6-53fc4c9116a8"}}},{"type":"Data Dependency","name":"Volumes Multi-Time-Frame-Market","project":"Foundations","id":"9580ee4c-eb61-4133-91be-b9b8065cc74e","savedPayload":{"position":{"x":18956.203005307943,"y":19624.14018765977},"targetPosition":{"x":19047.71875,"y":19418.592459690186},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Time-Frame-Market","id":"9bf0483c-4825-4a46-9cf4-1b5262579fc1"}}}],"dataMineDataDependencies":[],"id":"871fab7f-2e97-4a8a-a771-0f4769c7b82d","savedPayload":{"position":{"x":19047.71875,"y":19418.592459690186},"targetPosition":{"x":18935.21875,"y":19223.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"statusReport":{"type":"Status Report","name":"New Status Report","project":"Foundations","id":"f4b09884-97e4-44e6-b0cf-3025c4cc44f9","savedPayload":{"position":{"x":18935.21875,"y":19448.736743838686},"targetPosition":{"x":18935.21875,"y":19223.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},"executionStartedEvent":{"type":"Execution Started Event","name":"Candles Volumes Multi-Time-Frame-Market","project":"Foundations","id":"6319139b-bbb9-4250-831c-e57d8f8575c7","savedPayload":{"position":{"x":18822.71875,"y":19418.592459690186},"targetPosition":{"x":18935.21875,"y":19223.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Execution Finished Event","name":"New Execution Finished Event","id":"1824fa00-dd30-4cdc-acc0-01c2f29056c5"}}},"executionFinishedEvent":{"type":"Execution Finished Event","name":"New Execution Finished Event","project":"Foundations","id":"adadc3e2-074c-4429-b3d7-84592d6fd73a","savedPayload":{"position":{"x":18740.3630341485,"y":19336.236743838686},"targetPosition":{"x":18935.21875,"y":19223.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},"id":"b2d41186-2875-4058-8949-8acd8e5e8218","savedPayload":{"position":{"x":18922.21875,"y":19236.736743838686},"targetPosition":{"x":18922.21875,"y":18786.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"products":[{"type":"Product Definition","name":"MFI","config":"{\n \"codeName\": \"MFI\",\n \"singularVariableName\": \"mfi\",\n \"pluralVariableName\": \"mfis\"\n}","project":"Foundations","datasets":[{"type":"Dataset Definition","name":"Multi-Time-Frame-Daily","config":"{\n \"codeName\": \"Multi-Time-Frame-Daily\",\n \"type\": \"Daily Files\",\n \"validTimeFrames\": [\n \"45-min\",\n \"40-min\",\n \"30-min\",\n \"20-min\",\n \"15-min\",\n \"10-min\",\n \"05-min\",\n \"04-min\",\n \"03-min\",\n \"02-min\",\n \"01-min\"\n ],\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset/@TimeFrame/@Year/@Month/@Day\",\n \"fileName\": \"Data.json\",\n \"dataRange\": {\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset\",\n \"fileName\": \"Data.Range.json\"\n },\n \"timeFrames\": {\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset\",\n \"fileName\": \"Time.Frames.json\"\n }\n}","project":"Foundations","id":"22edf2c6-b165-4b9e-b6ac-0cfefd9ee01b","savedPayload":{"position":{"x":18639.218453100108,"y":19327.164672006536},"targetPosition":{"x":18604.020698466054,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}},{"type":"Dataset Definition","name":"Multi-Time-Frame-Market","config":"{\n \"codeName\": \"Multi-Time-Frame-Market\",\n \"type\": \"Market Files\",\n \"validTimeFrames\": [\n \"24-hs\",\n \"12-hs\",\n \"08-hs\",\n \"06-hs\",\n \"04-hs\",\n \"03-hs\",\n \"02-hs\",\n \"01-hs\"\n ],\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset/@TimeFrame\",\n \"fileName\": \"Data.json\",\n \"timeFrames\" : {\n \"filePath\": \"Project/@Project/@MineType/@Mine/@Bot/@Exchange/@BaseAsset-@QuotedAsset/Output/@Product/@Dataset\",\n \"fileName\": \"Time.Frames.json\"\n }\n}","project":"Foundations","id":"f5f04930-c2a3-48b7-ade9-f98e148344f1","savedPayload":{"position":{"x":18501.872836024657,"y":19305.411263315014},"targetPosition":{"x":18604.020698466054,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}}],"record":{"type":"Record Definition","name":"New Record Definition","project":"Foundations","properties":[{"type":"Record Property","name":"Begin","config":"{\n \"codeName\": \"begin\",\n \"isString\": false\n}","project":"Foundations","recordFormula":{"type":"Record Formula","name":"Begin","code":"record.current.begin","project":"Foundations","id":"3e93fd4c-c8d1-46f2-9097-409c0ae93699","savedPayload":{"position":{"x":18133.538938846927,"y":19523.21823642184},"targetPosition":{"x":18168.303350714108,"y":19416.224378338633},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"c1daf05e-b41f-4b76-9a2c-ce190c623b86","savedPayload":{"position":{"x":18168.303350714108,"y":19416.224378338633},"targetPosition":{"x":18203.06776258129,"y":19309.230520255427},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Record Property","name":"End","config":"{\n \"codeName\": \"end\",\n \"isString\": false\n}","project":"Foundations","recordFormula":{"type":"Record Formula","code":"record.current.end","project":"Foundations","id":"453226d1-0bef-4df3-93ed-68c914f8c5b5","savedPayload":{"position":{"x":18002.591294638907,"y":19411.37838269683},"targetPosition":{"x":18102.8295286101,"y":19360.304451476128},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"6326c213-145f-42f5-beb9-30b0426208da","savedPayload":{"position":{"x":18102.8295286101,"y":19360.304451476128},"targetPosition":{"x":18203.06776258129,"y":19309.230520255427},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Record Property","name":"Value","config":"{\n \"codeName\": \"value\",\n \"isString\": false\n}","project":"Foundations","recordFormula":{"type":"Record Formula","code":"variable.value","project":"Foundations","id":"f88be3cc-cb81-43db-8ee9-5eab5dc3833d","savedPayload":{"position":{"x":17989.080046414878,"y":19239.701696521064},"targetPosition":{"x":18096.073904498084,"y":19274.466108388246},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"ed8d0a42-0423-4c07-95dd-2453f6e49b83","savedPayload":{"position":{"x":18096.073904498084,"y":19274.466108388246},"targetPosition":{"x":18203.06776258129,"y":19309.230520255427},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"42782833-c816-4069-9d20-55cea2597ac0","savedPayload":{"position":{"x":18203.06776258129,"y":19309.230520255427},"targetPosition":{"x":18604.020698466054,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"dataBuilding":{"type":"Data Building Procedure","name":"New Data Building Procedure","project":"Foundations","loop":{"type":"Procedure Loop","name":"New Procedure Loop","project":"Foundations","procedureJavascriptCode":{"type":"Procedure Javascript Code","name":"New Procedure Javascript Code","code":"/* Loop Code */\nlet candle = record.current // This is the primary dependency\nlet volume = getElement('volumes', candle) // Here I get the volume bar corresponding to the current candle\nlet totalVolume = volume.buy + volume.sell // Candles Volumes split the volume received from the exchange evenly betwen buy and sell because it does not know how much of it there is.\n\nlet hlc3 = (candle.max + candle.min + candle.close) / 3\nlet lastHlc3 = variable.lastHlc3\n\nif (record.previous !== undefined) {\n\n let change = hlc3 - variable.lastHlc3\n\n variable.last14U.push(totalVolume * (change <= 0 ? 0 : hlc3))\n variable.last14D.push(totalVolume * (change >= 0 ? 0 : hlc3))\n \n if (variable.last14U.length > 14) {\n variable.last14U.splice(0, 1) // Remove the first element of the array to keep it at a maximun of 14 elements.\n }\n \n if (variable.last14D.length > 14) {\n variable.last14D.splice(0, 1) // Remove the first element of the array to keep it at a maximun of 14 elements.\n }\n\n let upper = variable.last14U.reduce(function(a, b){return a + b;}, 0);\n let lower = variable.last14D.reduce(function(a, b){return a + b;}, 0);\n\n let mfi\n\n if(lower == 0)\n mfi = 100\n else if(upper == 0)\n mfi = 0\n else // RSI\n mfi = 100 - (100 / (1 + upper / lower))\n\n if (mfi !== undefined) {\n variable.value = mfi.toFixed(2)\n } else {\n variable.value = 0\n }\n\n/*\n // Printing values to console to check\n console.log(\"HLC3: \", hlc3)\n console.log(\"Last HLC3: \", lastHlc3)\n console.log(\"Change: \", change)\n console.log(\"Upper: \", upper)\n console.log(\"Lower: \", lower)\n console.log(\"MFI: \", mfi)\n */\n\n} else {\n variable.value = 0\n}\n\nvariable.lastHlc3 = hlc3","project":"Foundations","id":"086b666c-f4d1-4167-a103-76b9d3eddf5f","savedPayload":{"position":{"x":17319.33856135076,"y":19357.070440695297},"targetPosition":{"x":17739.4497532745,"y":19195.804863399913},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"f29a8156-18e0-48cf-b0ee-0d54a1296dc4","savedPayload":{"position":{"x":17739.4497532745,"y":19195.804863399913},"targetPosition":{"x":18159.560945198242,"y":19034.53928610453},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"initialization":{"type":"Procedure Initialization","name":"New Procedure Initialization","project":"Foundations","procedureJavascriptCode":{"type":"Procedure Javascript Code","name":"New Procedure Javascript Code","code":"/* Initialization Code*/\n\nvariable.lastHlc3 = 0\nvariable.last14U = []\nvariable.last14D = []\n","project":"Foundations","id":"0255406d-ebc4-4841-aeb2-69bf3783a328","savedPayload":{"position":{"x":17460.129579886965,"y":18468.150934159672},"targetPosition":{"x":17809.845262542603,"y":18751.3451101321},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"8e1fc1c7-4306-4151-b4e7-cd155b4d7218","savedPayload":{"position":{"x":17809.845262542603,"y":18751.3451101321},"targetPosition":{"x":18159.560945198242,"y":19034.53928610453},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"id":"7e8031b3-b8cb-43bd-8103-14e14e7be3a6","savedPayload":{"position":{"x":18159.560945198242,"y":19034.53928610453},"targetPosition":{"x":18604.020698466054,"y":19104.934795372632},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"id":"019b29d1-0227-4185-aee7-aaba499cdf93","savedPayload":{"position":{"x":18604.020698466054,"y":19104.934795372632},"targetPosition":{"x":18922.21875,"y":18786.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"referenceParent":{"type":"Plotter Module","name":"MFI","id":"d10cdbe9-9416-490a-904e-ace49d0dfbf7"}}}],"id":"c43b88dc-4ad9-4321-976d-374f98e2434b","savedPayload":{"position":{"x":18922.21875,"y":18786.736743838686},"targetPosition":{"x":18922.21875,"y":18336.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"plotters":[{"type":"Plotter","name":"Relative Strength Index - Wilder Method (RSI-W)","config":"{\n \"codeName\": \"Plotter RSI-W\"\n}","project":"Foundations","modules":[{"type":"Plotter Module","name":"RSI-W14","config":"{\n \"codeName\": \"RSI-W14\"\n}","project":"Foundations","panels":[{"type":"Plotter Panel","name":"RSI-W 14","config":"{\n \"codeName\": \"\"\n}","project":"Foundations","panelData":[{"type":"Panel Data","name":"RSI-W14","config":"{\n \"valueDecimals\": 2\n}","project":"Foundations","dataFormula":{"type":"Data Formula","name":"New Data Formula","code":"record.value","project":"Foundations","id":"e65f0b5b-4579-4584-b58b-897c7c9c7aad","savedPayload":{"position":{"x":17960.21875,"y":18323.736743838686},"targetPosition":{"x":18060.21875,"y":18323.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"b0a1f908-aad9-4e31-95b7-fecf08315b68","savedPayload":{"position":{"x":18060.21875,"y":18323.736743838686},"targetPosition":{"x":18160.21875,"y":18323.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"534848ee-8d03-4555-8370-1df9044d283f","savedPayload":{"position":{"x":18160.21875,"y":18323.736743838686},"targetPosition":{"x":18260.21875,"y":18323.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"4045dbb5-77d9-46ed-837d-e05caded1a29","savedPayload":{"position":{"x":18260.21875,"y":18323.736743838686},"targetPosition":{"x":18485.21875,"y":18323.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":2,"arrangementStyle":0},"uiObject":{"isRunning":false,"shortcutKey":""}}}],"id":"31f1c7cf-fbde-446f-9921-793346e30c29","savedPayload":{"position":{"x":18472.21875,"y":18336.736743838686},"targetPosition":{"x":18922.21875,"y":18336.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Plotter","name":"Money Flow Index (MFI)","config":"{\n \"codeName\": \"Plotter MFI\"\n}","project":"Foundations","modules":[{"type":"Plotter Module","name":"MFI","config":"{ \n \"codeName\": \"Module-Name\", \n \"icon\": \"histogram|band|moving-average|oscillator|trend\"\n}","project":"Foundations","shapes":{"type":"Shapes","name":"New Shapes","project":"Foundations","chartPoints":[{"type":"Chart Points","name":"New Chart Points","project":"Foundations","points":[{"type":"Point","name":"New Point","project":"Foundations","pointFormula":{"type":"Point Formula","name":"New Point Formula","code":"x = record.begin\ny = record.property","project":"Foundations","id":"5e00d61b-c357-40dd-a0cf-a6d2fa76233d","savedPayload":{"position":{"x":18545.507318297008,"y":17873.736743838686},"targetPosition":{"x":18642.935176222756,"y":17817.486743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"a3fb852b-0aef-4518-a691-b6e9997a53e1","savedPayload":{"position":{"x":18642.935176222756,"y":17817.486743838686},"targetPosition":{"x":18740.363034148504,"y":17761.236743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"ca38b15d-e145-42c8-98a8-b0dbffc04720","savedPayload":{"position":{"x":18740.363034148504,"y":17761.236743838686},"targetPosition":{"x":18837.790892074252,"y":17704.986743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"polygons":[{"type":"Polygon","name":"New Polygon","project":"Foundations","polygonBody":{"type":"Polygon Body","name":"New Polygon Body","project":"Foundations","style":{"type":"Style","name":"New Style","config":" { \"default\": { \"opacity\": 0.2, \"lineWidth\": 1, \"lineDash\": [0,0], \"paletteColor\": \"UI_COLOR.DARK_TURQUOISE\" }, \"atMousePosition\": { \"opacity\": 0.3, \"lineWidth\": 2, \"lineDash\": [0,0], \"paletteColor\": \"UI_COLOR.RUSTED_RED\" }}","project":"Foundations","id":"bbc148c5-cfec-4cba-909c-29402cda8fb2","savedPayload":{"position":{"x":18612.790892074252,"y":17592.486743838686},"targetPosition":{"x":18725.290892074252,"y":17592.486743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"styleConditions":[],"id":"0d741cbf-553b-43e2-866c-414a637ac298","savedPayload":{"position":{"x":18725.290892074252,"y":17592.486743838686},"targetPosition":{"x":18837.790892074252,"y":17592.486743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"polygonBorder":{"type":"Polygon Border","name":"New Polygon Border","project":"Foundations","style":{"type":"Style","name":"New Style","config":" { \"default\": { \"opacity\": 0.2, \"lineWidth\": 1, \"lineDash\": [0,0], \"paletteColor\": \"UI_COLOR.DARK_TURQUOISE\" }, \"atMousePosition\": { \"opacity\": 0.3, \"lineWidth\": 2, \"lineDash\": [0,0], \"paletteColor\": \"UI_COLOR.RUSTED_RED\" }}","project":"Foundations","id":"06e0d64e-179d-4c28-a834-ac4cafba7147","savedPayload":{"position":{"x":18837.790892074252,"y":17367.486743838686},"targetPosition":{"x":18837.790892074252,"y":17479.986743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"styleConditions":[],"id":"da3b36a0-f339-4b35-b707-1e994704e0da","savedPayload":{"position":{"x":18837.790892074252,"y":17479.986743838686},"targetPosition":{"x":18837.790892074252,"y":17592.486743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"polygonVertexes":[{"type":"Polygon Vertex","name":"","project":"Foundations","id":"5ff95619-2158-48de-8c43-30a5009e4f47","savedPayload":{"position":{"x":18950.290892074252,"y":17592.486743838686},"targetPosition":{"x":18837.790892074252,"y":17592.486743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}}],"id":"915083b5-99cf-4abb-ac67-764bf1a9f26b","savedPayload":{"position":{"x":18837.790892074252,"y":17592.486743838686},"targetPosition":{"x":18837.790892074252,"y":17704.986743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"images":[],"texts":[],"id":"7afeb4e8-a789-4cfc-8394-a4253714891d","savedPayload":{"position":{"x":18837.790892074252,"y":17704.986743838686},"targetPosition":{"x":18935.21875,"y":17761.236743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"panels":[{"type":"Plotter Panel","name":"MFI","config":"{\n \"codeName\": \"\",\n \"isLegacy\": false\n}","project":"Foundations","panelData":[{"type":"Panel Data","name":"MFI","config":"{\n \"valueDecimals\": 2\n}","project":"Foundations","dataFormula":{"type":"Data Formula","name":"New Data Formula","code":"record.value","project":"Foundations","id":"53378fbb-eee0-4b7d-b771-ca2f9b813cde","savedPayload":{"position":{"x":19227.502323777244,"y":17592.486743838686},"targetPosition":{"x":19130.074465851496,"y":17648.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"8813ea4c-b38a-47f9-ae3e-d6c719246810","savedPayload":{"position":{"x":19130.074465851496,"y":17648.736743838686},"targetPosition":{"x":19032.646607925748,"y":17704.986743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"a4b4753e-e713-4bb2-9daa-cb7602e16e87","savedPayload":{"position":{"x":19032.646607925748,"y":17704.986743838686},"targetPosition":{"x":18935.21875,"y":17761.236743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"d10cdbe9-9416-490a-904e-ace49d0dfbf7","savedPayload":{"position":{"x":18935.21875,"y":17761.236743838686},"targetPosition":{"x":18935.21875,"y":17873.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":1,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"691c8481-d970-4eb0-a631-639bd1d53dd9","savedPayload":{"position":{"x":18922.21875,"y":17886.736743838686},"targetPosition":{"x":18922.21875,"y":18336.736743838686},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"63655ecf-cd7d-4d65-a367-e976c00631d3","savedPayload":{"position":{"x":18922.21875,"y":18336.736743838686},"targetPosition":{"x":18922.21875,"y":18336.736743838686},"floatingObject":{"isPinned":true,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":4,"arrangementStyle":0},"uiObject":{"isRunning":false,"shortcutKey":"s"}}} From 2c181aaeed69cf267966445ad7b50cd0adf04c66 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 3 Sep 2021 08:17:56 +0200 Subject: [PATCH 08/11] Create UserProfiles.js --- .../NT/Modules/Queries/UserProfiles.js | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 Projects/Social-Trading/NT/Modules/Queries/UserProfiles.js diff --git a/Projects/Social-Trading/NT/Modules/Queries/UserProfiles.js b/Projects/Social-Trading/NT/Modules/Queries/UserProfiles.js new file mode 100644 index 000000000..7454cba54 --- /dev/null +++ b/Projects/Social-Trading/NT/Modules/Queries/UserProfiles.js @@ -0,0 +1,69 @@ +exports.newSocialTradingModulesQueriesUserProfileStats = function newSocialTradingModulesQueriesUserProfileStats() { + /* + This query returns a list of user profiles ordered + by Ranking. It is useful to bootstrap new users + and provide them with alternative of who to follow. + */ + let thisObject = { + initialIndex: undefined, + amountRequested: undefined, + direction: undefined, + execute: execute, + initialize: initialize, + finalize: finalize + } + + return thisObject + + function finalize() { + } + + function initialize(queryReceived) { + + NT.utilities.queriesValidations.arrayValidations(queryReceived, thisObject) + + } + + function execute() { + + let response = [] + let array = Array.from(NT.projects.socialTrading.globals.memory.maps.USER_PROFILES_BY_ID) + array.sort((a, b) => (a["ranking"].toLowerCase() > b["ranking"].toLowerCase()) ? 1 : -1) + + switch (thisObject.direction) { + case NT.projects.socialTrading.globals.queryConstants.DIRECTION_FUTURE: { + for (let i = thisObject.initialIndex; i < thisObject.initialIndex + thisObject.amountRequested; i++) { + let arrayItem = array[i] + if (arrayItem === undefined) { break } + addToResponse(arrayItem) + } + break + } + case NT.projects.socialTrading.globals.queryConstants.DIRECTION_PAST: { + for (let i = thisObject.initialIndex; i > thisObject.initialIndex - thisObject.amountRequested; i--) { + let arrayItem = array[i] + if (arrayItem === undefined) { break } + addToResponse(arrayItem) + } + break + } + } + return response + + function addToResponse(profile) { + let postResponse = { + "userProfileId": profile.userProfileId, + "userProfileHandle": profile.userProfileHandle, + "blockchainAccount": profile.blockchainAccount, + "ranking": profile.ranking, + "followingCount": profile.following.size, + "followersCount": profile.followers.size, + "postsCount": profile.posts.size, + "botsCount": profile.bots.size, + "emitterEventsCount": profile.emitterEventsCount, + "targetEventsCount": profile.targetEventsCount + } + response.push(postResponse) + } + } +} \ No newline at end of file From 2645df775e8eed46e087827c8783c81dab28b97d Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 3 Sep 2021 08:42:54 +0200 Subject: [PATCH 09/11] Testing Frist Query --- Desktop/DesktopApp.js | 25 ++++++++++++++++--- .../Network/SA/Modules/WebSocketsClient.js | 3 +-- runDesktop.js | 1 + 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/Desktop/DesktopApp.js b/Desktop/DesktopApp.js index ea5bceab3..aac336353 100644 --- a/Desktop/DesktopApp.js +++ b/Desktop/DesktopApp.js @@ -7,15 +7,32 @@ exports.newDesktopApp = function newDesktopApp() { return thisObject async function run() { -/* - let socialGraphService = NT.projects.network.modules.socialGraph.newSocialGraph() - await socialGraphService.initialize() -*/ + /* + let socialGraphService = NT.projects.network.modules.socialGraph.newSocialGraph() + await socialGraphService.initialize() + */ /* Let's start the Network Interfaces */ DK.webSocketsClient = SA.projects.network.modules.webSocketsClient.newNetworkModulesWebSocketsClient() DK.webSocketsClient.initialize() + let request = { + equeryId: "123", + queryType: 0, + emitterUserProfileId: DK.TEST_NETWORK_CLIENT_USER_PROFILE_ID, + initialIndex: 'Last', + amountRequested: 10, + direction: 'Past' + } + DK.webSocketsClient.sendMessage( + JSON.stringify(request), + onResponse + ) + + function onResponse(message) { + let profiles = JSON.parse(message) + console.log(profiles) + } } } diff --git a/Projects/Network/SA/Modules/WebSocketsClient.js b/Projects/Network/SA/Modules/WebSocketsClient.js index d5925aae7..06f6a09b1 100644 --- a/Projects/Network/SA/Modules/WebSocketsClient.js +++ b/Projects/Network/SA/Modules/WebSocketsClient.js @@ -43,7 +43,6 @@ exports.newNetworkModulesWebSocketsClient = function newNetworkModulesWebSockets } socketClient = new SA.nodeModules.ws('ws://' + selectedNetworkNode.host + ':' + selectedNetworkNode.port) - //networkInterface = SA.projects.socialTrading.modules.networkInterface.newSocialTradingModulesNetworkInterface() setUpWebsocketClient() } @@ -204,7 +203,7 @@ exports.newNetworkModulesWebSocketsClient = function newNetworkModulesWebSockets } } - callbackFunction.receiveResponse(message) + callbackFunction.receiveResponse(response.message) callbackFunction = undefined } catch (err) { diff --git a/runDesktop.js b/runDesktop.js index 96d54c44b..f6e04a1d2 100644 --- a/runDesktop.js +++ b/runDesktop.js @@ -54,6 +54,7 @@ We will use this User Profile for Testing Purposes. } */ +DK.TEST_NETWORK_CLIENT_USER_PROFILE_ID = "baa2f02c-2920-4edb-a103-d452fc61d82f" DK.TEST_NETWORK_CLIENT_USER_PROFILE_HANDLE = "Test-Network-Client-Profile" DK.TEST_NETWORK_CLIENT_USER_PROFILE_PRIVATE_KEY = "0x5fed4817a87431c8a328d0936561e63f45b6db289adac6125b9306ded644dfe9" From 67ec9864229f2f96c255cdcaec642870bf64ddb5 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 3 Sep 2021 12:23:42 +0200 Subject: [PATCH 10/11] Superalgos Network: Query User Profiles debugged --- Desktop/DesktopApp.js | 26 +- .../Network/NT/Modules/WebSocketsInterface.js | 8 + .../Network/SA/Modules/WebSocketsClient.js | 320 +++++++++--------- Projects/ProjectsSchema.json | 2 +- .../NT/Modules/ClientInterface.js | 22 +- .../NT/Modules/Queries/Events.js | 4 +- .../NT/Modules/Queries/PostReplies.js | 16 +- .../NT/Modules/Queries/ProfileFollowers.js | 13 +- .../NT/Modules/Queries/ProfileFollowing.js | 13 +- .../NT/Modules/Queries/ProfilePosts.js | 13 +- .../NT/Modules/Queries/UserProfiles.js | 18 +- Projects/Social-Trading/NT/Modules/Query.js | 32 +- .../NT/Utilities/QueriesValidations.js | 6 +- 13 files changed, 266 insertions(+), 227 deletions(-) diff --git a/Desktop/DesktopApp.js b/Desktop/DesktopApp.js index aac336353..19b8726a0 100644 --- a/Desktop/DesktopApp.js +++ b/Desktop/DesktopApp.js @@ -15,9 +15,9 @@ exports.newDesktopApp = function newDesktopApp() { Let's start the Network Interfaces */ DK.webSocketsClient = SA.projects.network.modules.webSocketsClient.newNetworkModulesWebSocketsClient() - DK.webSocketsClient.initialize() + await DK.webSocketsClient.initialize() - let request = { + let queryMessage = { equeryId: "123", queryType: 0, emitterUserProfileId: DK.TEST_NETWORK_CLIENT_USER_PROFILE_ID, @@ -25,14 +25,24 @@ exports.newDesktopApp = function newDesktopApp() { amountRequested: 10, direction: 'Past' } - DK.webSocketsClient.sendMessage( - JSON.stringify(request), - onResponse - ) - function onResponse(message) { - let profiles = JSON.parse(message) + let query = { + requestType: 'Query', + queryMessage : JSON.stringify(queryMessage ) + } + + await DK.webSocketsClient.sendMessage( + JSON.stringify(query) + ) + .then(showProfiles) + .catch(onError) + + function showProfiles(profiles){ console.log(profiles) } + + function onError(errorMessage) { + console.log('[ERROR] Query not executed. ' + errorMessage) + } } } diff --git a/Projects/Network/NT/Modules/WebSocketsInterface.js b/Projects/Network/NT/Modules/WebSocketsInterface.js index f40faaed3..003e6798b 100644 --- a/Projects/Network/NT/Modules/WebSocketsInterface.js +++ b/Projects/Network/NT/Modules/WebSocketsInterface.js @@ -94,6 +94,14 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock } break } + default: { + let response = { + result: 'Error', + message: 'messageType Not Supported.' + } + socket.send(JSON.stringify(response)) + break + } } } catch (err) { console.log('[ERROR] Web Sockets Interface -> setUpWebSocketServer -> err.stack = ' + err.stack) diff --git a/Projects/Network/SA/Modules/WebSocketsClient.js b/Projects/Network/SA/Modules/WebSocketsClient.js index 06f6a09b1..8d47316f6 100644 --- a/Projects/Network/SA/Modules/WebSocketsClient.js +++ b/Projects/Network/SA/Modules/WebSocketsClient.js @@ -7,7 +7,6 @@ exports.newNetworkModulesWebSocketsClient = function newNetworkModulesWebSockets } let socketClient - let callbackFunction let web3 = new SA.nodeModules.web3() let called = {} @@ -25,7 +24,7 @@ exports.newNetworkModulesWebSocketsClient = function newNetworkModulesWebSockets called = undefined } - function initialize() { + async function initialize() { /* Here we will pick a Network Node from all users profiles available that do have a Network Node running. // TODO In the meantime, we will assume that we have chosen the following Network Node to connect to. @@ -44,203 +43,204 @@ exports.newNetworkModulesWebSocketsClient = function newNetworkModulesWebSockets socketClient = new SA.nodeModules.ws('ws://' + selectedNetworkNode.host + ':' + selectedNetworkNode.port) - setUpWebsocketClient() + await setUpWebsocketClient() } - function setUpWebsocketClient() { - try { - let handshakeDone = false + async function setUpWebsocketClient() { - socketClient.onopen = () => { onConnection() } - socketClient.onerror = err => { onError(err) } + return new Promise(connectToNewtwork) - function onConnection() { + function connectToNewtwork(resolve, reject) { - handshakeProcedure() + try { - function handshakeProcedure() { + socketClient.onopen = () => { onConnection() } + socketClient.onerror = err => { onError(err) } - let callerTimestamp + function onConnection() { - stepOneRequest() + handshakeProcedure() - function stepOneRequest() { - /* - Send Handshake Message Step One: - - At Step One we will just say hello, identify ourselves - as a Network Client, and send the Network Node our - User Profile Handle. - - This Handle will be signed by the Network Node to prove - it's ouwn identity, and later we will sign it's own handle - to prove ours. - */ - socketClient.onmessage = socketMessage => { stepOneResponse(socketMessage) } + function handshakeProcedure() { - callerTimestamp = (new Date()).valueOf() + let callerTimestamp - let message = { - messageType: 'Handshake', - callerRole: 'Network Client', - callerProfileHandle: DK.TEST_NETWORK_CLIENT_USER_PROFILE_HANDLE, - callerTimestamp: callerTimestamp, - step: 'One' - } - socketClient.send(JSON.stringify(message)) - } + stepOneRequest() - function stepOneResponse(socketMessage) { - let response = JSON.parse(socketMessage.data) + function stepOneRequest() { + /* + Send Handshake Message Step One: + + At Step One we will just say hello, identify ourselves + as a Network Client, and send the Network Node our + User Profile Handle. + + This Handle will be signed by the Network Node to prove + it's ouwn identity, and later we will sign it's own handle + to prove ours. + */ + socketClient.onmessage = socketMessage => { stepOneResponse(socketMessage) } - if (response.result !== 'Ok') { - console.log('[ERROR] Web Sockets Client -> stepOneResponse -> response.message = ' + response.message) - return + callerTimestamp = (new Date()).valueOf() + + let message = { + messageType: 'Handshake', + callerRole: 'Network Client', + callerProfileHandle: DK.TEST_NETWORK_CLIENT_USER_PROFILE_HANDLE, + callerTimestamp: callerTimestamp, + step: 'One' + } + socketClient.send(JSON.stringify(message)) } - let signature = JSON.parse(response.signature) - called.blockchainAccount = web3.eth.accounts.recover(signature) - /* - We will check that the signature received produces a valid Blockchain Account. - */ - if (called.blockchainAccount === undefined) { - console.log('[ERROR] Web Sockets Client -> stepOneResponse -> Signature does not produce a valid Blockchain Account.') - return - } - /* - We will check that the blockchain account taken from the signature matches - the one we have on record for the user profile of the Network Node we are calling. - */ - if (called.blockchainAccount !== selectedNetworkNode.blockchainAccount) { - console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node called does not have the expected Profile Handle.') - return + function stepOneResponse(socketMessage) { + let response = JSON.parse(socketMessage.data) + + if (response.result !== 'Ok') { + console.log('[ERROR] Web Sockets Client -> stepOneResponse -> response.message = ' + response.message) + reject() + } + + let signature = JSON.parse(response.signature) + called.blockchainAccount = web3.eth.accounts.recover(signature) + /* + We will check that the signature received produces a valid Blockchain Account. + */ + if (called.blockchainAccount === undefined) { + console.log('[ERROR] Web Sockets Client -> stepOneResponse -> Signature does not produce a valid Blockchain Account.') + reject() + } + /* + We will check that the blockchain account taken from the signature matches + the one we have on record for the user profile of the Network Node we are calling. + */ + if (called.blockchainAccount !== selectedNetworkNode.blockchainAccount) { + console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node called does not have the expected Profile Handle.') + reject() + } + + let signedMessage = JSON.parse(signature.message) + + /* + We will check that the Network Node that responded has the same User Profile Handle + that we have on record, otherwise something is wrong and we should not proceed. + */ + if (signedMessage.calledProfileHandle !== selectedNetworkNode.userProfileHandle) { + console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node called does not have the expected Profile Handle.') + reject() + } + /* + We will check that the profile handle we sent to the Network Node, is returned at the + signed message, to avoid man in the middle attackts. + */ + if (signedMessage.callerProfileHandle !== DK.TEST_NETWORK_CLIENT_USER_PROFILE_HANDLE) { + console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node callerProfileHandle does not match my own userProfileHandle.') + reject() + } + /* + We will also check that the callerTimestamp we sent to the Network Node, is returned at the + signed message, also to avoid man in the middle attackts. + */ + if (signedMessage.callerTimestamp !== callerTimestamp) { + console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node callerTimestamp does not match my own callerTimestamp.') + reject() + } + + /* + All validations passed, it seems we can continue with Step Two. + */ + stepTwoRequest(signedMessage) } - let signedMessage = JSON.parse(signature.message) + function stepTwoRequest(signedMessage) { + /* + Send Handshake Message Step Two: + + Here we will sign a message with the Network Node profile + handle and timestamp to prove our own identity. + */ + socketClient.onmessage = socketMessage => { stepTwoResponse(socketMessage) } - /* - We will check that the Network Node that responded has the same User Profile Handle - that we have on record, otherwise something is wrong and we should not proceed. - */ - if (signedMessage.calledProfileHandle !== selectedNetworkNode.userProfileHandle) { - console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node called does not have the expected Profile Handle.') - return - } - /* - We will check that the profile handle we sent to the Network Node, is returned at the - signed message, to avoid man in the middle attackts. - */ - if (signedMessage.callerProfileHandle !== DK.TEST_NETWORK_CLIENT_USER_PROFILE_HANDLE) { - console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node callerProfileHandle does not match my own userProfileHandle.') - return - } - /* - We will also check that the callerTimestamp we sent to the Network Node, is returned at the - signed message, also to avoid man in the middle attackts. - */ - if (signedMessage.callerTimestamp !== callerTimestamp) { - console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node callerTimestamp does not match my own callerTimestamp.') - return + let signature = web3.eth.accounts.sign(JSON.stringify(signedMessage), DK.TEST_NETWORK_CLIENT_USER_PROFILE_PRIVATE_KEY) + + let message = { + messageType: 'Handshake', + signature: JSON.stringify(signature), + step: 'Two' + } + socketClient.send(JSON.stringify(message)) } - /* - All validations passed, it seems we can continue with Step Two. - */ - stepTwoRequest(signedMessage) - } + function stepTwoResponse(socketMessage) { + let response = JSON.parse(socketMessage.data) - function stepTwoRequest(signedMessage) { - /* - Send Handshake Message Step Two: - - Here we will sign a message with the Network Node profile - handle and timestamp to prove our own identity. - */ - socketClient.onmessage = socketMessage => { stepTwoResponse(socketMessage) } - - let signature = web3.eth.accounts.sign(JSON.stringify(signedMessage), DK.TEST_NETWORK_CLIENT_USER_PROFILE_PRIVATE_KEY) - - let message = { - messageType: 'Handshake', - signature: JSON.stringify(signature), - step: 'Two' + if (response.result !== 'Ok') { + console.log('[ERROR] Web Sockets Client -> stepOneResponse -> response.message = ' + response.message) + reject() + } + console.log('[INFO] Web Sockets Client -> stepTwoResponse -> response.message = ' + response.message) + /* + This was the end of the Handshake producere. We are connected to the + Network Node and from now on, all response messages will be received + at this following function. + */ + resolve() } - socketClient.send(JSON.stringify(message)) - } - - function stepTwoResponse(socketMessage) { - let response = JSON.parse(socketMessage.data) - - if (response.result !== 'Ok') { - console.log('[ERROR] Web Sockets Client -> stepOneResponse -> response.message = ' + response.message) - return - } - console.log('[INFO] Web Sockets Client -> stepTwoResponse -> response.message = ' + response.message) - /* - This was the end of the Handshake producere. We are connected to the - Network Node and from now on, all response messages will be received - at this following function. - */ - socketClient.onmessage = socketMessage => { onMenssage(socketMessage) } } } + + function onError(err) { + console.log('[ERROR] Web Sockets Client -> onError -> err.message = ' + err.message) + console.log('[ERROR] Web Sockets Client -> onError -> err.stack = ' + err.stack) + } + + } catch (err) { + console.log('[ERROR] Web Sockets Client -> setUpWebsocketClient -> err.stack = ' + err.stack) } - async function onMenssage(socketMessage) { + } + } + + function sendMessage(message) { + + return new Promise(sendSocketMessage) + + function sendSocketMessage(resolve, reject) { + + if (socketClient.readyState !== 1) { // 1 means connected and ready. + console.log('[ERROR] Web Sockets Client -> sendMessage -> Cannot send message while connection is closed.') + reject('Websockets Connection Not Ready.') + } + + let socketMessage = { + messageType: 'Request', + payload: message + } + socketClient.onmessage = socketMessage => { onMenssage(socketMessage) } + socketClient.send( + JSON.stringify(socketMessage) + ) + + function onMenssage(socketMessage) { try { let response = JSON.parse(socketMessage.data) /* Chack if we are waiting for the Handshake response. */ - if (handshakeDone === false) { - if (response.result === 'Ok') { - handshakeDone = true - return - } else { - console.log('[ERROR] Web Sockets Client -> onMenssage -> handshakeDone -> response.message = ' + response.message) - return - } - } - callbackFunction.receiveResponse(response.message) - callbackFunction = undefined + if (response.result === 'Ok') { + resolve(response.data) + } else { + console.log('[ERROR] Web Sockets Client -> onMenssage -> response.message = ' + response.message) + reject(response.message) + } } catch (err) { callbackFunction = undefined console.log('[ERROR] Web Sockets Client -> err.stack = ' + err.stack) } } - - function onError(err) { - console.log('[ERROR] Web Sockets Client -> onError -> err.message = ' + err.message) - console.log('[ERROR] Web Sockets Client -> onError -> err.stack = ' + err.stack) - } - - } catch (err) { - console.log('[ERROR] Web Sockets Client -> setUpWebsocketClient -> err.stack = ' + err.stack) - } - } - - function sendMessage(message, callback) { - if (callbackFunction !== undefined) { - console.log('[ERROR] Web Sockets Client -> sendMessage -> Cannot send more messages while waiting for a response.') - return false - } - - if (socketClient.readyState !== 1) { // 1 means connected and ready. - console.log('[ERROR] Web Sockets Client -> sendMessage -> Cannot send message while connection is closed.') - return false - } - - try { - callbackFunction = callback - socketClient.send(message) - return true - } catch (err) { - callbackFunction = false - console.log('[ERROR] Web Sockets Client -> sendMessage -> err.stack = ' + err.stack) - return false } } } \ No newline at end of file diff --git a/Projects/ProjectsSchema.json b/Projects/ProjectsSchema.json index 9f9fd3da6..f1bac7bfd 100644 --- a/Projects/ProjectsSchema.json +++ b/Projects/ProjectsSchema.json @@ -1400,7 +1400,7 @@ }, { "name": "Query", - "propertyName": "Query", + "propertyName": "query", "functionName": "newSocialTradingModulesQuery", "fileName": "Query.js" }, diff --git a/Projects/Social-Trading/NT/Modules/ClientInterface.js b/Projects/Social-Trading/NT/Modules/ClientInterface.js index bbfd8b8f1..9a0e7b57f 100644 --- a/Projects/Social-Trading/NT/Modules/ClientInterface.js +++ b/Projects/Social-Trading/NT/Modules/ClientInterface.js @@ -35,23 +35,23 @@ exports.newSocialTradingModulesClientInterface = function newSocialTradingModule return response } - if (messageHeader.messageType === undefined) { + if (messageHeader.requestType === undefined) { let response = { result: 'Error', - message: 'Client Interface messageType Not Provided.' + message: 'Client Interface requestType Not Provided.' } return response } - if (messageHeader.messageType !== 'Event' && messageHeader.messageType !== 'Query') { + if (messageHeader.requestType !== 'Event' && messageHeader.requestType !== 'Query') { let response = { result: 'Error', - message: 'Client Interface messageType Not Supported.' + message: 'Client Interface requestType Not Supported.' } return response } - switch (messageHeader.messageType) { + switch (messageHeader.requestType) { case 'Event': { return await eventReceived(messageHeader.eventMessage, userProfile) } @@ -190,9 +190,15 @@ exports.newSocialTradingModulesClientInterface = function newSocialTradingModule Here we will process the query. This does not change the state of the Social Graph. */ try { - let query = NT.projects.socialTrading.modules.queriesQuery.newSocialTradingModulesQuery() + let query = NT.projects.socialTrading.modules.query.newSocialTradingModulesQuery() query.initialize(queryReceived) - return query.execute() + + let response = { + result: 'Ok', + message: 'Client Interface Query Processed.', + data: query.execute() + } + return response } catch (err) { /* @@ -200,7 +206,7 @@ exports.newSocialTradingModulesClientInterface = function newSocialTradingModule */ let response = { result: 'Error', - message: 'Client Interface ' + err.message + message: err.message } return response } diff --git a/Projects/Social-Trading/NT/Modules/Queries/Events.js b/Projects/Social-Trading/NT/Modules/Queries/Events.js index a68d7215b..981cb9323 100644 --- a/Projects/Social-Trading/NT/Modules/Queries/Events.js +++ b/Projects/Social-Trading/NT/Modules/Queries/Events.js @@ -21,8 +21,8 @@ exports.newSocialTradingModulesQueriesEvents = function newSocialTradingModulesQ function initialize(queryReceived) { - NT.utilities.queriesValidations.profilesValidations(queryReceived, thisObject) - NT.utilities.queriesValidations.arrayValidations(queryReceived, thisObject) + NT.projects.socialTrading.utilities.queriesValidations.profilesValidations(queryReceived, thisObject) + NT.projects.socialTrading.utilities.queriesValidations.arrayValidations(queryReceived, thisObject, NT.memory.arrays.EVENTS) } diff --git a/Projects/Social-Trading/NT/Modules/Queries/PostReplies.js b/Projects/Social-Trading/NT/Modules/Queries/PostReplies.js index 4c0b63ecf..3a18bc421 100644 --- a/Projects/Social-Trading/NT/Modules/Queries/PostReplies.js +++ b/Projects/Social-Trading/NT/Modules/Queries/PostReplies.js @@ -8,6 +8,7 @@ exports.newSocialTradingModulesQueriesPostReplies = function newSocialTradingMod of a certain post, with all its replies. */ let thisObject = { + array: undefined, profile: undefined, post: undefined, initialIndex: undefined, @@ -21,27 +22,30 @@ exports.newSocialTradingModulesQueriesPostReplies = function newSocialTradingMod return thisObject function finalize() { + thisObject.array = undefined thisObject.profile = undefined thisObject.post = undefined } function initialize(queryReceived) { - NT.utilities.queriesValidations.profilesValidations(queryReceived, thisObject) - NT.utilities.queriesValidations.postValidations(queryReceived, thisObject) - NT.utilities.queriesValidations.arrayValidations(queryReceived, thisObject) + thisObject.array = Array.from(thisObject.post.replies) + + NT.projects.socialTrading.utilities.queriesValidations.profilesValidations(queryReceived, thisObject) + NT.projects.socialTrading.utilities.queriesValidations.postValidations(queryReceived, thisObject) + NT.projects.socialTrading.utilities.queriesValidations.arrayValidations(queryReceived, thisObject, thisObject.array) } function execute() { let response = [] - let array = Array.from(thisObject.post.replies) + switch (thisObject.direction) { case NT.projects.socialTrading.globals.queryConstants.DIRECTION_FUTURE: { for (let i = thisObject.initialIndex; i < thisObject.initialIndex + thisObject.amountRequested; i++) { - let arrayItem = array[i] + let arrayItem = thisObject.array[i] if (post === undefined) { break } addToResponse(arrayItem) } @@ -49,7 +53,7 @@ exports.newSocialTradingModulesQueriesPostReplies = function newSocialTradingMod } case NT.projects.socialTrading.globals.queryConstants.DIRECTION_PAST: { for (let i = thisObject.initialIndex; i > thisObject.initialIndex - thisObject.amountRequested; i--) { - let arrayItem = array[i] + let arrayItem = thisObject.array[i] if (post === undefined) { break } addToResponse(arrayItem) } diff --git a/Projects/Social-Trading/NT/Modules/Queries/ProfileFollowers.js b/Projects/Social-Trading/NT/Modules/Queries/ProfileFollowers.js index 5b500c24c..dccdcfd2d 100644 --- a/Projects/Social-Trading/NT/Modules/Queries/ProfileFollowers.js +++ b/Projects/Social-Trading/NT/Modules/Queries/ProfileFollowers.js @@ -4,6 +4,7 @@ exports.newSocialTradingModulesQueriesProfileFollowers = function newSocialTradi all the User or Bot profiles that are following a certain User or Bot profile. */ let thisObject = { + array: undefined, profile: undefined, initialIndex: undefined, amountRequested: undefined, @@ -16,25 +17,27 @@ exports.newSocialTradingModulesQueriesProfileFollowers = function newSocialTradi return thisObject function finalize() { + thisObject.array = undefined thisObject.profile = undefined } function initialize(queryReceived) { - NT.utilities.queriesValidations.profilesValidations(queryReceived, thisObject) - NT.utilities.queriesValidations.arrayValidations(queryReceived, thisObject) + thisObject.array = Array.from(thisObject.profile.followers) + + NT.projects.socialTrading.utilities.queriesValidations.profilesValidations(queryReceived, thisObject) + NT.projects.socialTrading.utilities.queriesValidations.arrayValidations(queryReceived, thisObject, thisObject.array) } function execute() { let response = [] - let array = Array.from(thisObject.profile.followers) switch (thisObject.direction) { case NT.projects.socialTrading.globals.queryConstants.DIRECTION_FUTURE: { for (let i = thisObject.initialIndex; i < thisObject.initialIndex + thisObject.amountRequested; i++) { - let arrayItem = array[i] + let arrayItem = thisObject.array[i] if (arrayItem === undefined) { break } addToResponse(arrayItem) } @@ -42,7 +45,7 @@ exports.newSocialTradingModulesQueriesProfileFollowers = function newSocialTradi } case NT.projects.socialTrading.globals.queryConstants.DIRECTION_PAST: { for (let i = thisObject.initialIndex; i > thisObject.initialIndex - thisObject.amountRequested; i--) { - let arrayItem = array[i] + let arrayItem = thisObject.array[i] if (arrayItem === undefined) { break } addToResponse(arrayItem) } diff --git a/Projects/Social-Trading/NT/Modules/Queries/ProfileFollowing.js b/Projects/Social-Trading/NT/Modules/Queries/ProfileFollowing.js index aa21b6193..a1624dedb 100644 --- a/Projects/Social-Trading/NT/Modules/Queries/ProfileFollowing.js +++ b/Projects/Social-Trading/NT/Modules/Queries/ProfileFollowing.js @@ -4,6 +4,7 @@ exports.newSocialTradingModulesQueriesProfileFollowing = function newSocialTradi all the User or Bot profiles that are being followed by a certain User or Bot profile. */ let thisObject = { + array: undefined, profile: undefined, initialIndex: undefined, amountRequested: undefined, @@ -16,25 +17,27 @@ exports.newSocialTradingModulesQueriesProfileFollowing = function newSocialTradi return thisObject function finalize() { + thisObject.array = undefined thisObject.profile = undefined } function initialize(queryReceived) { - NT.utilities.queriesValidations.profilesValidations(queryReceived, thisObject) - NT.utilities.queriesValidations.arrayValidations(queryReceived, thisObject) + thisObject.array = Array.from(thisObject.profile.following) + + NT.projects.socialTrading.utilities.queriesValidations.profilesValidations(queryReceived, thisObject) + NT.projects.socialTrading.utilities.queriesValidations.arrayValidations(queryReceived, thisObject, thisObject.array) } function execute() { let response = [] - let array = Array.from(thisObject.profile.following) switch (thisObject.direction) { case NT.projects.socialTrading.globals.queryConstants.DIRECTION_FUTURE: { for (let i = thisObject.initialIndex; i < thisObject.initialIndex + thisObject.amountRequested; i++) { - let arrayItem = array[i] + let arrayItem = thisObject.array[i] if (arrayItem === undefined) { break } addToResponse(arrayItem) } @@ -42,7 +45,7 @@ exports.newSocialTradingModulesQueriesProfileFollowing = function newSocialTradi } case NT.projects.socialTrading.globals.queryConstants.DIRECTION_PAST: { for (let i = thisObject.initialIndex; i > thisObject.initialIndex - thisObject.amountRequested; i--) { - let arrayItem = array[i] + let arrayItem = thisObject.array[i] if (arrayItem === undefined) { break } addToResponse(arrayItem) } diff --git a/Projects/Social-Trading/NT/Modules/Queries/ProfilePosts.js b/Projects/Social-Trading/NT/Modules/Queries/ProfilePosts.js index c14dcd49f..45ab02b3b 100644 --- a/Projects/Social-Trading/NT/Modules/Queries/ProfilePosts.js +++ b/Projects/Social-Trading/NT/Modules/Queries/ProfilePosts.js @@ -8,6 +8,7 @@ exports.newSocialTradingModulesQueriesUserProfileStats = function newSocialTradi with all of its posts. */ let thisObject = { + array: undefined, profile: undefined, initialIndex: undefined, amountRequested: undefined, @@ -20,24 +21,26 @@ exports.newSocialTradingModulesQueriesUserProfileStats = function newSocialTradi return thisObject function finalize() { + thisObject.array = undefined thisObject.profile = undefined } function initialize(queryReceived) { - NT.utilities.queriesValidations.profilesValidations(queryReceived, thisObject) - NT.utilities.queriesValidations.arrayValidations(queryReceived, thisObject) + thisObject.array = Array.from(thisObject.profile.posts) + + NT.projects.socialTrading.utilities.queriesValidations.profilesValidations(queryReceived, thisObject) + NT.projects.socialTrading.utilities.queriesValidations.arrayValidations(queryReceived, thisObject, thisObject.array) } function execute() { let response = [] - let array = Array.from(thisObject.profile.posts) switch (thisObject.direction) { case NT.projects.socialTrading.globals.queryConstants.DIRECTION_FUTURE: { for (let i = thisObject.initialIndex; i < thisObject.initialIndex + thisObject.amountRequested; i++) { - let arrayItem = array[i] + let arrayItem = thisObject.array[i] if (arrayItem === undefined) { break } addToResponse(arrayItem) } @@ -45,7 +48,7 @@ exports.newSocialTradingModulesQueriesUserProfileStats = function newSocialTradi } case NT.projects.socialTrading.globals.queryConstants.DIRECTION_PAST: { for (let i = thisObject.initialIndex; i > thisObject.initialIndex - thisObject.amountRequested; i--) { - let arrayItem = array[i] + let arrayItem = thisObject.array[i] if (arrayItem === undefined) { break } addToResponse(arrayItem) } diff --git a/Projects/Social-Trading/NT/Modules/Queries/UserProfiles.js b/Projects/Social-Trading/NT/Modules/Queries/UserProfiles.js index 7454cba54..f90ef2f7d 100644 --- a/Projects/Social-Trading/NT/Modules/Queries/UserProfiles.js +++ b/Projects/Social-Trading/NT/Modules/Queries/UserProfiles.js @@ -1,10 +1,11 @@ -exports.newSocialTradingModulesQueriesUserProfileStats = function newSocialTradingModulesQueriesUserProfileStats() { +exports.newSocialTradingModulesQueriesUserProfiles = function newSocialTradingModulesQueriesUserProfiles() { /* This query returns a list of user profiles ordered by Ranking. It is useful to bootstrap new users and provide them with alternative of who to follow. */ let thisObject = { + array: undefined, initialIndex: undefined, amountRequested: undefined, direction: undefined, @@ -16,24 +17,29 @@ exports.newSocialTradingModulesQueriesUserProfileStats = function newSocialTradi return thisObject function finalize() { + thisObject.array = undefined } function initialize(queryReceived) { - NT.utilities.queriesValidations.arrayValidations(queryReceived, thisObject) + thisObject.array = Array.from( + NT.projects.socialTrading.globals.memory.maps.USER_PROFILES_BY_ID, + x => x[1] + ) + thisObject.array.sort((a, b) => (a["ranking"] > b["ranking"]) ? 1 : -1) + + NT.projects.socialTrading.utilities.queriesValidations.arrayValidations(queryReceived, thisObject, thisObject.array) } function execute() { let response = [] - let array = Array.from(NT.projects.socialTrading.globals.memory.maps.USER_PROFILES_BY_ID) - array.sort((a, b) => (a["ranking"].toLowerCase() > b["ranking"].toLowerCase()) ? 1 : -1) switch (thisObject.direction) { case NT.projects.socialTrading.globals.queryConstants.DIRECTION_FUTURE: { for (let i = thisObject.initialIndex; i < thisObject.initialIndex + thisObject.amountRequested; i++) { - let arrayItem = array[i] + let arrayItem = thisObject.array[i] if (arrayItem === undefined) { break } addToResponse(arrayItem) } @@ -41,7 +47,7 @@ exports.newSocialTradingModulesQueriesUserProfileStats = function newSocialTradi } case NT.projects.socialTrading.globals.queryConstants.DIRECTION_PAST: { for (let i = thisObject.initialIndex; i > thisObject.initialIndex - thisObject.amountRequested; i--) { - let arrayItem = array[i] + let arrayItem = thisObject.array[i] if (arrayItem === undefined) { break } addToResponse(arrayItem) } diff --git a/Projects/Social-Trading/NT/Modules/Query.js b/Projects/Social-Trading/NT/Modules/Query.js index b8e6f28f7..a45835cad 100644 --- a/Projects/Social-Trading/NT/Modules/Query.js +++ b/Projects/Social-Trading/NT/Modules/Query.js @@ -40,67 +40,61 @@ exports.newSocialTradingModulesQuery = function newSocialTradingModulesQuery() { thisObject.queryType = queryReceived.queryType switch (thisObject.queryType) { - + case QUERY_TYPES.USER_PROFILES: { thisObject.query = NT.projects.socialTrading.modules.queriesUserProfiles.newSocialTradingModulesQueriesUserProfiles() - query.initialize(queryReceived) - query.finalize() + thisObject.query.initialize(queryReceived) break } case QUERY_TYPES.USER_PROFILE_STATS: { thisObject.query = NT.projects.socialTrading.modules.queriesUserProfileStats.newSocialTradingModulesQueriesUserProfileStats() - query.initialize(queryReceived) - query.finalize() + thisObject.query.initialize(queryReceived) break } case QUERY_TYPES.BOT_PROFILE_STATS: { thisObject.query = NT.projects.socialTrading.modules.queriesBotProfileStats.newSocialTradingModulesQueriesBotProfileStats() - query.initialize(queryReceived) - query.finalize() + thisObject.query.initialize(queryReceived) break } case QUERY_TYPES.PROFILE_POSTS: { thisObject.query = NT.projects.socialTrading.modules.queriesProfilePosts.newSocialTradingModulesQueriesProfilePosts() - query.initialize(queryReceived) - query.finalize() + thisObject.query.initialize(queryReceived) break } case QUERY_TYPES.POST_REPLIES: { thisObject.query = NT.projects.socialTrading.modules.queriesPostReplies.newSocialTradingModulesQueriesPostReplies() - query.initialize(queryReceived) - query.finalize() + thisObject.query.initialize(queryReceived) break } case QUERY_TYPES.PROFILE_FOLLOWERS: { thisObject.query = NT.projects.socialTrading.modules.queriesProfileFollowers.newSocialTradingModulesQueriesProfileFollowers() - query.initialize(queryReceived) - query.finalize() + thisObject.query.initialize(queryReceived) break } case QUERY_TYPES.PROFILE_FOLLOWING: { thisObject.query = NT.projects.socialTrading.modules.queriesProfileFollowing.newSocialTradingModulesQueriesProfileFollowing() - query.initialize(queryReceived) - query.finalize() + thisObject.query.initialize(queryReceived) break } case QUERY_TYPES.maps.EVENTS: { thisObject.query = NT.projects.socialTrading.modules.queriesEvents.newSocialTradingModulesQueriesEvents() - query.initialize(queryReceived) - query.finalize() + thisObject.query.initialize(queryReceived) break } - default: throw('Query Type Not Supported.') + default: throw ('Query Type Not Supported.') } } function execute() { - return thisObject.query.execute() + let response = thisObject.query.execute() + thisObject.query.finalize() + return response } } \ No newline at end of file diff --git a/Projects/Social-Trading/NT/Utilities/QueriesValidations.js b/Projects/Social-Trading/NT/Utilities/QueriesValidations.js index 722b54835..20c00c0cf 100644 --- a/Projects/Social-Trading/NT/Utilities/QueriesValidations.js +++ b/Projects/Social-Trading/NT/Utilities/QueriesValidations.js @@ -43,7 +43,7 @@ exports.newSocialTradingUtilitiesQueriesValidations = function newSocialTradingU } } - function arrayValidations(queryReceived, thisObject) { + function arrayValidations(queryReceived, thisObject, array) { /* Validate Initial Index */ @@ -52,7 +52,7 @@ exports.newSocialTradingUtilitiesQueriesValidations = function newSocialTradingU } if (queryReceived.initialIndex === NT.projects.socialTrading.globals.queryConstants.INITIAL_INDEX_LAST) { - queryReceived.initialIndex = thisObject.profile.posts.length - 1 + queryReceived.initialIndex = array.length - 1 } if (queryReceived.initialIndex === NT.projects.socialTrading.globals.queryConstants.INITIAL_INDEX_FIRST) { @@ -82,6 +82,8 @@ exports.newSocialTradingUtilitiesQueriesValidations = function newSocialTradingU if (queryReceived.amountRequested > NT.projects.socialTrading.globals.queryConstants.MAX_AMOUNT_REQUESTED) { throw ('Amount Requested Above Max.') } + + thisObject.amountRequested = queryReceived.amountRequested /* Validate Direction */ From 412f099ee912b6f5a6d722a3e96eaed7caa35f86 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Fri, 3 Sep 2021 12:30:48 +0200 Subject: [PATCH 11/11] Superalgos Network: Deepscan bug fixed --- Projects/Network/SA/Modules/WebSocketsClient.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Projects/Network/SA/Modules/WebSocketsClient.js b/Projects/Network/SA/Modules/WebSocketsClient.js index 8d47316f6..150f31932 100644 --- a/Projects/Network/SA/Modules/WebSocketsClient.js +++ b/Projects/Network/SA/Modules/WebSocketsClient.js @@ -99,6 +99,7 @@ exports.newNetworkModulesWebSocketsClient = function newNetworkModulesWebSockets if (response.result !== 'Ok') { console.log('[ERROR] Web Sockets Client -> stepOneResponse -> response.message = ' + response.message) reject() + return } let signature = JSON.parse(response.signature) @@ -109,6 +110,7 @@ exports.newNetworkModulesWebSocketsClient = function newNetworkModulesWebSockets if (called.blockchainAccount === undefined) { console.log('[ERROR] Web Sockets Client -> stepOneResponse -> Signature does not produce a valid Blockchain Account.') reject() + return } /* We will check that the blockchain account taken from the signature matches @@ -117,6 +119,7 @@ exports.newNetworkModulesWebSocketsClient = function newNetworkModulesWebSockets if (called.blockchainAccount !== selectedNetworkNode.blockchainAccount) { console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node called does not have the expected Profile Handle.') reject() + return } let signedMessage = JSON.parse(signature.message) @@ -128,6 +131,7 @@ exports.newNetworkModulesWebSocketsClient = function newNetworkModulesWebSockets if (signedMessage.calledProfileHandle !== selectedNetworkNode.userProfileHandle) { console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node called does not have the expected Profile Handle.') reject() + return } /* We will check that the profile handle we sent to the Network Node, is returned at the @@ -136,6 +140,7 @@ exports.newNetworkModulesWebSocketsClient = function newNetworkModulesWebSockets if (signedMessage.callerProfileHandle !== DK.TEST_NETWORK_CLIENT_USER_PROFILE_HANDLE) { console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node callerProfileHandle does not match my own userProfileHandle.') reject() + return } /* We will also check that the callerTimestamp we sent to the Network Node, is returned at the @@ -144,6 +149,7 @@ exports.newNetworkModulesWebSocketsClient = function newNetworkModulesWebSockets if (signedMessage.callerTimestamp !== callerTimestamp) { console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node callerTimestamp does not match my own callerTimestamp.') reject() + return } /* @@ -177,6 +183,7 @@ exports.newNetworkModulesWebSocketsClient = function newNetworkModulesWebSockets if (response.result !== 'Ok') { console.log('[ERROR] Web Sockets Client -> stepOneResponse -> response.message = ' + response.message) reject() + return } console.log('[INFO] Web Sockets Client -> stepTwoResponse -> response.message = ' + response.message) /*