203 lines
9.6 KiB
JavaScript
203 lines
9.6 KiB
JavaScript
exports.newTradingEpisode = function newTradingEpisode(bot, logger) {
|
|
/*
|
|
This module packages all functions related to Episodes.
|
|
*/
|
|
const MODULE_NAME = 'Trading Episode'
|
|
let thisObject = {
|
|
openEpisode: openEpisode,
|
|
closingEpisode: closingEpisode,
|
|
closeEpisode: closeEpisode,
|
|
updateEnds: updateEnds,
|
|
resetTradingEngineDataStructure: resetTradingEngineDataStructure,
|
|
updateCounters: updateCounters,
|
|
updateStatistics: updateStatistics,
|
|
calculateResults: calculateResults,
|
|
calculateStatistics: calculateStatistics,
|
|
initialize: initialize,
|
|
finalize: finalize
|
|
}
|
|
|
|
let tradingEngine
|
|
let tradingSystem
|
|
let sessionParameters
|
|
|
|
return thisObject
|
|
|
|
function initialize() {
|
|
tradingSystem = bot.simulationState.tradingSystem
|
|
tradingEngine = bot.simulationState.tradingEngine
|
|
sessionParameters = bot.SESSION.parameters
|
|
}
|
|
|
|
function finalize() {
|
|
tradingEngine = undefined
|
|
tradingSystem = undefined
|
|
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 closingEpisode(exitType) {
|
|
tradingEngine.current.episode.status.value = 'Closing'
|
|
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
|
|
}
|
|
|
|
function resetEpisode() {
|
|
tradingEngine.current.episode.initialize(tradingEngine.current.episode)
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|
|
|
|
function resetTradingEngineDataStructure() {
|
|
if (tradingEngine.current.episode.status.value === 'Closed') {
|
|
resetEpisode()
|
|
}
|
|
}
|
|
|
|
function updateCounters() {
|
|
if (tradingEngine.current.episode.status.value === 'Open') {
|
|
tradingEngine.current.episode.episodeCounters.periods.value++
|
|
}
|
|
}
|
|
|
|
function updateStatistics() {
|
|
|
|
/* Daus Calculation */
|
|
tradingEngine.current.episode.episodeStatistics.days.value =
|
|
tradingEngine.current.episode.episodeCounters.periods.value *
|
|
sessionParameters.timeFrame.config.value /
|
|
global.ONE_DAY_IN_MILISECONDS
|
|
}
|
|
|
|
function calculateStatistics() {
|
|
|
|
/* Updating Profit Loss */
|
|
tradingEngine.current.episode.episodeStatistics.profitLoss.value =
|
|
tradingEngine.current.episode.episodeBaseAsset.profitLoss.value * tradingEngine.current.candle.close.value +
|
|
tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value
|
|
|
|
tradingEngine.current.episode.episodeStatistics.profitLoss.value = global.PRECISE(tradingEngine.current.episode.episodeStatistics.profitLoss.value, 10)
|
|
|
|
/* 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.sessionQuotedAsset.config.initialBalance +
|
|
tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value
|
|
) / (
|
|
sessionParameters.sessionBaseAsset.config.initialBalance * tradingEngine.current.candle.close.value +
|
|
sessionParameters.sessionQuotedAsset.config.initialBalance
|
|
) - 1
|
|
|
|
tradingEngine.current.episode.episodeStatistics.ROI.value = global.PRECISE(tradingEngine.current.episode.episodeStatistics.ROI.value, 10)
|
|
|
|
/* Updating Anualized Rate Of Return */
|
|
tradingEngine.current.episode.episodeStatistics.anualizedRateOfReturn.value =
|
|
tradingEngine.current.episode.episodeStatistics.ROI.value /
|
|
tradingEngine.current.episode.episodeStatistics.days.value * 365
|
|
|
|
tradingEngine.current.episode.episodeStatistics.anualizedRateOfReturn.value = global.PRECISE(tradingEngine.current.episode.episodeStatistics.anualizedRateOfReturn.value, 10)
|
|
|
|
/* Updating Hit or Fail */
|
|
if (tradingEngine.current.episode.episodeStatistics.profitLoss.value > 0) {
|
|
tradingEngine.current.episode.episodeStatistics.hitFail.value = 'Hit'
|
|
} else {
|
|
tradingEngine.current.episode.episodeStatistics.hitFail.value = 'Fail'
|
|
}
|
|
}
|
|
|
|
function calculateResults() {
|
|
|
|
/* Updating Hits & Fails */
|
|
if (tradingEngine.current.position.positionBaseAsset.profitLoss.value > 0) {
|
|
tradingEngine.current.episode.episodeBaseAsset.hits.value++
|
|
} else {
|
|
tradingEngine.current.episode.episodeBaseAsset.fails.value++
|
|
}
|
|
if (tradingEngine.current.position.positionQuotedAsset.profitLoss.value > 0) {
|
|
tradingEngine.current.episode.episodeQuotedAsset.hits.value++
|
|
} else {
|
|
tradingEngine.current.episode.episodeQuotedAsset.fails.value++
|
|
}
|
|
|
|
/* Updating Profit Loss */
|
|
tradingEngine.current.episode.episodeBaseAsset.profitLoss.value =
|
|
tradingEngine.current.balance.baseAsset.value -
|
|
sessionParameters.sessionBaseAsset.config.initialBalance
|
|
|
|
tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value =
|
|
tradingEngine.current.balance.quotedAsset.value -
|
|
sessionParameters.sessionQuotedAsset.config.initialBalance
|
|
|
|
tradingEngine.current.episode.episodeBaseAsset.profitLoss.value = global.PRECISE(tradingEngine.current.episode.episodeBaseAsset.profitLoss.value, 10)
|
|
tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value = global.PRECISE(tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value, 10)
|
|
|
|
/* Updating ROI */
|
|
tradingEngine.current.episode.episodeBaseAsset.ROI.value =
|
|
(sessionParameters.sessionBaseAsset.config.initialBalance + tradingEngine.current.episode.episodeBaseAsset.profitLoss.value) /
|
|
sessionParameters.sessionBaseAsset.config.initialBalance - 1
|
|
|
|
tradingEngine.current.episode.episodeQuotedAsset.ROI.value =
|
|
(sessionParameters.sessionQuotedAsset.config.initialBalance + tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value) /
|
|
sessionParameters.sessionQuotedAsset.config.initialBalance - 1
|
|
|
|
tradingEngine.current.episode.episodeBaseAsset.ROI.value = global.PRECISE(tradingEngine.current.episode.episodeBaseAsset.ROI.value, 10)
|
|
tradingEngine.current.episode.episodeQuotedAsset.ROI.value = global.PRECISE(tradingEngine.current.episode.episodeQuotedAsset.ROI.value, 10)
|
|
|
|
/* Updating Hit Ratio */
|
|
tradingEngine.current.episode.episodeBaseAsset.hitRatio.value =
|
|
tradingEngine.current.episode.episodeBaseAsset.hits.value /
|
|
tradingEngine.current.episode.episodeCounters.positions.value
|
|
|
|
tradingEngine.current.episode.episodeQuotedAsset.hitRatio.value =
|
|
tradingEngine.current.episode.episodeQuotedAsset.hits.value /
|
|
tradingEngine.current.episode.episodeCounters.positions.value
|
|
|
|
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 Anualized Rate Of Return */
|
|
tradingEngine.current.episode.episodeBaseAsset.anualizedRateOfReturn.value =
|
|
tradingEngine.current.episode.episodeBaseAsset.ROI.value /
|
|
tradingEngine.current.episode.episodeStatistics.days.value * 365
|
|
|
|
tradingEngine.current.episode.episodeQuotedAsset.anualizedRateOfReturn.value =
|
|
tradingEngine.current.episode.episodeQuotedAsset.ROI.value /
|
|
tradingEngine.current.episode.episodeStatistics.days.value * 365
|
|
|
|
tradingEngine.current.episode.episodeBaseAsset.anualizedRateOfReturn.value = global.PRECISE(tradingEngine.current.episode.episodeBaseAsset.anualizedRateOfReturn.value, 10)
|
|
tradingEngine.current.episode.episodeQuotedAsset.anualizedRateOfReturn.value = global.PRECISE(tradingEngine.current.episode.episodeQuotedAsset.anualizedRateOfReturn.value, 10)
|
|
|
|
/* Updating Hit or Fail */
|
|
if (tradingEngine.current.episode.episodeBaseAsset.profitLoss.value > 0) {
|
|
tradingEngine.current.episode.episodeBaseAsset.hitFail.value = 'Hit'
|
|
} else {
|
|
tradingEngine.current.episode.episodeBaseAsset.hitFail.value = 'Fail'
|
|
}
|
|
if (tradingEngine.current.episode.episodeQuotedAsset.profitLoss.value > 0) {
|
|
tradingEngine.current.episode.episodeQuotedAsset.hitFail.value = 'Hit'
|
|
} else {
|
|
tradingEngine.current.episode.episodeQuotedAsset.hitFail.value = 'Fail'
|
|
}
|
|
}
|
|
} |