Example #1
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)
Example #2
0
 def handle_errors(self, code, reason, url, method, headers, body):
     if body.find('Invalid order') >= 0:
         raise InvalidOrder(self.id + ' ' + body)
     if body.find('Invalid nonce') >= 0:
         raise InvalidNonce(self.id + ' ' + body)
     if body.find('Insufficient funds') >= 0:
         raise InsufficientFunds(self.id + ' ' + body)
     if body.find('Cancel pending') >= 0:
         raise CancelPending(self.id + ' ' + body)
     if body.find('Invalid arguments:volume') >= 0:
         raise InvalidOrder(self.id + ' ' + body)
Example #3
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))
Example #4
0
 def handle_errors(self, code, reason, url, method, headers, body):
     response = None
     try:
         response = json.loads(body)
     except Exception as e:
         # syntax error, resort to default error handler
         return
     if 'error' in response:
         error = response['error']
         feedback = self.id + ' ' + self.json(response)
         if error == 'Invalid order number, or you are not the person who placed the order.':
             raise OrderNotFound(feedback)
         elif error == 'Internal error. Please try again.':
             raise ExchangeNotAvailable(feedback)
         elif error == 'Order not found, or you are not the person who placed it.':
             raise OrderNotFound(feedback)
         elif error == 'Invalid API key/secret pair.':
             raise AuthenticationError(feedback)
         elif error == 'Please do not make more than 8 API calls per second.':
             raise DDoSProtection(feedback)
         elif error.find('Total must be at least') >= 0:
             raise InvalidOrder(feedback)
         elif error.find('Not enough') >= 0:
             raise InsufficientFunds(feedback)
         elif error.find('Nonce must be greater') >= 0:
             raise InvalidNonce(feedback)
         elif error.find(
                 'You have already called cancelOrder or moveOrder on self order.'
         ) >= 0:
             raise CancelPending(feedback)
         else:
             raise ExchangeError(self.id + ': unknown error: ' +
                                 self.json(response))
Example #5
0
 def handle_errors(self, code, reason, url, method, headers, body):
     if code == 400:
         if body[0] == '{':
             response = json.loads(body)
             if 'error' in response:
                 if 'message' in response['error']:
                     message = response['error']['message']
                     if message == 'Order not found':
                         raise OrderNotFound(self.id + ' order not found in active orders')
                     elif message == 'Quantity not a valid number':
                         raise InvalidOrder(self.id + ' ' + body)
                     elif message == 'Insufficient funds':
                         raise InsufficientFunds(self.id + ' ' + body)
                     elif message == 'Duplicate clientOrderId':
                         raise InvalidOrder(self.id + ' ' + body)
         raise ExchangeError(self.id + ' ' + body)
Example #6
0
 async def create_order(self,
                        symbol,
                        type,
                        side,
                        amount,
                        price=None,
                        params={}):
     await self.load_markets()
     order = {
         'pair': self.market_id(symbol),
         'type': side,
         'amount': amount,
     }
     if type == 'limit':
         order['price'] = price
     else:
         # for market buy CEX.io requires the amount of quote currency to spend
         if side == 'buy':
             if not price:
                 raise InvalidOrder(
                     'For market buy orders ' + self.id +
                     " requires the amount of quote currency to spend, to calculate proper costs call createOrder(symbol, 'market', 'buy', amount, price)"
                 )
             order['amount'] = amount * price
         order['order_type'] = type
     response = await self.privatePostPlaceOrderPair(
         self.extend(order, params))
     return {
         'info': response,
         'id': response['id'],
     }
