This repository has been archived on 2025-10-29. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
gekko/exchange/wrappers/quadriga.js.old
T
2021-06-06 20:25:14 +02:00

252 lines
7.5 KiB
Plaintext

var QuadrigaCX = require('quadrigacx');
var moment = require('moment');
var util = require('../core/util');
var _ = require('lodash');
var log = require('../core/log');
var Trader = function(config) {
_.bindAll(this);
if(_.isObject(config)) {
this.key = config.key;
this.secret = config.secret;
this.clientId = config.username;
this.asset = config.asset;
this.currency = config.currency;
}
this.pair = this.asset.toLowerCase() + '_' + this.currency.toLowerCase();
this.name = 'quadriga';
this.since = null;
this.quadriga = new QuadrigaCX(
this.clientId ? this.clientId : "1",
this.key ? this.key : "",
this.secret ? this.secret : "",
);
}
Trader.prototype.retry = function(method, warn, args, error) {
var wait = +moment.duration(30, 'seconds');
if (error.code === 200) {
log.debug(`${this.name}: API rate limit exceeded! unable to call ${method}, will retry in 2 minutes`)
wait = +moment.duration(120, 'seconds');
}
else {
log.debug(JSON.stringify(error));
log.debug(`${this.name}: ${warn}, will retry in 30 seconds`);
}
var self = this;
// make sure the callback (and any other fn)
// is bound to Trader
_.each(args, function(arg, i) {
if(_.isFunction(arg))
args[i] = _.bind(arg, self);
});
// run the failed method again with the same
// arguments after wait
setTimeout(
function() { method.apply(self, args) },
wait
);
};
Trader.prototype.getTrades = function(since, callback, descending) {
var args = _.toArray(arguments);
var process = function(err, trades) {
if (trades && trades.error) return this.retry(this.getTrades, 'unable to get trades', args, trades.error);
if (err) return this.retry(this.getTrades, 'unable to get trades', args, err);
var parsedTrades = [];
_.each(trades, function(trade) {
parsedTrades.push({
tid: trade.tid,
date: trade.date,
price: parseFloat(trade.price),
amount: parseFloat(trade.amount)
});
}, this);
if(descending)
callback(null, parsedTrades);
else
callback(null, parsedTrades.reverse());
};
var reqData = {
book: this.pair,
time: 'hour'
};
this.quadriga.api('transactions', reqData, _.bind(process, this));
};
Trader.prototype.getPortfolio = function(callback) {
var args = _.toArray(arguments);
var set = function(err, data) {
if (data && data.error) return this.retry(this.getPortfolio, 'unable to get balance', args, data.error);
if (err) return this.retry(this.getPortfolio, 'unable to get balance', args, err);
var assetAmount = parseFloat( data[this.asset.toLowerCase() + '_available'] );
var currencyAmount = parseFloat( data[this.currency.toLowerCase() + '_available'] );
if(!_.isNumber(assetAmount) || _.isNaN(assetAmount)) {
log.error(`Quadriga did not return balance for ${this.asset.toLowerCase()}, assuming 0.`);
assetAmount = 0;
}
if(!_.isNumber(currencyAmount) || _.isNaN(currencyAmount)) {
log.error(`Quadriga did not return balance for ${this.currency.toLowerCase()}, assuming 0.`);
currencyAmount = 0;
}
var portfolio = [
{ name: this.asset, amount: assetAmount },
{ name: this.currency, amount: currencyAmount }
];
callback(err, portfolio);
};
this.quadriga.api('balance', _.bind(set, this));
};
Trader.prototype.getFee = function(callback) {
callback(false, 0.005);
};
Trader.prototype.getTicker = function(callback) {
var set = function(err, data) {
if (data && data.error) return this.retry(this.getTicker, 'unable to get quote', args, data.error);
if (err) return this.retry(this.getTicker, 'unable to get quote', args, err);
var ticker = {
ask: data.ask,
bid: data.bid
};
callback(err, ticker);
};
this.quadriga.api('ticker', {book: this.pair}, _.bind(set, this));
};
Trader.prototype.roundAmount = function(amount) {
var precision = 100000000;
var market = Trader.getCapabilities().markets.find(function(market){ return market.pair[0] === this.currency && market.pair[1] === this.asset });
if(Number.isInteger(market.precision))
precision = 10 * market.precision;
amount *= precision;
amount = Math.floor(amount);
amount /= precision;
return amount;
};
Trader.prototype.addOrder = function(tradeType, amount, price, callback) {
var args = _.toArray(arguments);
amount = this.roundAmount(amount);
log.debug(tradeType.toUpperCase(), amount, this.asset, '@', price, this.currency);
var set = function(err, data) {
if (data && data.error) return this.retry(this.addOrder, 'unable to place order', args, data.error);
if (err) return this.retry(this.addOrder, 'unable to place order', args, err);
var txid = data.id;
log.debug('added order with txid:', txid);
callback(undefined, txid);
};
this.quadriga.api(tradeType, {
book: this.pair,
price: price,
amount: amount
}, _.bind(set, this));
};
Trader.prototype.getOrder = function(order, callback) {
var args = _.toArray(arguments);
var get = function(err, data) {
if (data && data.error) return this.retry(this.getOrder, 'unable to get order', args, data.error);
if (err) return this.retry(this.getOrder, 'unable to get order', args, err);
var price = parseFloat( data[0].price );
var amount = parseFloat( data[0].amount );
var date = (data[0].updated) ? moment.unix( data[0].updated ) : false;
callback(undefined, {price, amount, date});
}.bind(this);
this.quadriga.api('lookup_oder', {id: order}, get);
}
Trader.prototype.buy = function(amount, price, callback) {
this.addOrder('buy', amount, price, callback);
};
Trader.prototype.sell = function(amount, price, callback) {
this.addOrder('sell', amount, price, callback);
};
Trader.prototype.checkOrder = function(order, callback) {
var args = _.toArray(arguments);
var check = function(err, data) {
if (data && data.error) return this.retry(this.checkOrder, 'unable to get order', args, data.error);
if (err) return this.retry(this.checkOrder, 'unable to get order', args, err);
var result = data[0];
var stillThere = result.status === 0 || result.status === 1;
callback(err, !stillThere);
};
this.quadriga.api('lookup_order', {id: order}, _.bind(check, this));
};
Trader.prototype.cancelOrder = function(order, callback) {
var args = _.toArray(arguments);
var cancel = function(err, data) {
if (data && data.error) return this.retry(this.cancelOrder, 'unable to cancel order', args, data.error);
if (err) return this.retry(this.cancelOrder, 'unable to cancel order', args, err);
callback();
};
this.quadriga.api('cancel_order', {id: order}, _.bind(cancel, this));
};
Trader.getCapabilities = function () {
return {
name: 'Quadriga',
slug: 'quadriga',
currencies: ['CAD', 'USD', 'BTC'],
assets: ['BTC', 'ETH', 'LTC', 'BCH'],
markets: [
{ pair: ['BTC', 'ETH'], minimalOrder: { amount: 0.00001, unit: 'asset' }, precision: 8 },
{ pair: ['CAD', 'ETH'], minimalOrder: { amount: 0.00001, unit: 'asset' }, precision: 8 },
{ pair: ['USD', 'BTC'], minimalOrder: { amount: 0.00001, unit: 'asset' }, precision: 8 },
{ pair: ['CAD', 'BTC'], minimalOrder: { amount: 0.00001, unit: 'asset' }, precision: 8 },
{ pair: ['CAD', 'LTC'], minimalOrder: { amount: 0.00001, unit: 'asset' }, precision: 8 },
{ pair: ['CAD', 'BCH'], minimalOrder: { amount: 0.00001, unit: 'asset' }, precision: 8 },
],
requires: ['key', 'secret', 'username'],
providesHistory: false,
tid: 'tid',
tradable: true
};
}
module.exports = Trader;