ccxt 4.4.49__py2.py3-none-any.whl → 4.4.50__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ccxt/__init__.py CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  # ----------------------------------------------------------------------------
24
24
 
25
- __version__ = '4.4.49'
25
+ __version__ = '4.4.50'
26
26
 
27
27
  # ----------------------------------------------------------------------------
28
28
 
ccxt/abstract/binance.py CHANGED
@@ -220,6 +220,7 @@ class ImplicitAPI:
220
220
  sapi_get_portfolio_repay_futures_switch = sapiGetPortfolioRepayFuturesSwitch = Entry('portfolio/repay-futures-switch', 'sapi', 'GET', {'cost': 3})
221
221
  sapi_get_portfolio_margin_asset_leverage = sapiGetPortfolioMarginAssetLeverage = Entry('portfolio/margin-asset-leverage', 'sapi', 'GET', {'cost': 5})
222
222
  sapi_get_portfolio_balance = sapiGetPortfolioBalance = Entry('portfolio/balance', 'sapi', 'GET', {'cost': 2})
223
+ sapi_get_portfolio_negative_balance_exchange_record = sapiGetPortfolioNegativeBalanceExchangeRecord = Entry('portfolio/negative-balance-exchange-record', 'sapi', 'GET', {'cost': 2})
223
224
  sapi_get_staking_productlist = sapiGetStakingProductList = Entry('staking/productList', 'sapi', 'GET', {'cost': 0.1})
224
225
  sapi_get_staking_position = sapiGetStakingPosition = Entry('staking/position', 'sapi', 'GET', {'cost': 0.1})
225
226
  sapi_get_staking_stakingrecord = sapiGetStakingStakingRecord = Entry('staking/stakingRecord', 'sapi', 'GET', {'cost': 0.1})
@@ -220,6 +220,7 @@ class ImplicitAPI:
220
220
  sapi_get_portfolio_repay_futures_switch = sapiGetPortfolioRepayFuturesSwitch = Entry('portfolio/repay-futures-switch', 'sapi', 'GET', {'cost': 3})
221
221
  sapi_get_portfolio_margin_asset_leverage = sapiGetPortfolioMarginAssetLeverage = Entry('portfolio/margin-asset-leverage', 'sapi', 'GET', {'cost': 5})
222
222
  sapi_get_portfolio_balance = sapiGetPortfolioBalance = Entry('portfolio/balance', 'sapi', 'GET', {'cost': 2})
223
+ sapi_get_portfolio_negative_balance_exchange_record = sapiGetPortfolioNegativeBalanceExchangeRecord = Entry('portfolio/negative-balance-exchange-record', 'sapi', 'GET', {'cost': 2})
223
224
  sapi_get_staking_productlist = sapiGetStakingProductList = Entry('staking/productList', 'sapi', 'GET', {'cost': 0.1})
224
225
  sapi_get_staking_position = sapiGetStakingPosition = Entry('staking/position', 'sapi', 'GET', {'cost': 0.1})
225
226
  sapi_get_staking_stakingrecord = sapiGetStakingStakingRecord = Entry('staking/stakingRecord', 'sapi', 'GET', {'cost': 0.1})
@@ -220,6 +220,7 @@ class ImplicitAPI:
220
220
  sapi_get_portfolio_repay_futures_switch = sapiGetPortfolioRepayFuturesSwitch = Entry('portfolio/repay-futures-switch', 'sapi', 'GET', {'cost': 3})
221
221
  sapi_get_portfolio_margin_asset_leverage = sapiGetPortfolioMarginAssetLeverage = Entry('portfolio/margin-asset-leverage', 'sapi', 'GET', {'cost': 5})
222
222
  sapi_get_portfolio_balance = sapiGetPortfolioBalance = Entry('portfolio/balance', 'sapi', 'GET', {'cost': 2})
223
+ sapi_get_portfolio_negative_balance_exchange_record = sapiGetPortfolioNegativeBalanceExchangeRecord = Entry('portfolio/negative-balance-exchange-record', 'sapi', 'GET', {'cost': 2})
223
224
  sapi_get_staking_productlist = sapiGetStakingProductList = Entry('staking/productList', 'sapi', 'GET', {'cost': 0.1})
224
225
  sapi_get_staking_position = sapiGetStakingPosition = Entry('staking/position', 'sapi', 'GET', {'cost': 0.1})
225
226
  sapi_get_staking_stakingrecord = sapiGetStakingStakingRecord = Entry('staking/stakingRecord', 'sapi', 'GET', {'cost': 0.1})
@@ -220,6 +220,7 @@ class ImplicitAPI:
220
220
  sapi_get_portfolio_repay_futures_switch = sapiGetPortfolioRepayFuturesSwitch = Entry('portfolio/repay-futures-switch', 'sapi', 'GET', {'cost': 3})
221
221
  sapi_get_portfolio_margin_asset_leverage = sapiGetPortfolioMarginAssetLeverage = Entry('portfolio/margin-asset-leverage', 'sapi', 'GET', {'cost': 5})
222
222
  sapi_get_portfolio_balance = sapiGetPortfolioBalance = Entry('portfolio/balance', 'sapi', 'GET', {'cost': 2})
223
+ sapi_get_portfolio_negative_balance_exchange_record = sapiGetPortfolioNegativeBalanceExchangeRecord = Entry('portfolio/negative-balance-exchange-record', 'sapi', 'GET', {'cost': 2})
223
224
  sapi_get_staking_productlist = sapiGetStakingProductList = Entry('staking/productList', 'sapi', 'GET', {'cost': 0.1})
224
225
  sapi_get_staking_position = sapiGetStakingPosition = Entry('staking/position', 'sapi', 'GET', {'cost': 0.1})
225
226
  sapi_get_staking_stakingrecord = sapiGetStakingStakingRecord = Entry('staking/stakingRecord', 'sapi', 'GET', {'cost': 0.1})
ccxt/alpaca.py CHANGED
@@ -60,6 +60,9 @@ class alpaca(Exchange, ImplicitAPI):
60
60
  'cancelOrder': True,
61
61
  'closeAllPositions': False,
62
62
  'closePosition': False,
63
+ 'createMarketBuyOrder': True,
64
+ 'createMarketBuyOrderWithCost': True,
65
+ 'createMarketOrderWithCost': True,
63
66
  'createOrder': True,
64
67
  'createStopOrder': True,
65
68
  'createTriggerOrder': True,
@@ -905,6 +908,58 @@ class alpaca(Exchange, ImplicitAPI):
905
908
  clientOrderId = self.safe_string(params, 'clientOrderId', defaultClientId)
906
909
  return clientOrderId
907
910
 
911
+ def create_market_order_with_cost(self, symbol: str, side: OrderSide, cost: float, params={}):
912
+ """
913
+ create a market order by providing the symbol, side and cost
914
+
915
+ https://docs.alpaca.markets/reference/postorder
916
+
917
+ :param str symbol: unified symbol of the market to create an order in
918
+ :param str side: 'buy' or 'sell'
919
+ :param float cost: how much you want to trade in units of the quote currency
920
+ :param dict [params]: extra parameters specific to the exchange API endpoint
921
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
922
+ """
923
+ self.load_markets()
924
+ req = {
925
+ 'cost': cost,
926
+ }
927
+ return self.create_order(symbol, 'market', side, 0, None, self.extend(req, params))
928
+
929
+ def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
930
+ """
931
+ create a market buy order by providing the symbol and cost
932
+
933
+ https://docs.alpaca.markets/reference/postorder
934
+
935
+ :param str symbol: unified symbol of the market to create an order in
936
+ :param float cost: how much you want to trade in units of the quote currency
937
+ :param dict [params]: extra parameters specific to the exchange API endpoint
938
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
939
+ """
940
+ self.load_markets()
941
+ req = {
942
+ 'cost': cost,
943
+ }
944
+ return self.create_order(symbol, 'market', 'buy', 0, None, self.extend(req, params))
945
+
946
+ def create_market_sell_order_with_cost(self, symbol: str, cost: float, params={}):
947
+ """
948
+ create a market sell order by providing the symbol and cost
949
+
950
+ https://docs.alpaca.markets/reference/postorder
951
+
952
+ :param str symbol: unified symbol of the market to create an order in
953
+ :param float cost: how much you want to trade in units of the quote currency
954
+ :param dict [params]: extra parameters specific to the exchange API endpoint
955
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
956
+ """
957
+ self.load_markets()
958
+ req = {
959
+ 'cost': cost,
960
+ }
961
+ return self.create_order(symbol, 'market', 'sell', cost, None, self.extend(req, params))
962
+
908
963
  def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
909
964
  """
910
965
  create a trade order
@@ -918,6 +973,7 @@ class alpaca(Exchange, ImplicitAPI):
918
973
  :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
919
974
  :param dict [params]: extra parameters specific to the exchange API endpoint
920
975
  :param float [params.triggerPrice]: The price at which a trigger order is triggered at
976
+ :param float [params.cost]: *market orders only* the cost of the order in units of the quote currency
921
977
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
922
978
  """
923
979
  self.load_markets()
@@ -925,7 +981,6 @@ class alpaca(Exchange, ImplicitAPI):
925
981
  id = market['id']
926
982
  request: dict = {
927
983
  'symbol': id,
928
- 'qty': self.amount_to_precision(symbol, amount),
929
984
  'side': side,
930
985
  'type': type, # market, limit, stop_limit
931
986
  }
@@ -940,6 +995,12 @@ class alpaca(Exchange, ImplicitAPI):
940
995
  request['type'] = newType
941
996
  if type.find('limit') >= 0:
942
997
  request['limit_price'] = self.price_to_precision(symbol, price)
998
+ cost = self.safe_string(params, 'cost')
999
+ if cost is not None:
1000
+ params = self.omit(params, 'cost')
1001
+ request['notional'] = self.cost_to_precision(symbol, cost)
1002
+ else:
1003
+ request['qty'] = self.amount_to_precision(symbol, amount)
943
1004
  defaultTIF = self.safe_string(self.options, 'defaultTimeInForce')
944
1005
  request['time_in_force'] = self.safe_string(params, 'timeInForce', defaultTIF)
945
1006
  params = self.omit(params, ['timeInForce', 'triggerPrice'])
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.49'
7
+ __version__ = '4.4.50'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -60,6 +60,9 @@ class alpaca(Exchange, ImplicitAPI):
60
60
  'cancelOrder': True,
61
61
  'closeAllPositions': False,
62
62
  'closePosition': False,
63
+ 'createMarketBuyOrder': True,
64
+ 'createMarketBuyOrderWithCost': True,
65
+ 'createMarketOrderWithCost': True,
63
66
  'createOrder': True,
64
67
  'createStopOrder': True,
65
68
  'createTriggerOrder': True,
@@ -905,6 +908,58 @@ class alpaca(Exchange, ImplicitAPI):
905
908
  clientOrderId = self.safe_string(params, 'clientOrderId', defaultClientId)
906
909
  return clientOrderId
907
910
 
911
+ async def create_market_order_with_cost(self, symbol: str, side: OrderSide, cost: float, params={}):
912
+ """
913
+ create a market order by providing the symbol, side and cost
914
+
915
+ https://docs.alpaca.markets/reference/postorder
916
+
917
+ :param str symbol: unified symbol of the market to create an order in
918
+ :param str side: 'buy' or 'sell'
919
+ :param float cost: how much you want to trade in units of the quote currency
920
+ :param dict [params]: extra parameters specific to the exchange API endpoint
921
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
922
+ """
923
+ await self.load_markets()
924
+ req = {
925
+ 'cost': cost,
926
+ }
927
+ return await self.create_order(symbol, 'market', side, 0, None, self.extend(req, params))
928
+
929
+ async def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
930
+ """
931
+ create a market buy order by providing the symbol and cost
932
+
933
+ https://docs.alpaca.markets/reference/postorder
934
+
935
+ :param str symbol: unified symbol of the market to create an order in
936
+ :param float cost: how much you want to trade in units of the quote currency
937
+ :param dict [params]: extra parameters specific to the exchange API endpoint
938
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
939
+ """
940
+ await self.load_markets()
941
+ req = {
942
+ 'cost': cost,
943
+ }
944
+ return await self.create_order(symbol, 'market', 'buy', 0, None, self.extend(req, params))
945
+
946
+ async def create_market_sell_order_with_cost(self, symbol: str, cost: float, params={}):
947
+ """
948
+ create a market sell order by providing the symbol and cost
949
+
950
+ https://docs.alpaca.markets/reference/postorder
951
+
952
+ :param str symbol: unified symbol of the market to create an order in
953
+ :param float cost: how much you want to trade in units of the quote currency
954
+ :param dict [params]: extra parameters specific to the exchange API endpoint
955
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
956
+ """
957
+ await self.load_markets()
958
+ req = {
959
+ 'cost': cost,
960
+ }
961
+ return await self.create_order(symbol, 'market', 'sell', cost, None, self.extend(req, params))
962
+
908
963
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
909
964
  """
910
965
  create a trade order
@@ -918,6 +973,7 @@ class alpaca(Exchange, ImplicitAPI):
918
973
  :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
919
974
  :param dict [params]: extra parameters specific to the exchange API endpoint
920
975
  :param float [params.triggerPrice]: The price at which a trigger order is triggered at
976
+ :param float [params.cost]: *market orders only* the cost of the order in units of the quote currency
921
977
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
922
978
  """
923
979
  await self.load_markets()
@@ -925,7 +981,6 @@ class alpaca(Exchange, ImplicitAPI):
925
981
  id = market['id']
926
982
  request: dict = {
927
983
  'symbol': id,
928
- 'qty': self.amount_to_precision(symbol, amount),
929
984
  'side': side,
930
985
  'type': type, # market, limit, stop_limit
931
986
  }
@@ -940,6 +995,12 @@ class alpaca(Exchange, ImplicitAPI):
940
995
  request['type'] = newType
941
996
  if type.find('limit') >= 0:
942
997
  request['limit_price'] = self.price_to_precision(symbol, price)
998
+ cost = self.safe_string(params, 'cost')
999
+ if cost is not None:
1000
+ params = self.omit(params, 'cost')
1001
+ request['notional'] = self.cost_to_precision(symbol, cost)
1002
+ else:
1003
+ request['qty'] = self.amount_to_precision(symbol, amount)
943
1004
  defaultTIF = self.safe_string(self.options, 'defaultTimeInForce')
944
1005
  request['time_in_force'] = self.safe_string(params, 'timeInForce', defaultTIF)
945
1006
  params = self.omit(params, ['timeInForce', 'triggerPrice'])
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.4.49'
5
+ __version__ = '4.4.50'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -503,6 +503,7 @@ class binance(Exchange, ImplicitAPI):
503
503
  'portfolio/repay-futures-switch': 3, # Weight(IP): 30 => cost = 0.1 * 30 = 3
504
504
  'portfolio/margin-asset-leverage': 5, # Weight(IP): 50 => cost = 0.1 * 50 = 5
505
505
  'portfolio/balance': 2,
506
+ 'portfolio/negative-balance-exchange-record': 2,
506
507
  # staking
507
508
  'staking/productList': 0.1,
508
509
  'staking/position': 0.1,
@@ -5001,11 +5002,13 @@ class binance(Exchange, ImplicitAPI):
5001
5002
  until = self.safe_integer(params, 'until')
5002
5003
  if until is not None:
5003
5004
  request['endTime'] = until
5004
- if limit is not None:
5005
- isFutureOrSwap = (market['swap'] or market['future'])
5006
- request['limit'] = min(limit, 1000) if isFutureOrSwap else limit # default = 500, maximum = 1000
5007
5005
  method = self.safe_string(self.options, 'fetchTradesMethod')
5008
5006
  method = self.safe_string_2(params, 'fetchTradesMethod', 'method', method)
5007
+ if limit is not None:
5008
+ isFutureOrSwap = (market['swap'] or market['future'])
5009
+ isHistoricalEndpoint = (method is not None) and (method.find('GetHistoricalTrades') >= 0)
5010
+ maxLimitForContractHistorical = 500 if isHistoricalEndpoint else 1000
5011
+ request['limit'] = min(limit, maxLimitForContractHistorical) if isFutureOrSwap else limit # default = 500, maximum = 1000
5009
5012
  params = self.omit(params, ['until', 'fetchTradesMethod'])
5010
5013
  response = None
5011
5014
  if market['option'] or method == 'eapiPublicGetTrades':
@@ -6837,6 +6840,7 @@ class binance(Exchange, ImplicitAPI):
6837
6840
  :param str symbol: unified market symbol
6838
6841
  :param dict [params]: extra parameters specific to the exchange API endpoint
6839
6842
  :param str [params.trigger]: set to True if you would like to fetch portfolio margin account stop or conditional orders
6843
+ :param boolean [params.portfolioMargin]: set to True if you would like to fetch for a portfolio margin account
6840
6844
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
6841
6845
  """
6842
6846
  if symbol is None:
@@ -10159,7 +10163,7 @@ class binance(Exchange, ImplicitAPI):
10159
10163
  # }
10160
10164
  #
10161
10165
  marketId = self.safe_string(position, 'symbol')
10162
- market = self.safe_market(marketId, market)
10166
+ market = self.safe_market(marketId, market, None, 'swap')
10163
10167
  symbol = market['symbol']
10164
10168
  side = self.safe_string_lower(position, 'side')
10165
10169
  quantity = self.safe_string(position, 'quantity')
@@ -295,7 +295,7 @@ class blofin(Exchange, ImplicitAPI):
295
295
  'trailing': False,
296
296
  },
297
297
  'fetchOHLCV': {
298
- 'max': 1440,
298
+ 'limit': 1440,
299
299
  },
300
300
  },
301
301
  'spot': {
@@ -481,7 +481,7 @@ class coinex(Exchange, ImplicitAPI):
481
481
  'ERC20': 'ERC20',
482
482
  'BRC20': 'BRC20',
483
483
  'SOL': 'SOL',
484
- 'TON': 'SOL',
484
+ 'TON': 'TON',
485
485
  'BSV': 'BSV',
486
486
  'AVAXC': 'AVA_C',
487
487
  'AVAXX': 'AVA',
@@ -4609,13 +4609,13 @@ class coinex(Exchange, ImplicitAPI):
4609
4609
  self.check_address(address)
4610
4610
  await self.load_markets()
4611
4611
  currency = self.currency(code)
4612
- if tag:
4613
- address = address + ':' + tag
4614
4612
  request: dict = {
4615
4613
  'ccy': currency['id'],
4616
4614
  'to_address': address, # must be authorized, inter-user transfer by a registered mobile phone number or an email address is supported
4617
4615
  'amount': self.number_to_string(amount), # the actual amount without fees, https://www.coinex.com/fees
4618
4616
  }
4617
+ if tag is not None:
4618
+ request['memo'] = tag
4619
4619
  networkCode = None
4620
4620
  networkCode, params = self.handle_network_code_and_params(params)
4621
4621
  if networkCode is not None:
@@ -829,7 +829,7 @@ class hollaex(Exchange, ImplicitAPI):
829
829
 
830
830
  async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
831
831
  """
832
- fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
832
+ hollaex has large gaps between candles, so it's recommended to specify since
833
833
 
834
834
  https://apidocs.hollaex.com/#chart
835
835
 
@@ -838,6 +838,7 @@ class hollaex(Exchange, ImplicitAPI):
838
838
  :param int [since]: timestamp in ms of the earliest candle to fetch
839
839
  :param int [limit]: the maximum amount of candles to fetch
840
840
  :param dict [params]: extra parameters specific to the exchange API endpoint
841
+ :param int [params.until]: timestamp in ms of the latest candle to fetch
841
842
  :returns int[][]: A list of candles ordered, open, high, low, close, volume
