Bug Fixes, related to Limit Orders
This commit is contained in:
1 parent
d4af4a3865
commit
666e37bc6a
24 files changed
+209
-141
No files matched your search
@@ -75,7 +75,7 @@
|
||||
return
|
||||
}
|
||||
if (outputDatasetNode.referenceParent.parentNode.dataBuilding === undefined) {
|
||||
logger.write(MODULE_NAME, "[WARN] start -> Product Definition " + outputDatasetNode.referenceParent.parentNode.name + " without a Data Building Procedure. Product Definition = " + JSON.stringify(outputDatasetNode.referenceParent.parentNode));
|
||||
logger.write(MODULE_NAME, "[WARN] start -> Product Definition " + outputDatasetNode.referenceParent.parentNode.name + " without a Data Building Procedure. Product Definition Name = " + outputDatasetNode.referenceParent.parentNode.name);
|
||||
}
|
||||
if (outputDatasetNode.referenceParent.config.codeName === undefined) {
|
||||
logger.write(MODULE_NAME, "[ERROR] start -> Dataset witn no codeName defined. Product Dataset = " + JSON.stringify(outputDatasetNode.referenceParent));
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
const LOG_FILE_CONTENT = false;
|
||||
const MODULE_NAME = "Data Dependencies";
|
||||
|
||||
let bot = BOT
|
||||
let bot = BOT
|
||||
|
||||
let thisObject = {
|
||||
nodeArray: undefined,
|
||||
dataSetsModulesArray: [],
|
||||
isItADepenency: isItADepenency,
|
||||
isItADepenency: isItADepenency,
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
};
|
||||
@@ -21,9 +21,6 @@
|
||||
function initialize(callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
|
||||
|
||||
/* Basic Valdidations */
|
||||
if (bot.processNode.referenceParent.processDependencies !== undefined) {
|
||||
if (bot.processNode.referenceParent.processDependencies.dataDependencies !== undefined) {
|
||||
@@ -51,7 +48,7 @@
|
||||
if (bot.DEPENDENCY_FILTER !== undefined) {
|
||||
for (let i = 0; i < bot.DEPENDENCY_FILTER.length; i++) {
|
||||
let key = bot.DEPENDENCY_FILTER[i]
|
||||
filter.set(key, true)
|
||||
filter.set(key, true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +67,7 @@
|
||||
function onInitilized(err) {
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> onInitilized -> err = "+ JSON.stringify(err));
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> onInitilized -> err = " + JSON.stringify(err));
|
||||
|
||||
alreadyCalledBack = true;
|
||||
callBackFunction(err);
|
||||
@@ -81,9 +78,6 @@
|
||||
}
|
||||
|
||||
function addDataSet() {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> addDataSet -> Entering function."); }
|
||||
|
||||
addCount++;
|
||||
|
||||
thisObject.dataSetsModulesArray.push(dataSetModule);
|
||||
@@ -99,14 +93,14 @@
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> err = "+ err.stack);
|
||||
logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack);
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
function finalize() {
|
||||
for (let i = 0; i < thisObject.dataSetsModulesArray.length; i++) {
|
||||
let dataSetModule = thisObject.dataSetsModulesArray[i]
|
||||
let dataSetModule = thisObject.dataSetsModulesArray[i]
|
||||
dataSetModule.finalize()
|
||||
}
|
||||
thisObject.dataSetsModulesArray = undefined
|
||||
@@ -115,7 +109,7 @@
|
||||
}
|
||||
|
||||
function isItADepenency(timeFrame, product) {
|
||||
let key = timeFrame + '-' + product
|
||||
let key = timeFrame + '-' + product
|
||||
|
||||
return filter.get(key)
|
||||
}
|
||||
|
||||
@@ -23,9 +23,6 @@ exports.newDataSet = function newDataSet(BOT, logger) {
|
||||
function initialize(dataDependency, callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
|
||||
|
||||
thisObject.node = dataDependency.referenceParent;
|
||||
logger.fileName = MODULE_NAME + "." + thisObject.node.type + "." + thisObject.node.name + "." + thisObject.node.id;
|
||||
|
||||
|
||||
@@ -31,9 +31,6 @@ exports.newFileStorage = function newFileStorage(logger, host, port) {
|
||||
recursiveGetTextFile(filePath, callBackFunction, noRetry, canUsePrevious)
|
||||
|
||||
function recursiveGetTextFile(filePath, callBackFunction, noRetry, canUsePrevious) {
|
||||
|
||||
logger.write(MODULE_NAME, '[INFO] FileStorage -> getTextFile -> Entering Function.')
|
||||
|
||||
let fileDoesNotExist = false
|
||||
|
||||
/* Choose path for either bots or data */
|
||||
|
||||
@@ -24,14 +24,10 @@
|
||||
}
|
||||
|
||||
function initialize(callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
logger.fileName = MODULE_NAME;
|
||||
logger.initialize();
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
|
||||
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
|
||||
} catch (err) {
|
||||
|
||||
@@ -9,6 +9,7 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) {
|
||||
getNodeById: getNodeById,
|
||||
cloneValues: cloneValues,
|
||||
setCurrentCandle: setCurrentCandle,
|
||||
initializeNode: initializeNode,
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
}
|
||||
@@ -24,6 +25,8 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) {
|
||||
tradingEngine = bot.simulationState.tradingEngine
|
||||
sessionParameters = bot.SESSION.parameters
|
||||
|
||||
initializeNodeMap(tradingEngine)
|
||||
|
||||
if (bot.FIRST_EXECUTION === true) {
|
||||
/*
|
||||
Here we will go through all the nodes in the Trading Engine hiriarchy and
|
||||
@@ -97,18 +100,53 @@ exports.newTradingEngine = function newTradingEngine(bot, logger) {
|
||||
}
|
||||
}
|
||||
|
||||
function initializeNode(node) {
|
||||
function initializeNodeMap(node) {
|
||||
if (node === undefined) { return }
|
||||
/* Add to Node Map */
|
||||
nodesMap.set(node.id, node)
|
||||
|
||||
/* Now we go down through all this node children */
|
||||
let nodeDefinition = bot.APP_SCHEMA_MAP.get(node.type)
|
||||
if (nodeDefinition === undefined) { return }
|
||||
|
||||
if (nodeDefinition.properties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
for (let i = 0; i < nodeDefinition.properties.length; i++) {
|
||||
let property = nodeDefinition.properties[i]
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (property.name !== previousPropertyName) {
|
||||
if (node[property.name] !== undefined) {
|
||||
initializeNodeMap(node[property.name])
|
||||
}
|
||||
previousPropertyName = property.name
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'array': {
|
||||
if (node[property.name] !== undefined) {
|
||||
let nodePropertyArray = node[property.name]
|
||||
for (let m = 0; m < nodePropertyArray.length; m++) {
|
||||
initializeNodeMap(nodePropertyArray[m])
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function initializeNode(node) {
|
||||
if (node === undefined) { return }
|
||||
|
||||
/* Here we initialize the node value */
|
||||
if (node.config !== undefined) {
|
||||
if (node.config.initialValue !== undefined) {
|
||||
node.value = node.config.initialValue
|
||||
}
|
||||
}
|
||||
node.initialize = initializeNode // This will allow anyone to initialize this node and its children.
|
||||
|
||||
/* Now we go down through all this node children */
|
||||
let nodeDefinition = bot.APP_SCHEMA_MAP.get(node.type)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
exports.newTradingEpisode = function newTradingEpisode(bot, logger) {
|
||||
exports.newTradingEpisode = function newTradingEpisode(bot, logger, tradingEngineModule) {
|
||||
/*
|
||||
This module packages all functions related to Episodes.
|
||||
*/
|
||||
@@ -76,7 +76,7 @@ exports.newTradingEpisode = function newTradingEpisode(bot, logger) {
|
||||
}
|
||||
|
||||
function resetEpisode() {
|
||||
tradingEngine.current.episode.initialize(tradingEngine.current.episode)
|
||||
tradingEngineModule.initializeNode(tradingEngine.current.episode)
|
||||
}
|
||||
|
||||
function updateEnds() {
|
||||
|
||||
@@ -78,7 +78,12 @@ exports.newTradingOrders = function newTradingOrders(bot, logger, tradingEngineM
|
||||
let tradingSystemOrder = orders[i]
|
||||
if (tradingSystemOrder.referenceParent === undefined) { continue }
|
||||
let tradingEngineOrder = tradingEngineModule.getNodeById(tradingSystemOrder.referenceParent.id)
|
||||
if (tradingEngineOrder.status === undefined) { continue }
|
||||
try {
|
||||
if (tradingEngineOrder.status === undefined) { continue }
|
||||
} catch (err) {
|
||||
console.log(err.stack)
|
||||
}
|
||||
|
||||
|
||||
updateCounters(tradingEngineOrder)
|
||||
updateEnds(tradingEngineOrder)
|
||||
@@ -93,9 +98,9 @@ exports.newTradingOrders = function newTradingOrders(bot, logger, tradingEngineM
|
||||
for (let i = 0; i < orders.length; i++) {
|
||||
|
||||
let tradingSystemOrder = orders[i]
|
||||
tradingSystemValidations(tradingSystemOrder)
|
||||
let tradingEngineOrder = tradingEngineModule.getNodeById(tradingSystemOrder.referenceParent.id)
|
||||
|
||||
definitionValidations(tradingSystemOrder, tradingEngineOrder)
|
||||
tradingEngineValidations(tradingEngineOrder)
|
||||
|
||||
switch (tradingEngineOrder.status.value) {
|
||||
case 'Not Open': {
|
||||
@@ -142,7 +147,7 @@ exports.newTradingOrders = function newTradingOrders(bot, logger, tradingEngineM
|
||||
if (situationName !== undefined) {
|
||||
|
||||
/* Simulate Order Cancelation, if needed. */
|
||||
simulateCancelOrder(tradingSystemOrder, tradingEngineOrder, 'Cancel Event')
|
||||
simulateCancelOrder(tradingEngineStage, tradingSystemOrder, tradingEngineOrder, 'Cancel Event')
|
||||
|
||||
/* Cancel the order at the Exchange, if needed. */
|
||||
await exchangeCancelOrder(tradingEngineStage, tradingSystemOrder, tradingEngineOrder, 'Cancel Event')
|
||||
@@ -153,11 +158,13 @@ exports.newTradingOrders = function newTradingOrders(bot, logger, tradingEngineM
|
||||
}
|
||||
}
|
||||
|
||||
function definitionValidations(tradingSystemOrder, tradingEngineOrder) {
|
||||
function tradingSystemValidations(tradingSystemOrder) {
|
||||
/* Trading System Validations */
|
||||
if (tradingSystemOrder.config.percentageOfAlgorithmSize === undefined) { badDefinitionUnhandledException(undefined, 'tradingSystemOrder.config.percentageOfAlgorithmSize === undefined', tradingSystemOrder) }
|
||||
if (tradingSystemOrder.referenceParent === undefined) { badDefinitionUnhandledException(undefined, 'tradingSystemOrder.referenceParent === undefined', tradingSystemOrder) }
|
||||
}
|
||||
|
||||
function tradingEngineValidations(tradingEngineOrder) {
|
||||
/* Trading Engine Order Validations */
|
||||
if (tradingEngineOrder.serialNumber === undefined) { badDefinitionUnhandledException(undefined, 'tradingEngineOrder.serialNumber === undefined', tradingEngineOrder) }
|
||||
if (tradingEngineOrder.identifier === undefined) { badDefinitionUnhandledException(undefined, 'tradingEngineOrder.identifier === undefined', tradingEngineOrder) }
|
||||
@@ -180,7 +187,6 @@ exports.newTradingOrders = function newTradingOrders(bot, logger, tradingEngineM
|
||||
if (tradingEngineOrder.orderQuotedAsset.size === undefined) { badDefinitionUnhandledException(undefined, 'tradingEngineOrder.orderQuotedAsset.size === undefined', tradingEngineOrder) }
|
||||
if (tradingEngineOrder.orderQuotedAsset.sizeFilled === undefined) { badDefinitionUnhandledException(undefined, 'tradingEngineOrder.orderQuotedAsset.sizeFilled === undefined', tradingEngineOrder) }
|
||||
if (tradingEngineOrder.orderQuotedAsset.feesPaid === undefined) { badDefinitionUnhandledException(undefined, 'tradingEngineOrder.orderQuotedAsset.feesPaid === undefined', tradingEngineOrder) }
|
||||
|
||||
}
|
||||
|
||||
async function tryToOpenOrder(tradingEngineStage, executionAlgorithm, tradingSystemOrder, tradingEngineOrder, situationName) {
|
||||
@@ -343,7 +349,7 @@ exports.newTradingOrders = function newTradingOrders(bot, logger, tradingEngineM
|
||||
|
||||
/* If the Stage is Closing and this order is still open, we need to cancel it now */
|
||||
if (tradingEngineStage.status.value === 'Closing' && tradingEngineOrder.status.value !== 'Closed') {
|
||||
simulateCancelOrder(tradingSystemOrder, tradingEngineOrder, 'Closing Stage')
|
||||
simulateCancelOrder(tradingEngineStage, tradingSystemOrder, tradingEngineOrder, 'Closing Stage')
|
||||
}
|
||||
|
||||
function actualRateSimulation() {
|
||||
@@ -453,28 +459,54 @@ exports.newTradingOrders = function newTradingOrders(bot, logger, tradingEngineM
|
||||
}
|
||||
|
||||
function percentageFilledSimulation() {
|
||||
/* Order Filling Simulation */
|
||||
if (tradingSystemOrder.simulatedExchangeEvents.simulatedPartialFill !== undefined) {
|
||||
if (tradingSystemOrder.simulatedExchangeEvents.simulatedPartialFill.config.fillProbability !== undefined) {
|
||||
|
||||
/* Percentage Filled */
|
||||
let percentageFilled = tradingSystemOrder.simulatedExchangeEvents.simulatedPartialFill.config.fillProbability * 100
|
||||
if (tradingEngineOrder.orderStatistics.percentageFilled.value + percentageFilled > 100) {
|
||||
percentageFilled = 100 - tradingEngineOrder.orderStatistics.percentageFilled.value
|
||||
/*
|
||||
Order Filling Simulation: the way we are going to handle this is the following.
|
||||
For buy orders we are going to check if the price was below the order rate, and
|
||||
for sell orders we are going to check if the price was above the order rate.
|
||||
|
||||
If we have a partial filling defined we are going to use it to estimate how much
|
||||
of the order we will consider filled.
|
||||
*/
|
||||
let orderWasHit
|
||||
switch (tradingSystemOrder.type) {
|
||||
case 'Limit Buy Order': {
|
||||
if (tradingEngine.current.episode.candle.min.value <= tradingEngineOrder.rate.value) {
|
||||
orderWasHit = true
|
||||
}
|
||||
tradingEngineOrder.orderStatistics.percentageFilled.value = tradingEngineOrder.orderStatistics.percentageFilled.value + percentageFilled
|
||||
tradingEngineOrder.orderStatistics.percentageFilled.value = global.PRECISE(tradingEngineOrder.orderStatistics.percentageFilled.value, 10)
|
||||
|
||||
/* Check if we need to close */
|
||||
if (tradingEngineOrder.orderStatistics.percentageFilled.value === 100) {
|
||||
|
||||
/* Close this Order */
|
||||
tradingEngineOrder.status.value = 'Closed'
|
||||
tradingEngineOrder.exitType.value = 'Filled'
|
||||
|
||||
/* Initialize this */
|
||||
tradingEngine.current.episode.distanceToEvent.closeOrder.value = 1
|
||||
break
|
||||
}
|
||||
case 'Limit Sell Order': {
|
||||
if (tradingEngine.current.episode.candle.max.value >= tradingEngineOrder.rate.value) {
|
||||
orderWasHit = true
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if (orderWasHit === true) {
|
||||
if (tradingSystemOrder.simulatedExchangeEvents.simulatedPartialFill !== undefined) {
|
||||
if (tradingSystemOrder.simulatedExchangeEvents.simulatedPartialFill.config.fillProbability !== undefined) {
|
||||
|
||||
/* Percentage Filled */
|
||||
let percentageFilled = tradingSystemOrder.simulatedExchangeEvents.simulatedPartialFill.config.fillProbability * 100
|
||||
if (tradingEngineOrder.orderStatistics.percentageFilled.value + percentageFilled > 100) {
|
||||
percentageFilled = 100 - tradingEngineOrder.orderStatistics.percentageFilled.value
|
||||
}
|
||||
tradingEngineOrder.orderStatistics.percentageFilled.value = tradingEngineOrder.orderStatistics.percentageFilled.value + percentageFilled
|
||||
tradingEngineOrder.orderStatistics.percentageFilled.value = global.PRECISE(tradingEngineOrder.orderStatistics.percentageFilled.value, 10)
|
||||
}
|
||||
} else {
|
||||
/* We will assume that 100% of the order was filled */
|
||||
tradingEngineOrder.orderStatistics.percentageFilled.value = 100
|
||||
}
|
||||
/* Check if we need to close the order */
|
||||
if (tradingEngineOrder.orderStatistics.percentageFilled.value === 100) {
|
||||
|
||||
/* Close this Order */
|
||||
tradingEngineOrder.status.value = 'Closed'
|
||||
tradingEngineOrder.exitType.value = 'Filled'
|
||||
|
||||
/* Initialize this */
|
||||
tradingEngine.current.episode.distanceToEvent.closeOrder.value = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -728,7 +760,7 @@ exports.newTradingOrders = function newTradingOrders(bot, logger, tradingEngineM
|
||||
|
||||
}
|
||||
|
||||
function simulateCancelOrder(tradingSystemOrder, tradingEngineOrder, exitType) {
|
||||
function simulateCancelOrder(tradingEngineStage, tradingSystemOrder, tradingEngineOrder, exitType) {
|
||||
|
||||
/* Filter by Session Type */
|
||||
switch (bot.SESSION.type) {
|
||||
@@ -801,30 +833,30 @@ exports.newTradingOrders = function newTradingOrders(bot, logger, tradingEngineM
|
||||
|
||||
function recalculateStageSize(tradingEngineStage, tradingEngineOrder) {
|
||||
/*
|
||||
Since the order is Cancelled, we need to adjust the stage size. Remember that the Stage Size
|
||||
accumulates for each asset, the order size placed at the exchange. A cancelation means that
|
||||
Since the order is Cancelled, we need to adjust the stage sizePlaced. Remember that the Stage
|
||||
Size Placed accumulates for each asset, the order size placed at the exchange. A cancelation means that
|
||||
only the part filled can be considered placed, so we need to substract from the stage size
|
||||
the remainder. To achieve this with the information we currently have, we are going first
|
||||
to unaccount the order size, and the account only the sizeFilled + the feesPaid.
|
||||
*/
|
||||
tradingEngineStage.stageBaseAsset.size.value =
|
||||
tradingEngineStage.stageBaseAsset.size.value -
|
||||
tradingEngineStage.stageBaseAsset.sizePlaced.value =
|
||||
tradingEngineStage.stageBaseAsset.sizePlaced.value -
|
||||
tradingEngineOrder.orderBaseAsset.size.value
|
||||
tradingEngineStage.stageQuotedAsset.size.value =
|
||||
tradingEngineStage.stageQuotedAsset.size.value -
|
||||
tradingEngineStage.stageQuotedAsset.sizePlaced.value =
|
||||
tradingEngineStage.stageQuotedAsset.sizePlaced.value -
|
||||
tradingEngineOrder.orderQuotedAsset.size.value
|
||||
|
||||
tradingEngineStage.stageBaseAsset.size.value =
|
||||
tradingEngineStage.stageBaseAsset.size.value +
|
||||
tradingEngineStage.stageBaseAsset.sizePlaced.value =
|
||||
tradingEngineStage.stageBaseAsset.sizePlaced.value +
|
||||
tradingEngineOrder.orderBaseAsset.sizeFilled.value +
|
||||
tradingEngineOrder.orderBaseAsset.feesPaid.value
|
||||
tradingEngineStage.stageQuotedAsset.size.value =
|
||||
tradingEngineStage.stageQuotedAsset.size.value +
|
||||
tradingEngineStage.stageQuotedAsset.sizePlaced.value =
|
||||
tradingEngineStage.stageQuotedAsset.sizePlaced.value +
|
||||
tradingEngineOrder.orderQuotedAsset.sizeFilled.value +
|
||||
tradingEngineOrder.orderQuotedAsset.feesPaid.value
|
||||
|
||||
tradingEngineStage.stageBaseAsset.size.value = global.PRECISE(tradingEngineStage.stageBaseAsset.size.value, 10)
|
||||
tradingEngineStage.stageQuotedAsset.size.value = global.PRECISE(tradingEngineStage.stageQuotedAsset.size.value, 10)
|
||||
tradingEngineStage.stageBaseAsset.sizePlaced.value = global.PRECISE(tradingEngineStage.stageBaseAsset.sizePlaced.value, 10)
|
||||
tradingEngineStage.stageQuotedAsset.sizePlaced.value = global.PRECISE(tradingEngineStage.stageQuotedAsset.sizePlaced.value, 10)
|
||||
}
|
||||
|
||||
function checkOrderEvent(event, order, executionAlgorithm, executionNode) {
|
||||
@@ -873,7 +905,7 @@ exports.newTradingOrders = function newTradingOrders(bot, logger, tradingEngineM
|
||||
function resetTradingEngineDataStructure(tradingEngineOrder, tradingSystemOrder, stageStatus) {
|
||||
if (tradingEngineOrder.status.value === 'Closed') {
|
||||
/* We reset the order data structure inside the Trading Engine to its initial value */
|
||||
tradingEngineOrder.initialize(tradingEngineOrder)
|
||||
tradingEngineModule.initializeNode(tradingEngineOrder)
|
||||
if (tradingSystemOrder.config.spawnMultipleOrders !== true) {
|
||||
/*
|
||||
We close the lock so as to prevent this data structure to be used again during this same stage execution.
|
||||
|
||||
@@ -238,7 +238,7 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
|
||||
|
||||
function resetTradingEngineDataStructure() {
|
||||
if (tradingEngine.current.position.status.value === 'Closed') {
|
||||
tradingEngine.current.position.initialize(tradingEngine.current.position)
|
||||
tradingEngineModule.initializeNode(tradingEngine.current.position)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,14 @@ exports.newTradingRecords = function newTradingRecords(bot, logger) {
|
||||
*/
|
||||
let productRootNode = productRoot[index]
|
||||
let record = scanRecordDefinition(product, productRootNode, index)
|
||||
persistIndividualRecord(record, product, outputDatasetArray)
|
||||
if (record !== undefined) {
|
||||
/*
|
||||
We will add the index value to the record itself, so that the plotter can know to which
|
||||
brach of the trading engine data structure it belongs.
|
||||
*/
|
||||
record.push(index)
|
||||
persistIndividualRecord(record, product, outputDatasetArray)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@@ -101,7 +108,9 @@ exports.newTradingRecords = function newTradingRecords(bot, logger) {
|
||||
*/
|
||||
let productRootNode = productRoot
|
||||
let record = scanRecordDefinition(product, productRootNode)
|
||||
persistIndividualRecord(record, product, outputDatasetArray)
|
||||
if (record !== undefined) {
|
||||
persistIndividualRecord(record, product, outputDatasetArray)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -192,6 +201,13 @@ exports.newTradingRecords = function newTradingRecords(bot, logger) {
|
||||
value = targetNode
|
||||
}
|
||||
}
|
||||
|
||||
/* We are not going to add records where the begin or end are missing */
|
||||
if (
|
||||
recordProperty.config.codeName === 'begin' && value === 0 ||
|
||||
recordProperty.config.codeName === 'end' && value === 0
|
||||
) { return }
|
||||
|
||||
if (recordProperty.config.isString !== true && Array.isArray(value) !== true) {
|
||||
value = safeNumericValue(value)
|
||||
}
|
||||
@@ -213,27 +229,36 @@ exports.newTradingRecords = function newTradingRecords(bot, logger) {
|
||||
let propertyValue = record[j]
|
||||
|
||||
if (bot.processingDailyFiles) {
|
||||
/*
|
||||
When dealing with Daily Files, we need to avoid to write an open object at the last 'candle' of the day,
|
||||
since the object will be duplicated on the next day. How do we know we are positioned at the last candle
|
||||
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.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.
|
||||
if (product.config.doNotCutObjectInDays !== true) {
|
||||
/*
|
||||
By default we will cut objects in days.
|
||||
*/
|
||||
if (propertyValue === product.config.propertyValueThatClosesObject) {
|
||||
if (propertyValue !== product.config.propertyValueThatPreventsSavingObject) {
|
||||
outputDatasetArray.push(record)
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
When we are not at the end of the day, we will save the object normally, like in market files.
|
||||
When dealing with Daily Files, we need to avoid to write an open object at the last 'candle' of the day,
|
||||
since the object will be duplicated on the next day. How do we know we are positioned at the last candle
|
||||
of the day? Easy: the end of the candle must be 1 millisecod before the next day. That happens at any
|
||||
time frame.
|
||||
*/
|
||||
if (propertyValue !== product.config.propertyValueThatPreventsSavingObject) {
|
||||
outputDatasetArray.push(record)
|
||||
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.
|
||||
*/
|
||||
if (propertyValue === product.config.propertyValueThatClosesObject) {
|
||||
outputDatasetArray.push(record)
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
When we are not at the end of the day, we will save the object normally, like in market files.
|
||||
*/
|
||||
if (propertyValue !== product.config.propertyValueThatPreventsSavingObject) {
|
||||
outputDatasetArray.push(record)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
|
||||
tradingSystemModule.initialize()
|
||||
|
||||
const TRADING_EPISODE_MODULE = require('./TradingEpisode.js')
|
||||
let tradingEpisodeModule = TRADING_EPISODE_MODULE.newTradingEpisode(bot, logger)
|
||||
let tradingEpisodeModule = TRADING_EPISODE_MODULE.newTradingEpisode(bot, logger, tradingEngineModule)
|
||||
tradingEpisodeModule.initialize()
|
||||
|
||||
/* Setting up the candles array: The whole simulation is based on the array of candles at the time-frame defined at the session parameters. */
|
||||
@@ -177,7 +177,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
|
||||
|
||||
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 {
|
||||
closeEpisode('All Candles Processed')
|
||||
updateEpisode('All Candles Processed')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -269,7 +269,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM
|
||||
let executionNode = stageNode.openExecution
|
||||
|
||||
/* Reset the Exchange Orders data structure to its initial value */
|
||||
tradingEngine.exchangeOrders.initialize(tradingEngine.exchangeOrders)
|
||||
tradingEngineModule.initializeNode(tradingEngine.exchangeOrders)
|
||||
|
||||
tradingSystem.evalConditions(stageNode, 'Initial Definition')
|
||||
tradingSystem.evalFormulas(stageNode, 'Initial Definition')
|
||||
@@ -1066,7 +1066,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM
|
||||
}
|
||||
|
||||
function resetStage(stage) {
|
||||
stage.initialize(stage)
|
||||
tradingEngineModule.initializeNode(stage)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ exports.newTradingStrategy = function newTradingStrategy(bot, logger, tradingEng
|
||||
|
||||
function resetTradingEngineDataStructure() {
|
||||
if (tradingEngine.current.strategy.status.value === 'Closed') {
|
||||
tradingEngine.current.strategy.initialize(tradingEngine.current.strategy)
|
||||
tradingEngineModule.initializeNode(tradingEngine.current.strategy)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,11 +29,7 @@
|
||||
return thisObject;
|
||||
|
||||
function initialize(callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
|
||||
|
||||
let name = 'Not Depends on any Process'
|
||||
logger.fileName = MODULE_NAME + "." + name;
|
||||
|
||||
|
||||
+4
-25
@@ -56,50 +56,29 @@
|
||||
/* Global control of logging. */
|
||||
|
||||
global.LOG_CONTROL = {
|
||||
"Assistant": {
|
||||
logInfo: true,
|
||||
logWarnings: false,
|
||||
logErrors: true,
|
||||
logContent: false,
|
||||
intensiveLogging: false
|
||||
},
|
||||
"Exchange API": {
|
||||
logInfo: true,
|
||||
logWarnings: false,
|
||||
logErrors: true,
|
||||
logContent: false,
|
||||
intensiveLogging: false
|
||||
},
|
||||
"Status Report": {
|
||||
logInfo: true,
|
||||
logInfo: false,
|
||||
logWarnings: false,
|
||||
logErrors: true,
|
||||
logContent: false,
|
||||
intensiveLogging: false
|
||||
},
|
||||
"Dataset": {
|
||||
logInfo: true,
|
||||
logWarnings: false,
|
||||
logErrors: true,
|
||||
logContent: false,
|
||||
intensiveLogging: false
|
||||
},
|
||||
"Context": {
|
||||
logInfo: true,
|
||||
logInfo: false,
|
||||
logWarnings: false,
|
||||
logErrors: true,
|
||||
logContent: false,
|
||||
intensiveLogging: false
|
||||
},
|
||||
"Process Execution Events": {
|
||||
logInfo: true,
|
||||
logInfo: false,
|
||||
logWarnings: false,
|
||||
logErrors: true,
|
||||
logContent: false,
|
||||
intensiveLogging: false
|
||||
},
|
||||
"Process Output": {
|
||||
logInfo: true,
|
||||
logInfo: false,
|
||||
logWarnings: false,
|
||||
logErrors: true,
|
||||
logContent: false,
|
||||
|
||||
@@ -18,11 +18,7 @@
|
||||
return thisObject;
|
||||
|
||||
function initialize(callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
|
||||
|
||||
/* Basic Valdidations */
|
||||
if (bot.processNode.referenceParent.processDependencies !== undefined) {
|
||||
if (bot.processNode.referenceParent.processDependencies.statusDependencies !== undefined) {
|
||||
@@ -88,9 +84,6 @@
|
||||
|
||||
switch (err.message) {
|
||||
case global.DEFAULT_OK_RESPONSE.message: {
|
||||
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> onLoad -> Execution finished well. -> Status Dependency = " + JSON.stringify(statusDependency.dependency)) }
|
||||
|
||||
addReport();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -39,10 +39,7 @@
|
||||
return thisObject;
|
||||
|
||||
function initialize(pStatusDependencyNode, callBackFunction) {
|
||||
|
||||
try {
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
|
||||
|
||||
statusDependencyNode = pStatusDependencyNode;
|
||||
logger.fileName = MODULE_NAME + "." + statusDependencyNode.type + "." + statusDependencyNode.name + "." + statusDependencyNode.id;
|
||||
|
||||
|
||||
Reference in new issue
Block a user