From 9594d0545933de6d321bf1da22409a32b47ad2bc Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 9 Jul 2018 21:31:07 +0200 Subject: [PATCH 1/7] Balance and Available balance calculations fixed since they were not ok --- Assistant.js | 70 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/Assistant.js b/Assistant.js index e01f395da..461e560c2 100644 --- a/Assistant.js +++ b/Assistant.js @@ -787,33 +787,55 @@ context.newHistoryRecord.newTrades++; /* Calculate Balances */ - let assetA = 0; - let assetB = 0; - - if (trade.type === 'buy') { - let fee = Number(trade.fee) * trade.amountB; - let fixedFee = Number(parseFloat(fee).toFixed(8)); - - assetA = context.executionContext.balance.assetA - Number(trade.amountA); - assetB = context.executionContext.balance.assetB + Number(trade.amountB) - fixedFee; - let available = context.executionContext.availableBalance.assetB + Number(trade.amountB) - fixedFee; - context.executionContext.availableBalance.assetB = Number(parseFloat(available).toFixed(8)); + let assetA = 0; + let assetB = 0; + + if (trade.type === 'buy') { + + /* + + The fee received at each trade is the factor by which if we multiply asset B, we get the amount of Asset B extracted as fees by the exchange. + This happens with each individual trade. Remeber that one order can potentially be executed with 1 to many trades. + + */ + + let feeAmount = parseFloat(Number(trade.fee) * Number(trade.amountB)).toFixed(8); + + assetA = Number(trade.amountA); + assetB = Number(trade.amountB) - feeAmount; + + context.executionContext.balance.assetA = context.executionContext.balance.assetA - assetA; + context.executionContext.balance.assetB = context.executionContext.balance.assetB + assetB; + + context.executionContext.availableBalance.assetB = context.executionContext.availableBalance.assetB + assetB; + + /* Not the available balance for asset A is not affected since it was already reduced when the order was placed. */ + } if (trade.type === 'sell') { - let fee = Number(trade.fee) * trade.amountA; - let fixedFee = Number(parseFloat(fee).toFixed(8)); - - assetA = context.executionContext.balance.assetA + Number(trade.amountA) - fixedFee; - assetB = context.executionContext.balance.assetB - Number(trade.amountB); - - let available = context.executionContext.availableBalance.assetA + Number(trade.amountA) - fixedFee; - context.executionContext.availableBalance.assetA = Number(parseFloat(available).toFixed(8)); - } - - context.executionContext.balance.assetA = Number(parseFloat(assetA).toFixed(8)); - context.executionContext.balance.assetB = Number(parseFloat(assetB).toFixed(8)); + + /* + + The fee received at each trade is the factor by which if we multiply asset A, we get the amount of Asset A extracted as fees by the exchange. + This happens with each individual trade. Remeber that one order can potentially be executed with 1 to many trades. + + */ + + let feeAmount = parseFloat(Number(trade.fee) * Number(trade.amountA)).toFixed(8); + + assetA = Number(trade.amountA) - feeAmount; + assetB = Number(trade.amountB); + + context.executionContext.balance.assetA = context.executionContext.balance.assetA + assetA; + context.executionContext.balance.assetB = context.executionContext.balance.assetB - assetB; + + context.executionContext.availableBalance.assetA = context.executionContext.availableBalance.assetA + assetA; + + /* Not the available balance for asset B is not affected since it was already reduced when the order was placed. */ + + } } } catch (err) { @@ -1240,7 +1262,7 @@ function getBalance() { if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getBalance -> Entering function."); } - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getBalance -> JSON.stringify(context.executionContext.balance) = " + JSON.stringify(context.executionContext.positions)); } + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getBalance -> JSON.stringify(context.executionContext.balance) = " + JSON.stringify(context.executionContext.balance)); } return JSON.parse(JSON.stringify(context.executionContext.balance)); } From fe42ca0f3e9a39c2b72644e3eca04b5ad3125bdc Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 9 Jul 2018 22:06:49 +0200 Subject: [PATCH 2/7] Minor detail --- Assistant.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assistant.js b/Assistant.js index 416b02d1f..a0050df50 100644 --- a/Assistant.js +++ b/Assistant.js @@ -1107,7 +1107,7 @@ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] movePosition -> pNewRate = " + pNewRate); } /* Removing extra decimals. */ - pNewRate = Number(parseFloat(pNewRate).toFixed(8)); + pNewRate = parseFloat(pNewRate).toFixed(8); let newAmountB; if (pPosition.type === "buy") { From ab20276130c453c19568eabb5fa73f6d52b1dd8d Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 11 Jul 2018 09:27:07 +0200 Subject: [PATCH 3/7] Minor Log Label Change --- ExtractionBotProcessMainLoop.js | 2 +- IndicatorBotProcessMainLoop.js | 2 +- TradingBotProcessMainLoop.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ExtractionBotProcessMainLoop.js b/ExtractionBotProcessMainLoop.js index 02d55dce5..a70615bd7 100644 --- a/ExtractionBotProcessMainLoop.js +++ b/ExtractionBotProcessMainLoop.js @@ -588,7 +588,7 @@ if (bot.enableCheckLoopHealth === false) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> checkLoopHealth -> bot.enableCheckLoopHealth = " + bot.enableCheckLoopHealth); + logger.write(MODULE_NAME, "[WARN] run -> loop -> checkLoopHealth -> bot.enableCheckLoopHealth = " + bot.enableCheckLoopHealth); return; } // This gets disabled anytime the Main Loop is shut down by any condition. diff --git a/IndicatorBotProcessMainLoop.js b/IndicatorBotProcessMainLoop.js index 24b80f667..9cd328bf9 100644 --- a/IndicatorBotProcessMainLoop.js +++ b/IndicatorBotProcessMainLoop.js @@ -559,7 +559,7 @@ if (bot.enableCheckLoopHealth === false) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> checkLoopHealth -> bot.enableCheckLoopHealth = " + bot.enableCheckLoopHealth); + logger.write(MODULE_NAME, "[WARN] run -> loop -> checkLoopHealth -> bot.enableCheckLoopHealth = " + bot.enableCheckLoopHealth); return; } // This gets disabled anytime the Main Loop is shut down by any condition. diff --git a/TradingBotProcessMainLoop.js b/TradingBotProcessMainLoop.js index 4dd3897be..80d259ab8 100644 --- a/TradingBotProcessMainLoop.js +++ b/TradingBotProcessMainLoop.js @@ -1046,7 +1046,7 @@ if (bot.enableCheckLoopHealth === false) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> checkLoopHealth -> bot.enableCheckLoopHealth = " + bot.enableCheckLoopHealth); + logger.write(MODULE_NAME, "[WARN] run -> loop -> checkLoopHealth -> bot.enableCheckLoopHealth = " + bot.enableCheckLoopHealth); return; } // This gets disabled anytime the Main Loop is shut down by any condition. From b3ab5ebc4752976b8c39fd50944f0ce7d9928b28 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 11 Jul 2018 09:47:06 +0200 Subject: [PATCH 4/7] All Number() removed --- Assistant.js | 60 ++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/Assistant.js b/Assistant.js index a0050df50..806dcd5d3 100644 --- a/Assistant.js +++ b/Assistant.js @@ -184,7 +184,7 @@ if (bot.processDatetime.valueOf() >= candle.begin && bot.processDatetime.valueOf() < candle.end) { marketRate = (candle.open + candle.close) / 2; - marketRate = Number(parseFloat(marketRate).toFixed(8)); + marketRate = parseFloat(marketRate).toFixed(8); context.newHistoryRecord.marketRate = marketRate; ticker = { @@ -559,9 +559,9 @@ id: Math.trunc(Math.random(1) * 1000000), type: thisPosition.type, rate: thisPosition.rate.toString(), - amountA: Number(parseFloat(thisPosition.amountA).toFixed(8)).toString(), - amountB: Number(parseFloat(thisPosition.amountB).toFixed(8)).toString(), - fee: Number(parseFloat(feeRate).toFixed(8)).toString(), + amountA: parseFloat(thisPosition.amountA).toFixed(8).toString(), + amountB: parseFloat(thisPosition.amountB).toFixed(8).toString(), + fee: parseFloat(feeRate).toFixed(8).toString(), date: (new Date()).valueOf() } @@ -648,12 +648,12 @@ for (let k = 0; k < pTrades.length; k++) { let trade = pTrades[k]; - sumAssetA = sumAssetA + Number(trade.amountA); - sumAssetB = sumAssetB + Number(trade.amountB); + sumAssetA = sumAssetA + parseFloat(trade.amountA).toFixed(8); + sumAssetB = sumAssetB + parseFloat(trade.amountB).toFixed(8); } - sumAssetA = Number(parseFloat(sumAssetA).toFixed(8)); - sumAssetB = Number(parseFloat(sumAssetB).toFixed(8)); + sumAssetA = parseFloat(sumAssetA).toFixed(8); + sumAssetB = parseFloat(sumAssetB).toFixed(8); if (position.amountB !== sumAssetB) { logger.write(MODULE_NAME, "[ERROR] ordersExecutionCheck -> loopBody -> position.amountB = " + position.amountB); @@ -718,17 +718,17 @@ for (let k = 0; k < pTrades.length; k++) { let trade = pTrades[k]; - sumAssetA = sumAssetA + Number(trade.amountA); - sumAssetB = sumAssetB + Number(trade.amountB); + sumAssetA = sumAssetA + parseFloat(trade.amountA); + sumAssetB = sumAssetB + parseFloat(trade.amountB); } /* To this we add the current position amounts. */ - sumAssetA = sumAssetA + Number(exchangePosition.amountA); - sumAssetB = sumAssetB + Number(exchangePosition.amountB); + sumAssetA = sumAssetA + parseFloat(exchangePosition.amountA).toFixed(8); + sumAssetB = sumAssetB + parseFloat(exchangePosition.amountB).toFixed(8); - sumAssetA = Number(parseFloat(sumAssetA).toFixed(6)); // Fixed to 6 positions to avoid rounding issues - sumAssetB = Number(parseFloat(sumAssetB).toFixed(8)); + sumAssetA = parseFloat(sumAssetA).toFixed(8); + sumAssetB = parseFloat(sumAssetB).toFixed(8); if (parseFloat(position.amountA).toFixed(6) !== sumAssetA || position.amountB !== sumAssetB ) { logger.write(MODULE_NAME, "[ERROR] ordersExecutionCheck -> loopBody -> confirmOrderWasPartiallyExecuted -> position.amountA = " + position.amountA); @@ -805,8 +805,8 @@ let feeAmount = parseFloat(Number(trade.fee) * Number(trade.amountB)).toFixed(8); - assetA = Number(trade.amountA); - assetB = Number(trade.amountB) - feeAmount; + assetA = parseFloat(trade.amountA).toFixed(8); + assetB = parseFloat(trade.amountB).toFixed(8) - feeAmount; context.executionContext.balance.assetA = context.executionContext.balance.assetA - assetA; context.executionContext.balance.assetB = context.executionContext.balance.assetB + assetB; @@ -828,8 +828,8 @@ let feeAmount = parseFloat(Number(trade.fee) * Number(trade.amountA)).toFixed(8); - assetA = Number(trade.amountA) - feeAmount; - assetB = Number(trade.amountB); + assetA = parseFloat(trade.amountA).toFixed(8) - feeAmount; + assetB = parseFloat(trade.amountB).toFixed(8); context.executionContext.balance.assetA = context.executionContext.balance.assetA + assetA; context.executionContext.balance.assetB = context.executionContext.balance.assetB - assetB; @@ -904,19 +904,19 @@ /* Removing extra decimals. */ - pRate = Number(parseFloat(pRate).toFixed(8)); - pAmountA = Number(parseFloat(pAmountA).toFixed(8)); - pAmountB = Number(parseFloat(pAmountB).toFixed(8)); + pRate = parseFloat(pRate).toFixed(8); + pAmountA = parseFloat(pAmountA).toFixed(8); + pAmountB = parseFloat(pAmountB).toFixed(8); /* Validations that the limits are not surpassed. */ if (pType === 'buy') { - if (pAmountA > context.executionContext.availableBalance.assetA) { + if (pAmountA > parseFloat(context.executionContext.availableBalance.assetA).toFixed(8)) { logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountA is grater than the Available Balance."); logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountA = " + pAmountA); - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> Available Balance = " + context.executionContext.availableBalance.assetA); + logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> Available Balance = " + parseFloat(context.executionContext.availableBalance.assetA).toFixed(8)); let err = { result: global.DEFAULT_FAIL_RESPONSE.result, @@ -927,7 +927,7 @@ return; } - let aRate = Number(parseFloat(pAmountA / pRate).toFixed(8)); + let aRate = parseFloat(pAmountA / pRate).toFixed(8); if (aRate !== pAmountB) { @@ -948,11 +948,11 @@ if (pType === 'sell') { - if (pAmountB > context.executionContext.availableBalance.assetB) { + if (pAmountB > parseFloat(context.executionContext.availableBalance.assetB).toFixed(8)) { logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountB is grater than the Available Balance."); logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountB = " + pAmountB); - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> Available Balance = " + context.executionContext.availableBalance.assetB); + logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> Available Balance = " + parseFloat(context.executionContext.availableBalance.assetB).toFixed(8)); let err = { result: global.DEFAULT_FAIL_RESPONSE.result, @@ -963,7 +963,7 @@ return; } - let bRate = Number(parseFloat(pAmountB * pRate).toFixed(8)); + let bRate = parseFloat(pAmountB * pRate).toFixed(8); if (bRate !== pAmountA) { @@ -1060,14 +1060,14 @@ if (position.type === 'buy') { context.executionContext.availableBalance.assetA = context.executionContext.availableBalance.assetA - pAmountA; - context.executionContext.availableBalance.assetA = Number(parseFloat(context.executionContext.availableBalance.assetA).toFixed(8)); + context.executionContext.availableBalance.assetA = parseFloat(context.executionContext.availableBalance.assetA).toFixed(8); context.newHistoryRecord.lastBuyRate = pRate; } if (position.type === 'sell') { context.executionContext.availableBalance.assetB = context.executionContext.availableBalance.assetB - pAmountB; - context.executionContext.availableBalance.assetB = Number(parseFloat(context.executionContext.availableBalance.assetB).toFixed(8)); + context.executionContext.availableBalance.assetB = parseFloat(context.executionContext.availableBalance.assetB).toFixed(8); context.newHistoryRecord.lastSellRate = pRate; } @@ -1111,7 +1111,7 @@ let newAmountB; if (pPosition.type === "buy") { - newAmountB = Number(parseFloat(pPosition.amountA / pNewRate).toFixed(8)); + newAmountB = parseFloat(pPosition.amountA / pNewRate).toFixed(8); } else { newAmountB = pPosition.amountB; } From 896ac0e86d07851e2aebe025c7ef8585a4807f0a Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sun, 22 Jul 2018 19:49:54 +0200 Subject: [PATCH 5/7] BUG toFixed 6 instead of 8 --- Assistant.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Assistant.js b/Assistant.js index 806dcd5d3..27012b155 100644 --- a/Assistant.js +++ b/Assistant.js @@ -730,13 +730,14 @@ sumAssetA = parseFloat(sumAssetA).toFixed(8); sumAssetB = parseFloat(sumAssetB).toFixed(8); - if (parseFloat(position.amountA).toFixed(6) !== sumAssetA || position.amountB !== sumAssetB ) { + if (parseFloat(position.amountA).toFixed(8) !== sumAssetA || position.amountB !== sumAssetB) { + logger.write(MODULE_NAME, "[ERROR] ordersExecutionCheck -> loopBody -> confirmOrderWasPartiallyExecuted -> position.amountA = " + position.amountA); logger.write(MODULE_NAME, "[ERROR] ordersExecutionCheck -> loopBody -> confirmOrderWasPartiallyExecuted -> sumAssetA = " + sumAssetA); logger.write(MODULE_NAME, "[ERROR] ordersExecutionCheck -> loopBody -> confirmOrderWasPartiallyExecuted -> position.amountB = " + position.amountB); logger.write(MODULE_NAME, "[ERROR] ordersExecutionCheck -> loopBody -> confirmOrderWasPartiallyExecuted -> sumAssetB = " + sumAssetB); - logger.write(MODULE_NAME, "[ERROR] ordersExecutionCheck -> loopBody -> confirmOrderWasPartiallyExecuted -> Cannot be confirmed that a partially execution was done well."); + logger.write(MODULE_NAME, "[ERROR] ordersExecutionCheck -> loopBody -> confirmOrderWasPartiallyExecuted -> Cannot be confirmed that a partiall execution was done well."); /* There are diferences on the responses between the getPosition and getTrades that causes some issues, let's retry. */ callBack(global.DEFAULT_RETRY_RESPONSE); From f9cfc81f38ad7f8869540a8658640e5572e33369 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 23 Jul 2018 10:58:37 +0200 Subject: [PATCH 6/7] All float values explicitelly converted prior calculations. BUG in some cases adding strings. --- Assistant.js | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/Assistant.js b/Assistant.js index 27012b155..dc1b3c227 100644 --- a/Assistant.js +++ b/Assistant.js @@ -273,12 +273,14 @@ if (context.executionContext.investment.assetA > 0) { - context.executionContext.profits.assetA = (context.executionContext.balance.assetA - context.executionContext.investment.assetA) / context.executionContext.investment.assetA; + context.executionContext.profits.assetA = (parseFloat(context.executionContext.balance.assetA).toFixed(8) - parseFloat(context.executionContext.investment.assetA).toFixed(8)) / parseFloat(context.executionContext.investment.assetA).toFixed(8); + context.executionContext.profits.assetA = parseFloat(context.executionContext.profits.assetA).toFixed(8); } if (context.executionContext.investment.assetB > 0) { - context.executionContext.profits.assetB = (context.executionContext.balance.assetB - context.executionContext.investment.assetB) / context.executionContext.investment.assetB; + context.executionContext.profits.assetB = (parseFloat(context.executionContext.balance.assetB).toFixed(8) - parseFloat(context.executionContext.investment.assetB).toFixed(8)) / parseFloat(context.executionContext.investment.assetB).toFixed(8); + context.executionContext.profits.assetB = parseFloat(context.executionContext.profits.assetB).toFixed(8); } context.newHistoryRecord.profitsAssetA = context.executionContext.profits.assetA; @@ -288,16 +290,20 @@ if (context.executionContext.investment.assetA > 0) { - let convertedAssetsB = (context.executionContext.balance.assetB - context.executionContext.investment.assetB) * marketRate; + let convertedAssetsB = (parseFloat(context.executionContext.balance.assetB).toFixed(8) - parseFloat(context.executionContext.investment.assetB).toFixed(8)) * marketRate; + convertedAssetsB = parseFloat(convertedAssetsB).toFixed(8); - context.executionContext.combinedProfits.assetA = (context.executionContext.balance.assetA + convertedAssetsB - context.executionContext.investment.assetA) / context.executionContext.investment.assetA * 100; + context.executionContext.combinedProfits.assetA = (parseFloat(context.executionContext.balance.assetA).toFixed(8) + convertedAssetsB - parseFloat(context.executionContext.investment.assetA).toFixed(8)) / parseFloat(context.executionContext.investment.assetA).toFixed(8) * 100; + context.executionContext.combinedProfits.assetA = parseFloat(context.executionContext.combinedProfits.assetA).toFixed(8); } if (context.executionContext.investment.assetB > 0) { - let convertedAssetsA = (context.executionContext.balance.assetA - context.executionContext.investment.assetA) / marketRate; + let convertedAssetsA = (parseFloat(context.executionContext.balance.assetA).toFixed(8) - parseFloat(context.executionContext.investment.assetA).toFixed(8)) / marketRate; + convertedAssetsA = parseFloat(convertedAssetsA).toFixed(8); - context.executionContext.combinedProfits.assetB = (context.executionContext.balance.assetB + convertedAssetsA - context.executionContext.investment.assetB) / context.executionContext.investment.assetB * 100; + context.executionContext.combinedProfits.assetB = (parseFloat(context.executionContext.balance.assetB).toFixed(8) + convertedAssetsA - parseFloat(context.executionContext.investment.assetB).toFixed(8)) / parseFloat(context.executionContext.investment.assetB).toFixed(8) * 100; + context.executionContext.combinedProfits.assetB = parseFloat(context.executionContext.combinedProfits.assetB).toFixed(8); } context.newHistoryRecord.combinedProfitsA = context.executionContext.combinedProfits.assetA; @@ -809,10 +815,10 @@ assetA = parseFloat(trade.amountA).toFixed(8); assetB = parseFloat(trade.amountB).toFixed(8) - feeAmount; - context.executionContext.balance.assetA = context.executionContext.balance.assetA - assetA; - context.executionContext.balance.assetB = context.executionContext.balance.assetB + assetB; + context.executionContext.balance.assetA = parseFloat(context.executionContext.balance.assetA).toFixed(8) - assetA; + context.executionContext.balance.assetB = parseFloat(context.executionContext.balance.assetB).toFixed(8) + assetB; - context.executionContext.availableBalance.assetB = context.executionContext.availableBalance.assetB + assetB; + context.executionContext.availableBalance.assetB = parseFloat(context.executionContext.availableBalance.assetB).toFixed(8) + assetB; /* Not the available balance for asset A is not affected since it was already reduced when the order was placed. */ @@ -832,10 +838,10 @@ assetA = parseFloat(trade.amountA).toFixed(8) - feeAmount; assetB = parseFloat(trade.amountB).toFixed(8); - context.executionContext.balance.assetA = context.executionContext.balance.assetA + assetA; - context.executionContext.balance.assetB = context.executionContext.balance.assetB - assetB; + context.executionContext.balance.assetA = parseFloat(context.executionContext.balance.assetA).toFixed(8) + assetA; + context.executionContext.balance.assetB = parseFloat(context.executionContext.balance.assetB).toFixed(8) - assetB; - context.executionContext.availableBalance.assetA = context.executionContext.availableBalance.assetA + assetA; + context.executionContext.availableBalance.assetA = parseFloat(context.executionContext.availableBalance.assetA).toFixed(8) + assetA; /* Not the available balance for asset B is not affected since it was already reduced when the order was placed. */ @@ -1060,14 +1066,14 @@ if (position.type === 'buy') { - context.executionContext.availableBalance.assetA = context.executionContext.availableBalance.assetA - pAmountA; + context.executionContext.availableBalance.assetA = parseFloat(context.executionContext.availableBalance.assetA).toFixed(8) - pAmountA; context.executionContext.availableBalance.assetA = parseFloat(context.executionContext.availableBalance.assetA).toFixed(8); context.newHistoryRecord.lastBuyRate = pRate; } if (position.type === 'sell') { - context.executionContext.availableBalance.assetB = context.executionContext.availableBalance.assetB - pAmountB; + context.executionContext.availableBalance.assetB = parseFloat(context.executionContext.availableBalance.assetB).toFixed(8) - pAmountB; context.executionContext.availableBalance.assetB = parseFloat(context.executionContext.availableBalance.assetB).toFixed(8); context.newHistoryRecord.lastSellRate = pRate; } From c872dc4b61fe36ff1f172ba70317e77c511a2c7f Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 23 Jul 2018 11:52:50 +0200 Subject: [PATCH 7/7] New function truncDecimals to deal with too many decimals at float numbers. --- Assistant.js | 117 +++++++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 55 deletions(-) diff --git a/Assistant.js b/Assistant.js index dc1b3c227..7ddf29b58 100644 --- a/Assistant.js +++ b/Assistant.js @@ -29,6 +29,7 @@ sendMessage: sendMessage, rememberThis: rememberThis, remindMeOf: remindMeOf, + truncDecimals: truncDecimals, sendEmail: sendEmail }; @@ -184,7 +185,7 @@ if (bot.processDatetime.valueOf() >= candle.begin && bot.processDatetime.valueOf() < candle.end) { marketRate = (candle.open + candle.close) / 2; - marketRate = parseFloat(marketRate).toFixed(8); + marketRate = thisObject.truncDecimals(marketRate); context.newHistoryRecord.marketRate = marketRate; ticker = { @@ -273,14 +274,14 @@ if (context.executionContext.investment.assetA > 0) { - context.executionContext.profits.assetA = (parseFloat(context.executionContext.balance.assetA).toFixed(8) - parseFloat(context.executionContext.investment.assetA).toFixed(8)) / parseFloat(context.executionContext.investment.assetA).toFixed(8); - context.executionContext.profits.assetA = parseFloat(context.executionContext.profits.assetA).toFixed(8); + context.executionContext.profits.assetA = (thisObject.truncDecimals(context.executionContext.balance.assetA) - thisObject.truncDecimals(context.executionContext.investment.assetA)) / thisObject.truncDecimals(context.executionContext.investment.assetA); + context.executionContext.profits.assetA = thisObject.truncDecimals(context.executionContext.profits.assetA); } if (context.executionContext.investment.assetB > 0) { - context.executionContext.profits.assetB = (parseFloat(context.executionContext.balance.assetB).toFixed(8) - parseFloat(context.executionContext.investment.assetB).toFixed(8)) / parseFloat(context.executionContext.investment.assetB).toFixed(8); - context.executionContext.profits.assetB = parseFloat(context.executionContext.profits.assetB).toFixed(8); + context.executionContext.profits.assetB = (thisObject.truncDecimals(context.executionContext.balance.assetB) - thisObject.truncDecimals(context.executionContext.investment.assetB)) / thisObject.truncDecimals(context.executionContext.investment.assetB); + context.executionContext.profits.assetB = thisObject.truncDecimals(context.executionContext.profits.assetB); } context.newHistoryRecord.profitsAssetA = context.executionContext.profits.assetA; @@ -290,20 +291,20 @@ if (context.executionContext.investment.assetA > 0) { - let convertedAssetsB = (parseFloat(context.executionContext.balance.assetB).toFixed(8) - parseFloat(context.executionContext.investment.assetB).toFixed(8)) * marketRate; - convertedAssetsB = parseFloat(convertedAssetsB).toFixed(8); + let convertedAssetsB = (thisObject.truncDecimals(context.executionContext.balance.assetB) - thisObject.truncDecimals(context.executionContext.investment.assetB)) * marketRate; + convertedAssetsB = thisObject.truncDecimals(convertedAssetsB); - context.executionContext.combinedProfits.assetA = (parseFloat(context.executionContext.balance.assetA).toFixed(8) + convertedAssetsB - parseFloat(context.executionContext.investment.assetA).toFixed(8)) / parseFloat(context.executionContext.investment.assetA).toFixed(8) * 100; - context.executionContext.combinedProfits.assetA = parseFloat(context.executionContext.combinedProfits.assetA).toFixed(8); + context.executionContext.combinedProfits.assetA = (thisObject.truncDecimals(context.executionContext.balance.assetA) + convertedAssetsB - thisObject.truncDecimals(context.executionContext.investment.assetA)) / thisObject.truncDecimals(context.executionContext.investment.assetA) * 100; + context.executionContext.combinedProfits.assetA = thisObject.truncDecimals(context.executionContext.combinedProfits.assetA); } if (context.executionContext.investment.assetB > 0) { - let convertedAssetsA = (parseFloat(context.executionContext.balance.assetA).toFixed(8) - parseFloat(context.executionContext.investment.assetA).toFixed(8)) / marketRate; - convertedAssetsA = parseFloat(convertedAssetsA).toFixed(8); + let convertedAssetsA = (thisObject.truncDecimals(context.executionContext.balance.assetA) - thisObject.truncDecimals(context.executionContext.investment.assetA)) / marketRate; + convertedAssetsA = thisObject.truncDecimals(convertedAssetsA); - context.executionContext.combinedProfits.assetB = (parseFloat(context.executionContext.balance.assetB).toFixed(8) + convertedAssetsA - parseFloat(context.executionContext.investment.assetB).toFixed(8)) / parseFloat(context.executionContext.investment.assetB).toFixed(8) * 100; - context.executionContext.combinedProfits.assetB = parseFloat(context.executionContext.combinedProfits.assetB).toFixed(8); + context.executionContext.combinedProfits.assetB = (thisObject.truncDecimals(context.executionContext.balance.assetB) + convertedAssetsA - thisObject.truncDecimals(context.executionContext.investment.assetB)) / thisObject.truncDecimals(context.executionContext.investment.assetB) * 100; + context.executionContext.combinedProfits.assetB = thisObject.truncDecimals(context.executionContext.combinedProfits.assetB); } context.newHistoryRecord.combinedProfitsA = context.executionContext.combinedProfits.assetA; @@ -494,7 +495,7 @@ */ - if (position.amountB === parseFloat(exchangePosition.amountB)) { + if (position.amountB === thisObject.truncDecimals(exchangePosition.amountB)) { /* Position is still there, untouched. Nothing to do here. */ @@ -565,9 +566,9 @@ id: Math.trunc(Math.random(1) * 1000000), type: thisPosition.type, rate: thisPosition.rate.toString(), - amountA: parseFloat(thisPosition.amountA).toFixed(8).toString(), - amountB: parseFloat(thisPosition.amountB).toFixed(8).toString(), - fee: parseFloat(feeRate).toFixed(8).toString(), + amountA: thisObject.truncDecimals(thisPosition.amountA).toString(), + amountB: thisObject.truncDecimals(thisPosition.amountB).toString(), + fee: thisObject.truncDecimals(feeRate).toString(), date: (new Date()).valueOf() } @@ -654,12 +655,12 @@ for (let k = 0; k < pTrades.length; k++) { let trade = pTrades[k]; - sumAssetA = sumAssetA + parseFloat(trade.amountA).toFixed(8); - sumAssetB = sumAssetB + parseFloat(trade.amountB).toFixed(8); + sumAssetA = sumAssetA + thisObject.truncDecimals(trade.amountA); + sumAssetB = sumAssetB + thisObject.truncDecimals(trade.amountB); } - sumAssetA = parseFloat(sumAssetA).toFixed(8); - sumAssetB = parseFloat(sumAssetB).toFixed(8); + sumAssetA = thisObject.truncDecimals(sumAssetA); + sumAssetB = thisObject.truncDecimals(sumAssetB); if (position.amountB !== sumAssetB) { logger.write(MODULE_NAME, "[ERROR] ordersExecutionCheck -> loopBody -> position.amountB = " + position.amountB); @@ -724,19 +725,19 @@ for (let k = 0; k < pTrades.length; k++) { let trade = pTrades[k]; - sumAssetA = sumAssetA + parseFloat(trade.amountA); - sumAssetB = sumAssetB + parseFloat(trade.amountB); + sumAssetA = sumAssetA + thisObject.truncDecimals(trade.amountA); + sumAssetB = sumAssetB + thisObject.truncDecimals(trade.amountB); } /* To this we add the current position amounts. */ - sumAssetA = sumAssetA + parseFloat(exchangePosition.amountA).toFixed(8); - sumAssetB = sumAssetB + parseFloat(exchangePosition.amountB).toFixed(8); + sumAssetA = sumAssetA + thisObject.truncDecimals(exchangePosition.amountA); + sumAssetB = sumAssetB + thisObject.truncDecimals(exchangePosition.amountB); - sumAssetA = parseFloat(sumAssetA).toFixed(8); - sumAssetB = parseFloat(sumAssetB).toFixed(8); + sumAssetA = thisObject.truncDecimals(sumAssetA); + sumAssetB = thisObject.truncDecimals(sumAssetB); - if (parseFloat(position.amountA).toFixed(8) !== sumAssetA || position.amountB !== sumAssetB) { + if (thisObject.truncDecimals(position.amountA) !== sumAssetA || position.amountB !== sumAssetB) { logger.write(MODULE_NAME, "[ERROR] ordersExecutionCheck -> loopBody -> confirmOrderWasPartiallyExecuted -> position.amountA = " + position.amountA); logger.write(MODULE_NAME, "[ERROR] ordersExecutionCheck -> loopBody -> confirmOrderWasPartiallyExecuted -> sumAssetA = " + sumAssetA); @@ -810,15 +811,15 @@ */ - let feeAmount = parseFloat(Number(trade.fee) * Number(trade.amountB)).toFixed(8); + let feeAmount = thisObject.truncDecimals(Number(trade.fee) * Number(trade.amountB)); - assetA = parseFloat(trade.amountA).toFixed(8); - assetB = parseFloat(trade.amountB).toFixed(8) - feeAmount; + assetA = thisObject.truncDecimals(trade.amountA); + assetB = thisObject.truncDecimals(trade.amountB) - feeAmount; - context.executionContext.balance.assetA = parseFloat(context.executionContext.balance.assetA).toFixed(8) - assetA; - context.executionContext.balance.assetB = parseFloat(context.executionContext.balance.assetB).toFixed(8) + assetB; + context.executionContext.balance.assetA = thisObject.truncDecimals(context.executionContext.balance.assetA) - assetA; + context.executionContext.balance.assetB = thisObject.truncDecimals(context.executionContext.balance.assetB) + assetB; - context.executionContext.availableBalance.assetB = parseFloat(context.executionContext.availableBalance.assetB).toFixed(8) + assetB; + context.executionContext.availableBalance.assetB = thisObject.truncDecimals(context.executionContext.availableBalance.assetB) + assetB; /* Not the available balance for asset A is not affected since it was already reduced when the order was placed. */ @@ -833,15 +834,15 @@ */ - let feeAmount = parseFloat(Number(trade.fee) * Number(trade.amountA)).toFixed(8); + let feeAmount = thisObject.truncDecimals(Number(trade.fee) * Number(trade.amountA)); - assetA = parseFloat(trade.amountA).toFixed(8) - feeAmount; - assetB = parseFloat(trade.amountB).toFixed(8); + assetA = thisObject.truncDecimals(trade.amountA) - feeAmount; + assetB = thisObject.truncDecimals(trade.amountB); - context.executionContext.balance.assetA = parseFloat(context.executionContext.balance.assetA).toFixed(8) + assetA; - context.executionContext.balance.assetB = parseFloat(context.executionContext.balance.assetB).toFixed(8) - assetB; + context.executionContext.balance.assetA = thisObject.truncDecimals(context.executionContext.balance.assetA) + assetA; + context.executionContext.balance.assetB = thisObject.truncDecimals(context.executionContext.balance.assetB) - assetB; - context.executionContext.availableBalance.assetA = parseFloat(context.executionContext.availableBalance.assetA).toFixed(8) + assetA; + context.executionContext.availableBalance.assetA = thisObject.truncDecimals(context.executionContext.availableBalance.assetA) + assetA; /* Not the available balance for asset B is not affected since it was already reduced when the order was placed. */ @@ -911,19 +912,19 @@ /* Removing extra decimals. */ - pRate = parseFloat(pRate).toFixed(8); - pAmountA = parseFloat(pAmountA).toFixed(8); - pAmountB = parseFloat(pAmountB).toFixed(8); + pRate = thisObject.truncDecimals(pRate); + pAmountA = thisObject.truncDecimals(pAmountA); + pAmountB = thisObject.truncDecimals(pAmountB); /* Validations that the limits are not surpassed. */ if (pType === 'buy') { - if (pAmountA > parseFloat(context.executionContext.availableBalance.assetA).toFixed(8)) { + if (pAmountA > thisObject.truncDecimals(context.executionContext.availableBalance.assetA)) { logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountA is grater than the Available Balance."); logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountA = " + pAmountA); - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> Available Balance = " + parseFloat(context.executionContext.availableBalance.assetA).toFixed(8)); + logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> Available Balance = " + thisObject.truncDecimals(context.executionContext.availableBalance.assetA)); let err = { result: global.DEFAULT_FAIL_RESPONSE.result, @@ -934,7 +935,7 @@ return; } - let aRate = parseFloat(pAmountA / pRate).toFixed(8); + let aRate = thisObject.truncDecimals(pAmountA / pRate); if (aRate !== pAmountB) { @@ -955,11 +956,11 @@ if (pType === 'sell') { - if (pAmountB > parseFloat(context.executionContext.availableBalance.assetB).toFixed(8)) { + if (pAmountB > thisObject.truncDecimals(context.executionContext.availableBalance.assetB)) { logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountB is grater than the Available Balance."); logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountB = " + pAmountB); - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> Available Balance = " + parseFloat(context.executionContext.availableBalance.assetB).toFixed(8)); + logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> Available Balance = " + thisObject.truncDecimals(context.executionContext.availableBalance.assetB)); let err = { result: global.DEFAULT_FAIL_RESPONSE.result, @@ -970,7 +971,7 @@ return; } - let bRate = parseFloat(pAmountB * pRate).toFixed(8); + let bRate = thisObject.truncDecimals(pAmountB * pRate); if (bRate !== pAmountA) { @@ -1066,15 +1067,15 @@ if (position.type === 'buy') { - context.executionContext.availableBalance.assetA = parseFloat(context.executionContext.availableBalance.assetA).toFixed(8) - pAmountA; - context.executionContext.availableBalance.assetA = parseFloat(context.executionContext.availableBalance.assetA).toFixed(8); + context.executionContext.availableBalance.assetA = thisObject.truncDecimals(context.executionContext.availableBalance.assetA) - pAmountA; + context.executionContext.availableBalance.assetA = thisObject.truncDecimals(context.executionContext.availableBalance.assetA); context.newHistoryRecord.lastBuyRate = pRate; } if (position.type === 'sell') { - context.executionContext.availableBalance.assetB = parseFloat(context.executionContext.availableBalance.assetB).toFixed(8) - pAmountB; - context.executionContext.availableBalance.assetB = parseFloat(context.executionContext.availableBalance.assetB).toFixed(8); + context.executionContext.availableBalance.assetB = thisObject.truncDecimals(context.executionContext.availableBalance.assetB) - pAmountB; + context.executionContext.availableBalance.assetB = thisObject.truncDecimals(context.executionContext.availableBalance.assetB); context.newHistoryRecord.lastSellRate = pRate; } @@ -1114,11 +1115,11 @@ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] movePosition -> pNewRate = " + pNewRate); } /* Removing extra decimals. */ - pNewRate = parseFloat(pNewRate).toFixed(8); + pNewRate = thisObject.truncDecimals(pNewRate); let newAmountB; if (pPosition.type === "buy") { - newAmountB = parseFloat(pPosition.amountA / pNewRate).toFixed(8); + newAmountB = thisObject.truncDecimals(pPosition.amountA / pNewRate); } else { newAmountB = pPosition.amountB; } @@ -1410,4 +1411,10 @@ logger.write(MODULE_NAME, "[ERROR] sendEmail -> err = " + err.message); } } + + function truncDecimals(pFloatValue) { + + return parseFloat(parseFloat(pFloatValue).toFixed(8)); + + } }; \ No newline at end of file