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/mexc.py CHANGED
@@ -1007,8 +1007,9 @@ class mexc(Exchange, ImplicitAPI):
1007
1007
  :param dict [params]: extra parameters specific to the exchange API endpoint
1008
1008
  :returns dict[]: an array of objects representing market data
1009
1009
  """
1010
- spotMarket = self.fetch_spot_markets(params)
1011
- swapMarket = self.fetch_swap_markets(params)
1010
+ spotMarketPromise = self.fetch_spot_markets(params)
1011
+ swapMarketPromise = self.fetch_swap_markets(params)
1012
+ spotMarket, swapMarket = [spotMarketPromise, swapMarketPromise]
1012
1013
  return self.array_concat(spotMarket, swapMarket)
1013
1014
 
1014
1015
  def fetch_spot_markets(self, params={}):
@@ -1141,7 +1142,10 @@ class mexc(Exchange, ImplicitAPI):
1141
1142
  :param dict [params]: extra parameters specific to the exchange API endpoint
1142
1143
  :returns dict[]: an array of objects representing market data
1143
1144
  """
1145
+ currentRl: number = self.rateLimit
1146
+ self.set_property(self, 'rateLimit', 10) # see comment: https://github.com/ccxt/ccxt/pull/23698
1144
1147
  response = self.contractPublicGetDetail(params)
1148
+ self.set_property(self, 'rateLimit', currentRl)
1145
1149
  #
1146
1150
  # {
1147
1151
  # "success":true,
@@ -2865,6 +2869,9 @@ class mexc(Exchange, ImplicitAPI):
2865
2869
  def cancel_all_orders(self, symbol: Str = None, params={}):
2866
2870
  """
2867
2871
  cancel all open orders
2872
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#cancel-all-open-orders-on-a-symbol
2873
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#cancel-all-orders-under-a-contract-under-maintenance
2874
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#cancel-all-trigger-orders-under-maintenance
2868
2875
  :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
2869
2876
  :param dict [params]: extra parameters specific to the exchange API endpoint
2870
2877
  :param str [params.marginMode]: only 'isolated' is supported for spot-margin trading
@@ -3251,6 +3258,8 @@ class mexc(Exchange, ImplicitAPI):
3251
3258
  def fetch_accounts(self, params={}) -> List[Account]:
3252
3259
  """
3253
3260
  fetch all the accounts associated with a profile
3261
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#account-information
3262
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-all-informations-of-user-39-s-asset
3254
3263
  :param dict [params]: extra parameters specific to the exchange API endpoint
3255
3264
  :returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
3256
3265
  """
@@ -3275,6 +3284,8 @@ class mexc(Exchange, ImplicitAPI):
3275
3284
  def fetch_trading_fees(self, params={}) -> TradingFees:
3276
3285
  """
3277
3286
  fetch the trading fees for multiple markets
3287
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#account-information
3288
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-all-informations-of-user-39-s-asset
3278
3289
  :param dict [params]: extra parameters specific to the exchange API endpoint
3279
3290
  :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
3280
3291
  """
@@ -3539,6 +3550,8 @@ class mexc(Exchange, ImplicitAPI):
3539
3550
  def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
3540
3551
  """
3541
3552
  fetch all trades made by the user
3553
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#account-trade-list
3554
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-all-transaction-details-of-the-user-s-order
3542
3555
  :param str symbol: unified market symbol
3543
3556
  :param int [since]: the earliest time in ms to fetch trades for
3544
3557
  :param int [limit]: the maximum number of trades structures to retrieve
@@ -3619,6 +3632,8 @@ class mexc(Exchange, ImplicitAPI):
3619
3632
  def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
3620
3633
  """
3621
3634
  fetch all the trades made from a single order
3635
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#account-trade-list
3636
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#query-the-order-based-on-the-order-number
3622
3637
  :param str id: order id
3623
3638
  :param str symbol: unified market symbol
3624
3639
  :param int [since]: the earliest time in ms to fetch trades for
@@ -3710,6 +3725,7 @@ class mexc(Exchange, ImplicitAPI):
3710
3725
  def reduce_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
3711
3726
  """
3712
3727
  remove margin from a position
3728
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#increase-or-decrease-margin
3713
3729
  :param str symbol: unified market symbol
3714
3730
  :param float amount: the amount of margin to remove
3715
3731
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -3720,6 +3736,7 @@ class mexc(Exchange, ImplicitAPI):
3720
3736
  def add_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
3721
3737
  """
3722
3738
  add margin
3739
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#increase-or-decrease-margin
3723
3740
  :param str symbol: unified market symbol
3724
3741
  :param float amount: amount of margin to add
3725
3742
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -3730,6 +3747,7 @@ class mexc(Exchange, ImplicitAPI):
3730
3747
  def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
3731
3748
  """
3732
3749
  set the level of leverage for a market
3750
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#switch-leverage
3733
3751
  :param float leverage: the rate of leverage
3734
3752
  :param str symbol: unified market symbol
3735
3753
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -3757,6 +3775,7 @@ class mexc(Exchange, ImplicitAPI):
3757
3775
  def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
3758
3776
  """
3759
3777
  fetch the history of funding payments paid and received on self account
3778
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-details-of-user-s-funding-rate
3760
3779
  :param str symbol: unified market symbol
3761
3780
  :param int [since]: the earliest time in ms to fetch funding history for
3762
3781
  :param int [limit]: the maximum number of funding history structures to retrieve
@@ -3867,6 +3886,7 @@ class mexc(Exchange, ImplicitAPI):
3867
3886
  def fetch_funding_rate(self, symbol: str, params={}):
3868
3887
  """
3869
3888
  fetch the current funding rate
3889
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-contract-funding-rate
3870
3890
  :param str symbol: unified market symbol
3871
3891
  :param dict [params]: extra parameters specific to the exchange API endpoint
3872
3892
  :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
@@ -3898,6 +3918,7 @@ class mexc(Exchange, ImplicitAPI):
3898
3918
  def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
3899
3919
  """
3900
3920
  fetches historical funding rate prices
3921
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-contract-funding-rate-history
3901
3922
  :param str symbol: unified symbol of the market to fetch the funding rate history for
3902
3923
  :param int [since]: not used by mexc, but filtered internally by ccxt
3903
3924
  :param int [limit]: mexc limit is page_size default 20, maximum is 100
@@ -4588,6 +4609,14 @@ class mexc(Exchange, ImplicitAPI):
4588
4609
  })
4589
4610
 
4590
4611
  def fetch_transfer(self, id: str, code: Str = None, params={}) -> TransferEntry:
4612
+ """
4613
+ fetches a transfer
4614
+ :see: https://mexcdevelop.github.io/apidocs/spot_v2_en/#internal-assets-transfer-order-inquiry
4615
+ :param str id: transfer id
4616
+ :param str [code]: not used by mexc fetchTransfer
4617
+ :param dict params: extra parameters specific to the exchange api endpoint
4618
+ :returns dict: a `transfer structure <https://docs.ccxt.com/#/?id=transfer-structure>`
4619
+ """
4591
4620
  marketType, query = self.handle_market_type_and_params('fetchTransfer', None, params)
4592
4621
  self.load_markets()
4593
4622
  if marketType == 'spot':
@@ -4617,6 +4646,8 @@ class mexc(Exchange, ImplicitAPI):
4617
4646
  def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[TransferEntry]:
4618
4647
  """
4619
4648
  fetch a history of internal transfers made on an account
4649
+ :see: https://mexcdevelop.github.io/apidocs/spot_v2_en/#get-internal-assets-transfer-records
4650
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-the-user-39-s-asset-transfer-records
4620
4651
  :param str code: unified currency code of the currency transferred
4621
4652
  :param int [since]: the earliest time in ms to fetch transfers for
4622
4653
  :param int [limit]: the maximum number of transfers structures to retrieve
ccxt/ndax.py CHANGED
@@ -7,7 +7,7 @@ from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.ndax import ImplicitAPI
8
8
  import hashlib
9
9
  import json
10
- from ccxt.base.types import Account, Balances, Currencies, Currency, IndexType, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Ticker, Trade, Transaction
10
+ from ccxt.base.types import Account, Balances, Currencies, Currency, IndexType, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Ticker, Trade, Transaction
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import AuthenticationError
@@ -1084,7 +1084,7 @@ class ndax(Exchange, ImplicitAPI):
1084
1084
  }
1085
1085
  return self.safe_string(types, type, type)
1086
1086
 
1087
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
1087
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
1088
1088
  #
1089
1089
  # {
1090
1090
  # "TransactionId": 2663709493,
@@ -1102,6 +1102,7 @@ class ndax(Exchange, ImplicitAPI):
1102
1102
  # }
