ccxt-compiled
Version:
A JavaScript / Python / PHP cryptocurrency trading library with support for 90+ exchanges
402 lines (364 loc) • 15 kB
JavaScript
"use strict";
// ---------------------------------------------------------------------------
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const Exchange = require('./base/Exchange');
const { ExchangeError, OrderNotFound, InvalidOrder, InsufficientFunds } = require('./base/errors');
// ---------------------------------------------------------------------------
module.exports = class qryptos extends Exchange {
describe() {
return this.deepExtend(super.describe(), {
'id': 'qryptos',
'name': 'QRYPTOS',
'countries': ['CN', 'TW'],
'version': '2',
'rateLimit': 1000,
'hasFetchTickers': true,
'hasCORS': false,
'has': {
'fetchOrder': true,
'fetchOrders': true,
'fetchOpenOrders': true,
'fetchClosedOrders': true
},
'urls': {
'logo': 'https://user-images.githubusercontent.com/1294454/30953915-b1611dc0-a436-11e7-8947-c95bd5a42086.jpg',
'api': 'https://api.qryptos.com',
'www': 'https://www.qryptos.com',
'doc': 'https://developers.quoine.com'
},
'api': {
'public': {
'get': ['products', 'products/{id}', 'products/{id}/price_levels', 'executions', 'ir_ladders/{currency}']
},
'private': {
'get': ['accounts/balance', 'crypto_accounts', 'executions/me', 'fiat_accounts', 'loan_bids', 'loans', 'orders', 'orders/{id}', 'orders/{id}/trades', 'trades', 'trades/{id}/loans', 'trading_accounts', 'trading_accounts/{id}'],
'post': ['fiat_accounts', 'loan_bids', 'orders'],
'put': ['loan_bids/{id}/close', 'loans/{id}', 'orders/{id}', 'orders/{id}/cancel', 'trades/{id}', 'trades/{id}/close', 'trades/close_all', 'trading_accounts/{id}']
}
}
});
}
fetchMarkets() {
var _this = this;
return (0, _asyncToGenerator3.default)(function* () {
let markets = yield _this.publicGetProducts();
let result = [];
for (let p = 0; p < markets.length; p++) {
let market = markets[p];
let id = market['id'];
let base = market['base_currency'];
let quote = market['quoted_currency'];
let symbol = base + '/' + quote;
let maker = _this.safeFloat(market, 'maker_fee');
let taker = _this.safeFloat(market, 'taker_fee');
let active = !market['disabled'];
result.push({
'id': id,
'symbol': symbol,
'base': base,
'quote': quote,
'maker': maker,
'taker': taker,
'active': active,
'info': market
});
}
return result;
})();
}
fetchBalance(params = {}) {
var _this2 = this;
return (0, _asyncToGenerator3.default)(function* () {
yield _this2.loadMarkets();
let balances = yield _this2.privateGetAccountsBalance();
let result = { 'info': balances };
for (let b = 0; b < balances.length; b++) {
let balance = balances[b];
let currency = balance['currency'];
let total = parseFloat(balance['balance']);
let account = {
'free': total,
'used': 0.0,
'total': total
};
result[currency] = account;
}
return _this2.parseBalance(result);
})();
}
fetchOrderBook(symbol, params = {}) {
var _this3 = this;
return (0, _asyncToGenerator3.default)(function* () {
yield _this3.loadMarkets();
let orderbook = yield _this3.publicGetProductsIdPriceLevels(_this3.extend({
'id': _this3.marketId(symbol)
}, params));
return _this3.parseOrderBook(orderbook, undefined, 'buy_price_levels', 'sell_price_levels');
})();
}
parseTicker(ticker, market = undefined) {
let timestamp = this.milliseconds();
let last = undefined;
if ('last_traded_price' in ticker) {
if (ticker['last_traded_price']) {
let length = ticker['last_traded_price'].length;
if (length > 0) last = parseFloat(ticker['last_traded_price']);
}
}
let symbol = undefined;
if (market) symbol = market['symbol'];
return {
'symbol': symbol,
'timestamp': timestamp,
'datetime': this.iso8601(timestamp),
'high': this.safeFloat(ticker, 'high_market_ask'),
'low': this.safeFloat(ticker, 'low_market_bid'),
'bid': this.safeFloat(ticker, 'market_bid'),
'ask': this.safeFloat(ticker, 'market_ask'),
'vwap': undefined,
'open': undefined,
'close': undefined,
'first': undefined,
'last': last,
'change': undefined,
'percentage': undefined,
'average': undefined,
'baseVolume': this.safeFloat(ticker, 'volume_24h'),
'quoteVolume': undefined,
'info': ticker
};
}
fetchTickers(symbols = undefined, params = {}) {
var _this4 = this;
return (0, _asyncToGenerator3.default)(function* () {
yield _this4.loadMarkets();
let tickers = yield _this4.publicGetProducts(params);
let result = {};
for (let t = 0; t < tickers.length; t++) {
let ticker = tickers[t];
let base = ticker['base_currency'];
let quote = ticker['quoted_currency'];
let symbol = base + '/' + quote;
let market = _this4.markets[symbol];
result[symbol] = _this4.parseTicker(ticker, market);
}
return result;
})();
}
fetchTicker(symbol, params = {}) {
var _this5 = this;
return (0, _asyncToGenerator3.default)(function* () {
yield _this5.loadMarkets();
let market = _this5.market(symbol);
let ticker = yield _this5.publicGetProductsId(_this5.extend({
'id': market['id']
}, params));
return _this5.parseTicker(ticker, market);
})();
}
parseTrade(trade, market) {
let timestamp = trade['created_at'] * 1000;
return {
'info': trade,
'id': trade['id'].toString(),
'order': undefined,
'timestamp': timestamp,
'datetime': this.iso8601(timestamp),
'symbol': market['symbol'],
'type': undefined,
'side': trade['taker_side'],
'price': parseFloat(trade['price']),
'amount': parseFloat(trade['quantity'])
};
}
fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
var _this6 = this;
return (0, _asyncToGenerator3.default)(function* () {
yield _this6.loadMarkets();
let market = _this6.market(symbol);
let request = {
'product_id': market['id']
};
if (limit) request['limit'] = limit;
let response = yield _this6.publicGetExecutions(_this6.extend(request, params));
return _this6.parseTrades(response['models'], market, since, limit);
})();
}
createOrder(symbol, type, side, amount, price = undefined, params = {}) {
var _this7 = this;
return (0, _asyncToGenerator3.default)(function* () {
yield _this7.loadMarkets();
let order = {
'order_type': type,
'product_id': _this7.marketId(symbol),
'side': side,
'quantity': amount
};
if (type == 'limit') order['price'] = price;
let response = yield _this7.privatePostOrders(_this7.extend({
'order': order
}, params));
return _this7.parseOrder(response);
})();
}
cancelOrder(id, symbol = undefined, params = {}) {
var _this8 = this;
return (0, _asyncToGenerator3.default)(function* () {
yield _this8.loadMarkets();
let result = yield _this8.privatePutOrdersIdCancel(_this8.extend({
'id': id
}, params));
let order = _this8.parseOrder(result);
if (order['status'] == 'closed') throw new OrderNotFound(_this8.id + ' ' + _this8.json(order));
return order;
})();
}
parseOrder(order) {
let timestamp = order['created_at'] * 1000;
let marketId = order['product_id'];
let market = this.marketsById[marketId];
let status = undefined;
if ('status' in order) {
if (order['status'] == 'live') {
status = 'open';
} else if (order['status'] == 'filled') {
status = 'closed';
} else if (order['status'] == 'cancelled') {
// 'll' intended
status = 'canceled';
}
}
let amount = parseFloat(order['quantity']);
let filled = parseFloat(order['filled_quantity']);
let symbol = undefined;
if (market) {
symbol = market['symbol'];
}
return {
'id': order['id'],
'timestamp': timestamp,
'datetime': this.iso8601(timestamp),
'type': order['order_type'],
'status': status,
'symbol': symbol,
'side': order['side'],
'price': order['price'],
'amount': amount,
'filled': filled,
'remaining': amount - filled,
'trades': undefined,
'fee': {
'currency': undefined,
'cost': parseFloat(order['order_fee'])
},
'info': order
};
}
fetchOrder(id, symbol = undefined, params = {}) {
var _this9 = this;
return (0, _asyncToGenerator3.default)(function* () {
yield _this9.loadMarkets();
let order = yield _this9.privateGetOrdersId(_this9.extend({
'id': id
}, params));
return _this9.parseOrder(order);
})();
}
fetchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
var _this10 = this;
return (0, _asyncToGenerator3.default)(function* () {
yield _this10.loadMarkets();
let market = undefined;
let request = {};
if (symbol) {
market = _this10.market(symbol);
request['product_id'] = market['id'];
}
let status = params['status'];
if (status == 'open') {
request['status'] = 'live';
} else if (status == 'closed') {
request['status'] = 'filled';
} else if (status == 'canceled') {
request['status'] = 'cancelled';
}
let result = yield _this10.privateGetOrders(request);
let orders = result['models'];
return _this10.parseOrders(orders, market, since, limit);
})();
}
fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
return this.fetchOrders(symbol, since, limit, this.extend({ 'status': 'open' }, params));
}
fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
return this.fetchOrders(symbol, since, limit, this.extend({ 'status': 'closed' }, params));
}
handleErrors(code, reason, url, method, headers, body) {
let response = undefined;
if (code == 200 || code == 404 || code == 422) {
if (body[0] == '{' || body[0] == '[') {
response = JSON.parse(body);
} else {
// if not a JSON response
throw new ExchangeError(this.id + ' returned a non-JSON reply: ' + body);
}
}
if (code == 404) {
if ('message' in response) {
if (response['message'] == 'Order not found') {
throw new OrderNotFound(this.id + ' ' + body);
}
}
} else if (code == 422) {
if ('errors' in response) {
let errors = response['errors'];
if ('user' in errors) {
let messages = errors['user'];
if (messages.indexOf('not_enough_free_balance') >= 0) {
throw new InsufficientFunds(this.id + ' ' + body);
}
} else if ('quantity' in errors) {
let messages = errors['quantity'];
if (messages.indexOf('less_than_order_size') >= 0) {
throw new InvalidOrder(this.id + ' ' + body);
}
}
}
}
}
nonce() {
return this.milliseconds();
}
sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
let url = '/' + this.implodeParams(path, params);
let query = this.omit(params, this.extractParams(path));
headers = {
'X-Quoine-API-Version': this.version,
'Content-Type': 'application/json'
};
if (api == 'public') {
if ((0, _keys2.default)(query).length) url += '?' + this.urlencode(query);
} else {
this.checkRequiredCredentials();
if (method == 'GET') {
if ((0, _keys2.default)(query).length) url += '?' + this.urlencode(query);
} else if ((0, _keys2.default)(query).length) {
body = this.json(query);
}
let nonce = this.nonce();
let request = {
'path': url,
'nonce': nonce,
'token_id': this.apiKey,
'iat': Math.floor(nonce / 1000) // issued at
};
headers['X-Quoine-Auth'] = this.jwt(request, this.secret);
}
url = this.urls['api'] + url;
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
}
};