text: # -*- coding: utf-8 -*-
  
  # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
  # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
  
  from ccxt.async_support.base.exchange import Exchange
  
  # -----------------------------------------------------------------------------
  
  try:
      basestring  # Python 3
  except NameError:
      basestring = str  # Python 2
  from ccxt.base.errors import ExchangeError
  from ccxt.base.errors import AuthenticationError
  from ccxt.base.errors import PermissionDenied
  from ccxt.base.errors import ArgumentsRequired
  from ccxt.base.errors import BadRequest
  from ccxt.base.errors import BadSymbol
  from ccxt.base.errors import InsufficientFunds
  from ccxt.base.errors import InvalidOrder
  from ccxt.base.errors import OrderNotFound
  from ccxt.base.errors import CancelPending
  from ccxt.base.errors import RateLimitExceeded
  from ccxt.base.errors import ExchangeNotAvailable
  from ccxt.base.decimal_to_precision import TICK_SIZE
  from ccxt.base.precise import Precise
  
  
  class aax(Exchange):
  
      def describe(self):
          return self.deep_extend(super(aax, self).describe(), {
              'id': 'aax',
              'name': 'AAX',
              'countries': ['MT'],  # Malta
              'enableRateLimit': True,
              'rateLimit': 500,
              'version': 'v2',
              'hostname': 'aaxpro.com',  # aax.com
              'certified': True,
              'pro': True,
              'has': {
                  'cancelAllOrders': True,
                  'cancelOrder': True,
                  'createOrder': True,
                  'editOrder': True,
                  'fetchBalance': True,
                  'fetchCanceledOrders': True,
                  'fetchClosedOrders': True,
                  'fetchCurrencies': True,
                  'fetchDepositAddress': True,
                  'fetchMarkets': True,
                  'fetchMyTrades': True,
                  'fetchOHLCV': True,
                  'fetchOpenOrders': True,
                  'fetchOrder': True,
                  'fetchOrderBook': True,
                  'fetchOrders': True,
                  'fetchStatus': True,
                  'fetchTicker': 'emulated',
                  'fetchTickers': True,
                  'fetchTrades': True,
              },
              'timeframes': {
                  '1m': '1m',
                  '5m': '5m',
                  '15m': '15m',
                  '30m': '30m',
                  '1h': '1h',
                  '2h': '2h',
                  '4h': '4h',
                  '12h': '12h',
                  '1d': '1d',
                  '3d': '3d',
                  '1w': '1w',
              },
              'urls': {
                  'logo': 'https://user-images.githubusercontent.com/1294454/104140087-a27f2580-53c0-11eb-87c1-5d9e81208fe9.jpg',
                  'test': {
                      'v1': 'https://api.testnet.{hostname}/marketdata/v1',
                      'public': 'https://api.testnet.{hostname}',
                      'private': 'https://api.testnet.{hostname}',
                  },
                  'api': {
                      'v1': 'https://api.{hostname}/marketdata/v1',
                      'public': 'https://api.{hostname}',
                      'private': 'https://api.{hostname}',
                  },
                  'www': 'https://www.aaxpro.com',  # string website URL
                  'doc': 'https://www.aaxpro.com/apidoc/index.html',
                  'fees': 'https://www.aaxpro.com/en-US/fees/',
                  'referral': 'https://www.aaxpro.com/invite/sign-up?inviteCode=JXGm5Fy7R2MB',
              },
              'api': {
                  'v1': {
                      'get': [
                          'getHistMarketData',  # Get OHLC k line of specific market
                      ],
                  },
                  'public': {
                      # these endpoints are not documented
                      # 'get': [
                      #     'order_book',  # Get the order book of specified market
                      #     'order_book/{market}',
                      #     'trades',  # Get recent trades on market, each trade is included only once Trades are sorted in reverse creation order.
                      #     'trades/{market}',
                      #     'tickers',  # Get ticker of all markets
                      #     'tickers/{market}',  # Get ticker of specific market
                      # ],
                      'get': [
                          'currencies',
                          'announcement/maintenance',  # System Maintenance Notice
                          'instruments',  # Retrieve all trading pairs information
                          'market/orderbook',  # Order Book
                          'futures/position/openInterest',  # Open Interest
                          'market/tickers',  # Get the Last 24h Market Summary
                          'market/candles',  # Get Current Candlestick
                          'market/history/candles',  # Get Current Candlestick
                          'market/trades',  # Get the Most Recent Trades
                          'market/markPrice',  # Get Current Mark Price
                          'futures/funding/predictedFunding/{symbol}',  # Get Predicted Funding Rate
                          'futures/funding/prevFundingRate/{symbol}',  # Get Last Funding Rate
                          'market/candles/index',  # Get Current Index Candlestick
                      ],
                  },
                  'private': {
                      'get': [
                          'user/info',  # Retrieve user information
                          'account/balances',  # Get Account Balances
                          'account/deposit/address',  # undocumented
                          'spot/trades',  # Retrieve trades details for a spot order
                          'spot/openOrders',  # Retrieve spot open orders
                          'spot/orders',  # Retrieve historical spot orders
                          'futures/position',  # Get positions for all contracts
                          'futures/position/closed',  # Get closed positions
                          'futures/trades',  # Retrieve trade details for a futures order
                          'futures/openOrders',  # Retrieve futures open orders
                          'futures/orders',  # Retrieve historical futures orders
                          'futures/funding/predictedFundingFee/{symbol}',  # Get predicted funding fee
                      ],
                      'post': [
                          'account/transfer',  # Asset Transfer
                          'spot/orders',  # Create a new spot order
                          'spot/orders/cancelAllOnTimeout',  # Automatically cancel all your spot orders after a specified timeout.
                          'futures/orders',  # Create a new futures order
                          'futures/orders/cancelAllOnTimeout',  # Automatically cancel all your futures orders after a specified timeout.
                          'futures/position/sltp',  # Set take profit and stop loss orders for an opening position
                          'futures/position/close',  # Close position
                          'futures/position/leverage',  # Update leverage for position
                          'futures/position/margin',  # Modify Isolated Position Margin
                      ],
                      'put': [
                          'spot/orders',  # Amend spot order
                          'futures/orders',  # Amend the quantity of an open futures order
                      ],
                      'delete': [
                          'spot/orders/cancel/{orderID}',  # Cancel a spot order
                          'spot/orders/cancel/all',  # Batch cancel spot orders
                          'futures/orders/cancel/{orderID}',  # Cancel a futures order
                          'futures/orders/cancel/all',  # Batch cancel futures orders
                      ],
                  },
              },
              'fees': {
                  'trading': {
                      'tierBased': False,
                      'percentage': True,
                      'maker': self.parse_number('0.0006'),
                      'taker': self.parse_number('0.001'),
                  },
                  'funding': {
                      'tierBased': False,
                      'percentage': True,
                      'withdraw': {},  # There is only 1% fee on withdrawals to your bank account.
                  },
              },
              'commonCurrencies': {
                  'XBT': 'XBT',
              },
              'exceptions': {
                  'exact': {
                      '2002': InsufficientFunds,
                      '2003': OrderNotFound,
                      '10003': BadRequest,  # Parameter validation error
                      '10006': AuthenticationError,  # Session expired, please relogin
                      '10007': AuthenticationError,  # Invalid authentication key or token
                      '11007': AuthenticationError,  # Invalid key format
                      '20001': InsufficientFunds,  # Insufficient balance. Please deposit to trade.
                      '20009': InvalidOrder,  # Order amount must be positive
                      '30000': OrderNotFound,  # {"code":30000,"data":null,"message":"The order does not exist","ts":1610259732263}
                      '30001': InvalidOrder,  # The order is being submitted, please try again later
                      '30004': InvalidOrder,  # Minimum quantity is {0}
                      '30005': InvalidOrder,  # Quantity maximum precision is {0} decimal places
                      '30006': InvalidOrder,  # Price maximum precision is {0} decimal places
                      '30007': InvalidOrder,  # Minimum price is {0}
                      '30008': InvalidOrder,  # Stop price maximum precision is {0} decimal places
                      '30009': InvalidOrder,  # Stop Price cannot be less than {0}
                      '30010': InvalidOrder,  # Market price cannot be empty
                      '30011': CancelPending,  # The order is being cancelled, please wait.
                      '30012': BadRequest,  # Unknown currency
                      '30013': BadSymbol,  # Unknown symbol
                      '30014': OrderNotFound,  # Futures order cannot be found
                      '30015': InvalidOrder,  # This is not an open order and cannot modified
                      '30016': ExchangeError,  # No position found
                      '30017': InvalidOrder,  # The current close position is 0. It is recommended that you cancel the current order closing order.
                      '30018': InvalidOrder,  # Order price cannot be greater than {0}
                      '30019': InvalidOrder,  # Order quantity cannot be greater than {0}
                      '30020': InvalidOrder,  # Order price must be a multiple of {0}
                      '30021': InvalidOrder,  # Margin adjustement must be greater than 0
                      '30022': InvalidOrder,  # New quantity must be greater than filled quantity
                      '30023': InvalidOrder,  # Order failed, please try again
                      '30024': InvalidOrder,  # TimeInForce error, only GTC or IOC are allowed
                      '30025': InvalidOrder,  # TimeInForce error, only GTC is allowed
                      '30026': InvalidOrder,  # Quantity is not a multiple of {0}
                      '30027': InvalidOrder,  # Close position failed, it is recommended that you cancel the current order and then close the position.
                      '30028': BadSymbol,  # Symbol cannot be traded at self time
                      '30029': InvalidOrder,  # Modified quantity or price cannot be empty
                      '30030': InvalidOrder,  # Price cannot be specified for market orders
                      '30031': InvalidOrder,  # Liquidation orders cannot be modified
                      '30032': InvalidOrder,  # Leverage cannot be greater than {0}
                      '30033': InvalidOrder,  # Leverage cannot be smaller than {0}
                      '30034': RateLimitExceeded,  # The max number of open orders is {0}. To place a new order, please cancel a previous one
                      '30035': RateLimitExceeded,  # The max number of {0} open orders is {1}. To place a new order, please cancel a previous one
                      '30036': ExchangeNotAvailable,  # Liquidation is in progress, please try again later
                      '30037': InvalidOrder,  # Once stop limit order triggered, stop price cannot be amended
                      '30038': ExchangeError,  # The total value of your orders has exceeded the current risk limit. Please adjust the risk limit
                      '30039': InsufficientFunds,  # Your risk limit has now been changed to {0}, your maximum leverage less than 1, please readjust accordingly
                      '30040': InvalidOrder,  # Order status has changed, please try again later
                      '30041': InvalidOrder,  # Liquidation orders cannot be cancelled
                      '30042': InvalidOrder,  # Order cannot be placed as you will be breaching you max limit value of {1} BTC for {0}
                      '30043': InvalidOrder,  # The risk limit cannot be less than 0
                      '30044': BadRequest,  # Timeout cannot be greater than 60 minutes
                      '30045': InvalidOrder,  # Side is not valid, it should be BUY or SELL
                      '30046': InvalidOrder,  # Order type is not valid, it should be MARKET or LIMIT or STOP-LIMIT or STOP
                      '30047': InvalidOrder,  # The order is closed. Can't cancel
                      '30048': InvalidOrder,  # Market orders cannot be modified
                      '30049': InvalidOrder,  # The order is being modified, please wait
                      '30050': InvalidOrder,  # Maximum 10 orders
                      '40004': BadRequest,  # Requested resource doesn't exist
                      '40009': RateLimitExceeded,  # Too many requests
                      '40102': AuthenticationError,  # {"code":40102,"message":"Unauthorized(invalid key)"}
                      '40103': AuthenticationError,  # {"code":40103,"message":"Unauthorized(invalid sign)"}
                      '40303': PermissionDenied,  # {"code":40303,"message":"Forbidden(invalid scopes)"}
                      '41001': BadRequest,  # Incorrect HTTP request
                      '41002': BadRequest,  # Unsupported HTTP request method
                      '42001': ExchangeNotAvailable,  # Duplicated data entry, please check and try again
                      '50001': ExchangeError,  # Server side exception, please try again later
                      '50002': ExchangeError,  # Server is busy, please try again later
                  },
                  'broad': {},
              },
              'precisionMode': TICK_SIZE,
              'options': {
                  'defaultType': 'spot',  # 'spot', 'future'
                  'types': {
                      'spot': 'SPTP',
                      'future': 'FUTP',
                      'otc': 'F2CP',
                      'saving': 'VLTP',
                  },
                  'accounts': {
                      'SPTP': 'spot',
                      'FUTP': 'future',
                      'F2CP': 'otc',
                      'VLTP': 'saving',
                  },
                  'networks': {
                      'ETH': 'ERC20',
                      'TRX': 'TRC20',
                      'SOL': 'SPL',
                  },
              },
          })
  
      async def fetch_status(self, params={}):
          response = await self.publicGetAnnouncementMaintenance(params)
          #
          #     {
          #         "code": 1,
          #         "data": {
          #             "startTime":"2020-06-25T02:15:00.000Z",
          #             "endTime":"2020-06-25T02:45:00.000Z"，
          #             "description":"Spot Trading :UTC Jun 25, 2020 02:15 to 02:45(HKT Jun 25 10:15 to 10:45),Futures Trading: UTC Jun 25, 2020 02:15 to 02:45(HKT Jun 25 10:15 to 10:45).We apologize for any inconvenience caused. Thank you for your patience and understanding.Should you have any enquiries, please do not hesitate our live chat support or via email at cs@aax.com."
          #         },
          #         "message":"success",
          #         "ts":1593043237000
          #     }
          #
          data = self.safe_value(response, 'data', {})
          timestamp = self.milliseconds()
          startTime = self.parse8601(self.safe_string(data, 'startTime'))
          endTime = self.parse8601(self.safe_string(data, 'endTime'))
          update = {
              'updated': self.safe_integer(response, 'ts', timestamp),
          }
          if endTime is not None:
              startTimeIsOk = True if (startTime is None) else (timestamp < startTime)
              isOk = (timestamp > endTime) or startTimeIsOk
              update['eta'] = endTime
              update['status'] = 'ok' if isOk else 'maintenance'
          self.status = self.extend(self.status, update)
          return self.status
  
      async def fetch_markets(self, params={}):
          response = await self.publicGetInstruments(params)
          #
          #     {
          #         "code":1,
          #         "message":"success",
          #         "ts":1610159448962,
          #         "data":[
          #             {
          #                 "tickSize":"0.01",
          #                 "lotSize":"1",
          #                 "base":"BTC",
          #                 "quote":"USDT",
          #                 "minQuantity":"1.0000000000",
          #                 "maxQuantity":"30000",
          #                 "minPrice":"0.0100000000",
          #                 "maxPrice":"999999.0000000000",
          #                 "status":"readOnly",
          #                 "symbol":"BTCUSDTFP",
          #                 "code":"FP",
          #                 "takerFee":"0.00040",
          #                 "makerFee":"0.00020",
          #                 "multiplier":"0.001000000000",
          #                 "mmRate":"0.00500",
          #                 "imRate":"0.01000",
          #                 "type":"futures",
          #                 "settleType":"Vanilla",
          #                 "settleCurrency":"USDT"
          #             },
          #             {
          #                 "tickSize":"0.5",
          #                 "lotSize":"10",
          #                 "base":"BTC",
          #                 "quote":"USD",
          #                 "minQuantity":"10.0000000000",
          #                 "maxQuantity":"300000",
          #                 "minPrice":"0.5000000000",
          #                 "maxPrice":"999999.0000000000",
          #                 "status":"readOnly",
          #                 "symbol":"BTCUSDFP",
          #                 "code":"FP",
          #                 "takerFee":"0.00040",
          #                 "makerFee":"0.00020",
          #                 "multiplier":"1.000000000000",
          #                 "mmRate":"0.00500",
          #                 "imRate":"0.01000",
          #                 "type":"futures",
          #                 "settleType":"Inverse",
          #                 "settleCurrency":"BTC"
          #             },
          #             {
          #                 "tickSize":"0.0001",
          #                 "lotSize":"0.01",
          #                 "base":"AAB",
          #                 "quote":"USDT",
          #                 "minQuantity":"5.0000000000",
          #                 "maxQuantity":"50000.0000000000",
          #                 "minPrice":"0.0001000000",
          #                 "maxPrice":"999999.0000000000",
          #                 "status":"readOnly",
          #                 "symbol":"AABUSDT",
          #                 "code":null,
          #                 "takerFee":"0.00100",
          #                 "makerFee":"0.00100",
          #                 "multiplier":"1.000000000000",
          #                 "mmRate":"0.02500",
          #                 "imRate":"0.05000",
          #                 "type":"spot",
          #                 "settleType":null,
          #                 "settleCurrency":null
          #             },
          #         ]
          #     }
          #
          data = self.safe_value(response, 'data')
          result = []
          for i in range(0, len(data)):
              market = data[i]
              id = self.safe_string(market, 'symbol')
              baseId = self.safe_string(market, 'base')
              quoteId = self.safe_string(market, 'quote')
              base = self.safe_currency_code(baseId)
              quote = self.safe_currency_code(quoteId)
              status = self.safe_string(market, 'status')
              active = (status == 'enable')
              taker = self.safe_number(market, 'takerFee')
              maker = self.safe_number(market, 'makerFee')
              type = self.safe_string(market, 'type')
              inverse = None
              linear = None
              quanto = None
              spot = (type == 'spot')
              futures = (type == 'futures')
              settleType = self.safe_string_lower(market, 'settleType')
              if settleType is not None:
                  inverse = (settleType == 'inverse')
                  linear = (settleType == 'vanilla')
                  quanto = (settleType == 'quanto')
              symbol = id
              if type == 'spot':
                  symbol = base + '/' + quote
              precision = {
                  'amount': self.safe_number(market, 'lotSize'),
                  'price': self.safe_number(market, 'tickSize'),
              }
              result.append({
                  'id': id,
                  'symbol': symbol,
                  'base': base,
                  'quote': quote,
                  'baseId': baseId,
                  'quoteId': quoteId,
                  'type': type,
                  'spot': spot,
                  'futures': futures,
                  'inverse': inverse,
                  'linear': linear,
                  'quanto': quanto,
                  'precision': precision,
                  'info': market,
                  'active': active,
                  'taker': taker,
                  'maker': maker,
                  'percentage': False,
                  'tierBased': True,
                  'limits': {
                      'amount': {
                          'min': self.safe_string(market, 'minQuantity'),
                          'max': self.safe_string(market, 'maxQuantity'),
                      },
                      'price': {
                          'min': self.safe_string(market, 'minPrice'),
                          'max': self.safe_string(market, 'maxPrice'),
                      },
                      'cost': {
                          'min': None,
                          'max': None,
                      },
                  },
              })
          return result
  
      async def fetch_currencies(self, params={}):
          response = await self.publicGetCurrencies(params)
          #
          #     {
          #         "code":1,
          #         "data":[
          #             {
          #                 "chain":"BTC",
          #                 "displayName":"Bitcoin",
          #                 "withdrawFee":"0.0004",
          #                 "withdrawMin":"0.001",
          #                 "otcFee":"0",
          #                 "enableOTC":true,
          #                 "visible":true,
          #                 "enableTransfer":true,
          #                 "transferMin":"0.00001",
          #                 "depositMin":"0.0005",
          #                 "enableWithdraw":true,
          #                 "enableDeposit":true,
          #                 "addrWithMemo":false,
          #                 "withdrawPrecision":"0.00000001",
          #                 "currency":"BTC",
          #                 "network":"BTC",  # ETH, ERC20, TRX, TRC20, OMNI, LTC, XRP, XLM, ...
          #                 "minConfirm":"2"
          #             },
          #         ],
          #         "message":"success",
          #         "ts":1624330530697
          #     }
          #
          result = {}
          data = self.safe_value(response, 'data', [])
          for i in range(0, len(data)):
              currency = data[i]
              id = self.safe_string(currency, 'chain')
              name = self.safe_string(currency, 'displayName')
              code = self.safe_currency_code(id)
              precision = self.safe_number(currency, 'withdrawPrecision')
              enableWithdraw = self.safe_value(currency, 'enableWithdraw')
              enableDeposit = self.safe_value(currency, 'enableDeposit')
              fee = self.safe_number(currency, 'withdrawFee')
              visible = self.safe_value(currency, 'visible')
              active = (enableWithdraw and enableDeposit and visible)
              network = self.safe_string(currency, 'network')
              result[code] = {
                  'id': id,
                  'name': name,
                  'code': code,
                  'precision': precision,
                  'info': currency,
                  'active': active,
                  'fee': fee,
                  'network': network,
                  'limits': {
                      'deposit': {
                          'min': self.safe_number(currency, 'depositMin'),
                          'max': None,
                      },
                      'withdraw': {
                          'min': self.safe_number(currency, 'withdrawMin'),
                          'max': None,
                      },
                  },
              }
          return result
  
      def parse_ticker(self, ticker, market=None):
          #
          #     {
          #         "t":1610162685342,  # timestamp
          #         "a":"0.00000000",  # trading volume in USD in the last 24 hours, futures only
          #         "c":"435.20000000",  # close
          #         "d":"4.22953489",  # change
          #         "h":"455.04000000",  # high
          #         "l":"412.78000000",  # low
          #         "o":"417.54000000",  # open
          #         "s":"BCHUSDTFP",  # market id
          #         "v":"2031068.00000000",  # trading volume in quote currency of last 24 hours
          #     }
          #
          timestamp = self.safe_integer(ticker, 't')
          marketId = self.safe_string(ticker, 's')
          symbol = self.safe_symbol(marketId, market)
          last = self.safe_number(ticker, 'c')
          open = self.safe_number(ticker, 'o')
          quoteVolume = self.safe_number(ticker, 'v')
          return self.safe_ticker({
              'symbol': symbol,
              'timestamp': timestamp,
              'datetime': None,
              'high': self.safe_number(ticker, 'h'),
              'low': self.safe_number(ticker, 'l'),
              'bid': None,
              'bidVolume': None,
              'ask': None,
              'askVolume': None,
              'vwap': None,
              'open': open,
              'close': last,
              'last': last,
              'previousClose': None,
              'change': None,
              'percentage': None,
              'average': None,
              'baseVolume': None,
              'quoteVolume': quoteVolume,
              'info': ticker,
          }, market)
  
      async def fetch_tickers(self, symbols=None, params={}):
          await self.load_markets()
          response = await self.publicGetMarketTickers(params)
          #
          #     {
          #         "e":"tickers",
          #         "t":1610162685342,
          #         "tickers":[
          #             {
          #                 "a":"0.00000000",
          #                 "c":"435.20000000",
          #                 "d":"4.22953489",
          #                 "h":"455.04000000",
          #                 "l":"412.78000000",
          #                 "o":"417.54000000",
          #                 "s":"BCHUSDTFP",
          #                 "v":"2031068.00000000",
          #             },
          #         ],
          #     }
          #
          tickers = self.safe_value(response, 'tickers', [])
          result = []
          timestamp = self.safe_integer(response, 't')
          for i in range(0, len(tickers)):
              ticker = self.parse_ticker(self.extend(tickers[i], {'t': timestamp}))
              result.append(ticker)
          return self.filter_by_array(result, 'symbol', symbols)
  
      async def fetch_order_book(self, symbol, limit=None, params={}):
          await self.load_markets()
          market = self.market(symbol)
          if limit is None:
              limit = 20
          else:
              if (limit != 20) and (limit != 50):
                  raise BadRequest(self.id + ' fetchOrderBook() limit argument must be None, 20 or 50')
          request = {
              'symbol': market['id'],
              'level': limit,  # required
          }
          #
          response = await self.publicGetMarketOrderbook(self.extend(request, params))
          #
          #     {
          #         "asks":[
          #             ["10823.00000000","0.004000"],
          #             ["10823.10000000","0.100000"],
          #             ["10823.20000000","0.010000"]
          #         ],
          #         "bids":[
          #             ["10821.20000000","0.002000"],
          #             ["10821.10000000","0.005000"],
          #             ["10820.40000000","0.013000"]
          #         ],
          #         "e":"BTCUSDT@book_50",
          #         "t":1561543614756
          #     }
          #
          timestamp = self.safe_integer(response, 't')  # need unix type
          return self.parse_order_book(response, symbol, timestamp)
  
      def parse_trade(self, trade, market=None):
          #
          # public fetchTrades
          #
          #     {
          #         "p":"9395.50000000",
          #         "q":"50.000000",
          #         "t":1592563996718
          #     }
          #
          # private fetchMyTrades
          #
          #     {
          #         "avgPrice":"1199.8",
          #         "base":"ETH",
          #         "clOrdID":null,
          #         "commission":"0.00002",
          #         "createTime":"2021-01-11T02:47:51.512Z",
          #         "cumQty":"0.02",
          #         "filledOrderID":"1eUD4F5rwK",
          #         "filledPrice":"1199.8",
          #         "filledQty":"0.02",
          #         "leavesQty":"0",
          #         "oCreateTime":"2021-01-11T02:47:51.377Z",
          #         "orderID":"1eUD4EHfdU",
          #         "orderQty":"0.02",
          #         "orderStatus":3,
          #         "orderType":1,
          #         "price":"1198.25",
          #         "quote":"USDT",
          #         "rejectCode":null,
          #         "rejectReason":null,
          #         "side":1,
          #         "stopPrice":"0",
          #         "symbol":"ETHUSDT",
          #         "taker":true,
          #         "tradeID":"E04WTIgfmULU",
          #         "transactTime":"2021-01-11T02:47:51.389Z",
          #         "updateTime":null,
          #         "userID":"1362494"
          #     }
          #
          timestamp = self.safe_integer(trade, 't')
          if timestamp is None:
              timestamp = self.parse8601(self.safe_string(trade, 'createTime'))
          id = self.safe_string_2(trade, 'tid', 'tradeID')
          symbol = None
          marketId = self.safe_string(trade, 'symbol')
          market = self.safe_market(marketId, market)
          if market is not None:
              symbol = market['symbol']
          priceString = self.safe_string_2(trade, 'p', 'filledPrice')
          amountString = self.safe_string_2(trade, 'q', 'filledQty')
          orderId = self.safe_string(trade, 'orderID')
          isTaker = self.safe_value(trade, 'taker')
          takerOrMaker = None
          if isTaker is not None:
              takerOrMaker = 'taker' if isTaker else 'maker'
          side = self.safe_string(trade, 'side')
          if side == '1':
              side = 'buy'
          elif side == '2':
              side = 'sell'
          if side is None:
              side = 'sell' if (priceString[0] == '-') else 'buy'
          priceString = Precise.string_abs(priceString)
          price = self.parse_number(priceString)
          amount = self.parse_number(amountString)
          cost = self.parse_number(Precise.string_mul(priceString, amountString))
          orderType = self.parse_order_type(self.safe_string(trade, 'orderType'))
          fee = None
          feeCost = self.safe_number(trade, 'commission')
          if feeCost is not None:
              feeCurrency = None
              if market is not None:
                  if side == 'buy':
                      feeCurrency = market['base']
                  elif side == 'sell':
                      feeCurrency = market['quote']
              fee = {
                  'currency': feeCurrency,
                  'cost': feeCost,
              }
          return {
              'info': trade,
              'id': id,
              'timestamp': timestamp,
              'datetime': self.iso8601(timestamp),
              'symbol': symbol,
              'type': orderType,
              'side': side,
              'order': orderId,
              'takerOrMaker': takerOrMaker,
              'price': price,
              'amount': amount,
              'cost': cost,
              'fee': fee,
          }
  
      async def fetch_trades(self, symbol, since=None, limit=None, params={}):
          await self.load_markets()
          market = self.market(symbol)
          limit = 2000 if (limit is None) else limit
          limit = min(limit, 2000)
          request = {
              'symbol': market['id'],
              'limit': limit,
          }
          response = await self.publicGetMarketTrades(request)
          #
          #     {
          #         "e":"BTCUSDFP@trades",
          #         "trades": [
          #             {"p":"9395.50000000","q":"50.000000","t":1592563996718},
          #             {"p":"9395.50000000","q":"50.000000","t":1592563993577},
          #         ],
          #     }
          #
          trades = self.safe_value(response, 'trades', [])
          return self.parse_trades(trades, market, since, limit)
  
      def parse_ohlcv(self, ohlcv, market=None):
          #
          #     [
          #         0.042398,  # 0 open
          #         0.042684,  # 1 high
          #         0.042366,  # 2 low
          #         0.042386,  # 3 close
          #         0.93734243,  # 4 volume
          #         1611514800,  # 5 timestamp
          #     ]
          #
          return [
              self.safe_timestamp(ohlcv, 5),
              self.safe_number(ohlcv, 0),
              self.safe_number(ohlcv, 1),
              self.safe_number(ohlcv, 2),
              self.safe_number(ohlcv, 3),
              self.safe_number(ohlcv, 4),
          ]
  
      async def fetch_ohlcv(self, symbol, timeframe='1h', since=None, limit=None, params={}):
          await self.load_markets()
          market = self.market(symbol)
          request = {
              # 'limit': limit,  # if set counts from now into the past
              'symbol': market['id'],
              'timeFrame': self.timeframes[timeframe],
          }
          limit = 500 if (limit is None) else limit
          duration = self.parse_timeframe(timeframe)
          if since is None:
              end = self.seconds()
              request['start'] = end - duration * limit
              request['end'] = end
          else:
              start = int(since / 1000)
              request['start'] = start
              request['end'] = self.sum(start, duration * limit)
          response = await self.publicGetMarketHistoryCandles(self.extend(request, params))
          #
          #     {
          #         "data":[
          #             [0.042398,0.042684,0.042366,0.042386,0.93734243,1611514800],
          #             [0.042386,0.042602,0.042234,0.042373,1.01925239,1611518400],
          #             [0.042373,0.042558,0.042362,0.042389,0.93801705,1611522000],
          #         ],
          #         "success":true,
          #         "t":1611875157
          #     }
          #
          data = self.safe_value(response, 'data', [])
          return self.parse_ohlcvs(data, market, timeframe, since, limit)
  
      async def fetch_balance(self, params={}):
          await self.load_markets()
          defaultType = self.safe_string_2(self.options, 'fetchBalance', 'defaultType', 'spot')
          type = self.safe_string(params, 'type', defaultType)
          types = self.safe_value(self.options, 'types', {})
          purseType = self.safe_string(types, type, type)
          request = {
              'purseType': purseType,
          }
          params = self.omit(params, 'type')
          response = await self.privateGetAccountBalances(self.extend(request, params))
          #
          #     {
          #         "code":1,
          #         "data":[
          #             {
          #                 "purseType":"FUTP",
          #                 "currency":"BTC",
          #                 "available":"0.41000000",
          #                 "unavailable":"0.00000000"
          #             },
          #             {
          #                 "purseType":"FUTP",
          #                 "currency":"USDT",
          #                 "available":"0.21000000",
          #                 "unvaliable":"0.00000000"
          #             }
          #         ]
          #         "message":"success",
          #         "ts":1573530401020
          #     }
          #
          data = self.safe_value(response, 'data')
          timestamp = self.safe_integer(response, 'ts')
          result = {
              'info': response,
              'timestamp': timestamp,
              'datetime': self.iso8601(timestamp),
          }
          for i in range(0, len(data)):
              balance = data[i]
              balanceType = self.safe_string(balance, 'purseType')
              if balanceType == purseType:
                  currencyId = self.safe_string(balance, 'currency')
                  code = self.safe_currency_code(currencyId)
                  account = self.account()
                  account['free'] = self.safe_string(balance, 'available')
                  account['used'] = self.safe_string(balance, 'unavailable')
                  result[code] = account
          return self.parse_balance(result)
  
      async def create_order(self, symbol, type, side, amount, price=None, params={}):
          orderType = type.upper()
          orderSide = side.upper()
          await self.load_markets()
          market = self.market(symbol)
          request = {
              # 'orderType': orderType,  # MARKET, LIMIT, STOP, STOP-LIMIT
              'symbol': market['id'],
              'orderQty': self.amount_to_precision(symbol, amount),
              'side': orderSide,
              # 'stopPrice': self.price_to_precision(symbol, stopPrice),
              # 'clOrdID': clientOrderId,  # up to 20 chars, lowercase and uppercase letters only
              # 'timeInForce': 'GTC',  # GTC, IOC, FOK, default is GTC
              # 'execInst': 'Post-Only',  # the only value supported by the exchange, futures-only
          }
          timeInForce = self.safe_string(params, 'timeInForce')
          if timeInForce is not None:
              request['timeInForce'] = timeInForce
              params = self.omit(params, 'timeInForce')
          clientOrderId = self.safe_string_2(params, 'clOrdID', 'clientOrderId')
          if clientOrderId is not None:
              request['clOrdID'] = clientOrderId
              params = self.omit(params, ['clOrdID', 'clientOrderId'])
          stopPrice = self.safe_number(params, 'stopPrice')
          if stopPrice is None:
              if (orderType == 'STOP-LIMIT') or (orderType == 'STOP'):
                  raise ArgumentsRequired(self.id + ' createOrder() requires a stopPrice parameter for ' + orderType + ' orders')
          else:
              if orderType == 'LIMIT':
                  orderType = 'STOP-LIMIT'
              elif orderType == 'MARKET':
                  orderType = 'STOP'
              request['stopPrice'] = self.price_to_precision(symbol, stopPrice)
              params = self.omit(params, 'stopPrice')
          if orderType == 'LIMIT' or orderType == 'STOP-LIMIT':
              request['price'] = self.price_to_precision(symbol, price)
          request['orderType'] = orderType
          method = None
          if market['spot']:
              method = 'privatePostSpotOrders'
          elif market['futures']:
              method = 'privatePostFuturesOrders'
          response = await getattr(self, method)(self.extend(request, params))
          #
          # spot
          #
          #     {
          #         "code":1,
          #         "data":{
          #             "symbol":"ETHUSDT",
          #             "orderType":2,
          #             "avgPrice":"0",
          #             "execInst":null,
          #             "orderStatus":0,
          #             "userID":"1362494",
          #             "quote":"USDT",
          #             "rejectReason":null,
          #             "rejectCode":null,
          #             "price":"1500",
          #             "orderQty":"1",
          #             "commission":"0",
          #             "id":"268323430253735936",
          #             "timeInForce":1,
          #             "isTriggered":false,
          #             "side":2,
          #             "orderID":"1eO51MDSpQ",
          #             "leavesQty":"0",
          #             "cumQty":"0",
          #             "updateTime":null,
          #             "lastQty":"0",
          #             "clOrdID":null,
          #             "stopPrice":null,
          #             "createTime":null,
          #             "transactTime":null,
          #             "base":"ETH",
          #             "lastPrice":"0"
          #         },
          #         "message":"success",
          #         "ts":1610245290980
          #     }
          #
          # futures
          #
          #     {
          #         "code":1,
          #         "data":{
          #             "liqType":0,
          #             "symbol":"ETHUSDTFP",
          #             "orderType":2,
          #             "leverage":"1",
          #             "marketPrice":"1318.3150000000",
          #             "code":"FP",
          #             "avgPrice":"0",
          #             "execInst":null,
          #             "orderStatus":0,
          #             "userID":"1362494",
          #             "quote":"USDT",
          #             "rejectReason":null,
          #             "rejectCode":null,
          #             "price":"500",
          #             "orderQty":"1",
          #             "commission":"0",
          #             "id":"268346885133053953",
          #             "timeInForce":1,
          #             "isTriggered":false,
          #             "side":1,
          #             "orderID":"1eOuPUAAkq",
          #             "leavesQty":"1",
          #             "cumQty":"0",
          #             "updateTime":null,
          #             "lastQty":null,
          #             "clOrdID":null,
          #             "stopPrice":null,
          #             "createTime":null,
          #             "transactTime":null,
          #             "settleType":"VANILLA",
          #             "base":"ETH",
          #             "lastPrice":"0"
          #         },
          #         "message":"success",
          #         "ts":1610250883059
          #     }
          #
          data = self.safe_value(response, 'data', {})
          return self.parse_order(data, market)
  
      async def edit_order(self, id, symbol, type, side, amount, price=None, params={}):
          await self.load_markets()
          market = self.market(symbol)
          request = {
              'orderID': id,
              # 'orderQty': self.amount_to_precision(symbol, amount),
              # 'price': self.price_to_precision(symbol, price),
              # 'stopPrice': self.price_to_precision(symbol, stopPrice),
          }
          stopPrice = self.safe_number(params, 'stopPrice')
          if stopPrice is not None:
              request['stopPrice'] = self.price_to_precision(symbol, stopPrice)
              params = self.omit(params, 'stopPrice')
          if price is not None:
              request['price'] = self.price_to_precision(symbol, price)
          if amount is not None:
              request['orderQty'] = self.amount_to_precision(symbol, amount)
          method = None
          if market['spot']:
              method = 'privatePutSpotOrders'
          elif market['futures']:
              method = 'privatePutFuturesOrders'
          response = await getattr(self, method)(self.extend(request, params))
          #
          # spot
          #
          #     {
          #         "code":1,
          #         "data":{
          #             "symbol":"ETHUSDT",
          #             "orderType":2,
          #             "avgPrice":"0",
          #             "execInst":null,
          #             "orderStatus":0,
          #             "userID":"1362494",
          #             "quote":"USDT",
          #             "rejectReason":null,
          #             "rejectCode":null,
          #             "price":"1500",
          #             "orderQty":"1",
          #             "commission":"0",
          #             "id":"268323430253735936",
          #             "timeInForce":1,
          #             "isTriggered":false,
          #             "side":2,
          #             "orderID":"1eO51MDSpQ",
          #             "leavesQty":"0",
          #             "cumQty":"0",
          #             "updateTime":null,
          #             "lastQty":"0",
          #             "clOrdID":null,
          #             "stopPrice":null,
          #             "createTime":null,
          #             "transactTime":null,
          #             "base":"ETH",
          #             "lastPrice":"0"
          #         },
          #         "message":"success",
          #         "ts":1610245290980
          #     }
          #
          # futures
          #
          #     {
          #         "code":1,
          #         "data":{
          #             "liqType":0,
          #             "symbol":"ETHUSDTFP",
          #             "orderType":2,
          #             "leverage":"1",
          #             "marketPrice":"1318.3150000000",
          #             "code":"FP",
          #             "avgPrice":"0",
          #             "execInst":null,
          #             "orderStatus":0,
          #             "userID":"1362494",
          #             "quote":"USDT",
          #             "rejectReason":null,
          #             "rejectCode":null,
          #             "price":"500",
          #             "orderQty":"1",
          #             "commission":"0",
          #             "id":"268346885133053953",
          #             "timeInForce":1,
          #             "isTriggered":false,
          #             "side":1,
          #             "orderID":"1eOuPUAAkq",
          #             "leavesQty":"1",
          #             "cumQty":"0",
          #             "updateTime":null,
          #             "lastQty":null,
          #             "clOrdID":null,
          #             "stopPrice":null,
          #             "createTime":null,
          #             "transactTime":null,
          #             "settleType":"VANILLA",
          #             "base":"ETH",
          #             "lastPrice":"0"
          #         },
          #         "message":"success",
          #         "ts":1610250883059
          #     }
          #
          data = self.safe_value(response, 'data', {})
          return self.parse_order(data, market)
  
      async def cancel_order(self, id, symbol=None, params={}):
          await self.load_markets()
          request = {
              'orderID': id,
          }
          method = None
          defaultType = self.safe_string_2(self.options, 'cancelOrder', 'defaultType', 'spot')
          type = self.safe_string(params, 'type', defaultType)
          params = self.omit(params, 'type')
          market = None
          if symbol is not None:
              market = self.market(symbol)
              type = market['type']
          if type == 'spot':
              method = 'privateDeleteSpotOrdersCancelOrderID'
          elif type == 'futures':
              method = 'privateDeleteFuturesOrdersCancelOrderID'
          response = await getattr(self, method)(self.extend(request, params))
          #
          # spot
          #
          #     {
          #         "code":1,
          #         "data":{
          #             "avgPrice":"0",
          #             "base":"BTC",
          #             "clOrdID":"aax",
          #             "commission":"0",
          #             "createTime":"2019-11-12T03:46:41Z",
          #             "cumQty":"0",
          #             "id":"114330021504606208",
          #             "isTriggered":false,
          #             "lastPrice":"0",
          #             "lastQty":"0",
          #             "leavesQty":"0",
          #             "orderID":"wJ4L366KB",
          #             "orderQty":"0.05",
          #             "orderStatus":1,
          #             "orderType":2,
          #             "price":"8000",
          #             "quote":"USDT",
          #             "rejectCode":0,
          #             "rejectReason":null,
          #             "side":1,
          #             "stopPrice":"0",
          #             "symbol":"BTCUSDT",
          #             "transactTime":null,
          #             "updateTime":"2019-11-12T03:46:41Z",
          #             "timeInForce":1,
          #             "userID":"216214"
          #         },
          #         "message":"success",
          #         "ts":1573530402029
          #     }
          #
          # futures
          #
          #     {
          #         "code":1,
          #         "data":{
          #             "avgPrice":"0",
          #             "base":"BTC",
          #             "clOrdID":"aax_futures",
          #             "code":"FP",
          #             "commission":"0",
          #             "createTime":"2019-11-12T06:48:58Z",
          #             "cumQty":"0",
          #             "id":"114375893764395008",
          #             "isTriggered":false,
          #             "lastPrice":"0",
          #             "lastQty":null,
          #             "leavesQty":"300",
          #             "leverage":"1",
          #             "liqType":0,
          #             "marketPrice":"8760.75",
          #             "orderID":"wJTewQc81",
          #             "orderQty":"300",
          #             "orderStatus":1,
          #             "orderType":2,
          #             "price":"8000",
          #             "quote":"USD",
          #             "rejectCode":0,
          #             "rejectReason":null,
          #             "settleType":"INVERSE",
          #             "side":1,
          #             "stopPrice":"0",
          #             "symbol":"BTCUSDFP",
          #             "transactTime":"2019-11-12T06:48:58Z",
          #             "updateTime":"2019-11-12T06:48:58Z",
          #             "timeInForce":1,
          #             "execInst": "",
          #             "userID":"216214"
          #         },
          #         "message":"success",
          #         "ts":1573541642970
          #     }
          #
          data = self.safe_value(response, 'data', {})
          return self.parse_order(data, market)
  
      async def cancel_all_orders(self, symbol=None, params={}):
          if symbol is None:
              raise ArgumentsRequired(self.id + ' cancelAllOrders() requires a symbol argument')
          await self.load_markets()
          market = self.market(symbol)
          request = {
              'symbol': market['id'],
          }
          method = None
          if market['spot']:
              method = 'privateDeleteSpotOrdersCancelAll'
          elif market['futures']:
              method = 'privateDeleteFuturesOrdersCancelAll'
          response = await getattr(self, method)(self.extend(request, params))
          #
          #     {
          #         "code":1,
          #         "data":[
          #             "vBC9rXsEE",
          #             "vBCc46OI0"
          #             ],
          #         "message":"success",
          #         "ts":1572597435470
          #     }
          #
          return response
  
      async def fetch_order(self, id, symbol=None, params={}):
          await self.load_markets()
          defaultType = self.safe_string_2(self.options, 'fetchOrder', 'defaultType', 'spot')
          params['type'] = self.safe_string(params, 'type', defaultType)
          request = {}
          clientOrderId = self.safe_string_2(params, 'clOrdID', 'clientOrderId')
          if clientOrderId is None:
              request['orderID'] = id
          else:
              request['clOrdID'] = clientOrderId
              params = self.omit(params, ['clOrdID', 'clientOrderId'])
          orders = await self.fetch_orders(symbol, None, None, self.extend(request, params))
          order = self.safe_value(orders, 0)
          if order is None:
              if clientOrderId is None:
                  raise OrderNotFound(self.id + ' fetchOrder() could not find order id ' + id)
              else:
                  raise OrderNotFound(self.id + ' fetchOrder() could not find order clientOrderID ' + clientOrderId)
          return order
  
      async def fetch_open_orders(self, symbol=None, since=None, limit=None, params={}):
          await self.load_markets()
          request = {
              # 'pageNum': '1',
              # 'pageSize': '10',
              # 'symbol': market['id'],
              # 'orderID': id,
              # 'side': 'None',  # BUY, SELL
              # 'clOrdID': clientOrderId,
          }
          defaultType = self.safe_string_2(self.options, 'fetchOpenOrders', 'defaultType', 'spot')
          type = self.safe_string(params, 'type', defaultType)
          params = self.omit(params, 'type')
          market = None
          if symbol is not None:
              market = self.market(symbol)
              request['symbol'] = market['id']
              type = market['type']
          clientOrderId = self.safe_string_2(params, 'clOrdID', 'clientOrderId')
          if clientOrderId is not None:
              request['clOrdID'] = clientOrderId
              params = self.omit(params, ['clOrdID', 'clientOrderId'])
          method = None
          if type == 'spot':
              method = 'privateGetSpotOpenOrders'
          elif type == 'futures':
              method = 'privateGetFuturesOpenOrders'
          if limit is not None:
              request['pageSize'] = limit  # default 10
          response = await getattr(self, method)(self.extend(request, params))
          #
          # spot
          #
          #     {
          #         "code":1,
          #         "data":{
          #             "total":19,
          #             "pageSize":10,
          #             "list":[
          #                 {
          #                     "orderType":2,
          #                     "symbol":"BTCUSDT",
          #                     "avgPrice":"0",
          #                     "orderStatus":0,
          #                     "userID":"7225",
          #                     "quote":"USDT",
          #                     "rejectReason":null,
          #                     "rejectCode":null,
          #                     "price":"0",
          #                     "orderQty":"0.002",
          #                     "commission":"0",
          #                     "id":"110419975166304256",
          #                     "isTriggered":null,
          #                     "side":1,
          #                     "orderID":"vBGlDcLwk",
          #                     "cumQty":"0",
          #                     "leavesQty":"0",
          #                     "updateTime":null,
          #                     "clOrdID":"0001",
          #                     "lastQty":"0",
          #                     "stopPrice":"0",
          #                     "createTime":"2019-11-01T08:49:33Z",
          #                     "transactTime":null,
          #                     "timeInForce":1,
          #                     "base":"BTC",
          #                     "lastPrice":"0"
          #                 }
          #             ],
          #             "pageNum":1
          #         },
          #         "message":"success",
          #         "ts":1572598173682
          #     }
          #
          # futures
          #
          #     {
          #         "code":1,
          #         "data":{
          #             "list":[
          #                 {
          #                     "avgPrice":"8768.99999999484997",
          #                     "base":"BTC",
          #                     "clOrdID":null,
          #                     "code":"FP",
          #                     "commission":"0.00000913",
          #                     "createTime":"2019-11-12T07:05:52.000Z,
          #                     "cumQty":"100",
          #                     "id":"114380149603028993",
          #                     "isTriggered":false,
          #                     "lastPrice":"8769",
          #                     "lastQty":"100",
          #                     "leavesQty":"0",
          #                     "leverage":"1",
          #                     "liqType":1,
          #                     "marketPrice":"8769.75",
          #                     "orderID":"wJXURIFBT",
          #                     "orderQty":"100",
          #                     "orderStatus":3,
          #                     "orderType":1,
          #                     "price":"8769.75",
          #                     "quote":"USD",
          #                     "rejectCode":0,
          #                     "rejectReason":null,
          #                     "settleType":"INVERSE",
          #                     "side":2,
          #                     "stopPrice":"0",
          #                     "symbol":"BTCUSDFP",
          #                     "transactTime":"2019-11-12T07:05:52.000Z,
          #                     "updateTime":"2019-11-12T07:05:52.000Z,
          #                     "timeInForce":1,
          #                     "execInst": "",
          #                     "userID":"216214"
          #                 },
          #             ],
          #             "pageNum":1,
          #             "pageSize":10,
          #             "total":21
          #         },
          #         "message":"success",
          #         "ts":1573546960172
          #     }
          #
          data = self.safe_value(response, 'data', {})
          orders = self.safe_value(data, 'list', [])
          return self.parse_orders(orders, market, since, limit)
  
      async def fetch_closed_orders(self, symbol=None, since=None, limit=None, params={}):
          request = {
              'orderStatus': '2',  # 1 new, 2 filled, 3 canceled
          }
          return await self.fetch_orders(symbol, since, limit, self.extend(request, params))
  
      async def fetch_canceled_orders(self, symbol=None, since=None, limit=None, params={}):
          request = {
              'orderStatus': '3',  # 1 new, 2 filled, 3 canceled
          }
          return await self.fetch_orders(symbol, since, limit, self.extend(request, params))
  
      async def fetch_orders(self, symbol=None, since=None, limit=None, params={}):
          await self.load_markets()
          request = {
              # 'pageNum': '1',
              # 'pageSize': '10',
              # 'symbol': market['id'],
              # 'orderID': id,
              # 'base': market['baseId'],
              # 'quote': market['quoteId'],
              # 'orderStatus': None,  # 1 new, 2 filled, 3 canceled
              # 'startDate': self.ymd(since),
              # 'endDate': self.ymd(self.milliseconds()),
              # 'orderType': None,  # MARKET, LIMIT, STOP, STOP-LIMIT
              # 'side': 'None',  # BUY, SELL
              # 'clOrdID': clientOrderId,
          }
          method = None
          defaultType = self.safe_string_2(self.options, 'fetchOrders', 'defaultType', 'spot')
          type = self.safe_string(params, 'type', defaultType)
          params = self.omit(params, 'type')
          market = None
          if symbol is not None:
              market = self.market(symbol)
              request['symbol'] = market['id']
              type = market['type']
          if type == 'spot':
              method = 'privateGetSpotOrders'
          elif type == 'futures':
              method = 'privateGetFuturesOrders'
          clientOrderId = self.safe_string_2(params, 'clOrdID', 'clientOrderId')
          if clientOrderId is not None:
              request['clOrdID'] = clientOrderId
              params = self.omit(params, ['clOrdID', 'clientOrderId'])
          if limit is not None:
              request['pageSize'] = limit  # default 10
          if since is not None:
              request['startDate'] = self.ymd(since)
          response = await getattr(self, method)(self.extend(request, params))
          #
          # spot
          #
          #     {
          #         "code":1,
          #         "data":{
          #             "total":19,
          #             "pageSize":10,
          #             "list":[
          #                 {
          #                     "orderType":2,
          #                     "symbol":"BTCUSDT",
          #                     "avgPrice":"0",
          #                     "orderStatus":0,
          #                     "userID":"7225",
          #                     "quote":"USDT",
          #                     "rejectReason":null,
          #                     "rejectCode":null,
          #                     "price":"0",
          #                     "orderQty":"0.002",
          #                     "commission":"0",
          #                     "id":"110419975166304256",
          #                     "isTriggered":null,
          #                     "side":1,
          #                     "orderID":"vBGlDcLwk",
          #                     "cumQty":"0",
          #                     "leavesQty":"0",
          #                     "updateTime":null,
          #                     "clOrdID":"0001",
          #                     "lastQty":"0",
          #                     "stopPrice":"0",
          #                     "createTime":"2019-11-01T08:49:33Z",
          #                     "transactTime":null,
          #                     "timeInForce":1,
          #                     "base":"BTC",
          #                     "lastPrice":"0"
          #                 }
          #             ],
          #             "pageNum":1
          #         },
          #         "message":"success",
          #         "ts":1572598173682
          #     }
          #
          # futures
          #
          #     {
          #         "code":1,
          #         "data":{
          #             "list":[
          #                 {
          #                     "avgPrice":"8768.99999999484997",
          #                     "base":"BTC",
          #                     "clOrdID":null,
          #                     "code":"FP",
          #                     "commission":"0.00000913",
          #                     "createTime":"2019-11-12T07:05:52.000Z,
          #                     "cumQty":"100",
          #                     "id":"114380149603028993",
          #                     "isTriggered":false,
          #                     "lastPrice":"8769",
          #                     "lastQty":"100",
          #                     "leavesQty":"0",
          #                     "leverage":"1",
          #                     "liqType":1,
          #                     "marketPrice":"8769.75",
          #                     "orderID":"wJXURIFBT",
          #                     "orderQty":"100",
          #                     "orderStatus":3,
          #                     "orderType":1,
          #                     "price":"8769.75",
          #                     "quote":"USD",
          #                     "rejectCode":0,
          #                     "rejectReason":null,
          #                     "settleType":"INVERSE",
          #                     "side":2,
          #                     "stopPrice":"0",
          #                     "symbol":"BTCUSDFP",
          #                     "transactTime":"2019-11-12T07:05:52.000Z,
          #                     "updateTime":"2019-11-12T07:05:52.000Z,
          #                     "timeInForce":1,
          #                     "execInst": "",
          #                     "userID":"216214"
          #                 },
          #             ],
          #             "pageNum":1,
          #             "pageSize":10,
          #             "total":21
          #         },
          #         "message":"success",
          #         "ts":1573546960172
          #     }
          #
          data = self.safe_value(response, 'data', {})
          orders = self.safe_value(data, 'list', [])
          return self.parse_orders(orders, market, since, limit)
  
      def parse_order_status(self, status):
          statuses = {
              '0': 'open',  # pending new
              '1': 'open',  # new
              '2': 'open',  # partially-filled
              '3': 'closed',  # filled
              '4': 'canceled',  # cancel-reject
              '5': 'canceled',  # canceled
              '6': 'rejected',  # rejected
              '10': 'expired',  # expired
              '11': 'rejected',  # business-reject
          }
          return self.safe_string(statuses, status, status)
  
      def parse_order_type(self, status):
          statuses = {
              '1': 'market',
              '2': 'limit',
              '3': 'stop',
              '4': 'stop-limit',
              '7': 'stop-loss',
              '8': 'take-profit',
          }
          return self.safe_string(statuses, status, status)
  
      def parse_time_in_force(self, timeInForce):
          timeInForces = {
              '1': 'GTC',
              '3': 'IOC',
              '4': 'FOK',
          }
          return self.safe_string(timeInForces, timeInForce, timeInForce)
  
      def parse_order(self, order, market=None):
          #
          #     {
          #         "avgPrice":"8768.99999999484997",
          #         "base":"BTC",
          #         "clOrdID":null,
          #         "code":"FP",  # futures only
          #         "commission":"0.00000913",
          #         "createTime":"2019-11-12T07:05:52.000Z,
          #         "cumQty":"100",
          #         "id":"114380149603028993",  # futures only
          #         "isTriggered":false,
          #         "lastPrice":"8769",
          #         "lastQty":"100",
          #         "leavesQty":"0",
          #         "leverage":"1",  # futures only
          #         "liqType":1,  # futures only
          #         "marketPrice":"8769.75",  # futures only
          #         "orderID":"wJXURIFBT",
          #         "orderQty":"100",
          #         "orderStatus":3,
          #         "orderType":1,
          #         "price":"8769.75",
          #         "quote":"USD",
          #         "rejectCode":0,
          #         "rejectReason":null,
          #         "settleType":"INVERSE",  # futures only
          #         "side":2,
          #         "stopPrice":"0",
          #         "symbol":"BTCUSDFP",
          #         "transactTime":"2019-11-12T07:05:52.000Z,
          #         "updateTime":"2019-11-12T07:05:52.000Z,
          #         "timeInForce":1,
          #         "execInst": "",
          #         "userID":"216214"
          #     }
          #
          # sometimes the timestamp is returned in milliseconds
          timestamp = self.safe_value(order, 'createTime')
          if isinstance(timestamp, basestring):
              timestamp = self.parse8601(timestamp)
          status = self.parse_order_status(self.safe_string(order, 'orderStatus'))
          type = self.parse_order_type(self.safe_string(order, 'orderType'))
          side = self.safe_string(order, 'side')
          if side == '1':
              side = 'buy'
          elif side == '2':
              side = 'sell'
          id = self.safe_string(order, 'orderID')
          clientOrderId = self.safe_string(order, 'clOrdID')
          marketId = self.safe_string(order, 'symbol')
          market = self.safe_market(marketId, market)
          symbol = market['symbol']
          price = self.safe_string(order, 'price')
          stopPrice = self.safe_number(order, 'stopPrice')
          timeInForce = self.parse_time_in_force(self.safe_string(order, 'timeInForce'))
          execInst = self.safe_string(order, 'execInst')
          postOnly = (execInst == 'Post-Only')
          average = self.safe_string(order, 'avgPrice')
          amount = self.safe_string(order, 'orderQty')
          filled = self.safe_string(order, 'cumQty')
          remaining = self.safe_string(order, 'leavesQty')
          if (Precise.string_equals(filled, '0')) and (Precise.string_equals(remaining, '0')):
              remaining = None
          lastTradeTimestamp = self.safe_value(order, 'transactTime')
          if isinstance(lastTradeTimestamp, basestring):
              lastTradeTimestamp = self.parse8601(lastTradeTimestamp)
          fee = None
          feeCost = self.safe_number(order, 'commission')
          if feeCost is not None:
              feeCurrency = None
              if market is not None:
                  if side == 'buy':
                      feeCurrency = market['base']
                  elif side == 'sell':
                      feeCurrency = market['quote']
              fee = {
                  'currency': feeCurrency,
                  'cost': feeCost,
              }
          return self.safe_order2({
              'id': id,
              'info': order,
              'clientOrderId': clientOrderId,
              'timestamp': timestamp,
              'datetime': self.iso8601(timestamp),
              'lastTradeTimestamp': lastTradeTimestamp,
              'status': status,
              'symbol': symbol,
              'type': type,
              'timeInForce': timeInForce,
              'postOnly': postOnly,
              'side': side,
              'price': price,
              'stopPrice': stopPrice,
              'average': average,
              'amount': amount,
              'filled': filled,
              'remaining': remaining,
              'cost': None,
              'trades': None,
              'fee': fee,
          })
  
      async def fetch_my_trades(self, symbol=None, since=None, limit=None, params={}):
          await self.load_markets()
          request = {
              # 'pageNum': '1',
              # 'pageSize': '10',
              # 'symbol': market['id'],
              # 'orderID': id,
              # 'base': market['baseId'],
              # 'quote': market['quoteId'],
              # 'startDate': self.ymd(since),
              # 'endDate': self.ymd(self.milliseconds()),
              # 'orderType': None,  # MARKET, LIMIT, STOP, STOP-LIMIT
              # 'side': 'None',  # BUY, SELL
          }
          method = None
          defaultType = self.safe_string_2(self.options, 'fetchMyTrades', 'defaultType', 'spot')
          type = self.safe_string(params, 'type', defaultType)
          params = self.omit(params, 'type')
          market = None
          if symbol is not None:
              market = self.market(symbol)
              request['symbol'] = market['id']
              type = market['type']
          if type == 'spot':
              method = 'privateGetSpotTrades'
          elif type == 'futures':
              method = 'privateGetFuturesTrades'
          if limit is not None:
              request['pageSize'] = limit  # default 10
          if since is not None:
              request['startDate'] = self.ymd(since)
          response = await getattr(self, method)(self.extend(request, params))
          #
          #     {
          #         "code":1,
          #         "data":{
          #             "list":[
          #                 {
          #                     "avgPrice":"1199.8",
          #                     "base":"ETH",
          #                     "clOrdID":null,
          #                     "commission":"0.00002",
          #                     "createTime":"2021-01-11T02:47:51.512Z",
          #                     "cumQty":"0.02",
          #                     "filledOrderID":"1eUD4F5rwK",
          #                     "filledPrice":"1199.8",
          #                     "filledQty":"0.02",
          #                     "leavesQty":"0",
          #                     "oCreateTime":"2021-01-11T02:47:51.377Z",
          #                     "orderID":"1eUD4EHfdU",
          #                     "orderQty":"0.02",
          #                     "orderStatus":3,
          #                     "orderType":1,
          #                     "price":"1198.25",
          #                     "quote":"USDT",
          #                     "rejectCode":null,
          #                     "rejectReason":null,
          #                     "side":1,
          #                     "stopPrice":"0",
          #                     "symbol":"ETHUSDT",
          #                     "taker":true,
          #                     "tradeID":"E04WTIgfmULU",
          #                     "transactTime":"2021-01-11T02:47:51.389Z",
          #                     "updateTime":null,
          #                     "userID":"1362494"
          #                 }
          #             ],
          #             "pageNum":1,
          #             "pageSize":10,
          #             "total":1
          #         },
          #         "message":"success",
          #         "ts":1610333278042
          #     }
          #
          data = self.safe_value(response, 'data', {})
          trades = self.safe_value(data, 'list', [])
          return self.parse_trades(trades, market, since, limit)
  
      async def fetch_deposit_address(self, code, params={}):
          await self.load_markets()
          currency = self.currency(code)
          request = {
              'currency': currency['id'],
              # 'network': None,  # 'ERC20
          }
          if 'network' in params:
              networks = self.safe_value(self.options, 'networks', {})
              network = self.safe_string_upper(params, 'network')
              params = self.omit(params, 'network')
              request['network'] = self.safe_string_upper(networks, network, network)
          response = await self.privateGetAccountDepositAddress(self.extend(request, params))
          #
          #     {
          #         "code":1,
          #         "data":{
          #             "address":"0x080c5c667381404cca9be0be9a04b2e47691ff86",
          #             "tag":null,
          #             "currency":"USDT",
          #             "network":"ERC20"
          #         },
          #         "message":"success",
          #         "ts":1610270465132
          #     }
          #
          data = self.safe_value(response, 'data', {})
          return self.parse_deposit_address(data, currency)
  
      def parse_deposit_address(self, depositAddress, currency=None):
          #
          #     {
          #         "address":"0x080c5c667381404cca9be0be9a04b2e47691ff86",
          #         "tag":null,
          #         "currency":"USDT",
          #         "network":"ERC20"
          #     }
          #
          address = self.safe_string(depositAddress, 'address')
          tag = self.safe_string(depositAddress, 'tag')
          currencyId = self.safe_string(depositAddress, 'currency')
          network = self.safe_string(depositAddress, 'network')
          if network is not None:
              currencyId = currencyId.replace(network, '')
          code = self.safe_currency_code(currencyId)
          return {
              'info': depositAddress,
              'code': code,
              'address': address,
              'tag': tag,
              'network': network,
          }
  
      def nonce(self):
          return self.milliseconds()
  
      def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
          url = '/' + self.implode_params(path, params)
          query = self.omit(params, self.extract_params(path))
          if api == 'v1':
              if query:
                  url += '?' + self.urlencode(query)
          else:
              url = '/' + self.version + url
              if api == 'public':
                  if query:
                      url += '?' + self.urlencode(query)
              elif api == 'private':
                  self.check_required_credentials()
                  nonce = str(self.nonce())
                  headers = {
                      'X-ACCESS-KEY': self.apiKey,
                      'X-ACCESS-NONCE': nonce,
                  }
                  auth = nonce + ':' + method
                  if method == 'GET':
                      if query:
                          url += '?' + self.urlencode(query)
                      auth += url
                  else:
                      headers['Content-Type'] = 'application/json'
                      body = self.json(query)
                      auth += url + body
                  signature = self.hmac(self.encode(auth), self.encode(self.secret))
                  headers['X-ACCESS-SIGN'] = signature
          url = self.implode_hostname(self.urls['api'][api]) + url
          return {'url': url, 'method': method, 'body': body, 'headers': headers}
  
      def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
          if response is None:
              return  # fallback to default error handler
          #
          #     {"code":40102,"message":"Unauthorized(invalid key)"}
          #
          errorCode = self.safe_string(response, 'code')
          if (errorCode is not None) and (errorCode != '1'):
              feedback = self.id + ' ' + self.json(response)
              self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
              self.throw_broadly_matched_exception(self.exceptions['broad'], body, feedback)
  