ccxt 4.2.86__py2.py3-none-any.whl → 4.2.87__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 (78) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/ascendex.py +16 -6
  3. ccxt/async_support/__init__.py +1 -1
  4. ccxt/async_support/ascendex.py +16 -6
  5. ccxt/async_support/base/exchange.py +1 -1
  6. ccxt/async_support/binance.py +18 -5
  7. ccxt/async_support/bingx.py +39 -3
  8. ccxt/async_support/bitfinex.py +2 -0
  9. ccxt/async_support/bitfinex2.py +18 -4
  10. ccxt/async_support/bitflyer.py +18 -0
  11. ccxt/async_support/bitget.py +20 -6
  12. ccxt/async_support/bitopro.py +2 -0
  13. ccxt/async_support/bitrue.py +16 -8
  14. ccxt/async_support/bitvavo.py +2 -0
  15. ccxt/async_support/btcmarkets.py +1 -1
  16. ccxt/async_support/btcturk.py +2 -1
  17. ccxt/async_support/coinex.py +182 -58
  18. ccxt/async_support/currencycom.py +1 -1
  19. ccxt/async_support/delta.py +8 -6
  20. ccxt/async_support/digifinex.py +9 -7
  21. ccxt/async_support/exmo.py +15 -15
  22. ccxt/async_support/gate.py +9 -6
  23. ccxt/async_support/hitbtc.py +31 -7
  24. ccxt/async_support/htx.py +2 -2
  25. ccxt/async_support/huobijp.py +1 -1
  26. ccxt/async_support/hyperliquid.py +242 -16
  27. ccxt/async_support/idex.py +1 -1
  28. ccxt/async_support/krakenfutures.py +2 -4
  29. ccxt/async_support/kucoinfutures.py +2 -2
  30. ccxt/async_support/lbank.py +2 -0
  31. ccxt/async_support/mexc.py +3 -3
  32. ccxt/async_support/oceanex.py +1 -1
  33. ccxt/async_support/okx.py +29 -15
  34. ccxt/async_support/phemex.py +6 -4
  35. ccxt/async_support/wazirx.py +1 -1
  36. ccxt/async_support/zonda.py +2 -0
  37. ccxt/base/exchange.py +1 -1
  38. ccxt/base/types.py +12 -0
  39. ccxt/binance.py +18 -5
  40. ccxt/bingx.py +39 -3
  41. ccxt/bitfinex.py +2 -0
  42. ccxt/bitfinex2.py +18 -4
  43. ccxt/bitflyer.py +18 -0
  44. ccxt/bitget.py +20 -6
  45. ccxt/bitopro.py +2 -0
  46. ccxt/bitrue.py +16 -8
  47. ccxt/bitvavo.py +2 -0
  48. ccxt/btcmarkets.py +1 -1
  49. ccxt/btcturk.py +2 -1
  50. ccxt/coinex.py +182 -58
  51. ccxt/currencycom.py +1 -1
  52. ccxt/delta.py +8 -6
  53. ccxt/digifinex.py +9 -7
  54. ccxt/exmo.py +15 -15
  55. ccxt/gate.py +9 -6
  56. ccxt/hitbtc.py +31 -7
  57. ccxt/htx.py +2 -2
  58. ccxt/huobijp.py +1 -1
  59. ccxt/hyperliquid.py +241 -16
  60. ccxt/idex.py +1 -1
  61. ccxt/krakenfutures.py +2 -4
  62. ccxt/kucoinfutures.py +2 -2
  63. ccxt/lbank.py +2 -0
  64. ccxt/mexc.py +3 -3
  65. ccxt/oceanex.py +1 -1
  66. ccxt/okx.py +29 -15
  67. ccxt/phemex.py +6 -4
  68. ccxt/pro/__init__.py +1 -1
  69. ccxt/pro/kucoin.py +10 -6
  70. ccxt/test/base/test_last_price.py +0 -1
  71. ccxt/test/base/test_shared_methods.py +1 -2
  72. ccxt/test/base/test_status.py +1 -1
  73. ccxt/wazirx.py +1 -1
  74. ccxt/zonda.py +2 -0
  75. {ccxt-4.2.86.dist-info → ccxt-4.2.87.dist-info}/METADATA +4 -4
  76. {ccxt-4.2.86.dist-info → ccxt-4.2.87.dist-info}/RECORD +78 -78
  77. {ccxt-4.2.86.dist-info → ccxt-4.2.87.dist-info}/WHEEL +0 -0
  78. {ccxt-4.2.86.dist-info → ccxt-4.2.87.dist-info}/top_level.txt +0 -0
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.hitbtc import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currency, Int, Leverage, MarginMode, MarginModes, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
9
+ from ccxt.base.types import Balances, Currency, Int, Leverage, MarginMode, MarginModes, MarginModification, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import PermissionDenied
@@ -1658,7 +1658,7 @@ class hitbtc(Exchange, ImplicitAPI):
1658
1658
  request['from'] = self.iso8601(since)
