text: # -*- coding: utf-8 -*-
  
  from ccxt.base.exchange import Exchange
  from ccxt.base.errors import ExchangeError
  
  
  class _1btcxe (Exchange):
  
      def describe(self):
          return self.deep_extend(super(_1btcxe, self).describe(), {
              'id': '_1btcxe',
              'name': '1BTCXE',
              'countries': 'PA',  # Panama
              'comment': 'Crypto Capital API',
              'has': {
                  'CORS': True,
                  'withdraw': True,
              },
              'timeframes': {
                  '1d': '1year',
              },
              'urls': {
                  'logo': 'https://user-images.githubusercontent.com/1294454/27766049-2b294408-5ecc-11e7-85cc-adaff013dc1a.jpg',
                  'api': 'https://1btcxe.com/api',
                  'www': 'https://1btcxe.com',
                  'doc': 'https://1btcxe.com/api-docs.php',
              },
              'api': {
                  'public': {
                      'get': [
                          'stats',
                          'historical-prices',
                          'order-book',
                          'transactions',
                      ],
                  },
                  'private': {
                      'post': [
                          'balances-and-info',
                          'open-orders',
                          'user-transactions',
                          'btc-deposit-address/get',
                          'btc-deposit-address/new',
                          'deposits/get',
                          'withdrawals/get',
                          'orders/new',
                          'orders/edit',
                          'orders/cancel',
                          'orders/status',
                          'withdrawals/new',
                      ],
                  },
              },
              'markets': {
                  'BTC/USD': {'id': 'USD', 'symbol': 'BTC/USD', 'base': 'BTC', 'quote': 'USD'},
                  'BTC/EUR': {'id': 'EUR', 'symbol': 'BTC/EUR', 'base': 'BTC', 'quote': 'EUR'},
                  'BTC/CNY': {'id': 'CNY', 'symbol': 'BTC/CNY', 'base': 'BTC', 'quote': 'CNY'},
                  'BTC/RUB': {'id': 'RUB', 'symbol': 'BTC/RUB', 'base': 'BTC', 'quote': 'RUB'},
                  'BTC/CHF': {'id': 'CHF', 'symbol': 'BTC/CHF', 'base': 'BTC', 'quote': 'CHF'},
                  'BTC/JPY': {'id': 'JPY', 'symbol': 'BTC/JPY', 'base': 'BTC', 'quote': 'JPY'},
                  'BTC/GBP': {'id': 'GBP', 'symbol': 'BTC/GBP', 'base': 'BTC', 'quote': 'GBP'},
                  'BTC/CAD': {'id': 'CAD', 'symbol': 'BTC/CAD', 'base': 'BTC', 'quote': 'CAD'},
                  'BTC/AUD': {'id': 'AUD', 'symbol': 'BTC/AUD', 'base': 'BTC', 'quote': 'AUD'},
                  'BTC/AED': {'id': 'AED', 'symbol': 'BTC/AED', 'base': 'BTC', 'quote': 'AED'},
                  'BTC/BGN': {'id': 'BGN', 'symbol': 'BTC/BGN', 'base': 'BTC', 'quote': 'BGN'},
                  'BTC/CZK': {'id': 'CZK', 'symbol': 'BTC/CZK', 'base': 'BTC', 'quote': 'CZK'},
                  'BTC/DKK': {'id': 'DKK', 'symbol': 'BTC/DKK', 'base': 'BTC', 'quote': 'DKK'},
                  'BTC/HKD': {'id': 'HKD', 'symbol': 'BTC/HKD', 'base': 'BTC', 'quote': 'HKD'},
                  'BTC/HRK': {'id': 'HRK', 'symbol': 'BTC/HRK', 'base': 'BTC', 'quote': 'HRK'},
                  'BTC/HUF': {'id': 'HUF', 'symbol': 'BTC/HUF', 'base': 'BTC', 'quote': 'HUF'},
                  'BTC/ILS': {'id': 'ILS', 'symbol': 'BTC/ILS', 'base': 'BTC', 'quote': 'ILS'},
                  'BTC/INR': {'id': 'INR', 'symbol': 'BTC/INR', 'base': 'BTC', 'quote': 'INR'},
                  'BTC/MUR': {'id': 'MUR', 'symbol': 'BTC/MUR', 'base': 'BTC', 'quote': 'MUR'},
                  'BTC/MXN': {'id': 'MXN', 'symbol': 'BTC/MXN', 'base': 'BTC', 'quote': 'MXN'},
                  'BTC/NOK': {'id': 'NOK', 'symbol': 'BTC/NOK', 'base': 'BTC', 'quote': 'NOK'},
                  'BTC/NZD': {'id': 'NZD', 'symbol': 'BTC/NZD', 'base': 'BTC', 'quote': 'NZD'},
                  'BTC/PLN': {'id': 'PLN', 'symbol': 'BTC/PLN', 'base': 'BTC', 'quote': 'PLN'},
                  'BTC/RON': {'id': 'RON', 'symbol': 'BTC/RON', 'base': 'BTC', 'quote': 'RON'},
                  'BTC/SEK': {'id': 'SEK', 'symbol': 'BTC/SEK', 'base': 'BTC', 'quote': 'SEK'},
                  'BTC/SGD': {'id': 'SGD', 'symbol': 'BTC/SGD', 'base': 'BTC', 'quote': 'SGD'},
                  'BTC/THB': {'id': 'THB', 'symbol': 'BTC/THB', 'base': 'BTC', 'quote': 'THB'},
                  'BTC/TRY': {'id': 'TRY', 'symbol': 'BTC/TRY', 'base': 'BTC', 'quote': 'TRY'},
                  'BTC/ZAR': {'id': 'ZAR', 'symbol': 'BTC/ZAR', 'base': 'BTC', 'quote': 'ZAR'},
              },
          })
  
      def fetch_balance(self, params={}):
          response = self.privatePostBalancesAndInfo()
          balance = response['balances-and-info']
          result = {'info': balance}
          currencies = list(self.currencies.keys())
          for i in range(0, len(currencies)):
              currency = currencies[i]
              account = self.account()
              account['free'] = self.safe_float(balance['available'], currency, 0.0)
              account['used'] = self.safe_float(balance['on_hold'], currency, 0.0)
              account['total'] = self.sum(account['free'], account['used'])
              result[currency] = account
          return self.parse_balance(result)
  
      def fetch_order_book(self, symbol, params={}):
          response = self.publicGetOrderBook(self.extend({
              'currency': self.market_id(symbol),
          }, params))
          return self.parse_order_book(response['order-book'], None, 'bid', 'ask', 'price', 'order_amount')
  
      def fetch_ticker(self, symbol, params={}):
          response = self.publicGetStats(self.extend({
              'currency': self.market_id(symbol),
          }, params))
          ticker = response['stats']
          timestamp = self.milliseconds()
          return {
              'symbol': symbol,
              'timestamp': timestamp,
              'datetime': self.iso8601(timestamp),
              'high': float(ticker['max']),
              'low': float(ticker['min']),
              'bid': float(ticker['bid']),
              'ask': float(ticker['ask']),
              'vwap': None,
              'open': float(ticker['open']),
              'close': None,
              'first': None,
              'last': float(ticker['last_price']),
              'change': float(ticker['daily_change']),
              'percentage': None,
              'average': None,
              'baseVolume': None,
              'quoteVolume': float(ticker['total_btc_traded']),
          }
  
      def parse_ohlcv(self, ohlcv, market=None, timeframe='1d', since=None, limit=None):
          return [
              self.parse8601(ohlcv['date'] + ' 00:00:00'),
              None,
              None,
              None,
              float(ohlcv['price']),
              None,
          ]
  
      def fetch_ohlcv(self, symbol, timeframe='1d', since=None, limit=None, params={}):
          market = self.market(symbol)
          response = self.publicGetHistoricalPrices(self.extend({
              'currency': market['id'],
              'timeframe': self.timeframes[timeframe],
          }, params))
          ohlcvs = self.omit(response['historical-prices'], 'request_currency')
          return self.parse_ohlcvs(ohlcvs, market, timeframe, since, limit)
  
      def parse_trade(self, trade, market):
          timestamp = int(trade['timestamp']) * 1000
          return {
              'id': trade['id'],
              'info': trade,
              'timestamp': timestamp,
              'datetime': self.iso8601(timestamp),
              'symbol': market['symbol'],
              'order': None,
              'type': None,
              'side': trade['maker_type'],
              'price': float(trade['price']),
              'amount': float(trade['amount']),
          }
  
      def fetch_trades(self, symbol, since=None, limit=None, params={}):
          market = self.market(symbol)
          response = self.publicGetTransactions(self.extend({
              'currency': market['id'],
          }, params))
          trades = self.omit(response['transactions'], 'request_currency')
          return self.parse_trades(trades, market, since, limit)
  
      def create_order(self, symbol, type, side, amount, price=None, params={}):
          order = {
              'side': side,
              'type': type,
              'currency': self.market_id(symbol),
              'amount': amount,
          }
          if type == 'limit':
              order['limit_price'] = price
          result = self.privatePostOrdersNew(self.extend(order, params))
          return {
              'info': result,
              'id': result,
          }
  
      def cancel_order(self, id, symbol=None, params={}):
          return self.privatePostOrdersCancel({'id': id})
  
      def withdraw(self, currency, amount, address, tag=None, params={}):
          self.load_markets()
          response = self.privatePostWithdrawalsNew(self.extend({
              'currency': currency,
              'amount': float(amount),
              'address': address,
          }, params))
          return {
              'info': response,
              'id': response['result']['uuid'],
          }
  
      def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
          if self.id == 'cryptocapital':
              raise ExchangeError(self.id + ' is an abstract base API for _1btcxe')
          url = self.urls['api'] + '/' + path
          if api == 'public':
              if params:
                  url += '?' + self.urlencode(params)
          else:
              self.check_required_credentials()
              query = self.extend({
                  'api_key': self.apiKey,
                  'nonce': self.nonce(),
              }, params)
              request = self.json(query)
              query['signature'] = self.hmac(self.encode(request), self.encode(self.secret))
              body = self.json(query)
              headers = {'Content-Type': 'application/json'}
          return {'url': url, 'method': method, 'body': body, 'headers': headers}
  
      def request(self, path, api='public', method='GET', params={}, headers=None, body=None):
          response = self.fetch2(path, api, method, params, headers, body)
          if 'errors' in response:
              errors = []
              for e in range(0, len(response['errors'])):
                  error = response['errors'][e]
                  errors.append(error['code'] + ': ' + error['message'])
              errors = ' '.join(errors)
              raise ExchangeError(self.id + ' ' + errors)
          return response
  