Пример #1
0
 def fetch_ticker(self, symbol, params={}):
     self.load_markets()
     market = self.market(symbol)
     method = 'publicGet'
     request = {
         'symbol': market['id'],
     }
     if market['future']:
         method += 'Future'
         if not params.get('contract_type'):
             raise ExchangeError(
                 self.id +
                 ' futureTicker requires a contract_type parameter in params'
             )
         request['contract_type'] = params.get('contract_type')
     method += 'Ticker'
     response = getattr(self, method)(self.extend(request, params))
     ticker = self.safe_value(response, 'ticker')
     if ticker is None:
         raise ExchangeError(self.id +
                             ' fetchTicker returned an empty response: ' +
                             self.json(response))
     timestamp = self.safe_integer(response, 'date')
     if timestamp is not None:
         timestamp *= 1000
         ticker = self.extend(ticker, {'timestamp': timestamp})
     return self.parse_ticker(ticker, market)
Пример #2
0
 def handle_errors(self, code, reason, url, method, headers, body):
     if body[0] == '{':
         response = json.loads(body)
         # {success: False, message: "message"}
         success = self.safe_value(response, 'success')
         if success is None:
             raise ExchangeError(self.id + ': malformed response: ' +
                                 self.json(response))
         if isinstance(success, basestring):
             # bleutrade uses string instead of boolean
             success = True if (success == 'true') else False
         if not success:
             message = self.safe_string(response, 'message')
             feedback = self.id + ' ' + self.json(response)
             exceptions = self.exceptions
             if message in exceptions:
                 raise exceptions[message](feedback)
             if message == 'APIKEY_INVALID':
                 if self.hasAlreadyAuthenticatedSuccessfully:
                     raise DDoSProtection(feedback)
                 else:
                     raise AuthenticationError(feedback)
             if message == 'DUST_TRADE_DISALLOWED_MIN_VALUE_50K_SAT':
                 raise InvalidOrder(
                     self.id + ' order cost should be over 50k satoshi ' +
                     self.json(response))
             raise ExchangeError(self.id + ' ' + self.json(response))
Пример #3
0
 def handle_errors(self, httpCode, reason, url, method, headers, body):
     if not isinstance(body, basestring):
         return  # fallback to default error handler
     if len(body) < 2:
         return  # fallback to default error handler
     if (body[0] == '{') or (body[0] == '['):
         response = json.loads(body)
         if 'success' in response:
             #
             #     {"success":false,"error":{"code":104,"message":"Cannot perform request - nonce must be higher than 1520307203724237"}}
             #
             success = self.safe_value(response, 'success', False)
             if isinstance(success, basestring):
                 if (success == 'true') or (success == '1'):
                     success = True
                 else:
                     success = False
             if not success:
                 feedback = self.id + ' ' + self.json(response)
                 error = self.safe_value(response, 'error')
                 if error is None:
                     raise ExchangeError(feedback)
                 code = self.safe_string(error, 'code')
                 exceptions = self.exceptions
                 if code in exceptions:
                     raise exceptions[code](feedback)
                 else:
                     raise ExchangeError(feedback)
Пример #4
0
 async def request(self,
                   path,
                   api='public',
                   method='GET',
                   params={},
                   headers=None,
                   body=None):
     response = await self.fetch2(path, api, method, params, headers, body)
     if not isinstance(response, basestring):
         if 'error' in response:
             numErrors = len(response['error'])
             if numErrors:
                 message = self.id + ' ' + self.json(response)
                 for i in range(0, len(response['error'])):
                     if response['error'][
                             i] == 'EFunding:Unknown withdraw key':
                         raise ExchangeError(message)
                     if response['error'][i] == 'EService:Unavailable':
                         raise ExchangeNotAvailable(message)
                     if response['error'][i] == 'EDatabase:Internal error':
                         raise ExchangeNotAvailable(message)
                     if response['error'][i] == 'EService:Busy':
                         raise DDoSProtection(message)
                 raise ExchangeError(message)
     return response
