ccxt 4.4.20__py2.py3-none-any.whl → 4.4.22__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 (52) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/bitflyer.py +1 -0
  3. ccxt/abstract/bitget.py +3 -0
  4. ccxt/abstract/bybit.py +1 -0
  5. ccxt/abstract/cex.py +28 -29
  6. ccxt/abstract/gate.py +5 -0
  7. ccxt/abstract/gateio.py +5 -0
  8. ccxt/abstract/kucoin.py +2 -0
  9. ccxt/abstract/kucoinfutures.py +2 -0
  10. ccxt/abstract/okx.py +4 -0
  11. ccxt/alpaca.py +1 -0
  12. ccxt/async_support/__init__.py +1 -1
  13. ccxt/async_support/alpaca.py +1 -0
  14. ccxt/async_support/base/exchange.py +7 -1
  15. ccxt/async_support/bigone.py +3 -0
  16. ccxt/async_support/binance.py +96 -10
  17. ccxt/async_support/bingx.py +5 -1
  18. ccxt/async_support/bitflyer.py +56 -1
  19. ccxt/async_support/bitget.py +73 -1
  20. ccxt/async_support/bybit.py +135 -4
  21. ccxt/async_support/cex.py +1247 -1326
  22. ccxt/async_support/cryptocom.py +1 -1
  23. ccxt/async_support/gate.py +97 -2
  24. ccxt/async_support/htx.py +27 -7
  25. ccxt/async_support/hyperliquid.py +15 -12
  26. ccxt/async_support/kucoin.py +42 -88
  27. ccxt/async_support/kucoinfutures.py +2 -2
  28. ccxt/async_support/okx.py +76 -10
  29. ccxt/base/exchange.py +33 -1
  30. ccxt/base/types.py +9 -0
  31. ccxt/bigone.py +3 -0
  32. ccxt/binance.py +96 -10
  33. ccxt/bingx.py +5 -1
  34. ccxt/bitflyer.py +56 -1
  35. ccxt/bitget.py +73 -1
  36. ccxt/bybit.py +135 -4
  37. ccxt/cex.py +1246 -1326
  38. ccxt/cryptocom.py +1 -1
  39. ccxt/gate.py +97 -2
  40. ccxt/htx.py +27 -7
  41. ccxt/hyperliquid.py +15 -12
  42. ccxt/kucoin.py +42 -88
  43. ccxt/kucoinfutures.py +2 -2
  44. ccxt/okx.py +76 -10
  45. ccxt/pro/__init__.py +1 -1
  46. ccxt/test/tests_async.py +4 -4
  47. ccxt/test/tests_sync.py +4 -4
  48. {ccxt-4.4.20.dist-info → ccxt-4.4.22.dist-info}/METADATA +5 -5
  49. {ccxt-4.4.20.dist-info → ccxt-4.4.22.dist-info}/RECORD +52 -52
  50. {ccxt-4.4.20.dist-info → ccxt-4.4.22.dist-info}/LICENSE.txt +0 -0
  51. {ccxt-4.4.20.dist-info → ccxt-4.4.22.dist-info}/WHEEL +0 -0
  52. {ccxt-4.4.20.dist-info → ccxt-4.4.22.dist-info}/top_level.txt +0 -0
ccxt/cryptocom.py CHANGED
@@ -1496,7 +1496,7 @@ class cryptocom(Exchange, ImplicitAPI):
1496
1496
  paginate = False
1497
1497
  paginate, params = self.handle_option_and_params(params, 'fetchMyTrades', 'paginate')
1498
1498
  if paginate:
1499
- return self.fetch_paginated_call_dynamic('fetchMyTrades', symbol, since, limit, params)
1499
+ return self.fetch_paginated_call_dynamic('fetchMyTrades', symbol, since, limit, params, 100)
1500
1500
  request: dict = {}
1501
1501
  market = None
1502
1502
  if symbol is not None:
ccxt/gate.py CHANGED
@@ -339,10 +339,17 @@ class gate(Exchange, ImplicitAPI):
339
339
  'interest_records': 20 / 15,
340
340
  'estimate_rate': 20 / 15,
341
341
  'currency_discount_tiers': 20 / 15,
342
+ 'risk_units': 20 / 15,
343
+ 'unified_mode': 20 / 15,
344
+ 'loan_margin_tiers': 20 / 15,
342
345
  },
343
346
  'post': {
344
347
  'account_mode': 20 / 15,
345
348
  'loans': 200 / 15, # 15r/10s cost = 20 / 1.5 = 13.33
349
+ 'portfolio_calculator': 20 / 15,
350
+ },
351
+ 'put': {
352
+ 'unified_mode': 20 / 15,
346
353
  },
347
354
  },
348
355
  'spot': {
@@ -644,6 +651,7 @@ class gate(Exchange, ImplicitAPI):
644
651
  },
645
652
  'options': {
646
653
  'sandboxMode': False,
654
+ 'unifiedAccount': None,
647
655
  'createOrder': {
648
656
  'expiration': 86400, # for conditional orders
649
657
  },
@@ -905,6 +913,34 @@ class gate(Exchange, ImplicitAPI):
905
913
  super(gate, self).set_sandbox_mode(enable)
906
914
  self.options['sandboxMode'] = enable
907
915
 
916
+ def load_unified_status(self, params={}):
917
+ """
918
+ returns unifiedAccount so the user can check if the unified account is enabled
919
+ :see: https://www.gate.io/docs/developers/apiv4/#get-account-detail
920
+ :returns boolean: True or False if the enabled unified account is enabled or not and sets the unifiedAccount option if it is None
921
+ """
922
+ unifiedAccount = self.safe_bool(self.options, 'unifiedAccount')
923
+ if unifiedAccount is None:
924
+ response = self.privateAccountGetDetail(params)
925
+ #
926
+ # {
927
+ # "user_id": 10406147,
928
+ # "ip_whitelist": [],
929
+ # "currency_pairs": [],
930
+ # "key": {
931
+ # "mode": 1
932
+ # },
933
+ # "tier": 0,
934
+ # "tier_expire_time": "0001-01-01T00:00:00Z",
935
+ # "copy_trading_role": 0
936
+ # }
937
+ #
938
+ result = self.safe_dict(response, 'key', {})
939
+ self.options['unifiedAccount'] = self.safe_integer(result, 'mode') == 2
940
+
941
+ def upgrade_unified_trade_account(self, params={}):
942
+ return self.privateUnifiedPutUnifiedMode(params)
943
+
908
944
  def create_expired_option_market(self, symbol: str):
909
945
  # support expired option contracts
910
946
  quote = 'USDT'
@@ -1549,6 +1585,8 @@ class gate(Exchange, ImplicitAPI):
1549
1585
  apiBackup = self.safe_value(self.urls, 'apiBackup')
1550
1586
  if apiBackup is not None:
1551
1587
  return None
1588
+ if self.check_required_credentials(False):
1589
+ self.load_unified_status()
1552
1590
  response = self.publicSpotGetCurrencies(params)
1553
1591
  #
1554
1592
  # {
@@ -2573,10 +2611,14 @@ class gate(Exchange, ImplicitAPI):
2573
2611
  :param str [params.settle]: 'btc' or 'usdt' - settle currency for perpetual swap and future - default="usdt" for swap and "btc" for future
2574
2612
  :param str [params.marginMode]: 'cross' or 'isolated' - marginMode for margin trading if not provided self.options['defaultMarginMode'] is used
2575
2613
  :param str [params.symbol]: margin only - unified ccxt symbol
2614
+ :param boolean [params.unifiedAccount]: default False, set to True for fetching the unified account balance
2576
2615
  """
2577
2616
  self.load_markets()
2617
+ self.load_unified_status()
2578
2618
  symbol = self.safe_string(params, 'symbol')
2579
2619
  params = self.omit(params, 'symbol')
2620
+ isUnifiedAccount = False
2621
+ isUnifiedAccount, params = self.handle_option_and_params(params, 'fetchBalance', 'unifiedAccount')
2580
2622
  type, query = self.handle_market_type_and_params('fetchBalance', None, params)
2581
2623
  request, requestParams = self.prepare_request(None, type, query)
2582
2624
  marginMode, requestQuery = self.get_margin_mode(False, requestParams)
@@ -2584,7 +2626,9 @@ class gate(Exchange, ImplicitAPI):
2584
2626
  market = self.market(symbol)
2585
2627
  request['currency_pair'] = market['id']
2586
2628
  response = None
2587
- if type == 'spot':
2629
+ if isUnifiedAccount:
2630
+ response = self.privateUnifiedGetAccounts(self.extend(request, params))
2631
+ elif type == 'spot':
2588
2632
  if marginMode == 'spot':
2589
2633
  response = self.privateSpotGetAccounts(self.extend(request, requestQuery))
2590
2634
  elif marginMode == 'margin':
@@ -2747,12 +2791,63 @@ class gate(Exchange, ImplicitAPI):
2747
2791
  # "orders_limit": 10
2748
2792
  # }
2749
2793
  #
2794
+ # unified
2795
+ #
2796
+ # {
2797
+ # "user_id": 10001,
2798
+ # "locked": False,
2799
+ # "balances": {
2800
+ # "ETH": {
2801
+ # "available": "0",
2802
+ # "freeze": "0",
2803
+ # "borrowed": "0.075393666654",
2804
+ # "negative_liab": "0",
2805
+ # "futures_pos_liab": "0",
2806
+ # "equity": "1016.1",
2807
+ # "total_freeze": "0",
2808
+ # "total_liab": "0"
2809
+ # },
2810
+ # "POINT": {
2811
+ # "available": "9999999999.017023138734",
2812
+ # "freeze": "0",
2813
+ # "borrowed": "0",
2814
+ # "negative_liab": "0",
2815
+ # "futures_pos_liab": "0",
2816
+ # "equity": "12016.1",
2817
+ # "total_freeze": "0",
2818
+ # "total_liab": "0"
2819
+ # },
2820
+ # "USDT": {
2821
+ # "available": "0.00000062023",
2822
+ # "freeze": "0",
2823
+ # "borrowed": "0",
2824
+ # "negative_liab": "0",
2825
+ # "futures_pos_liab": "0",
2826
+ # "equity": "16.1",
2827
+ # "total_freeze": "0",
2828
+ # "total_liab": "0"
2829
+ # }
2830
+ # },
2831
+ # "total": "230.94621713",
2832
+ # "borrowed": "161.66395521",
2833
+ # "total_initial_margin": "1025.0524665088",
2834
+ # "total_margin_balance": "3382495.944473949183",
2835
+ # "total_maintenance_margin": "205.01049330176",
2836
+ # "total_initial_margin_rate": "3299.827135672679",
2837
+ # "total_maintenance_margin_rate": "16499.135678363399",
2838
+ # "total_available_margin": "3381470.892007440383",
2839
+ # "unified_account_total": "3381470.892007440383",
2840
+ # "unified_account_total_liab": "0",
2841
+ # "unified_account_total_equity": "100016.1",
2842
+ # "leverage": "2"
2843
+ # }
2844
+ #
2750
2845
  result: dict = {
2751
2846
  'info': response,
2752
2847
  }
2753
2848
  isolated = marginMode == 'margin'
2754
2849
  data = response
2755
- if 'balances' in data: # True for cross_margin
2850
+ if 'balances' in data: # True for cross_margin and unified
2756
2851
  flatBalances = []
2757
2852
  balances = self.safe_value(data, 'balances', [])
2758
2853
  # inject currency and create an artificial balance object
ccxt/htx.py CHANGED
@@ -1627,6 +1627,10 @@ class htx(Exchange, ImplicitAPI):
1627
1627
  def fetch_markets(self, params={}) -> List[Market]:
1628
1628
  """
1629
1629
  retrieves data on all markets for huobi
1630
+ :see: https://huobiapi.github.io/docs/spot/v1/en/#get-all-supported-trading-symbol-v1-deprecated
1631
+ :see: https://huobiapi.github.io/docs/dm/v1/en/#get-contract-info
1632
+ :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-swap-info
1633
+ :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-swap-info
1630
1634
  :param dict [params]: extra parameters specific to the exchange API endpoint
1631
1635
  :returns dict[]: an array of objects representing market data
1632
1636
  """
@@ -1650,7 +1654,19 @@ class htx(Exchange, ImplicitAPI):
1650
1654
  allMarkets = self.array_concat(allMarkets, promises[i])
1651
1655
  return allMarkets
1652
1656
 
1653
- def fetch_markets_by_type_and_sub_type(self, type, subType, params={}):
1657
+ def fetch_markets_by_type_and_sub_type(self, type: Str, subType: Str, params={}):
1658
+ """
1659
+ * @ignore
1660
+ retrieves data on all markets of a certain type and/or subtype
1661
+ :see: https://huobiapi.github.io/docs/spot/v1/en/#get-all-supported-trading-symbol-v1-deprecated
1662
+ :see: https://huobiapi.github.io/docs/dm/v1/en/#get-contract-info
1663
+ :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-swap-info
1664
+ :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-swap-info
1665
+ :param str [type]: 'spot', 'swap' or 'future'
1666
+ :param str [subType]: 'linear' or 'inverse'
1667
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1668
+ :returns dict[]: an array of objects representing market data
1669
+ """
1654
1670
  isSpot = (type == 'spot')
1655
1671
  request: dict = {}
1656
1672
  response = None
@@ -3014,7 +3030,15 @@ class htx(Exchange, ImplicitAPI):
3014
3030
  'code': None,
3015
3031
  }
3016
3032
 
3017
- def fetch_account_id_by_type(self, type, marginMode=None, symbol=None, params={}):
3033
+ def fetch_account_id_by_type(self, type: str, marginMode: Str = None, symbol: Str = None, params={}):
3034
+ """
3035
+ fetch all the accounts by a type and marginModeassociated with a profile
3036
+ :see: https://huobiapi.github.io/docs/spot/v1/en/#get-all-accounts-of-the-current-user
3037
+ :param str type: 'spot', 'swap' or 'future
3038
+ :param str [marginMode]: 'cross' or 'isolated'
3039
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3040
+ :returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
3041
+ """
3018
3042
  accounts = self.load_accounts()
3019
3043
  accountId = self.safe_value_2(params, 'accountId', 'account-id')
3020
3044
  if accountId is not None:
@@ -4755,11 +4779,7 @@ class htx(Exchange, ImplicitAPI):
4755
4779
  cost = None
4756
4780
  amount = None
4757
4781
  if (type is not None) and (type.find('market') >= 0):
4758
- # for market orders amount is in quote currency, meaning it is the cost
4759
- if side == 'sell':
4760
- cost = self.safe_string(order, 'field-cash-amount')
4761
- else:
4762
- cost = self.safe_string(order, 'amount')
4782
+ cost = self.safe_string(order, 'field-cash-amount')
4763
4783
  else:
4764
4784
  amount = self.safe_string_2(order, 'volume', 'amount')
4765
4785
  cost = self.safe_string_n(order, ['filled-cash-amount', 'field-cash-amount', 'trade_turnover']) # same typo here
ccxt/hyperliquid.py CHANGED
@@ -638,17 +638,17 @@ class hyperliquid(Exchange, ImplicitAPI):
638
638
  code = self.safe_currency_code(self.safe_string(balance, 'coin'))
639
639
  account = self.account()
640
640
  total = self.safe_string(balance, 'total')
641
- free = self.safe_string(balance, 'hold')
641
+ used = self.safe_string(balance, 'hold')
642
642
  account['total'] = total
643
- account['used'] = free
643
+ account['used'] = used
644
644
  spotBalances[code] = account
645
645
  return self.safe_balance(spotBalances)
646
646
  data = self.safe_dict(response, 'marginSummary', {})
647
647
  result: dict = {
648
648
  'info': response,
649
649
  'USDC': {
650
- 'total': self.safe_float(data, 'accountValue'),
651
- 'used': self.safe_float(data, 'totalMarginUsed'),
650
+ 'total': self.safe_number(data, 'accountValue'),
651
+ 'free': self.safe_number(response, 'withdrawable'),
652
652
  },
653
653
  }
654
654
  timestamp = self.safe_integer(response, 'time')
@@ -2112,13 +2112,16 @@ class hyperliquid(Exchange, ImplicitAPI):
2112
2112
  leverage = self.safe_dict(entry, 'leverage', {})
2113
2113
  marginMode = self.safe_string(leverage, 'type')
2114
2114
  isIsolated = (marginMode == 'isolated')
2115
- size = self.safe_number(entry, 'szi')
2115
+ rawSize = self.safe_string(entry, 'szi')
2116
+ size = rawSize
2116
2117
  side = None
2117
2118
  if size is not None:
2118
- side = 'long' if (size > 0) else 'short'
2119
- unrealizedPnl = self.safe_number(entry, 'unrealizedPnl')
2120
- initialMargin = self.safe_number(entry, 'marginUsed')
2121
- percentage = unrealizedPnl / initialMargin * 100
2119
+ side = 'long' if Precise.string_gt(rawSize, '0') else 'short'
2120
+ size = Precise.string_abs(size)
2121
+ rawUnrealizedPnl = self.safe_string(entry, 'unrealizedPnl')
2122
+ absRawUnrealizedPnl = Precise.string_abs(rawUnrealizedPnl)
2123
+ initialMargin = self.safe_string(entry, 'marginUsed')
2124
+ percentage = Precise.string_mul(Precise.string_div(absRawUnrealizedPnl, initialMargin), '100')
2122
2125
  return self.safe_position({
2123
2126
  'info': position,
2124
2127
  'id': None,
@@ -2128,7 +2131,7 @@ class hyperliquid(Exchange, ImplicitAPI):
2128
2131
  'isolated': isIsolated,
2129
2132
  'hedged': None,
2130
2133
  'side': side,
2131
- 'contracts': size,
2134
+ 'contracts': self.parse_number(size),
2132
2135
  'contractSize': None,
2133
2136
  'entryPrice': self.safe_number(entry, 'entryPx'),
2134
2137
  'markPrice': None,
@@ -2139,10 +2142,10 @@ class hyperliquid(Exchange, ImplicitAPI):
2139
2142
  'maintenanceMargin': None,
2140
2143
  'initialMarginPercentage': None,
2141
2144
  'maintenanceMarginPercentage': None,
2142
- 'unrealizedPnl': unrealizedPnl,
2145
+ 'unrealizedPnl': self.parse_number(rawUnrealizedPnl),
2143
2146
  'liquidationPrice': self.safe_number(entry, 'liquidationPx'),
2144
2147
  'marginMode': marginMode,
2145
- 'percentage': percentage,
2148
+ 'percentage': self.parse_number(percentage),
2146
2149
  })
2147
2150
 
2148
2151
  def set_margin_mode(self, marginMode: str, symbol: Str = None, params={}):
ccxt/kucoin.py CHANGED
@@ -183,6 +183,7 @@ class kucoin(Exchange, ImplicitAPI):
183
183
  'mark-price/{symbol}/current': 3, # 2PW
184
184
  'mark-price/all-symbols': 3,
185
185
  'margin/config': 25, # 25SW
186
+ 'announcements': 20, # 20W
186
187
  },
187
188
  'post': {
188
189
  # ws
@@ -306,6 +307,7 @@ class kucoin(Exchange, ImplicitAPI):
306
307
  # ws
307
308
  'bullet-private': 10, # 10SW
308
309
  'position/update-user-leverage': 5,
310
+ 'deposit-address/create': 20,
309
311
  },
310
312
  'delete': {
311
313
  # account
@@ -472,6 +474,7 @@ class kucoin(Exchange, ImplicitAPI):
472
474
  'precisionMode': TICK_SIZE,
473
475
  'exceptions': {
474
476
  'exact': {
477
+ 'The order does not exist.': OrderNotFound,
475
478
  'order not exist': OrderNotFound,
476
479
  'order not exist.': OrderNotFound, # duplicated error temporarily
477
480
  'order_not_exist': OrderNotFound, # {"code":"order_not_exist","msg":"order_not_exist"} ¯\_(ツ)_/¯
@@ -672,6 +675,7 @@ class kucoin(Exchange, ImplicitAPI):
672
675
  'currencies/{currency}': 'v3',
673
676
  'symbols': 'v2',
674
677
  'mark-price/all-symbols': 'v3',
678
+ 'announcements': 'v3',
675
679
  },
676
680
  },
677
681
  'private': {
@@ -723,6 +727,7 @@ class kucoin(Exchange, ImplicitAPI):
723
727
  'accounts/sub-transfer': 'v2',
724
728
  'accounts/inner-transfer': 'v2',
725
729
  'transfer-out': 'v3',
730
+ 'deposit-address/create': 'v3',
726
731
  # spot trading
727
732
  'oco/order': 'v3',
728
733
  # margin trading
@@ -734,6 +739,7 @@ class kucoin(Exchange, ImplicitAPI):
734
739
  'redeem': 'v3',
735
740
  'lend/purchase/update': 'v3',
736
741
  'position/update-user-leverage': 'v3',
742
+ 'withdrawals': 'v3',
737
743
  },
738
744
  'DELETE': {
739
745
  # account
@@ -799,7 +805,7 @@ class kucoin(Exchange, ImplicitAPI):
799
805
  'TLOS': 'tlos', # tlosevm is different
800
806
  'CFX': 'cfx',
801
807
  'ACA': 'aca',
802
- 'OPTIMISM': 'optimism',
808
+ 'OP': 'optimism',
803
809
  'ONT': 'ont',
804
810
  'GLMR': 'glmr',
805
811
  'CSPR': 'cspr',
@@ -1529,38 +1535,28 @@ class kucoin(Exchange, ImplicitAPI):
1529
1535
  # "chain": "ERC20"
1530
1536
  # }
1531
1537
  #
1538
+ minWithdrawFee = self.safe_number(fee, 'withdrawMinFee')
1532
1539
  result: dict = {
1533
1540
  'info': fee,
1534
1541
  'withdraw': {
1542
+ 'fee': minWithdrawFee,
1543
+ 'percentage': False,
1544
+ },
1545
+ 'deposit': {
1535
1546
  'fee': None,
1536
1547
  'percentage': None,
1537
1548
  },
1549
+ 'networks': {},
1550
+ }
1551
+ networkId = self.safe_string(fee, 'chain')
1552
+ networkCode = self.network_id_to_code(networkId, self.safe_string(currency, 'code'))
1553
+ result['networks'][networkCode] = {
1554
+ 'withdraw': minWithdrawFee,
1538
1555
  'deposit': {
1539
1556
  'fee': None,
1540
1557
  'percentage': None,
1541
1558
  },
1542
- 'networks': {},
1543
1559
  }
1544
- isWithdrawEnabled = self.safe_bool(fee, 'isWithdrawEnabled', True)
1545
- minFee = None
1546
- if isWithdrawEnabled:
1547
- result['withdraw']['percentage'] = False
1548
- chains = self.safe_list(fee, 'chains', [])
1549
- for i in range(0, len(chains)):
1550
- chain = chains[i]
1551
- networkId = self.safe_string(chain, 'chainId')
1552
- networkCode = self.network_id_to_code(networkId, self.safe_string(currency, 'code'))
1553
- withdrawFee = self.safe_string(chain, 'withdrawalMinFee')
1554
- if minFee is None or (Precise.string_lt(withdrawFee, minFee)):
1555
- minFee = withdrawFee
1556
- result['networks'][networkCode] = {
1557
- 'withdraw': self.parse_number(withdrawFee),
1558
- 'deposit': {
1559
- 'fee': None,
1560
- 'percentage': None,
1561
- },
1562
- }
1563
- result['withdraw']['fee'] = self.parse_number(minFee)
1564
1560
  return result
1565
1561
 
1566
1562
  def is_futures_method(self, methodName, params):
@@ -1869,7 +1865,7 @@ class kucoin(Exchange, ImplicitAPI):
1869
1865
 
1870
1866
  def create_deposit_address(self, code: str, params={}):
1871
1867
  """
1872
- :see: https://docs.kucoin.com/#create-deposit-address
1868
+ :see: https://www.kucoin.com/docs/rest/funding/deposit/create-deposit-address-v3-
1873
1869
  create a currency deposit address
1874
1870
  :param str code: unified currency code of the currency for the deposit address
1875
1871
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -1884,11 +1880,23 @@ class kucoin(Exchange, ImplicitAPI):
1884
1880
  networkCode = None
1885
1881
  networkCode, params = self.handle_network_code_and_params(params)
1886
1882
  if networkCode is not None:
1887
- request['chain'] = self.network_code_to_id(networkCode).lower()
1888
- response = self.privatePostDepositAddresses(self.extend(request, params))
1883
+ request['chain'] = self.network_code_to_id(networkCode) # docs mention "chain-name", but seems "chain-id" is used, like in "fetchDepositAddress"
1884
+ response = self.privatePostDepositAddressCreate(self.extend(request, params))
1889
1885
  # {"code":"260000","msg":"Deposit address already exists."}
1890
- # BCH {"code":"200000","data":{"address":"bitcoincash:qza3m4nj9rx7l9r0cdadfqxts6f92shvhvr5ls4q7z","memo":""}}
1891
- # BTC {"code":"200000","data":{"address":"36SjucKqQpQSvsak9A7h6qzFjrVXpRNZhE","memo":""}}
1886
+ #
1887
+ # {
1888
+ # "code": "200000",
1889
+ # "data": {
1890
+ # "address": "0x2336d1834faab10b2dac44e468f2627138417431",
1891
+ # "memo": null,
1892
+ # "chainId": "bsc",
1893
+ # "to": "MAIN",
1894
+ # "expirationDate": 0,
1895
+ # "currency": "BNB",
1896
+ # "chainName": "BEP20"
1897
+ # }
1898
+ # }
1899
+ #
1892
1900
  data = self.safe_dict(response, 'data', {})
1893
1901
  return self.parse_deposit_address(data, currency)
1894
1902
 
@@ -1938,7 +1946,7 @@ class kucoin(Exchange, ImplicitAPI):
1938
1946
  return {
1939
1947
  'info': depositAddress,
1940
1948
  'currency': code,
1941
- 'network': self.network_id_to_code(self.safe_string(depositAddress, 'chain')),
1949
+ 'network': self.network_id_to_code(self.safe_string(depositAddress, 'chainId')),
1942
1950
  'address': address,
1943
1951
  'tag': self.safe_string(depositAddress, 'memo'),
1944
1952
  }
@@ -2920,7 +2928,7 @@ class kucoin(Exchange, ImplicitAPI):
2920
2928
  },