Example #7
0
 def handle_errors(self,
                   code,
                   reason,
                   url,
                   method,
                   headers,
                   body,
                   response=None):
     # {success: 0, error: "invalid order."}
     # or
     # [{data, ...}, {...}, ...]
     if response is None:
         if body[0] == '{' or body[0] == '[':
             response = json.loads(body)
     if isinstance(response, list):
         return  # public endpoints may return []-arrays
     if not ('success' in list(response.keys())):
         return  # no 'success' property on public responses
     if response['success'] == 1:
         # {success: 1, return: {orders: []}}
         if not ('return' in list(response.keys())):
             raise ExchangeError(self.id + ': malformed response: ' +
                                 self.json(response))
         else:
             return
     message = response['error']
     feedback = self.id + ' ' + self.json(response)
     if message == 'Insufficient balance.':
         raise InsufficientFunds(feedback)
     elif message == 'invalid order.':
         raise OrderNotFound(feedback)  # cancelOrder(1)
     elif message.find('Minimum price ') >= 0:
         raise InvalidOrder(
             feedback
         )  # price < limits.price.min, on createLimitBuyOrder('ETH/BTC', 1, 0)
     elif message.find('Minimum order ') >= 0:
         raise InvalidOrder(
             feedback
         )  # cost < limits.cost.min on createLimitBuyOrder('ETH/BTC', 0, 1)
     elif message == 'Invalid credentials. API not found or session has expired.':
         raise AuthenticationError(feedback)  # on bad apiKey
     elif message == 'Invalid credentials. Bad sign.':
         raise AuthenticationError(feedback)  # on bad secret
     raise ExchangeError(self.id + ': unknown error: ' +
                         self.json(response))
Example #8
0
 def handle_errors(self, code, reason, url, method, headers, body):
     if (code == 400) or (code == 404):
         if body[0] == '{':
             response = json.loads(body)
             message = response['message']
             error = self.id + ' ' + message
             if message.find('price too small') >= 0:
                 raise InvalidOrder(error)
             elif message.find('price too precise') >= 0:
                 raise InvalidOrder(error)
             elif message == 'Insufficient funds':
                 raise InsufficientFunds(error)
             elif message == 'NotFound':
                 raise OrderNotFound(error)
             elif message == 'Invalid API Key':
                 raise AuthenticationError(error)
             raise ExchangeError(self.id + ' ' + message)
         raise ExchangeError(self.id + ' ' + body)
Example #9
0
 def throw_exception_on_error(self, response):
     #
     # API endpoints return the following formats
     #     {success: False, code: "ERROR", msg: "Min price:100.0"}
     #     {success: True,  code: "OK",    msg: "Operation succeeded."}
     #
     # Web OHLCV endpoint returns self:
     #     {s: "ok", o: [], h: [], l: [], c: [], v: []}
     #
     # This particular method handles API responses only
     #
     if not ('success' in list(response.keys())):
         return
     if response['success'] is True:
         return  # not an error
     if not ('code' in list(response.keys())) or not ('msg' in list(
             response.keys())):
         raise ExchangeError(self.id + ': malformed response: ' +
                             self.json(response))
     code = self.safe_string(response, 'code')
     message = self.safe_string(response, 'msg')
     feedback = self.id + ' ' + self.json(response)
     if code == 'UNAUTH':
         if message == 'Invalid nonce':
             raise InvalidNonce(feedback)
         raise AuthenticationError(feedback)
     elif code == 'ERROR':
         if message.find('The precision of amount') >= 0:
             raise InvalidOrder(
                 feedback)  # amount violates precision.amount
         if message.find('Min amount each order') >= 0:
             raise InvalidOrder(feedback)  # amount < limits.amount.min
         if message.find('Min price:') >= 0:
             raise InvalidOrder(feedback)  # price < limits.price.min
         if message.find('The precision of price') >= 0:
             raise InvalidOrder(feedback)  # price violates precision.price
     elif code == 'NO_BALANCE':
         if message.find('Insufficient balance') >= 0:
             raise InsufficientFunds(feedback)
     raise ExchangeError(self.id + ': unknown response: ' +
                         self.json(response))
Example #10
0
 def create_order(self, symbol, type, side, amount, price=None, params={}):
     if type != 'limit':
         raise InvalidOrder(self.id + ' allows limit orders only')
     self.load_markets()
     order = {
         'price': self.price_to_precision(symbol, price),
         'amount': self.amount_to_string(symbol, amount),
         'tradeType': '1' if (side == 'buy') else '0',
         'currency': self.market_id(symbol),
     }
     response = self.privateGetOrder(self.extend(order, params))
     return {
         'info': response,
         'id': response['id'],
     }
