ccxt 4.4.36__py2.py3-none-any.whl → 4.4.38__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 (53) hide show
  1. ccxt/__init__.py +3 -3
  2. ccxt/abstract/bingx.py +0 -1
  3. ccxt/abstract/bitfinex.py +136 -65
  4. ccxt/abstract/bitfinex1.py +69 -0
  5. ccxt/async_support/__init__.py +3 -3
  6. ccxt/async_support/base/exchange.py +1 -1
  7. ccxt/async_support/binance.py +0 -2
  8. ccxt/async_support/bingx.py +89 -8
  9. ccxt/async_support/bitfinex.py +3005 -1084
  10. ccxt/async_support/bitfinex1.py +1704 -0
  11. ccxt/async_support/bitget.py +2 -4
  12. ccxt/async_support/bithumb.py +1 -1
  13. ccxt/async_support/bitmart.py +160 -13
  14. ccxt/async_support/bybit.py +3 -2
  15. ccxt/async_support/coinbase.py +86 -0
  16. ccxt/async_support/gate.py +1 -1
  17. ccxt/async_support/hyperliquid.py +124 -14
  18. ccxt/async_support/kucoin.py +75 -2
  19. ccxt/async_support/kucoinfutures.py +92 -5
  20. ccxt/async_support/ndax.py +5 -1
  21. ccxt/async_support/okx.py +0 -1
  22. ccxt/async_support/paradex.py +2 -2
  23. ccxt/async_support/probit.py +3 -1
  24. ccxt/base/exchange.py +9 -2
  25. ccxt/binance.py +0 -2
  26. ccxt/bingx.py +89 -8
  27. ccxt/bitfinex.py +3005 -1084
  28. ccxt/bitfinex1.py +1703 -0
  29. ccxt/bitget.py +2 -4
  30. ccxt/bithumb.py +1 -1
  31. ccxt/bitmart.py +160 -13
  32. ccxt/bybit.py +3 -2
  33. ccxt/coinbase.py +86 -0
  34. ccxt/gate.py +1 -1
  35. ccxt/hyperliquid.py +124 -14
  36. ccxt/kucoin.py +75 -2
  37. ccxt/kucoinfutures.py +92 -5
  38. ccxt/ndax.py +5 -1
  39. ccxt/okx.py +0 -1
  40. ccxt/paradex.py +2 -2
  41. ccxt/pro/__init__.py +3 -3
  42. ccxt/pro/bitfinex.py +725 -274
  43. ccxt/pro/bitfinex1.py +635 -0
  44. ccxt/pro/probit.py +1 -0
  45. ccxt/probit.py +3 -1
  46. ccxt/test/tests_async.py +5 -1
  47. ccxt/test/tests_sync.py +5 -1
  48. {ccxt-4.4.36.dist-info → ccxt-4.4.38.dist-info}/METADATA +8 -8
  49. {ccxt-4.4.36.dist-info → ccxt-4.4.38.dist-info}/RECORD +52 -49
  50. ccxt/abstract/bitfinex2.py +0 -140
  51. {ccxt-4.4.36.dist-info → ccxt-4.4.38.dist-info}/LICENSE.txt +0 -0
  52. {ccxt-4.4.36.dist-info → ccxt-4.4.38.dist-info}/WHEEL +0 -0
  53. {ccxt-4.4.36.dist-info → ccxt-4.4.38.dist-info}/top_level.txt +0 -0
@@ -1474,8 +1474,8 @@ class bitget(Exchange, ImplicitAPI):
1474
1474
  'index': False, # not on spot
1475
1475
  },
1476
1476
  'triggerDirection': False,
