ccxt 4.4.99__py2.py3-none-any.whl → 4.4.100__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 (197) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/bingx.py +1 -0
  3. ccxt/alpaca.py +1 -1
  4. ccxt/apex.py +1 -1
  5. ccxt/ascendex.py +1 -1
  6. ccxt/async_support/__init__.py +1 -1
  7. ccxt/async_support/alpaca.py +1 -1
  8. ccxt/async_support/apex.py +1 -1
  9. ccxt/async_support/ascendex.py +1 -1
  10. ccxt/async_support/base/exchange.py +44 -9
  11. ccxt/async_support/base/ws/client.py +3 -1
  12. ccxt/async_support/bigone.py +1 -1
  13. ccxt/async_support/binance.py +3 -2
  14. ccxt/async_support/bingx.py +33 -4
  15. ccxt/async_support/bitbank.py +1 -1
  16. ccxt/async_support/bitfinex.py +4 -1
  17. ccxt/async_support/bitflyer.py +1 -1
  18. ccxt/async_support/bitget.py +32 -14
  19. ccxt/async_support/bithumb.py +1 -1
  20. ccxt/async_support/bitmart.py +2 -2
  21. ccxt/async_support/bitmex.py +3 -2
  22. ccxt/async_support/bitopro.py +1 -1
  23. ccxt/async_support/bitrue.py +2 -2
  24. ccxt/async_support/bitso.py +1 -1
  25. ccxt/async_support/bitstamp.py +1 -1
  26. ccxt/async_support/bittrade.py +1 -1
  27. ccxt/async_support/bitvavo.py +1 -1
  28. ccxt/async_support/blockchaincom.py +1 -1
  29. ccxt/async_support/blofin.py +1 -1
  30. ccxt/async_support/btcmarkets.py +1 -1
  31. ccxt/async_support/bybit.py +2 -2
  32. ccxt/async_support/coinbase.py +1 -1
  33. ccxt/async_support/coinbaseexchange.py +1 -1
  34. ccxt/async_support/coinbaseinternational.py +1 -1
  35. ccxt/async_support/coincatch.py +2 -2
  36. ccxt/async_support/coinex.py +3 -3
  37. ccxt/async_support/coinmate.py +1 -1
  38. ccxt/async_support/coinsph.py +1 -1
  39. ccxt/async_support/cryptocom.py +1 -1
  40. ccxt/async_support/defx.py +2 -2
  41. ccxt/async_support/delta.py +1 -1
  42. ccxt/async_support/deribit.py +1 -1
  43. ccxt/async_support/digifinex.py +2 -2
  44. ccxt/async_support/ellipx.py +1 -1
  45. ccxt/async_support/exmo.py +1 -1
  46. ccxt/async_support/foxbit.py +3 -3
  47. ccxt/async_support/gate.py +17 -2
  48. ccxt/async_support/gemini.py +1 -1
  49. ccxt/async_support/hashkey.py +2 -2
  50. ccxt/async_support/hibachi.py +1 -1
  51. ccxt/async_support/hitbtc.py +2 -2
  52. ccxt/async_support/hollaex.py +1 -1
  53. ccxt/async_support/htx.py +4 -3
  54. ccxt/async_support/hyperliquid.py +71 -29
  55. ccxt/async_support/independentreserve.py +1 -1
  56. ccxt/async_support/indodax.py +1 -1
  57. ccxt/async_support/kraken.py +1 -1
  58. ccxt/async_support/krakenfutures.py +2 -1
  59. ccxt/async_support/kucoin.py +2 -2
  60. ccxt/async_support/kucoinfutures.py +2 -1
  61. ccxt/async_support/lbank.py +2 -2
  62. ccxt/async_support/mercado.py +1 -1
  63. ccxt/async_support/mexc.py +9 -2
  64. ccxt/async_support/modetrade.py +93 -2
  65. ccxt/async_support/ndax.py +1 -1
  66. ccxt/async_support/novadax.py +1 -1
  67. ccxt/async_support/okcoin.py +1 -1
  68. ccxt/async_support/okx.py +2 -2
  69. ccxt/async_support/onetrading.py +33 -0
  70. ccxt/async_support/oxfun.py +1 -1
  71. ccxt/async_support/p2b.py +32 -0
  72. ccxt/async_support/paradex.py +2 -1
  73. ccxt/async_support/phemex.py +2 -2
  74. ccxt/async_support/poloniex.py +2 -2
  75. ccxt/async_support/probit.py +36 -1
  76. ccxt/async_support/tokocrypto.py +1 -1
  77. ccxt/async_support/upbit.py +1 -1
  78. ccxt/async_support/vertex.py +1 -1
  79. ccxt/async_support/wavesexchange.py +1 -1
  80. ccxt/async_support/whitebit.py +2 -2
  81. ccxt/async_support/woo.py +4 -4
  82. ccxt/async_support/woofipro.py +93 -2
  83. ccxt/async_support/xt.py +2 -2
  84. ccxt/async_support/yobit.py +1 -1
  85. ccxt/async_support/zaif.py +1 -1
  86. ccxt/async_support/zonda.py +1 -1
  87. ccxt/base/exchange.py +11 -9
  88. ccxt/base/types.py +1 -0
  89. ccxt/bigone.py +1 -1
  90. ccxt/binance.py +3 -2
  91. ccxt/bingx.py +33 -4
  92. ccxt/bitbank.py +1 -1
  93. ccxt/bitfinex.py +4 -1
  94. ccxt/bitflyer.py +1 -1
  95. ccxt/bitget.py +32 -14
  96. ccxt/bithumb.py +1 -1
  97. ccxt/bitmart.py +2 -2
  98. ccxt/bitmex.py +3 -2
  99. ccxt/bitopro.py +1 -1
  100. ccxt/bitrue.py +2 -2
  101. ccxt/bitso.py +1 -1
  102. ccxt/bitstamp.py +1 -1
  103. ccxt/bittrade.py +1 -1
  104. ccxt/bitvavo.py +1 -1
  105. ccxt/blockchaincom.py +1 -1
  106. ccxt/blofin.py +1 -1
  107. ccxt/btcmarkets.py +1 -1
  108. ccxt/bybit.py +2 -2
  109. ccxt/coinbase.py +1 -1
  110. ccxt/coinbaseexchange.py +1 -1
  111. ccxt/coinbaseinternational.py +1 -1
  112. ccxt/coincatch.py +2 -2
  113. ccxt/coinex.py +3 -3
  114. ccxt/coinmate.py +1 -1
  115. ccxt/coinsph.py +1 -1
  116. ccxt/cryptocom.py +1 -1
  117. ccxt/defx.py +2 -2
  118. ccxt/delta.py +1 -1
  119. ccxt/deribit.py +1 -1
  120. ccxt/digifinex.py +2 -2
  121. ccxt/ellipx.py +1 -1
  122. ccxt/exmo.py +1 -1
  123. ccxt/foxbit.py +3 -3
  124. ccxt/gate.py +17 -2
  125. ccxt/gemini.py +1 -1
  126. ccxt/hashkey.py +2 -2
  127. ccxt/hibachi.py +1 -1
  128. ccxt/hitbtc.py +2 -2
  129. ccxt/hollaex.py +1 -1
  130. ccxt/htx.py +4 -3
  131. ccxt/hyperliquid.py +71 -29
  132. ccxt/independentreserve.py +1 -1
  133. ccxt/indodax.py +1 -1
  134. ccxt/kraken.py +1 -1
  135. ccxt/krakenfutures.py +2 -1
  136. ccxt/kucoin.py +2 -2
  137. ccxt/kucoinfutures.py +2 -1
  138. ccxt/lbank.py +2 -2
  139. ccxt/mercado.py +1 -1
  140. ccxt/mexc.py +9 -2
  141. ccxt/modetrade.py +93 -2
  142. ccxt/ndax.py +1 -1
  143. ccxt/novadax.py +1 -1
  144. ccxt/okcoin.py +1 -1
  145. ccxt/okx.py +2 -2
  146. ccxt/onetrading.py +33 -0
  147. ccxt/oxfun.py +1 -1
  148. ccxt/p2b.py +32 -0
  149. ccxt/paradex.py +2 -1
  150. ccxt/phemex.py +2 -2
  151. ccxt/poloniex.py +2 -2
  152. ccxt/pro/__init__.py +1 -1
  153. ccxt/pro/binance.py +2 -1
  154. ccxt/pro/bitvavo.py +1 -1
  155. ccxt/pro/bybit.py +1 -0
  156. ccxt/pro/coinex.py +1 -1
  157. ccxt/pro/hyperliquid.py +99 -12
  158. ccxt/pro/kucoin.py +1 -1
  159. ccxt/pro/kucoinfutures.py +1 -1
  160. ccxt/pro/mexc.py +328 -139
  161. ccxt/pro/okx.py +2 -1
  162. ccxt/pro/oxfun.py +1 -1
  163. ccxt/probit.py +36 -1
  164. ccxt/protobuf/__init__.py +0 -0
  165. ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
  166. ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
  167. ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
  168. ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
  169. ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
  170. ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
  171. ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
  172. ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
  173. ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
  174. ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
  175. ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
  176. ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
  177. ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
  178. ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
  179. ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
  180. ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
  181. ccxt/protobuf/mexc/__init__.py +0 -0
  182. ccxt/tokocrypto.py +1 -1
  183. ccxt/upbit.py +1 -1
  184. ccxt/vertex.py +1 -1
  185. ccxt/wavesexchange.py +1 -1
  186. ccxt/whitebit.py +2 -2
  187. ccxt/woo.py +4 -4
  188. ccxt/woofipro.py +93 -2
  189. ccxt/xt.py +2 -2
  190. ccxt/yobit.py +1 -1
  191. ccxt/zaif.py +1 -1
  192. ccxt/zonda.py +1 -1
  193. {ccxt-4.4.99.dist-info → ccxt-4.4.100.dist-info}/METADATA +5 -5
  194. {ccxt-4.4.99.dist-info → ccxt-4.4.100.dist-info}/RECORD +197 -179
  195. {ccxt-4.4.99.dist-info → ccxt-4.4.100.dist-info}/LICENSE.txt +0 -0
  196. {ccxt-4.4.99.dist-info → ccxt-4.4.100.dist-info}/WHEEL +0 -0
  197. {ccxt-4.4.99.dist-info → ccxt-4.4.100.dist-info}/top_level.txt +0 -0