1659
1659
  request, params = self.handle_until_option('till', request, params)
1660
1660
  if limit is not None:
1661
- request['limit'] = limit
1661
+ request['limit'] = min(limit, 1000)
1662
1662
  price = self.safe_string(params, 'price')
1663
1663
  params = self.omit(params, 'price')
1664
1664
  response = None
@@ -2999,7 +2999,7 @@ class hitbtc(Exchange, ImplicitAPI):
2999
2999
  'previousFundingDatetime': None,
3000
3000
  }
3001
3001
 
3002
- async def modify_margin_helper(self, symbol: str, amount, type, params={}):
3002
+ async def modify_margin_helper(self, symbol: str, amount, type, params={}) -> MarginModification:
3003
3003
  await self.load_markets()
3004
3004
  market = self.market(symbol)
3005
3005
  leverage = self.safe_string(params, 'leverage')
@@ -3052,19 +3052,43 @@ class hitbtc(Exchange, ImplicitAPI):
3052
3052
  'type': type,
3053
3053
  })
3054
3054
 
3055
- def parse_margin_modification(self, data, market: Market = None):
3055
+ def parse_margin_modification(self, data, market: Market = None) -> MarginModification:
3056
+ #
3057
+ # addMargin/reduceMargin
3058
+ #
3059
+ # {
3060
+ # "symbol": "BTCUSDT_PERP",
3061
+ # "type": "isolated",
3062
+ # "leverage": "8.00",
3063
+ # "created_at": "2022-03-30T23:34:27.161Z",
3064
+ # "updated_at": "2022-03-30T23:34:27.161Z",
3065
+ # "currencies": [
3066
+ # {
3067
+ # "code": "USDT",
3068
+ # "margin_balance": "7.000000000000",
3069
+ # "reserved_orders": "0",
3070
+ # "reserved_positions": "0"
3071
+ # }
3072
+ # ],
3073
+ # "positions": null
3074
+ # }
3075
+ #
3056
3076
  currencies = self.safe_value(data, 'currencies', [])
3057
3077
  currencyInfo = self.safe_value(currencies, 0)
3078
+ datetime = self.safe_string(data, 'updated_at')
3058
3079
  return {
3059
3080
  'info': data,
3081
+ 'symbol': market['symbol'],
3060
3082
  'type': None,
3061
3083
  'amount': None,
3084
+ 'total': None,
3062
3085
  'code': self.safe_string(currencyInfo, 'code'),
3063
- 'symbol': market['symbol'],
3064
3086
  'status': None,
3087
+ 'timestamp': self.parse8601(datetime),
3088
+ 'datetime': datetime,
3065
3089
  }
3066
3090
 