1477
- 'stopLossPrice': True, # but not yet implemented in spot
1478
- 'takeProfitPrice': True, # but not yet implemented in spot
1477
+ 'stopLossPrice': True, # todo: not yet implemented in spot
1478
+ 'takeProfitPrice': True, # todo: not yet implemented in spot
1479
1479
  'attachedStopLossTakeProfit': {
1480
1480
  'triggerPriceType': {
1481
1481
  'last': False,
@@ -1485,7 +1485,6 @@ class bitget(Exchange, ImplicitAPI):
1485
1485
  'limitPrice': True,
1486
1486
  },
1487
1487
  'timeInForce': {
1488
- 'GTC': True,
1489
1488
  'IOC': True,
1490
1489
  'FOK': True,
1491
1490
  'PO': True,
@@ -1556,7 +1555,6 @@ class bitget(Exchange, ImplicitAPI):
1556
1555
  'limitPrice': False,
1557
1556
  },
1558
1557
  'timeInForce': {
1559
- 'GTC': True,
1560
1558
  'IOC': True,
1561
1559
  'FOK': True,
1562
1560
  'PO': True,
@@ -1028,7 +1028,7 @@ class bithumb(Exchange, ImplicitAPI):
1028
1028
  'address': address,
1029
1029
  'currency': currency['id'],
1030
1030
  }
1031
- if code == 'XRP' or code == 'XMR' or code == 'EOS' or code == 'STEEM':
1031
+ if code == 'XRP' or code == 'XMR' or code == 'EOS' or code == 'STEEM' or code == 'TON':
1032
1032
  destination = self.safe_string(params, 'destination')
1033
1033
  if (tag is None) and (destination is None):
1034
1034
  raise ArgumentsRequired(self.id + ' ' + code + ' withdraw() requires a tag argument or an extra destination param')
@@ -704,6 +704,151 @@ class bitmart(Exchange, ImplicitAPI):
704
704
  'createMarketBuyOrderRequiresPrice': True,
705
705
  'brokerId': 'CCXTxBitmart000',
706
706
  },
