cleaning
This commit is contained in:
1 parent
083788d36c
commit
7e142a01dc
4 files changed
+240
-248
No files matched your search
@@ -1,16 +1,11 @@
|
||||
exports.newTradingEngine = function newTradingEngine(bot, logger) {
|
||||
|
||||
const MODULE_NAME = 'Trading Engine'
|
||||
|
||||
let thisObject = {
|
||||
setCurrentCandle: setCurrentCandle,
|
||||
updateEpisodeCountersAndStatistics: updateEpisodeCountersAndStatistics,
|
||||
resetPositionCountersAndStatistics: resetPositionCountersAndStatistics,
|
||||
updatePositionCountersAndStatistics: updatePositionCountersAndStatistics,
|
||||
updateDistanceToEventsCounters: updateDistanceToEventsCounters,
|
||||
getReadyToTakePosition: getReadyToTakePosition,
|
||||
takePosition: takePosition,
|
||||
getReadyToClosePosition: getReadyToClosePosition,
|
||||
closePosition: closePosition,
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
}
|
||||
@@ -138,20 +133,23 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) {
|
||||
tradingEngine.episode.episodeStatistics.days.value = tradingEngine.episode.episodeCounters.periods.value * sessionParameters.timeFrame.config.value / global.ONE_DAY_IN_MILISECONDS
|
||||
}
|
||||
|
||||
function resetPositionCountersAndStatistics() {
|
||||
/* Keeping Position Counters Up-to-date */
|
||||
if (
|
||||
(tradingEngine.current.strategy.stageType.value === 'Open Stage' || tradingEngine.current.strategy.stageType.value === 'Manage Stage')
|
||||
) { return }
|
||||
|
||||
tradingEngine.current.position.positionCounters.periods.value = tradingEngine.current.position.positionCounters.periods.config.initialValue
|
||||
tradingEngine.current.position.positionStatistics.days.value = tradingEngine.current.position.positionStatistics.days.config.initialValue
|
||||
}
|
||||
|
||||
function updatePositionCountersAndStatistics() {
|
||||
/* Keeping Position Counters Up-to-date */
|
||||
if (
|
||||
(tradingEngine.current.strategy.stageType.value === 'Open Stage' || tradingEngine.current.strategy.stageType.value === 'Manage Stage')
|
||||
) {
|
||||
if (takePositionNow === true) {
|
||||
tradingEngine.current.position.positionCounters.periods.value = 0
|
||||
}
|
||||
|
||||
tradingEngine.current.position.positionCounters.periods.value++
|
||||
tradingEngine.current.position.positionStatistics.days.value = tradingEngine.current.position.positionCounters.periods.value * sessionParameters.timeFrame.config.value / global.ONE_DAY_IN_MILISECONDS
|
||||
} else {
|
||||
tradingEngine.current.position.positionCounters.periods.value = 0
|
||||
tradingEngine.current.position.positionStatistics.days.value = 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,124 +180,5 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) {
|
||||
}
|
||||
}
|
||||
|
||||
function getReadyToTakePosition(candle) {
|
||||
/* Inicializing this counter */
|
||||
tradingEngine.current.distanceToEvent.takePosition.value = 1
|
||||
|
||||
/* Position size and rate */
|
||||
tradingEngine.current.position.size.value = getPositionSize()
|
||||
tradingEngine.current.position.rate.value = getPositionRate()
|
||||
|
||||
/* We take what was calculated at the formula and apply the slippage. */
|
||||
let slippageAmount = tradingEngine.current.position.rate.value * bot.SESSION.parameters.slippage.config.positionRate / 100
|
||||
|
||||
if (bot.sessionAndMarketBaseAssetsAreEqual) {
|
||||
tradingEngine.current.position.rate.value = tradingEngine.current.position.rate.value - slippageAmount
|
||||
} else {
|
||||
tradingEngine.current.position.rate.value = tradingEngine.current.position.rate.value + slippageAmount
|
||||
}
|
||||
|
||||
/* Update the trade record information. */
|
||||
tradingEngine.current.position.begin.value = candle.begin
|
||||
tradingEngine.current.position.beginRate.value = tradingEngine.current.position.rate.value
|
||||
}
|
||||
|
||||
function takePosition() {
|
||||
calculateTakeProfit() // TODO: Check if this is really necesary
|
||||
calculateStopLoss() // TODO: Check if this is really necesary
|
||||
|
||||
tradingEngine.previous.balance.baseAsset.value = tradingEngine.current.balance.baseAsset.value
|
||||
tradingEngine.previous.balance.quotedAsset.value = tradingEngine.current.balance.quotedAsset.value
|
||||
|
||||
tradingEngine.last.position.profitLoss.value = 0
|
||||
tradingEngine.last.position.ROI.value = 0
|
||||
|
||||
let feePaid = 0
|
||||
|
||||
if (bot.sessionAndMarketBaseAssetsAreEqual) {
|
||||
feePaid = tradingEngine.current.position.size.value * tradingEngine.current.position.rate.value * bot.SESSION.parameters.feeStructure.config.taker / 100
|
||||
|
||||
tradingEngine.current.balance.quotedAsset.value = tradingEngine.current.balance.quotedAsset.value + tradingEngine.current.position.size.value * tradingEngine.current.position.rate.value - feePaid
|
||||
tradingEngine.current.balance.baseAsset.value = tradingEngine.current.balance.baseAsset.value - tradingEngine.current.position.size.value
|
||||
} else {
|
||||
feePaid = tradingEngine.current.position.size.value / tradingEngine.current.position.rate.value * bot.SESSION.parameters.feeStructure.config.taker / 100
|
||||
|
||||
tradingEngine.current.balance.baseAsset.value = tradingEngine.current.balance.baseAsset.value + tradingEngine.current.position.size.value / tradingEngine.current.position.rate.value - feePaid
|
||||
tradingEngine.current.balance.quotedAsset.value = tradingEngine.current.balance.quotedAsset.value - tradingEngine.current.position.size.value
|
||||
}
|
||||
}
|
||||
|
||||
function getReadyToClosePosition() {
|
||||
/* Inicializing this counter */
|
||||
tradingEngine.current.distanceToEvent.closePosition.value = 1
|
||||
|
||||
/* Position size and rate */
|
||||
let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value]
|
||||
}
|
||||
|
||||
function closePosition() {
|
||||
tradingEngine.episode.positionCounters.positions.value++
|
||||
|
||||
let feePaid = 0
|
||||
|
||||
if (bot.sessionAndMarketBaseAssetsAreEqual) {
|
||||
|
||||
feePaid = tradingEngine.current.balance.quotedAsset.value / tradingEngine.current.position.endRate.value * bot.SESSION.parameters.feeStructure.config.taker / 100
|
||||
|
||||
tradingEngine.current.balance.baseAsset.value = tradingEngine.current.balance.baseAsset.value + tradingEngine.current.balance.quotedAsset.value / tradingEngine.current.position.endRate.value - feePaid
|
||||
tradingEngine.current.balance.quotedAsset.value = 0
|
||||
} else {
|
||||
|
||||
feePaid = tradingEngine.current.balance.baseAsset.value * tradingEngine.current.position.endRate.value * bot.SESSION.parameters.feeStructure.config.taker / 100
|
||||
|
||||
tradingEngine.current.balance.quotedAsset.value = tradingEngine.current.balance.quotedAsset.value + tradingEngine.current.balance.baseAsset.value * tradingEngine.current.position.endRate.value - feePaid
|
||||
tradingEngine.current.balance.baseAsset.value = 0
|
||||
}
|
||||
|
||||
if (bot.sessionAndMarketBaseAssetsAreEqual) {
|
||||
tradingEngine.last.position.profitLoss.value = tradingEngine.current.balance.baseAsset.value - tradingEngine.previous.balance.baseAsset.value
|
||||
tradingEngine.last.position.ROI.value = tradingEngine.last.position.profitLoss.value * 100 / tradingEngine.current.position.size.value
|
||||
if (isNaN(tradingEngine.last.position.ROI.value)) { tradingEngine.last.position.ROI.value = 0 }
|
||||
tradingEngine.episode.episodeStatistics.profitLoss.value = tradingEngine.current.balance.baseAsset.value - sessionParameters.sessionBaseAsset.config.initialBalance
|
||||
} else {
|
||||
tradingEngine.last.position.profitLoss.value = tradingEngine.current.balance.quotedAsset.value - tradingEngine.previous.balance.quotedAsset.value
|
||||
tradingEngine.last.position.ROI.value = tradingEngine.last.position.profitLoss.value * 100 / tradingEngine.current.position.size.value
|
||||
if (isNaN(tradingEngine.last.position.ROI.value)) { tradingEngine.last.position.ROI.value = 0 }
|
||||
tradingEngine.episode.episodeStatistics.profitLoss.value = tradingEngine.current.balance.quotedAsset.value - sessionParameters.sessionQuotedAsset.config.initialBalance
|
||||
}
|
||||
|
||||
tradingEngine.current.position.positionStatistics.ROI.value = tradingEngine.last.position.ROI.value
|
||||
|
||||
if (tradingEngine.last.position.profitLoss.value > 0) {
|
||||
tradingEngine.episode.episodeCounters.hits.value++
|
||||
} else {
|
||||
tradingEngine.episode.episodeCounters.fails.value++
|
||||
}
|
||||
|
||||
if (bot.sessionAndMarketBaseAssetsAreEqual) {
|
||||
tradingEngine.episode.episodeStatistics.ROI.value = (sessionParameters.sessionBaseAsset.config.initialBalance + tradingEngine.episode.episodeStatistics.profitLoss.value) / sessionParameters.sessionBaseAsset.config.initialBalance - 1
|
||||
tradingEngine.episode.episodeStatistics.hitRatio.value = tradingEngine.episode.episodeCounters.hits.value / tradingEngine.episode.positionCounters.positions.value
|
||||
tradingEngine.episode.episodeStatistics.anualizedRateOfReturn.value = tradingEngine.episode.episodeStatistics.ROI.value / tradingEngine.episode.episodeStatistics.days.value * 365
|
||||
} else {
|
||||
tradingEngine.episode.episodeStatistics.ROI.value = (sessionParameters.sessionQuotedAsset.config.initialBalance + tradingEngine.episode.episodeStatistics.profitLoss.value) / sessionParameters.sessionQuotedAsset.config.initialBalance - 1
|
||||
tradingEngine.episode.episodeStatistics.hitRatio.value = tradingEngine.episode.episodeCounters.hits.value / tradingEngine.episode.positionCounters.positions.value
|
||||
tradingEngine.episode.episodeStatistics.anualizedRateOfReturn.value = tradingEngine.episode.episodeStatistics.ROI.value / tradingEngine.episode.episodeStatistics.days.value * 365
|
||||
}
|
||||
|
||||
addRecords()
|
||||
|
||||
tradingEngine.current.position.stopLoss.value = 0
|
||||
tradingEngine.current.position.takeProfit.value = 0
|
||||
|
||||
tradingEngine.current.position.rate.value = 0
|
||||
tradingEngine.current.position.size.value = 0
|
||||
|
||||
timerToCloseStage = candle.begin
|
||||
tradingEngine.current.position.stopLoss.stopLossStage.value = 'No Stage'
|
||||
tradingEngine.current.position.takeProfit.takeProfitStage.value = 'No Stage'
|
||||
tradingEngine.current.position.stopLoss.stopLossPhase.value = -1
|
||||
tradingEngine.current.position.takeProfit.takeProfitPhase.value = -1
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,70 +24,65 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) {
|
||||
}
|
||||
|
||||
function takePosition() {
|
||||
/* Check if we need to execute. */
|
||||
if (currentCandleIndex > 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 (bot.SESSION.type === 'Live Trading Session' || bot.SESSION.type === 'Fordward Testion Session') {
|
||||
logger.write(MODULE_NAME, '[PERSIST] runSimulation -> loop -> takePositionNow -> Taking a Position in ' + bot.SESSION.type)
|
||||
logger.write(MODULE_NAME, '[PERSIST] runSimulation -> loop -> takePositionNow -> tradingEngine.current.position.size.value = ' + tradingEngine.current.position.size.value)
|
||||
logger.write(MODULE_NAME, '[PERSIST] runSimulation -> loop -> takePositionNow -> tradingEngine.current.position.rate.value = ' + tradingEngine.current.position.rate.value)
|
||||
logger.write(MODULE_NAME, '[PERSIST] runSimulation -> loop -> takePositionNow -> slippageAmount = ' + slippageAmount)
|
||||
logger.write(MODULE_NAME, '[PERSIST] runSimulation -> loop -> takePositionNow -> tradingEngine.current.position.rate.value = ' + tradingEngine.current.position.rate.value)
|
||||
/* Check that we are in LIVE MODE */
|
||||
if (bot.SESSION.type === 'Live Trading Session' || bot.SESSION.type === 'Fordward Testion Session') {
|
||||
logger.write(MODULE_NAME, '[PERSIST] runSimulation -> loop -> takePositionNow -> Taking a Position in ' + bot.SESSION.type)
|
||||
logger.write(MODULE_NAME, '[PERSIST] runSimulation -> loop -> takePositionNow -> tradingEngine.current.position.size.value = ' + tradingEngine.current.position.size.value)
|
||||
logger.write(MODULE_NAME, '[PERSIST] runSimulation -> loop -> takePositionNow -> tradingEngine.current.position.rate.value = ' + tradingEngine.current.position.rate.value)
|
||||
logger.write(MODULE_NAME, '[PERSIST] runSimulation -> loop -> takePositionNow -> slippageAmount = ' + slippageAmount)
|
||||
logger.write(MODULE_NAME, '[PERSIST] runSimulation -> loop -> takePositionNow -> tradingEngine.current.position.rate.value = ' + tradingEngine.current.position.rate.value)
|
||||
|
||||
/* We see if we need to put the actual order at the exchange. */
|
||||
if (variable.executionContext !== undefined) {
|
||||
switch (variable.executionContext.status) {
|
||||
case 'Without a Position': { // We need to put the order because It was not put yet.
|
||||
if (strategy.openStage !== undefined) {
|
||||
if (strategy.openStage.openExecution !== undefined) {
|
||||
putOpeningOrder()
|
||||
return
|
||||
}
|
||||
/* We see if we need to put the actual order at the exchange. */
|
||||
if (variable.executionContext !== undefined) {
|
||||
switch (variable.executionContext.status) {
|
||||
case 'Without a Position': { // We need to put the order because It was not put yet.
|
||||
if (strategy.openStage !== undefined) {
|
||||
if (strategy.openStage.openExecution !== undefined) {
|
||||
putOpeningOrder()
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'Position Closed': { // Waiting for a confirmation that the position was closed.
|
||||
if (strategy.openStage !== undefined) {
|
||||
if (strategy.openStage.openExecution !== undefined) {
|
||||
putOpeningOrder()
|
||||
return
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'Taking Position': { // Waiting for a confirmation that the position was taken.
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> takePositionNow -> Exiting code block because status is Taking Position.') }
|
||||
break
|
||||
}
|
||||
case 'In a Position': { // This should mean that we already put the order at the exchange.
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> takePositionNow -> Exiting code block because status is In a Position.') }
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
} else { // The context does not exist so it means we are not in a position.
|
||||
if (strategy.openStage !== undefined) {
|
||||
if (strategy.openStage.openExecution !== undefined) {
|
||||
putOpeningOrder()
|
||||
return
|
||||
case 'Position Closed': { // Waiting for a confirmation that the position was closed.
|
||||
if (strategy.openStage !== undefined) {
|
||||
if (strategy.openStage.openExecution !== undefined) {
|
||||
putOpeningOrder()
|
||||
return
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'Taking Position': { // Waiting for a confirmation that the position was taken.
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> takePositionNow -> Exiting code block because status is Taking Position.')
|
||||
break
|
||||
}
|
||||
case 'In a Position': { // This should mean that we already put the order at the exchange.
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> takePositionNow -> Exiting code block because status is In a Position.')
|
||||
break
|
||||
}
|
||||
}
|
||||
} else { // The context does not exist so it means we are not in a position.
|
||||
if (strategy.openStage !== undefined) {
|
||||
if (strategy.openStage.openExecution !== undefined) {
|
||||
putOpeningOrder()
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> takePositionNow -> Not trading live.') }
|
||||
}
|
||||
} else {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> takePositionNow -> Not the last closed candle.') }
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> takePositionNow -> Not trading live.')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function putOpeningOrder() {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> Entering function.') }
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> Entering function.')
|
||||
|
||||
/* We wont take a position unless we are withing the sessionParameters.timeRange.config.initialDatetime and the sessionParameters.timeRange.config.finalDatetime range */
|
||||
if (sessionParameters.timeRange.config.initialDatetime !== undefined) {
|
||||
if (candle.end < sessionParameters.timeRange.config.initialDatetime) {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> Not placing the trade at the exchange because current candle ends before the start date. -> sessionParameters.timeRange.config.initialDatetime = ' + sessionParameters.timeRange.config.initialDatetime) }
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> Not placing the trade at the exchange because current candle ends before the start date. -> sessionParameters.timeRange.config.initialDatetime = ' + sessionParameters.timeRange.config.initialDatetime)
|
||||
takePositionAtSimulation()
|
||||
return
|
||||
}
|
||||
@@ -96,7 +91,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) {
|
||||
/* We wont take a position if we are past the final datetime */
|
||||
if (sessionParameters.timeRange.config.finalDatetime !== undefined) {
|
||||
if (candle.begin > sessionParameters.timeRange.config.finalDatetime) {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> putOpeningOrder -> Not placing the trade at the exchange because current candle begins after the end date. -> sessionParameters.timeRange.config.finalDatetime = ' + sessionParameters.timeRange.config.finalDatetime) }
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> putOpeningOrder -> Not placing the trade at the exchange because current candle begins after the end date. -> sessionParameters.timeRange.config.finalDatetime = ' + sessionParameters.timeRange.config.finalDatetime)
|
||||
takePositionAtSimulation()
|
||||
return
|
||||
}
|
||||
@@ -106,7 +101,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) {
|
||||
if (variable.executionContext !== undefined) {
|
||||
if (variable.executionContext.periods !== undefined) {
|
||||
if (tradingEngine.episode.episodeCounters.periods.value <= variable.executionContext.periods) {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> Not placing the trade at the exchange because it was already placed at a previous execution.') }
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> Not placing the trade at the exchange because it was already placed at a previous execution.')
|
||||
takePositionAtSimulation()
|
||||
return
|
||||
}
|
||||
@@ -118,9 +113,9 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) {
|
||||
let today = new Date(Math.trunc((new Date().valueOf()) / global.ONE_DAY_IN_MILISECONDS) * global.ONE_DAY_IN_MILISECONDS)
|
||||
let processDay = new Date(Math.trunc(currentDay.valueOf() / global.ONE_DAY_IN_MILISECONDS) * global.ONE_DAY_IN_MILISECONDS)
|
||||
if (today.valueOf() !== processDay.valueOf()) {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> Not placing the trade at the exchange because the current candle belongs to the previous day and that is considered simulation and not live trading.') }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> today = ' + today) }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> processDay = ' + processDay) }
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> Not placing the trade at the exchange because the current candle belongs to the previous day and that is considered simulation and not live trading.')
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> today = ' + today)
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> processDay = ' + processDay)
|
||||
takePositionAtSimulation()
|
||||
return
|
||||
}
|
||||
@@ -152,16 +147,16 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) {
|
||||
periods: tradingEngine.episode.episodeCounters.periods.value
|
||||
}
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> Ready to create order.') }
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> Ready to create order.')
|
||||
exchangeAPI.createOrder(bot.market, orderSide, orderPrice, amountA, amountB, onOrderCreated)
|
||||
|
||||
function onOrderCreated(err, order) {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> Entering function.') }
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> Entering function.')
|
||||
|
||||
try {
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> DEFAULT_OK_RESPONSE ') }
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> DEFAULT_OK_RESPONSE ')
|
||||
variable.executionContext = {
|
||||
status: 'In a Position',
|
||||
periods: tradingEngine.episode.episodeCounters.periods.value,
|
||||
@@ -173,21 +168,21 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) {
|
||||
return
|
||||
}
|
||||
case global.DEFAULT_FAIL_RESPONSE.result: {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> DEFAULT_FAIL_RESPONSE ') }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[ERROR] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> Message = ' + err.message) }
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> DEFAULT_FAIL_RESPONSE ')
|
||||
logger.write(MODULE_NAME, '[ERROR] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> Message = ' + err.message)
|
||||
strategy.openStage.openExecution.error = err.message
|
||||
afterLoop()
|
||||
return
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> DEFAULT_RETRY_RESPONSE ') }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[ERROR] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> Message = ' + err.message) }
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> DEFAULT_RETRY_RESPONSE ')
|
||||
logger.write(MODULE_NAME, '[ERROR] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> Message = ' + err.message)
|
||||
strategy.openStage.openExecution.error = err.message
|
||||
afterLoop()
|
||||
return
|
||||
}
|
||||
}
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[ERROR] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> Unexpected Response -> Message = ' + err.message) }
|
||||
logger.write(MODULE_NAME, '[ERROR] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> Unexpected Response -> Message = ' + err.message)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
return
|
||||
} catch (err) {
|
||||
@@ -199,39 +194,37 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) {
|
||||
}
|
||||
|
||||
function closePosition() {
|
||||
if (currentCandleIndex > 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 (bot.SESSION.type === 'Live Trading Session' || bot.SESSION.type === 'Fordward Testion Session') {
|
||||
/* We see if we need to put the actual order at the exchange. */
|
||||
if (variable.executionContext !== undefined) {
|
||||
switch (variable.executionContext.status) {
|
||||
case 'Without a Position': { // No way to close anything at the exchange.
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> Closing a Position -> Exiting code block because status is Without a Position.') }
|
||||
break
|
||||
}
|
||||
case 'In a Position': { // This should mean that we already put the order at the exchange.
|
||||
if (strategy.closeStage !== undefined) {
|
||||
if (strategy.closeStage.closeExecution !== undefined) {
|
||||
putClosingOrder()
|
||||
return
|
||||
}
|
||||
/* Check that we are in LIVE MODE */
|
||||
if (bot.SESSION.type === 'Live Trading Session' || bot.SESSION.type === 'Fordward Testion Session') {
|
||||
/* We see if we need to put the actual order at the exchange. */
|
||||
if (variable.executionContext !== undefined) {
|
||||
switch (variable.executionContext.status) {
|
||||
case 'Without a Position': { // No way to close anything at the exchange.
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> Closing a Position -> Exiting code block because status is Without a Position.')
|
||||
break
|
||||
}
|
||||
case 'In a Position': { // This should mean that we already put the order at the exchange.
|
||||
if (strategy.closeStage !== undefined) {
|
||||
if (strategy.closeStage.closeExecution !== undefined) {
|
||||
putClosingOrder()
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'Closing Position': { // Waiting for a confirmation that the position was taken.
|
||||
if (strategy.closeStage !== undefined) {
|
||||
if (strategy.closeStage.closeExecution !== undefined) {
|
||||
putClosingOrder()
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'Closing Position': { // Waiting for a confirmation that the position was taken.
|
||||
if (strategy.closeStage !== undefined) {
|
||||
if (strategy.closeStage.closeExecution !== undefined) {
|
||||
putClosingOrder()
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
case 'Position Closed': { //
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> Closing a Position -> Exiting code block because status is Position Closed.') }
|
||||
break
|
||||
}
|
||||
case 'Position Closed': { //
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> Closing a Position -> Exiting code block because status is Position Closed.')
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -239,13 +232,11 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) {
|
||||
}
|
||||
|
||||
function putClosingOrder() {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> putClosingOrder -> Entering function.') }
|
||||
|
||||
/* Mechanism to avoid putting the same order over and over again at different executions of the simulation engine. */
|
||||
if (variable.executionContext !== undefined) {
|
||||
if (variable.executionContext.periods !== undefined) {
|
||||
if (tradingEngine.episode.episodeCounters.periods.value <= variable.executionContext.periods) {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putClosingOrder -> Exiting function because this closing was already submited at a previous execution.') }
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putClosingOrder -> Exiting function because this closing was already submited at a previous execution.')
|
||||
closePositionAtSimulation()
|
||||
return
|
||||
}
|
||||
@@ -278,16 +269,16 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) {
|
||||
periods: tradingEngine.episode.episodeCounters.periods.value
|
||||
}
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putClosingOrder -> About to close position at the exchange.') }
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putClosingOrder -> About to close position at the exchange.')
|
||||
exchangeAPI.createOrder(bot.market, orderSide, orderPrice, amountA, amountB, onOrderCreated)
|
||||
|
||||
function onOrderCreated(err, order) {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putClosingOrder -> onOrderCreated -> Entering function.') }
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putClosingOrder -> onOrderCreated -> Entering function.')
|
||||
|
||||
try {
|
||||
switch (err.result) {
|
||||
case global.DEFAULT_OK_RESPONSE.result: {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putClosingOrder -> onOrderCreated -> DEFAULT_OK_RESPONSE ') }
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putClosingOrder -> onOrderCreated -> DEFAULT_OK_RESPONSE ')
|
||||
variable.executionContext = {
|
||||
status: 'Position Closed',
|
||||
periods: tradingEngine.episode.episodeCounters.periods.value,
|
||||
@@ -299,20 +290,20 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) {
|
||||
return
|
||||
}
|
||||
case global.DEFAULT_FAIL_RESPONSE.result: {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putClosingOrder -> onOrderCreated -> DEFAULT_FAIL_RESPONSE ') }
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putClosingOrder -> onOrderCreated -> DEFAULT_FAIL_RESPONSE ')
|
||||
/* We will assume that the problem is temporary, and expect that it will work at the next execution. */
|
||||
strategy.closeStage.closeExecution.error = err.message
|
||||
afterLoop()
|
||||
return
|
||||
}
|
||||
case global.DEFAULT_RETRY_RESPONSE.result: {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> DEFAULT_RETRY_RESPONSE ') }
|
||||
logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> DEFAULT_RETRY_RESPONSE ')
|
||||
strategy.closeStage.closeExecution.error = err.message
|
||||
afterLoop()
|
||||
return
|
||||
}
|
||||
}
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[ERROR] runSimulation -> loop -> putClosingOrder -> onOrderCreated -> Unexpected Response -> Message = ' + err.message) }
|
||||
logger.write(MODULE_NAME, '[ERROR] runSimulation -> loop -> putClosingOrder -> onOrderCreated -> Unexpected Response -> Message = ' + err.message)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
return
|
||||
} catch (err) {
|
||||
|
||||
@@ -182,6 +182,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
|
||||
tradingSystemModule.calculateTakeProfit()
|
||||
}
|
||||
|
||||
tradingEngineModule.resetPositionCountersAndStatistics()
|
||||
tradingEngineModule.updatePositionCountersAndStatistics()
|
||||
tradingEngineModule.updateDistanceToEventsCounters()
|
||||
|
||||
@@ -192,17 +193,17 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
|
||||
|
||||
/* Taking a Position */
|
||||
if (takingPosition === true) {
|
||||
tradingEngineModule.getReadyToTakePosition(candle)
|
||||
tradingSystemModule.getReadyToTakePosition()
|
||||
tradingExecutionModule.takePosition()
|
||||
tradingEngineModule.takePosition()
|
||||
tradingSystemModule.takePosition()
|
||||
takingPosition = false
|
||||
}
|
||||
|
||||
/* Closing a Position */
|
||||
if (closingPosition === true) {
|
||||
tradingEngineModule.getReadyToClosePosition(candle)
|
||||
tradingSystemModule.getReadyToClosePosition()
|
||||
tradingExecutionModule.closePosition()
|
||||
tradingEngineModule.closePosition()
|
||||
tradingSystemModule.closePosition()
|
||||
closingPosition = false
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
exports.newTradingSystem = function newTradingSystem(bot, logger) {
|
||||
|
||||
const MODULE_NAME = 'Trading System'
|
||||
const FULL_LOG = true
|
||||
|
||||
let thisObject = {
|
||||
reset: reset,
|
||||
evalConditions: evalConditions,
|
||||
@@ -15,6 +12,10 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
|
||||
checkTakeProfitPhaseEvents: checkTakeProfitPhaseEvents,
|
||||
calculateTakeProfit: calculateTakeProfit,
|
||||
checkStopLossOrTakeProfitWasHit: checkStopLossOrTakeProfitWasHit,
|
||||
getReadyToTakePosition: getReadyToTakePosition,
|
||||
takePosition: takePosition,
|
||||
getReadyToClosePosition: getReadyToClosePosition,
|
||||
closePosition: closePosition,
|
||||
exitStrategyAfterPosition: exitStrategyAfterPosition,
|
||||
getPositionSize: getPositionSize,
|
||||
getPositionRate: getPositionRate,
|
||||
@@ -138,7 +139,7 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
|
||||
}
|
||||
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] evalCondition -> code = ' + code) }
|
||||
logger.write(MODULE_NAME, '[INFO] evalCondition -> code = ' + code)
|
||||
value = eval(code)
|
||||
} catch (err) {
|
||||
/*
|
||||
@@ -170,8 +171,8 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
|
||||
tradingSystem.values.push([node.id, value])
|
||||
}
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] evalCondition -> value = ' + value) }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] evalCondition -> error = ' + error) }
|
||||
logger.write(MODULE_NAME, '[INFO] evalCondition -> value = ' + value)
|
||||
logger.write(MODULE_NAME, '[INFO] evalCondition -> error = ' + error)
|
||||
}
|
||||
|
||||
function evalFormula(node) {
|
||||
@@ -179,7 +180,7 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
|
||||
let error
|
||||
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] evalFormula -> code = ' + node.code) }
|
||||
logger.write(MODULE_NAME, '[INFO] evalFormula -> code = ' + node.code)
|
||||
value = eval(node.code)
|
||||
} catch (err) {
|
||||
/*
|
||||
@@ -208,8 +209,8 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
|
||||
tradingSystem.values.push([node.id, value])
|
||||
}
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] evalFormula -> value = ' + value) }
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] evalFormula -> error = ' + error) }
|
||||
logger.write(MODULE_NAME, '[INFO] evalFormula -> value = ' + value)
|
||||
logger.write(MODULE_NAME, '[INFO] evalFormula -> error = ' + error)
|
||||
}
|
||||
|
||||
function checkTriggerOn() {
|
||||
@@ -273,7 +274,7 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
|
||||
saveAsLastTriggerOnSnapshot = true
|
||||
*/
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] checkTriggerOn -> Entering into Strategy: ' + strategy.name) }
|
||||
logger.write(MODULE_NAME, '[INFO] checkTriggerOn -> Entering into Strategy: ' + strategy.name)
|
||||
return true // This Means that we have just met the conditions to trigger on.
|
||||
}
|
||||
}
|
||||
@@ -325,7 +326,7 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
|
||||
checkAnnouncements(triggerStage.triggerOff)
|
||||
*/
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] checkTriggerOff -> Closing Strategy: ' + strategy.name) }
|
||||
logger.write(MODULE_NAME, '[INFO] checkTriggerOff -> Closing Strategy: ' + strategy.name)
|
||||
return true // This Means that we have just met the conditions to trigger off.
|
||||
}
|
||||
}
|
||||
@@ -379,7 +380,7 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
|
||||
saveAsLastTakePositionSnapshot = true
|
||||
*/
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] checkTakePosition -> Conditions at the Take Position Event were met.') }
|
||||
logger.write(MODULE_NAME, '[INFO] checkTakePosition -> Conditions at the Take Position Event were met.')
|
||||
return true // This Means that we have just met the conditions to take position.
|
||||
}
|
||||
}
|
||||
@@ -725,7 +726,7 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
|
||||
(bot.sessionAndMarketBaseAssetsAreEqual && tradingEngine.current.candle.max.value >= tradingEngine.current.position.stopLoss.value) ||
|
||||
(sessionParameters.sessionBaseAsset.name !== bot.market.baseAsset && tradingEngine.current.candle.min.value <= tradingEngine.current.position.stopLoss.value)
|
||||
) {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] checkStopLossOrTakeProfitWasHit -> Stop Loss was hit.') }
|
||||
logger.write(MODULE_NAME, '[INFO] checkStopLossOrTakeProfitWasHit -> Stop Loss was hit.')
|
||||
/*
|
||||
Hit Point Validation
|
||||
|
||||
@@ -772,7 +773,7 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
|
||||
(bot.sessionAndMarketBaseAssetsAreEqual && tradingEngine.current.candle.min.value <= tradingEngine.current.position.takeProfit.value) ||
|
||||
(sessionParameters.sessionBaseAsset.name !== bot.market.baseAsset && tradingEngine.current.candle.max.value >= tradingEngine.current.position.takeProfit.value)
|
||||
) {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] checkStopLossOrTakeProfitWasHit -> Take Profit was hit.') }
|
||||
logger.write(MODULE_NAME, '[INFO] checkStopLossOrTakeProfitWasHit -> Take Profit was hit.')
|
||||
/*
|
||||
Hit Point Validation:
|
||||
|
||||
@@ -819,6 +820,126 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
|
||||
}
|
||||
}
|
||||
|
||||
function getReadyToTakePosition() {
|
||||
/* Inicializing this counter */
|
||||
tradingEngine.current.distanceToEvent.takePosition.value = 1
|
||||
|
||||
/* Position size and rate */
|
||||
tradingEngine.current.position.size.value = getPositionSize()
|
||||
tradingEngine.current.position.rate.value = getPositionRate()
|
||||
|
||||
/* We take what was calculated at the formula and apply the slippage. */
|
||||
let slippageAmount = tradingEngine.current.position.rate.value * bot.SESSION.parameters.slippage.config.positionRate / 100
|
||||
|
||||
if (bot.sessionAndMarketBaseAssetsAreEqual) {
|
||||
tradingEngine.current.position.rate.value = tradingEngine.current.position.rate.value - slippageAmount
|
||||
} else {
|
||||
tradingEngine.current.position.rate.value = tradingEngine.current.position.rate.value + slippageAmount
|
||||
}
|
||||
|
||||
/* Update the position information. */
|
||||
tradingEngine.current.position.begin.value = tradingEngine.current.candle.begin.value
|
||||
tradingEngine.current.position.beginRate.value = tradingEngine.current.position.rate.value
|
||||
}
|
||||
|
||||
function takePosition() {
|
||||
calculateTakeProfit() // TODO: Check if this is really necesary
|
||||
calculateStopLoss() // TODO: Check if this is really necesary
|
||||
|
||||
tradingEngine.previous.balance.baseAsset.value = tradingEngine.current.balance.baseAsset.value
|
||||
tradingEngine.previous.balance.quotedAsset.value = tradingEngine.current.balance.quotedAsset.value
|
||||
|
||||
tradingEngine.last.position.profitLoss.value = 0
|
||||
tradingEngine.last.position.ROI.value = 0
|
||||
|
||||
let feePaid = 0
|
||||
|
||||
if (bot.sessionAndMarketBaseAssetsAreEqual) {
|
||||
feePaid = tradingEngine.current.position.size.value * tradingEngine.current.position.rate.value * bot.SESSION.parameters.feeStructure.config.taker / 100
|
||||
|
||||
tradingEngine.current.balance.quotedAsset.value = tradingEngine.current.balance.quotedAsset.value + tradingEngine.current.position.size.value * tradingEngine.current.position.rate.value - feePaid
|
||||
tradingEngine.current.balance.baseAsset.value = tradingEngine.current.balance.baseAsset.value - tradingEngine.current.position.size.value
|
||||
} else {
|
||||
feePaid = tradingEngine.current.position.size.value / tradingEngine.current.position.rate.value * bot.SESSION.parameters.feeStructure.config.taker / 100
|
||||
|
||||
tradingEngine.current.balance.baseAsset.value = tradingEngine.current.balance.baseAsset.value + tradingEngine.current.position.size.value / tradingEngine.current.position.rate.value - feePaid
|
||||
tradingEngine.current.balance.quotedAsset.value = tradingEngine.current.balance.quotedAsset.value - tradingEngine.current.position.size.value
|
||||
}
|
||||
}
|
||||
|
||||
function getReadyToClosePosition() {
|
||||
/* Inicializing this counter */
|
||||
tradingEngine.current.distanceToEvent.closePosition.value = 1
|
||||
|
||||
/* Position size and rate */
|
||||
let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value]
|
||||
}
|
||||
|
||||
function closePosition() {
|
||||
tradingEngine.episode.positionCounters.positions.value++
|
||||
|
||||
let feePaid = 0
|
||||
|
||||
if (bot.sessionAndMarketBaseAssetsAreEqual) {
|
||||
|
||||
feePaid = tradingEngine.current.balance.quotedAsset.value / tradingEngine.current.position.endRate.value * bot.SESSION.parameters.feeStructure.config.taker / 100
|
||||
|
||||
tradingEngine.current.balance.baseAsset.value = tradingEngine.current.balance.baseAsset.value + tradingEngine.current.balance.quotedAsset.value / tradingEngine.current.position.endRate.value - feePaid
|
||||
tradingEngine.current.balance.quotedAsset.value = 0
|
||||
} else {
|
||||
|
||||
feePaid = tradingEngine.current.balance.baseAsset.value * tradingEngine.current.position.endRate.value * bot.SESSION.parameters.feeStructure.config.taker / 100
|
||||
|
||||
tradingEngine.current.balance.quotedAsset.value = tradingEngine.current.balance.quotedAsset.value + tradingEngine.current.balance.baseAsset.value * tradingEngine.current.position.endRate.value - feePaid
|
||||
tradingEngine.current.balance.baseAsset.value = 0
|
||||
}
|
||||
|
||||
if (bot.sessionAndMarketBaseAssetsAreEqual) {
|
||||
tradingEngine.last.position.profitLoss.value = tradingEngine.current.balance.baseAsset.value - tradingEngine.previous.balance.baseAsset.value
|
||||
tradingEngine.last.position.ROI.value = tradingEngine.last.position.profitLoss.value * 100 / tradingEngine.current.position.size.value
|
||||
if (isNaN(tradingEngine.last.position.ROI.value)) { tradingEngine.last.position.ROI.value = 0 }
|
||||
tradingEngine.episode.episodeStatistics.profitLoss.value = tradingEngine.current.balance.baseAsset.value - sessionParameters.sessionBaseAsset.config.initialBalance
|
||||
} else {
|
||||
tradingEngine.last.position.profitLoss.value = tradingEngine.current.balance.quotedAsset.value - tradingEngine.previous.balance.quotedAsset.value
|
||||
tradingEngine.last.position.ROI.value = tradingEngine.last.position.profitLoss.value * 100 / tradingEngine.current.position.size.value
|
||||
if (isNaN(tradingEngine.last.position.ROI.value)) { tradingEngine.last.position.ROI.value = 0 }
|
||||
tradingEngine.episode.episodeStatistics.profitLoss.value = tradingEngine.current.balance.quotedAsset.value - sessionParameters.sessionQuotedAsset.config.initialBalance
|
||||
}
|
||||
|
||||
tradingEngine.current.position.positionStatistics.ROI.value = tradingEngine.last.position.ROI.value
|
||||
|
||||
if (tradingEngine.last.position.profitLoss.value > 0) {
|
||||
tradingEngine.episode.episodeCounters.hits.value++
|
||||
} else {
|
||||
tradingEngine.episode.episodeCounters.fails.value++
|
||||
}
|
||||
|
||||
if (bot.sessionAndMarketBaseAssetsAreEqual) {
|
||||
tradingEngine.episode.episodeStatistics.ROI.value = (sessionParameters.sessionBaseAsset.config.initialBalance + tradingEngine.episode.episodeStatistics.profitLoss.value) / sessionParameters.sessionBaseAsset.config.initialBalance - 1
|
||||
tradingEngine.episode.episodeStatistics.hitRatio.value = tradingEngine.episode.episodeCounters.hits.value / tradingEngine.episode.positionCounters.positions.value
|
||||
tradingEngine.episode.episodeStatistics.anualizedRateOfReturn.value = tradingEngine.episode.episodeStatistics.ROI.value / tradingEngine.episode.episodeStatistics.days.value * 365
|
||||
} else {
|
||||
tradingEngine.episode.episodeStatistics.ROI.value = (sessionParameters.sessionQuotedAsset.config.initialBalance + tradingEngine.episode.episodeStatistics.profitLoss.value) / sessionParameters.sessionQuotedAsset.config.initialBalance - 1
|
||||
tradingEngine.episode.episodeStatistics.hitRatio.value = tradingEngine.episode.episodeCounters.hits.value / tradingEngine.episode.positionCounters.positions.value
|
||||
tradingEngine.episode.episodeStatistics.anualizedRateOfReturn.value = tradingEngine.episode.episodeStatistics.ROI.value / tradingEngine.episode.episodeStatistics.days.value * 365
|
||||
}
|
||||
|
||||
addRecords()
|
||||
|
||||
tradingEngine.current.position.stopLoss.value = 0
|
||||
tradingEngine.current.position.takeProfit.value = 0
|
||||
|
||||
tradingEngine.current.position.rate.value = 0
|
||||
tradingEngine.current.position.size.value = 0
|
||||
|
||||
timerToCloseStage = candle.begin
|
||||
tradingEngine.current.position.stopLoss.stopLossStage.value = 'No Stage'
|
||||
tradingEngine.current.position.takeProfit.takeProfitStage.value = 'No Stage'
|
||||
tradingEngine.current.position.stopLoss.stopLossPhase.value = -1
|
||||
tradingEngine.current.position.takeProfit.takeProfitPhase.value = -1
|
||||
|
||||
}
|
||||
|
||||
function exitStrategyAfterPosition() {
|
||||
if (tradingEngine.current.strategy.stageType.value === 'Close Stage') {
|
||||
if (candle.begin - 5 * 60 * 1000 > timerToCloseStage) {
|
||||
@@ -832,9 +953,9 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
|
||||
timerToCloseStage = 0
|
||||
tradingEngine.current.distanceToEvent.triggerOff.value = 1
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] exitStrategyAfterPosition -> Exiting the Strategy.') }
|
||||
logger.write(MODULE_NAME, '[INFO] exitStrategyAfterPosition -> Exiting the Strategy.')
|
||||
} else {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] exitStrategyAfterPosition -> Waiting for timer.') }
|
||||
logger.write(MODULE_NAME, '[INFO] exitStrategyAfterPosition -> Waiting for timer.')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user