ccxt 4.4.3__py2.py3-none-any.whl → 4.4.5__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 (90) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/binanceus.py +36 -36
  3. ccxt/async_support/__init__.py +1 -1
  4. ccxt/async_support/base/exchange.py +24 -13
  5. ccxt/async_support/base/ws/cache.py +1 -0
  6. ccxt/async_support/binance.py +43 -18
  7. ccxt/async_support/binanceus.py +1 -0
  8. ccxt/async_support/bingx.py +1 -0
  9. ccxt/async_support/bitfinex2.py +10 -9
  10. ccxt/async_support/bitget.py +55 -99
  11. ccxt/async_support/bitmex.py +14 -13
  12. ccxt/async_support/bitso.py +8 -7
  13. ccxt/async_support/bitstamp.py +12 -12
  14. ccxt/async_support/blofin.py +24 -26
  15. ccxt/async_support/bybit.py +101 -29
  16. ccxt/async_support/coinbase.py +31 -10
  17. ccxt/async_support/coinbaseexchange.py +14 -14
  18. ccxt/async_support/coinlist.py +9 -8
  19. ccxt/async_support/coinmetro.py +6 -6
  20. ccxt/async_support/cryptocom.py +10 -8
  21. ccxt/async_support/currencycom.py +9 -9
  22. ccxt/async_support/delta.py +8 -8
  23. ccxt/async_support/digifinex.py +11 -9
  24. ccxt/async_support/gate.py +9 -8
  25. ccxt/async_support/hashkey.py +12 -10
  26. ccxt/async_support/htx.py +16 -19
  27. ccxt/async_support/hyperliquid.py +70 -117
  28. ccxt/async_support/kraken.py +12 -10
  29. ccxt/async_support/kucoin.py +12 -11
  30. ccxt/async_support/luno.py +13 -12
  31. ccxt/async_support/lykke.py +2 -2
  32. ccxt/async_support/mexc.py +41 -3
  33. ccxt/async_support/ndax.py +9 -8
  34. ccxt/async_support/okcoin.py +21 -30
  35. ccxt/async_support/okx.py +21 -29
  36. ccxt/async_support/paradex.py +1 -1
  37. ccxt/async_support/woo.py +10 -9
  38. ccxt/async_support/woofipro.py +11 -9
  39. ccxt/async_support/xt.py +7 -6
  40. ccxt/async_support/zonda.py +9 -8
  41. ccxt/base/exchange.py +3 -1
  42. ccxt/binance.py +43 -18
  43. ccxt/binanceus.py +1 -0
  44. ccxt/bingx.py +1 -0
  45. ccxt/bitfinex2.py +10 -9
  46. ccxt/bitget.py +55 -99
  47. ccxt/bitmex.py +14 -13
  48. ccxt/bitso.py +8 -7
  49. ccxt/bitstamp.py +12 -12
  50. ccxt/blofin.py +24 -26
  51. ccxt/bybit.py +101 -29
  52. ccxt/coinbase.py +31 -10
  53. ccxt/coinbaseexchange.py +14 -14
  54. ccxt/coinlist.py +9 -8
  55. ccxt/coinmetro.py +6 -6
  56. ccxt/cryptocom.py +10 -8
  57. ccxt/currencycom.py +9 -9
  58. ccxt/delta.py +8 -8
  59. ccxt/digifinex.py +11 -9
  60. ccxt/gate.py +9 -8
  61. ccxt/hashkey.py +12 -10
  62. ccxt/htx.py +16 -19
  63. ccxt/hyperliquid.py +70 -117
  64. ccxt/kraken.py +12 -10
  65. ccxt/kucoin.py +12 -11
  66. ccxt/luno.py +13 -12
  67. ccxt/lykke.py +2 -2
  68. ccxt/mexc.py +40 -3
  69. ccxt/ndax.py +9 -8
  70. ccxt/okcoin.py +21 -30
  71. ccxt/okx.py +21 -29
  72. ccxt/paradex.py +1 -1
  73. ccxt/pro/__init__.py +1 -1
  74. ccxt/pro/binance.py +6 -2
  75. ccxt/pro/binanceus.py +2 -1
  76. ccxt/pro/bybit.py +51 -0
  77. ccxt/pro/hyperliquid.py +14 -1
  78. ccxt/pro/mexc.py +78 -0
  79. ccxt/pro/paradex.py +1 -0
  80. ccxt/test/tests_async.py +1 -1
  81. ccxt/test/tests_sync.py +1 -1
  82. ccxt/woo.py +10 -9
  83. ccxt/woofipro.py +11 -9
  84. ccxt/xt.py +7 -6
  85. ccxt/zonda.py +9 -8
  86. {ccxt-4.4.3.dist-info → ccxt-4.4.5.dist-info}/METADATA +5 -5
  87. {ccxt-4.4.3.dist-info → ccxt-4.4.5.dist-info}/RECORD +90 -90
  88. {ccxt-4.4.3.dist-info → ccxt-4.4.5.dist-info}/LICENSE.txt +0 -0
  89. {ccxt-4.4.3.dist-info → ccxt-4.4.5.dist-info}/WHEEL +0 -0
  90. {ccxt-4.4.3.dist-info → ccxt-4.4.5.dist-info}/top_level.txt +0 -0
