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
ccxt/bitget.py CHANGED
@@ -1473,8 +1473,8 @@ class bitget(Exchange, ImplicitAPI):
1473
1473
  'index': False, # not on spot
1474
1474
  },
1475
1475
  'triggerDirection': False,
1476
- 'stopLossPrice': True, # but not yet implemented in spot
1477
- 'takeProfitPrice': True, # but not yet implemented in spot
1476
+ 'stopLossPrice': True, # todo: not yet implemented in spot
1477
+ 'takeProfitPrice': True, # todo: not yet implemented in spot
1478
1478
  'attachedStopLossTakeProfit': {
1479
1479
  'triggerPriceType': {
1480
1480
  'last': False,
@@ -1484,7 +1484,6 @@ class bitget(Exchange, ImplicitAPI):
1484
1484
  'limitPrice': True,
1485
1485
  },
1486
1486
  'timeInForce': {
1487
- 'GTC': True,
1488
1487
  'IOC': True,
1489
1488
  'FOK': True,
1490
1489
  'PO': True,
@@ -1555,7 +1554,6 @@ class bitget(Exchange, ImplicitAPI):
1555
1554
  'limitPrice': False,
1556
1555
  },
1557
1556
  'timeInForce': {
1558
- 'GTC': True,
1559
1557
  'IOC': True,
1560
1558
  'FOK': True,
1561
1559
  'PO': True,
ccxt/bithumb.py CHANGED
@@ -1027,7 +1027,7 @@ class bithumb(Exchange, ImplicitAPI):
1027
1027
  'address': address,
1028
1028
  'currency': currency['id'],
1029
1029
  }
1030
- if code == 'XRP' or code == 'XMR' or code == 'EOS' or code == 'STEEM':
1030
+ if code == 'XRP' or code == 'XMR' or code == 'EOS' or code == 'STEEM' or code == 'TON':
1031
1031
  destination = self.safe_string(params, 'destination')
1032
1032
  if (tag is None) and (destination is None):
1033
1033
  raise ArgumentsRequired(self.id + ' ' + code + ' withdraw() requires a tag argument or an extra destination param')
ccxt/bitmart.py CHANGED
@@ -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
  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 = 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 = 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 = self.privatePostSpotV4QueryHistoryOrders(self.extend(request, params))
3131
3278
  else:
3132
3279
  response = self.privateGetContractPrivateOrderHistory(self.extend(request, params))
ccxt/bybit.py CHANGED
@@ -676,6 +676,9 @@ class bybit(Exchange, ImplicitAPI):
676
676
  '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.
677
677
  '110072': InvalidOrder, # OrderLinkedID is duplicate
678
678
  '110073': ExchangeError, # Set margin mode failed
679
+ '110092': InvalidOrder, # expect Rising, but trigger_price[XXXXX] <= current[XXXXX]
680
+ '110093': InvalidOrder, # expect Falling, but trigger_price[XXXXX] >= current[XXXXX]
681
+ '110094': InvalidOrder, # Order notional value below the lower limit
679
682
  '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}
680
683
  '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
681
684
  '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}
@@ -1115,7 +1118,6 @@ class bybit(Exchange, ImplicitAPI):
1115
1118
  'limitPrice': True,
1116
1119
  },
1117
1120
  'timeInForce': {
1118
- 'GTC': True,
1119
1121
  'IOC': True,
1120
1122
  'FOK': True,
1121
1123
  'PO': True,
@@ -1177,7 +1179,6 @@ class bybit(Exchange, ImplicitAPI):
1177
1179
  'limitPrice': True,
1178
1180
  },
1179
1181
  'timeInForce': {
1180
- 'GTC': True,
1181
1182
  'IOC': True,
1182
1183
  'FOK': True,
1183
1184
  'PO': True,
ccxt/coinbase.py CHANGED
@@ -88,6 +88,8 @@ class coinbase(Exchange, ImplicitAPI):
88
88
  'fetchDepositAddress': 'emulated',
89
89
  'fetchDepositAddresses': False,
90
90
  'fetchDepositAddressesByNetwork': True,
91
+ 'fetchDepositMethodId': True,
92
+ 'fetchDepositMethodIds': True,
91
93
  'fetchDeposits': True,
92
94
  'fetchDepositsWithdrawals': True,
93
95
  'fetchFundingHistory': False,
@@ -4102,6 +4104,90 @@ class coinbase(Exchange, ImplicitAPI):
4102
4104
  data = self.safe_dict(response, 'data', {})
4103
4105
  return self.parse_transaction(data)
4104
4106
 
4107
+ def fetch_deposit_method_ids(self, params={}):
4108
+ """
4109
+ fetch the deposit id for a fiat currency associated with self account
4110
+
4111
+ https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpaymentmethods
4112
+
4113
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4114
+ :returns dict: an array of `deposit id structures <https://docs.ccxt.com/#/?id=deposit-id-structure>`
4115
+ """
4116
+ self.load_markets()
4117
+ response = self.v3PrivateGetBrokeragePaymentMethods(params)
4118
+ #
4119
+ # {
4120
+ # "payment_methods": [
4121
+ # {
4122
+ # "id": "21b39a5d-f7b46876fb2e",
4123
+ # "type": "COINBASE_FIAT_ACCOUNT",
4124
+ # "name": "CAD Wallet",
4125
+ # "currency": "CAD",
4126
+ # "verified": True,
4127
+ # "allow_buy": False,
4128
+ # "allow_sell": True,
4129
+ # "allow_deposit": False,
4130
+ # "allow_withdraw": False,
4131
+ # "created_at": "2023-06-29T19:58:46Z",
4132
+ # "updated_at": "2023-10-30T20:25:01Z"
4133
+ # }
4134
+ # ]
4135
+ # }
4136
+ #
4137
+ result = self.safe_list(response, 'payment_methods', [])
4138
+ return self.parse_deposit_method_ids(result)
4139
+
4140
+ def fetch_deposit_method_id(self, id: str, params={}):
4141
+ """
4142
+ fetch the deposit id for a fiat currency associated with self account
4143
+
4144
+ https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpaymentmethod
4145
+
4146
+ :param str id: the deposit payment method id
4147
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4148
+ :returns dict: a `deposit id structure <https://docs.ccxt.com/#/?id=deposit-id-structure>`
4149
+ """
4150
+ self.load_markets()
4151
+ request: dict = {
4152
+ 'payment_method_id': id,
4153
+ }
4154
+ response = self.v3PrivateGetBrokeragePaymentMethodsPaymentMethodId(self.extend(request, params))
4155
+ #
4156
+ # {
4157
+ # "payment_method": {
4158
+ # "id": "21b39a5d-f7b46876fb2e",
4159
+ # "type": "COINBASE_FIAT_ACCOUNT",
4160
+ # "name": "CAD Wallet",
4161
+ # "currency": "CAD",
4162
+ # "verified": True,
4163
+ # "allow_buy": False,
4164
+ # "allow_sell": True,
4165
+ # "allow_deposit": False,
4166
+ # "allow_withdraw": False,
4167
+ # "created_at": "2023-06-29T19:58:46Z",
4168
+ # "updated_at": "2023-10-30T20:25:01Z"
4169
+ # }
4170
+ # }
4171
+ #
4172
+ result = self.safe_dict(response, 'payment_method', {})
4173
+ return self.parse_deposit_method_id(result)
4174
+
4175
+ def parse_deposit_method_ids(self, ids, params={}):
4176
+ result = []
4177
+ for i in range(0, len(ids)):
4178
+ id = self.extend(self.parse_deposit_method_id(ids[i]), params)
4179
+ result.append(id)
4180
+ return result
4181
+
4182
+ def parse_deposit_method_id(self, depositId):
4183
+ return {
4184
+ 'info': depositId,
4185
+ 'id': self.safe_string(depositId, 'id'),
4186
+ 'currency': self.safe_string(depositId, 'currency'),
4187
+ 'verified': self.safe_bool(depositId, 'verified'),
4188
+ 'tag': self.safe_string(depositId, 'name'),
4189
+ }
4190
+
4105
4191
  def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
4106
4192
  """
4107
4193
  fetch a quote for converting from one currency to another
ccxt/gate.py CHANGED
@@ -40,7 +40,7 @@ class gate(Exchange, ImplicitAPI):
40
40
  'certified': True,
41
41
  'pro': True,
42
42
  'urls': {
43
- 'logo': 'https://user-images.githubusercontent.com/1294454/31784029-0313c702-b509-11e7-9ccc-bc0da6a0e435.jpg',
43
+ 'logo': 'https://github.com/user-attachments/assets/64f988c5-07b6-4652-b5c1-679a6bf67c85',
44
44
  'doc': 'https://www.gate.io/docs/developers/apiv4/en/',
45
45
  'www': 'https://gate.io/',
46
46
  'api': {
ccxt/hyperliquid.py CHANGED
@@ -225,6 +225,96 @@ class hyperliquid(Exchange, ImplicitAPI):
225
225
  'defaultSlippage': 0.05,
226
226
  'zeroAddress': '0x0000000000000000000000000000000000000000',
227
227
  },
228
+ 'features': {
229
+ 'default': {
230
+ 'sandbox': True,
231
+ 'createOrder': {
232
+ 'marginMode': False,
233
+ 'triggerPrice': False,
234
+ 'triggerPriceType': None,
235
+ 'triggerDirection': False,
236
+ 'stopLossPrice': False,
237
+ 'takeProfitPrice': False,
238
+ 'attachedStopLossTakeProfit': None,
239
+ 'timeInForce': {
240
+ 'GTC': True,
241
+ 'IOC': True,
242
+ 'FOK': False,
243
+ 'PO': True,
244
+ 'GTD': False,
245
+ },
246
+ 'hedged': False,
247
+ 'trailing': False,
248
+ },
249
+ 'createOrders': {
250
+ 'max': 1000,
251
+ },
252
+ 'fetchMyTrades': {
253
+ 'marginMode': False,
254
+ 'limit': 2000,
255
+ 'daysBack': None,
256
+ 'untilDays': None,
257
+ },
258
+ 'fetchOrder': {
259
+ 'marginMode': False,
260
+ 'trigger': False,
261
+ 'trailing': False,
262
+ },
263
+ 'fetchOpenOrders': {
264
+ 'marginMode': False,
265
+ 'limit': 2000,
266
+ 'trigger': False,
267
+ 'trailing': False,
268
+ },
269
+ 'fetchOrders': {
270
+ 'marginMode': False,
271
+ 'limit': 2000,
272
+ 'daysBack': None,
273
+ 'untilDays': None,
274
+ 'trigger': False,
275
+ 'trailing': False,
276
+ },
277
+ 'fetchClosedOrders': {
278
+ 'marginMode': False,
279
+ 'limit': 2000,
280
+ 'daysBackClosed': None,
281
+ 'daysBackCanceled': None,
282
+ 'untilDays': None,
283
+ 'trigger': False,
284
+ 'trailing': False,
285
+ },
286
+ 'fetchOHLCV': {
287
+ 'limit': 5000,
288
+ },
289
+ },
290
+ 'spot': {
291
+ 'extends': 'default',
292
+ },
293
+ 'forPerps': {
294
+ 'extends': 'default',
295
+ 'createOrder': {
296
+ 'stopLossPrice': True,
297
+ 'takeProfitPrice': True,
298
+ 'attachedStopLossTakeProfit': None, # todo, in two orders
299
+ },
300
+ },
301
+ 'swap': {
302
+ 'linear': {
303
+ 'extends': 'forPerps',
304
+ },
305
+ 'inverse': {
306
+ 'extends': 'forPerps',
307
+ },
308
+ },
309
+ 'future': {
310
+ 'linear': {
311
+ 'extends': 'forPerps',
312
+ },
313
+ 'inverse': {
314
+ 'extends': 'forPerps',
315
+ },
316
+ },
317
+ },
228
318
  })
229
319
 
230
320
  def set_sandbox_mode(self, enabled):
@@ -502,7 +592,7 @@ class hyperliquid(Exchange, ImplicitAPI):
502
592
  pricePrecision = self.calculate_price_precision(price, amountPrecision, 8)
503
593
  pricePrecisionStr = self.number_to_string(pricePrecision)
504
594
  # quotePrecision = self.parse_number(self.parse_precision(self.safe_string(innerQuoteTokenInfo, 'szDecimals')))
505
- baseId = self.number_to_string(i + 10000)
595
+ baseId = self.number_to_string(index + 10000)
506
596
  markets.append(self.safe_market_structure({
507
597
  'id': marketName,
508
598
  'symbol': symbol,
@@ -1191,7 +1281,7 @@ class hyperliquid(Exchange, ImplicitAPI):
1191
1281
  signature = self.sign_message(msg, self.privateKey)
1192
1282
  return signature
1193
1283
 
1194
- def build_transfer_sig(self, message):
1284
+ def build_usd_send_sig(self, message):
1195
1285
  messageTypes: dict = {
1196
1286
  'HyperliquidTransaction:UsdSend': [
1197
1287
  {'name': 'hyperliquidChain', 'type': 'string'},
@@ -1202,6 +1292,17 @@ class hyperliquid(Exchange, ImplicitAPI):
1202
1292
  }
1203
1293
  return self.sign_user_signed_action(messageTypes, message)
1204
1294
 
1295
+ def build_usd_class_send_sig(self, message):
1296
+ messageTypes: dict = {
1297
+ 'HyperliquidTransaction:UsdClassTransfer': [
1298
+ {'name': 'hyperliquidChain', 'type': 'string'},
1299
+ {'name': 'amount', 'type': 'string'},
1300
+ {'name': 'toPerp', 'type': 'bool'},
1301
+ {'name': 'nonce', 'type': 'uint64'},
1302
+ ],
1303
+ }
1304
+ return self.sign_user_signed_action(messageTypes, message)
1305
+
1205
1306
  def build_withdraw_sig(self, message):
1206
1307
  messageTypes: dict = {
1207
1308
  'HyperliquidTransaction:Withdraw': [
@@ -2589,25 +2690,34 @@ class hyperliquid(Exchange, ImplicitAPI):
2589
2690
  # handle swap <> spot account transfer
2590
2691
  if not self.in_array(toAccount, ['spot', 'swap', 'perp']):
2591
2692
  raise NotSupported(self.id + 'transfer() only support spot <> swap transfer')
2693
+ strAmount = self.number_to_string(amount)
2592
2694
  vaultAddress = self.format_vault_address(self.safe_string(params, 'vaultAddress'))
2593
2695
  params = self.omit(params, 'vaultAddress')
2696
+ if vaultAddress is not None:
2697
+ strAmount = strAmount + ' subaccount:' + vaultAddress
2594
2698
  toPerp = (toAccount == 'perp') or (toAccount == 'swap')
2595
- action: dict = {
2596
- 'type': 'spotUser',
2597
- 'classTransfer': {
2598
- 'usdc': amount,
2699
+ transferPayload: dict = {
2700
+ 'hyperliquidChain': 'Testnet' if isSandboxMode else 'Mainnet',
2701
+ 'amount': strAmount,
2702
+ 'toPerp': toPerp,
2703
+ 'nonce': nonce,
2704
+ }
2705
+ transferSig = self.build_usd_class_send_sig(transferPayload)
2706
+ transferRequest: dict = {
2707
+ 'action': {
2708
+ 'hyperliquidChain': transferPayload['hyperliquidChain'],
2709
+ 'signatureChainId': '0x66eee',
2710
+ 'type': 'usdClassTransfer',
2711
+ 'amount': strAmount,
2599
2712
  'toPerp': toPerp,
2713
+ 'nonce': nonce,
2600
2714
  },
2601
- }
2602
- signature = self.sign_l1_action(action, nonce, vaultAddress)
2603
- innerRequest: dict = {
2604
- 'action': action,
2605
2715
  'nonce': nonce,
2606
- 'signature': signature,
2716
+ 'signature': transferSig,
2607
2717
  }
2608
2718
  if vaultAddress is not None:
2609
- innerRequest['vaultAddress'] = vaultAddress
2610
- transferResponse = self.privatePostExchange(innerRequest)
2719
+ transferRequest['vaultAddress'] = vaultAddress
2720
+ transferResponse = self.privatePostExchange(transferRequest)
2611
2721
  return transferResponse
2612
2722
  # handle sub-account/different account transfer
2613
2723
  self.check_address(toAccount)
@@ -2621,7 +2731,7 @@ class hyperliquid(Exchange, ImplicitAPI):
2621
2731
  'amount': self.number_to_string(amount),
2622
2732
  'time': nonce,
2623
2733
  }
2624
- sig = self.build_transfer_sig(payload)
2734
+ sig = self.build_usd_send_sig(payload)
2625
2735
  request: dict = {
2626
2736
  'action': {
2627
2737
  'hyperliquidChain': payload['hyperliquidChain'],