ccxt/pro/mexc.py CHANGED
@@ -49,13 +49,14 @@ class mexc(ccxt.async_support.mexc):
49
49
  'urls': {
50
50
  'api': {
51
51
  'ws': {
52
- 'spot': 'wss://wbs.mexc.com/ws',
52
+ 'spot': 'wss://wbs-api.mexc.com/ws',
53
53
  'swap': 'wss://contract.mexc.com/edge',
54
54
  },
55
55
  },
56
56
  },
57
57
  'options': {
58
58
  'listenKeyRefreshRate': 1200000,
59
+ 'decompressBinary': False,
59
60
  # TODO add reset connection after #16754 is merged
60
61
  'timeframes': {
61
62
  '1m': 'Min1',
@@ -100,13 +101,7 @@ class mexc(ccxt.async_support.mexc):
100
101
  market = self.market(symbol)
101
102
  messageHash = 'ticker:' + market['symbol']
102
103
  if market['spot']:
103
- miniTicker = False
104
- miniTicker, params = self.handle_option_and_params(params, 'watchTicker', 'miniTicker')
105
- channel = None
106
- if miniTicker:
107
- channel = 'spot@public.miniTicker.v3.api@' + market['id'] + '@UTC+8'
108
- else:
109
- channel = 'spot@public.bookTicker.v3.api@' + market['id']
104
+ channel = 'spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id']
110
105
  return await self.watch_spot_public(channel, messageHash, params)
111
106
  else:
112
107
  channel = 'sub.ticker'
@@ -184,9 +179,9 @@ class mexc(ccxt.async_support.mexc):
184
179
  # }
185
180
  #
186
181
  self.handle_bid_ask(client, message)
187
- rawTicker = self.safe_dict_2(message, 'd', 'data')
182
+ rawTicker = self.safe_dict_n(message, ['d', 'data', 'publicAggreBookTicker'])
188
183
  marketId = self.safe_string_2(message, 's', 'symbol')
189
- timestamp = self.safe_integer(message, 't')
184
+ timestamp = self.safe_integer_2(message, 't', 'sendtime')
190
185
  market = self.safe_market(marketId)
191
186
  symbol = market['symbol']
192
187
  ticker = None
@@ -226,27 +221,33 @@ class mexc(ccxt.async_support.mexc):
226
221
  url = self.urls['api']['ws']['spot'] if (isSpot) else self.urls['api']['ws']['swap']
227
222
  request: dict = {}
228
223
  if isSpot:
229
- miniTicker = False
230
- miniTicker, params = self.handle_option_and_params(params, 'watchTickers', 'miniTicker')
231
- topics = []
232
- if not miniTicker:
233
- if symbols is None:
234
- raise ArgumentsRequired(self.id + ' watchTickers required symbols argument for the bookTicker channel')
235
- marketIds = self.market_ids(symbols)
236
- for i in range(0, len(marketIds)):
237
- marketId = marketIds[i]
238
- messageHashes.append('ticker:' + symbols[i])
239
- channel = 'spot@public.bookTicker.v3.api@' + marketId
240
- topics.append(channel)
241
- else:
242
- topics.append('spot@public.miniTickers.v3.api@UTC+8')
243
- if symbols is None:
244
- messageHashes.append('spot:ticker')
245
- else:
246
- for i in range(0, len(symbols)):
247
- messageHashes.append('ticker:' + symbols[i])
248
- request['method'] = 'SUBSCRIPTION'
249
- request['params'] = topics
224
+ raise NotSupported(self.id + ' watchTickers does not support spot markets')
225
+ # miniTicker = False
226
+ # miniTicker, params = self.handle_option_and_params(params, 'watchTickers', 'miniTicker')
227
+ # topics = []
228
+ # if not miniTicker:
229
+ # if symbols is None:
230
+ # raise ArgumentsRequired(self.id + ' watchTickers required symbols argument for the bookTicker channel')
231
+ # }
232
+ # marketIds = self.market_ids(symbols)
233
+ # for i in range(0, len(marketIds)):
234
+ # marketId = marketIds[i]
235
+ # messageHashes.append('ticker:' + symbols[i])
236
+ # channel = 'spot@public.bookTicker.v3.api@' + marketId
237
+ # topics.append(channel)
238
+ # }
239
+ # else:
240
+ # topics.append('spot@public.miniTickers.v3.api@UTC+8')
241
+ # if symbols is None:
242
+ # messageHashes.append('spot:ticker')
243
+ # else:
244
+ # for i in range(0, len(symbols)):
245
+ # messageHashes.append('ticker:' + symbols[i])
246
+ # }
247
+ # }
248
+ # }
249
+ # request['method'] = 'SUBSCRIPTION'
250
+ # request['params'] = topics
250
251
  else:
251
252
  request['method'] = 'sub.tickers'
252
253
  request['params'] = {}
@@ -345,6 +346,11 @@ class mexc(ccxt.async_support.mexc):
345
346
  client.resolve(result, topic)
346
347
 
347
348
  def parse_ws_ticker(self, ticker, market=None):
349
+ # protobuf ticker
350
+ # "bidprice": "93387.28", # Best bid price
351
+ # "bidquantity": "3.73485", # Best bid quantity
352
+ # "askprice": "93387.29", # Best ask price
353
+ # "askquantity": "7.669875" # Best ask quantity
348
354
  #
349
355
  # spot
350
356
  #
@@ -359,7 +365,7 @@ class mexc(ccxt.async_support.mexc):
359
365
  #
360
366
  # {
361
367
  # "s": "BTCUSDT",
362
- # "p": "76522",
368
+ # "p": "76521",
363
369
  # "r": "0.0012",
364
370
  # "tr": "0.0012",
365
371
  # "h": "77196.3",
@@ -385,10 +391,10 @@ class mexc(ccxt.async_support.mexc):
385
391
  'low': self.safe_number(ticker, 'l'),
386
392
  'close': price,
387
393
  'last': price,
388
- 'bid': self.safe_number(ticker, 'b'),
389
- 'bidVolume': self.safe_number(ticker, 'B'),
390
- 'ask': self.safe_number(ticker, 'a'),
391
- 'askVolume': self.safe_number(ticker, 'A'),
394
+ 'bid': self.safe_number_2(ticker, 'b', 'bidPrice'),
395
+ 'bidVolume': self.safe_number_2(ticker, 'B', 'bidQuantity'),
396
+ 'ask': self.safe_number_2(ticker, 'a', 'askPrice'),
397
+ 'askVolume': self.safe_number_2(ticker, 'A', 'askQuantity'),
392
398
  'vwap': None,
393
399
  'previousClose': None,
394
400
  'change': None,
@@ -423,7 +429,7 @@ class mexc(ccxt.async_support.mexc):
423
429
  for i in range(0, len(symbols)):
424
430
  if isSpot:
425
431
  market = self.market(symbols[i])
426
- topics.append('spot@public.bookTicker.v3.api@' + market['id'])
432
+ topics.append('spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id'])
427
433
  messageHashes.append('bidask:' + symbols[i])