707
+ 'features': {
708
+ 'default': {
709
+ 'sandbox': False,
710
+ 'createOrder': {
711
+ 'marginMode': True,
712
+ 'triggerPrice': False,
713
+ 'triggerPriceType': None,
714
+ 'triggerDirection': False,
715
+ 'stopLossPrice': False,
716
+ 'takeProfitPrice': False,
717
+ 'attachedStopLossTakeProfit': None,
718
+ 'timeInForce': {
719
+ 'IOC': True,
720
+ 'FOK': False,
721
+ 'PO': True,
722
+ 'GTD': False,
723
+ },
724
+ 'hedged': False,
725
+ 'trailing': False,
726
+ 'marketBuyRequiresPrice': True,
727
+ 'marketBuyByCost': True,
728
+ # exchange-supported features
729
+ # 'leverage': True,
730
+ # 'selfTradePrevention': False,
731
+ # 'twap': False,
732
+ # 'iceberg': False,
733
+ # 'oco': False,
734
+ },
735
+ 'createOrders': {
736
+ 'max': 10,
737
+ },
738
+ 'fetchMyTrades': {
739
+ 'marginMode': True,
740
+ 'limit': 200,
741
+ 'daysBack': None,
742
+ 'untilDays': 99999,
743
+ },
744
+ 'fetchOrder': {
745
+ 'marginMode': False,
746
+ 'trigger': False,
747
+ 'trailing': False,
748
+ },
749
+ 'fetchOpenOrders': {
750
+ 'marginMode': True,
751
+ 'limit': 200,
752
+ 'trigger': False,
753
+ 'trailing': False,
754
+ },
755
+ 'fetchOrders': None,
756
+ 'fetchClosedOrders': {
757
+ 'marginMode': True,
758
+ 'limit': 200,
759
+ 'daysBackClosed': None,
760
+ 'daysBackCanceled': None,
761
+ 'untilDays': None,
762
+ 'trigger': False,
763
+ 'trailing': False,
764
+ },
765
+ 'fetchOHLCV': {
766
+ 'limit': 1000, # variable timespans for recent endpoint, 200 for historical
767
+ },
768
+ },
769
+ 'forDerivatives': {
770
+ 'extends': 'default',
771
+ 'createOrder': {
772
+ 'marginMode': True,
773
+ 'triggerPrice': True,
774
+ 'triggerPriceType': {
775
+ 'last': True,
776
+ 'mark': True,
777
+ 'index': False,
778
+ },
779
+ 'triggerDirection': True, # todo: implementation broken
780
+ 'stopLossPrice': True,
781
+ 'takeProfitPrice': True,
782
+ 'attachedStopLossTakeProfit': {
783
+ 'triggerPriceType': {
784
+ 'last': True,
785
+ 'mark': True,
786
+ 'index': False,
787
+ },
788
+ 'limitPrice': False,
789
+ },
790
+ 'timeInForce': {
791
+ 'IOC': True,
792
+ 'FOK': True,
793
+ 'PO': True,
794
+ 'GTD': False,
795
+ },
796
+ 'hedged': False,
797
+ 'trailing': True,
798
+ 'marketBuyRequiresPrice': True,
799
+ 'marketBuyByCost': True,
800
+ # exchange-supported features
801
+ # 'selfTradePrevention': True,
802
+ # 'twap': False,
803
+ # 'iceberg': False,
804
+ # 'oco': False,
805
+ },
806
+ 'fetchMyTrades': {
807
+ 'marginMode': True,
808
+ 'limit': None,
809
+ 'daysBack': None,
810
+ 'untilDays': 99999,
811
+ },
812
+ 'fetchOrder': {
813
+ 'marginMode': False,
814
+ 'trigger': False,
815
+ 'trailing': True,
816
+ },
817
+ 'fetchOpenOrders': {
818
+ 'marginMode': False,
819
+ 'limit': 100,
820
+ 'trigger': True,
821
+ 'trailing': False,
822
+ },
823
+ 'fetchClosedOrders': {
824
+ 'marginMode': True,
825
+ 'limit': 200,
826
+ 'daysBackClosed': None,
827
+ 'daysBackCanceled': None,
828
+ 'untilDays': None,
829
+ 'trigger': False,
830
+ 'trailing': False,
831
+ },
832
+ 'fetchOHLCV': {
833
+ 'limit': 500,
834
+ },
835
+ },
836
+ 'spot': {
837
+ 'extends': 'default',
838
+ },
839
+ 'swap': {
840
+ 'linear': {
841
+ 'extends': 'forDerivatives',
842
+ },
843
+ 'inverse': {
844
+ 'extends': 'forDerivatives',
845
+ },
846
+ },
847
+ 'future': {
848
+ 'linear': None,
849
+ 'inverse': None,
850
+ },
851
+ },
707
852
  })
708
853
 
709
854
  async def fetch_time(self, params={}):
@@ -1906,10 +2051,11 @@ class bitmart(Exchange, ImplicitAPI):
1906
2051
  if marginMode == 'isolated':
1907
2052
  request['orderMode'] = 'iso_margin'
1908
2053
  options = self.safe_dict(self.options, 'fetchMyTrades', {})
1909
- defaultLimit = self.safe_integer(options, 'limit', 200)
2054
+ maxLimit = 200
2055
+ defaultLimit = self.safe_integer(options, 'limit', maxLimit)
1910
2056
  if limit is None:
1911
2057
  limit = defaultLimit
1912
- request['limit'] = limit
2058
+ request['limit'] = min(limit, maxLimit)
1913
2059
  if since is not None:
1914
2060
  request['startTime'] = since
1915
2061
  if until is not None:
@@ -2549,8 +2695,7 @@ class bitmart(Exchange, ImplicitAPI):
2549
2695
  """
2550
2696
  @ignore
2551
2697
  create a trade order
2552
- https://developer-pro.bitmart.com/en/futures/#submit-order-signed
2553
- https://developer-pro.bitmart.com/en/futures/#submit-plan-order-signed
2698
+ https://developer-pro.bitmart.com/en/futuresv2/#submit-order-signed
2554
2699
  https://developer-pro.bitmart.com/en/futuresv2/#submit-plan-order-signed
2555
2700
  https://developer-pro.bitmart.com/en/futuresv2/#submit-tp-or-sl-order-signed
2556
2701
  :param str symbol: unified symbol of the market to create an order in
@@ -2996,12 +3141,12 @@ class bitmart(Exchange, ImplicitAPI):
2996
3141
  if symbol is not None:
2997
3142
  market = self.market(symbol)
2998
3143
  request['symbol'] = market['id']
2999
- if limit is not None:
3000
- request['limit'] = limit
3001
3144
  type = None
3002
3145
  response = None
3003
3146
  type, params = self.handle_market_type_and_params('fetchOpenOrders', market, params)
3004
3147
  if type == 'spot':
3148
+ if limit is not None:
3149
+ request['limit'] = min(limit, 200)
3005
3150
  marginMode = None
3006
3151
  marginMode, params = self.handle_margin_mode_and_params('fetchOpenOrders', params)
3007
3152
  if marginMode == 'isolated':
@@ -3014,9 +3159,11 @@ class bitmart(Exchange, ImplicitAPI):
3014
3159
  request['endTime'] = until
3015
3160
  response = await self.privatePostSpotV4QueryOpenOrders(self.extend(request, params))
3016
3161
  elif type == 'swap':
3017
- isStop = self.safe_bool_2(params, 'stop', 'trigger')
3162
+ if limit is not None:
3163
+ request['limit'] = min(limit, 100)
3164
+ isTrigger = self.safe_bool_2(params, 'stop', 'trigger')
3018
3165
  params = self.omit(params, ['stop', 'trigger'])
3019
- if isStop:
3166
+ if isTrigger:
3020
3167
  response = await self.privateGetContractPrivateCurrentPlanOrder(self.extend(request, params))
3021
3168
  else:
3022
3169
  trailing = self.safe_bool(params, 'trailing', False)
@@ -3113,12 +3260,8 @@ class bitmart(Exchange, ImplicitAPI):
3113
3260
  if type != 'spot':
3114
3261
  if symbol is None:
3115
3262
  raise ArgumentsRequired(self.id + ' fetchClosedOrders() requires a symbol argument')
3116
- marginMode = None
3117
- marginMode, params = self.handle_margin_mode_and_params('fetchClosedOrders', params)
3118
- if marginMode == 'isolated':
3119
- request['orderMode'] = 'iso_margin'
3120
- startTimeKey = 'startTime' if (type == 'spot') else 'start_time'
3121
3263
  if since is not None:
3264
+ startTimeKey = 'startTime' if (type == 'spot') else 'start_time'
3122
3265
  request[startTimeKey] = since
3123
3266
  endTimeKey = 'endTime' if (type == 'spot') else 'end_time'
3124
3267
  until = self.safe_integer_2(params, 'until', endTimeKey)
@@ -3127,6 +3270,10 @@ class bitmart(Exchange, ImplicitAPI):
3127
3270
  request[endTimeKey] = until
3128
3271
  response = None
3129
3272
  if type == 'spot':
3273
+ marginMode = None
3274
+ marginMode, params = self.handle_margin_mode_and_params('fetchClosedOrders', params)
3275
+ if marginMode == 'isolated':
3276
+ request['orderMode'] = 'iso_margin'
3130
3277
  response = await self.privatePostSpotV4QueryHistoryOrders(self.extend(request, params))
3131
3278
  else:
3132
3279
  response = await self.privateGetContractPrivateOrderHistory(self.extend(request, params))
@@ -677,6 +677,9 @@ class bybit(Exchange, ImplicitAPI):
677
677
  '110071': ExchangeError, # Sorry, we're revamping the Unified Margin Account! Currently, new upgrades are not supported. If you have any questions, please contact our 24/7 customer support.
678
678
  '110072': InvalidOrder, # OrderLinkedID is duplicate
679
679
  '110073': ExchangeError, # Set margin mode failed
680
+ '110092': InvalidOrder, # expect Rising, but trigger_price[XXXXX] <= current[XXXXX]
681
+ '110093': InvalidOrder, # expect Falling, but trigger_price[XXXXX] >= current[XXXXX]
682
+ '110094': InvalidOrder, # Order notional value below the lower limit
680
683
  '130006': InvalidOrder, # {"ret_code":130006,"ret_msg":"The number of contracts exceeds maximum limit allowed: too large","ext_code":"","ext_info":"","result":null,"time_now":"1658397095.099030","rate_limit_status":99,"rate_limit_reset_ms":1658397095097,"rate_limit":100}
681
684
  '130021': InsufficientFunds, # {"ret_code":130021,"ret_msg":"orderfix price failed for CannotAffordOrderCost.","ext_code":"","ext_info":"","result":null,"time_now":"1644588250.204878","rate_limit_status":98,"rate_limit_reset_ms":1644588250200,"rate_limit":100} | {"ret_code":130021,"ret_msg":"oc_diff[1707966351], new_oc[1707966351] with ob[....]+AB[....]","ext_code":"","ext_info":"","result":null,"time_now":"1658395300.872766","rate_limit_status":99,"rate_limit_reset_ms":1658395300855,"rate_limit":100} caused issues/9149#issuecomment-1146559498
682
685
  '130074': InvalidOrder, # {"ret_code":130074,"ret_msg":"expect Rising, but trigger_price[190000000] \u003c= current[211280000]??LastPrice","ext_code":"","ext_info":"","result":null,"time_now":"1655386638.067076","rate_limit_status":97,"rate_limit_reset_ms":1655386638065,"rate_limit":100}
@@ -1116,7 +1119,6 @@ class bybit(Exchange, ImplicitAPI):
1116
1119
  'limitPrice': True,
1117
1120
  },
1118
1121
  'timeInForce': {
1119
- 'GTC': True,
1120
1122
  'IOC': True,
1121
1123
  'FOK': True,
1122
1124
  'PO': True,
@@ -1178,7 +1180,6 @@ class bybit(Exchange, ImplicitAPI):
1178
1180
  'limitPrice': True,
1179
1181
  },
1180
1182
  'timeInForce': {
1181
- 'GTC': True,
1182
1183
  'IOC': True,
1183
1184
  'FOK': True,
1184
1185
  'PO': True,
@@ -89,6 +89,8 @@ class coinbase(Exchange, ImplicitAPI):
89
89
  'fetchDepositAddress': 'emulated',
90
90
  'fetchDepositAddresses': False,
91
91
  'fetchDepositAddressesByNetwork': True,
92
+ 'fetchDepositMethodId': True,
93
+ 'fetchDepositMethodIds': True,
92
94
  'fetchDeposits': True,
93
95
  'fetchDepositsWithdrawals': True,
94
96
  'fetchFundingHistory': False,
@@ -4103,6 +4105,90 @@ class coinbase(Exchange, ImplicitAPI):
4103
4105
  data = self.safe_dict(response, 'data', {})
4104
4106
  return self.parse_transaction(data)
4105
4107
 
4108
+ async def fetch_deposit_method_ids(self, params={}):
4109
+ """
4110
+ fetch the deposit id for a fiat currency associated with self account
4111
+
4112
+ https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpaymentmethods
4113
+
4114
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4115
+ :returns dict: an array of `deposit id structures <https://docs.ccxt.com/#/?id=deposit-id-structure>`
4116
+ """
4117
+ await self.load_markets()
4118
+ response = await self.v3PrivateGetBrokeragePaymentMethods(params)
4119
+ #
4120
+ # {
4121
+ # "payment_methods": [
4122
+ # {
4123
+ # "id": "21b39a5d-f7b46876fb2e",
4124
+ # "type": "COINBASE_FIAT_ACCOUNT",
4125
+ # "name": "CAD Wallet",
4126
+ # "currency": "CAD",
4127
+ # "verified": True,
4128
+ # "allow_buy": False,
4129
+ # "allow_sell": True,
4130
+ # "allow_deposit": False,
4131
+ # "allow_withdraw": False,
4132
+ # "created_at": "2023-06-29T19:58:46Z",
4133
+ # "updated_at": "2023-10-30T20:25:01Z"
4134
+ # }
4135
+ # ]
4136
+ # }
4137
+ #
4138
+ result = self.safe_list(response, 'payment_methods', [])
4139
+ return self.parse_deposit_method_ids(result)
4140
+
4141
+ async def fetch_deposit_method_id(self, id: str, params={}):
4142
+ """
4143
+ fetch the deposit id for a fiat currency associated with self account
4144
+
4145
+ https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpaymentmethod
4146
+
4147
+ :param str id: the deposit payment method id
4148
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4149
+ :returns dict: a `deposit id structure <https://docs.ccxt.com/#/?id=deposit-id-structure>`
4150
+ """
4151
+ await self.load_markets()
4152
+ request: dict = {
4153
+ 'payment_method_id': id,
4154
+ }
4155
+ response = await self.v3PrivateGetBrokeragePaymentMethodsPaymentMethodId(self.extend(request, params))
4156
+ #
4157
+ # {
4158
+ # "payment_method": {
4159
+ # "id": "21b39a5d-f7b46876fb2e",
4160
+ # "type": "COINBASE_FIAT_ACCOUNT",
4161
+ # "name": "CAD Wallet",
4162
+ # "currency": "CAD",
4163
+ # "verified": True,
4164
+ # "allow_buy": False,
4165
+ # "allow_sell": True,
4166
+ # "allow_deposit": False,
4167
+ # "allow_withdraw": False,
4168
+ # "created_at": "2023-06-29T19:58:46Z",
4169
+ # "updated_at": "2023-10-30T20:25:01Z"
4170
+ # }
4171
+ # }
4172
+ #
4173
+ result = self.safe_dict(response, 'payment_method', {})
4174
+ return self.parse_deposit_method_id(result)
4175
+
4176
+ def parse_deposit_method_ids(self, ids, params={}):
4177
+ result = []
4178
+ for i in range(0, len(ids)):
4179
+ id = self.extend(self.parse_deposit_method_id(ids[i]), params)
4180
+ result.append(id)
4181
+ return result
4182
+
4183
+ def parse_deposit_method_id(self, depositId):
4184
+ return {
4185
+ 'info': depositId,
4186
+ 'id': self.safe_string(depositId, 'id'),
4187
+ 'currency': self.safe_string(depositId, 'currency'),
4188
+ 'verified': self.safe_bool(depositId, 'verified'),
4189
+ 'tag': self.safe_string(depositId, 'name'),
4190
+ }
4191
+
4106
4192
  async def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
4107
4193
  """
4108
4194
  fetch a quote for converting from one currency to another
@@ -41,7 +41,7 @@ class gate(Exchange, ImplicitAPI):
41
41
  'certified': True,
42
42
  'pro': True,
43
43
  'urls': {
44
- 'logo': 'https://user-images.githubusercontent.com/1294454/31784029-0313c702-b509-11e7-9ccc-bc0da6a0e435.jpg',
44
+ 'logo': 'https://github.com/user-attachments/assets/64f988c5-07b6-4652-b5c1-679a6bf67c85',
45
45
  'doc': 'https://www.gate.io/docs/developers/apiv4/en/',
46
46
  'www': 'https://gate.io/',
47
47
  'api': {
@@ -226,6 +226,96 @@ class hyperliquid(Exchange, ImplicitAPI):
226
226
  'defaultSlippage': 0.05,
227
227
  'zeroAddress': '0x0000000000000000000000000000000000000000',
228
228
  },
229
+ 'features': {
230
+ 'default': {
231
+ 'sandbox': True,
232
+ 'createOrder': {
233
+ 'marginMode': False,
234
+ 'triggerPrice': False,
235
+ 'triggerPriceType': None,
236
+ 'triggerDirection': False,
237
+ 'stopLossPrice': False,
238
+ 'takeProfitPrice': False,
239
+ 'attachedStopLossTakeProfit': None,
240
+ 'timeInForce': {
241
+ 'GTC': True,
242
+ 'IOC': True,
243
+ 'FOK': False,
244
+ 'PO': True,
245
+ 'GTD': False,
246
+ },
247
+ 'hedged': False,
248
+ 'trailing': False,
249
+ },
250
+ 'createOrders': {
251
+ 'max': 1000,
252
+ },
253
+ 'fetchMyTrades': {
254
+ 'marginMode': False,
255
+ 'limit': 2000,
256
+ 'daysBack': None,
257
+ 'untilDays': None,
258
+ },
259
+ 'fetchOrder': {
260
+ 'marginMode': False,
261
+ 'trigger': False,
262
+ 'trailing': False,
263
+ },
264
+ 'fetchOpenOrders': {
265
+ 'marginMode': False,
266
+ 'limit': 2000,
267
+ 'trigger': False,
268
+ 'trailing': False,
269
+ },
270
+ 'fetchOrders': {
271
+ 'marginMode': False,
272
+ 'limit': 2000,
273
+ 'daysBack': None,
274
+ 'untilDays': None,
275
+ 'trigger': False,
276
+ 'trailing': False,
277
+ },
278
+ 'fetchClosedOrders': {
279
+ 'marginMode': False,
280
+ 'limit': 2000,
281
+ 'daysBackClosed': None,
282
+ 'daysBackCanceled': None,
283
+ 'untilDays': None,
284
+ 'trigger': False,
285
+ 'trailing': False,
286
+ },
287
+ 'fetchOHLCV': {
288
+ 'limit': 5000,
289
+ },
290
+ },
291
+ 'spot': {
292
+ 'extends': 'default',
293
+ },
294
+ 'forPerps': {
295
+ 'extends': 'default',
296
+ 'createOrder': {
297
+ 'stopLossPrice': True,
298
+ 'takeProfitPrice': True,
299
+ 'attachedStopLossTakeProfit': None, # todo, in two orders
300
+ },
301
+ },
302
+ 'swap': {
303
+ 'linear': {
304
+ 'extends': 'forPerps',
305
+ },
306
+ 'inverse': {
307
+ 'extends': 'forPerps',
308
+ },
309
+ },
310
+ 'future': {
311
+ 'linear': {
312
+ 'extends': 'forPerps',
313
+ },
314
+ 'inverse': {
315
+ 'extends': 'forPerps',
316
+ },
317
+ },
318
+ },
229
319
  })
