Trading Engine Changes

This commit is contained in:
Luis Fernando Molina committed 2019-08-23 18:12:31 +02:00
1 parent d7ac972312
commit 9ef05adf0c
2 files changed
+153 -78

No files matched your search

+149 -74
View File
@@ -164,16 +164,61 @@ exports.newCommons = function newCommons(bot, logger, UTILITIES) {
}
/* Slippage */
let slippage = 0
let slippage = { // Default Values
positionRate: 0,
stopLoss: 0,
takeProfit: 0
}
if (definition.tradingSystem !== undefined) {
if (definition.tradingSystem.parameters !== undefined) {
if (definition.tradingSystem.parameters.baseAsset !== undefined) {
if (definition.tradingSystem.parameters.baseAsset.formula !== undefined) {
if (definition.tradingSystem.parameters.baseAsset.formula.code !== undefined) {
let code = JSON.parse(definition.tradingSystem.parameters.baseAsset.formula.code)
if (code.initialDatetime !== undefined) {
slippage = code.slippage
try {
let code = JSON.parse(definition.tradingSystem.parameters.baseAsset.formula.code)
if (code.slippage !== undefined) {
if (code.slippage.positionRate !== undefined) {
slippage.positionRate = code.slippage.positionRate
}
if (code.slippage.stopLoss !== undefined) {
slippage.stopLoss = code.slippage.stopLoss
}
if (code.slippage.takeProfit !== undefined) {
slippage.takeProfit = code.slippage.takeProfit
}
}
} catch (err) {
tradingSystem.parameters.baseAsset.formula.error = "Slippage Error: " + err.message
}
}
}
}
}
}
/* Fee Structure */
let feeStructure = { // Default Values
maker: 0,
taker: 0
}
if (definition.tradingSystem !== undefined) {
if (definition.tradingSystem.parameters !== undefined) {
if (definition.tradingSystem.parameters.baseAsset !== undefined) {
if (definition.tradingSystem.parameters.baseAsset.formula !== undefined) {
if (definition.tradingSystem.parameters.baseAsset.formula.code !== undefined) {
try {
let code = JSON.parse(definition.tradingSystem.parameters.baseAsset.formula.code)
if (code.feeStructure !== undefined) {
if (code.feeStructure.maker !== undefined) {
feeStructure.maker = code.feeStructure.maker
}
if (code.feeStructure.taker !== undefined) {
feeStructure.taker = code.feeStructure.taker
}
}
} catch (err) {
tradingSystem.parameters.baseAsset.formula.error = "Fee Structure Error: " + err.message
}
}
}
@@ -550,16 +595,10 @@ exports.newCommons = function newCommons(bot, logger, UTILITIES) {
/* Assistant Info */
let ticker
if (process.env.START_MODE === "live" && i === candles.length - 2) {
ticker = assistant.getTicker()
} else {
ticker = {
bid: candle.close,
ask: candle.close,
last: candle.close
}
let ticker = {
bid: candle.close,
ask: candle.close,
last: candle.close
}
//let LRC = LRCMap.get(candle.begin);
@@ -1280,8 +1319,6 @@ exports.newCommons = function newCommons(bot, logger, UTILITIES) {
takeProfitStage = 'Open Stage';
stopLossPhase = 1;
takeProfitPhase = 1;
currentTrade.begin = candle.begin;
currentTrade.beginRate = strategy.positionRate;
if (processingDailyFiles) {
if (positionedAtYesterday) {
@@ -1290,8 +1327,6 @@ exports.newCommons = function newCommons(bot, logger, UTILITIES) {
yesterday.takeProfitStage = takeProfitStage;
yesterday.stopLossPhase = stopLossPhase;
yesterday.takeProfitPhase = takeProfitPhase;
yesterday.currentTrade.begin = currentTrade.begin;
yesterday.currentTrade.beginRate = currentTrade.beginRate;
}
}
@@ -1583,20 +1618,23 @@ exports.newCommons = function newCommons(bot, logger, UTILITIES) {
if ((baseAsset === 'BTC' && candle.max >= stopLoss) || (baseAsset !== 'BTC' && candle.min <= stopLoss)) {
/* Check the Slipagge */
/*
Hit Point Validation
let stopLossHitPoint = stopLoss
This prevents misscalculations when a formula places the stop loss in this case way beyond the market price.
If we take the stop loss value at those situation would be a huge distortion of facts.
*/
if (baseAsset === 'BTC') {
if (stopLossHitPoint < candle.open) { stopLossHitPoint = candle.open}
if (stopLossHitPoint < candle.close) { stopLossHitPoint = candle.close }
if (stopLoss < candle.min) { stopLoss = candle.min }
} else {
if (stopLossHitPoint > candle.open) { stopLossHitPoint = candle.open }
if (stopLossHitPoint > candle.close) { stopLossHitPoint = candle.close }
if (stopLoss > candle.max) { stopLoss = candle.max }
}
let slippedStopLoss = stopLossHitPoint
let slippageAmount = stopLossHitPoint * slippage / 100
let slippedStopLoss = stopLoss
/* Apply the Slippage */
let slippageAmount = slippedStopLoss * slippage.stopLoss / 100
if (baseAsset === 'BTC') {
slippedStopLoss = slippedStopLoss + slippageAmount
@@ -1604,17 +1642,25 @@ exports.newCommons = function newCommons(bot, logger, UTILITIES) {
slippedStopLoss = slippedStopLoss - slippageAmount
}
if (baseAsset === 'BTC') {
strategy.positionSize = balanceAssetB / slippedStopLoss;
strategy.positionRate = slippedStopLoss;
let finalStopLoss = slippedStopLoss;
balanceAssetA = balanceAssetA + balanceAssetB / slippedStopLoss;
let feePaid = 0
if (baseAsset === 'BTC') {
strategy.positionSize = balanceAssetB / finalStopLoss;
strategy.positionRate = finalStopLoss;
feePaid = balanceAssetB / finalStopLoss * feeStructure.taker / 100
balanceAssetA = balanceAssetA + balanceAssetB / finalStopLoss - feePaid;
balanceAssetB = 0;
} else {
strategy.positionSize = balanceAssetA * slippedStopLoss;
strategy.positionRate = slippedStopLoss;
strategy.positionSize = balanceAssetA * finalStopLoss;
strategy.positionRate = finalStopLoss;
balanceAssetB = balanceAssetB + balanceAssetA * slippedStopLoss;
feePaid = balanceAssetA * finalStopLoss * feeStructure.taker / 100
balanceAssetB = balanceAssetB + balanceAssetA * finalStopLoss - feePaid;
balanceAssetA = 0;
}
@@ -1625,7 +1671,7 @@ exports.newCommons = function newCommons(bot, logger, UTILITIES) {
}
}
marketRate = slippedStopLoss;
marketRate = finalStopLoss;
type = '"Close@StopLoss"';
strategyStage = 'Close Stage';
stopLossStage = 'No Stage';
@@ -1633,8 +1679,8 @@ exports.newCommons = function newCommons(bot, logger, UTILITIES) {
currentTrade.end = candle.end;
currentTrade.status = 1;
currentTrade.exitType = 1;
currentTrade.endRate = slippedStopLoss;
currentTrade.endRate = finalStopLoss;
closePositionNow = true;
if (processingDailyFiles) {
@@ -1654,38 +1700,48 @@ exports.newCommons = function newCommons(bot, logger, UTILITIES) {
if ((baseAsset === 'BTC' && candle.min <= takeProfit) || (baseAsset !== 'BTC' && candle.max >= takeProfit)) {
/* Check the Slipagge */
/*
Hit Point Validation:
let takeProfitHitPoint = stopLoss
This prevents misscalculations when a formula places the take profit in this case way beyond the market price.
If we take the stop loss value at those situation would be a huge distortion of facts.
*/
if (baseAsset === 'BTC') {
if (takeProfitHitPoint > candle.open) { takeProfitHitPoint = candle.open }
if (takeProfitHitPoint > candle.close) { takeProfitHitPoint = candle.close }
if (takeProfit > candle.max) { takeProfit = candle.max }
} else {
if (takeProfitHitPoint < candle.open) { takeProfitHitPoint = candle.open }
if (takeProfitHitPoint < candle.close) { takeProfitHitPoint = candle.close }
if (takeProfit < candle.min) { takeProfit = candle.min }
}
let slippedTakeProfit = takeProfit
let slippageAmount = stopLoss * slippage / 100
/* Apply the Slippage */
let slippageAmount = slippedTakeProfit * slippage.takeProfit / 100
if (baseAsset === 'BTC') {
slippedTakeProfit = slippedTakeProfit - slippageAmount
} else {
slippedTakeProfit = slippedTakeProfit + slippageAmount
} else {
slippedTakeProfit = slippedTakeProfit - slippageAmount
}
if (baseAsset === 'BTC') {
strategy.positionSize = balanceAssetB / slippedTakeProfit;
strategy.positionRate = slippedTakeProfit;
let finalTakeProfit = slippedTakeProfit;
balanceAssetA = balanceAssetA + balanceAssetB / slippedTakeProfit;
let feePaid = 0
if (baseAsset === 'BTC') {
strategy.positionSize = balanceAssetB / finalTakeProfit;
strategy.positionRate = finalTakeProfit;
feePaid = balanceAssetB / finalTakeProfit * feeStructure.taker / 100
balanceAssetA = balanceAssetA + balanceAssetB / finalTakeProfit - feePaid;
balanceAssetB = 0;
} else {
strategy.positionSize = balanceAssetA * slippedTakeProfit;
strategy.positionRate = slippedTakeProfit;
strategy.positionSize = balanceAssetA * finalTakeProfit;
strategy.positionRate = finalTakeProfit;
balanceAssetB = balanceAssetB + balanceAssetA * slippedTakeProfit;
feePaid = balanceAssetA * finalTakeProfit * feeStructure.taker / 100
balanceAssetB = balanceAssetB + balanceAssetA * finalTakeProfit - feePaid;
balanceAssetA = 0;
}
@@ -1697,7 +1753,7 @@ exports.newCommons = function newCommons(bot, logger, UTILITIES) {
}
}
marketRate = slippedTakeProfit;
marketRate = finalTakeProfit;
type = '"Close@TakeProfit"';
strategyStage = 'Close Stage';
stopLossStage = 'No Stage';
@@ -1706,8 +1762,8 @@ exports.newCommons = function newCommons(bot, logger, UTILITIES) {
currentTrade.end = candle.end;
currentTrade.status = 1;
currentTrade.exitType = 2;
currentTrade.endRate = slippedTakeProfit;
currentTrade.endRate = finalTakeProfit;
closePositionNow = true;
if (processingDailyFiles) {
@@ -1736,22 +1792,15 @@ exports.newCommons = function newCommons(bot, logger, UTILITIES) {
let strategy = tradingSystem.strategies[currentStrategyIndex];
tradePositionSize = strategy.positionSize;
tradePositionRate = strategy.positionRate;
if (i === candles.length - 2) { /* Only at the last closed candle I can take the value from the formula, since the use of ticker could alter the value at previous candles.*/
tradePositionRate = strategy.positionRate;
/* We take what was calculated at the formula and apply the slippage. */
let slippageAmount = tradePositionRate * slippage.positionRate / 100
if (baseAsset === 'BTC') {
tradePositionRate = tradePositionRate - slippageAmount
} else {
/* Check the Slipagge */
tradePositionRate = candle.close;
let slippageAmount = tradePositionRate * slippage / 100
if (baseAsset === 'BTC') {
tradePositionRate = tradePositionRate - slippageAmount
} else {
tradePositionRate = tradePositionRate + slippageAmount
}
tradePositionRate = tradePositionRate + slippageAmount
}
if (processingDailyFiles) {
@@ -1761,6 +1810,18 @@ exports.newCommons = function newCommons(bot, logger, UTILITIES) {
}
}
/* Update the trade record information. */
currentTrade.begin = candle.begin;
currentTrade.beginRate = tradePositionRate;
if (processingDailyFiles) {
if (positionedAtYesterday) {
yesterday.currentTrade.begin = currentTrade.begin;
yesterday.currentTrade.beginRate = currentTrade.beginRate;
}
}
/* Check if we need to execute. */
if (i > candles.length - 10) { /* Only at the last candles makes sense to check if we are in live mode or not.*/
/* Check that we are in LIVE MODE */
if (process.env.START_MODE === "live") {
@@ -1972,11 +2033,19 @@ exports.newCommons = function newCommons(bot, logger, UTILITIES) {
lastTradeProfitLoss = 0;
lastTradeROI = 0;
let feePaid = 0
if (baseAsset === 'BTC') {
balanceAssetB = balanceAssetB + tradePositionSize * tradePositionRate;
feePaid = tradePositionSize * tradePositionRate * feeStructure.taker / 100
balanceAssetB = balanceAssetB + tradePositionSize * tradePositionRate - feePaid;
balanceAssetA = balanceAssetA - tradePositionSize;
} else {
balanceAssetA = balanceAssetA + tradePositionSize / tradePositionRate;
feePaid = tradePositionSize / tradePositionRate * feeStructure.taker / 100
balanceAssetA = balanceAssetA + tradePositionSize / tradePositionRate - feePaid;
balanceAssetB = balanceAssetB - tradePositionSize;
}
@@ -2257,8 +2326,6 @@ exports.newCommons = function newCommons(bot, logger, UTILITIES) {
if (processingDailyFiles) {
if (positionedAtYesterday) {
yesterday.currentStrategyIndex = currentStrategyIndex;
yesterday.strategyStage = strategyStage;
yesterday.stopLossStage = stopLossStage;
yesterday.takeProfitStage = takeProfitStage;
yesterday.stopLossPhase = stopLossPhase;
@@ -2293,6 +2360,14 @@ exports.newCommons = function newCommons(bot, logger, UTILITIES) {
currentStrategyIndex = -1;
strategyStage = 'No Stage';
if (processingDailyFiles) {
if (positionedAtYesterday) {
yesterday.currentStrategyIndex = currentStrategyIndex;
yesterday.strategyStage = strategyStage;
}
}
timerToCloseStage = 0
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> Closing the Closing Stage -> Exiting Close Stage."); }
+4 -4
View File
@@ -54,8 +54,8 @@
}
USER_BOT_MODULE = {}
//USER_BOT_MODULE.newUserBot = require(ROOT_DIR + 'User.Bot').newUserBot // Use this for a better debugging experience. You need to bring this js module to this folder in order to work.
USER_BOT_MODULE.newUserBot = eval(text); // Use this for production
USER_BOT_MODULE.newUserBot = require(ROOT_DIR + 'User.Bot').newUserBot // Use this for a better debugging experience. You need to bring this js module to this folder in order to work.
//USER_BOT_MODULE.newUserBot = eval(text); // Use this for production
filePath = global.DEV_TEAM + "/" + "bots" + "/" + bot.repo;
filePath += "/Commons.js"
@@ -70,8 +70,8 @@
return;
}
COMMONS_MODULE = {}
//COMMONS_MODULE.newCommons = require(ROOT_DIR + 'Commons').newCommons // Use this for a better debugging experience. You need to bring this js module to this folder in order to work.
COMMONS_MODULE.newCommons = eval(text); // Use this for production
COMMONS_MODULE.newCommons = require(ROOT_DIR + 'Commons').newCommons // Use this for a better debugging experience. You need to bring this js module to this folder in order to work.
//COMMONS_MODULE.newCommons = eval(text); // Use this for production
callBackFunction(global.DEFAULT_OK_RESPONSE);
}