ccxt 4.4.91__py2.py3-none-any.whl → 4.4.93__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.
Files changed (57) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/lbank.py +2 -1
  3. ccxt/ascendex.py +9 -8
  4. ccxt/async_support/__init__.py +1 -1
  5. ccxt/async_support/ascendex.py +9 -8
  6. ccxt/async_support/base/exchange.py +4 -1
  7. ccxt/async_support/base/ws/client.py +4 -1
  8. ccxt/async_support/binance.py +42 -1
  9. ccxt/async_support/bitmart.py +7 -0
  10. ccxt/async_support/bitmex.py +3 -3
  11. ccxt/async_support/bitvavo.py +7 -1
  12. ccxt/async_support/bybit.py +81 -8
  13. ccxt/async_support/coinbaseexchange.py +53 -0
  14. ccxt/async_support/coincheck.py +45 -4
  15. ccxt/async_support/coinex.py +16 -12
  16. ccxt/async_support/cryptomus.py +30 -52
  17. ccxt/async_support/deribit.py +6 -6
  18. ccxt/async_support/exmo.py +70 -50
  19. ccxt/async_support/htx.py +1 -1
  20. ccxt/async_support/hyperliquid.py +2 -1
  21. ccxt/async_support/krakenfutures.py +1 -1
  22. ccxt/async_support/kucoin.py +12 -14
  23. ccxt/async_support/latoken.py +19 -71
  24. ccxt/async_support/lbank.py +115 -35
  25. ccxt/async_support/okx.py +151 -2
  26. ccxt/async_support/paradex.py +54 -0
  27. ccxt/async_support/phemex.py +3 -3
  28. ccxt/base/exchange.py +69 -30
  29. ccxt/base/types.py +1 -0
  30. ccxt/binance.py +42 -1
  31. ccxt/bitmart.py +7 -0
  32. ccxt/bitmex.py +3 -3
  33. ccxt/bitvavo.py +7 -1
  34. ccxt/bybit.py +81 -8
  35. ccxt/coinbaseexchange.py +53 -0
  36. ccxt/coincheck.py +45 -4
  37. ccxt/coinex.py +16 -12
  38. ccxt/cryptomus.py +30 -52
  39. ccxt/deribit.py +6 -6
  40. ccxt/exmo.py +70 -50
  41. ccxt/htx.py +1 -1
  42. ccxt/hyperliquid.py +2 -1
  43. ccxt/krakenfutures.py +1 -1
  44. ccxt/kucoin.py +12 -14
  45. ccxt/latoken.py +19 -71
  46. ccxt/lbank.py +115 -35
  47. ccxt/okx.py +151 -2
  48. ccxt/paradex.py +54 -0
  49. ccxt/phemex.py +3 -3
  50. ccxt/pro/__init__.py +1 -1
  51. ccxt/pro/bitstamp.py +48 -16
  52. ccxt/pro/bybit.py +5 -5
  53. {ccxt-4.4.91.dist-info → ccxt-4.4.93.dist-info}/METADATA +4 -4
  54. {ccxt-4.4.91.dist-info → ccxt-4.4.93.dist-info}/RECORD +57 -57
  55. {ccxt-4.4.91.dist-info → ccxt-4.4.93.dist-info}/LICENSE.txt +0 -0
  56. {ccxt-4.4.91.dist-info → ccxt-4.4.93.dist-info}/WHEEL +0 -0
  57. {ccxt-4.4.91.dist-info → ccxt-4.4.93.dist-info}/top_level.txt +0 -0
@@ -10,6 +10,7 @@ from ccxt.base.types import Any, Balances, Currency, Int, Market, Num, Order, Or
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
13
+ from ccxt.base.errors import ArgumentsRequired
13
14
  from ccxt.base.errors import BadSymbol
14
15
  from ccxt.base.decimal_to_precision import TICK_SIZE
15
16
 
@@ -30,30 +31,59 @@ class coincheck(Exchange, ImplicitAPI):
30
31
  'future': False,
31
32
  'option': False,
32
33
  'addMargin': False,
34
+ 'borrowCrossMargin': False,
35
+ 'borrowIsolatedMargin': False,
36
+ 'borrowMargin': False,
33
37
  'cancelOrder': True,
34
38
  'closeAllPositions': False,
