Exemplo n.º 1
0
 async def fetch_currencies(self, params={}):
     if not self.apiKey or not self.secret:
         raise AuthenticationError(self.id + " fetchCurrencies is an authenticated endpoint, therefore it requires 'apiKey' and 'secret' credentials. If you don't need currency details, set exchange.has['fetchCurrencies'] = False before calling its methods.")
     request = {
         'cmd': 'transfer/coinList',
         'body': {},
     }
     response = await self.privatePostTransfer(self.extend(request, params))
     #
     #     {
     #         "result":[
     #             {
     #                 "result":[
     #                     {
     #                         "totalBalance":"14.57582269",
     #                         "balance":"14.57582269",
     #                         "freeze":"0.00000000",
     #                         "id":60,
     #                         "symbol":"USDT",
     #                         "icon_url":"/appimg/USDT_icon.png",
     #                         "describe_url":"[{\"lang\":\"zh-cn\",\"link\":\"https://bibox.zendesk.com/hc/zh-cn/articles/115004798234\"},{\"lang\":\"en-ww\",\"link\":\"https://bibox.zendesk.com/hc/en-us/articles/115004798234\"}]",
     #                         "name":"USDT",
     #                         "enable_withdraw":1,
     #                         "enable_deposit":1,
     #                         "enable_transfer":1,
     #                         "confirm_count":2,
     #                         "is_erc20":1,
     #                         "forbid_info":null,
     #                         "describe_summary":"[{\"lang\":\"zh-cn\",\"text\":\"USDT 是 Tether 公司推出的基于稳定价值货币美元(USD)的代币 Tether USD(简称USDT),1USDT=1美元,用户可以随时使用 USDT 与 USD 进行1:1的兑换。\"},{\"lang\":\"en-ww\",\"text\":\"USDT is a cryptocurrency asset issued on the Bitcoin blockchain via the Omni Layer Protocol. Each USDT unit is backed by a U.S Dollar held in the reserves of the Tether Limited and can be redeemed through the Tether Platform.\"}]",
     #                         "total_amount":4776930644,
     #                         "supply_amount":4642367414,
     #                         "price":"--",
     #                         "contract_father":"OMNI",
     #                         "supply_time":"--",
     #                         "comment":null,
     #                         "contract":"31",
     #                         "original_decimals":8,
     #                         "deposit_type":0,
     #                         "hasCobo":0,
     #                         "BTCValue":"0.00126358",
     #                         "CNYValue":"100.93381445",
     #                         "USDValue":"14.57524654",
     #                         "children":[
     #                             {"type":"OMNI","symbol":"USDT","enable_deposit":1,"enable_withdraw":1,"confirm_count":2},
     #                             {"type":"TRC20","symbol":"tUSDT","enable_deposit":1,"enable_withdraw":1,"confirm_count":20},
     #                             {"type":"ERC20","symbol":"eUSDT","enable_deposit":1,"enable_withdraw":1,"confirm_count":25}
     #                         ]
     #                     },
     #                 ],
     #                 "cmd":"transfer/coinList"
     #             }
     #         ]
     #     }
     #
     currencies = self.safe_value(response, 'result')
     result = {}
     for i in range(0, len(currencies)):
         currency = currencies[i]
         id = self.safe_string(currency, 'symbol')
         name = currency['name']  # contains hieroglyphs causing python ASCII bug
         code = self.safe_currency_code(id)
         precision = 8
         deposit = self.safe_value(currency, 'enable_deposit')
         withdraw = self.safe_value(currency, 'enable_withdraw')
         active = (deposit and withdraw)
         result[code] = {
             'id': id,
             'code': code,
             'info': currency,
             'name': name,
             'active': active,
             'fee': None,
             'precision': precision,
             'limits': {
                 'amount': {
                     'min': math.pow(10, -precision),
                     'max': math.pow(10, precision),
                 },
                 'price': {
                     'min': math.pow(10, -precision),
                     'max': math.pow(10, precision),
                 },
                 'cost': {
                     'min': None,
                     'max': None,
                 },
                 'withdraw': {
                     'min': None,
                     'max': math.pow(10, precision),
                 },
             },
         }
     return result
Exemplo n.º 2
0
 def check_required_credentials(self):
     keys = list(self.requiredCredentials.keys())
     for key in keys:
         if self.requiredCredentials[key] and not getattr(self, key):
             raise AuthenticationError(self.id + ' requires `' + key + '`')
Exemplo n.º 3
0
Arquivo: liqui.py Projeto: jzajpt/ccxt
 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 == 'invalid sign':
                     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 ExchangeNotAvailable(feedback)
                 elif message == 'data unavailable':
                     raise ExchangeNotAvailable(feedback)
                 elif message == 'external service unavailable':
                     raise ExchangeNotAvailable(feedback)
                 else:
                     raise ExchangeError(self.id +
                                         ' unknown "error" value: ' +
                                         self.json(response))
Exemplo n.º 4
0
 async def create_order(self,
                        symbol,
                        type,
                        side,
                        amount,
                        price=None,
                        params={}):
     await self.load_markets()
     if not self.password:
         raise AuthenticationError(
             self.id +
             ' createOrder requires exchange.password to be set to user trading password(not login passwordnot )'
         )
     self.check_required_credentials()
     market = self.market(symbol)
     orderType = 1 if (type == 'limit') else 2
     order = {
         'symbol': market['id'],
         'side': side.upper(),
         'type': orderType,
         'volume': self.amount_to_precision(symbol, amount),
         'capital_password': self.password,
     }
     if (type == 'market') and (side == 'buy'):
         if price is None:
             raise InvalidOrder(
                 self.id +
                 ' createOrder requires price argument for market buy orders to calculate total cost according to exchange rules'
             )
         order['volume'] = self.amount_to_precision(
             symbol,
             float(amount) * float(price))
     if type == 'limit':
         order['price'] = self.price_to_precision(symbol, price)
     else:
         if price is None:
             order['price'] = self.price_to_precision(symbol, 0)
         else:
             order['price'] = self.price_to_precision(symbol, price)
     response = await self.privatePostOrder(self.extend(order, params))
     #
     #     {"order_id":34343}
     #
     timestamp = self.milliseconds()
     return {
         'info': response,
         'id': str(response['data']['order_id']),
         'timestamp': timestamp,
         'datetime': self.iso8601(timestamp),
         'lastTradeTimestamp': None,
         'status': None,
         'symbol': symbol,
         'type': type,
         'side': side,
         'price': price,
         'amount': amount,
         'filled': None,
         'remaining': None,
         'cost': None,
         'trades': None,
         'fee': None,
     }
Exemplo n.º 5
0
 def handle_errors(self,
                   code,
                   reason,
                   url,
                   method,
                   headers,
                   body,
                   response=None):
     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 == 'APIKEY_INVALID':
                 if self.options['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))
             if message == 'INVALID_ORDER':
                 # Bittrex will return an ambiguous INVALID_ORDER message
                 # upon canceling already-canceled and closed orders
                 # therefore self special case for cancelOrder
                 # url = 'https://bittrex.com/api/v1.1/market/cancel?apikey=API_KEY&uuid=ORDER_UUID'
                 cancel = 'cancel'
                 indexOfCancel = url.find(cancel)
                 if indexOfCancel >= 0:
                     parts = url.split('&')
                     orderId = None
                     for i in range(0, len(parts)):
                         part = parts[i]
                         keyValue = part.split('=')
                         if keyValue[0] == 'uuid':
                             orderId = keyValue[1]
                             break
                     if orderId is not None:
                         raise OrderNotFound(self.id + ' cancelOrder ' +
                                             orderId + ' ' +
                                             self.json(response))
                     else:
                         raise OrderNotFound(self.id + ' cancelOrder ' +
                                             self.json(response))
             if message in exceptions:
                 raise exceptions[message](feedback)
             if message is not None:
                 if message.find('throttled. Try again') >= 0:
                     raise DDoSProtection(feedback)
                 if message.find('problem') >= 0:
                     raise ExchangeNotAvailable(
                         feedback
                     )  # 'There was a problem processing your request.  If self problem persists, please contact...')
             raise ExchangeError(feedback)
Exemplo n.º 6
0
 def handle_errors(self,
                   httpCode,
                   reason,
                   url,
                   method,
                   headers,
                   body,
                   response=None):
     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 'code' in response:
             #
             #     {"code": "100005", "msg": "request sign illegal", "data": null}
             #
             code = self.safe_string(response, 'code')
             if code is not None:
                 message = self.safe_string(response, 'msg')
                 feedback = self.id + ' ' + self.json(response)
                 if code != '0':
                     exceptions = self.exceptions
                     if code in exceptions:
                         if code == '1':
                             #
                             #    {"code":"1","msg":"系统错误","data":null}
                             #    {“code”:“1",“msg”:“Balance insufficient,余额不足“,”data”:null}
                             #
                             if message.find('Balance insufficient') >= 0:
                                 raise InsufficientFunds(feedback)
                         elif code == '2':
                             if message == 'offsetNot Null':
                                 raise ExchangeError(feedback)
                             elif message == 'api_keyNot EXIST':
                                 raise AuthenticationError(feedback)
                             elif message == 'price precision exceed the limit':
                                 raise InvalidOrder(feedback)
                             elif message == 'Parameter error':
                                 raise BadRequest(feedback)
                         raise exceptions[code](feedback)
                     else:
                         raise ExchangeError(self.id +
                                             ' unknown "error" value: ' +
                                             self.json(response))
                 else:
                     #
                     # Google Translate:
                     # 订单状态不能取消,订单取消失败 = Order status cannot be canceled
                     # 根据订单号没有查询到订单,订单取消失败 = The order was not queried according to the order number
                     #
                     # {"code":"0","msg":"suc","data":{"success":[],"failed":[{"err-msg":"订单状态不能取消,订单取消失败","order-id":32857051,"err-code":"8"}]}}
                     # {"code":"0","msg":"suc","data":{"success":[],"failed":[{"err-msg":"Parameter error","order-id":32857050,"err-code":"2"},{"err-msg":"订单状态不能取消,订单取消失败","order-id":32857050,"err-code":"8"}]}}
                     # {"code":"0","msg":"suc","data":{"success":[],"failed":[{"err-msg":"Parameter error","order-id":98549677,"err-code":"2"},{"err-msg":"根据订单号没有查询到订单,订单取消失败","order-id":98549677,"err-code":"8"}]}}
                     #
                     if feedback.find('订单状态不能取消,订单取消失败') >= 0:
                         if feedback.find('Parameter error') >= 0:
                             raise OrderNotFound(feedback)
                         else:
                             raise InvalidOrder(feedback)
                     elif feedback.find('根据订单号没有查询到订单,订单取消失败') >= 0:
                         raise OrderNotFound(feedback)