diff --git a/LowFrequencyTrading/TradingEpisode.js b/LowFrequencyTrading/TradingEpisode.js index de5c74f75..ff08c22a1 100644 --- a/LowFrequencyTrading/TradingEpisode.js +++ b/LowFrequencyTrading/TradingEpisode.js @@ -47,27 +47,27 @@ exports.newTradingEpisode = function newTradingEpisode(bot, logger, tradingEngin /* This function is called each time the simulation starts. That does not mean the Episode must be opened there, since it might happen that it is looping at the end of the market - or the task / session was restarted. + or the task / session was restarted. We will only execute if the episode was never opened before. */ - if (bot.FIRST_EXECUTION === true) { - /* Starting begin and end */ - tradingEngine.current.episode.begin.value = tradingEngine.current.episode.candle.begin.value - tradingEngine.current.episode.end.value = tradingEngine.current.episode.candle.end.value + if (tradingEngine.current.episode.begin.value !== tradingEngine.current.episode.begin.config.initialValue) { return } - /* Getting the begin Balance from the session configuration */ - tradingEngine.current.episode.episodeBaseAsset.beginBalance.value = sessionParameters.sessionBaseAsset.config.initialBalance - tradingEngine.current.episode.episodeQuotedAsset.beginBalance.value = sessionParameters.sessionQuotedAsset.config.initialBalance + /* Starting begin and end */ + tradingEngine.current.episode.begin.value = tradingEngine.current.episode.candle.begin.value + tradingEngine.current.episode.end.value = tradingEngine.current.episode.candle.end.value - /* The current balance is also the begin balance, that is how this starts. */ - tradingEngine.current.episode.episodeBaseAsset.balance.value = sessionParameters.sessionBaseAsset.config.initialBalance - tradingEngine.current.episode.episodeQuotedAsset.balance.value = sessionParameters.sessionQuotedAsset.config.initialBalance + /* Getting the begin Balance from the session configuration */ + tradingEngine.current.episode.episodeBaseAsset.beginBalance.value = sessionParameters.sessionBaseAsset.config.initialBalance + tradingEngine.current.episode.episodeQuotedAsset.beginBalance.value = sessionParameters.sessionQuotedAsset.config.initialBalance - /* Recording the opening at the Trading Engine Data Structure */ - tradingEngine.current.episode.status.value = 'Open' - tradingEngine.current.episode.serialNumber.value = 1 - tradingEngine.current.episode.identifier.value = global.UNIQUE_ID() - tradingEngine.current.episode.beginRate.value = tradingEngine.current.episode.candle.close.value - } + /* The current balance is also the begin balance, that is how this starts. */ + tradingEngine.current.episode.episodeBaseAsset.balance.value = sessionParameters.sessionBaseAsset.config.initialBalance + tradingEngine.current.episode.episodeQuotedAsset.balance.value = sessionParameters.sessionQuotedAsset.config.initialBalance + + /* Recording the opening at the Trading Engine Data Structure */ + tradingEngine.current.episode.status.value = 'Open' + tradingEngine.current.episode.serialNumber.value = 1 + tradingEngine.current.episode.identifier.value = global.UNIQUE_ID() + tradingEngine.current.episode.beginRate.value = tradingEngine.current.episode.candle.close.value } function updateExitType(exitType) { diff --git a/LowFrequencyTrading/TradingOrders.js b/LowFrequencyTrading/TradingOrders.js index 2b55c08b7..c84fb623b 100644 --- a/LowFrequencyTrading/TradingOrders.js +++ b/LowFrequencyTrading/TradingOrders.js @@ -906,14 +906,9 @@ exports.newTradingOrders = function newTradingOrders(bot, logger, tradingEngineM /* We receive the actual size from the exchange at the order.amount field. */ tradingEngineOrder.orderBaseAsset.actualSize.value = order.amount - /* - If the exchange accepted the size sent on the request to create the order, - we don't need to do anything else here. - */ - if (tradingEngineOrder.orderBaseAsset.size.value === tradingEngineOrder.orderBaseAsset.actualSize.value) { return } /* If not, we will calculate the Quoted Asset Actual Size too. Note that the amount received - is in Base Asset only. In the next formula, we are useing the rate of the order. + is in Base Asset only. In the next formula, we are unsing the rate of the order. This rate might be replaced afteerwards for an actual rate. When that happens we will need to adjust these results. */ @@ -922,6 +917,12 @@ exports.newTradingOrders = function newTradingOrders(bot, logger, tradingEngineM tradingEngineOrder.orderBaseAsset.actualSize.value = global.PRECISE(tradingEngineOrder.orderBaseAsset.actualSize.value, 10) tradingEngineOrder.orderQuotedAsset.actualSize.value = global.PRECISE(tradingEngineOrder.orderQuotedAsset.actualSize.value, 10) + /* + If the exchange accepted the size sent on the request to create the order, + we don't need to do anything else here. + */ + if (tradingEngineOrder.orderBaseAsset.size.value === tradingEngineOrder.orderBaseAsset.actualSize.value) { return } + recalculateSizePlaced() function recalculateSizePlaced() { @@ -1197,7 +1198,7 @@ exports.newTradingOrders = function newTradingOrders(bot, logger, tradingEngineM /* Balance Base Asset: Account the current filling and fees */ tradingEngine.current.episode.episodeBaseAsset.balance.value = tradingEngine.current.episode.episodeBaseAsset.balance.value + - tradingEngineOrder.orderBaseAsset.sizeFilled.value + tradingEngineOrder.orderBaseAsset.sizeFilled.value /* Balance Quoted Asset: Undo the previous accounting */ tradingEngine.current.episode.episodeQuotedAsset.balance.value = @@ -1223,24 +1224,24 @@ exports.newTradingOrders = function newTradingOrders(bot, logger, tradingEngineM /* Balance Base Asset: Undo the previous accounting */ tradingEngine.current.episode.episodeBaseAsset.balance.value = tradingEngine.current.episode.episodeBaseAsset.balance.value + - previousBaseAssetSizeFilled + + previousBaseAssetSizeFilled + previousBaseAssetFeesPaid /* Balance Base Asset: Account the current filling and fees */ tradingEngine.current.episode.episodeBaseAsset.balance.value = tradingEngine.current.episode.episodeBaseAsset.balance.value - - tradingEngineOrder.orderBaseAsset.sizeFilled.value - + tradingEngineOrder.orderBaseAsset.sizeFilled.value - tradingEngineOrder.orderBaseAsset.feesPaid.value /* Balance Quoted Asset: Undo the previous accounting */ tradingEngine.current.episode.episodeQuotedAsset.balance.value = tradingEngine.current.episode.episodeQuotedAsset.balance.value - - previousQuotedAssetSizeFilled + previousQuotedAssetSizeFilled /* Balance Quoted Asset: Account the current filling and fees */ tradingEngine.current.episode.episodeQuotedAsset.balance.value = tradingEngine.current.episode.episodeQuotedAsset.balance.value + - tradingEngineOrder.orderQuotedAsset.sizeFilled.value + tradingEngineOrder.orderQuotedAsset.sizeFilled.value break } } @@ -1381,7 +1382,7 @@ exports.newTradingOrders = function newTradingOrders(bot, logger, tradingEngineM /* In this case the fees are taken from the Quoted Asset you receive as a result of the trade at the exchange. */ - tradingEngineOrder.orderQuotedAsset.feesPaid.value = + feesNode.value = tradingEngineOrder.orderQuotedAsset.actualSize.value * feePercentage / 100 * percentageFilled / 100 diff --git a/LowFrequencyTrading/TradingProcess.js b/LowFrequencyTrading/TradingProcess.js index bddb9883a..17aca909c 100644 --- a/LowFrequencyTrading/TradingProcess.js +++ b/LowFrequencyTrading/TradingProcess.js @@ -151,7 +151,7 @@ await writeProcessFiles() bot.sessionHeartBeat(undefined, undefined, 'Sleeping') } else { - bot.sessionHeartBeat(undefined, undefined, 'Waiting for Data Mining to be up to date') + bot.sessionHeartBeat(undefined, undefined, 'Waiting for Data Mining to be up to date. No candles found at.') callBackFunction(global.DEFAULT_RETRY_RESPONSE) return } diff --git a/LowFrequencyTrading/TradingSimulation.js b/LowFrequencyTrading/TradingSimulation.js index 186f2872e..87a64b504 100644 --- a/LowFrequencyTrading/TradingSimulation.js +++ b/LowFrequencyTrading/TradingSimulation.js @@ -53,7 +53,6 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, tradin /* Variables needed for heartbeat functionality */ let heartBeatDate let previousHeartBeatDate - let firstLoopExecution = true /* Estimation of the Initial Candle to Process in this Run. */ @@ -73,7 +72,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, tradin meaning that the dataSet needs to be updated with more up-to-date data. */ bot.SESSION.stop('Data is not up-to-date enough. Please start the Masters Data Mining Operation.') - if (FULL_LOG === true) { logger.write(MODULE_NAME, '[IMPORTANT] runSimulation -> Data is not up-to-date enough. Stopping the Session now. ' ) } + if (FULL_LOG === true) { logger.write(MODULE_NAME, '[IMPORTANT] runSimulation -> Data is not up-to-date enough. Stopping the Session now. ') } return } } else { @@ -107,7 +106,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, tradin tradingEngine.current.episode.candle.index.value = i /* This is the current candle the Simulation is working at. */ - let candle = candles[tradingEngine.current.episode.candle.index.value] + let candle = candles[tradingEngine.current.episode.candle.index.value] if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> Candle Begin @ ' + (new Date(candle.begin)).toLocaleString()) } if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> Candle End @ ' + (new Date(candle.end)).toLocaleString()) } @@ -117,10 +116,8 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, tradin /* We emit a heart beat so that the UI can now where we are at the overal process.*/ heartBeat() - if (firstLoopExecution === true) { - tradingEpisodeModule.openEpisode() - firstLoopExecution = false - } + /* Opening the Episode, if needed. */ + tradingEpisodeModule.openEpisode() if (checkInitialDatetime() === false) { if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> Candle Before the Initia Date Time @ ' + (new Date(candle.begin)).toLocaleString()) } @@ -214,7 +211,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, tradin closeEpisode('Final Datetime Reached') breakLoop = true bot.SESSION.stop('Final Datetime Reached') - if (FULL_LOG === true) { logger.write(MODULE_NAME, '[IMPORTANT] runSimulation -> Final Datetime Reached. Stopping the Session now. ' ) } + if (FULL_LOG === true) { logger.write(MODULE_NAME, '[IMPORTANT] runSimulation -> Final Datetime Reached. Stopping the Session now. ') } return } @@ -222,7 +219,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, tradin closeEpisode('Min or Max Balance Reached') breakLoop = true bot.SESSION.stop('Min or Max Balance Reached') - if (FULL_LOG === true) { logger.write(MODULE_NAME, '[IMPORTANT] runSimulation -> Min or Max Balance Reached. Stopping the Session now. ' ) } + if (FULL_LOG === true) { logger.write(MODULE_NAME, '[IMPORTANT] runSimulation -> Min or Max Balance Reached. Stopping the Session now. ') } return } } @@ -287,23 +284,23 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, tradin } /* Date only hearbeat */ - if (sessionParameters.heartbeats.config.date === true && sessionParameters.heartbeats.config.candleIndex === false) { + if (sessionParameters.heartbeats.config.date === true && sessionParameters.heartbeats.config.candleIndex === false) { hartbeatText = hartbeatText + currentDateString bot.processHeartBeat(hartbeatText, percentage) return } } - + /* When the Candle Index nees to be shown, then we can not send the hearbet only when the dates changes, we have to send it for every candle. It might also contain the date information. */ - if (sessionParameters.heartbeats.config.candleIndex === true ) { - if (sessionParameters.heartbeats.config.date === true ) { + if (sessionParameters.heartbeats.config.candleIndex === true) { + if (sessionParameters.heartbeats.config.date === true) { hartbeatText = hartbeatText + currentDateString } - hartbeatText = hartbeatText + ' Candle # ' + tradingEngine.current.episode.candle.index.value + hartbeatText = hartbeatText + ' Candle # ' + tradingEngine.current.episode.candle.index.value bot.processHeartBeat(hartbeatText, percentage) } } @@ -420,7 +417,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, tradin The second +1 is because we need to compare the next candle (remember that the loops allways avoid the last candle of the dataset available.) */ - if (tradingEngine.current.episode.candle.index.value + 1 + 1 === candles.length ) { + if (tradingEngine.current.episode.candle.index.value + 1 + 1 === candles.length) { /* When processing daily files, we need a mechanism to turn from one day to the next one. That mechanism is the one implemented here. If we detect that the next candle is the last candle of diff --git a/LowFrequencyTrading/TradingStages.js b/LowFrequencyTrading/TradingStages.js index 2de568a8c..774e1c1d2 100644 --- a/LowFrequencyTrading/TradingStages.js +++ b/LowFrequencyTrading/TradingStages.js @@ -435,48 +435,48 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value] let manageStage = strategy.manageStage let phase - + if (manageStage !== undefined) { if (manageStage.managedStopLoss !== undefined) { phase = manageStage.managedStopLoss.phases[tradingEngine.current.position.stopLoss.stopLossPhase.value - 1] } } - + if (phase !== undefined) { if (phase.formula !== undefined) { let previousValue = tradingEngine.current.position.stopLoss.value tradingPositionModule.applyStopLossFormula(tradingSystem.formulas, phase.formula.id) - + if (tradingEngine.current.position.stopLoss.value !== previousValue) { announcementsModule.makeAnnoucements(phase) } } } } - + function calculateTakeProfit() { let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value] let manageStage = strategy.manageStage let phase - + if (manageStage !== undefined) { if (manageStage.managedTakeProfit !== undefined) { phase = manageStage.managedTakeProfit.phases[tradingEngine.current.position.takeProfit.takeProfitPhase.value - 1] } } - + if (phase !== undefined) { if (phase.formula !== undefined) { let previousValue = tradingEngine.current.position.takeProfit.value tradingPositionModule.applyTakeProfitFormula(tradingSystem.formulas, phase.formula.id) - + if (tradingEngine.current.position.takeProfit.value !== previousValue) { announcementsModule.makeAnnoucements(phase) } } } } - + function calculateStopLossPosition() { /* The position of the Stop Loss (above or below the price) is needed in order to know @@ -492,7 +492,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM } } } - + function calculateTakeProfitPosition() { /* The position of the Take Profit (above or below the price) is needed in order to know @@ -508,7 +508,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM } } } - + function checkStopPhasesEvents() { let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value] let manageStage = strategy.manageStage @@ -516,7 +516,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM let phaseIndex let phase let stopLoss - + if (manageStage !== undefined) { if (manageStage.managedStopLoss !== undefined) { parentNode = manageStage @@ -525,10 +525,10 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM phase = stopLoss.phases[phaseIndex] } } - + if (parentNode !== undefined) { if (phase === undefined) { return } // trying to jump to a phase that does not exists. - + /* Check the next Phase Event. */ let nextPhaseEvent = phase.nextPhaseEvent if (nextPhaseEvent !== undefined) { @@ -538,9 +538,9 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM if (situation.conditions.length > 0) { passed = true } - + passed = tradingSystem.checkConditions(situation, passed) - + tradingSystem.values.push([situation.id, passed]) if (passed) { tradingSystem.highlights.push(situation.id) @@ -549,18 +549,18 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM tradingSystem.highlights.push(stopLoss.id) tradingSystem.highlights.push(parentNode.id) tradingSystem.highlights.push(manageStage.id) - + tradingPositionModule.updateStopLoss(tradingEngine.current.position.stopLoss.stopLossPhase.value + 1) - + announcementsModule.makeAnnoucements(nextPhaseEvent) - + /* Reset this counter */ tradingEngine.current.episode.distanceToEvent.nextPhase.value = 1 return // only one event can pass at the time } } } - + /* Check the Move to Phase Events. */ for (let n = 0; n < phase.moveToPhaseEvents.length; n++) { let moveToPhaseEvent = phase.moveToPhaseEvents[n] @@ -571,9 +571,9 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM if (situation.conditions.length > 0) { passed = true } - + passed = tradingSystem.checkConditions(situation, passed) - + tradingSystem.values.push([situation.id, passed]) if (passed) { tradingSystem.highlights.push(situation.id) @@ -582,7 +582,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM tradingSystem.highlights.push(stopLoss.id) tradingSystem.highlights.push(parentNode.id) tradingSystem.highlights.push(manageStage.id) - + let moveToPhase = moveToPhaseEvent.referenceParent if (moveToPhase !== undefined) { for (let q = 0; q < stopLoss.phases.length; q++) { @@ -594,9 +594,9 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM tradingSystem.errors.push([moveToPhaseEvent.id, 'This Node needs to reference a Phase.']) continue } - + announcementsModule.makeAnnoucements(moveToPhaseEvent) - + /* Reset this counter */ tradingEngine.current.episode.distanceToEvent.moveToPhase.value = 1 return // only one event can pass at the time @@ -606,7 +606,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM } } } - + function checkTakeProfitPhaseEvents() { let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value] let openStage = strategy.openStage @@ -615,7 +615,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM let phaseIndex let phase let takeProfit - + if (manageStage !== undefined) { if (manageStage.managedTakeProfit !== undefined) { parentNode = manageStage @@ -624,10 +624,10 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM phase = takeProfit.phases[phaseIndex] } } - + if (parentNode !== undefined) { if (phase === undefined) { return } // trying to jump to a phase that does not exists. - + /* Check the next Phase Event. */ let nextPhaseEvent = phase.nextPhaseEvent if (nextPhaseEvent !== undefined) { @@ -637,9 +637,9 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM if (situation.conditions.length > 0) { passed = true } - + passed = tradingSystem.checkConditions(situation, passed) - + tradingSystem.values.push([situation.id, passed]) if (passed) { tradingSystem.highlights.push(situation.id) @@ -648,18 +648,18 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM tradingSystem.highlights.push(takeProfit.id) tradingSystem.highlights.push(parentNode.id) tradingSystem.highlights.push(manageStage.id) - + tradingPositionModule.updateTakeProfit(tradingEngine.current.position.takeProfit.takeProfitPhase.value + 1) - + announcementsModule.makeAnnoucements(nextPhaseEvent) - + /* Reset this counter */ tradingEngine.current.episode.distanceToEvent.nextPhase.value = 1 return // only one event can pass at the time } } } - + /* Check the Move to Phase Events. */ for (let n = 0; n < phase.moveToPhaseEvents.length; n++) { let moveToPhaseEvent = phase.moveToPhaseEvents[n] @@ -670,9 +670,9 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM if (situation.conditions.length > 0) { passed = true } - + passed = tradingSystem.checkConditions(situation, passed) - + tradingSystem.values.push([situation.id, passed]) if (passed) { tradingSystem.highlights.push(situation.id) @@ -681,7 +681,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM tradingSystem.highlights.push(takeProfit.id) tradingSystem.highlights.push(parentNode.id) tradingSystem.highlights.push(manageStage.id) - + let moveToPhase = moveToPhaseEvent.referenceParent if (moveToPhase !== undefined) { for (let q = 0; q < takeProfit.phases.length; q++) { @@ -693,9 +693,9 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM tradingSystem.errors.push([moveToPhaseEvent.id, 'This Node needs to reference a Phase.']) continue } - + announcementsModule.makeAnnoucements(moveToPhaseEvent) - + /* Reset this counter */ tradingEngine.current.episode.distanceToEvent.moveToPhase.value = 1 return // only one event can pass at the time @@ -705,7 +705,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM } } } - + function checkStopLossOrTakeProfitWasHit() { { let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value] @@ -713,7 +713,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM Checking what happened since the last execution. We need to know if the Stop Loss or our Take Profit were hit. */ - + /* Stop Loss condition: Here we verify if the Stop Loss was hitted or not. */ if ( ( @@ -726,14 +726,14 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM ) ) { logger.write(MODULE_NAME, '[INFO] checkStopLossOrTakeProfitWasHit -> Stop Loss was hit.') - + tradingPositionModule.closingPosition('Stop Loss') changeStageStatus('Close Stage', 'Opening') changeStageStatus('Manage Stage', 'Closed') announcementsModule.makeAnnoucements(strategy.closeStage) return } - + /* Take Profit condition: Here we verify if the Take Profit was hit or not. */ if ( ( @@ -746,7 +746,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM ) ) { logger.write(MODULE_NAME, '[INFO] checkStopLossOrTakeProfitWasHit -> Take Profit was hit.') - + tradingPositionModule.closingPosition('Take Profit') changeStageStatus('Close Stage', 'Opening') changeStageStatus('Manage Stage', 'Closed') @@ -894,7 +894,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM This can happens at any time when we update the sizeFilled and the feesPaid values when we see at the exchange that orders were filled. - + Note that the comparison is made with a Rounding Factor in order to avoid rounding problems. */ const ROUNDING_ERROR_CORRECTION_FACTOR = 1.001 @@ -902,7 +902,11 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM switch (tradingEngineStage.stageDefinedIn.value) { case 'Base Asset': { if ( - tradingEngineStage.stageBaseAsset.sizeFilled.value * ROUNDING_ERROR_CORRECTION_FACTOR + ( + tradingEngineStage.stageBaseAsset.sizeFilled.value + + tradingEngineStage.stageBaseAsset.feesPaid.value + ) + * ROUNDING_ERROR_CORRECTION_FACTOR >= tradingEngineStage.stageBaseAsset.targetSize.value ) { @@ -914,7 +918,11 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM } case 'Quoted Asset': { if ( - tradingEngineStage.stageQuotedAsset.sizeFilled.value * ROUNDING_ERROR_CORRECTION_FACTOR + ( + tradingEngineStage.stageQuotedAsset.sizeFilled.value + + tradingEngineStage.stageQuotedAsset.feesPaid.value + ) + * ROUNDING_ERROR_CORRECTION_FACTOR >= tradingEngineStage.stageQuotedAsset.targetSize.value ) { diff --git a/Session.js b/Session.js index 582500864..e35d08c1b 100644 --- a/Session.js +++ b/Session.js @@ -369,7 +369,9 @@ function startLiveTrading(message) { if (bot.KEY === undefined || bot.SECRET === undefined) { - if (FULL_LOG === true) { parentLogger.write(MODULE_NAME, "[ERROR] initialize -> startLiveTrading -> Key 'codeName' or 'secret' not provided. Plese check that and try again."); } + let errorMessage = "Key 'codeName' or 'secret' not provided. Plese check that and try again." + if (FULL_LOG === true) { parentLogger.write(MODULE_NAME, "[ERROR] initialize -> startLiveTrading -> " + errorMessage); } + bot.sessionError(bot.SESSION, errorMessage) return false } return true