ccxt 4.3.58__py2.py3-none-any.whl → 4.3.60__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.

Potentially problematic release.


This version of ccxt might be problematic. Click here for more details.

Files changed (84) hide show
  1. ccxt/__init__.py +5 -5
  2. ccxt/abstract/bingx.py +1 -1
  3. ccxt/abstract/bitmart.py +1 -0
  4. ccxt/abstract/btcbox.py +1 -0
  5. ccxt/abstract/upbit.py +3 -0
  6. ccxt/abstract/xt.py +1 -0
  7. ccxt/async_support/__init__.py +5 -5
  8. ccxt/async_support/base/exchange.py +1 -1
  9. ccxt/async_support/binance.py +91 -2
  10. ccxt/async_support/bingx.py +448 -123
  11. ccxt/async_support/bitfinex.py +38 -4
  12. ccxt/async_support/bitget.py +1 -1
  13. ccxt/async_support/bitmart.py +1 -0
  14. ccxt/async_support/bitso.py +4 -1
  15. ccxt/async_support/btcbox.py +145 -8
  16. ccxt/async_support/bybit.py +3 -5
  17. ccxt/async_support/cex.py +1 -1
  18. ccxt/async_support/coinsph.py +1 -1
  19. ccxt/async_support/cryptocom.py +11 -5
  20. ccxt/async_support/deribit.py +15 -1
  21. ccxt/async_support/digifinex.py +30 -7
  22. ccxt/async_support/gate.py +17 -18
  23. ccxt/async_support/htx.py +7 -7
  24. ccxt/async_support/hyperliquid.py +107 -3
  25. ccxt/async_support/kraken.py +2 -2
  26. ccxt/async_support/mexc.py +11 -11
  27. ccxt/async_support/novadax.py +1 -1
  28. ccxt/async_support/okcoin.py +1 -1
  29. ccxt/async_support/okx.py +11 -2
  30. ccxt/async_support/phemex.py +1 -1
  31. ccxt/async_support/probit.py +1 -1
  32. ccxt/async_support/timex.py +16 -2
  33. ccxt/async_support/tokocrypto.py +1 -1
  34. ccxt/async_support/upbit.py +139 -45
  35. ccxt/async_support/xt.py +71 -8
  36. ccxt/base/errors.py +23 -23
  37. ccxt/base/exchange.py +9 -9
  38. ccxt/binance.py +91 -2
  39. ccxt/bingx.py +448 -123
  40. ccxt/bitfinex.py +38 -4
  41. ccxt/bitget.py +1 -1
  42. ccxt/bitmart.py +1 -0
  43. ccxt/bitso.py +4 -1
  44. ccxt/btcbox.py +145 -8
  45. ccxt/bybit.py +3 -5
  46. ccxt/cex.py +1 -1
  47. ccxt/coinsph.py +1 -1
  48. ccxt/cryptocom.py +11 -5
  49. ccxt/deribit.py +15 -1
  50. ccxt/digifinex.py +30 -7
  51. ccxt/gate.py +17 -18
  52. ccxt/htx.py +7 -7
  53. ccxt/hyperliquid.py +107 -3
  54. ccxt/kraken.py +2 -2
  55. ccxt/mexc.py +11 -11
  56. ccxt/novadax.py +1 -1
  57. ccxt/okcoin.py +1 -1
  58. ccxt/okx.py +11 -2
  59. ccxt/phemex.py +1 -1
  60. ccxt/pro/__init__.py +3 -1
  61. ccxt/pro/binance.py +11 -13
  62. ccxt/pro/bingx.py +11 -8
  63. ccxt/pro/bitmart.py +2 -2
  64. ccxt/pro/bitopro.py +1 -1
  65. ccxt/pro/cex.py +1 -1
  66. ccxt/pro/coincheck.py +1 -1
  67. ccxt/pro/coinone.py +1 -1
  68. ccxt/pro/hyperliquid.py +1 -1
  69. ccxt/pro/kucoin.py +35 -3
  70. ccxt/pro/phemex.py +1 -1
  71. ccxt/pro/xt.py +1046 -0
  72. ccxt/probit.py +1 -1
  73. ccxt/test/tests_async.py +2 -2
  74. ccxt/test/tests_helpers.py +1 -1
  75. ccxt/test/tests_sync.py +2 -2
  76. ccxt/timex.py +16 -2
  77. ccxt/tokocrypto.py +1 -1
  78. ccxt/upbit.py +139 -45
  79. ccxt/xt.py +71 -8
  80. {ccxt-4.3.58.dist-info → ccxt-4.3.60.dist-info}/METADATA +5 -5
  81. {ccxt-4.3.58.dist-info → ccxt-4.3.60.dist-info}/RECORD +84 -83
  82. {ccxt-4.3.58.dist-info → ccxt-4.3.60.dist-info}/LICENSE.txt +0 -0
  83. {ccxt-4.3.58.dist-info → ccxt-4.3.60.dist-info}/WHEEL +0 -0
  84. {ccxt-4.3.58.dist-info → ccxt-4.3.60.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, Trade, Transaction, TransferEntry
8
+ from ccxt.base.types import Balances, Currencies, Currency, Int, MarginModification, Market, Num, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Str, Strings, 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
@@ -105,7 +105,7 @@ class hyperliquid(Exchange, ImplicitAPI):
105
105
  'fetchTickers': False,
106
106
  'fetchTime': False,
107
107
  'fetchTrades': True,
108
- 'fetchTradingFee': False,
108
+ 'fetchTradingFee': True,
109
109
  'fetchTradingFees': False,
110
110
  'fetchTransfer': False,
111
111
  'fetchTransfers': False,
@@ -1260,7 +1260,7 @@ class hyperliquid(Exchange, ImplicitAPI):
1260
1260
  cancel multiple orders for multiple symbols
1261
1261
  :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s
1262
1262
  :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s-by-cloid
1263
- :param CancellationRequest[] orders: each order should contain the parameters required by cancelOrder namely id and symbol
1263
+ :param CancellationRequest[] orders: each order should contain the parameters required by cancelOrder namely id and symbol, example [{"id": "a", "symbol": "BTC/USDT"}, {"id": "b", "symbol": "ETH/USDT"}]
1264
1264
  :param dict [params]: extra parameters specific to the exchange API endpoint
1265
1265
  :param str [params.vaultAddress]: the vault address
1266
1266
  :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
@@ -2381,6 +2381,110 @@ class hyperliquid(Exchange, ImplicitAPI):
2381
2381
  'fee': None,
2382
2382
  }
