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.base.exchange import Exchange
  from ccxt.base.errors import ExchangeError
  from ccxt.base.errors import AuthenticationError
  from ccxt.base.errors import PermissionDenied
  from ccxt.base.errors import AccountNotEnabled
  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 NotSupported
  from ccxt.base.errors import DDoSProtection
  from ccxt.base.errors import InvalidNonce
  from ccxt.base.precise import Precise
  
  
  class cryptocom(Exchange):
  
      def describe(self):
          return self.deep_extend(super(cryptocom, self).describe(), {
              'id': 'cryptocom',
              'name': 'Crypto.com',
              'countries': ['MT'],
              'version': 'v2',
              'rateLimit': 10,  # 100 requests per second
              'has': {
                  'CORS': False,
                  'spot': True,
                  'margin': None,  # has but not fully implemented
                  'swap': None,  # has but not fully implemented
                  'future': None,  # has but not fully implemented
                  'option': None,
                  'cancelAllOrders': True,
                  'cancelOrder': True,
                  'createOrder': True,
                  'fetchBalance': True,
                  'fetchBidsAsks': False,
                  'fetchClosedOrders': 'emulated',
                  'fetchCurrencies': False,
                  'fetchDepositAddress': True,
                  'fetchDepositAddressesByNetwork': True,
                  'fetchDeposits': True,
                  'fetchFundingHistory': False,
                  'fetchFundingRate': False,
                  'fetchFundingRates': False,
                  'fetchMarkets': True,
                  'fetchMyTrades': True,
                  'fetchOHLCV': True,
                  'fetchOpenOrders': True,
                  'fetchOrder': True,
                  'fetchOrderBook': True,
                  'fetchOrders': True,
                  'fetchPositions': False,
                  'fetchStatus': False,
                  'fetchTicker': True,
                  'fetchTickers': True,
                  'fetchTime': False,
                  'fetchTrades': True,
                  'fetchTradingFee': False,
                  'fetchTradingFees': False,
                  'fetchTransactionFees': False,
                  'fetchTransactions': False,
                  'fetchTransfers': True,
                  'fetchWithdrawals': True,
                  'setLeverage': False,
                  'setMarginMode': False,
                  'transfer': True,
                  'withdraw': True,
              },
              'timeframes': {
                  '1m': '1m',
                  '5m': '5m',
                  '15m': '15m',
                  '30m': '30m',
                  '1h': '1h',
                  '4h': '4h',
                  '6h': '6h',
                  '12h': '12h',
                  '1d': '1D',
                  '1w': '7D',
                  '2w': '14D',
                  '1M': '1M',
              },
              'urls': {
                  'logo': 'https://user-images.githubusercontent.com/1294454/147792121-38ed5e36-c229-48d6-b49a-48d05fc19ed4.jpeg',
                  'test': 'https://uat-api.3ona.co/v2',
                  'api': {
                      'spot': 'https://api.crypto.com/v2',
                      'derivatives': 'https://deriv-api.crypto.com/v1',
                  },
                  'www': 'https://crypto.com/',
                  'referral': 'https://crypto.com/exch/5835vstech',
                  'doc': 'https://exchange-docs.crypto.com/',
                  'fees': 'https://crypto.com/exchange/document/fees-limits',
              },
              'api': {
                  'spot': {
                      'public': {
                          'get': {
                              'public/auth': 1,
                              'public/get-instruments': 1,
                              'public/get-book': 1,
                              'public/get-candlestick': 1,
                              'public/get-ticker': 1,
                              'public/get-trades': 1,
                              'public/margin/get-transfer-currencies': 1,
                              'public/margin/get-load-currenices': 1,
                              'public/respond-heartbeat': 1,
                          },
                      },
                      'private': {
                          'post': {
                              'private/set-cancel-on-disconnect': 10 / 3,
                              'private/get-cancel-on-disconnect': 10 / 3,
                              'private/create-withdrawal': 10 / 3,
                              'private/get-withdrawal-history': 10 / 3,
                              'private/get-deposit-history': 10 / 3,
                              'private/get-deposit-address': 10 / 3,
                              'private/get-account-summary': 10 / 3,
                              'private/create-order': 2 / 3,
                              'private/cancel-order': 2 / 3,
                              'private/cancel-all-orders': 2 / 3,
                              'private/get-order-history': 10 / 3,
                              'private/get-open-orders': 10 / 3,
                              'private/get-order-detail': 1 / 3,
                              'private/get-trades': 100,
                              'private/margin/get-user-config': 10 / 3,
                              'private/margin/get-account-summary': 10 / 3,
                              'private/margin/transfer': 10 / 3,
                              'private/margin/borrow': 10 / 3,
                              'private/margin/repay': 10 / 3,
                              'private/margin/get-transfer-history': 10 / 3,
                              'private/margin/get-borrow-history': 10 / 3,
                              'private/margin/get-interest-history': 10 / 3,
                              'private/margin/get-repay-history': 10 / 3,
                              'private/margin/get-liquidation-history': 10 / 3,
                              'private/margin/get-liquidation-orders': 10 / 3,
                              'private/margin/create-order': 2 / 3,
                              'private/margin/cancel-order': 2 / 3,
                              'private/margin/cancel-all-orders': 2 / 3,
                              'private/margin/get-order-history': 10 / 3,
                              'private/margin/get-open-orders': 10 / 3,
                              'private/margin/get-order-detail': 1 / 3,
                              'private/margin/get-trades': 100,
                              'private/deriv/transfer': 10 / 3,
                              'private/deriv/get-transfer-history': 10 / 3,
                              'private/subaccount/get-sub-accounts': 10 / 3,
                              'private/subaccount/get-transfer-history': 10 / 3,
                              'private/subaccount/transfer': 10 / 3,
                          },
                      },
                  },
                  'derivatives': {
                      'public': {
                          'get': {
                              'public/auth': 10 / 3,
                              'public/get-instruments': 10 / 3,
                              'public/get-book': 1,
                              'public/get-candlestick': 1,
                              'public/get-trades': 1,
                              'public/get-tickers': 1,
                              'public/get-valuations': 1,
                              'public/get-expired-settlement-price': 10 / 3,
                              'public/get-insurance': 1,
                          },
                      },
                      'private': {
                          'post': {
                              'private/set-cancel-on-disconnect': 10 / 3,
                              'private/get-cancel-on-disconnect': 10 / 3,
                              'private/user-balance': 10 / 3,
                              'private/user-balance-history': 10 / 3,
                              'private/get-positions': 10 / 3,
                              'private/create-order': 2 / 3,
                              'private/cancel-order': 2 / 3,
                              'private/cancel-all-orders': 2 / 3,
                              'private/close-position': 10 / 3,
                              'private/convert-collateral': 10 / 3,
                              'private/get-order-history': 100,
                              'private/get-open-orders': 10 / 3,
                              'private/get-order-detail': 1 / 3,
                              'private/get-trades': 100,
                              'private/change-account-leverage': 10 / 3,
                              'private/get-transactions': 10 / 3,
                          },
                      },
                  },
              },
              'fees': {
                  'trading': {
                      'maker': self.parse_number('0.004'),
                      'taker': self.parse_number('0.004'),
                      'tiers': {
                          'maker': [
                              [self.parse_number('0'), self.parse_number('0.004')],
                              [self.parse_number('25000'), self.parse_number('0.0035')],
                              [self.parse_number('50000'), self.parse_number('0.0015')],
                              [self.parse_number('100000'), self.parse_number('0.001')],
                              [self.parse_number('250000'), self.parse_number('0.0009')],
                              [self.parse_number('1000000'), self.parse_number('0.0008')],
                              [self.parse_number('20000000'), self.parse_number('0.0007')],
                              [self.parse_number('100000000'), self.parse_number('0.0006')],
                              [self.parse_number('200000000'), self.parse_number('0.0004')],
                          ],
                          'taker': [
                              [self.parse_number('0'), self.parse_number('0.004')],
                              [self.parse_number('25000'), self.parse_number('0.0035')],
                              [self.parse_number('50000'), self.parse_number('0.0025')],
                              [self.parse_number('100000'), self.parse_number('0.0016')],
                              [self.parse_number('250000'), self.parse_number('0.00015')],
                              [self.parse_number('1000000'), self.parse_number('0.00014')],
                              [self.parse_number('20000000'), self.parse_number('0.00013')],
                              [self.parse_number('100000000'), self.parse_number('0.00012')],
                              [self.parse_number('200000000'), self.parse_number('0.0001')],
                          ],
                      },
                  },
              },
              'options': {
                  'defaultType': 'spot',
                  'accountsByType': {
                      'funding': 'SPOT',
                      'spot': 'SPOT',
                      'derivatives': 'DERIVATIVES',
                      'swap': 'DERIVATIVES',
                      'future': 'DERIVATIVES',
                  },
              },
              # https://exchange-docs.crypto.com/spot/index.html#response-and-reason-codes
              'commonCurrencies': {
                  'USD_STABLE_COIN': 'USDC',
              },
              'exceptions': {
                  'exact': {
                      '10001': ExchangeError,
                      '10002': PermissionDenied,
                      '10003': PermissionDenied,
                      '10004': BadRequest,
                      '10005': PermissionDenied,
                      '10006': DDoSProtection,
                      '10007': InvalidNonce,
                      '10008': BadRequest,
                      '10009': BadRequest,
                      '20001': BadRequest,
                      '20002': InsufficientFunds,
                      '20005': AccountNotEnabled,  # {"id":"123xxx","method":"private/margin/xxx","code":"20005","message":"ACCOUNT_NOT_FOUND"}
                      '30003': BadSymbol,
                      '30004': BadRequest,
                      '30005': BadRequest,
                      '30006': BadRequest,
                      '30007': BadRequest,
                      '30008': BadRequest,
                      '30009': BadRequest,
                      '30010': BadRequest,
                      '30013': BadRequest,
                      '30014': BadRequest,
                      '30016': BadRequest,
                      '30017': BadRequest,
                      '30023': BadRequest,
                      '30024': BadRequest,
                      '30025': BadRequest,
                      '40001': BadRequest,
                      '40002': BadRequest,
                      '40003': BadRequest,
                      '40004': BadRequest,
                      '40005': BadRequest,
                      '40006': BadRequest,
                      '40007': BadRequest,
                      '40101': AuthenticationError,
                      '50001': BadRequest,
                  },
              },
          })
  
      def fetch_markets(self, params={}):
          #
          #    {
          #        id: 11,
          #        method: 'public/get-instruments',
          #        code: 0,
          #        result: {
          #            'instruments': [
          #                {
          #                    instrument_name: 'NEAR_BTC',
          #                    quote_currency: 'BTC',
          #                    base_currency: 'NEAR',
          #                    price_decimals: '8',
          #                    quantity_decimals: '2',
          #                    margin_trading_enabled: True,
          #                    margin_trading_enabled_5x: True,
          #                    margin_trading_enabled_10x: True,
          #                    max_quantity: '100000000',
          #                    min_quantity: '0.01'
          #               },
          #            ]
          #        }
          #    }
          #
          response = self.spotPublicGetPublicGetInstruments(params)
          resultResponse = self.safe_value(response, 'result', {})
          markets = self.safe_value(resultResponse, 'instruments', [])
          result = []
          for i in range(0, len(markets)):
              market = markets[i]
              id = self.safe_string(market, 'instrument_name')
              baseId = self.safe_string(market, 'base_currency')
              quoteId = self.safe_string(market, 'quote_currency')
              base = self.safe_currency_code(baseId)
              quote = self.safe_currency_code(quoteId)
              priceDecimals = self.safe_string(market, 'price_decimals')
              minPrice = self.parse_precision(priceDecimals)
              minQuantity = self.safe_string(market, 'min_quantity')
              maxLeverage = self.parse_number('1')
              margin_trading_enabled_5x = self.safe_value(market, 'margin_trading_enabled_5x')
              if margin_trading_enabled_5x:
                  maxLeverage = self.parse_number('5')
              margin_trading_enabled_10x = self.safe_value(market, 'margin_trading_enabled_10x')
              if margin_trading_enabled_10x:
                  maxLeverage = self.parse_number('10')
              result.append({
                  'id': id,
                  'symbol': base + '/' + quote,
                  'base': base,
                  'quote': quote,
                  'settle': None,
                  'baseId': baseId,
                  'quoteId': quoteId,
                  'settleId': None,
                  'type': 'spot',
                  'spot': True,
                  'margin': self.safe_value(market, 'margin_trading_enabled'),
                  'swap': False,
                  'future': False,
                  'option': False,
                  'active': None,
                  'contract': False,
                  'linear': None,
                  'inverse': None,
                  'contractSize': None,
                  'expiry': None,
                  'expiryDatetime': None,
                  'strike': None,
                  'optionType': None,
                  'precision': {
                      'amount': self.safe_integer(market, 'quantity_decimals'),
                      'price': int(priceDecimals),
                  },
                  'limits': {
                      'leverage': {
                          'min': self.parse_number('1'),
                          'max': maxLeverage,
                      },
                      'amount': {
                          'min': self.parse_number(minQuantity),
                          'max': self.safe_number(market, 'max_quantity'),
                      },
                      'price': {
                          'min': self.parse_number(minPrice),
                          'max': None,
                      },
                      'cost': {
                          'min': self.parse_number(Precise.string_mul(minQuantity, minPrice)),
                          'max': None,
                      },
                  },
                  'info': market,
              })
          futuresResponse = self.derivativesPublicGetPublicGetInstruments()
          #
          #     {
          #       id: -1,
          #       method: 'public/get-instruments',
          #       code: 0,
          #       result: {
          #         data: [
          #           {
          #             symbol: '1INCHUSD-PERP',
          #             inst_type: 'PERPETUAL_SWAP',
          #             display_name: '1INCHUSD Perpetual',
          #             base_ccy: '1INCH',
          #             quote_ccy: 'USD_Stable_Coin',
          #             quote_decimals: 4,
          #             quantity_decimals: 0,
          #             price_tick_size: '0.0001',
          #             qty_tick_size: '1',
          #             max_leverage: '50',
          #             tradable: True,
          #             expiry_timestamp_ms: 0,
          #             beta_product: False,
          #             underlying_symbol: '1INCHUSD-INDEX',
          #             put_call: 'UNDEFINED',
          #             strike: '0',
          #             contract_size: '1'
          #           },
          #         ]
          #       }
          #     }
          #
          futuresResult = self.safe_value(futuresResponse, 'result', {})
          data = self.safe_value(futuresResult, 'data', [])
          for i in range(0, len(data)):
              market = data[i]
              inst_type = self.safe_string(market, 'inst_type')
              swap = inst_type == 'PERPETUAL_SWAP'
              future = inst_type == 'FUTURE'
              baseId = self.safe_string(market, 'base_ccy')
              quoteId = self.safe_string(market, 'quote_ccy')
              base = self.safe_currency_code(baseId)
              quote = self.safe_currency_code(quoteId)
              symbol = base + '/' + quote + ':' + quote
              expiry = self.safe_integer(market, 'expiry_timestamp_ms')
              if expiry == 0:
                  expiry = None
              type = 'swap'
              if future:
                  type = 'future'
                  symbol = symbol + '-' + self.yymmdd(expiry)
              contractSize = self.safe_number(market, 'contract_size')
              result.append({
                  'id': self.safe_string(market, 'symbol'),
                  'symbol': symbol,
                  'base': base,
                  'quote': quote,
                  'settle': quote,
                  'baseId': baseId,
                  'quoteId': quoteId,
                  'settleId': quoteId,
                  'type': type,
                  'spot': False,
                  'margin': False,
                  'swap': swap,
                  'future': future,
                  'option': False,
                  'active': self.safe_value(market, 'tradable'),
                  'contract': True,
                  'linear': True,
                  'inverse': False,
                  'contractSize': contractSize,
                  'expiry': expiry,
                  'expiryDatetime': self.iso8601(expiry),
                  'strike': None,
                  'optionType': None,
                  'precision': {
                      'price': self.safe_integer(market, 'quote_decimals'),
                      'amount': self.safe_integer(market, 'quantity_decimals'),
                  },
                  'limits': {
                      'leverage': {
                          'min': self.parse_number('1'),
                          'max': self.safe_number(market, 'max_leverage'),
                      },
                      'amount': {
                          'min': self.parse_number(contractSize),
                          'max': None,
                      },
                      'price': {
                          'min': None,
                          'max': None,
                      },
                      'cost': {
                          'min': None,
                          'max': None,
                      },
                  },
                  'info': market,
              })
          return result
  
      def fetch_tickers(self, symbols=None, params={}):
          self.load_markets()
          marketType, query = self.handle_market_type_and_params('fetchTickers', None, params)
          method = self.get_supported_mapping(marketType, {
              'spot': 'spotPublicGetPublicGetTicker',
              'future': 'derivativesPublicGetPublicGetTickers',
              'swap': 'derivativesPublicGetPublicGetTickers',
          })
          response = getattr(self, method)(query)
          # {
          #     "code":0,
          #     "method":"public/get-ticker",
          #     "result":{
          #       "data": [
          #         {"i":"CRO_BTC","b":0.00000890,"k":0.00001179,"a":0.00001042,"t":1591770793901,"v":14905879.59,"h":0.00,"l":0.00,"c":0.00},
          #         {"i":"EOS_USDT","b":2.7676,"k":2.7776,"a":2.7693,"t":1591770798500,"v":774.51,"h":0.05,"l":0.05,"c":0.00},
          #         {"i":"BCH_USDT","b":247.49,"k":251.73,"a":251.67,"t":1591770797601,"v":1.01693,"h":0.01292,"l":0.01231,"c":-0.00047},
          #         {"i":"ETH_USDT","b":239.92,"k":242.59,"a":240.30,"t":1591770798701,"v":0.97575,"h":0.01236,"l":0.01199,"c":-0.00018},
          #         {"i":"ETH_CRO","b":2693.11,"k":2699.84,"a":2699.55,"t":1591770795053,"v":95.680,"h":8.218,"l":7.853,"c":-0.050}
          #       ]
          #     }
          # }
          resultResponse = self.safe_value(response, 'result', {})
          tickers = self.safe_value(resultResponse, 'data', [])
          result = {}
          for i in range(0, len(tickers)):
              ticker = tickers[i]
              marketId = self.safe_string(ticker, 'i')
              market = self.safe_market(marketId, None, '_')
              symbol = market['symbol']
              result[symbol] = self.parse_ticker(ticker, market)
          unifiedSymbols = []
          for i in range(0, len(symbols)):
              market = self.market(symbols[i])
              if market is not None:
                  unifiedSymbols.append(market['symbol'])
          return self.filter_by_array(result, 'symbol', unifiedSymbols)
  
      def fetch_ticker(self, symbol, params={}):
          self.load_markets()
          market = self.market(symbol)
          request = {
              'instrument_name': market['id'],
          }
          marketType, query = self.handle_market_type_and_params('fetchTicker', market, params)
          if marketType != 'spot':
              raise NotSupported(self.id + ' fetchTicker() only supports spot markets')
          response = self.spotPublicGetPublicGetTicker(self.extend(request, query))
          # {
          #     "code":0,
          #     "method":"public/get-ticker",
          #     "result":{
          #       "data": {"i":"CRO_BTC","b":0.00000890,"k":0.00001179,"a":0.00001042,"t":1591770793901,"v":14905879.59,"h":0.00,"l":0.00,"c":0.00}
          #     }
          # }
          resultResponse = self.safe_value(response, 'result', {})
          data = self.safe_value(resultResponse, 'data', {})
          return self.parse_ticker(data, market)
  
      def fetch_orders(self, symbol=None, since=None, limit=None, params={}):
          if symbol is None:
              raise ArgumentsRequired(self.id + ' fetchClosedOrders() requires a symbol argument')
          self.load_markets()
          market = self.market(symbol)
          request = {
              'instrument_name': market['id'],
          }
          if since is not None:
              # maximum date range is one day
              request['start_ts'] = since
          if limit is not None:
              request['page_size'] = limit
          marketType, query = self.handle_market_type_and_params('fetchOrders', market, params)
          method = self.get_supported_mapping(marketType, {
              'spot': 'spotPrivatePostPrivateGetOrderHistory',
              'future': 'derivativesPrivatePostPrivateGetOrderHistory',
              'swap': 'derivativesPrivatePostPrivateGetOrderHistory',
          })
          response = getattr(self, method)(self.extend(request, query))
          #
          # spot
          #     {
          #       id: 1641026542065,
          #       method: 'private/get-order-history',
          #       code: 0,
          #       result: {
          #         order_list: [
          #           {
          #             status: 'FILLED',
          #             side: 'BUY',
          #             price: 0,
          #             quantity: 110,
          #             order_id: '2120246337927715937',
          #             client_oid: '',
          #             create_time: 1641025064904,
          #             update_time: 1641025064958,
          #             type: 'MARKET',
          #             instrument_name: 'USDC_USDT',
          #             avg_price: 1.0001,
          #             cumulative_quantity: 110,
          #             cumulative_value: 110.011,
          #             fee_currency: 'USDC',
          #             exec_inst: '',
          #             time_in_force: 'GOOD_TILL_CANCEL'
          #           }
          #         ]
          #       }
          #     }
          #
          # swap
          #     {
          #       id: 1641026373106,
          #       method: 'private/get-order-history',
          #       code: 0,
          #       result: {
          #         data: [
          #           {
          #             account_id: '85ff689a-7508-4b96-aa79-dc0545d6e637',
          #             order_id: 13191401932,
          #             client_oid: '1641025941461',
          #             order_type: 'LIMIT',
          #             time_in_force: 'GOOD_TILL_CANCEL',
          #             side: 'BUY',
          #             exec_inst: [],
          #             quantity: '0.0001',
          #             limit_price: '48000.0',
          #             order_value: '4.80000000',
          #             maker_fee_rate: '0.00050',
          #             taker_fee_rate: '0.00070',
          #             avg_price: '47253.5',
          #             trigger_price: '0.0',
          #             ref_price_type: 'NULL_VAL',
          #             cumulative_quantity: '0.0001',
          #             cumulative_value: '4.72535000',
          #             cumulative_fee: '0.00330775',
          #             status: 'FILLED',
          #             update_user_id: 'ce075bef-b600-4277-bd6e-ff9007251e63',
          #             order_date: '2022-01-01',
          #             instrument_name: 'BTCUSD-PERP',
          #             fee_instrument_name: 'USD_Stable_Coin',
          #             create_time: 1641025941827,
          #             create_time_ns: '1641025941827994756',
          #             update_time: 1641025941827
          #           }
          #         ]
          #       }
          #     }
          #
          data = self.safe_value(response, 'result', {})
          orderList = self.safe_value_2(data, 'order_list', 'data', [])
          return self.parse_orders(orderList, market, since, limit)
  
      def fetch_trades(self, symbol, since=None, limit=None, params={}):
          self.load_markets()
          market = self.market(symbol)
          request = {
              'instrument_name': market['id'],
          }
          if since is not None:
              # maximum date range is one day
              request['start_ts'] = since
          if limit is not None:
              request['page_size'] = limit
          marketType, query = self.handle_market_type_and_params('fetchTrades', market, params)
          method = self.get_supported_mapping(marketType, {
              'spot': 'spotPublicGetPublicGetTrades',
              'future': 'derivativesPublicGetPublicGetTrades',
              'swap': 'derivativesPublicGetPublicGetTrades',
          })
          response = getattr(self, method)(self.extend(request, query))
          # {
          #     "code":0,
          #     "method":"public/get-trades",
          #     "result": {
          #          "instrument_name": "BTC_USDT",
          #          "data:": [
          #              {"dataTime":1591710781947,"d":465533583799589409,"s":"BUY","p":2.96,"q":16.0,"t":1591710781946,"i":"ICX_CRO"},
          #              {"dataTime":1591707701899,"d":465430234542863152,"s":"BUY","p":0.007749,"q":115.0,"t":1591707701898,"i":"VET_USDT"},
          #              {"dataTime":1591710786155,"d":465533724976458209,"s":"SELL","p":25.676,"q":0.55,"t":1591710786154,"i":"XTZ_CRO"},
          #              {"dataTime":1591710783300,"d":465533629172286576,"s":"SELL","p":2.9016,"q":0.6,"t":1591710783298,"i":"XTZ_USDT"},
          #              {"dataTime":1591710784499,"d":465533669425626384,"s":"SELL","p":2.7662,"q":0.58,"t":1591710784498,"i":"EOS_USDT"},
          #              {"dataTime":1591710784700,"d":465533676120104336,"s":"SELL","p":243.21,"q":0.01647,"t":1591710784698,"i":"ETH_USDT"},
          #              {"dataTime":1591710786600,"d":465533739878620208,"s":"SELL","p":253.06,"q":0.00516,"t":1591710786598,"i":"BCH_USDT"},
          #              {"dataTime":1591710786900,"d":465533749959572464,"s":"BUY","p":0.9999,"q":0.2,"t":1591710786898,"i":"USDC_USDT"},
          #              {"dataTime":1591710787500,"d":465533770081010000,"s":"BUY","p":3.159,"q":1.65,"t":1591710787498,"i":"ATOM_USDT"},
          #            ]
          #      }
          # }
          resultResponse = self.safe_value(response, 'result', {})
          data = self.safe_value(resultResponse, 'data', [])
          return self.parse_trades(data, market, since, limit)
  
      def fetch_ohlcv(self, symbol, timeframe='1m', since=None, limit=None, params={}):
          self.load_markets()
          market = self.market(symbol)
          request = {
              'instrument_name': market['id'],
              'timeframe': self.timeframes[timeframe],
          }
          marketType, query = self.handle_market_type_and_params('fetchOHLCV', market, params)
          method = self.get_supported_mapping(marketType, {
              'spot': 'spotPublicGetPublicGetCandlestick',
              'future': 'derivativesPublicGetPublicGetCandlestick',
              'swap': 'derivativesPublicGetPublicGetCandlestick',
          })
          response = getattr(self, method)(self.extend(request, query))
          # {
          #     "code":0,
          #     "method":"public/get-candlestick",
          #     "result":{
          #       "instrument_name":"BTC_USDT",
          #       "interval":"5m",
          #       "data":[
          #         {"t":1596944700000,"o":11752.38,"h":11754.77,"l":11746.65,"c":11753.64,"v":3.694583},
          #         {"t":1596945000000,"o":11753.63,"h":11754.77,"l":11739.83,"c":11746.17,"v":2.073019},
          #         {"t":1596945300000,"o":11746.16,"h":11753.24,"l":11738.1,"c":11740.65,"v":0.867247},
          #         ...
          #       ]
          #     }
          # }
          resultResponse = self.safe_value(response, 'result', {})
          data = self.safe_value(resultResponse, 'data', [])
          return self.parse_ohlcvs(data, market, timeframe, since, limit)
  
      def fetch_order_book(self, symbol, limit=None, params={}):
          self.load_markets()
          market = self.market(symbol)
          request = {
              'instrument_name': market['id'],
          }
          if limit:
              request['depth'] = limit
          marketType, query = self.handle_market_type_and_params('fetchOrderBook', market, params)
          method = self.get_supported_mapping(marketType, {
              'spot': 'spotPublicGetPublicGetBook',
              'future': 'derivativesPublicGetPublicGetBook',
              'swap': 'derivativesPublicGetPublicGetBook',
          })
          response = getattr(self, method)(self.extend(request, query))
          # {
          #     "code":0,
          #     "method":"public/get-book",
          #     "result":{
          #       "bids":[[9668.44,0.006325,1.0],[9659.75,0.006776,1.0],[9653.14,0.011795,1.0],[9647.13,0.019434,1.0],[9634.62,0.013765,1.0],[9633.81,0.021395,1.0],[9628.46,0.037834,1.0],[9627.6,0.020909,1.0],[9621.51,0.026235,1.0],[9620.83,0.026701,1.0]],
          #       "asks":[[9697.0,0.68251,1.0],[9697.6,1.722864,2.0],[9699.2,1.664177,2.0],[9700.8,1.824953,2.0],[9702.4,0.85778,1.0],[9704.0,0.935792,1.0],[9713.32,0.002926,1.0],[9716.42,0.78923,1.0],[9732.19,0.00645,1.0],[9737.88,0.020216,1.0]],
          #       "t":1591704180270
          #     }
          # }
          result = self.safe_value(response, 'result')
          data = self.safe_value(result, 'data')
          orderBook = self.safe_value(data, 0)
          timestamp = self.safe_integer(orderBook, 't')
          return self.parse_order_book(orderBook, symbol, timestamp)
  
      def parse_swap_balance(self, response):
          responseResult = self.safe_value(response, 'result', {})
          data = self.safe_value(responseResult, 'data', [])
          result = {'info': response}
          for i in range(0, len(data)):
              balance = data[i]
              currencyId = self.safe_string(balance, 'instrument_name')
              code = self.safe_currency_code(currencyId)
              account = self.account()
              account['total'] = self.safe_string(balance, 'total_cash_balance')
              account['free'] = self.safe_string(balance, 'total_available_balance')
              result[code] = account
          return self.safe_balance(result)
  
      def parse_spot_balance(self, response):
          data = self.safe_value(response, 'result', {})
          coinList = self.safe_value(data, 'accounts', [])
          result = {'info': response}
          for i in range(0, len(coinList)):
              balance = coinList[i]
              currencyId = self.safe_string(balance, 'currency')
              code = self.safe_currency_code(currencyId)
              account = self.account()
              account['total'] = self.safe_string(balance, 'balance')
              account['free'] = self.safe_string(balance, 'available')
              account['used'] = self.safe_string(balance, 'order')
              result[code] = account
          return self.safe_balance(result)
  
      def fetch_balance(self, params={}):
          self.load_markets()
          marketType, query = self.handle_market_type_and_params('fetchBalance', None, params)
          method = self.get_supported_mapping(marketType, {
              'spot': 'spotPrivatePostPrivateGetAccountSummary',
              'future': 'derivativesPrivatePostPrivateUserBalance',
              'swap': 'derivativesPrivatePostPrivateUserBalance',
          })
          response = getattr(self, method)(query)
          # spot
          #     {
          #         "id": 11,
          #         "method": "private/get-account-summary",
          #         "code": 0,
          #         "result": {
          #             "accounts": [
          #                 {
          #                     "balance": 99999999.905000000000000000,
          #                     "available": 99999996.905000000000000000,
          #                     "order": 3.000000000000000000,
          #                     "stake": 0,
          #                     "currency": "CRO"
          #                 }
          #             ]
          #         }
          #     }
          #
          # swap
          #     {
          #       "id" : 1641025392400,
          #       "method" : "private/user-balance",
          #       "code" : 0,
          #       "result" : {
          #         "data" : [{
          #           "total_available_balance" : "109.56000000",
          #           "total_margin_balance" : "109.56000000",
          #           "total_initial_margin" : "0.00000000",
          #           "total_maintenance_margin" : "0.00000000",
          #           "total_position_cost" : "0.00000000",
          #           "total_cash_balance" : "109.56000000",
          #           "total_collateral_value" : "109.56000000",
          #           "total_session_unrealized_pnl" : "0.00000000",
          #           "instrument_name" : "USD_Stable_Coin",
          #           "total_session_realized_pnl" : "0.00000000",
          #           "position_balances" : [{
          #             "quantity" : "109.56000000",
          #             "collateral_weight" : "1.000000",
          #             "collateral_amount" : "109.56000000",
          #             "market_value" : "109.56000000",
          #             "max_withdrawal_balance" : "109.56000000",
          #             "instrument_name" : "USD_Stable_Coin"
          #           }],
          #           "total_effective_leverage" : "0.000000",
          #           "position_limit" : "3000000.00000000",
          #           "used_position_limit" : "0.00000000",
          #           "is_liquidating" : False
          #         }]
          #       }
          #     }
          #
          parser = self.get_supported_mapping(marketType, {
              'spot': 'parseSpotBalance',
              'future': 'parseSwapBalance',
              'swap': 'parseSwapBalance',
          })
          return getattr(self, parser)(response)
  
      def fetch_order(self, id, symbol=None, params={}):
          self.load_markets()
          market = None
          if symbol is not None:
              market = self.market(symbol)
          request = {}
          marketType, query = self.handle_market_type_and_params('fetchOrder', market, params)
          if marketType == 'spot':
              request['order_id'] = str(id)
          else:
              request['order_id'] = int(id)
          method = self.get_supported_mapping(marketType, {
              'spot': 'spotPrivatePostPrivateGetOrderDetail',
              'future': 'derivativesPrivatePostPrivateGetOrderDetail',
              'swap': 'derivativesPrivatePostPrivateGetOrderDetail',
          })
          response = getattr(self, method)(self.extend(request, query))
          # {
          #     "id": 11,
          #     "method": "private/get-order-detail",
          #     "code": 0,
          #     "result": {
          #       "trade_list": [
          #         {
          #           "side": "BUY",
          #           "instrument_name": "ETH_CRO",
          #           "fee": 0.007,
          #           "trade_id": "371303044218155296",
          #           "create_time": 1588902493045,
          #           "traded_price": 7,
          #           "traded_quantity": 7,
          #           "fee_currency": "CRO",
          #           "order_id": "371302913889488619"
          #         }
          #       ],
          #       "order_info": {
          #         "status": "FILLED",
          #         "side": "BUY",
          #         "order_id": "371302913889488619",
          #         "client_oid": "9_yMYJDNEeqHxLqtD_2j3g",
          #         "create_time": 1588902489144,
          #         "update_time": 1588902493024,
          #         "type": "LIMIT",
          #         "instrument_name": "ETH_CRO",
          #         "cumulative_quantity": 7,
          #         "cumulative_value": 7,
          #         "avg_price": 7,
          #         "fee_currency": "CRO",
          #         "time_in_force": "GOOD_TILL_CANCEL",
          #         "exec_inst": "POST_ONLY"
          #       }
          #     }
          # }
          result = self.safe_value(response, 'result', {})
          order = self.safe_value(result, 'order_info', result)
          return self.parse_order(order, market)
  
      def create_order(self, symbol, type, side, amount, price=None, params={}):
          self.load_markets()
          market = self.market(symbol)
          uppercaseType = type.upper()
          request = {
              'instrument_name': market['id'],
              'side': side.upper(),
              'type': uppercaseType,
              'quantity': self.amount_to_precision(symbol, amount),
          }
          if (uppercaseType == 'LIMIT') or (uppercaseType == 'STOP_LIMIT'):
              request['price'] = self.price_to_precision(symbol, price)
          postOnly = self.safe_value(params, 'postOnly', False)
          if postOnly:
              request['exec_inst'] = 'POST_ONLY'
              params = self.omit(params, ['postOnly'])
          marketType, query = self.handle_market_type_and_params('createOrder', market, params)
          method = self.get_supported_mapping(marketType, {
              'spot': 'spotPrivatePostPrivateCreateOrder',
              'future': 'derivativesPrivatePostPrivateCreateOrder',
              'swap': 'derivativesPrivatePostPrivateCreateOrder',
          })
          response = getattr(self, method)(self.extend(request, query))
          # {
          #     "id": 11,
          #     "method": "private/create-order",
          #     "result": {
          #       "order_id": "337843775021233500",
          #       "client_oid": "my_order_0002"
          #     }
          # }
          result = self.safe_value(response, 'result', {})
          return self.parse_order(result, market)
  
      def cancel_all_orders(self, symbol=None, params={}):
          self.load_markets()
          market = None
          if symbol is not None:
              market = self.market(symbol)
          request = {}
          marketType, query = self.handle_market_type_and_params('cancelAllOrders', market, params)
          if marketType == 'spot':
              if symbol is None:
                  raise ArgumentsRequired(self.id + ' cancelAllOrders() requires a symbol argument for ' + marketType + ' orders')
              request['instrument_name'] = market['id']
          method = self.get_supported_mapping(marketType, {
              'spot': 'spotPrivatePostPrivateCancelAllOrders',
              'future': 'derivativesPrivatePostPrivateCancelAllOrders',
              'swap': 'derivativesPrivatePostPrivateCancelAllOrders',
          })
          return getattr(self, method)(self.extend(request, query))
  
      def cancel_order(self, id, symbol=None, params={}):
          self.load_markets()
          market = None
          if symbol is not None:
              market = self.market(symbol)
          request = {}
          marketType, query = self.handle_market_type_and_params('cancelOrder', market, params)
          if marketType == 'spot':
              if symbol is None:
                  raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument for ' + marketType + ' orders')
              request['instrument_name'] = market['id']
              request['order_id'] = str(id)
          else:
              request['order_id'] = int(id)
          method = self.get_supported_mapping(marketType, {
              'spot': 'spotPrivatePostPrivateCancelOrder',
              'future': 'derivativesPrivatePostPrivateCancelOrder',
              'swap': 'derivativesPrivatePostPrivateCancelOrder',
          })
          response = getattr(self, method)(self.extend(request, query))
          result = self.safe_value(response, 'result', response)
          return self.parse_order(result)
  
      def fetch_open_orders(self, symbol=None, since=None, limit=None, params={}):
          self.load_markets()
          market = None
          request = {}
          if symbol is not None:
              market = self.market(symbol)
              request['instrument_name'] = market['id']
          if limit is not None:
              request['page_size'] = limit
          marketType, query = self.handle_market_type_and_params('fetchOpenOrders', market, params)
          method = self.get_supported_mapping(marketType, {
              'spot': 'spotPrivatePostPrivateGetOpenOrders',
              'future': 'derivativesPrivatePostPrivateGetOpenOrders',
              'swap': 'derivativesPrivatePostPrivateGetOpenOrders',
          })
          response = getattr(self, method)(self.extend(request, query))
          # {
          #     "id": 11,
          #     "method": "private/get-open-orders",
          #     "code": 0,
          #     "result": {
          #       "count": 1177,
          #       "order_list": [
          #         {
          #           "status": "ACTIVE",
          #           "side": "BUY",
          #           "price": 1,
          #           "quantity": 1,
          #           "order_id": "366543374673423753",
          #           "client_oid": "my_order_0002",
          #           "create_time": 1588760643829,
          #           "update_time": 1588760644292,
          #           "type": "LIMIT",
          #           "instrument_name": "ETH_CRO",
          #           "cumulative_quantity": 0,
          #           "cumulative_value": 0,
          #           "avg_price": 0,
          #           "fee_currency": "CRO",
          #           "time_in_force": "GOOD_TILL_CANCEL"
          #         },
          #         {
          #           "status": "ACTIVE",
          #           "side": "BUY",
          #           "price": 1,
          #           "quantity": 1,
          #           "order_id": "366455245775097673",
          #           "client_oid": "my_order_0002",
          #           "create_time": 1588758017375,
          #           "update_time": 1588758017411,
          #           "type": "LIMIT",
          #           "instrument_name": "ETH_CRO",
          #           "cumulative_quantity": 0,
          #           "cumulative_value": 0,
          #           "avg_price": 0,
          #           "fee_currency": "CRO",
          #           "time_in_force": "GOOD_TILL_CANCEL"
          #         }
          #       ]
          #     }
          # }
          data = self.safe_value(response, 'result', {})
          resultList = self.safe_value_2(data, 'order_list', 'data', [])
          return self.parse_orders(resultList, market, since, limit)
  
      def fetch_my_trades(self, symbol=None, since=None, limit=None, params={}):
          self.load_markets()
          request = {}
          market = None
          if symbol is not None:
              market = self.market(symbol)
              request['instrument_name'] = market['id']
          if since is not None:
              # maximum date range is one day
              request['start_ts'] = since
              endTimestamp = self.sum(since, 24 * 60 * 60 * 1000)
              request['end_ts'] = endTimestamp
          if limit is not None:
              request['page_size'] = limit
          marketType, query = self.handle_market_type_and_params('fetchMyTrades', market, params)
          method = self.get_supported_mapping(marketType, {
              'spot': 'spotPrivatePostPrivateGetTrades',
              'future': 'derivativesPrivatePostPrivateGetTrades',
              'swap': 'derivativesPrivatePostPrivateGetTrades',
          })
          response = getattr(self, method)(self.extend(request, query))
          # {
          #     "id": 11,
          #     "method": "private/get-trades",
          #     "code": 0,
          #     "result": {
          #       "trade_list": [
          #         {
          #           "side": "SELL",
          #           "instrument_name": "ETH_CRO",
          #           "fee": 0.014,
          #           "trade_id": "367107655537806900",
          #           "create_time": 1588777459755,
          #           "traded_price": 7,
          #           "traded_quantity": 1,
          #           "fee_currency": "CRO",
          #           "order_id": "367107623521528450"
          #         }
          #       ]
          #     }
          # }
          data = self.safe_value(response, 'result', {})
          resultList = self.safe_value_2(data, 'trade_list', 'data', [])
          return self.parse_trades(resultList, market, since, limit)
  
      def parse_address(self, addressString):
          address = None
          tag = None
          rawTag = None
          if addressString.find('?') > 0:
              address, rawTag = addressString.split('?')
              splitted = rawTag.split('=')
              tag = splitted[1]
          else:
              address = addressString
          return [address, tag]
  
      def withdraw(self, code, amount, address, tag=None, params={}):
          tag, params = self.handle_withdraw_tag_and_params(tag, params)
          self.load_markets()
          currency = self.currency(code)
          request = {
              'currency': currency['id'],
              'amount': amount,
              'address': address,
          }
          if tag is not None:
              request['address_tag'] = tag
          response = self.spotPrivatePostPrivateCreateWithdrawal(self.extend(request, params))
          #
          #    {
          #        "id":-1,
          #        "method":"private/create-withdrawal",
          #        "code":0,
          #        "result": {
          #            "id": 2220,
          #            "amount": 1,
          #            "fee": 0.0004,
          #            "symbol": "BTC",
          #            "address": "2NBqqD5GRJ8wHy1PYyCXTe9ke5226FhavBf",
          #            "client_wid": "my_withdrawal_002",
          #            "create_time":1607063412000
          #        }
          #     }
          #
          result = self.safe_value(response, 'result')
          return self.parse_transaction(result, currency)
  
      def fetch_deposit_addresses_by_network(self, code, params={}):
          self.load_markets()
          currency = self.currency(code)
          request = {
              'currency': currency['id'],
          }
          response = self.spotPrivatePostPrivateGetDepositAddress(self.extend(request, params))
          # {
          #     "id": 11,
          #     "method": "private/get-deposit-address",
          #     "code": 0,
          #     "result": {
          #          "deposit_address_list": [
          #              {
          #                  "currency": "CRO",
          #                  "create_time": 1615886328000,
          #                  "id": "12345",
          #                  "address": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
          #                  "status": "1",
          #                  "network": "CRO"
          #              },
          #              {
          #                  "currency": "CRO",
          #                  "create_time": 1615886332000,
          #                  "id": "12346",
          #                  "address": "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
          #                  "status": "1",
          #                  "network": "ETH"
          #              }
          #          ]
          #    }
          # }
          data = self.safe_value(response, 'result', {})
          addresses = self.safe_value(data, 'deposit_address_list', [])
          if len(addresses) == 0:
              raise ExchangeError(self.id + ' fetchDepositAddressesByNetwork() generating address...')
          result = {}
          for i in range(0, len(addresses)):
              value = self.safe_value(addresses, i)
              addressString = self.safe_string(value, 'address')
              currencyId = self.safe_string(value, 'currency')
              responseCode = self.safe_currency_code(currencyId)
              address, tag = self.parse_address(addressString)
              self.check_address(address)
              networkId = self.safe_string(value, 'network')
              network = self.safe_network(networkId)
              result[network] = {
                  'info': value,
                  'currency': responseCode,
                  'address': address,
                  'tag': tag,
                  'network': network,
              }
          return result
  
      def fetch_deposit_address(self, code, params={}):
          network = self.safe_string_upper(params, 'network')
          params = self.omit(params, ['network'])
          depositAddresses = self.fetch_deposit_addresses_by_network(code, params)
          if network in depositAddresses:
              return depositAddresses[network]
          else:
              keys = list(depositAddresses.keys())
              return depositAddresses[keys[0]]
  
      def safe_network(self, networkId):
          # stub for now
          # TODO: figure out which networks are supported on cryptocom
          return networkId
  
      def fetch_deposits(self, code=None, since=None, limit=None, params={}):
          self.load_markets()
          currency = None
          request = {}
          if code is not None:
              currency = self.currency(code)
              request['currency'] = currency['id']
          if since is not None:
              # 90 days date range
              request['start_ts'] = since
          if limit is not None:
              request['page_size'] = limit
          response = self.spotPrivatePostPrivateGetDepositHistory(self.extend(request, params))
          # {
          #     "id": 11,
          #     "method": "private/get-deposit-history",
          #     "code": 0,
          #     "result": {
          #       "deposit_list": [
          #         {
          #           "currency": "XRP",
          #           "fee": 1.0,
          #           "create_time": 1607063412000,
          #           "id": "2220",
          #           "update_time": 1607063460000,
          #           "amount": 100,
          #           "address": "2NBqqD5GRJ8wHy1PYyCXTe9ke5226FhavBf?1234567890",
          #           "status": "1"
          #         }
          #       ]
          #     }
          # }
          data = self.safe_value(response, 'result', {})
          depositList = self.safe_value(data, 'deposit_list', [])
          return self.parse_transactions(depositList, currency, since, limit)
  
      def fetch_withdrawals(self, code=None, since=None, limit=None, params={}):
          self.load_markets()
          currency = None
          request = {}
          if code is not None:
              currency = self.currency(code)
              request['currency'] = currency['id']
          if since is not None:
              # 90 days date range
              request['start_ts'] = since
          if limit is not None:
              request['page_size'] = limit
          response = self.spotPrivatePostPrivateGetWithdrawalHistory(self.extend(request, params))
          #
          #     {
          #       id: 1640704829096,
          #       method: 'private/get-withdrawal-history',
          #       code: 0,
          #       result: {
          #         withdrawal_list: [
          #           {
          #             currency: 'DOGE',
          #             client_wid: '',
          #             fee: 50,
          #             create_time: 1640425168000,
          #             id: '3180557',
          #             update_time: 1640425168000,
          #             amount: 1102.64092,
          #             address: 'DDrGGqmp5Ddo1QH9tUvDfoL4u4rqys5975',
          #             status: '5',
          #             txid: 'ce23e9e21b6c38eef953070a05110e6dca2fd2bcc76d3381000547b9ff5290b2/0'
          #           }
          #         ]
          #       }
          #     }
          #
          data = self.safe_value(response, 'result', {})
          withdrawalList = self.safe_value(data, 'withdrawal_list', [])
          return self.parse_transactions(withdrawalList, currency, since, limit)
  
      def transfer(self, code, amount, fromAccount, toAccount, params={}):
          self.load_markets()
          currency = self.currency(code)
          fromAccount = fromAccount.lower()
          toAccount = toAccount.lower()
          accountsById = self.safe_value(self.options, 'accountsByType', {})
          fromId = self.safe_string(accountsById, fromAccount, fromAccount)
          toId = self.safe_string(accountsById, toAccount, toAccount)
          request = {
              'currency': currency['id'],
              'amount': float(amount),
              'from': fromId,
              'to': toId,
          }
          repsonse = self.spotPrivatePostPrivateDerivTransfer(self.extend(request, params))
          #
          #     {
          #         "id": 11,
          #         "method": "private/deriv/transfer",
          #         "code": 0
          #     }
          #
          return self.parse_transfer(repsonse, currency)
  
      def fetch_transfers(self, code=None, since=None, limit=None, params={}):
          if not ('direction' in params):
              raise ArgumentsRequired(self.id + ' fetchTransfers() requires a direction param to be either "IN" or "OUT"')
          self.load_markets()
          currency = None
          request = {
              'direction': 'OUT',
          }
          if code is not None:
              currency = self.currency(code)
              request['currency'] = currency['id']
          response = self.spotPrivatePostPrivateDerivGetTransferHistory(self.extend(request, params))
          #
          #     {
          #       id: '1641032709328',
          #       method: 'private/deriv/get-transfer-history',
          #       code: '0',
          #       result: {
          #         transfer_list: [
          #           {
          #             direction: 'IN',
          #             time: '1641025185223',
          #             amount: '109.56',
          #             status: 'COMPLETED',
          #             information: 'From Spot Wallet',
          #             currency: 'USDC'
          #           }
          #         ]
          #       }
          #     }
          #
          result = self.safe_value(response, 'result', {})
          transferList = self.safe_value(result, 'transfer_list', [])
          return self.parse_transfers(transferList, currency, since, limit, params)
  
      def parse_transfer_status(self, status):
          statuses = {
              'COMPLETED': 'ok',
              'PROCESSING': 'pending',
          }
          return self.safe_string(statuses, status, status)
  
      def parse_transfer(self, transfer, currency=None):
          #
          #     {
          #       direction: 'IN',
          #       time: '1641025185223',
          #       amount: '109.56',
          #       status: 'COMPLETED',
          #       information: 'From Spot Wallet',
          #       currency: 'USDC'
          #     }
          #
          timestamp = self.safe_integer(transfer, 'time')
          amount = self.safe_number(transfer, 'amount')
          currencyId = self.safe_string(transfer, 'currency')
          code = self.safe_currency_code(currencyId)
          information = self.safe_string(transfer, 'information')
          fromAccount = None
          toAccount = None
          if information is not None:
              parts = information.split(' ')
              fromAccount = self.safe_string_lower(parts, 1)
              toAccount = 'derivative' if (fromAccount == 'spot') else 'spot'
          rawStatus = self.safe_string(transfer, 'status')
          status = self.parse_transfer_status(rawStatus)
          return {
              'info': transfer,
              'id': self.safe_string(transfer, 'id'),
              'timestamp': timestamp,
              'datetime': self.iso8601(timestamp),
              'currency': code,
              'amount': amount,
              'fromAccount': fromAccount,
              'toAccount': toAccount,
              'status': status,
          }
  
      def parse_ticker(self, ticker, market=None):
          # {
          #     "i":"CRO_BTC",
          #     "b":0.00000890,
          #     "k":0.00001179,
          #     "a":0.00001042,
          #     "t":1591770793901,
          #     "v":14905879.59,
          #     "h":0.00,
          #     "l":0.00,
          #     "c":0.00
          # }
          timestamp = self.safe_integer(ticker, 't')
          marketId = self.safe_string(ticker, 'i')
          market = self.safe_market(marketId, market, '_')
          symbol = market['symbol']
          last = self.safe_string(ticker, 'a')
          relativeChange = self.safe_string(ticker, 'c')
          return self.safe_ticker({
              'symbol': symbol,
              'timestamp': timestamp,
              'datetime': self.iso8601(timestamp),
              'high': self.safe_string(ticker, 'h'),
              'low': self.safe_string(ticker, 'l'),
              'bid': self.safe_string(ticker, 'b'),
              'bidVolume': None,
              'ask': self.safe_string(ticker, 'k'),
              'askVolume': None,
              'vwap': None,
              'open': None,
              'close': last,
              'last': last,
              'previousClose': None,
              'change': relativeChange,
              'percentage': None,
              'average': None,
              'baseVolume': self.safe_string(ticker, 'v'),
              'quoteVolume': None,
              'info': ticker,
          }, market, False)
  
      def parse_trade(self, trade, market=None):
          #
          # public/get-trades
          #
          # {"dataTime":1591710781947,"d":465533583799589409,"s":"BUY","p":2.96,"q":16.0,"t":1591710781946,"i":"ICX_CRO"},
          #
          # private/get-trades
          #
          # {
          #     "side": "SELL",
          #     "instrument_name": "ETH_CRO",
          #     "fee": 0.014,
          #     "trade_id": "367107655537806900",
          #     "create_time": 1588777459755,
          #     "traded_price": 7,
          #     "traded_quantity": 1,
          #     "fee_currency": "CRO",
          #     "order_id": "367107623521528450"
          # }
          timestamp = self.safe_integer_2(trade, 't', 'create_time')
          marketId = self.safe_string_2(trade, 'i', 'instrument_name')
          market = self.safe_market(marketId, market, '_')
          symbol = market['symbol']
          price = self.safe_string_2(trade, 'p', 'traded_price')
          amount = self.safe_string_2(trade, 'q', 'traded_quantity')
          side = self.safe_string_2(trade, 's', 'side')
          if side is not None:
              side = side.lower()
          id = self.safe_string_2(trade, 'd', 'trade_id')
          takerOrMaker = self.safe_string_lower_2(trade, 'liquidity_indicator', 'taker_side')
          order = self.safe_string(trade, 'order_id')
          fee = None
          feeCost = self.safe_string_2(trade, 'fee', 'fees')
          if feeCost is not None:
              contract = self.safe_value(market, 'contract', False)
              if contract:
                  feeCost = Precise.string_neg(feeCost)
              feeCurrency = None
              if market['spot']:
                  feeCurrency = self.safe_string(trade, 'fee_currency')
              elif market['linear']:
                  feeCurrency = market['quote']
              fee = {
                  'currency': feeCurrency,
                  'cost': feeCost,
              }
          return self.safe_trade({
              'info': trade,
              'id': id,
              'timestamp': timestamp,
              'datetime': self.iso8601(timestamp),
              'symbol': symbol,
              'side': side,
              'price': price,
              'amount': amount,
              'cost': None,
              'order': order,
              'takerOrMaker': takerOrMaker,
              'type': None,
              'fee': fee,
          }, market)
  
      def parse_ohlcv(self, ohlcv, market=None):
          #      {"t":1596944700000,"o":11752.38,"h":11754.77,"l":11746.65,"c":11753.64,"v":3.694583}
          return [
              self.safe_integer(ohlcv, 't'),
              self.safe_number(ohlcv, 'o'),
              self.safe_number(ohlcv, 'h'),
              self.safe_number(ohlcv, 'l'),
              self.safe_number(ohlcv, 'c'),
              self.safe_number(ohlcv, 'v'),
          ]
  
      def parse_order_status(self, status):
          statuses = {
              'ACTIVE': 'open',
              'CANCELED': 'canceled',
              'FILLED': 'closed',
              'REJECTED': 'rejected',
              'EXPIRED': 'expired',
          }
          return self.safe_string(statuses, status, status)
  
      def parse_time_in_force(self, timeInForce):
          timeInForces = {
              'GOOD_TILL_CANCEL': 'GTC',
              'IMMEDIATE_OR_CANCEL': 'IOC',
              'FILL_OR_KILL': 'FOK',
          }
          return self.safe_string(timeInForces, timeInForce, timeInForce)
  
      def parse_order(self, order, market=None):
          #       {
          #         "status": "FILLED",
          #         "side": "BUY",
          #         "order_id": "371302913889488619",
          #         "client_oid": "9_yMYJDNEeqHxLqtD_2j3g",
          #         "create_time": 1588902489144,
          #         "update_time": 1588902493024,
          #         "type": "LIMIT",
          #         "instrument_name": "ETH_CRO",
          #         "cumulative_quantity": 7,
          #         "cumulative_value": 7,
          #         "avg_price": 7,
          #         "fee_currency": "CRO",
          #         "time_in_force": "GOOD_TILL_CANCEL",
          #         "exec_inst": "POST_ONLY"
          #       }
          #
          #     {
          #       id: 1641026373106,
          #       method: 'private/get-order-history',
          #       code: 0,
          #       result: {
          #         data: [
          #           {
          #             account_id: '85ff689a-7508-4b96-aa79-dc0545d6e637',
          #             order_id: 13191401932,
          #             client_oid: '1641025941461',
          #             order_type: 'LIMIT',
          #             time_in_force: 'GOOD_TILL_CANCEL',
          #             side: 'BUY',
          #             exec_inst: [],
          #             quantity: '0.0001',
          #             limit_price: '48000.0',
          #             order_value: '4.80000000',
          #             maker_fee_rate: '0.00050',
          #             taker_fee_rate: '0.00070',
          #             avg_price: '47253.5',
          #             trigger_price: '0.0',
          #             ref_price_type: 'NULL_VAL',
          #             cumulative_quantity: '0.0001',
          #             cumulative_value: '4.72535000',
          #             cumulative_fee: '0.00330775',
          #             status: 'FILLED',
          #             update_user_id: 'ce075bef-b600-4277-bd6e-ff9007251e63',
          #             order_date: '2022-01-01',
          #             instrument_name: 'BTCUSD-PERP',
          #             fee_instrument_name: 'USD_Stable_Coin',
          #             create_time: 1641025941827,
          #             create_time_ns: '1641025941827994756',
          #             update_time: 1641025941827
          #           }
          #         ]
          #       }
          #     }
          #
          created = self.safe_integer(order, 'create_time')
          updated = self.safe_integer(order, 'update_time')
          marketId = self.safe_string(order, 'instrument_name')
          symbol = self.safe_symbol(marketId, market)
          amount = self.safe_string(order, 'quantity')
          filled = self.safe_string(order, 'cumulative_quantity')
          status = self.parse_order_status(self.safe_string(order, 'status'))
          id = self.safe_string(order, 'order_id')
          clientOrderId = self.safe_string(order, 'client_oid')
          if clientOrderId == '':
              clientOrderId = None
          price = self.safe_string_2(order, 'price', 'limit_price')
          average = self.safe_string(order, 'avg_price')
          type = self.safe_string_lower_2(order, 'type', 'order_type')
          side = self.safe_string_lower(order, 'side')
          timeInForce = self.parse_time_in_force(self.safe_string(order, 'time_in_force'))
          execInst = self.safe_string(order, 'exec_inst')
          postOnly = None
          if execInst is not None:
              postOnly = (execInst == 'POST_ONLY')
          cost = self.safe_string(order, 'cumulative_value')
          feeCost = self.safe_string(order, 'cumulative_fee')
          fee = None
          if feeCost is not None:
              feeCurrency = self.safe_string(order, 'fee_instrument_name')
              fee = {
                  'cost': feeCost,
                  'currency': self.safe_currency_code(feeCurrency),
              }
          return self.safe_order({
              'info': order,
              'id': id,
              'clientOrderId': clientOrderId,
              'timestamp': created,
              'datetime': self.iso8601(created),
              'lastTradeTimestamp': updated,
              'status': status,
              'symbol': symbol,
              'type': type,
              'timeInForce': timeInForce,
              'postOnly': postOnly,
              'side': side,
              'price': price,
              'amount': amount,
              'filled': filled,
              'remaining': None,
              'cost': cost,
              'fee': fee,
              'average': average,
              'trades': [],
          }, market)
  
      def parse_deposit_status(self, status):
          statuses = {
              '0': 'pending',
              '1': 'ok',
              '2': 'failed',
              '3': 'pending',
          }
          return self.safe_string(statuses, status, status)
  
      def parse_withdrawal_status(self, status):
          statuses = {
              '0': 'pending',
              '1': 'pending',
              '2': 'failed',
              '3': 'pending',
              '4': 'failed',
              '5': 'ok',
              '6': 'canceled',
          }
          return self.safe_string(statuses, status, status)
  
      def parse_transaction(self, transaction, currency=None):
          #
          # fetchDeposits
          #
          #     {
          #         "currency": "XRP",
          #         "fee": 1.0,
          #         "create_time": 1607063412000,
          #         "id": "2220",
          #         "update_time": 1607063460000,
          #         "amount": 100,
          #         "address": "2NBqqD5GRJ8wHy1PYyCXTe9ke5226FhavBf?1234567890",
          #         "status": "1"
          #     }
          #
          # fetchWithdrawals
          #
          #     {
          #         "currency": "XRP",
          #         "client_wid": "my_withdrawal_002",
          #         "fee": 1.0,
          #         "create_time": 1607063412000,
          #         "id": "2220",
          #         "update_time": 1607063460000,
          #         "amount": 100,
          #         "address": "2NBqqD5GRJ8wHy1PYyCXTe9ke5226FhavBf?1234567890",
          #         "status": "1"
          #     }
          #
          # withdraw
          #
          #     {
          #         "id": 2220,
          #         "amount": 1,
          #         "fee": 0.0004,
          #         "symbol": "BTC",
          #         "address": "2NBqqD5GRJ8wHy1PYyCXTe9ke5226FhavBf",
          #         "client_wid": "my_withdrawal_002",
          #         "create_time":1607063412000
          #     }
          #
          type = None
          rawStatus = self.safe_string(transaction, 'status')
          status = None
          if 'client_wid' in transaction:
              type = 'withdrawal'
              status = self.parse_withdrawal_status(rawStatus)
          else:
              type = 'deposit'
              status = self.parse_deposit_status(rawStatus)
          id = self.safe_string(transaction, 'id')
          addressString = self.safe_string(transaction, 'address')
          address, tag = self.parse_address(addressString)
          currencyId = self.safe_string(transaction, 'currency')
          code = self.safe_currency_code(currencyId, currency)
          timestamp = self.safe_integer(transaction, 'create_time')
          amount = self.safe_number(transaction, 'amount')
          txId = self.safe_string(transaction, 'txid')
          feeCost = self.safe_number(transaction, 'fee')
          fee = None
          if feeCost is not None:
              fee = {'currency': code, 'cost': feeCost}
          updated = self.safe_integer(transaction, 'update_time')
          return {
              'info': transaction,
              'id': id,
              'txid': txId,
              'timestamp': timestamp,
              'datetime': self.iso8601(timestamp),
              'network': None,
              'address': address,
              'addressTo': address,
              'addressFrom': None,
              'tag': tag,
              'tagTo': tag,
              'tagFrom': None,
              'type': type,
              'amount': amount,
              'currency': code,
              'status': status,
              'updated': updated,
              'internal': None,
              'fee': fee,
          }
  
      def nonce(self):
          return self.milliseconds()
  
      def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
          type, access = api
          url = self.urls['api'][type] + '/' + path
          query = self.omit(params, self.extract_params(path))
          if access == 'public':
              if query:
                  url += '?' + self.urlencode(query)
          else:
              self.check_required_credentials()
              nonce = str(self.nonce())
              requestParams = self.extend({}, params)
              keysorted = self.keysort(requestParams)
              paramsKeys = list(keysorted.keys())
              strSortKey = ''
              for i in range(0, len(paramsKeys)):
                  strSortKey = strSortKey + str(paramsKeys[i]) + str(requestParams[paramsKeys[i]])
              payload = path + nonce + self.apiKey + strSortKey + nonce
              signature = self.hmac(self.encode(payload), self.encode(self.secret))
              paramsKeysLength = len(paramsKeys)
              body = self.json({
                  'id': nonce,
                  'method': path,
                  'params': params,
                  'api_key': self.apiKey,
                  'sig': signature,
                  'nonce': nonce,
              })
              # fix issue https://github.com/ccxt/ccxt/issues/11179
              # php always encodes dictionaries as arrays
              # if an array is empty, php will put it in square brackets
              # python and js will put it in curly brackets
              # the code below checks and replaces those brackets in empty requests
              if paramsKeysLength == 0:
                  paramsString = '{}'
                  arrayString = '[]'
                  body = body.replace(arrayString, paramsString)
              headers = {
                  'Content-Type': 'application/json',
              }
          return {'url': url, 'method': method, 'body': body, 'headers': headers}
  
      def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
          errorCode = self.safe_string(response, 'code')
          if errorCode != '0':
              feedback = self.id + ' ' + body
              self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
              raise ExchangeError(self.id + ' ' + body)
  