append to records implemented
This commit is contained in:
1 parent
7df9297c3f
commit
0ae546d115
5 files changed
+132
-543
No files matched your search
+59
-362
@@ -45,8 +45,13 @@ exports.newTradingBot = function newTradingBot(bot, logger, UTILITIES, FILE_STOR
|
||||
|
||||
function start(multiPeriodDataFiles, timeFrame, timeFrameLabel, currentDay, simulationState, callBackFunction) {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> Entering function.') }
|
||||
|
||||
bot.processingDailyFiles
|
||||
if (timeFrame > global.dailyFilePeriods[0][0]) {
|
||||
bot.processingDailyFiles = false
|
||||
} else {
|
||||
bot.processingDailyFiles = true
|
||||
}
|
||||
let chart = {}
|
||||
let mainDependency = {}
|
||||
|
||||
@@ -89,7 +94,6 @@ exports.newTradingBot = function newTradingBot(bot, logger, UTILITIES, FILE_STOR
|
||||
}
|
||||
|
||||
/* Single Files */
|
||||
|
||||
let dataFiles = multiPeriodDataFiles.get('Single Files')
|
||||
let products = {}
|
||||
|
||||
@@ -103,24 +107,12 @@ exports.newTradingBot = function newTradingBot(bot, logger, UTILITIES, FILE_STOR
|
||||
}
|
||||
|
||||
/* Simulation */
|
||||
|
||||
const SNAPSHOTS_FOLDER_NAME = 'Snapshots'
|
||||
const TRADING_SIMULATION = require('./TradingSimulation.js')
|
||||
let tradingSimulation = TRADING_SIMULATION.newTradingSimulation(bot, logger, UTILITIES)
|
||||
|
||||
let market = bot.market
|
||||
|
||||
const SIMULATED_RECORDS_FOLDER_NAME = 'Trading-Simulation'
|
||||
const CONDITIONS_FOLDER_NAME = 'Simulation-Conditions'
|
||||
const STRATEGIES_FOLDER_NAME = 'Simulation-Strategies'
|
||||
const TRADES_FOLDER_NAME = 'Simulation-Trades'
|
||||
const SNAPSHOTS_FOLDER_NAME = 'Snapshots'
|
||||
|
||||
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000
|
||||
|
||||
let recordsArray = []
|
||||
let conditionsArray = []
|
||||
let strategiesArray = []
|
||||
let positionsArray = []
|
||||
let totalFilesRead = 0
|
||||
let outputDatasetsMap = new Map()
|
||||
|
||||
let snapshotHeaders
|
||||
let triggerOnSnapshot
|
||||
@@ -128,369 +120,78 @@ exports.newTradingBot = function newTradingBot(bot, logger, UTILITIES, FILE_STOR
|
||||
|
||||
let tradingSystem = {}
|
||||
|
||||
if (bot.RESUME === true) {
|
||||
readFiles()
|
||||
} else {
|
||||
if (bot.RESUME !== true) {
|
||||
simulationState.tradingEngine = bot.SESSION.tradingEngine
|
||||
simulationState.tradingSystem = bot.SESSION.tradingSystem
|
||||
runSimulation()
|
||||
}
|
||||
readFiles()
|
||||
return
|
||||
|
||||
function readFiles() {
|
||||
|
||||
if (timeFrame > global.dailyFilePeriods[0][0]) {
|
||||
readMarketFiles(runSimulation)
|
||||
/*
|
||||
This bot have an output of files that it generates. At every call to the bot, it needs to read the previously generated
|
||||
files in order to later append more information after the execution is over. Here in this function we are going to
|
||||
read those output files and get them ready for appending content during the simulation.
|
||||
*/
|
||||
if (bot.processingDailyFiles) {
|
||||
readDailyFiles()
|
||||
} else {
|
||||
readDailyFiles(runSimulation)
|
||||
readMarketFiles()
|
||||
}
|
||||
}
|
||||
|
||||
function readMarketFiles(callBack) {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readMarketFiles -> Entering function.') }
|
||||
function readMarketFiles() {
|
||||
for (let i = 0; i < outputDatasets.length; i++) {
|
||||
let outputDatasetNode = outputDatasets[i]
|
||||
let dataset = outputDatasetNode.referenceParent
|
||||
|
||||
readRecordsFile()
|
||||
|
||||
function readRecordsFile() {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readMarketFiles -> readRecordsFile -> Entering function.') }
|
||||
if (dataset.config.type === 'Market Files') {
|
||||
|
||||
let fileName = 'Data.json'
|
||||
let filePath = bot.filePathRoot + '/Output/' + bot.SESSION.folderName + '/' + SIMULATED_RECORDS_FOLDER_NAME + '/' + 'Multi-Period-Market' + '/' + timeFrameLabel
|
||||
filePath += '/' + fileName
|
||||
let filePath = bot.filePathRoot + '/Output/' + bot.SESSION.folderName + '/' + dataset.parentNode.config.codeName + '/' + dataset.config.codeName + '/' + timeFrameLabel
|
||||
|
||||
fileStorage.getTextFile(filePath, onFileRead, true)
|
||||
|
||||
function onFileRead(err, text) {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readMarketFiles -> readRecordsFile -> onFileRead -> Entering function.') }
|
||||
|
||||
if (err.message === 'File does not exist.') {
|
||||
recordsArray = []
|
||||
readConditionsFile()
|
||||
return
|
||||
}
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readRecordsFile -> onFileRead -> err = ' + err.stack)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readRecordsFile -> onFileRead -> filePath = ' + filePath)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readRecordsFile -> onFileRead -> market = ' + market.baseAsset + '_' + market.quotedAsset)
|
||||
|
||||
callBackFunction(err)
|
||||
return
|
||||
}
|
||||
|
||||
recordsArray = JSON.parse(text)
|
||||
readConditionsFile()
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readRecordsFile -> onFileRead -> err = ' + err.stack)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readRecordsFile -> err = ' + err.stack)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
readOutputFile(fileName, filePath, dataset.parentNode.config.pluralVariableName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function readConditionsFile() {
|
||||
function readOutputFile(fileName, filePath, productName) {
|
||||
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.getTextFile(filePath, onFileRead, true)
|
||||
|
||||
function onFileRead(err, text) {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readMarketFiles -> readConditionsFile -> Entering function.') }
|
||||
|
||||
let fileName = 'Data.json'
|
||||
let filePath = bot.filePathRoot + '/Output/' + bot.SESSION.folderName + '/' + CONDITIONS_FOLDER_NAME + '/' + 'Multi-Period-Market' + '/' + timeFrameLabel
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.getTextFile(filePath, onFileRead, true)
|
||||
|
||||
function onFileRead(err, text) {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readMarketFiles -> readConditionsFile -> onFileRead -> Entering function.') }
|
||||
|
||||
if (err.message === 'File does not exist.') {
|
||||
conditionsArray = []
|
||||
readStrategiesFile()
|
||||
return
|
||||
}
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readConditionsFile -> onFileRead -> err = ' + err.stack)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readConditionsFile -> onFileRead -> filePath = ' + filePath)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readConditionsFile -> onFileRead -> market = ' + market.baseAsset + '_' + market.quotedAsset)
|
||||
|
||||
callBackFunction(err)
|
||||
return
|
||||
}
|
||||
|
||||
conditionsArray = JSON.parse(text)
|
||||
conditionsArray = conditionsArray[1] // conditionsArray[0] = a snapshot of the trading system.
|
||||
readStrategiesFile()
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readConditionsFile -> onFileRead -> err = ' + err.stack)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
if (err.message === 'File does not exist.') {
|
||||
outputDatasetsMap.set(productName, [])
|
||||
anotherFileRead()
|
||||
return
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readConditionsFile -> err = ' + err.stack)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
|
||||
function readStrategiesFile() {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readMarketFiles -> readStrategiesFile -> Entering function.') }
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readOutputFile -> onFileRead -> err = ' + err.stack)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readOutputFile -> onFileRead -> filePath = ' + filePath)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readOutputFile -> onFileRead -> market = ' + market.baseAsset + '_' + market.quotedAsset)
|
||||
|
||||
let fileName = 'Data.json'
|
||||
let filePath = bot.filePathRoot + '/Output/' + bot.SESSION.folderName + '/' + STRATEGIES_FOLDER_NAME + '/' + 'Multi-Period-Market' + '/' + timeFrameLabel
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.getTextFile(filePath, onFileRead, true)
|
||||
|
||||
function onFileRead(err, text) {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readMarketFiles -> readStrategiesFile -> onFileRead -> Entering function.') }
|
||||
|
||||
if (err.message === 'File does not exist.') {
|
||||
strategiesArray = []
|
||||
readPositionsFile()
|
||||
return
|
||||
}
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readStrategiesFile -> onFileRead -> err = ' + err.stack)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readStrategiesFile -> onFileRead -> filePath = ' + filePath)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readStrategiesFile -> onFileRead -> market = ' + market.baseAsset + '_' + market.quotedAsset)
|
||||
|
||||
callBackFunction(err)
|
||||
return
|
||||
}
|
||||
|
||||
strategiesArray = JSON.parse(text)
|
||||
readPositionsFile()
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readStrategiesFile -> onFileRead -> err = ' + err.stack)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
callBackFunction(err)
|
||||
return
|
||||
}
|
||||
|
||||
outputDatasetsMap.set(productName, JSON.parse(text))
|
||||
anotherFileRead()
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readStrategiesFile -> err = ' + err.stack)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
|
||||
function readPositionsFile() {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readMarketFiles -> readPositionsFile -> Entering function.') }
|
||||
|
||||
let fileName = 'Data.json'
|
||||
let filePath = bot.filePathRoot + '/Output/' + bot.SESSION.folderName + '/' + TRADES_FOLDER_NAME + '/' + 'Multi-Period-Market' + '/' + timeFrameLabel
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.getTextFile(filePath, onFileRead, true)
|
||||
|
||||
function onFileRead(err, text) {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readMarketFiles -> readPositionsFile -> onFileRead -> Entering function.') }
|
||||
|
||||
if (err.message === 'File does not exist.') {
|
||||
positionsArray = []
|
||||
callBack()
|
||||
return
|
||||
}
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readPositionsFile -> onFileRead -> err = ' + err.stack)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readPositionsFile -> onFileRead -> filePath = ' + filePath)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readPositionsFile -> onFileRead -> market = ' + market.baseAsset + '_' + market.quotedAsset)
|
||||
|
||||
callBackFunction(err)
|
||||
return
|
||||
}
|
||||
|
||||
positionsArray = JSON.parse(text)
|
||||
callBack()
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readPositionsFile -> onFileRead -> err = ' + err.stack)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readPositionsFile -> err = ' + err.stack)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readMarketFiles -> readOutputFile -> onFileRead -> err = ' + err.stack)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function readDailyFiles(callBack) {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readDailyFiles -> Entering function.') }
|
||||
|
||||
readRecordsFile()
|
||||
|
||||
function readRecordsFile() {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readDailyFiles -> readRecordsFile -> Entering function.') }
|
||||
|
||||
let dateForPath = currentDay.getUTCFullYear() + '/' + utilities.pad(currentDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(currentDay.getUTCDate(), 2)
|
||||
let fileName = 'Data.json'
|
||||
let filePath = bot.filePathRoot + '/Output/' + bot.SESSION.folderName + '/' + SIMULATED_RECORDS_FOLDER_NAME + '/' + 'Multi-Period-Daily' + '/' + timeFrameLabel + '/' + dateForPath
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.getTextFile(filePath, onFileRead, true)
|
||||
|
||||
function onFileRead(err, text) {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readDailyFiles -> readRecordsFile -> onFileRead -> Entering function.') }
|
||||
|
||||
if (err.message === 'File does not exist.') {
|
||||
recordsArray = []
|
||||
readConditionsFile()
|
||||
return
|
||||
}
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readRecordsFile -> onFileRead -> err = ' + err.stack)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readRecordsFile -> onFileRead -> filePath = ' + filePath)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readRecordsFile -> onFileRead -> market = ' + market.baseAsset + '_' + market.quotedAsset)
|
||||
|
||||
callBackFunction(err)
|
||||
return
|
||||
}
|
||||
|
||||
recordsArray = JSON.parse(text)
|
||||
readConditionsFile()
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readRecordsFile -> onFileRead -> err = ' + err.stack)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readRecordsFile -> err = ' + err.stack)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
|
||||
function readConditionsFile() {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readDailyFiles -> readConditionsFile -> Entering function.') }
|
||||
|
||||
fileStorage.getTextFile(filePath, onFileRead, true)
|
||||
|
||||
function onFileRead(err, text) {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readDailyFiles -> readConditionsFile -> onFileRead -> Entering function.') }
|
||||
|
||||
if (err.message === 'File does not exist.') {
|
||||
conditionsArray = []
|
||||
readStrategiesFile()
|
||||
return
|
||||
}
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readConditionsFile -> onFileRead -> err = ' + err.stack)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readConditionsFile -> onFileRead -> filePath = ' + filePath)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readConditionsFile -> onFileRead -> market = ' + market.baseAsset + '_' + market.quotedAsset)
|
||||
|
||||
callBackFunction(err)
|
||||
return
|
||||
}
|
||||
|
||||
conditionsArray = JSON.parse(text)
|
||||
conditionsArray = conditionsArray[1] // conditionsArray[0] = a snapshot of the trading system.
|
||||
readStrategiesFile()
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readConditionsFile -> onFileRead -> err = ' + err.stack)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readConditionsFile -> err = ' + err.stack)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
|
||||
function readStrategiesFile() {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readDailyFiles -> readStrategiesFile -> Entering function.') }
|
||||
|
||||
let dateForPath = currentDay.getUTCFullYear() + '/' + utilities.pad(currentDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(currentDay.getUTCDate(), 2)
|
||||
let fileName = 'Data.json'
|
||||
let filePath = bot.filePathRoot + '/Output/' + bot.SESSION.folderName + '/' + STRATEGIES_FOLDER_NAME + '/' + 'Multi-Period-Daily' + '/' + timeFrameLabel + '/' + dateForPath
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.getTextFile(filePath, onFileRead, true)
|
||||
|
||||
function onFileRead(err, text) {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readDailyFiles -> readStrategiesFile -> onFileRead -> Entering function.') }
|
||||
|
||||
if (err.message === 'File does not exist.') {
|
||||
strategiesArray = []
|
||||
readPositionsFile()
|
||||
return
|
||||
}
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readStrategiesFile -> onFileRead -> err = ' + err.stack)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readStrategiesFile -> onFileRead -> filePath = ' + filePath)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readStrategiesFile -> onFileRead -> market = ' + market.baseAsset + '_' + market.quotedAsset)
|
||||
|
||||
callBackFunction(err)
|
||||
return
|
||||
}
|
||||
|
||||
strategiesArray = JSON.parse(text)
|
||||
readPositionsFile()
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readStrategiesFile -> onFileRead -> err = ' + err.stack)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readStrategiesFile -> err = ' + err.stack)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
|
||||
function readPositionsFile() {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readDailyFiles -> readPositionsFile -> Entering function.') }
|
||||
|
||||
let dateForPath = currentDay.getUTCFullYear() + '/' + utilities.pad(currentDay.getUTCMonth() + 1, 2) + '/' + utilities.pad(currentDay.getUTCDate(), 2)
|
||||
let fileName = 'Data.json'
|
||||
let filePath = bot.filePathRoot + '/Output/' + bot.SESSION.folderName + '/' + TRADES_FOLDER_NAME + '/' + 'Multi-Period-Daily' + '/' + timeFrameLabel + '/' + dateForPath
|
||||
filePath += '/' + fileName
|
||||
|
||||
fileStorage.getTextFile(filePath, onFileRead, true)
|
||||
|
||||
function onFileRead(err, text) {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] start -> readDailyFiles -> readPositionsFile -> onFileRead -> Entering function.') }
|
||||
|
||||
if (err.message === 'File does not exist.') {
|
||||
positionsArray = []
|
||||
callBack()
|
||||
return
|
||||
}
|
||||
|
||||
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readPositionsFile -> onFileRead -> err = ' + err.stack)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readPositionsFile -> onFileRead -> filePath = ' + filePath)
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readPositionsFile -> onFileRead -> market = ' + market.baseAsset + '_' + market.quotedAsset)
|
||||
|
||||
callBackFunction(err)
|
||||
return
|
||||
}
|
||||
|
||||
positionsArray = JSON.parse(text)
|
||||
callBack()
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readPositionsFile -> onFileRead -> err = ' + err.stack)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.write(MODULE_NAME, '[ERROR] start -> readDailyFiles -> readPositionsFile -> err = ' + err.stack)
|
||||
callBackFunction(global.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
function anotherFileRead() {
|
||||
totalFilesRead++
|
||||
if (totalFilesRead === outputDatasets.length) {
|
||||
runSimulation()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -498,19 +199,15 @@ exports.newTradingBot = function newTradingBot(bot, logger, UTILITIES, FILE_STOR
|
||||
tradingSimulation.runSimulation(
|
||||
chart,
|
||||
dataDependencies,
|
||||
timeFrame,
|
||||
timeFrameLabel,
|
||||
currentDay,
|
||||
simulationState,
|
||||
exchangeAPI,
|
||||
recordsArray,
|
||||
conditionsArray,
|
||||
strategiesArray,
|
||||
positionsArray,
|
||||
outputDatasets,
|
||||
outputDatasetsMap,
|
||||
writeFiles,
|
||||
callBackFunction)
|
||||
}
|
||||
|
||||
|
||||
function writeFiles(pTradingSystem, pSnapshotHeaders, pTriggerOnSnapshot, pTakePositionSnapshot) {
|
||||
tradingSystem = pTradingSystem
|
||||
|
||||
@@ -518,10 +215,10 @@ exports.newTradingBot = function newTradingBot(bot, logger, UTILITIES, FILE_STOR
|
||||
triggerOnSnapshot = pTriggerOnSnapshot
|
||||
takePositionSnapshot = pTakePositionSnapshot
|
||||
|
||||
if (timeFrame > global.dailyFilePeriods[0][0]) {
|
||||
writeMarketFiles()
|
||||
} else {
|
||||
if (bot.processingDailyFiles) {
|
||||
writeDailyFiles()
|
||||
} else {
|
||||
writeMarketFiles()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
exports.newMultiPeriod = function newMultiPeriod(bot, logger, UTILITIES, USER_BOT_MODULE, USER_BOT_COMMONS) {
|
||||
exports.newTradingProcess = function newTradingProcess(bot, logger, UTILITIES, USER_BOT_MODULE, USER_BOT_COMMONS) {
|
||||
|
||||
/*
|
||||
This Module will load all the process data dependencies from files and send them to the Trading Bot.
|
||||
After execution, will save the time range and status report of the process.
|
||||
*/
|
||||
const FULL_LOG = true;
|
||||
const LOG_FILE_CONTENT = false;
|
||||
const MODULE_NAME = "Multi Period";
|
||||
const MODULE_NAME = "Trading Process";
|
||||
const GMT_SECONDS = ':00.000 GMT+0000';
|
||||
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000;
|
||||
|
||||
@@ -21,7 +25,7 @@
|
||||
|
||||
let botInstance;
|
||||
|
||||
const FILE_STORAGE = require('./FileStorage.js');
|
||||
const FILE_STORAGE = require('../FileStorage.js');
|
||||
let fileStorage = FILE_STORAGE.newFileStorage(logger);
|
||||
|
||||
let processConfig;
|
||||
@@ -29,7 +33,6 @@
|
||||
return thisObject;
|
||||
|
||||
function initialize(pProcessConfig, pStatusDependencies, pDataDependencies, exchangeAPI, callBackFunction) {
|
||||
|
||||
try {
|
||||
|
||||
logger.fileName = MODULE_NAME;
|
||||
@@ -39,7 +42,7 @@
|
||||
dataDependenciesModule = pDataDependencies;
|
||||
processConfig = pProcessConfig;
|
||||
|
||||
let USER_BOT_MODULE = require("./Trading/TradingBot")
|
||||
let USER_BOT_MODULE = require("./TradingBot")
|
||||
|
||||
botInstance = USER_BOT_MODULE.newTradingBot(bot, logger, UTILITIES, FILE_STORAGE);
|
||||
botInstance.initialize(exchangeAPI, callBackFunction);
|
||||
+56
-139
@@ -3,166 +3,83 @@ exports.newTradingRecords = function newTradingRecords(bot, logger) {
|
||||
const MODULE_NAME = 'Trading Records'
|
||||
|
||||
let thisObject = {
|
||||
addSimulationRecord: addSimulationRecord,
|
||||
addConditionsRecord: addConditionsRecord,
|
||||
addStrategyRecord: addStrategyRecord,
|
||||
addPositionRecord: addPositionRecord,
|
||||
appendRecords: appendRecords,
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
let tradingEngine
|
||||
let tradingSystem
|
||||
let outputDatasets
|
||||
let outputDatasetsMap
|
||||
|
||||
return thisObject
|
||||
|
||||
function initialize() {
|
||||
function initialize(pOutputDatasets, pOutputDatasetsMap) {
|
||||
tradingEngine = bot.TRADING_ENGINE
|
||||
tradingSystem = bot.TRADING_SYSTEM
|
||||
outputDatasets = pOutputDatasets // These are the nodes defined at the UI
|
||||
outputDatasetsMap = pOutputDatasetsMap // These are the files turned into arrays, stored in a Map by Product codeName.
|
||||
}
|
||||
|
||||
function finalize() {
|
||||
tradingEngine = undefined
|
||||
tradingSystem = undefined
|
||||
outputDatasets = undefined
|
||||
outputDatasetsMap = undefined
|
||||
}
|
||||
|
||||
function addSimulationRecord() {
|
||||
/* Simulation Record */
|
||||
let simulationRecord
|
||||
|
||||
if (tradingEngine.current.balance.baseAsset.value === Infinity) {
|
||||
tradingEngine.current.balance.baseAsset.value = Number.MAX_SAFE_INTEGER
|
||||
}
|
||||
|
||||
if (tradingEngine.current.balance.quotedAsset.value === Infinity) {
|
||||
tradingEngine.current.balance.quotedAsset.value = Number.MAX_SAFE_INTEGER
|
||||
}
|
||||
|
||||
simulationRecord = [
|
||||
candle.begin,
|
||||
candle.end,
|
||||
tradingEngine.current.balance.baseAsset.value,
|
||||
tradingEngine.current.balance.quotedAsset.value,
|
||||
tradingEngine.episode.episodeStatistics.profitLoss.value,
|
||||
tradingEngine.last.position.profitLoss.value,
|
||||
tradingEngine.current.position.stopLoss.value,
|
||||
tradingEngine.episode.positionCounters.positions.value,
|
||||
tradingEngine.episode.episodeCounters.hits.value,
|
||||
tradingEngine.episode.episodeCounters.fails.value,
|
||||
tradingEngine.episode.episodeStatistics.hitRatio.value,
|
||||
tradingEngine.episode.episodeStatistics.ROI.value,
|
||||
tradingEngine.episode.episodeCounters.periods,
|
||||
tradingEngine.episode.episodeStatistics.days,
|
||||
tradingEngine.episode.episodeStatistics.anualizedRateOfReturn.value,
|
||||
tradingEngine.current.position.rate.value,
|
||||
tradingEngine.last.position.ROI.value,
|
||||
tradingEngine.current.position.takeProfit.value,
|
||||
tradingEngine.current.position.stopLoss.stopLossPhase.value,
|
||||
tradingEngine.current.position.takeProfit.takeProfitPhase.value,
|
||||
tradingEngine.current.position.size.value,
|
||||
sessionParameters.sessionBaseAsset.config.initialBalance,
|
||||
sessionParameters.sessionBaseAsset.config.minimumBalance,
|
||||
sessionParameters.sessionBaseAsset.config.maximumBalance,
|
||||
sessionParameters.sessionQuotedAsset.config.initialBalance,
|
||||
sessionParameters.sessionQuotedAsset.config.minimumBalance,
|
||||
sessionParameters.sessionQuotedAsset.config.maximumBalance,
|
||||
'"' + sessionParameters.sessionBaseAsset.name + '"',
|
||||
'"' + sessionParameters.sessionQuotedAsset.name + '"',
|
||||
'"' + bot.market.marketBaseAsset + '"',
|
||||
'"' + bot.market.marketQuotedAsset + '"',
|
||||
tradingEngine.current.position.positionCounters.periods.value,
|
||||
tradingEngine.current.position.positionStatistics.days.value
|
||||
]
|
||||
|
||||
recordsArray.push(simulationRecord)
|
||||
}
|
||||
|
||||
function addConditionsRecord() {
|
||||
/* Prepare the information for the Conditions File */
|
||||
let conditionsRecord = [
|
||||
candle.begin,
|
||||
candle.end,
|
||||
tradingEngine.current.strategy.index.value,
|
||||
tradingEngine.current.position.stopLoss.stopLossPhase.value,
|
||||
tradingEngine.current.position.takeProfit.takeProfitPhase.value,
|
||||
conditionsValues,
|
||||
formulasErrors,
|
||||
formulasValues
|
||||
]
|
||||
|
||||
conditionsArray.push(conditionsRecord)
|
||||
}
|
||||
|
||||
function addStrategyRecord() {
|
||||
function appendRecords() {
|
||||
/*
|
||||
Lets see if there will be an open strategy ...
|
||||
Except if we are at the head of the market (remember we skipped the last candle for not being closed.)
|
||||
*/
|
||||
if (
|
||||
tradingEngine.current.strategy.begin.value !== 0 &&
|
||||
tradingEngine.current.strategy.end.value === 0 &&
|
||||
currentCandleIndex === candles.length - 2 &&
|
||||
lastCandle.end !== lastInstantOfTheDay
|
||||
) {
|
||||
tradingEngine.current.strategy.status.value = 'Open'
|
||||
tradingEngine.current.strategy.end.value = candle.end
|
||||
}
|
||||
Here we add records to the output files. At the product config property nodePath
|
||||
we have a pointer to the node that have the information we need to extract.
|
||||
Later, based on the product record definition we will extract each individual value.
|
||||
*/
|
||||
for (let i = 0; i < outputDatasets.length; i++) {
|
||||
let outputDatasetNode = outputDatasets[i]
|
||||
let dataset = outputDatasetNode.referenceParent
|
||||
let product = dataset.parentNode
|
||||
let record
|
||||
|
||||
/* Prepare the information for the Strategies File */
|
||||
if (tradingEngine.current.strategy.begin.value !== 0 && tradingEngine.current.strategy.end.value !== 0) {
|
||||
let strategyRecord = [
|
||||
tradingEngine.current.strategy.begin.value,
|
||||
tradingEngine.current.strategy.end.value,
|
||||
tradingEngine.current.strategy.status.value,
|
||||
tradingEngine.current.strategy.index.value,
|
||||
tradingEngine.current.strategy.beginRate.value,
|
||||
tradingEngine.current.strategy.endRate.value,
|
||||
'"' + tradingEngine.current.strategy.situationName.value + '"',
|
||||
'"' + tradingEngine.current.strategy.strategyName.value + '"'
|
||||
]
|
||||
|
||||
strategiesArray.push(strategyRecord)
|
||||
|
||||
inializeCurrentStrategy()
|
||||
}
|
||||
}
|
||||
|
||||
function addPositionRecord() {
|
||||
/*
|
||||
Lets see if there will be an open trade ...
|
||||
Except if we are at the head of the market (remember we skipped the last candle for not being closed.)
|
||||
*/
|
||||
if (tradingEngine.current.position.begin.value !== 0 &&
|
||||
tradingEngine.current.position.end.value === 0 &&
|
||||
currentCandleIndex === candles.length - 2 &&
|
||||
lastCandle.end !== lastInstantOfTheDay) {
|
||||
|
||||
/* This means the trade is open */
|
||||
tradingEngine.current.position.status.value = 2
|
||||
tradingEngine.current.position.end.value = candle.end
|
||||
tradingEngine.current.position.endRate.value = candle.close
|
||||
|
||||
/* Here we will calculate the ongoing ROI */
|
||||
if (sessionParameters.sessionBaseAsset.name === bot.market.marketBaseAsset) {
|
||||
tradingEngine.current.position.positionStatistics.ROI.value = (tradingEngine.current.position.rate.value - candle.close) / tradingEngine.current.position.rate.value * 100
|
||||
} else {
|
||||
tradingEngine.current.position.positionStatistics.ROI.value = (candle.close - tradingEngine.current.position.rate.value) / tradingEngine.current.position.rate.value * 100
|
||||
if (bot.processingDailyFiles === true && dataset.config.type === 'Daily Files') {
|
||||
record = scanRecordDefinition(product)
|
||||
}
|
||||
|
||||
if (bot.processingDailyFiles === false && dataset.config.type === 'Market Files') {
|
||||
record = scanRecordDefinition(product)
|
||||
}
|
||||
|
||||
let outputDatasetArray = outputDatasetsMap.get(product.config.codeName)
|
||||
outputDatasetArray.push(record)
|
||||
}
|
||||
|
||||
/* Prepare the information for the Positions File */
|
||||
if (tradingEngine.current.position.begin.value !== 0 && tradingEngine.current.position.end.value !== 0) {
|
||||
let positionRecord = [
|
||||
tradingEngine.current.position.begin.value,
|
||||
tradingEngine.current.position.end.value,
|
||||
tradingEngine.current.position.status.value,
|
||||
tradingEngine.current.position.positionStatistics.ROI.value,
|
||||
tradingEngine.current.position.beginRate.value,
|
||||
tradingEngine.current.position.endRate.value,
|
||||
tradingEngine.current.position.exitType.value,
|
||||
'"' + tradingEngine.current.position.situationName.value + '"'
|
||||
]
|
||||
function scanRecordDefinition(product) {
|
||||
let rootNode = eval(product.config.nodePath)
|
||||
let record = []
|
||||
for (let j = 0; j < product.recordDefinition.recordProperties.length; j++) {
|
||||
let recordProperty = product.recordDefinition.recordProperties[j]
|
||||
let value
|
||||
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
|
||||
}
|
||||
if (value === Infinity) {
|
||||
value = Number.MAX_SAFE_INTEGER
|
||||
}
|
||||
if (recordProperty.config.isString === true) {
|
||||
value = '"' + value + '"'
|
||||
}
|
||||
record.push(value)
|
||||
}
|
||||
|
||||
positionsArray.push(positionRecord)
|
||||
|
||||
initializeCurrentPosition()
|
||||
return record
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,8 @@
|
||||
exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILITIES) {
|
||||
const FULL_LOG = true
|
||||
const LOG_FILE_CONTENT = false
|
||||
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000
|
||||
const MODULE_NAME = 'Trading Simulation -> ' + bot.SESSION.name
|
||||
|
||||
const GMT_SECONDS = ':00.000 GMT+0000'
|
||||
|
||||
let thisObject = {
|
||||
finalize: finalize,
|
||||
runSimulation: runSimulation
|
||||
@@ -22,25 +19,13 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
|
||||
function runSimulation(
|
||||
chart,
|
||||
dataDependencies,
|
||||
timeFrame,
|
||||
timeFrameLabel,
|
||||
currentDay,
|
||||
simulationState,
|
||||
exchangeAPI,
|
||||
recordsArray,
|
||||
conditionsArray,
|
||||
strategiesArray,
|
||||
positionsArray,
|
||||
outputDatasets,
|
||||
outputDatasetsMap,
|
||||
callback,
|
||||
callBackFunction) {
|
||||
try {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> Entering function.') }
|
||||
let processingDailyFiles
|
||||
if (timeFrame > global.dailyFilePeriods[0][0]) {
|
||||
processingDailyFiles = false
|
||||
} else {
|
||||
processingDailyFiles = true
|
||||
}
|
||||
|
||||
let tradingSystem = simulationState.tradingSystem
|
||||
let tradingEngine = simulationState.tradingEngine
|
||||
@@ -63,12 +48,6 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
|
||||
let takePositionNow = false
|
||||
let closePositionNow = false
|
||||
|
||||
/* In some cases we need to know if we are positioned at the last candle of the calendar day, for that we need these variables. */
|
||||
let lastInstantOfTheDay = 0
|
||||
if (currentDay) {
|
||||
lastInstantOfTheDay = currentDay.valueOf() + ONE_DAY_IN_MILISECONDS - 1
|
||||
}
|
||||
|
||||
/* These are the Modules we will need to run the Simulation */
|
||||
const TRADING_ENGINE_MODULE = require('./TradingEngine.js')
|
||||
let tradingEngineModule = TRADING_ENGINE_MODULE.newTradingEngine(bot, logger)
|
||||
@@ -80,7 +59,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
|
||||
|
||||
const TRADING_RECORDS_MODULE = require('./TradingRecords.js')
|
||||
let tradingRecordsModule = TRADING_RECORDS_MODULE.newTradingRecords(bot, logger)
|
||||
tradingRecordsModule.initialize()
|
||||
tradingRecordsModule.initialize(outputDatasets, outputDatasetsMap)
|
||||
|
||||
const SNAPSHOTS_MODULE = require('./Snapshots.js')
|
||||
let snapshotsModule = SNAPSHOTS_MODULE.newSnapshots(bot, logger)
|
||||
@@ -255,18 +234,13 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
|
||||
}
|
||||
|
||||
snapshotsModule.manageSnapshots()
|
||||
tradingRecordsModule.addSimulationRecord()
|
||||
tradingRecordsModule.addConditionsRecord()
|
||||
tradingRecordsModule.addStrategyRecord()
|
||||
tradingRecordsModule.addPositionRecord()
|
||||
tradingRecordsModule.appendRecords()
|
||||
annoucementsModule.makeAnnoucements() // After everything at the simulation level was done, we will do the annoucements that are pending.
|
||||
|
||||
controlLoop()
|
||||
}
|
||||
|
||||
function controlLoop() {
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> controlLoop -> Entering function.') }
|
||||
|
||||
/* Checking if we should continue processing this loop or not. */
|
||||
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.') }
|
||||
@@ -374,7 +348,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
|
||||
*/
|
||||
|
||||
/* Finding the Current Element on Market Files */
|
||||
if (processingDailyFiles) {
|
||||
if (bot.processingDailyFiles) {
|
||||
for (let j = 0; j < global.dailyFilePeriods.length; j++) {
|
||||
let mapKey = dailyFilePeriods[j][1]
|
||||
let propertyName = 'at' + mapKey.replace('-', '')
|
||||
@@ -430,7 +404,7 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
|
||||
We skip the candle at the head of the market because it has not closed yet. The procedure to determine if we are at the head of the market is different
|
||||
when we are processing Market Files than when we are processing Daily Files. TODO Check that the procedure is good for Beta 6
|
||||
*/
|
||||
if (processingDailyFiles) { // We are processing Daily Files
|
||||
if (bot.processingDailyFiles) { // We are processing Daily Files
|
||||
let candlesPerDay = ONE_DAY_IN_MILISECONDS / sessionParameters.timeFrame.config.value
|
||||
if (tradingEngine.current.candle.index.value === candles.length - 1) {
|
||||
if ((candles.length < candlesPerDay) || (candles.length > candlesPerDay && candles.length < candlesPerDay * 2)) {
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
let USER_BOT_MODULE;
|
||||
let USER_BOT_COMMONS;
|
||||
|
||||
const MULTI_PERIOD_MARKET = require(ROOT_DIR + 'MultiPeriodMarket');
|
||||
const MULTI_PERIOD_DAILY = require(ROOT_DIR + 'MultiPeriodDaily');
|
||||
const MULTI_PERIOD = require(ROOT_DIR + 'MultiPeriod');
|
||||
const TRADING_PROCESS_MODULE = require(ROOT_DIR + '/Trading/TradingProcess.js');
|
||||
const FILE_STORAGE = require('./FileStorage.js');
|
||||
const SESSION = require(ROOT_DIR + 'Session');
|
||||
|
||||
@@ -526,8 +524,8 @@
|
||||
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeExchangeAPI -> onInizialized -> Execution finished well."); }
|
||||
|
||||
switch (processConfig.framework.name) {
|
||||
case 'Multi-Period': {
|
||||
processFramework = MULTI_PERIOD.newMultiPeriod(bot, logger, UTILITIES, USER_BOT_MODULE, USER_BOT_COMMONS);
|
||||
case 'Trading-Process': {
|
||||
processFramework = TRADING_PROCESS_MODULE.newTradingProcess(bot, logger, UTILITIES, USER_BOT_MODULE, USER_BOT_COMMONS);
|
||||
intitializeProcessFramework();
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user