1103
1103
  #
1104
1104
  currencyId = self.safe_string(item, 'ProductId')
1105
+ currency = self.safe_currency(currencyId, currency)
1105
1106
  credit = self.safe_string(item, 'CR')
1106
1107
  debit = self.safe_string(item, 'DR')
1107
1108
  amount = None
@@ -1119,7 +1120,7 @@ class ndax(Exchange, ImplicitAPI):
1119
1120
  elif direction == 'in':
1120
1121
  before = Precise.string_max('0', Precise.string_sub(after, amount))
1121
1122
  timestamp = self.safe_integer(item, 'TimeStamp')
1122
- return {
1123
+ return self.safe_ledger_entry({
1123
1124
  'info': item,
1124
1125
  'id': self.safe_string(item, 'TransactionId'),
1125
1126
  'direction': direction,
@@ -1135,15 +1136,15 @@ class ndax(Exchange, ImplicitAPI):
1135
1136
  'timestamp': timestamp,
1136
1137
  'datetime': self.iso8601(timestamp),
1137
1138
  'fee': None,
1138
- }
1139
+ }, currency)
1139
1140
 
1140
- def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
1141
+ def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
1141
1142
  """
1142
- fetch the history of changes, actions done by the user or operations that altered balance of the user
1143
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
1143
1144
  :see: https://apidoc.ndax.io/#getaccounttransactions
1144
- :param str code: unified currency code, default is None
1145
+ :param str [code]: unified currency code, default is None
1145
1146
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
1146
- :param int [limit]: max number of ledger entrys to return, default is None
1147
+ :param int [limit]: max number of ledger entries to return, default is None
1147
1148
  :param dict [params]: extra parameters specific to the exchange API endpoint
1148
1149
  :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
1149
1150
  """
ccxt/okcoin.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.okcoin 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, Transaction, TransferEntry
9
+ from ccxt.base.types import Balances, Currencies, Currency, Int, LedgerEntry, 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 AuthenticationError
@@ -2668,15 +2668,15 @@ class okcoin(Exchange, ImplicitAPI):
2668
2668
  }
2669
2669
  return self.fetch_my_trades(symbol, since, limit, self.extend(request, params))
2670
2670
 
2671
- def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
2671
+ def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
2672
2672
  """
2673
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
2673
2674
  :see: https://www.okcoin.com/docs-v5/en/#rest-api-funding-asset-bills-details
2674
2675
  :see: https://www.okcoin.com/docs-v5/en/#rest-api-account-get-bills-details-last-7-days
2675
2676
  :see: https://www.okcoin.com/docs-v5/en/#rest-api-account-get-bills-details-last-3-months
2676
- fetch the history of changes, actions done by the user or operations that altered balance of the user
2677
- :param str code: unified currency code, default is None
2677
+ :param str [code]: unified currency code, default is None
2678
2678
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
2679
- :param int [limit]: max number of ledger entrys to return, default is None
2679
+ :param int [limit]: max number of ledger entries to return, default is None
2680
2680
  :param dict [params]: extra parameters specific to the exchange API endpoint
2681
2681
  :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
2682
2682
  """
@@ -2776,7 +2776,7 @@ class okcoin(Exchange, ImplicitAPI):
2776
2776
  }
2777
2777
  return self.safe_string(types, type, type)
2778
2778
 
2779
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
2779
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
2780
2780
  #
2781
2781
  # privateGetAccountBills, privateGetAccountBillsArchive
2782
2782
  #
@@ -2813,45 +2813,36 @@ class okcoin(Exchange, ImplicitAPI):
2813
2813
  # "ts": "1597026383085"
2814
2814
  # }
2815
2815
  #
2816
- id = self.safe_string(item, 'billId')
2817
- account = None
2818
- referenceId = self.safe_string(item, 'ordId')
2819
- referenceAccount = None
2820
- type = self.parse_ledger_entry_type(self.safe_string(item, 'type'))
2821
- code = self.safe_currency_code(self.safe_string(item, 'ccy'), currency)
2822
- amountString = self.safe_string(item, 'balChg')
2823
- amount = self.parse_number(amountString)
2816
+ currencyId = self.safe_string(item, 'ccy')
2817
+ code = self.safe_currency_code(currencyId, currency)
2818
+ currency = self.safe_currency(currencyId, currency)
2824
2819
  timestamp = self.safe_integer(item, 'ts')
2825
2820
  feeCostString = self.safe_string(item, 'fee')
