Files
Superalgos/Run.js
T

338 lines
13 KiB
JavaScript

require('dotenv').config();
const strategy = require('./Integrations/Strategy');
const path = require('path');
global.SHALL_BOT_STOP = false
global.AT_BREAKPOINT = false // This is used only when running at the browser.
global.FULL_LOG = process.env.FULL_LOG
/* Default parameters can be changed by the execution configuration */
global.EXCHANGE_NAME = process.env.EXCHANGE_NAME
global.MARKET = { assetA: 'USDT', assetB: 'BTC' }
global.CLONE_EXECUTOR = { codeName: 'AACloud', version: '1.1' }
process.on('uncaughtException', function (err) {
console.log('[INFO] Run -> uncaughtException -> err.message = ' + err.message)
console.log('[INFO] Run -> uncaughtException -> err.stack = ' + err.stack)
process.exit(1)
})
process.on('unhandledRejection', (reason, p) => {
console.log('[INFO] Run -> unhandledRejection -> reason = ' + JSON.stringify(reason))
console.log('[INFO] Run -> unhandledRejection -> p = ' + JSON.stringify(p))
process.exit(1)
})
process.on('exit', function (code) {
console.log('[INFO] Run -> process.on.exit -> About to exit -> code = ' + code)
})
const definitionPath = path.resolve(process.env.INTER_PROCESS_FILES_PATH + '/definition.json');
const definition = require(definitionPath);
let sequenceList = require('./sequence');
let isRunSequence = false;
let sequenceStep = 0;
let processedSteps = new Map()
if (process.env.RUN_SEQUENCE !== undefined) {
isRunSequence = JSON.parse(process.env.RUN_SEQUENCE)
}
if (isRunSequence) {
sequenceExecution(sequenceStep, false)
} else {
readExecutionConfiguration()
}
function sequenceExecution(currentStep, notFirstSequence) {
let execution = sequenceList[currentStep];
process.env.STOP_GRACEFULLY = true;
execution.devTeam ? process.env.DEV_TEAM = execution.devTeam : undefined;
execution.bot ? process.env.BOT = execution.bot : undefined;
execution.mode ? process.env.START_MODE = execution.mode : undefined;
execution.resumeExecution = notFirstSequence
execution.type ? process.env.TYPE = execution.type : undefined;
execution.process ? process.env.PROCESS = execution.process : undefined;
execution.startYear ? process.env.MIN_YEAR = execution.startYear : undefined;
execution.endYear ? process.env.MAX_YEAR = execution.endYear : undefined;
execution.month ? process.env.MONTH = execution.month : undefined;
execution.beginDatetime ? process.env.BEGIN_DATE_TIME = execution.beginDatetime : undefined;
execution.endDatetime ? process.env.END_DATE_TIME = execution.endDatetime : undefined;
execution.dataSet ? process.env.DATA_SET = execution.dataSet : undefined;
execution.timePeriod ? process.env.TIME_PERIOD = execution.timePeriod : undefined;
execution.baseAsset ? process.env.BASE_ASSET = execution.baseAsset : undefined;
execution.balanceAssetA ? process.env.INITIAL_BALANCE_ASSET_A = execution.balanceAssetA : undefined;
execution.balanceAssetB ? process.env.INITIAL_BALANCE_ASSET_B = execution.balanceAssetB : undefined;
execution.type === 'Trading' ? process.env.CLONE_ID = 1 : undefined;
execution.exchangeName ? global.EXCHANGE_NAME = execution.exchangeName : undefined;
if (definition)
{
if (definition.personalData) {
if (definition.personalData.exchangeAccounts) {
if (definition.personalData.exchangeAccounts.length > 0) {
let exchangeAccount = definition.personalData.exchangeAccounts[0]
if (exchangeAccount.keys) {
if (exchangeAccount.keys.length > 0) {
let key = exchangeAccount.keys[0]
process.env.KEY = key.name
process.env.SECRET = key.code
}
}
}
}
}
}
let stepKey = execution.devTeam + '.' + execution.bot + '.' + execution.process;
if (processedSteps.has(stepKey)) {
processedSteps.set(stepKey, processedSteps.get(stepKey) + 1);
} else {
processedSteps.set(stepKey, 0);
}
console.log("Sequence Execution Parameters: " + JSON.stringify(execution))
readExecutionConfiguration(execution);
sequenceStep++;
}
function onExecutionFinish(result, finishStepKey) {
processedSteps.set(finishStepKey, processedSteps.get(finishStepKey) + 1)
if (processedSteps.get(finishStepKey) > 1) {
console.log('[INFO] onExecutionFinish -> Step already processed.')
} else {
if (sequenceStep < sequenceList.length) {
sequenceExecution(sequenceStep, true)
} else {
if (sequenceStep < sequenceList.length) {
sequenceExecution(sequenceStep, true);
} else {
setTimeout(function () {
console.log("[INFO] onExecutionFinish -> New round for sequence execution started.");
sequenceList = require('./sequence'); // We read again the sequence after every loop
sequenceStep = 0;
processedSteps = new Map();
sequenceExecution(sequenceStep, true);
}, process.env.EXECUTION_LOOP_DELAY);
}
}
}
}
async function readExecutionConfiguration(execution) {
try {
console.log("[INFO] Run -> readExecutionConfiguration -> Entering function. ");
let timePeriod
let botProcess
/* Try to get the begin and end dates from the Definition */
let definition = await strategy.getStrategy()
/* Dates are taken initially from .env, but can be overwritten if they are defined by the user */
let initialDatetime = process.env.BEGIN_DATE_TIME
let finalDatetime = process.env.END_DATE_TIME
if (execution.type === 'Trading-Engine') {
if (definition !== undefined) {
if (definition.simulationParams !== undefined) {
if (definition.simulationParams.beginDatetime !== undefined) {
initialDatetime = new Date(definition.simulationParams.beginDatetime) /* The first override occurs here, with the simulation parameters */
}
/* Here we only look for one timePeriod, in the future we will be able to process the whole array, but not for now. */
if (definition.simulationParams.timePeriodDailyArray !== undefined) {
if (definition.simulationParams.timePeriodDailyArray.length > 0) {
timePeriod = definition.simulationParams.timePeriodDailyArray[0]
botProcess = "Multi-Period-Daily"
}
}
if (definition.simulationParams.timePeriodMarketArray !== undefined) {
if (definition.simulationParams.timePeriodMarketArray.length > 0) {
timePeriod = definition.simulationParams.timePeriodMarketArray[0]
botProcess = "Multi-Period-Market"
}
}
}
if (definition.tradingSystem !== undefined) {
if (definition.tradingSystem.parameters !== undefined) {
if (definition.tradingSystem.parameters.baseAsset !== undefined) {
if (definition.tradingSystem.parameters.baseAsset.formula !== undefined) {
if (definition.tradingSystem.parameters.baseAsset.formula.code !== undefined) {
let code = JSON.parse(definition.tradingSystem.parameters.baseAsset.formula.code)
if (code.initialDatetime !== undefined) {
initialDatetime = code.initialDatetime /* The second override occurs here, with the date explicitelly defined by the user */
}
if (code.finalDatetime !== undefined) {
finalDatetime = code.finalDatetime
}
}
}
}
}
}
}
}
let startMode
// General Financial Being Configuration
global.DEV_TEAM = process.env.DEV_TEAM
global.CURRENT_BOT_REPO = process.env.BOT + "-" + process.env.TYPE + "-Bot"
if (process.env.TYPE === 'Trading' || process.env.TYPE === 'Trading-Engine') {
let live = {
run: 'false',
resumeExecution: execution.resumeExecution,
beginDatetime: initialDatetime,
endDatetime: finalDatetime
}
let backtest = {
run: 'false',
resumeExecution: execution.resumeExecution,
beginDatetime: initialDatetime,
endDatetime: finalDatetime
}
let competition = {
run: 'false',
resumeExecution: execution.resumeExecution,
beginDatetime: initialDatetime,
endDatetime: finalDatetime
}
startMode = {
live: live,
backtest: backtest,
competition: competition
}
} else if (process.env.TYPE === 'Indicator' || process.env.TYPE === 'Sensor') {
let allMonths = {
run: "false",
minYear: process.env.MIN_YEAR,
maxYear: process.env.MAX_YEAR
}
let oneMonth = {
run: "false",
year: process.env.MIN_YEAR,
month: process.env.MONTH
}
let noTime = {
run: "false",
beginDatetime: process.env.BEGIN_DATE_TIME,
resumeExecution: execution.resumeExecution
}
let fixedInterval = {
run: "false",
interval: process.env.INTERVAL
}
startMode = {
allMonths: allMonths,
oneMonth: oneMonth,
noTime: noTime,
fixedInterval: fixedInterval
}
} else {
console.log("[ERROR] readExecutionConfiguration -> Bot Type is invalid.");
throw new Error("readExecutionConfiguration -> Bot Type is invalid.")
}
startMode[process.env.START_MODE].run = "true"
if (botProcess === undefined) { botProcess = process.env.PROCESS } // Only use the .env when nothing comes at Definition.json
let cloneToExecute = {
enabled: "true",
devTeam: process.env.DEV_TEAM,
bot: process.env.BOT,
process: botProcess,
repo: global.CURRENT_BOT_REPO
}
if (timePeriod === undefined) { timePeriod = process.env.TIME_PERIOD } // Only use the .env when nothing comes at Definition.json
global.EXECUTION_CONFIG = {
cloneToExecute: cloneToExecute,
startMode: startMode,
timePeriod: getTimePeriod(timePeriod),
timePeriodFileStorage: timePeriod,
dataSet: process.env.DATA_SET
};
global.CLONE_EXECUTOR = {
codeName: 'AACloud',
version: '1.1'
}
startRoot();
}
catch (err) {
console.log("[ERROR] readExecutionConfiguration -> err = " + err);
console.log("[ERROR] readExecutionConfiguration -> Please verify that the Start Mode for the type of Bot configured applies to that type.");
console.log("[ERROR] readExecutionConfiguration -> err = " + err.stack);
}
}
function getTimePeriod(timePeriod) {
if (timePeriod !== undefined) {
try {
let timePeriodMap = new Map()
timePeriodMap.set('24-hs', 86400000)
timePeriodMap.set('12-hs', 43200000)
timePeriodMap.set('08-hs', 28800000)
timePeriodMap.set('06-hs', 21600000)
timePeriodMap.set('04-hs', 14400000)
timePeriodMap.set('03-hs', 10800000)
timePeriodMap.set('02-hs', 7200000)
timePeriodMap.set('01-hs', 3600000)
timePeriodMap.set('45-min', 2700000)
timePeriodMap.set('40-min', 2400000)
timePeriodMap.set('30-min', 1800000)
timePeriodMap.set('20-min', 1200000)
timePeriodMap.set('15-min', 900000)
timePeriodMap.set('10-min', 600000)
timePeriodMap.set('05-min', 300000)
timePeriodMap.set('04-min', 240000)
timePeriodMap.set('03-min', 180000)
timePeriodMap.set('02-min', 120000)
timePeriodMap.set('01-min', 60000)
return timePeriodMap.get(timePeriod)
} catch (error) {
console.log('[WARN] Run -> readExecutionConfiguration -> getTimePeriod -> Error: ', error)
}
} else {
return undefined
}
}
function startRoot() {
console.log('[INFO] Run -> startRoot -> Entering function. ')
const ROOT_DIR = './'
const ROOT_MODULE = require(ROOT_DIR + 'Root')
let root = ROOT_MODULE.newRoot()
let UI_COMMANDS = {
beginDatetime: undefined,
endDatetime: undefined,
timePeriod: undefined,
startMode: undefined,
eventHandler: undefined
}
root.initialize(UI_COMMANDS, onInitialized)
function onInitialized() {
console.log('[INFO] Run -> startRoot -> onInitialized -> Entering function. ')
root.start(onExecutionFinish)
}
}