exports.newIndicatorBotMarket = function newIndicatorBotMarket(bot, logger, COMMONS, UTILITIES, FILE_STORAGE) { const FULL_LOG = true; const LOG_FILE_CONTENT = false; const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000; const MODULE_NAME = "User Bot"; const BOLLINGER_CHANNELS_FOLDER_NAME = "Bollinger-Channels"; const BOLLINGER_STANDARD_CHANNELS_FOLDER_NAME = "Bollinger-Standard-Channels"; const BOLLINGER_SUB_CHANNELS_FOLDER_NAME = "Bollinger-Sub-Channels"; const BOLLINGER_STANDARD_SUB_CHANNELS_FOLDER_NAME = "Bollinger-Standard-Sub-Channels"; const commons = COMMONS.newIndicatorBotCommons(bot, logger, UTILITIES); thisObject = { initialize: initialize, start: start }; let fileStorage = FILE_STORAGE.newFileStorage(logger); let processConfig; return thisObject; function initialize(pProcessConfig, callBackFunction) { try { logger.fileName = MODULE_NAME; logger.initialize(); if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); } processConfig = pProcessConfig; callBackFunction(global.DEFAULT_OK_RESPONSE); } catch (err) { logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } function start(dataFiles, timePeriod, outputPeriodLabel, startDate, endDate, callBackFunction) { try { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> Entering function."); } let market = global.MARKET; let dataFile; let bands = []; let channels = []; let standardChannels = []; let subChannels = []; let standardSubChannels = []; dataFile = dataFiles[0]; // We only need the bollinger bands. commons.buildBandsArray(dataFile, bands, timePeriod, callBackFunction); commons.buildChannels(bands, channels, callBackFunction); commons.buildStandardChannels(bands, standardChannels, callBackFunction); commons.buildSubChannels(bands, subChannels, callBackFunction); commons.buildStandardSubChannels(bands, standardSubChannels, callBackFunction); let dataDependency = {} for (let i = 0; i < processConfig.dataDependencies.length; i++) { let dependency = processConfig.dataDependencies[i] let recordDefinition = processConfig.recordDefinition let dependencyArray = commons.buildDependencyArray(dataFiles[i], recordDefinition); dependencyArray = commons.addCalculatedProperties(dependencyArray, dependency.singularVariableName, timePeriod); dataDependency[dependency.pluralVariableName] = dependencyArray } for (let i = 0; i < processConfig.updatesDatasets.length; i++) { let product = processConfig.updatesDatasets[i].product let dataset = processConfig.updatesDatasets[i].dataset let recordDefinition = getRecordDefinition(product) let records = commons.buildRecords(dataDependency, recordDefinition) let fileContent = generateFileContent(indicatorData, recordDefinition) writeFile(product, dataset, fileContent) } let totalFilesWritten = 0 function anotherFileWritten() { totalFilesWritten++ if (totalFilesWritten === processConfig.updatesDatasets.length) { callBackFunction(global.DEFAULT_OK_RESPONSE); } } function getRecordDefinition(product) { for (let j = 0; j < bot.products.length; j++) { if (bot.products[j].codeName === product) { return bot.products[j].recordDefinition } } } function generateFileContent(records, recordDefinition) { try { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> generateFileContent -> Entering function."); } let fileContent = ""; let recordSeparator = ""; for (let i = 0; i < records.length; i++) { let record = records[i]; fileContent = fileContent + recordSeparator + '[' let propertySeparator = "" for (let j = 0; j < recordDefinition.length; j++) { let property = recordDefinition[j] fileContent = fileContent + propertySeparator if (property.isNumeric !== true) { fileContent = fileContent + '"' } fileContent = fileContent + record[property.name] if (property.isNumeric !== true) { fileContent = fileContent + '"' } if (recordSeparator === "") { propertySeparator = ","; } } fileContent = fileContent + ']' if (recordSeparator === "") { recordSeparator = ","; } } fileContent = "[" + fileContent + "]"; return fileContent } catch (err) { logger.write(MODULE_NAME, "[ERROR] start -> generateFileContent -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } function writeFile(product, dataset, fileContent) { try { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeFile -> Entering function."); } let fileName = '' + market.assetA + '_' + market.assetB + '.json'; let filePathRoot = bot.devTeam + "/" + bot.codeName + "." + bot.version.major + "." + bot.version.minor + "/" + global.CLONE_EXECUTOR.codeName + "." + global.CLONE_EXECUTOR.version + "/" + global.EXCHANGE_NAME + "/" + bot.dataSetVersion; let filePath = filePathRoot + "/Output/" + product + "/" + dataset + "/" + outputPeriodLabel; filePath += '/' + fileName fileStorage.createTextFile(bot.devTeam, filePath, fileContent + '\n', onFileCreated); function onFileCreated(err) { try { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> writeFile -> onFileCreated -> Entering function."); } if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] start -> writeFile -> onFileCreated -> fileContent = " + fileContent); } if (err.result !== global.DEFAULT_OK_RESPONSE.result) { logger.write(MODULE_NAME, "[ERROR] start -> writeFile -> onFileCreated -> err = " + err.stack); logger.write(MODULE_NAME, "[ERROR] start -> writeFile -> onFileCreated -> filePath = " + filePath); logger.write(MODULE_NAME, "[ERROR] start -> writeFile -> onFileCreated -> market = " + market.assetA + "_" + market.assetB); callBackFunction(err); return; } anotherFileWritten(); } catch (err) { logger.write(MODULE_NAME, "[ERROR] start -> writeFile -> onFileCreated -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { logger.write(MODULE_NAME, "[ERROR] start -> writeFile -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { logger.write(MODULE_NAME, "[ERROR] start -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } };