コード例 #1
0
 def create_order(self, symbol, type, side, amount, price=None, params={}):
     self.load_markets()
     market = self.market(symbol)
     request = {
         'instrument': market['id'],
         'volume': self.amount_to_precision(symbol, amount),
         # The value must comply with the list of order types supported by the instrument(see the value of parameter supportedOrderTypes of the Instrument)
         # If the parameter is not specified, the default value "limit" is used
         # More about order types in the corresponding section of documentation
         'type':
         type,  # 'limit', 'market', 'stopLimit', in fact as of 2018-10-31, only 'limit' orders are supported for all markets
         'side': side,  # 'buy' or 'sell'
         # "GTC" - Good-Til-Cancelled
         # "IOC" - Immediate-Or-Cancel(currently not supported by the exchange API, reserved for future use)
         # "FOK" - Fill-Or-Kill(currently not supported by the exchange API, reserved for future use)
         # 'timeInForce': 'GTC',  # IOC', 'FOK'
         # 'strictValidation': False,  # False - prices will be rounded to meet the requirement, True - execution of the method will be aborted and an error message will be returned
     }
     priceIsRequired = False
     stopPriceIsRequired = False
     if type == 'limit':
         priceIsRequired = True
     elif type == 'stopLimit':
         priceIsRequired = True
         stopPriceIsRequired = True
     if priceIsRequired:
         if price is None:
             raise InvalidOrder(
                 self.id +
                 ' createOrder method requires a price argument for a ' +
                 type + ' order')
         request['price'] = self.price_to_precision(symbol, price)
     if stopPriceIsRequired:
         stopPrice = self.safe_float(params, 'stopPrice')
         if stopPrice is None:
             raise InvalidOrder(
                 self.id +
                 ' createOrder method requires a stopPrice extra param for a '
                 + type + ' order')
         else:
             request['stopPrice'] = self.price_to_precision(
                 symbol, stopPrice)
     response = self.tradingPostPlaceOrder(self.extend(request, params))
     #
     #     {
     #         "id": 469594855,
     #         "timestamp": "2018-06-08T16:59:44Z",
     #         "instrument": "BTS-BTC",
     #         "side": "buy",
     #         "type": "limit",
     #         "status": "submitting",
     #         "cancellationReason": null,
     #         "timeInForce": "GTC",
     #         "volume": 4.0,
     #         "price": 0.000025,
     #         "stopPrice": null,
     #         "remainingVolume": 4.0,
     #         "lastUpdate": null,
     #         "parentOrderId": null,
     #         "childOrderId": null
     #     }
     #
     return self.parse_order(response, market)
コード例 #2
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))
コード例 #3
0
ファイル: cointiger.py プロジェクト: w31w31/ccxt
 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,
     }
コード例 #4
0
 async def create_order(self,
                        symbol,
                        type,
                        side,
                        amount,
                        price=None,
                        params={}):
     # for market buy it requires the amount of quote currency to spend
     if (type == 'market') and (side == 'buy'):
         if self.options['createMarketBuyOrderRequiresPrice']:
             if price is None:
                 raise InvalidOrder(
                     self.id +
                     " createOrder() requires the price argument with market buy orders to calculate total order cost(amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = False to supply the cost in the amount argument(the exchange-specific behaviour)"
                 )
             else:
                 amount = amount * price
     await self.load_markets()
     request = {
         'pair': self.market_id(symbol),
         'type': side,
         'amount': amount,
     }
     if type == 'limit':
         request['price'] = price
     else:
         request['order_type'] = type
     response = await self.privatePostPlaceOrderPair(
         self.extend(request, params))
     #
     #     {
     #         "id": "12978363524",
     #         "time": 1586610022259,
     #         "type": "buy",
     #         "price": "0.033934",
     #         "amount": "0.10722802",
     #         "pending": "0.10722802",
     #         "complete": False
     #     }
     #
     placedAmount = self.safe_float(response, 'amount')
     remaining = self.safe_float(response, 'pending')
     timestamp = self.safe_value(response, 'time')
     complete = self.safe_value(response, 'complete')
     status = 'closed' if complete else 'open'
     filled = None
     if (placedAmount is not None) and (remaining is not None):
         filled = max(placedAmount - remaining, 0)
     return {
         'id': self.safe_string(response, 'id'),
         'info': response,
         'clientOrderId': None,
         'timestamp': timestamp,
         'datetime': self.iso8601(timestamp),
         'lastTradeTimestamp': None,
         'type': type,
         'side': self.safe_string(response, 'type'),
         'symbol': symbol,
         'status': status,
         'price': self.safe_float(response, 'price'),
         'amount': placedAmount,
         'cost': None,
         'average': None,
         'remaining': remaining,
         'filled': filled,
         'fee': None,
         'trades': None,
     }
コード例 #5
0
ファイル: novadax.py プロジェクト: PolozovT/ccxt
 async def create_order(self,
                        symbol,
                        type,
                        side,
                        amount,
                        price=None,
                        params={}):
     await self.load_markets()
     market = self.market(symbol)
     uppercaseType = type.upper()
     uppercaseSide = side.upper()
     request = {
         'symbol': market['id'],
         'type': uppercaseType,  # LIMIT, MARKET
         'side': uppercaseSide,  # or SELL
         # 'amount': self.amount_to_precision(symbol, amount),
         # "price": "1234.5678",  # required for LIMIT and STOP orders
         # 'operator': ''  # for stop orders, can be found in order introduction
         # 'stopPrice': self.price_to_precision(symbol, stopPrice),
         # 'accountId': '...',  # subaccount id, optional
     }
     stopPrice = self.safe_number(params, 'stopPrice')
     if stopPrice is None:
         if (uppercaseType == 'STOP_LIMIT') or (uppercaseType
                                                == 'STOP_MARKET'):
             raise ArgumentsRequired(
                 self.id +
                 ' createOrder() requires a stopPrice parameter for ' +
                 uppercaseType + ' orders')
     else:
         if uppercaseType == 'LIMIT':
             uppercaseType = 'STOP_LIMIT'
         elif uppercaseType == 'MARKET':
             uppercaseType = 'STOP_MARKET'
         operatorString = self.safe_string(params, 'operator')
         if operatorString is None:
             raise ArgumentsRequired(
                 self.id +
                 " createOrder() requires an operator parameter 'GTE' or 'LTE' for "
                 + uppercaseType + ' orders')
         request['operator'] = operatorString
         request['stopPrice'] = self.price_to_precision(symbol, stopPrice)
         params = self.omit(params, 'stopPrice')
     if (uppercaseType == 'LIMIT') or (uppercaseType == 'STOP_LIMIT'):
         request['price'] = self.price_to_precision(symbol, price)
         request['amount'] = self.amount_to_precision(symbol, amount)
     elif (uppercaseType == 'MARKET') or (uppercaseType == 'STOP_MARKET'):
         if uppercaseSide == 'SELL':
             request['amount'] = self.amount_to_precision(symbol, amount)
         elif uppercaseSide == 'BUY':
             value = self.safe_number(params, 'value')
             createMarketBuyOrderRequiresPrice = self.safe_value(
                 self.options, 'createMarketBuyOrderRequiresPrice', True)
             if createMarketBuyOrderRequiresPrice:
                 if price is not None:
                     if value is None:
                         value = amount * price
                 elif value is None:
                     raise InvalidOrder(
                         self.id +
                         " createOrder() requires the price argument with market buy orders to calculate total order cost(amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = False and supply the total cost value in the 'amount' argument or in the 'value' extra parameter(the exchange-specific behaviour)"
                     )
             else:
                 value = amount if (value is None) else value
             precision = market['precision']['price']
             request['value'] = self.decimal_to_precision(
                 value, TRUNCATE, precision, self.precisionMode)
     response = await self.privatePostOrdersCreate(
         self.extend(request, params))
     #
     #     {
     #         "code": "A10000",
     #         "data": {
     #             "amount": "0.001",
     #             "averagePrice": null,
     #             "filledAmount": "0",
     #             "filledFee": "0",
     #             "filledValue": "0",
     #             "id": "870613508008464384",
     #             "operator": "GTE",
     #             "price": "210000",
     #             "side": "BUY",
     #             "status": "SUBMITTED",
     #             "stopPrice": "211000",
     #             "symbol": "BTC_BRL",
     #             "timestamp": 1627612035528,
     #             "type": "STOP_LIMIT",
     #             "value": "210"
     #         },
     #         "message": "Success"
     #     }
     #
     data = self.safe_value(response, 'data', {})
     return self.parse_order(data, market)
コード例 #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)
コード例 #7
0
 async def create_order(self,
                        symbol,
                        type,
                        side,
                        amount,
                        price=None,
                        params={}):
     await self.load_markets()
     #
     # obsolete since v2
     # https://github.com/ccxt/ccxt/issues/4815
     #
     #     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,  # obsolete since v2, https://github.com/ccxt/ccxt/issues/4815
     }
     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.v2PostOrder(self.extend(order, params))
     #
     #     {
     #         "code": "0",
     #         "msg": "suc",
     #         "data": {
     #             "order_id": 481
     #         }
     #     }
     #
     timestamp = self.milliseconds()
     return {
         'info': response,
         'id': self.safe_string(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,
     }
コード例 #8
0
 async def create_order(self,
                        symbol,
                        type,
                        side,
                        amount,
                        price=None,
                        params={}):
     if type == 'market':
         # for market buy it requires the amount of quote currency to spend
         if side == 'buy':
             if self.options['createMarketBuyOrderRequiresPrice']:
                 if price is None:
                     raise InvalidOrder(
                         self.id +
                         " createOrder() requires the price argument with market buy orders to calculate total order cost(amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = False to supply the cost in the amount argument(the exchange-specific behaviour)"
                     )
                 else:
                     amount = amount * price
     await self.load_markets()
     market = self.market(symbol)
     orderType = '1' if (type == 'limit') else '2'
     orderSide = side.upper()
     amountToPrecision = self.amount_to_precision(symbol, amount)
     request = {
         'side': orderSide,
         'type': orderType,
         'symbol': market['id'],
         'volume': amountToPrecision,
         # An excerpt from their docs:
         # side required Trading Direction
         # type required pending order types,1:Limit-price Delegation 2:Market- price Delegation
         # volume required
         #     Purchase Quantity(polysemy,multiplex field)
         #     type=1: Quantity of buying and selling
         #     type=2: Buying represents gross price, and selling represents total number
         #     Trading restriction user/me-user information
         # price optional Delegation Price:type=2:self parameter is no use.
         # fee_is_user_exchange_coin optional
         #     0,when making transactions with all platform currencies,
         #     self parameter represents whether to use them to pay
         #     fees or not and 0 is no, 1 is yes.
     }
     priceToPrecision = None
     if type == 'limit':
         priceToPrecision = self.price_to_precision(symbol, price)
         request['price'] = priceToPrecision
     response = await self.privatePostCreateOrder(
         self.extend(request, params))
     #
     #     {code: '0',
     #        msg: 'suc',
     #       data: {'order_id' : 34343} }
     #
     result = self.parse_order(response['data'], market)
     return self.extend(
         result, {
             'info': response,
             'symbol': symbol,
             'type': type,
             'side': side,
             'status': 'open',
             'price': float(priceToPrecision),
             'amount': float(amountToPrecision),
         })
コード例 #9
0
 async def create_order(self,
                        symbol,
                        type,
                        side,
                        amount,
                        price=None,
                        params={}):
     await self.load_markets()
     market = self.market(symbol)
     uppercaseType = type.upper()
     uppercaseSide = side.upper()
     request = {
         'symbol': market['id'],
         'type': uppercaseType,  # LIMIT, MARKET
         'side': uppercaseSide,  # or SELL
         # 'accountId': '...',  # subaccount id, optional
         # 'amount': self.amount_to_precision(symbol, amount),
         # "price": "1234.5678",  # required for LIMIT and STOP orders
     }
     if uppercaseType == 'LIMIT':
         request['price'] = self.price_to_precision(symbol, price)
         request['amount'] = self.amount_to_precision(symbol, amount)
     elif uppercaseType == 'MARKET':
         if uppercaseSide == 'SELL':
             request['amount'] = self.amount_to_precision(symbol, amount)
         elif uppercaseSide == 'BUY':
             value = self.safe_float(params, 'value')
             createMarketBuyOrderRequiresPrice = self.safe_value(
                 self.options, 'createMarketBuyOrderRequiresPrice', True)
             if createMarketBuyOrderRequiresPrice:
                 if price is not None:
                     if value is None:
                         value = amount * price
                 elif value is None:
                     raise InvalidOrder(
                         self.id +
                         " createOrder() requires the price argument with market buy orders to calculate total order cost(amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = False and supply the total cost value in the 'amount' argument or in the 'value' extra parameter(the exchange-specific behaviour)"
                     )
             else:
                 value = amount if (value is None) else value
             precision = market['precision']['price']
             request['value'] = self.decimal_to_precision(
                 value, TRUNCATE, precision, self.precisionMode)
     response = await self.privatePostOrdersCreate(
         self.extend(request, params))
     #
     #     {
     #         "code": "A10000",
     #         "data": {
     #             "amount": "0.001",
     #             "averagePrice": null,
     #             "filledAmount": "0",
     #             "filledFee": "0",
     #             "filledValue": "0",
     #             "id": "633679992971251712",
     #             "price": "35000",
     #             "side": "BUY",
     #             "status": "PROCESSING",
     #             "symbol": "BTC_BRL",
     #             "timestamp": 1571122683535,
     #             "type": "LIMIT",
     #             "value": "35"
     #         },
     #         "message": "Success"
     #     }
     #
     data = self.safe_value(response, 'data', {})
     return self.parse_order(data, market)
コード例 #10
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 ' +
                 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:
                 message = self.safe_string(response, 'msg')
                 parsedMessage = None
                 if message is not None:
                     try:
                         parsedMessage = json.loads(message)
                     except Exception as e:
                         # do nothing
                         parsedMessage = None
                     if parsedMessage is not None:
                         response = parsedMessage
             # checks against error codes
             error = self.safe_string(response, 'code')
             if error is not None:
                 exceptions = self.exceptions
                 if error in exceptions:
                     # a workaround for {"code":-2015,"msg":"Invalid API-key, IP, or permissions for action."}
                     # despite that their message is very confusing, it is raised by Binance
                     # on a temporary ban(the API key is valid, but disabled for a while)
                     if (error == '-2015') and self.options[
                             'hasAlreadyAuthenticatedSuccessfully']:
                         raise DDoSProtection(self.id +
                                              ' temporary banned: ' + body)
                     message = self.safe_string(response, 'msg')
                     if message == 'Order would trigger immediately.':
                         raise InvalidOrder(self.id + ' ' + body)
                     elif message == 'Account has insufficient balance for requested action.':
                         raise InsufficientFunds(self.id + ' ' + body)
                     elif message == 'Rest API trading is not enabled.':
                         raise ExchangeNotAvailable(self.id + ' ' + body)
                     raise exceptions[error](self.id + ' ' + body)
                 else:
                     raise ExchangeError(self.id + ' ' + body)
             if not success:
                 raise ExchangeError(self.id + ' ' + body)
コード例 #11
0
 async def create_order(self,
                        symbol,
                        type,
                        side,
                        amount,
                        price=None,
                        params={}):
     await self.load_markets()
     market = self.market(symbol)
     # the next 5 lines are added to support for testing orders
     method = 'privatePostOrder'
     test = self.safe_value(params, 'test', False)
     if test:
         method += 'Test'
         params = self.omit(params, 'test')
     uppercaseType = type.upper()
     order = {
         'symbol': market['id'],
         'quantity': self.amount_to_precision(symbol, amount),
         'type': uppercaseType,
         'side': side.upper(),
         'newOrderRespType': self.options[
             'newOrderRespType'],  # 'ACK' for order id, 'RESULT' for full order or 'FULL' for order with fills
     }
     timeInForceIsRequired = False
     priceIsRequired = False
     stopPriceIsRequired = False
     if uppercaseType == 'LIMIT':
         priceIsRequired = True
         timeInForceIsRequired = True
     elif (uppercaseType == 'STOP_LOSS') or (uppercaseType
                                             == 'TAKE_PROFIT'):
         stopPriceIsRequired = True
     elif (uppercaseType == 'STOP_LOSS_LIMIT') or (uppercaseType
                                                   == 'TAKE_PROFIT_LIMIT'):
         stopPriceIsRequired = True
         priceIsRequired = True
         timeInForceIsRequired = True
     elif uppercaseType == 'LIMIT_MAKER':
         priceIsRequired = True
     if priceIsRequired:
         if price is None:
             raise InvalidOrder(
                 self.id +
                 ' createOrder method requires a price argument for a ' +
                 type + ' order')
         order['price'] = self.price_to_precision(symbol, price)
     if timeInForceIsRequired:
         order['timeInForce'] = self.options[
             'defaultTimeInForce']  # 'GTC' = Good To Cancel(default), 'IOC' = Immediate Or Cancel
     if stopPriceIsRequired:
         stopPrice = self.safe_float(params, 'stopPrice')
         if stopPrice is None:
             raise InvalidOrder(
                 self.id +
                 ' createOrder method requires a stopPrice extra param for a '
                 + type + ' order')
         else:
             order['stopPrice'] = self.price_to_precision(symbol, stopPrice)
     response = await getattr(self, method)(self.extend(order, params))
     return self.parse_order(response, market)
コード例 #12
0
ファイル: ftx.py プロジェクト: yezune/ccxt
 async def create_order(self, symbol, type, side, amount, price=None, params={}):
     await self.load_markets()
     market = self.market(symbol)
     request = {
         'market': market['id'],
         'side': side,  # "buy" or "sell"
         # 'price': 0.306525,  # send null for market orders
         'type': type,  # "limit", "market", "stop", "trailingStop", or "takeProfit"
         'size': float(self.amount_to_precision(symbol, amount)),
         # 'reduceOnly': False,  # optional, default is False
         # 'ioc': False,  # optional, default is False, limit or market orders only
         # 'postOnly': False,  # optional, default is False, limit or market orders only
         # 'clientId': 'abcdef0123456789',  # string, optional, client order id, limit or market orders only
     }
     priceToPrecision = None
     if price is not None:
         priceToPrecision = float(self.price_to_precision(symbol, price))
     method = 'privatePostConditionalOrders'
     if type == 'limit':
         method = 'privatePostOrders'
         request['price'] = priceToPrecision
     elif type == 'market':
         method = 'privatePostOrders'
         request['price'] = None
     elif (type == 'stop') or (type == 'takeProfit'):
         request['triggerPrice'] = priceToPrecision
         # request['orderPrice'] = number  # optional, order type is limit if self is specified, otherwise market
     elif type == 'trailingStop':
         request['trailValue'] = priceToPrecision  # negative for "sell", positive for "buy"
     else:
         raise InvalidOrder(self.id + ' createOrder() does not support order type ' + type + ', only limit, market, stop, trailingStop, or takeProfit orders are supported')
     response = await getattr(self, method)(self.extend(request, params))
     #
     # orders
     #
     #     {
     #         "success": True,
     #         "result": [
     #             {
     #                 "createdAt": "2019-03-05T09:56:55.728933+00:00",
     #                 "filledSize": 0,
     #                 "future": "XRP-PERP",
     #                 "id": 9596912,
     #                 "market": "XRP-PERP",
     #                 "price": 0.306525,
     #                 "remainingSize": 31431,
     #                 "side": "sell",
     #                 "size": 31431,
     #                 "status": "open",
     #                 "type": "limit",
     #                 "reduceOnly": False,
     #                 "ioc": False,
     #                 "postOnly": False,
     #                 "clientId": null,
     #             }
     #         ]
     #     }
     #
     # conditional orders
     #
     #     {
     #         "success": True,
     #         "result": [
     #             {
     #                 "createdAt": "2019-03-05T09:56:55.728933+00:00",
     #                 "future": "XRP-PERP",
     #                 "id": 9596912,
     #                 "market": "XRP-PERP",
     #                 "triggerPrice": 0.306525,
     #                 "orderId": null,
     #                 "side": "sell",
     #                 "size": 31431,
     #                 "status": "open",
     #                 "type": "stop",
     #                 "orderPrice": null,
     #                 "error": null,
     #                 "triggeredAt": null,
     #                 "reduceOnly": False
     #             }
     #         ]
     #     }
     #
     #
     result = self.safe_value(response, 'result', [])
     return self.parse_order(result, market)
コード例 #13
0
 async def create_order(self,
                        symbol,
                        type,
                        side,
                        amount,
                        price=None,
                        params={}):
     await self.load_markets()
     market = self.market(symbol)
     type = type.upper()
     if type == 'STOP_LIMIT':
         type = 'STOP-LIMIT'
     request = {
         # == Required ==
         # orderType : string  # can be MARKET,LIMIT,STOP,STOP-LIMIT
         # symbol : string
         # orderQty : string  # Buying or selling quantity
         # side : string  # BUY or SELL
         # == Required according to ordeType ==
         # price : string  # limit price in limit and stop-limit orders
         # stopPrice : string  # Trigger price for stop-limit order and stop order
         # == Optional ==
         # clOrdID : string
         # timeInForce :string  # GTC/IOC/FOK,default is GTC
         'orderType': type,
         'symbol': market['id'],
         'orderQty': self.amount_to_precision(symbol, amount),
         'side': side.upper(),
     }
     if (type == 'LIMIT') or (type == 'STOP-LIMIT'):
         if price is None:
             raise InvalidOrder(
                 self.id + ' createOrder method requires a price for a ' +
                 type + ' order')
         request['price'] = self.price_to_precision(symbol, price)
     if (type == 'STOP') or (type == 'STOP-LIMIT'):
         stopPrice = self.safe_float(params, 'stopPrice')
         if stopPrice is None:
             raise InvalidOrder(
                 self.id +
                 ' createOrder method requires a stopPrice extra param for a '
                 + type + ' order')
         request['stopPrice'] = self.price_to_precision(symbol, stopPrice)
     response = await self.privatePostV2SpotOrders(
         self.extend(request, params))
     # Response
     # {
     #     "code":1,
     #     "data":{
     #        "avgPrice":"0",
     #        "base":"BTC",
     #        "clOrdID":"aax",
     #        "commission":"0",
     #        "createTime":null,
     #        "cumQty":"0",
     #        "id":null,
     #        "isTriggered":null,
     #        "lastPrice":"0",
     #        "lastQty":"0",
     #        "leavesQty":"0",
     #        "orderID":"wJ4L366KB",
     #        "orderQty":"0.02",
     #        "orderStatus":0,
     #        "orderType":2,
     #        "price":"8000",
     #        "quote":"USDT",
     #        "rejectCode":null,
     #        "rejectReason":null,
     #        "side":1,
     #        "stopPrice":null,
     #        "symbol":"BTCUSDT",
     #        "transactTime":null,
     #        "updateTime":null,
     #        "timeInForce":1,
     #        "userID":"216214"
     #     },
     #     "message":"success",
     #     "ts":1573530401264
     #  }
     data = self.safe_value(response, 'data')
     order = await self.fetch_order(data['orderID'])
     if order['status'] == 'rejected':
         info = self.safe_value(order, 'info')
         raise InvalidOrder(' order was rejected by the exchange ' +
                            self.safe_value(info, 'rejectReason'))
     return order
コード例 #14
0
ファイル: youngplatform.py プロジェクト: YoungAgency/ccxt
 async def create_order(self, symbol, type, side, amount, price=None, params={}):
     await self.load_markets()
     market = self.market(symbol)
     exchangeType = type.upper()
     exchangeSide = side.upper()
     baseId = market['id'].split('_')[1]
     quoteId = market['id'].split('_')[0]
     request = {
         'market': quoteId,
         'trade': baseId,
         'side': exchangeSide,
         'type': exchangeType,  # MARKET, LIMIT, STOPLIMIT
         'volume': self.amount_to_precision(symbol, amount),
     }
     if exchangeType == 'LIMIT':
         if price is None:
             raise InvalidOrder(self.id + ' createOrder method requires a price argument for a ' + type + ' order')
         request['rate'] = self.price_to_precision(symbol, price)
         timeInForce = self.safe_string(params, 'timeInForce')
         if timeInForce is not None:
             if timeInForce != 'GTC' and timeInForce != 'IOC' and timeInForce != 'FOK':
                 request['timeInForce'] = timeInForce
     if exchangeType == 'STOPLIMIT':
         stopPrice = self.safe_float(params, 'stopPrice')
         if price is None:
             raise InvalidOrder(self.id + ' createOrder method requires a price argument for a ' + type + ' order')
         if stopPrice is None:
             raise InvalidOrder(self.id + ' createOrder method requires a stop argument for a ' + type + ' order')
         request['rate'] = self.price_to_precision(symbol, price)
         request['stop'] = self.price_to_precision(symbol, stopPrice)
     if exchangeType == 'STOPMARKET':
         stopPrice = self.safe_float(params, 'stopPrice')
         if stopPrice is None:
             raise InvalidOrder(self.id + ' createOrder method requires a stop argument for a ' + type + ' order')
         request['stop'] = self.price_to_precision(symbol, stopPrice)
         request['timeInForce'] = 'GTC'
     if exchangeType == 'MARKET':
         if price is not None:
             raise InvalidOrder(self.id + ' createOrder method does not support price argument for a ' + type + ' order')
     response = await self.privatePostPlaceOrder(request)
     #
     #     {
     #         status: 'Success',
     #         data: {
     #             "orderId": 214083724
     #         }
     #    }
     #
     timestamp = self.seconds()
     result = self.safe_value(response, 'data')
     id = self.safe_integer(result, 'orderId')
     order = {
         'id': id,
         'info': response,
         'timestamp': timestamp,
         'datetime': self.iso8601(timestamp),
         'symbol': symbol,
         'type': type,
         'side': side,
         'price': price,
         'amount': amount,
         'cost': None,
         'average': None,
         'filled': None,
         'remaining': None,
         'status': None,
         'fee': None,
         'trades': None,
     }
     return order
コード例 #15
0
ファイル: probit.py プロジェクト: zsyh/ccxt
 async def create_order(self, symbol, type, side, amount, price=None, params={}):
     await self.load_markets()
     market = self.market(symbol)
     options = self.safe_value(self.options, 'timeInForce')
     defaultTimeInForce = self.safe_value(options, type)
     timeInForce = self.safe_string_2(params, 'timeInForce', 'time_in_force', defaultTimeInForce)
     request = {
         'market_id': market['id'],
         'type': type,
         'side': side,
         'time_in_force': timeInForce,
     }
     clientOrderId = self.safe_string_2(params, 'clientOrderId', 'client_order_id')
     if clientOrderId is not None:
         request['client_order_id'] = clientOrderId
     costToPrecision = None
     if type == 'limit':
         request['limit_price'] = self.price_to_precision(symbol, price)
         request['quantity'] = self.amount_to_precision(symbol, amount)
     elif type == 'market':
         # for market buy it requires the amount of quote currency to spend
         if side == 'buy':
             cost = self.safe_number(params, 'cost')
             createMarketBuyOrderRequiresPrice = self.safe_value(self.options, 'createMarketBuyOrderRequiresPrice', True)
             if createMarketBuyOrderRequiresPrice:
                 if price is not None:
                     if cost is None:
                         cost = amount * price
                 elif cost is None:
                     raise InvalidOrder(self.id + " createOrder() requires the price argument for market buy orders to calculate total order cost(amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = False and supply the total cost value in the 'amount' argument or in the 'cost' extra parameter(the exchange-specific behaviour)")
             else:
                 cost = amount if (cost is None) else cost
             costToPrecision = self.cost_to_precision(symbol, cost)
             request['cost'] = costToPrecision
         else:
             request['quantity'] = self.amount_to_precision(symbol, amount)
     query = self.omit(params, ['timeInForce', 'time_in_force', 'clientOrderId', 'client_order_id'])
     response = await self.privatePostNewOrder(self.extend(request, query))
     #
     #     {
     #         data: {
     #             id: string,
     #             user_id: string,
     #             market_id: string,
     #             type: 'orderType',
     #             side: 'side',
     #             quantity: string,
     #             limit_price: string,
     #             time_in_force: 'timeInForce',
     #             filled_cost: string,
     #             filled_quantity: string,
     #             open_quantity: string,
     #             cancelled_quantity: string,
     #             status: 'orderStatus',
     #             time: 'date',
     #             client_order_id: string,
     #         }
     #     }
     #
     data = self.safe_value(response, 'data')
     order = self.parse_order(data, market)
     # a workaround for incorrect huge amounts
     # returned by the exchange on market buys
     if (type == 'market') and (side == 'buy'):
         order['amount'] = None
         order['cost'] = self.parse_number(costToPrecision)
         order['remaining'] = None
     return order
コード例 #16
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)
コード例 #17
0
ファイル: eterbase.py プロジェクト: zhuhgit/ccxt
 def create_order(self, symbol, type, side, amount, price=None, params={}):
     self.load_markets()
     market = self.market(symbol)
     uppercaseType = type.upper()
     if uppercaseType == 'MARKET':
         type = 1
     elif uppercaseType == 'LIMIT':
         type = 2
     elif uppercaseType == 'STOPMARKET':
         type = 3
     elif uppercaseType == 'STOPLIMIT':
         type = 4
     uppercaseSide = side.upper()
     side = uppercaseSide == 1 if 'BUY' else 2
     request = {
         'accountId': self.uid,
         'marketId': market['id'],
         'type': type,
         'side': side,
         # 'postOnly': False,
         # 'timeInForce': 'GTC',
     }
     clientOrderId = self.safe_value_2(params, 'refId', 'clientOrderId')
     query = params
     if clientOrderId is not None:
         request['refId'] = clientOrderId
         query = self.omit(params, ['refId', 'clientOrderId'])
     if (uppercaseType == 'MARKET') and (uppercaseSide == 'BUY'):
         # for market buy it requires the amount of quote currency to spend
         cost = self.safe_number(params, 'cost')
         if self.options['createMarketBuyOrderRequiresPrice']:
             if cost is None:
                 if price is not None:
                     cost = amount * price
                 else:
                     raise InvalidOrder(
                         self.id +
                         " createOrder() requires the price argument with market buy orders to calculate total order cost(amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = False to supply the cost in the amount argument(the exchange-specific behaviour)"
                     )
         else:
             cost = amount if (cost is None) else cost
         precision = market['precision']['price']
         request['cost'] = self.decimal_to_precision(
             cost, TRUNCATE, precision, self.precisionMode)
     else:
         request['qty'] = self.amount_to_precision(symbol, amount)
     if uppercaseType == 'LIMIT':
         request['limitPrice'] = self.price_to_precision(symbol, price)
     response = self.privatePostOrders(self.extend(request, query))
     #
     # market buy
     #
     #     {
     #         "id":"ff81127c-8fd5-4846-b683-110639dcd322",
     #         "accountId":"6d445378-d8a3-4932-91cd-545d0a4ad2a2",
     #         "marketId":33,
     #         "type":1,
     #         "side":1,
     #         "cost":"25",
     #         "postOnly":false,
     #         "timeInForce":"GTC",
     #         "state":1,
     #         "placedAt":1589510846735
     #     }
     #
     # market sell, limit buy, limit sell
     #
     #     {
     #         "id":"042a38b0-e369-4ad2-ae73-a18ff6b1dcf1",
     #         "accountId":"6d445378-d8a3-4932-91cd-545d0a4ad2a2",
     #         "marketId":33,
     #         "type":2,
     #         "side":1,
     #         "qty":"1000",
     #         "limitPrice":"100",
     #         "postOnly":false,
     #         "timeInForce":"GTC",
     #         "state":1,
     #         "placedAt":1589403938682,
     #     }
     #
     return self.parse_order(response, market)
コード例 #18
0
ファイル: exchange_account.py プロジェクト: fodrh1201/btrccts
    def create_order(self, market, type, price, side, amount):
        self._update_orders()
        type_market = False
        type_limit = False
        if type == 'market':
            if price is not None:
                raise InvalidOrder(
                    'ExchangeAccount: market order has no price')
            type_market = True
        elif type == 'limit':
            price = _convert_float_or_raise(price, 'ExchangeAccount: price')
            type_limit = True
            if price <= 0:
                raise BadRequest('ExchangeAccount: price needs to be positive')
        else:
            raise InvalidOrder(
                'ExchangeAccount: only market and limit order supported')
        if market is None:
            raise InvalidOrder('ExchangeAccount: market is None')
        symbol = market.get('symbol')
        ohlcv = self._ohlcvs.get(symbol)
        if ohlcv is None:
            raise InvalidOrder('ExchangeAccount: no prices available for {}'
                               .format(symbol))
        if side not in ['buy', 'sell']:
            raise InvalidOrder('ExchangeAccount: side {} not supported'
                               .format(side))
        buy = side == 'buy'
        amount = _convert_float_or_raise(amount, 'ExchangeAccount: amount')
        if amount <= 0:
            raise BadRequest('ExchangeAccount: amount needs to be positive')
        base = market.get('base')
        quote = market.get('quote')
        if base is None:
            raise BadRequest('ExchangeAccount: market has no base')
        if quote is None:
            raise BadRequest('ExchangeAccount: market has no quote')

        self._last_order_id += 1
        order_id = str(self._last_order_id)
        date = self._timeframe.date()
        timestamp = int(date.value / 10e5)
        order = {
            'info': {},
            'id': order_id,
            'timestamp': timestamp,
            'datetime': Exchange.iso8601(timestamp),
            'lastTradeTimestamp': None,
            'symbol': symbol,
            'type': type,
            'side': side,
            'price': None,
            'amount': amount,
            'cost': None,
            'average': None,
            'filled': 0,
            'remaining': amount,
            'status': 'open',
            'fee': {'currency': base if buy else quote,
                    'cost': None,
                    'rate': None},
            'trades': None,
        }

        if type_market:
            # Determinie the price of the market order
            # We could use the next low/high to fill the order, but then we
            # need to wait for the next date to fill the order, otherwise we
            # would introduce a possibility to see the future price
            # (Look-Ahead Bias)
            # If we wait for the next date, we would return a market order that
            # is pending, but this should never happen in reality
            # Maybe the factor should depend on the volume
            factor = Decimal('0.0015')
            if buy:
                price = (1 + factor) * _convert_float(ohlcv['high'][date])
            else:
                price = (1 - factor) * _convert_float(ohlcv['low'][date])
            fee_percentage = market.get('taker', 0)
            fee_percentage = _convert_float_or_raise(fee_percentage,
                                                     'ExchangeAccount: fee')
            self._update_balance(price, amount, base, quote, buy,
                                 fee_percentage)
            self._fill_order(order, buy, price, timestamp, fee_percentage)
            self._closed_orders[order_id] = order
        if type_limit:
            # TODO Probably use taker fee, if the order can be filled now
            fee_percentage = market.get('maker', 0)
            fee_percentage = _convert_float_or_raise(fee_percentage,
                                                     'ExchangeAccount: fee')
            if buy:
                self._balances[quote].change_used(price * amount)
            else:
                self._balances[base].change_used(amount)
            self._open_orders[order_id] = order
            self._private_order_info[order_id] = {
                'id': order_id,
                'base': base,
                'quote': quote,
                'price': price,
                'buy': buy,
                'fee_percentage': fee_percentage,
                'fillable_date': self._limit_order_fillable_date(
                    symbol, buy, price),
            }
            self._update_next_private_order_to_update()

        return {'id': order_id,
                'info': {}}