ccxt 4.4.3__py2.py3-none-any.whl → 4.4.4__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 (79) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/async_support/__init__.py +1 -1
  3. ccxt/async_support/base/exchange.py +24 -13
  4. ccxt/async_support/base/ws/cache.py +1 -0
  5. ccxt/async_support/binance.py +40 -15
  6. ccxt/async_support/bingx.py +1 -0
  7. ccxt/async_support/bitfinex2.py +10 -9
  8. ccxt/async_support/bitget.py +13 -9
  9. ccxt/async_support/bitmex.py +14 -13
  10. ccxt/async_support/bitso.py +8 -7
  11. ccxt/async_support/bitstamp.py +12 -12
  12. ccxt/async_support/blofin.py +24 -26
  13. ccxt/async_support/bybit.py +24 -23
  14. ccxt/async_support/coinbase.py +31 -10
  15. ccxt/async_support/coinbaseexchange.py +14 -14
  16. ccxt/async_support/coinlist.py +9 -8
  17. ccxt/async_support/coinmetro.py +6 -6
  18. ccxt/async_support/cryptocom.py +10 -8
  19. ccxt/async_support/currencycom.py +9 -9
  20. ccxt/async_support/delta.py +8 -8
  21. ccxt/async_support/digifinex.py +11 -9
  22. ccxt/async_support/gate.py +9 -8
  23. ccxt/async_support/hashkey.py +12 -10
  24. ccxt/async_support/htx.py +16 -19
  25. ccxt/async_support/hyperliquid.py +70 -117
  26. ccxt/async_support/kraken.py +12 -10
  27. ccxt/async_support/kucoin.py +12 -11
  28. ccxt/async_support/luno.py +13 -12
  29. ccxt/async_support/mexc.py +34 -2
  30. ccxt/async_support/ndax.py +9 -8
  31. ccxt/async_support/okcoin.py +21 -30
  32. ccxt/async_support/okx.py +21 -29
  33. ccxt/async_support/woo.py +10 -9
  34. ccxt/async_support/woofipro.py +11 -9
  35. ccxt/async_support/xt.py +7 -6
  36. ccxt/async_support/zonda.py +9 -8
  37. ccxt/base/exchange.py +3 -1
  38. ccxt/binance.py +40 -15
  39. ccxt/bingx.py +1 -0
  40. ccxt/bitfinex2.py +10 -9
  41. ccxt/bitget.py +13 -9
  42. ccxt/bitmex.py +14 -13
  43. ccxt/bitso.py +8 -7
  44. ccxt/bitstamp.py +12 -12
  45. ccxt/blofin.py +24 -26
  46. ccxt/bybit.py +24 -23
  47. ccxt/coinbase.py +31 -10
  48. ccxt/coinbaseexchange.py +14 -14
  49. ccxt/coinlist.py +9 -8
  50. ccxt/coinmetro.py +6 -6
  51. ccxt/cryptocom.py +10 -8
  52. ccxt/currencycom.py +9 -9
  53. ccxt/delta.py +8 -8
  54. ccxt/digifinex.py +11 -9
  55. ccxt/gate.py +9 -8
  56. ccxt/hashkey.py +12 -10
  57. ccxt/htx.py +16 -19
  58. ccxt/hyperliquid.py +70 -117
  59. ccxt/kraken.py +12 -10
  60. ccxt/kucoin.py +12 -11
  61. ccxt/luno.py +13 -12
  62. ccxt/mexc.py +33 -2
  63. ccxt/ndax.py +9 -8
  64. ccxt/okcoin.py +21 -30
  65. ccxt/okx.py +21 -29
  66. ccxt/pro/__init__.py +1 -1
  67. ccxt/pro/bybit.py +51 -0
  68. ccxt/pro/mexc.py +78 -0
  69. ccxt/test/tests_async.py +1 -1
  70. ccxt/test/tests_sync.py +1 -1
  71. ccxt/woo.py +10 -9
  72. ccxt/woofipro.py +11 -9
  73. ccxt/xt.py +7 -6
  74. ccxt/zonda.py +9 -8
  75. {ccxt-4.4.3.dist-info → ccxt-4.4.4.dist-info}/METADATA +5 -5
  76. {ccxt-4.4.3.dist-info → ccxt-4.4.4.dist-info}/RECORD +79 -79
  77. {ccxt-4.4.3.dist-info → ccxt-4.4.4.dist-info}/LICENSE.txt +0 -0
  78. {ccxt-4.4.3.dist-info → ccxt-4.4.4.dist-info}/WHEEL +0 -0
  79. {ccxt-4.4.3.dist-info → ccxt-4.4.4.dist-info}/top_level.txt +0 -0
ccxt/hyperliquid.py CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.hyperliquid import ImplicitAPI
8
- from ccxt.base.types import Balances, Currencies, Currency, Int, MarginModification, Market, Num, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
8
+ from ccxt.base.types import Balances, Currencies, Currency, Int, LedgerEntry, MarginModification, Market, Num, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
9
9
  from typing import List
10
10
  from ccxt.base.errors import ExchangeError
11
11
  from ccxt.base.errors import ArgumentsRequired
@@ -16,7 +16,6 @@ from ccxt.base.errors import NotSupported
16
16
  from ccxt.base.decimal_to_precision import ROUND
17
17
  from ccxt.base.decimal_to_precision import DECIMAL_PLACES
18
18
  from ccxt.base.decimal_to_precision import SIGNIFICANT_DIGITS
19
- from ccxt.base.decimal_to_precision import TICK_SIZE
20
19
  from ccxt.base.precise import Precise
21
20
 
22
21
 
@@ -196,9 +195,11 @@ class hyperliquid(Exchange, ImplicitAPI):
196
195
  'No liquidity available for market order.': InvalidOrder,
197
196
  'Order was never placed, already canceled, or filled.': OrderNotFound,
198
197
  'User or API Wallet ': InvalidOrder,
198
+ 'Order has invalid size': InvalidOrder,
199
+ 'Order price cannot be more than 80% away from the reference price': InvalidOrder,
199
200
  },
200
201
  },
201
- 'precisionMode': TICK_SIZE,
202
+ 'precisionMode': DECIMAL_PLACES,
202
203
  'commonCurrencies': {
203
204
  },