Пример #5
0
 async def create_order(self,
                        symbol,
                        type,
                        side,
                        amount,
                        price=None,
                        params={}):
     if type == 'market':
         raise ExchangeError(self.id + ' allows limit orders only')
     walletIdInParams = ('walletId' in list(params.keys()))
     if not walletIdInParams:
         raise ExchangeError(self.id +
                             ' createOrder requires a walletId parameter')
     amount = str(amount)
     price = str(price)
     market = self.market(symbol)
     order = {
         'side': side,
         'type': type,
         'currency': market['base'],
         'amount': amount,
         'display': amount,
         'price': price,
         'instrument': market['id'],
     }
     response = await self.privatePostTradeAdd(self.extend(order, params))
     return {
         'info': response,
         'id': response['id'],
     }
Пример #6
0
 async def fetch_order(self, id, symbol=None, params={}):
     if symbol is None:
         raise ExchangeError(self.id +
                             ' fetchOrder requires a symbol argument')
     orderType = self.safe_value(params, 'type')
     if orderType is None:
         raise ExchangeError(
             self.id +
             ' fetchOrder requires a type parameter("BUY" or "SELL")')
     await self.load_markets()
     market = self.market(symbol)
     request = {
         'symbol': market['id'],
         'type': orderType,
         'orderOid': id,
     }
     response = await self.privateGetOrderDetail(
         self.extend(request, params))
     if not response['data']:
         raise OrderNotFound(self.id + ' ' + self.json(response))
     #
     # the caching part to be removed
     #
     #     order = self.parse_order(response['data'], market)
     #     orderId = order['id']
     #     if orderId in self.orders:
     #         order['status'] = self.orders[orderId]['status']
     #     self.orders[orderId] = order
     #
     return self.parse_order(response['data'], market)
Пример #7
0
 def handle_errors(self, code, reason, url, method, headers, body):
     if (code == 418) or (code == 429):
         raise DDoSProtection(self.id + ' ' + str(code) + ' ' + reason + ' ' + body)
     # error response in a form: {"code": -1013, "msg": "Invalid quantity."}
     # following block cointains legacy checks against message patterns in "msg" property
     # will switch "code" checks eventually, when we know all of them
     if code >= 400:
         if body.find('Price * QTY is zero or less') >= 0:
             raise InvalidOrder(self.id + ' order cost = amount * price is zero or less ' + body)
         if body.find('LOT_SIZE') >= 0:
             raise InvalidOrder(self.id + ' order amount should be evenly divisible by lot size, use self.amount_to_lots(symbol, amount) ' + body)
         if body.find('PRICE_FILTER') >= 0:
             raise InvalidOrder(self.id + ' order price exceeds allowed price precision or invalid, use self.price_to_precision(symbol, amount) ' + body)
     if len(body) > 0:
         if body[0] == '{':
             response = json.loads(body)
             # check success value for wapi endpoints
             # response in format {'msg': 'The coin does not exist.', 'success': True/false}
             success = self.safe_value(response, 'success', True)
             if not success:
                 if 'msg' in response:
                     try:
                         response = json.loads(response['msg'])
                     except Exception as e:
                         response = {}
             # checks against error codes
             error = self.safe_string(response, 'code')
             if error is not None:
                 exceptions = self.exceptions
                 if error in exceptions:
                     raise exceptions[error](self.id + ' ' + body)
                 else:
                     raise ExchangeError(self.id + ': unknown error code: ' + body + ' ' + error)
             if not success:
                 raise ExchangeError(self.id + ': success value False: ' + body)
Пример #8
0
 def fetch_order(self, id, symbol=None, params={}):
     if not symbol:
         raise ExchangeError(self.id +
                             ' fetchOrder requires a symbol parameter')
     self.load_markets()
     market = self.market(symbol)
     method = 'privatePost'
     request = {
         'order_id': id,
         'symbol': market['id'],
         # 'status': 0,  # 0 for unfilled orders, 1 for filled orders
         # 'current_page': 1,  # current page number
         # 'page_length': 200,  # number of orders returned per page, maximum 200
     }
     if market['future']:
         method += 'Future'
         if not params.get('contract_type'):
             raise ExchangeError(
                 self.id +
                 ' futureOrderInfo requires a contract_type parameter in params'
             )
         request['contract_type'] = params.get('contract_type')
     method += 'OrderInfo'
     response = getattr(self, method)(self.extend(request, params))
     ordersField = self.get_orders_field()
     numOrders = len(response[ordersField])
     if numOrders > 0:
         return self.parse_order(response[ordersField][0])
     raise OrderNotFound(self.id + ' order ' + id + ' not found')
