First Iteration of Fixes

This commit is contained in:
Luis Fernando Molina committed 2020-10-25 08:59:10 +01:00
1 parent b3b4c7f4ad
commit 8d284696fa
6 files changed
+101 -93

No files matched your search

+17 -17
View File
@@ -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) {
+13 -12
View File
@@ -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
+1 -1
View File
@@ -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
}
+12 -15
View File
@@ -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
+55 -47
View File
@@ -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
) {
+3 -1
View File
@@ -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