Final Polishing Iteration done

This commit is contained in:
Luis Fernando Molina committed 2020-08-08 12:52:24 +02:00
1 parent b0add9b805
commit b312313586
13 files changed
+359 -333

No files matched your search

+33 -30
View File
@@ -5,10 +5,10 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) {
*/
const MODULE_NAME = 'Trading Engine'
let thisObject = {
mantain: mantain,
getNodeById: getNodeById,
cloneValues: cloneValues,
setCurrentCandle: setCurrentCandle,
updateDistanceToEventsCounters: updateDistanceToEventsCounters,
initialize: initialize,
finalize: finalize
}
@@ -20,15 +20,16 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) {
return thisObject
function initialize() {
/* Here we will go through all the nodes in the Trading Engine hiriarchy and apply the initial value to the value property when needed */
tradingEngine = bot.simulationState.tradingEngine
sessionParameters = bot.SESSION.parameters
if (bot.FIRST_EXECUTION === true) {
/*
Here we will go through all the nodes in the Trading Engine hiriarchy and
apply the initial value to the value property when needed
*/
initializeNode(tradingEngine)
tradingEngine.current.balance.baseAsset.value = sessionParameters.sessionBaseAsset.config.initialBalance
tradingEngine.current.balance.quotedAsset.value = sessionParameters.sessionQuotedAsset.config.initialBalance
}
}
@@ -38,19 +39,21 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) {
nodesMap = undefined
}
function mantain() {
updateDistanceToEventsCounters()
}
function getNodeById(NodeId) {
return nodesMap.get(NodeId)
}
function setCurrentCandle(candle) {
cloneValues(tradingEngine.current.candle, tradingEngine.previous.candle)
tradingEngine.current.candle.begin.value = candle.begin
tradingEngine.current.candle.end.value = candle.end
tradingEngine.current.candle.open.value = candle.open
tradingEngine.current.candle.close.value = candle.close
tradingEngine.current.candle.min.value = candle.min
tradingEngine.current.candle.max.value = candle.max
tradingEngine.current.episode.candle.begin.value = candle.begin
tradingEngine.current.episode.candle.end.value = candle.end
tradingEngine.current.episode.candle.open.value = candle.open
tradingEngine.current.episode.candle.close.value = candle.close
tradingEngine.current.episode.candle.min.value = candle.min
tradingEngine.current.episode.candle.max.value = candle.max
}
function cloneValues(originNode, destinationNode) {
@@ -143,57 +146,57 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) {
function updateDistanceToEventsCounters() {
/* Keeping Distance Counters Up-to-date while avoinding counting before the first event happens. */
if (
tradingEngine.current.distanceToEvent.triggerOn.value > 0
tradingEngine.current.episode.distanceToEvent.triggerOn.value > 0
) {
tradingEngine.current.distanceToEvent.triggerOn.value++
tradingEngine.current.episode.distanceToEvent.triggerOn.value++
}
if (
tradingEngine.current.distanceToEvent.triggerOff.value > 0
tradingEngine.current.episode.distanceToEvent.triggerOff.value > 0
) {
tradingEngine.current.distanceToEvent.triggerOff.value++
tradingEngine.current.episode.distanceToEvent.triggerOff.value++
}
if (
tradingEngine.current.distanceToEvent.takePosition.value > 0
tradingEngine.current.episode.distanceToEvent.takePosition.value > 0
) {
tradingEngine.current.distanceToEvent.takePosition.value++
tradingEngine.current.episode.distanceToEvent.takePosition.value++
}
if (
tradingEngine.current.distanceToEvent.closePosition.value > 0
tradingEngine.current.episode.distanceToEvent.closePosition.value > 0
) {
tradingEngine.current.distanceToEvent.closePosition.value++
tradingEngine.current.episode.distanceToEvent.closePosition.value++
}
if (
tradingEngine.current.distanceToEvent.nextPhase.value > 0
tradingEngine.current.episode.distanceToEvent.nextPhase.value > 0
) {
tradingEngine.current.distanceToEvent.nextPhase.value++
tradingEngine.current.episode.distanceToEvent.nextPhase.value++
}
if (
tradingEngine.current.distanceToEvent.moveToPhase.value > 0
tradingEngine.current.episode.distanceToEvent.moveToPhase.value > 0
) {
tradingEngine.current.distanceToEvent.moveToPhase.value++
tradingEngine.current.episode.distanceToEvent.moveToPhase.value++
}
if (
tradingEngine.current.distanceToEvent.createOrder.value > 0
tradingEngine.current.episode.distanceToEvent.createOrder.value > 0
) {
tradingEngine.current.distanceToEvent.createOrder.value++
tradingEngine.current.episode.distanceToEvent.createOrder.value++
}
if (
tradingEngine.current.distanceToEvent.cancelOrder.value > 0
tradingEngine.current.episode.distanceToEvent.cancelOrder.value > 0
) {
tradingEngine.current.distanceToEvent.cancelOrder.value++
tradingEngine.current.episode.distanceToEvent.cancelOrder.value++
}
if (
tradingEngine.current.distanceToEvent.closeOrder.value > 0
tradingEngine.current.episode.distanceToEvent.closeOrder.value > 0
) {
tradingEngine.current.distanceToEvent.closeOrder.value++
tradingEngine.current.episode.distanceToEvent.closeOrder.value++
}
}
@@ -4,13 +4,10 @@ exports.newTradingEpisode = function newTradingEpisode(bot, logger) {
*/
const MODULE_NAME = 'Trading Episode'
let thisObject = {
mantain: mantain,
openEpisode: openEpisode,
closingEpisode: closingEpisode,
updateExitType: updateExitType,
closeEpisode: closeEpisode,
updateEnds: updateEnds,
resetTradingEngineDataStructure: resetTradingEngineDataStructure,
updateCounters: updateCounters,
updateStatistics: updateStatistics,
calculateResults: calculateResults,
calculateStatistics: calculateStatistics,
initialize: initialize,
@@ -35,25 +32,47 @@ exports.newTradingEpisode = function newTradingEpisode(bot, logger) {
sessionParameters = undefined
}
function openEpisode() {
/* Recording the opening at the Trading Engine Data Structure */
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.candle.begin.value
tradingEngine.current.episode.beginRate.value = tradingEngine.current.candle.close.value
function mantain() {
resetTradingEngineDataStructure()
updateCounters()
updateStatistics()
updateEnds()
}
function closingEpisode(exitType) {
tradingEngine.current.episode.status.value = 'Closing'
function openEpisode() {
/*
This function is called each time the simulation starts. That does not mean the Episode
must be opened there, since it might happen that it is looping at the end of the market
or the task / session was restarted.
*/
if (bot.FIRST_EXECUTION === true) {
/* 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
/* The current balance is also the begin balance, that is how this starts. */
tradingEngine.current.episode.episodeBaseAsset.balance.value = sessionParameters.sessionBaseAsset.config.initialBalance
tradingEngine.current.episode.episodeQuotedAsset.balance.value = sessionParameters.sessionQuotedAsset.config.initialBalance
/* Recording the opening at the Trading Engine Data Structure */
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
}
}
function updateExitType(exitType) {
tradingEngine.current.episode.exitType.value = exitType
}
function closeEpisode() {
tradingEngine.current.episode.status.value = 'Closed'
tradingEngine.current.episode.end.value = tradingEngine.current.candle.end.value
tradingEngine.current.episode.endRate.value = tradingEngine.current.candle.close.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
}
function resetEpisode() {
@@ -62,8 +81,10 @@ exports.newTradingEpisode = function newTradingEpisode(bot, logger) {
function updateEnds() {
if (tradingEngine.current.episode.status.value === 'Open') {
tradingEngine.current.episode.end.value = tradingEngine.current.candle.end.value
tradingEngine.current.episode.endRate.value = tradingEngine.current.candle.close.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
}
}
@@ -92,7 +113,7 @@ exports.newTradingEpisode = function newTradingEpisode(bot, logger) {
/* Updating Profit Loss */
tradingEngine.current.episode.episodeStatistics.profitLoss.value =
tradingEngine.current.episode.episodeBaseAsset.profitLoss.value * tradingEngine.current.candle.close.value +
tradingEngine.current.episode.episodeBaseAsset.profitLoss.value * tradingEngine.current.episode.candle.close.value +
tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value
tradingEngine.current.episode.episodeStatistics.profitLoss.value = global.PRECISE(tradingEngine.current.episode.episodeStatistics.profitLoss.value, 10)
@@ -100,12 +121,12 @@ exports.newTradingEpisode = function newTradingEpisode(bot, logger) {
/* Updating ROI */
tradingEngine.current.episode.episodeStatistics.ROI.value =
(
sessionParameters.sessionBaseAsset.config.initialBalance * tradingEngine.current.candle.close.value +
tradingEngine.current.episode.episodeBaseAsset.profitLoss.value * tradingEngine.current.candle.close.value +
sessionParameters.sessionBaseAsset.config.initialBalance * tradingEngine.current.episode.candle.close.value +
tradingEngine.current.episode.episodeBaseAsset.profitLoss.value * tradingEngine.current.episode.candle.close.value +
sessionParameters.sessionQuotedAsset.config.initialBalance +
tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value
) / (
sessionParameters.sessionBaseAsset.config.initialBalance * tradingEngine.current.candle.close.value +
sessionParameters.sessionBaseAsset.config.initialBalance * tradingEngine.current.episode.candle.close.value +
sessionParameters.sessionQuotedAsset.config.initialBalance
) - 1
@@ -142,11 +163,11 @@ exports.newTradingEpisode = function newTradingEpisode(bot, logger) {
/* Updating Profit Loss */
tradingEngine.current.episode.episodeBaseAsset.profitLoss.value =
tradingEngine.current.balance.baseAsset.value -
tradingEngine.current.episode.episodeBaseAsset.balance.value -
sessionParameters.sessionBaseAsset.config.initialBalance
tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value =
tradingEngine.current.balance.quotedAsset.value -
tradingEngine.current.episode.episodeQuotedAsset.balance.value -
sessionParameters.sessionQuotedAsset.config.initialBalance
tradingEngine.current.episode.episodeBaseAsset.profitLoss.value = global.PRECISE(tradingEngine.current.episode.episodeBaseAsset.profitLoss.value, 10)
@@ -135,7 +135,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
}
case 'Open': {
/* Update this order properties */
tradingEngineOrder.end.value = tradingEngine.current.candle.end.value
tradingEngineOrder.end.value = tradingEngine.current.episode.candle.end.value
tradingEngineOrder.orderCounters.periods.value++
tradingEngineOrder.orderStatistics.days.value = tradingEngineOrder.orderCounters.periods.value * sessionParameters.timeFrame.config.value / global.ONE_DAY_IN_MILISECONDS
@@ -191,13 +191,13 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
tradingEngine.current.episode.episodeCounters.orders.value++
/* Initialize this */
tradingEngine.current.distanceToEvent.createOrder.value = 1
tradingEngine.current.episode.distanceToEvent.createOrder.value = 1
/* Create Order Procedure */
tradingEngineOrder.status.value = 'Open'
tradingEngineOrder.identifier.value = global.UNIQUE_ID()
tradingEngineOrder.begin.value = tradingEngine.current.candle.begin.value
tradingEngineOrder.end.value = tradingEngine.current.candle.end.value
tradingEngineOrder.begin.value = tradingEngine.current.episode.candle.begin.value
tradingEngineOrder.end.value = tradingEngine.current.episode.candle.end.value
tradingEngineOrder.serialNumber.value = tradingEngine.current.episode.episodeCounters.orders.value
tradingEngineOrder.orderName.value = tradingSystemOrder.name
tradingEngineOrder.algorithmName.value = executionAlgorithm.name
@@ -205,7 +205,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
function calculateOrderRate() {
/* By default this is the order rate and it is the rate that applies to Market Orders */
tradingEngineOrder.rate.value = tradingEngine.current.candle.close.value
tradingEngineOrder.rate.value = tradingEngine.current.episode.candle.close.value
/* Optional Rate Definition */
if (tradingSystemOrder.orderRate !== undefined) {
@@ -458,7 +458,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
tradingEngineOrder.exitType.value = 'Filled'
/* Initialize this */
tradingEngine.current.distanceToEvent.closeOrder.value = 1
tradingEngine.current.episode.distanceToEvent.closeOrder.value = 1
}
}
}
@@ -515,7 +515,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
tradingEngineOrder.exitType.value = 'Filled'
/* Initialize this */
tradingEngine.current.distanceToEvent.closeOrder.value = 1
tradingEngine.current.episode.distanceToEvent.closeOrder.value = 1
}
if (order.remaining > 0 && order.status === AT_EXCHANGE_STATUS.CLOSED) {
@@ -524,7 +524,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
tradingEngineOrder.exitType.value = 'Closed at the Exchange'
/* Initialize this */
tradingEngine.current.distanceToEvent.closeOrder.value = 1
tradingEngine.current.episode.distanceToEvent.closeOrder.value = 1
}
if (order.status === AT_EXCHANGE_STATUS.CANCELLED) {
@@ -533,7 +533,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
tradingEngineOrder.exitType.value = 'Cancelled at the Exchange'
/* Initialize this */
tradingEngine.current.distanceToEvent.closeOrder.value = 1
tradingEngine.current.episode.distanceToEvent.closeOrder.value = 1
}
syncWithExchange(tradingSystemOrder, tradingEngineOrder, order)
@@ -657,24 +657,24 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
case tradingSystemOrder.type === 'Market Buy Order' || tradingSystemOrder.type === 'Limit Buy Order': {
/* Balance Base Asset: Undo the previous accounting */
tradingEngine.current.balance.baseAsset.value =
tradingEngine.current.balance.baseAsset.value -
tradingEngine.current.episode.episodeBaseAsset.balance.value =
tradingEngine.current.episode.episodeBaseAsset.balance.value -
previousBaseAssetSizeFilled
/* Balance Base Asset: Account the current filling and fees */
tradingEngine.current.balance.baseAsset.value =
tradingEngine.current.balance.baseAsset.value +
tradingEngine.current.episode.episodeBaseAsset.balance.value =
tradingEngine.current.episode.episodeBaseAsset.balance.value +
tradingEngineOrder.orderBaseAsset.sizeFilled.value
/* Balance Quoted Asset: Undo the previous accounting */
tradingEngine.current.balance.quotedAsset.value =
tradingEngine.current.balance.quotedAsset.value +
tradingEngine.current.episode.episodeQuotedAsset.balance.value =
tradingEngine.current.episode.episodeQuotedAsset.balance.value +
previousQuotedAssetSizeFilled +
previousQuotedAssetFeesPaid
/* Balance Quoted Asset: Account the current filling and fees */
tradingEngine.current.balance.quotedAsset.value =
tradingEngine.current.balance.quotedAsset.value -
tradingEngine.current.episode.episodeQuotedAsset.balance.value =
tradingEngine.current.episode.episodeQuotedAsset.balance.value -
tradingEngineOrder.orderQuotedAsset.sizeFilled.value -
tradingEngineOrder.orderQuotedAsset.feesPaid.value
break
@@ -682,31 +682,31 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
case tradingSystemOrder.type === 'Market Sell Order' || tradingSystemOrder.type === 'Limit Sell Order': {
/* Balance Base Asset: Undo the previous accounting */
tradingEngine.current.balance.baseAsset.value =
tradingEngine.current.balance.baseAsset.value +
tradingEngine.current.episode.episodeBaseAsset.balance.value =
tradingEngine.current.episode.episodeBaseAsset.balance.value +
previousBaseAssetSizeFilled +
previousBaseAssetFeesPaid
/* Balance Base Asset: Account the current filling and fees */
tradingEngine.current.balance.baseAsset.value =
tradingEngine.current.balance.baseAsset.value -
tradingEngine.current.episode.episodeBaseAsset.balance.value =
tradingEngine.current.episode.episodeBaseAsset.balance.value -
tradingEngineOrder.orderBaseAsset.sizeFilled.value -
tradingEngineOrder.orderBaseAsset.feesPaid.value
/* Balance Quoted Asset: Undo the previous accounting */
tradingEngine.current.balance.quotedAsset.value =
tradingEngine.current.balance.quotedAsset.value -
tradingEngine.current.episode.episodeQuotedAsset.balance.value =
tradingEngine.current.episode.episodeQuotedAsset.balance.value -
previousQuotedAssetSizeFilled
/* Balance Quoted Asset: Account the current filling and fees */
tradingEngine.current.balance.quotedAsset.value =
tradingEngine.current.balance.quotedAsset.value +
tradingEngine.current.episode.episodeQuotedAsset.balance.value =
tradingEngine.current.episode.episodeQuotedAsset.balance.value +
tradingEngineOrder.orderQuotedAsset.sizeFilled.value
break
}
}
tradingEngine.current.balance.baseAsset.value = global.PRECISE(tradingEngine.current.balance.baseAsset.value, 10)
tradingEngine.current.balance.quotedAsset.value = global.PRECISE(tradingEngine.current.balance.quotedAsset.value, 10)
tradingEngine.current.episode.episodeBaseAsset.balance.value = global.PRECISE(tradingEngine.current.episode.episodeBaseAsset.balance.value, 10)
tradingEngine.current.episode.episodeQuotedAsset.balance.value = global.PRECISE(tradingEngine.current.episode.episodeQuotedAsset.balance.value, 10)
}
}
@@ -734,7 +734,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
tradingEngineOrder.exitType.value = exitType
/* Initialize this */
tradingEngine.current.distanceToEvent.closeOrder.value = 1
tradingEngine.current.episode.distanceToEvent.closeOrder.value = 1
recalculateStageSize(tradingEngineOrder)
}
@@ -765,7 +765,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
tradingEngineOrder.exitType.value = exitType
/* Initialize this */
tradingEngine.current.distanceToEvent.closeOrder.value = 1
tradingEngine.current.episode.distanceToEvent.closeOrder.value = 1
/*
Perhaps the order was filled a bit more between the last time we checked and when it was cancelled.
@@ -4,6 +4,7 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
*/
const MODULE_NAME = 'Trading Position'
let thisObject = {
mantain: mantain,
openPosition: openPosition,
closingPosition: closingPosition,
closePosition: closePosition,
@@ -15,7 +16,6 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
updateEnds: updateEnds,
resetTradingEngineDataStructure: resetTradingEngineDataStructure,
updateCounters: updateCounters,
resetPosition: resetPosition,
initialize: initialize,
finalize: finalize
}
@@ -38,14 +38,22 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
sessionParameters = undefined
}
function mantain() {
resetTradingEngineDataStructure()
updateCounters()
updateEnds()
}
function openPosition(situationName) {
/* 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
tradingEngine.current.position.identifier.value = global.UNIQUE_ID()
tradingEngine.current.position.begin.value = tradingEngine.current.candle.begin.value
tradingEngine.current.position.beginRate.value = tradingEngine.current.candle.close.value
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
tradingEngine.current.position.situationName.value = situationName
/* Initializing Stop and Take Profit Stage / Phase */
@@ -58,7 +66,7 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
tradingEngine.current.episode.episodeCounters.positions.value++
/* Inicializing this counter */
tradingEngine.current.distanceToEvent.takePosition.value = 1
tradingEngine.current.episode.distanceToEvent.takePosition.value = 1
}
function closingPosition(exitType) {
@@ -68,8 +76,10 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
function closePosition() {
tradingEngine.current.position.status.value = 'Closed'
tradingEngine.current.position.end.value = tradingEngine.current.candle.end.value
tradingEngine.current.position.endRate.value = tradingEngine.current.candle.close.value
tradingEngine.current.position.end.value = tradingEngine.current.episode.candle.end.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
/* Position Statistics & Results */
updateStatistics()
@@ -80,10 +90,6 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
tradingEngineModule.cloneValues(tradingEngine.current.position, tradingEngine.last.position)
}
function resetPosition() {
tradingEngine.current.position.initialize(tradingEngine.current.position)
}
function applyStopLossFormula(formulas, formulaId) {
tradingEngine.current.position.stopLoss.value = formulas.get(formulaId)
}
@@ -223,14 +229,16 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
function updateEnds() {
if (tradingEngine.current.position.status.value === 'Open') {
tradingEngine.current.position.end.value = tradingEngine.current.candle.end.value
tradingEngine.current.position.endRate.value = tradingEngine.current.candle.close.value
tradingEngine.current.position.end.value = tradingEngine.current.episode.candle.end.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
}
}
function resetTradingEngineDataStructure() {
if (tradingEngine.current.position.status.value === 'Closed') {
resetPosition()
tradingEngine.current.position.initialize(tradingEngine.current.position)
}
}
@@ -245,12 +253,12 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
/* Profit Loss Calculation */
tradingEngine.current.position.positionStatistics.profitLoss.value =
(
tradingEngine.current.balance.baseAsset.value * tradingEngine.current.position.endRate.value +
tradingEngine.current.balance.quotedAsset.value
tradingEngine.current.episode.episodeBaseAsset.balance.value * tradingEngine.current.position.endRate.value +
tradingEngine.current.episode.episodeQuotedAsset.balance.value
) -
(
tradingEngine.previous.balance.baseAsset.value * tradingEngine.current.position.beginRate.value +
tradingEngine.previous.balance.quotedAsset.value
tradingEngine.current.position.positionBaseAsset.beginBalance * tradingEngine.current.position.beginRate.value +
tradingEngine.current.position.positionQuotedAsset.beginBalance
)
tradingEngine.current.position.positionStatistics.profitLoss.value = global.PRECISE(tradingEngine.current.position.positionStatistics.profitLoss.value, 10)
@@ -261,8 +269,8 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
)
* 100 /
(
tradingEngine.previous.balance.baseAsset.value * tradingEngine.current.position.beginRate.value +
tradingEngine.previous.balance.quotedAsset.value
tradingEngine.current.position.positionBaseAsset.beginBalance * tradingEngine.current.position.beginRate.value +
tradingEngine.current.position.positionQuotedAsset.beginBalance
)
tradingEngine.current.position.positionStatistics.ROI.value = global.PRECISE(tradingEngine.current.position.positionStatistics.ROI.value, 10)
@@ -284,12 +292,12 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
function updateResults() {
/* Profit Loss Calculation */
tradingEngine.current.position.positionBaseAsset.profitLoss.value =
tradingEngine.current.balance.baseAsset.value -
tradingEngine.previous.balance.baseAsset.value
tradingEngine.current.episode.episodeBaseAsset.balance.value -
tradingEngine.current.position.positionBaseAsset.beginBalance
tradingEngine.current.position.positionQuotedAsset.profitLoss.value =
tradingEngine.current.balance.quotedAsset.value -
tradingEngine.previous.balance.quotedAsset.value
tradingEngine.current.episode.episodeQuotedAsset.balance.value -
tradingEngine.current.position.positionQuotedAsset.beginBalance
tradingEngine.current.position.positionBaseAsset.profitLoss.value = global.PRECISE(tradingEngine.current.position.positionBaseAsset.profitLoss.value, 10)
tradingEngine.current.position.positionQuotedAsset.profitLoss.value = global.PRECISE(tradingEngine.current.position.positionQuotedAsset.profitLoss.value, 10)
@@ -219,8 +219,8 @@ exports.newTradingRecords = function newTradingRecords(bot, logger) {
of the day? Easy: the end of the candle must be 1 millisecod before the next day. That happens at any
time frame.
*/
let currentDay = new Date(tradingEngine.current.candle.end.value)
let nextDay = new Date(tradingEngine.current.candle.end.value + 1)
let currentDay = new Date(tradingEngine.current.episode.candle.end.value)
let nextDay = new Date(tradingEngine.current.episode.candle.end.value + 1)
if (currentDay.getUTCDate() !== nextDay.getUTCDate()) {
/*
We will save the object only if it is closed, becasuse we are at the last candle of the day.
@@ -302,7 +302,7 @@ exports.newTradingRecords = function newTradingRecords(bot, logger) {
let recordProperty = product.record.properties[j]
if (recordProperty.config.codeName === 'end') {
let end = record[j]
if (end >= tradingEngine.current.candle.end.value) {
if (end >= tradingEngine.current.episode.candle.end.value) {
outputFile.splice(i, 1)
pruneOutputFile(product, outputFile)
return
@@ -69,10 +69,10 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
let diff = lastBegin - firstBegin
let amount = diff / sessionParameters.timeFrame.config.value
tradingEngine.current.candle.index.value = Math.trunc(amount) + 1 // Because we need to start from the next candle
if (tradingEngine.current.candle.index.value < 0 || tradingEngine.current.candle.index.value > candles.length - 1) {
tradingEngine.current.episode.candle.index.value = Math.trunc(amount) + 1 // Because we need to start from the next candle
if (tradingEngine.current.episode.candle.index.value < 0 || tradingEngine.current.episode.candle.index.value > candles.length - 1) {
logger.write(MODULE_NAME, '[ERROR] runSimulation -> initializeLoop -> Cannot resume simulation.')
logger.write(MODULE_NAME, '[ERROR] runSimulation -> initializeLoop -> tradingEngine.current.candle.index.value = ' + tradingEngine.current.candle.index.value)
logger.write(MODULE_NAME, '[ERROR] runSimulation -> initializeLoop -> tradingEngine.current.episode.candle.index.value = ' + tradingEngine.current.episode.candle.index.value)
logger.write(MODULE_NAME, '[ERROR] runSimulation -> initializeLoop -> firstBegin = ' + firstBegin)
logger.write(MODULE_NAME, '[ERROR] runSimulation -> initializeLoop -> lastBegin = ' + lastBegin)
logger.write(MODULE_NAME, '[ERROR] runSimulation -> initializeLoop -> diff = ' + diff)
@@ -88,14 +88,14 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
let diff = targetEnd - firstEnd
let amount = diff / sessionParameters.timeFrame.config.value
tradingEngine.current.candle.index.value = Math.trunc(amount)
if (tradingEngine.current.candle.index.value < 0) { tradingEngine.current.candle.index.value = 0 }
if (tradingEngine.current.candle.index.value > candles.length - 1) {
tradingEngine.current.episode.candle.index.value = Math.trunc(amount)
if (tradingEngine.current.episode.candle.index.value < 0) { tradingEngine.current.episode.candle.index.value = 0 }
if (tradingEngine.current.episode.candle.index.value > candles.length - 1) {
/*
This will happen when the sessionParameters.timeRange.config.initialDatetime is beyond the last candle available,
meaning that the dataSet needs to be updated with more up-to-date data.
*/
tradingEngine.current.candle.index.value = candles.length - 1
tradingEngine.current.episode.candle.index.value = candles.length - 1
}
}
@@ -103,8 +103,8 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
}
async function loop() {
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> Processing candle # ' + tradingEngine.current.candle.index.value) }
let candle = candles[tradingEngine.current.candle.index.value] // This is the current candle the Simulation is working at.
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> Processing candle # ' + tradingEngine.current.episode.candle.index.value) }
let candle = candles[tradingEngine.current.episode.candle.index.value] // This is the current candle the Simulation is working at.
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> Candle Begin @ ' + (new Date(candle.begin)).toLocaleString()) }
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> Candle End @ ' + (new Date(candle.end)).toLocaleString()) }
@@ -140,11 +140,11 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
/* Do the stuff needed previous to the run */
tradingSystemModule.mantain()
/* Episode Counters and Statistics */
tradingEpisodeModule.updateCounters()
tradingEpisodeModule.updateStatistics()
/* Episode Counters and Statistics update */
tradingEpisodeModule.mantain()
tradingEngineModule.updateDistanceToEventsCounters()
/* Run your maintaince procedure */
tradingEngineModule.mantain()
/* Run one cycle of the Trading System*/
await tradingSystemModule.run()
@@ -157,23 +157,23 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
if (bot.STOP_SESSION === true) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> controlLoop -> We are going to stop here bacause we were requested to stop processing this session.') }
console.log('[INFO] runSimulation -> controlLoop -> We are going to stop here bacause we were requested to stop processing this session.')
closeEpisode('Session Stopped')
updateEpisode('Session Stopped')
return
}
if (global.STOP_TASK_GRACEFULLY === true) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> controlLoop -> We are going to stop here bacause we were requested to stop processing this task.') }
console.log('[INFO] runSimulation -> controlLoop -> We are going to stop here bacause we were requested to stop processing this task.')
closeEpisode('Task Stopped')
updateEpisode('Task Stopped')
return
}
if (tradingEngine.current.candle.index.value + 1 < candles.length) {
if (tradingEngine.current.episode.candle.index.value + 1 < candles.length) {
/* Add new records to the process output */
tradingRecordsModule.appendRecords()
tradingEngine.current.candle.index.value++
tradingEngine.current.episode.candle.index.value++
setImmediate(loop) // This will execute the next loop in the next iteration of the NodeJs event loop allowing for other callbacks to be executed.
} else {
@@ -182,7 +182,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
}
function closeEpisode(exitType) {
tradingEpisodeModule.closingEpisode(exitType)
tradingEpisodeModule.updateExitType(exitType)
tradingEpisodeModule.closeEpisode()
/* Add new records to the process output */
@@ -191,6 +191,15 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
afterLoop()
}
function updateEpisode(exitType) {
tradingEpisodeModule.updateExitType(exitType)
/* Add new records to the process output */
tradingRecordsModule.appendRecords()
afterLoop()
}
function afterLoop() {
tradingEngineModule.finalize()
@@ -208,11 +217,11 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
function heartBeat() {
/* We will produce a simulation level heartbeat in order to inform the user this is running. */
heartBeatDate = new Date(Math.trunc(tradingEngine.current.candle.begin.value / global.ONE_DAY_IN_MILISECONDS) * global.ONE_DAY_IN_MILISECONDS)
heartBeatDate = new Date(Math.trunc(tradingEngine.current.episode.candle.begin.value / global.ONE_DAY_IN_MILISECONDS) * global.ONE_DAY_IN_MILISECONDS)
if (heartBeatDate.valueOf() !== previousHeartBeatDate) {
let processingDate = heartBeatDate.getUTCFullYear() + '-' + utilities.pad(heartBeatDate.getUTCMonth() + 1, 2) + '-' + utilities.pad(heartBeatDate.getUTCDate(), 2)
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> Simulation ' + bot.sessionKey + ' Loop # ' + tradingEngine.current.candle.index.value + ' @ ' + processingDate) }
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> Simulation ' + bot.sessionKey + ' Loop # ' + tradingEngine.current.episode.candle.index.value + ' @ ' + processingDate) }
/* Telling the world we are alive and doing well */
let fromDate = new Date(sessionParameters.timeRange.config.initialDatetime)
@@ -305,15 +314,15 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
for (let i = 0; i < pArray.length; i++) {
element = pArray[i]
if (tradingEngine.current.candle.end.value === element.end) { // when there is an exact match at the end we take that element
if (tradingEngine.current.episode.candle.end.value === element.end) { // when there is an exact match at the end we take that element
return element
} else {
if (
i > 0 &&
element.end > tradingEngine.current.candle.end.value
element.end > tradingEngine.current.episode.candle.end.value
) {
let previousElement = pArray[i - 1]
if (previousElement.end < tradingEngine.current.candle.end.value) {
if (previousElement.end < tradingEngine.current.episode.candle.end.value) {
return previousElement // If one elements goes into the future of currentCandle, then we stop and take the previous element.
} else {
return
@@ -336,7 +345,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
*/
if (bot.processingDailyFiles) { // We are processing Daily Files
let candlesPerDay = global.ONE_DAY_IN_MILISECONDS / sessionParameters.timeFrame.config.value
if (tradingEngine.current.candle.index.value === candles.length - 1) {
if (tradingEngine.current.episode.candle.index.value === candles.length - 1) {
if ((candles.length < candlesPerDay) || (candles.length > candlesPerDay && candles.length < candlesPerDay * 2)) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> checkLastCandle -> Skipping Candle because it is the last one and has not been closed yet.') }
return false
@@ -347,7 +356,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
}
}
} else { // We are processing Market Files
if (tradingEngine.current.candle.index.value === candles.length - 1) {
if (tradingEngine.current.episode.candle.index.value === candles.length - 1) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> checkLastCandle -> Skipping Candle because it is the last one and has not been closed yet.') }
return false
}
@@ -357,11 +366,11 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
function checkInitialAndFinalDatetime() {
/* Here we check that the current candle is not outside of user-defined time range at the session parameters.*/
if (tradingEngine.current.candle.end.value < sessionParameters.timeRange.config.initialDatetime) {
if (tradingEngine.current.episode.candle.end.value < sessionParameters.timeRange.config.initialDatetime) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> checkInitialAndFinalDatetime -> Skipping Candle before the sessionParameters.timeRange.config.initialDatetime.') }
return false
}
if (tradingEngine.current.candle.begin.value > sessionParameters.timeRange.config.finalDatetime) {
if (tradingEngine.current.episode.candle.begin.value > sessionParameters.timeRange.config.finalDatetime) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> checkInitialAndFinalDatetime -> Skipping Candle after the sessionParameters.timeRange.config.finalDatetime.') }
return false
}
@@ -378,10 +387,10 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
because there the balances have shifted from their resting position.
*/
let stopRunningDate = (new Date(tradingEngine.current.candle.begin.value)).toLocaleString()
let stopRunningDate = (new Date(tradingEngine.current.episode.candle.begin.value)).toLocaleString()
if (sessionParameters.sessionBaseAsset.config.minimumBalance !== undefined) {
if (tradingEngine.current.balance.baseAsset.value <= sessionParameters.sessionBaseAsset.config.minimumBalance) {
if (tradingEngine.current.episode.episodeBaseAsset.balance.value <= sessionParameters.sessionBaseAsset.config.minimumBalance) {
const errorMessage = 'Min Balance reached @ ' + stopRunningDate
tradingSystem.errors.push([tradingSystem.id, errorMessage])
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[WARN] runSimulation -> checkMinimunAndMaximunBalance -> ' + errorMessage) }
@@ -390,7 +399,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
}
if (sessionParameters.sessionBaseAsset.config.maximumBalance !== undefined) {
if (tradingEngine.current.balance.baseAsset.value >= sessionParameters.sessionBaseAsset.config.maximumBalance) {
if (tradingEngine.current.episode.episodeBaseAsset.balance.value >= sessionParameters.sessionBaseAsset.config.maximumBalance) {
const errorMessage = 'Max Balance reached @ ' + stopRunningDate
tradingSystem.errors.push([tradingSystem.id, errorMessage])
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[WARN] runSimulation -> checkMinimunAndMaximunBalance -> ' + errorMessage) }
@@ -399,7 +408,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
}
if (sessionParameters.sessionQuotedAsset.config.minimumBalance !== undefined) {
if (tradingEngine.current.balance.quotedAsset.value <= sessionParameters.sessionQuotedAsset.config.minimumBalance) {
if (tradingEngine.current.episode.episodeQuotedAsset.balance.value <= sessionParameters.sessionQuotedAsset.config.minimumBalance) {
const errorMessage = 'Min Balance reached @ ' + stopRunningDate
tradingSystem.errors.push([tradingSystem.id, errorMessage])
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[WARN] runSimulation -> checkMinimunAndMaximunBalance -> ' + errorMessage) }
@@ -408,7 +417,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
}
if (sessionParameters.sessionQuotedAsset.config.maximumBalance !== undefined) {
if (tradingEngine.current.balance.quotedAsset.value >= sessionParameters.sessionQuotedAsset.config.maximumBalance) {
if (tradingEngine.current.episode.episodeQuotedAsset.balance.value >= sessionParameters.sessionQuotedAsset.config.maximumBalance) {
const errorMessage = 'Max Balance reached @ ' + stopRunningDate
tradingSystem.errors.push([tradingSystem.id, errorMessage])
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[WARN] runSimulation -> checkMinimunAndMaximunBalance -> ' + errorMessage) }
+29 -38
View File
@@ -14,7 +14,6 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM
resetTradingEngineDataStructure: resetTradingEngineDataStructure,
updateCounters: updateCounters,
updateStatistics: updateStatistics,
resetStage: resetStage,
initialize: initialize,
finalize: finalize
}
@@ -85,29 +84,17 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM
}
function mantain() {
mantainPositions()
mantainStrategies()
tradingPositionModule.mantain()
tradingStrategyModule.mantain()
mantainStages()
mantainOrders()
function mantainStrategies() {
tradingStrategyModule.resetTradingEngineDataStructure()
tradingStrategyModule.updateCounters()
tradingStrategyModule.updateEnds()
}
function mantainStages() {
resetTradingEngineDataStructure()
updateCounters()
updateEnds()
}
function mantainPositions() {
tradingPositionModule.resetTradingEngineDataStructure()
tradingPositionModule.updateCounters()
tradingPositionModule.updateEnds()
}
function mantainOrders() {
/* Reset All Exchange Orders that are on Closed status, to their initial value */
if (tradingEngine.current.strategy.index.value === tradingEngine.current.strategy.index.config.initialValue) { return }
@@ -209,7 +196,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM
tradingStrategyModule.openStrategy(j, situation.name, strategy.name)
/* Initialize this */
tradingEngine.current.distanceToEvent.triggerOn.value = 1
tradingEngine.current.episode.distanceToEvent.triggerOn.value = 1
announcementsModule.makeAnnoucements(triggerStage.triggerOn)
announcementsModule.makeAnnoucements(triggerStage)
@@ -256,7 +243,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM
tradingSystem.highlights.push(triggerStage.triggerOff.id)
tradingSystem.highlights.push(triggerStage.id)
tradingEngine.current.distanceToEvent.triggerOff.value = 1
tradingEngine.current.episode.distanceToEvent.triggerOff.value = 1
announcementsModule.makeAnnoucements(triggerStage.triggerOff)
changeStageStatus('Trigger Stage', 'Closed')
tradingStrategyModule.closeStrategy('Trigger Off')
@@ -343,8 +330,8 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM
tradingSystem.evalFormulas(stageNode, 'Initial Definition')
/* Remember the balance we had before taking the position to later calculate profit or loss */
tradingEngine.previous.balance.baseAsset.value = tradingEngine.current.balance.baseAsset.value
tradingEngine.previous.balance.quotedAsset.value = tradingEngine.current.balance.quotedAsset.value
tradingEngine.current.position.positionBaseAsset.beginBalance = tradingEngine.current.episode.episodeBaseAsset.balance.value
tradingEngine.current.position.positionQuotedAsset.beginBalance = tradingEngine.current.episode.episodeQuotedAsset.balance.value
/* Entry Position size and rate */
tradingSystem.evalFormulas(stageNode, 'Initial Targets')
@@ -839,11 +826,11 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM
if (
(
tradingEngine.current.position.stopLoss.stopLossPosition.value === 'Above' &&
tradingEngine.current.candle.max.value >= tradingEngine.current.position.stopLoss.value
tradingEngine.current.episode.candle.max.value >= tradingEngine.current.position.stopLoss.value
) ||
(
tradingEngine.current.position.stopLoss.stopLossPosition.value === 'Below' &&
tradingEngine.current.candle.min.value <= tradingEngine.current.position.stopLoss.value
tradingEngine.current.episode.candle.min.value <= tradingEngine.current.position.stopLoss.value
)
) {
logger.write(MODULE_NAME, '[INFO] checkStopLossOrTakeProfitWasHit -> Stop Loss was hit.')
@@ -859,11 +846,11 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM
if (
(
tradingEngine.current.position.takeProfit.takeProfitPosition.value === 'Below' &&
tradingEngine.current.candle.min.value <= tradingEngine.current.position.takeProfit.value
tradingEngine.current.episode.candle.min.value <= tradingEngine.current.position.takeProfit.value
) ||
(
tradingEngine.current.position.takeProfit.takeProfitPosition.value === 'Above' &&
tradingEngine.current.candle.max.value >= tradingEngine.current.position.takeProfit.value
tradingEngine.current.episode.candle.max.value >= tradingEngine.current.position.takeProfit.value
)
) {
logger.write(MODULE_NAME, '[INFO] checkStopLossOrTakeProfitWasHit -> Take Profit was hit.')
@@ -1023,8 +1010,8 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM
tradingStrategyModule.closeStrategy('Position Closed')
/* Distance to Events Updates */
tradingEngine.current.distanceToEvent.closePosition.value = 1
tradingEngine.current.distanceToEvent.triggerOff.value = 1
tradingEngine.current.episode.distanceToEvent.closePosition.value = 1
tradingEngine.current.episode.distanceToEvent.triggerOff.value = 1
}
}
@@ -1089,34 +1076,34 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM
function openStage(stage) {
/* Recording the opening at the Trading Engine Data Structure */
stage.begin.value = tradingEngine.current.candle.begin.value
stage.beginRate.value = tradingEngine.current.candle.close.value
stage.end.value = tradingEngine.current.candle.end.value
stage.begin.value = tradingEngine.current.episode.candle.begin.value
stage.beginRate.value = tradingEngine.current.episode.candle.close.value
stage.end.value = tradingEngine.current.episode.candle.end.value
}
function closeStage(stage) {
/* Recording the closing at the Trading Engine Data Structure */
stage.end.value = tradingEngine.current.candle.end.value
stage.endRate.value = tradingEngine.current.candle.close.value
stage.end.value = tradingEngine.current.episode.candle.end.value
stage.endRate.value = tradingEngine.current.episode.candle.close.value
}
}
function resetStage(stage) {
stage.initialize(stage)
}
function updateEnds() {
if (tradingEngine.current.strategyTriggerStage.status.value === 'Open') {
tradingEngine.current.strategyTriggerStage.end.value = tradingEngine.current.candle.end.value
tradingEngine.current.strategyTriggerStage.end.value = tradingEngine.current.episode.candle.end.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.candle.end.value
tradingEngine.current.strategyOpenStage.end.value = tradingEngine.current.episode.candle.end.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.candle.end.value
tradingEngine.current.strategyManageStage.end.value = tradingEngine.current.episode.candle.end.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.candle.end.value
tradingEngine.current.strategyCloseStage.end.value = tradingEngine.current.episode.candle.end.value
tradingEngine.current.strategyCloseStage.endRate.value = tradingEngine.current.episode.candle.close.value
}
}
@@ -1136,6 +1123,10 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM
resetStage(tradingEngine.current.strategyManageStage)
resetStage(tradingEngine.current.strategyCloseStage)
}
function resetStage(stage) {
stage.initialize(stage)
}
}
function updateCounters() {
@@ -4,12 +4,9 @@ exports.newTradingStrategy = function newTradingStrategy(bot, logger, tradingEng
*/
const MODULE_NAME = 'Trading Strategy'
let thisObject = {
mantain: mantain,
openStrategy: openStrategy,
closeStrategy: closeStrategy,
updateEnds: updateEnds,
resetTradingEngineDataStructure: resetTradingEngineDataStructure,
updateCounters: updateCounters,
resetStrategy: resetStrategy,
initialize: initialize,
finalize: finalize
}
@@ -26,13 +23,19 @@ exports.newTradingStrategy = function newTradingStrategy(bot, logger, tradingEng
tradingEngine = undefined
}
function mantain() {
resetTradingEngineDataStructure()
updateCounters()
updateEnds()
}
function openStrategy(index, situationName, strategyName) {
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.candle.begin.value
tradingEngine.current.strategy.end.value = tradingEngine.current.candle.end.value
tradingEngine.current.strategy.beginRate.value = tradingEngine.current.candle.min.value
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
tradingEngine.current.strategy.situationName.value = situationName
@@ -45,28 +48,24 @@ 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.candle.end.value
tradingEngine.current.strategy.endRate.value = tradingEngine.current.candle.min.value
tradingEngine.current.strategy.end.value = tradingEngine.current.episode.candle.end.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.
*/
tradingEngineModule.cloneValues(tradingEngine.current.strategy, tradingEngine.last.strategy)
}
function resetStrategy() {
tradingEngine.current.strategy.initialize(tradingEngine.current.strategy)
}
function updateEnds() {
if (tradingEngine.current.strategy.status.value === 'Open') {
tradingEngine.current.strategy.end.value = tradingEngine.current.candle.end.value
tradingEngine.current.strategy.endRate.value = tradingEngine.current.candle.close.value
tradingEngine.current.strategy.end.value = tradingEngine.current.episode.candle.end.value
tradingEngine.current.strategy.endRate.value = tradingEngine.current.episode.candle.close.value
}
}
function resetTradingEngineDataStructure() {
if (tradingEngine.current.strategy.status.value === 'Closed') {
resetStrategy()
tradingEngine.current.strategy.initialize(tradingEngine.current.strategy)
}
}