Take Profit and Stop Loss being Plotted

This commit is contained in:
Luis Fernando Molina committed 2020-06-22 19:20:34 +02:00
1 parent 3badcfb2a5
commit 03b69d0a0c
6 files changed
+272 -170

No files matched your search

+1 -22
View File
@@ -7,8 +7,6 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) {
let thisObject = {
setCurrentCandle: setCurrentCandle,
updateEpisodeCountersAndStatistics: updateEpisodeCountersAndStatistics,
resetPositionCountersAndStatistics: resetPositionCountersAndStatistics,
updatePositionCountersAndStatistics: updatePositionCountersAndStatistics,
updateDistanceToEventsCounters: updateDistanceToEventsCounters,
initialize: initialize,
finalize: finalize
@@ -98,6 +96,7 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) {
node.value = node.config.initialValue
}
}
node.initialize = initializeNode // This will allow anyone to initialize this node and its children.
/* Now we go down through all this node children */
let nodeDefinition = bot.APP_SCHEMA_MAP.get(node.type)
@@ -137,26 +136,6 @@ 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')
) {
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
}
}
function updateDistanceToEventsCounters() {
/* Keeping Distance Counters Up-to-date */
if (
+192
View File
@@ -0,0 +1,192 @@
exports.newTradingPosition = function newTradingPosition(bot, logger) {
/*
This module packages all functions related to Positions.
*/
const MODULE_NAME = 'Trading Position'
let thisObject = {
openPosition: openPosition,
closePosition: closePosition,
applyStopLossFormula: applyStopLossFormula,
applyTakeProfitFormula: applyTakeProfitFormula,
preventStopLossDistortion: preventStopLossDistortion,
applySlippageToStopLoss: applySlippageToStopLoss,
preventTakeProfitDistortion: preventTakeProfitDistortion,
applySlippageToTakeProfit: applySlippageToTakeProfit,
updateStopLoss: updateStopLoss,
updateTakeProfit: updateTakeProfit,
updateSizeAndRate: updateSizeAndRate,
applySlippageToRate: applySlippageToRate,
updateEnds: updateEnds,
updateStatus: updateStatus,
updateCounters: updateCounters,
updateStatistics: updateStatistics,
resetPosition: resetPosition,
initialize: initialize,
finalize: finalize
}
let tradingEngine
let sessionParameters
return thisObject
function initialize() {
tradingEngine = bot.simulationState.tradingEngine
sessionParameters = bot.SESSION.parameters
}
function finalize() {
tradingEngine = undefined
sessionParameters = undefined
}
function openPosition(situationName) {
tradingEngine.current.position.status.value = 'Open'
tradingEngine.current.position.begin.value = tradingEngine.current.candle.begin.value
tradingEngine.current.position.end.value = tradingEngine.current.candle.end.value
tradingEngine.current.position.situationName.value = situationName
tradingEngine.current.position.stopLoss.stopLossStage.value = 'Open Stage'
tradingEngine.current.position.takeProfit.takeProfitStage.value = 'Open Stage'
tradingEngine.current.position.stopLoss.stopLossPhase.value = 0
tradingEngine.current.position.takeProfit.takeProfitPhase.value = 0
}
function closePosition(exitType) {
tradingEngine.current.position.status.value = 'Closed'
tradingEngine.current.position.end.value = tradingEngine.current.candle.end.value
tradingEngine.current.position.exitType.value = exitType
}
function resetPosition() {
tradingEngine.current.position.initialize(tradingEngine.current.position)
}
function applyStopLossFormula(formulas, formulaId) {
tradingEngine.current.position.stopLoss.value = formulas.get(formulaId)
}
function applyTakeProfitFormula(formulas, formulaId) {
tradingEngine.current.position.takeProfit.value = formulas.get(formulaId)
}
function updateStopLoss(phase, stage) {
tradingEngine.current.position.stopLoss.stopLossPhase.value = phase
tradingEngine.current.position.stopLoss.stopLossStage.value = stage
}
function updateTakeProfit(phase, stage) {
tradingEngine.current.position.takeProfit.takeProfitPhase.value = phase
tradingEngine.current.position.takeProfit.takeProfitStage.value = stage
}
function updateSizeAndRate(size, rate) {
tradingEngine.current.position.size.value = size
tradingEngine.current.position.rate.value = rate
}
function applySlippageToRate() {
let slippageAmount = tradingEngine.current.position.rate.value * bot.SESSION.parameters.slippage.config.positionRate / 100
if (bot.sessionAndMarketBaseAssetsAreEqual) {
tradingEngine.current.position.beginRate.value = tradingEngine.current.position.rate.value - slippageAmount
} else {
tradingEngine.current.position.beginRate.value = tradingEngine.current.position.rate.value + slippageAmount
}
}
function preventStopLossDistortion() {
/*
Hit Point Validation
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 (bot.sessionAndMarketBaseAssetsAreEqual) {
if (tradingEngine.current.position.stopLoss.value < tradingEngine.current.candle.min.value) {
tradingEngine.current.position.stopLoss.value = tradingEngine.current.candle.min.value
}
} else {
if (tradingEngine.current.position.stopLoss.value > tradingEngine.current.candle.max.value) {
tradingEngine.current.position.stopLoss.value = tradingEngine.current.candle.max.value
}
}
}
function applySlippageToStopLoss() {
let slippedStopLoss = tradingEngine.current.position.stopLoss.value
/* Apply the Slippage */
let slippageAmount = slippedStopLoss * bot.SESSION.parameters.slippage.config.stopLoss / 100
if (bot.sessionAndMarketBaseAssetsAreEqual) {
slippedStopLoss = slippedStopLoss + slippageAmount
} else {
slippedStopLoss = slippedStopLoss - slippageAmount
}
tradingEngine.current.position.endRate.value = slippedStopLoss
}
function preventTakeProfitDistortion() {
/*
Hit Point Validation:
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 (bot.sessionAndMarketBaseAssetsAreEqual) {
if (tradingEngine.current.position.takeProfit.value > tradingEngine.current.candle.max.value) {
tradingEngine.current.position.takeProfit.value = tradingEngine.current.candle.max.value
}
} else {
if (tradingEngine.current.position.takeProfit.value < tradingEngine.current.candle.min.value) {
tradingEngine.current.position.takeProfit.value = tradingEngine.current.candle.min.value
}
}
}
function applySlippageToTakeProfit() {
let slippedTakeProfit = tradingEngine.current.position.takeProfit.value
/* Apply the Slippage */
let slippageAmount = slippedTakeProfit * bot.SESSION.parameters.slippage.config.takeProfit / 100
if (bot.sessionAndMarketBaseAssetsAreEqual) {
slippedTakeProfit = slippedTakeProfit + slippageAmount
} else {
slippedTakeProfit = slippedTakeProfit - slippageAmount
}
tradingEngine.current.position.endRate.value = slippedTakeProfit
}
function updateEnds() {
if (tradingEngine.current.position.status.value === 'Open') {
tradingEngine.current.position.end.value = tradingEngine.current.candle.end.value
}
}
function updateStatus() {
if (tradingEngine.current.position.status.value === 'Closed') {
resetPosition()
}
}
function updateCounters() {
if (tradingEngine.current.position.status.value === 'Open') {
tradingEngine.current.position.positionCounters.periods.value++
}
}
function updateStatistics() {
if (bot.sessionAndMarketBaseAssetsAreEqual) {
tradingEngine.current.position.positionStatistics.profitLoss.value = tradingEngine.current.balance.baseAsset.value - tradingEngine.previous.balance.baseAsset.value
tradingEngine.current.position.positionStatistics.ROI.value = tradingEngine.current.position.positionStatistics.profitLoss.value * 100 / tradingEngine.current.position.size.value
} else {
tradingEngine.current.position.positionStatistics.profitLoss.value = tradingEngine.current.balance.quotedAsset.value - tradingEngine.previous.balance.quotedAsset.value
tradingEngine.current.position.positionStatistics.ROI.value = tradingEngine.current.position.positionStatistics.profitLoss.value * 100 / tradingEngine.current.position.size.value
}
tradingEngine.current.position.positionStatistics.days.value = tradingEngine.current.position.positionCounters.periods.value * sessionParameters.timeFrame.config.value / global.ONE_DAY_IN_MILISECONDS
}
}
+20 -4
View File
@@ -41,10 +41,6 @@ exports.newTradingRecords = function newTradingRecords(bot, logger) {
let product = dataset.parentNode
let outputDatasetArray = outputDatasetsMap.get(product.config.codeName)
if (product.config.codeName === 'Strategy-Objects') {
let a = 1
}
if (bot.processingDailyFiles === true && dataset.config.type === 'Daily Files') {
persistRecord()
}
@@ -91,6 +87,9 @@ exports.newTradingRecords = function newTradingRecords(bot, logger) {
}
function scanRecordDefinition(product) {
if (product.config.codeName === 'Position-Objects') {
let a = 1
}
/*
The Product Root Node is the root of the node hiriarchy branch that we need to look at
in order to fnd the node where we are going to extract the value.
@@ -166,6 +165,9 @@ exports.newTradingRecords = function newTradingRecords(bot, logger) {
if (recordProperty.config.isString !== true && Array.isArray(value) !== true) {
value = safeNumericValue(value)
}
if (recordProperty.config.isString === true && Array.isArray(value) !== true) {
value = safeStringValue(value)
}
record.push(value)
}
return record
@@ -191,4 +193,18 @@ exports.newTradingRecords = function newTradingRecords(bot, logger) {
}
return value
}
function safeStringValue(value) {
/*
The purpose of this function is to check that value variable does not have a value that
will later break the JSON format of files where this is going to be stored at.
*/
if (value === undefined) {
value = ''
}
if (value === null) {
value = ''
}
return value
}
}
+10 -2
View File
@@ -186,8 +186,6 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
tradingSystemModule.calculateTakeProfit()
}
tradingEngineModule.resetPositionCountersAndStatistics()
tradingEngineModule.updatePositionCountersAndStatistics()
tradingEngineModule.updateDistanceToEventsCounters()
/* Checking if Stop or Take Profit were hit */
@@ -198,6 +196,16 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
/* Taking a Position */
if (takingPosition === true) {
tradingSystemModule.getReadyToTakePosition()
/*
Whem we calculated all the formulas at the begining of the loop, we didn't know
we were going to take position in this same loop cycle. Some might formulas depends on
calculations that are triggered only when we are taking position. For that reason
we will calculate all formulas again, and after that the Stop Loss and Take Profit.
*/
tradingSystemModule.evalFormulas()
tradingSystemModule.calculateTakeProfit()
tradingSystemModule.calculateStopLoss()
tradingExecutionModule.takePosition()
tradingSystemModule.takePosition()
takingPosition = false
+3 -5
View File
@@ -40,17 +40,15 @@ exports.newTradingStrategy = function newTradingStrategy(bot, logger) {
tradingEngine.current.strategy.strategyName.value = strategyName
}
function closeStrategy() {
function closeStrategy(exitType) {
tradingEngine.current.strategy.status.value = 'Closed'
tradingEngine.current.strategy.exitType.value = exitType
tradingEngine.current.strategy.end.value = tradingEngine.current.candle.end.value
tradingEngine.current.strategy.endRate.value = tradingEngine.current.candle.min.value
}
function resetStrategy() {
tradingEngine.current.strategy.status.value = tradingEngine.current.strategy.status.config.initialValue
tradingEngine.current.strategy.stageType.value = tradingEngine.current.strategy.stageType.config.initialValue
tradingEngine.current.strategy.index.value = tradingEngine.current.strategy.index.config.initialValue
tradingEngine.current.strategy.strategyCounters.periods.value = tradingEngine.current.strategy.strategyCounters.periods.config.initialValue
tradingEngine.current.strategy.initialize(tradingEngine.current.strategy)
}
function updateEnds() {
+46 -137
View File
@@ -41,6 +41,9 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
const TRADING_STRATEGY_MODULE = require('./TradingStrategy.js')
let tradingStrategyModule = TRADING_STRATEGY_MODULE.newTradingStrategy(bot, logger)
const TRADING_POSITION_MODULE = require('./TradingPosition.js')
let tradingPositionModule = TRADING_POSITION_MODULE.newTradingPosition(bot, logger)
return thisObject
function initialize() {
@@ -49,12 +52,16 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
sessionParameters = bot.SESSION.parameters
tradingStrategyModule.initialize()
tradingPositionModule.initialize()
}
function finalize() {
tradingStrategyModule.finalize()
tradingStrategyModule = undefined
tradingPositionModule.finalize()
tradingPositionModule = undefined
chart = undefined
conditions = undefined
@@ -89,7 +96,9 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
}
function mantainPositions() {
tradingPositionModule.updateStatus()
tradingPositionModule.updateCounters()
tradingPositionModule.updateEnds()
}
function evalConditions() {
@@ -333,7 +342,7 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
tradingSystem.highlights.push(triggerStage.triggerOff.id)
tradingSystem.highlights.push(triggerStage.id)
tradingStrategyModule.closeStrategy()
tradingStrategyModule.closeStrategy('Trigger Off')
tradingEngine.current.distanceToEvent.triggerOff.value = 1
@@ -353,7 +362,10 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
function checkTakePosition() {
/* Take Position Condition */
if (tradingEngine.current.strategy.stageType.value === 'Trigger Stage') {
if (
tradingEngine.current.strategy.stageType.value === 'Trigger Stage' &&
tradingEngine.current.strategy.status.value === 'Open'
) {
let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value]
let triggerStage = strategy.triggerStage
@@ -383,12 +395,7 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
tradingSystem.highlights.push(triggerStage.id)
tradingStrategyModule.updateStageType('Open Stage')
tradingEngine.current.position.stopLoss.stopLossStage.value = 'Open Stage'
tradingEngine.current.position.takeProfit.takeProfitStage.value = 'Open Stage'
tradingEngine.current.position.stopLoss.stopLossPhase.value = 0
tradingEngine.current.position.takeProfit.takeProfitPhase.value = 0
tradingEngine.current.position.situationName.value = situation.name
tradingPositionModule.openPosition(situation.name)
/* TODO See what to do with this:
checkAnnouncements(triggerStage.takePosition)
@@ -470,8 +477,8 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
tradingSystem.highlights.push(parentNode.id)
tradingSystem.highlights.push(stage.id)
tradingEngine.current.position.stopLoss.stopLossPhase.value++
tradingEngine.current.position.stopLoss.stopLossStage.value = 'Manage Stage'
tradingPositionModule.updateStopLoss(tradingEngine.current.position.stopLoss.stopLossPhase.value + 1, 'Manage Stage')
if (tradingEngine.current.position.takeProfit.takeProfitPhase.value > 0) {
tradingStrategyModule.updateStageType('Manage Stage')
/* TODO ANNOUNCEMENT
@@ -521,7 +528,7 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
if (moveToPhase !== undefined) {
for (let q = 0; q < stopLoss.phases.length; q++) {
if (stopLoss.phases[q].id === moveToPhase.id) {
tradingEngine.current.position.stopLoss.stopLossPhase.value = q + 1
tradingPositionModule.updateStopLoss(q + 1, 'Manage Stage')
}
}
} else {
@@ -529,7 +536,6 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
continue
}
tradingEngine.current.position.stopLoss.stopLossStage.value = 'Manage Stage'
if (tradingEngine.current.position.takeProfit.takeProfitPhase.value > 0) {
tradingStrategyModule.updateStageType('Manage Stage')
/* TODO ANNOUNCEMENT
@@ -572,7 +578,7 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
if (phase !== undefined) {
if (phase.formula !== undefined) {
let previousValue = tradingEngine.current.position.stopLoss.value
tradingEngine.current.position.stopLoss.value = formulas.get(phase.formula.id)
tradingPositionModule.applyStopLossFormula(formulas, phase.formula.id)
/* TODO ANNOUNCEMENTS
if (tradingEngine.current.position.stopLoss.value !== previousValue) {
@@ -648,8 +654,8 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
tradingSystem.highlights.push(parentNode.id)
tradingSystem.highlights.push(stage.id)
tradingEngine.current.position.takeProfit.takeProfitPhase.value++
tradingEngine.current.position.takeProfit.takeProfitStage.value = 'Manage Stage'
tradingPositionModule.updateTakeProfit(tradingEngine.current.position.takeProfit.takeProfitPhase.value + 1, 'Manage Stage')
if (tradingEngine.current.position.stopLoss.stopLossPhase.value > 0) {
tradingStrategyModule.updateStageType('Manage Stage')
/* TODO ANNOUNCEMENT
@@ -698,7 +704,7 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
if (moveToPhase !== undefined) {
for (let q = 0; q < takeProfit.phases.length; q++) {
if (takeProfit.phases[q].id === moveToPhase.id) {
tradingEngine.current.position.takeProfit.takeProfitPhase.value = q + 1
tradingPositionModule.updateTakeProfit(q + 1, 'Manage Stage')
}
}
} else {
@@ -706,7 +712,6 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
continue
}
tradingEngine.current.position.takeProfit.takeProfitStage.value = 'Manage Stage'
if (tradingEngine.current.position.stopLoss.stopLossPhase.value > 0) {
tradingStrategyModule.updateStageType('Manage Stage')
/* TODO ANNOUNCEMENT
@@ -748,8 +753,8 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
if (phase !== undefined) {
if (phase.formula !== undefined) {
let previousValue = tradingEngine.current.position.stopLoss.value
tradingEngine.current.position.takeProfit.value = formulas.get(phase.formula.id)
let previousValue = tradingEngine.current.position.takeProfit.value
tradingPositionModule.applyTakeProfitFormula(formulas, phase.formula.id)
/* TODO ANNOUNCEMENTS
if (tradingEngine.current.position.takeProfit.value !== previousValue) {
@@ -776,45 +781,16 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
(!bot.sessionAndMarketBaseAssetsAreEqual && tradingEngine.current.candle.min.value <= tradingEngine.current.position.stopLoss.value)
) {
logger.write(MODULE_NAME, '[INFO] checkStopLossOrTakeProfitWasHit -> Stop Loss was hit.')
/*
Hit Point Validation
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 (bot.sessionAndMarketBaseAssetsAreEqual) {
if (tradingEngine.current.position.stopLoss.value < tradingEngine.current.candle.min.value) {
tradingEngine.current.position.stopLoss.value = tradingEngine.current.candle.min.value
}
} else {
if (tradingEngine.current.position.stopLoss.value > tradingEngine.current.candle.max.value) {
tradingEngine.current.position.stopLoss.value = tradingEngine.current.candle.max.value
}
}
let slippedStopLoss = tradingEngine.current.position.stopLoss.value
/* Apply the Slippage */
let slippageAmount = slippedStopLoss * bot.SESSION.parameters.slippage.config.stopLoss / 100
if (bot.sessionAndMarketBaseAssetsAreEqual) {
slippedStopLoss = slippedStopLoss + slippageAmount
} else {
slippedStopLoss = slippedStopLoss - slippageAmount
}
tradingEngine.current.position.endRate.value = slippedStopLoss
tradingPositionModule.preventStopLossDistortion()
tradingPositionModule.applySlippageToStopLoss()
tradingPositionModule.closePosition('Stop Loss')
tradingStrategyModule.updateStageType('Close Stage')
/* TODO ANNOUNCEMENT
checkAnnouncements(strategy.closeStage, 'Stop')
*/
tradingEngine.current.position.stopLoss.stopLossStage.value = 'No Stage'
tradingEngine.current.position.takeProfit.takeProfitStage.value = 'No Stage'
tradingEngine.current.position.end.value = tradingEngine.current.candle.end.value
tradingEngine.current.position.status.value = 1
tradingEngine.current.position.exitType.value = 1
return true // This means that the STOP was hit.
}
@@ -824,46 +800,16 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
(!bot.sessionAndMarketBaseAssetsAreEqual && tradingEngine.current.candle.max.value >= tradingEngine.current.position.takeProfit.value)
) {
logger.write(MODULE_NAME, '[INFO] checkStopLossOrTakeProfitWasHit -> Take Profit was hit.')
/*
Hit Point Validation:
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 (bot.sessionAndMarketBaseAssetsAreEqual) {
if (tradingEngine.current.position.takeProfit.value > tradingEngine.current.candle.max.value) {
tradingEngine.current.position.takeProfit.value = tradingEngine.current.candle.max.value
}
} else {
if (tradingEngine.current.position.takeProfit.value < tradingEngine.current.candle.min.value) {
tradingEngine.current.position.takeProfit.value = tradingEngine.current.candle.min.value
}
}
let slippedTakeProfit = tradingEngine.current.position.takeProfit.value
/* Apply the Slippage */
let slippageAmount = slippedTakeProfit * bot.SESSION.parameters.slippage.config.takeProfit / 100
if (bot.sessionAndMarketBaseAssetsAreEqual) {
slippedTakeProfit = slippedTakeProfit + slippageAmount
} else {
slippedTakeProfit = slippedTakeProfit - slippageAmount
}
tradingEngine.current.position.endRate.value = slippedTakeProfit
tradingPositionModule.preventTakeProfitDistortion()
tradingPositionModule.applySlippageToTakeProfit()
tradingPositionModule.closePosition('Take Profit')
tradingStrategyModule.updateStageType('Close Stage')
/* TODO ANNOUNCEMENT
checkAnnouncements(strategy.closeStage, 'Take Profit')
*/
tradingEngine.current.position.stopLoss.stopLossStage.value = 'No Stage'
tradingEngine.current.position.takeProfit.takeProfitStage.value = 'No Stage'
tradingEngine.current.position.end.value = tradingEngine.current.candle.end.value
tradingEngine.current.position.status.value = 1
tradingEngine.current.position.exitType.value = 2
addToSnapshots = true
return true // This means that the Take Profit was hit.
}
}
@@ -872,31 +818,20 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
}
function getReadyToTakePosition() {
/* Updating Episode Counters */
tradingEngine.episode.episodeCounters.positions.value++
/* 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()
tradingPositionModule.updateSizeAndRate(getPositionSize(), 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
/* We take what was calculated at the formula of position rate and apply the slippage. */
tradingPositionModule.applySlippageToRate()
}
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
@@ -927,70 +862,44 @@ exports.newTradingSystem = function newTradingSystem(bot, logger) {
}
function closePosition() {
tradingEngine.episode.episodeCounters.positions.value++
/* We calculate the new balances after the position is closed. */
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.positionStatistics.profitLoss.value = tradingEngine.current.balance.baseAsset.value - tradingEngine.previous.balance.baseAsset.value
tradingEngine.last.position.positionStatistics.ROI.value = tradingEngine.last.position.positionStatistics.profitLoss.value * 100 / tradingEngine.current.position.size.value
if (isNaN(tradingEngine.last.position.positionStatistics.ROI.value)) { tradingEngine.last.position.positionStatistics.ROI.value = 0 }
tradingEngine.episode.episodeStatistics.profitLoss.value = tradingEngine.current.balance.baseAsset.value - sessionParameters.sessionBaseAsset.config.initialBalance
} else {
tradingEngine.last.position.positionStatistics.profitLoss.value = tradingEngine.current.balance.quotedAsset.value - tradingEngine.previous.balance.quotedAsset.value
tradingEngine.last.position.positionStatistics.ROI.value = tradingEngine.last.position.positionStatistics.profitLoss.value * 100 / tradingEngine.current.position.size.value
if (isNaN(tradingEngine.last.position.positionStatistics.ROI.value)) { tradingEngine.last.position.positionStatistics.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.positionStatistics.ROI.value
tradingPositionModule.updateStatistics()
/* Recalculating Episode Counters */
if (tradingEngine.last.position.positionStatistics.profitLoss.value > 0) {
tradingEngine.episode.episodeCounters.hits.value++
} else {
tradingEngine.episode.episodeCounters.fails.value++
}
/* Recalculating Episode Statistics */
if (bot.sessionAndMarketBaseAssetsAreEqual) {
tradingEngine.episode.episodeStatistics.profitLoss.value = tradingEngine.current.balance.baseAsset.value - sessionParameters.sessionBaseAsset.config.initialBalance
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.episodeCounters.positions.value
tradingEngine.episode.episodeStatistics.anualizedRateOfReturn.value = tradingEngine.episode.episodeStatistics.ROI.value / tradingEngine.episode.episodeStatistics.days.value * 365
} else {
tradingEngine.episode.episodeStatistics.profitLoss.value = tradingEngine.current.balance.quotedAsset.value - sessionParameters.sessionQuotedAsset.config.initialBalance
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.episodeCounters.positions.value
tradingEngine.episode.episodeStatistics.anualizedRateOfReturn.value = tradingEngine.episode.episodeStatistics.ROI.value / tradingEngine.episode.episodeStatistics.days.value * 365
}
tradingEngine.current.position.stopLoss.value = 0
tradingEngine.current.position.takeProfit.value = 0
tradingEngine.current.position.rate.value = 0
tradingEngine.current.position.size.value = 0
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') {
tradingStrategyModule.closeStrategy()
tradingStrategyModule.closeStrategy('Position Closed')
tradingEngine.current.distanceToEvent.triggerOff.value = 1
}
}