diff --git a/Projects/Algorithmic-Trading/TS/Bot-Modules/Trading-Bot/Low-Frequency-Trading/TradingStages.js b/Projects/Algorithmic-Trading/TS/Bot-Modules/Trading-Bot/Low-Frequency-Trading/TradingStages.js index 685424b19..6de0535d3 100644 --- a/Projects/Algorithmic-Trading/TS/Bot-Modules/Trading-Bot/Low-Frequency-Trading/TradingStages.js +++ b/Projects/Algorithmic-Trading/TS/Bot-Modules/Trading-Bot/Low-Frequency-Trading/TradingStages.js @@ -25,6 +25,8 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) { let tradingPositionModuleObject = TS.projects.algorithmicTrading.botModules.tradingPosition.newAlgorithmicTradingBotModulesTradingPosition(processIndex) let tradingExecutionModuleObject = TS.projects.algorithmicTrading.botModules.tradingExecution.newAlgorithmicTradingBotModulesTradingExecution(processIndex) let announcementsModuleObject = TS.projects.socialBots.botModules.announcements.newSocialBotsBotModulesAnnouncements(processIndex) + let outgoingTradingSignalsModuleObject = TS.projects.tradingSignals.modules.outgoingTradingSignals.newTradingSignalsModulesOutgoingTradingSignals(processIndex) + let portfolioManagerClient = TS.projects.portfolioManagement.modules.portfolioManagerClient.newPortfolioManagementModulesPortfolioManagerClient(processIndex) let snapshotsModuleObject = TS.projects.algorithmicTrading.botModules.snapshots.newAlgorithmicTradingBotModulesSnapshots(processIndex) let tradingEpisodeModuleObject = TS.projects.algorithmicTrading.botModules.tradingEpisode.newAlgorithmicTradingBotModulesTradingEpisode(processIndex) @@ -137,7 +139,11 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) { passed = tradingSystem.checkConditions(situation, passed) tradingSystem.values.push([situation.id, passed]) + + portfolioManagerClient.askPortfolioEventManager(triggerStage.triggerOn, { status: passed }) + if (passed) { + tradingSystem.highlights.push(situation.id) tradingSystem.highlights.push(triggerStage.triggerOn.id) tradingSystem.highlights.push(triggerStage.id) @@ -147,6 +153,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) { /* Initialize this */ tradingEngine.tradingCurrent.tradingEpisode.distanceToTradingEvent.triggerOn.value = 1 + outgoingTradingSignalsModuleObject.broadcastSignal(triggerStage.triggerOn) announcementsModuleObject.makeAnnouncements(triggerStage.triggerOn) if (TS.projects.foundations.globals.processConstants.CONSTANTS_BY_PROCESS_INDEX_MAP.get(processIndex).SESSION_NODE.type === 'Backtesting Session') { @@ -156,9 +163,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) { } } } - changeStageStatus('Trigger Stage', 'Open') - } } } @@ -194,6 +199,8 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) { tradingSystem.highlights.push(triggerStage.id) tradingEngine.tradingCurrent.tradingEpisode.distanceToTradingEvent.triggerOff.value = 1 + + outgoingTradingSignalsModuleObject.broadcastSignal(triggerStage.triggerOff) announcementsModuleObject.makeAnnouncements(triggerStage.triggerOff) changeStageStatus('Trigger Stage', 'Closed', 'Trigger Off Event') tradingStrategyModuleObject.closeStrategy('Trigger Off') @@ -233,6 +240,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) { tradingPositionModuleObject.openPosition(situation.name) + outgoingTradingSignalsModuleObject.broadcastSignal(triggerStage.takePosition) announcementsModuleObject.makeAnnouncements(triggerStage.takePosition) if (TS.projects.foundations.globals.processConstants.CONSTANTS_BY_PROCESS_INDEX_MAP.get(processIndex).SESSION_NODE.type === 'Backtesting Session') { @@ -266,7 +274,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) { function checkIfWeNeedToAbortTheStage() { /* Abort Open Stage Check */ if (tradingEngine.tradingCurrent.strategyOpenStage.status.value === 'Open' && - (tradingEngine.tradingCurrent.strategyCloseStage.status.value === 'Opening' || tradingEngine.tradingCurrent.strategyCloseStage.status.value === 'Open') ){ + (tradingEngine.tradingCurrent.strategyCloseStage.status.value === 'Opening' || tradingEngine.tradingCurrent.strategyCloseStage.status.value === 'Open')) { /* if the Close stage is opened while the open stage is still open that means that we need to stop placing orders, check what happened to the orders already placed, @@ -331,7 +339,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) { /* User Defined Code if runWhileAtStage==true */ if (tradingEngine.tradingCurrent.strategyOpenStage.status.value === 'Open') { - checkUserDefinedCode('Open Stage', 'Running', 'last'); + checkUserDefinedCode('Open Stage', 'Running', 'last'); } } } @@ -464,7 +472,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) { /* If User Defined Code exists check for runWhileAtStage */ if (tradingEngine.tradingCurrent.strategyManageStage.status.value === 'Open') { - checkUserDefinedCode('Manage Stage', 'Running', 'last'); + checkUserDefinedCode('Manage Stage', 'Running', 'last'); } } @@ -696,6 +704,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) { tradingPositionModuleObject.updateTakeProfit(tradingEngine.tradingCurrent.position.takeProfit.takeProfitPhase.value + 1) + outgoingTradingSignalsModuleObject.broadcastSignal(nextPhaseEvent) announcementsModuleObject.makeAnnouncements(nextPhaseEvent) /* Reset this counter */ @@ -747,6 +756,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) { continue } + outgoingTradingSignalsModuleObject.broadcastSignal(moveToPhaseEvent) announcementsModuleObject.makeAnnouncements(moveToPhaseEvent) /* Reset this counter */ @@ -876,7 +886,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) { checkIfStageNeedsToBeClosed(tradingEngineStage, tradingSystemStage, 'Close Stage') /* If User Defined Code exists check for runWhileAtStage */ if (tradingEngine.tradingCurrent.strategyCloseStage.status.value === 'Open') { - checkUserDefinedCode('Close Stage', 'Running', 'last'); + checkUserDefinedCode('Close Stage', 'Running', 'last'); } } } @@ -1108,6 +1118,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) { tradingSystem.highlights.push(closeStageEvent.id) tradingSystem.highlights.push(stage.id) + outgoingTradingSignalsModuleObject.broadcastSignal(closeStageEvent) announcementsModuleObject.makeAnnouncements(closeStageEvent) return true } @@ -1172,7 +1183,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) { /* Recording the closing at the Trading Engine Data Structure */ stage.end.value = tradingEngine.tradingCurrent.tradingEpisode.cycle.lastEnd.value stage.endRate.value = tradingEngine.tradingCurrent.tradingEpisode.candle.close.value - + if (stageName === 'Open Stage') { if (tradingEngine.tradingCurrent.strategyCloseStage.status.value !== 'Opening' && tradingEngine.tradingCurrent.strategyCloseStage.status.value !== 'Open' && tradingEngine.tradingCurrent.strategyManageStage.status.value !== 'Opening' && tradingEngine.tradingCurrent.strategyManageStage.status.value !== 'Open') { @@ -1272,20 +1283,20 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) { tradingSystemStage.userDefinedCode !== undefined) { if (status === 'Running' && when !== tradingSystemStage.userDefinedCode.config.whileAtStageWhenToRun) { return; } - switch(status) { - case 'Open' : { + switch (status) { + case 'Open': { if (tradingSystemStage.userDefinedCode.config.runWhenEnteringStage) { tradingSystem.evalUserCode(tradingSystemStage, 'User Defined Code'); } break; } - case 'Running' : { + case 'Running': { if (tradingSystemStage.userDefinedCode.config.runWhileAtStage) { tradingSystem.evalUserCode(tradingSystemStage, 'User Defined Code'); } break; } - case 'Closed' : { + case 'Closed': { if (tradingSystemStage.userDefinedCode.config.runWhenExitingStage) { tradingSystem.evalUserCode(tradingSystemStage, 'User Defined Code'); } @@ -1305,23 +1316,23 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) { /* getTradingSystemStage(): takes stage name returns stage object. */ function getTradingSystemStage(stage) { - switch(stage) { - case 'Trigger Stage' : { - return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].triggerStage; - break; + switch (stage) { + case 'Trigger Stage': { + return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].triggerStage; + break; + } + case 'Open Stage': { + return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].openStage; + break; + } + case 'Manage Stage': { + return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].manageStage; + break + } + case 'Close Stage': { + return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].closeStage; + break; + } } - case 'Open Stage' : { - return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].openStage; - break; - } - case 'Manage Stage' : { - return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].manageStage; - break - } - case 'Close Stage' : { - return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].closeStage; - break; - } - } } } diff --git a/Projects/Governance/Plugins/Pools/Superalgos.json b/Projects/Governance/Plugins/Pools/Superalgos.json index fc05ac501..e4b41c636 100644 --- a/Projects/Governance/Plugins/Pools/Superalgos.json +++ b/Projects/Governance/Plugins/Pools/Superalgos.json @@ -961,8 +961,10 @@ }, "referenceParentCombinedNodePath": [ [ - "Superalgos", - "Positions" + "Teams of Contributors", + "Positions", + "Governance", + "862caa2e-7c05-4051-b5eb-3494174e2cd9" ] ] } @@ -1006,7 +1008,7 @@ "floatingObject": { "isPinned": false, "isFrozen": false, - "isCollapsed": false, + "isCollapsed": true, "angleToParent": 1, "distanceToParent": 3, "arrangementStyle": 0 diff --git a/Projects/Governance/Plugins/Positions/Superalgos.json b/Projects/Governance/Plugins/Positions/Superalgos.json index d15001599..0a4e15d1f 100644 --- a/Projects/Governance/Plugins/Positions/Superalgos.json +++ b/Projects/Governance/Plugins/Positions/Superalgos.json @@ -2343,7 +2343,7 @@ "floatingObject": { "isPinned": false, "isFrozen": false, - "isCollapsed": false, + "isCollapsed": true, "angleToParent": 1, "distanceToParent": 3, "arrangementStyle": 0 diff --git a/Projects/Portfolio-Management/TS/Modules/PortfolioManagerClient.js b/Projects/Portfolio-Management/TS/Modules/PortfolioManagerClient.js new file mode 100644 index 000000000..26dece856 --- /dev/null +++ b/Projects/Portfolio-Management/TS/Modules/PortfolioManagerClient.js @@ -0,0 +1,30 @@ +exports.newPortfolioManagementModulesPortfolioManagerClient = function (processIndex) { + /* + This object represents a proxy of the Profile Manager. It is used to send + questions to the Event and Formula Managers and receive their answers. + */ + let thisObject = { + askPortfolioEventManager: askPortfolioEventManager, + askPortfolioFormulaManager: askPortfolioFormulaManager, + initialize: initialize, + finalize: finalize + } + + return thisObject + + function initialize() { + + } + + function finalize() { + + } + + async function askPortfolioEventManager(eventNode, conectInfo) { + console.log('here') + } + + async function askPortfolioFormulaManager() { + + } +} \ No newline at end of file diff --git a/Projects/Portfolio-Management/TS/Modules/PortfolioManagerEventsClient.js b/Projects/Portfolio-Management/TS/Modules/PortfolioManagerEventsClient.js new file mode 100644 index 000000000..df5d5a51a --- /dev/null +++ b/Projects/Portfolio-Management/TS/Modules/PortfolioManagerEventsClient.js @@ -0,0 +1,28 @@ +exports.newPortfolioManagementModulesPortfolioManagerEventsClient = function (processIndex) { + /* + This object represents the client to access the Portfolio Manager from a Trading Bot. + It is an events client because the communication with the Portfolio Manager happens + at the events layer, provided by the Events Server. + */ + let thisObject = { + sendMessage: sendMessage, + initialize: initialize, + finalize: finalize + } + + return thisObject + + function initialize() { + + } + + function finalize() { + + } + + async function sendMessage(message) { + + } + + +} \ No newline at end of file diff --git a/Projects/Portfolio-Management/TS/Modules/PortfolioManagerEventsInterface.js b/Projects/Portfolio-Management/TS/Modules/PortfolioManagerEventsInterface.js new file mode 100644 index 000000000..b3105f2f5 --- /dev/null +++ b/Projects/Portfolio-Management/TS/Modules/PortfolioManagerEventsInterface.js @@ -0,0 +1,20 @@ +exports.newPortfolioManagementModulesPortfolioManagerEventsInterface = function (processIndex) { + /* + This object represents the interface between the Portfolio Manager and Trading Bots. + It is an events based interface because the communicatin happens via the Events Server. + */ + let thisObject = { + initialize: initialize, + finalize: finalize + } + + return thisObject + + function initialize() { + + } + + function finalize() { + + } +} \ No newline at end of file diff --git a/Projects/ProjectsSchema.json b/Projects/ProjectsSchema.json index e81e1577a..527b02889 100644 --- a/Projects/ProjectsSchema.json +++ b/Projects/ProjectsSchema.json @@ -171,6 +171,26 @@ ] }, "TS": { + "modules": [ + { + "name": "Portfolio Manager Client", + "propertyName": "portfolioManagerClient", + "functionName": "newPortfolioManagementModulesPortfolioManagerClient", + "fileName": "PortfolioManagerClient.js" + }, + { + "name": "Portfolio Manager Events Client", + "propertyName": "portfolioManagerEventsClient", + "functionName": "newPortfolioManagementModulesPortfolioManagerEventsClient", + "fileName": "PortfolioManagerEventsClient.js" + }, + { + "name": "Portfolio Manager Events Interface", + "propertyName": "portfolioManagerEventsInterface", + "functionName": "newPortfolioManagementModulesPortfolioManagerEventsInterface", + "fileName": "PortfolioManagerEventsInterface.js" + } + ], "botModules": [ { "name": "PM Communication Module - Portfolio", @@ -1921,12 +1941,12 @@ "utilities": [] }, "TS": { - "botModules": [ + "modules": [ { - "name": "Trading Signals", - "propertyName": "tradingSignals", - "functionName": "newTradingSignalsBotModulesTradingSignals", - "fileName": "TradingSignals.js", + "name": "Outgoing Trading Signals", + "propertyName": "outgoingTradingSignals", + "functionName": "newTradingSignalsModulesOutgoingTradingSignals", + "fileName": "OutgoingTradingSignals.js", "folderName": "" } ] diff --git a/Projects/Trading-Signals/TS/Bot-Modules/TradingSignals.js b/Projects/Trading-Signals/TS/Bot-Modules/TradingSignals.js deleted file mode 100644 index 1ca3f825a..000000000 --- a/Projects/Trading-Signals/TS/Bot-Modules/TradingSignals.js +++ /dev/null @@ -1,129 +0,0 @@ -exports.newTradingSignalsBotModulesTradingSignals = function (processIndex) { - - let thisObject = { - makeAnnouncements: makeAnnouncements, - initialize: initialize, - finalize: finalize - } - - let tradingSystem - let tradingEngine - let sessionParameters - let taskParameters - - return thisObject - - function initialize() { - tradingSystem = TS.projects.foundations.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).SIMULATION_STATE.tradingSystem - tradingEngine = TS.projects.foundations.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).SIMULATION_STATE.tradingEngine - sessionParameters = TS.projects.foundations.globals.processConstants.CONSTANTS_BY_PROCESS_INDEX_MAP.get(processIndex).SESSION_NODE.tradingParameters - - - taskParameters = { - exchange: TS.projects.foundations.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.parentNode.parentNode.name, - market: TS.projects.foundations.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.baseAsset.referenceParent.config.codeName + - '/' + - TS.projects.foundations.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.quotedAsset.referenceParent.config.codeName - } - } - - function finalize() { - tradingSystem = undefined - tradingEngine = undefined - sessionParameters = undefined - taskParameters = undefined - TS.projects.foundations.globals.processConstants.CONSTANTS_BY_PROCESS_INDEX_MAP.get(processIndex).SESSION_NODE.messagesSent = undefined - } - - function makeAnnouncements(node, status='Open') { - if (node === undefined) { return } - if (node.announcements === undefined) { return } - - for (let i = 0; i < node.announcements.length; i++) { - let announcement = node.announcements[i] - let canAnnounce = true - - // Check configuration to see if Announcement should be run at Enter or Exit of Node - // set defaults, protect against empty configurations or missing values - let onEnter = true - let onExit = false - if (announcement.config.onEnter !== undefined) { - onEnter = announcement.config.onEnter - } - if (announcement.config.onExit !== undefined) { - onExit = announcement.config.onExit - if (announcement.config.onEnter === undefined) { - onEnter = false - } - } - if ((status === 'Open' && onEnter) || (status === 'Closed' && onExit)) { - canAnnounce = true - } else { - canAnnounce = false - } - - if (announcement.announcementCondition !== undefined) { - let conditionValue - try { - conditionValue = eval(announcement.announcementCondition.code) - } catch (err) { - - const message = 'Announcement Condition Evaluation Error' - let docs = { - project: 'Foundations', - category: 'Topic', - type: 'TS LF Trading Bot Error - ' + message, - placeholder: {} - } - - TS.projects.education.utilities.docsFunctions.buildPlaceholder(docs, err, announcement.announcementCondition.name, announcement.announcementCondition.code, undefined, undefined, undefined) - - tradingSystem.addError([announcement.announcementCondition.id, err.message, docs]) - } - if (conditionValue !== true) { canAnnounce = false } - } - if (canAnnounce === true) { - let text = announcement.config.text - if (announcement.announcementFormula !== undefined) { - let formulaValue - let errorMessage - - try { - formulaValue = eval(announcement.announcementFormula.code) - } catch (err) { - - errorMessage = err.message - const message = 'Announcement Formula Evaluation Error' - let docs = { - project: 'Foundations', - category: 'Topic', - type: 'TS LF Trading Bot Error - ' + message, - placeholder: {} - } - - TS.projects.education.utilities.docsFunctions.buildPlaceholder(docs, err, announcement.announcementFormula.name, announcement.announcementFormula.code, undefined, undefined, undefined) - - tradingSystem.addError([announcement.announcementFormula.id, err.message, docs]) - } - if (errorMessage == undefined) { text = formulaValue } - } - - if (TS.projects.foundations.globals.processConstants.CONSTANTS_BY_PROCESS_INDEX_MAP.get(processIndex).SESSION_NODE.socialBots !== undefined) { - TS.projects.foundations.globals.processConstants.CONSTANTS_BY_PROCESS_INDEX_MAP.get(processIndex).SESSION_NODE.socialBots.announce(text) - tradingSystem.announcements.push([announcement.id, text]) - } else { - - const message = 'Social Bots Node Missing' - let docs = { - project: 'Foundations', - category: 'Topic', - type: 'TS LF Trading Bot Error - ' + message, - placeholder: {} - } - - tradingSystem.addError([TS.projects.foundations.globals.processConstants.CONSTANTS_BY_PROCESS_INDEX_MAP.get(processIndex).SESSION_NODE.id, message, docs]) - } - } - } - } -} diff --git a/Projects/Trading-Signals/TS/Modules/OutgoingTradingSignals.js b/Projects/Trading-Signals/TS/Modules/OutgoingTradingSignals.js new file mode 100644 index 000000000..62dd6917a --- /dev/null +++ b/Projects/Trading-Signals/TS/Modules/OutgoingTradingSignals.js @@ -0,0 +1,22 @@ +exports.newTradingSignalsModulesOutgoingTradingSignals = function (processIndex) { + + let thisObject = { + broadcastSignal: broadcastSignal, + initialize: initialize, + finalize: finalize + } + + return thisObject + + function initialize() { + + } + + function finalize() { + } + + function broadcastSignal(node) { + if (node === undefined) { return } + if (node.outgoingSignals === undefined) { return } + } +}