204
205
  'options': {
@@ -216,7 +217,7 @@ class hyperliquid(Exchange, ImplicitAPI):
216
217
  def fetch_currencies(self, params={}) -> Currencies:
217
218
  """
218
219
  fetches all available currencies on an exchange
219
- :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-exchange-metadata
220
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-perpetuals-metadata
220
221
  :param dict [params]: extra parameters specific to the exchange API endpoint
221
222
  :returns dict: an associative dictionary of currencies
222
223
  """
@@ -272,7 +273,8 @@ class hyperliquid(Exchange, ImplicitAPI):
272
273
  def fetch_markets(self, params={}) -> List[Market]:
273
274
  """
274
275
  retrieves data on all markets for hyperliquid
275
- :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-asset-contexts-includes-mark-price-current-funding-open-interest-etc
276
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-perpetuals-asset-contexts-includes-mark-price-current-funding-open-interest-etc
277
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/spot#retrieve-spot-asset-contexts
276
278
  :param dict [params]: extra parameters specific to the exchange API endpoint
277
279
  :returns dict[]: an array of objects representing market data
278
280
  """
@@ -288,7 +290,7 @@ class hyperliquid(Exchange, ImplicitAPI):
288
290
  def fetch_swap_markets(self, params={}) -> List[Market]:
289
291
  """
290
292
  retrieves data on all swap markets for hyperliquid
291
- :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-asset-contexts-includes-mark-price-current-funding-open-interest-etc
293
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-perpetuals-asset-contexts-includes-mark-price-current-funding-open-interest-etc
292
294
  :param dict [params]: extra parameters specific to the exchange API endpoint
293
295
  :returns dict[]: an array of objects representing market data
294
296
  """
@@ -343,7 +345,7 @@ class hyperliquid(Exchange, ImplicitAPI):
343
345
  def fetch_spot_markets(self, params={}) -> List[Market]:
344
346
  """
345
347
  retrieves data on all spot markets for hyperliquid
346
- :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-asset-contexts-includes-mark-price-current-funding-open-interest-etc
348
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/spot#retrieve-spot-asset-contexts
347
349
  :param dict [params]: extra parameters specific to the exchange API endpoint
348
350
  :returns dict[]: an array of objects representing market data
349
351
  """
@@ -354,102 +356,51 @@ class hyperliquid(Exchange, ImplicitAPI):
354
356
  #
355
357
  # [
356
358
  # {
357
- # 'tokens': [
359
+ # "tokens": [
358
360
  # {
359
- # 'name': 'USDC',
360
- # 'szDecimals': '8',
361
- # 'weiDecimals': '8',
361
+ # "name": "USDC",
362
+ # "szDecimals": 8,
363
+ # "weiDecimals" 8,
364
+ # "index": 0,
365
+ # "tokenId": "0x6d1e7cde53ba9467b783cb7c530ce054",
366
+ # "isCanonical": True,
367
+ # "evmContract":null,
368
+ # "fullName":null
362
369
  # },
363
370
  # {
364
- # 'name': 'PURR',
365
- # 'szDecimals': '0',
366
- # 'weiDecimals': '5',
367
- # },
371
+ # "name": "PURR",
372
+ # "szDecimals": 0,
373
+ # "weiDecimals": 5,
374
+ # "index": 1,
375
+ # "tokenId": "0xc1fb593aeffbeb02f85e0308e9956a90",
376
+ # "isCanonical": True,
377
+ # "evmContract":null,
378
+ # "fullName":null
379
+ # }
368
380
  # ],
369
- # 'universe': [
381
+ # "universe": [
370
382
  # {
371
- # 'name': 'PURR/USDC',
372
- # 'tokens': [
373
- # 1,
374
- # 0,
375
- # ],
376
- # },
377
- # ],
383
+ # "name": "PURR/USDC",
384
+ # "tokens": [1, 0],
385
+ # "index": 0,
386
+ # "isCanonical": True
387
+ # }
388
+ # ]
378
389
  # },
379
390
  # [
380
391
  # {
381
- # 'dayNtlVlm': '264250385.14640012',
382
- # 'markPx': '0.018314',
383
- # 'midPx': '0.0182235',
384
- # 'prevDayPx': '0.017427',
385
- # },
386
- # ],
387
- # ]
388
- # mainnet
389
- # [
390
- # {
391
- # "canonical_tokens2":[
392
- # 0,
393
- # 1
394
- # ],
395
- # "spot_infos":[
396
- # {
397
- # "name":"PURR/USDC",
398
- # "tokens":[
399
- # 1,
400
- # 0
401
- # ]
402
- # }
403
- # ],
404
- # "token_id_to_token":[
405
- # [
406
- # "0x6d1e7cde53ba9467b783cb7c530ce054",
407
- # 0
408
- # ],
409
- # [
410
- # "0xc1fb593aeffbeb02f85e0308e9956a90",
411
- # 1
412
- # ]
413
- # ],
414
- # "token_infos":[
415
- # {
416
- # "deployer":null,
417
- # "spec":{
418
- # "name":"USDC",
419
- # "szDecimals":"8",
420
- # "weiDecimals":"8"
421
- # },
422
- # "spots":[
423
- # ]
424
- # },
425
- # {
426
- # "deployer":null,
427
- # "spec":{
428
- # "name":"PURR",
429
- # "szDecimals":"0",
430
- # "weiDecimals":"5"
431
- # },
432
- # "spots":[
433
- # 0
434
- # ]
435
- # }
436
- # ]
437
- # },
438
- # [
439
- # {
440
- # "dayNtlVlm":"35001170.16631",
441
- # "markPx":"0.15743",
442
- # "midPx":"0.157555",
443
- # "prevDayPx":"0.158"
444
- # }
392
+ # "dayNtlVlm":"8906.0",
393
+ # "markPx":"0.14",
394
+ # "midPx":"0.209265",
395
+ # "prevDayPx":"0.20432"
396
+ # }
445
397
  # ]
446
398
  # ]
447
399
  #
448
- # response differs depending on the environment(mainnet vs sandbox)
449
400
  first = self.safe_dict(response, 0, {})
450
401
  second = self.safe_list(response, 1, [])
451
- meta = self.safe_list_2(first, 'universe', 'spot_infos', [])
452
- tokens = self.safe_list_2(first, 'tokens', 'token_infos', [])
402
+ meta = self.safe_list(first, 'universe', [])
403
+ tokens = self.safe_list(first, 'tokens', [])
453
404
  markets = []
454
405
  for i in range(0, len(meta)):
455
406
  market = self.safe_dict(meta, i, {})
@@ -477,7 +428,7 @@ class hyperliquid(Exchange, ImplicitAPI):
477
428
  symbol = base + '/' + quote
478
429
  innerBaseTokenInfo = self.safe_dict(baseTokenInfo, 'spec', baseTokenInfo)
479
430
  # innerQuoteTokenInfo = self.safe_dict(quoteTokenInfo, 'spec', quoteTokenInfo)
480
- amountPrecision = self.parse_number(self.parse_precision(self.safe_string(innerBaseTokenInfo, 'szDecimals')))
431
+ amountPrecision = self.safe_integer(innerBaseTokenInfo, 'szDecimals')
481
432
  # quotePrecision = self.parse_number(self.parse_precision(self.safe_string(innerQuoteTokenInfo, 'szDecimals')))
482
433
  baseId = self.number_to_string(i + 10000)
483
434
  markets.append(self.safe_market_structure({
@@ -509,7 +460,7 @@ class hyperliquid(Exchange, ImplicitAPI):
509
460
  'optionType': None,
510
461
  'precision': {
511
462
  'amount': amountPrecision, # decimal places
512
- 'price': 5, # significant digits
463
+ 'price': 8 - amountPrecision, # MAX_DECIMALS is 8
513
464
  },
514
465
  'limits': {
515
466
  'leverage': {
@@ -525,7 +476,7 @@ class hyperliquid(Exchange, ImplicitAPI):
525
476
  'max': None,
526
477
  },
527
478
  'cost': {
528
- 'min': None,
479
+ 'min': self.parse_number('10'),
529
480
  'max': None,
530
481
  },
531
482
  },
@@ -570,7 +521,8 @@ class hyperliquid(Exchange, ImplicitAPI):
570
521
  fees = self.safe_dict(self.fees, 'swap', {})
571
522
  taker = self.safe_number(fees, 'taker')
572
523
  maker = self.safe_number(fees, 'maker')
573
- return {
524
+ amountPrecision = self.safe_integer(market, 'szDecimals')
525
+ return self.safe_market_structure({
574
526
  'id': baseId,
575
527
  'symbol': symbol,
576
528
  'base': base,
@@ -597,8 +549,8 @@ class hyperliquid(Exchange, ImplicitAPI):
597
549
  'strike': None,
598
550
  'optionType': None,
599
551
  'precision': {
600
- 'amount': self.parse_number(self.parse_precision(self.safe_string(market, 'szDecimals'))), # decimal places
601
- 'price': 5, # significant digits
552
+ 'amount': amountPrecision, # decimal places
553
+ 'price': 6 - amountPrecision, # MAX_DECIMALS is 6
602
554
  },
603
555
  'limits': {
604
556
  'leverage': {
@@ -614,18 +566,19 @@ class hyperliquid(Exchange, ImplicitAPI):
614
566
  'max': None,
615
567
  },
616
568
  'cost': {
617
- 'min': None,
569
+ 'min': self.parse_number('10'),
618
570
  'max': None,
619
571
  },
620
572
  },
621
573
  'created': None,
622
574
  'info': market,
623
- }
575
+ })
624
576
 
625
577
  def fetch_balance(self, params={}) -> Balances:
626
578
  """
627
579
  query for balance and get the amount of funds available for trading or funds locked in orders
628
- :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-a-users-state
580
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/spot#retrieve-a-users-token-balances
581
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-users-perpetuals-account-summary
629
582
  :param dict [params]: extra parameters specific to the exchange API endpoint
630
583
  :param str [params.user]: user address, will default to self.walletAddress if not provided
631
584
  :param str [params.type]: wallet type, ['spot', 'swap'], defaults to swap
@@ -706,7 +659,7 @@ class hyperliquid(Exchange, ImplicitAPI):
706
659
  def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
707
660
  """
708
661
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
709
- :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#info
662
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#l2-book-snapshot
710
663
  :param str symbol: unified symbol of the market to fetch the order book for
711
664
  :param int [limit]: the maximum amount of order book entries to return
712
665
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -752,7 +705,8 @@ class hyperliquid(Exchange, ImplicitAPI):
752
705
  def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
753
706
  """
754
707
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
755
- :see: https://www.bitmex.com/api/explorer/#not /Instrument/Instrument_getActiveAndIndices
708
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-perpetuals-asset-contexts-includes-mark-price-current-funding-open-interest-etc
709
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/spot#retrieve-spot-asset-contexts
756
710
  :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
757
711
  :param dict [params]: extra parameters specific to the exchange API endpoint
758
712
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -803,7 +757,7 @@ class hyperliquid(Exchange, ImplicitAPI):
803
757
  def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
804
758
  """
805
759
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
806
- :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#info-1
760
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#candle-snapshot
807
761
  :param str symbol: unified symbol of the market to fetch OHLCV data for
808
762
  :param str timeframe: the length of time each candle represents, support '1m', '15m', '1h', '1d'
809
763
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -926,14 +880,13 @@ class hyperliquid(Exchange, ImplicitAPI):
926
880
 
927
881
  def amount_to_precision(self, symbol, amount):
928
882
  market = self.market(symbol)
929
- if market['spot']:
930
- return super(hyperliquid, self).amount_to_precision(symbol, amount)
931
- return self.decimal_to_precision(amount, ROUND, self.markets[symbol]['precision']['amount'], self.precisionMode)
883
+ return self.decimal_to_precision(amount, ROUND, market['precision']['amount'], self.precisionMode, self.paddingMode)
932
884
 
933
885
  def price_to_precision(self, symbol: str, price) -> str:
934
886
  market = self.market(symbol)
935
- result = self.decimal_to_precision(price, ROUND, market['precision']['price'], SIGNIFICANT_DIGITS, self.paddingMode)
936
- decimalParsedResult = self.decimal_to_precision(result, ROUND, 6, DECIMAL_PLACES, self.paddingMode)
887
+ # https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/tick-and-lot-size
888
+ result = self.decimal_to_precision(price, ROUND, 5, SIGNIFICANT_DIGITS, self.paddingMode)
889
+ decimalParsedResult = self.decimal_to_precision(result, ROUND, market['precision']['price'], self.precisionMode, self.paddingMode)
937
890
  return decimalParsedResult
938
891
 
939
892
  def hash_message(self, message):
@@ -1563,7 +1516,7 @@ class hyperliquid(Exchange, ImplicitAPI):
1563
1516
  def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1564
1517
  """
1565
1518
  fetches historical funding rate prices
1566
- :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-historical-funding-rates
1519
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-historical-funding-rates
1567
1520
  :param str symbol: unified symbol of the market to fetch the funding rate history for
1568
1521
  :param int [since]: timestamp in ms of the earliest funding rate to fetch
1569
1522
  :param int [limit]: the maximum amount of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>` to fetch
@@ -2037,7 +1990,7 @@ class hyperliquid(Exchange, ImplicitAPI):
2037
1990
  def fetch_position(self, symbol: str, params={}):
2038
1991
  """
2039
1992
  fetch data on an open position
2040
- :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-a-users-state
1993
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-users-perpetuals-account-summary
2041
1994
  :param str symbol: unified market symbol of the market the position is held in
2042
1995
  :param dict [params]: extra parameters specific to the exchange API endpoint
2043
1996
  :param str [params.user]: user address, will default to self.walletAddress if not provided
@@ -2049,7 +2002,7 @@ class hyperliquid(Exchange, ImplicitAPI):
2049
2002
  def fetch_positions(self, symbols: Strings = None, params={}):
2050
2003
  """
2051
2004
  fetch all open positions
2052
- :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-a-users-state
2005
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-users-perpetuals-account-summary
2053
2006
  :param str[] [symbols]: list of unified market symbols
2054
2007
  :param dict [params]: extra parameters specific to the exchange API endpoint
2055
2008
  :param str [params.user]: user address, will default to self.walletAddress if not provided
@@ -2639,12 +2592,12 @@ class hyperliquid(Exchange, ImplicitAPI):
2639
2592
  'tierBased': None,
2640
2593
  }
2641
2594
 
2642
- def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
2595
+ def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
2643
2596
  """
2644
2597
  fetch the history of changes, actions done by the user or operations that altered the balance of the user
2645
- :param str code: unified currency code
2598
+ :param str [code]: unified currency code
2646
2599
  :param int [since]: timestamp in ms of the earliest ledger entry
2647
- :param int [limit]: max number of ledger entrys to return
2600
+ :param int [limit]: max number of ledger entries to return
2648
2601
  :param dict [params]: extra parameters specific to the exchange API endpoint
2649
2602
  :param int [params.until]: timestamp in ms of the latest ledger entry
2650
2603
  :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
@@ -2678,7 +2631,7 @@ class hyperliquid(Exchange, ImplicitAPI):
2678
2631
  #
2679
2632
  return self.parse_ledger(response, None, since, limit)
2680
2633
 
2681
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
2634
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
2682
2635
  #
2683
2636
  # {
2684
2637
  # "time":1724762307531,
@@ -2701,7 +2654,8 @@ class hyperliquid(Exchange, ImplicitAPI):
2701
2654
  }
2702
2655
  type = self.safe_string(delta, 'type')
2703
2656
  amount = self.safe_string(delta, 'usdc')
2704
- return {
2657
+ return self.safe_ledger_entry({
2658
+ 'info': item,
2705
2659
  'id': self.safe_string(item, 'hash'),
2706
2660
  'direction': None,
2707
2661
  'account': None,
@@ -2716,8 +2670,7 @@ class hyperliquid(Exchange, ImplicitAPI):
2716
2670
  'after': None,
2717
2671
  'status': None,
2718
2672
  'fee': fee,
2719
- 'info': item,
2720
- }
2673
+ }, currency)
2721
2674
 
2722
2675
  def parse_ledger_entry_type(self, type):
2723
2676
  ledgerType: dict = {
ccxt/kraken.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.kraken import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currencies, Currency, IndexType, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
9
+ from ccxt.base.types import Balances, Currencies, Currency, IndexType, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -1026,7 +1026,7 @@ class kraken(Exchange, ImplicitAPI):
1026
1026
  }
1027
1027
  return self.safe_string(types, type, type)
1028
1028
 
1029
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
1029
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
1030
1030
  #
1031
1031
  # {
1032
1032
  # 'LTFK7F-N2CUX-PNY4SX': {
@@ -1048,7 +1048,9 @@ class kraken(Exchange, ImplicitAPI):
1048
1048
  referenceId = self.safe_string(item, 'refid')
1049
1049
  referenceAccount = None
1050
1050
  type = self.parse_ledger_entry_type(self.safe_string(item, 'type'))
1051
- code = self.safe_currency_code(self.safe_string(item, 'asset'), currency)
1051
+ currencyId = self.safe_string(item, 'asset')
1052
+ code = self.safe_currency_code(currencyId, currency)
1053
+ currency = self.safe_currency(currencyId, currency)
1052
1054
  amount = self.safe_string(item, 'amount')
1053
1055
  if Precise.string_lt(amount, '0'):
1054
1056
  direction = 'out'
@@ -1056,7 +1058,7 @@ class kraken(Exchange, ImplicitAPI):
1056
1058
  else:
1057
1059
  direction = 'in'
1058
1060
  timestamp = self.safe_integer_product(item, 'time', 1000)
1059
- return {
1061
+ return self.safe_ledger_entry({
1060
1062
  'info': item,
1061
1063
  'id': id,
1062
1064
  'direction': direction,
@@ -1075,15 +1077,15 @@ class kraken(Exchange, ImplicitAPI):
1075
1077
  'cost': self.safe_number(item, 'fee'),
1076
1078
  'currency': code,
1077
1079
  },
1078
- }
1080
+ }, currency)
1079
1081
 
1080
- def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
1082
+ def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
1081
1083
  """
1082
- fetch the history of changes, actions done by the user or operations that altered balance of the user
1084
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
1083
1085
  :see: https://docs.kraken.com/rest/#tag/Account-Data/operation/getLedgers
1084
- :param str code: unified currency code, default is None
1086
+ :param str [code]: unified currency code, default is None
1085
1087
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
1086
- :param int [limit]: max number of ledger entrys to return, default is None
1088
+ :param int [limit]: max number of ledger entries to return, default is None
1087
1089
  :param dict [params]: extra parameters specific to the exchange API endpoint
1088
1090
  :param int [params.until]: timestamp in ms of the latest ledger entry
1089
1091
  :param int [params.end]: timestamp in seconds of the latest ledger entry
@@ -1151,7 +1153,7 @@ class kraken(Exchange, ImplicitAPI):
1151
1153
  items.append(value)
1152
1154
  return self.parse_ledger(items)
1153
1155
 
1154
- def fetch_ledger_entry(self, id: str, code: Str = None, params={}):
1156
+ def fetch_ledger_entry(self, id: str, code: Str = None, params={}) -> LedgerEntry:
1155
1157
  items = self.fetch_ledger_entries_by_ids([id], code, params)
1156
1158
  return items[0]
1157
1159
 
ccxt/kucoin.py CHANGED
@@ -8,7 +8,7 @@ from ccxt.abstract.kucoin import ImplicitAPI
8
8
  import hashlib
9
9
  import math
10
10
  import json
11
- from ccxt.base.types import Account, Balances, Bool, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
11
+ from ccxt.base.types import Account, Balances, Bool, Currencies, Currency, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
12
12
  from typing import List
13
13
  from ccxt.base.errors import ExchangeError
14
14
  from ccxt.base.errors import AuthenticationError
@@ -3931,7 +3931,7 @@ class kucoin(Exchange, ImplicitAPI):
3931
3931
  }
3932
3932
  return self.safe_string(types, type, type)
3933
3933
 
3934
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
3934
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
3935
3935
  #
3936
3936
  # {
3937
3937
  # "id": "611a1e7c6a053300067a88d9", #unique key for each ledger entry
@@ -3949,6 +3949,7 @@ class kucoin(Exchange, ImplicitAPI):
3949
3949
  id = self.safe_string(item, 'id')
3950
3950
  currencyId = self.safe_string(item, 'currency')
3951
3951
  code = self.safe_currency_code(currencyId, currency)
3952
+ currency = self.safe_currency(currencyId, currency)
3952
3953
  amount = self.safe_number(item, 'amount')
3953
3954
  balanceAfter = None
3954
3955
  # balanceAfter = self.safe_number(item, 'balance'); only returns zero string
@@ -3991,7 +3992,8 @@ class kucoin(Exchange, ImplicitAPI):
3991
3992
  if feeCost != '0':
3992
3993
  feeCurrency = code
3993
3994
  fee = {'cost': self.parse_number(feeCost), 'currency': feeCurrency}
3994
- return {
3995
+ return self.safe_ledger_entry({
3996
+ 'info': item,
3995
3997
  'id': id,
3996
3998
  'direction': direction,
3997
3999
  'account': account,
@@ -4006,22 +4008,21 @@ class kucoin(Exchange, ImplicitAPI):
4006
4008
  'after': balanceAfter, # None
4007
4009
  'status': None,
4008
4010
  'fee': fee,
4009
- 'info': item,
4010
- }
4011
+ }, currency)
4011
4012
 
4012
- def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
4013
+ def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
4013
4014
  """
4015
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
4014
4016
  :see: https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-spot-margin
4015
4017
  :see: https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-trade_hf
4016
4018
  :see: https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-margin_hf
4017
- fetch the history of changes, actions done by the user or operations that altered balance of the user
4018
- :param str code: unified currency code, default is None
4019
+ :param str [code]: unified currency code, default is None
4019
4020
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
4020
- :param int [limit]: max number of ledger entrys to return, default is None
4021
+ :param int [limit]: max number of ledger entries to return, default is None
4021
4022
  :param dict [params]: extra parameters specific to the exchange API endpoint
4022
4023
  :param boolean [params.hf]: default False, when True will fetch ledger entries for the high frequency trading account
4023
4024
  :param int [params.until]: the latest time in ms to fetch entries for
4024
- :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
4025
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
4025
4026
  :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
4026
4027
  """
4027
4028
  self.load_markets()
@@ -4742,7 +4743,7 @@ class kucoin(Exchange, ImplicitAPI):
4742
4743
  #
4743
4744
  errorCode = self.safe_string(response, 'code')
4744
4745
  message = self.safe_string_2(response, 'msg', 'data', '')
4745
- feedback = self.id + ' ' + message
4746
+ feedback = self.id + ' ' + body
4746
4747
  self.throw_exactly_matched_exception(self.exceptions['exact'], message, feedback)
4747
4748
  self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
4748
4749
  self.throw_broadly_matched_exception(self.exceptions['broad'], body, feedback)
ccxt/luno.py CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.luno import ImplicitAPI
8
- from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface
8
+ from ccxt.base.types import Account, Balances, Currency, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface
9
9
  from typing import List
10
10
  from ccxt.base.errors import ExchangeError
11
11
  from ccxt.base.errors import ArgumentsRequired
@@ -920,13 +920,13 @@ class luno(Exchange, ImplicitAPI):
920
920
  }
921
921
  return self.fetch_ledger(code, since, limit, self.extend(request, params))
922
922
 
923
- def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
923
+ def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
924
924
  """
925
- fetch the history of changes, actions done by the user or operations that altered balance of the user
925
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
926
926
  :see: https://www.luno.com/en/developers/api#tag/Accounts/operation/ListTransactions
927
- :param str code: unified currency code, default is None
927
+ :param str [code]: unified currency code, default is None
928
928
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
929
- :param int [limit]: max number of ledger entrys to return, default is None
929
+ :param int [limit]: max number of ledger entries to return, default is None
930
930
  :param dict [params]: extra parameters specific to the exchange API endpoint
931
931
  :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
932
932
  """
@@ -995,13 +995,14 @@ class luno(Exchange, ImplicitAPI):
995
995
  'referenceId': referenceId,
996
996
  }
997
997
 
998
- def parse_ledger_entry(self, entry, currency: Currency = None):
998
+ def parse_ledger_entry(self, entry, currency: Currency = None) -> LedgerEntry:
999
999
  # details = self.safe_value(entry, 'details', {})
1000
1000
  id = self.safe_string(entry, 'row_index')
1001
1001
  account_id = self.safe_string(entry, 'account_id')
1002
1002
  timestamp = self.safe_integer(entry, 'timestamp')
1003
1003
  currencyId = self.safe_string(entry, 'currency')
1004
1004
  code = self.safe_currency_code(currencyId, currency)
1005
+ currency = self.safe_currency(currencyId, currency)
1005
1006
  available_delta = self.safe_string(entry, 'available_delta')
1006
1007
  balance_delta = self.safe_string(entry, 'balance_delta')
1007
1008
  after = self.safe_string(entry, 'balance')
@@ -1027,7 +1028,8 @@ class luno(Exchange, ImplicitAPI):
1027
1028
  direction = 'in'
1028
1029
  elif Precise.string_lt(balance_delta, '0') or Precise.string_lt(available_delta, '0'):
1029
1030
  direction = 'out'
1030
- return {
1031
+ return self.safe_ledger_entry({
1032
+ 'info': entry,
1031
1033
  'id': id,
1032
1034
  'direction': direction,
1033
1035
  'account': account_id,
@@ -1035,15 +1037,14 @@ class luno(Exchange, ImplicitAPI):
1035
1037
  'referenceAccount': None,
1036
1038
  'type': type,
1037
1039
  'currency': code,
1038
- 'amount': self.parse_number(amount),
1040
+ 'amount': self.parse_to_numeric(amount),
1039
1041
  'timestamp': timestamp,
1040
1042
  'datetime': self.iso8601(timestamp),
1041
- 'before': self.parse_number(before),
1042
- 'after': self.parse_number(after),
1043
+ 'before': self.parse_to_numeric(before),
1044
+ 'after': self.parse_to_numeric(after),
1043
1045
  'status': status,
1044
1046
  'fee': None,
1045
- 'info': entry,
1046
- }
1047
+ }, currency)
1047
1048
 
1048
1049
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
1049
1050
  url = self.urls['api'][api] + '/' + self.version + '/' + self.implode_params(path, params)