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 tradingPositionModuleObject = TS.projects.algorithmicTrading.botModules.tradingPosition.newAlgorithmicTradingBotModulesTradingPosition(processIndex)
let tradingExecutionModuleObject = TS.projects.algorithmicTrading.botModules.tradingExecution.newAlgorithmicTradingBotModulesTradingExecution(processIndex) let tradingExecutionModuleObject = TS.projects.algorithmicTrading.botModules.tradingExecution.newAlgorithmicTradingBotModulesTradingExecution(processIndex)
let announcementsModuleObject = TS.projects.socialBots.botModules.announcements.newSocialBotsBotModulesAnnouncements(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 snapshotsModuleObject = TS.projects.algorithmicTrading.botModules.snapshots.newAlgorithmicTradingBotModulesSnapshots(processIndex)
let tradingEpisodeModuleObject = TS.projects.algorithmicTrading.botModules.tradingEpisode.newAlgorithmicTradingBotModulesTradingEpisode(processIndex) let tradingEpisodeModuleObject = TS.projects.algorithmicTrading.botModules.tradingEpisode.newAlgorithmicTradingBotModulesTradingEpisode(processIndex)
@@ -97,15 +99,15 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
tradingPositionModuleObject.cycleBasedStatistics() tradingPositionModuleObject.cycleBasedStatistics()
} }
function runTriggerStage() { async function runTriggerStage() {
/* /*
We check if we will be triggering on, off or taking position. We check if we will be triggering on, off or taking position.
*/ */
checkTriggerOn() await checkTriggerOn()
checkTriggerOff() await checkTriggerOff()
checkTakePosition() await checkTakePosition()
function checkTriggerOn() { async function checkTriggerOn() {
if ( if (
tradingEngine.tradingCurrent.strategy.index.value === tradingEngine.tradingCurrent.strategy.index.config.initialValue tradingEngine.tradingCurrent.strategy.index.value === tradingEngine.tradingCurrent.strategy.index.config.initialValue
) { ) {
@@ -137,7 +139,12 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
passed = tradingSystem.checkConditions(situation, passed) passed = tradingSystem.checkConditions(situation, passed)
tradingSystem.values.push([situation.id, passed]) tradingSystem.values.push([situation.id, passed])
let response = await portfolioManagerClient.askPortfolioEventsManager(triggerStage.triggerOn, passed)
passed = response.raiseEvent
if (passed) { if (passed) {
tradingSystem.highlights.push(situation.id) tradingSystem.highlights.push(situation.id)
tradingSystem.highlights.push(triggerStage.triggerOn.id) tradingSystem.highlights.push(triggerStage.triggerOn.id)
tradingSystem.highlights.push(triggerStage.id) tradingSystem.highlights.push(triggerStage.id)
@@ -147,6 +154,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
/* Initialize this */ /* Initialize this */
tradingEngine.tradingCurrent.tradingEpisode.distanceToTradingEvent.triggerOn.value = 1 tradingEngine.tradingCurrent.tradingEpisode.distanceToTradingEvent.triggerOn.value = 1
outgoingTradingSignalsModuleObject.broadcastSignal(triggerStage.triggerOn)
announcementsModuleObject.makeAnnouncements(triggerStage.triggerOn) announcementsModuleObject.makeAnnouncements(triggerStage.triggerOn)
if (TS.projects.foundations.globals.processConstants.CONSTANTS_BY_PROCESS_INDEX_MAP.get(processIndex).SESSION_NODE.type === 'Backtesting Session') { 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') changeStageStatus('Trigger Stage', 'Open')
} }
} }
} }
@@ -167,7 +173,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
} }
} }
function checkTriggerOff() { async function checkTriggerOff() {
if (tradingEngine.tradingCurrent.strategyTriggerStage.status.value === 'Open') { if (tradingEngine.tradingCurrent.strategyTriggerStage.status.value === 'Open') {
checkUserDefinedCode('Trigger Stage', 'Running', 'first'); checkUserDefinedCode('Trigger Stage', 'Running', 'first');
@@ -188,12 +194,18 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
passed = tradingSystem.checkConditions(situation, passed) passed = tradingSystem.checkConditions(situation, passed)
tradingSystem.values.push([situation.id, passed]) tradingSystem.values.push([situation.id, passed])
let response = await portfolioManagerClient.askPortfolioEventsManager(triggerStage.triggerOff, passed)
passed = response.raiseEvent
if (passed) { if (passed) {
tradingSystem.highlights.push(situation.id) tradingSystem.highlights.push(situation.id)
tradingSystem.highlights.push(triggerStage.triggerOff.id) tradingSystem.highlights.push(triggerStage.triggerOff.id)
tradingSystem.highlights.push(triggerStage.id) tradingSystem.highlights.push(triggerStage.id)
tradingEngine.tradingCurrent.tradingEpisode.distanceToTradingEvent.triggerOff.value = 1 tradingEngine.tradingCurrent.tradingEpisode.distanceToTradingEvent.triggerOff.value = 1
outgoingTradingSignalsModuleObject.broadcastSignal(triggerStage.triggerOff)
announcementsModuleObject.makeAnnouncements(triggerStage.triggerOff) announcementsModuleObject.makeAnnouncements(triggerStage.triggerOff)
changeStageStatus('Trigger Stage', 'Closed', 'Trigger Off Event') changeStageStatus('Trigger Stage', 'Closed', 'Trigger Off Event')
tradingStrategyModuleObject.closeStrategy('Trigger Off') tradingStrategyModuleObject.closeStrategy('Trigger Off')
@@ -204,7 +216,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
} }
} }
function checkTakePosition() { async function checkTakePosition() {
if ( if (
tradingEngine.tradingCurrent.strategyTriggerStage.status.value === 'Open' tradingEngine.tradingCurrent.strategyTriggerStage.status.value === 'Open'
) { ) {
@@ -212,7 +224,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
let triggerStage = strategy.triggerStage let triggerStage = strategy.triggerStage
tradingSystem.evalConditions(strategy, 'Take Position Event') tradingSystem.evalConditions(strategy, 'Take Position Event')
tradingSystem.evalFormulas(strategy, 'Take Position Event') await tradingSystem.evalFormulas(strategy, 'Take Position Event')
if (triggerStage !== undefined) { if (triggerStage !== undefined) {
if (triggerStage.takePosition !== undefined) { if (triggerStage.takePosition !== undefined) {
@@ -226,6 +238,10 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
passed = tradingSystem.checkConditions(situation, passed) passed = tradingSystem.checkConditions(situation, passed)
tradingSystem.values.push([situation.id, passed]) tradingSystem.values.push([situation.id, passed])
let response = await portfolioManagerClient.askPortfolioEventsManager(triggerStage.takePosition, passed)
passed = response.raiseEvent
if (passed) { if (passed) {
tradingSystem.highlights.push(situation.id) tradingSystem.highlights.push(situation.id)
tradingSystem.highlights.push(triggerStage.takePosition.id) tradingSystem.highlights.push(triggerStage.takePosition.id)
@@ -233,6 +249,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
tradingPositionModuleObject.openPosition(situation.name) tradingPositionModuleObject.openPosition(situation.name)
outgoingTradingSignalsModuleObject.broadcastSignal(triggerStage.takePosition)
announcementsModuleObject.makeAnnouncements(triggerStage.takePosition) announcementsModuleObject.makeAnnouncements(triggerStage.takePosition)
if (TS.projects.foundations.globals.processConstants.CONSTANTS_BY_PROCESS_INDEX_MAP.get(processIndex).SESSION_NODE.type === 'Backtesting Session') { 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() { async function runOpenStage() {
checkIfWeNeedToAbortTheStage() checkIfWeNeedToAbortTheStage()
runWhenStatusIsOpening() await runWhenStatusIsOpening()
await runWhenStatusIsOpen() await runWhenStatusIsOpen()
await runWhenStatusIsClosing() await runWhenStatusIsClosing()
function checkIfWeNeedToAbortTheStage() { function checkIfWeNeedToAbortTheStage() {
/* Abort Open Stage Check */ /* Abort Open Stage Check */
if (tradingEngine.tradingCurrent.strategyOpenStage.status.value === 'Open' && 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 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, 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 */ /* Opening Status Procedure */
if (tradingEngine.tradingCurrent.strategyOpenStage.status.value === 'Opening') { 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) 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 */ /* Entry Position size and rate */
tradingSystem.evalFormulas(tradingSystemStage, 'Initial Targets') await tradingSystem.evalFormulas(tradingSystemStage, 'Initial Targets')
tradingPositionModuleObject.initialTargets(tradingSystemStage, tradingEngineStage) tradingPositionModuleObject.initialTargets(tradingSystemStage, tradingEngineStage)
initializeStageTargetSize() initializeStageTargetSize()
@@ -321,7 +338,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
/* Evaluate conditions and formulas so they are ready during the execution run */ /* Evaluate conditions and formulas so they are ready during the execution run */
tradingSystem.evalConditions(executionNode, 'Open Execution') tradingSystem.evalConditions(executionNode, 'Open Execution')
tradingSystem.evalFormulas(executionNode, 'Open Execution') await tradingSystem.evalFormulas(executionNode, 'Open Execution')
await tradingExecutionModuleObject.runExecution( await tradingExecutionModuleObject.runExecution(
executionNode, executionNode,
@@ -331,7 +348,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
/* User Defined Code if runWhileAtStage==true */ /* User Defined Code if runWhileAtStage==true */
if (tradingEngine.tradingCurrent.strategyOpenStage.status.value === 'Open') { 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. and cancel the ones that were not.
*/ */
tradingSystem.evalConditions(tradingSystemStage, 'Open Execution') tradingSystem.evalConditions(tradingSystemStage, 'Open Execution')
tradingSystem.evalFormulas(tradingSystemStage, 'Open Execution') await tradingSystem.evalFormulas(tradingSystemStage, 'Open Execution')
await tradingExecutionModuleObject.runExecution( await tradingExecutionModuleObject.runExecution(
executionNode, executionNode,
@@ -407,12 +424,12 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
} }
} }
function runManageStage() { async function runManageStage() {
if (tradingEngine.tradingCurrent.tradingEpisode.cycle.value !== 'First') { return } if (tradingEngine.tradingCurrent.tradingEpisode.cycle.value !== 'First') { return }
runWhenStatusIsOpening() runWhenStatusIsOpening()
runWhenStatusIsOpen() await runWhenStatusIsOpen()
function runWhenStatusIsOpening() { function runWhenStatusIsOpening() {
/* Opening Status Procedure */ /* Opening Status Procedure */
@@ -438,7 +455,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
} }
} }
function runWhenStatusIsOpen() { async function runWhenStatusIsOpen() {
/* Open Status Procedure */ /* Open Status Procedure */
if (tradingEngine.tradingCurrent.strategyManageStage.status.value === 'Open') { if (tradingEngine.tradingCurrent.strategyManageStage.status.value === 'Open') {
checkUserDefinedCode('Manage Stage', 'Running', 'first'); checkUserDefinedCode('Manage Stage', 'Running', 'first');
@@ -447,7 +464,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
/* Evaluate all the stage conditions and formulas to have them ready */ /* Evaluate all the stage conditions and formulas to have them ready */
tradingSystem.evalConditions(manageStage, 'Manage Stage') tradingSystem.evalConditions(manageStage, 'Manage Stage')
tradingSystem.evalFormulas(manageStage, 'Manage Stage') await tradingSystem.evalFormulas(manageStage, 'Manage Stage')
/* Stop Loss Management */ /* Stop Loss Management */
checkStopPhasesEvents() checkStopPhasesEvents()
@@ -464,7 +481,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
/* If User Defined Code exists check for runWhileAtStage */ /* If User Defined Code exists check for runWhileAtStage */
if (tradingEngine.tradingCurrent.strategyManageStage.status.value === 'Open') { 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) tradingPositionModuleObject.updateTakeProfit(tradingEngine.tradingCurrent.position.takeProfit.takeProfitPhase.value + 1)
outgoingTradingSignalsModuleObject.broadcastSignal(nextPhaseEvent)
announcementsModuleObject.makeAnnouncements(nextPhaseEvent) announcementsModuleObject.makeAnnouncements(nextPhaseEvent)
/* Reset this counter */ /* Reset this counter */
@@ -747,6 +765,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
continue continue
} }
outgoingTradingSignalsModuleObject.broadcastSignal(moveToPhaseEvent)
announcementsModuleObject.makeAnnouncements(moveToPhaseEvent) announcementsModuleObject.makeAnnouncements(moveToPhaseEvent)
/* Reset this counter */ /* Reset this counter */
@@ -810,11 +829,11 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
async function runCloseStage() { async function runCloseStage() {
runWhenStatusIsOpening() await runWhenStatusIsOpening()
await runWhenStatusIsOpen() await runWhenStatusIsOpen()
await runWhenStatusIsClosing() await runWhenStatusIsClosing()
function runWhenStatusIsOpening() { async function runWhenStatusIsOpening() {
/* Opening Status Procedure */ /* Opening Status Procedure */
if (tradingEngine.tradingCurrent.strategyCloseStage.status.value === 'Opening') { 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 let tradingSystemStage = tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].closeStage
/* Exit Position size and rate */ /* 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) { if (tradingPositionModuleObject.initialTargets(tradingSystemStage, tradingEngine.tradingCurrent.strategyCloseStage, 'Close Stage') === false) {
//console.log("No Close-Stage Target Asset to Trade: Strategy Closing."); //console.log("No Close-Stage Target Asset to Trade: Strategy Closing.");
} }
@@ -866,7 +885,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
let executionNode = tradingSystemStage.closeExecution let executionNode = tradingSystemStage.closeExecution
tradingSystem.evalConditions(tradingSystemStage, 'Close Execution') tradingSystem.evalConditions(tradingSystemStage, 'Close Execution')
tradingSystem.evalFormulas(tradingSystemStage, 'Close Execution') await tradingSystem.evalFormulas(tradingSystemStage, 'Close Execution')
await tradingExecutionModuleObject.runExecution( await tradingExecutionModuleObject.runExecution(
executionNode, executionNode,
@@ -876,7 +895,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
checkIfStageNeedsToBeClosed(tradingEngineStage, tradingSystemStage, 'Close Stage') checkIfStageNeedsToBeClosed(tradingEngineStage, tradingSystemStage, 'Close Stage')
/* If User Defined Code exists check for runWhileAtStage */ /* If User Defined Code exists check for runWhileAtStage */
if (tradingEngine.tradingCurrent.strategyCloseStage.status.value === 'Open') { 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. and cancel the ones that were not.
*/ */
tradingSystem.evalConditions(tradingSystemStage, 'Close Execution') tradingSystem.evalConditions(tradingSystemStage, 'Close Execution')
tradingSystem.evalFormulas(tradingSystemStage, 'Close Execution') await tradingSystem.evalFormulas(tradingSystemStage, 'Close Execution')
await tradingExecutionModuleObject.runExecution( await tradingExecutionModuleObject.runExecution(
executionNode, executionNode,
@@ -1108,6 +1127,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
tradingSystem.highlights.push(closeStageEvent.id) tradingSystem.highlights.push(closeStageEvent.id)
tradingSystem.highlights.push(stage.id) tradingSystem.highlights.push(stage.id)
outgoingTradingSignalsModuleObject.broadcastSignal(closeStageEvent)
announcementsModuleObject.makeAnnouncements(closeStageEvent) announcementsModuleObject.makeAnnouncements(closeStageEvent)
return true return true
} }
@@ -1172,7 +1192,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
/* Recording the closing at the Trading Engine Data Structure */ /* Recording the closing at the Trading Engine Data Structure */
stage.end.value = tradingEngine.tradingCurrent.tradingEpisode.cycle.lastEnd.value stage.end.value = tradingEngine.tradingCurrent.tradingEpisode.cycle.lastEnd.value
stage.endRate.value = tradingEngine.tradingCurrent.tradingEpisode.candle.close.value stage.endRate.value = tradingEngine.tradingCurrent.tradingEpisode.candle.close.value
if (stageName === 'Open Stage') { if (stageName === 'Open Stage') {
if (tradingEngine.tradingCurrent.strategyCloseStage.status.value !== 'Opening' && tradingEngine.tradingCurrent.strategyCloseStage.status.value !== 'Open' && 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') { tradingEngine.tradingCurrent.strategyManageStage.status.value !== 'Opening' && tradingEngine.tradingCurrent.strategyManageStage.status.value !== 'Open') {
@@ -1272,20 +1292,20 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
tradingSystemStage.userDefinedCode !== undefined) { tradingSystemStage.userDefinedCode !== undefined) {
if (status === 'Running' && when !== tradingSystemStage.userDefinedCode.config.whileAtStageWhenToRun) { return; } if (status === 'Running' && when !== tradingSystemStage.userDefinedCode.config.whileAtStageWhenToRun) { return; }
switch(status) { switch (status) {
case 'Open' : { case 'Open': {
if (tradingSystemStage.userDefinedCode.config.runWhenEnteringStage) { if (tradingSystemStage.userDefinedCode.config.runWhenEnteringStage) {
tradingSystem.evalUserCode(tradingSystemStage, 'User Defined Code'); tradingSystem.evalUserCode(tradingSystemStage, 'User Defined Code');
} }
break; break;
} }
case 'Running' : { case 'Running': {
if (tradingSystemStage.userDefinedCode.config.runWhileAtStage) { if (tradingSystemStage.userDefinedCode.config.runWhileAtStage) {
tradingSystem.evalUserCode(tradingSystemStage, 'User Defined Code'); tradingSystem.evalUserCode(tradingSystemStage, 'User Defined Code');
} }
break; break;
} }
case 'Closed' : { case 'Closed': {
if (tradingSystemStage.userDefinedCode.config.runWhenExitingStage) { if (tradingSystemStage.userDefinedCode.config.runWhenExitingStage) {
tradingSystem.evalUserCode(tradingSystemStage, 'User Defined Code'); tradingSystem.evalUserCode(tradingSystemStage, 'User Defined Code');
} }
@@ -1305,23 +1325,23 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
/* getTradingSystemStage(): takes stage name returns stage object. */ /* getTradingSystemStage(): takes stage name returns stage object. */
function getTradingSystemStage(stage) { function getTradingSystemStage(stage) {
switch(stage) { switch (stage) {
case 'Trigger Stage' : { case 'Trigger Stage': {
return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].triggerStage; return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].triggerStage;
break; 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 dynamicIndicators
let tradingStagesModuleObject = TS.projects.algorithmicTrading.botModules.tradingStages.newAlgorithmicTradingBotModulesTradingStages(processIndex) let tradingStagesModuleObject = TS.projects.algorithmicTrading.botModules.tradingStages.newAlgorithmicTradingBotModulesTradingStages(processIndex)
let portfolioManagerClient = TS.projects.portfolioManagement.modules.portfolioManagerClient.newPortfolioManagementModulesPortfolioManagerClient(processIndex)
let taskParameters = { let taskParameters = {
market: TS.projects.foundations.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.baseAsset.referenceParent.config.codeName + 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) evalNode(startingNode, 'Conditions', descendentOfNodeType)
} }
tradingSystem.evalFormulas = function (startingNode, descendentOfNodeType) { tradingSystem.evalFormulas = async function (startingNode, descendentOfNodeType) {
evalNode(startingNode, 'Formulas', descendentOfNodeType) await evalNode(startingNode, 'Formulas', descendentOfNodeType)
} }
tradingSystem.evalUserCode = function (startingNode, descendentOfNodeType) { tradingSystem.evalUserCode = function (startingNode, descendentOfNodeType) {
evalNode(startingNode, 'User Codes', descendentOfNodeType); evalNode(startingNode, 'User Codes', descendentOfNodeType);
} }
tradingSystem.addError = function (errorDataArray) { tradingSystem.addError = function (errorDataArray) {
@@ -203,13 +204,13 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
buildDynamicIndicators() buildDynamicIndicators()
/* Run the Trigger Stage */ /* Run the Trigger Stage */
tradingStagesModuleObject.runTriggerStage() await tradingStagesModuleObject.runTriggerStage()
/* Run the Open Stage */ /* Run the Open Stage */
await tradingStagesModuleObject.runOpenStage() await tradingStagesModuleObject.runOpenStage()
/* Run the Manage Stage */ /* Run the Manage Stage */
tradingStagesModuleObject.runManageStage() await tradingStagesModuleObject.runManageStage()
/* Run the Close Stage */ /* Run the Close Stage */
await tradingStagesModuleObject.runCloseStage() 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 } if (node === undefined) { return }
/* Verify if this node is descendent of the specified node type */ /* Verify if this node is descendent of the specified node type */
@@ -257,18 +258,18 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
if (node.code !== undefined) { if (node.code !== undefined) {
/* We will eval this formula */ /* We will eval this formula */
if (isDescendent === true) { if (isDescendent === true) {
evalFormula(node) await evalFormula(node, parentNode)
} }
} }
} }
/* Here we check if there is a User Defined-Javascript Code to be evaluated: */ /* Here we check if there is a User Defined-Javascript Code to be evaluated: */
if (node.type === 'Javascript Code' && evaluating === 'User Codes') { if (node.type === 'Javascript Code' && evaluating === 'User Codes') {
if (node.code !== undefined) { if (node.code !== undefined) {
if (isDescendent === true) { if (isDescendent === true) {
evalJSCode(node); evalJSCode(node);
}
} }
}
} }
/* Now we go down through all this node children */ /* Now we go down through all this node children */
@@ -284,7 +285,7 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
case 'node': { case 'node': {
if (property.name !== previousPropertyName) { if (property.name !== previousPropertyName) {
if (node[property.name] !== undefined) { if (node[property.name] !== undefined) {
evalNode(node[property.name], evaluating, descendentOfNodeType, isDescendent) await evalNode(node[property.name], evaluating, descendentOfNodeType, isDescendent, node)
} }
previousPropertyName = property.name previousPropertyName = property.name
} }
@@ -294,7 +295,7 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
if (node[property.name] !== undefined) { if (node[property.name] !== undefined) {
let nodePropertyArray = node[property.name] let nodePropertyArray = node[property.name]
for (let m = 0; m < nodePropertyArray.length; m++) { for (let m = 0; m < nodePropertyArray.length; m++) {
evalNode(nodePropertyArray[m], evaluating, descendentOfNodeType, isDescendent) await evalNode(nodePropertyArray[m], evaluating, descendentOfNodeType, isDescendent, node)
} }
} }
break 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) 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 value
let errorMessage let errorMessage
let docs let docs
@@ -365,6 +366,10 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
try { 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) 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) value = eval(node.code)
let response = await portfolioManagerClient.askPortfolioFormulaManager(parentNode, value)
value = response.value
} catch (err) { } catch (err) {
/* /*
One possible error is that the formula references a .previous that is undefined. This 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) { function evalJSCode(node) {
let value let value
let errorMessage let errorMessage
let docs let docs
try { try {
value = eval(node.code); value = eval(node.code);
} catch (err) { } catch (err) {
value = 0 value = 0
errorMessage = err.message errorMessage = err.message
docs = { docs = {
project: 'Foundations', project: 'Foundations',
category: 'Topic', category: 'Topic',
type: 'TS LF Trading Bot Error - Evaluating User Code Error', type: 'TS LF Trading Bot Error - Evaluating User Code Error',
placeholder: {} 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) { if (errorMessage !== undefined) {
tradingSystem.addError([node.id, errorMessage, docs]) 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) 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 return
} }
} }
} }
@@ -961,8 +961,10 @@
}, },
"referenceParentCombinedNodePath": [ "referenceParentCombinedNodePath": [
[ [
"Superalgos", "Teams of Contributors",
"Positions" "Positions",
"Governance",
"862caa2e-7c05-4051-b5eb-3494174e2cd9"
] ]
] ]
} }
@@ -1006,7 +1008,7 @@
"floatingObject": { "floatingObject": {
"isPinned": false, "isPinned": false,
"isFrozen": false, "isFrozen": false,
"isCollapsed": false, "isCollapsed": true,
"angleToParent": 1, "angleToParent": 1,
"distanceToParent": 3, "distanceToParent": 3,
"arrangementStyle": 0 "arrangementStyle": 0
@@ -2343,7 +2343,7 @@
"floatingObject": { "floatingObject": {
"isPinned": false, "isPinned": false,
"isFrozen": false, "isFrozen": false,
"isCollapsed": false, "isCollapsed": true,
"angleToParent": 1, "angleToParent": 1,
"distanceToParent": 3, "distanceToParent": 3,
"arrangementStyle": 0 "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": { "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": [ "botModules": [
{ {
"name": "PM Communication Module - Portfolio", "name": "PM Communication Module - Portfolio",
@@ -1921,12 +1941,12 @@
"utilities": [] "utilities": []
}, },
"TS": { "TS": {
"botModules": [ "modules": [
{ {
"name": "Trading Signals", "name": "Outgoing Trading Signals",
"propertyName": "tradingSignals", "propertyName": "outgoingTradingSignals",
"functionName": "newTradingSignalsBotModulesTradingSignals", "functionName": "newTradingSignalsModulesOutgoingTradingSignals",
"fileName": "TradingSignals.js", "fileName": "OutgoingTradingSignals.js",
"folderName": "" "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 }
}
}