@@ -8,7 +8,7 @@ from ccxt.abstract.bitget import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
10
  import json
11
- from ccxt.base.types import Balances, Conversion, CrossBorrowRate, Currencies, Currency, FundingHistory, Int, IsolatedBorrowRate, Leverage, LeverageTier, Liquidation, MarginMode, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
11
+ from ccxt.base.types import Balances, Conversion, CrossBorrowRate, Currencies, Currency, FundingHistory, Int, IsolatedBorrowRate, LedgerEntry, Leverage, LeverageTier, Liquidation, MarginMode, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
12
12
  from typing import List
13
13
  from ccxt.base.errors import ExchangeError
14
14
  from ccxt.base.errors import AuthenticationError
@@ -1535,6 +1535,7 @@ class bitget(Exchange, ImplicitAPI):
1535
1535
  retrieves data on all markets for bitget
1536
1536
  :see: https://www.bitget.com/api-doc/spot/market/Get-Symbols
1537
1537
  :see: https://www.bitget.com/api-doc/contract/market/Get-All-Symbols-Contracts
1538
+ :see: https://www.bitget.com/api-doc/margin/common/support-currencies
1538
1539
  :param dict [params]: extra parameters specific to the exchange API endpoint
1539
1540
  :returns dict[]: an array of objects representing market data