2826
2821
  fee = None
2827
2822
  if feeCostString is not None:
2828
2823
  fee = {
2829
- 'cost': self.parse_number(Precise.string_neg(feeCostString)),
2824
+ 'cost': self.parse_to_numeric(Precise.string_neg(feeCostString)),
2830
2825
  'currency': code,
2831
2826
  }
2832
- before = None
2833
- afterString = self.safe_string(item, 'bal')
2834
- after = self.parse_number(afterString)
2835
- status = 'ok'
2836
2827
  marketId = self.safe_string(item, 'instId')
2837
2828
  symbol = self.safe_symbol(marketId, None, '-')
2838
- return {
2839
- 'id': id,
2829
+ return self.safe_ledger_entry({
2840
2830
  'info': item,
2831
+ 'id': self.safe_string(item, 'billId'),
2841
2832
  'timestamp': timestamp,
2842
2833
  'datetime': self.iso8601(timestamp),
2843
- 'account': account,
2844
- 'referenceId': referenceId,
2845
- 'referenceAccount': referenceAccount,
2846
- 'type': type,
2834
+ 'account': None,
2835
+ 'referenceId': self.safe_string(item, 'ordId'),
2836
+ 'referenceAccount': None,
2837
+ 'type': self.parse_ledger_entry_type(self.safe_string(item, 'type')),
2847
2838
  'currency': code,
2848
2839
  'symbol': symbol,
2849
- 'amount': amount,
2850
- 'before': before, # balance before
2851
- 'after': after, # balance after
2852
- 'status': status,
2840
+ 'amount': self.safe_number(item, 'balChg'),
2841
+ 'before': None, # balance before
2842
+ 'after': self.safe_number(item, 'bal'), # balance after
2843
+ 'status': 'ok',
2853
2844
  'fee': fee,
2854
- }
2845
+ }, currency)
2855
2846
 
2856
2847
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
2857
2848
  isArray = isinstance(params, list)
ccxt/okx.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.okx import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Account, Balances, Conversion, CrossBorrowRate, CrossBorrowRates, Currencies, Currency, Greeks, Int, Leverage, LeverageTier, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
9
+ from ccxt.base.types import Account, Balances, Conversion, CrossBorrowRate, CrossBorrowRates, Currencies, Currency, Greeks, Int, LedgerEntry, Leverage, LeverageTier, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from typing import Any
12
12
  from ccxt.base.errors import ExchangeError
@@ -814,6 +814,7 @@ class okx(Exchange, ImplicitAPI):
814
814
  # SPOT/MARGIN error codes 54000-54999
815
815
  '54000': ExchangeError, # Margin transactions unavailable
816
816
  '54001': ExchangeError, # Only Multi-currency margin account can be set to borrow coins automatically
817
+ '54011': InvalidOrder, # 200 Pre-market trading contracts are only allowed to reduce the number of positions within 1 hour before delivery. Please modify or cancel the order.
817
818
  # Trading bot Error Code from 55100 to 55999
818
819
  '55100': InvalidOrder, # Take profit % should be within the range of {parameter1}-{parameter2}
819
820
  '55101': InvalidOrder, # Stop loss % should be within the range of {parameter1}-{parameter2}
@@ -4183,19 +4184,19 @@ class okx(Exchange, ImplicitAPI):
4183
4184
  }
4184
4185
  return self.fetch_my_trades(symbol, since, limit, self.extend(request, params))
4185
4186
 
4186
- def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
4187
+ def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
4187
4188
  """
4188
4189
  fetch the history of changes, actions done by the user or operations that altered balance of the user
4189
4190
  :see: https://www.okx.com/docs-v5/en/#rest-api-account-get-bills-details-last-7-days
4190
4191
  :see: https://www.okx.com/docs-v5/en/#rest-api-account-get-bills-details-last-3-months
4191
4192
  :see: https://www.okx.com/docs-v5/en/#rest-api-funding-asset-bills-details
4192
- :param str code: unified currency code, default is None
4193
+ :param str [code]: unified currency code, default is None
4193
4194
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
4194
- :param int [limit]: max number of ledger entrys to return, default is None
4195
+ :param int [limit]: max number of ledger entries to return, default is None
4195
4196
  :param dict [params]: extra parameters specific to the exchange API endpoint
4196
4197
  :param str [params.marginMode]: 'cross' or 'isolated'
4197
4198
  :param int [params.until]: the latest time in ms to fetch entries for
4198
- :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)
4199
+ :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)
4199
4200
  :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
4200
4201
  """
