From ded7998d0bd391089379dc7cef5d5c621faae778 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 17 Aug 2020 13:32:52 +0200 Subject: [PATCH] Statistics at every candle --- FileStorage.js | 4 +- LowFrequencyTrading/TradingEpisode.js | 216 ++++++++++++----------- LowFrequencyTrading/TradingPosition.js | 156 ++++++++-------- LowFrequencyTrading/TradingSimulation.js | 28 ++- LowFrequencyTrading/TradingStages.js | 9 +- LowFrequencyTrading/TradingSystem.js | 3 + 6 files changed, 219 insertions(+), 197 deletions(-) diff --git a/FileStorage.js b/FileStorage.js index 9b9245883..7cb2bf26b 100644 --- a/FileStorage.js +++ b/FileStorage.js @@ -4,7 +4,7 @@ const path = require('path') exports.newFileStorage = function newFileStorage(logger, host, port) { const MODULE_NAME = 'FileStorage' - const MAX_RETRY = 30 + const MAX_RETRY = 10 const FAST_RETRY_TIME_IN_MILISECONDS = 500 const SLOW_RETRY_TIME_IN_MILISECONDS = 2000 @@ -160,7 +160,7 @@ exports.newFileStorage = function newFileStorage(logger, host, port) { } function retry() { - console.log(new Date(), ' Retry #: ' + currentRetryGetTextFile, fileLocation) + console.log(new Date(), 'Read File Retry #: ' + currentRetryGetTextFile, fileLocation) if (currentRetryGetTextFile < MAX_RETRY) { currentRetryGetTextFile++ logger.write(MODULE_NAME, '[WARN] FileStorage -> getTextFile -> retry -> Will try to read the file again -> Retry #: ' + currentRetryGetTextFile) diff --git a/LowFrequencyTrading/TradingEpisode.js b/LowFrequencyTrading/TradingEpisode.js index 5276ba5bc..96b6e5adc 100644 --- a/LowFrequencyTrading/TradingEpisode.js +++ b/LowFrequencyTrading/TradingEpisode.js @@ -9,7 +9,6 @@ exports.newTradingEpisode = function newTradingEpisode(bot, logger, tradingEngin openEpisode: openEpisode, updateExitType: updateExitType, closeEpisode: closeEpisode, - calculateResults: calculateResults, calculateStatistics: calculateStatistics, initialize: initialize, finalize: finalize @@ -114,118 +113,123 @@ exports.newTradingEpisode = function newTradingEpisode(bot, logger, tradingEngin global.ONE_DAY_IN_MILISECONDS } - function calculateStatistics() { + function calculateStatistics() { + calculateEpisodeStatistics() + calculateAssetsStatistics() - /* Updating Profit Loss */ - tradingEngine.current.episode.episodeStatistics.profitLoss.value = - tradingEngine.current.episode.episodeBaseAsset.profitLoss.value * tradingEngine.current.episode.candle.close.value + - tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value - - tradingEngine.current.episode.episodeStatistics.profitLoss.value = global.PRECISE(tradingEngine.current.episode.episodeStatistics.profitLoss.value, 10) - - /* Updating ROI */ - tradingEngine.current.episode.episodeStatistics.ROI.value = - ( - sessionParameters.sessionBaseAsset.config.initialBalance * tradingEngine.current.episode.candle.close.value + + function calculateEpisodeStatistics() { + /* Updating Profit Loss */ + tradingEngine.current.episode.episodeStatistics.profitLoss.value = tradingEngine.current.episode.episodeBaseAsset.profitLoss.value * tradingEngine.current.episode.candle.close.value + - sessionParameters.sessionQuotedAsset.config.initialBalance + tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value - ) / ( - sessionParameters.sessionBaseAsset.config.initialBalance * tradingEngine.current.episode.candle.close.value + + + tradingEngine.current.episode.episodeStatistics.profitLoss.value = global.PRECISE(tradingEngine.current.episode.episodeStatistics.profitLoss.value, 10) + + /* Updating ROI */ + tradingEngine.current.episode.episodeStatistics.ROI.value = + ( + sessionParameters.sessionBaseAsset.config.initialBalance * tradingEngine.current.episode.candle.close.value + + tradingEngine.current.episode.episodeBaseAsset.profitLoss.value * tradingEngine.current.episode.candle.close.value + + sessionParameters.sessionQuotedAsset.config.initialBalance + + tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value + ) / ( + sessionParameters.sessionBaseAsset.config.initialBalance * tradingEngine.current.episode.candle.close.value + + sessionParameters.sessionQuotedAsset.config.initialBalance + ) - 1 + + tradingEngine.current.episode.episodeStatistics.ROI.value = global.PRECISE(tradingEngine.current.episode.episodeStatistics.ROI.value, 10) + + /* Updating Annualized Rate Of Return */ + tradingEngine.current.episode.episodeStatistics.annualizedRateOfReturn.value = + tradingEngine.current.episode.episodeStatistics.ROI.value / + tradingEngine.current.episode.episodeStatistics.days.value * 365 + + tradingEngine.current.episode.episodeStatistics.annualizedRateOfReturn.value = global.PRECISE(tradingEngine.current.episode.episodeStatistics.annualizedRateOfReturn.value, 10) + + /* Updating Hit or Fail */ + if (tradingEngine.current.episode.episodeStatistics.profitLoss.value > 0) { + tradingEngine.current.episode.episodeStatistics.hitFail.value = 'Hit' + } else { + tradingEngine.current.episode.episodeStatistics.hitFail.value = 'Fail' + } + } + + function calculateAssetsStatistics() { + + /* Updating Hits & Fails */ + if (tradingEngine.current.position.positionBaseAsset.profitLoss.value > 0) { + tradingEngine.current.episode.episodeBaseAsset.hits.value++ + } else { + tradingEngine.current.episode.episodeBaseAsset.fails.value++ + } + if (tradingEngine.current.position.positionQuotedAsset.profitLoss.value > 0) { + tradingEngine.current.episode.episodeQuotedAsset.hits.value++ + } else { + tradingEngine.current.episode.episodeQuotedAsset.fails.value++ + } + + /* Updating Profit Loss */ + tradingEngine.current.episode.episodeBaseAsset.profitLoss.value = + tradingEngine.current.episode.episodeBaseAsset.balance.value - + sessionParameters.sessionBaseAsset.config.initialBalance + + tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value = + tradingEngine.current.episode.episodeQuotedAsset.balance.value - sessionParameters.sessionQuotedAsset.config.initialBalance - ) - 1 - - tradingEngine.current.episode.episodeStatistics.ROI.value = global.PRECISE(tradingEngine.current.episode.episodeStatistics.ROI.value, 10) - - /* Updating Annualized Rate Of Return */ - tradingEngine.current.episode.episodeStatistics.annualizedRateOfReturn.value = - tradingEngine.current.episode.episodeStatistics.ROI.value / - tradingEngine.current.episode.episodeStatistics.days.value * 365 - - tradingEngine.current.episode.episodeStatistics.annualizedRateOfReturn.value = global.PRECISE(tradingEngine.current.episode.episodeStatistics.annualizedRateOfReturn.value, 10) - - /* Updating Hit or Fail */ - if (tradingEngine.current.episode.episodeStatistics.profitLoss.value > 0) { - tradingEngine.current.episode.episodeStatistics.hitFail.value = 'Hit' - } else { - tradingEngine.current.episode.episodeStatistics.hitFail.value = 'Fail' + + tradingEngine.current.episode.episodeBaseAsset.profitLoss.value = global.PRECISE(tradingEngine.current.episode.episodeBaseAsset.profitLoss.value, 10) + tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value = global.PRECISE(tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value, 10) + + /* Updating ROI */ + tradingEngine.current.episode.episodeBaseAsset.ROI.value = + (sessionParameters.sessionBaseAsset.config.initialBalance + tradingEngine.current.episode.episodeBaseAsset.profitLoss.value) / + sessionParameters.sessionBaseAsset.config.initialBalance - 1 + + tradingEngine.current.episode.episodeQuotedAsset.ROI.value = + (sessionParameters.sessionQuotedAsset.config.initialBalance + tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value) / + sessionParameters.sessionQuotedAsset.config.initialBalance - 1 + + tradingEngine.current.episode.episodeBaseAsset.ROI.value = global.PRECISE(tradingEngine.current.episode.episodeBaseAsset.ROI.value, 10) + tradingEngine.current.episode.episodeQuotedAsset.ROI.value = global.PRECISE(tradingEngine.current.episode.episodeQuotedAsset.ROI.value, 10) + + /* Updating Hit Ratio */ + tradingEngine.current.episode.episodeBaseAsset.hitRatio.value = + tradingEngine.current.episode.episodeBaseAsset.hits.value / + tradingEngine.current.episode.episodeCounters.positions.value + + tradingEngine.current.episode.episodeQuotedAsset.hitRatio.value = + tradingEngine.current.episode.episodeQuotedAsset.hits.value / + tradingEngine.current.episode.episodeCounters.positions.value + + tradingEngine.current.episode.episodeBaseAsset.hitRatio.value = global.PRECISE(tradingEngine.current.episode.episodeBaseAsset.hitRatio.value, 10) + tradingEngine.current.episode.episodeQuotedAsset.hitRatio.value = global.PRECISE(tradingEngine.current.episode.episodeQuotedAsset.hitRatio.value, 10) + + /* Updating Annualized Rate Of Return */ + tradingEngine.current.episode.episodeBaseAsset.annualizedRateOfReturn.value = + tradingEngine.current.episode.episodeBaseAsset.ROI.value / + tradingEngine.current.episode.episodeStatistics.days.value * 365 + + tradingEngine.current.episode.episodeQuotedAsset.annualizedRateOfReturn.value = + tradingEngine.current.episode.episodeQuotedAsset.ROI.value / + tradingEngine.current.episode.episodeStatistics.days.value * 365 + + tradingEngine.current.episode.episodeBaseAsset.annualizedRateOfReturn.value = global.PRECISE(tradingEngine.current.episode.episodeBaseAsset.annualizedRateOfReturn.value, 10) + tradingEngine.current.episode.episodeQuotedAsset.annualizedRateOfReturn.value = global.PRECISE(tradingEngine.current.episode.episodeQuotedAsset.annualizedRateOfReturn.value, 10) + + /* Updating Hit or Fail */ + if (tradingEngine.current.episode.episodeBaseAsset.profitLoss.value > 0) { + tradingEngine.current.episode.episodeBaseAsset.hitFail.value = 'Hit' + } else { + tradingEngine.current.episode.episodeBaseAsset.hitFail.value = 'Fail' + } + if (tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value > 0) { + tradingEngine.current.episode.episodeQuotedAsset.hitFail.value = 'Hit' + } else { + tradingEngine.current.episode.episodeQuotedAsset.hitFail.value = 'Fail' + } } } - function calculateResults() { - - /* Updating Hits & Fails */ - if (tradingEngine.current.position.positionBaseAsset.profitLoss.value > 0) { - tradingEngine.current.episode.episodeBaseAsset.hits.value++ - } else { - tradingEngine.current.episode.episodeBaseAsset.fails.value++ - } - if (tradingEngine.current.position.positionQuotedAsset.profitLoss.value > 0) { - tradingEngine.current.episode.episodeQuotedAsset.hits.value++ - } else { - tradingEngine.current.episode.episodeQuotedAsset.fails.value++ - } - - /* Updating Profit Loss */ - tradingEngine.current.episode.episodeBaseAsset.profitLoss.value = - tradingEngine.current.episode.episodeBaseAsset.balance.value - - sessionParameters.sessionBaseAsset.config.initialBalance - - tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value = - tradingEngine.current.episode.episodeQuotedAsset.balance.value - - sessionParameters.sessionQuotedAsset.config.initialBalance - - tradingEngine.current.episode.episodeBaseAsset.profitLoss.value = global.PRECISE(tradingEngine.current.episode.episodeBaseAsset.profitLoss.value, 10) - tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value = global.PRECISE(tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value, 10) - - /* Updating ROI */ - tradingEngine.current.episode.episodeBaseAsset.ROI.value = - (sessionParameters.sessionBaseAsset.config.initialBalance + tradingEngine.current.episode.episodeBaseAsset.profitLoss.value) / - sessionParameters.sessionBaseAsset.config.initialBalance - 1 - - tradingEngine.current.episode.episodeQuotedAsset.ROI.value = - (sessionParameters.sessionQuotedAsset.config.initialBalance + tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value) / - sessionParameters.sessionQuotedAsset.config.initialBalance - 1 - - tradingEngine.current.episode.episodeBaseAsset.ROI.value = global.PRECISE(tradingEngine.current.episode.episodeBaseAsset.ROI.value, 10) - tradingEngine.current.episode.episodeQuotedAsset.ROI.value = global.PRECISE(tradingEngine.current.episode.episodeQuotedAsset.ROI.value, 10) - - /* Updating Hit Ratio */ - tradingEngine.current.episode.episodeBaseAsset.hitRatio.value = - tradingEngine.current.episode.episodeBaseAsset.hits.value / - tradingEngine.current.episode.episodeCounters.positions.value - - tradingEngine.current.episode.episodeQuotedAsset.hitRatio.value = - tradingEngine.current.episode.episodeQuotedAsset.hits.value / - tradingEngine.current.episode.episodeCounters.positions.value - - tradingEngine.current.episode.episodeBaseAsset.hitRatio.value = global.PRECISE(tradingEngine.current.episode.episodeBaseAsset.hitRatio.value, 10) - tradingEngine.current.episode.episodeQuotedAsset.hitRatio.value = global.PRECISE(tradingEngine.current.episode.episodeQuotedAsset.hitRatio.value, 10) - - /* Updating Annualized Rate Of Return */ - tradingEngine.current.episode.episodeBaseAsset.annualizedRateOfReturn.value = - tradingEngine.current.episode.episodeBaseAsset.ROI.value / - tradingEngine.current.episode.episodeStatistics.days.value * 365 - - tradingEngine.current.episode.episodeQuotedAsset.annualizedRateOfReturn.value = - tradingEngine.current.episode.episodeQuotedAsset.ROI.value / - tradingEngine.current.episode.episodeStatistics.days.value * 365 - - tradingEngine.current.episode.episodeBaseAsset.annualizedRateOfReturn.value = global.PRECISE(tradingEngine.current.episode.episodeBaseAsset.annualizedRateOfReturn.value, 10) - tradingEngine.current.episode.episodeQuotedAsset.annualizedRateOfReturn.value = global.PRECISE(tradingEngine.current.episode.episodeQuotedAsset.annualizedRateOfReturn.value, 10) - - /* Updating Hit or Fail */ - if (tradingEngine.current.episode.episodeBaseAsset.profitLoss.value > 0) { - tradingEngine.current.episode.episodeBaseAsset.hitFail.value = 'Hit' - } else { - tradingEngine.current.episode.episodeBaseAsset.hitFail.value = 'Fail' - } - if (tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value > 0) { - tradingEngine.current.episode.episodeQuotedAsset.hitFail.value = 'Hit' - } else { - tradingEngine.current.episode.episodeQuotedAsset.hitFail.value = 'Fail' - } - } function updateDistanceToEventsCounters() { /* Keeping Distance Counters Up-to-date while avoinding counting before the first event happens. */ diff --git a/LowFrequencyTrading/TradingPosition.js b/LowFrequencyTrading/TradingPosition.js index d815cad3b..c5606741a 100644 --- a/LowFrequencyTrading/TradingPosition.js +++ b/LowFrequencyTrading/TradingPosition.js @@ -6,6 +6,7 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng let thisObject = { mantain: mantain, reset: reset, + calculateStatistics: calculateStatistics, openPosition: openPosition, closingPosition: closingPosition, closePosition: closePosition, @@ -87,9 +88,6 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng tradingEngine.current.position.positionBaseAsset.endBalance.value = tradingEngine.current.episode.episodeBaseAsset.balance.value tradingEngine.current.position.positionQuotedAsset.endBalance.value = tradingEngine.current.episode.episodeQuotedAsset.balance.value - /* Position Statistics & Results */ - updateStatistics() - updateResults() /* Now that the position is closed, it is the right time to move this position from current to last at the Trading Engine data structure. */ @@ -258,82 +256,86 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng } } - function updateStatistics() { + function calculateStatistics() { + calculatePositionStatistics() + calculateAssetsStatistics() - /* Profit Loss Calculation */ - tradingEngine.current.position.positionStatistics.profitLoss.value = - ( - tradingEngine.current.episode.episodeBaseAsset.balance.value * tradingEngine.current.position.endRate.value + - tradingEngine.current.episode.episodeQuotedAsset.balance.value - ) - - ( - tradingEngine.current.position.positionBaseAsset.beginBalance * tradingEngine.current.position.beginRate.value + - tradingEngine.current.position.positionQuotedAsset.beginBalance - ) - tradingEngine.current.position.positionStatistics.profitLoss.value = global.PRECISE(tradingEngine.current.position.positionStatistics.profitLoss.value, 10) - - /* ROI Calculation */ - tradingEngine.current.position.positionStatistics.ROI.value = - ( - tradingEngine.current.position.positionStatistics.profitLoss.value - ) - * 100 / - ( - tradingEngine.current.position.positionBaseAsset.beginBalance * tradingEngine.current.position.beginRate.value + - tradingEngine.current.position.positionQuotedAsset.beginBalance - ) - tradingEngine.current.position.positionStatistics.ROI.value = global.PRECISE(tradingEngine.current.position.positionStatistics.ROI.value, 10) - - /* Hit Fail Calculation */ - if (tradingEngine.current.position.positionStatistics.ROI.value > 0) { - tradingEngine.current.position.positionStatistics.hitFail.value = 'Hit' - } else { - tradingEngine.current.position.positionStatistics.hitFail.value = 'Fail' + function calculatePositionStatistics() { + /* Profit Loss Calculation */ + tradingEngine.current.position.positionStatistics.profitLoss.value = + ( + tradingEngine.current.episode.episodeBaseAsset.balance.value * tradingEngine.current.position.endRate.value + + tradingEngine.current.episode.episodeQuotedAsset.balance.value + ) - + ( + tradingEngine.current.position.positionBaseAsset.beginBalance * tradingEngine.current.position.beginRate.value + + tradingEngine.current.position.positionQuotedAsset.beginBalance + ) + tradingEngine.current.position.positionStatistics.profitLoss.value = global.PRECISE(tradingEngine.current.position.positionStatistics.profitLoss.value, 10) + + /* ROI Calculation */ + tradingEngine.current.position.positionStatistics.ROI.value = + ( + tradingEngine.current.position.positionStatistics.profitLoss.value + ) + * 100 / + ( + tradingEngine.current.position.positionBaseAsset.beginBalance * tradingEngine.current.position.beginRate.value + + tradingEngine.current.position.positionQuotedAsset.beginBalance + ) + tradingEngine.current.position.positionStatistics.ROI.value = global.PRECISE(tradingEngine.current.position.positionStatistics.ROI.value, 10) + + /* Hit Fail Calculation */ + if (tradingEngine.current.position.positionStatistics.ROI.value > 0) { + tradingEngine.current.position.positionStatistics.hitFail.value = 'Hit' + } else { + tradingEngine.current.position.positionStatistics.hitFail.value = 'Fail' + } + + /* Days Calculation */ + tradingEngine.current.position.positionStatistics.days.value = + tradingEngine.current.position.positionCounters.periods.value * + sessionParameters.timeFrame.config.value / global.ONE_DAY_IN_MILISECONDS + + tradingEngine.current.position.positionStatistics.days.value = global.PRECISE(tradingEngine.current.position.positionStatistics.days.value, 10) } - - /* Days Calculation */ - tradingEngine.current.position.positionStatistics.days.value = - tradingEngine.current.position.positionCounters.periods.value * - sessionParameters.timeFrame.config.value / global.ONE_DAY_IN_MILISECONDS - - tradingEngine.current.position.positionStatistics.days.value = global.PRECISE(tradingEngine.current.position.positionStatistics.days.value, 10) - } - - function updateResults() { - /* Profit Loss Calculation */ - tradingEngine.current.position.positionBaseAsset.profitLoss.value = - tradingEngine.current.episode.episodeBaseAsset.balance.value - - tradingEngine.current.position.positionBaseAsset.beginBalance - - tradingEngine.current.position.positionQuotedAsset.profitLoss.value = - tradingEngine.current.episode.episodeQuotedAsset.balance.value - - tradingEngine.current.position.positionQuotedAsset.beginBalance - - tradingEngine.current.position.positionBaseAsset.profitLoss.value = global.PRECISE(tradingEngine.current.position.positionBaseAsset.profitLoss.value, 10) - tradingEngine.current.position.positionQuotedAsset.profitLoss.value = global.PRECISE(tradingEngine.current.position.positionQuotedAsset.profitLoss.value, 10) - - /* ROI Calculation */ - tradingEngine.current.position.positionBaseAsset.ROI.value = - tradingEngine.current.position.positionBaseAsset.profitLoss.value * 100 / - tradingEngine.current.position.positionBaseAsset.entryTargetSize.value - - tradingEngine.current.position.positionQuotedAsset.ROI.value = - tradingEngine.current.position.positionQuotedAsset.profitLoss.value * 100 / - tradingEngine.current.position.positionQuotedAsset.entryTargetSize.value - - tradingEngine.current.position.positionBaseAsset.ROI.value = global.PRECISE(tradingEngine.current.position.positionBaseAsset.ROI.value, 10) - tradingEngine.current.position.positionQuotedAsset.ROI.value = global.PRECISE(tradingEngine.current.position.positionQuotedAsset.ROI.value, 10) - - /* Hit Fail Calculation */ - if (tradingEngine.current.position.positionBaseAsset.ROI.value > 0) { - tradingEngine.current.position.positionBaseAsset.hitFail.value = 'Hit' - } else { - tradingEngine.current.position.positionBaseAsset.hitFail.value = 'Fail' - } - if (tradingEngine.current.position.positionQuotedAsset.ROI.value > 0) { - tradingEngine.current.position.positionQuotedAsset.hitFail.value = 'Hit' - } else { - tradingEngine.current.position.positionQuotedAsset.hitFail.value = 'Fail' + + function calculateAssetsStatistics() { + /* Profit Loss Calculation */ + tradingEngine.current.position.positionBaseAsset.profitLoss.value = + tradingEngine.current.episode.episodeBaseAsset.balance.value - + tradingEngine.current.position.positionBaseAsset.beginBalance + + tradingEngine.current.position.positionQuotedAsset.profitLoss.value = + tradingEngine.current.episode.episodeQuotedAsset.balance.value - + tradingEngine.current.position.positionQuotedAsset.beginBalance + + tradingEngine.current.position.positionBaseAsset.profitLoss.value = global.PRECISE(tradingEngine.current.position.positionBaseAsset.profitLoss.value, 10) + tradingEngine.current.position.positionQuotedAsset.profitLoss.value = global.PRECISE(tradingEngine.current.position.positionQuotedAsset.profitLoss.value, 10) + + /* ROI Calculation */ + tradingEngine.current.position.positionBaseAsset.ROI.value = + tradingEngine.current.position.positionBaseAsset.profitLoss.value * 100 / + tradingEngine.current.position.positionBaseAsset.entryTargetSize.value + + tradingEngine.current.position.positionQuotedAsset.ROI.value = + tradingEngine.current.position.positionQuotedAsset.profitLoss.value * 100 / + tradingEngine.current.position.positionQuotedAsset.entryTargetSize.value + + tradingEngine.current.position.positionBaseAsset.ROI.value = global.PRECISE(tradingEngine.current.position.positionBaseAsset.ROI.value, 10) + tradingEngine.current.position.positionQuotedAsset.ROI.value = global.PRECISE(tradingEngine.current.position.positionQuotedAsset.ROI.value, 10) + + /* Hit Fail Calculation */ + if (tradingEngine.current.position.positionBaseAsset.ROI.value > 0) { + tradingEngine.current.position.positionBaseAsset.hitFail.value = 'Hit' + } else { + tradingEngine.current.position.positionBaseAsset.hitFail.value = 'Fail' + } + if (tradingEngine.current.position.positionQuotedAsset.ROI.value > 0) { + tradingEngine.current.position.positionQuotedAsset.hitFail.value = 'Hit' + } else { + tradingEngine.current.position.positionQuotedAsset.hitFail.value = 'Fail' + } } } diff --git a/LowFrequencyTrading/TradingSimulation.js b/LowFrequencyTrading/TradingSimulation.js index c63f6988e..cd3ef2ae6 100644 --- a/LowFrequencyTrading/TradingSimulation.js +++ b/LowFrequencyTrading/TradingSimulation.js @@ -119,8 +119,18 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT firstLoopExecution = false } + if (checkInitialDatetime() === false) { + controlLoop() + return + } + + if (checkFinalDatetime() === false) { + closeEpisode('Final Datetime Reached') + return + } + if (checkLastCandle() === false) { - closeEpisode('Last Candle Reached') + controlLoop() return } @@ -129,11 +139,6 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT return } - if (checkInitialAndFinalDatetime() === false) { - controlLoop() - return - } - positionChartAtCurrentCandle() /* The chart was recalculated based on the current candle. */ @@ -211,7 +216,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT */ setImmediate(loop) } else { - updateEpisode('All Candles Processed') + updateEpisode('All Available Candles Processed') } } @@ -398,12 +403,17 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT return true } - function checkInitialAndFinalDatetime() { - /* Here we check that the current candle is not outside of user-defined time range at the session parameters.*/ + function checkInitialDatetime() { + /* Here we check that the current candle is not before the initial datetime defined at the session parameters.*/ if (tradingEngine.current.episode.candle.end.value < sessionParameters.timeRange.config.initialDatetime) { if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> checkInitialAndFinalDatetime -> Skipping Candle before the sessionParameters.timeRange.config.initialDatetime.') } return false } + return true + } + + function checkFinalDatetime() { + /* Here we check that the current candle is not after of the user-defined final datetime at the session parameters.*/ if (tradingEngine.current.episode.candle.begin.value > sessionParameters.timeRange.config.finalDatetime) { if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> checkInitialAndFinalDatetime -> Skipping Candle after the sessionParameters.timeRange.config.finalDatetime.') } return false diff --git a/LowFrequencyTrading/TradingStages.js b/LowFrequencyTrading/TradingStages.js index 9bead0bd2..1b5090964 100644 --- a/LowFrequencyTrading/TradingStages.js +++ b/LowFrequencyTrading/TradingStages.js @@ -7,6 +7,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM updateChart: updateChart, mantain: mantain, reset: reset, + calculateStatistics: calculateStatistics, runTriggerStage: runTriggerStage, runOpenStage: runOpenStage, runManageStage: runManageStage, @@ -101,6 +102,11 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM resetTradingEngineDataStructure() } + function calculateStatistics() { + tradingEpisodeModule.calculateStatistics() + tradingPositionModule.calculateStatistics() + } + function runTriggerStage() { /* We check if we will be triggering on, off or taking position. @@ -870,9 +876,6 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM /* Close the Position */ tradingPositionModule.closePosition() - tradingEpisodeModule.calculateResults() - tradingEpisodeModule.calculateStatistics() - /* Close the Strategy */ tradingStrategyModule.closeStrategy('Position Closed') diff --git a/LowFrequencyTrading/TradingSystem.js b/LowFrequencyTrading/TradingSystem.js index 83148dbad..b938b9a31 100644 --- a/LowFrequencyTrading/TradingSystem.js +++ b/LowFrequencyTrading/TradingSystem.js @@ -131,6 +131,9 @@ exports.newTradingSystem = function newTradingSystem(bot, logger, tradingEngineM /* Run the Close Stage */ await tradingStagesModule.runCloseStage() + + tradingStagesModule.calculateStatistics() + } catch (err) { /* If an error ocurred during execution, it was alreeady logged and