Fixed Transaction Records

This commit is contained in:
Luis Fernando Molina committed 2020-06-13 19:51:41 +02:00
1 parent 83d54fefe2
commit 5e6f946f60
6 files changed
+87 -35

No files matched your search

+3 -3
View File
@@ -45,7 +45,7 @@ exports.newAnnouncements = function newAnnouncements(bot, logger) {
}
}
if (tradingEngine.episode.episodeCounters.periods > lastPeriodAnnounced) {
if (tradingEngine.episode.episodeCounters.periods.value > lastPeriodAnnounced) {
if (isNaN(value) === false) {
/* The Value Variation is what tells us how much the value already announced must change in order to annouce it again. */
let valueVariation
@@ -72,12 +72,12 @@ exports.newAnnouncements = function newAnnouncements(bot, logger) {
/* Next, we will remmeber this announcement was already done, so that it is not announced again in further processing of the same day. */
if (newAnnouncementRecord.periods !== undefined) {
newAnnouncementRecord.periods = tradingEngine.episode.episodeCounters.periods
newAnnouncementRecord.periods = tradingEngine.episode.episodeCounters.periods.value
newAnnouncementRecord.value = value
} else {
newAnnouncementRecord = {
key: key,
periods: tradingEngine.episode.episodeCounters.periods,
periods: tradingEngine.episode.episodeCounters.periods.value,
value: value
}
variable.announcements.push(newAnnouncementRecord)
+4 -4
View File
@@ -133,8 +133,8 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) {
}
function updateEpisodeCountersAndStatistics() {
tradingEngine.episode.episodeCounters.periods++
tradingEngine.episode.episodeStatistics.days = tradingEngine.episode.episodeCounters.periods * sessionParameters.timeFrame.config.value / global.ONE_DAY_IN_MILISECONDS
tradingEngine.episode.episodeCounters.periods.value++
tradingEngine.episode.episodeStatistics.days.value = tradingEngine.episode.episodeCounters.periods.value * sessionParameters.timeFrame.config.value / global.ONE_DAY_IN_MILISECONDS
}
function updatePositionCountersAndStatistics() {
@@ -278,11 +278,11 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) {
if (sessionParameters.sessionBaseAsset.name === bot.market.marketBaseAsset) {
tradingEngine.episode.episodeStatistics.ROI.value = (sessionParameters.sessionBaseAsset.config.initialBalance + tradingEngine.episode.episodeStatistics.profitLoss.value) / sessionParameters.sessionBaseAsset.config.initialBalance - 1
tradingEngine.episode.episodeStatistics.hitRatio.value = tradingEngine.episode.episodeCounters.hits.value / tradingEngine.episode.positionCounters.positions.value
tradingEngine.episode.episodeStatistics.anualizedRateOfReturn.value = tradingEngine.episode.episodeStatistics.ROI.value / tradingEngine.episode.episodeStatistics.days * 365
tradingEngine.episode.episodeStatistics.anualizedRateOfReturn.value = tradingEngine.episode.episodeStatistics.ROI.value / tradingEngine.episode.episodeStatistics.days.value * 365
} else {
tradingEngine.episode.episodeStatistics.ROI.value = (sessionParameters.sessionQuotedAsset.config.initialBalance + tradingEngine.episode.episodeStatistics.profitLoss.value) / sessionParameters.sessionQuotedAsset.config.initialBalance - 1
tradingEngine.episode.episodeStatistics.hitRatio.value = tradingEngine.episode.episodeCounters.hits.value / tradingEngine.episode.positionCounters.positions.value
tradingEngine.episode.episodeStatistics.anualizedRateOfReturn.value = tradingEngine.episode.episodeStatistics.ROI.value / tradingEngine.episode.episodeStatistics.days * 365
tradingEngine.episode.episodeStatistics.anualizedRateOfReturn.value = tradingEngine.episode.episodeStatistics.ROI.value / tradingEngine.episode.episodeStatistics.days.value * 365
}
addRecords()
+6 -6
View File
@@ -105,7 +105,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) {
/* Mechanism to avoid putting the same order over and over again at different executions of the simulation engine. */
if (variable.executionContext !== undefined) {
if (variable.executionContext.periods !== undefined) {
if (tradingEngine.episode.episodeCounters.periods <= variable.executionContext.periods) {
if (tradingEngine.episode.episodeCounters.periods.value <= variable.executionContext.periods) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> Not placing the trade at the exchange because it was already placed at a previous execution.') }
takePositionAtSimulation()
return
@@ -149,7 +149,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) {
variable.executionContext = {
status: 'Taking Position',
periods: tradingEngine.episode.episodeCounters.periods
periods: tradingEngine.episode.episodeCounters.periods.value
}
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> Ready to create order.') }
@@ -164,7 +164,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> DEFAULT_OK_RESPONSE ') }
variable.executionContext = {
status: 'In a Position',
periods: tradingEngine.episode.episodeCounters.periods,
periods: tradingEngine.episode.episodeCounters.periods.value,
amountA: amountA,
amountB: amountB,
orderId: order.id
@@ -244,7 +244,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) {
/* Mechanism to avoid putting the same order over and over again at different executions of the simulation engine. */
if (variable.executionContext !== undefined) {
if (variable.executionContext.periods !== undefined) {
if (tradingEngine.episode.episodeCounters.periods <= variable.executionContext.periods) {
if (tradingEngine.episode.episodeCounters.periods.value <= variable.executionContext.periods) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putClosingOrder -> Exiting function because this closing was already submited at a previous execution.') }
closePositionAtSimulation()
return
@@ -275,7 +275,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) {
variable.executionContext = {
status: 'Closing Position',
periods: tradingEngine.episode.episodeCounters.periods
periods: tradingEngine.episode.episodeCounters.periods.value
}
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putClosingOrder -> About to close position at the exchange.') }
@@ -290,7 +290,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> putClosingOrder -> onOrderCreated -> DEFAULT_OK_RESPONSE ') }
variable.executionContext = {
status: 'Position Closed',
periods: tradingEngine.episode.episodeCounters.periods,
periods: tradingEngine.episode.episodeCounters.periods.value,
amountA: amountA,
amountB: amountB,
orderId: order.id
+4 -4
View File
@@ -83,7 +83,7 @@ exports.newTradingOutput = function newTradingOutput(bot, logger, UTILITIES, FIL
let fileName = 'Data.json'
let filePath = bot.filePathRoot + '/Output/' + bot.SESSION.folderName + '/' + dataset.parentNode.config.codeName + '/' + dataset.config.codeName + '/' + timeFrameLabel
readOutputFile(fileName, filePath, dataset.parentNode.config.pluralVariableName)
readOutputFile(fileName, filePath, dataset.parentNode.config.codeName)
}
}
}
@@ -99,7 +99,7 @@ exports.newTradingOutput = function newTradingOutput(bot, logger, UTILITIES, FIL
let fileName = 'Data.json'
let filePath = bot.filePathRoot + '/Output/' + bot.SESSION.folderName + '/' + dataset.parentNode.config.codeName + '/' + dataset.config.codeName + '/' + timeFrameLabel + "/" + dateForPath
readOutputFile(fileName, filePath, dataset.parentNode.config.pluralVariableName)
readOutputFile(fileName, filePath, dataset.parentNode.config.codeName)
}
}
}
@@ -172,7 +172,7 @@ exports.newTradingOutput = function newTradingOutput(bot, logger, UTILITIES, FIL
let fileName = 'Data.json'
let filePath = bot.filePathRoot + '/Output/' + bot.SESSION.folderName + '/' + dataset.parentNode.config.codeName + '/' + dataset.config.codeName + '/' + timeFrameLabel
writeOutputFile(fileName, filePath, dataset.parentNode.config.pluralVariableName)
writeOutputFile(fileName, filePath, dataset.parentNode.config.codeName)
}
}
}
@@ -188,7 +188,7 @@ exports.newTradingOutput = function newTradingOutput(bot, logger, UTILITIES, FIL
let fileName = 'Data.json'
let filePath = bot.filePathRoot + '/Output/' + bot.SESSION.folderName + '/' + dataset.parentNode.config.codeName + '/' + dataset.config.codeName + '/' + timeFrameLabel + "/" + dateForPath
writeOutputFile(fileName, filePath, dataset.parentNode.config.pluralVariableName)
writeOutputFile(fileName, filePath, dataset.parentNode.config.codeName)
}
}
}
+69 -17
View File
@@ -14,7 +14,7 @@ exports.newTradingRecords = function newTradingRecords(bot, logger) {
return thisObject
function initialize(pOutputDatasets, pOutputDatasetsMap) {
function initialize(pOutputDatasetsMap) {
tradingEngine = bot.simulationState.tradingEngine
tradingSystem = bot.simulationState.tradingSystem
outputDatasetsMap = pOutputDatasetsMap // These are the files turned into arrays, stored in a Map by Product codeName.
@@ -52,32 +52,84 @@ exports.newTradingRecords = function newTradingRecords(bot, logger) {
}
function scanRecordDefinition(product) {
let rootNode = eval(product.config.nodePath)
/*
The Product Root Node is the root of the node hiriarchy branch that we need to look at
in order to fnd the node where we are going to extract the value.
*/
let productRootNode = eval(product.config.nodePath)
let record = []
for (let j = 0; j < product.recordDefinition.recordProperties.length; j++) {
let recordProperty = product.recordDefinition.recordProperties[j]
let value
for (let j = 0; j < product.record.properties.length; j++) {
let recordProperty = product.record.properties[j]
/*
The Property Root Node is the Root of the Hiriarchy branch we must find in order
to get the node where we are going to extract the value. Initially
we point it to the Product Root Node, because that is the default in case
a property does not have at its configuration a different nodePath configured
pointing to an specific Root for the property.
*/
let propertyRootNode = productRootNode
/*
If we find at the configuration a nodePath, then we take this path to find
the Root Node specifically for this property only.
*/
if (recordProperty.config.nodePath !== undefined) {
let childNode = rootNode[recordProperty.config.childNode]
if (recordProperty.config.index !== undefined) {
value = childNode[recordProperty.config.codeName] // this returns an array
value = value[recordProperty.config.index].value // this return a node item of the array and its value
} else {
value = childNode[recordProperty.config.codeName].value // here we get the value of the childNode
}
} else {
value = rootNode[recordProperty.config.codeName].value // this is the standard way
propertyRootNode = eval(recordProperty.config.nodePath)
}
if (value === Infinity) {
value = Number.MAX_SAFE_INTEGER
/*
The Target Node is the node from where we are going to exctract the value.
We will use the codeName of the Record Property to match it with
the any of the properties of the Root Node to get the Target Node.
*/
let targetNode = propertyRootNode[recordProperty.config.codeName]
/*
If the codeName of the Record Property can not match the name of the property at
the target node, the user can explicitly specify the property name at the configuration,
and in those cases we need to use that. This happens when there are many Record Properties
pointing to the same property at the Target Node.
*/
if (recordProperty.config.childProperty !== undefined) {
targetNode = propertyRootNode[recordProperty.config.childProperty]
}
/*
It can happen that intead of having a Node in targetNode what we have is an
array of nodes. We need to pick one of the elements of the array and for that
we use the Index value we find at the configuration of the Record Property.
*/
if (recordProperty.config.index !== undefined) {
targetNode = targetNode[recordProperty.config.index]
}
/*
By Default the value is extracted from the value property of the Target Node.
But it might happen the the Target Node does not exist for example when there is an Array
of Nodes defined in the Record Properties but not all of them exist at the Root Node.
We filter out those cases by not extracting the value from the value property.
*/
let value
if (targetNode !== undefined) {
value = targetNode.value
}
value = safeValue(value)
if (recordProperty.config.isString === true) {
value = '"' + value + '"'
}
record.push(value)
}
return record
}
}
function safeValue(value) {
/*
The purpose of this function is to check that value variable does not have a value that
will later break the JSON format of files where this is going to be stored at.
*/
if (value === Infinity) {
value = Number.MAX_SAFE_INTEGER
}
if (value === undefined) {
value = 0
}
return value
}
}
+1 -1
View File
@@ -233,7 +233,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
snapshotsModule.manageSnapshots()
tradingRecordsModule.appendRecords()
annoucementsModule.makeAnnoucements() // After everything at the simulation level was done, we will do the annoucements that are pending.
announcementsModule.makeAnnoucements() // After everything at the simulation level was done, we will do the annoucements that are pending.
controlLoop()
}