Merge pull request #2776 from Luis-Fernando-Molina/develop
Contribution: Integration of Trading Bot with Portfolio Manager Part 1
This commit is contained in:
11 files changed
+720
-4490
No files matched your search
+70
-50
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+39
-34
@@ -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
|
||||
|
||||
+409
-4268
File diff suppressed because it is too large.
Load diff
@@ -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() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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 }
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user