4201
4202
  self.load_markets()
@@ -4311,7 +4312,7 @@ class okx(Exchange, ImplicitAPI):
4311
4312
  }
4312
4313
  return self.safe_string(types, type, type)
4313
4314
 
4314
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
4315
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
4315
4316
  #
4316
4317
  # privateGetAccountBills, privateGetAccountBillsArchive
4317
4318
  #
@@ -4348,14 +4349,9 @@ class okx(Exchange, ImplicitAPI):
4348
4349
  # "ts": "1597026383085"
4349
4350
  # }
4350
4351
  #
4351
- id = self.safe_string(item, 'billId')
4352
- account = None
4353
- referenceId = self.safe_string(item, 'ordId')
4354
- referenceAccount = None
4355
- type = self.parse_ledger_entry_type(self.safe_string(item, 'type'))
4356
- code = self.safe_currency_code(self.safe_string(item, 'ccy'), currency)
4357
- amountString = self.safe_string(item, 'balChg')
4358
- amount = self.parse_number(amountString)
4352
+ currencyId = self.safe_string(item, 'ccy')
4353
+ code = self.safe_currency_code(currencyId, currency)
4354
+ currency = self.safe_currency(currencyId, currency)
4359
4355
  timestamp = self.safe_integer(item, 'ts')
4360
4356
  feeCostString = self.safe_string(item, 'fee')
4361
4357
  fee = None
@@ -4364,29 +4360,25 @@ class okx(Exchange, ImplicitAPI):
4364
4360
  'cost': self.parse_number(Precise.string_neg(feeCostString)),
4365
4361
  'currency': code,
4366
4362
  }
4367
- before = None
4368
- afterString = self.safe_string(item, 'bal')
4369
- after = self.parse_number(afterString)
4370
- status = 'ok'
4371
4363
  marketId = self.safe_string(item, 'instId')
4372
4364
  symbol = self.safe_symbol(marketId, None, '-')
4373
- return {
4374
- 'id': id,
4365
+ return self.safe_ledger_entry({
4375
4366
  'info': item,
4367
+ 'id': self.safe_string(item, 'billId'),
4376
4368
  'timestamp': timestamp,
4377
4369
  'datetime': self.iso8601(timestamp),
4378
- 'account': account,
4379
- 'referenceId': referenceId,
4380
- 'referenceAccount': referenceAccount,
4381
- 'type': type,
4370
+ 'account': None,
4371
+ 'referenceId': self.safe_string(item, 'ordId'),
4372
+ 'referenceAccount': None,
4373
+ 'type': self.parse_ledger_entry_type(self.safe_string(item, 'type')),
4382
4374
  'currency': code,
4383
4375
  'symbol': symbol,
4384
- 'amount': amount,
4385
- 'before': before, # balance before
4386
- 'after': after, # balance after
4387
- 'status': status,
4376
+ 'amount': self.safe_number(item, 'balChg'),
4377
+ 'before': None,
4378
+ 'after': self.safe_number(item, 'bal'),
4379
+ 'status': 'ok',
4388
4380
  'fee': fee,
4389
- }
4381
+ }, currency)
4390
4382
 
4391
4383
  def parse_deposit_address(self, depositAddress, currency: Currency = None):
4392
4384
  #
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.3'
7
+ __version__ = '4.4.4'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
ccxt/pro/bybit.py CHANGED
@@ -33,6 +33,7 @@ class bybit(ccxt.async_support.bybit):
33
33
  'fetchTradesWs': False,
34
34
  'fetchBalanceWs': False,
35
35
  'watchBalance': True,
36
+ 'watchBidsAsks': True,
36
37
  'watchLiquidations': True,
37
38
  'watchLiquidationsForSymbols': False,
38
39
  'watchMyLiquidations': False,
@@ -559,6 +560,48 @@ class bybit(ccxt.async_support.bybit):
559
560
  messageHash = 'ticker:' + symbol
560
561
  client.resolve(self.tickers[symbol], messageHash)
561
562
 