842
843
  """
843
844
  await self.load_markets()
@@ -846,22 +847,17 @@ class hollaex(Exchange, ImplicitAPI):
846
847
  'symbol': market['id'],
847
848
  'resolution': self.safe_string(self.timeframes, timeframe, timeframe),
848
849
  }
849
- duration = self.parse_timeframe(timeframe)
850
- if since is None:
851
- if limit is None:
852
- limit = 1000 # they have no defaults and can actually provide tens of thousands of bars in one request, but we should cap "default" at generous amount
853
- end = self.seconds()
854
- start = end - duration * limit
855
- request['to'] = end
856
- request['from'] = start
850
+ until = self.safe_integer(params, 'until')
851
+ end = self.seconds()
852
+ if until is not None:
853
+ end = self.parse_to_int(until / 1000)
854
+ defaultSpan = 2592000 # 30 days
855
+ if since is not None:
856
+ request['from'] = self.parse_to_int(since / 1000)
857
857
  else:
858
- if limit is None:
859
- request['from'] = self.parse_to_int(since / 1000)
860
- request['to'] = self.seconds()
861
- else:
862
- start = self.parse_to_int(since / 1000)
863
- request['from'] = start
864
- request['to'] = self.sum(start, duration * limit)
858
+ request['from'] = end - defaultSpan
859
+ request['to'] = end
860
+ params = self.omit(params, 'until')
865
861
  response = await self.publicGetChart(self.extend(request, params))
866
862
  #
867
863
  # [
@@ -1352,8 +1352,7 @@ class kucoin(Exchange, ImplicitAPI):
1352
1352
  :param dict params: extra parameters specific to the exchange API endpoint
1353
1353
  :returns dict: an associative dictionary of currencies
1354
1354
  """
1355
- promises = []
1356
- promises.append(self.publicGetCurrencies(params))
1355
+ response = await self.publicGetCurrencies(params)
1357
1356
  #
1358
1357
  # {
1359
1358
  # "code":"200000",
@@ -1379,87 +1378,39 @@ class kucoin(Exchange, ImplicitAPI):
1379
1378
  # "isDepositEnabled":false,
1380
1379
  # "confirms":12,
1381
1380
  # "preConfirms":12,
1381
+ # "withdrawPrecision": 8,
1382
+ # "maxWithdraw": null,
1383
+ # "maxDeposit": null,
1384
+ # "needTag": False,
1382
1385
  # "contractAddress":"0xa6446d655a0c34bc4f05042ee88170d056cbaf45",
1383
1386
  # "depositFeeRate": "0.001", # present for some currencies/networks
1384
1387
  # }
1385
1388
  # ]
1386
1389
  # },
1387
- # }
1388
- #
1389
- promises.append(self.fetch_web_endpoint('fetchCurrencies', 'webExchangeGetCurrencyCurrencyChainInfo', True))
1390
- #
1391
- # {
1392
- # "success": True,
1393
- # "code": "200",
1394
- # "msg": "success",
1395
- # "retry": False,
1396
- # "data": [
1397
- # {
1398
- # "status": "enabled",
1399
- # "currency": "BTC",
1400
- # "isChainEnabled": "true",
1401
- # "chain": "btc",
1402
- # "chainName": "BTC",
1403
- # "chainFullName": "Bitcoin",
1404
- # "walletPrecision": "8",
1405
- # "isDepositEnabled": "true",
1406
- # "depositMinSize": "0.00005",
1407
- # "confirmationCount": "2",
1408
- # "isWithdrawEnabled": "true",
1409
- # "withdrawMinSize": "0.001",
1410
- # "withdrawMinFee": "0.0005",
1411
- # "withdrawFeeRate": "0",
1412
- # "depositDisabledTip": "Wallet Maintenance",
1413
- # "preDepositTipEnabled": "true",
1414
- # "preDepositTip": "Do not transfer from ETH network directly",
1415
- # "withdrawDisabledTip": "",
1416
- # "preWithdrawTipEnabled": "false",
1417
- # "preWithdrawTip": "",
1418
- # "orgAddress": "",
1419
- # "userAddressName": "Memo",
1420
- # },
1421
1390
  # ]
1422
1391
  # }
1423
1392
  #