Example #11
0
 async def create_order(self,
                        symbol,
                        type,
                        side,
                        amount,
                        price=None,
                        params={}):
     await self.load_markets()
     market = self.market(symbol)
     method = 'privatePost' + self.capitalize(side)
     response = await getattr(self, method)(
         self.extend(
             {
                 'market': market['id'],
                 # 'price': self.price_to_precision(symbol, price),
                 # 'amount': self.amount_to_precision(symbol, amount),
                 'price': price,
                 'amount': amount,
             },
             params))
     success = self.safe_integer(response, 'success')
     if success != 1:
         raise InvalidOrder(self.id + ' ' + self.json(response))
     parts = response['message'].split(' / ')
     parts = parts[1:]
     feeParts = parts[5].split(' ')
     order = self.parse_order(
         {
             'timestamp': self.milliseconds(),
             'order_number': response['order_number'],
             'type': parts[0].lower(),
             'market': parts[0].lower(),
             'amount': parts[2].split(' ')[1],
             'price': parts[3].split(' ')[1],
             'total': parts[4].split(' ')[1],
             'fee': {
                 'cost': float(feeParts[1]),
                 'currency': feeParts[2],
             },
             'progress': '0.0',
             'info': response,
         }, market)
     id = order['id']
     self.orders[id] = order
     return order
Example #12
0
 def cancel_order(self, id, symbol=None, params={}):
     if not symbol:
         raise ExchangeError(self.id + ' cancelOrder requires a symbol argument')
     self.load_markets()
     market = self.market(symbol)
     currencyPair = market['id']
     response = self.privatePostExchangeCancellimit(self.extend({
         'orderId': id,
         'currencyPair': currencyPair,
     }, params))
     message = self.safe_string(response, 'message', self.json(response))
     if 'success' in response:
         if not response['success']:
             raise InvalidOrder(message)
         elif 'cancelled' in response:
             if response['cancelled']:
                 return response
             else:
                 raise OrderNotFound(message)
     raise ExchangeError(self.id + ' cancelOrder() failed: ' + self.json(response))
Example #13
0
 def create_order(self, symbol, type, side, amount, price=None, params={}):
     self.load_markets()
     market = self.market(symbol)
     if price is None:
         raise InvalidOrder(
             self.id +
             ' createOrder requires a price argument for both market and limit orders'
         )
     request = {
         'pair': market['id'],
         'amount': self.amount_to_string(symbol, amount),
         'price': self.price_to_precision(symbol, price),
         'side': side,
         'type': type,
     }
     response = self.privatePostUserSpotOrder(self.extend(request, params))
     id = response['data']['order_id']
     order = self.parse_order(response['data'], market)
     self.orders[id] = order
     return order
Example #14
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:
             #
             # 1 - Liqui only returns the integer 'success' key from their private API
             #
             #     {"success": 1, ...} httpCode == 200
             #     {"success": 0, ...} httpCode == 200
             #
             # 2 - However, exchanges derived from Liqui, can return non-integers
             #
             #     It can be a numeric string
             #     {"sucesss": "1", ...}
             #     {"sucesss": "0", ...}, httpCode >= 200(can be 403, 502, etc)
             #
             #     Or just a string
             #     {"success": "true", ...}
             #     {"success": "false", ...}, httpCode >= 200
             #
             #     Or a boolean
             #     {"success": True, ...}
             #     {"success": False, ...}, httpCode >= 200
             #
             # 3 - Oversimplified, Python PEP8 forbids comparison operator(==) of different types
             #
             # 4 - We do not want to copy-paste and duplicate the code of self handler to other exchanges derived from Liqui
             #
             # To cover points 1, 2, 3 and 4 combined self handler should work like self:
             #
             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:
                 code = self.safe_string(response, 'code')
                 message = self.safe_string(response, 'error')
                 feedback = self.id + ' ' + self.json(response)
                 exceptions = self.exceptions
                 if code in exceptions:
                     raise exceptions[code](feedback)
                 # need a second error map for these messages, apparently...
                 # in fact, we can use the same .exceptions with string-keys to save some loc here
                 if message == 'invalid api key':
                     raise AuthenticationError(feedback)
                 elif message == 'api key dont have trade permission':
                     raise AuthenticationError(feedback)
                 elif message.find(
                         'invalid parameter'
                 ) >= 0:  # errorCode 0, returned on buy(symbol, 0, 0)
                     raise InvalidOrder(feedback)
                 elif message == 'invalid order':
                     raise InvalidOrder(feedback)
                 elif message == 'Requests too often':
                     raise DDoSProtection(feedback)
                 elif message == 'not available':
                     raise DDoSProtection(feedback)
                 elif message == 'data unavailable':
                     raise DDoSProtection(feedback)
                 elif message == 'external service unavailable':
                     raise DDoSProtection(feedback)
                 else:
                     raise ExchangeError(self.id +
                                         ' unknown "error" value: ' +
                                         self.json(response))