3067
- async def reduce_margin(self, symbol: str, amount, params={}):
3091
+ async def reduce_margin(self, symbol: str, amount, params={}) -> MarginModification:
3068
3092
  """
3069
3093
  remove margin from a position
3070
3094
  :see: https://api.hitbtc.com/#create-update-margin-account-2
@@ -3080,7 +3104,7 @@ class hitbtc(Exchange, ImplicitAPI):
3080
3104
  raise BadRequest(self.id + ' reduceMargin() on hitbtc requires the amount to be 0 and that will remove the entire margin amount')
3081
3105
  return await self.modify_margin_helper(symbol, amount, 'reduce', params)
3082
3106
 
3083
- async def add_margin(self, symbol: str, amount, params={}):
3107
+ async def add_margin(self, symbol: str, amount, params={}) -> MarginModification:
3084
3108
  """
3085
3109
  add margin
3086
3110
  :see: https://api.hitbtc.com/#create-update-margin-account-2
ccxt/async_support/htx.py CHANGED
@@ -2834,7 +2834,7 @@ class htx(Exchange, ImplicitAPI):
2834
2834
  untilSeconds = self.parse_to_int(until / 1000) if (until is not None) else None
2835
2835
  if market['contract']:
2836
2836
  if limit is not None:
2837
- request['size'] = limit # when using limit: from & to are ignored
2837
+ request['size'] = min(limit, 2000) # when using limit: from & to are ignored
2838
2838
  # https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-kline-data
2839
2839
  else:
2840
2840
  limit = 2000 # only used for from/to calculation
@@ -2898,7 +2898,7 @@ class htx(Exchange, ImplicitAPI):
2898
2898
  useHistorical, params = self.handle_option_and_params(params, 'fetchOHLCV', 'useHistoricalEndpointForSpot', True)
2899
2899
  if not useHistorical:
2900
2900
  if limit is not None:
2901
- request['size'] = min(2000, limit) # max 2000
2901
+ request['size'] = min(limit, 2000) # max 2000
2902
2902
  response = await self.spotPublicGetMarketHistoryKline(self.extend(request, params))
2903
2903
  else:
2904
2904
  # "from & to" only available for the self endpoint
@@ -927,7 +927,7 @@ class huobijp(Exchange, ImplicitAPI):
927
927
  'period': self.safe_string(self.timeframes, timeframe, timeframe),
928
928
  }
929
929
  if limit is not None:
930
- request['size'] = limit
930
+ request['size'] = min(limit, 2000)
931
931
  response = await self.marketGetHistoryKline(self.extend(request, params))
932
932
  #
933
933
  # {
@@ -5,7 +5,8 @@
5
5
 
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.hyperliquid import ImplicitAPI
8
- from ccxt.base.types import Balances, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Trade, TransferEntry
8
+ import asyncio
9
+ from ccxt.base.types import Balances, Int, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Trade, TransferEntry
9
10
  from typing import List
10
11
  from ccxt.base.errors import ExchangeError
11
12
  from ccxt.base.errors import ArgumentsRequired
@@ -32,7 +33,7 @@ class hyperliquid(Exchange, ImplicitAPI):
32
33
  'pro': True,
33
34
  'has': {
34
35
  'CORS': None,
35
- 'spot': False,
36
+ 'spot': True,
36
37
  'margin': False,
37
38
  'swap': True,
38
39
  'future': True,
@@ -165,6 +166,10 @@ class hyperliquid(Exchange, ImplicitAPI):
165
166
  'taker': self.parse_number('0.00035'),
166
167
  'maker': self.parse_number('0.0001'),
167
168
  },
169
+ 'spot': {
170
+ 'taker': self.parse_number('0.00035'),
171
+ 'maker': self.parse_number('0.0001'),
172
+ },
168
173
  },
