diff --git a/Assistant.js b/Assistant.js
index 8856864fb..e34cf5884 100644
--- a/Assistant.js
+++ b/Assistant.js
@@ -487,7 +487,12 @@
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] ordersExecutionCheck -> loopBody -> positionFound -> Entering function."); }
- /*
+ /* We update the final amountA based on what we got from the exchange.
+ This is needed since the values could be different from what we calculate.
+ */
+ position.amountA = exchangePosition.amountA;
+
+ /*
We need to know if the order was partially executed. To know that, we compare the amounts on file with the ones
received from the exchange. If they are the same, then the order is intact. Otherwise, to confirm a partial execution,
@@ -497,8 +502,7 @@
if (position.amountB === exchangePosition.amountB) {
- /* Position is still there, untouched. We update the final amountA on exchange. */
- position.amountA = exchangePosition.amountA;
+ /* Position is still there, untouched. Nothing to do here. */
next();
return;
@@ -558,10 +562,7 @@
if (thisPosition.id === pPositionId) {
- let feeRate = 0.0025; // Default fee
-
- if (Math.random(1) < 0.5)
- feeRate = 0.0015; // Some times we will pay less fee
+ let feeRate = 0.002; // Default backtesting fee simulation
let trade = {
id: Math.trunc(Math.random(1) * 1000000),
@@ -630,7 +631,6 @@
callBack(global.DEFAULT_FAIL_RESPONSE);
}
}
-
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] ordersExecutionCheck -> loopBody -> getPositionTradesAtExchange -> err = " + err.message);
callBack(global.DEFAULT_FAIL_RESPONSE);
@@ -749,9 +749,9 @@
let exchangeParam = exchangeAPI.getMaxDecimalPositions();
let minValue = '0.' + (1).toPrecision(exchangeParam-1).split('.').reverse().join('');
- let decimalPositions = parseFloat(parseFloat(minValue).toFixed(exchangeParam));
+ let exchangePrecision = parseFloat(parseFloat(minValue).toFixed(exchangeParam));
- if (Math.abs(position.amountA - sumAssetA) > decimalPositions || Math.abs(position.amountB - sumAssetB) > decimalPositions) {
+ if (Math.abs(position.amountA - sumAssetA) > exchangePrecision || Math.abs(position.amountB - sumAssetB) > exchangePrecision) {
logger.write(MODULE_NAME, "[INFO] ordersExecutionCheck -> loopBody -> confirmOrderWasPartiallyExecuted -> position.amountA = " + position.amountA);
logger.write(MODULE_NAME, "[INFO] ordersExecutionCheck -> loopBody -> confirmOrderWasPartiallyExecuted -> sumAssetA = " + sumAssetA);
@@ -857,8 +857,8 @@
context.executionContext.balance.assetA = thisObject.truncDecimals(context.executionContext.balance.assetA + assetA);
context.executionContext.balance.assetB = thisObject.truncDecimals(context.executionContext.balance.assetB - assetB);
- let calculatedBalance =
- context.executionContext.availableBalance.assetA = thisObject.truncDecimals(context.executionContext.availableBalance.assetA + assetA);
+
+ context.executionContext.availableBalance.assetA = thisObject.truncDecimals(context.executionContext.availableBalance.assetA + assetA);
/* Not the available balance for asset B is not affected since it was already reduced when the order was placed. */
diff --git a/Context.js b/Context.js
index 9dd5053a5..133598a8b 100644
--- a/Context.js
+++ b/Context.js
@@ -70,15 +70,18 @@
let runIndex; // This is the index for this run and depends on the startMode.
+ let totalAlgobots;
+
return thisObject;
- function initialize(pStatusDependencies, callBackFunction) {
+ function initialize(pStatusDependencies, pTotalAlgobots, callBackFunction) {
try {
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
statusDependencies = pStatusDependencies;
+ totalAlgobots = pTotalAlgobots;
/*
@@ -114,8 +117,6 @@
case global.DEFAULT_OK_RESPONSE.result: {
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> onDone -> Execution finished well."); }
- bot.hasTheBotJustStarted = false;
-
callBackFunction(global.DEFAULT_OK_RESPONSE);
return;
}
@@ -328,8 +329,8 @@
once we advance into multiple competitions scheme.
*/
- const INITIAL_INVESTMENT_A = 0; // This is just for this release of the platform.
- const INITIAL_INVESTMENT_B = .002; // This is just for this release of the platform.
+ const INITIAL_INVESTMENT_A = 0; // This is just for this release of the platform.
+ const INITIAL_INVESTMENT_B = .002 / totalAlgobots; // This is just for this release of the platform.
thisObject.executionContext = {
investment: { // This is used to calculate profits.
@@ -384,6 +385,9 @@
switch (err.result) {
case global.DEFAULT_OK_RESPONSE.result: {
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] saveThemAll -> onDone -> Execution finished well."); }
+
+ bot.hasTheBotJustStarted = false;
+
callBackFunction(global.DEFAULT_OK_RESPONSE);
return;
}
diff --git a/Project.njsproj b/Project.njsproj
index a7e60900f..52d61dad1 100644
--- a/Project.njsproj
+++ b/Project.njsproj
@@ -39,6 +39,12 @@
Code
+
+
+
+
+
+
Code
@@ -52,13 +58,12 @@
Code
-
+
Code
Code
-
Code
@@ -70,8 +75,14 @@
+
+
+
+
+
+
diff --git a/Root.js b/Root.js
index cf2dd5839..2e689d2a0 100644
--- a/Root.js
+++ b/Root.js
@@ -386,7 +386,7 @@ exports.newRoot = function newRoot() {
}
- /* We tesst each type of start Mode to get what to run and how. */
+ /* We test each type of start Mode to get what to run and how. */
if (processConfig.startMode.allMonths !== undefined) {
@@ -756,57 +756,163 @@ exports.newRoot = function newRoot() {
function runTradingBot(pBotConfig, pProcessConfig) {
try {
- const DEBUG_MODULE = require(ROOT_DIR + 'DebugLog');
- let logger;
- logger = DEBUG_MODULE.newDebugLog();
- logger.bot = pBotConfig;
+ if (FULL_LOG === true) { console.log(logDisplace + "[INFO] start -> findProcess -> runTradingBot -> Entering function."); }
- if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runTradingBot -> Entering function."); }
+ if (pBotConfig.genes !== undefined) {
- let tradingBotMainLoop = TRADING_BOT_MAIN_LOOP_MODULE.newTradingBotProcessMainLoop(pBotConfig, logger);
- tradingBotMainLoop.initialize(UI_COMMANDS, pProcessConfig, onInitializeReady);
+ /* Here, based on the gene we will create one instance for each combination of genes */
- function onInitializeReady(err) {
+ let valueMatrix = [];
- if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+ for (let i = 0; i < pBotConfig.genes.length; i++) {
- tradingBotMainLoop.run(whenRunFinishes);
+ let gene = pBotConfig.genes[i];
- function whenRunFinishes(err) {
+ let possibleValues = [];
- pBotConfig.loopCounter = 0;
+ for (let j = gene.lowerLimit; j <= gene.upperLimit; j++) {
- let botId;
+ possibleValues.push(j);
- botId = pBotConfig.devTeam + "." + pBotConfig.codeName + "." + pBotConfig.process;
+ }
- if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+ valueMatrix.push(possibleValues);
- logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runTradingBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
- logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runTradingBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
+ }
- console.log(logDisplace + "Root : [INFO] start -> findProcess -> runTradingBot -> onInitializeReady -> whenStartFinishes -> botId = " + botId);
- console.log(logDisplace + "Root : [INFO] start -> findProcess -> runTradingBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
- logger.persist();
+ /*
+ Now we have all the possible genes values in a multi-dimensional matrix.
+ We will go thorugh each of the elements of each dimension and get each combination possible with the other dimmensions.
+ */
+
+ let combinations = [];
+ let combination = [];
+ let dimensionIndex = 0;
+
+ calculateCombinations(dimensionIndex, combination);
+
+ function calculateCombinations(pDimensionIndex, pCombination) {
+
+ let dimension = valueMatrix[pDimensionIndex];
+
+ for (let j = 0; j < dimension.length; j++) {
+
+ let copy = JSON.parse(JSON.stringify(pCombination));
+
+ let value = dimension[j];
+ copy.push(value);
+
+ if (pDimensionIndex < valueMatrix.length - 1) {
+
+ calculateCombinations(pDimensionIndex + 1, copy);
} else {
- logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> onInitializeReady -> whenStartFinishes -> err = " + err.message);
- logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> onInitializeReady -> whenStartFinishes -> Execution will be stopped. ");
- logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> onInitializeReady -> whenStartFinishes -> Bye.");
- logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
- console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished with errors. Please check the logs.");
- logger.persist();
+ combinations.push(copy);
+
}
}
+ }
- } else {
- logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> onInitializeReady -> err = " + err.message);
- logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> onInitializeReady -> Bot will not be started. ");
- console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingBot -> onInitializeReady -> err = " + err.message);
+ /* At this point we have an array with all the possible combinations, we just need to create an instance for each one and set the genes according to that. */
- logger.persist();
+ for (let i = 0; i < combinations.length; i++) {
+
+ let botConfig = JSON.parse(JSON.stringify(pBotConfig));
+ let combination = combinations[i];
+ let genes = {};
+ let clonKey = "";
+
+ for (let j = 0; j < botConfig.genes.length; j++) {
+
+ genes[botConfig.genes[j].name] = combination[j];
+ clonKey = clonKey + "." + combination[j];
+
+ }
+
+ let clonName = "Clon" + clonKey;
+
+ botConfig.filePathRoot = botConfig.devTeam + "/" + botConfig.codeName + "-" + clonName + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + botConfig.dataSetVersion;
+
+ botConfig.instance = "Clon" + clonKey;
+ botConfig.instanceIndex = i;
+
+ setTimeout(execute, i * Math.random() * 10 * 1000);
+
+ function execute() {
+
+ createBotInstance(genes, combinations.length, botConfig);
+
+ }
+ }
+ } else {
+
+ /* If the bot does not have any genes at all */
+
+ let genes = {};
+ pBotConfig.instance = "Master";
+ pBotConfig.instanceIndex = 0;
+
+ createBotInstance(genes, 1, pBotConfig);
+
+ }
+
+
+ function createBotInstance(pGenes, pTotalInstances, pBotConfig) {
+
+ const DEBUG_MODULE = require(ROOT_DIR + 'DebugLog');
+ let logger;
+
+ logger = DEBUG_MODULE.newDebugLog();
+ logger.bot = pBotConfig;
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runTradingBot -> createBotInstance -> Entering function."); }
+
+ let tradingBotMainLoop = TRADING_BOT_MAIN_LOOP_MODULE.newTradingBotProcessMainLoop(pBotConfig, logger);
+ tradingBotMainLoop.initialize(UI_COMMANDS, pProcessConfig, onInitializeReady);
+
+ function onInitializeReady(err) {
+
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+
+ tradingBotMainLoop.run(pGenes, pTotalInstances, whenRunFinishes);
+
+ function whenRunFinishes(err) {
+
+ pBotConfig.loopCounter = 0;
+
+ let botId;
+
+ botId = pBotConfig.devTeam + "." + pBotConfig.codeName + "." + pBotConfig.instance + "." + pBotConfig.process;
+
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+
+ logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
+ logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
+
+ console.log(logDisplace + "Root : [INFO] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> botId = " + botId);
+ console.log(logDisplace + "Root : [INFO] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
+ logger.persist();
+
+ } else {
+
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> err = " + err.message);
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> Execution will be stopped. ");
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> Bye.");
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
+ console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> Bot execution finished with errors. Please check the logs.");
+ logger.persist();
+ }
+ }
+
+ } else {
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> err = " + err.message);
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> Bot will not be started. ");
+ console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> err = " + err.message);
+
+ logger.persist();
+ }
}
}
}
diff --git a/Run.js b/Run.js
index fbfb498a1..4911e433d 100644
--- a/Run.js
+++ b/Run.js
@@ -97,10 +97,10 @@ function readExchangeAPIKey() {
console.log("[HINT] You need to have a file at this path -> " + filePath);
global.EXCHANGE_KEYS = {
- Poloniex: {
+ Poloniex: [{
Key: "",
Secret: ""
- }
+ }]
}
startRoot();
diff --git a/StatusReport.js b/StatusReport.js
index a736ae325..155f2aaf9 100644
--- a/StatusReport.js
+++ b/StatusReport.js
@@ -88,10 +88,24 @@
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> load -> Entering function."); }
- let rootPath = owner.devTeam + "/" + owner.bot + "." + owner.botVersion.major + "." + owner.botVersion.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + owner.dataSetVersion;
let fileName = "Status.Report." + global.MARKET.assetA + '_' + global.MARKET.assetB + ".json";
- let filePath = rootPath + "/Reports/" + owner.process + timePath;
-
+ let filePath;
+
+ let ownerId = owner.devTeam + "-" + owner.bot + "-" + owner.botVersion.major + "-" + owner.botVersion.minor + "-" + owner.process + "-" + owner.dataSetVersion;
+ let botId = bot.devTeam + "-" + bot.codeName + "-" + bot.version.major + "-" + bot.version.minor + "-" + bot.process + "-" + bot.dataSetVersion;
+
+ if (ownerId !== botId) {
+
+ let rootPath = owner.devTeam + "/" + owner.bot + "." + owner.botVersion.major + "." + owner.botVersion.minor + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + owner.dataSetVersion;
+
+ filePath = rootPath + "/Reports/" + owner.process + timePath;
+
+ } else {
+
+ filePath = bot.filePathRoot + "/Reports/" + owner.process + timePath;
+
+ }
+
if (bot.type === 'Trading') {
fileName = bot.startMode + "." + fileName;
}
diff --git a/TradingBotProcessMainLoop.js b/TradingBotProcessMainLoop.js
index 8a40bd772..877150c6b 100644
--- a/TradingBotProcessMainLoop.js
+++ b/TradingBotProcessMainLoop.js
@@ -132,7 +132,7 @@
}
}
- function run(callBackFunction) {
+ function run(pGenes, pTotalAlgobots, callBackFunction) {
try {
if (FULL_LOG === true) { parentLogger.write(MODULE_NAME, "[INFO] run -> Entering function."); }
@@ -160,7 +160,7 @@
return str.length < max ? pad(" " + str, max) : str;
}
- console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " Entered into Main Loop # " + pad(Number(bot.loopCounter) + 1, 8));
+ console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.instance, 20) + " " + pad(bot.process, 30) + " Entered into Main Loop # " + pad(Number(bot.loopCounter) + 1, 8));
/* For each loop we want to create a new log file. */
@@ -535,7 +535,7 @@
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeContext -> Entering function."); }
context = CONTEXT.newContext(bot, logger, BLOB_STORAGE, UTILITIES, STATUS_REPORT);
- context.initialize(statusDependencies, onInizialized);
+ context.initialize(statusDependencies, pTotalAlgobots, onInizialized);
function onInizialized(err) {
@@ -756,7 +756,7 @@
usertBot = USER_BOT_MODULE.newUserBot(bot, logger, COMMONS_MODULE);
- usertBot.initialize(assistant, onInizialized);
+ usertBot.initialize(assistant, pGenes, onInizialized);
function onInizialized(err) {
@@ -1058,7 +1058,7 @@
if (now - bot.loopStartTime > processConfig.normalWaitTime) {
logger.write(MODULE_NAME, "[ERROR] run -> loop -> checkLoopHealth -> Dead loop found -> pLastLoop = " + pLastLoop);
- console.log((new Date().toISOString() + " [ERROR] run -> loop -> checkLoopHealth -> " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " Loop # " + pad(Number(bot.loopCounter), 5) + " found dead. Resurrecting it now."));
+ console.log((new Date().toISOString() + " [ERROR] run -> loop -> checkLoopHealth -> " + pad(bot.codeName, 20) + " " + pad(bot.instance, 20) + " " + pad(bot.process, 30) + " Loop # " + pad(Number(bot.loopCounter), 5) + " found dead. Resurrecting it now."));
logger.persist(); // We persist the logs of the failed execution.
clearTimeout(nextLoopTimeoutHandle); // We cancel the timeout in case the original loop was still running and schedulled to reexecute.
@@ -1066,7 +1066,7 @@
} else {
- console.log((new Date().toISOString() + " [WARN] run -> loop -> checkLoopHealth -> " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " Loop # " + pad(Number(bot.loopCounter), 5) + " found delayed but still alive. No action taken."));
+ console.log((new Date().toISOString() + " [WARN] run -> loop -> checkLoopHealth -> " + pad(bot.codeName, 20) + " " + pad(bot.instance, 20) + " " + pad(bot.process, 30) + " Loop # " + pad(Number(bot.loopCounter), 5) + " found delayed but still alive. No action taken."));
}
}
diff --git a/exchange/ExchangeAPI.js b/exchange/ExchangeAPI.js
index c205f26c6..235d2d7a5 100644
--- a/exchange/ExchangeAPI.js
+++ b/exchange/ExchangeAPI.js
@@ -31,7 +31,8 @@
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
- let exchange = bot.products[0].exchangeList[0].name.toLowerCase() + 'Client.js'; //TODO Improve
+ //let exchange = bot.products[0].exchangeList[0].name.toLowerCase() + 'Client.js'; //TODO Define
+ let exchange = 'binanceClient.js'; //TODO Define
let api = require('./wrappers/' + exchange);
apiClient = api.newAPIClient(global.EXCHANGE_KEYS[global.EXCHANGE_NAME].Key, global.EXCHANGE_KEYS[global.EXCHANGE_NAME].Secret, logger);
@@ -168,8 +169,8 @@
let check = isValidOrder({
market: getMarketConfig(),
api: apiClient,
- pAmountB: truncDecimals(pAmountB),
- pRate: truncDecimals(pRate)
+ amount: truncDecimals(pAmountB),
+ price: truncDecimals(pRate)
});
if (check.valid) {
diff --git a/exchange/exchangeUtils.js b/exchange/exchangeUtils.js
index 4ac0fe9fd..853d6d825 100644
--- a/exchange/exchangeUtils.js
+++ b/exchange/exchangeUtils.js
@@ -83,9 +83,18 @@ const includes = function(str, list) {
return _.some(list, item => str.includes(item));
}
+
+const getMarketConfig = function(exchangeProperties) {
+ return _.find(exchangeProperties.markets, (p) => {
+ return _.first(p.pair) === global.MARKET.assetA.toUpperCase() &&
+ _.last(p.pair) === global.MARKET.assetB.toUpperCase();
+ });
+}
+
module.exports = {
retry: retryInstance,
includes: includes,
- isValidOrder
+ isValidOrder,
+ getMarketConfig
}
\ No newline at end of file
diff --git a/exchange/wrappers/binanceClient.js b/exchange/wrappers/binanceClient.js
index d97b182c7..a46ca7d24 100644
--- a/exchange/wrappers/binanceClient.js
+++ b/exchange/wrappers/binanceClient.js
@@ -44,7 +44,9 @@
sell: sell,
movePosition: movePosition,
getPublicTradeHistory: getPublicTradeHistory,
- getExchangeProperties: getExchangeProperties
+ getExchangeProperties: getExchangeProperties,
+ isValidPrice: isValidPrice,
+ isValidLot: isValidLot
};
return thisObject;
@@ -65,6 +67,14 @@
return exchangeProperties;
}
+ function truncDecimals(pFloatValue) {
+
+ let decimals = 6;
+
+ return parseFloat(parseFloat(pFloatValue).toFixed(decimals));
+
+ }
+
/*
* Returns the price for a given pair of assets.
* The object returned is an array of trades:
diff --git a/exchange/wrappers/poloniexClient.js b/exchange/wrappers/poloniexClient.js
index 1f6529d7b..0f38e13d5 100644
--- a/exchange/wrappers/poloniexClient.js
+++ b/exchange/wrappers/poloniexClient.js
@@ -58,7 +58,8 @@
sell: sell,
movePosition: movePosition,
getPublicTradeHistory: getPublicTradeHistory,
- getExchangeProperties: getExchangeProperties
+ getExchangeProperties: getExchangeProperties,
+ isValidLot: isValidLot
};
return thisObject;