100 lines
2.1 KiB
JavaScript
100 lines
2.1 KiB
JavaScript
// generic low level reusuable utils for interacting with exchanges.
|
|
|
|
const retry = require('retry');
|
|
const _ = require('lodash');
|
|
|
|
const retryInstance = (options, checkFn, callback) => {
|
|
if(!options) {
|
|
options = {
|
|
retries: 100,
|
|
factor: 1.2,
|
|
minTimeout: 1 * 1000,
|
|
maxTimeout: 4 * 1000
|
|
};
|
|
}
|
|
|
|
let attempt = 0;
|
|
|
|
const operation = retry.operation(options);
|
|
operation.attempt(function(currentAttempt) {
|
|
checkFn((err, result) => {
|
|
if (!err) {
|
|
return callback(global.DEFAULT_OK_RESPONSE, result);
|
|
} else {
|
|
if (err.result === global.CUSTOM_OK_RESPONSE.result) {
|
|
return callback(err, result);
|
|
}
|
|
}
|
|
|
|
let maxAttempts = err.retry;
|
|
if(maxAttempts === true)
|
|
maxAttempts = 10;
|
|
|
|
if(err.retry && attempt++ < maxAttempts) {
|
|
return operation.retry(err);
|
|
}
|
|
|
|
if(err.notFatal) {
|
|
if(err.backoffDelay) {
|
|
return setTimeout(() => operation.retry(err), err.backoffDelay);
|
|
}
|
|
|
|
return operation.retry(err);
|
|
}
|
|
|
|
callback(err, result);
|
|
});
|
|
});
|
|
}
|
|
|
|
const isValidOrder = ({api, market, amount, price}) => {
|
|
let reason = false;
|
|
|
|
// Check amount
|
|
if(amount < market.minimalOrder.amount) {
|
|
reason = 'Amount is too small';
|
|
}
|
|
|
|
// Some exchanges have restrictions on prices
|
|
if(
|
|
_.isFunction(api.isValidPrice) &&
|
|
!api.isValidPrice(price)
|
|
) {
|
|
reason = 'Price is not valid';
|
|
}
|
|
|
|
if(
|
|
_.isFunction(api.isValidLot) &&
|
|
!api.isValidLot(price, amount)
|
|
) {
|
|
reason = 'Lot size is too small';
|
|
}
|
|
|
|
return {
|
|
reason,
|
|
valid: !reason
|
|
}
|
|
}
|
|
|
|
const includes = function(str, list) {
|
|
if (!_.isString(str))
|
|
return false;
|
|
|
|
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,
|
|
getMarketConfig
|
|
|
|
} |