Пример #9
0
 def withdraw(self, code, amount, address, tag=None, params={}):
     self.check_address(address)
     self.load_markets()
     currency = self.currency(code)
     if self.password is None:
         if not ('trade_pwd' in list(params.keys())):
             raise ExchangeError(
                 self.id +
                 ' withdraw() requires self.password set on the exchange instance or a trade_pwd parameter'
             )
     if not ('totp_code' in list(params.keys())):
         raise ExchangeError(
             self.id +
             ' withdraw() requires a totp_code parameter for 2FA authentication'
         )
     body = {
         'trade_pwd': self.password,
         'coin_symbol': currency['id'],
         'amount': amount,
         'addr': address,
     }
     if tag is not None:
         body['address_remark'] = tag
     response = self.privatePostTransfer({
         'cmd': 'transfer/transferOut',
         'body': self.extend(body, params),
     })
     return {
         'info': response,
         'id': None,
     }
Пример #10
0
 async def withdraw(self, currency, amount, address, tag=None, params={}):
     self.check_address(address)
     await self.load_markets()
     request = {
         'coin': currency,
         'quantity': '{:.10f}'.format(amount),
         'address': address,
     }
     if currency == 'BRL':
         account_ref = ('account_ref' in list(params.keys()))
         if not account_ref:
             raise ExchangeError(
                 self.id + ' requires account_ref parameter to withdraw ' +
                 currency)
     elif currency != 'LTC':
         tx_fee = ('tx_fee' in list(params.keys()))
         if not tx_fee:
             raise ExchangeError(self.id +
                                 ' requires tx_fee parameter to withdraw ' +
                                 currency)
     response = await self.privatePostWithdrawCoin(
         self.extend(request, params))
     return {
         'info': response,
         'id': response['response_data']['withdrawal']['id'],
     }
Пример #11
0
 def handle_errors(self, code, reason, url, method, headers, body):
     if code < 400 or code >= 600:
         return
     if body[0] != '{':
         raise ExchangeError(self.id + ' ' + body)
     response = json.loads(body)
     message = self.safe_value(response['error'], 'error_code')
     raise ExchangeError(self.id + ' ' + message)
Пример #12
0
 def fetch_orders(self, symbol=None, since=None, limit=None, params={}):
     if not symbol:
         raise ExchangeError(self.id +
                             ' fetchOrders requires a symbol parameter')
     self.load_markets()
     market = self.market(symbol)
     method = 'privatePost'
     request = {
         'symbol': market['id'],
     }
     order_id_in_params = ('order_id' in list(params.keys()))
     if market['future']:
         method += 'FutureOrdersInfo'
         if not params.get('contract_type'):
             raise ExchangeError(
                 self.id +
                 ' futureOrdersInfo requires a contract_type parameter in params'
             )
         request['contract_type'] = params.get('contract_type')
         if not order_id_in_params:
             raise ExchangeError(
                 self.id +
                 ' fetchOrders() requires order_id param for futures market '
                 + symbol +
                 '(a string of one or more order ids, comma-separated)')
     else:
         status = None
         if 'type' in params:
             status = params['type']
         elif 'status' in params:
             status = params['status']
         else:
             name = 'type' if order_id_in_params else 'status'
             raise ExchangeError(
                 self.id + ' fetchOrders() requires ' + name +
                 ' param for spot market ' + symbol +
                 '(0 - for unfilled orders, 1 - for filled/canceled orders)'
             )
         if order_id_in_params:
             method += 'OrdersInfo'
             request = self.extend(request, {
                 'type': status,
                 'order_id': params['order_id'],
             })
         else:
             method += 'OrderHistory'
             request = self.extend(
                 request,
                 {
                     'status': status,
                     'current_page': 1,  # current page number
                     'page_length':
                     200,  # number of orders returned per page, maximum 200
                 })
         params = self.omit(params, ['type', 'status'])
     response = getattr(self, method)(self.extend(request, params))
     ordersField = self.get_orders_field()
     return self.parse_orders(response[ordersField], market, since, limit)
