Files
Superalgos/Session.js
T

341 lines
17 KiB
JavaScript

exports.newSession = function newSession(bot, parentLogger) {
const MODULE_NAME = "Session"
const FULL_LOG = true;
let thisObject = {
initialize: initialize
}
return thisObject;
function initialize(callBackFunction) {
try {
if (FULL_LOG === true) { parentLogger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
/* Initialize this info so that everything is logged propeerly */
bot.SESSION = {
name: bot.processNode.session.name
}
/* Check if there is a session */
if (bot.processNode.session === undefined) {
parentLogger.write(MODULE_NAME, "[ERROR] initialize -> Cannot run without a Session.");
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
/* Listen to event to start or stop the session. */
bot.sessionKey = bot.processNode.session.name + '-' + bot.processNode.session.type + '-' + bot.processNode.session.id
global.SYSTEM_EVENT_HANDLER.listenToEvent(bot.sessionKey, 'Run Session', undefined, undefined, undefined, runSession)
global.SYSTEM_EVENT_HANDLER.listenToEvent(bot.sessionKey, 'Stop Session', undefined, undefined, undefined, stopSession)
function runSession(message) {
/* We are going to run the Definition comming at the event. */
bot.DEFINITION = JSON.parse(message.event.definition)
bot.SESSION = JSON.parse(message.event.session)
setValuesToUse(message)
switch (bot.SESSION.type) {
case 'Backtesting Session': {
startBackTesting(message)
break
}
case 'Live Trading Session': {
startLiveTrading(message)
break
}
}
bot.SESSION_STATUS = 'Idle'
bot.STOP_SESSION = false
}
function stopSession(message) {
bot.STOP_SESSION = true
}
function startBackTesting(message) {
bot.startMode = "Backtest"
bot.resumeExecution = false;
bot.hasTheBotJustStarted = true
bot.multiPeriodProcessDatetime = bot.VALUES_TO_USE.timeRange.initialDatetime
}
function startLiveTrading(message) {
if (bot.DEFINITION.personalData) {
if (bot.DEFINITION.personalData.exchangeAccounts) {
if (bot.DEFINITION.personalData.exchangeAccounts.length > 0) {
let exchangeAccount = bot.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
}
}
}
}
}
if (process.env.KEY === undefined || process.env.SECRET === undefined) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[WARN] initialize -> startLiveTrading -> Key name or Secret not provided, not possible to run the process in Live mode."); }
return
}
bot.startMode = "Live"
if (bot.VALUES_TO_USE.timeRange.initialDatetime.valueOf() < (new Date()).valueOf) {
bot.VALUES_TO_USE.timeRange.initialDatetime = new Date()
}
bot.resumeExecution = false;
bot.multiPeriodProcessDatetime = bot.VALUES_TO_USE.timeRange.initialDatetime
bot.hasTheBotJustStarted = true
}
function setValuesToUse(message) {
/*
Base on the information received we will determined which values ultimatelly are going to be used,
and once we do, they will become constants across the multiple loops executions.
*/
/* Set all default values */
bot.VALUES_TO_USE = {
baseAsset: "BTC",
initialBalanceA: 0.001,
initialBalanceB: 0,
minimumBalanceA: 0.0005,
minimumBalanceB: 0,
maximumBalanceA: 0.002,
maximumBalanceB: 0,
timePeriod: bot.DEFINITION.uiCurrentValues.timePeriod,
slippage: {
positionRate: 0,
stopLoss: 0,
takeProfit: 0
},
feeStructure: {
maker: 0,
taker: 0
},
timeRange: {
initialDatetime: new Date(),
finalDatetime: new Date()
}
}
/* Session Type Dependant Default Values */
const ONE_YEAR_IN_MILISECONDS = 365 * 24 * 60 * 60 * 1000
switch (bot.SESSION.type) {
case 'Backtesting Session': {
bot.VALUES_TO_USE.timeRange.initialDatetime = new Date(bot.DEFINITION.uiCurrentValues.initialDatetime)
bot.VALUES_TO_USE.timeRange.finalDatetime = new Date()
break
}
case 'Live Trading Session': {
bot.VALUES_TO_USE.timeRange.initialDatetime = new Date()
bot.VALUES_TO_USE.timeRange.finalDatetime = new Date((new Date()).valueOf() + ONE_YEAR_IN_MILISECONDS)
break
}
}
let tradingSystem = bot.DEFINITION.tradingSystem
if (tradingSystem !== undefined) {
/* Applying Trading System Level Parameters */
if (tradingSystem.parameters !== undefined) {
/* Base Asset and Initial Balances. */
{
if (tradingSystem.parameters.baseAsset !== undefined) {
let code
try {
code = JSON.parse(tradingSystem.parameters.baseAsset.code);
if (code.name !== undefined) {
bot.VALUES_TO_USE.baseAsset = code.name;
}
if (baseAsset === 'BTC') {
if (code.initialBalance !== undefined) {
bot.VALUES_TO_USE.initialBalanceA = code.initialBalance;
bot.VALUES_TO_USE.initialBalanceB = 0
}
if (code.minimumBalance !== undefined) {
bot.VALUES_TO_USE.minimumBalanceA = code.minimumBalance;
bot.VALUES_TO_USE.minimumBalanceB = 0
}
if (code.maximumBalance !== undefined) {
bot.VALUES_TO_USE.maximumBalanceA = code.maximumBalance;
bot.VALUES_TO_USE.maximumBalanceB = 0
}
} else {
if (code.initialBalance !== undefined) {
bot.VALUES_TO_USE.initialBalanceB = code.initialBalance;
bot.VALUES_TO_USE.initialBalanceA = 0
}
if (code.minimumBalance !== undefined) {
bot.VALUES_TO_USE.minimumBalanceB = code.minimumBalance;
bot.VALUES_TO_USE.minimumBalanceA = 0
}
if (code.maximumBalance !== undefined) {
bot.VALUES_TO_USE.maximumBalanceB = code.maximumBalance;
bot.VALUES_TO_USE.maximumBalanceA = 0
}
}
} catch (err) {
tradingSystem.parameters.baseAsset.error = err.message
}
}
}
/* Time Period */
if (tradingSystem.parameters.timePeriod !== undefined) {
bot.VALUES_TO_USE.timePeriod = tradingSystem.parameters.timePeriod.code
}
/* Slippage */
if (tradingSystem.parameters.slippage !== undefined) {
if (tradingSystem.parameters.slippage.code !== undefined) {
try {
let code = JSON.parse(tradingSystem.parameters.slippage.code)
if (code.positionRate !== undefined) {
bot.VALUES_TO_USE.slippage.positionRate = code.positionRate
}
if (code.stopLoss !== undefined) {
bot.VALUES_TO_USE.slippage.stopLoss = code.stopLoss
}
if (code.takeProfit !== undefined) {
bot.VALUES_TO_USE.slippage.takeProfit = code.takeProfit
}
} catch (err) {
tradingSystem.parameters.slippage.error = err.message
}
}
}
/* Fee Structure */
if (tradingSystem.parameters.feeStructure !== undefined) {
if (tradingSystem.parameters.feeStructure.code !== undefined) {
try {
let code = JSON.parse(tradingSystem.parameters.feeStructure.code)
if (code.maker !== undefined) {
bot.VALUES_TO_USE.feeStructure.maker = code.maker
}
if (code.taker !== undefined) {
bot.VALUES_TO_USE.feeStructure.taker = code.taker
}
} catch (err) {
tradingSystem.parameters.feeStructure.error = err.message
}
}
}
/* Time Range */
if (tradingSystem.parameters.timeRange !== undefined) {
if (tradingSystem.parameters.timeRange.code !== undefined) {
try {
let code = JSON.parse(tradingSystem.parameters.timeRange.code)
if (code.initialDatetime !== undefined) {
bot.VALUES_TO_USE.timeRange.initialDatetime = new Date(code.initialDatetime)
}
if (code.finalDatetime !== undefined) {
bot.VALUES_TO_USE.timeRange.finalDatetime = new Date(code.finalDatetime)
}
} catch (err) {
tradingSystem.parameters.timeRange.error = err.message
}
}
}
}
/* Applying Session Level Parameters */
if (bot.SESSION !== undefined) {
if (bot.SESSION.parameters !== undefined) {
/* Time Period */
if (bot.SESSION.parameters.timePeriod !== undefined) {
bot.VALUES_TO_USE.timePeriod = bot.SESSION.parameters.timePeriod.code
}
/* Slippage */
if (bot.SESSION.parameters.slippage !== undefined) {
if (bot.SESSION.parameters.slippage.code !== undefined) {
try {
let code = JSON.parse(bot.SESSION.parameters.slippage.code)
if (code.positionRate !== undefined) {
bot.VALUES_TO_USE.slippage.positionRate = code.positionRate
}
if (code.stopLoss !== undefined) {
bot.VALUES_TO_USE.slippage.stopLoss = code.stopLoss
}
if (code.takeProfit !== undefined) {
bot.VALUES_TO_USE.slippage.takeProfit = code.takeProfit
}
} catch (err) {
parentLogger.write(MODULE_NAME, "[WARN] initialize -> startLiveTrading -> Invalid Slippage Value -> err = " + err.stack);
}
}
}
/* Fee Structure */
if (bot.SESSION.parameters.feeStructure !== undefined) {
if (bot.SESSION.parameters.feeStructure.code !== undefined) {
try {
let code = JSON.parse(bot.SESSION.parameters.feeStructure.code)
if (code.maker !== undefined) {
bot.VALUES_TO_USE.feeStructure.maker = code.maker
}
if (code.taker !== undefined) {
bot.VALUES_TO_USE.feeStructure.taker = code.taker
}
} catch (err) {
parentLogger.write(MODULE_NAME, "[WARN] initialize -> startLiveTrading -> Invalid Fee Structure Value -> err = " + err.stack);
}
}
}
/* Time Range */
if (bot.SESSION.parameters.timeRange !== undefined) {
if (bot.SESSION.parameters.timeRange.code !== undefined) {
try {
let code = JSON.parse(bot.SESSION.parameters.timeRange.code)
if (code.initialDatetime !== undefined) {
bot.VALUES_TO_USE.timeRange.initialDatetime = new Date(code.initialDatetime)
}
if (code.finalDatetime !== undefined) {
bot.VALUES_TO_USE.timeRange.finalDatetime = new Date(code.finalDatetime)
}
} catch (err) {
parentLogger.write(MODULE_NAME, "[WARN] initialize -> startLiveTrading -> Invalid Time Range Value -> err = " + err.stack);
}
}
}
}
}
}
}
callBackFunction(global.DEFAULT_OK_RESPONSE)
} catch (err) {
parentLogger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
};