1540
1541
  """
@@ -1543,9 +1544,10 @@ class bitget(Exchange, ImplicitAPI):
1543
1544
  if sandboxMode:
1544
1545
  types = ['swap']
1545
1546
  promises = []
1547
+ fetchMargins = False
1546
1548
  for i in range(0, len(types)):
1547
1549
  type = types[i]
1548
- if type == 'swap':
1550
+ if (type == 'swap') or (type == 'future'):
1549
1551
  subTypes = None
1550
1552
  if sandboxMode:
1551
1553
  # the following are simulated trading markets ['SUSDT-FUTURES', 'SCOIN-FUTURES', 'SUSDC-FUTURES']
@@ -1553,15 +1555,33 @@ class bitget(Exchange, ImplicitAPI):
1553
1555
  else:
1554
1556
  subTypes = ['USDT-FUTURES', 'COIN-FUTURES', 'USDC-FUTURES']
1555
1557
  for j in range(0, len(subTypes)):
1556
- promises.append(self.fetch_markets_by_type(type, self.extend(params, {
1558
+ promises.append(self.publicMixGetV2MixMarketContracts(self.extend(params, {
1557
1559
  'productType': subTypes[j],
1558
1560
  })))
1561
+ elif type == 'spot':
1562
+ promises.append(self.publicSpotGetV2SpotPublicSymbols(params))
1563
+ fetchMargins = True
1564
+ promises.append(self.publicMarginGetV2MarginCurrencies(params))
1565
+ else:
1566
+ raise NotSupported(self.id + ' does not support ' + type + ' market')
1567
+ results = await asyncio.gather(*promises)
1568
+ markets = []
1569
+ self.options['crossMarginPairsData'] = []
1570
+ self.options['isolatedMarginPairsData'] = []
1571
+ for i in range(0, len(results)):
1572
+ res = self.safe_dict(results, i)
1573
+ data = self.safe_list(res, 'data', [])
1574
+ firstData = self.safe_dict(data, 0, {})
1575
+ isBorrowable = self.safe_string(firstData, 'isBorrowable')
1576
+ if fetchMargins and isBorrowable is not None:
1577
+ keysList = list(self.index_by(data, 'symbol').keys())
1578
+ self.options['crossMarginPairsData'] = keysList
1579
+ self.options['isolatedMarginPairsData'] = keysList
1559
1580
  else:
1560
- promises.append(self.fetch_markets_by_type(types[i], params))
1561
- promises = await asyncio.gather(*promises)
1562
- result = promises[0]
1563
- for i in range(1, len(promises)):
1564
- result = self.array_concat(result, promises[i])
1581
+ markets = self.array_concat(markets, data)
1582
+ result = []
1583
+ for i in range(0, len(markets)):
1584
+ result.append(self.parse_market(markets[i]))
1565
1585
  return result
1566
1586
 
1567
1587
  def parse_market(self, market: dict) -> Market:
@@ -1649,11 +1669,20 @@ class bitget(Exchange, ImplicitAPI):
1649
1669
  expiry = None
1650
1670
  expiryDatetime = None
1651
1671
  symbolType = self.safe_string(market, 'symbolType')
1672
+ marginModes = None
1673
+ isMarginTradingAllowed = False
1652
1674
  if symbolType is None:
1653
1675
  type = 'spot'
1654
1676
  spot = True
1655
1677
  pricePrecision = self.parse_number(self.parse_precision(self.safe_string(market, 'pricePrecision')))
1656
1678
  amountPrecision = self.parse_number(self.parse_precision(self.safe_string(market, 'quantityPrecision')))
1679
+ hasCrossMargin = self.in_array(marketId, self.options['crossMarginPairsData'])
1680
+ hasIsolatedMargin = self.in_array(marketId, self.options['isolatedMarginPairsData'])
1681
+ marginModes = {
1682
+ 'cross': hasCrossMargin,
1683
+ 'isolated': hasIsolatedMargin,
1684
+ }
1685
+ isMarginTradingAllowed = hasCrossMargin or hasCrossMargin
1657
1686
  else:
1658
1687
  if symbolType == 'perpetual':
1659
1688
  type = 'swap'
@@ -1689,6 +1718,10 @@ class bitget(Exchange, ImplicitAPI):
1689
1718
  preciseAmount.reduce()
1690
1719
  amountString = str(preciseAmount)
1691
1720
  amountPrecision = self.parse_number(amountString)
1721
+ marginModes = {
1722
+ 'cross': True,
1723
+ 'isolated': True,
1724
+ }
1692
1725
  status = self.safe_string_2(market, 'status', 'symbolStatus')
1693
1726
  active = None
1694
1727
  if status is not None:
@@ -1708,7 +1741,8 @@ class bitget(Exchange, ImplicitAPI):
1708
1741
  'settleId': settleId,
1709
1742
  'type': type,
1710
1743
  'spot': spot,
1711
- 'margin': None,
1744
+ 'margin': spot and isMarginTradingAllowed,
1745
+ 'marginModes': marginModes,
1712
1746
  'swap': swap,
1713
1747
  'future': future,
1714
1748
  'option': False,
@@ -1749,88 +1783,6 @@ class bitget(Exchange, ImplicitAPI):
1749
1783
  'info': market,
1750
1784
  }
1751
1785
 
1752
- async def fetch_markets_by_type(self, type, params={}):
1753
- response = None
1754
- if type == 'spot':
1755
- response = await self.publicSpotGetV2SpotPublicSymbols(params)
1756
- elif (type == 'swap') or (type == 'future'):
1757
- response = await self.publicMixGetV2MixMarketContracts(params)
1758
- else:
1759
- raise NotSupported(self.id + ' does not support ' + type + ' market')
1760
- #
1761
- # spot
1762
- #
1763
- # {
1764
- # "code": "00000",
1765
- # "msg": "success",
1766
- # "requestTime": 1700102364653,
1767
- # "data": [
1768
- # {
1769
- # "symbol": "TRXUSDT",
1770
- # "baseCoin": "TRX",
1771
- # "quoteCoin": "USDT",
1772
- # "minTradeAmount": "0",
1773
- # "maxTradeAmount": "10000000000",
1774
- # "takerFeeRate": "0.002",
1775
- # "makerFeeRate": "0.002",
1776
- # "pricePrecision": "6",
1777
- # "quantityPrecision": "4",
1778
- # "quotePrecision": "6",
1779
- # "status": "online",
1780
- # "minTradeUSDT": "5",
1781
- # "buyLimitPriceRatio": "0.05",
1782
- # "sellLimitPriceRatio": "0.05"
1783
- # },
1784
- # ]
1785
- # }
1786
- #
1787
- # swap and future
1788
- #
1789
- # {
1790
- # "code": "00000",
1791
- # "msg": "success",
1792
- # "requestTime": 1700102364709,
1793
- # "data": [
1794
- # {
1795
- # "symbol": "BTCUSDT",
1796
- # "baseCoin": "BTC",
1797
- # "quoteCoin": "USDT",
1798
- # "buyLimitPriceRatio": "0.01",
1799
- # "sellLimitPriceRatio": "0.01",
1800
- # "feeRateUpRatio": "0.005",
1801
- # "makerFeeRate": "0.0002",
1802
- # "takerFeeRate": "0.0006",
1803
- # "openCostUpRatio": "0.01",
1804
- # "supportMarginCoins": ["USDT"],
1805
- # "minTradeNum": "0.001",
1806
- # "priceEndStep": "1",
1807
- # "volumePlace": "3",
1808
- # "pricePlace": "1",
1809
- # "sizeMultiplier": "0.001",
1810
- # "symbolType": "perpetual",
1811
- # "minTradeUSDT": "5",
1812
- # "maxSymbolOrderNum": "200",
1813
- # "maxProductOrderNum": "400",
1814
- # "maxPositionNum": "150",
1815
- # "symbolStatus": "normal",
1816
- # "offTime": "-1",
1817
- # "limitOpenTime": "-1",
1818
- # "deliveryTime": "",
1819
- # "deliveryStartTime": "",
1820
- # "deliveryPeriod": "",
1821
- # "launchTime": "",
1822
- # "fundInterval": "8",
1823
- # "minLever": "1",
1824
- # "maxLever": "125",
1825
- # "posLimit": "0.05",
1826
- # "maintainTime": ""
1827
- # },
1828
- # ]
1829
- # }
1830
- #
1831
- data = self.safe_value(response, 'data', [])
1832
- return self.parse_markets(data)
1833
-
1834
1786
  async def fetch_currencies(self, params={}) -> Currencies:
1835
1787
  """