563
+ async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
564
+ """
565
+ watches best bid & ask for symbols
566
+ :see: https://bybit-exchange.github.io/docs/v5/websocket/public/orderbook
567
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
568
+ :param dict [params]: extra parameters specific to the exchange API endpoint
569
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
570
+ """
571
+ await self.load_markets()
572
+ symbols = self.market_symbols(symbols, None, False)
573
+ messageHashes = []
574
+ url = await self.get_url_by_market_type(symbols[0], False, 'watchBidsAsks', params)
575
+ params = self.clean_params(params)
576
+ marketIds = self.market_ids(symbols)
577
+ topics = []
578
+ for i in range(0, len(marketIds)):
579
+ marketId = marketIds[i]
580
+ topic = 'orderbook.1.' + marketId
581
+ topics.append(topic)
582
+ messageHashes.append('bidask:' + symbols[i])
583
+ ticker = await self.watch_topics(url, messageHashes, topics, params)
584
+ if self.newUpdates:
585
+ return ticker
586
+ return self.filter_by_array(self.bidsasks, 'symbol', symbols)
587
+
588
+ def parse_ws_bid_ask(self, orderbook, market=None):
589
+ timestamp = self.safe_integer(orderbook, 'timestamp')
590
+ bids = self.sort_by(self.aggregate(orderbook['bids']), 0)
591
+ asks = self.sort_by(self.aggregate(orderbook['asks']), 0)
592
+ bestBid = self.safe_list(bids, 0, [])
593
+ bestAsk = self.safe_list(asks, 0, [])
594
+ return self.safe_ticker({
595
+ 'symbol': market['symbol'],
596
+ 'timestamp': timestamp,
597
+ 'datetime': self.iso8601(timestamp),
598
+ 'ask': self.safe_number(bestAsk, 0),
599
+ 'askVolume': self.safe_number(bestAsk, 1),
600
+ 'bid': self.safe_number(bestBid, 0),
601
+ 'bidVolume': self.safe_number(bestBid, 1),
602
+ 'info': orderbook,
603
+ }, market)
604
+
562
605
  async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