428
434
  url = self.urls['api']['ws']['spot']
429
435
  request: dict = {
@@ -527,7 +533,7 @@ class mexc(ccxt.async_support.mexc):
527
533
  async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
528
534
  """
529
535
 
530
- https://mexcdevelop.github.io/apidocs/spot_v3_en/#kline-streams
536
+ https://www.mexc.com/api-docs/spot-v3/websocket-market-streams#trade-streams
531
537
 
532
538
  watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
533
539
  :param str symbol: unified symbol of the market to fetch OHLCV data for
@@ -545,7 +551,7 @@ class mexc(ccxt.async_support.mexc):
545
551
  messageHash = 'candles:' + symbol + ':' + timeframe
546
552
  ohlcv = None
547
553
  if market['spot']:
548
- channel = 'spot@public.kline.v3.api@' + market['id'] + '@' + timeframeId
554
+ channel = 'spot@public.kline.v3.api.pb@' + market['id'] + '@' + timeframeId
549
555
  ohlcv = await self.watch_spot_public(channel, messageHash, params)
550
556
  else:
551
557
  channel = 'sub.kline'
@@ -604,17 +610,45 @@ class mexc(ccxt.async_support.mexc):
604
610
  # "symbol": "BTC_USDT",
605
611
  # "ts": 1651230713067
606
612
  # }
613
+ # protobuf
614
+ # {
615
+ # "channel":"spot@public.kline.v3.api.pb@BTCUSDT@Min1",
616
+ # "symbol":"BTCUSDT",
617
+ # "symbolId":"2fb942154ef44a4ab2ef98c8afb6a4a7",
618
+ # "createTime":"1754737941062",
619
+ # "publicSpotKline":{
620
+ # "interval":"Min1",
621
+ # "windowStart":"1754737920",
622
+ # "openingPrice":"117317.31",
623
+ # "closingPrice":"117325.26",
624
+ # "highestPrice":"117341",
625
+ # "lowestPrice":"117317.3",
626
+ # "volume":"3.12599854",
627
+ # "amount":"366804.43",
628
+ # "windowEnd":"1754737980"
629
+ # }
630
+ # }
607
631
  #
608
- d = self.safe_value_2(message, 'd', 'data', {})
609
- rawOhlcv = self.safe_value(d, 'k', d)
610
- timeframeId = self.safe_string_2(rawOhlcv, 'i', 'interval')
611
- timeframes = self.safe_value(self.options, 'timeframes', {})
612
- timeframe = self.find_timeframe(timeframeId, timeframes)
613
- marketId = self.safe_string_2(message, 's', 'symbol')
614
- market = self.safe_market(marketId)
615
- symbol = market['symbol']
632
+ parsed: dict = None
633
+ symbol: Str = None
634
+ timeframe: Str = None
635
+ if 'publicSpotKline' in message:
636
+ symbol = self.symbol(self.safe_string(message, 'symbol'))
637
+ data = self.safe_dict(message, 'publicSpotKline', {})
638
+ timeframeId = self.safe_string(data, 'interval')
639
+ timeframe = self.find_timeframe(timeframeId, self.options['timeframes'])
640
+ parsed = self.parse_ws_ohlcv(data, self.safe_market(symbol))
641
+ else:
642
+ d = self.safe_value_2(message, 'd', 'data', {})
643
+ rawOhlcv = self.safe_value(d, 'k', d)
644
+ timeframeId = self.safe_string_2(rawOhlcv, 'i', 'interval')
645
+ timeframes = self.safe_value(self.options, 'timeframes', {})
646
+ timeframe = self.find_timeframe(timeframeId, timeframes)
647
+ marketId = self.safe_string_2(message, 's', 'symbol')
648
+ market = self.safe_market(marketId)
649
+ symbol = market['symbol']
650
+ parsed = self.parse_ws_ohlcv(rawOhlcv, market)
616
651
  messageHash = 'candles:' + symbol + ':' + timeframe
617
- parsed = self.parse_ws_ohlcv(rawOhlcv, market)
618
652
  self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
619
653
  stored = self.safe_value(self.ohlcvs[symbol], timeframe)
620
654
  if stored is None:
@@ -656,26 +690,38 @@ class mexc(ccxt.async_support.mexc):
656
690
  # "rh": 27301.8,
657
691
  # "rl": 27301.8
658
692
  # }
693
+ # protobuf
694
+ #
695
+ # "interval":"Min1",
696
+ # "windowStart":"1754737920",
697
+ # "openingPrice":"117317.31",
698
+ # "closingPrice":"117325.26",
699
+ # "highestPrice":"117341",
700
+ # "lowestPrice":"117317.3",
701
+ # "volume":"3.12599854",
702
+ # "amount":"366804.43",
703
+ # "windowEnd":"1754737980"
659
704
  #
660
705
  return [
661
- self.safe_timestamp(ohlcv, 't'),
662
- self.safe_number(ohlcv, 'o'),
663
- self.safe_number(ohlcv, 'h'),
664
- self.safe_number(ohlcv, 'l'),
665
- self.safe_number(ohlcv, 'c'),
666
- self.safe_number_2(ohlcv, 'v', 'q'),
706
+ self.safe_timestamp_2(ohlcv, 't', 'windowStart'),
707
+ self.safe_number_2(ohlcv, 'o', 'openingPrice'),
708
+ self.safe_number_2(ohlcv, 'h', 'highestPrice'),
709
+ self.safe_number_2(ohlcv, 'l', 'lowestPrice'),
710
+ self.safe_number_2(ohlcv, 'c', 'closingPrice'),
711
+ self.safe_number_2(ohlcv, 'v', 'volume'),
667
712
  ]
668
713
 
669
714
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
670
715
  """
671
716
 
672
- https://mexcdevelop.github.io/apidocs/spot_v3_en/#diff-depth-stream
717
+ https://www.mexc.com/api-docs/spot-v3/websocket-market-streams#trade-streams
673
718
  https://mexcdevelop.github.io/apidocs/contract_v1_en/#public-channels
674
719
 
675
720
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
676
721
  :param str symbol: unified symbol of the market to fetch the order book for
677
722
  :param int [limit]: the maximum amount of order book entries to return
678
723
  :param dict [params]: extra parameters specific to the exchange API endpoint
724
+ :param str [params.frequency]: the frequency of the order book updates, default is '10ms', can be '100ms' or '10ms
679
725
  :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
680
726
  """
681
727
  await self.load_markets()
@@ -684,7 +730,9 @@ class mexc(ccxt.async_support.mexc):
684
730
  messageHash = 'orderbook:' + symbol
685
731
  orderbook = None
686
732
  if market['spot']:
687
- channel = 'spot@public.increase.depth.v3.api@' + market['id']
733
+ frequency = None
734
+ frequency, params = self.handle_option_and_params(params, 'watchOrderBook', 'frequency', '100ms')
735
+ channel = 'spot@public.aggre.depth.v3.api.pb@' + frequency + '@' + market['id']
688
736
  orderbook = await self.watch_spot_public(channel, messageHash, params)
689
737
  else:
690
738
  channel = 'sub.depth'
@@ -708,12 +756,12 @@ class mexc(ccxt.async_support.mexc):
708
756
  # return the first index of the cache that can be applied to the orderbook or -1 if not possible
709
757
  nonce = self.safe_integer(orderbook, 'nonce')
710
758
  firstDelta = self.safe_value(cache, 0)
711
- firstDeltaNonce = self.safe_integer_2(firstDelta, 'r', 'version')
759
+ firstDeltaNonce = self.safe_integer_n(firstDelta, ['r', 'version', 'fromVersion'])
712
760
  if nonce < firstDeltaNonce - 1:
713
761
  return -1
714
762
  for i in range(0, len(cache)):
715
763
  delta = cache[i]
716
- deltaNonce = self.safe_integer_2(delta, 'r', 'version')
764
+ deltaNonce = self.safe_integer_n(delta, ['r', 'version', 'fromVersion'])
717
765
  if deltaNonce >= nonce:
718
766
  return i
719
767
  return len(cache)
@@ -761,8 +809,31 @@ class mexc(ccxt.async_support.mexc):
761
809
  # "symbol":"BTC_USDT",
762
810
  # "ts":1651239652372
763
811
  # }
812
+ # protofbuf
813
+ # {
814
+ # "channel":"spot@public.aggre.depth.v3.api.pb@100ms@BTCUSDT",
815
+ # "symbol":"BTCUSDT",
816
+ # "sendTime":"1754741322152",
817
+ # "publicAggreDepths":{
818
+ # "asks":[
819
+ # {
820
+ # "price":"117145.49",
821
+ # "quantity":"0"
822
+ # }
823
+ # ],
824
+ # "bids":[
825
+ # {
826
+ # "price":"117053.41",
827
+ # "quantity":"1.86837271"
828
+ # }
829
+ # ],
830
+ # "eventType":"spot@public.aggre.depth.v3.api.pb@100ms",
831
+ # "fromVersion":"43296363236",
832
+ # "toVersion":"43296363255"
833
+ # }
834
+ # }
764
835
  #
765
- data = self.safe_value_2(message, 'd', 'data')
836
+ data = self.safe_dict_n(message, ['d', 'data', 'publicAggreDepths'])
766
837
  marketId = self.safe_string_2(message, 's', 'symbol')
767
838
  symbol = self.safe_symbol(marketId)
768
839
  messageHash = 'orderbook:' + symbol
@@ -781,9 +852,10 @@ class mexc(ccxt.async_support.mexc):
781
852
  return
782
853
  try:
783
854
  self.handle_delta(storedOrderBook, data)
784
- timestamp = self.safe_integer_2(message, 't', 'ts')
855
+ timestamp = self.safe_integer_n(message, ['t', 'ts', 'sendTime'])
785
856
  storedOrderBook['timestamp'] = timestamp
786
857
  storedOrderBook['datetime'] = self.iso8601(timestamp)
858
+ storedOrderBook['nonce'] = self.safe_integer(data, 'fromVersion')
787
859
  except Exception as e:
788
860
  del client.subscriptions[messageHash]
789
861
  client.reject(e, messageHash)
@@ -801,13 +873,13 @@ class mexc(ccxt.async_support.mexc):
801
873
  if isinstance(bidask, list):
802
874
  bookside.storeArray(bidask)
803
875
  else:
804
- price = self.safe_float(bidask, 'p')
805
- amount = self.safe_float(bidask, 'v')
876
+ price = self.safe_float_2(bidask, 'p', 'price')
877
+ amount = self.safe_float_2(bidask, 'v', 'quantity')
806
878
  bookside.store(price, amount)
807
879
 
808
880
  def handle_delta(self, orderbook, delta):
809
881
  existingNonce = self.safe_integer(orderbook, 'nonce')
810
- deltaNonce = self.safe_integer_2(delta, 'r', 'version')
882
+ deltaNonce = self.safe_integer_n(delta, ['r', 'version', 'fromVersion'])
811
883
  if deltaNonce < existingNonce:
812
884
  # even when doing < comparison, self happens: https://app.travis-ci.com/github/ccxt/ccxt/builds/269234741#L1809
813
885
  # so, we just skip old updates
@@ -823,7 +895,7 @@ class mexc(ccxt.async_support.mexc):
823
895
  async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
824
896
  """
825
897
 
826
- https://mexcdevelop.github.io/apidocs/spot_v3_en/#trade-streams
898
+ https://www.mexc.com/api-docs/spot-v3/websocket-market-streams#trade-streams
827
899
  https://mexcdevelop.github.io/apidocs/contract_v1_en/#public-channels
828
900
 
829
901
  get the list of most recent trades for a particular symbol
@@ -839,7 +911,7 @@ class mexc(ccxt.async_support.mexc):
839
911
  messageHash = 'trades:' + symbol
840
912
  trades = None
841
913
  if market['spot']:
842
- channel = 'spot@public.deals.v3.api@' + market['id']
914
+ channel = 'spot@public.aggre.deals.v3.api.pb@100ms@' + market['id']
843
915
  trades = await self.watch_spot_public(channel, messageHash, params)
844
916
  else:
845
917
  channel = 'sub.deal'
@@ -852,6 +924,23 @@ class mexc(ccxt.async_support.mexc):
852
924
  return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
853
925
 
854
926
  def handle_trades(self, client: Client, message):
927
+ # protobuf
928
+ # {
929
+ # "channel": "spot@public.aggre.deals.v3.api.pb@100ms@BTCUSDT",
930
+ # "publicdeals": {
931
+ # "dealsList": [
932
+ # {
933
+ # "price": "93220.00", # Trade price
934
+ # "quantity": "0.04438243", # Trade quantity
935
+ # "tradetype": 2, # Trade type(1: Buy, 2: Sell)
936
+ # "time": 1736409765051 # Trade time
937
+ # }
938
+ # ],
939
+ # "eventtype": "spot@public.aggre.deals.v3.api.pb@100ms" # Event type
940
+ # },
941
+ # "symbol": "BTCUSDT", # Trading pair
942
+ # "sendtime": 1736409765052 # Event time
943
+ # }
855
944
  #
856
945
  # {
857
946
  # "c": "spot@public.deals.v3.api@BTCUSDT",
@@ -892,8 +981,8 @@ class mexc(ccxt.async_support.mexc):
892
981
  limit = self.safe_integer(self.options, 'tradesLimit', 1000)
893
982
  stored = ArrayCache(limit)
894
983
  self.trades[symbol] = stored
895
- d = self.safe_value_2(message, 'd', 'data')
896
- trades = self.safe_value(d, 'deals', [d])
984
+ d = self.safe_dict_n(message, ['d', 'data', 'publicAggreDeals'])
985
+ trades = self.safe_list_2(d, 'deals', 'dealsList', [d])
897
986
  for j in range(0, len(trades)):
898
987
  parsedTrade = None
899
988
  if market['spot']:
@@ -906,7 +995,7 @@ class mexc(ccxt.async_support.mexc):
906
995
  async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
907
996
  """
908
997
 
909
- https://mexcdevelop.github.io/apidocs/spot_v3_en/#spot-account-deals
998
+ https://www.mexc.com/api-docs/spot-v3/websocket-user-data-streams#spot-account-deals
910
999
  https://mexcdevelop.github.io/apidocs/contract_v1_en/#private-channels
911
1000
 
912
1001
  watches information on multiple trades made by the user
@@ -927,7 +1016,7 @@ class mexc(ccxt.async_support.mexc):
927
1016
  type, params = self.handle_market_type_and_params('watchMyTrades', market, params)
928
1017
  trades = None
929
1018
  if type == 'spot':
930
- channel = 'spot@private.deals.v3.api'
1019
+ channel = 'spot@private.deals.v3.api.pb'
931
1020
  trades = await self.watch_spot_private(channel, messageHash, params)
932
1021
  else:
933
1022
  trades = await self.watch_swap_private(messageHash, params)
@@ -953,11 +1042,27 @@ class mexc(ccxt.async_support.mexc):
953
1042
  # "s": "BTCUSDT",
954
1043
  # "t": 1678670940700
955
1044
  # }
1045
+ # {
1046
+ # channel: "spot@private.deals.v3.api.pb",
1047
+ # symbol: "MXUSDT",
1048
+ # sendTime: 1736417034332,
1049
+ # privateDeals {
1050
+ # price: "3.6962",
1051
+ # quantity: "1",
1052
+ # amount: "3.6962",
1053
+ # tradeType: 2,
1054
+ # tradeId: "505979017439002624X1",
1055
+ # orderId: "C02__505979017439002624115",
1056
+ # feeAmount: "0.0003998377369698171",
1057
+ # feeCurrency: "MX",
1058
+ # time: 1736417034280
1059
+ # }
1060
+ # }
956
1061
  #
957
1062
  messageHash = 'myTrades'
958
- data = self.safe_value_2(message, 'd', 'data')
1063
+ data = self.safe_dict_n(message, ['d', 'data', 'privateDeals'])
959
1064
  futuresMarketId = self.safe_string(data, 'symbol')
960
- marketId = self.safe_string(message, 's', futuresMarketId)
1065
+ marketId = self.safe_string_2(message, 's', 'symbol', futuresMarketId)
961
1066
  market = self.safe_market(marketId)
962
1067
  symbol = market['symbol']
963
1068
  trade = None
@@ -977,7 +1082,7 @@ class mexc(ccxt.async_support.mexc):
977
1082
 
978
1083
  def parse_ws_trade(self, trade, market=None):
979
1084
  #
980
- # public trade
1085
+ # public trade(protobuf)
981
1086
  # {
982
1087
  # "p": "20382.70",
983
1088
  # "v": "0.043800",
@@ -997,7 +1102,6 @@ class mexc(ccxt.async_support.mexc):
997
1102
  # "v": "5"
998
1103
  # }
999
1104
  #
1000
- #
1001
1105
  # d: {
1002
1106
  # p: '1.0005',
1003
1107
  # v: '5.71',
@@ -1012,22 +1116,36 @@ class mexc(ccxt.async_support.mexc):
1012
1116
  # n: '0.005712855',
1013
1117
  # N: 'USDT'
1014
1118
  # }
1015
- timestamp = self.safe_integer(trade, 'T')
1016
- tradeId = self.safe_string(trade, 't')
1119
+ # protobuf
1120
+ #
1121
+ # {
1122
+ # price: "3.6962",
1123
+ # quantity: "1",
1124
+ # amount: "3.6962",
1125
+ # tradeType: 2,
1126
+ # tradeId: "505979017439002624X1",
1127
+ # orderId: "C02__505979017439002624115",
1128
+ # feeAmount: "0.0003998377369698171",
1129
+ # feeCurrency: "MX",
1130
+ # time: 1736417034280
1131
+ # }
1132
+ #
1133
+ timestamp = self.safe_integer_2(trade, 'T', 'time')
1134
+ tradeId = self.safe_string_2(trade, 't', 'tradeId')
1017
1135
  if timestamp is None:
1018
1136
  timestamp = self.safe_integer(trade, 't')
1019
1137
  tradeId = None
1020
- priceString = self.safe_string(trade, 'p')
1021
- amountString = self.safe_string(trade, 'v')
1022
- rawSide = self.safe_string(trade, 'S')
1138
+ priceString = self.safe_string_2(trade, 'p', 'price')
1139
+ amountString = self.safe_string_2(trade, 'v', 'quantity')
1140
+ rawSide = self.safe_string_2(trade, 'S', 'tradeType')
1023
1141
  side = 'buy' if (rawSide == '1') else 'sell'
1024
1142
  isMaker = self.safe_integer(trade, 'm')
1025
- feeAmount = self.safe_number(trade, 'n')
1026
- feeCurrencyId = self.safe_string(trade, 'N')
1143
+ feeAmount = self.safe_string_2(trade, 'n', 'feeAmount')
1144
+ feeCurrencyId = self.safe_string_2(trade, 'N', 'feeCurrency')
1027
1145
  return self.safe_trade({
1028
1146
  'info': trade,
1029
1147
  'id': tradeId,
1030
- 'order': self.safe_string(trade, 'i'),
1148
+ 'order': self.safe_string_2(trade, 'i', 'orderId'),
1031
1149
  'timestamp': timestamp,
1032
1150
  'datetime': self.iso8601(timestamp),
1033
1151
  'symbol': self.safe_symbol(None, market),
@@ -1036,7 +1154,7 @@ class mexc(ccxt.async_support.mexc):
1036
1154
  'takerOrMaker': 'maker' if (isMaker) else 'taker',
1037
1155
  'price': priceString,
1038
1156
  'amount': amountString,
1039
- 'cost': None,
1157
+ 'cost': self.safe_string(trade, 'amount'),
1040
1158
  'fee': {
1041
1159
  'cost': feeAmount,
1042
1160
  'currency': self.safe_currency_code(feeCurrencyId),
@@ -1046,7 +1164,7 @@ class mexc(ccxt.async_support.mexc):
1046
1164
  async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1047
1165
  """
1048
1166
 
1049
- https://mexcdevelop.github.io/apidocs/spot_v3_en/#spot-account-orders
1167
+ https://www.mexc.com/api-docs/spot-v3/websocket-user-data-streams#spot-account-orders
1050
1168
  https://mexcdevelop.github.io/apidocs/spot_v3_en/#margin-account-orders
1051
1169
 
1052
1170
  watches information on multiple orders made by the user
@@ -1068,7 +1186,7 @@ class mexc(ccxt.async_support.mexc):
1068
1186
  type, params = self.handle_market_type_and_params('watchOrders', market, params)
1069
1187
  orders = None
1070
1188
  if type == 'spot':
1071
- channel = type + '@private.orders.v3.api'
1189
+ channel = 'spot@private.orders.v3.api.pb'
1072
1190
  orders = await self.watch_spot_private(channel, messageHash, params)
1073
1191
  else:
1074
1192
  orders = await self.watch_swap_private(messageHash, params)
@@ -1141,11 +1259,18 @@ class mexc(ccxt.async_support.mexc):
1141
1259
  # "s": "MXUSDT",
1142
1260
  # "t":1661938138193
1143
1261
  # }
1262
+ # protobuf
1263
+ # {
1264
+ # channel: "spot@private.orders.v3.api.pb",
1265
+ # symbol: "MXUSDT",
1266
+ # sendTime: 1736417034281,
1267
+ # privateOrders {}
1268
+ # }
1144
1269
  #
1145
1270
  messageHash = 'orders'
1146
- data = self.safe_value_2(message, 'd', 'data')
1271
+ data = self.safe_dict_n(message, ['d', 'data', 'privateOrders'])
1147
1272
  futuresMarketId = self.safe_string(data, 'symbol')
1148
- marketId = self.safe_string(message, 's', futuresMarketId)
1273
+ marketId = self.safe_string_2(message, 's', 'symbol', futuresMarketId)
1149
1274
  market = self.safe_market(marketId)
1150
1275
  symbol = market['symbol']
1151
1276
  parsed = None
@@ -1213,11 +1338,28 @@ class mexc(ccxt.async_support.mexc):
1213
1338
  # "s":1,
1214
1339
  # "i":"e03a5c7441e44ed899466a7140b71391",
1215
1340
  # }
1341
+ # protofbuf spot order
1342
+ # {
1343
+ # "id":"C02__583905164440776704043",
1344
+ # "price":"0.001053",
1345
+ # "quantity":"2000",
1346
+ # "amount":"0",
1347
+ # "avgPrice":"0.001007",
1348
+ # "orderType":5,
1349
+ # "tradeType":1,
1350
+ # "remainAmount":"0.092",
1351
+ # "remainQuantity":"0",
1352
+ # "lastDealQuantity":"2000",
1353
+ # "cumulativeQuantity":"2000",
1354
+ # "cumulativeAmount":"2.014",
1355
+ # "status":2,
1356
+ # "createTime":"1754996075502"
1357
+ # }
1216
1358
  #
1217
- timestamp = self.safe_integer(order, 'O')
1218
- side = self.safe_string(order, 'S')
1219
- status = self.safe_string(order, 's')
1220
- type = self.safe_string(order, 'o')
1359
+ timestamp = self.safe_integer(order, 'createTime')
1360
+ side = self.safe_string(order, 'tradeType')
1361
+ status = self.safe_string(order, 'status')
1362
+ type = self.safe_string(order, 'orderType')
1221
1363
  fee = None
1222
1364
  feeCurrency = self.safe_string(order, 'N')
1223
1365
  if feeCurrency is not None:
@@ -1226,8 +1368,8 @@ class mexc(ccxt.async_support.mexc):
1226
1368
  'cost': None,
1227
1369
  }