Пример #13
0
 async def request(self, path, api='public', method='GET', params={}, headers=None, body=None):
     response = await self.fetch2(path, api, method, params, headers, body)
     if api == 'private':
         if 'code' in response:
             raise ExchangeError(self.id + ' ' + self.json(response))
     if 'result' in response:
         if not response['result']:
             raise ExchangeError(self.id + ' ' + self.json(response))
     return response
Пример #14
0
 def create_order(self, symbol, type, side, amount, price=None, params={}):
     if type == 'market':
         raise ExchangeError(self.id + ' allows limit orders only')
     self.load_markets()
     market = self.market(symbol)
     # price = float(price)
     # amount = float(amount)
     request = {
         'TradePairId': market['id'],
         'Type': self.capitalize(side),
         # 'Rate': self.price_to_precision(symbol, price),
         # 'Amount': self.amount_to_precision(symbol, amount),
         'Rate': price,
         'Amount': amount,
     }
     response = self.privatePostSubmitTrade(self.extend(request, params))
     if not response:
         raise ExchangeError(self.id +
                             ' createOrder returned unknown error: ' +
                             self.json(response))
     id = None
     filled = 0.0
     if 'Data' in response:
         if 'OrderId' in response['Data']:
             if response['Data']['OrderId']:
                 id = str(response['Data']['OrderId'])
         if 'FilledOrders' in response['Data']:
             filledOrders = response['Data']['FilledOrders']
             filledOrdersLength = len(filledOrders)
             if filledOrdersLength:
                 filled = None
     timestamp = self.milliseconds()
     order = {
         'id': id,
         'timestamp': timestamp,
         'datetime': self.iso8601(timestamp),
         'lastTradeTimestamp': None,
         'status': 'open',
         'symbol': symbol,
         'type': type,
         'side': side,
         'price': price,
         'cost': price * amount,
         'amount': amount,
         'remaining': amount,
         'filled': filled,
         'fee': None,
         # 'trades': self.parse_trades(order['trades'], market),
     }
     if id:
         self.orders[id] = order
     return self.extend({'info': response}, order)
Пример #15
0
 def cancel_order(self, id, symbol=None, params={}):
     side = ('side' in list(params.keys()))
     if not side:
         raise ExchangeError(self.id + ' cancelOrder requires a side parameter(sell or buy) and a currency parameter')
     side = 'purchase' if (side == 'buy') else 'sales'
     currency = ('currency' in list(params.keys()))
     if not currency:
         raise ExchangeError(self.id + ' cancelOrder requires a currency parameter')
     return self.privatePostTradeCancel({
         'order_id': id,
         'type': params['side'],
         'currency': params['currency'],
     })
Пример #16
0
 async def request(self,
                   path,
                   api='trade',
                   method='GET',
                   params={},
                   headers=None,
                   body=None):
     response = await self.fetch2(path, api, method, params, headers, body)
     if 'status' in response:
         if response['status'] == 'error':
             raise ExchangeError(self.id + ' ' + self.json(response))
     if 'code' in response:
         raise ExchangeError(self.id + ' ' + self.json(response))
     return response
Пример #17
0
 def request(self,
             path,
             api='api',
             method='GET',
             params={},
             headers=None,
             body=None):
     response = self.fetch2(path, api, method, params, headers, body)
     if 'error' in response:
         raise ExchangeError(self.id + ' ' + response['error'])
     if 'success' in response:
         if not response['success']:
             raise ExchangeError(self.id + ' ' + self.json(response))
     return response
Пример #18
0
 def fetch_order_book(self, symbol, limit=None, params={}):
     self.load_markets()
     market = self.market(symbol)
     response = self.marketGetDepth(self.extend({
         'symbol': market['id'],
         'type': 'step0',
     }, params))
     if 'tick' in response:
         if not response['tick']:
             raise ExchangeError(self.id + ' fetchOrderBook() returned empty response: ' + self.json(response))
         orderbook = response['tick']
         timestamp = orderbook['ts']
         orderbook['nonce'] = orderbook['version']
         return self.parse_order_book(orderbook, timestamp)
     raise ExchangeError(self.id + ' fetchOrderBook() returned unrecognized response: ' + self.json(response))