1836
1788
  fetches all available currencies on an exchange
@@ -5493,14 +5445,14 @@ class bitget(Exchange, ImplicitAPI):
5493
5445
  orders = self.safe_list(response, 'data', [])
5494
5446
  return self.parse_orders(orders, market, since, limit)
5495
5447
 
5496
- async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
5448
+ async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
5497
5449
  """
5450
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
5498
5451
  :see: https://www.bitget.com/api-doc/spot/account/Get-Account-Bills
5499
5452
  :see: https://www.bitget.com/api-doc/contract/account/Get-Account-Bill
5500
- fetch the history of changes, actions done by the user or operations that altered balance of the user
5501
- :param str code: unified currency code, default is None
5453
+ :param str [code]: unified currency code, default is None
5502
5454
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
5503
- :param int [limit]: max number of ledger entrys to return, default is None
5455
+ :param int [limit]: max number of ledger entries to return, default is None
5504
5456
  :param dict [params]: extra parameters specific to the exchange API endpoint
5505
5457
  :param int [params.until]: end time in ms
5506
5458
  :param str [params.symbol]: *contract only* unified market symbol
@@ -5598,7 +5550,7 @@ class bitget(Exchange, ImplicitAPI):
5598
5550
  return self.parse_ledger(bills, currency, since, limit)
5599
5551
  return self.parse_ledger(data, currency, since, limit)
5600
5552
 
5601
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
5553
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
5602
5554
  #
5603
5555
  # spot
5604
5556
  #
@@ -5628,6 +5580,7 @@ class bitget(Exchange, ImplicitAPI):
5628
5580
  #
5629
5581
  currencyId = self.safe_string(item, 'coin')
5630
5582
  code = self.safe_currency_code(currencyId, currency)
5583
+ currency = self.safe_currency(currencyId, currency)
5631
5584
  timestamp = self.safe_integer(item, 'cTime')
5632
5585
  after = self.safe_number(item, 'balance')
5633
5586
  fee = self.safe_number_2(item, 'fees', 'fee')
@@ -5636,7 +5589,7 @@ class bitget(Exchange, ImplicitAPI):
5636
5589
  direction = 'in'
5637
5590
  if amountRaw.find('-') >= 0:
5638
5591
  direction = 'out'
5639
- return {
5592
+ return self.safe_ledger_entry({
5640
5593
  'info': item,
5641
5594
  'id': self.safe_string(item, 'billId'),
5642
5595
  'timestamp': timestamp,
@@ -5651,8 +5604,11 @@ class bitget(Exchange, ImplicitAPI):
5651
5604
  'before': None,
5652
5605
  'after': after,
5653
5606
  'status': None,
5654
- 'fee': fee,
5655
- }
5607
+ 'fee': {
5608
+ 'currency': code,
5609
+ 'cost': fee,
5610
+ },
5611
+ }, currency)
5656
5612
 
5657
5613
  def parse_ledger_type(self, type):
5658
5614
  types: dict = {
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.bitmex import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currencies, Currency, Int, Leverage, Leverages, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
9
+ from ccxt.base.types import Balances, Currencies, Currency, Int, LedgerEntry, Leverage, Leverages, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -1050,7 +1050,7 @@ class bitmex(Exchange, ImplicitAPI):
1050
1050
  }
1051
1051
  return self.safe_string(types, type, type)
1052
1052
 
1053
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
1053
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
1054
1054
  #
1055
1055
  # {
1056
1056
  # "transactID": "69573da3-7744-5467-3207-89fd6efe7a47",
@@ -1099,6 +1099,7 @@ class bitmex(Exchange, ImplicitAPI):
1099
1099
  type = self.parse_ledger_entry_type(self.safe_string(item, 'transactType'))
1100
1100
  currencyId = self.safe_string(item, 'currency')
1101
1101
  code = self.safe_currency_code(currencyId, currency)
1102
+ currency = self.safe_currency(currencyId, currency)
1102
1103
  amountString = self.safe_string(item, 'amount')
1103
1104
  amount = self.convert_to_real_amount(code, amountString)
1104
1105
  timestamp = self.parse8601(self.safe_string(item, 'transactTime'))
@@ -1111,13 +1112,13 @@ class bitmex(Exchange, ImplicitAPI):
1111
1112
  if feeCost is not None:
1112
1113
  feeCost = self.convert_to_real_amount(code, feeCost)
1113
1114
  fee = {
1114
- 'cost': self.parse_number(feeCost),
1115
+ 'cost': self.parse_to_numeric(feeCost),
1115
1116
  'currency': code,
1116
1117
  }
1117
1118
  after = self.safe_string(item, 'walletBalance')
1118
1119
  if after is not None:
1119
1120
  after = self.convert_to_real_amount(code, after)
1120
- before = self.parse_number(Precise.string_sub(self.number_to_string(after), self.number_to_string(amount)))
1121
+ before = self.parse_to_numeric(Precise.string_sub(self.number_to_string(after), self.number_to_string(amount)))
1121
1122
  direction = None
1122
1123
  if Precise.string_lt(amountString, '0'):
1123
1124
  direction = 'out'
@@ -1125,9 +1126,9 @@ class bitmex(Exchange, ImplicitAPI):
1125
1126
  else:
1126
1127
  direction = 'in'
1127
1128
  status = self.parse_transaction_status(self.safe_string(item, 'transactStatus'))
1128
- return {
1129
- 'id': id,
1129
+ return self.safe_ledger_entry({
1130
1130
  'info': item,
1131
+ 'id': id,
1131
1132
  'timestamp': timestamp,
1132
1133
  'datetime': self.iso8601(timestamp),
1133
1134
  'direction': direction,
@@ -1136,20 +1137,20 @@ class bitmex(Exchange, ImplicitAPI):
1136
1137
  'referenceAccount': referenceAccount,
1137
1138
  'type': type,
1138
1139
  'currency': code,
1139
- 'amount': amount,
1140
+ 'amount': self.parse_to_numeric(amount),
1140
1141
  'before': before,
1141
- 'after': self.parse_number(after),
1142
+ 'after': self.parse_to_numeric(after),
1142
1143
  'status': status,
1143
1144
  'fee': fee,
1144
- }
1145
+ }, currency)
1145
1146
 
1146
- async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
1147
+ async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
1147
1148
  """