563
606
  """
564
607
  watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
@@ -852,6 +895,8 @@ class bybit(ccxt.async_support.bybit):
852
895
  # }
853
896
  # }
854
897
  #
898
+ topic = self.safe_string(message, 'topic')
899
+ limit = topic.split('.')[1]
855
900
  isSpot = client.url.find('spot') >= 0
856
901
  type = self.safe_string(message, 'type')
857
902
  isSnapshot = (type == 'snapshot')
@@ -877,6 +922,12 @@ class bybit(ccxt.async_support.bybit):
877
922
  messageHash = 'orderbook' + ':' + symbol
878
923
  self.orderbooks[symbol] = orderbook
879
924
  client.resolve(orderbook, messageHash)
925
+ if limit == '1':
926
+ bidask = self.parse_ws_bid_ask(self.orderbooks[symbol], market)
927
+ newBidsAsks: dict = {}
928
+ newBidsAsks[symbol] = bidask
929
+ self.bidsasks[symbol] = bidask
930
+ client.resolve(newBidsAsks, 'bidask:' + symbol)
880
931
 
881
932
  def handle_delta(self, bookside, delta):
882
933
  bidAsk = self.parse_bid_ask(delta, 0, 1)
ccxt/pro/mexc.py CHANGED
@@ -10,6 +10,8 @@ from ccxt.base.types import Balances, Int, Order, OrderBook, Str, Strings, Ticke
10
10
  from ccxt.async_support.base.ws.client import Client
11
11
  from typing import List
12
12
  from ccxt.base.errors import AuthenticationError
13
+ from ccxt.base.errors import ArgumentsRequired
14
+ from ccxt.base.errors import NotSupported
13
15
 
14
16
 
15
17
  class mexc(ccxt.async_support.mexc):
@@ -34,6 +36,7 @@ class mexc(ccxt.async_support.mexc):
34
36
  'watchOrders': True,
35
37
  'watchTicker': True,
36
38
  'watchTickers': True,
39
+ 'watchBidsAsks': True,
37
40
  'watchTrades': True,
38
41
  'watchTradesForSymbols': False,
39
42
  },
@@ -110,6 +113,7 @@ class mexc(ccxt.async_support.mexc):
110
113
  # "t": 1678643605721
111
114
  # }
112
115
  #
116
+ self.handle_bid_ask(client, message)
113
117
  rawTicker = self.safe_value_2(message, 'd', 'data')
114
118
  marketId = self.safe_string_2(message, 's', 'symbol')
115
119
  timestamp = self.safe_integer(message, 't')
@@ -229,6 +233,80 @@ class mexc(ccxt.async_support.mexc):
229
233
  'info': ticker,
230
234
  }, market)
231
235
 
236
+ async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
237
+ """
238
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#individual-symbol-book-ticker-streams
239
+ watches best bid & ask for symbols
240
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
241
+ :param dict [params]: extra parameters specific to the exchange API endpoint
242
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
243
+ """
244
+ await self.load_markets()
245
+ symbols = self.market_symbols(symbols, None, True, False, True)
246
+ marketType = None
247
+ if symbols is None:
248
+ raise ArgumentsRequired(self.id + 'watchBidsAsks required symbols argument')
249
+ markets = self.markets_for_symbols(symbols)
250
+ marketType, params = self.handle_market_type_and_params('watchBidsAsks', markets[0], params)
251
+ isSpot = marketType == 'spot'
252
+ if not isSpot:
253
+ raise NotSupported(self.id + 'watchBidsAsks only support spot market')
254
+ messageHashes = []
255
+ topics = []
256
+ for i in range(0, len(symbols)):
257
+ if isSpot:
258
+ market = self.market(symbols[i])
259
+ topics.append('spot@public.bookTicker.v3.api@' + market['id'])
260
+ messageHashes.append('bidask:' + symbols[i])
261
+ url = self.urls['api']['ws']['spot']
262
+ request: dict = {
263
+ 'method': 'SUBSCRIPTION',
264
+ 'params': topics,
265
+ }
266
+ ticker = await self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
267
+ if self.newUpdates:
268
+ tickers: dict = {}
269
+ tickers[ticker['symbol']] = ticker
270
+ return tickers
271
+ return self.filter_by_array(self.bidsasks, 'symbol', symbols)
272
+
273
+ def handle_bid_ask(self, client: Client, message):
274
+ #
275
+ # {
276
+ # "c": "spot@public.bookTicker.v3.api@BTCUSDT",
277
+ # "d": {
278
+ # "A": "4.70432",
279
+ # "B": "6.714863",
280
+ # "a": "20744.54",
281
+ # "b": "20744.17"
282
+ # },
283
+ # "s": "BTCUSDT",
284
+ # "t": 1678643605721
285
+ # }
286
+ #
287
+ parsedTicker = self.parse_ws_bid_ask(message)
288
+ symbol = parsedTicker['symbol']
289
+ self.bidsasks[symbol] = parsedTicker
290
+ messageHash = 'bidask:' + symbol
291
+ client.resolve(parsedTicker, messageHash)
292
+
293
+ def parse_ws_bid_ask(self, ticker, market=None):
294
+ data = self.safe_dict(ticker, 'd')
295
+ marketId = self.safe_string(ticker, 's')
296
+ market = self.safe_market(marketId, market)
297
+ symbol = self.safe_string(market, 'symbol')
298
+ timestamp = self.safe_integer(ticker, 't')
299
+ return self.safe_ticker({
300
+ 'symbol': symbol,
301
+ 'timestamp': timestamp,
302
+ 'datetime': self.iso8601(timestamp),
303
+ 'ask': self.safe_number(data, 'a'),
304
+ 'askVolume': self.safe_number(data, 'A'),
305
+ 'bid': self.safe_number(data, 'b'),
306
+ 'bidVolume': self.safe_number(data, 'B'),
307
+ 'info': ticker,
308
+ }, market)
309
+
232
310
  async def watch_spot_public(self, channel, messageHash, params={}):
233
311
  url = self.urls['api']['ws']['spot']
234
312
  request: dict = {
ccxt/test/tests_async.py CHANGED
@@ -282,7 +282,7 @@ class testMainClass(baseMainTestClass):
282
282
  else:
283
283
  # wait and retry again
284
284
  # (increase wait time on every retry)
285
- await exchange.sleep(i * 1000)
285
+ await exchange.sleep((i + 1) * 1000)
286
286
  continue
287
287
  else:
288
288
  # if it's loadMarkets, then fail test, because it's mandatory for tests
ccxt/test/tests_sync.py CHANGED
@@ -279,7 +279,7 @@ class testMainClass(baseMainTestClass):
279
279
  else:
280
280
  # wait and retry again
281
281
  # (increase wait time on every retry)
282
- exchange.sleep(i * 1000)
282
+ exchange.sleep((i + 1) * 1000)
283
283
  continue
284
284
  else:
285
285
  # if it's loadMarkets, then fail test, because it's mandatory for tests