1228
1370
  return self.safe_order({
1229
- 'id': self.safe_string(order, 'i'),
1230
- 'clientOrderId': self.safe_string(order, 'c'),
1371
+ 'id': self.safe_string(order, 'id'),
1372
+ 'clientOrderId': self.safe_string(order, 'clientOrderId'),
1231
1373
  'timestamp': timestamp,
1232
1374
  'datetime': self.iso8601(timestamp),
1233
1375
  'lastTradeTimestamp': None,
@@ -1236,14 +1378,14 @@ class mexc(ccxt.async_support.mexc):
1236
1378
  'type': self.parse_ws_order_type(type),
1237
1379
  'timeInForce': self.parse_ws_time_in_force(type),
1238
1380
  'side': 'buy' if (side == '1') else 'sell',
1239
- 'price': self.safe_string(order, 'p'),
1381
+ 'price': self.safe_string(order, 'price'),
1240
1382
  'stopPrice': None,
1241
- 'triggerPrice': self.safe_number(order, 'P'),
1242
- 'average': self.safe_string(order, 'ap'),
1243
- 'amount': self.safe_string(order, 'v'),
1244
- 'cost': self.safe_string(order, 'a'),
1245
- 'filled': self.safe_string(order, 'cv'),
1246
- 'remaining': self.safe_string(order, 'V'),
1383
+ 'triggerPrice': None,
1384
+ 'average': self.safe_string(order, 'avgPrice'),
1385
+ 'amount': self.safe_string(order, 'quantity'),
1386
+ 'cost': self.safe_string(order, 'amount'),
1387
+ 'filled': self.safe_string(order, 'cumulativeQuantity'),
1388
+ 'remaining': self.safe_string(order, 'remainQuantity'),
1247
1389
  'fee': fee,
1248
1390
  'trades': None,
1249
1391
  'info': order,
@@ -1266,7 +1408,7 @@ class mexc(ccxt.async_support.mexc):
1266
1408
  def parse_ws_order_type(self, type):
1267
1409
  types: dict = {
1268
1410
  '1': 'limit', # LIMIT_ORDER
1269
- '2': None, # POST_ONLY
1411
+ '2': 'limit', # POST_ONLY
1270
1412
  '3': None, # IMMEDIATE_OR_CANCEL
1271
1413
  '4': None, # FILL_OR_KILL
1272
1414
  '5': 'market', # MARKET_ORDER
@@ -1288,7 +1430,7 @@ class mexc(ccxt.async_support.mexc):
1288
1430
  async def watch_balance(self, params={}) -> Balances:
1289
1431
  """
1290
1432
 
1291
- https://mexcdevelop.github.io/apidocs/spot_v3_en/#spot-account-upadte
1433
+ https://www.mexc.com/api-docs/spot-v3/websocket-user-data-streams#spot-account-update
1292
1434
 
1293
1435
  watch balance and get the amount of funds available for trading or funds locked in orders
1294
1436
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -1299,7 +1441,7 @@ class mexc(ccxt.async_support.mexc):
1299
1441
  type, params = self.handle_market_type_and_params('watchBalance', None, params)
1300
1442
  messageHash = 'balance:' + type
1301
1443
  if type == 'spot':
1302
- channel = 'spot@private.account.v3.api'
1444
+ channel = 'spot@private.account.v3.api.pb'
1303
1445
  return await self.watch_spot_private(channel, messageHash, params)
1304
1446
  else:
1305
1447
  return await self.watch_swap_private(messageHash, params)
@@ -1336,22 +1478,22 @@ class mexc(ccxt.async_support.mexc):
1336
1478
  # "ts": 1680059188190
1337
1479
  # }
1338
1480
  #
1339
- c = self.safe_string(message, 'c')
1481
+ c = self.safe_string_2(message, 'c', 'channel')
1340
1482
  type = 'swap' if (c is None) else 'spot'
1341
1483
  messageHash = 'balance:' + type
1342
- data = self.safe_value_2(message, 'd', 'data')
1484
+ data = self.safe_dict_n(message, ['d', 'data', 'privateAccount'])
1343
1485
  futuresTimestamp = self.safe_integer(message, 'ts')
1344
- timestamp = self.safe_integer(data, 'c', futuresTimestamp)
1486
+ timestamp = self.safe_integer_2(data, 'c', 'time', futuresTimestamp)
1345
1487
  if not (type in self.balance):
1346
1488
  self.balance[type] = {}
1347
1489
  self.balance[type]['info'] = data
1348
1490
  self.balance[type]['timestamp'] = timestamp
1349
1491
  self.balance[type]['datetime'] = self.iso8601(timestamp)
1350
- currencyId = self.safe_string_2(data, 'a', 'currency')
1492
+ currencyId = self.safe_string_n(data, ['a', 'currency', 'vcoinName'])
1351
1493
  code = self.safe_currency_code(currencyId)
1352
1494
  account = self.account()
1353
- account['free'] = self.safe_string_2(data, 'f', 'availableBalance')
1354
- account['used'] = self.safe_string_2(data, 'l', 'frozenBalance')
1495
+ account['total'] = self.safe_string_n(data, ['f', 'availableBalance', 'balanceAmount'])
1496
+ account['used'] = self.safe_string_n(data, ['l', 'frozenBalance', 'frozenAmount'])
1355
1497
  self.balance[type][code] = account
1356
1498
  self.balance[type] = self.safe_balance(self.balance[type])
1357
1499
  client.resolve(self.balance[type], messageHash)
@@ -1369,12 +1511,7 @@ class mexc(ccxt.async_support.mexc):
1369
1511
  url = None
1370
1512
  channel = None
1371
1513
  if market['spot']:
1372
- miniTicker = False
1373
- miniTicker, params = self.handle_option_and_params(params, 'watchTicker', 'miniTicker')
1374
- if miniTicker:
1375
- channel = 'spot@public.miniTicker.v3.api@' + market['id'] + '@UTC+8'
1376
- else:
1377
- channel = 'spot@public.bookTicker.v3.api@' + market['id']
1514
+ channel = 'spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id']
1378
1515
  url = self.urls['api']['ws']['spot']
1379
1516
  params['unsubscribed'] = True
1380
1517
  await self.watch_spot_public(channel, messageHash, params)
@@ -1409,27 +1546,33 @@ class mexc(ccxt.async_support.mexc):
1409
1546
  url = self.urls['api']['ws']['spot'] if (isSpot) else self.urls['api']['ws']['swap']
1410
1547
  request: dict = {}
1411
1548
  if isSpot:
1412
- miniTicker = False
1413
- miniTicker, params = self.handle_option_and_params(params, 'watchTickers', 'miniTicker')
1414
- topics = []
1415
- if not miniTicker:
1416
- if symbols is None:
1417
- raise ArgumentsRequired(self.id + ' watchTickers required symbols argument for the bookTicker channel')
1418
- marketIds = self.market_ids(symbols)
1419
- for i in range(0, len(marketIds)):
1420
- marketId = marketIds[i]
1421
- messageHashes.append('unsubscribe:ticker:' + symbols[i])
1422
- channel = 'spot@public.bookTicker.v3.api@' + marketId
1423
- topics.append(channel)
1424
- else:
1425
- topics.append('spot@public.miniTickers.v3.api@UTC+8')
1426
- if symbols is None:
1427
- messageHashes.append('unsubscribe:spot:ticker')
1428
- else:
1429
- for i in range(0, len(symbols)):
1430
- messageHashes.append('unsubscribe:ticker:' + symbols[i])
1431
- request['method'] = 'UNSUBSCRIPTION'
1432
- request['params'] = topics
1549
+ raise NotSupported(self.id + ' watchTickers does not support spot markets')
1550
+ # miniTicker = False
1551
+ # miniTicker, params = self.handle_option_and_params(params, 'watchTickers', 'miniTicker')
1552
+ # topics = []
1553
+ # if not miniTicker:
1554
+ # if symbols is None:
1555
+ # raise ArgumentsRequired(self.id + ' watchTickers required symbols argument for the bookTicker channel')
1556
+ # }
1557
+ # marketIds = self.market_ids(symbols)
1558
+ # for i in range(0, len(marketIds)):
1559
+ # marketId = marketIds[i]
1560
+ # messageHashes.append('unsubscribe:ticker:' + symbols[i])
1561
+ # channel = 'spot@public.bookTicker.v3.api@' + marketId
1562
+ # topics.append(channel)
1563
+ # }
1564
+ # else:
1565
+ # topics.append('spot@public.miniTickers.v3.api@UTC+8')
1566
+ # if symbols is None:
1567
+ # messageHashes.append('unsubscribe:spot:ticker')
1568
+ # else:
1569
+ # for i in range(0, len(symbols)):
1570
+ # messageHashes.append('unsubscribe:ticker:' + symbols[i])
1571
+ # }
1572
+ # }
1573
+ # }
1574
+ # request['method'] = 'UNSUBSCRIPTION'
1575
+ # request['params'] = topics
1433
1576
  else:
1434
1577
  request['method'] = 'unsub.tickers'
1435
1578
  request['params'] = {}
@@ -1461,7 +1604,7 @@ class mexc(ccxt.async_support.mexc):
1461
1604
  for i in range(0, len(symbols)):
1462
1605
  if isSpot:
1463
1606
  market = self.market(symbols[i])
1464
- topics.append('spot@public.bookTicker.v3.api@' + market['id'])
1607
+ topics.append('spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id'])
1465
1608
  messageHashes.append('unsubscribe:bidask:' + symbols[i])
1466
1609
  url = self.urls['api']['ws']['spot']
1467
1610
  request: dict = {
@@ -1491,7 +1634,7 @@ class mexc(ccxt.async_support.mexc):
1491
1634
  url = None
1492
1635
  if market['spot']:
1493
1636
  url = self.urls['api']['ws']['spot']
1494
- channel = 'spot@public.kline.v3.api@' + market['id'] + '@' + timeframeId
1637
+ channel = 'spot@public.kline.v3.api.pb@' + market['id'] + '@' + timeframeId
1495
1638
  params['unsubscribed'] = True
1496
1639
  await self.watch_spot_public(channel, messageHash, params)
1497
1640
  else:
@@ -1511,6 +1654,7 @@ class mexc(ccxt.async_support.mexc):
1511
1654
  unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
1512
1655
  :param str symbol: unified array of symbols
1513
1656
  :param dict [params]: extra parameters specific to the exchange API endpoint
1657
+ :param str [params.frequency]: the frequency of the order book updates, default is '10ms', can be '100ms' or '10ms
1514
1658
  :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
1515
1659
  """
1516
1660
  await self.load_markets()
@@ -1520,7 +1664,9 @@ class mexc(ccxt.async_support.mexc):
1520
1664
  url = None
1521
1665
  if market['spot']:
1522
1666
  url = self.urls['api']['ws']['spot']
1523
- channel = 'spot@public.increase.depth.v3.api@' + market['id']
1667
+ frequency = None
1668
+ frequency, params = self.handle_option_and_params(params, 'watchOrderBook', 'frequency', '100ms')
1669
+ channel = 'spot@public.aggre.depth.v3.api.pb@' + frequency + '@' + market['id']
1524
1670
  params['unsubscribed'] = True
1525
1671
  await self.watch_spot_public(channel, messageHash, params)
1526
1672
  else:
@@ -1549,7 +1695,7 @@ class mexc(ccxt.async_support.mexc):
1549
1695
  url = None
1550
1696
  if market['spot']:
1551
1697
  url = self.urls['api']['ws']['spot']
1552
- channel = 'spot@public.deals.v3.api@' + market['id']
1698
+ channel = 'spot@public.aggre.deals.v3.api.pb@100ms@' + market['id']
1553
1699
  params['unsubscribed'] = True
1554
1700
  await self.watch_spot_public(channel, messageHash, params)
1555
1701
  else:
@@ -1651,16 +1797,59 @@ class mexc(ccxt.async_support.mexc):
1651
1797
  channel = self.safe_string(parts, 1)
1652
1798
  methods: dict = {
1653
1799
  'public.increase.depth.v3.api': self.handle_order_book_subscription,
1800
+ 'public.aggre.depth.v3.api.pb': self.handle_order_book_subscription,
1654
1801
  }
1655
1802
  method = self.safe_value(methods, channel)
1656
1803
  if method is not None:
1657
1804
  method(client, message)
1658
1805
 
1806
+ def handle_protobuf_message(self, client: Client, message):
1807
+ # protobuf message decoded
1808
+ # {
1809
+ # "channel":"spot@public.kline.v3.api.pb@BTCUSDT@Min1",
1810
+ # "symbol":"BTCUSDT",
1811
+ # "symbolId":"2fb942154ef44a4ab2ef98c8afb6a4a7",
1812
+ # "createTime":"1754737941062",
1813
+ # "publicSpotKline":{
1814
+ # "interval":"Min1",
1815
+ # "windowStart":"1754737920",
1816
+ # "openingPrice":"117317.31",
1817
+ # "closingPrice":"117325.26",
1818
+ # "highestPrice":"117341",
1819
+ # "lowestPrice":"117317.3",
1820
+ # "volume":"3.12599854",
1821
+ # "amount":"366804.43",
1822
+ # "windowEnd":"1754737980"
1823
+ # }
1824
+ # }
1825
+ channel = self.safe_string(message, 'channel')
1826
+ channelParts = channel.split('@')
1827
+ channelId = self.safe_string(channelParts, 1)
1828
+ if channelId == 'public.kline.v3.api.pb':
1829
+ self.handle_ohlcv(client, message)
1830
+ elif channelId == 'public.aggre.deals.v3.api.pb':
1831
+ self.handle_trades(client, message)
1832
+ elif channelId == 'public.aggre.bookTicker.v3.api.pb':
1833
+ self.handle_ticker(client, message)
1834
+ elif channelId == 'public.aggre.depth.v3.api.pb':
1835
+ self.handle_order_book(client, message)
1836
+ elif channelId == 'private.account.v3.api.pb':
1837
+ self.handle_balance(client, message)
1838
+ elif channelId == 'private.deals.v3.api.pb':
1839
+ self.handle_my_trade(client, message)
1840
+ elif channelId == 'private.orders.v3.api.pb':
1841
+ self.handle_order(client, message)
1842
+ return True
1843
+
1659
1844
  def handle_message(self, client: Client, message):
1660
1845
  if isinstance(message, str):
1661
1846
  if message == 'Invalid listen key':
1662
1847
  error = AuthenticationError(self.id + ' invalid listen key')
1663
1848
  client.reject(error)
1849
+ return
1850
+ if self.is_binary_message(message):
1851
+ message = self.decode_proto_msg(message)
1852
+ self.handle_protobuf_message(client, message)
1664
1853
  return
1665
1854
  if 'msg' in message:
1666
1855
  self.handle_subscription_status(client, message)