UNPKG

ccxt-compiled

Version:

A JavaScript / Python / PHP cryptocurrency trading library with support for 90+ exchanges

402 lines (364 loc) 15 kB
"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 }; } };