2383
2383
 
2384
+ def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
2385
+ """
2386
+ fetch the trading fees for a market
2387
+ :param str symbol: unified market symbol
2388
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2389
+ :param str [params.user]: user address, will default to self.walletAddress if not provided
2390
+ :returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
2391
+ """
2392
+ self.load_markets()
2393
+ userAddress = None
2394
+ userAddress, params = self.handle_public_address('fetchTradingFee', params)
2395
+ market = self.market(symbol)
2396
+ request: dict = {
2397
+ 'type': 'userFees',
2398
+ 'user': userAddress,
2399
+ }
2400
+ response = self.publicPostInfo(self.extend(request, params))
2401
+ #
2402
+ # {
2403
+ # "dailyUserVlm": [
2404
+ # {
2405
+ # "date": "2024-07-08",
2406
+ # "userCross": "0.0",
2407
+ # "userAdd": "0.0",
2408
+ # "exchange": "90597185.23639999"
2409
+ # }
2410
+ # ],
2411
+ # "feeSchedule": {
2412
+ # "cross": "0.00035",
2413
+ # "add": "0.0001",
2414
+ # "tiers": {
2415
+ # "vip": [
2416
+ # {
2417
+ # "ntlCutoff": "5000000.0",
2418
+ # "cross": "0.0003",
2419
+ # "add": "0.00005"
2420
+ # }
2421
+ # ],
2422
+ # "mm": [
2423
+ # {
2424
+ # "makerFractionCutoff": "0.005",
2425
+ # "add": "-0.00001"
2426
+ # }
2427
+ # ]
2428
+ # },
2429
+ # "referralDiscount": "0.04"
2430
+ # },
2431
+ # "userCrossRate": "0.00035",
2432
+ # "userAddRate": "0.0001",
2433
+ # "activeReferralDiscount": "0.0"
2434
+ # }
2435
+ #
2436
+ data: dict = {
2437
+ 'userCrossRate': self.safe_string(response, 'userCrossRate'),
2438
+ 'userAddRate': self.safe_string(response, 'userAddRate'),
2439
+ }
2440
+ return self.parse_trading_fee(data, market)
2441
+
2442
+ def parse_trading_fee(self, fee: dict, market: Market = None) -> TradingFeeInterface:
2443
+ #
2444
+ # {
2445
+ # "dailyUserVlm": [
2446
+ # {
2447
+ # "date": "2024-07-08",
2448
+ # "userCross": "0.0",
2449
+ # "userAdd": "0.0",
2450
+ # "exchange": "90597185.23639999"
2451
+ # }
2452
+ # ],
2453
+ # "feeSchedule": {
2454
+ # "cross": "0.00035",
2455
+ # "add": "0.0001",
2456
+ # "tiers": {
2457
+ # "vip": [
2458
+ # {
2459
+ # "ntlCutoff": "5000000.0",
2460
+ # "cross": "0.0003",
2461
+ # "add": "0.00005"
2462
+ # }
2463
+ # ],
2464
+ # "mm": [
2465
+ # {
2466
+ # "makerFractionCutoff": "0.005",
2467
+ # "add": "-0.00001"
2468
+ # }
2469
+ # ]
2470
+ # },
2471
+ # "referralDiscount": "0.04"
2472
+ # },
2473
+ # "userCrossRate": "0.00035",
2474
+ # "userAddRate": "0.0001",
2475
+ # "activeReferralDiscount": "0.0"
2476
+ # }
2477
+ #
2478
+ symbol = self.safe_symbol(None, market)
2479
+ return {
2480
+ 'info': fee,
2481
+ 'symbol': symbol,
2482
+ 'maker': self.safe_number(fee, 'userAddRate'),
2483
+ 'taker': self.safe_number(fee, 'userCrossRate'),
2484
+ 'percentage': None,
2485
+ 'tierBased': None,
2486
+ }
2487
+
2384
2488
  def format_vault_address(self, address: Str = None):