2921
2929
  'status': status,
2922
2930
  'lastTradeTimestamp': None,
2923
- 'average': None,
2931
+ 'average': self.safe_string(order, 'avgDealPrice'),
2924
2932
  'trades': None,
2925
2933
  }, market)
2926
2934
 
@@ -3245,7 +3253,7 @@ class kucoin(Exchange, ImplicitAPI):
3245
3253
  def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
3246
3254
  """
3247
3255
  make a withdrawal
3248
- :see: https://www.kucoin.com/docs/rest/funding/withdrawals/apply-withdraw
3256
+ :see: https://www.kucoin.com/docs/rest/funding/withdrawals/apply-withdraw-v3-
3249
3257
  :param str code: unified currency code
3250
3258
  :param float amount: the amount to withdraw
3251
3259
  :param str address: the address to withdraw to
@@ -3259,7 +3267,8 @@ class kucoin(Exchange, ImplicitAPI):
3259
3267
  currency = self.currency(code)
3260
3268
  request: dict = {
3261
3269
  'currency': currency['id'],
3262
- 'address': address,
3270
+ 'toAddress': address,
3271
+ 'withdrawType': 'ADDRESS',
3263
3272
  # 'memo': tag,
3264
3273
  # 'isInner': False, # internal transfer or external withdrawal
3265
3274
  # 'remark': 'optional',
@@ -3271,15 +3280,14 @@ class kucoin(Exchange, ImplicitAPI):
3271
3280
  networkCode, params = self.handle_network_code_and_params(params)
3272
3281
  if networkCode is not None:
3273
3282
  request['chain'] = self.network_code_to_id(networkCode).lower()
3274
- self.load_currency_precision(currency, networkCode)
3275
- request['amount'] = self.currency_to_precision(code, amount, networkCode)
3283
+ request['amount'] = float(self.currency_to_precision(code, amount, networkCode))
3276
3284
  includeFee = None
3277
3285
  includeFee, params = self.handle_option_and_params(params, 'withdraw', 'includeFee', False)
3278
3286
  if includeFee:
3279
3287
  request['feeDeductType'] = 'INTERNAL'
3280
3288
  response = self.privatePostWithdrawals(self.extend(request, params))
3281
3289
  #
3282
- # https://github.com/ccxt/ccxt/issues/5558
3290
+ # the id is inside "data"
3283
3291
  #
3284
3292
  # {
3285
3293
  # "code": 200000,
@@ -3291,51 +3299,6 @@ class kucoin(Exchange, ImplicitAPI):
3291
3299
  data = self.safe_dict(response, 'data', {})
3292
3300
  return self.parse_transaction(data, currency)
3293
3301
 
3294
- def load_currency_precision(self, currency, networkCode: Str = None):
3295
- # might not have network specific precisions defined in fetchCurrencies(because of webapi failure)
3296
- # we should check and refetch precision once-per-instance for that specific currency & network
3297
- # so avoids thorwing exceptions and burden to users
3298
- # Note: self needs to be executed only if networkCode was provided
3299
- if networkCode is not None:
3300
- networks = currency['networks']
3301
- network = self.safe_dict(networks, networkCode)
3302
- if self.safe_number(network, 'precision') is not None:
3303
- # if precision exists, no need to refetch
3304
- return
3305
- # otherwise try to fetch and store in instance
3306
- request: dict = {
3307
- 'currency': currency['id'],
3308
- 'chain': self.network_code_to_id(networkCode).lower(),
3309
- }
3310
- response = self.privateGetWithdrawalsQuotas(request)
3311
- #
3312
- # {
3313
- # "code": "200000",
3314
- # "data": {
3315
- # "currency": "USDT",
3316
- # "limitBTCAmount": "14.24094850",
3317
- # "usedBTCAmount": "0.00000000",
3318
- # "quotaCurrency": "USDT",
3319
- # "limitQuotaCurrencyAmount": "999999.00000000",
3320
- # "usedQuotaCurrencyAmount": "0",
3321
- # "remainAmount": "999999.0000",
3322
- # "availableAmount": "10.77545071",
3323
- # "withdrawMinFee": "1",
3324
- # "innerWithdrawMinFee": "0",
3325
- # "withdrawMinSize": "10",
3326
- # "isWithdrawEnabled": True,
3327
- # "precision": 4,
3328
- # "chain": "EOS",
3329
- # "reason": null,
3330
- # "lockedAmount": "0"
3331
- # }
3332
- # }
3333
- #
3334
- data = self.safe_dict(response, 'data', {})
3335
- precision = self.parse_number(self.parse_precision(self.safe_string(data, 'precision')))
3336
- code = currency['code']
3337
- self.currencies[code]['networks'][networkCode]['precision'] = precision
3338
-
3339
3302
  def parse_transaction_status(self, status: Str):
3340
3303
  statuses: dict = {
3341
3304
  'SUCCESS': 'ok',
@@ -4153,15 +4116,6 @@ class kucoin(Exchange, ImplicitAPI):
4153
4116
  return config['v1']
4154
4117
  return self.safe_value(config, 'cost', 1)
4155
4118
 
4156
- def parse_borrow_rate_history(self, response, code, since, limit):
4157
- result = []
4158
- for i in range(0, len(response)):
4159
- item = response[i]
4160
- borrowRate = self.parse_borrow_rate(item)
4161
- result.append(borrowRate)
4162
- sorted = self.sort_by(result, 'timestamp')
4163
- return self.filter_by_currency_since_limit(sorted, code, since, limit)
4164
-
4165
4119
  def parse_borrow_rate(self, info, currency: Currency = None):
4166
4120
  #
4167
4121
  # {
ccxt/kucoinfutures.py CHANGED
@@ -2103,8 +2103,8 @@ class kucoinfutures(kucoin, ImplicitAPI):
2103
2103
  amount = self.safe_string(order, 'size')
2104
2104
  filled = self.safe_string(order, 'filledSize')
2105
2105
  cost = self.safe_string(order, 'filledValue')
2106
- average = None
2107
- if Precise.string_gt(filled, '0'):
2106
+ average = self.safe_string(order, 'avgDealPrice')
2107
+ if (average is None) and Precise.string_gt(filled, '0'):
2108
2108
  contractSize = self.safe_string(market, 'contractSize')
2109
2109
  if market['linear']:
2110
2110
  average = Precise.string_div(cost, Precise.string_mul(contractSize, filled))