1148
- fetch the history of changes, actions done by the user or operations that altered balance of the user
1149
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
1149
1150
  :see: https://www.bitmex.com/api/explorer/#not /User/User_getWalletHistory
1150
- :param str code: unified currency code, default is None
1151
+ :param str [code]: unified currency code, default is None
1151
1152
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
1152
- :param int [limit]: max number of ledger entrys to return, default is None
1153
+ :param int [limit]: max number of ledger entries to return, default is None
1153
1154
  :param dict [params]: extra parameters specific to the exchange API endpoint
1154
1155
  :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
1155
1156
  """
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.bitso import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Trade, TradingFees, Transaction
9
+ from ccxt.base.types import Balances, Currency, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Trade, TradingFees, Transaction
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -195,12 +195,12 @@ class bitso(Exchange, ImplicitAPI):
195
195
  },
196
196
  })
197
197
 
198
- async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
198
+ async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
199
199
  """
200
- fetch the history of changes, actions done by the user or operations that altered balance of the user
201
- :param str code: unified currency code, default is None
200
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
201
+ :param str [code]: unified currency code, default is None
202
202
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
203
- :param int [limit]: max number of ledger entrys to return, default is None
203
+ :param int [limit]: max number of ledger entries to return, default is None
204
204
  :param dict [params]: extra parameters specific to the exchange API endpoint