230
320
 
231
321
  def set_sandbox_mode(self, enabled):
@@ -503,7 +593,7 @@ class hyperliquid(Exchange, ImplicitAPI):
503
593
  pricePrecision = self.calculate_price_precision(price, amountPrecision, 8)
504
594
  pricePrecisionStr = self.number_to_string(pricePrecision)
505
595
  # quotePrecision = self.parse_number(self.parse_precision(self.safe_string(innerQuoteTokenInfo, 'szDecimals')))
506
- baseId = self.number_to_string(i + 10000)
596
+ baseId = self.number_to_string(index + 10000)
507
597
  markets.append(self.safe_market_structure({
508
598
  'id': marketName,
509
599
  'symbol': symbol,
@@ -1192,7 +1282,7 @@ class hyperliquid(Exchange, ImplicitAPI):
1192
1282
  signature = self.sign_message(msg, self.privateKey)
1193
1283
  return signature
1194
1284
 
1195
- def build_transfer_sig(self, message):
1285
+ def build_usd_send_sig(self, message):
1196
1286
  messageTypes: dict = {
1197
1287
  'HyperliquidTransaction:UsdSend': [
1198
1288
  {'name': 'hyperliquidChain', 'type': 'string'},
@@ -1203,6 +1293,17 @@ class hyperliquid(Exchange, ImplicitAPI):
1203
1293
  }
1204
1294
  return self.sign_user_signed_action(messageTypes, message)
1205
1295
 
1296
+ def build_usd_class_send_sig(self, message):
1297
+ messageTypes: dict = {
1298
+ 'HyperliquidTransaction:UsdClassTransfer': [
1299
+ {'name': 'hyperliquidChain', 'type': 'string'},
1300
+ {'name': 'amount', 'type': 'string'},
1301
+ {'name': 'toPerp', 'type': 'bool'},
1302
+ {'name': 'nonce', 'type': 'uint64'},
1303
+ ],
1304
+ }
1305
+ return self.sign_user_signed_action(messageTypes, message)
1306
+
1206
1307
  def build_withdraw_sig(self, message):
1207
1308
  messageTypes: dict = {
1208
1309
  'HyperliquidTransaction:Withdraw': [
@@ -2590,25 +2691,34 @@ class hyperliquid(Exchange, ImplicitAPI):
2590
2691
  # handle swap <> spot account transfer
2591
2692
  if not self.in_array(toAccount, ['spot', 'swap', 'perp']):
2592
2693
  raise NotSupported(self.id + 'transfer() only support spot <> swap transfer')
2694
+ strAmount = self.number_to_string(amount)
2593
2695
  vaultAddress = self.format_vault_address(self.safe_string(params, 'vaultAddress'))
2594
2696
  params = self.omit(params, 'vaultAddress')
2697
+ if vaultAddress is not None:
2698
+ strAmount = strAmount + ' subaccount:' + vaultAddress
2595
2699
  toPerp = (toAccount == 'perp') or (toAccount == 'swap')
2596
- action: dict = {
2597
- 'type': 'spotUser',
2598
- 'classTransfer': {
2599
- 'usdc': amount,
2700
+ transferPayload: dict = {
2701
+ 'hyperliquidChain': 'Testnet' if isSandboxMode else 'Mainnet',
2702
+ 'amount': strAmount,
2703
+ 'toPerp': toPerp,
2704
+ 'nonce': nonce,
2705
+ }
2706
+ transferSig = self.build_usd_class_send_sig(transferPayload)
2707
+ transferRequest: dict = {
2708
+ 'action': {
2709
+ 'hyperliquidChain': transferPayload['hyperliquidChain'],
2710
+ 'signatureChainId': '0x66eee',
2711
+ 'type': 'usdClassTransfer',
2712
+ 'amount': strAmount,
2600
2713
  'toPerp': toPerp,
2714
+ 'nonce': nonce,
2601
2715
  },
2602
- }
2603
- signature = self.sign_l1_action(action, nonce, vaultAddress)
2604
- innerRequest: dict = {
2605
- 'action': action,
2606
2716
  'nonce': nonce,
2607
- 'signature': signature,
2717
+ 'signature': transferSig,
2608
2718
  }
2609
2719
  if vaultAddress is not None:
2610
- innerRequest['vaultAddress'] = vaultAddress
2611
- transferResponse = await self.privatePostExchange(innerRequest)
2720
+ transferRequest['vaultAddress'] = vaultAddress
2721
+ transferResponse = await self.privatePostExchange(transferRequest)
2612
2722
  return transferResponse
2613
2723
  # handle sub-account/different account transfer
2614
2724
  self.check_address(toAccount)
@@ -2622,7 +2732,7 @@ class hyperliquid(Exchange, ImplicitAPI):
2622
2732
  'amount': self.number_to_string(amount),
2623
2733
  'time': nonce,
2624
2734
  }
2625
- sig = self.build_transfer_sig(payload)
2735
+ sig = self.build_usd_send_sig(payload)
2626
2736
  request: dict = {
2627
2737
  'action': {
2628
2738
  'hyperliquidChain': payload['hyperliquidChain'],