1424
- responses = await asyncio.gather(*promises)
1425
- currenciesResponse = self.safe_dict(responses, 0, {})
1426
- currenciesData = self.safe_list(currenciesResponse, 'data', [])
1427
- additionalResponse = self.safe_dict(responses, 1, {})
1428
- additionalData = self.safe_list(additionalResponse, 'data', [])
1429
- additionalDataGrouped = self.group_by(additionalData, 'currency')
1393
+ currenciesData = self.safe_list(response, 'data', [])
1430
1394
  result: dict = {}
1431
1395
  for i in range(0, len(currenciesData)):
1432
1396
  entry = currenciesData[i]
1433
1397
  id = self.safe_string(entry, 'currency')
1434
1398
  name = self.safe_string(entry, 'fullName')
1435
1399
  code = self.safe_currency_code(id)
1436
- isWithdrawEnabled = None
1437
- isDepositEnabled = None
1438
1400
  networks: dict = {}
1439
1401
  chains = self.safe_list(entry, 'chains', [])
1440
- extraChainsData = self.index_by(self.safe_list(additionalDataGrouped, id, []), 'chain')
1441
1402
  rawPrecision = self.safe_string(entry, 'precision')
1442
1403
  precision = self.parse_number(self.parse_precision(rawPrecision))
1443
1404
  chainsLength = len(chains)
1444
1405
  if not chainsLength:
1445
- # https://t.me/KuCoin_API/173118
1446
- isWithdrawEnabled = False
1447
- isDepositEnabled = False
1406
+ # one buggy coin, which doesn't contain info https://t.me/KuCoin_API/173118
1407
+ continue
1448
1408
  for j in range(0, chainsLength):
1449
1409
  chain = chains[j]
1450
1410
  chainId = self.safe_string(chain, 'chainId')
1451
1411
  networkCode = self.network_id_to_code(chainId, code)
1452
1412
  chainWithdrawEnabled = self.safe_bool(chain, 'isWithdrawEnabled', False)
1453
- if isWithdrawEnabled is None:
1454
- isWithdrawEnabled = chainWithdrawEnabled
1455
- else:
1456
- isWithdrawEnabled = isWithdrawEnabled or chainWithdrawEnabled
1457
1413
  chainDepositEnabled = self.safe_bool(chain, 'isDepositEnabled', False)
1458
- if isDepositEnabled is None:
1459
- isDepositEnabled = chainDepositEnabled
1460
- else:
1461
- isDepositEnabled = isDepositEnabled or chainDepositEnabled
1462
- chainExtraData = self.safe_dict(extraChainsData, chainId, {})
1463
1414
  networks[networkCode] = {
1464
1415
  'info': chain,
1465
1416
  'id': chainId,
@@ -1469,34 +1420,34 @@ class kucoin(Exchange, ImplicitAPI):
1469
1420
  'fee': self.safe_number(chain, 'withdrawalMinFee'),
1470
1421
  'deposit': chainDepositEnabled,
1471
1422
  'withdraw': chainWithdrawEnabled,
1472
- 'precision': self.parse_number(self.parse_precision(self.safe_string(chainExtraData, 'walletPrecision'))),
1423
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'withdrawPrecision'))),
1473
1424
  'limits': {
1474
1425
  'withdraw': {
1475
1426
  'min': self.safe_number(chain, 'withdrawalMinSize'),
1476
- 'max': None,
1427
+ 'max': self.safe_number(chain, 'maxWithdraw'),
1477
1428
  },
1478
1429
  'deposit': {
1479
1430
  'min': self.safe_number(chain, 'depositMinSize'),
1480
- 'max': None,
1431
+ 'max': self.safe_number(chain, 'maxDeposit'),
1481
1432
  },
1482
1433
  },
1483
1434
  }
1484
1435
  # kucoin has determined 'fiat' currencies with below logic
1485
1436
  isFiat = (rawPrecision == '2') and (chainsLength == 0)