205
205
  :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
206
206
  """
@@ -244,7 +244,7 @@ class bitso(Exchange, ImplicitAPI):
244
244
  }
245
245
  return self.safe_string(types, type, type)
246
246
 
247
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
247
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
248
248
  #
249
249
  # {
250
250
  # "eid": "2510b3e2bc1c87f584500a18084f35ed",
@@ -308,6 +308,7 @@ class bitso(Exchange, ImplicitAPI):
308
308
  amount = self.safe_string(firstBalance, 'amount')
309
309
  currencyId = self.safe_string(firstBalance, 'currency')
310
310
  code = self.safe_currency_code(currencyId, currency)
311
+ currency = self.safe_currency(currencyId, currency)
311
312
  details = self.safe_value(item, 'details', {})
312
313
  referenceId = self.safe_string_2(details, 'fid', 'wid')
313
314
  if referenceId is None:
@@ -327,6 +328,7 @@ class bitso(Exchange, ImplicitAPI):
327
328
  }
328
329
  timestamp = self.parse8601(self.safe_string(item, 'created_at'))
329
330
  return self.safe_ledger_entry({
331
+ 'info': item,
330
332
  'id': self.safe_string(item, 'eid'),
331
333
  'direction': direction,
332
334
  'account': None,
@@ -341,7 +343,6 @@ class bitso(Exchange, ImplicitAPI):
341
343
  'after': None,
342
344
  'status': 'ok',
343
345
  'fee': fee,
344
- 'info': item,
345
346
  }, currency)
346
347
 
347
348
  async def fetch_markets(self, params={}) -> List[Market]:
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.bitstamp import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
9
+ from ccxt.base.types import Balances, Currencies, Currency, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -1831,7 +1831,7 @@ class bitstamp(Exchange, ImplicitAPI):
1831
1831
  }
1832
1832
  return self.safe_string(types, type, type)
1833
1833
 
1834
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
1834
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
1835
1835
  #
1836
1836
  # [
1837
1837
  # {
@@ -1872,9 +1872,9 @@ class bitstamp(Exchange, ImplicitAPI):
1872
1872
  if market is None:
1873
1873
  market = self.get_market_from_trade(item)
1874
1874
  direction = 'in' if (parsedTrade['side'] == 'buy') else 'out'
1875
- return {
1876
- 'id': parsedTrade['id'],
1875
+ return self.safe_ledger_entry({
1877
1876
  'info': item,
1877
+ 'id': parsedTrade['id'],
1878
1878
  'timestamp': parsedTrade['timestamp'],
1879
1879
  'datetime': parsedTrade['datetime'],
1880
1880
  'direction': direction,
@@ -1888,7 +1888,7 @@ class bitstamp(Exchange, ImplicitAPI):
1888
1888
  'after': None,
1889
1889
  'status': 'ok',
1890
1890
  'fee': parsedTrade['fee'],
1891
- }
1891
+ }, currency)
1892
1892
  else:
1893
1893
  parsedTransaction = self.parse_transaction(item, currency)
1894
1894
  direction = None
@@ -1900,9 +1900,9 @@ class bitstamp(Exchange, ImplicitAPI):
1900
1900
  currency = self.currency(currencyCode)
1901
1901
  amount = self.safe_string(item, currency['id'])
1902
1902
  direction = 'in' if Precise.string_gt(amount, '0') else 'out'
1903
- return {
1904
- 'id': parsedTransaction['id'],
1903
+ return self.safe_ledger_entry({
1905
1904
  'info': item,
1905
+ 'id': parsedTransaction['id'],
1906
1906
  'timestamp': parsedTransaction['timestamp'],
1907
1907
  'datetime': parsedTransaction['datetime'],
1908
1908
  'direction': direction,
@@ -1916,15 +1916,15 @@ class bitstamp(Exchange, ImplicitAPI):
1916
1916
  'after': None,
1917
1917
  'status': parsedTransaction['status'],
1918
1918
  'fee': parsedTransaction['fee'],
1919
- }
1919
+ }, currency)
1920
1920
 
1921
- async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
1921
+ async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
1922
1922
  """
