/python/ccxt/async_support/coinex.py
https://github.com/kroitor/ccxt · Python · 895 lines · 620 code · 32 blank · 243 comment · 50 complexity · af99fc6813fd8ec876d259c78a696831 MD5 · raw file
- # -*- coding: utf-8 -*-
- # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
- # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
- from ccxt.async_support.base.exchange import Exchange
- import math
- from ccxt.base.errors import ExchangeError
- from ccxt.base.errors import AuthenticationError
- from ccxt.base.errors import ArgumentsRequired
- from ccxt.base.errors import InsufficientFunds
- from ccxt.base.errors import InvalidOrder
- from ccxt.base.errors import OrderNotFound
- class coinex(Exchange):
- def describe(self):
- return self.deep_extend(super(coinex, self).describe(), {
- 'id': 'coinex',
- 'name': 'CoinEx',
- 'version': 'v1',
- 'countries': ['CN'],
- 'rateLimit': 1000,
- 'has': {
- 'cancelOrder': True,
- 'createOrder': True,
- 'fetchBalance': True,
- 'fetchClosedOrders': True,
- 'fetchDeposits': True,
- 'fetchMarkets': True,
- 'fetchMyTrades': True,
- 'fetchOHLCV': True,
- 'fetchOpenOrders': True,
- 'fetchOrder': True,
- 'fetchOrderBook': True,
- 'fetchTicker': True,
- 'fetchTickers': True,
- 'fetchTrades': True,
- 'fetchWithdrawals': True,
- 'withdraw': True,
- },
- 'timeframes': {
- '1m': '1min',
- '3m': '3min',
- '5m': '5min',
- '15m': '15min',
- '30m': '30min',
- '1h': '1hour',
- '2h': '2hour',
- '4h': '4hour',
- '6h': '6hour',
- '12h': '12hour',
- '1d': '1day',
- '3d': '3day',
- '1w': '1week',
- },
- 'urls': {
- 'logo': 'https://user-images.githubusercontent.com/51840849/87182089-1e05fa00-c2ec-11ea-8da9-cc73b45abbbc.jpg',
- 'api': 'https://api.coinex.com',
- 'www': 'https://www.coinex.com',
- 'doc': 'https://github.com/coinexcom/coinex_exchange_api/wiki',
- 'fees': 'https://www.coinex.com/fees',
- 'referral': 'https://www.coinex.com/register?refer_code=yw5fz',
- },
- 'api': {
- 'public': {
- 'get': [
- 'common/currency/rate',
- 'common/asset/config',
- 'market/info',
- 'market/list',
- 'market/ticker',
- 'market/ticker/all',
- 'market/depth',
- 'market/deals',
- 'market/kline',
- ],
- },
- 'private': {
- 'get': [
- 'balance/coin/deposit',
- 'balance/coin/withdraw',
- 'balance/info',
- 'future/account',
- 'future/config',
- 'future/limitprice',
- 'future/loan/history',
- 'future/market',
- 'margin/account',
- 'margin/config',
- 'margin/loan/history',
- 'margin/market',
- 'order',
- 'order/deals',
- 'order/finished',
- 'order/finished/{id}',
- 'order/pending',
- 'order/status',
- 'order/status/batch',
- 'order/user/deals',
- ],
- 'post': [
- 'balance/coin/withdraw',
- 'future/flat',
- 'future/loan',
- 'future/transfer',
- 'margin/flat',
- 'margin/loan',
- 'margin/transfer',
- 'order/batchlimit',
- 'order/ioc',
- 'order/limit',
- 'order/market',
- 'sub_account/transfer',
- ],
- 'delete': [
- 'balance/coin/withdraw',
- 'order/pending/batch',
- 'order/pending',
- ],
- },
- },
- 'fees': {
- 'trading': {
- 'maker': 0.001,
- 'taker': 0.001,
- },
- 'funding': {
- 'withdraw': {
- 'BCH': 0.0,
- 'BTC': 0.001,
- 'LTC': 0.001,
- 'ETH': 0.001,
- 'ZEC': 0.0001,
- 'DASH': 0.0001,
- },
- },
- },
- 'limits': {
- 'amount': {
- 'min': 0.001,
- 'max': None,
- },
- },
- 'precision': {
- 'amount': 8,
- 'price': 8,
- },
- 'options': {
- 'createMarketBuyOrderRequiresPrice': True,
- },
- })
- async def fetch_markets(self, params={}):
- response = await self.publicGetMarketInfo(params)
- #
- # {
- # "code": 0,
- # "data": {
- # "WAVESBTC": {
- # "name": "WAVESBTC",
- # "min_amount": "1",
- # "maker_fee_rate": "0.001",
- # "taker_fee_rate": "0.001",
- # "pricing_name": "BTC",
- # "pricing_decimal": 8,
- # "trading_name": "WAVES",
- # "trading_decimal": 8
- # }
- # }
- # }
- #
- markets = self.safe_value(response, 'data', {})
- result = []
- keys = list(markets.keys())
- for i in range(0, len(keys)):
- key = keys[i]
- market = markets[key]
- id = self.safe_string(market, 'name')
- tradingName = self.safe_string(market, 'trading_name')
- baseId = tradingName
- quoteId = self.safe_string(market, 'pricing_name')
- base = self.safe_currency_code(baseId)
- quote = self.safe_currency_code(quoteId)
- symbol = base + '/' + quote
- if tradingName == id:
- symbol = id
- precision = {
- 'amount': self.safe_integer(market, 'trading_decimal'),
- 'price': self.safe_integer(market, 'pricing_decimal'),
- }
- active = None
- result.append({
- 'id': id,
- 'symbol': symbol,
- 'base': base,
- 'quote': quote,
- 'baseId': baseId,
- 'quoteId': quoteId,
- 'active': active,
- 'taker': self.safe_float(market, 'taker_fee_rate'),
- 'maker': self.safe_float(market, 'maker_fee_rate'),
- 'info': market,
- 'precision': precision,
- 'limits': {
- 'amount': {
- 'min': self.safe_float(market, 'min_amount'),
- 'max': None,
- },
- 'price': {
- 'min': math.pow(10, -precision['price']),
- 'max': None,
- },
- },
- })
- return result
- def parse_ticker(self, ticker, market=None):
- timestamp = self.safe_integer(ticker, 'date')
- symbol = None
- if market is not None:
- symbol = market['symbol']
- ticker = self.safe_value(ticker, 'ticker', {})
- 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': None,
- 'baseVolume': self.safe_float_2(ticker, 'vol', 'volume'),
- 'quoteVolume': None,
- 'info': ticker,
- }
- async def fetch_ticker(self, symbol, params={}):
- await self.load_markets()
- market = self.market(symbol)
- request = {
- 'market': market['id'],
- }
- response = await self.publicGetMarketTicker(self.extend(request, params))
- return self.parse_ticker(response['data'], market)
- async def fetch_tickers(self, symbols=None, params={}):
- await self.load_markets()
- response = await self.publicGetMarketTickerAll(params)
- data = self.safe_value(response, 'data')
- timestamp = self.safe_integer(data, 'date')
- tickers = self.safe_value(data, 'ticker')
- marketIds = list(tickers.keys())
- result = {}
- for i in range(0, len(marketIds)):
- marketId = marketIds[i]
- symbol = marketId
- market = None
- if marketId in self.markets_by_id:
- market = self.markets_by_id[marketId]
- symbol = market['symbol']
- ticker = self.parse_ticker({
- 'date': timestamp,
- 'ticker': tickers[marketId],
- }, market)
- ticker['symbol'] = symbol
- result[symbol] = ticker
- return self.filter_by_array(result, 'symbol', symbols)
- async def fetch_order_book(self, symbol, limit=20, params={}):
- await self.load_markets()
- if limit is None:
- limit = 20 # default
- request = {
- 'market': self.market_id(symbol),
- 'merge': '0.0000000001',
- 'limit': str(limit),
- }
- response = await self.publicGetMarketDepth(self.extend(request, params))
- return self.parse_order_book(response['data'])
- def parse_trade(self, trade, market=None):
- # self method parses both public and private trades
- timestamp = self.safe_timestamp(trade, 'create_time')
- if timestamp is None:
- timestamp = self.safe_integer(trade, 'date_ms')
- tradeId = self.safe_string(trade, 'id')
- orderId = self.safe_string(trade, 'order_id')
- price = self.safe_float(trade, 'price')
- amount = self.safe_float(trade, 'amount')
- marketId = self.safe_string(trade, 'market')
- market = self.safe_value(self.markets_by_id, marketId, market)
- symbol = None
- if market is not None:
- symbol = market['symbol']
- cost = self.safe_float(trade, 'deal_money')
- if not cost:
- cost = float(self.cost_to_precision(symbol, price * amount))
- fee = None
- feeCost = self.safe_float(trade, 'fee')
- if feeCost is not None:
- feeCurrencyId = self.safe_string(trade, 'fee_asset')
- feeCurrencyCode = self.safe_currency_code(feeCurrencyId)
- fee = {
- 'cost': feeCost,
- 'currency': feeCurrencyCode,
- }
- takerOrMaker = self.safe_string(trade, 'role')
- side = self.safe_string(trade, 'type')
- return {
- 'info': trade,
- 'timestamp': timestamp,
- 'datetime': self.iso8601(timestamp),
- 'symbol': symbol,
- 'id': tradeId,
- 'order': orderId,
- 'type': None,
- 'side': side,
- 'takerOrMaker': takerOrMaker,
- 'price': price,
- 'amount': amount,
- 'cost': cost,
- 'fee': fee,
- }
- async def fetch_trades(self, symbol, since=None, limit=None, params={}):
- await self.load_markets()
- market = self.market(symbol)
- request = {
- 'market': market['id'],
- }
- response = await self.publicGetMarketDeals(self.extend(request, params))
- return self.parse_trades(response['data'], market, since, limit)
- def parse_ohlcv(self, ohlcv, market=None):
- #
- # [
- # 1591484400,
- # "0.02505349",
- # "0.02506988",
- # "0.02507000",
- # "0.02505304",
- # "343.19716223",
- # "8.6021323866383196",
- # "ETHBTC"
- # ]
- #
- return [
- self.safe_timestamp(ohlcv, 0),
- self.safe_float(ohlcv, 1),
- self.safe_float(ohlcv, 3),
- self.safe_float(ohlcv, 4),
- self.safe_float(ohlcv, 2),
- self.safe_float(ohlcv, 5),
- ]
- async def fetch_ohlcv(self, symbol, timeframe='5m', since=None, limit=None, params={}):
- await self.load_markets()
- market = self.market(symbol)
- request = {
- 'market': market['id'],
- 'type': self.timeframes[timeframe],
- }
- if limit is not None:
- request['limit'] = limit
- response = await self.publicGetMarketKline(self.extend(request, params))
- #
- # {
- # "code": 0,
- # "data": [
- # [1591484400, "0.02505349", "0.02506988", "0.02507000", "0.02505304", "343.19716223", "8.6021323866383196", "ETHBTC"],
- # [1591484700, "0.02506990", "0.02508109", "0.02508109", "0.02506979", "91.59841581", "2.2972047780447000", "ETHBTC"],
- # [1591485000, "0.02508106", "0.02507996", "0.02508106", "0.02507500", "65.15307697", "1.6340597822306000", "ETHBTC"],
- # ],
- # "message": "OK"
- # }
- #
- data = self.safe_value(response, 'data', [])
- return self.parse_ohlcvs(data, market, timeframe, since, limit)
- async def fetch_balance(self, params={}):
- await self.load_markets()
- response = await self.privateGetBalanceInfo(params)
- #
- # {
- # "code": 0,
- # "data": {
- # "BCH": { # BCH account
- # "available": "13.60109", # Available BCH
- # "frozen": "0.00000" # Frozen BCH
- # },
- # "BTC": { # BTC account
- # "available": "32590.16", # Available BTC
- # "frozen": "7000.00" # Frozen BTC
- # },
- # "ETH": { # ETH account
- # "available": "5.06000", # Available ETH
- # "frozen": "0.00000" # Frozen ETH
- # }
- # },
- # "message": "Ok"
- # }
- #
- result = {'info': response}
- balances = self.safe_value(response, 'data')
- currencyIds = list(balances.keys())
- for i in range(0, len(currencyIds)):
- currencyId = currencyIds[i]
- code = self.safe_currency_code(currencyId)
- balance = self.safe_value(balances, currencyId, {})
- account = self.account()
- account['free'] = self.safe_float(balance, 'available')
- account['used'] = self.safe_float(balance, 'frozen')
- result[code] = account
- return self.parse_balance(result)
- def parse_order_status(self, status):
- statuses = {
- 'not_deal': 'open',
- 'part_deal': 'open',
- 'done': 'closed',
- 'cancel': 'canceled',
- }
- return self.safe_string(statuses, status, status)
- def parse_order(self, order, market=None):
- #
- # fetchOrder
- #
- # {
- # "amount": "0.1",
- # "asset_fee": "0.22736197736197736197",
- # "avg_price": "196.85000000000000000000",
- # "create_time": 1537270135,
- # "deal_amount": "0.1",
- # "deal_fee": "0",
- # "deal_money": "19.685",
- # "fee_asset": "CET",
- # "fee_discount": "0.5",
- # "id": 1788259447,
- # "left": "0",
- # "maker_fee_rate": "0",
- # "market": "ETHUSDT",
- # "order_type": "limit",
- # "price": "170.00000000",
- # "status": "done",
- # "taker_fee_rate": "0.0005",
- # "type": "sell",
- # }
- #
- timestamp = self.safe_timestamp(order, 'create_time')
- price = self.safe_float(order, 'price')
- cost = self.safe_float(order, 'deal_money')
- amount = self.safe_float(order, 'amount')
- filled = self.safe_float(order, 'deal_amount')
- average = self.safe_float(order, 'avg_price')
- symbol = None
- marketId = self.safe_string(order, 'market')
- market = self.safe_value(self.markets_by_id, marketId)
- feeCurrencyId = self.safe_string(order, 'fee_asset')
- feeCurrency = self.safe_currency_code(feeCurrencyId)
- if market is not None:
- symbol = market['symbol']
- if feeCurrency is None:
- feeCurrency = market['quote']
- remaining = self.safe_float(order, 'left')
- status = self.parse_order_status(self.safe_string(order, 'status'))
- type = self.safe_string(order, 'order_type')
- side = self.safe_string(order, 'type')
- return {
- 'id': self.safe_string(order, 'id'),
- 'clientOrderId': None,
- 'datetime': self.iso8601(timestamp),
- 'timestamp': timestamp,
- 'lastTradeTimestamp': None,
- 'status': status,
- 'symbol': symbol,
- 'type': type,
- 'side': side,
- 'price': price,
- 'cost': cost,
- 'average': average,
- 'amount': amount,
- 'filled': filled,
- 'remaining': remaining,
- 'trades': None,
- 'fee': {
- 'currency': feeCurrency,
- 'cost': self.safe_float(order, 'deal_fee'),
- },
- 'info': order,
- }
- async def create_order(self, symbol, type, side, amount, price=None, params={}):
- await self.load_markets()
- method = 'privatePostOrder' + self.capitalize(type)
- market = self.market(symbol)
- request = {
- 'market': market['id'],
- 'type': side,
- }
- amount = float(amount)
- # for market buy it requires the amount of quote currency to spend
- if (type == 'market') and (side == 'buy'):
- if self.options['createMarketBuyOrderRequiresPrice']:
- if price is None:
- raise InvalidOrder(self.id + " createOrder() requires the price argument with market buy orders to calculate total order cost(amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = False to supply the cost in the amount argument(the exchange-specific behaviour)")
- else:
- price = float(price)
- request['amount'] = self.cost_to_precision(symbol, amount * price)
- else:
- request['amount'] = self.cost_to_precision(symbol, amount)
- else:
- request['amount'] = self.amount_to_precision(symbol, amount)
- if (type == 'limit') or (type == 'ioc'):
- request['price'] = self.price_to_precision(symbol, price)
- response = await getattr(self, method)(self.extend(request, params))
- data = self.safe_value(response, 'data')
- return self.parse_order(data, market)
- async def cancel_order(self, id, symbol=None, params={}):
- await self.load_markets()
- market = self.market(symbol)
- request = {
- 'id': id,
- 'market': market['id'],
- }
- response = await self.privateDeleteOrderPending(self.extend(request, params))
- data = self.safe_value(response, 'data')
- return self.parse_order(data, market)
- async def fetch_order(self, id, symbol=None, params={}):
- if symbol is None:
- raise ArgumentsRequired(self.id + ' fetchOrder requires a symbol argument')
- await self.load_markets()
- market = self.market(symbol)
- request = {
- 'id': id,
- 'market': market['id'],
- }
- response = await self.privateGetOrder(self.extend(request, params))
- #
- # {
- # "code": 0,
- # "data": {
- # "amount": "0.1",
- # "asset_fee": "0.22736197736197736197",
- # "avg_price": "196.85000000000000000000",
- # "create_time": 1537270135,
- # "deal_amount": "0.1",
- # "deal_fee": "0",
- # "deal_money": "19.685",
- # "fee_asset": "CET",
- # "fee_discount": "0.5",
- # "id": 1788259447,
- # "left": "0",
- # "maker_fee_rate": "0",
- # "market": "ETHUSDT",
- # "order_type": "limit",
- # "price": "170.00000000",
- # "status": "done",
- # "taker_fee_rate": "0.0005",
- # "type": "sell",
- # },
- # "message": "Ok"
- # }
- #
- data = self.safe_value(response, 'data')
- return self.parse_order(data, market)
- async def fetch_orders_by_status(self, status, symbol=None, since=None, limit=None, params={}):
- await self.load_markets()
- if limit is None:
- limit = 100
- request = {
- 'page': 1,
- 'limit': limit,
- }
- market = None
- if symbol is not None:
- market = self.market(symbol)
- request['market'] = market['id']
- method = 'privateGetOrder' + self.capitalize(status)
- response = await getattr(self, method)(self.extend(request, params))
- data = self.safe_value(response, 'data')
- orders = self.safe_value(data, 'data', [])
- return self.parse_orders(orders, market, since, limit)
- async def fetch_open_orders(self, symbol=None, since=None, limit=None, params={}):
- return await self.fetch_orders_by_status('pending', symbol, since, limit, params)
- async def fetch_closed_orders(self, symbol=None, since=None, limit=None, params={}):
- return await self.fetch_orders_by_status('finished', symbol, since, limit, params)
- async def fetch_my_trades(self, symbol=None, since=None, limit=None, params={}):
- await self.load_markets()
- if limit is None:
- limit = 100
- request = {
- 'page': 1,
- 'limit': limit,
- }
- market = None
- if symbol is not None:
- market = self.market(symbol)
- request['market'] = market['id']
- response = await self.privateGetOrderUserDeals(self.extend(request, params))
- data = self.safe_value(response, 'data')
- trades = self.safe_value(data, 'data', [])
- return self.parse_trades(trades, market, since, limit)
- async def withdraw(self, code, amount, address, tag=None, params={}):
- self.check_address(address)
- await self.load_markets()
- currency = self.currency(code)
- if tag:
- address = address + ':' + tag
- request = {
- 'coin_type': currency['id'],
- 'coin_address': address, # must be authorized, inter-user transfer by a registered mobile phone number or an email address is supported
- 'actual_amount': float(amount), # the actual amount without fees, https://www.coinex.com/fees
- 'transfer_method': 'onchain', # onchain, local
- }
- response = await self.privatePostBalanceCoinWithdraw(self.extend(request, params))
- #
- # {
- # "code": 0,
- # "data": {
- # "actual_amount": "1.00000000",
- # "amount": "1.00000000",
- # "coin_address": "1KAv3pazbTk2JnQ5xTo6fpKK7p1it2RzD4",
- # "coin_type": "BCH",
- # "coin_withdraw_id": 206,
- # "confirmations": 0,
- # "create_time": 1524228297,
- # "status": "audit",
- # "tx_fee": "0",
- # "tx_id": ""
- # },
- # "message": "Ok"
- # }
- #
- transaction = self.safe_value(response, 'data', {})
- return self.parse_transaction(transaction, currency)
- def parse_transaction_status(self, status):
- statuses = {
- 'audit': 'pending',
- 'pass': 'pending',
- 'processing': 'pending',
- 'confirming': 'pending',
- 'not_pass': 'failed',
- 'cancel': 'canceled',
- 'finish': 'ok',
- 'fail': 'failed',
- }
- return self.safe_string(statuses, status, status)
- def parse_transaction(self, transaction, currency=None):
- #
- # fetchDeposits
- #
- # {
- # "actual_amount": "120.00000000",
- # "actual_amount_display": "120",
- # "add_explorer": "XXX",
- # "amount": "120.00000000",
- # "amount_display": "120",
- # "coin_address": "XXXXXXXX",
- # "coin_address_display": "XXXXXXXX",
- # "coin_deposit_id": 1866,
- # "coin_type": "USDT",
- # "confirmations": 0,
- # "create_time": 1539595701,
- # "explorer": "",
- # "remark": "",
- # "status": "finish",
- # "status_display": "finish",
- # "transfer_method": "local",
- # "tx_id": "",
- # "tx_id_display": "XXXXXXXXXX"
- # }
- #
- # fetchWithdrawals
- #
- # {
- # "actual_amount": "0.10000000",
- # "amount": "0.10000000",
- # "coin_address": "15sr1VdyXQ6sVLqeJUJ1uPzLpmQtgUeBSB",
- # "coin_type": "BCH",
- # "coin_withdraw_id": 203,
- # "confirmations": 11,
- # "create_time": 1515806440,
- # "status": "finish",
- # "tx_fee": "0",
- # "tx_id": "896371d0e23d64d1cac65a0b7c9e9093d835affb572fec89dd4547277fbdd2f6"
- # }
- #
- id = self.safe_string_2(transaction, 'coin_withdraw_id', 'coin_deposit_id')
- address = self.safe_string(transaction, 'coin_address')
- tag = self.safe_string(transaction, 'remark') # set but unused
- if tag is not None:
- if len(tag) < 1:
- tag = None
- txid = self.safe_value(transaction, 'tx_id')
- if txid is not None:
- if len(txid) < 1:
- txid = None
- currencyId = self.safe_string(transaction, 'coin_type')
- code = self.safe_currency_code(currencyId, currency)
- timestamp = self.safe_timestamp(transaction, 'create_time')
- type = 'withdraw' if ('coin_withdraw_id' in transaction) else 'deposit'
- status = self.parse_transaction_status(self.safe_string(transaction, 'status'))
- amount = self.safe_float(transaction, 'amount')
- feeCost = self.safe_float(transaction, 'tx_fee')
- if type == 'deposit':
- feeCost = 0
- fee = {
- 'cost': feeCost,
- 'currency': code,
- }
- return {
- 'info': transaction,
- 'id': id,
- 'txid': txid,
- 'timestamp': timestamp,
- 'datetime': self.iso8601(timestamp),
- 'address': address,
- 'tag': tag,
- 'type': type,
- 'amount': amount,
- 'currency': code,
- 'status': status,
- 'updated': None,
- 'fee': fee,
- }
- async def fetch_withdrawals(self, code=None, since=None, limit=None, params={}):
- if code is None:
- raise ArgumentsRequired(self.id + ' fetchWithdrawals requires a currency code argument')
- await self.load_markets()
- currency = self.currency(code)
- request = {
- 'coin_type': currency['id'],
- }
- if limit is not None:
- request['Limit'] = limit
- response = await self.privateGetBalanceCoinWithdraw(self.extend(request, params))
- #
- # {
- # "code": 0,
- # "data": [
- # {
- # "actual_amount": "1.00000000",
- # "amount": "1.00000000",
- # "coin_address": "1KAv3pazbTk2JnQ5xTo6fpKK7p1it2RzD4",
- # "coin_type": "BCH",
- # "coin_withdraw_id": 206,
- # "confirmations": 0,
- # "create_time": 1524228297,
- # "status": "audit",
- # "tx_fee": "0",
- # "tx_id": ""
- # },
- # {
- # "actual_amount": "0.10000000",
- # "amount": "0.10000000",
- # "coin_address": "15sr1VdyXQ6sVLqeJUJ1uPzLpmQtgUeBSB",
- # "coin_type": "BCH",
- # "coin_withdraw_id": 203,
- # "confirmations": 11,
- # "create_time": 1515806440,
- # "status": "finish",
- # "tx_fee": "0",
- # "tx_id": "896371d0e23d64d1cac65a0b7c9e9093d835affb572fec89dd4547277fbdd2f6"
- # },
- # {
- # "actual_amount": "0.00100000",
- # "amount": "0.00100000",
- # "coin_address": "1GVVx5UBddLKrckTprNi4VhHSymeQ8tsLF",
- # "coin_type": "BCH",
- # "coin_withdraw_id": 27,
- # "confirmations": 0,
- # "create_time": 1513933541,
- # "status": "cancel",
- # "tx_fee": "0",
- # "tx_id": ""
- # }
- # ],
- # "message": "Ok"
- # }
- #
- data = self.safe_value(response, 'data', [])
- return self.parse_transactions(data, currency, since, limit)
- async def fetch_deposits(self, code=None, since=None, limit=None, params={}):
- if code is None:
- raise ArgumentsRequired(self.id + ' fetchDeposits requires a currency code argument')
- await self.load_markets()
- currency = self.currency(code)
- request = {
- 'coin_type': currency['id'],
- }
- if limit is not None:
- request['Limit'] = limit
- response = await self.privateGetBalanceCoinDeposit(self.extend(request, params))
- # {
- # "code": 0,
- # "data": [
- # {
- # "actual_amount": "4.65397682",
- # "actual_amount_display": "4.65397682",
- # "add_explorer": "https://etherscan.io/address/0x361XXXXXX",
- # "amount": "4.65397682",
- # "amount_display": "4.65397682",
- # "coin_address": "0x36dabcdXXXXXX",
- # "coin_address_display": "0x361X*****XXXXX",
- # "coin_deposit_id": 966191,
- # "coin_type": "ETH",
- # "confirmations": 30,
- # "create_time": 1531661445,
- # "explorer": "https://etherscan.io/tx/0x361XXXXXX",
- # "remark": "",
- # "status": "finish",
- # "status_display": "finish",
- # "transfer_method": "onchain",
- # "tx_id": "0x361XXXXXX",
- # "tx_id_display": "0x361XXXXXX"
- # }
- # ],
- # "message": "Ok"
- # }
- #
- data = self.safe_value(response, 'data', [])
- return self.parse_transactions(data, currency, since, limit)
- def nonce(self):
- return self.milliseconds()
- def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
- path = self.implode_params(path, params)
- url = self.urls['api'] + '/' + self.version + '/' + path
- query = self.omit(params, self.extract_params(path))
- if api == 'public':
- if query:
- url += '?' + self.urlencode(query)
- else:
- self.check_required_credentials()
- nonce = self.nonce()
- query = self.extend({
- 'access_id': self.apiKey,
- 'tonce': str(nonce),
- }, query)
- query = self.keysort(query)
- urlencoded = self.urlencode(query)
- signature = self.hash(self.encode(urlencoded + '&secret_key=' + self.secret))
- headers = {
- 'Authorization': signature.upper(),
- 'Content-Type': 'application/json',
- }
- if (method == 'GET') or (method == 'DELETE'):
- url += '?' + urlencoded
- else:
- body = self.json(query)
- return {'url': url, 'method': method, 'body': body, 'headers': headers}
- async def request(self, path, api='public', method='GET', params={}, headers=None, body=None):
- response = await self.fetch2(path, api, method, params, headers, body)
- code = self.safe_string(response, 'code')
- data = self.safe_value(response, 'data')
- message = self.safe_string(response, 'message')
- if (code != '0') or (data is None) or ((message != 'Ok') and not data):
- responseCodes = {
- '24': AuthenticationError,
- '25': AuthenticationError,
- '107': InsufficientFunds,
- '600': OrderNotFound,
- '601': InvalidOrder,
- '602': InvalidOrder,
- '606': InvalidOrder,
- }
- ErrorClass = self.safe_value(responseCodes, code, ExchangeError)
- raise ErrorClass(response['message'])
- return response