STOP TP fixes
This commit is contained in:
1 parent
b7811b2914
commit
e0f683aec3
10 files changed
+406
-316
No files matched your search
@@ -50,6 +50,10 @@ exports.newTradingEpisode = function newTradingEpisode(bot, logger, tradingEngin
|
||||
or the task / session was restarted.
|
||||
*/
|
||||
if (bot.FIRST_EXECUTION === true) {
|
||||
/* Starting begin and end */
|
||||
tradingEngine.current.episode.begin.value = tradingEngine.current.episode.candle.begin.value
|
||||
tradingEngine.current.episode.end.value = tradingEngine.current.episode.candle.end.value
|
||||
|
||||
/* Getting the begin Balance from the session configuration */
|
||||
tradingEngine.current.episode.episodeBaseAsset.beginBalance.value = sessionParameters.sessionBaseAsset.config.initialBalance
|
||||
tradingEngine.current.episode.episodeQuotedAsset.beginBalance.value = sessionParameters.sessionQuotedAsset.config.initialBalance
|
||||
@@ -62,7 +66,6 @@ exports.newTradingEpisode = function newTradingEpisode(bot, logger, tradingEngin
|
||||
tradingEngine.current.episode.status.value = 'Open'
|
||||
tradingEngine.current.episode.serialNumber.value = 1
|
||||
tradingEngine.current.episode.identifier.value = global.UNIQUE_ID()
|
||||
tradingEngine.current.episode.begin.value = tradingEngine.current.episode.candle.begin.value
|
||||
tradingEngine.current.episode.beginRate.value = tradingEngine.current.episode.candle.close.value
|
||||
}
|
||||
}
|
||||
@@ -73,7 +76,7 @@ exports.newTradingEpisode = function newTradingEpisode(bot, logger, tradingEngin
|
||||
|
||||
function closeEpisode() {
|
||||
tradingEngine.current.episode.status.value = 'Closed'
|
||||
tradingEngine.current.episode.end.value = tradingEngine.current.episode.candle.begin.value
|
||||
tradingEngine.current.episode.end.value = tradingEngine.current.episode.candle.end.value
|
||||
tradingEngine.current.episode.endRate.value = tradingEngine.current.episode.candle.close.value
|
||||
tradingEngine.current.episode.episodeBaseAsset.endBalance.value = tradingEngine.current.episode.episodeBaseAsset.balance.value
|
||||
tradingEngine.current.episode.episodeQuotedAsset.endBalance.value = tradingEngine.current.episode.episodeQuotedAsset.balance.value
|
||||
@@ -85,7 +88,7 @@ exports.newTradingEpisode = function newTradingEpisode(bot, logger, tradingEngin
|
||||
|
||||
function updateEnds() {
|
||||
if (tradingEngine.current.episode.status.value === 'Open') {
|
||||
tradingEngine.current.episode.end.value = tradingEngine.current.episode.candle.end.value
|
||||
tradingEngine.current.episode.end.value = tradingEngine.current.episode.end.value + sessionParameters.timeFrame.config.value
|
||||
tradingEngine.current.episode.endRate.value = tradingEngine.current.episode.candle.close.value
|
||||
tradingEngine.current.episode.episodeBaseAsset.endBalance.value = tradingEngine.current.episode.episodeBaseAsset.balance.value
|
||||
tradingEngine.current.episode.episodeQuotedAsset.endBalance.value = tradingEngine.current.episode.episodeQuotedAsset.balance.value
|
||||
@@ -160,7 +163,7 @@ exports.newTradingEpisode = function newTradingEpisode(bot, logger, tradingEngin
|
||||
tradingEngine.current.episode.episodeBaseAsset.hitRatio.value = global.PRECISE(tradingEngine.current.episode.episodeBaseAsset.hitRatio.value, 10)
|
||||
tradingEngine.current.episode.episodeQuotedAsset.hitRatio.value = global.PRECISE(tradingEngine.current.episode.episodeQuotedAsset.hitRatio.value, 10)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Updating Annualized Rate Of Return
|
||||
|
||||
|
||||
@@ -51,11 +51,14 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
|
||||
|
||||
function openPosition(situationName) {
|
||||
|
||||
/* Starting begin and end */
|
||||
tradingEngine.current.position.begin.value = tradingEngine.current.episode.cycle.lastBegin.value
|
||||
tradingEngine.current.position.end.value = tradingEngine.current.episode.cycle.lastEnd.value
|
||||
|
||||
/* Recording the opening at the Trading Engine Data Structure */
|
||||
tradingEngine.current.position.status.value = 'Open'
|
||||
tradingEngine.current.position.serialNumber.value = tradingEngine.current.episode.episodeCounters.positions.value + 1
|
||||
tradingEngine.current.position.identifier.value = global.UNIQUE_ID()
|
||||
tradingEngine.current.position.begin.value = tradingEngine.current.episode.candle.begin.value
|
||||
tradingEngine.current.position.beginRate.value = tradingEngine.current.episode.candle.close.value
|
||||
tradingEngine.current.position.positionBaseAsset.beginBalance.value = tradingEngine.current.episode.episodeBaseAsset.balance.value
|
||||
tradingEngine.current.position.positionQuotedAsset.beginBalance.value = tradingEngine.current.episode.episodeQuotedAsset.balance.value
|
||||
@@ -79,11 +82,20 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
|
||||
function closingPosition(exitType) {
|
||||
tradingEngine.current.position.status.value = 'Closing'
|
||||
tradingEngine.current.position.exitType.value = exitType
|
||||
|
||||
/*
|
||||
By the time we figured out that the stop loss or take profit were hit, or
|
||||
for whatever reason the position needs to be closed, the take profit and
|
||||
stop loss values for the next candle have already been calculated. In order
|
||||
to avoid being plotted, we will put them in zero.
|
||||
*/
|
||||
tradingEngine.current.position.stopLoss.value = 0
|
||||
tradingEngine.current.position.takeProfit.value = 0
|
||||
}
|
||||
|
||||
function closePosition() {
|
||||
tradingEngine.current.position.status.value = 'Closed'
|
||||
tradingEngine.current.position.end.value = tradingEngine.current.episode.candle.begin.value
|
||||
tradingEngine.current.position.end.value = tradingEngine.current.episode.cycle.lastEnd.value
|
||||
tradingEngine.current.position.endRate.value = tradingEngine.current.episode.candle.close.value
|
||||
tradingEngine.current.position.positionBaseAsset.endBalance.value = tradingEngine.current.episode.episodeBaseAsset.balance.value
|
||||
tradingEngine.current.position.positionQuotedAsset.endBalance.value = tradingEngine.current.episode.episodeQuotedAsset.balance.value
|
||||
@@ -94,17 +106,17 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
|
||||
tradingEngineModule.cloneValues(tradingEngine.current.position, tradingEngine.last.position)
|
||||
|
||||
cycleBasedStatistics()
|
||||
|
||||
|
||||
/* Updating Hits & Fails */
|
||||
if (tradingEngine.current.position.positionBaseAsset.profitLoss.value > 0) {
|
||||
tradingEngine.current.episode.episodeBaseAsset.hits.value++
|
||||
}
|
||||
}
|
||||
if (tradingEngine.current.position.positionBaseAsset.profitLoss.value < 0) {
|
||||
tradingEngine.current.episode.episodeBaseAsset.fails.value++
|
||||
}
|
||||
if (tradingEngine.current.position.positionQuotedAsset.profitLoss.value > 0) {
|
||||
tradingEngine.current.episode.episodeQuotedAsset.hits.value++
|
||||
}
|
||||
}
|
||||
if (tradingEngine.current.position.positionQuotedAsset.profitLoss.value < 0) {
|
||||
tradingEngine.current.episode.episodeQuotedAsset.fails.value++
|
||||
}
|
||||
@@ -112,10 +124,27 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
|
||||
|
||||
function applyStopLossFormula(formulas, formulaId) {
|
||||
tradingEngine.current.position.stopLoss.value = formulas.get(formulaId)
|
||||
updateStopLossTakeProfitBeginEnd(tradingEngine.current.position.stopLoss)
|
||||
}
|
||||
|
||||
function applyTakeProfitFormula(formulas, formulaId) {
|
||||
tradingEngine.current.position.takeProfit.value = formulas.get(formulaId)
|
||||
updateStopLossTakeProfitBeginEnd(tradingEngine.current.position.takeProfit)
|
||||
}
|
||||
|
||||
function updateStopLossTakeProfitBeginEnd(node) {
|
||||
/*
|
||||
Both the Stop Loss and the Take Profit have their own Begin and End.
|
||||
Ther reason for this is because they represent targets to be checked
|
||||
at the next candle, so it does not apply that they share the begin and
|
||||
end of the position itself.
|
||||
*/
|
||||
node.begin.value =
|
||||
tradingEngine.current.episode.candle.begin.value +
|
||||
sessionParameters.timeFrame.config.value
|
||||
node.end.value =
|
||||
tradingEngine.current.episode.candle.end.value +
|
||||
sessionParameters.timeFrame.config.value
|
||||
}
|
||||
|
||||
function updateStopLoss(phase) {
|
||||
@@ -253,7 +282,7 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
|
||||
|
||||
function updateEnds() {
|
||||
if (tradingEngine.current.position.status.value === 'Open') {
|
||||
tradingEngine.current.position.end.value = tradingEngine.current.episode.candle.end.value
|
||||
tradingEngine.current.position.end.value = tradingEngine.current.position.end.value + sessionParameters.timeFrame.config.value
|
||||
tradingEngine.current.position.endRate.value = tradingEngine.current.episode.candle.close.value
|
||||
tradingEngine.current.position.positionBaseAsset.endBalance.value = tradingEngine.current.episode.episodeBaseAsset.balance.value
|
||||
tradingEngine.current.position.positionQuotedAsset.endBalance.value = tradingEngine.current.episode.episodeQuotedAsset.balance.value
|
||||
@@ -305,7 +334,7 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
|
||||
/* Hit Fail Calculation */
|
||||
if (tradingEngine.current.position.positionBaseAsset.ROI.value > 0) {
|
||||
tradingEngine.current.position.positionBaseAsset.hitFail.value = 'Hit'
|
||||
}
|
||||
}
|
||||
if (tradingEngine.current.position.positionBaseAsset.ROI.value < 0) {
|
||||
tradingEngine.current.position.positionBaseAsset.hitFail.value = 'Fail'
|
||||
}
|
||||
@@ -314,7 +343,7 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
|
||||
}
|
||||
if (tradingEngine.current.position.positionQuotedAsset.ROI.value > 0) {
|
||||
tradingEngine.current.position.positionQuotedAsset.hitFail.value = 'Hit'
|
||||
}
|
||||
}
|
||||
if (tradingEngine.current.position.positionQuotedAsset.ROI.value < 0) {
|
||||
tradingEngine.current.position.positionQuotedAsset.hitFail.value = 'Fail'
|
||||
}
|
||||
@@ -348,7 +377,7 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
|
||||
/* Hit Fail Calculation */
|
||||
if (tradingEngine.current.position.positionStatistics.ROI.value > 0) {
|
||||
tradingEngine.current.position.positionStatistics.hitFail.value = 'Hit'
|
||||
}
|
||||
}
|
||||
if (tradingEngine.current.position.positionStatistics.ROI.value < 0) {
|
||||
tradingEngine.current.position.positionStatistics.hitFail.value = 'Fail'
|
||||
}
|
||||
|
||||
@@ -393,6 +393,8 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM
|
||||
|
||||
function runManageStage() {
|
||||
|
||||
if (tradingEngine.current.episode.cycle.value !== 'First') { return }
|
||||
|
||||
runWhenStatusIsOpening()
|
||||
runWhenStatusIsOpen()
|
||||
|
||||
@@ -428,331 +430,331 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM
|
||||
/* Checking if Stop or Take Profit were hit */
|
||||
checkStopLossOrTakeProfitWasHit()
|
||||
}
|
||||
}
|
||||
|
||||
function calculateStopLoss() {
|
||||
let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value]
|
||||
let manageStage = strategy.manageStage
|
||||
let phase
|
||||
|
||||
if (manageStage !== undefined) {
|
||||
if (manageStage.managedStopLoss !== undefined) {
|
||||
phase = manageStage.managedStopLoss.phases[tradingEngine.current.position.stopLoss.stopLossPhase.value - 1]
|
||||
}
|
||||
}
|
||||
|
||||
if (phase !== undefined) {
|
||||
if (phase.formula !== undefined) {
|
||||
let previousValue = tradingEngine.current.position.stopLoss.value
|
||||
tradingPositionModule.applyStopLossFormula(tradingSystem.formulas, phase.formula.id)
|
||||
|
||||
if (tradingEngine.current.position.stopLoss.value !== previousValue) {
|
||||
announcementsModule.makeAnnoucements(phase)
|
||||
function calculateStopLoss() {
|
||||
let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value]
|
||||
let manageStage = strategy.manageStage
|
||||
let phase
|
||||
|
||||
if (manageStage !== undefined) {
|
||||
if (manageStage.managedStopLoss !== undefined) {
|
||||
phase = manageStage.managedStopLoss.phases[tradingEngine.current.position.stopLoss.stopLossPhase.value - 1]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateTakeProfit() {
|
||||
let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value]
|
||||
let manageStage = strategy.manageStage
|
||||
let phase
|
||||
|
||||
if (manageStage !== undefined) {
|
||||
if (manageStage.managedTakeProfit !== undefined) {
|
||||
phase = manageStage.managedTakeProfit.phases[tradingEngine.current.position.takeProfit.takeProfitPhase.value - 1]
|
||||
}
|
||||
}
|
||||
|
||||
if (phase !== undefined) {
|
||||
if (phase.formula !== undefined) {
|
||||
let previousValue = tradingEngine.current.position.takeProfit.value
|
||||
tradingPositionModule.applyTakeProfitFormula(tradingSystem.formulas, phase.formula.id)
|
||||
|
||||
if (tradingEngine.current.position.takeProfit.value !== previousValue) {
|
||||
announcementsModule.makeAnnoucements(phase)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateStopLossPosition() {
|
||||
/*
|
||||
The position of the Stop Loss (above or below the price) is needed in order to know
|
||||
later if the price hit the Stop Loss or not at every Simulation candle. When we get
|
||||
the first values of the simulation of the Stop Loss we check if it is above or below
|
||||
the Position Rate, and we assign the values Above or Below to it.
|
||||
*/
|
||||
if (tradingEngine.current.position.stopLoss.stopLossPosition.value === tradingEngine.current.position.stopLoss.stopLossPosition.config.initialValue) {
|
||||
if (tradingEngine.current.position.stopLoss.value > tradingEngine.current.position.entryTargetRate.value) {
|
||||
tradingEngine.current.position.stopLoss.stopLossPosition.value = 'Above'
|
||||
} else {
|
||||
tradingEngine.current.position.stopLoss.stopLossPosition.value = 'Below'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateTakeProfitPosition() {
|
||||
/*
|
||||
The position of the Take Profit (above or below the price) is needed in order to know
|
||||
later if the price hit the Take Profit or not at every Simulation candle. When we get
|
||||
the first values of the simulation of the Take Profits we check if it is above or below
|
||||
the Position Rates, and we assign the values Above or Below to it.
|
||||
*/
|
||||
if (tradingEngine.current.position.takeProfit.takeProfitPosition.value === tradingEngine.current.position.takeProfit.takeProfitPosition.config.initialValue) {
|
||||
if (tradingEngine.current.position.takeProfit.value > tradingEngine.current.position.entryTargetRate.value) {
|
||||
tradingEngine.current.position.takeProfit.takeProfitPosition.value = 'Above'
|
||||
} else {
|
||||
tradingEngine.current.position.takeProfit.takeProfitPosition.value = 'Below'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkStopPhasesEvents() {
|
||||
let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value]
|
||||
let manageStage = strategy.manageStage
|
||||
let parentNode
|
||||
let phaseIndex
|
||||
let phase
|
||||
let stopLoss
|
||||
|
||||
if (manageStage !== undefined) {
|
||||
if (manageStage.managedStopLoss !== undefined) {
|
||||
parentNode = manageStage
|
||||
phaseIndex = tradingEngine.current.position.stopLoss.stopLossPhase.value - 1
|
||||
stopLoss = manageStage.managedStopLoss
|
||||
phase = stopLoss.phases[phaseIndex]
|
||||
}
|
||||
}
|
||||
|
||||
if (parentNode !== undefined) {
|
||||
if (phase === undefined) { return } // trying to jump to a phase that does not exists.
|
||||
|
||||
/* Check the next Phase Event. */
|
||||
let nextPhaseEvent = phase.nextPhaseEvent
|
||||
if (nextPhaseEvent !== undefined) {
|
||||
for (let k = 0; k < nextPhaseEvent.situations.length; k++) {
|
||||
let situation = nextPhaseEvent.situations[k]
|
||||
let passed
|
||||
if (situation.conditions.length > 0) {
|
||||
passed = true
|
||||
}
|
||||
|
||||
passed = tradingSystem.checkConditions(situation, passed)
|
||||
|
||||
tradingSystem.values.push([situation.id, passed])
|
||||
if (passed) {
|
||||
tradingSystem.highlights.push(situation.id)
|
||||
tradingSystem.highlights.push(nextPhaseEvent.id)
|
||||
tradingSystem.highlights.push(phase.id)
|
||||
tradingSystem.highlights.push(stopLoss.id)
|
||||
tradingSystem.highlights.push(parentNode.id)
|
||||
tradingSystem.highlights.push(manageStage.id)
|
||||
|
||||
tradingPositionModule.updateStopLoss(tradingEngine.current.position.stopLoss.stopLossPhase.value + 1)
|
||||
|
||||
announcementsModule.makeAnnoucements(nextPhaseEvent)
|
||||
|
||||
/* Reset this counter */
|
||||
tradingEngine.current.episode.distanceToEvent.nextPhase.value = 1
|
||||
return // only one event can pass at the time
|
||||
|
||||
if (phase !== undefined) {
|
||||
if (phase.formula !== undefined) {
|
||||
let previousValue = tradingEngine.current.position.stopLoss.value
|
||||
tradingPositionModule.applyStopLossFormula(tradingSystem.formulas, phase.formula.id)
|
||||
|
||||
if (tradingEngine.current.position.stopLoss.value !== previousValue) {
|
||||
announcementsModule.makeAnnoucements(phase)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the Move to Phase Events. */
|
||||
for (let n = 0; n < phase.moveToPhaseEvents.length; n++) {
|
||||
let moveToPhaseEvent = phase.moveToPhaseEvents[n]
|
||||
if (moveToPhaseEvent !== undefined) {
|
||||
for (let k = 0; k < moveToPhaseEvent.situations.length; k++) {
|
||||
let situation = moveToPhaseEvent.situations[k]
|
||||
}
|
||||
|
||||
function calculateTakeProfit() {
|
||||
let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value]
|
||||
let manageStage = strategy.manageStage
|
||||
let phase
|
||||
|
||||
if (manageStage !== undefined) {
|
||||
if (manageStage.managedTakeProfit !== undefined) {
|
||||
phase = manageStage.managedTakeProfit.phases[tradingEngine.current.position.takeProfit.takeProfitPhase.value - 1]
|
||||
}
|
||||
}
|
||||
|
||||
if (phase !== undefined) {
|
||||
if (phase.formula !== undefined) {
|
||||
let previousValue = tradingEngine.current.position.takeProfit.value
|
||||
tradingPositionModule.applyTakeProfitFormula(tradingSystem.formulas, phase.formula.id)
|
||||
|
||||
if (tradingEngine.current.position.takeProfit.value !== previousValue) {
|
||||
announcementsModule.makeAnnoucements(phase)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateStopLossPosition() {
|
||||
/*
|
||||
The position of the Stop Loss (above or below the price) is needed in order to know
|
||||
later if the price hit the Stop Loss or not at every Simulation candle. When we get
|
||||
the first values of the simulation of the Stop Loss we check if it is above or below
|
||||
the Position Rate, and we assign the values Above or Below to it.
|
||||
*/
|
||||
if (tradingEngine.current.position.stopLoss.stopLossPosition.value === tradingEngine.current.position.stopLoss.stopLossPosition.config.initialValue) {
|
||||
if (tradingEngine.current.position.stopLoss.value > tradingEngine.current.position.entryTargetRate.value) {
|
||||
tradingEngine.current.position.stopLoss.stopLossPosition.value = 'Above'
|
||||
} else {
|
||||
tradingEngine.current.position.stopLoss.stopLossPosition.value = 'Below'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateTakeProfitPosition() {
|
||||
/*
|
||||
The position of the Take Profit (above or below the price) is needed in order to know
|
||||
later if the price hit the Take Profit or not at every Simulation candle. When we get
|
||||
the first values of the simulation of the Take Profits we check if it is above or below
|
||||
the Position Rates, and we assign the values Above or Below to it.
|
||||
*/
|
||||
if (tradingEngine.current.position.takeProfit.takeProfitPosition.value === tradingEngine.current.position.takeProfit.takeProfitPosition.config.initialValue) {
|
||||
if (tradingEngine.current.position.takeProfit.value > tradingEngine.current.position.entryTargetRate.value) {
|
||||
tradingEngine.current.position.takeProfit.takeProfitPosition.value = 'Above'
|
||||
} else {
|
||||
tradingEngine.current.position.takeProfit.takeProfitPosition.value = 'Below'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkStopPhasesEvents() {
|
||||
let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value]
|
||||
let manageStage = strategy.manageStage
|
||||
let parentNode
|
||||
let phaseIndex
|
||||
let phase
|
||||
let stopLoss
|
||||
|
||||
if (manageStage !== undefined) {
|
||||
if (manageStage.managedStopLoss !== undefined) {
|
||||
parentNode = manageStage
|
||||
phaseIndex = tradingEngine.current.position.stopLoss.stopLossPhase.value - 1
|
||||
stopLoss = manageStage.managedStopLoss
|
||||
phase = stopLoss.phases[phaseIndex]
|
||||
}
|
||||
}
|
||||
|
||||
if (parentNode !== undefined) {
|
||||
if (phase === undefined) { return } // trying to jump to a phase that does not exists.
|
||||
|
||||
/* Check the next Phase Event. */
|
||||
let nextPhaseEvent = phase.nextPhaseEvent
|
||||
if (nextPhaseEvent !== undefined) {
|
||||
for (let k = 0; k < nextPhaseEvent.situations.length; k++) {
|
||||
let situation = nextPhaseEvent.situations[k]
|
||||
let passed
|
||||
if (situation.conditions.length > 0) {
|
||||
passed = true
|
||||
}
|
||||
|
||||
|
||||
passed = tradingSystem.checkConditions(situation, passed)
|
||||
|
||||
|
||||
tradingSystem.values.push([situation.id, passed])
|
||||
if (passed) {
|
||||
tradingSystem.highlights.push(situation.id)
|
||||
tradingSystem.highlights.push(moveToPhaseEvent.id)
|
||||
tradingSystem.highlights.push(nextPhaseEvent.id)
|
||||
tradingSystem.highlights.push(phase.id)
|
||||
tradingSystem.highlights.push(stopLoss.id)
|
||||
tradingSystem.highlights.push(parentNode.id)
|
||||
tradingSystem.highlights.push(manageStage.id)
|
||||
|
||||
let moveToPhase = moveToPhaseEvent.referenceParent
|
||||
if (moveToPhase !== undefined) {
|
||||
for (let q = 0; q < stopLoss.phases.length; q++) {
|
||||
if (stopLoss.phases[q].id === moveToPhase.id) {
|
||||
tradingPositionModule.updateStopLoss(q + 1)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tradingSystem.errors.push([moveToPhaseEvent.id, 'This Node needs to reference a Phase.'])
|
||||
continue
|
||||
}
|
||||
|
||||
announcementsModule.makeAnnoucements(moveToPhaseEvent)
|
||||
|
||||
|
||||
tradingPositionModule.updateStopLoss(tradingEngine.current.position.stopLoss.stopLossPhase.value + 1)
|
||||
|
||||
announcementsModule.makeAnnoucements(nextPhaseEvent)
|
||||
|
||||
/* Reset this counter */
|
||||
tradingEngine.current.episode.distanceToEvent.moveToPhase.value = 1
|
||||
tradingEngine.current.episode.distanceToEvent.nextPhase.value = 1
|
||||
return // only one event can pass at the time
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the Move to Phase Events. */
|
||||
for (let n = 0; n < phase.moveToPhaseEvents.length; n++) {
|
||||
let moveToPhaseEvent = phase.moveToPhaseEvents[n]
|
||||
if (moveToPhaseEvent !== undefined) {
|
||||
for (let k = 0; k < moveToPhaseEvent.situations.length; k++) {
|
||||
let situation = moveToPhaseEvent.situations[k]
|
||||
let passed
|
||||
if (situation.conditions.length > 0) {
|
||||
passed = true
|
||||
}
|
||||
|
||||
passed = tradingSystem.checkConditions(situation, passed)
|
||||
|
||||
tradingSystem.values.push([situation.id, passed])
|
||||
if (passed) {
|
||||
tradingSystem.highlights.push(situation.id)
|
||||
tradingSystem.highlights.push(moveToPhaseEvent.id)
|
||||
tradingSystem.highlights.push(phase.id)
|
||||
tradingSystem.highlights.push(stopLoss.id)
|
||||
tradingSystem.highlights.push(parentNode.id)
|
||||
tradingSystem.highlights.push(manageStage.id)
|
||||
|
||||
let moveToPhase = moveToPhaseEvent.referenceParent
|
||||
if (moveToPhase !== undefined) {
|
||||
for (let q = 0; q < stopLoss.phases.length; q++) {
|
||||
if (stopLoss.phases[q].id === moveToPhase.id) {
|
||||
tradingPositionModule.updateStopLoss(q + 1)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tradingSystem.errors.push([moveToPhaseEvent.id, 'This Node needs to reference a Phase.'])
|
||||
continue
|
||||
}
|
||||
|
||||
announcementsModule.makeAnnoucements(moveToPhaseEvent)
|
||||
|
||||
/* Reset this counter */
|
||||
tradingEngine.current.episode.distanceToEvent.moveToPhase.value = 1
|
||||
return // only one event can pass at the time
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkTakeProfitPhaseEvents() {
|
||||
let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value]
|
||||
let openStage = strategy.openStage
|
||||
let manageStage = strategy.manageStage
|
||||
let parentNode
|
||||
let phaseIndex
|
||||
let phase
|
||||
let takeProfit
|
||||
|
||||
if (manageStage !== undefined) {
|
||||
if (manageStage.managedTakeProfit !== undefined) {
|
||||
parentNode = manageStage
|
||||
phaseIndex = tradingEngine.current.position.takeProfit.takeProfitPhase.value - 1
|
||||
takeProfit = manageStage.managedTakeProfit
|
||||
phase = takeProfit.phases[phaseIndex]
|
||||
}
|
||||
}
|
||||
|
||||
if (parentNode !== undefined) {
|
||||
if (phase === undefined) { return } // trying to jump to a phase that does not exists.
|
||||
|
||||
/* Check the next Phase Event. */
|
||||
let nextPhaseEvent = phase.nextPhaseEvent
|
||||
if (nextPhaseEvent !== undefined) {
|
||||
for (let k = 0; k < nextPhaseEvent.situations.length; k++) {
|
||||
let situation = nextPhaseEvent.situations[k]
|
||||
let passed
|
||||
if (situation.conditions.length > 0) {
|
||||
passed = true
|
||||
}
|
||||
|
||||
passed = tradingSystem.checkConditions(situation, passed)
|
||||
|
||||
tradingSystem.values.push([situation.id, passed])
|
||||
if (passed) {
|
||||
tradingSystem.highlights.push(situation.id)
|
||||
tradingSystem.highlights.push(nextPhaseEvent.id)
|
||||
tradingSystem.highlights.push(phase.id)
|
||||
tradingSystem.highlights.push(takeProfit.id)
|
||||
tradingSystem.highlights.push(parentNode.id)
|
||||
tradingSystem.highlights.push(manageStage.id)
|
||||
|
||||
tradingPositionModule.updateTakeProfit(tradingEngine.current.position.takeProfit.takeProfitPhase.value + 1)
|
||||
|
||||
announcementsModule.makeAnnoucements(nextPhaseEvent)
|
||||
|
||||
/* Reset this counter */
|
||||
tradingEngine.current.episode.distanceToEvent.nextPhase.value = 1
|
||||
return // only one event can pass at the time
|
||||
}
|
||||
|
||||
function checkTakeProfitPhaseEvents() {
|
||||
let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value]
|
||||
let openStage = strategy.openStage
|
||||
let manageStage = strategy.manageStage
|
||||
let parentNode
|
||||
let phaseIndex
|
||||
let phase
|
||||
let takeProfit
|
||||
|
||||
if (manageStage !== undefined) {
|
||||
if (manageStage.managedTakeProfit !== undefined) {
|
||||
parentNode = manageStage
|
||||
phaseIndex = tradingEngine.current.position.takeProfit.takeProfitPhase.value - 1
|
||||
takeProfit = manageStage.managedTakeProfit
|
||||
phase = takeProfit.phases[phaseIndex]
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the Move to Phase Events. */
|
||||
for (let n = 0; n < phase.moveToPhaseEvents.length; n++) {
|
||||
let moveToPhaseEvent = phase.moveToPhaseEvents[n]
|
||||
if (moveToPhaseEvent !== undefined) {
|
||||
for (let k = 0; k < moveToPhaseEvent.situations.length; k++) {
|
||||
let situation = moveToPhaseEvent.situations[k]
|
||||
|
||||
if (parentNode !== undefined) {
|
||||
if (phase === undefined) { return } // trying to jump to a phase that does not exists.
|
||||
|
||||
/* Check the next Phase Event. */
|
||||
let nextPhaseEvent = phase.nextPhaseEvent
|
||||
if (nextPhaseEvent !== undefined) {
|
||||
for (let k = 0; k < nextPhaseEvent.situations.length; k++) {
|
||||
let situation = nextPhaseEvent.situations[k]
|
||||
let passed
|
||||
if (situation.conditions.length > 0) {
|
||||
passed = true
|
||||
}
|
||||
|
||||
|
||||
passed = tradingSystem.checkConditions(situation, passed)
|
||||
|
||||
|
||||
tradingSystem.values.push([situation.id, passed])
|
||||
if (passed) {
|
||||
tradingSystem.highlights.push(situation.id)
|
||||
tradingSystem.highlights.push(moveToPhaseEvent.id)
|
||||
tradingSystem.highlights.push(nextPhaseEvent.id)
|
||||
tradingSystem.highlights.push(phase.id)
|
||||
tradingSystem.highlights.push(takeProfit.id)
|
||||
tradingSystem.highlights.push(parentNode.id)
|
||||
tradingSystem.highlights.push(manageStage.id)
|
||||
|
||||
let moveToPhase = moveToPhaseEvent.referenceParent
|
||||
if (moveToPhase !== undefined) {
|
||||
for (let q = 0; q < takeProfit.phases.length; q++) {
|
||||
if (takeProfit.phases[q].id === moveToPhase.id) {
|
||||
tradingPositionModule.updateTakeProfit(q + 1)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tradingSystem.errors.push([moveToPhaseEvent.id, 'This Node needs to reference a Phase.'])
|
||||
continue
|
||||
}
|
||||
|
||||
announcementsModule.makeAnnoucements(moveToPhaseEvent)
|
||||
|
||||
|
||||
tradingPositionModule.updateTakeProfit(tradingEngine.current.position.takeProfit.takeProfitPhase.value + 1)
|
||||
|
||||
announcementsModule.makeAnnoucements(nextPhaseEvent)
|
||||
|
||||
/* Reset this counter */
|
||||
tradingEngine.current.episode.distanceToEvent.moveToPhase.value = 1
|
||||
tradingEngine.current.episode.distanceToEvent.nextPhase.value = 1
|
||||
return // only one event can pass at the time
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the Move to Phase Events. */
|
||||
for (let n = 0; n < phase.moveToPhaseEvents.length; n++) {
|
||||
let moveToPhaseEvent = phase.moveToPhaseEvents[n]
|
||||
if (moveToPhaseEvent !== undefined) {
|
||||
for (let k = 0; k < moveToPhaseEvent.situations.length; k++) {
|
||||
let situation = moveToPhaseEvent.situations[k]
|
||||
let passed
|
||||
if (situation.conditions.length > 0) {
|
||||
passed = true
|
||||
}
|
||||
|
||||
passed = tradingSystem.checkConditions(situation, passed)
|
||||
|
||||
tradingSystem.values.push([situation.id, passed])
|
||||
if (passed) {
|
||||
tradingSystem.highlights.push(situation.id)
|
||||
tradingSystem.highlights.push(moveToPhaseEvent.id)
|
||||
tradingSystem.highlights.push(phase.id)
|
||||
tradingSystem.highlights.push(takeProfit.id)
|
||||
tradingSystem.highlights.push(parentNode.id)
|
||||
tradingSystem.highlights.push(manageStage.id)
|
||||
|
||||
let moveToPhase = moveToPhaseEvent.referenceParent
|
||||
if (moveToPhase !== undefined) {
|
||||
for (let q = 0; q < takeProfit.phases.length; q++) {
|
||||
if (takeProfit.phases[q].id === moveToPhase.id) {
|
||||
tradingPositionModule.updateTakeProfit(q + 1)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tradingSystem.errors.push([moveToPhaseEvent.id, 'This Node needs to reference a Phase.'])
|
||||
continue
|
||||
}
|
||||
|
||||
announcementsModule.makeAnnoucements(moveToPhaseEvent)
|
||||
|
||||
/* Reset this counter */
|
||||
tradingEngine.current.episode.distanceToEvent.moveToPhase.value = 1
|
||||
return // only one event can pass at the time
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkStopLossOrTakeProfitWasHit() {
|
||||
{
|
||||
let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value]
|
||||
/*
|
||||
Checking what happened since the last execution. We need to know if the Stop Loss
|
||||
or our Take Profit were hit.
|
||||
*/
|
||||
|
||||
/* Stop Loss condition: Here we verify if the Stop Loss was hitted or not. */
|
||||
if (
|
||||
(
|
||||
tradingEngine.current.position.stopLoss.stopLossPosition.value === 'Above' &&
|
||||
tradingEngine.current.episode.candle.max.value >= tradingEngine.current.position.stopLoss.value
|
||||
) ||
|
||||
(
|
||||
tradingEngine.current.position.stopLoss.stopLossPosition.value === 'Below' &&
|
||||
tradingEngine.current.episode.candle.min.value <= tradingEngine.current.position.stopLoss.value
|
||||
)
|
||||
) {
|
||||
logger.write(MODULE_NAME, '[INFO] checkStopLossOrTakeProfitWasHit -> Stop Loss was hit.')
|
||||
|
||||
tradingPositionModule.closingPosition('Stop Loss')
|
||||
changeStageStatus('Close Stage', 'Opening')
|
||||
changeStageStatus('Manage Stage', 'Closed')
|
||||
announcementsModule.makeAnnoucements(strategy.closeStage)
|
||||
|
||||
function checkStopLossOrTakeProfitWasHit() {
|
||||
{
|
||||
let strategy = tradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value]
|
||||
/*
|
||||
Checking what happened since the last execution. We need to know if the Stop Loss
|
||||
or our Take Profit were hit.
|
||||
*/
|
||||
|
||||
/* Stop Loss condition: Here we verify if the Stop Loss was hitted or not. */
|
||||
if (
|
||||
(
|
||||
tradingEngine.current.position.stopLoss.stopLossPosition.value === 'Above' &&
|
||||
tradingEngine.current.episode.candle.max.value >= tradingEngine.current.position.stopLoss.value
|
||||
) ||
|
||||
(
|
||||
tradingEngine.current.position.stopLoss.stopLossPosition.value === 'Below' &&
|
||||
tradingEngine.current.episode.candle.min.value <= tradingEngine.current.position.stopLoss.value
|
||||
)
|
||||
) {
|
||||
logger.write(MODULE_NAME, '[INFO] checkStopLossOrTakeProfitWasHit -> Stop Loss was hit.')
|
||||
|
||||
tradingPositionModule.closingPosition('Stop Loss')
|
||||
changeStageStatus('Close Stage', 'Opening')
|
||||
changeStageStatus('Manage Stage', 'Closed')
|
||||
announcementsModule.makeAnnoucements(strategy.closeStage)
|
||||
return
|
||||
}
|
||||
|
||||
/* Take Profit condition: Here we verify if the Take Profit was hit or not. */
|
||||
if (
|
||||
(
|
||||
tradingEngine.current.position.takeProfit.takeProfitPosition.value === 'Below' &&
|
||||
tradingEngine.current.episode.candle.min.value <= tradingEngine.current.position.takeProfit.value
|
||||
) ||
|
||||
(
|
||||
tradingEngine.current.position.takeProfit.takeProfitPosition.value === 'Above' &&
|
||||
tradingEngine.current.episode.candle.max.value >= tradingEngine.current.position.takeProfit.value
|
||||
)
|
||||
) {
|
||||
logger.write(MODULE_NAME, '[INFO] checkStopLossOrTakeProfitWasHit -> Take Profit was hit.')
|
||||
|
||||
tradingPositionModule.closingPosition('Take Profit')
|
||||
changeStageStatus('Close Stage', 'Opening')
|
||||
changeStageStatus('Manage Stage', 'Closed')
|
||||
announcementsModule.makeAnnoucements(strategy.closeStage)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/* Take Profit condition: Here we verify if the Take Profit was hit or not. */
|
||||
if (
|
||||
(
|
||||
tradingEngine.current.position.takeProfit.takeProfitPosition.value === 'Below' &&
|
||||
tradingEngine.current.episode.candle.min.value <= tradingEngine.current.position.takeProfit.value
|
||||
) ||
|
||||
(
|
||||
tradingEngine.current.position.takeProfit.takeProfitPosition.value === 'Above' &&
|
||||
tradingEngine.current.episode.candle.max.value >= tradingEngine.current.position.takeProfit.value
|
||||
)
|
||||
) {
|
||||
logger.write(MODULE_NAME, '[INFO] checkStopLossOrTakeProfitWasHit -> Take Profit was hit.')
|
||||
|
||||
tradingPositionModule.closingPosition('Take Profit')
|
||||
changeStageStatus('Close Stage', 'Opening')
|
||||
changeStageStatus('Manage Stage', 'Closed')
|
||||
announcementsModule.makeAnnoucements(strategy.closeStage)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -786,12 +788,12 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM
|
||||
to be known before we start placing orders at the Close Stage.
|
||||
*/
|
||||
if (
|
||||
tradingEngine.current.strategyCloseStage.status.value === 'Open' &&
|
||||
(
|
||||
tradingEngine.current.strategyOpenStage.status.value === 'Closed' ||
|
||||
tradingEngine.current.strategyOpenStage.status.value == tradingEngine.current.strategyOpenStage.status.config.initialValue
|
||||
)
|
||||
) {
|
||||
tradingEngine.current.strategyCloseStage.status.value === 'Open' &&
|
||||
(
|
||||
tradingEngine.current.strategyOpenStage.status.value === 'Closed' ||
|
||||
tradingEngine.current.strategyOpenStage.status.value == tradingEngine.current.strategyOpenStage.status.config.initialValue
|
||||
)
|
||||
) {
|
||||
/*
|
||||
This will happen as long as the Close Stage is Open.
|
||||
*/
|
||||
@@ -893,7 +895,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM
|
||||
when we see at the exchange that orders were filled.
|
||||
Note that the comparison is made with a Rounding Factor in order to avoid rounding problems.
|
||||
*/
|
||||
const ROUNDING_ERROR_CORRECTION_FACTOR = 1.001
|
||||
const ROUNDING_ERROR_CORRECTION_FACTOR = 1.001
|
||||
|
||||
switch (tradingEngineStage.stageDefinedIn.value) {
|
||||
case 'Base Asset': {
|
||||
@@ -990,35 +992,50 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM
|
||||
closeStage(stage)
|
||||
}
|
||||
|
||||
/*
|
||||
The way the begining and end of the Stages object works is as follows:
|
||||
This object begins with the last cycle, that is the current cycle diplaced
|
||||
backwards to the current candle. And it ends at the end of the last cycle.
|
||||
During mantainance, we add the time frame of the candle, since we assume it
|
||||
will survive the 2 cycles without the end being updated. If it closes,
|
||||
then we update the end to the end of the last cycle, overrinding the
|
||||
mantainance if needed. If we assume that in the same cycle there will be
|
||||
no closing and opening of the same type of object, then there can be no
|
||||
overlap.
|
||||
*/
|
||||
function openStage(stage) {
|
||||
/* Recording the opening at the Trading Engine Data Structure */
|
||||
stage.begin.value = tradingEngine.current.episode.candle.begin.value
|
||||
stage.begin.value = tradingEngine.current.episode.cycle.lastBegin.value
|
||||
stage.end.value = tradingEngine.current.episode.cycle.lastEnd.value
|
||||
stage.beginRate.value = tradingEngine.current.episode.candle.close.value
|
||||
stage.end.value = tradingEngine.current.episode.candle.begin.value
|
||||
}
|
||||
|
||||
function closeStage(stage) {
|
||||
/* Recording the closing at the Trading Engine Data Structure */
|
||||
stage.end.value = tradingEngine.current.episode.candle.begin.value
|
||||
stage.end.value = tradingEngine.current.episode.cycle.lastEnd.value
|
||||
stage.endRate.value = tradingEngine.current.episode.candle.close.value
|
||||
}
|
||||
}
|
||||
|
||||
function updateEnds() {
|
||||
/*
|
||||
Note that we can not use the cycle here because this is executed via mantain
|
||||
which in turn is executed before the first cycle for this candle is set.
|
||||
*/
|
||||
if (tradingEngine.current.strategyTriggerStage.status.value === 'Open') {
|
||||
tradingEngine.current.strategyTriggerStage.end.value = tradingEngine.current.episode.cycle.end.value
|
||||
tradingEngine.current.strategyTriggerStage.end.value = tradingEngine.current.strategyTriggerStage.end.value + sessionParameters.timeFrame.config.value
|
||||
tradingEngine.current.strategyTriggerStage.endRate.value = tradingEngine.current.episode.candle.close.value
|
||||
}
|
||||
if (tradingEngine.current.strategyOpenStage.status.value === 'Open') {
|
||||
tradingEngine.current.strategyOpenStage.end.value = tradingEngine.current.episode.cycle.end.value
|
||||
tradingEngine.current.strategyOpenStage.end.value = tradingEngine.current.strategyOpenStage.end.value + sessionParameters.timeFrame.config.value
|
||||
tradingEngine.current.strategyOpenStage.endRate.value = tradingEngine.current.episode.candle.close.value
|
||||
}
|
||||
if (tradingEngine.current.strategyManageStage.status.value === 'Open') {
|
||||
tradingEngine.current.strategyManageStage.end.value = tradingEngine.current.episode.cycle.end.value
|
||||
tradingEngine.current.strategyManageStage.end.value = tradingEngine.current.strategyManageStage.end.value + sessionParameters.timeFrame.config.value
|
||||
tradingEngine.current.strategyManageStage.endRate.value = tradingEngine.current.episode.candle.close.value
|
||||
}
|
||||
if (tradingEngine.current.strategyCloseStage.status.value === 'Open') {
|
||||
tradingEngine.current.strategyCloseStage.end.value = tradingEngine.current.episode.cycle.end.value
|
||||
tradingEngine.current.strategyCloseStage.end.value = tradingEngine.current.strategyCloseStage.end.value + sessionParameters.timeFrame.config.value
|
||||
tradingEngine.current.strategyCloseStage.endRate.value = tradingEngine.current.episode.candle.close.value
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,15 +13,18 @@ exports.newTradingStrategy = function newTradingStrategy(bot, logger, tradingEng
|
||||
}
|
||||
|
||||
let tradingEngine
|
||||
let sessionParameters
|
||||
|
||||
return thisObject
|
||||
|
||||
function initialize() {
|
||||
tradingEngine = bot.simulationState.tradingEngine
|
||||
sessionParameters = bot.SESSION.parameters
|
||||
}
|
||||
|
||||
function finalize() {
|
||||
tradingEngine = undefined
|
||||
sessionParameters = undefined
|
||||
}
|
||||
|
||||
function mantain() {
|
||||
@@ -34,11 +37,14 @@ exports.newTradingStrategy = function newTradingStrategy(bot, logger, tradingEng
|
||||
}
|
||||
|
||||
function openStrategy(index, situationName, strategyName) {
|
||||
/* Starting begin and end */
|
||||
tradingEngine.current.strategy.begin.value = tradingEngine.current.episode.cycle.lastBegin.value
|
||||
tradingEngine.current.strategy.end.value = tradingEngine.current.episode.cycle.lastEnd.value
|
||||
|
||||
/* Recording the opening at the Trading Engine Data Structure */
|
||||
tradingEngine.current.strategy.status.value = 'Open'
|
||||
tradingEngine.current.strategy.serialNumber.value = tradingEngine.current.episode.episodeCounters.strategies.value
|
||||
tradingEngine.current.strategy.identifier.value = global.UNIQUE_ID()
|
||||
tradingEngine.current.strategy.begin.value = tradingEngine.current.episode.candle.begin.value
|
||||
tradingEngine.current.strategy.end.value = tradingEngine.current.episode.candle.end.value
|
||||
tradingEngine.current.strategy.beginRate.value = tradingEngine.current.episode.candle.min.value
|
||||
|
||||
tradingEngine.current.strategy.index.value = index
|
||||
@@ -52,7 +58,7 @@ exports.newTradingStrategy = function newTradingStrategy(bot, logger, tradingEng
|
||||
function closeStrategy(exitType) {
|
||||
tradingEngine.current.strategy.status.value = 'Closed'
|
||||
tradingEngine.current.strategy.exitType.value = exitType
|
||||
tradingEngine.current.strategy.end.value = tradingEngine.current.episode.candle.begin.value
|
||||
tradingEngine.current.strategy.end.value = tradingEngine.current.episode.cycle.lastEnd.value
|
||||
tradingEngine.current.strategy.endRate.value = tradingEngine.current.episode.candle.min.value
|
||||
/*
|
||||
Now that the strategy is closed, it is the right time to move this strategy from current to last at the Trading Engine data structure.
|
||||
@@ -62,7 +68,7 @@ exports.newTradingStrategy = function newTradingStrategy(bot, logger, tradingEng
|
||||
|
||||
function updateEnds() {
|
||||
if (tradingEngine.current.strategy.status.value === 'Open') {
|
||||
tradingEngine.current.strategy.end.value = tradingEngine.current.episode.candle.end.value
|
||||
tradingEngine.current.strategy.end.value = tradingEngine.current.strategy.end.value + sessionParameters.timeFrame.config.value
|
||||
tradingEngine.current.strategy.endRate.value = tradingEngine.current.episode.candle.close.value
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user