Пример #19
0
 def create_order(self, symbol, type, side, amount, price=None, params={}):
     if type != 'limit':
         raise ExchangeError(self.id + ' ' + self.version + ' accepts limit orders only')
     if symbol != 'BTC/USD':
         raise ExchangeError(self.id + ' v1 supports BTC/USD orders only')
     method = 'privatePost' + self.capitalize(side)
     order = {
         'amount': amount,
         'price': price,
     }
     response = getattr(self, method)(self.extend(order, params))
     return {
         'info': response,
         'id': response['id'],
     }
Пример #20
0
 def handle_errors(self, code, reason, url, method, headers, body):
     if code == 200:
         if (body[0] == '{') or (body[0] == '['):
             response = json.loads(body)
             if 'result' in response:
                 result = response['result']
                 if 'errorCode' in result:
                     errorCode = result['errorCode']
                     if errorCode != 'OK':
                         raise ExchangeError(self.id + ' error returned: ' + body)
             else:
                 raise ExchangeError(self.id + ' malformed response: no result in response: ' + body)
         else:
             # if not a JSON response
             raise ExchangeError(self.id + ' returned a non-JSON reply: ' + body)
Пример #21
0
 def request(self, path, api='public', method='GET', params={}, headers=None, body=None):
     response = self.fetch2(path, api, method, params, headers, body)
     if not response:
         raise ExchangeError(self.id + ' returned ' + self.json(response))
     elif response is True:
         return response
     elif 'e' in response:
         if 'ok' in response:
             if response['ok'] == 'ok':
                 return response
         raise ExchangeError(self.id + ' ' + self.json(response))
     elif 'error' in response:
         if response['error']:
             raise ExchangeError(self.id + ' ' + self.json(response))
     return response
Пример #22
0
 def request(self,
             path,
             api='public',
             method='GET',
             params={},
             headers=None,
             body=None):
     response = self.fetch2(path, api, method, params, headers, body)
     if 'warning' in response:
         if response['warning']:
             raise ExchangeError(self.id + ' ' + self.json(response))
     if 'error' in response:
         if response['error']:
             raise ExchangeError(self.id + ' ' + self.json(response))
     return response
Пример #23
0
 def handle_errors(self, code, reason, url, method, headers, body):
     if code == 200:
         if (body[0] == '{') or (body[0] == '['):
             response = json.loads(body)
             if 'success' in response:
                 success = response['success']
                 if not success:
                     raise ExchangeError(self.id + ' error returned: ' + body)
                 if not('message' in list(response.keys())):
                     raise ExchangeError(self.id + ' malformed response: no "message" in response: ' + body)
             else:
                 raise ExchangeError(self.id + ' malformed response: no "success" in response: ' + body)
         else:
             # if not a JSON response
             raise ExchangeError(self.id + ' returned a non-JSON reply: ' + body)
Пример #24
0
 def handle_errors(self, code, reason, url, method, headers, body):
     if not isinstance(body, basestring):
         return
     if body[0] == '{':
         response = json.loads(body)
         if code >= 300:
             errorCode = self.safe_string(response, 'errorCode')
             if errorCode in self.exceptions:
                 ExceptionClass = self.exceptions[errorCode]
                 raise ExceptionClass(self.id + ' ' + body)
             else:
                 raise ExchangeError(self.id + ' ' + body)
         # returns status code 200 even if success == False
         success = self.safe_value(response, 'success', True)
         if not success:
             raise ExchangeError(self.id + ' ' + body)
Пример #25
0
 def fetch_ticker(self, symbol, params={}):
     if symbol != 'BTC/USD':
         raise ExchangeError(self.id + ' ' + self.version + " fetchTicker doesn't support " + symbol + ', use it for BTC/USD only')
     ticker = self.publicGetTicker(params)
     timestamp = int(ticker['timestamp']) * 1000
     vwap = float(ticker['vwap'])
     baseVolume = float(ticker['volume'])
     quoteVolume = baseVolume * vwap
     last = float(ticker['last'])
     return {
         'symbol': symbol,
         'timestamp': timestamp,
         'datetime': self.iso8601(timestamp),
         'high': float(ticker['high']),
         'low': float(ticker['low']),
         'bid': float(ticker['bid']),
         'bidVolume': None,
         'ask': float(ticker['ask']),
         'askVolume': None,
         'vwap': vwap,
         'open': float(ticker['open']),
         'close': last,
         'last': last,
         'previousClose': None,
         'change': None,
         'percentage': None,
         'average': None,
         'baseVolume': baseVolume,
         'quoteVolume': quoteVolume,
         'info': ticker,
     }
