Merge pull request #65 from AAMasters/develop

Working with Exchange Gateway
This commit is contained in:
benme authored and GitHub committed 2019-04-03 21:07:44 +02:00
commit 468d3d6e67
17 files changed
+1858 -10764

No files matched your search

-314
View File
@@ -1,314 +0,0 @@
exports.newExchangeAPI = function newExchangeAPI(logger, exchangeName) {
/*
This module allows trading bots to connect to the exchange and do trading operations on it. So far it can only work with Poloniex.
*/
const _ = require('lodash')
const isValidOrder = require('./exchangeUtils').isValidOrder
const axios = require('axios')
let MODULE_NAME = "Exchange API";
let thisObject = {
initialize: initialize,
getTicker: getTicker,
getOpenPositions: getOpenPositions,
getExecutedTrades: getExecutedTrades,
putPosition: putPosition,
movePosition: movePosition,
getPublicTradeHistory: getPublicTradeHistory,
getExchangeProperties: getExchangeProperties,
getMaxDecimalPositions: getMaxDecimalPositions
};
let apiClient;
return thisObject;
async function initialize(callBackFunction) {
try {
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
let botExchange
if (exchangeName === undefined) {
botExchange = 'Poloniex'; // Default Value
} else {
botExchange = exchangeName;
}
let exchange = botExchange.toLowerCase() + 'Client.js';
let api = require('./wrappers/' + exchange);
let accessToken
let keyId
let cloneId
if (global.CURRENT_EXECUTION_AT === "Node") {
keyId = process.env.KEY_ID
cloneId = process.env.CLONE_ID
let auth = require('../utils/auth')
let authTokenCloud = await auth.authenticate()
accessToken = 'Bearer ' + authTokenCloud
}
let keyVaultAPI = createKeyVaultAPIClient(accessToken, keyId, cloneId)
apiClient = api.newAPIClient(keyVaultAPI, logger);
callBackFunction(global.DEFAULT_OK_RESPONSE);
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function createKeyVaultAPIClient(accessToken, keyId, cloneId) {
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] createKeyVaultAPIClient -> Entering function."); }
const keyVaultAPI = {}
keyVaultAPI.signTransaction = function (transaction, next) {
axios({
url: global.GATEWAY_ENDPOINT,
method: 'post',
data: {
query: `
mutation keyVault_SignTransaction($transaction: String!, $keyId: String, $cloneId: String){
keyVault_SignTransaction(transaction: $transaction, keyId: $keyId, cloneId: $cloneId){
key,
signature,
date
}
}
`,
variables: {
transaction: transaction,
keyId: keyId,
cloneId: cloneId
}
},
headers: {
authorization: accessToken
}
}).then(res => {
if (res.errors) {
next(undefined, 'Error from graphql: ' + res.errors);
} else {
let signature = {
Key: res.data.data.keyVault_SignTransaction.key,
Sign: res.data.data.keyVault_SignTransaction.signature
}
next(signature)
}
}).catch(error => {
next(undefined, 'Error signing the message on the key vault: ' + error.message);
});
}
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] createKeyVaultAPIClient -> Returning graphql client."); }
return keyVaultAPI;
}
/*
* Position Object = {
* id, String
* type, String
* rate, Number
* amountA, Number
* amountB, Number
* fee, Number
* datetime Date
* };
*/
function truncDecimals(pFloatValue) {
let decimals = getMaxDecimalPositions();
return parseFloat(parseFloat(pFloatValue).toFixed(decimals));
}
/*
* Return number of decimals for the current market
*/
function getMaxDecimalPositions() {
return getMarketConfig().maxDecimals;
}
/*
* Return number of decimals for the current market
*/
function getMarketConfig() {
return _.find(getExchangeProperties().markets, (p) => {
return _.first(p.pair) === global.MARKET.assetA.toUpperCase() &&
_.last(p.pair) === global.MARKET.assetB.toUpperCase();
});
}
/*
* Return number of decimals for the current market
*/
function getExchangeProperties() {
try {
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getExchangeProperties -> Entering function."); }
return apiClient.getExchangeProperties();
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] getExchangeProperties -> err = " + err.message);
callBack(global.DEFAULT_FAIL_RESPONSE);
}
}
/*
* Returns the price for a given pair of assets.
* The object returned is an array of trades:
* ticker = {
* bid, Number
* ask, Number
* last Number
* };
*/
function getTicker(pMarket, callBack) {
try {
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getTicker -> Entering function."); }
apiClient.getTicker(pMarket, callBack);
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] getTicker -> err = " + err.message);
callBack(global.DEFAULT_FAIL_RESPONSE);
}
}
/*
* Returns the open positions ath the exchange for a given market and user account.
* The object returned is an array of positions
*
*/
function getOpenPositions(pMarket, callBack) {
try {
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getOpenPositions -> Entering function."); }
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getOpenPositions -> pMarket = " + JSON.stringify(pMarket)); }
apiClient.getOpenPositions(pMarket, callBack);
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] getOpenPositions -> Error = " + err.message);
callBack(global.DEFAULT_FAIL_RESPONSE);
}
}
/*
* Returns the trades for a given order number.
* The object returned is an array of positions
*/
function getExecutedTrades(pPositionId, callBack) {
try {
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getExecutedTrades -> Entering function."); }
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getExecutedTrades -> pPositionId = " + pPositionId); }
apiClient.getExecutedTrades(pPositionId, callBack);
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] getExecutedTrades -> Error = " + err.message);
callBack(global.DEFAULT_FAIL_RESPONSE);
}
}
/*
* Creates a new buy or sell order.
* The orderNumber is returned. String
*/
function putPosition(pMarket, pType, pRate, pAmountA, pAmountB, callBack) {
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] putPosition -> pMarket = " + JSON.stringify(pMarket)); }
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 = " + truncDecimals(pRate)); }
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pAmountA = " + truncDecimals(pAmountA)); }
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pAmountB = " + truncDecimals(pAmountB)); }
let check = isValidOrder({
market: getMarketConfig(),
api: apiClient,
amount: truncDecimals(pAmountB),
price: truncDecimals(pRate)
});
if (check.valid) {
if (pType === "buy") {
apiClient.buy(pMarket.assetA, pMarket.assetB, truncDecimals(pRate), truncDecimals(pAmountB), callBack);
return;
}
if (pType === "sell") {
apiClient.sell(pMarket.assetA, pMarket.assetB, truncDecimals(pRate), truncDecimals(pAmountB), callBack);
return;
}
logger.write(MODULE_NAME, "[ERROR] putPosition -> pType must be either 'buy' or 'sell'.");
callBack(global.DEFAULT_FAIL_RESPONSE);
} else {
logger.write(MODULE_NAME, "[ERROR] putPosition -> The order is invalid: " + check.reason);
callBack(global.DEFAULT_FAIL_RESPONSE);
}
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] putPosition -> err = " + err.message);
callBack(global.DEFAULT_FAIL_RESPONSE);
}
}
/*
* Move an existing position to the new rate.
* The new orderNumber is returned.
*/
function movePosition(pPosition, pNewRate, pNewAmountB, callBack) {
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 = " + truncDecimals(pNewRate)); }
apiClient.movePosition(pPosition, truncDecimals(pNewRate), truncDecimals(pNewAmountB), callBack);
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] movePosition -> err = " + err.message);
callBack(global.DEFAULT_FAIL_RESPONSE);
}
}
/*
* Returns all the trade history from the Exchange since startTime to endTime orderd by tradeId.
* It's possible that the exchange doesn't support this method.
* The object returned is an array of trades:
* trade = {
* tradeID, String
* globalTradeID, String
* type, String
* rate, Number
* amountA, Number
* amountB, Number
* date Date
* };
*/
function getPublicTradeHistory(assetA, assetB, startTime, endTime, callBack) {
try {
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] getTradeHistory -> Entering function."); }
apiClient.getPublicTradeHistory(assetA, assetB, startTime, endTime, callBack);
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] getTradeHistory -> err = " + err.message);
callBack(global.DEFAULT_FAIL_RESPONSE);
}
}
};
-100
View File
@@ -1,100 +0,0 @@
// 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
}
-183
View File
@@ -1,183 +0,0 @@
const _ = require('underscore');
class Beautifier {
constructor() {
this._beautifications = {
aggTrades: {
a: 'aggTradeId',
p: 'price',
q: 'quantity',
f: 'firstTradeId',
l: 'lastTradeId',
T: 'timestamp',
m: 'maker',
M: 'bestPriceMatch'
},
klines: {
0: 'openTime',
1: 'open',
2: 'high',
3: 'low',
4: 'close',
5: 'volume',
6: 'closeTime',
7: 'quoteAssetVolume',
8: 'trades',
9: 'takerBaseAssetVolume',
10: 'takerQuoteAssetVolume',
11: 'ignored'
},
bids: [
{
0: 'price',
1: 'quantity',
2: 'ignored'
}
],
asks: [
{
0: 'price',
1: 'quantity',
2: 'ignored'
}
],
depthUpdateEvent: {
e: 'eventType',
E: 'eventTime',
s: 'symbol',
u: 'updateId',
b: 'bidDepthDelta',
a: 'askDepthDelta'
},
bidDepthDelta: [
{
0: 'price',
1: 'quantity',
2: 'ignored'
}
],
askDepthDelta: [
{
0: 'price',
1: 'quantity',
2: 'ignored'
}
],
klineEvent: {
e: 'eventType',
E: 'eventTime',
s: 'symbol',
k: 'kline'
},
kline: {
t: 'startTime',
T: 'endTime',
s: 'symbol',
i: 'interval',
f: 'firstTradeId',
L: 'lastTradeId',
o: 'open',
c: 'close',
h: 'high',
l: 'low',
v: 'volume',
n: 'trades',
x: 'final',
q: 'quoteVolume',
V: 'volumeActive',
Q: 'quoteVolumeActive',
B: 'ignored'
},
aggTradeEvent: {
e: 'eventType',
E: 'eventTime',
s: 'symbol',
a: 'tradeId',
p: 'price',
q: 'quantity',
f: 'firstTradeId',
l: 'lastTradeId',
T: 'time',
m: 'maker',
M: 'ignored'
},
outboundAccountInfoEvent: {
e: 'eventType',
E: 'eventTime',
m: 'makerCommission',
t: 'takerCommission',
b: 'buyerCommission',
s: 'sellerCommission',
T: 'canTrade',
W: 'canWithdraw',
D: 'canDeposit',
B: 'balances'
},
balances: [
{
a: 'asset',
f: 'availableBalance',
l: 'onOrderBalance'
}
],
executionReportEvent: {
e: 'eventType',
E: 'eventTime',
s: 'symbol',
c: 'newClientOrderId',
S: 'side',
o: 'orderType',
f: 'cancelType', // GTC 'Good till Cancel', IOC: 'Immediate or Cancel'
q: 'quantity',
p: 'price',
x: 'executionType',
X: 'orderStatus',
r: 'rejectReason',
i: 'orderId',
l: 'lastTradeQuantity',
z: 'accumulatedQuantity',
L: 'lastTradePrice',
n: 'commission',
N: 'commissionAsset',
m: 'maker',
T: 'tradeTime',
t: 'tradeId'
}
}
}
beautify(object, type) {
const beautifications = _.isObject(type) ? type : this._beautifications[type];
if (!beautifications) {
return object;
}
let newItem = {};
_.each(object, (value, key) => {
if (_.isArray(value)) {
const newArray = [];
if (_.isArray(this._beautifications[beautifications[key]])) {
_.each(value, arrayValue => {
newArray.push(this.beautify(arrayValue, this._beautifications[beautifications[key]][0]));
});
} else {
_.each(value, (value, key) => {
newItem.push(this.beautify(value, beautifications[key]))
});
}
const newKey = beautifications[key] || key;
newItem[newKey] = newArray;
} else if (_.isObject(value)) {
const newKey = beautifications[key] || key;
newItem[newKey] = this.beautify(value, beautifications[key]);
} else {
const newKey = beautifications[key] || key;
newItem[newKey] = value;
}
});
return newItem;
}
}
module.exports = Beautifier;
-368
View File
@@ -1,368 +0,0 @@
// Source: https://github.com/zoeyg/binance/blob/master/lib/rest.js
const request = require('request');
const qs = require('querystring');
const _ = require('underscore');
const crypto = require('crypto');
const Beautifier = require('./beautifier.js');
const assert = require('assert');
class BinanceRest {
constructor({
key,
secret,
recvWindow = false,
timeout = 15000,
disableBeautification = false,
handleDrift = false
}) {
this.key = key;
this.secret = secret;
this.recvWindow = recvWindow;
this.timeout = timeout;
this.disableBeautification = disableBeautification;
this.handleDrift = handleDrift;
this._beautifier = new Beautifier();
this._baseUrl = 'https://api.binance.com/';
this._drift = 0;
this._syncInterval = 0;
}
_makeRequest(query, callback, route, security, method, attempt = 0) {
assert(_.isUndefined(callback) || _.isFunction(callback), 'callback must be a function or undefined');
assert(_.isObject(query), 'query must be an object');
let queryString;
const type = _.last(route.split('/')),
options = {
url: `${this._baseUrl}${route}`,
timeout: this.timeout
};
if (security === 'SIGNED') {
if (this.recvWindow) {
query.recvWindow = this.recvWindow;
}
queryString = qs.stringify(query);
options.url += '?' + queryString;
if (options.url.substr(options.url.length - 1) !== '?') {
options.url += '&';
}
options.url += `signature=${this._sign(queryString)}`;
} else {
queryString = qs.stringify(query);
if (queryString) {
options.url += '?' + queryString;
}
}
if (security === 'API-KEY' || security === 'SIGNED') {
options.headers = { 'X-MBX-APIKEY': this.key };
}
if (method) {
options.method = method;
}
const action = cb => {
request(options, (err, response, body) => {
let payload;
try {
payload = JSON.parse(body);
} catch (e) {
payload = body;
}
if (err) {
cb(err, payload);
} else if (response.statusCode < 200 || response.statusCode > 299) {
/*
* If we get a response that the timestamp is ahead of the server,
* calculate the drift and then attempt the request again
*/
if (response.statusCode === 400 && payload.code === -1021 &&
this.handleDrift && attempt === 0) {
this.calculateDrift()
.then(() => {
query.timestamp = this._getTime() + this._drift;
return this._makeRequest(query, cb, route, security, method,
++attempt);
});
} else {
cb(new Error(`Response code ${response.statusCode}`), payload);
}
} else {
if (_.isArray(payload)) {
payload = _.map(payload, (item) => {
return this._doBeautifications(item, type);
});
} else {
payload = this._doBeautifications(payload);
}
cb(err, payload);
}
});
};
if (callback) {
action(callback);
} else {
return new Promise((resolve, reject) => action((err, payload) => {
if (err) {
if (payload === undefined) {
reject(err);
} else {
reject(payload);
}
} else {
resolve(payload);
}
}));
}
}
_doBeautifications(response, route) {
if (this.disableBeautification) {
return response;
}
return this._beautifier.beautify(response, route);
}
_sign(queryString) {
return crypto.createHmac('sha256', this.secret)
.update(queryString)
.digest('hex');
}
_setTimestamp(query) {
if (!query.timestamp) {
query.timestamp = this._getTime() + this._drift;
}
}
_getTime() {
return new Date().getTime();
}
calculateDrift() {
const systemTime = this._getTime();
return this.time()
.then((response) => {
// Calculate the approximate trip time from here to binance
const transitTime = parseInt((this._getTime() - systemTime) / 2);
this._drift = response.serverTime - (systemTime + transitTime);
});
}
startTimeSync(interval = 300000, onRecalculateDriftCb) {
return new Promise((resolve, reject) => {
// If there's already an interval running, clear it and reset values
if (this._syncInterval !== 0) {
this.endTimeSync();
return resolve();
}
// Calculate initial drift value and setup interval to periodically update it
this.calculateDrift()
.then(resolve)
.catch(reject);
this._syncInterval = setInterval(() => {
const promise = this.calculateDrift();
if (_.isFunction(onRecalculateDriftCb)) {
onRecalculateDriftCb(promise);
}
}, interval);
});
}
endTimeSync() {
clearInterval(this._syncInterval);
this._drift = 0;
this._syncInterval = 0;
}
// Public APIs
ping(callback) {
return this._makeRequest({}, callback, 'api/v1/ping');
}
time(callback) {
return this._makeRequest({}, callback, 'api/v1/time');
}
depth(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
return this._makeRequest(query, callback, 'api/v1/depth');
}
trades(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
return this._makeRequest(query, callback, 'api/v1/trades');
}
historicalTrades(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
return this._makeRequest(query, callback, 'api/v1/historicalTrades', 'API-KEY');
}
aggTrades(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
return this._makeRequest(query, callback, 'api/v1/aggTrades');
}
exchangeInfo(callback) {
return this._makeRequest({}, callback, 'api/v1/exchangeInfo');
}
klines(query = {}, callback) {
return this._makeRequest(query, callback, 'api/v1/klines');
}
ticker24hr(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
return this._makeRequest(query, callback, 'api/v1/ticker/24hr');
}
tickerPrice(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
return this._makeRequest(query, callback, 'api/v3/ticker/price');
}
bookTicker(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
return this._makeRequest(query, callback, 'api/v3/ticker/bookTicker');
}
allBookTickers(callback) {
return this._makeRequest({}, callback, 'api/v1/ticker/allBookTickers');
}
allPrices(callback) {
return this._makeRequest({}, callback, 'api/v1/ticker/allPrices');
}
// Private APIs
newOrder(query = {}, callback) {
this._setTimestamp(query);
return this._makeRequest(query, callback, 'api/v3/order', 'SIGNED', 'POST');
}
testOrder(query = {}, callback) {
this._setTimestamp(query);
return this._makeRequest(query, callback, 'api/v3/order/test', 'SIGNED', 'POST');
}
queryOrder(query = {}, callback) {
this._setTimestamp(query);
return this._makeRequest(query, callback, 'api/v3/order', 'SIGNED');
}
cancelOrder(query = {}, callback) {
this._setTimestamp(query);
return this._makeRequest(query, callback, 'api/v3/order', 'SIGNED', 'DELETE');
}
openOrders(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
this._setTimestamp(query);
return this._makeRequest(query, callback, 'api/v3/openOrders', 'SIGNED');
}
allOrders(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
this._setTimestamp(query);
return this._makeRequest(query, callback, 'api/v3/allOrders', 'SIGNED');
}
account(query = {}, callback) {
if (_.isFunction(query)) {
callback = query;
query = {};
}
this._setTimestamp(query);
return this._makeRequest(query, callback, 'api/v3/account', 'SIGNED');
}
myTrades(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
this._setTimestamp(query);
return this._makeRequest(query, callback, 'api/v3/myTrades', 'SIGNED');
}
withdraw(query = {}, callback) {
this._setTimestamp(query);
return this._makeRequest(query, callback, 'wapi/v3/withdraw.html', 'SIGNED', 'POST');
}
depositHistory(query = {}, callback) {
if (_.isString(query)) {
query = { asset: query };
}
this._setTimestamp(query);
return this._makeRequest(query, callback, 'wapi/v3/depositHistory.html', 'SIGNED');
}
withdrawHistory(query = {}, callback) {
if (_.isString(query)) {
query = { asset: query };
}
this._setTimestamp(query);
return this._makeRequest(query, callback, 'wapi/v3/withdrawHistory.html', 'SIGNED');
}
depositAddress(query = {}, callback) {
if (_.isString(query)) {
query = { asset: query };
}
this._setTimestamp(query);
return this._makeRequest(query, callback, 'wapi/v3/depositAddress.html', 'SIGNED');
}
accountStatus(callback) {
const query = {};
this._setTimestamp(query);
return this._makeRequest(query, callback, 'wapi/v3/accountStatus.html', 'SIGNED');
}
startUserDataStream(callback) {
return this._makeRequest({}, callback, 'api/v1/userDataStream', 'API-KEY', 'POST');
}
keepAliveUserDataStream(query = {}, callback) {
return this._makeRequest(query, callback, 'api/v1/userDataStream', 'API-KEY', 'PUT');
}
closeUserDataStream(query = {}, callback) {
return this._makeRequest(query, callback, 'api/v1/userDataStream', 'API-KEY', 'DELETE');
}
}
module.exports = BinanceRest;
-355
View File
@@ -1,355 +0,0 @@
exports.newAPIClient = function newAPIClient(pKey, pSecret, logger) {
const FULL_LOG = true;
const LOG_FILE_CONTENT = true;
const MODULE_NAME = "binanceClient";
const retry = require('../exchangeUtils').retry;
const includes = require('../exchangeUtils').includes;
const _ = require('lodash');
const Binance = require("./binance");
const exchangeProperties = require('./poloniexProperties.json');
const recoverableErrors = [
'SOCKETTIMEDOUT',
'TIMEDOUT',
'CONNRESET',
'CONNREFUSED',
'NOTFOUND',
'Error -1021',
'Response code 429',
'Response code 5',
'ETIMEDOUT'
];
let API = new Binance({
key: pKey,
secret: pSecret,
timeout: 15000,
recvWindow: 60000,
disableBeautification: false,
handleDrift: true,
});
let thisObject = {
getTicker: getTicker,
getOpenPositions: getOpenPositions,
getExecutedTrades: getExecutedTrades,
buy: buy,
sell: sell,
movePosition: movePosition,
getPublicTradeHistory: getPublicTradeHistory,
getExchangeProperties: getExchangeProperties,
isValidPrice: isValidPrice,
isValidLot: isValidLot
};
return thisObject;
function joinCurrencies(currencyA, currencyB) {
// If only one arg, then return the first
if (typeof currencyB !== 'string') {
return currencyA;
}
return currencyB + '' + currencyA;
}
/*
* Returns the properties for this exchange
*/
function getExchangeProperties() {
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:
* ticker = {
* bid, Number
* ask, Number
* last Number
* };
*/
function getTicker(pMarket, callBack) {
let market = joinCurrencies(pMarket.assetA, pMarket.assetB);
const handle = (err, response) => {
let ticker;
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
ticker = {
bid: Number(response.bidPrice),
ask: Number(response.askPrice),
last: Number(response.lastPrice)
};
}
callBack(err, ticker);
};
const fetch = next => API.ticker24hr(market, analizeResponse(next));
retry(null, fetch, handle);
}
/*
* Returns the open positions ath the exchange for a given market and user account.
* The object returned is an array of positions:
* position = {
* id,
* type,
* rate, Number
* amountA, Number
* amountB, Number
* fee, (not required) Number
* datetime
* };
*/
function getOpenPositions(pMarket, callBack) {
let market = joinCurrencies(pMarket.assetA, pMarket.assetB);
const handle = (err, response) => {
let exchangePositions = [];
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
for (let i = 0; i < response.length; i++) {
let openPosition = {
id: response[i].orderId,
type: response[i].side.toLowerCase(),
rate: Number(response[i].price),
amountA: truncDecimals(response[i].origQty * response[i].price),
amountB: Number(response[i].origQty),
date: (new Date(response[i].time)).valueOf()
};
exchangePositions.push(openPosition);
}
}
callBack(err, exchangePositions);
};
const fetch = next => API.openOrders(market, analizeResponse(next));
retry(null, fetch, handle);
}
/*
* Returns the trades for a given order number.
* The object returned is an array of positions:
* position = {
* id,
* type,
* rate, Number
* amountA, Number
* amountB, Number
* fee, Number
* datetime
* };
*/
function getExecutedTrades(pPositionId, callBack) {
let market = joinCurrencies(global.MARKET.assetA, global.MARKET.assetB);
const handle = (err, response) => {
let exchangeTrades = [];
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
for (let i = 0; i < response.length; i++) {
if (response[i].orderId === pPositionId) {
let type = "sell"
if (response[i].isBuyer === true) {
type = "buy";
}
let trade = {
id: response[i].orderId,
type: type,
rate: Number(response[i].price),
amountA: truncDecimals(response[i].qty * response[i].price),
amountB: Number(response[i].qty),
fee: Number(response[i].commission),
date: (new Date(response[i].time)).valueOf()
};
exchangeTrades.push(trade);
break;
}
}
}
callBack(err, exchangeTrades);
};
const fetch = next => API.myTrades(market, analizeResponse(next));
retry(null, fetch, handle);
}
/*
* Creates a new buy order.
* The orderNumber is returned.
*/
function buy(pCurrencyA, pCurrencyB, pRate, pAmount, callBack) {
var parameters = {
symbol: joinCurrencies(pCurrencyA, pCurrencyB),
side: 'BUY',
type: 'LIMIT',
quantity: pAmount,
price: pRate,
timeInForce: 'GTC'
};
const handle = (err, response) => {
let orderNumber;
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
orderNumber = response.orderId;
}
callBack(err, orderNumber);
};
const fetch = next => API.newOrder(parameters, analizeResponse(next));
retry(null, fetch, handle);
}
/*
* Creates a new sell order.
* The orderNumber is returned. String
*/
function sell(pCurrencyA, pCurrencyB, pRate, pAmount, callBack) {
var parameters = {
symbol: joinCurrencies(pCurrencyA, pCurrencyB),
side: 'SELL',
type: 'LIMIT',
quantity: pAmount,
price: pRate,
timeInForce: 'GTC'
};
const handle = (err, response) => {
let orderNumber;
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
orderNumber = response.orderId;
}
callBack(err, orderNumber);
};
const fetch = next => API.newOrder(parameters, analizeResponse(next));
retry(null, fetch, handle);
}
/* //TODO Complete partial orders
* Move an existing position to the new rate.
* The new orderNumber is returned. String
*/
function movePosition(pPosition, pNewRate, pNewAmountB, callBack) {
var parameters = {
symbol: joinCurrencies(global.MARKET.assetA, global.MARKET.assetB),
orderId: pPosition.id
};
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] moveOrder -> Step1 - Cancelling Position: " + JSON.stringify(pPosition)); }
const handle = (err, response) => {
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] moveOrder -> Step1 Complete - Position Cancelled. Proceeding to put the new position."); }
if (position.type === "buy")
thisObject.buy(global.MARKET.assetA, global.MARKET.assetB, pNewRate, pNewAmountB, callBack);
else
thisObject.sell(global.MARKET.assetA, global.MARKET.assetB, pNewRate, pNewAmountB, callBack);
} else {
callBack(err);
}
};
const fetch = next => API.cancelOrder(parameters, analizeResponse(next));
retry(null, fetch, handle);
}
/* //TODO Pending Review
* Returns all the trade history from the Exchange since startTime to endTime orderd by tradeId.
* It's possible that the exchange doesn't support this method.
* The object returned is an array of trades:
* trade = {
* tradeIdAtExchange,
* marketIdAtExchange,
* type,
* rate, Number
* amountA, Number
* amountB, Number
* datetime
* };
*/
function getPublicTradeHistory(assetA, assetB, startTime, endTime, callBack) {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] getPublicTradeHistory -> Not implemented yet."); }
callBack(global.DEFAULT_FAIL_RESPONSE);
}
function isValidPrice(price) {
return price >= market.minimalOrder.price;
}
function isValidLot(price, amount) {
return amount * price >= market.minimalOrder.order;
}
function analizeResponse(callBack) {
return (exchangeErr, exchangeResponse) => {
let error;
/* This function analizes the different situations we might encounter trying to access Binance and returns appropiate standard errors. */
let stringExchangeErr = JSON.stringify(exchangeErr);
let stringExchangeResponse = JSON.stringify(exchangeResponse);
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] analizeResponse -> exchangeErr = " + stringExchangeErr); }
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] analizeResponse -> exchangeResponse = " + stringExchangeResponse); }
if (exchangeErr) {
error = global.DEFAULT_FAIL_RESPONSE;
} else if (!exchangeResponse) {
error = {
result: global.DEFAULT_FAIL_RESPONSE.result,
message: 'Empty response'
};
} else if (includes(exchangeResponse.error, ['<!DOCTYPE html>'])) {
error = {
result: global.DEFAULT_FAIL_RESPONSE.result,
message: exchangeResponse
};
} else if (includes(exchangeResponse.error, ['Order does not exist.'])) {
error = {
result: global.CUSTOM_OK_RESPONSE.result,
message: exchangeResponse.error
};
} else if (exchangeResponse.error) {
error = {
result: global.DEFAULT_FAIL_RESPONSE.result,
message: exchangeResponse.error
};
}
if (error) {
if (includes(error.message, recoverableErrors)) {
error.notFatal = true;
}
}
return callBack(error, exchangeResponse);
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] analizeResponse -> err.message = " + err.message);
return callBack(global.DEFAULT_FAIL_RESPONSE, exchangeResponse);
}
}
}
}
File diff suppressed because it is too large. Load diff
-340
View File
@@ -1,340 +0,0 @@
// Source: https://github.com/coss-exchange/trading-api-wrapper-node-js/blob/master/index.js
// Documentation: https://api.coss.io/v1/spec
const request = require('superagent');
const querystring = require('querystring');
const HttpMethod = { POST: 1, GET: 2, DELETE: 3 };
const util = require('util');
const HOST_URL = "https://trade.coss.io/c/api/v1";
const HOST_URL2 = "https://engine.coss.io/api/v1";
const EXCHANGE_HOST = "https://exchange.coss.io/api";
//WRAPPER STARTS HERE (Commenting out stuff that coss wrote which should be part of bot.js (the actual trading bot) rather than index.js (the wrapper core functionality))
let Coss = (keyVaultAPI) => {
//HTTPS Private Request
async function transmit_encrypted_request(method, url, payload) {
var payload_json_str = method == HttpMethod.GET ? querystring.stringify(payload) : JSON.stringify(payload)
var sign = await transmit_payload_signature_get(payload_json_str)
var req_headers = transmit_signed_header_get(sign)
console.log(`sending ${payload_json_str} to ${url}`)
if (method == HttpMethod.POST) {
let response = await request.post(url).set(req_headers).send(payload_json_str)
return (response.body);
} else if (method == HttpMethod.DELETE) {
let response = await request.delete(url).set(req_headers).send(payload_json_str)
return (response.body);
} else if (method == HttpMethod.GET) {
let response = await request.get(url).set(req_headers).query(payload_json_str)
return (response.body);
}
}
function transmit_signed_header_get(sign) {
var req_headers = {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
'Authorization': sign.Key,
'Signature': sign.Sign,
}
return req_headers
}
//AUTHBUILDER
async function transmit_payload_signature_get(payload_json_str) {
const signTransaction = util.promisify(keyVaultAPI.signTransaction)
return await signTransaction(payload_json_str)
}
//HTTPS Public Request
async function publicRequest(url) {
let response = await request.get(url)
return response.body;
}
return {
//PLACE LIMIT ORDER
placeLimitOrder: async (params = {}) => {
if (!params.Symbol) {
return Promise.reject("placeLimitOrder(), You must supply a valid trading pair Symbol, e.g. 'COSS_ETH'!");
} else if (params.Symbol && typeof params.Symbol !== 'string') {
return Promise.reject("placeLimitOrder(), You must supply a valid trading pair Symbol as a string, e.g. 'COSS_ETH'!");
} else if (!params.Side) {
return Promise.reject("placeLimitOrder(), You must supply a valid Side, e.g. 'BUY' or 'SELL'!");
} else if (params.Side && params.Side !== 'Buy' && params.Side !== 'Sell') {
return Promise.reject("placeLimitOrder(), You must supply a valid Side, e.g. 'BUY' or 'SELL'!");
} else if (!params.Price || !params.Amount) {
return Promise.reject("placeLimitOrder(), You must supply a valid Price and Amount, e.g. Price: '0.00000034' or Amount: '123.00000000'!");
//} else if (typeof params.Price !== 'number' || typeof params.Amount !== 'number') {
//return Promise.reject("placeLimitOrder(), You must supply a valid Price and Amount as a number, e.g. Price: '0.00000034' or Amount: '123.00000000'!");
}
var now = new Date().getTime()
var query_params = {
'order_symbol': params.Symbol,
'order_price': params.Price.toString(),
'order_side': params.Side,
'order_size': params.Amount.toString(),
'type': 'limit',
'timestamp': now,
'recvWindow': 5000
}
let url = HOST_URL + "/order/add";
return transmit_encrypted_request(HttpMethod.POST, url, query_params)
},
//PLACE MARKET ORDER
placeMarketOrder: async (params = {}) => {
if (!params.Symbol) {
return Promise.reject("placeMarketOrder(), You must supply a valid trading pair Symbol, e.g. 'COSS_ETH'!");
} else if (params.Symbol && typeof params.Symbol !== 'string') {
return Promise.reject("placeMarketOrder(), You must supply a valid trading pair Symbol as a string, e.g. 'COSS_ETH'!");
} else if (!params.Side) {
return Promise.reject("placeMarketOrder(), You must supply a valid Side, e.g. 'BUY' or 'SELL'!");
} else if (params.Side && params.Side !== 'Buy' && params.Side !== 'Sell') {
return Promise.reject("placeMarketOrder(), You must supply a valid Side, e.g. 'BUY' or 'SELL'!");
} else if (!params.Amount) {
return Promise.reject("placeMarketOrder(), You must supply a valid Amount, e.g. Amount: '123.00000000'!");
} else if (typeof params.Amount !== 'number') {
return Promise.reject("placeMarketOrder(), You must supply a valid Amount as a number, e.g. Amount: '123.00000000'!");
}
var now = new Date().getTime()
var query_params = {
'order_symbol': params.Symbol,
'order_side': params.Side,
'order_size': params.Amount.toString(),
'type': 'market',
'timestamp': now,
'recvWindow': 5000
}
let url = HOST_URL + "/order/add";
return transmit_encrypted_request(HttpMethod.POST, url, query_params)
},
//Get Account Balances
getAccountBalances: async (params = {}) => {
var now = new Date().getTime()
var query_params = {
'recvWindow': 5000,
'timestamp': now
}
let url = HOST_URL + "/account/balances";
return transmit_encrypted_request(HttpMethod.GET, url, query_params)
},
//Get Account Details
getAccountDetails: async (params = {}) => {
var now = new Date().getTime()
var query_params = {
'recvWindow': 5000,
'timestamp': now
}
let url = HOST_URL + "/account/details";
return transmit_encrypted_request(HttpMethod.GET, url, query_params)
},
//CANCEL ORDER BY ID #
cancelOrder: async (params = {}) => {
if (!params.ID) {
return Promise.reject("cancelOrder(), You must supply a valid order_ID to cancel, e.g. '9e5ae4dd-3369-401d-81f5-dff985e1c4e7'!");
} else if (params.ID && typeof params.ID !== 'string') {
return Promise.reject("cancelOrder(), You must supply a valid order_ID to cancel as a string, e.g. '9e5ae4dd-3369-401d-81f5-dff985e1c4e7'!");
} else if (!params.Symbol) {
return Promise.reject("cancelOrder(), You must supply a valid trading pair Symbol, e.g. 'COSS_ETH'!");
} else if (params.Symbol && typeof params.Symbol !== 'string') {
return Promise.reject("cancelOrder(), You must supply a valid trading pair Symbol as a string, e.g. 'COSS_ETH'!");
}
var now = new Date().getTime()
var query_params = {
'order_id': params.ID,
'order_symbol': params.Symbol,
'timestamp': now,
'recvWindow': 5000
}
let url = HOST_URL + "/order/cancel";
return transmit_encrypted_request(HttpMethod.DELETE, url, query_params)
},
//GET ORDER DETAILS
getOrderDetails: async (params = {}) => {
if (!params.ID) {
return Promise.reject("getOrderDetails(), You must supply a valid order_ID to cancel, e.g. '9e5ae4dd-3369-401d-81f5-dff985e1c4e7'!");
} else if (params.ID && typeof params.ID !== 'string') {
return Promise.reject("getOrderDetails(), You must supply a valid order_ID to cancel as a string, e.g. '9e5ae4dd-3369-401d-81f5-dff985e1c4e7'!");
}
var now = new Date().getTime()
var query_params = {
'order_id': params.ID,
'timestamp': now,
'recvWindow': 5000
}
let url = HOST_URL + "/order/details";
return transmit_encrypted_request(HttpMethod.POST, url, query_params)
},
//GET OPEN ORDERS
getOpenOrders: async (params = {}) => {
if (!params.Limit) {
return Promise.reject("getOpenOrders(), You must supply a valid Limit for your open orders, e.g. '10'!");
} else if (params.Limit && typeof params.Limit !== 'number') {
return Promise.reject("getOpenOrders(), You must supply a valid Limit as a number for your open orders, e.g. '10'!");
} else if (!params.Symbol) {
return Promise.reject("getOpenOrders(), You must supply a valid trading pair Symbol, e.g. 'COSS_ETH'!");
} else if (params.Symbol && typeof params.Symbol !== 'string') {
return Promise.reject("getOpenOrders(), You must supply a valid trading pair Symbol as a string, e.g. 'COSS_ETH'!");
}
var now = new Date().getTime()
var query_params = {
'limit': params.Limit.toString(),
'page': 0,
'symbol': params.Symbol,
'timestamp': now,
'recvWindow': 5000
}
let url = HOST_URL + "/order/list/open";
return transmit_encrypted_request(HttpMethod.POST, url, query_params)
},
//GET COMPLETED ORDERS
getCompletedOrders: async (params = {}) => {
if (!params.Limit) {
return Promise.reject("getCompletedOrders(), You must supply a valid Limit for your open orders, e.g. '10'!");
} else if (params.Limit && typeof params.Limit !== 'number') {
return Promise.reject("getCompletedOrders(), You must supply a valid Limit as a number for your open orders, e.g. '10'!");
} else if (!params.Symbol) {
return Promise.reject("getCompletedOrders(), You must supply a valid trading pair Symbol, e.g. 'COSS_ETH'!");
} else if (params.Symbol && typeof params.Symbol !== 'string') {
return Promise.reject("getCompletedOrders(), You must supply a valid trading pair Symbol as a string, e.g. 'COSS_ETH'!");
}
var now = new Date().getTime()
var query_params = {
'limit': params.Limit.toString(),
'page': 0,
'symbol': params.Symbol,
'timestamp': now,
'recvWindow': 5000
}
let url = HOST_URL + "/order/list/completed";
return transmit_encrypted_request(HttpMethod.POST, url, query_params)
},
//GET ALL USER ORDERS
getAllOrders: async (params = {}) => {
if (!params.Limit) {
return Promise.reject("getAllOrders(), You must supply a valid Limit for your open orders, e.g. '10'!");
} else if (params.Limit && typeof params.Limit !== 'number') {
return Promise.reject("getAllOrders(), You must supply a valid Limit as a number for your open orders, e.g. '10'!");
} else if (!params.Symbol) {
return Promise.reject("getAllOrders(), You must supply a valid trading pair Symbol, e.g. 'COSS_ETH'!");
} else if (params.Symbol && typeof params.Symbol !== 'string') {
return Promise.reject("getAllOrders(), You must supply a valid trading pair Symbol as a string, e.g. 'COSS_ETH'!");
} else if (!params.ID) {
return Promise.reject("getAllOrders(), You must supply a valid account ID");
} else if (params.ID && typeof params.ID !== 'string') {
return Promise.reject("getAllOrders(), You must supply a valid account ID as a string");
}
var now = new Date().getTime()
var query_params = {
'symbol': params.Symbol,
'from_id': params.ACCT_ID,
'limit': params.Limit,
'timestamp': now,
'recvWindow': 5000
}
let url = HOST_URL + "/order/list/all";
return transmit_encrypted_request(HttpMethod.POST, url, query_params)
},
//Public API Calls (don't need to be signed)
//get Market Price
getMarketPrice: async (params = {}) => {
if (!params.Symbol) {
return Promise.reject("getMarketPrice(), You must supply a valid trading pair Symbol, e.g. 'COSS_ETH'!");
} else if (params.Symbol && typeof params.Symbol !== 'string') {
return Promise.reject("getMarketPrice(), You must supply a valid trading pair Symbol as a string, e.g. 'COSS_ETH'!");
}
let url = HOST_URL + "/market-price/" + '?symbol=' + params.Symbol;
return publicRequest(url);
},
//get Market Price
getPairDepth: async (params = {}) => {
if (!params.Symbol) {
return Promise.reject("getPairDepth(), You must supply a valid trading pair Symbol, e.g. 'COSS_ETH'!");
} else if (params.Symbol && typeof params.Symbol !== 'string') {
return Promise.reject("getPairDepth(), You must supply a valid trading pair Symbol as a string, e.g. 'COSS_ETH'!");
}
console.log(HOST_URL2 + "/dp" + '?symbol=' + params.Symbol);
let url = HOST_URL2 + "/dp" + '?symbol=' + params.Symbol;
return publicRequest(url);
},
//get Market Price
getMarketSides: async (params = {}) => {
if (!params.Symbol) {
return Promise.reject("getMarketSides(), You must supply a valid trading pair Symbol, e.g. 'COSS_ETH'!");
} else if (params.Symbol && typeof params.Symbol !== 'string') {
return Promise.reject("getMarketSides(), You must supply a valid trading pair Symbol as a string, e.g. 'COSS_ETH'!");
}
console.log(HOST_URL2 + "/dp" + '?symbol=' + params.Symbol);
let url = HOST_URL2 + "/dp" + '?symbol=' + params.Symbol;
let pairDepth = await publicRequest(url);
let marketSides = [[pairDepth.bids[0][0], pairDepth.bids[0][1]], [pairDepth.asks[0][0], pairDepth.asks[0][1]]];
return (marketSides)
},
//get Exchange Info
getExchangeInfo: async () => {
console.log(HOST_URL + "/exchange-info");
let url = HOST_URL + "/exchange-info";
return publicRequest(url);
},
//get Market Summary (NOT WORKING ATM)
getMarketSummary: async (params = {}) => {
if (!params.Symbol) {
return Promise.reject("getMarketSummary(), You must supply a valid trading pair Symbol, e.g. 'COSS_ETH'!");
} else if (params.Symbol && typeof params.Symbol !== 'string') {
return Promise.reject("getMarketSummary(), You must supply a valid trading pair Symbol as a string, e.g. 'COSS_ETH'!");
}
console.log(EXCHANGE_HOST + "/getmarketsummaries/" + '?symbol=' + params.Symbol);
let url = EXCHANGE_HOST + "/getmarketsummaries/" + '?symbol=' + params.Symbol;
return publicRequest(url);
},
getTradeHistory: async (params = {}) => {
if (!params.Symbol) {
return Promise.reject("getTradeHistory(), You must supply a valid trading pair Symbol, e.g. 'COSS_ETH'!");
} else if (params.Symbol && typeof params.Symbol !== 'string') {
return Promise.reject("getTradeHistory(), You must supply a valid trading pair Symbol as a string, e.g. 'COSS_ETH'!");
}
console.log(HOST_URL2 + "/ht" + '?symbol=' + params.Symbol);
let url = HOST_URL2 + "/ht" + '?symbol=' + params.Symbol;
return publicRequest(url);
}
}
};
module.exports = exports = Coss;
-178
View File
@@ -1,178 +0,0 @@
exports.newAPIClient = function newAPIClient(keyVaultAPI, logger) {
const Coss = require("./coss");
const exchangeProperties = require('./cossProperties.json');
let API = Coss(keyVaultAPI);
let thisObject = {
getTicker: getTicker,
getOpenPositions: getOpenPositions,
getExecutedTrades: getExecutedTrades,
buy: buy,
sell: sell,
movePosition: movePosition,
getPublicTradeHistory: getPublicTradeHistory,
getExchangeProperties: getExchangeProperties,
isValidLot: isValidLot
};
return thisObject;
function joinCurrencies(currencyA, currencyB) {
// If only one arg, then return the first
if (typeof currencyB !== 'string') {
return currencyA;
}
return currencyA + '_' + currencyB;
}
/*
* Returns the properties for this exchange
*/
function getExchangeProperties() {
return exchangeProperties;
}
/*
* Returns the price for a given pair of assets.
* The object returned is an array of trades:
* ticker = {
* bid, Number
* ask, Number
* last Number
* };
*/
async function getTicker(pMarket, callBack) {
let params = {}
params.Symbol = joinCurrencies(pMarket.assetB, pMarket.assetA)
try {
var response = await API.getPairDepth(params)
let ticker = {
bid: Number(response.bids[0][0]),
ask: Number(response.asks[0][0]),
last: Number((response.bids[0][0] + response.asks[0][0]) / 2) // TODO Pending review
};
callBack(global.DEFAULT_OK_RESPONSE.result, ticker)
} catch (error) {
callBack(global.DEFAULT_FAIL_RESPONSE.result)
}
}
/*
* Returns the open positions ath the exchange for a given market and user account.
* The object returned is an array of positions:
* position = {
* id,
* type,
* rate, Number
* amountA, Number
* amountB, Number
* fee, (not required) Number
* datetime
* };
*/
function getOpenPositions(pMarket, callBack) {
// Not implemented yet
callBack(global.DEFAULT_OK_RESPONSE)
}
/*
* Returns the trades for a given order number.
* The object returned is an array of positions:
* position = {
* id,
* type,
* rate, Number
* amountA, Number
* amountB, Number
* fee, Number
* datetime
* };
*/
function getExecutedTrades(pPositionId, callBack) {
// Not implemented yet
callBack(global.DEFAULT_OK_RESPONSE)
}
/*
* Creates a new buy order.
* The orderNumber is returned. String
*/
function buy(pCurrencyA, pCurrencyB, pRate, pAmount, callBack) {
// Not implemented yet
callBack(global.DEFAULT_OK_RESPONSE)
}
/*
* Creates a new sell order.
* The orderNumber is returned. String
*/
function sell(pCurrencyA, pCurrencyB, pRate, pAmount, callBack) {
// Not implemented yet
callBack(global.DEFAULT_OK_RESPONSE)
}
/*
* Move an existing position to the new rate.
* The orderNumber is returned. String
*/
function movePosition(pPosition, pNewRate, pNewAmountB, callBack) {
// Not implemented yet
callBack(global.DEFAULT_OK_RESPONSE)
}
/*
* Returns all the trade history from the Exchange since startTime to endTime orderd by tradeId.
* It's possible that the exchange doesn't support this method.
* The object returned is an array of trades:
* trade = {
* tradeID, String
* globalTradeID, String
* type, String
* rate, Number
* amountA, Number
* amountB, Number
* date Date
* };
*/
async function getPublicTradeHistory(assetA, assetB, startTime, endTime, callBack) {
let params = {}
params.Symbol = joinCurrencies(assetB, assetA)
try {
let trades = []
var response = await API.getTradeHistory(params);
for (let i = 0; i < response.history.length; i++) {
let record = response.history[i]
let type
if (record.isBuyerMaker) {
type = "sell"
} else {
type = "buy"
}
let trade = {
tradeID: record.id,
globalTradeID: record.id,
type: type,
rate: Number(record.price),
amount: Number(record.qty),
total: Number(record.price) * Number(record.qty),
date: new Date(record.time)
}
trades.push(trade);
}
trades.sort((a, b) => b.tradeID - a.tradeID);
callBack(global.DEFAULT_OK_RESPONSE.result, trades);
} catch (error) {
callBack(global.DEFAULT_FAIL_RESPONSE.result);
}
}
function isValidLot(price, amount) {
return amount * price >= 0.0001;
}
}
-23
View File
@@ -1,23 +0,0 @@
{
"currencies": [
"BTC",
"USDT"
],
"assets": [
"BTC",
"USDT"
],
"markets": [
{
"pair": [
"BTC",
"USDT"
],
"maxDecimals": 5,
"minimalOrder": {
"amount": 0.0001,
"unit": "asset"
}
}
]
}
-440
View File
@@ -1,440 +0,0 @@
// Source: https://github.com/premasagar/poloniex.js
// Documentation: https://poloniex.com/support/api/
module.exports = (function () {
'use strict';
// Module dependencies
var request = require('request'),
nonce = require('nonce')();
// Constants
var version = '0.0.9',
PUBLIC_API_URL = 'https://poloniex.com/public',
PRIVATE_API_URL = 'https://poloniex.com/tradingApi',
USER_AGENT = 'poloniex.js ' + version;
//USER_AGENT = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0'
// Helper methods
function joinCurrencies(currencyA, currencyB) {
// If only one arg, then return the first
if (typeof currencyB !== 'string') {
return currencyA;
}
return currencyA + '_' + currencyB;
}
// Constructor
function Poloniex(keyVaultAPI) {
// Generate headers signed by this user's key and secret.
// The secret is encapsulated and never exposed
this._getPrivateHeaders = function (parameters, next) {
var paramString, signature;
// Convert to `arg1=foo&arg2=bar`
paramString = Object.keys(parameters).map(function (param) {
return encodeURIComponent(param) + '=' + encodeURIComponent(parameters[param]);
}).join('&');
keyVaultAPI.signTransaction(paramString, next);
};
}
// Currently, this fails with `Error: CERT_UNTRUSTED`
// Poloniex.STRICT_SSL can be set to `false` to avoid this. Use with caution.
// Will be removed in future, once this is resolved.
Poloniex.STRICT_SSL = true;
// Customisable user agent string
Poloniex.USER_AGENT = USER_AGENT;
// Prototype
Poloniex.prototype = {
constructor: Poloniex,
// Make an API request
_request: function (options, callback) {
if (!('headers' in options)) {
options.headers = {};
}
options.json = true;
options.headers['User-Agent'] = Poloniex.USER_AGENT;
options.strictSSL = Poloniex.STRICT_SSL;
options.timeout = 60 * 1000;
request(options, function (err, response, body) {
// Empty response
if (!err && (typeof body === 'undefined' || body === null)) {
err = 'Empty response';
}
callback(err, body);
});
return this;
},
// Make a public API request
_public: function (command, parameters, callback) {
var options;
if (typeof parameters === 'function') {
callback = parameters;
parameters = {};
}
parameters || (parameters = {});
parameters.command = command;
options = {
method: 'GET',
url: PUBLIC_API_URL,
qs: parameters
};
options.qs.command = command;
return this._request(options, callback);
},
// Make a private API request
_private: function (command, parameters, callback) {
var options;
if (typeof parameters === 'function') {
callback = parameters;
parameters = {};
}
parameters || (parameters = {});
parameters.command = command;
parameters.nonce = nonce();
options = {
method: 'POST',
url: PRIVATE_API_URL,
form: parameters
};
let headers = this._getPrivateHeaders(parameters, next)
let thisObject = this
function next(pHeaders, error) {
if (!error) {
options.headers = pHeaders;
return thisObject._request(options, callback);
} else {
callback(error);
}
}
},
/////
// PUBLIC METHODS
returnTicker: function (callback) {
return this._public('returnTicker', callback);
},
return24hVolume: function (callback) {
return this._public('return24hVolume', callback);
},
returnOrderBook: function (currencyA, currencyB, callback) {
var currencyPair;
if (typeof currencyB === 'function') {
currencyPair = currencyA;
callback = currencyB;
currencyB = null;
}
else {
currencyPair = joinCurrencies(currencyA, currencyB);
}
var parameters = {
currencyPair: currencyPair
};
return this._public('returnOrderBook', parameters, callback);
},
returnChartData: function (currencyA, currencyB, period, start, end, callback) {
var parameters = {
currencyPair: joinCurrencies(currencyA, currencyB),
period: period,
start: start,
end: end
};
return this._public('returnChartData', parameters, callback);
},
returnCurrencies: function (callback) {
return this._public('returnCurrencies', callback);
},
returnLoanOrders: function (currency, callback) {
return this._public('returnLoanOrders', { currency: currency }, callback);
},
returnTradeHistory: function (currencyA, currencyB, start, end, callback) {
if (arguments.length < 5) {
callback = start;
start = Date.now() / 1000 - 60 * 60;
end = Date.now() / 1000 + 60 * 60; // Some buffer in case of client/server time out of sync.
}
var parameters = {
currencyPair: joinCurrencies(currencyA, currencyB),
start: start,
end: end
};
return this._public('returnTradeHistory', parameters, callback);
},
/////
// PRIVATE METHODS
returnBalances: function (callback) {
return this._private('returnBalances', {}, callback);
},
returnCompleteBalances: function (account, callback) {
var parameters = {};
if (typeof account === 'function') {
callback = account;
}
else if (typeof account === 'string' && !!account) {
parameters.account = account;
}
return this._private('returnCompleteBalances', parameters, callback);
},
returnDepositAddresses: function (callback) {
return this._private('returnDepositAddresses', {}, callback);
},
generateNewAddress: function (currency, callback) {
return this._private('generateNewAddress', { currency: currency }, callback);
},
returnDepositsWithdrawals: function (start, end, callback) {
return this._private('returnDepositsWithdrawals', { start: start, end: end }, callback);
},
// can be called with `returnOpenOrders('all', callback)`
returnOpenOrders: function (currencyA, currencyB, callback) {
var currencyPair;
if (typeof currencyB === 'function') {
currencyPair = currencyA;
callback = currencyB;
currencyB = null;
}
else {
currencyPair = joinCurrencies(currencyA, currencyB);
}
var parameters = {
currencyPair: currencyPair
};
return this._private('returnOpenOrders', parameters, callback);
},
returnOrderTrades: function (orderNumber, callback) {
var parameters = {
orderNumber: orderNumber
};
return this._private('returnOrderTrades', parameters, callback);
},
buy: function (currencyA, currencyB, rate, amount, callback) {
var parameters = {
currencyPair: joinCurrencies(currencyA, currencyB),
rate: rate,
amount: amount
};
return this._private('buy', parameters, callback);
},
sell: function (currencyA, currencyB, rate, amount, callback) {
var parameters = {
currencyPair: joinCurrencies(currencyA, currencyB),
rate: rate,
amount: amount
};
return this._private('sell', parameters, callback);
},
cancelOrder: function (currencyA, currencyB, orderNumber, callback) {
var parameters = {
currencyPair: joinCurrencies(currencyA, currencyB),
orderNumber: orderNumber
};
return this._private('cancelOrder', parameters, callback);
},
moveOrder: function (orderNumber, rate, amount, callback) {
var parameters = {
orderNumber: orderNumber,
rate: rate,
amount: amount ? amount : null
};
return this._private('moveOrder', parameters, callback);
},
withdraw: function (currency, amount, address, callback) {
var parameters = {
currency: currency,
amount: amount,
address: address
};
return this._private('withdraw', parameters, callback);
},
returnFeeInfo: function (callback) {
return this._private('returnFeeInfo', {}, callback);
},
returnAvailableAccountBalances: function (account, callback) {
var parameters = {};
if (typeof account === 'function') {
callback = account;
}
else if (typeof account === 'string' && !!account) {
parameters.account = account;
}
return this._private('returnAvailableAccountBalances', parameters, callback);
},
returnTradableBalances: function (callback) {
return this._private('returnTradableBalances', {}, callback);
},
transferBalance: function (currency, amount, fromAccount, toAccount, callback) {
var parameters = {
currency: currency,
amount: amount,
fromAccount: fromAccount,
toAccount: toAccount
};
return this._private('transferBalance', parameters, callback);
},
returnMarginAccountSummary: function (callback) {
return this._private('returnMarginAccountSummary', {}, callback);
},
marginBuy: function (currencyA, currencyB, rate, amount, lendingRate, callback) {
var parameters = {
currencyPair: joinCurrencies(currencyA, currencyB),
rate: rate,
amount: amount,
lendingRate: lendingRate ? lendingRate : null
};
return this._private('marginBuy', parameters, callback);
},
marginSell: function (currencyA, currencyB, rate, amount, lendingRate, callback) {
var parameters = {
currencyPair: joinCurrencies(currencyA, currencyB),
rate: rate,
amount: amount,
lendingRate: lendingRate ? lendingRate : null
};
return this._private('marginSell', parameters, callback);
},
getMarginPosition: function (currencyA, currencyB, callback) {
var parameters = {
currencyPair: joinCurrencies(currencyA, currencyB)
};
return this._private('getMarginPosition', parameters, callback);
},
closeMarginPosition: function (currencyA, currencyB, callback) {
var parameters = {
currencyPair: joinCurrencies(currencyA, currencyB)
};
return this._private('closeMarginPosition', parameters, callback);
},
createLoanOffer: function (currency, amount, duration, autoRenew, lendingRate, callback) {
var parameters = {
currency: currency,
amount: amount,
duration: duration,
autoRenew: autoRenew,
lendingRate: lendingRate
};
return this._private('createLoanOffer', parameters, callback);
},
cancelLoanOffer: function (orderNumber, callback) {
var parameters = {
orderNumber: orderNumber
};
return this._private('cancelLoanOffer', parameters, callback);
},
returnOpenLoanOffers: function (callback) {
return this._private('returnOpenLoanOffers', {}, callback);
},
returnActiveLoans: function (callback) {
return this._private('returnActiveLoans', {}, callback);
},
returnLendingHistory: function (start, end, limit, callback) {
var parameters = {
start: start,
end: end,
limit: limit
};
return this._private('returnLendingHistory', parameters, callback);
},
toggleAutoRenew: function (orderNumber, callback) {
return this._private('toggleAutoRenew', { orderNumber: orderNumber }, callback);
}
};
// Backwards Compatibility
Poloniex.prototype.getTicker = Poloniex.prototype.returnTicker;
Poloniex.prototype.get24hVolume = Poloniex.prototype.return24hVolume;
Poloniex.prototype.getOrderBook = Poloniex.prototype.returnOrderBook;
Poloniex.prototype.getTradeHistory = Poloniex.prototype.returnChartData;
Poloniex.prototype.myBalances = Poloniex.prototype.returnBalances;
Poloniex.prototype.myOpenOrders = Poloniex.prototype.returnOpenOrders;
Poloniex.prototype.myTradeHistory = Poloniex.prototype.returnTradeHistory;
return Poloniex;
})();
-348
View File
@@ -1,348 +0,0 @@
exports.newAPIClient = function newAPIClient(keyVaultAPI, logger) {
const FULL_LOG = true;
const LOG_FILE_CONTENT = false;
const MODULE_NAME = "poloniexClient";
const retry = require('../exchangeUtils').retry;
const includes = require('../exchangeUtils').includes;
const _ = require('lodash');
const Poloniex = require("./poloniex");
const exchangeProperties = require('./poloniexProperties.json');
const recoverableErrors = [
'SOCKETTIMEDOUT',
'TIMEDOUT',
'CONNRESET',
'CONNREFUSED',
'NOTFOUND',
'429',
'522',
'504',
'503',
'500',
'502',
'Empty response',
'Please try again in a few minutes.',
'Nonce must be greater than',
'Internal error. Please try again.',
'Connection timed out. Please try again.',
'ENOTFOUND',
'ECONNREFUSED',
'CONNREFUSED',
'NOTFOUND',
'ESOCKETTIMEDOUT',
'ECONNRESET',
'Connection timed out',
'Connection Error',
'Order not found, or you are not the person who placed it.',
'ETIMEDOUT'
];
let API = new Poloniex(keyVaultAPI);
let thisObject = {
getTicker: getTicker,
getOpenPositions: getOpenPositions,
getExecutedTrades: getExecutedTrades,
buy: buy,
sell: sell,
movePosition: movePosition,
getPublicTradeHistory: getPublicTradeHistory,
getExchangeProperties: getExchangeProperties,
isValidLot: isValidLot
};
return thisObject;
function joinCurrencies(currencyA, currencyB) {
// If only one arg, then return the first
if (typeof currencyB !== 'string') {
return currencyA;
}
return currencyA + '_' + currencyB;
}
/*
* Returns the properties for this exchange
*/
function getExchangeProperties() {
return exchangeProperties;
}
/*
* Returns the price for a given pair of assets.
* The object returned is an array of trades:
* ticker = {
* bid, Number
* ask, Number
* last Number
* };
*/
function getTicker(pMarket, callBack) {
const handle = (err, response) => {
let ticker;
let market = joinCurrencies(pMarket.assetA, pMarket.assetB);
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
ticker = {
bid: Number(response[market].highestBid),
ask: Number(response[market].lowestAsk),
last: Number(response[market].last)
};
}
callBack(err, ticker);
};
const fetch = next => API.getTicker(analizeResponse(next));
retry(null, fetch, handle);
}
/*
* Returns the open positions ath the exchange for a given market and user account.
* The object returned is an array of positions:
* position = {
* id,
* type,
* rate, Number
* amountA, Number
* amountB, Number
* fee, (not required) Number
* datetime
* };
*/
function getOpenPositions(pMarket, callBack) {
const handle = (err, response) => {
let exchangePositions = [];
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
for (let i = 0; i < response.length; i++) {
let openPosition = {
id: response[i].orderNumber,
type: response[i].type,
rate: Number(response[i].rate),
amountA: Number(response[i].total),
amountB: Number(response[i].amount),
date: (new Date(response[i].time)).valueOf()
};
exchangePositions.push(openPosition);
}
}
callBack(err, exchangePositions);
};
const fetch = next => API.returnOpenOrders(pMarket.assetA, pMarket.assetB, analizeResponse(next));
retry(null, fetch, handle);
}
/*
* Returns the trades for a given order number.
* The object returned is an array of positions:
* position = {
* id,
* type,
* rate, Number
* amountA, Number
* amountB, Number
* fee, Number
* datetime
* };
*/
function getExecutedTrades(pPositionId, callBack) {
const handle = (err, response) => {
let trades = [];
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
for (let i = 0; i < response.length; i++) {
let trade = {
id: response[i].tradeID,
type: response[i].type,
rate: Number(response[i].rate),
amountA: Number(response[i].total),
amountB: Number(response[i].amount),
fee: Number(response[i].fee),
date: (new Date(response[i].date)).valueOf()
}
trades.push(trade);
}
} else if (err.result === global.CUSTOM_OK_RESPONSE.result) {
// No trades found at the exchange for the position, but returning empy trades object.
err = global.DEFAULT_OK_RESPONSE;
}
callBack(err, trades);
};
const fetch = next => API.returnOrderTrades(pPositionId, analizeResponse(next));
retry(null, fetch, handle);
}
/*
* Creates a new buy order.
* The orderNumber is returned. String
*/
function buy(pCurrencyA, pCurrencyB, pRate, pAmount, callBack) {
const handle = (err, response) => {
let orderNumber;
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
orderNumber = response.orderNumber;
}
callBack(err, orderNumber);
};
const fetch = next => API.buy(pCurrencyA, pCurrencyB, pRate, pAmount, analizeResponse(next));
retry(null, fetch, handle);
}
/*
* Creates a new sell order.
* The orderNumber is returned. String
*/
function sell(pCurrencyA, pCurrencyB, pRate, pAmount, callBack) {
const handle = (err, response) => {
let orderNumber;
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
orderNumber = response.orderNumber;
}
callBack(err, orderNumber);
};
const fetch = next => API.sell(pCurrencyA, pCurrencyB, pRate, pAmount, analizeResponse(next));
retry(null, fetch, handle);
}
/*
* Move an existing position to the new rate.
* The orderNumber is returned. String
*/
function movePosition(pPosition, pNewRate, pNewAmountB, callBack) {
const handle = (err, response) => {
let orderNumber;
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
orderNumber = response.orderNumber;
}
callBack(err, orderNumber);
};
const fetch = next => API.moveOrder(pPosition.id, pNewRate, pNewAmountB, analizeResponse(next));
retry(null, fetch, handle);
}
/*
* Returns all the trade history from the Exchange since startTime to endTime orderd by tradeId.
* It's possible that the exchange doesn't support this method.
* The object returned is an array of trades:
* trade = {
* tradeID, String
* globalTradeID, String
* type, String
* rate, Number
* amountA, Number
* amountB, Number
* date Date
* };
*/
function getPublicTradeHistory(assetA, assetB, startTime, endTime, callBack) {
const handle = (err, response) => {
let trades = [];
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
for (let i = 0; i < response.length; i++) {
let trade = {
tradeID: response[i].tradeID,
globalTradeID: response[i].globalTradeID,
type: response[i].type,
rate: Number(response[i].rate),
total: Number(response[i].total),
amount: Number(response[i].amount),
date: new Date(response[i].date)
}
trades.push(trade);
}
}
callBack(err, trades);
};
const fetch = next => API.returnTradeHistory(assetA, assetB, startTime, endTime, analizeResponse(next));
retry(null, fetch, handle);
}
function isValidLot(price, amount) {
return amount * price >= 0.0001;
}
function analizeResponse(callBack) {
return (exchangeErr, exchangeResponse) => {
let error;
/* This function analizes the different situations we might encounter trying to access Poloniex and returns appropiate standard errors. */
let stringExchangeErr = JSON.stringify(exchangeErr);
let stringExchangeResponse = JSON.stringify(exchangeResponse);
try {
if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] analizeResponse -> exchangeErr = " + stringExchangeErr); }
if (LOG_FILE_CONTENT === true) { logger.write(MODULE_NAME, "[INFO] analizeResponse -> exchangeResponse = " + stringExchangeResponse); }
if (exchangeErr) {
error = global.DEFAULT_FAIL_RESPONSE;
if (includes(exchangeErr.code, recoverableErrors)) {
error.notFatal = true;
}
} else if (!exchangeResponse || exchangeResponse === undefined) {
error = {
result: global.DEFAULT_FAIL_RESPONSE.result,
message: 'Empty response',
notFatal: true
};
} else if (includes(exchangeResponse.error, ['Please complete the security check to proceed.'])) {
error = {
result: global.DEFAULT_FAIL_RESPONSE.result,
message: 'The IP has been flagged by CloudFlare.'
};
} else if (includes(exchangeResponse.error, ['<!DOCTYPE html>'])) {
error = {
result: global.DEFAULT_FAIL_RESPONSE.result,
message: exchangeResponse
};
} else if (includes(exchangeResponse.error, ['Not enough'])) {
error = {
result: global.DEFAULT_RETRY_RESPONSE.result,
message: exchangeResponse.error
};
} else if (includes(exchangeResponse.error, ['Order not found, or you are not the person who placed it.'])) {
error = {
result: global.CUSTOM_OK_RESPONSE.result,
message: exchangeResponse.error
};
} else if (exchangeResponse.error) {
error = {
result: global.DEFAULT_FAIL_RESPONSE.result,
message: exchangeResponse.error
};
}
return callBack(error, exchangeResponse);
} catch (err) {
logger.write(MODULE_NAME, "[ERROR] analizeResponse -> err.message = " + err.message);
return callBack(global.DEFAULT_FAIL_RESPONSE, exchangeResponse);
}
}
}
}
File diff suppressed because it is too large. Load diff
-1
View File
@@ -53,7 +53,6 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="exchange\exchangeUtils.js" />
<Compile Include="exchange\wrappers\beautifier.js" />
<Compile Include="exchange\wrappers\binance.js" />
<Compile Include="exchange\wrappers\binanceClient.js" />
<Compile Include="exchange\wrappers\poloniex.js" />
+1 -1
View File
@@ -144,7 +144,7 @@
const UTILITIES = require(ROOT_DIR + 'CloudUtilities');
const STATUS_REPORT = require(ROOT_DIR + 'StatusReport');
const EXCHANGE_API = require(ROOT_DIR + 'Exchange/ExchangeAPI');
const EXCHANGE_API = require('@superalgos/exchangegateway');
const STATUS_DEPENDENCIES = require(ROOT_DIR + 'StatusDependencies');
/* We define the datetime for the process that we are running now. This will be the official processing time for both the infraestructure and the bot. */
+1 -1
View File
@@ -163,7 +163,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(ROOT_DIR + 'Exchange/ExchangeAPI');
const EXCHANGE_API = require('@superalgos/exchangegateway');
const CONTEXT = require(ROOT_DIR + 'Context');
const ASSISTANT = require(ROOT_DIR + 'Assistant');
const STATUS_REPORT = require(ROOT_DIR + 'StatusReport');
+1854 -4
View File
File diff suppressed because it is too large. Load diff
+2 -1
View File
@@ -9,7 +9,8 @@
"author": "Luis-Fernando-Molina",
"license": "ISC",
"dependencies": {
"@superalgos/mqservice": "0.0.9",
"@superalgos/exchangegateway": "0.0.1",
"@superalgos/mqservice": "0.0.12",
"apollo-boost": "^0.1.16",
"assert": "^1.4.1",
"axios": "^0.18.0",