35
39
  'closePosition': False,
36
40
  'createOrder': True,
41
+ 'createOrderWithTakeProfitAndStopLoss': False,
42
+ 'createOrderWithTakeProfitAndStopLossWs': False,
43
+ 'createPostOnlyOrder': False,
37
44
  'createReduceOnlyOrder': False,
38
45
  'fetchBalance': True,
46
+ 'fetchBorrowInterest': False,
47
+ 'fetchBorrowRate': False,
39
48
  'fetchBorrowRateHistories': False,
40
49
  'fetchBorrowRateHistory': False,
50
+ 'fetchBorrowRates': False,
51
+ 'fetchBorrowRatesPerSymbol': False,
41
52
  'fetchCrossBorrowRate': False,
42
53
  'fetchCrossBorrowRates': False,
43
54
  'fetchDeposits': True,
44
55
  'fetchFundingHistory': False,
56
+ 'fetchFundingInterval': False,
57
+ 'fetchFundingIntervals': False,
45
58
  'fetchFundingRate': False,
46
59
  'fetchFundingRateHistory': False,
47
60
  'fetchFundingRates': False,
61
+ 'fetchGreeks': False,
48
62
  'fetchIndexOHLCV': False,
49
63
  'fetchIsolatedBorrowRate': False,
50
64
  'fetchIsolatedBorrowRates': False,
65
+ 'fetchIsolatedPositions': False,
51
66
  'fetchLeverage': False,
67
+ 'fetchLeverages': False,
68
+ 'fetchLeverageTiers': False,
69
+ 'fetchLiquidations': False,
70
+ 'fetchLongShortRatio': False,
71
+ 'fetchLongShortRatioHistory': False,
72
+ 'fetchMarginAdjustmentHistory': False,
52
73
  'fetchMarginMode': False,
74
+ 'fetchMarginModes': False,
75
+ 'fetchMarketLeverageTiers': False,
53
76
  'fetchMarkOHLCV': False,
77
+ 'fetchMarkPrices': False,
78
+ 'fetchMyLiquidations': False,
79
+ 'fetchMySettlementHistory': False,
54
80
  'fetchMyTrades': True,
81
+ 'fetchOpenInterest': False,
55
82
  'fetchOpenInterestHistory': False,
83
+ 'fetchOpenInterests': False,
56
84
  'fetchOpenOrders': True,
85
+ 'fetchOption': False,
86
+ 'fetchOptionChain': False,
57
87
  'fetchOrderBook': True,
58
88
  'fetchPosition': False,
59
89
  'fetchPositionHistory': False,
@@ -63,13 +93,19 @@ class coincheck(Exchange, ImplicitAPI):
63
93
  'fetchPositionsHistory': False,
64
94
  'fetchPositionsRisk': False,
65
95
  'fetchPremiumIndexOHLCV': False,
96
+ 'fetchSettlementHistory': False,
66
97
  'fetchTicker': True,
67
98
  'fetchTrades': True,
68
99
  'fetchTradingFee': False,
69
100
  'fetchTradingFees': True,
101
+ 'fetchVolatilityHistory': False,
70
102
  'fetchWithdrawals': True,
71
103
  'reduceMargin': False,
104
+ 'repayCrossMargin': False,
105
+ 'repayIsolatedMargin': False,
106
+ 'repayMargin': False,
72
107
  'setLeverage': False,
108
+ 'setMargin': False,
73
109
  'setMarginMode': False,
74
110
  'setPositionMode': False,
75
111
  'ws': True,
@@ -637,10 +673,15 @@ class coincheck(Exchange, ImplicitAPI):
637
673
  'pair': market['id'],
638
674
  }
639
675
  if type == 'market':
640
- order_type = type + '_' + side
641
- request['order_type'] = order_type
642
- prefix = (order_type + '_') if (side == 'buy') else ''
643
- request[prefix + 'amount'] = amount
676
+ request['order_type'] = type + '_' + side
677
+ if side == 'sell':
678
+ request['amount'] = amount
679
+ else:
680
+ cost = self.safe_number(params, 'cost')
681
+ params = self.omit(params, 'cost')
682
+ if cost is not None:
683
+ raise ArgumentsRequired(self.id + ' createOrder() : you should use "cost" parameter instead of "amount" argument to create market buy orders')
684
+ request['market_buy_amount'] = cost
644
685
  else:
645
686
  request['order_type'] = side
646
687
  request['rate'] = price
@@ -19,6 +19,7 @@ from ccxt.base.errors import InsufficientFunds
19
19
  from ccxt.base.errors import InvalidOrder
20
20
  from ccxt.base.errors import OrderNotFound
21
21
  from ccxt.base.errors import NotSupported
22
+ from ccxt.base.errors import OperationFailed
22
23
  from ccxt.base.errors import RateLimitExceeded
23
24
  from ccxt.base.errors import ExchangeNotAvailable
24
25
  from ccxt.base.errors import RequestTimeout
@@ -671,6 +672,7 @@ class coinex(Exchange, ImplicitAPI):
671
672
  'broad': {
672
673
  'ip not allow visit': PermissionDenied,
673
674
  'service too busy': ExchangeNotAvailable,
675
+ 'Service is not available during funding fee settlement': OperationFailed,
674
676
  },
675
677
  },
676
678
  })
@@ -795,7 +797,7 @@ class coinex(Exchange, ImplicitAPI):
795
797
  'max': None,
796
798
  },
797
799
  },
798
- 'networks': {},
800
+ 'networks': networks,
799
801
  'type': 'crypto',
800
802
  'info': coin,
801
803
  })
@@ -827,17 +829,19 @@ class coinex(Exchange, ImplicitAPI):
827
829
  # "code": 0,
828
830
  # "data": [
829
831
  # {
830
- # "base_ccy": "SORA",
832
+ # "market": "BTCUSDT",
833
+ # "taker_fee_rate": "0.002",
834
+ # "maker_fee_rate": "0.002",
835
+ # "min_amount": "0.0005",
836
+ # "base_ccy": "BTC",
837
+ # "quote_ccy": "USDT",
831
838
  # "base_ccy_precision": 8,
839
+ # "quote_ccy_precision": 2,
832
840
  # "is_amm_available": True,
833
- # "is_margin_available": False,
834
- # "maker_fee_rate": "0.003",
835
- # "market": "SORAUSDT",
836
- # "min_amount": "500",
837
- # "quote_ccy": "USDT",
838
- # "quote_ccy_precision": 6,
839
- # "taker_fee_rate": "0.003"
840
- # },
841
+ # "is_margin_available": True,
842
+ # "is_pre_trading_available": True,
843
+ # "is_api_trading_available": True
844
+ # }
841
845
  # ],
842
846
  # "message": "OK"
843
847
  # }
@@ -863,11 +867,11 @@ class coinex(Exchange, ImplicitAPI):
863
867
  'settleId': None,
864
868
  'type': 'spot',
865
869
  'spot': True,
866
- 'margin': None,
870
+ 'margin': self.safe_bool(market, 'is_margin_available'),
867
871
  'swap': False,
868
872
  'future': False,
869
873
  'option': False,
870
- 'active': None,
874
+ 'active': self.safe_bool(market, 'is_api_trading_available'),
871
875
  'contract': False,
872
876
  'linear': None,
873
877
  'inverse': None,
@@ -367,66 +367,44 @@ class cryptomus(Exchange, ImplicitAPI):
367
367
  # }
368
368
  #
369
369
  coins = self.safe_list(response, 'result')
370
+ groupedById = self.group_by(coins, 'currency_code')
371
+ keys = list(groupedById.keys())
370
372
  result: dict = {}
