crypto-nodes
Version:
259 lines (182 loc) • 5.53 kB
JavaScript
var ccxt = require('ccxt');
const fs = require('fs');
var started = false;
var utils = {
exchanges: {},
ccxt_exchanges: {},
ccxt_ticks: {},
started,
init: function () {
var that = this;
if(started || this.started) {
return;
}
started = true;
console.log('Loading..');
const exchangesFolder = __dirname + '/exchanges/';
fs.readdirSync(exchangesFolder).forEach(file => {
var ex = file.split('.')[0];
that.exchanges[ex] = require(exchangesFolder + file);
//console.log(ex);
//console.log(that.exchanges[ex]);
that.exchanges[ex].utils = this;
that.exchanges[ex].data.create = function(node, config) {
if(config.disabled) {
console.log('Exchange is disabled');
return false;
}
if(!this.setup) {
console.log('Missing setup function');
return false;
} else {
console.log('SETTING UP..');
return this.setup(node, config.config);
}
}
});
this.started = true;
started = true;
},
load: function(exchange_id, config, callback) {
that = this;
let exchangeFound = ccxt.exchanges.indexOf (exchange_id) > -1;
if (exchangeFound) {
if(!this.exchanges[exchange_id]) {
//return;
console.log('Exchange not supported');
callback(false);
}
if(!this.exchanges[exchange_id].ccxt) {
//console.log('Starting..');
this.ccxt_init(exchange_id, config).then(function() {
callback(that.exchanges[exchange_id]);
});
} else {
callback(that.exchanges[exchange_id]);
return this.exchanges[exchange_id];
}
} else {
return false;
}
},
ccxt_init: async function(exchange_id, config) {
//console.log('CCXT INIT::');
//console.log(config);
//console.log(ccxt[exchange_id].urls);
var opts = {
enableRateLimit: false,
urls: { api: '' }
};
// Set USER / PASS CONFIG
if(config.api_key) {
opts.apiKey = config.api_key;
}
if(config.api_pass) {
opts.password = config.api_pass;
}
if(config.api_secret) {
opts.secret = config.api_secret;
}
var tmp = new ccxt[exchange_id] (opts);
// Set TESTNET CONFIG
if(config.testnet && tmp.urls.test) {
opts.urls.api = tmp.urls.test;
}
console.log(opts);
// instantiate the exchange by id
let exchange = new ccxt[exchange_id] (opts);
console.log(exchange.urls);
// load all markets from the exchange
exchange.loadMarkets().catch(function (err) {
//subscribeOrderBook(id, symbol, node);
exchange = false;
return;
});
this.exchanges[exchange_id].ccxt = exchange;
/*if(this.supported.indexOf(exchange_id)) {
}*/
return true;
},
// Send Order via CCXT
// Callback [false, ccxt formatted obj]
// Callback [true, error msg]
ccxt_order: async function(exchange_id, data, node, callback) {
if(!this.exchanges[exchange_id].ccxt) {
console.log('CCXT NOT INITIALIZED');
return false;
}
var ccxt_obj = this.exchanges[exchange_id].ccxt;
try {
const response = await ccxt_obj.createOrder(
data.tx.symbol,
'limit',
(data.tx.is_buy ? 'buy' : 'sell'),
data.tx.qty,
data.tx.price,
{ 'timeInForce': 'IOC', 'client_order_id': data.tx.acc.toString(), options: ['immediate-or-cancel'] });
callback(false, response);
} catch (e) {
callback(e.constructor.name, e.message);
}
},
ccxt_subscribe(exchange_id, symbols, node) {
var that = this;
console.log('SUBBING');
if(!this.exchanges[exchange_id].ccxt) {
console.log('CCXT NOT INITIALIZED');
return false;
}
for(x in symbols) {
var symbol = symbols[x];
if (symbol in this.exchanges[exchange_id].ccxt.markets) {
this.ccxt_loop(this.exchanges[exchange_id].ccxt, symbol, node);
}
}
console.log('Setting Timers ..');
setInterval(function () {
node.status({ fill: that.ccxt_ticks[exchange_id] ? 'green' : 'red' ,
shape:'ring',
text: that.ccxt_ticks[exchange_id] + ' Requests per second'
});
that.ccxt_ticks[exchange_id] = 0;
}, 1000);
},
ccxt_loop: async function (exchange, symbol, node) {
var that = this;
async function fnk(exchange, symbol, node, e) {
setTimeout(async function () {
var e = false;
const orderbook = await exchange.fetchOrderBook (symbol, 50).catch(function (err) {
node.status({ fill: 'red' ,shape:'ring', text: err.toString() });
e = err;
});
/*
console.log('.');
console.log(orderbook);
*/
if(!e) {
if(that.ccxt_ticks[exchange.id]) {
that.ccxt_ticks[exchange.id]++;
} else {
that.ccxt_ticks[exchange.id] = 1;
}
node.send({
payload: {
exchange: 'generic_' + exchange.id,
fees: {},//exchange.fees,
sym_from: symbol.split('/')[0],
sym_to: symbol.split('/')[1],
data: orderbook
}
});
}
fnk(exchange, symbol, node, e);
}, e ? 10000 : 2000 + Math.floor(Math.random() * 500));
}
fnk(exchange, symbol, node, false);
}
}
if(!started) {
utils.init();
}
module.exports = utils;