1486
- result[code] = {
1437
+ result[code] = self.safe_currency_structure({
1487
1438
  'id': id,
1488
1439
  'name': name,
1489
1440
  'code': code,
1490
1441
  'type': 'fiat' if isFiat else 'crypto',
1491
1442
  'precision': precision,
1492
1443
  'info': entry,
1493
- 'active': (isDepositEnabled or isWithdrawEnabled),
1494
- 'deposit': isDepositEnabled,
1495
- 'withdraw': isWithdrawEnabled,
1496
- 'fee': None,
1497
- 'limits': self.limits,
1498
1444
  'networks': networks,
1499
- }
1445
+ 'deposit': None,
1446
+ 'withdraw': None,
1447
+ 'active': None,
1448
+ 'fee': None,
1449
+ 'limits': None,
1450
+ })
1500
1451
  return result
1501
1452
 
1502
1453
  async def fetch_accounts(self, params={}) -> List[Account]:
@@ -1636,6 +1587,35 @@ class kucoin(Exchange, ImplicitAPI):
1636
1587
  # "chain": "ERC20"
1637
1588
  # }
1638
1589
  #
1590
+ if 'chains' in fee:
1591
+ # if data obtained through `currencies` endpoint
1592
+ resultNew: dict = {
1593
+ 'info': fee,
1594
+ 'withdraw': {
1595
+ 'fee': None,
1596
+ 'percentage': False,
1597
+ },
1598
+ 'deposit': {
1599
+ 'fee': None,
1600
+ 'percentage': None,
1601
+ },
1602
+ 'networks': {},
1603
+ }
1604
+ chains = self.safe_list(fee, 'chains', [])
1605
+ for i in range(0, len(chains)):
1606
+ chain = chains[i]
1607
+ networkCodeNew = self.network_id_to_code(self.safe_string(chain, 'chainId'), self.safe_string(currency, 'code'))
1608
+ resultNew['networks'][networkCodeNew] = {
1609
+ 'withdraw': {
1610
+ 'fee': self.safe_number(chain, 'withdrawMinFee'),
1611
+ 'percentage': False,
1612
+ },
1613
+ 'deposit': {
1614
+ 'fee': None,
1615
+ 'percentage': None,
1616
+ },
1617
+ }
1618
+ return resultNew
1639
1619
  minWithdrawFee = self.safe_number(fee, 'withdrawMinFee')
1640
1620
  result: dict = {
1641
1621
  'info': fee,
@@ -1380,6 +1380,7 @@ class mexc(Exchange, ImplicitAPI):
1380
1380
  quote = self.safe_currency_code(quoteId)
1381
1381
  settle = self.safe_currency_code(settleId)
1382
1382
  state = self.safe_string(market, 'state')
1383
+ isLinear = quote == settle
1383
1384
  result.append({
1384
1385
  'id': id,
1385
1386
  'symbol': base + '/' + quote + ':' + settle,
@@ -1397,8 +1398,8 @@ class mexc(Exchange, ImplicitAPI):
1397
1398
  'option': False,
1398
1399
  'active': (state == '0'),
1399
1400
  'contract': True,
1400
- 'linear': True,
1401
- 'inverse': False,
1401
+ 'linear': isLinear,
1402
+ 'inverse': not isLinear,
1402
1403
  'taker': self.safe_number(market, 'takerFeeRate'),
1403
1404
  'maker': self.safe_number(market, 'makerFeeRate'),
1404
1405
  'contractSize': self.safe_number(market, 'contractSize'),
@@ -707,12 +707,20 @@ class okcoin(Exchange, ImplicitAPI):
707
707
  """
708
708
  response = await self.publicGetPublicTime(params)
709
709
  #
710
- # {
711
- # "iso": "2015-01-07T23:47:25.201Z",
712
- # "epoch": 1420674445.201
713
- # }
710
+ # {
711
+ # "code": "0",
712
+ # "data":
713
+ # [
714
+ # {
715
+ # "ts": "1737379360033"
716
+ # }
717
+ # ],
718
+ # "msg": ""
719
+ # }
714
720
  #
715
- return self.parse8601(self.safe_string(response, 'iso'))
721
+ data = self.safe_list(response, 'data')
722
+ timestamp = self.safe_dict(data, 0)
723
+ return self.safe_integer(timestamp, 'ts')
716
724
 
717
725
  async def fetch_markets(self, params={}) -> List[Market]:
718
726
  """