Пример #26
0
 def sign(self,
          path,
          api='public',
          method='GET',
          params={},
          headers=None,
          body=None):
     if self.id == 'cryptocapital':
         raise ExchangeError(self.id +
                             ' is an abstract base API for _1btcxe')
     url = self.urls['api'] + '/' + path
     if api == 'public':
         if params:
             url += '?' + self.urlencode(params)
     else:
         self.check_required_credentials()
         query = self.extend(
             {
                 'api_key': self.apiKey,
                 'nonce': self.nonce(),
             }, params)
         request = self.json(query)
         query['signature'] = self.hmac(self.encode(request),
                                        self.encode(self.secret))
         body = self.json(query)
         headers = {'Content-Type': 'application/json'}
     return {'url': url, 'method': method, 'body': body, 'headers': headers}
Пример #27
0
 def sign(self,
          path,
          api='public',
          method='GET',
          params={},
          headers=None,
          body=None):
     if self.id == 'btctrader':
         raise ExchangeError(
             self.id + ' is an abstract base API for BTCExchange, BTCTurk')
     url = self.urls['api'] + '/' + path
     if api == 'public':
         if params:
             url += '?' + self.urlencode(params)
     else:
         self.check_required_credentials()
         nonce = str(self.nonce())
         body = self.urlencode(params)
         secret = base64.b64decode(self.secret)
         auth = self.apiKey + nonce
         headers = {
             'X-PCK':
             self.apiKey,
             'X-Stamp':
             nonce,
             'X-Signature':
             base64.b64encode(
                 self.hmac(self.encode(auth), secret, hashlib.sha256,
                           'binary')),
             'Content-Type':
             'application/x-www-form-urlencoded',
         }
     return {'url': url, 'method': method, 'body': body, 'headers': headers}
Пример #28
0
 async def create_order(self,
                        symbol,
                        type,
                        side,
                        amount,
                        price=None,
                        params={}):
     await self.load_markets()
     order = {
         'PairSymbol': self.market_id(symbol),
         'OrderType': 0 if (side == 'buy') else 1,
         'OrderMethod': 1 if (type == 'market') else 0,
     }
     if type == 'market':
         if not ('Total' in list(params.keys())):
             raise ExchangeError(
                 self.id +
                 ' createOrder requires the "Total" extra parameter for market orders(amount and price are both ignored)'
             )
     else:
         order['Price'] = price
         order['Amount'] = amount
     response = await self.privatePostExchange(self.extend(order, params))
     return {
         'info': response,
         'id': response['id'],
     }
Пример #29
0
 def fetch_closed_orders(self,
                         symbol=None,
                         since=None,
                         limit=200,
                         params={}):
     if symbol is None:
         raise ExchangeError(
             self.id + ' fetchClosedOrders requires a symbol argument')
     self.load_markets()
     market = self.market(symbol)
     response = self.privatePostOrderpending({
         'cmd':
         'orderpending/pendingHistoryList',
         'body':
         self.extend(
             {
                 'pair': market['id'],
                 'account_type': 0,  # 0 - regular, 1 - margin
                 'page': 1,
                 'size': limit,
             },
             params),
     })
     orders = self.safe_value(response['result'], 'items', [])
     return self.parse_orders(orders, market, since, limit)
Пример #30
0
 async def deposit(self, currency, amount, address, params={}):
     await self.load_markets()
     request = {
         'currency': currency,
         'amount': amount,
     }
     method = 'privatePostDeposits'
     if 'payment_method_id' in params:
         # deposit from a payment_method, like a bank account
         method += 'PaymentMethod'
     elif 'coinbase_account_id' in params:
         # deposit into GDAX account from a Coinbase account
         method += 'CoinbaseAccount'
     else:
         # deposit methodotherwise we did not receive a supported deposit location
         # relevant docs link for the Googlers
         # https://docs.gdax.com/#deposits
         raise NotSupported(
             self.id +
             ' deposit() requires one of `coinbase_account_id` or `payment_method_id` extra params'
         )
     response = await getattr(self, method)(self.extend(request, params))
     if not response:
         raise ExchangeError(self.id + ' deposit() error: ' +
                             self.json(response))
     return {
         'info': response,
         'id': response['id'],
     }