371
- for i in range(0, len(coins)):
372
- networkEntry = coins[i]
373
- currencyId = self.safe_string(networkEntry, 'currency_code')
374
- code = self.safe_currency_code(currencyId)
375
- if not (code in result):
376
- result[code] = {
377
- 'id': currencyId,
378
- 'code': code,
379
- 'precision': None,
380
- 'type': None,
381
- 'name': None,
382
- 'active': None,
383
- 'deposit': None,
384
- 'withdraw': None,
385
- 'fee': None,
373
+ for i in range(0, len(keys)):
374
+ id = keys[i]
375
+ code = self.safe_currency_code(id)
376
+ networks = {}
377
+ networkEntries = groupedById[id]
378
+ for j in range(0, len(networkEntries)):
379
+ networkEntry = networkEntries[j]
380
+ networkId = self.safe_string(networkEntry, 'network_code')
381
+ networkCode = self.network_id_to_code(networkId)
382
+ networks[networkCode] = {
383
+ 'id': networkId,
384
+ 'network': networkCode,
386
385
  'limits': {
387
386
  'withdraw': {
388
- 'min': None,
389
- 'max': None,
387
+ 'min': self.safe_number(networkEntry, 'min_withdraw'),
388
+ 'max': self.safe_number(networkEntry, 'max_withdraw'),
390
389
  },
391
390
  'deposit': {
392
- 'min': None,
393
- 'max': None,
391
+ 'min': self.safe_number(networkEntry, 'min_deposit'),
392
+ 'max': self.safe_number(networkEntry, 'max_deposit'),
394
393
  },
395
394
  },
396
- 'networks': {},
397
- 'info': {},
395
+ 'active': None,
396
+ 'deposit': self.safe_bool(networkEntry, 'can_withdraw'),
397
+ 'withdraw': self.safe_bool(networkEntry, 'can_deposit'),
398
+ 'fee': None,
399
+ 'precision': None,
400
+ 'info': networkEntry,
398
401
  }
399
- networkId = self.safe_string(networkEntry, 'network_code')
400
- networkCode = self.network_id_to_code(networkId)
401
- result[code]['networks'][networkCode] = {
402
- 'id': networkId,
403
- 'network': networkCode,
404
- 'limits': {
405
- 'withdraw': {
406
- 'min': self.safe_number(networkEntry, 'min_withdraw'),
407
- 'max': self.safe_number(networkEntry, 'max_withdraw'),
408
- },
409
- 'deposit': {
410
- 'min': self.safe_number(networkEntry, 'min_deposit'),
411
- 'max': self.safe_number(networkEntry, 'max_deposit'),
412
- },
413
- },
414
- 'active': None,
415
- 'deposit': self.safe_bool(networkEntry, 'can_withdraw'),
416
- 'withdraw': self.safe_bool(networkEntry, 'can_deposit'),
417
- 'fee': None,
418
- 'precision': None,
419
- 'info': networkEntry,
420
- }
421
- # add entry in info
422
- info = self.safe_list(result[code], 'info', [])
423
- info.append(networkEntry)
424
- result[code]['info'] = info
425
- # only after all entries are formed in currencies, restructure each entry
426
- allKeys = list(result.keys())
427
- for i in range(0, len(allKeys)):
428
- code = allKeys[i]
429
- result[code] = self.safe_currency_structure(result[code]) # self is needed after adding network entry
402
+ result[code] = self.safe_currency_structure({
403
+ 'id': id,
404
+ 'code': code,
405
+ 'networks': networks,
406
+ 'info': networkEntries,
407
+ })
430
408
  return result
431
409
 
432
410
  async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
@@ -2596,21 +2596,21 @@ class deribit(Exchange, ImplicitAPI):
2596
2596
  unrealizedPnl = self.safe_string(position, 'floating_profit_loss')
2597
2597
  initialMarginString = self.safe_string(position, 'initial_margin')
2598
2598
  notionalString = self.safe_string(position, 'size_currency')
2599
+ notionalStringAbs = Precise.string_abs(notionalString)
2599
2600
  maintenanceMarginString = self.safe_string(position, 'maintenance_margin')
2600
- currentTime = self.milliseconds()
2601
2601
  return self.safe_position({
2602
2602
  'info': position,
2603
2603
  'id': None,
2604
2604
  'symbol': self.safe_string(market, 'symbol'),
2605
- 'timestamp': currentTime,
2606
- 'datetime': self.iso8601(currentTime),
2605
+ 'timestamp': None,
2606
+ 'datetime': None,
2607
2607
  'lastUpdateTimestamp': None,
2608
2608
  'initialMargin': self.parse_number(initialMarginString),
2609
- 'initialMarginPercentage': self.parse_number(Precise.string_mul(Precise.string_div(initialMarginString, notionalString), '100')),
2609
+ 'initialMarginPercentage': self.parse_number(Precise.string_mul(Precise.string_div(initialMarginString, notionalStringAbs), '100')),
2610
2610
  'maintenanceMargin': self.parse_number(maintenanceMarginString),
2611
- 'maintenanceMarginPercentage': self.parse_number(Precise.string_mul(Precise.string_div(maintenanceMarginString, notionalString), '100')),
2611
+ 'maintenanceMarginPercentage': self.parse_number(Precise.string_mul(Precise.string_div(maintenanceMarginString, notionalStringAbs), '100')),
2612
2612
  'entryPrice': self.safe_number(position, 'average_price'),
2613
- 'notional': self.parse_number(notionalString),
2613
+ 'notional': self.parse_number(notionalStringAbs),
2614
2614
  'leverage': self.safe_integer(position, 'leverage'),
2615
2615
  'unrealizedPnl': self.parse_number(unrealizedPnl),
2616
2616
  'contracts': None,
@@ -667,8 +667,9 @@ class exmo(Exchange, ImplicitAPI):
667
667
  :param dict [params]: extra parameters specific to the exchange API endpoint
668
668
  :returns dict: an associative dictionary of currencies
669
669
  """
670
+ promises = []
670
671
  #
671
- currencyList = await self.publicGetCurrencyListExtended(params)
672
+ promises.append(self.publicGetCurrencyListExtended(params))
672
673
  #
673
674
  # [
674
675
  # {"name":"VLX","description":"Velas"},
@@ -677,7 +678,7 @@ class exmo(Exchange, ImplicitAPI):
677
678
  # {"name":"USD","description":"US Dollar"}
678
679
  # ]
679
680
  #
680
- cryptoList = await self.publicGetPaymentsProvidersCryptoList(params)
681
+ promises.append(self.publicGetPaymentsProvidersCryptoList(params))
681
682
  #
682
683
  # {
683
684
  # "BTC":[
@@ -702,73 +703,92 @@ class exmo(Exchange, ImplicitAPI):
702
703
  # ],
703
704
  # }
704
705
  #
706
+ responses = await asyncio.gather(*promises)
707
+ currencyList = responses[0]
708
+ cryptoList = responses[1]
705
709
  result: dict = {}
706
710
  for i in range(0, len(currencyList)):
707
711
  currency = currencyList[i]
708
712
  currencyId = self.safe_string(currency, 'name')
709
- name = self.safe_string(currency, 'description')
710
- providers = self.safe_value(cryptoList, currencyId)
711
- active = False
713
+ code = self.safe_currency_code(currencyId)
712
714
  type = 'crypto'
713
- limits: dict = {
714
- 'deposit': {
715
- 'min': None,
716
- 'max': None,
717
- },
718
- 'withdraw': {
719
- 'min': None,
720
- 'max': None,
721
- },
722
- }
723
- fee = None
724
- depositEnabled = None
725
- withdrawEnabled = None
715
+ networks = {}
716
+ providers = self.safe_list(cryptoList, currencyId)
726
717
  if providers is None:
727
- active = True
728
718
  type = 'fiat'
729
719
  else:
730
720
  for j in range(0, len(providers)):
731
721
  provider = providers[j]
722
+ name = self.safe_string(provider, 'name')
723
+ # get network-id by removing extra things
724
+ networkId = name.replace(currencyId + ' ', '')
725
+ networkId = networkId.replace('(', '')
726
+ replaceChar = ')' # transpiler trick
727
+ networkId = networkId.replace(replaceChar, '')
728
+ networkCode = self.network_id_to_code(networkId)
729
+ if not (networkCode in networks):
730
+ networks[networkCode] = {
731
+ 'id': networkId,
732
+ 'network': networkCode,
733
+ 'active': None,
734
+ 'deposit': None,
735
+ 'withdraw': None,
736
+ 'fee': None,
737
+ 'limits': {
738
+ 'withdraw': {
739
+ 'min': None,
740
+ 'max': None,
741
+ },
742
+ 'deposit': {
743
+ 'min': None,
744
+ 'max': None,
745
+ },
746
+ },
747
+ 'info': [], # set, because of multiple network sub-entries
748
+ }
732
749
  typeInner = self.safe_string(provider, 'type')
733
750
  minValue = self.safe_string(provider, 'min')
734
751
  maxValue = self.safe_string(provider, 'max')
735
- if Precise.string_eq(maxValue, '0.0'):
736
- maxValue = None
737
- activeProvider = self.safe_value(provider, 'enabled')
752
+ activeProvider = self.safe_bool(provider, 'enabled')
753
+ networkEntry = networks[networkCode]
738
754
  if typeInner == 'deposit':
739
- if activeProvider and not depositEnabled:
740
- depositEnabled = True
741
- elif not activeProvider:
742
- depositEnabled = False
755
+ networkEntry['deposit'] = activeProvider
756
+ networkEntry['limits']['deposit']['min'] = minValue
757
+ networkEntry['limits']['deposit']['max'] = maxValue
743
758
  elif typeInner == 'withdraw':
744
- if activeProvider and not withdrawEnabled:
745
- withdrawEnabled = True
746
- elif not activeProvider:
747
- withdrawEnabled = False
748
- if activeProvider:
749
- active = True
750
- limitMin = self.number_to_string(limits[typeInner]['min'])
751
- if (limits[typeInner]['min'] is None) or (Precise.string_lt(minValue, limitMin)):
752
- limits[typeInner]['min'] = minValue
753
- limits[typeInner]['max'] = maxValue
754
- if typeInner == 'withdraw':
755
- commissionDesc = self.safe_string(provider, 'commission_desc')
756
- fee = self.parse_fixed_float_value(commissionDesc)
757
- code = self.safe_currency_code(currencyId)
758
- result[code] = {
759
+ networkEntry['withdraw'] = activeProvider
760
+ networkEntry['limits']['withdraw']['min'] = minValue
761
+ networkEntry['limits']['withdraw']['max'] = maxValue
762
+ info = self.safe_list(networkEntry, 'info')
763
+ info.append(provider)
764
+ networkEntry['info'] = info
765
+ networks[networkCode] = networkEntry
766
+ result[code] = self.safe_currency_structure({
759
767
  'id': currencyId,
760
768
  'code': code,
761
- 'name': name,
769
+ 'name': self.safe_string(currency, 'description'),
762
770
  'type': type,
763
- 'active': active,
764
- 'deposit': depositEnabled,
765
- 'withdraw': withdrawEnabled,
766
- 'fee': fee,
771
+ 'active': None,
772
+ 'deposit': None,
773
+ 'withdraw': None,
774
+ 'fee': None,
767
775
  'precision': self.parse_number('1e-8'),
768
- 'limits': limits,
769
- 'info': providers,
770
- 'networks': {},
771
- }
776
+ 'limits': {
777
+ 'withdraw': {
778
+ 'min': None,
779
+ 'max': None,
780
+ },
781
+ 'deposit': {
782
+ 'min': None,
783
+ 'max': None,
784
+ },
785
+ },
786
+ 'info': {
787
+ 'currency': currency,
788
+ 'providers': providers,
789
+ },
790
+ 'networks': networks,
791
+ })
772
792
  return result
773
793
 
774
794
  async def fetch_markets(self, params={}) -> List[Market]:
ccxt/async_support/htx.py CHANGED
@@ -6342,7 +6342,7 @@ class htx(Exchange, ImplicitAPI):
6342
6342
  fee = self.safe_number(params, 'fee')
6343
6343
  if fee is None:
6344
6344
  currencies = await self.fetch_currencies()
6345
- self.currencies = self.deep_extend(self.currencies, currencies)
6345
+ self.currencies = self.map_to_safe_map(self.deep_extend(self.currencies, currencies))
6346
6346
  targetNetwork = self.safe_value(currency['networks'], networkCode, {})
6347
6347
  fee = self.safe_number(targetNetwork, 'fee')
6348
6348
  if fee is None:
@@ -696,7 +696,8 @@ class hyperliquid(Exchange, ImplicitAPI):
696
696
  # }
697
697
  #
698
698
  quoteId = 'USDC'
699
- base = self.safe_string(market, 'name')
699
+ baseName = self.safe_string(market, 'name')
700
+ base = self.safe_currency_code(baseName)
700
701
  quote = self.safe_currency_code(quoteId)
701
702
  baseId = self.safe_string(market, 'baseId')
702
703
  settleId = 'USDC'
@@ -538,7 +538,7 @@ class krakenfutures(Exchange, ImplicitAPI):
538
538
  'code': code,
539
539
  'precision': None,
540
540
  })
541
- self.currencies = self.deep_extend(currencies, self.currencies)
541
+ self.currencies = self.map_to_safe_map(self.deep_extend(currencies, self.currencies))
542
542
  return result
543
543
 
544
544
  async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
@@ -1397,35 +1397,31 @@ class kucoin(Exchange, ImplicitAPI):
1397
1397
  # }
1398
1398
  #
1399
1399
  currenciesData = self.safe_list(response, 'data', [])
1400
+ brokenCurrencies = self.safe_list(self.options, 'brokenCurrencies', ['00', 'OPEN_ERROR', 'HUF', 'BDT'])
1401
+ otherFiats = self.safe_list(self.options, 'fiats', ['KWD', 'IRR', 'PKR'])
1400
1402
  result: dict = {}
1401
1403
  for i in range(0, len(currenciesData)):
1402
1404
  entry = currenciesData[i]
1403
1405
  id = self.safe_string(entry, 'currency')
1404
- name = self.safe_string(entry, 'fullName')
1406
+ if self.in_array(id, brokenCurrencies):
1407
+ continue # skip buggy entries: https://t.me/KuCoin_API/217798
1405
1408
  code = self.safe_currency_code(id)
1406
1409
  networks: dict = {}
1407
1410
  chains = self.safe_list(entry, 'chains', [])
1408
- rawPrecision = self.safe_string(entry, 'precision')
1409
- precision = self.parse_number(self.parse_precision(rawPrecision))
1410
1411
  chainsLength = len(chains)
1411
- if not chainsLength:
1412
- # one buggy coin, which doesn't contain info https://t.me/KuCoin_API/173118
1413
- continue
1414
1412
  for j in range(0, chainsLength):
1415
1413
  chain = chains[j]
1416
1414
  chainId = self.safe_string(chain, 'chainId')
1417
1415
  networkCode = self.network_id_to_code(chainId, code)
1418
- chainWithdrawEnabled = self.safe_bool(chain, 'isWithdrawEnabled', False)
1419
- chainDepositEnabled = self.safe_bool(chain, 'isDepositEnabled', False)
1420
1416
  networks[networkCode] = {
1421
1417
  'info': chain,
1422
1418
  'id': chainId,
1423
1419
  'name': self.safe_string(chain, 'chainName'),
1424
1420
  'code': networkCode,
1425
- 'active': chainWithdrawEnabled and chainDepositEnabled,
1421
+ 'active': None,
1426
1422
  'fee': self.safe_number(chain, 'withdrawalMinFee'),
1427
- 'deposit': chainDepositEnabled,
1428
- 'withdraw': chainWithdrawEnabled,
1423
+ 'deposit': self.safe_bool(chain, 'isDepositEnabled'),
1424
+ 'withdraw': self.safe_bool(chain, 'isWithdrawEnabled'),
1429
1425
  'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'withdrawPrecision'))),
1430
1426
  'limits': {
1431
1427
  'withdraw': {
@@ -1439,10 +1435,12 @@ class kucoin(Exchange, ImplicitAPI):
1439
1435
  },
1440
1436
  }
1441
1437
  # kucoin has determined 'fiat' currencies with below logic
1442
- isFiat = (rawPrecision == '2') and (chainsLength == 0)
1438
+ rawPrecision = self.safe_string(entry, 'precision')
1439
+ precision = self.parse_number(self.parse_precision(rawPrecision))
1440
+ isFiat = self.in_array(id, otherFiats) or ((rawPrecision == '2') and (chainsLength == 0))
1443
1441
  result[code] = self.safe_currency_structure({
1444
1442
  'id': id,
1445
- 'name': name,
1443
+ 'name': self.safe_string(entry, 'fullName'),
1446
1444
  'code': code,
1447
1445
  'type': 'fiat' if isFiat else 'crypto',
1448
1446
  'precision': precision,
@@ -2628,7 +2626,7 @@ class kucoin(Exchange, ImplicitAPI):
2628
2626
  """
2629
2627
  await self.load_markets()
2630
2628
  request: dict = {}
2631
- trigger = self.safe_bool(params, 'stop', False)
2629
+ trigger = self.safe_bool_2(params, 'trigger', 'stop', False)
2632
2630
  hf = None
2633
2631
  hf, params = self.handle_hf_and_params(params)
2634
2632
  params = self.omit(params, 'stop')