1923
- fetch the history of changes, actions done by the user or operations that altered balance of the user
1923
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
1924
1924
  :see: https://www.bitstamp.net/api/#tag/Transactions-private/operation/GetUserTransactions
1925
- :param str code: unified currency code, default is None
1925
+ :param str [code]: unified currency code, default is None
1926
1926
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
1927
- :param int [limit]: max number of ledger entrys to return, default is None
1927
+ :param int [limit]: max number of ledger entries to return, default is None
1928
1928
  :param dict [params]: extra parameters specific to the exchange API endpoint
1929
1929
  :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
1930
1930
  """
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.blofin import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currency, Int, Leverage, Leverages, MarginMode, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
9
+ from ccxt.base.types import Balances, Currency, Int, LedgerEntry, Leverage, Leverages, MarginMode, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, 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
@@ -1413,17 +1413,17 @@ class blofin(Exchange, ImplicitAPI):
1413
1413
  data = self.safe_list(response, 'data', [])
1414
1414
  return self.parse_transactions(data, currency, since, limit, params)
1415
1415
 
1416
- async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
1416
+ async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
1417
1417
  """
1418
- fetch the history of changes, actions done by the user or operations that altered balance of the user
1418
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
1419
1419
  :see: https://blofin.com/docs#get-funds-transfer-history
