diff --git a/CanvasApp/CockpitSpace/AssetBalances.js b/CanvasApp/CockpitSpace/AssetBalances.js index d9fa9ff85..6cb267ef4 100644 --- a/CanvasApp/CockpitSpace/AssetBalances.js +++ b/CanvasApp/CockpitSpace/AssetBalances.js @@ -37,9 +37,6 @@ function newQuotedAssetalances () { for (let i = 0; i < 2; i++) { let speedometer = newSpeedometer() - speedometer.container.frame.position.x = thisObject.container.frame.width / 2 - speedometer.container.frame.width / 2 - speedometer.container.frame.position.y = thisObject.container.frame.height / 2 - speedometer.container.frame.height / 2 - speedometer.initialize() thisObject.speedometers.push(speedometer) } @@ -109,7 +106,7 @@ function newQuotedAssetalances () { label = 'ASSET BALANCES' xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO - yOffset = -45 + yOffset = -45 + 9 labelPoint = { x: 0 - xOffset + (thisObject.paramsArray[1].LEFT_OFFSET - thisObject.paramsArray[0].LEFT_OFFSET) / 2 + thisObject.paramsArray[0].LEFT_OFFSET - 20, @@ -120,3 +117,4 @@ function newQuotedAssetalances () { browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) } } + diff --git a/CanvasApp/CockpitSpace/Speedometer.js b/CanvasApp/CockpitSpace/Speedometer.js index 93178ab38..7a2f0a857 100644 --- a/CanvasApp/CockpitSpace/Speedometer.js +++ b/CanvasApp/CockpitSpace/Speedometer.js @@ -51,13 +51,13 @@ function newSpeedometer () { } function drawAssetCircle () { - const RED_LINE_HIGHT = 5 + const RED_LINE_HIGHT = 2 const RADIUS = 50 const OPACITY = 1 let centerPoint = { x: thisObject.params.LEFT_OFFSET, - y: COCKPIT_SPACE_POSITION - COCKPIT_SPACE_HEIGHT / 2 + y: COCKPIT_SPACE_POSITION - COCKPIT_SPACE_HEIGHT / 2 - 9 } browserCanvasContext.beginPath() diff --git a/CanvasApp/DesignerSpace/Workspace/FunctionLibraries/SessionFunctions.js b/CanvasApp/DesignerSpace/Workspace/FunctionLibraries/SessionFunctions.js index fe40011be..5b967b29d 100644 --- a/CanvasApp/DesignerSpace/Workspace/FunctionLibraries/SessionFunctions.js +++ b/CanvasApp/DesignerSpace/Workspace/FunctionLibraries/SessionFunctions.js @@ -34,6 +34,7 @@ function newSessionFunctions () { 'Trading System->' + 'Parameters->' + 'Base Asset->Time Range->Time Frame->Slippage->Fee Structure->' + + 'Exchange Account Asset->Asset->' + 'Strategy->' + 'Trigger Stage->Trigger On Event->Trigger Off Event->Take Position Event->' + 'Announcement->Telegram Bot->' + @@ -44,14 +45,16 @@ function newSessionFunctions () { 'Stop->Take Profit->' + 'Phase->Formula->Next Phase Event->' + 'Situation->Condition->Javascript Code->' + - 'Announcement->Telegram Bot->' + 'Announcement->Telegram Bot->' + + 'Close Stage->Close Execution->' let tradingSystem = functionLibraryProtocolNode.getProtocolNode(node.payload.referenceParent, false, true, true, false, false, lightingPath) lightingPath = '' + 'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' + 'Parameters->' + - 'Base Asset->Time Range->Time Frame->Slippage->Fee Structure->' + 'Base Asset->Time Range->Time Frame->Slippage->Fee Structure->' + + 'Exchange Account Asset->Asset->' let session = functionLibraryProtocolNode.getProtocolNode(node, false, true, true, false, false, lightingPath) @@ -62,6 +65,11 @@ function newSessionFunctions () { } systemEventHandler.raiseEvent(key, 'Run Session', event) + + if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) { + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) + return + } } function stopSession (node, functionLibraryProtocolNode, callBackFunction) { diff --git a/CanvasApp/FloatingSpace/CircularMenuItem.js b/CanvasApp/FloatingSpace/CircularMenuItem.js index d088385e6..4a66f3679 100644 --- a/CanvasApp/FloatingSpace/CircularMenuItem.js +++ b/CanvasApp/FloatingSpace/CircularMenuItem.js @@ -320,7 +320,7 @@ function newCircularMenuItem () { } } else { if (thisObject.workFailedLabel != undefined) { - setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 500, STATUS_PRIMARY_WORK_FAILED) + setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 250, STATUS_PRIMARY_WORK_FAILED) } } } else { @@ -331,7 +331,7 @@ function newCircularMenuItem () { } } else { if (thisObject.workFailedLabel != undefined) { - setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 500, STATUS_PRIMARY_WORK_FAILED) + setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 250, STATUS_PRIMARY_WORK_FAILED) } } } @@ -343,7 +343,7 @@ function newCircularMenuItem () { } } else { if (thisObject.secondaryWorkFailedLabel != undefined) { - setStatus(thisObject.secondaryWorkFailedLabel, UI_COLOR.TITANIUM_YELLOW, 500, STATUS_SECONDARY_WORK_FAILED) + setStatus(thisObject.secondaryWorkFailedLabel, UI_COLOR.TITANIUM_YELLOW, 250, STATUS_SECONDARY_WORK_FAILED) } } } diff --git a/CanvasApp/Spaces/DesignerSpace.js b/CanvasApp/Spaces/DesignerSpace.js index 1618ab0b1..bbf20057f 100644 --- a/CanvasApp/Spaces/DesignerSpace.js +++ b/CanvasApp/Spaces/DesignerSpace.js @@ -232,7 +232,13 @@ function newDesignerSpace () { 'angle-to-parent-180', 'angle-to-parent-090', 'angle-to-parent-045', - 'angle-to-parent-000' + 'angle-to-parent-000', + 'data-mining', + 'initial-definition', + 'next-phase-event', + 'testing-environment', + 'production-environment', + 'task-manager' ] for (let i = 0; i < iconsNames.length; i++) { diff --git a/Inter-Process-Files/AppSchema.json b/Inter-Process-Files/AppSchema.json index 840d8fdb8..787e8936f 100644 --- a/Inter-Process-Files/AppSchema.json +++ b/Inter-Process-Files/AppSchema.json @@ -976,7 +976,7 @@ "chainAttachesTo": { "compatibleTypes": "->Data Mining->Testing Environment->Production Environment->" }, - "icon": "task", + "icon": "task-manager", "properties": [ { "name": "tasks", @@ -3523,7 +3523,7 @@ "chainAttachesTo": { "compatibleTypes": "->Open Stage->" }, - "icon": "task", + "icon": "initial-definition", "properties": [ { "name": "stopLoss", @@ -3713,7 +3713,7 @@ "chainAttachesTo": { "compatibleTypes": "->Phase->" }, - "icon": "pantone", + "icon": "next-phase-event", "properties": [ { "name": "situations", @@ -5293,7 +5293,7 @@ ], "addLeftIcons": true, "level": 2, - "icon": "data-storage", + "icon": "data-mining", "chainAttachesTo": { "compatibleTypes": "->Network Node->" }, @@ -5328,7 +5328,7 @@ ], "addLeftIcons": true, "level": 2, - "icon": "data-storage", + "icon": "testing-environment", "chainAttachesTo": { "compatibleTypes": "->Network Node->" }, @@ -5363,7 +5363,7 @@ ], "addLeftIcons": true, "level": 2, - "icon": "data-storage", + "icon": "production-environment", "chainAttachesTo": { "compatibleTypes": "->Network Node->" }, diff --git a/Legacy-Code/AAMasters/bots/AACharly-Sensor-Bot/Historic-Trades/User.Bot.js b/Legacy-Code/AAMasters/bots/AACharly-Sensor-Bot/Historic-Trades/User.Bot.js index 333539f29..b89352ef4 100644 --- a/Legacy-Code/AAMasters/bots/AACharly-Sensor-Bot/Historic-Trades/User.Bot.js +++ b/Legacy-Code/AAMasters/bots/AACharly-Sensor-Bot/Historic-Trades/User.Bot.js @@ -27,6 +27,14 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt let initialProcessTimestamp let beginingOfMarket let lastFileSaved + let exchangeId + let options = {} + let fetchType = "by Time" + let lastId + let firstId + let exchange + + const limit = 1000 return thisObject; @@ -37,27 +45,8 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt logger.initialize(); statusDependencies = pStatusDependencies; - callBackFunction(global.DEFAULT_OK_RESPONSE); - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - - function start(callBackFunction) { - try { - - if (global.STOP_TASK_GRACEFULLY === true) { - callBackFunction(global.DEFAULT_OK_RESPONSE); - return - } - - let exchangeId = bot.exchange.toLowerCase() - let options = {} - let fetchType = "by Time" - let lastId - let firstId + exchangeId = bot.exchange.toLowerCase() /* Applying the parameters defined by the user at the Exchange node */ if (bot.exchangeNode.code.API !== undefined) { @@ -87,7 +76,7 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt if (key === "undefined") { key = undefined } if (secret === "undefined") { secret = undefined } - const limit = 1000 + const exchangeClass = ccxt[exchangeId] const exchangeConstructorParams = { 'apiKey': key, @@ -98,7 +87,23 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt options: options } - const exchange = new exchangeClass(exchangeConstructorParams) + exchange = new exchangeClass(exchangeConstructorParams) + + callBackFunction(global.DEFAULT_OK_RESPONSE); + + } catch (err) { + logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function start(callBackFunction) { + try { + + if (global.STOP_TASK_GRACEFULLY === true) { + callBackFunction(global.DEFAULT_OK_RESPONSE); + return + } begin() @@ -219,7 +224,7 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getTrades -> Trades Fetched to " + endDate) } } - if (trades.length > 1 && allTrades.length < MAX_TRADES_PER_EXECUTION) { + if (trades.length > 1) { previousSince = since since = trades[trades.length - 1]['timestamp'] if (since === previousSince) { @@ -240,20 +245,20 @@ exports.newUserBot = function newUserBot(bot, logger, COMMONS, UTILITIES, fileSt if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> getTrades -> Fetching Trades @ " + processingDate + "-> exchange = " + bot.exchange + " -> symbol = " + symbol + " -> since = " + since + " -> limit = " + limit) } bot.processHeartBeat("Fetching " + allTrades.length.toFixed(0) + " trades from " + bot.exchange + " " + symbol + " @ " + processingDate) // tell the world we are alive and doing well - } else { - break } - if (global.STOP_TASK_GRACEFULLY === true) { + + if ( + trades.length < limit - 1 || + global.STOP_TASK_GRACEFULLY === true || + allTrades.length >= MAX_TRADES_PER_EXECUTION + ) { break } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] start -> getTrades -> err = " + err.stack); - if (err.message.indexOf('exchange is down or offline') >= 0) { - callBackFunction(global.DEFAULT_RETRY_RESPONSE); - } else { - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } + logger.write(MODULE_NAME, "[ERROR] start -> getTrades -> Retrying Later -> err = " + err.stack); + callBackFunction(global.DEFAULT_RETRY_RESPONSE); + } } diff --git a/Legacy-Code/AAMasters/plotters/Plotters-Trading-Simulation/TradingSimulation.js b/Legacy-Code/AAMasters/plotters/Plotters-Trading-Simulation/TradingSimulation.js index 21d966750..856a22f61 100644 --- a/Legacy-Code/AAMasters/plotters/Plotters-Trading-Simulation/TradingSimulation.js +++ b/Legacy-Code/AAMasters/plotters/Plotters-Trading-Simulation/TradingSimulation.js @@ -668,7 +668,7 @@ let imagePosition = { x: recordPoint4.x + imageOffset.x, - y: recordPoint4.y + imageOffset.y + y: 0 } imagePosition = canvas.chartSpace.viewport.fitIntoVisibleArea(imagePosition) diff --git a/TaskServer/Assistant.js b/TaskServer/Assistant.js index 00d3176bb..9a98b1cbd 100644 --- a/TaskServer/Assistant.js +++ b/TaskServer/Assistant.js @@ -11,8 +11,7 @@ let thisObject = { dataDependencies: undefined, initialize: initialize, - putPosition: putPosition, - movePosition: movePosition, + createOrder: createOrder, getPositions: getPositions, getBalance: getBalance, getAvailableBalance: getAvailableBalance, @@ -32,7 +31,7 @@ let utilities = UTILITIES.newCloudUtilities(logger); - let exchangePositions = []; // These are the open positions at the exchange at the account the bot is authorized to use. + let openOrders = []; // These are the open positions at the exchange at the account the bot is authorized to use. let openPositions = []; // These are the open positions the bot knows it made by itself. let context; @@ -63,16 +62,10 @@ } case 'Backtest': { - // getMarketRateFromIndicator(); NOTE: This path is disabled since for now we do not allow ticker in simulation. Also it allow us to ship a dataset without bruce validateExchangeSyncronicity(); break; } - case 'Competition': { - getMarketRateFromExchange(); - break; - } - default: { logger.write(MODULE_NAME, "[ERROR] initialize -> Unexpected bot.startMode."); logger.write(MODULE_NAME, "[ERROR] initialize -> bot.startMode = " + bot.startMode); @@ -124,99 +117,6 @@ } } - function getMarketRateFromIndicator() { - - try { - - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> getMarketRateFromIndicator -> Entering function."); } - - /* Procedure to get the current market rate. */ - - let key = - bot.marketRateProvider.dataMine + "-" + - bot.marketRateProvider.bot + "-" + - bot.marketRateProvider.product + "-" + - bot.marketRateProvider.dataSet + "-" + - bot.marketRateProvider.dataSetVersion; - - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> getMarketRateFromIndicator -> key = " + key); } - - let dataSet = thisObject.dataDependencies.dataSets.get(key); - - let dateForPath = bot.processDatetime.getUTCFullYear() + '/' + utilities.pad(bot.processDatetime.getUTCMonth() + 1, 2) + '/' + utilities.pad(bot.processDatetime.getUTCDate(), 2); - let fileName = '' + bot.market.baseAsset + '_' + bot.market.quotedAsset + '.json'; - let filePath = bot.marketRateProvider.product + "/" + bot.marketRateProvider.dataSet + "/" + dateForPath; - - dataSet.getTextFile(filePath, fileName, onFileReceived); - - function onFileReceived(err, text) { - - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> getMarketRateFromIndicator -> onFileReceived -> Entering function."); } - if (global.LOG_CONTROL[MODULE_NAME].logContent === true) { logger.write(MODULE_NAME, "[INFO] initialize -> getMarketRateFromIndicator -> onFileReceived -> text = " + text); } - - let candleArray; - - if (err.result === global.CUSTOM_FAIL_RESPONSE.result || err.code === "The specified key does not exist." || err.message === "File does not exist.") { // Just past midnight, this file will not exist for a couple of minutes. - - logger.write(MODULE_NAME, "[WARN] initialize -> getMarketRateFromIndicator -> onFileReceived -> err = " + JSON.stringify(err)); - logger.write(MODULE_NAME, "[WARN] initialize -> getMarketRateFromIndicator -> This could happen when there are still holes on trades and the process needs to catch up. "); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - - } - - if (err.result === global.DEFAULT_OK_RESPONSE.result) { - try { - candleArray = JSON.parse(text); - - /* We need to find the candle at which the process is currently running. */ - - for (let i = 0; i < candleArray.length; i++) { - - let candle = { - open: candleArray[i][2], - close: candleArray[i][3], - min: candleArray[i][0], - max: candleArray[i][1], - begin: candleArray[i][4], - end: candleArray[i][5] - }; - - // TODO condition added for when there is no market rate available. - if ((bot.processDatetime.valueOf() >= candle.begin && bot.processDatetime.valueOf() < candle.end) - || (i + 1) === candleArray.length) { - - marketRate = (candle.open + candle.close) / 2; - marketRate = thisObject.truncDecimals(marketRate); - context.newHistoryRecord.marketRate = marketRate; - - ticker = { - bid: marketRate, - ask: marketRate, - last: marketRate - }; - - validateExchangeSyncronicity(); - return; - } - } - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] initialize -> getMarketRateFromIndicator -> onFileReceived -> err = " + JSON.stringify(err)); - logger.write(MODULE_NAME, "[ERROR] initialize -> getMarketRateFromIndicator -> onFileReceived -> Asuming this is a temporary situation. Requesting a Retry."); - callBackFunction(global.DEFAULT_RETRY_RESPONSE); - } - } else { - logger.write(MODULE_NAME, "[ERROR] initialize -> getMarketRateFromIndicator -> onFileReceived -> err = " + JSON.stringify(err)); - callBackFunction(err); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] initialize -> getMarketRateFromIndicator -> err = " + err.stack); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - function validateExchangeSyncronicity() { try { @@ -345,22 +245,15 @@ case "Live": { if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getPositionsAtExchange -> Live Mode Detected."); } - exchangeAPI.getOpenPositions(bot.market, onResponse); + exchangeAPI.getOpenOrders(bot.market, onResponse); break; } case "Backtest": { if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getPositionsAtExchange -> Backtest Mode Detected."); } - let exchangePositions = []; // We simulate all positions were executed. - onResponse(global.DEFAULT_OK_RESPONSE, exchangePositions); - break; - } - - case "Competition": { - - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getPositionsAtExchange -> Competition Mode Detected."); } - exchangeAPI.getOpenPositions(bot.market, onResponse); + let openOrders = []; // We simulate all positions were executed. + onResponse(global.DEFAULT_OK_RESPONSE, openOrders); break; } @@ -372,15 +265,15 @@ } } - function onResponse(err, pExchangePositions) { + function onResponse(err, pOpenOrders) { if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getPositionsAtExchange -> onResponse -> Entering function."); } - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getPositionsAtExchange -> onResponse -> pExchangePositions = " + JSON.stringify(pExchangePositions)); } + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getPositionsAtExchange -> onResponse -> pOpenOrders = " + JSON.stringify(pOpenOrders)); } switch (err.result) { case global.DEFAULT_OK_RESPONSE.result: { // Everything went well, we have the information requested. if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getPositionsAtExchange -> onResponse -> Execution finished well."); } - exchangePositions = pExchangePositions; + openOrders = pOpenOrders; ordersExecutionCheck(callBack); return; } @@ -471,11 +364,11 @@ let position = context.executionContext.positions[i]; let exchangePosition; - for (let j = 0; j < exchangePositions.length; j++) { + for (let j = 0; j < openOrders.length; j++) { - if (position.id === exchangePositions[j].id) { + if (position.id === openOrders[j].id) { - exchangePosition = exchangePositions[j]; + exchangePosition = openOrders[j]; positionFound(); return; } @@ -525,12 +418,12 @@ } - function getPositionTradesAtExchange(pPositionId, innerCallBack) { + function getPositionTradesAtExchange(pOrderId, innerCallBack) { try { if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] ordersExecutionCheck -> loopBody -> getPositionTradesAtExchange -> Entering function."); } - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] ordersExecutionCheck -> loopBody -> getPositionTradesAtExchange -> pPositionId = " + pPositionId); } + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] ordersExecutionCheck -> loopBody -> getPositionTradesAtExchange -> pOrderId = " + pOrderId); } /* @@ -543,7 +436,7 @@ case "Live": { if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] ordersExecutionCheck -> loopBody -> getPositionTradesAtExchange -> Live Mode Detected."); } - exchangeAPI.getExecutedTrades(pPositionId, onResponse); + exchangeAPI.getOrder(pOrderId, bot.market, onResponse); return; } @@ -558,25 +451,28 @@ for (let i = 0; i < context.executionContext.positions.length; i++) { - let thisPosition = context.executionContext.positions[i]; + let thisOrder = context.executionContext.positions[i]; - if (thisPosition.id === pPositionId) { + if (thisOrder.id === pOrderId) { let feeRate = 0.002; // Default backtesting fee simulation let trade = { id: Math.trunc(Math.random(1) * 1000000), - type: thisPosition.type, - rate: thisPosition.rate.toString(), - amountA: thisObject.truncDecimals(thisPosition.amountA).toString(), - amountB: thisObject.truncDecimals(thisPosition.amountB).toString(), + type: thisOrder.type, + rate: thisOrder.rate.toString(), + amountA: thisObject.truncDecimals(thisOrder.amountA).toString(), + amountB: thisObject.truncDecimals(thisOrder.amountB).toString(), fee: thisObject.truncDecimals(feeRate).toString(), date: (new Date()).valueOf() } trades.push(trade); - onResponse(global.DEFAULT_OK_RESPONSE, trades); + let order = { + trades: trades + } + onResponse(global.DEFAULT_OK_RESPONSE, order); return; } @@ -587,13 +483,6 @@ return; } - case "Competition": { - - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] ordersExecutionCheck -> loopBody -> getPositionTradesAtExchange -> Competition Mode Detected."); } - exchangeAPI.getExecutedTrades(pPositionId, onResponse); - return; - } - default: { logger.write(MODULE_NAME, "[ERROR] ordersExecutionCheck -> loopBody -> getPositionTradesAtExchange -> Unexpected bot.startMode."); logger.write(MODULE_NAME, "[ERROR] ordersExecutionCheck -> loopBody -> getPositionTradesAtExchange -> bot.startMode = " + bot.startMode); @@ -602,7 +491,7 @@ } } - function onResponse(err, pTrades) { + function onResponse(err, order) { try { if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] ordersExecutionCheck -> loopBody -> getPositionTradesAtExchange -> onResponse -> Entering function."); } @@ -610,7 +499,7 @@ switch (err.result) { case global.DEFAULT_OK_RESPONSE.result: { // Everything went well, we have the information requested. if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] ordersExecutionCheck -> loopBody -> getPositionTradesAtExchange -> onResponse -> Execution finished well."); } - innerCallBack(pTrades); + innerCallBack(order); } break; case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. @@ -637,13 +526,14 @@ } } - function confirmOrderWasExecuted(pTrades) { + function confirmOrderWasExecuted(order) { try { if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] ordersExecutionCheck -> loopBody -> confirmOrderWasExecuted -> Entering function."); } - if (global.LOG_CONTROL[MODULE_NAME].logContent === true) { logger.write(MODULE_NAME, "[INFO] ordersExecutionCheck -> loopBody -> confirmOrderWasExecuted -> pTrades = " + JSON.stringify(pTrades)); } + if (global.LOG_CONTROL[MODULE_NAME].logContent === true) { logger.write(MODULE_NAME, "[INFO] ordersExecutionCheck -> loopBody -> confirmOrderWasExecuted -> trades = " + JSON.stringify(trades)); } + let trades = order.trades /* To confirm everything is ok, we will add all the amounts on trades asociated to the order and @@ -656,8 +546,8 @@ let sumQuotedAsset = 0; let sumRate = 0; - for (let k = 0; k < pTrades.length; k++) { - let trade = pTrades[k]; + for (let k = 0; k < trades.length; k++) { + let trade = trades[k]; sumBaseAsset = sumBaseAsset + thisObject.truncDecimals(trade.amountA); sumQuotedAsset = sumQuotedAsset + thisObject.truncDecimals(trade.amountB); sumRate = sumRate + thisObject.truncDecimals(trade.rate); @@ -686,12 +576,12 @@ position.status = "executed"; if (position.type === "sell") { - context.newHistoryRecord.sellExecRate = sumRate / pTrades.length; + context.newHistoryRecord.sellExecRate = sumRate / trades.length; } else { - context.newHistoryRecord.buyExecRate = sumRate / pTrades.length; + context.newHistoryRecord.buyExecRate = sumRate / trades.length; } - applyTradesToContext(pTrades); + applyTradesToContext(trades); let newTransaction = { type: position.type + " executed", @@ -711,11 +601,13 @@ } } - function confirmOrderWasPartiallyExecuted(pTrades) { + function confirmOrderWasPartiallyExecuted(trades) { try { if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] ordersExecutionCheck -> loopBody -> confirmOrderWasPartiallyExecuted -> Entering function."); } + let trades = order.trades + /* To confirm everything is ok, we will add all the amounts on trades plus the remaining amounts @@ -727,8 +619,8 @@ let sumBaseAsset = 0; let sumQuotedAsset = 0; - for (let k = 0; k < pTrades.length; k++) { - let trade = pTrades[k]; + for (let k = 0; k < trades.length; k++) { + let trade = trades[k]; sumBaseAsset = sumBaseAsset + thisObject.truncDecimals(trade.amountA); sumQuotedAsset = sumQuotedAsset + thisObject.truncDecimals(trade.amountB); } @@ -777,7 +669,7 @@ position.amountB = exchangePosition.amountB; position.date = (new Date(exchangePosition.date)).valueOf(); - applyTradesToContext(pTrades); + applyTradesToContext(trades); let newTransaction = { type: position.type + " partially executed", @@ -797,7 +689,7 @@ } } - function applyTradesToContext(pTrades) { + function applyTradesToContext(trades) { try { @@ -805,9 +697,9 @@ /* Here we apply the trades that already happened at the exchange to the balance and available balance of the bot. We also calculate its profits. */ - for (k = 0; k < pTrades.length; k++) { + for (k = 0; k < trades.length; k++) { - let trade = pTrades[k]; + let trade = trades[k]; position.trades.push(trade); @@ -917,10 +809,10 @@ } } - function putPosition(pType, pRate, pAmountA, pAmountB, callBackFunction) { + function createOrder(pType, pRate, pAmountA, pAmountB, callBackFunction) { try { - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> Entering function."); } + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] createOrder -> Entering function."); } /* Removing extra decimals. */ @@ -928,10 +820,10 @@ pAmountA = thisObject.truncDecimals(pAmountA); pAmountB = thisObject.truncDecimals(pAmountB); - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pType = " + pType); } - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pRate = " + pRate); } - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pAmountA = " + pAmountA); } - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pAmountB = " + pAmountB); } + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] createOrder -> pType = " + pType); } + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] createOrder -> pRate = " + pRate); } + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] createOrder -> pAmountA = " + pAmountA); } + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] createOrder -> pAmountB = " + pAmountB); } /* Validations that the limits are not surpassed. */ @@ -939,9 +831,9 @@ if (pAmountA > thisObject.truncDecimals(context.executionContext.availableBalance.baseAsset)) { - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountA is grater than the Available Balance."); - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountA = " + pAmountA); - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> Available Balance = " + thisObject.truncDecimals(context.executionContext.availableBalance.baseAsset)); + logger.write(MODULE_NAME, "[ERROR] createOrder -> Input Validations -> pAmountA is grater than the Available Balance."); + logger.write(MODULE_NAME, "[ERROR] createOrder -> Input Validations -> pAmountA = " + pAmountA); + logger.write(MODULE_NAME, "[ERROR] createOrder -> Input Validations -> Available Balance = " + thisObject.truncDecimals(context.executionContext.availableBalance.baseAsset)); let err = { result: global.DEFAULT_FAIL_RESPONSE.result, @@ -957,9 +849,9 @@ if (pAmountB > thisObject.truncDecimals(context.executionContext.availableBalance.quotedAsset)) { - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountB is grater than the Available Balance."); - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountB = " + pAmountB); - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> Available Balance = " + thisObject.truncDecimals(context.executionContext.availableBalance.quotedAsset)); + logger.write(MODULE_NAME, "[ERROR] createOrder -> Input Validations -> pAmountB is grater than the Available Balance."); + logger.write(MODULE_NAME, "[ERROR] createOrder -> Input Validations -> pAmountB = " + pAmountB); + logger.write(MODULE_NAME, "[ERROR] createOrder -> Input Validations -> Available Balance = " + thisObject.truncDecimals(context.executionContext.availableBalance.quotedAsset)); let err = { result: global.DEFAULT_FAIL_RESPONSE.result, @@ -977,7 +869,7 @@ case "Live": { - exchangeAPI.putPosition(bot.market, pType, pRate, pAmountA, pAmountB, onResponse); + exchangeAPI.createOrder(bot.market, pType, pRate, pAmountA, pAmountB, onResponse); return; } @@ -985,43 +877,37 @@ if (pRate !== marketRate) { - logger.write(MODULE_NAME, "[WARNING] putPosition -> Input Validations -> putPosition Rate can is different to marketRate while in Backtesting Mode. "); + logger.write(MODULE_NAME, "[WARNING] createOrder -> Input Validations -> createOrder Rate can is different to marketRate while in Backtesting Mode. "); //onResponse(global.DEFAULT_FAIL_RESPONSE, positionId); } let positionId = Math.trunc(Math.random(1) * 1000000); - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> Simulating Exchange Response -> orderId = " + positionId); } + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] createOrder -> Simulating Exchange Response -> orderId = " + positionId); } onResponse(global.DEFAULT_OK_RESPONSE, positionId); return; } - case "Competition": { - - exchangeAPI.putPosition(bot.market, pType, pRate, pAmountA, pAmountB, onResponse); - return; - } - default: { - logger.write(MODULE_NAME, "[ERROR] putPosition -> Unexpected bot.startMode."); - logger.write(MODULE_NAME, "[ERROR] putPosition -> bot.startMode = " + bot.startMode); + logger.write(MODULE_NAME, "[ERROR] createOrder -> Unexpected bot.startMode."); + logger.write(MODULE_NAME, "[ERROR] createOrder -> bot.startMode = " + bot.startMode); callBackFunction(global.DEFAULT_FAIL_RESPONSE); return; } } - function onResponse(err, pPositionId) { + function onResponse(err, order) { try { - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> onResponse -> Entering function."); } - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> onResponse -> pPositionId = " + pPositionId); } + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] createOrder -> onResponse -> Entering function."); } + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] createOrder -> onResponse -> order.id = " + order.id); } switch (err.result) { case global.DEFAULT_OK_RESPONSE.result: { // Everything went well, we have the information requested. - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> onResponse -> Execution finished well."); } + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] createOrder -> onResponse -> Execution finished well."); } let position = { - id: pPositionId, + id: order.id, type: pType, rate: pRate, amountA: pAmountA, @@ -1063,149 +949,25 @@ } break; case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. - logger.write(MODULE_NAME, "[ERROR] putPosition -> onResponse -> Retry Later. Requesting Execution Retry."); + logger.write(MODULE_NAME, "[ERROR] createOrder -> onResponse -> Retry Later. Requesting Execution Retry."); callBackFunction(global.DEFAULT_RETRY_RESPONSE); return; } break; case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle. - logger.write(MODULE_NAME, "[ERROR] putPosition -> onResponse -> Operation Failed. Aborting the process."); + logger.write(MODULE_NAME, "[ERROR] createOrder -> onResponse -> Operation Failed. Aborting the process."); callBackFunction(err); return; } break; } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] putPosition -> onResponse -> err = " + err.stack); + logger.write(MODULE_NAME, "[ERROR] createOrder -> onResponse -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] putPosition -> err = " + err.stack); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - - function movePosition(pPosition, pNewRate, callBackFunction) { - - try { - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] movePosition -> Entering function."); } - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] movePosition -> pPosition = " + JSON.stringify(pPosition)); } - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] movePosition -> pNewRate = " + pNewRate); } - - /* Removing extra decimals. */ - pNewRate = thisObject.truncDecimals(pNewRate); - - let newAmountB; - if (pPosition.type === "buy") { - newAmountB = thisObject.truncDecimals(pPosition.amountA / pNewRate); - } else { - newAmountB = pPosition.amountB; - } - - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] movePosition -> newAmountB = " + newAmountB); } - - switch (bot.startMode) { - - case "Live": { - - exchangeAPI.movePosition(pPosition, pNewRate, newAmountB, onResponse); - return; - } - - case "Backtest": { - - let positionId = Math.trunc(Math.random(1) * 1000000); - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> Simulating Exchange Response -> orderId = " + positionId); } - onResponse(global.DEFAULT_OK_RESPONSE, positionId); - return; - } - - case "Competition": { - - exchangeAPI.movePosition(pPosition, pNewRate, newAmountB, onResponse); - return; - } - - default: { - logger.write(MODULE_NAME, "[ERROR] movePosition -> Unexpected bot.startMode."); - logger.write(MODULE_NAME, "[ERROR] movePosition -> bot.startMode = " + bot.startMode); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - } - - function onResponse(err, pPositionId) { - - try { - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] movePosition -> onResponse -> Entering function."); } - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] movePosition -> onResponse -> pPositionId = " + pPositionId); } - - switch (err.result) { - case global.DEFAULT_OK_RESPONSE.result: { // Everything went well, we have the information requested. - - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] movePosition -> onResponse -> Execution finished well."); } - - let newPosition = { - id: pPositionId, - type: pPosition.type, - rate: pNewRate, - amountA: pPosition.amountA, - amountB: newAmountB, - date: (bot.processDatetime.valueOf()), - status: "open", - trades: [] - }; - - let oldPosition = JSON.parse(JSON.stringify(pPosition)); - - /* We need to update the position we have on file. */ - - for (let i = 0; i < context.executionContext.positions.length; i++) { - - if (context.executionContext.positions[i].id === pPosition.id) { - - context.executionContext.positions[i] = newPosition; - - break; - } - } - - let newTransaction = { - type: "movePosition", - oldPosition: oldPosition, - newPosition: newPosition - }; - - context.executionContext.transactions.push(newTransaction); - - context.newHistoryRecord.movedPositions++; - - recalculateRateAverages(); - - callBackFunction(global.DEFAULT_OK_RESPONSE, newPosition); - } - break; - case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. - logger.write(MODULE_NAME, "[ERROR] movePosition -> onResponse -> Retry Later. Requesting Execution Retry."); - callBackFunction(global.DEFAULT_RETRY_RESPONSE); - return; - } - break; - case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle. - logger.write(MODULE_NAME, "[ERROR] movePosition -> onResponse -> Operation Failed. Aborting the process."); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - break; - } - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] movePosition -> onResponse -> err = " + err.stack); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } - } - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] movePosition -> err = " + err.stack); + logger.write(MODULE_NAME, "[ERROR] createOrder -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } diff --git a/TaskServer/Commons.js b/TaskServer/Commons.js index aaf3d3dcf..5ad2fb509 100644 --- a/TaskServer/Commons.js +++ b/TaskServer/Commons.js @@ -71,7 +71,7 @@ return } if (outputDatasetNode.referenceParent.parentNode.dataBuilding === undefined) { - logger.write(MODULE_NAME, "[WARN] start -> Product Definition 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 = " + JSON.stringify(outputDatasetNode.referenceParent.parentNode)); } if (outputDatasetNode.referenceParent.code.codeName === undefined) { logger.write(MODULE_NAME, "[ERROR] start -> Dataset witn no codeName defined. Product Dataset = " + JSON.stringify(outputDatasetNode.referenceParent)); diff --git a/TaskServer/ExchangeAPI.js b/TaskServer/ExchangeAPI.js new file mode 100644 index 000000000..54c3c52e7 --- /dev/null +++ b/TaskServer/ExchangeAPI.js @@ -0,0 +1,160 @@ +exports.newExchangeAPI = function newExchangeAPI(logger, BOT) { + + let MODULE_NAME = "Exchange API"; + let LOG_INFO = true; + let apiClient; + let bot = BOT + + let thisObject = { + initialize: initialize, + getTicker: getTicker, + getOpenOrders: getOpenOrders, + getOrder: getOrder, + createOrder: createOrder, + getMaxDecimalPositions: getMaxDecimalPositions + }; + + let exchangeId + let options = {} + let exchange + + const ccxt = require('ccxt') + + return thisObject; + + function initialize(callBackFunction) { + try { + exchangeId = bot.exchange.toLowerCase() + + let key = process.env.KEY + let secret = process.env.SECRET + + if (key === "undefined") { key = undefined } + if (secret === "undefined") { secret = undefined } + + const exchangeClass = ccxt[exchangeId] + const exchangeConstructorParams = { + 'apiKey': key, + 'secret': secret, + 'timeout': 30000, + 'enableRateLimit': true, + verbose: false, + options: options + } + + exchange = new exchangeClass(exchangeConstructorParams) + + callBackFunction(global.DEFAULT_OK_RESPONSE) + } catch (err) { + logError("initialize -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function getMaxDecimalPositions() { + return 8 + } + + async function getTicker(market, callBackFunction) { + try { + logInfo("getTicker -> Entering function."); + const symbol = bot.market.baseAsset + '/' + bot.market.quotedAsset + let ticker + + if (exchange.has['fetchTicker']) { + ticker = await (exchange.fetchTicker(symbol)) + callBackFunction(global.DEFAULT_OK_RESPONSE, ticker) + } else { + logError("getTicker -> Exchange does not support fetchTicker command."); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + + } catch (err) { + logError("getTicker -> err = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + async function getOpenOrders(market, callBackFunction) { + try { + logInfo("getOpenOrders -> Entering function. market = " + JSON.stringify(market)); + + const symbol = bot.market.baseAsset + '/' + bot.market.quotedAsset + let openOrders + + if (exchange.has['fetchOpenOrders']) { + openOrders = await(exchange.fetchOpenOrders (symbol)) + callBackFunction(global.DEFAULT_OK_RESPONSE, openOrders) + } else { + logError("getOpenOrders -> Exchange does not support fetchOpenOrders command."); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + + } catch (err) { + logError("getOpenOrders -> Error = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + async function getOrder(orderId, market, callBackFunction) { + try { + logInfo("getOrder -> Entering function. orderId = " + orderId); + + const symbol = bot.market.baseAsset + '/' + bot.market.quotedAsset + let order + + if (exchange.has['fetchOrder']) { + order = await (exchange.fetchOrder(orderId, symbol)) + callBackFunction(global.DEFAULT_OK_RESPONSE, order) + } else { + logError("getOrder -> Exchange does not support fetchOrder command."); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } catch (err) { + logError("getOrder -> Error = " + err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + async function createOrder(market, side, price, cost, amount, callBackFunction) { + try { + logInfo("createOrder -> Entering function."); + + const symbol = bot.market.baseAsset + '/' + bot.market.quotedAsset + + logInfo("createOrder -> market = " + market.assetA + "_" + market.assetB); + logInfo("createOrder -> side = " + side); + logInfo("createOrder -> cost = " + cost); + logInfo("createOrder -> amount = " + amount); + logInfo("createOrder -> price = " + price); + + if (side !== "buy" && side !== "sell") { + logError("createOrder -> side must be either 'buy' or 'sell'."); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + + let type = 'market' + let order + + if (exchange.has['createOrder']) { + order = await(exchange.createOrder(symbol, type, side, amount)) + callBackFunction(global.DEFAULT_OK_RESPONSE, order) + } else { + logError("createOrder -> Exchange does not support createOrder command."); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + + } catch (err) { + logError("createOrder -> err = " + JSON.stringify(err.stack) || err.message); + callBackFunction(global.DEFAULT_FAIL_RESPONSE); + } + } + + function logInfo(message) { + if (LOG_INFO === true) { logger.write(MODULE_NAME, '[INFO] ' + message) } + } + + function logError(message) { + logger.write(MODULE_NAME, '[ERROR] ' + message) + } +}; diff --git a/TaskServer/MultiPeriod.js b/TaskServer/MultiPeriod.js index 94a1cd318..2ad6c0757 100644 --- a/TaskServer/MultiPeriod.js +++ b/TaskServer/MultiPeriod.js @@ -29,7 +29,7 @@ return thisObject; - function initialize(pProcessConfig, pStatusDependencies, pDataDependencies, pAssistant, callBackFunction) { + function initialize(pProcessConfig, pStatusDependencies, pDataDependencies, exchangeAPI, callBackFunction) { try { @@ -63,7 +63,7 @@ let USER_BOT_MODULE = require("./TradingBot") botInstance = USER_BOT_MODULE.newTradingBot(bot, logger, UTILITIES, FILE_STORAGE); - botInstance.initialize(pAssistant, callBackFunction); + botInstance.initialize(exchangeAPI, callBackFunction); } catch (err) { logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack); diff --git a/TaskServer/Session.js b/TaskServer/Session.js index 0aaf44d55..3d61e42aa 100644 --- a/TaskServer/Session.js +++ b/TaskServer/Session.js @@ -2,6 +2,7 @@ const MODULE_NAME = "Session" const FULL_LOG = true; + const ONE_YEAR_IN_MILISECONDS = 365 * 24 * 60 * 60 * 1000 let thisObject = { initialize: initialize @@ -97,6 +98,17 @@ bot.STOP_SESSION = true } + function checkDatetimes() { + if (bot.VALUES_TO_USE.timeRange.initialDatetime.valueOf() < (new Date()).valueOf()) { + if (FULL_LOG === true) { parentLogger.write(MODULE_NAME, "[WARN] initialize -> startLiveTrading -> Overriding initialDatetime with present datetime because " + bot.VALUES_TO_USE.timeRange.initialDatetime + " is in the past."); } + bot.VALUES_TO_USE.timeRange.initialDatetime = new Date() + } + if (bot.VALUES_TO_USE.timeRange.finalDatetime.valueOf() < (new Date()).valueOf()) { + if (FULL_LOG === true) { parentLogger.write(MODULE_NAME, "[WARN] initialize -> startLiveTrading -> Overriding finalDatetime with present datetime plus one year because " + bot.VALUES_TO_USE.timeRange.finalDatetime + " is in the past."); } + bot.VALUES_TO_USE.timeRange.finalDatetime = new Date() + ONE_YEAR_IN_MILISECONDS + } + } + function startBackTesting(message) { bot.startMode = "Backtest" if (bot.VALUES_TO_USE.timeRange.finalDatetime.valueOf() > (new Date()).valueOf()) { @@ -117,9 +129,7 @@ } bot.startMode = "Live" - if (bot.VALUES_TO_USE.timeRange.initialDatetime.valueOf() < (new Date()).valueOf()) { - bot.VALUES_TO_USE.timeRange.initialDatetime = new Date() - } + checkDatetimes() bot.resumeExecution = false; bot.multiPeriodProcessDatetime = new Date(bot.VALUES_TO_USE.timeRange.initialDatetime.valueOf()) bot.hasTheBotJustStarted = true @@ -135,9 +145,7 @@ } bot.startMode = "Live" - if (bot.VALUES_TO_USE.timeRange.initialDatetime.valueOf() < (new Date()).valueOf()) { - bot.VALUES_TO_USE.timeRange.initialDatetime = new Date() - } + checkDatetimes() bot.resumeExecution = false; bot.multiPeriodProcessDatetime = new Date(bot.VALUES_TO_USE.timeRange.initialDatetime.valueOf()) bot.hasTheBotJustStarted = true @@ -164,9 +172,7 @@ function startPaperTrading(message) { bot.startMode = "Backtest" - if (bot.VALUES_TO_USE.timeRange.initialDatetime.valueOf() < (new Date()).valueOf()) { - bot.VALUES_TO_USE.timeRange.initialDatetime = new Date() - } + checkDatetimes() bot.resumeExecution = false; bot.hasTheBotJustStarted = true bot.multiPeriodProcessDatetime = new Date(bot.VALUES_TO_USE.timeRange.initialDatetime.valueOf()) @@ -204,7 +210,7 @@ } /* 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((new Date()).valueOf() - ONE_YEAR_IN_MILISECONDS) @@ -247,7 +253,9 @@ bot.VALUES_TO_USE.baseAsset = code.codeName; } - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { + code = tradingSystem.parameters.baseAsset.code + + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { if (code.initialBalance !== undefined) { bot.VALUES_TO_USE.initialBalanceA = code.initialBalance; bot.VALUES_TO_USE.initialBalanceB = 0 @@ -347,16 +355,18 @@ /* Base Asset and Initial Balances. */ { if (bot.SESSION.parameters.baseAsset !== undefined) { - if (tradingSystem.parameters.baseAsset.referenceParent !== undefined) { - if (tradingSystem.parameters.baseAsset.referenceParent.referenceParent !== undefined) { + if (bot.SESSION.parameters.baseAsset.referenceParent !== undefined) { + if (bot.SESSION.parameters.baseAsset.referenceParent.referenceParent !== undefined) { - let code = tradingSystem.parameters.baseAsset.referenceParent.referenceParent.code + let code = bot.SESSION.parameters.baseAsset.referenceParent.referenceParent.code if (code.codeName !== undefined) { bot.VALUES_TO_USE.baseAsset = code.codeName; } - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { + code = bot.SESSION.parameters.baseAsset.code + + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { if (code.initialBalance !== undefined) { bot.VALUES_TO_USE.initialBalanceA = code.initialBalance; bot.VALUES_TO_USE.initialBalanceB = 0 diff --git a/TaskServer/TradingBot.js b/TaskServer/TradingBot.js index e969a90fc..3129df6d7 100644 --- a/TaskServer/TradingBot.js +++ b/TaskServer/TradingBot.js @@ -18,7 +18,7 @@ const COMMONS = require('./Commons.js'); let commons = COMMONS.newCommons(bot, logger, UTILITIES, FILE_STORAGE); - let assistant; + let exchangeAPI; return thisObject; @@ -29,7 +29,7 @@ commons = undefined } - function initialize(pAssistant, callBackFunction) { + function initialize(pExchangeAPI, callBackFunction) { try { @@ -38,7 +38,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); } - assistant = pAssistant; + exchangeAPI = pExchangeAPI; callBackFunction(global.DEFAULT_OK_RESPONSE); } catch (err) { @@ -130,7 +130,7 @@ timeFrameLabel, currentDay, interExecutionMemory, - assistant, + exchangeAPI, writeFiles, callBackFunction) diff --git a/TaskServer/TradingBotProcessMainLoop.js b/TaskServer/TradingBotProcessMainLoop.js index e2ef012a6..85ae4182d 100644 --- a/TaskServer/TradingBotProcessMainLoop.js +++ b/TaskServer/TradingBotProcessMainLoop.js @@ -145,9 +145,7 @@ /* We define here all the modules that the rest of the infraestructure, including the bots themselves can consume. */ const UTILITIES = require(ROOT_DIR + 'CloudUtilities'); - const EXCHANGE_API = require('@superalgos/exchange-gateway'); - const CONTEXT = require(ROOT_DIR + 'Context'); - const ASSISTANT = require(ROOT_DIR + 'Assistant'); + const EXCHANGE_API = require(ROOT_DIR + 'ExchangeAPI'); const STATUS_REPORT = require(ROOT_DIR + 'StatusReport'); const STATUS_DEPENDENCIES = require(ROOT_DIR + 'StatusDependencies'); const DATA_DEPENDENCIES = require(ROOT_DIR + 'DataDependencies'); @@ -443,7 +441,7 @@ switch (err.result) { case global.DEFAULT_OK_RESPONSE.result: { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeDataDependencies -> onInizialized -> Execution finished well."); } - initializeContext(); + initializeExchangeAPI(); return; } case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. @@ -500,88 +498,13 @@ } } - function initializeContext() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeContext -> Entering function."); } - - context = CONTEXT.newContext(bot, logger, UTILITIES); - context.initialize(statusDependencies, onInizialized); - - function onInizialized(err) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeContext -> onInizialized -> Entering function."); } - - switch (err.result) { - case global.DEFAULT_OK_RESPONSE.result: { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeContext -> onInizialized -> Execution finished well."); } - initializeExchangeAPI(); - return; - } - case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. - logger.write(MODULE_NAME, "[WARN] run -> loop -> initializeContext -> onInizialized -> Retry Later. Requesting Execution Retry."); - nextWaitTime = 'Retry'; - loopControl(nextWaitTime); - return; - } - case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle. - sessionStopped() - processStopped() - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeContext -> onInizialized -> Operation Failed. Aborting the process."); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - return; - } - default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeContext -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeContext -> onInizialized -> Unhandled err.result received. -> err = " + err.message); - - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeContext -> onInizialized -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeContext -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - function initializeExchangeAPI() { try { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeExchangeAPI -> Entering function."); } - exchangeAPI = EXCHANGE_API.newExchangeAPI(logger, bot.exchange); + exchangeAPI = EXCHANGE_API.newExchangeAPI(logger, bot); exchangeAPI.initialize(onInizialized); @@ -594,7 +517,25 @@ switch (err.result) { case global.DEFAULT_OK_RESPONSE.result: { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeExchangeAPI -> onInizialized -> Execution finished well."); } - initializeAssistant(); + + switch (processConfig.framework.name) { + case 'Multi-Period': { + processFramework = MULTI_PERIOD.newMultiPeriod(bot, logger, UTILITIES, USER_BOT_MODULE, USER_BOT_COMMONS); + intitializeProcessFramework(); + break; + } + default: { + logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeExchangeAPI -> onInizialized -> Process Framework not Supported."); + logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeExchangeAPI -> onInizialized -> Process Framework Name = " + processConfig.framework.name); + logger.persist(); + clearInterval(fixedTimeLoopIntervalHandle); + clearTimeout(nextLoopTimeoutHandle); + clearTimeout(checkLoopHealthHandle); + bot.enableCheckLoopHealth = false; + callBackFunction(err); + return; + } + } return; } case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. @@ -651,112 +592,13 @@ } } - function initializeAssistant() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeAssistant -> Entering function."); } - - assistant = ASSISTANT.newAssistant(bot, logger, UTILITIES); - assistant.initialize(context, exchangeAPI, dataDependencies, onInizialized); - - function onInizialized(err) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeAssistant -> onInizialized -> Entering function."); } - - switch (err.result) { - case global.DEFAULT_OK_RESPONSE.result: { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeAssistant -> onInizialized -> Execution finished well."); } - - /* If the process is configured to run inside a framework, we continue there, otherwise we run the bot directly. */ - if (processConfig.framework === undefined) { - initializeUserBot(); - return; - } - - switch (processConfig.framework.name) { - case 'Multi-Period': { - processFramework = MULTI_PERIOD.newMultiPeriod(bot, logger, UTILITIES, USER_BOT_MODULE, USER_BOT_COMMONS); - intitializeProcessFramework(); - break; - } - default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeAssistant -> onInizialized -> Process Framework not Supported."); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeAssistant -> onInizialized -> Process Framework Name = " + processConfig.framework.name); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - return; - } - } - return; - } - case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. - logger.write(MODULE_NAME, "[WARN] run -> loop -> initializeAssistant -> onInizialized -> Retry Later. Requesting Execution Retry."); - nextWaitTime = 'Retry'; - loopControl(nextWaitTime); - return; - } - case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle. - sessionStopped() - processStopped() - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeAssistant -> onInizialized -> Operation Failed. Aborting the process."); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - return; - } - default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeAssistant -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeAssistant -> onInizialized -> Unhandled err.result received. -> err = " + err.message); - - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeAssistant -> onInizialized -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeAssistant -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - function intitializeProcessFramework() { try { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> intitializeProcessFramework -> Entering function."); } - processFramework.initialize(processConfig, statusDependencies, dataDependencies, assistant, onInizialized); + processFramework.initialize(processConfig, statusDependencies, dataDependencies, exchangeAPI, onInizialized); function onInizialized(err) { @@ -859,7 +701,7 @@ case global.DEFAULT_OK_RESPONSE.result: { logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessFramework -> onFinished -> Execution finished well."); nextWaitTime = 'Normal'; - saveContext(); + raiseEventsProcessOutput() return; } case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. @@ -943,84 +785,6 @@ } } - function saveContext() { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> saveContext -> Entering function."); } - - context.saveThemAll(onFinished); - - function onFinished(err) { - - try { - - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> saveContext -> onFinished -> Entering function."); } - - switch (err.result) { - case global.DEFAULT_OK_RESPONSE.result: { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> saveContext -> onFinished -> Execution finished well."); } - raiseEventsProcessOutput() - return; - } - case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time. - logger.write(MODULE_NAME, "[ERROR] run -> loop -> saveContext -> onFinished -> Can not retry at this point."); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle. - sessionStopped() - processStopped() - logger.write(MODULE_NAME, "[ERROR] run -> loop -> saveContext -> onFinished -> Operation Failed. Aborting the process."); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - return; - } - default: { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> saveContext -> onFinished -> Unhandled err.result received. -> err.result = " + err.result); - logger.write(MODULE_NAME, "[ERROR] run -> loop -> saveContext -> onFinished -> Unhandled err.result received. -> err = " + err.message); - - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - return; - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> saveContext -> onFinished -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] run -> loop -> saveContext -> err = "+ err.stack); - logger.persist(); - clearInterval(fixedTimeLoopIntervalHandle); - clearTimeout(nextLoopTimeoutHandle); - clearTimeout(checkLoopHealthHandle); - bot.enableCheckLoopHealth = false; - callBackFunction(err); - } - } - function raiseEventsProcessOutput() { try { diff --git a/TaskServer/TradingSimulation.js b/TaskServer/TradingSimulation.js index 0573fe091..06c48ab4a 100644 --- a/TaskServer/TradingSimulation.js +++ b/TaskServer/TradingSimulation.js @@ -39,7 +39,7 @@ timeFrameLabel, currentDay, interExecutionMemory, - assistant, + exchangeAPI, callback, callBackFunction) { @@ -167,6 +167,8 @@ let periods = 0; let positionPeriods = 0; + let closeRate + /* Usefull counters for conditions and formulas */ let distanceToLast = { @@ -554,8 +556,6 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> Candle Begin @ " + (new Date(candle.begin)).toLocaleString()) } if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> Candle End @ " + (new Date(candle.end)).toLocaleString()) } - /* Assistant Info */ - let ticker = { bid: candle.close, ask: candle.close, @@ -706,7 +706,7 @@ if (openStage !== undefined) { /* Default Values*/ - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { positionSize = balanceBaseAsset; positionRate = candle.close; } else { @@ -729,13 +729,13 @@ initialDefinition.positionSize.formula.error = err.message } if (isNaN(positionSize)) { - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { positionSize = balanceBaseAsset; } else { positionSize = balanceQuotedAsset; } } else { - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { if (positionSize > balanceBaseAsset) { positionSize = balanceBaseAsset } } else { if (positionSize > balanceQuotedAsset) { positionSize = balanceQuotedAsset } @@ -756,7 +756,7 @@ initialDefinition.positionRate.formula.error = err.message } if (isNaN(positionRate)) { - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { positionRate = candle.close; } else { positionRate = candle.close; @@ -1093,7 +1093,7 @@ let maximumBalance let balance - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { balance = balanceBaseAsset minimumBalance = bot.VALUES_TO_USE.minimumBalanceA maximumBalance = bot.VALUES_TO_USE.maximumBalanceA @@ -1675,7 +1675,7 @@ /* Stop Loss condition: Here we verify if the Stop Loss was hitted or not. */ - if ((bot.VALUES_TO_USE.baseAsset === 'BTC' && candle.max >= stopLoss) || (bot.VALUES_TO_USE.baseAsset !== 'BTC' && candle.min <= stopLoss)) { + if ((bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset && candle.max >= stopLoss) || (bot.VALUES_TO_USE.baseAsset !== bot.market.baseAsset && candle.min <= stopLoss)) { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> Stop Loss was hit."); } /* @@ -1685,7 +1685,7 @@ If we take the stop loss value at those situation would be a huge distortion of facts. */ - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { if (stopLoss < candle.min) { stopLoss = candle.min if (processingDailyFiles) { @@ -1710,42 +1710,15 @@ /* Apply the Slippage */ let slippageAmount = slippedStopLoss * bot.VALUES_TO_USE.slippage.stopLoss / 100 - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { slippedStopLoss = slippedStopLoss + slippageAmount } else { slippedStopLoss = slippedStopLoss - slippageAmount } - let finalStopLoss = slippedStopLoss; + closeRate = slippedStopLoss; - let feePaid = 0 - - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { - strategy.positionSize = balanceQuotedAsset / finalStopLoss; - strategy.positionRate = finalStopLoss; - - feePaid = balanceQuotedAsset / finalStopLoss * bot.VALUES_TO_USE.feeStructure.taker / 100 - - balanceBaseAsset = balanceBaseAsset + balanceQuotedAsset / finalStopLoss - feePaid; - balanceQuotedAsset = 0; - } else { - strategy.positionSize = balanceBaseAsset * finalStopLoss; - strategy.positionRate = finalStopLoss; - - feePaid = balanceBaseAsset * finalStopLoss * bot.VALUES_TO_USE.feeStructure.taker / 100 - - balanceQuotedAsset = balanceQuotedAsset + balanceBaseAsset * finalStopLoss - feePaid; - balanceBaseAsset = 0; - } - - if (processingDailyFiles) { - if (positionedAtYesterday) { - yesterday.balanceBaseAsset = balanceBaseAsset; - yesterday.balanceQuotedAsset = balanceQuotedAsset; - } - } - - marketRate = finalStopLoss; + marketRate = closeRate; type = '"Close@StopLoss"'; strategyStage = 'Close Stage'; stopLossStage = 'No Stage'; @@ -1753,7 +1726,7 @@ currentTrade.end = candle.end; currentTrade.status = 1; currentTrade.exitType = 1; - currentTrade.endRate = finalStopLoss; + currentTrade.endRate = closeRate; closePositionNow = true; @@ -1772,7 +1745,7 @@ /* Take Profit condition: Here we verify if the Take Profit was hit or not. */ - if ((bot.VALUES_TO_USE.baseAsset === 'BTC' && candle.min <= takeProfit) || (bot.VALUES_TO_USE.baseAsset !== 'BTC' && candle.max >= takeProfit)) { + if ((bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset && candle.min <= takeProfit) || (bot.VALUES_TO_USE.baseAsset !== bot.market.baseAsset && candle.max >= takeProfit)) { if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> Take Profit was hit."); } /* @@ -1782,7 +1755,7 @@ If we take the stop loss value at those situation would be a huge distortion of facts. */ - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { if (takeProfit > candle.max) { takeProfit = candle.max if (processingDailyFiles) { @@ -1806,43 +1779,15 @@ /* Apply the Slippage */ let slippageAmount = slippedTakeProfit * bot.VALUES_TO_USE.slippage.takeProfit / 100 - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { slippedTakeProfit = slippedTakeProfit + slippageAmount } else { slippedTakeProfit = slippedTakeProfit - slippageAmount } - let finalTakeProfit = slippedTakeProfit; + closeRate = slippedTakeProfit; - let feePaid = 0 - - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { - strategy.positionSize = balanceQuotedAsset / finalTakeProfit; - strategy.positionRate = finalTakeProfit; - - feePaid = balanceQuotedAsset / finalTakeProfit * bot.VALUES_TO_USE.feeStructure.taker / 100 - - balanceBaseAsset = balanceBaseAsset + balanceQuotedAsset / finalTakeProfit - feePaid; - balanceQuotedAsset = 0; - } else { - strategy.positionSize = balanceBaseAsset * finalTakeProfit; - strategy.positionRate = finalTakeProfit; - - feePaid = balanceBaseAsset * finalTakeProfit * bot.VALUES_TO_USE.feeStructure.taker / 100 - - balanceQuotedAsset = balanceQuotedAsset + balanceBaseAsset * finalTakeProfit - feePaid; - balanceBaseAsset = 0; - } - - if (processingDailyFiles) { - if (positionedAtYesterday) { - yesterday.balanceBaseAsset = balanceBaseAsset; - yesterday.balanceQuotedAsset = balanceQuotedAsset; - - } - } - - marketRate = finalTakeProfit; + marketRate = closeRate; type = '"Close@TakeProfit"'; strategyStage = 'Close Stage'; stopLossStage = 'No Stage'; @@ -1851,7 +1796,7 @@ currentTrade.end = candle.end; currentTrade.status = 1; currentTrade.exitType = 2; - currentTrade.endRate = finalTakeProfit; + currentTrade.endRate = closeRate; closePositionNow = true; @@ -1895,7 +1840,7 @@ /* We take what was calculated at the formula and apply the slippage. */ let slippageAmount = tradePositionRate * bot.VALUES_TO_USE.slippage.positionRate / 100 - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { tradePositionRate = tradePositionRate - slippageAmount } else { tradePositionRate = tradePositionRate + slippageAmount @@ -1993,20 +1938,7 @@ } } - - /* Checking the status of current positions */ - let positions = assistant.getPositions(); - if (positions.length > 0) { - let position = positions[positions.length - 1] // We are allways checking the the last position is not open. - if (position.status === 'open') { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putOpeningOrder -> Not placing the trade at the exchange because the last position is still open. "); } - afterLoop(); - return - } - } - /* Mechanism to avoid putting the same order over and over again at different executions of the simulation engine. */ - if (interExecutionMemory.executionContext !== undefined) { if (interExecutionMemory.executionContext.periods !== undefined) { if (periods <= interExecutionMemory.executionContext.periods) { @@ -2030,34 +1962,28 @@ } } - let openPositionRate + let orderPrice let amountA let amountB - let positionDirection - let availableBalance = assistant.getAvailableBalance() + let orderSide + - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { - positionDirection = "sell" + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { + orderSide = "sell" - openPositionRate = tradePositionRate - 100 // 100 is Provisional since we do have management of orders yet + orderPrice = tradePositionRate - 100 // This is going to be ingnored at the Exchange API for now since we only put market orders. - amountA = tradePositionSize * openPositionRate + amountA = tradePositionSize * orderPrice amountB = tradePositionSize - - if (amountB > availableBalance.quotedAsset) { // The assistant know what fees were paid. - amountB = availableBalance.quotedAsset - } + } else { - positionDirection = "buy" + orderSide = "buy" - openPositionRate = tradePositionRate + 100 // 100 is Provisional since we do have management of orders yet + orderPrice = tradePositionRate // This is going to be ingnored at the Exchange API for now since we only put market orders. amountA = tradePositionSize - amountB = tradePositionSize / openPositionRate + amountB = tradePositionSize / orderPrice - if (amountA > availableBalance.baseAsset) { // The assistant know what fees were paid. - amountA = availableBalance.baseAsset - } } interExecutionMemory.executionContext = { @@ -2065,46 +1991,47 @@ periods: periods, } - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putOpeningOrder -> Ready to put order."); } - assistant.putPosition(positionDirection, openPositionRate, amountA, amountB, onOrderPut) + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putOpeningOrder -> Ready to create order."); } + exchangeAPI.createOrder(bot.market, orderSide, orderPrice, amountA, amountB, onOrderCreated) - function onOrderPut(err) { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderPut -> Entering function."); } + function onOrderCreated(err, order) { + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> Entering function."); } try { switch (err.result) { case global.DEFAULT_OK_RESPONSE.result: { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderPut -> DEFAULT_OK_RESPONSE "); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> DEFAULT_OK_RESPONSE "); } interExecutionMemory.executionContext = { status: "In a Position", periods: periods, amountA: amountA, - amountB: amountB + amountB: amountB, + orderId: order.id } takePositionAtSimulation() return; } case global.DEFAULT_FAIL_RESPONSE.result: { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderPut -> DEFAULT_FAIL_RESPONSE "); } - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[ERROR] runSimulation -> loop -> putOpeningOrder -> onOrderPut -> Message = " + err.message); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> DEFAULT_FAIL_RESPONSE "); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[ERROR] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> Message = " + err.message); } strategy.openStage.openExecution.error = err.message afterLoop() return; } case global.DEFAULT_RETRY_RESPONSE.result: { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderPut -> DEFAULT_RETRY_RESPONSE "); } - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[ERROR] runSimulation -> loop -> putOpeningOrder -> onOrderPut -> Message = " + err.message); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> DEFAULT_RETRY_RESPONSE "); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[ERROR] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> Message = " + err.message); } strategy.openStage.openExecution.error = err.message afterLoop() return; } } - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[ERROR] runSimulation -> loop -> putOpeningOrder -> onOrderPut -> Unexpected Response -> Message = " + err.message); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[ERROR] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> Unexpected Response -> Message = " + err.message); } callBackFunction(global.DEFAULT_FAIL_RESPONSE); return } catch (err) { - logger.write(MODULE_NAME, "[ERROR] runSimulation -> loop -> putOpeningOrder -> onOrderPut -> err = " + err.stack); + logger.write(MODULE_NAME, "[ERROR] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); return } @@ -2135,7 +2062,7 @@ let feePaid = 0 - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { feePaid = tradePositionSize * tradePositionRate * bot.VALUES_TO_USE.feeStructure.taker / 100 @@ -2231,19 +2158,7 @@ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> putClosingOrder -> Entering function."); } - /* Checking the status of current positions */ - let positions = assistant.getPositions(); - if (positions.length > 0) { - let position = positions[positions.length - 1] // We are allways checking the the last position is not open. - if (position.status === 'open') { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putClosingOrder -> Exiting function because status of last position is Open."); } - afterLoop(); - return - } - } - /* Mechanism to avoid putting the same order over and over again at different executions of the simulation engine. */ - if (interExecutionMemory.executionContext !== undefined) { if (interExecutionMemory.executionContext.periods !== undefined) { if (periods <= interExecutionMemory.executionContext.periods) { @@ -2254,27 +2169,26 @@ } } - let closePositionRate + let orderPrice let amountA let amountB - let positionDirection - let availableBalance = assistant.getAvailableBalance() + let orderSide - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { - positionDirection = "buy" + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { + orderSide = "buy" - closePositionRate = ticker.last + 100; // This is provisional and totally arbitrary, until we have a formula on the designer that defines this stuff. + orderPrice = ticker.last + 100; // This is provisional and totally arbitrary, until we have a formula on the designer that defines this stuff. - amountA = availableBalance.baseAsset - amountB = availableBalance.baseAsset / closePositionRate + amountA = balanceQuotedAsset + amountB = balanceQuotedAsset / orderPrice } else { - positionDirection = "sell" + orderSide = "sell" - closePositionRate = ticker.last - 100; // This is provisional and totally arbitrary, until we have a formula on the designer that defines this stuff. + orderPrice = ticker.last - 100; // This is provisional and totally arbitrary, until we have a formula on the designer that defines this stuff. - amountA = availableBalance.quotedAsset * closePositionRate - amountB = availableBalance.quotedAsset + amountA = balanceBaseAsset * orderPrice + amountB = balanceBaseAsset } @@ -2284,44 +2198,45 @@ } if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putClosingOrder -> About to close position at the exchange."); } - assistant.putPosition(positionDirection, closePositionRate, amountA, amountB, onOrderPut) + exchangeAPI.createOrder(bot.market, orderSide, orderPrice, amountA, amountB, onOrderCreated) - function onOrderPut(err) { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putClosingOrder -> onOrderPut -> Entering function."); } + function onOrderCreated(err, order) { + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putClosingOrder -> onOrderCreated -> Entering function."); } try { switch (err.result) { case global.DEFAULT_OK_RESPONSE.result: { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putClosingOrder -> onOrderPut -> DEFAULT_OK_RESPONSE "); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putClosingOrder -> onOrderCreated -> DEFAULT_OK_RESPONSE "); } interExecutionMemory.executionContext = { status: "Position Closed", periods: periods, amountA: amountA, - amountB: amountB + amountB: amountB, + orderId: order.id } closePositionAtSimulation() return; } case global.DEFAULT_FAIL_RESPONSE.result: { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putClosingOrder -> onOrderPut -> DEFAULT_FAIL_RESPONSE "); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putClosingOrder -> onOrderCreated -> DEFAULT_FAIL_RESPONSE "); } /* We will assume that the problem is temporary, and expect that it will work at the next execution.*/ strategy.closeStage.closeExecution.error = err.message afterLoop() return; } case global.DEFAULT_RETRY_RESPONSE.result: { - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderPut -> DEFAULT_RETRY_RESPONSE "); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] runSimulation -> loop -> putOpeningOrder -> onOrderCreated -> DEFAULT_RETRY_RESPONSE "); } strategy.closeStage.closeExecution.error = err.message afterLoop() return; } } - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[ERROR] runSimulation -> loop -> putClosingOrder -> onOrderPut -> Unexpected Response -> Message = " + err.message); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[ERROR] runSimulation -> loop -> putClosingOrder -> onOrderCreated -> Unexpected Response -> Message = " + err.message); } callBackFunction(global.DEFAULT_FAIL_RESPONSE); return } catch (err) { - logger.write(MODULE_NAME, "[ERROR] runSimulation -> loop -> putClosingOrder -> onOrderPut -> err = " + err.stack); + logger.write(MODULE_NAME, "[ERROR] runSimulation -> loop -> putClosingOrder -> onOrderCreated -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); return } @@ -2339,7 +2254,35 @@ } } - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { + let feePaid = 0 + + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { + strategy.positionSize = balanceQuotedAsset / closeRate; + strategy.positionRate = closeRate; + + feePaid = balanceQuotedAsset / closeRate * bot.VALUES_TO_USE.feeStructure.taker / 100 + + balanceBaseAsset = balanceBaseAsset + balanceQuotedAsset / closeRate - feePaid; + balanceQuotedAsset = 0; + } else { + strategy.positionSize = balanceBaseAsset * closeRate; + strategy.positionRate = closeRate; + + feePaid = balanceBaseAsset * closeRate * bot.VALUES_TO_USE.feeStructure.taker / 100 + + balanceQuotedAsset = balanceQuotedAsset + balanceBaseAsset * closeRate - feePaid; + balanceBaseAsset = 0; + } + + if (processingDailyFiles) { + if (positionedAtYesterday) { + yesterday.balanceBaseAsset = balanceBaseAsset; + yesterday.balanceQuotedAsset = balanceQuotedAsset; + + } + } + + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { lastTradeProfitLoss = balanceBaseAsset - previousBalanceBaseAsset; lastTradeROI = lastTradeProfitLoss * 100 / tradePositionSize; if (isNaN(lastTradeROI)) { lastTradeROI = 0; } @@ -2386,7 +2329,7 @@ } } - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { ROI = (bot.VALUES_TO_USE.initialBalanceA + profit) / bot.VALUES_TO_USE.initialBalanceA - 1; hitRatio = hits / roundtrips; anualizedRateOfReturn = ROI / days * 365; @@ -2652,7 +2595,7 @@ currentTrade.endRate = candle.close /* Here we will calculate the ongoing ROI */ - if (bot.VALUES_TO_USE.baseAsset === 'BTC') { + if (bot.VALUES_TO_USE.baseAsset === bot.market.baseAsset) { currentTrade.lastTradeROI = (tradePositionRate - candle.close) / tradePositionRate * 100 } else { currentTrade.lastTradeROI = (candle.close - tradePositionRate) / tradePositionRate * 100 diff --git a/TaskServer/package-lock.json b/TaskServer/package-lock.json index e576ae33f..fbf97a4f3 100644 --- a/TaskServer/package-lock.json +++ b/TaskServer/package-lock.json @@ -1,212 +1,19 @@ { - "name": "@superalgos/clone-executor", - "version": "1.0.51", + "name": "@superalgos/taskserver", + "version": "2.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { - "@superalgos/exchange-gateway": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/@superalgos/exchange-gateway/-/exchange-gateway-0.0.10.tgz", - "integrity": "sha512-VsiGeEyqD7NXvn2tFoqqz036WRBtzy6HvpbXqhl/+xG4SMbo2w9hb6AdAeH4KxuU2S7l/oO8zI9d15f30Q191Q==", - "requires": { - "axios": "0.19.0", - "dotenv": "8.0.0", - "nonce": "1.0.4", - "querystring": "0.2.0", - "request": "2.88.0", - "retry": "0.12.0", - "superagent": "5.1.0", - "underscore": "1.9.1" - } - }, - "@superalgos/mqservice": { - "version": "0.0.17", - "resolved": "https://registry.npmjs.org/@superalgos/mqservice/-/mqservice-0.0.17.tgz", - "integrity": "sha512-mxg2AtfFJ78n/p+JK/o6nTrnR+ZPlBNcq7k+6Epnl1t63ldrcm98WOgIQZaNezPPf0E7gSjVX3p+uZO1Ass0kA==" - }, "@types/node": { "version": "12.7.12", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.12.tgz", "integrity": "sha512-KPYGmfD0/b1eXurQ59fXD1GBzhSQfz6/lKBxkaHX9dKTzjXbK68Zt7yGUxUsCS1jeTy/8aL+d9JEr+S54mpkWQ==" }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.4.1", - "uri-js": "4.2.2" - } - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "2.1.2" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", - "requires": { - "lodash": "4.17.11" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "axios": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz", - "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==", - "requires": { - "follow-redirects": "1.5.10", - "is-buffer": "2.0.3" - } - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "0.14.5" - } - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, "ccxt": { "version": "1.21.82", "resolved": "https://registry.npmjs.org/ccxt/-/ccxt-1.21.82.tgz", "integrity": "sha512-+HX/6WK8BM5c9OwhALl9zzMKvueZfHDXVmfrKNmQ4005hc+BtNuNe47XEs6dAylY+ll7n9JpzaoIZhy6Lipiew==" }, - "color": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", - "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", - "requires": { - "color-convert": "1.9.3", - "color-string": "1.5.3" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", - "requires": { - "color-name": "1.1.3", - "simple-swizzle": "0.2.2" - } - }, - "colornames": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz", - "integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y=" - }, - "colors": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", - "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==" - }, - "colorspace": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", - "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", - "requires": { - "color": "3.0.0", - "text-hex": "1.0.0" - } - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "1.0.0" - } - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "1.0.0" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "diagnostics": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz", - "integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==", - "requires": { - "colorspace": "1.1.2", - "enabled": "1.0.2", - "kuler": "1.0.1" - } - }, "dotenv": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.0.0.tgz", @@ -217,153 +24,11 @@ "resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.0.tgz", "integrity": "sha1-EskbMIWjfwuqM26UhurEv5Tj54g=" }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "0.1.1", - "safer-buffer": "2.1.2" - } - }, - "enabled": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz", - "integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=", - "requires": { - "env-variable": "0.0.5" - } - }, - "env-variable": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.5.tgz", - "integrity": "sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==" - }, "event-pubsub": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/event-pubsub/-/event-pubsub-4.3.0.tgz", "integrity": "sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ==" }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "fast-safe-stringify": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz", - "integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==" - }, - "fecha": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", - "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==" - }, - "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "requires": { - "debug": "3.1.0" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.8", - "mime-types": "2.1.24" - } - }, - "formidable": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", - "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "1.0.0" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "6.10.2", - "har-schema": "2.0.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.16.1" - } - }, - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "is-buffer": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, "js-message": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.5.tgz", @@ -377,97 +42,6 @@ "easy-stack": "1.0.0" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "kuler": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz", - "integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==", - "requires": { - "colornames": "1.1.1" - } - }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - }, - "logform": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.1.2.tgz", - "integrity": "sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ==", - "requires": { - "colors": "1.3.3", - "fast-safe-stringify": "2.0.6", - "fecha": "2.3.3", - "ms": "2.1.1", - "triple-beam": "1.3.0" - }, - "dependencies": { - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - } - } - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, "node-fetch": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", @@ -483,195 +57,11 @@ "js-queue": "2.0.0" } }, - "nonce": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/nonce/-/nonce-1.0.4.tgz", - "integrity": "sha1-7nMCrejBvvR28wG4yR9cxRpIdhI=" - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "one-time": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz", - "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=" - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" - }, - "psl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz", - "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==" - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "2.0.3", - "string_decoder": "1.2.0", - "util-deprecate": "1.0.2" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - } - } - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.8.0", - "caseless": "0.12.0", - "combined-stream": "1.0.8", - "extend": "3.0.2", - "forever-agent": "0.6.1", - "form-data": "2.3.3", - "har-validator": "5.1.3", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.24", - "oauth-sign": "0.9.0", - "performance-now": "2.1.0", - "qs": "6.5.2", - "safe-buffer": "5.1.2", - "tough-cookie": "2.4.3", - "tunnel-agent": "0.6.0", - "uuid": "3.3.2" - } - }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, "sandwich-stream": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/sandwich-stream/-/sandwich-stream-2.0.2.tgz", "integrity": "sha512-jLYV0DORrzY3xaz/S9ydJL6Iz7essZeAfnAavsJ+zsJGZ1MOnsS52yRjU3uF3pJa/lla7+wisp//fxOwOH8SKQ==" }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "requires": { - "is-arrayish": "0.3.2" - } - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "0.2.4", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.2", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.2", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "safer-buffer": "2.1.2", - "tweetnacl": "0.14.5" - } - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" - }, - "string_decoder": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", - "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "superagent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-5.1.0.tgz", - "integrity": "sha512-7V6JVx5N+eTL1MMqRBX0v0bG04UjrjAvvZJTF/VDH/SH2GjSLqlrcYepFlpTrXpm37aSY6h3GGVWGxXl/98TKA==", - "requires": { - "component-emitter": "1.3.0", - "cookiejar": "2.1.2", - "debug": "4.1.1", - "fast-safe-stringify": "2.0.6", - "form-data": "2.3.3", - "formidable": "1.2.1", - "methods": "1.1.2", - "mime": "2.4.4", - "qs": "6.7.0", - "readable-stream": "3.4.0", - "semver": "6.3.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" - } - } - }, "telegraf": { "version": "3.32.0", "resolved": "https://registry.npmjs.org/telegraf/-/telegraf-3.32.0.tgz", @@ -703,132 +93,6 @@ "version": "3.6.1", "resolved": "https://registry.npmjs.org/telegram-typings/-/telegram-typings-3.6.1.tgz", "integrity": "sha512-njVv1EAhIZnmQVLocZEADYUyqA1WIXuVcDYlsp+mXua/XB0pxx+PKtMSPeZ/EE4wPWTw9h/hA9ASTT6yQelkiw==" - }, - "text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "1.2.0", - "punycode": "1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "2.1.1" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "1.3.0" - } - }, - "winston": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.2.1.tgz", - "integrity": "sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw==", - "requires": { - "async": "2.6.2", - "diagnostics": "1.1.1", - "is-stream": "1.1.0", - "logform": "2.1.2", - "one-time": "0.0.4", - "readable-stream": "3.4.0", - "stack-trace": "0.0.10", - "triple-beam": "1.3.0", - "winston-transport": "4.3.0" - } - }, - "winston-transport": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz", - "integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==", - "requires": { - "readable-stream": "2.3.6", - "triple-beam": "1.3.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "5.1.2" - } - } - } } } } diff --git a/TaskServer/package.json b/TaskServer/package.json index f50ec7979..e9977e889 100644 --- a/TaskServer/package.json +++ b/TaskServer/package.json @@ -1,25 +1,21 @@ { - "name": "@superalgos/clone-executor", - "version": "1.0.51", - "description": "Module responsible for executing the bots on the cloud.", - "author": "Superalgos, ltd.", + "name": "@superalgos/taskserver", + "version": "2.0.0", + "description": "Executes Tasks.", + "author": "Superalgos.org", "license": "Apache-2.0", "repository": { "type": "git", - "url": "https://github.com/Superalgos/CloneExecutor.git" + "url": "https://github.com/Superalgos/TaskServer.git" }, "main": "Run.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { - "@superalgos/exchange-gateway": "0.0.10", - "@superalgos/mqservice": "^0.0.17", - "axios": "^0.19.0", "ccxt": "^1.21.82", "dotenv": "^8.0.0", "node-ipc": "^9.1.1", - "telegraf": "^3.32.0", - "winston": "^3.2.1" + "telegraf": "^3.32.0" } } diff --git a/WebServer/Images/Icons/style-01/angle-to-parent-000.png b/WebServer/Images/Icons/style-01/angle-to-parent-000.png index d458e70c1..08de6ae0f 100644 Binary files a/WebServer/Images/Icons/style-01/angle-to-parent-000.png and b/WebServer/Images/Icons/style-01/angle-to-parent-000.png differ diff --git a/WebServer/Images/Icons/style-01/angle-to-parent-045.png b/WebServer/Images/Icons/style-01/angle-to-parent-045.png index 906a1d914..736285891 100644 Binary files a/WebServer/Images/Icons/style-01/angle-to-parent-045.png and b/WebServer/Images/Icons/style-01/angle-to-parent-045.png differ diff --git a/WebServer/Images/Icons/style-01/angle-to-parent-090.png b/WebServer/Images/Icons/style-01/angle-to-parent-090.png index 4b3583bc6..4170f18ef 100644 Binary files a/WebServer/Images/Icons/style-01/angle-to-parent-090.png and b/WebServer/Images/Icons/style-01/angle-to-parent-090.png differ diff --git a/WebServer/Images/Icons/style-01/angle-to-parent-180.png b/WebServer/Images/Icons/style-01/angle-to-parent-180.png index ce921425f..a6b79d09b 100644 Binary files a/WebServer/Images/Icons/style-01/angle-to-parent-180.png and b/WebServer/Images/Icons/style-01/angle-to-parent-180.png differ diff --git a/WebServer/Images/Icons/style-01/angle-to-parent-360.png b/WebServer/Images/Icons/style-01/angle-to-parent-360.png index 6cf98ad3f..bbe1a83ff 100644 Binary files a/WebServer/Images/Icons/style-01/angle-to-parent-360.png and b/WebServer/Images/Icons/style-01/angle-to-parent-360.png differ diff --git a/WebServer/Images/Icons/style-01/data-mining.png b/WebServer/Images/Icons/style-01/data-mining.png new file mode 100644 index 000000000..19b697435 Binary files /dev/null and b/WebServer/Images/Icons/style-01/data-mining.png differ diff --git a/WebServer/Images/Icons/style-01/distance-to-parent-000.png b/WebServer/Images/Icons/style-01/distance-to-parent-000.png index 984873dd9..4a4e8b578 100644 Binary files a/WebServer/Images/Icons/style-01/distance-to-parent-000.png and b/WebServer/Images/Icons/style-01/distance-to-parent-000.png differ diff --git a/WebServer/Images/Icons/style-01/distance-to-parent-025.png b/WebServer/Images/Icons/style-01/distance-to-parent-025.png index e9fa9f3a0..e03403d12 100644 Binary files a/WebServer/Images/Icons/style-01/distance-to-parent-025.png and b/WebServer/Images/Icons/style-01/distance-to-parent-025.png differ diff --git a/WebServer/Images/Icons/style-01/distance-to-parent-050.png b/WebServer/Images/Icons/style-01/distance-to-parent-050.png index dce0a9386..3c3f68e33 100644 Binary files a/WebServer/Images/Icons/style-01/distance-to-parent-050.png and b/WebServer/Images/Icons/style-01/distance-to-parent-050.png differ diff --git a/WebServer/Images/Icons/style-01/distance-to-parent-100.png b/WebServer/Images/Icons/style-01/distance-to-parent-100.png index 6ba242342..82a025731 100644 Binary files a/WebServer/Images/Icons/style-01/distance-to-parent-100.png and b/WebServer/Images/Icons/style-01/distance-to-parent-100.png differ diff --git a/WebServer/Images/Icons/style-01/distance-to-parent-150.png b/WebServer/Images/Icons/style-01/distance-to-parent-150.png index 041adb15c..d0646bdd7 100644 Binary files a/WebServer/Images/Icons/style-01/distance-to-parent-150.png and b/WebServer/Images/Icons/style-01/distance-to-parent-150.png differ diff --git a/WebServer/Images/Icons/style-01/distance-to-parent-200.png b/WebServer/Images/Icons/style-01/distance-to-parent-200.png index 54aa46ff2..f381ad210 100644 Binary files a/WebServer/Images/Icons/style-01/distance-to-parent-200.png and b/WebServer/Images/Icons/style-01/distance-to-parent-200.png differ diff --git a/WebServer/Images/Icons/style-01/initial-definition.png b/WebServer/Images/Icons/style-01/initial-definition.png new file mode 100644 index 000000000..d6e3db3d5 Binary files /dev/null and b/WebServer/Images/Icons/style-01/initial-definition.png differ diff --git a/WebServer/Images/Icons/style-01/next-phase-event.png b/WebServer/Images/Icons/style-01/next-phase-event.png new file mode 100644 index 000000000..7f958daf5 Binary files /dev/null and b/WebServer/Images/Icons/style-01/next-phase-event.png differ diff --git a/WebServer/Images/Icons/style-01/production-environment.png b/WebServer/Images/Icons/style-01/production-environment.png new file mode 100644 index 000000000..6d0820e63 Binary files /dev/null and b/WebServer/Images/Icons/style-01/production-environment.png differ diff --git a/WebServer/Images/Icons/style-01/task-manager.png b/WebServer/Images/Icons/style-01/task-manager.png new file mode 100644 index 000000000..109d16159 Binary files /dev/null and b/WebServer/Images/Icons/style-01/task-manager.png differ diff --git a/WebServer/Images/Icons/style-01/testing-environment.png b/WebServer/Images/Icons/style-01/testing-environment.png new file mode 100644 index 000000000..a8e493ed1 Binary files /dev/null and b/WebServer/Images/Icons/style-01/testing-environment.png differ diff --git a/docs/_data/charting_space.md b/docs/_data/charting_space.md new file mode 100644 index 000000000..67aebbc0a --- /dev/null +++ b/docs/_data/charting_space.md @@ -0,0 +1,17 @@ +charting_space: "The Charting Space is the hierarchy that governs the configuration of the charts." + +viewport: "A viewport represents the bidimensional space on which the charts are drawn." + +time_machine: "A time machine synchronizes multiple timeline charts over the same timeline. Timeline charts within a time machine may have different rate scales or time frame scales, but their time scale will always match." + +time_scale: "The time scale controls the scale of the horizontal axis, that is, the timeline of the corresponding time machine, and of all of the timeline charts within it." + +rate_scale: "The rate scale controls the scale of the vertical axis, that is, the scale of the quoted asset, either of the time machine or of the timeline chart, depending on where the node is located." + +time_frame_scale: "The time frame scale controls the time frame setting, that is, the period represented by each candle, either of the time machine or of the timeline chart, depending on where the node is located." + +timeline_chart: "The timeline chart represents a chart within a time machine, which may have independent rate and time frame scales, as well as particular layers." + +layers_manager: "The layer manager determines which layers will be visible on the corresponding timeline chart." + +layer: "A layer represents a reference to a data product in the data storage node of the Network hierarchy. Conceptually, it means that a certain data product, which exists in a certain location on the network, holds the data to be rendered on the charts." \ No newline at end of file diff --git a/docs/_data/charting_space.yml b/docs/_data/charting_space.yml new file mode 100644 index 000000000..67aebbc0a --- /dev/null +++ b/docs/_data/charting_space.yml @@ -0,0 +1,17 @@ +charting_space: "The Charting Space is the hierarchy that governs the configuration of the charts." + +viewport: "A viewport represents the bidimensional space on which the charts are drawn." + +time_machine: "A time machine synchronizes multiple timeline charts over the same timeline. Timeline charts within a time machine may have different rate scales or time frame scales, but their time scale will always match." + +time_scale: "The time scale controls the scale of the horizontal axis, that is, the timeline of the corresponding time machine, and of all of the timeline charts within it." + +rate_scale: "The rate scale controls the scale of the vertical axis, that is, the scale of the quoted asset, either of the time machine or of the timeline chart, depending on where the node is located." + +time_frame_scale: "The time frame scale controls the time frame setting, that is, the period represented by each candle, either of the time machine or of the timeline chart, depending on where the node is located." + +timeline_chart: "The timeline chart represents a chart within a time machine, which may have independent rate and time frame scales, as well as particular layers." + +layers_manager: "The layer manager determines which layers will be visible on the corresponding timeline chart." + +layer: "A layer represents a reference to a data product in the data storage node of the Network hierarchy. Conceptually, it means that a certain data product, which exists in a certain location on the network, holds the data to be rendered on the charts." \ No newline at end of file diff --git a/docs/_data/concepts.md b/docs/_data/concepts.md index 72949b763..1e817f5b6 100644 --- a/docs/_data/concepts.md +++ b/docs/_data/concepts.md @@ -10,7 +10,7 @@ parent-offspring_relationships: "Nodes in structures of nodes are chained to eac chain: "Nodes in the workspace may be unchained or detached from its parent, carrying all offspring with it. When a node is left unchained, it is no longer taken into account in the logic of the hierarchy, as it no longer belongs to it. When a node is chained back or reattached to the hierarchy, it goes back to being functional." -hierarchy: "A hierarchy is the representation of an overarching, top-level concept resulting in a long chain of nodes, usually with many ramifications. Currently, the system manages five different types of hierarchies: Charting System, Crypto Ecosystem, Trading Systems, Network, and Data Mines." +hierarchy: "A hierarchy is the representation of an overarching, top-level concept resulting in a long chain of nodes, usually with many ramifications. Currently, the system manages five different types of hierarchies: Charting Space, Crypto Ecosystem, Trading Systems, Network, and Data Mines." reference: "A reference is a mechanism by which information in a node is related to, or accessed by, other nodes. The ability of a node to establish a reference with another node enables the first to access the information or features entailed in the second one." diff --git a/docs/_data/concepts.yml b/docs/_data/concepts.yml index 72949b763..1e817f5b6 100644 --- a/docs/_data/concepts.yml +++ b/docs/_data/concepts.yml @@ -10,7 +10,7 @@ parent-offspring_relationships: "Nodes in structures of nodes are chained to eac chain: "Nodes in the workspace may be unchained or detached from its parent, carrying all offspring with it. When a node is left unchained, it is no longer taken into account in the logic of the hierarchy, as it no longer belongs to it. When a node is chained back or reattached to the hierarchy, it goes back to being functional." -hierarchy: "A hierarchy is the representation of an overarching, top-level concept resulting in a long chain of nodes, usually with many ramifications. Currently, the system manages five different types of hierarchies: Charting System, Crypto Ecosystem, Trading Systems, Network, and Data Mines." +hierarchy: "A hierarchy is the representation of an overarching, top-level concept resulting in a long chain of nodes, usually with many ramifications. Currently, the system manages five different types of hierarchies: Charting Space, Crypto Ecosystem, Trading Systems, Network, and Data Mines." reference: "A reference is a mechanism by which information in a node is related to, or accessed by, other nodes. The ability of a node to establish a reference with another node enables the first to access the information or features entailed in the second one." diff --git a/docs/_data/data_mine.md b/docs/_data/data_mine.md index 860236ac3..b583f394b 100644 --- a/docs/_data/data_mine.md +++ b/docs/_data/data_mine.md @@ -1,8 +1,8 @@ data_mine: "A data mine is a hierarchy that contains definitions regarding bots, including the trading bot, sensors, indicators, and even plotters. These definitions make up the actual programs of such bots—the source code." -indicator_bot: "An indicator bot is an algorithm that processes information that other bots have generated, and produces elaborate datasets for others to consume. " +indicator_bot: "An indicator bot is an algorithm that processes information that other bots have generated, and produces elaborate datasets for others to consume." -process_definition: "The process definition node groups all definitions required for a process to function. The Multi Period Market Process deals with time frames of one hour and above. The Multi Period Daily Process deals with time frames of 45 minutes and below." +process_definition: "The process definition node groups all definitions required for a process to function. The Multi-Period-Market Process deals with time frames of one hour and above. The Multi-Period-Daily Process deals with time frames of 45 minutes and below." process_output: "The process output groups the definitions of which datasets are impacted by the process, that is, which datasets the process builds or takes a part in building." @@ -22,7 +22,7 @@ execution_finished_event: "The execution finished event is the event that proces product_definition: "The product definition node holds all definitions that make up a product, including how the product is calculated and the datasets the product is comprised of." -dataset_definition: "A dataset definition contains a configuration file that defines all aspects of the dataset. There are two types of dataset definitions: multi period market and multi period daily." +dataset_definition: "A dataset definition contains a configuration file that defines all aspects of the dataset. There are two types of dataset definitions: Multi-Period-Market and Multi-Period-Daily." record_definition: "The record definition is where indicators define how many fields, what fields and in which order those fields will be stored in each record." @@ -32,7 +32,7 @@ formula: "In the context of a record definition, formulas are used to assign a v calculations_procedure: "The calculations procedure processes information to be fed to calculated properties. Calculated properties are not stored in the data set; instead, they are calculated in real-time as the data is consumed by others." -procedure_loop: "The procedure loop holds the JavaScript code that cycles through an input processing information to generate an output." +procedure_loop: "The procedure loop holds the JavaScript code that reads an input, processes the information, and generates an output recursively." javascript_code: "The JavaScript code node may hold any snippet of valid JavaScript." @@ -40,34 +40,34 @@ procedure_initialization: "The procedure initialization is used to initialize va data_building_procedure: "The data building procedure processes information to be fed to properties that are stored in the output dataset." -plotter: "A plotter is a device used to produce a graphic representation of the data generated by indicators." +plotter: "A plotter is a device used to produce a graphic representation of datasets generated by bots." -plotter_module: "A plotter module is a device within a plotter that contains the definitions to create the visualization, often times, for a particular product definition." +plotter_module: "A plotter module is a device within a plotter that contains the definitions to create the visualization for a product definition." plotter_panel: "A plotter panel usually shows numerical representations of data over the charts on a small window or panel. The plotter panel node features definitions to make that possible." panel_data: "A panel data node represents a data field to be plotted on the plotter panel." -data_formula: "A data formula is the device used to assign a value to the panel data, usually in the form of the name of the corresponding record property." +data_formula: "A data formula is a device used to assign a value to the panel data, usually in the form of the name of the corresponding record property." -shapes: "The shapes node contains definitions that define polygons and styles to be rendered on a per period basis over the charts." +shapes: "The shapes node contains definitions of polygons and styles to be rendered on a per-period basis over the charts." -chart_points: "The chart points node groups definitions of points." +chart_points: "A chart points groups definitions of coordinate points used to define polygons." -point: "A point is a definition of an [x,y] coordinate where x is usually a datetime and y is usually a value that refers to a price, as output by the indicator." +point: "A point is a definition of an [x,y] coordinate. The value [x] usually represents a datetime. The value [y] may refer to a price or some other concept." -point_formula: "A point formula is the node used to input the coordinates of a point." +point_formula: "A point formula is a node used to input the [x,y] coordinates of a point." -polygon: "A polygon features definitions that make up shapes and their styles." +polygon: "A polygon features definitions that makeup shapes and their styles." -polygon_vertex: "A polygon vertex is a reference to a point defined in the chart points, constituting a specific coordinate to be used as vertex of a shape." +polygon_vertex: "A polygon vertex is a reference to a point defined in the chart points, constituting a specific coordinate to be used as a vertex of a shape." polygon_border: "A polygon border is a shape defined by at least two vertices used to draw lines or to apply a style to the stroke of a closed shape." -style: "A style is a definition of color and opacity in case of a polygon body, and of color, opacity and line thickness in case of polygon borders." +style: "A style is a definition of color and opacity in case of a polygon body, and color, opacity and line thickness in case of polygon borders." style_condition: "A style condition is a rule that allows applying an alternative style in cases where the rule validates true." -polygon_body: "A polygon body is is the fill of a shape made out of at least 3 vertices." +polygon_body: "A polygon body is the fill of a shape made out of at least three vertices." pending: "daily files, market files and so on, Multi-Period-Daily, Multi-Period-Market" \ No newline at end of file diff --git a/docs/_data/data_mine.yml b/docs/_data/data_mine.yml index 860236ac3..b583f394b 100644 --- a/docs/_data/data_mine.yml +++ b/docs/_data/data_mine.yml @@ -1,8 +1,8 @@ data_mine: "A data mine is a hierarchy that contains definitions regarding bots, including the trading bot, sensors, indicators, and even plotters. These definitions make up the actual programs of such bots—the source code." -indicator_bot: "An indicator bot is an algorithm that processes information that other bots have generated, and produces elaborate datasets for others to consume. " +indicator_bot: "An indicator bot is an algorithm that processes information that other bots have generated, and produces elaborate datasets for others to consume." -process_definition: "The process definition node groups all definitions required for a process to function. The Multi Period Market Process deals with time frames of one hour and above. The Multi Period Daily Process deals with time frames of 45 minutes and below." +process_definition: "The process definition node groups all definitions required for a process to function. The Multi-Period-Market Process deals with time frames of one hour and above. The Multi-Period-Daily Process deals with time frames of 45 minutes and below." process_output: "The process output groups the definitions of which datasets are impacted by the process, that is, which datasets the process builds or takes a part in building." @@ -22,7 +22,7 @@ execution_finished_event: "The execution finished event is the event that proces product_definition: "The product definition node holds all definitions that make up a product, including how the product is calculated and the datasets the product is comprised of." -dataset_definition: "A dataset definition contains a configuration file that defines all aspects of the dataset. There are two types of dataset definitions: multi period market and multi period daily." +dataset_definition: "A dataset definition contains a configuration file that defines all aspects of the dataset. There are two types of dataset definitions: Multi-Period-Market and Multi-Period-Daily." record_definition: "The record definition is where indicators define how many fields, what fields and in which order those fields will be stored in each record." @@ -32,7 +32,7 @@ formula: "In the context of a record definition, formulas are used to assign a v calculations_procedure: "The calculations procedure processes information to be fed to calculated properties. Calculated properties are not stored in the data set; instead, they are calculated in real-time as the data is consumed by others." -procedure_loop: "The procedure loop holds the JavaScript code that cycles through an input processing information to generate an output." +procedure_loop: "The procedure loop holds the JavaScript code that reads an input, processes the information, and generates an output recursively." javascript_code: "The JavaScript code node may hold any snippet of valid JavaScript." @@ -40,34 +40,34 @@ procedure_initialization: "The procedure initialization is used to initialize va data_building_procedure: "The data building procedure processes information to be fed to properties that are stored in the output dataset." -plotter: "A plotter is a device used to produce a graphic representation of the data generated by indicators." +plotter: "A plotter is a device used to produce a graphic representation of datasets generated by bots." -plotter_module: "A plotter module is a device within a plotter that contains the definitions to create the visualization, often times, for a particular product definition." +plotter_module: "A plotter module is a device within a plotter that contains the definitions to create the visualization for a product definition." plotter_panel: "A plotter panel usually shows numerical representations of data over the charts on a small window or panel. The plotter panel node features definitions to make that possible." panel_data: "A panel data node represents a data field to be plotted on the plotter panel." -data_formula: "A data formula is the device used to assign a value to the panel data, usually in the form of the name of the corresponding record property." +data_formula: "A data formula is a device used to assign a value to the panel data, usually in the form of the name of the corresponding record property." -shapes: "The shapes node contains definitions that define polygons and styles to be rendered on a per period basis over the charts." +shapes: "The shapes node contains definitions of polygons and styles to be rendered on a per-period basis over the charts." -chart_points: "The chart points node groups definitions of points." +chart_points: "A chart points groups definitions of coordinate points used to define polygons." -point: "A point is a definition of an [x,y] coordinate where x is usually a datetime and y is usually a value that refers to a price, as output by the indicator." +point: "A point is a definition of an [x,y] coordinate. The value [x] usually represents a datetime. The value [y] may refer to a price or some other concept." -point_formula: "A point formula is the node used to input the coordinates of a point." +point_formula: "A point formula is a node used to input the [x,y] coordinates of a point." -polygon: "A polygon features definitions that make up shapes and their styles." +polygon: "A polygon features definitions that makeup shapes and their styles." -polygon_vertex: "A polygon vertex is a reference to a point defined in the chart points, constituting a specific coordinate to be used as vertex of a shape." +polygon_vertex: "A polygon vertex is a reference to a point defined in the chart points, constituting a specific coordinate to be used as a vertex of a shape." polygon_border: "A polygon border is a shape defined by at least two vertices used to draw lines or to apply a style to the stroke of a closed shape." -style: "A style is a definition of color and opacity in case of a polygon body, and of color, opacity and line thickness in case of polygon borders." +style: "A style is a definition of color and opacity in case of a polygon body, and color, opacity and line thickness in case of polygon borders." style_condition: "A style condition is a rule that allows applying an alternative style in cases where the rule validates true." -polygon_body: "A polygon body is is the fill of a shape made out of at least 3 vertices." +polygon_body: "A polygon body is the fill of a shape made out of at least three vertices." pending: "daily files, market files and so on, Multi-Period-Daily, Multi-Period-Market" \ No newline at end of file diff --git a/docs/_data/network.md b/docs/_data/network.md index 974e534e0..31ee62915 100644 --- a/docs/_data/network.md +++ b/docs/_data/network.md @@ -1,4 +1,4 @@ -network: "The network hierarchy contains definitions regarding the physical location in which certain nodes live or function. For instance, a certain process my run and store data in your local machine, or in some other machine in the network." +network: "The network hierarchy contains definitions regarding the physical location in which certain nodes live or function. For instance, a certain process my run and store data in your local machine or some other machine in the network." network_node: "A network node represents a machine in the network on which processes run or data is stored." diff --git a/docs/_data/network.yml b/docs/_data/network.yml index 974e534e0..31ee62915 100644 --- a/docs/_data/network.yml +++ b/docs/_data/network.yml @@ -1,4 +1,4 @@ -network: "The network hierarchy contains definitions regarding the physical location in which certain nodes live or function. For instance, a certain process my run and store data in your local machine, or in some other machine in the network." +network: "The network hierarchy contains definitions regarding the physical location in which certain nodes live or function. For instance, a certain process my run and store data in your local machine or some other machine in the network." network_node: "A network node represents a machine in the network on which processes run or data is stored." diff --git a/docs/_data/sidebars/suite_sidebar.yml b/docs/_data/sidebars/suite_sidebar.yml index 6411824c0..6a1afafe1 100644 --- a/docs/_data/sidebars/suite_sidebar.yml +++ b/docs/_data/sidebars/suite_sidebar.yml @@ -6,108 +6,108 @@ entries: version: 0.0.6 folders: - - title: - output: pdf - type: frontmatter - folderitems: - - title: - url: /titlepage.html - output: pdf - type: frontmatter - - title: - url: /tocpage.html - output: pdf - type: frontmatter +# - title: +# output: pdf +# type: frontmatter +# folderitems: +# - title: +# url: /titlepage.html +# output: pdf +# type: frontmatter +# - title: +# url: /tocpage.html +# output: pdf +# type: frontmatter - - title: Before you Begin - output: web - folderitems: +# - title: Before you Begin +# output: web +# folderitems: - - title: Welcome! - url: /index.html - output: web - type: homepage +# - title: Welcome! +# url: /index.html +# output: web +# type: homepage - - title: What to expect - url: /suite-what-to-expect.html - output: web +# - title: What to expect +# url: /suite-what-to-expect.html +# output: web - - title: System requirements - url: /suite-system-requirements.html - output: web +# - title: System requirements +# url: /suite-system-requirements.html +# output: web - - title: Getting Started - output: web - folderitems: +# - title: Getting Started +# output: web +# folderitems: - - title: Download and set up - url: /suite-download-and-set-up.html - output: web +# - title: Download and set up +# url: /suite-download-and-set-up.html +# output: web - - title: Run the suite - url: /suite-run-the-suite.html - output: web +# - title: Run the suite +# url: /suite-run-the-suite.html +# output: web - - title: Quick overview - url: /suite-quick-overview.html - output: web +# - title: Quick overview +# url: /suite-quick-overview.html +# output: web - - title: Run your first backtest - url: /suite-run-your-first-backtest.html - output: web +# - title: Run your first backtest +# url: /suite-run-your-first-backtest.html +# output: web - - title: Update datasets - url: /suite-update-datasets.html - output: web +# - title: Update datasets +# url: /suite-update-datasets.html +# output: web - - title: Trade with an open-source strategy - url: /suite-trade-live-with-an-open-source-strategy.html - output: web +# - title: Trade with an open-source strategy +# url: /suite-trade-live-with-an-open-source-strategy.html +# output: web - - title: What's next? - url: /suite-what-is-next.html - output: web +# - title: What's next? +# url: /suite-what-is-next.html +# output: web - - title: Charts - output: web - folderitems: +# - title: Charts +# output: web +# folderitems: - - title: Overview - url: /suite-charts-overview.html - output: web +# - title: Overview +# url: /suite-charts-overview.html +# output: web - - title: Interface - url: /suite-charts-interface.html - output: web +# - title: Interface +# url: /suite-charts-interface.html +# output: web - - title: Layers panel - url: /suite-layers-panel.html - output: web +# - title: Layers panel +# url: /suite-layers-panel.html +# output: web - - title: Designer - output: web - folderitems: +# - title: Designer +# output: web +# folderitems: - - title: Intro, workspace and data structures - url: /suite-designer-workspace-and-data-structures.html - output: web +# - title: Intro, workspace and data structures +# url: /suite-designer-workspace-and-data-structures.html +# output: web - - title: Hierarchies - url: /suite-hierarchies.html - output: web +# - title: Hierarchies +# url: /suite-hierarchies.html +# output: web - - title: Interface - url: /suite-designer-interface.html - output: web +# - title: Interface +# url: /suite-designer-interface.html +# output: web - - title: Atachment and detachment of nodes - url: /suite-detachment-and-attachment-of-nodes.html - output: web +# - title: Atachment and detachment of nodes +# url: /suite-detachment-and-attachment-of-nodes.html +# output: web - - title: References - url: /suite-references.html - output: web +# - title: References +# url: /suite-references.html +# output: web - title: Trading Concepts output: web @@ -129,149 +129,149 @@ entries: url: /suite-parameters.html output: web - - title: Conditions & Formulas - output: web - folderitems: +# - title: Conditions & Formulas +# output: web +# folderitems: - - title: Syntax Overview - url: /suite-sysntax-overview.html - output: web +# - title: Syntax Overview +# url: /suite-sysntax-overview.html +# output: web - - title: Internal variables - url: /suite-internal-variables.html - output: web +# - title: Internal variables +# url: /suite-internal-variables.html +# output: web - - title: Indicators included in the data release - url: /suite-indicators-included-in-the-data-release.html - output: web +# - title: Indicators included in the data release +# url: /suite-indicators-included-in-the-data-release.html +# output: web - - title: Indicators not included in the release - url: /suite-indicators-not-included-in-the-data-release.html - output: web +# - title: Indicators not included in the release +# url: /suite-indicators-not-included-in-the-data-release.html +# output: web - - title: Using non-included indicators - url: /suite-using-non-included-indicators.html - output: web +# - title: Using non-included indicators +# url: /suite-using-non-included-indicators.html +# output: web - - title: Network - output: web - folderitems: +# - title: Network +# output: web +# folderitems: - - title: Overview - url: /suite-network-overview.html - output: web +# - title: Overview +# url: /suite-network-overview.html +# output: web - - title: Managing processes - url: /suite-managing-processes.html - output: web +# - title: Managing processes +# url: /suite-managing-processes.html +# output: web - - title: Backtests & Paper Trading - output: web - folderitems: +# - title: Backtests & Paper Trading +# output: web +# folderitems: - - title: Overview - url: /suite-testing-overview.html - output: web +# - title: Overview +# url: /suite-testing-overview.html +# output: web - - title: Session parameters - url: /suite-session-parameters.html - output: web +# - title: Session parameters +# url: /suite-session-parameters.html +# output: web - - title: Simulation layers - url: /suite-simulation-layers.html - output: web +# - title: Simulation layers +# url: /suite-simulation-layers.html +# output: web - - title: Advanced backtesting - url: /suite-advanced-backtesting.html - output: web +# - title: Advanced backtesting +# url: /suite-advanced-backtesting.html +# output: web - - title: Forward Tests & Live Trading - output: web - folderitems: +# - title: Forward Tests & Live Trading +# output: web +# folderitems: - - title: Overview - url: /suite-live-trading-overview.html - output: web +# - title: Overview +# url: /suite-live-trading-overview.html +# output: web - - title: Getting ready to trade live - url: /suite-getting-ready-to-trade-live.html - output: web +# - title: Getting ready to trade live +# url: /suite-getting-ready-to-trade-live.html +# output: web - - title: Live trading history layer - url: /suite-live-trading-history-layer.html - output: web +# - title: Live trading history layer +# url: /suite-live-trading-history-layer.html +# output: web - - title: Execution limitations - url: /suite-execution-limitations.html - output: web +# - title: Execution limitations +# url: /suite-execution-limitations.html +# output: web - - title: Multiple sessions - url: /suite-multiple-forward-testing-and-live-trading-sessions.html - output: web +# - title: Multiple sessions +# url: /suite-multiple-forward-testing-and-live-trading-sessions.html +# output: web - - title: Data Mining & Research - output: web - folderitems: +# - title: Data Mining & Research +# output: web +# folderitems: - - title: Data Mining Overview - url: /suite-data-mining-overview.html - output: web +# - title: Data Mining Overview +# url: /suite-data-mining-overview.html +# output: web - - title: Bots - url: /suite-bots.html - output: web +# - title: Bots +# url: /suite-bots.html +# output: web - - title: Anatomy of an indicator - url: /suite-anatomy-of-an-indicator.html - output: web +# - title: Anatomy of an indicator +# url: /suite-anatomy-of-an-indicator.html +# output: web - - title: ":: Process definition" - url: /suite-process-definition.html - output: web +# - title: ":: Process definition" +# url: /suite-process-definition.html +# output: web - - title: ":: Product definition" - url: /suite-product-definition.html - output: web +# - title: ":: Product definition" +# url: /suite-product-definition.html +# output: web - - title: Input-to-output cycle - url: /suite-input-to-output-cycle.html - output: web +# - title: Input-to-output cycle +# url: /suite-input-to-output-cycle.html +# output: web - - title: Datasets - url: /suite-datasets.html - output: web +# - title: Datasets +# url: /suite-datasets.html +# output: web - - title: Dependencies - url: /suite-dependencies.html - output: web +# - title: Dependencies +# url: /suite-dependencies.html +# output: web - - title: Build an indicator - url: /suite-build-an-indicator.html - output: web +# - title: Build an indicator +# url: /suite-build-an-indicator.html +# output: web - - title: Build a plotter - url: /suite-build-a-plotter.html - output: web +# - title: Build a plotter +# url: /suite-build-a-plotter.html +# output: web - - title: Productivity Tools - output: web - folderitems: +# - title: Productivity Tools +# output: web +# folderitems: - - title: Backups - url: /suite-backups.html - output: web +# - title: Backups +# url: /suite-backups.html +# output: web - - title: Clones - url: /suite-clones.html - output: web +# - title: Clones +# url: /suite-clones.html +# output: web - - title: Shares - url: /suite-shares.html - output: web +# - title: Shares +# url: /suite-shares.html +# output: web - - title: Telegram Announcements - url: /suite-telegram-announcements.html - output: web +# - title: Telegram Announcements +# url: /suite-telegram-announcements.html +# output: web - title: Hierarchies Directory output: web @@ -281,8 +281,8 @@ entries: url: /suite-crypto-ecosystem-hierarchy.html output: web - - title: Charting system - url: /suite-charting-system-hierarchy.html + - title: Charting Space + url: /suite-charting-space-hierarchy.html output: web - title: Trading system @@ -297,33 +297,33 @@ entries: url: /suite-data-mine-hierarchy.html output: web - - title: Troubleshooting - output: web - folderitems: +# - title: Troubleshooting +# output: web +# folderitems: - - title: Upgrading your existing installation - url: /suite-upgrading-your-existing-instalation.html - output: web +# - title: Upgrading your existing installation +# url: /suite-upgrading-your-existing-instalation.html +# output: web - - title: My system gets slow - url: /suite-my-system-gets-slow.html - output: web +# - title: My system gets slow +# url: /suite-my-system-gets-slow.html +# output: web - - title: On-screen errors and warnings - url: /suite-on-screen-errors-and-warnings.html - output: web +# - title: On-screen errors and warnings +# url: /suite-on-screen-errors-and-warnings.html +# output: web - - title: Market data seems to be outdated - url: /suite-market-data-indicators-seem-to-be-outdated.html - output: web +# - title: Market data seems to be outdated +# url: /suite-market-data-indicators-seem-to-be-outdated.html +# output: web - - title: Reporting bugs - url: /suite-reporting-bugs.html - output: web +# - title: Reporting bugs +# url: /suite-reporting-bugs.html +# output: web - - title: Consulting logs - url: /suite-consulting-logs.html - output: web +# - title: Consulting logs +# url: /suite-consulting-logs.html +# output: web diff --git a/docs/_data/topnav.yml b/docs/_data/topnav.yml index 63a54875b..e232fbb32 100644 --- a/docs/_data/topnav.yml +++ b/docs/_data/topnav.yml @@ -11,24 +11,24 @@ topnav: url: index.html #Topnav dropdowns -topnav_dropdowns: -- title: Topnav dropdowns - folders: - - title: Product Docs - folderitems: - - title: Systematic Trading - url: /systematic-trading-system-overview.html - - title: Algorithmic Trading - url: /algorithmic-trading-system-overview.html - - title: Discretionary Trading - url: /discretionary-introduction.html - - title: Smart Holding - url: /smart-introduction.html - - title: Trading Coach - url: /coach-introduction_page.html - - title: Signals Broadcast - url: /signal-introduction.html - - title: Markets Research - url: /market-introduction_page.html - - title: Data Mining - url: /mine-introduction.html \ No newline at end of file +#topnav_dropdowns: +#- title: Topnav dropdowns +# folders: +# - title: Product Docs +# folderitems: +# - title: Systematic Trading +# url: /systematic-trading-system-overview.html +# - title: Algorithmic Trading +# url: /algorithmic-trading-system-overview.html +# - title: Discretionary Trading +# url: /discretionary-introduction.html +# - title: Smart Holding +# url: /smart-introduction.html +# - title: Trading Coach +# url: /coach-introduction_page.html +# - title: Signals Broadcast +# url: /signal-introduction.html +# - title: Markets Research +# url: /market-introduction_page.html +# - title: Data Mining +# url: /mine-introduction.html \ No newline at end of file diff --git a/docs/_includes/sidebar.html b/docs/_includes/sidebar.html index 6bdcbb1e1..4ed2627c8 100644 --- a/docs/_includes/sidebar.html +++ b/docs/_includes/sidebar.html @@ -47,11 +47,11 @@ {% endif %} {% endfor %} {% endfor %} - + diff --git a/docs/_includes/trading_system/base-asset.md b/docs/_includes/trading_system/base-asset.md index 3a886ca33..669fb7347 100644 --- a/docs/_includes/trading_system/base-asset.md +++ b/docs/_includes/trading_system/base-asset.md @@ -89,14 +89,3 @@ Select *Configure Base Asset* on the menu to access the configuration. {% endif %} -{% if include.starting != "" %} - -{{include.starting}} Starting {{preposition}} {{title}} - - - -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - - - -{% endif %} \ No newline at end of file diff --git a/docs/_includes/trading_system/fee-structure.md b/docs/_includes/trading_system/fee-structure.md index 9c7aada7b..2b9a2028d 100644 --- a/docs/_includes/trading_system/fee-structure.md +++ b/docs/_includes/trading_system/fee-structure.md @@ -1,7 +1,7 @@ {% assign title = "Fee Structure" %} -{% assign definition = site.data.trading_system.free_structure %} +{% assign definition = site.data.trading_system.fee_structure %} {% assign preposition = "a" %} @@ -40,8 +40,6 @@ {% if include.content != "n" %} -**{{ definition }}** - Exchange fees are a crucial part of trading. A strategy may work like a charm when you leave fees out of the equation but would lead you to bankruptcy in a live trading situation. @@ -101,14 +99,3 @@ Select *Configure Fee Structure* on the menu to access the configuration. {% endif %} -{% if include.starting != "" %} - -{{include.starting}} Starting {{preposition}} {{title}} - - - -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - - - -{% endif %} \ No newline at end of file diff --git a/docs/_includes/trading_system/quoted-asset.md b/docs/_includes/trading_system/quoted-asset.md index 4657da30a..552c0a88c 100644 --- a/docs/_includes/trading_system/quoted-asset.md +++ b/docs/_includes/trading_system/quoted-asset.md @@ -1,7 +1,7 @@ {% assign title = "Quoted Asset" %} -{% assign definition = site.data.trading_system.quote_asset %} +{% assign definition = site.data.trading_system.quoted_asset %} {% assign preposition = "a" %} diff --git a/docs/_includes/trading_system/slippage.md b/docs/_includes/trading_system/slippage.md index 465e51abb..e2c44b857 100644 --- a/docs/_includes/trading_system/slippage.md +++ b/docs/_includes/trading_system/slippage.md @@ -1,7 +1,7 @@ {% assign title = "Slippage" %} -{% assign definition = site.data.trading_system.slipage %} +{% assign definition = site.data.trading_system.slippage %} {% assign preposition = "a" %} diff --git a/docs/css/theme-blue.css b/docs/css/theme-blue.css index 1ded1de0d..277a304ab 100644 --- a/docs/css/theme-blue.css +++ b/docs/css/theme-blue.css @@ -104,7 +104,7 @@ div.sidebarTitle { li.sidebarTitle { margin-top:30px; font-weight:600; - font-size:130%; + font-size:120%; color: #000; margin-bottom:10px; margin-left: 5px; diff --git a/docs/images/icons/150-charting-space.png b/docs/images/icons/150-charting-space.png new file mode 100644 index 000000000..f47ef3d3f Binary files /dev/null and b/docs/images/icons/150-charting-space.png differ diff --git a/docs/images/icons/charting-space.png b/docs/images/icons/charting-space.png new file mode 100644 index 000000000..025131da1 Binary files /dev/null and b/docs/images/icons/charting-space.png differ diff --git a/docs/index.md b/docs/index.md index c880d81dc..beaa4e3ae 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,32 +4,16 @@ sidebar: suite_sidebar permalink: index.html --- -The Superalgos Platform provides a visual environment for developing, testing and automating crypto-trading strategies. +## About this Documentation -**The platform's vocation is to become the most comprehensive data processing and trading automation system available to all traders, data scientists, analysts and crypto holders.** +This documentation is currently work in progress and corresponds to an unreleased version of the Superalgos Suite, still in development. The system has experienced a major shift on multiple fronts, and changes are currently being documented. -The platform allows designing and automating a wide variety of strategies, as well as augmenting your *intelligence* by handling and creating your own datasets, with great flexibility. - -This is not a simple plug-and-play bot. However, we try our best to make light use of the platform as easy as possible, for instance, for loading existing strategies and trading live right off the bat, with minimal user input. - -[](https://user-images.githubusercontent.com/13994516/63528460-4550ae80-c503-11e9-8db6-22995e0b9c16.gif) - -## About this Manual - -This manual is arranged in three sections: - -* **Basic Use** helps you set up the platform, teaches you the very basic operation, and takes you by the hand until you are ready to start trading live with one of the open-source strategies currently available. - -* **Power Use** takes you through the learning curve to modify strategies and design your own, and shows you what's under the hood of the platform so that you may take control of all the resources that make up a successful trader. - -* **Data Mining** pumps the potential for growing your *intelligence* through the roof by teaching you how to process data and build your own datasets. Analysing and processing data is what turns data into *information*. Using information effectively is what realises *intelligence*. - -You may access each topic by using the menu on the right. We try our best to organize the content in a logical order, so that you are exposed to information incrementally, as you need it while you go through the learning curve. +The Hierarchies Directory feature extensive information about all the data structures handled by the designer, including the new, unreleased ones. ## Beta Stage Notice This is a pre-release in beta stage. The platform is under heavy development. We appreciate your help in testing the platform and reporting any errors you may experience. We will keep improving user experience with your feedback. -> **WARNING:** The Superalgos Platform is at a very early stage of development. As such, errors may occur at any point, including errors that may cause you to lose money. You are responsible for taking all precautions before starting trading live. Make sure you forward-test with small amounts of money, the kind you can afford losing. Trade live at your own risk. +{% include important.html content="The Superalgos Platform is at a very early stage of development. As such, errors may occur at any point, including errors that may cause you to lose money. You are responsible for taking all precautions before starting trading live. Make sure you forward-test with small amounts of money, the kind you can afford losing. Trade live at your own risk." %} diff --git a/docs/pages/suite/suite-charting-space-hierarchy.md b/docs/pages/suite/suite-charting-space-hierarchy.md new file mode 100644 index 000000000..021097a92 --- /dev/null +++ b/docs/pages/suite/suite-charting-space-hierarchy.md @@ -0,0 +1,420 @@ +--- +title: Charting Space Hierarchy +summary: "The charting space provides the tools to flexibly configure charts with data from different markets, exchanges, and multiple data products." +sidebar: suite_sidebar +permalink: suite-charting-space-hierarchy.html +toc: false +--- + +{% include note.html content="Hover your mouse over a node for a tooltip definition, and click to get all the details." %} + +
|
+ Charting Space + |
+ + | + | + | + | + | + | + | + |
|---|---|---|---|---|---|---|---|---|
|
+ |
+
+ Viewport + |
+ + | + | + | + | + | + | + |
|
+ |
+
+ Time Machine + |
+ + | + | + | + | + | + | + |
| + |
+ |
+
+ Time Scale + |
+ + | + | + | + | + | + |
| + |
+ |
+
+ Rate Scale + |
+ + | + | + | + | + | + |
| + |
+ |
+
+ Time Frame Scale + |
+ + | + | + | + | + | + |
| + |
+ |
+
+ Timeline Chart + |
+ + | + | + | + | + | + |
| + | + |
+ |
+
+ Rate Scale + |
+ + | + | + | + | + |
| + | + |
+ |
+
+ Time Frame Scale + |
+ + | + | + | + | + |
| + | + |
+ |
+
+ Layers Manager + |
+ + | + | + | + | + |
| + | + | + |
+ |
+
+ Layer + |
+ + | + | + | + |
Network | ||||||||
|---|---|---|---|---|---|---|---|---|
Network Node | ||||||||
Task Manager |
Charting System | ||||||||
|---|---|---|---|---|---|---|---|---|
Viewport | ||||||||
Time Machine | ||||||||
Time Scale | ||||||||
Rate Scale | ||||||||
Time Frame Scale | ||||||||
Timeline Chart | ||||||||
Rate Scale | ||||||||
Time Frame Scale | ||||||||
Layers Manager | ||||||||
Layer |
Charting Space | ||||||||
|---|---|---|---|---|---|---|---|---|
Viewport | ||||||||
Time Machine | ||||||||
Time Scale | ||||||||
Rate Scale | ||||||||
Time Frame Scale | ||||||||
Timeline Chart | ||||||||
Rate Scale | ||||||||
Time Frame Scale | ||||||||
Layers Manager | ||||||||
Layer |