2385
2489
  if address is None:
2386
2490
  return None
ccxt/kraken.py CHANGED
@@ -19,13 +19,13 @@ from ccxt.base.errors import InsufficientFunds
19
19
  from ccxt.base.errors import InvalidAddress
20
20
  from ccxt.base.errors import InvalidOrder
21
21
  from ccxt.base.errors import OrderNotFound
22
- from ccxt.base.errors import CancelPending
23
22
  from ccxt.base.errors import NotSupported
24
23
  from ccxt.base.errors import DDoSProtection
25
24
  from ccxt.base.errors import RateLimitExceeded
26
25
  from ccxt.base.errors import ExchangeNotAvailable
27
26
  from ccxt.base.errors import OnMaintenance
28
27
  from ccxt.base.errors import InvalidNonce
28
+ from ccxt.base.errors import CancelPending
29
29
  from ccxt.base.decimal_to_precision import TRUNCATE
30
30
  from ccxt.base.decimal_to_precision import TICK_SIZE
31
31
  from ccxt.base.precise import Precise
@@ -1030,7 +1030,7 @@ class kraken(Exchange, ImplicitAPI):
1030
1030
  amount = Precise.string_abs(amount)
1031
1031
  else:
1032
1032
  direction = 'in'
1033
- timestamp = self.safe_timestamp(item, 'time')
1033
+ timestamp = self.safe_integer_product(item, 'time', 1000)
1034
1034
  return {
1035
1035
  'info': item,
1036
1036
  'id': id,
ccxt/mexc.py CHANGED
@@ -810,24 +810,24 @@ class mexc(Exchange, ImplicitAPI):
810
810
  'commonCurrencies': {
811
811
  'BEYONDPROTOCOL': 'BEYOND',
812
812
  'BIFI': 'BIFIF',
813
- 'BYN': 'BeyondFi',
813
+ 'BYN': 'BEYONDFI',
814
814
  'COFI': 'COFIX', # conflict with CoinFi
815
- 'DFI': 'DfiStarter',
816
- 'DFT': 'dFuture',
815
+ 'DFI': 'DFISTARTER',
816
+ 'DFT': 'DFUTURE',
817
817
  'DRK': 'DRK',
818
- 'EGC': 'Egoras Credit',
818
+ 'EGC': 'EGORASCREDIT',
819
819
  'FLUX1': 'FLUX', # switched places
820
820
  'FLUX': 'FLUX1', # switched places
821
- 'FREE': 'FreeRossDAO', # conflict with FREE Coin
821
+ 'FREE': 'FREEROSSDAO', # conflict with FREE Coin
822
822
  'GAS': 'GASDAO',
823
823
  'GASNEO': 'GAS',
824
- 'GMT': 'GMT Token', # Conflict with GMT(STEPN)
824
+ 'GMT': 'GMTTOKEN', # Conflict with GMT(STEPN)
825
825
  'STEPN': 'GMT', # Conflict with GMT Token
826
- 'HERO': 'Step Hero', # conflict with Metahero
827
- 'MIMO': 'Mimosa',
828
- 'PROS': 'Pros.Finance', # conflict with Prosper
829
- 'SIN': 'Sin City Token',
830
- 'SOUL': 'Soul Swap',
826
+ 'HERO': 'STEPHERO', # conflict with Metahero
827
+ 'MIMO': 'MIMOSA',
828
+ 'PROS': 'PROSFINANCE', # conflict with Prosper
829
+ 'SIN': 'SINCITYTOKEN',
830
+ 'SOUL': 'SOULSWAP',
831
831
  },
832
832
  'exceptions': {
833
833
  'exact': {
ccxt/novadax.py CHANGED
@@ -19,9 +19,9 @@ from ccxt.base.errors import BadSymbol
19
19
  from ccxt.base.errors import InsufficientFunds
20
20
  from ccxt.base.errors import InvalidOrder
21
21
  from ccxt.base.errors import OrderNotFound
22
- from ccxt.base.errors import CancelPending
23
22
  from ccxt.base.errors import RateLimitExceeded
24
23
  from ccxt.base.errors import OnMaintenance
24
+ from ccxt.base.errors import CancelPending
25
25
  from ccxt.base.decimal_to_precision import TICK_SIZE
26
26
  from ccxt.base.precise import Precise
27
27
 
ccxt/okcoin.py CHANGED
@@ -20,7 +20,6 @@ from ccxt.base.errors import InsufficientFunds
20
20
  from ccxt.base.errors import InvalidAddress
21
21
  from ccxt.base.errors import InvalidOrder
22
22
  from ccxt.base.errors import OrderNotFound
23
- from ccxt.base.errors import CancelPending
24
23
  from ccxt.base.errors import NotSupported
25
24
  from ccxt.base.errors import NetworkError
26
25
  from ccxt.base.errors import RateLimitExceeded
@@ -28,6 +27,7 @@ from ccxt.base.errors import ExchangeNotAvailable
28
27
  from ccxt.base.errors import OnMaintenance
29
28
  from ccxt.base.errors import InvalidNonce
30
29
  from ccxt.base.errors import RequestTimeout
30
+ from ccxt.base.errors import CancelPending
31
31
  from ccxt.base.decimal_to_precision import TICK_SIZE
32
32
  from ccxt.base.precise import Precise
33
33
 
ccxt/okx.py CHANGED
@@ -21,7 +21,6 @@ from ccxt.base.errors import InsufficientFunds
21
21
  from ccxt.base.errors import InvalidAddress
22
22
  from ccxt.base.errors import InvalidOrder
23
23
  from ccxt.base.errors import OrderNotFound
24
- from ccxt.base.errors import CancelPending
25
24
  from ccxt.base.errors import ContractUnavailable
26
25
  from ccxt.base.errors import NotSupported
27
26
  from ccxt.base.errors import NetworkError
@@ -31,6 +30,7 @@ from ccxt.base.errors import ExchangeNotAvailable
31
30
  from ccxt.base.errors import OnMaintenance
32
31
  from ccxt.base.errors import InvalidNonce
33
32
  from ccxt.base.errors import RequestTimeout
33
+ from ccxt.base.errors import CancelPending
34
34
  from ccxt.base.decimal_to_precision import TICK_SIZE
35
35
  from ccxt.base.precise import Precise
36
36
 
@@ -949,6 +949,15 @@ class okx(Exchange, ImplicitAPI):
949
949
  '70010': BadRequest, # Timestamp parameters need to be in Unix timestamp format in milliseconds.
950
950
  '70013': BadRequest, # endTs needs to be bigger than or equal to beginTs.
951
951
  '70016': BadRequest, # Please specify your instrument settings for at least one instType.
952
+ '1009': BadRequest, # Request message exceeds the maximum frame length
953
+ '4001': AuthenticationError, # Login Failed
954
+ '4002': BadRequest, # Invalid Request
955
+ '4003': RateLimitExceeded, # APIKey subscription amount exceeds the limit 100
956
+ '4004': NetworkError, # No data received in 30s
957
+ '4005': ExchangeNotAvailable, # Buffer is full, cannot write data
958
+ '4006': BadRequest, # Abnormal disconnection
959
+ '4007': AuthenticationError, # API key has been updated or deleted. Please reconnect.
960
+ '4008': RateLimitExceeded, # The number of subscribed channels exceeds the maximum limit.
952
961
  },
953
962
  'broad': {
954
963
  'Internal Server Error': ExchangeNotAvailable, # {"code":500,"data":{},"detailMsg":"","error_code":"500","error_message":"Internal Server Error","msg":"Internal Server Error"}
@@ -3143,7 +3152,7 @@ class okx(Exchange, ImplicitAPI):
3143
3152
  cancel multiple orders for multiple symbols
3144
3153
  :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-multiple-orders
3145
3154
  :see: https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-cancel-algo-order
3146
- :param CancellationRequest[] orders: each order should contain the parameters required by cancelOrder namely id and symbol
3155
+ :param CancellationRequest[] orders: each order should contain the parameters required by cancelOrder namely id and symbol, example [{"id": "a", "symbol": "BTC/USDT"}, {"id": "b", "symbol": "ETH/USDT"}]
3147
3156
  :param dict [params]: extra parameters specific to the exchange API endpoint
3148
3157
  :param boolean [params.trigger]: whether the order is a stop/trigger order
3149
3158
  :param boolean [params.trailing]: set to True if you want to cancel trailing orders
ccxt/phemex.py CHANGED
@@ -19,10 +19,10 @@ from ccxt.base.errors import BadSymbol
19
19
  from ccxt.base.errors import InsufficientFunds
20
20
  from ccxt.base.errors import InvalidOrder
21
21
  from ccxt.base.errors import OrderNotFound
22
- from ccxt.base.errors import CancelPending
23
22
  from ccxt.base.errors import DuplicateOrderId
24
23
  from ccxt.base.errors import DDoSProtection
25
24
  from ccxt.base.errors import RateLimitExceeded
25
+ from ccxt.base.errors import CancelPending
26
26
  from ccxt.base.decimal_to_precision import TICK_SIZE
27
27
  from ccxt.base.precise import Precise
28
28
 
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.58'
7
+ __version__ = '4.3.60'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
@@ -79,6 +79,7 @@ from ccxt.pro.wazirx import wazirx # noqa
79
79
  from ccxt.pro.whitebit import whitebit # noqa: F401
80
80
  from ccxt.pro.woo import woo # noqa: F401
81
81
  from ccxt.pro.woofipro import woofipro # noqa: F401
82
+ from ccxt.pro.xt import xt # noqa: F401
82
83
 
83
84
  exchanges = [
84
85
  'alpaca',
@@ -148,4 +149,5 @@ exchanges = [
148
149
  'whitebit',
149
150
  'woo',
150
151
  'woofipro',
152
+ 'xt',
151
153
  ]
ccxt/pro/binance.py CHANGED
@@ -584,9 +584,9 @@ class binance(ccxt.async_support.binance):
584
584
  for i in range(0, len(symbols)):
585
585
  symbol = symbols[i]
586
586
  market = self.market(symbol)
587
- messageHash = market['lowercaseId'] + '@' + name
588
- messageHashes.append(messageHash)
589
- symbolHash = messageHash + '@' + watchOrderBookRate + 'ms'
587
+ messageHashes.append('orderbook::' + symbol)
588
+ subscriptionHash = market['lowercaseId'] + '@' + name
589
+ symbolHash = subscriptionHash + '@' + watchOrderBookRate + 'ms'
590
590
  subParams.append(symbolHash)
591
591
  messageHashesLength = len(messageHashes)
592
592
  url = self.urls['api']['ws'][type] + '/' + self.stream(type, streamHash, messageHashesLength)
@@ -605,8 +605,7 @@ class binance(ccxt.async_support.binance):
605
605
  'type': type,
606
606
  'params': params,
607
607
  }
608
- message = self.extend(request, params)
609
- orderbook = await self.watch_multiple(url, messageHashes, message, messageHashes, subscription)
608
+ orderbook = await self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes, subscription)
610
609
  return orderbook.limit()
611
610
 
612
611
  async def fetch_order_book_ws(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
@@ -770,8 +769,7 @@ class binance(ccxt.async_support.binance):
770
769
  marketId = self.safe_string(message, 's')
771
770
  market = self.safe_market(marketId, None, None, marketType)
772
771
  symbol = market['symbol']
773
- name = 'depth'
774
- messageHash = market['lowercaseId'] + '@' + name
772
+ messageHash = 'orderbook::' + symbol
775
773
  if not (symbol in self.orderbooks):
776
774
  #
777
775
  # https://github.com/ccxt/ccxt/issues/6672
@@ -887,12 +885,14 @@ class binance(ccxt.async_support.binance):
887
885
  type = firstMarket['type']
888
886
  if firstMarket['contract']:
889
887
  type = 'future' if firstMarket['linear'] else 'delivery'
888
+ messageHashes = []
890
889
  subParams = []
891
890
  for i in range(0, len(symbols)):
892
891
  symbol = symbols[i]
893
892
  market = self.market(symbol)
894
- currentMessageHash = market['lowercaseId'] + '@' + name
895
- subParams.append(currentMessageHash)
893
+ messageHashes.append('trade::' + symbol)
894
+ rawHash = market['lowercaseId'] + '@' + name
895
+ subParams.append(rawHash)
896
896
  query = self.omit(params, 'type')
897
897
  subParamsLength = len(subParams)
898
898
  url = self.urls['api']['ws'][type] + '/' + self.stream(type, streamHash, subParamsLength)
@@ -905,7 +905,7 @@ class binance(ccxt.async_support.binance):
905
905
  subscribe: dict = {
906
906
  'id': requestId,
907
907
  }
908
- trades = await self.watch_multiple(url, subParams, self.extend(request, query), subParams, subscribe)
908
+ trades = await self.watch_multiple(url, messageHashes, self.extend(request, query), messageHashes, subscribe)
909
909
  if self.newUpdates:
910
910
  first = self.safe_value(trades, 0)
911
911
  tradeSymbol = self.safe_string(first, 'symbol')
@@ -1086,9 +1086,7 @@ class binance(ccxt.async_support.binance):
1086
1086
  marketId = self.safe_string(message, 's')
1087
1087
  market = self.safe_market(marketId, None, None, marketType)
1088
1088
  symbol = market['symbol']
1089
- lowerCaseId = self.safe_string_lower(message, 's')
1090
- event = self.safe_string(message, 'e')
1091
- messageHash = lowerCaseId + '@' + event
1089
+ messageHash = 'trade::' + symbol
1092
1090
  trade = self.parse_ws_trade(message, market)
1093
1091
  tradesArray = self.safe_value(self.trades, symbol)
1094
1092
  if tradesArray is None:
ccxt/pro/bingx.py CHANGED
@@ -101,10 +101,10 @@ class bingx(ccxt.async_support.bingx):
101
101
  """
102
102
  await self.load_markets()
103
103
  market = self.market(symbol)
104
- marketType, query = self.handle_market_type_and_params('watchTrades', market, params)
104
+ marketType, query = self.handle_market_type_and_params('watchTicker', market, params)
105
105
  url = self.safe_value(self.urls['api']['ws'], marketType)
106
106
  if url is None:
107
- raise BadRequest(self.id + ' watchTrades is not supported for ' + marketType + ' markets.')
107
+ raise BadRequest(self.id + ' watchTicker is not supported for ' + marketType + ' markets.')
108
108
  subscriptionHash = market['id'] + '@ticker'
109
109
  messageHash = self.get_message_hash('ticker', market['symbol'])
110
110
  uuid = self.uuid()
@@ -413,19 +413,21 @@ class bingx(ccxt.async_support.bingx):
413
413
  """
414
414
  await self.load_markets()
415
415
  market = self.market(symbol)
416
- marketType, query = self.handle_market_type_and_params('watchTrades', market, params)
416
+ marketType = None
417
+ marketType, params = self.handle_market_type_and_params('watchTrades', market, params)
417
418
  url = self.safe_value(self.urls['api']['ws'], marketType)
418
419
  if url is None:
419
420
  raise BadRequest(self.id + ' watchTrades is not supported for ' + marketType + ' markets.')
420
- messageHash = market['id'] + '@trade'
421
+ rawHash = market['id'] + '@trade'
422
+ messageHash = 'trade::' + symbol
421
423
  uuid = self.uuid()
422
424
  request: dict = {
423
425
  'id': uuid,
424
- 'dataType': messageHash,
426
+ 'dataType': rawHash,
425
427
  }
426
428
  if marketType == 'swap':
427
429
  request['reqType'] = 'sub'
428
- trades = await self.watch(url, messageHash, self.extend(request, query), messageHash)
430
+ trades = await self.watch(url, messageHash, self.extend(request, params), messageHash)
429
431
  if self.newUpdates:
430
432
  limit = trades.getLimit(symbol, limit)
431
433
  return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
@@ -491,12 +493,13 @@ class bingx(ccxt.async_support.bingx):
491
493
  # }
492
494
  #
493
495
  data = self.safe_value(message, 'data', [])
494
- messageHash = self.safe_string(message, 'dataType')
495
- marketId = messageHash.split('@')[0]
496
+ rawHash = self.safe_string(message, 'dataType')
497
+ marketId = rawHash.split('@')[0]
496
498
  isSwap = client.url.find('swap') >= 0
497
499
  marketType = 'swap' if isSwap else 'spot'
498
500
  market = self.safe_market(marketId, None, None, marketType)
499
501
  symbol = market['symbol']
502
+ messageHash = 'trade::' + symbol
500
503
  trades = None
501
504
  if isinstance(data, list):
502
505
  trades = self.parse_trades(data, market)
ccxt/pro/bitmart.py CHANGED
@@ -452,7 +452,7 @@ class bitmart(ccxt.async_support.bitmart):
452
452
  client.resolve(newOrders, symbolSpecificMessageHash)
453
453
  client.resolve(newOrders, messageHash)
454
454
 
455
- def parse_ws_order(self, order, market: Market = None):
455
+ def parse_ws_order(self, order: dict, market: Market = None):
456
456
  #
457
457
  # spot
458
458
  # {
@@ -802,7 +802,7 @@ class bitmart(ccxt.async_support.bitmart):
802
802
  stored.append(trade)
803
803
  return symbol
804
804
 
805
- def parse_ws_trade(self, trade, market: Market = None):
805
+ def parse_ws_trade(self, trade: dict, market: Market = None):
806
806
  # spot
807
807
  # {
808
808
  # "price": "52700.50",
ccxt/pro/bitopro.py CHANGED
@@ -231,7 +231,7 @@ class bitopro(ccxt.async_support.bitopro):
231
231
  client.resolve(trades, messageHash)
232
232
  client.resolve(trades, messageHash + ':' + symbol)
233
233
 
234
- def parse_ws_trade(self, trade, market: Market = None) -> Trade:
234
+ def parse_ws_trade(self, trade: dict, market: Market = None) -> Trade:
235
235
  #
236
236
  # {
237
237
  # "base": "usdt",
ccxt/pro/cex.py CHANGED
@@ -961,7 +961,7 @@ class cex(ccxt.async_support.cex):
961
961
  # }
962
962
  #
963
963
  data = self.safe_value(message, 'data', {})
964
- incrementalId = self.safe_number(data, 'id')
964
+ incrementalId = self.safe_integer(data, 'id')
965
965
  pair = self.safe_string(data, 'pair', '')
966
966
  symbol = self.pair_to_symbol(pair)
967
967
  storedOrderBook = self.safe_value(self.orderbooks, symbol)
ccxt/pro/coincheck.py CHANGED
@@ -157,7 +157,7 @@ class coincheck(ccxt.async_support.coincheck):
157
157
  messageHash = 'trade:' + symbol
158
158
  client.resolve(stored, messageHash)
159
159
 
160
- def parse_ws_trade(self, trade, market: Market = None) -> Trade:
160
+ def parse_ws_trade(self, trade: dict, market: Market = None) -> Trade:
161
161
  #
162
162
  # [
163
163
  # "1663318663", # transaction timestamp(unix time)
ccxt/pro/coinone.py CHANGED
@@ -300,7 +300,7 @@ class coinone(ccxt.async_support.coinone):
300
300
  messageHash = 'trade:' + symbol
301
301
  client.resolve(stored, messageHash)
302
302
 
303
- def parse_ws_trade(self, trade, market: Market = None) -> Trade:
303
+ def parse_ws_trade(self, trade: dict, market: Market = None) -> Trade:
304
304
  #
305
305
  # {
306
306
  # "quote_currency": "KRW",
ccxt/pro/hyperliquid.py CHANGED
@@ -269,7 +269,7 @@ class hyperliquid(ccxt.async_support.hyperliquid):
269
269
  messageHash = 'trade:' + symbol
270
270
  client.resolve(trades, messageHash)
271
271
 
272
- def parse_ws_trade(self, trade, market: Market = None) -> Trade:
272
+ def parse_ws_trade(self, trade: dict, market: Market = None) -> Trade:
273
273
  #
274
274
  # fetchMyTrades
275
275
  #
ccxt/pro/kucoin.py CHANGED
@@ -47,6 +47,9 @@ class kucoin(ccxt.async_support.kucoin):
47
47
  'snapshotMaxRetries': 3,
48
48
  'method': '/market/level2', # '/spotMarket/level2Depth5' or '/spotMarket/level2Depth50'
49
49
  },
50
+ 'watchMyTrades': {
51
+ 'method': '/spotMarket/tradeOrders', # or '/spot/tradeFills'
52
+ },
50
53
  },
51
54
  'streaming': {
52
55
  # kucoin does not support built-in ws protocol-level ping-pong
@@ -912,11 +915,14 @@ class kucoin(ccxt.async_support.kucoin):
912
915
  :param int [since]: the earliest time in ms to fetch trades for
913
916
  :param int [limit]: the maximum number of trade structures to retrieve
914
917
  :param dict [params]: extra parameters specific to the exchange API endpoint
918
+ :param str [params.method]: '/spotMarket/tradeOrders' or '/spot/tradeFills' default is '/spotMarket/tradeOrders'
915
919
  :returns dict[]: a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
916
920
  """
917
921
  await self.load_markets()
918
922
  url = await self.negotiate(True)
919
- topic = '/spotMarket/tradeOrders'
923
+ options = self.safe_dict(self.options, 'watchMyTrades')
924
+ defaultMethod = self.safe_string(params, 'method', '/spotMarket/tradeOrders')
925
+ topic = defaultMethod if (defaultMethod is not None) else self.safe_string(options, 'method')
920
926
  request: dict = {
921
927
  'privateChannel': True,
922
928
  }
@@ -971,6 +977,8 @@ class kucoin(ccxt.async_support.kucoin):
971
977
  client.resolve(self.myTrades, symbolSpecificMessageHash)
972
978
 
973
979
  def parse_ws_trade(self, trade, market=None):
980
+ #
981
+ # /spotMarket/tradeOrders
974
982
  #
975
983
  # {
976
984
  # "symbol": "KCS-USDT",
@@ -993,6 +1001,22 @@ class kucoin(ccxt.async_support.kucoin):
993
1001
  # "ts": 1670329987311000000
994
1002
  # }
995
1003
  #
1004
+ # /spot/tradeFills
1005
+ #
1006
+ # {
1007
+ # "fee": 0.00262148,
1008
+ # "feeCurrency": "USDT",
1009
+ # "feeRate": 0.001,
1010
+ # "orderId": "62417436b29df8000183df2f",
1011
+ # "orderType": "market",
1012
+ # "price": 131.074,
1013
+ # "side": "sell",
1014
+ # "size": 0.02,
1015
+ # "symbol": "LTC-USDT",
1016
+ # "time": "1648456758734571745",
1017
+ # "tradeId": "624174362e113d2f467b3043"
1018
+ # }
1019
+ #
996
1020
  marketId = self.safe_string(trade, 'symbol')
997
1021
  market = self.safe_market(marketId, market, '-')
998
1022
  symbol = market['symbol']
@@ -1002,7 +1026,10 @@ class kucoin(ccxt.async_support.kucoin):
1002
1026
  price = self.safe_string(trade, 'matchPrice')
1003
1027
  amount = self.safe_string(trade, 'matchSize')
1004
1028
  order = self.safe_string(trade, 'orderId')
1005
- timestamp = self.safe_integer_product(trade, 'ts', 0.000001)
1029
+ timestamp = self.safe_integer_product_2(trade, 'ts', 'time', 0.000001)
1030
+ feeCurrency = market['quote']
1031
+ feeRate = self.safe_string(trade, 'feeRate')
1032
+ feeCost = self.safe_string(trade, 'fee')
1006
1033
  return self.safe_trade({
1007
1034
  'info': trade,
1008
1035
  'timestamp': timestamp,
@@ -1016,7 +1043,11 @@ class kucoin(ccxt.async_support.kucoin):
1016
1043
  'price': price,
1017
1044
  'amount': amount,
1018
1045
  'cost': None,
1019
- 'fee': None,
1046
+ 'fee': {
1047
+ 'cost': feeCost,
1048
+ 'rate': feeRate,
1049
+ 'currency': feeCurrency,
1050
+ },
1020
1051
  }, market)
1021
1052
 
1022
1053
  async def watch_balance(self, params={}) -> Balances:
@@ -1119,6 +1150,7 @@ class kucoin(ccxt.async_support.kucoin):
1119
1150
  'account.balance': self.handle_balance,
1120
1151
  'orderChange': self.handle_order,
1121
1152
  'stopOrder': self.handle_order,
1153
+ '/spot/tradeFills': self.handle_my_trade,
1122
1154
  }
1123
1155
  method = self.safe_value(methods, subject)
1124
1156
  if method is not None:
ccxt/pro/phemex.py CHANGED
@@ -45,7 +45,7 @@ class phemex(ccxt.async_support.phemex):
45
45
  'OHLCVLimit': 1000,
46
46
  },
47
47
  'streaming': {
48
- 'keepAlive': 10000,
48
+ 'keepAlive': 9000,
49
49
  },
50
50
  })
51
51