1420
- :param str code: unified currency code, default is None
1420
+ :param str [code]: unified currency code, default is None
1421
1421
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
1422
- :param int [limit]: max number of ledger entrys to return, default is None
1422
+ :param int [limit]: max number of ledger entries to return, default is None
1423
1423
  :param dict [params]: extra parameters specific to the exchange API endpoint
1424
1424
  :param str [params.marginMode]: 'cross' or 'isolated'
1425
1425
  :param int [params.until]: the latest time in ms to fetch entries for
1426
- :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)
1426
+ :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)
1427
1427
  :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
1428
1428
  """
1429
1429
  await self.load_markets()
@@ -1554,30 +1554,28 @@ class blofin(Exchange, ImplicitAPI):
1554
1554
  }
1555
1555
  return self.safe_string(types, type, type)
1556
1556
 
1557
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
1558
- id = self.safe_string(item, 'transferId')
1559
- referenceId = self.safe_string(item, 'clientId')
1560
- fromAccount = self.safe_string(item, 'fromAccount')
1561
- toAccount = self.safe_string(item, 'toAccount')
1562
- type = self.parse_ledger_entry_type(self.safe_string(item, 'type'))
1563
- code = self.safe_currency_code(self.safe_string(item, 'currency'), currency)
1564
- amountString = self.safe_string(item, 'amount')
1565
- amount = self.parse_number(amountString)
1557
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
1558
+ currencyId = self.safe_string(item, 'currency')
1559
+ code = self.safe_currency_code(currencyId, currency)
1560
+ currency = self.safe_currency(currencyId, currency)
1566
1561
  timestamp = self.safe_integer(item, 'ts')
1567
- status = 'ok'
1568
- return {
1569
- 'id': id,
1562
+ return self.safe_ledger_entry({
1570
1563
  'info': item,
1564
+ 'id': self.safe_string(item, 'transferId'),
1565
+ 'direction': None,
1566
+ 'account': None,
1567
+ 'referenceId': self.safe_string(item, 'clientId'),
1568
+ 'referenceAccount': None,
1569
+ 'type': self.parse_ledger_entry_type(self.safe_string(item, 'type')),
1570
+ 'currency': code,
1571
+ 'amount': self.safe_number(item, 'amount'),
1571
1572
  'timestamp': timestamp,
1572
1573
  'datetime': self.iso8601(timestamp),
1573
- 'fromAccount': fromAccount,
1574
- 'toAccount': toAccount,
1575
- 'type': type,
1576
- 'currency': code,
1577
- 'amount': amount,
1578
- 'clientId': referenceId, # balance before
1579
- 'status': status,
1580
- }
1574
+ 'before': None,
1575
+ 'after': None,
1576
+ 'status': 'ok',
1577
+ 'fee': None,
1578
+ }, currency)
1581
1579
 
1582
1580
  def parse_ids(self, ids):
1583
1581
  """