169
174
  'requiredCredentials': {
170
175
  'apiKey': False,
@@ -192,6 +197,7 @@ class hyperliquid(Exchange, ImplicitAPI):
192
197
  'commonCurrencies': {
193
198
  },
194
199
  'options': {
200
+ 'defaultType': 'swap',
195
201
  'sandboxMode': False,
196
202
  'defaultSlippage': 0.05,
197
203
  'zeroAddress': '0x0000000000000000000000000000000000000000',
@@ -257,6 +263,22 @@ class hyperliquid(Exchange, ImplicitAPI):
257
263
  :param dict [params]: extra parameters specific to the exchange API endpoint
258
264
  :returns dict[]: an array of objects representing market data
259
265
  """
266
+ rawPromises = [
267
+ self.fetch_swap_markets(params),
268
+ self.fetch_spot_markets(params),
269
+ ]
270
+ promises = await asyncio.gather(*rawPromises)
271
+ swapMarkets = promises[0]
272
+ spotMarkets = promises[1]
273
+ return self.array_concat(swapMarkets, spotMarkets)
274
+
275
+ async def fetch_swap_markets(self, params={}) -> List[Market]:
276
+ """
277
+ retrieves data on all swap markets for hyperliquid
278
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-asset-contexts-includes-mark-price-current-funding-open-interest-etc
279
+ :param dict [params]: extra parameters specific to the exchange API endpoint
280
+ :returns dict[]: an array of objects representing market data
281
+ """
260
282
  request = {
261
283
  'type': 'metaAndAssetCtxs',
262
284
  }
@@ -304,6 +326,129 @@ class hyperliquid(Exchange, ImplicitAPI):
304
326
  result.append(data)
305
327
  return self.parse_markets(result)
306
328
 
329
+ async def fetch_spot_markets(self, params={}) -> List[Market]:
330
+ """
331
+ retrieves data on all spot markets for hyperliquid
332
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-asset-contexts-includes-mark-price-current-funding-open-interest-etc
333
+ :param dict [params]: extra parameters specific to the exchange API endpoint
334
+ :returns dict[]: an array of objects representing market data
335
+ """
336
+ request = {
337
+ 'type': 'spotMetaAndAssetCtxs',
338
+ }
339
+ response = await self.publicPostInfo(self.extend(request, params))
340
+ #
341
+ # [
342
+ # {
343
+ # 'tokens': [
344
+ # {
345
+ # 'name': 'USDC',
346
+ # 'szDecimals': '8',
347
+ # 'weiDecimals': '8',
348
+ # },
349
+ # {
350
+ # 'name': 'PURR',
351
+ # 'szDecimals': '0',
352
+ # 'weiDecimals': '5',
353
+ # },
354
+ # ],
355
+ # 'universe': [
356
+ # {
357
+ # 'name': 'PURR/USDC',
358
+ # 'tokens': [
359
+ # 1,
360
+ # 0,
361
+ # ],
362
+ # },
363
+ # ],
364
+ # },
365
+ # [
366
+ # {
367
+ # 'dayNtlVlm': '264250385.14640012',
368
+ # 'markPx': '0.018314',
369
+ # 'midPx': '0.0182235',
370
+ # 'prevDayPx': '0.017427',
371
+ # },
372
+ # ],
373
+ # ]
374
+ #
375
+ first = self.safe_dict(response, 0, {})
376
+ meta = self.safe_list(first, 'universe', [])
377
+ tokens = self.safe_list(first, 'tokens', [])
378
+ markets = []
379
+ for i in range(0, len(meta)):
380
+ market = self.safe_dict(meta, i, {})
381
+ marketName = self.safe_string(market, 'name')
382
+ marketParts = marketName.split('/')
383
+ baseName = self.safe_string(marketParts, 0)
384
+ quoteId = self.safe_string(marketParts, 1)
385
+ base = self.safe_currency_code(baseName)
386
+ quote = self.safe_currency_code(quoteId)
387
+ symbol = base + '/' + quote
388
+ fees = self.safe_dict(self.fees, 'spot', {})
389
+ taker = self.safe_number(fees, 'taker')
390
+ maker = self.safe_number(fees, 'maker')
391
+ tokensPos = self.safe_list(market, 'tokens', [])
392
+ baseTokenPos = self.safe_integer(tokensPos, 0)
393
+ quoteTokenPos = self.safe_integer(tokensPos, 1)
394
+ baseTokenInfo = self.safe_dict(tokens, baseTokenPos, {})
395
+ quoteTokenInfo = self.safe_dict(tokens, quoteTokenPos, {})
396
+ baseDecimals = self.safe_string(baseTokenInfo, 'szDecimals')
397
+ quoteDecimals = self.safe_integer(quoteTokenInfo, 'szDecimals')
398
+ baseId = self.number_to_string(i + 10000)
399
+ markets.append(self.safe_market_structure({
400
+ 'id': baseId,
401
+ 'symbol': symbol,
402
+ 'base': base,
403
+ 'quote': quote,
404
+ 'settle': None,
405
+ 'baseId': baseId,
406
+ 'quoteId': quoteId,
407
+ 'settleId': None,
408
+ 'type': 'spot',
409
+ 'spot': True,
410
+ 'margin': None,
411
+ 'swap': False,
412
+ 'future': False,
413
+ 'option': False,
414
+ 'active': True,
415
+ 'contract': False,
416
+ 'linear': True,
417
+ 'inverse': False,
418
+ 'taker': taker,
419
+ 'maker': maker,
420
+ 'contractSize': None,
421
+ 'expiry': None,
422
+ 'expiryDatetime': None,
423
+ 'strike': None,
424
+ 'optionType': None,
425
+ 'precision': {
426
+ 'amount': self.parse_number(self.parse_precision(baseDecimals)), # decimal places
427
+ 'price': quoteDecimals, # significant digits
428
+ },
429
+ 'limits': {
430
+ 'leverage': {
431
+ 'min': None,
432
+ 'max': None,
433
+ },
434
+ 'amount': {
435
+ 'min': None,
436
+ 'max': None,
437
+ },
438
+ 'price': {
439
+ 'min': None,
440
+ 'max': None,
441
+ },
442
+ 'cost': {
443
+ 'min': None,
444
+ 'max': None,
445
+ },
446
+ },
447
+ 'created': None,
448
+ 'info': market,
449
+ }))
450
+ return markets
451
+
307
452
  def parse_market(self, market) -> Market:
308
453
  #
309
454
  # {
@@ -398,12 +543,17 @@ class hyperliquid(Exchange, ImplicitAPI):
398
543
  :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-a-users-state
399
544
  :param dict [params]: extra parameters specific to the exchange API endpoint
400
545
  :param str [params.user]: user address, will default to self.walletAddress if not provided
546
+ :param str [params.type]: wallet type, ['spot', 'swap'], defaults to swap
401
547
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
402
548
  """
403
549
  userAddress = None
404
550
  userAddress, params = self.handle_public_address('fetchBalance', params)
551
+ type = None
552
+ type, params = self.handle_market_type_and_params('fetchBalance', None, params)
553
+ isSpot = (type == 'spot')
554
+ reqType = 'spotClearinghouseState' if (isSpot) else 'clearinghouseState'
405
555
  request = {
406
- 'type': 'clearinghouseState',
556
+ 'type': reqType,
407
557
  'user': userAddress,
408
558
  }
409
559
  response = await self.publicPostInfo(self.extend(request, params))
@@ -426,7 +576,35 @@ class hyperliquid(Exchange, ImplicitAPI):
426
576
  # "time": "1704261007014",
427
577
  # "withdrawable": "100.0"
428
578
  # }
579
+ # spot
580
+ #
581
+ # {
582
+ # "balances":[
583
+ # {
584
+ # "coin":"USDC",
585
+ # "hold":"0.0",
586
+ # "total":"1481.844"
587
+ # },
588
+ # {
589
+ # "coin":"PURR",
590
+ # "hold":"0.0",
591
+ # "total":"999.65004"
592
+ # }
593
+ # }
429
594
  #
595
+ balances = self.safe_list(response, 'balances')
596
+ if balances is not None:
597
+ spotBalances = {'info': response}
598
+ for i in range(0, len(balances)):
599
+ balance = balances[i]
600
+ code = self.safe_currency_code(self.safe_string(balance, 'coin'))
601
+ account = self.account()
602
+ total = self.safe_string(balance, 'total')
603
+ free = self.safe_string(balance, 'hold')
604
+ account['total'] = total
605
+ account['free'] = free
606
+ spotBalances[code] = account
607
+ return self.safe_balance(spotBalances)
430
608
  data = self.safe_dict(response, 'marginSummary', {})
431
609
  result = {
432
610
  'info': response,
@@ -915,6 +1093,7 @@ class hyperliquid(Exchange, ImplicitAPI):
915
1093
  :param str symbol: unified symbol of the market the order was made in
916
1094
  :param dict [params]: extra parameters specific to the exchange API endpoint
917
1095
  :param str [params.clientOrderId]: client order id,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
1096
+ :param str [params.vaultAddress]: the vault address for order
918
1097
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
919
1098
  """
920
1099
  return await self.cancel_orders([id], symbol, params)
@@ -928,6 +1107,7 @@ class hyperliquid(Exchange, ImplicitAPI):
928
1107
  :param str [symbol]: unified market symbol
929
1108
  :param dict [params]: extra parameters specific to the exchange API endpoint
930
1109
  :param string|str[] [params.clientOrderId]: client order ids,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
1110
+ :param str [params.vaultAddress]: the vault address
931
1111
  :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
932
1112
  """
933
1113
  self.check_required_credentials()
@@ -1377,7 +1557,10 @@ class hyperliquid(Exchange, ImplicitAPI):
1377
1557
  coin = self.safe_string(entry, 'coin')
1378
1558
  marketId = None
1379
1559
  if coin is not None:
1380
- marketId = coin + '/USDC:USDC'
1560
+ if coin.find('/') > -1:
1561
+ marketId = coin
1562
+ else:
1563
+ marketId = coin + '/USDC:USDC'
1381
1564
  if self.safe_string(entry, 'id') is None:
1382
1565
  market = self.safe_market(marketId, None)
1383
1566
  else:
@@ -1772,7 +1955,7 @@ class hyperliquid(Exchange, ImplicitAPI):
1772
1955
  #
1773
1956
  return response
1774
1957
 
1775
- async def add_margin(self, symbol: str, amount, params={}):
1958
+ async def add_margin(self, symbol: str, amount, params={}) -> MarginModification:
1776
1959
  """
1777
1960
  add margin
1778
1961
  :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#update-isolated-margin
@@ -1783,7 +1966,7 @@ class hyperliquid(Exchange, ImplicitAPI):
1783
1966
  """
1784
1967
  return await self.modify_margin_helper(symbol, amount, 'add', params)
1785
1968
 
1786
- async def reduce_margin(self, symbol: str, amount, params={}):
1969
+ async def reduce_margin(self, symbol: str, amount, params={}) -> MarginModification:
1787
1970
  """
1788
1971
  :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#update-isolated-margin
1789
1972
  remove margin from a position
@@ -1794,7 +1977,7 @@ class hyperliquid(Exchange, ImplicitAPI):
1794
1977
  """
1795
1978
  return await self.modify_margin_helper(symbol, amount, 'reduce', params)
1796
1979
 
1797
- async def modify_margin_helper(self, symbol: str, amount, type, params={}):
1980
+ async def modify_margin_helper(self, symbol: str, amount, type, params={}) -> MarginModification:
1798
1981
  await self.load_markets()
1799
1982
  market = self.market(symbol)
1800
1983
  asset = self.parse_to_int(market['baseId'])
@@ -1828,10 +2011,27 @@ class hyperliquid(Exchange, ImplicitAPI):
1828
2011
  # 'status': 'ok'
1829
2012
  # }
1830
2013
  #
1831
- return response
1832
- # return self.extend(self.parse_margin_modification(response, market), {
1833
- # 'code': code,
1834
- # })
2014
+ return self.extend(self.parse_margin_modification(response, market), {
2015
+ 'code': self.safe_string(response, 'status'),
2016
+ })
2017
+
2018
+ def parse_margin_modification(self, data, market: Market = None) -> MarginModification:
2019
+ #
2020
+ # {
2021
+ # 'type': 'default'
2022
+ # }
2023
+ #
2024
+ return {
2025
+ 'info': data,
2026
+ 'symbol': self.safe_symbol(None, market),
2027
+ 'type': None,
2028
+ 'amount': None,
2029
+ 'total': None,
2030
+ 'code': self.safe_string(market, 'settle'),
2031
+ 'status': None,
2032
+ 'timestamp': None,
2033
+ 'datetime': None,
2034
+ }
1835
2035
 
1836
2036
  async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
1837
2037
  """
@@ -1839,23 +2039,49 @@ class hyperliquid(Exchange, ImplicitAPI):
1839
2039
  :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#l1-usdc-transfer
1840
2040
  :param str code: unified currency code
1841
2041
  :param float amount: amount to transfer
1842
- :param str fromAccount: account to transfer from
1843
- :param str toAccount: account to transfer to
2042
+ :param str fromAccount: account to transfer from *spot, swap*
2043
+ :param str toAccount: account to transfer to *swap, spot or address*
1844
2044
  :param dict [params]: extra parameters specific to the exchange API endpoint
2045
+ :param str [params.vaultAddress]: the vault address for order
1845
2046
  :returns dict: a `transfer structure <https://docs.ccxt.com/#/?id=transfer-structure>`
1846
2047
  """
1847
2048
  self.check_required_credentials()
1848
2049
  await self.load_markets()
2050
+ isSandboxMode = self.safe_bool(self.options, 'sandboxMode')
2051
+ nonce = self.milliseconds()
2052
+ if self.in_array(fromAccount, ['spot', 'swap', 'perp']):
2053
+ # handle swap <> spot account transfer
2054
+ if not self.in_array(toAccount, ['spot', 'swap', 'perp']):
2055
+ raise NotSupported(self.id + 'transfer() only support spot <> swap transfer')
2056
+ vaultAddress = self.format_vault_address(self.safe_string(params, 'vaultAddress'))
2057
+ params = self.omit(params, 'vaultAddress')
2058
+ toPerp = (toAccount == 'perp') or (toAccount == 'swap')
2059
+ action = {
2060
+ 'type': 'spotUser',
2061
+ 'classTransfer': {
2062
+ 'usdc': amount,
2063
+ 'toPerp': toPerp,
2064
+ },
2065
+ }
2066
+ signature = self.sign_l1_action(action, nonce, vaultAddress)
2067
+ innerRequest = {
2068
+ 'action': self.extend(action, params),
2069
+ 'nonce': nonce,
2070
+ 'signature': signature,
2071
+ }
2072
+ if vaultAddress is not None:
2073
+ innerRequest['vaultAddress'] = vaultAddress
2074
+ transferResponse = await self.privatePostExchange(innerRequest)
2075
+ return transferResponse
2076
+ # handle sub-account/different account transfer
1849
2077
  self.check_address(toAccount)
1850
2078
  if code is not None:
1851
2079
  code = code.upper()
1852
2080
  if code != 'USDC':
1853
2081
  raise NotSupported(self.id + 'withdraw() only support USDC')
1854
- isSandboxMode = self.safe_bool(self.options, 'sandboxMode')
1855
- nonce = self.milliseconds()
1856
2082
  payload = {
1857
2083
  'destination': toAccount,
1858
- 'amount': str(amount),
2084
+ 'amount': self.number_to_string(amount),
1859
2085
  'time': nonce,
1860
2086
  }
1861
2087
  sig = self.build_transfer_sig(payload)
@@ -463,7 +463,7 @@ class idex(Exchange, ImplicitAPI):
463
463
  if since is not None:
464
464
  request['start'] = since
465
465
  if limit is not None:
466
- request['limit'] = limit
466
+ request['limit'] = min(limit, 1000)
467
467
  response = await self.publicGetCandles(self.extend(request, params))
468
468
  if isinstance(response, list):
469
469
  # [
@@ -635,14 +635,12 @@ class krakenfutures(Exchange, ImplicitAPI):
635
635
  request['from'] = self.parse_to_int(since / 1000)
636
636
  if limit is None:
637
637
  limit = 5000
638
- elif limit > 5000:
639
- raise BadRequest(self.id + ' fetchOHLCV() limit cannot exceed 5000')
638
+ limit = min(limit, 5000)
640
639
  toTimestamp = self.sum(request['from'], limit * duration - 1)
641
640
  currentTimestamp = self.seconds()
642
641
  request['to'] = min(toTimestamp, currentTimestamp)
643
642
  elif limit is not None:
644
- if limit > 5000:
645
- raise BadRequest(self.id + ' fetchOHLCV() limit cannot exceed 5000')
643
+ limit = min(limit, 5000)
646
644
  duration = self.parse_timeframe(timeframe)
647
645
  request['to'] = self.seconds()
648
646
  request['from'] = self.parse_to_int(request['to'] - (duration * limit))
@@ -5,7 +5,7 @@
5
5
 
6
6
  from ccxt.async_support.kucoin import kucoin
7
7
  from ccxt.abstract.kucoinfutures import ImplicitAPI
8
- from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
8
+ from ccxt.base.types import Balances, Currency, Int, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
9
9
  from typing import List
10
10
  from ccxt.base.errors import PermissionDenied
11
11
  from ccxt.base.errors import AccountSuspended
@@ -1424,7 +1424,7 @@ class kucoinfutures(kucoin, ImplicitAPI):
1424
1424
  #
1425
1425
  return self.safe_value(response, 'data')
1426
1426
 
1427
- async def add_margin(self, symbol: str, amount, params={}):
1427
+ async def add_margin(self, symbol: str, amount, params={}) -> MarginModification:
1428
1428
  """
1429
1429
  add margin
1430
1430
  :see: https://www.kucoin.com/docs/rest/futures-trading/positions/add-margin-manually
@@ -970,6 +970,8 @@ class lbank(Exchange, ImplicitAPI):
970
970
  market = self.market(symbol)
971
971
  if limit is None:
972
972
  limit = 100
973
+ else:
974
+ limit = min(limit, 2000)
973
975
  if since is None:
974
976
  duration = self.parse_timeframe(timeframe)
975
977
  since = self.milliseconds() - duration * 1000 * limit
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.mexc import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Account, Balances, Currency, IndexType, Int, Leverage, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
9
+ from ccxt.base.types import Account, Balances, Currency, IndexType, Int, Leverage, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import PermissionDenied
@@ -3778,7 +3778,7 @@ class mexc(Exchange, ImplicitAPI):
3778
3778
  # }
3779
3779
  return response
3780
3780
 
3781
- async def reduce_margin(self, symbol: str, amount, params={}):
3781
+ async def reduce_margin(self, symbol: str, amount, params={}) -> MarginModification:
3782
3782
  """
3783
3783
  remove margin from a position
3784
3784
  :param str symbol: unified market symbol
@@ -3788,7 +3788,7 @@ class mexc(Exchange, ImplicitAPI):
3788
3788
  """
3789
3789
  return await self.modify_margin_helper(symbol, amount, 'SUB', params)
3790
3790
 
3791
- async def add_margin(self, symbol: str, amount, params={}):
3791
+ async def add_margin(self, symbol: str, amount, params={}) -> MarginModification:
3792
3792
  """
3793
3793
  add margin
3794
3794
  :param str symbol: unified market symbol
@@ -750,7 +750,7 @@ class oceanex(Exchange, ImplicitAPI):
750
750
  if since is not None:
751
751
  request['timestamp'] = since
752
752
  if limit is not None:
753
- request['limit'] = limit
753
+ request['limit'] = min(limit, 10000)
754
754
  response = await self.publicPostK(self.extend(request, params))
755
755
  ohlcvs = self.safe_list(response, 'data', [])
756
756
  return self.parse_ohlcvs(ohlcvs, market, timeframe, since, limit)