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
  
  # -----------------------------------------------------------------------------
  
  try:
      basestring  # Python 3
  except NameError:
      basestring = str  # Python 2
  import hashlib
  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 InsufficientFunds
  from ccxt.base.errors import InvalidOrder
  from ccxt.base.errors import DDoSProtection
  from ccxt.base.errors import ExchangeNotAvailable
  from ccxt.base.errors import InvalidNonce
  
  
  class dsx (Exchange):
  
      def describe(self):
          return self.deep_extend(super(dsx, self).describe(), {
              'id': 'dsx',
              'name': 'DSX',
              'countries': ['UK'],
              'rateLimit': 1500,
              'version': 'v3',
              'has': {
                  'CORS': False,
                  'createMarketOrder': False,
                  'fetchOHLCV': True,
                  'fetchOrder': True,
                  'fetchOrders': True,
                  'fetchOpenOrders': True,
                  'fetchClosedOrders': False,
                  'fetchOrderBooks': False,
                  'createDepositAddress': True,
                  'fetchDepositAddress': True,
                  'fetchTransactions': True,
                  'fetchTickers': True,
                  'fetchMyTrades': True,
                  'withdraw': True,
              },
              'urls': {
                  'logo': 'https://user-images.githubusercontent.com/1294454/27990275-1413158a-645a-11e7-931c-94717f7510e3.jpg',
                  'api': {
                      'public': 'https://dsx.uk/mapi',  # market data
                      'private': 'https://dsx.uk/tapi',  # trading
                      'dwapi': 'https://dsx.uk/dwapi',  # deposit/withdraw
                  },
                  'www': 'https://dsx.uk',
                  'doc': [
                      'https://dsx.uk/developers/publicApi',
                  ],
              },
              'fees': {
                  'trading': {
                      'tierBased': True,
                      'percentage': True,
                      'maker': 0.15 / 100,
                      'taker': 0.25 / 100,
                  },
              },
              'timeframes': {
                  '1m': 'm',
                  '1h': 'h',
                  '1d': 'd',
              },
              'api': {
                  # market data(public)
                  'public': {
                      'get': [
                          'barsFromMoment/{pair}/{period}/{start}',
                          'depth/{pair}',
                          'info',
                          'lastBars/{pair}/{period}/{amount}',  # period is 'm', 'h' or 'd'
                          'periodBars/{pair}/{period}/{start}/{end}',
                          'ticker/{pair}',
                          'trades/{pair}',
                      ],
                  },
                  # trading(private)
                  'private': {
                      'post': [
                          'info/account',
                          'history/transactions',
                          'history/trades',
                          'history/orders',
                          'orders',
                          'order/cancel',
                          # 'order/cancel/all',
                          'order/status',
                          'order/new',
                          'volume',
                          'fees',  # trading fee schedule
                      ],
                  },
                  # deposit / withdraw(private)
                  'dwapi': {
                      'post': [
                          'deposit/cryptoaddress',
                          'withdraw/crypto',
                          'withdraw/fiat',
                          'withdraw/submit',
                          # 'withdraw/cancel',
                          'transaction/status',  # see 'history/transactions' in private tapi above
                      ],
                  },
              },
              'exceptions': {
                  'exact': {
                      'Sign is invalid': AuthenticationError,  # {"success":0,"error":"Sign is invalid"}
                      'Order was rejected. Incorrect price.': InvalidOrder,  # {"success":0,"error":"Order was rejected. Incorrect price."}
                      "Order was rejected. You don't have enough money.": InsufficientFunds,  # {"success":0,"error":"Order was rejected. You don't have enough money."}
                      'This method is blocked for your pair of keys': PermissionDenied,  # {"success":0,"error":"This method is blocked for your pair of keys"}
                  },
                  'broad': {
                      'INVALID_PARAMETER': BadRequest,
                      'Invalid pair name': ExchangeError,  # {"success":0,"error":"Invalid pair name: btc_eth"}
                      'invalid api key': AuthenticationError,
                      'invalid sign': AuthenticationError,
                      'api key dont have trade permission': AuthenticationError,
                      'invalid parameter': InvalidOrder,
                      'invalid order': InvalidOrder,
                      'Requests too often': DDoSProtection,
                      'not available': ExchangeNotAvailable,
                      'data unavailable': ExchangeNotAvailable,
                      'external service unavailable': ExchangeNotAvailable,
                      'nonce is invalid': InvalidNonce,  # {"success":0,"error":"Parameter: nonce is invalid"}
                  },
              },
              'options': {
                  'fetchTickersMaxLength': 250,
              },
              'commonCurrencies': {
                  'DSH': 'DASH',
              },
          })
  
      def fetch_markets(self, params={}):
          response = self.publicGetInfo(params)
          #
          #     {
          #         "server_time": 1522057909,
          #         "pairs": {
          #             "ethusd": {
          #                 "decimal_places": 5,
          #                 "min_price": 100,
          #                 "max_price": 1500,
          #                 "min_amount": 0.01,
          #                 "hidden": 0,
          #                 "fee": 0,
          #                 "amount_decimal_places": 4,
          #                 "quoted_currency": "USD",
          #                 "base_currency": "ETH"
          #             }
          #         }
          #     }
          #
          markets = self.safe_value(response, 'pairs')
          keys = list(markets.keys())
          result = []
          for i in range(0, len(keys)):
              id = keys[i]
              market = markets[id]
              baseId = self.safe_string(market, 'base_currency')
              quoteId = self.safe_string(market, 'quoted_currency')
              base = self.safe_currency_code(baseId)
              quote = self.safe_currency_code(quoteId)
              symbol = base + '/' + quote
              precision = {
                  'amount': self.safe_integer(market, 'decimal_places'),
                  'price': self.safe_integer(market, 'decimal_places'),
              }
              amountLimits = {
                  'min': self.safe_float(market, 'min_amount'),
                  'max': self.safe_float(market, 'max_amount'),
              }
              priceLimits = {
                  'min': self.safe_float(market, 'min_price'),
                  'max': self.safe_float(market, 'max_price'),
              }
              costLimits = {
                  'min': self.safe_float(market, 'min_total'),
              }
              limits = {
                  'amount': amountLimits,
                  'price': priceLimits,
                  'cost': costLimits,
              }
              hidden = self.safe_integer(market, 'hidden')
              active = (hidden == 0)
              result.append({
                  'id': id,
                  'symbol': symbol,
                  'base': base,
                  'quote': quote,
                  'baseId': baseId,
                  'quoteId': quoteId,
                  'active': active,
                  'precision': precision,
                  'limits': limits,
                  'info': market,
              })
          return result
  
      def fetch_balance(self, params={}):
          self.load_markets()
          response = self.privatePostInfoAccount()
          #
          #     {
          #         "success" : 1,
          #         "return" : {
          #             "funds" : {
          #                 "BTC" : {
          #                     "total" : 0,
          #                     "available" : 0
          #                 },
          #                 "USD" : {
          #                     "total" : 0,
          #                     "available" : 0
          #                 },
          #                 "USDT" : {
          #                     "total" : 0,
          #                     "available" : 0
          #                 }
          #             },
          #             "rights" : {
          #                 "info" : 1,
          #                 "trade" : 1
          #             },
          #             "transactionCount" : 0,
          #             "openOrders" : 0,
          #             "serverTime" : 1537451465
          #         }
          #     }
          #
          balances = self.safe_value(response, 'return')
          result = {'info': response}
          funds = self.safe_value(balances, 'funds')
          currencyIds = list(funds.keys())
          for i in range(0, len(currencyIds)):
              currencyId = currencyIds[i]
              code = self.safe_currency_code(currencyId)
              balance = self.safe_value(funds, currencyId, {})
              account = self.account()
              account['free'] = self.safe_float(balance, 'available')
              account['total'] = self.safe_float(balance, 'total')
              result[code] = account
          return self.parse_balance(result)
  
      def parse_ticker(self, ticker, market=None):
          #
          #   {   high:  0.03492,
          #         low:  0.03245,
          #         avg:  29.46133,
          #         vol:  500.8661,
          #     vol_cur:  17.000797104,
          #        last:  0.03364,
          #         buy:  0.03362,
          #        sell:  0.03381,
          #     updated:  1537521993,
          #        pair: "ethbtc"       }
          #
          timestamp = self.safe_timestamp(ticker, 'updated')
          symbol = None
          marketId = self.safe_string(ticker, 'pair')
          if marketId in self.markets_by_id:
              market = self.markets_by_id[marketId]
          if market is not None:
              symbol = market['symbol']
          # dsx average is inverted, liqui average is not
          average = self.safe_float(ticker, 'avg')
          if average is not None:
              if average > 0:
                  average = 1 / average
          last = self.safe_float(ticker, 'last')
          return {
              'symbol': symbol,
              'timestamp': timestamp,
              'datetime': self.iso8601(timestamp),
              'high': self.safe_float(ticker, 'high'),
              'low': self.safe_float(ticker, 'low'),
              'bid': self.safe_float(ticker, 'buy'),
              'bidVolume': None,
              'ask': self.safe_float(ticker, 'sell'),
              'askVolume': None,
              'vwap': None,
              'open': None,
              'close': last,
              'last': last,
              'previousClose': None,
              'change': None,
              'percentage': None,
              'average': average,
              'baseVolume': self.safe_float(ticker, 'vol'),
              'quoteVolume': self.safe_float(ticker, 'vol_cur'),
              'info': ticker,
          }
  
      def parse_trade(self, trade, market=None):
          #
          # fetchTrades(public)
          #
          #     {
          #         "amount" : 0.0128,
          #         "price" : 6483.99000,
          #         "timestamp" : 1540334614,
          #         "tid" : 35684364,
          #         "type" : "ask"
          #     }
          #
          # fetchMyTrades(private)
          #
          #     {
          #         "number": "36635882",  # <-- self is present if the trade has come from the '/order/status' call
          #         "id": "36635882",  # <-- self may have been artifically added by the parseTrades method
          #         "pair": "btcusd",
          #         "type": "buy",
          #         "volume": 0.0595,
          #         "rate": 9750,
          #         "orderId": 77149299,
          #         "timestamp": 1519612317,
          #         "commission": 0.00020825,
          #         "commissionCurrency": "btc"
          #     }
          #
          timestamp = self.safe_timestamp(trade, 'timestamp')
          side = self.safe_string(trade, 'type')
          if side == 'ask':
              side = 'sell'
          elif side == 'bid':
              side = 'buy'
          price = self.safe_float_2(trade, 'rate', 'price')
          id = self.safe_string_2(trade, 'number', 'id')
          orderId = self.safe_string(trade, 'orderId')
          marketId = self.safe_string(trade, 'pair')
          market = self.safe_value(self.markets_by_id, marketId, market)
          symbol = None
          if market is not None:
              symbol = market['symbol']
          amount = self.safe_float_2(trade, 'amount', 'volume')
          type = 'limit'  # all trades are still limit trades
          takerOrMaker = None
          fee = None
          feeCost = self.safe_float(trade, 'commission')
          if feeCost is not None:
              feeCurrencyId = self.safe_string(trade, 'commissionCurrency')
              feeCurrencyCode = self.safe_currency_code(feeCurrencyId)
              fee = {
                  'cost': feeCost,
                  'currency': feeCurrencyCode,
              }
          isYourOrder = self.safe_value(trade, 'is_your_order')
          if isYourOrder is not None:
              takerOrMaker = 'taker'
              if isYourOrder:
                  takerOrMaker = 'maker'
              if fee is None:
                  fee = self.calculate_fee(symbol, type, side, amount, price, takerOrMaker)
          cost = None
          if price is not None:
              if amount is not None:
                  cost = price * amount
          return {
              'id': id,
              'order': orderId,
              'timestamp': timestamp,
              'datetime': self.iso8601(timestamp),
              'symbol': symbol,
              'type': type,
              'side': side,
              'takerOrMaker': takerOrMaker,
              'price': price,
              'amount': amount,
              'cost': cost,
              'fee': fee,
              'info': trade,
          }
  
      def parse_trades(self, trades, market=None, since=None, limit=None, params={}):
          result = []
          if isinstance(trades, list):
              for i in range(0, len(trades)):
                  result.append(self.parse_trade(trades[i], market))
          else:
              ids = list(trades.keys())
              for i in range(0, len(ids)):
                  id = ids[i]
                  trade = self.parse_trade(trades[id], market)
                  result.append(self.extend(trade, {'id': id}, params))
          result = self.sort_by(result, 'timestamp')
          symbol = market['symbol'] if (market is not None) else None
          return self.filter_by_symbol_since_limit(result, symbol, since, limit)
  
      def calculate_fee(self, symbol, type, side, amount, price, takerOrMaker='taker', params={}):
          market = self.markets[symbol]
          key = 'quote'
          rate = market[takerOrMaker]
          cost = float(self.cost_to_precision(symbol, amount * rate))
          if side == 'sell':
              cost *= price
          else:
              key = 'base'
          return {
              'type': takerOrMaker,
              'currency': market[key],
              'rate': rate,
              'cost': cost,
          }
  
      def fetch_order_book(self, symbol, limit=None, params={}):
          self.load_markets()
          market = self.market(symbol)
          request = {
              'pair': market['id'],
          }
          if limit is not None:
              request['limit'] = limit  # default = 150, max = 2000
          response = self.publicGetDepthPair(self.extend(request, params))
          market_id_in_reponse = (market['id'] in list(response.keys()))
          if not market_id_in_reponse:
              raise ExchangeError(self.id + ' ' + market['symbol'] + ' order book is empty or not available')
          orderbook = response[market['id']]
          return self.parse_order_book(orderbook)
  
      def fetch_order_books(self, symbols=None, params={}):
          self.load_markets()
          ids = None
          if symbols is None:
              ids = '-'.join(self.ids)
              # max URL length is 2083 symbols, including http schema, hostname, tld, etc...
              if len(ids) > 2048:
                  numIds = len(self.ids)
                  raise ExchangeError(self.id + ' has ' + str(numIds) + ' symbols exceeding max URL length, you are required to specify a list of symbols in the first argument to fetchOrderBooks')
          else:
              ids = self.market_ids(symbols)
              ids = '-'.join(ids)
          request = {
              'pair': ids,
          }
          response = self.publicGetDepthPair(self.extend(request, params))
          result = {}
          ids = list(response.keys())
          for i in range(0, len(ids)):
              id = ids[i]
              symbol = id
              if id in self.markets_by_id:
                  market = self.markets_by_id[id]
                  symbol = market['symbol']
              result[symbol] = self.parse_order_book(response[id])
          return result
  
      def fetch_tickers(self, symbols=None, params={}):
          self.load_markets()
          ids = self.ids
          if symbols is None:
              numIds = len(ids)
              ids = '-'.join(ids)
              maxLength = self.safe_integer(self.options, 'fetchTickersMaxLength', 2048)
              # max URL length is 2048 symbols, including http schema, hostname, tld, etc...
              if len(ids) > self.options['fetchTickersMaxLength']:
                  raise ArgumentsRequired(self.id + ' has ' + str(numIds) + ' markets exceeding max URL length for self endpoint(' + str(maxLength) + ' characters), please, specify a list of symbols of interest in the first argument to fetchTickers')
          else:
              ids = self.market_ids(symbols)
              ids = '-'.join(ids)
          request = {
              'pair': ids,
          }
          tickers = self.publicGetTickerPair(self.extend(request, params))
          result = {}
          keys = list(tickers.keys())
          for k in range(0, len(keys)):
              id = keys[k]
              ticker = tickers[id]
              symbol = id
              market = None
              if id in self.markets_by_id:
                  market = self.markets_by_id[id]
                  symbol = market['symbol']
              result[symbol] = self.parse_ticker(ticker, market)
          return result
  
      def fetch_ticker(self, symbol, params={}):
          tickers = self.fetch_tickers([symbol], params)
          return tickers[symbol]
  
      def fetch_trades(self, symbol, since=None, limit=None, params={}):
          self.load_markets()
          market = self.market(symbol)
          request = {
              'pair': market['id'],
          }
          if limit is not None:
              request['limit'] = limit
          response = self.publicGetTradesPair(self.extend(request, params))
          if isinstance(response, list):
              numElements = len(response)
              if numElements == 0:
                  return []
          return self.parse_trades(response[market['id']], market, since, limit)
  
      def parse_ohlcv(self, ohlcv, market=None, timeframe='1m', since=None, limit=None):
          #
          #     {
          #         "high" : 0.01955,
          #         "open" : 0.01955,
          #         "low" : 0.01955,
          #         "close" : 0.01955,
          #         "amount" : 2.5,
          #         "timestamp" : 1565155740000
          #     }
          #
          return [
              self.safe_integer(ohlcv, 'timestamp'),
              self.safe_float(ohlcv, 'open'),
              self.safe_float(ohlcv, 'high'),
              self.safe_float(ohlcv, 'low'),
              self.safe_float(ohlcv, 'close'),
              self.safe_float(ohlcv, 'amount'),
          ]
  
      def fetch_ohlcv(self, symbol, timeframe='1m', since=None, limit=None, params={}):
          self.load_markets()
          market = self.market(symbol)
          request = {
              'pair': market['id'],
              'period': self.timeframes[timeframe],
          }
          method = 'publicGetLastBarsPairPeriodAmount'
          if since is None:
              if limit is None:
                  limit = 100  # required, max 2000
              request['amount'] = limit
          else:
              method = 'publicGetPeriodBarsPairPeriodStartEnd'
              # in their docs they expect milliseconds
              # but it returns empty arrays with milliseconds
              # however, it does work properly with seconds
              request['start'] = int(since / 1000)
              if limit is None:
                  request['end'] = self.seconds()
              else:
                  duration = self.parse_timeframe(timeframe) * 1000
                  end = self.sum(since, duration * limit)
                  request['end'] = int(end / 1000)
          response = getattr(self, method)(self.extend(request, params))
          #
          #     {
          #         "ethbtc": [
          #             {
          #                 "high" : 0.01955,
          #                 "open" : 0.01955,
          #                 "low" : 0.01955,
          #                 "close" : 0.01955,
          #                 "amount" : 2.5,
          #                 "timestamp" : 1565155740000
          #             },
          #             {
          #                 "high" : 0.01967,
          #                 "open" : 0.01967,
          #                 "low" : 0.01967,
          #                 "close" : 0.01967,
          #                 "amount" : 0,
          #                 "timestamp" : 1565155680000
          #             }
          #         ]
          #     }
          #
          candles = self.safe_value(response, market['id'], [])
          return self.parse_ohlcvs(candles, market, timeframe, since, limit)
  
      def create_order(self, symbol, type, side, amount, price=None, params={}):
          self.load_markets()
          market = self.market(symbol)
          if type == 'market' and price is None:
              raise ArgumentsRequired(self.id + ' createOrder requires a price argument even for market orders, that is the worst price that you agree to fill your order for')
          request = {
              'pair': market['id'],
              'type': side,
              'volume': self.amount_to_precision(symbol, amount),
              'rate': self.price_to_precision(symbol, price),
              'orderType': type,
          }
          price = float(price)
          amount = float(amount)
          response = self.privatePostOrderNew(self.extend(request, params))
          #
          #     {
          #       "success": 1,
          #       "return": {
          #         "received": 0,
          #         "remains": 10,
          #         "funds": {
          #           "BTC": {
          #             "total": 100,
          #             "available": 95
          #           },
          #           "USD": {
          #             "total": 10000,
          #             "available": 9995
          #           },
          #           "EUR": {
          #             "total": 1000,
          #             "available": 995
          #           },
          #           "LTC": {
          #             "total": 1000,
          #             "available": 995
          #           }
          #         },
          #         "orderId": 0,  # https://github.com/ccxt/ccxt/issues/3677
          #       }
          #     }
          #
          status = 'open'
          filled = 0.0
          remaining = amount
          responseReturn = self.safe_value(response, 'return')
          id = self.safe_string_2(responseReturn, 'orderId', 'order_id')
          if id == '0':
              id = self.safe_string(responseReturn, 'initOrderId', 'init_order_id')
              status = 'closed'
          filled = self.safe_float(responseReturn, 'received', 0.0)
          remaining = self.safe_float(responseReturn, 'remains', amount)
          timestamp = self.milliseconds()
          return {
              'info': response,
              'id': id,
              'timestamp': timestamp,
              'datetime': self.iso8601(timestamp),
              'lastTradeTimestamp': None,
              'status': status,
              'symbol': symbol,
              'type': type,
              'side': side,
              'price': price,
              'cost': price * filled,
              'amount': amount,
              'remaining': remaining,
              'filled': filled,
              'fee': None,
              # 'trades': self.parse_trades(order['trades'], market),
          }
  
      def parse_order_status(self, status):
          statuses = {
              '0': 'open',  # Active
              '1': 'closed',  # Filled
              '2': 'canceled',  # Killed
              '3': 'canceling',  # Killing
              '7': 'canceled',  # Rejected
          }
          return self.safe_string(statuses, status, status)
  
      def parse_order(self, order, market=None):
          #
          # fetchOrder
          #
          #   {
          #     "number": 36635882,
          #     "pair": "btcusd",
          #     "type": "buy",
          #     "remainingVolume": 10,
          #     "volume": 10,
          #     "rate": 1000.0,
          #     "timestampCreated": 1496670,
          #     "status": 0,
          #     "orderType": "limit",
          #     "deals": [
          #       {
          #         "pair": "btcusd",
          #         "type": "buy",
          #         "amount": 1,
          #         "rate": 1000.0,
          #         "orderId": 1,
          #         "timestamp": 1496672724,
          #         "commission": 0.001,
          #         "commissionCurrency": "btc"
          #       }
          #     ]
          #   }
          #
          id = self.safe_string(order, 'id')
          status = self.parse_order_status(self.safe_string(order, 'status'))
          timestamp = self.safe_timestamp(order, 'timestampCreated')
          marketId = self.safe_string(order, 'pair')
          market = self.safe_value(self.markets_by_id, marketId, market)
          symbol = None
          if market is not None:
              symbol = market['symbol']
          remaining = self.safe_float(order, 'remainingVolume')
          amount = self.safe_float(order, 'volume')
          price = self.safe_float(order, 'rate')
          filled = None
          cost = None
          if amount is not None:
              if remaining is not None:
                  filled = amount - remaining
                  cost = price * filled
          orderType = self.safe_string(order, 'orderType')
          side = self.safe_string(order, 'type')
          fee = None
          deals = self.safe_value(order, 'deals', [])
          numDeals = len(deals)
          trades = None
          lastTradeTimestamp = None
          if numDeals > 0:
              trades = self.parse_trades(deals)
              feeCost = None
              feeCurrency = None
              for i in range(0, len(trades)):
                  trade = trades[i]
                  if feeCost is None:
                      feeCost = 0
                  feeCost = self.sum(feeCost, trade['fee']['cost'])
                  feeCurrency = trade['fee']['currency']
                  lastTradeTimestamp = trade['timestamp']
              if feeCost is not None:
                  fee = {
                      'cost': feeCost,
                      'currency': feeCurrency,
                  }
          return {
              'info': order,
              'id': id,
              'symbol': symbol,
              'timestamp': timestamp,
              'datetime': self.iso8601(timestamp),
              'lastTradeTimestamp': lastTradeTimestamp,
              'type': orderType,
              'side': side,
              'price': price,
              'cost': cost,
              'amount': amount,
              'remaining': remaining,
              'filled': filled,
              'status': status,
              'fee': fee,
              'trades': trades,
          }
  
      def fetch_order(self, id, symbol=None, params={}):
          self.load_markets()
          request = {
              'orderId': int(id),
          }
          response = self.privatePostOrderStatus(self.extend(request, params))
          #
          #     {
          #       "success": 1,
          #       "return": {
          #         "pair": "btcusd",
          #         "type": "buy",
          #         "remainingVolume": 10,
          #         "volume": 10,
          #         "rate": 1000.0,
          #         "timestampCreated": 1496670,
          #         "status": 0,
          #         "orderType": "limit",
          #         "deals": [
          #           {
          #             "pair": "btcusd",
          #             "type": "buy",
          #             "amount": 1,
          #             "rate": 1000.0,
          #             "orderId": 1,
          #             "timestamp": 1496672724,
          #             "commission": 0.001,
          #             "commissionCurrency": "btc"
          #           }
          #         ]
          #       }
          #     }
          #
          return self.parse_order(self.extend({
              'id': id,
          }, response['return']))
  
      def parse_orders_by_id(self, orders, symbol=None, since=None, limit=None):
          ids = list(orders.keys())
          result = []
          for i in range(0, len(ids)):
              id = ids[i]
              order = self.parse_order(self.extend({
                  'id': str(id),
              }, orders[id]))
              result.append(order)
          return self.filter_by_symbol_since_limit(result, symbol, since, limit)
  
      def fetch_open_orders(self, symbol=None, since=None, limit=None, params={}):
          self.load_markets()
          request = {
              # 'count': 10,  # Decimal, The maximum number of orders to return
              # 'fromId': 123,  # Decimal, ID of the first order of the selection
              # 'endId': 321,  # Decimal, ID of the last order of the selection
              # 'order': 'ASC',  # String, Order in which orders shown. Possible values are "ASC" — from first to last, "DESC" — from last to first.
          }
          response = self.privatePostOrders(self.extend(request, params))
          #
          #     {
          #       "success": 1,
          #       "return": {
          #         "0": {
          #           "pair": "btcusd",
          #           "type": "buy",
          #           "remainingVolume": 10,
          #           "volume": 10,
          #           "rate": 1000.0,
          #           "timestampCreated": 1496670,
          #           "status": 0,
          #           "orderType": "limit"
          #         }
          #       }
          #     }
          #
          return self.parse_orders_by_id(self.safe_value(response, 'return', {}), symbol, since, limit)
  
      def fetch_orders(self, symbol=None, since=None, limit=None, params={}):
          self.load_markets()
          request = {
              # 'count': 10,  # Decimal, The maximum number of orders to return
              # 'fromId': 123,  # Decimal, ID of the first order of the selection
              # 'endId': 321,  # Decimal, ID of the last order of the selection
              # 'order': 'ASC',  # String, Order in which orders shown. Possible values are "ASC" — from first to last, "DESC" — from last to first.
          }
          response = self.privatePostHistoryOrders(self.extend(request, params))
          #
          #     {
          #       "success": 1,
          #       "return": {
          #         "0": {
          #           "pair": "btcusd",
          #           "type": "buy",
          #           "remainingVolume": 10,
          #           "volume": 10,
          #           "rate": 1000.0,
          #           "timestampCreated": 1496670,
          #           "status": 0,
          #           "orderType": "limit"
          #         }
          #       }
          #     }
          #
          return self.parse_orders_by_id(self.safe_value(response, 'return', {}), symbol, since, limit)
  
      def cancel_order(self, id, symbol=None, params={}):
          self.load_markets()
          request = {
              'orderId': id,
          }
          response = self.privatePostOrderCancel(self.extend(request, params))
          if id in self.orders:
              self.orders[id]['status'] = 'canceled'
          return response
  
      def parse_orders(self, orders, market=None, since=None, limit=None, params={}):
          result = []
          ids = list(orders.keys())
          symbol = None
          if market is not None:
              symbol = market['symbol']
          for i in range(0, len(ids)):
              id = ids[i]
              order = self.extend({'id': id}, orders[id])
              result.append(self.extend(self.parse_order(order, market), params))
          return self.filter_by_symbol_since_limit(result, symbol, since, limit)
  
      def fetch_closed_orders(self, symbol=None, since=None, limit=None, params={}):
          orders = self.fetch_orders(symbol, since, limit, params)
          return self.filter_by(orders, 'status', 'closed')
  
      def fetch_my_trades(self, symbol=None, since=None, limit=None, params={}):
          self.load_markets()
          market = None
          # some derived classes use camelcase notation for request fields
          request = {
              # 'from': 123456789,  # trade ID, from which the display starts numerical 0(test result: liqui ignores self field)
              # 'count': 1000,  # the number of trades for display numerical, default = 1000
              # 'from_id': trade ID, from which the display starts numerical 0
              # 'end_id': trade ID on which the display ends numerical ∞
              # 'order': 'ASC',  # sorting, default = DESC(test result: liqui ignores self field, most recent trade always goes last)
              # 'since': 1234567890,  # UTC start time, default = 0(test result: liqui ignores self field)
              # 'end': 1234567890,  # UTC end time, default = ∞(test result: liqui ignores self field)
              # 'pair': 'eth_btc',  # default = all markets
          }
          if symbol is not None:
              market = self.market(symbol)
              request['pair'] = market['id']
          if limit is not None:
              request['count'] = int(limit)
          if since is not None:
              request['since'] = int(since / 1000)
          response = self.privatePostHistoryTrades(self.extend(request, params))
          trades = []
          if 'return' in response:
              trades = response['return']
          return self.parse_trades(trades, market, since, limit)
  
      def fetch_transactions(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:
              request['since'] = since
          if limit is not None:
              request['count'] = limit
          response = self.privatePostHistoryTransactions(self.extend(request, params))
          #
          #     {
          #         "success": 1,
          #         "return": [
          #             {
          #                 "id": 1,
          #                 "timestamp": 11,
          #                 "type": "Withdraw",
          #                 "amount": 1,
          #                 "currency": "btc",
          #                 "confirmationsCount": 6,
          #                 "address": "address",
          #                 "status": 2,
          #                 "commission": 0.0001
          #             }
          #         ]
          #     }
          #
          transactions = self.safe_value(response, 'return', [])
          return self.parseTransactions(transactions, currency, since, limit)
  
      def parse_transaction_status(self, status):
          statuses = {
              '1': 'failed',
              '2': 'ok',
              '3': 'pending',
              '4': 'failed',
          }
          return self.safe_string(statuses, status, status)
  
      def parse_transaction(self, transaction, currency=None):
          #
          #     {
          #         "id": 1,
          #         "timestamp": 11,  # 11 in their docs(
          #         "type": "Withdraw",
          #         "amount": 1,
          #         "currency": "btc",
          #         "confirmationsCount": 6,
          #         "address": "address",
          #         "status": 2,
          #         "commission": 0.0001
          #     }
          #
          timestamp = self.safe_timestamp(transaction, 'timestamp')
          type = self.safe_string(transaction, 'type')
          if type is not None:
              if type == 'Incoming':
                  type = 'deposit'
              elif type == 'Withdraw':
                  type = 'withdrawal'
          currencyId = self.safe_string(transaction, 'currency')
          code = self.safe_currency_code(currencyId, currency)
          status = self.parse_transaction_status(self.safe_string(transaction, 'status'))
          return {
              'id': self.safe_string(transaction, 'id'),
              'txid': self.safe_string(transaction, 'txid'),
              'timestamp': timestamp,
              'datetime': self.iso8601(timestamp),
              'address': self.safe_string(transaction, 'address'),
              'type': type,
              'amount': self.safe_float(transaction, 'amount'),
              'currency': code,
              'status': status,
              'fee': {
                  'currency': code,
                  'cost': self.safe_float(transaction, 'commission'),
                  'rate': None,
              },
              'info': transaction,
          }
  
      def create_deposit_address(self, code, params={}):
          request = {
              'new': 1,
          }
          response = self.fetch_deposit_address(code, self.extend(request, params))
          return response
  
      def fetch_deposit_address(self, code, params={}):
          self.load_markets()
          currency = self.currency(code)
          request = {
              'currency': currency['id'],
          }
          response = self.dwapiPostDepositCryptoaddress(self.extend(request, params))
          result = self.safe_value(response, 'return', {})
          address = self.safe_string(result, 'address')
          self.check_address(address)
          return {
              'currency': code,
              'address': address,
              'tag': None,  # not documented in DSX API
              'info': response,
          }
  
      def withdraw(self, code, amount, address, tag=None, params={}):
          self.check_address(address)
          self.load_markets()
          currency = self.currency(code)
          commission = self.safe_value(params, 'commission')
          if commission is None:
              raise ArgumentsRequired(self.id + ' withdraw() requires a `commission`(withdrawal fee) parameter(string)')
          params = self.omit(params, commission)
          request = {
              'currency': currency['id'],
              'amount': float(amount),
              'address': address,
              'commission': commission,
          }
          if tag is not None:
              request['address'] += ':' + tag
          response = self.dwapiPostWithdrawCrypto(self.extend(request, params))
          #
          #     [
          #         {
          #             "success": 1,
          #             "return": {
          #                 "transactionId": 2863073
          #             }
          #         }
          #     ]
          #
          data = self.safe_value(response, 'return', {})
          id = self.safe_string(data, 'transactionId')
          return {
              'info': response,
              'id': id,
          }
  
      def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
          url = self.urls['api'][api]
          query = self.omit(params, self.extract_params(path))
          if api == 'private' or api == 'dwapi':
              url += '/' + self.version + '/' + self.implode_params(path, params)
              self.check_required_credentials()
              nonce = self.nonce()
              body = self.urlencode(self.extend({
                  'nonce': nonce,
              }, query))
              signature = self.decode(self.hmac(self.encode(body), self.encode(self.secret), hashlib.sha512, 'base64'))
              headers = {
                  'Content-Type': 'application/x-www-form-urlencoded',
                  'Key': self.apiKey,
                  'Sign': signature,
              }
          elif api == 'public':
              url += '/' + self.implode_params(path, params)
              if query:
                  url += '?' + self.urlencode(query)
          else:
              url += '/' + self.implode_params(path, params)
              if method == 'GET':
                  if query:
                      url += '?' + self.urlencode(query)
              else:
                  if query:
                      body = self.json(query)
                      headers = {
                          'Content-Type': 'application/json',
                      }
          return {'url': url, 'method': method, 'body': body, 'headers': headers}
  
      def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
          if response is None:
              return  # fallback to default error handler
          if 'success' in response:
              #
              # 1 - Liqui only returns the integer 'success' key from their private API
              #
              #     {"success": 1, ...} httpCode == 200
              #     {"success": 0, ...} httpCode == 200
              #
              # 2 - However, exchanges derived from Liqui, can return non-integers
              #
              #     It can be a numeric string
              #     {"sucesss": "1", ...}
              #     {"sucesss": "0", ...}, httpCode >= 200(can be 403, 502, etc)
              #
              #     Or just a string
              #     {"success": "true", ...}
              #     {"success": "false", ...}, httpCode >= 200
              #
              #     Or a boolean
              #     {"success": True, ...}
              #     {"success": False, ...}, httpCode >= 200
              #
              # 3 - Oversimplified, Python PEP8 forbids comparison operator(==) of different types
              #
              # 4 - We do not want to copy-paste and duplicate the code of self handler to other exchanges derived from Liqui
              #
              # To cover points 1, 2, 3 and 4 combined self handler should work like self:
              #
              success = self.safe_value(response, 'success', False)
              if isinstance(success, basestring):
                  if (success == 'true') or (success == '1'):
                      success = True
                  else:
                      success = False
              if not success:
                  code = self.safe_string(response, 'code')
                  message = self.safe_string(response, 'error')
                  feedback = self.id + ' ' + self.json(response)
                  exact = self.exceptions['exact']
                  if code in exact:
                      raise exact[code](feedback)
                  elif message in exact:
                      raise exact[message](feedback)
                  broad = self.exceptions['broad']
                  broadKey = self.findBroadlyMatchedKey(broad, message)
                  if broadKey is not None:
                      raise broad[broadKey](feedback)
                  raise ExchangeError(feedback)  # unknown message
  