Merge pull request #2776 from Luis-Fernando-Molina/develop

Contribution: Integration of Trading Bot with Portfolio Manager Part 1
This commit is contained in:
Luis Fernando Molina authored and GitHub committed 2021-11-29 11:43:59 -04:00
commit 0bea7d4ff4
11 files changed
+720 -4490

No files matched your search

@@ -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)
@@ -97,15 +99,15 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
tradingPositionModuleObject.cycleBasedStatistics()
}
function runTriggerStage() {
async function runTriggerStage() {
/*
We check if we will be triggering on, off or taking position.
*/
checkTriggerOn()
checkTriggerOff()
checkTakePosition()
await checkTriggerOn()
await checkTriggerOff()
await checkTakePosition()
function checkTriggerOn() {
async function checkTriggerOn() {
if (
tradingEngine.tradingCurrent.strategy.index.value === tradingEngine.tradingCurrent.strategy.index.config.initialValue
) {
@@ -137,7 +139,12 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
passed = tradingSystem.checkConditions(situation, passed)
tradingSystem.values.push([situation.id, passed])
let response = await portfolioManagerClient.askPortfolioEventsManager(triggerStage.triggerOn, passed)
passed = response.raiseEvent
if (passed) {
tradingSystem.highlights.push(situation.id)
tradingSystem.highlights.push(triggerStage.triggerOn.id)
tradingSystem.highlights.push(triggerStage.id)
@@ -147,6 +154,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 +164,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
}
}
}
changeStageStatus('Trigger Stage', 'Open')
}
}
}
@@ -167,7 +173,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
}
}
function checkTriggerOff() {
async function checkTriggerOff() {
if (tradingEngine.tradingCurrent.strategyTriggerStage.status.value === 'Open') {
checkUserDefinedCode('Trigger Stage', 'Running', 'first');
@@ -188,12 +194,18 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
passed = tradingSystem.checkConditions(situation, passed)
tradingSystem.values.push([situation.id, passed])
let response = await portfolioManagerClient.askPortfolioEventsManager(triggerStage.triggerOff, passed)
passed = response.raiseEvent
if (passed) {
tradingSystem.highlights.push(situation.id)
tradingSystem.highlights.push(triggerStage.triggerOff.id)
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')
@@ -204,7 +216,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
}
}
function checkTakePosition() {
async function checkTakePosition() {
if (
tradingEngine.tradingCurrent.strategyTriggerStage.status.value === 'Open'
) {
@@ -212,7 +224,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
let triggerStage = strategy.triggerStage
tradingSystem.evalConditions(strategy, 'Take Position Event')
tradingSystem.evalFormulas(strategy, 'Take Position Event')
await tradingSystem.evalFormulas(strategy, 'Take Position Event')
if (triggerStage !== undefined) {
if (triggerStage.takePosition !== undefined) {
@@ -226,6 +238,10 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
passed = tradingSystem.checkConditions(situation, passed)
tradingSystem.values.push([situation.id, passed])
let response = await portfolioManagerClient.askPortfolioEventsManager(triggerStage.takePosition, passed)
passed = response.raiseEvent
if (passed) {
tradingSystem.highlights.push(situation.id)
tradingSystem.highlights.push(triggerStage.takePosition.id)
@@ -233,6 +249,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') {
@@ -259,14 +276,14 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
async function runOpenStage() {
checkIfWeNeedToAbortTheStage()
runWhenStatusIsOpening()
await runWhenStatusIsOpening()
await runWhenStatusIsOpen()
await runWhenStatusIsClosing()
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,
@@ -276,7 +293,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
}
}
function runWhenStatusIsOpening() {
async function runWhenStatusIsOpening() {
/* Opening Status Procedure */
if (tradingEngine.tradingCurrent.strategyOpenStage.status.value === 'Opening') {
/*
@@ -298,7 +315,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
TS.projects.foundations.globals.processModuleObjects.MODULE_OBJECTS_BY_PROCESS_INDEX_MAP.get(processIndex).TRADING_ENGINE_MODULE_OBJECT.initializeNode(tradingEngine.exchangeOrders)
/* Entry Position size and rate */
tradingSystem.evalFormulas(tradingSystemStage, 'Initial Targets')
await tradingSystem.evalFormulas(tradingSystemStage, 'Initial Targets')
tradingPositionModuleObject.initialTargets(tradingSystemStage, tradingEngineStage)
initializeStageTargetSize()
@@ -321,7 +338,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
/* Evaluate conditions and formulas so they are ready during the execution run */
tradingSystem.evalConditions(executionNode, 'Open Execution')
tradingSystem.evalFormulas(executionNode, 'Open Execution')
await tradingSystem.evalFormulas(executionNode, 'Open Execution')
await tradingExecutionModuleObject.runExecution(
executionNode,
@@ -331,7 +348,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');
}
}
}
@@ -351,7 +368,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
and cancel the ones that were not.
*/
tradingSystem.evalConditions(tradingSystemStage, 'Open Execution')
tradingSystem.evalFormulas(tradingSystemStage, 'Open Execution')
await tradingSystem.evalFormulas(tradingSystemStage, 'Open Execution')
await tradingExecutionModuleObject.runExecution(
executionNode,
@@ -407,12 +424,12 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
}
}
function runManageStage() {
async function runManageStage() {
if (tradingEngine.tradingCurrent.tradingEpisode.cycle.value !== 'First') { return }
runWhenStatusIsOpening()
runWhenStatusIsOpen()
await runWhenStatusIsOpen()
function runWhenStatusIsOpening() {
/* Opening Status Procedure */
@@ -438,7 +455,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
}
}
function runWhenStatusIsOpen() {
async function runWhenStatusIsOpen() {
/* Open Status Procedure */
if (tradingEngine.tradingCurrent.strategyManageStage.status.value === 'Open') {
checkUserDefinedCode('Manage Stage', 'Running', 'first');
@@ -447,7 +464,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
/* Evaluate all the stage conditions and formulas to have them ready */
tradingSystem.evalConditions(manageStage, 'Manage Stage')
tradingSystem.evalFormulas(manageStage, 'Manage Stage')
await tradingSystem.evalFormulas(manageStage, 'Manage Stage')
/* Stop Loss Management */
checkStopPhasesEvents()
@@ -464,7 +481,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 +713,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 +765,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
continue
}
outgoingTradingSignalsModuleObject.broadcastSignal(moveToPhaseEvent)
announcementsModuleObject.makeAnnouncements(moveToPhaseEvent)
/* Reset this counter */
@@ -810,11 +829,11 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
async function runCloseStage() {
runWhenStatusIsOpening()
await runWhenStatusIsOpening()
await runWhenStatusIsOpen()
await runWhenStatusIsClosing()
function runWhenStatusIsOpening() {
async function runWhenStatusIsOpening() {
/* Opening Status Procedure */
if (tradingEngine.tradingCurrent.strategyCloseStage.status.value === 'Opening') {
@@ -834,7 +853,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
let tradingSystemStage = tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].closeStage
/* Exit Position size and rate */
tradingSystem.evalFormulas(tradingSystemStage, 'Initial Targets')
await tradingSystem.evalFormulas(tradingSystemStage, 'Initial Targets')
if (tradingPositionModuleObject.initialTargets(tradingSystemStage, tradingEngine.tradingCurrent.strategyCloseStage, 'Close Stage') === false) {
//console.log("No Close-Stage Target Asset to Trade: Strategy Closing.");
}
@@ -866,7 +885,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
let executionNode = tradingSystemStage.closeExecution
tradingSystem.evalConditions(tradingSystemStage, 'Close Execution')
tradingSystem.evalFormulas(tradingSystemStage, 'Close Execution')
await tradingSystem.evalFormulas(tradingSystemStage, 'Close Execution')
await tradingExecutionModuleObject.runExecution(
executionNode,
@@ -876,7 +895,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');
}
}
}
@@ -896,7 +915,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
and cancel the ones that were not.
*/
tradingSystem.evalConditions(tradingSystemStage, 'Close Execution')
tradingSystem.evalFormulas(tradingSystemStage, 'Close Execution')
await tradingSystem.evalFormulas(tradingSystemStage, 'Close Execution')
await tradingExecutionModuleObject.runExecution(
executionNode,
@@ -1108,6 +1127,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 +1192,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 +1292,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 +1325,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;
}
}
}
}
@@ -27,6 +27,7 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
let dynamicIndicators
let tradingStagesModuleObject = TS.projects.algorithmicTrading.botModules.tradingStages.newAlgorithmicTradingBotModulesTradingStages(processIndex)
let portfolioManagerClient = TS.projects.portfolioManagement.modules.portfolioManagerClient.newPortfolioManagementModulesPortfolioManagerClient(processIndex)
let taskParameters = {
market: TS.projects.foundations.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.baseAsset.referenceParent.config.codeName +
@@ -70,12 +71,12 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
evalNode(startingNode, 'Conditions', descendentOfNodeType)
}
tradingSystem.evalFormulas = function (startingNode, descendentOfNodeType) {
evalNode(startingNode, 'Formulas', descendentOfNodeType)
tradingSystem.evalFormulas = async function (startingNode, descendentOfNodeType) {
await evalNode(startingNode, 'Formulas', descendentOfNodeType)
}
tradingSystem.evalUserCode = function (startingNode, descendentOfNodeType) {
evalNode(startingNode, 'User Codes', descendentOfNodeType);
evalNode(startingNode, 'User Codes', descendentOfNodeType);
}
tradingSystem.addError = function (errorDataArray) {
@@ -203,13 +204,13 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
buildDynamicIndicators()
/* Run the Trigger Stage */
tradingStagesModuleObject.runTriggerStage()
await tradingStagesModuleObject.runTriggerStage()
/* Run the Open Stage */
await tradingStagesModuleObject.runOpenStage()
/* Run the Manage Stage */
tradingStagesModuleObject.runManageStage()
await tradingStagesModuleObject.runManageStage()
/* Run the Close Stage */
await tradingStagesModuleObject.runCloseStage()
@@ -234,7 +235,7 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
}
}
function evalNode(node, evaluating, descendentOfNodeType, isDescendent) {
async function evalNode(node, evaluating, descendentOfNodeType, isDescendent, parentNode) {
if (node === undefined) { return }
/* Verify if this node is descendent of the specified node type */
@@ -257,18 +258,18 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
if (node.code !== undefined) {
/* We will eval this formula */
if (isDescendent === true) {
evalFormula(node)
await evalFormula(node, parentNode)
}
}
}
/* Here we check if there is a User Defined-Javascript Code to be evaluated: */
if (node.type === 'Javascript Code' && evaluating === 'User Codes') {
if (node.code !== undefined) {
if (isDescendent === true) {
evalJSCode(node);
if (node.code !== undefined) {
if (isDescendent === true) {
evalJSCode(node);
}
}
}
}
/* Now we go down through all this node children */
@@ -284,7 +285,7 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
case 'node': {
if (property.name !== previousPropertyName) {
if (node[property.name] !== undefined) {
evalNode(node[property.name], evaluating, descendentOfNodeType, isDescendent)
await evalNode(node[property.name], evaluating, descendentOfNodeType, isDescendent, node)
}
previousPropertyName = property.name
}
@@ -294,7 +295,7 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
if (node[property.name] !== undefined) {
let nodePropertyArray = node[property.name]
for (let m = 0; m < nodePropertyArray.length; m++) {
evalNode(nodePropertyArray[m], evaluating, descendentOfNodeType, isDescendent)
await evalNode(nodePropertyArray[m], evaluating, descendentOfNodeType, isDescendent, node)
}
}
break
@@ -357,7 +358,7 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
TS.projects.foundations.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, '[INFO] evalCondition -> value = ' + value)
}
function evalFormula(node) {
async function evalFormula(node, parentNode) {
let value
let errorMessage
let docs
@@ -365,6 +366,10 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
try {
TS.projects.foundations.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, '[INFO] evalFormula -> ' + node.name + ' -> code = ' + node.code)
value = eval(node.code)
let response = await portfolioManagerClient.askPortfolioFormulaManager(parentNode, value)
value = response.value
} catch (err) {
/*
One possible error is that the formula references a .previous that is undefined. This
@@ -423,29 +428,29 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
}
function evalJSCode(node) {
let value
let errorMessage
let docs
let value
let errorMessage
let docs
try {
value = eval(node.code);
try {
value = eval(node.code);
} catch (err) {
value = 0
errorMessage = err.message
docs = {
project: 'Foundations',
category: 'Topic',
type: 'TS LF Trading Bot Error - Evaluating User Code Error',
placeholder: {}
} catch (err) {
value = 0
errorMessage = err.message
docs = {
project: 'Foundations',
category: 'Topic',
type: 'TS LF Trading Bot Error - Evaluating User Code Error',
placeholder: {}
}
TS.projects.education.utilities.docsFunctions.buildPlaceholder(docs, err, node.name, node.code, undefined)
}
TS.projects.education.utilities.docsFunctions.buildPlaceholder(docs, err, node.name, node.code, undefined)
}
if (errorMessage !== undefined) {
tradingSystem.addError([node.id, errorMessage, docs])
TS.projects.foundations.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, '[INFO] evalFormula -> errorMessage = ' + errorMessage)
return
}
if (errorMessage !== undefined) {
tradingSystem.addError([node.id, errorMessage, docs])
TS.projects.foundations.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, '[INFO] evalFormula -> errorMessage = ' + errorMessage)
return
}
}
}
@@ -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
@@ -2343,7 +2343,7 @@
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"isCollapsed": true,
"angleToParent": 1,
"distanceToParent": 3,
"arrangementStyle": 0
@@ -0,0 +1,101 @@
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 = {
askPortfolioEventsManager: askPortfolioEventsManager,
askPortfolioFormulaManager: askPortfolioFormulaManager,
initialize: initialize,
finalize: finalize
}
return thisObject
function initialize() {
}
function finalize() {
}
async function askPortfolioEventsManager(eventNode, eventStatus) {
let response = {
raiseEvent: eventStatus,
reason: "No need to ask Portfolio Manager"
}
if (eventNode.askPortfolioEventsManager === undefined) {
return response
}
if (eventStatus === true) {
/*
First we will check if the Portfolio Manager confirms this event
can be raised.
*/
if (eventNode.askPortfolioEventsManager.confirmEvent !== undefined) {
let message = {
question: "Confirm This Event Can Be Raised",
event: eventNode.type
}
response = await portfolioManagerEventsClient.sendMessage(message)
}
} else {
/*
In this case, we will check if the Porfolio Manager would like to
raise this event anyways.
*/
if (eventNode.askPortfolioEventsManager.raiseEvent !== undefined) {
let message = {
question: "Must This Event Be Raised",
event: eventNode.type
}
response = await portfolioManagerEventsClient.sendMessage(message)
}
}
return response
}
async function askPortfolioFormulaManager(formulaParentNode, formulaValue) {
let response = {
value: formulaValue,
reason: "No need to ask Portfolio Manager"
}
if (formulaParentNode === undefined) {
return response
}
if (formulaParentNode.askPortfolioFormulaManager === undefined) {
return response
}
if (formulaValue === true) {
/*
First we will check if the Portfolio Manager confirms this formula
value.
*/
if (formulaParentNode.askPortfolioEventsManager.confirmFormula !== undefined) {
let message = {
question: "Confirm This Formula Value",
formula: formulaParentNode.type
}
response = await portfolioManagerEventsClient.sendMessage(message)
}
} else {
/*
In this case, we will check if the Porfolio Manager would like to
replace this formula value for something else.
*/
if (formulaParentNode.askPortfolioEventsManager.raiseEvent !== undefined) {
let message = {
question: "Give me a Value for this Formula",
formula: formulaParentNode.type
}
response = await portfolioManagerEventsClient.sendMessage(message)
}
}
return response
}
}
@@ -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) {
}
}
@@ -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() {
}
}
+25 -5
View File
@@ -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": ""
}
]
@@ -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])
}
}
}
}
}
@@ -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 }
}
}