ccxt 4.4.99__py2.py3-none-any.whl → 4.5.0__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.
- ccxt/__init__.py +1 -1
- ccxt/abstract/bingx.py +1 -0
- ccxt/alpaca.py +1 -1
- ccxt/apex.py +1 -1
- ccxt/ascendex.py +1 -1
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/alpaca.py +1 -1
- ccxt/async_support/apex.py +1 -1
- ccxt/async_support/ascendex.py +1 -1
- ccxt/async_support/base/exchange.py +44 -9
- ccxt/async_support/base/ws/client.py +3 -1
- ccxt/async_support/bigone.py +1 -1
- ccxt/async_support/binance.py +3 -2
- ccxt/async_support/bingx.py +33 -4
- ccxt/async_support/bitbank.py +1 -1
- ccxt/async_support/bitfinex.py +4 -1
- ccxt/async_support/bitflyer.py +1 -1
- ccxt/async_support/bitget.py +32 -14
- ccxt/async_support/bithumb.py +1 -1
- ccxt/async_support/bitmart.py +2 -2
- ccxt/async_support/bitmex.py +3 -2
- ccxt/async_support/bitopro.py +1 -1
- ccxt/async_support/bitrue.py +2 -2
- ccxt/async_support/bitso.py +1 -1
- ccxt/async_support/bitstamp.py +1 -1
- ccxt/async_support/bittrade.py +1 -1
- ccxt/async_support/bitvavo.py +1 -1
- ccxt/async_support/blockchaincom.py +1 -1
- ccxt/async_support/blofin.py +1 -1
- ccxt/async_support/btcmarkets.py +1 -1
- ccxt/async_support/bybit.py +2 -2
- ccxt/async_support/coinbase.py +1 -1
- ccxt/async_support/coinbaseexchange.py +1 -1
- ccxt/async_support/coinbaseinternational.py +1 -1
- ccxt/async_support/coincatch.py +2 -2
- ccxt/async_support/coinex.py +3 -3
- ccxt/async_support/coinmate.py +1 -1
- ccxt/async_support/coinsph.py +1 -1
- ccxt/async_support/cryptocom.py +1 -1
- ccxt/async_support/defx.py +2 -2
- ccxt/async_support/delta.py +1 -1
- ccxt/async_support/deribit.py +1 -1
- ccxt/async_support/digifinex.py +2 -2
- ccxt/async_support/ellipx.py +1 -1
- ccxt/async_support/exmo.py +1 -1
- ccxt/async_support/foxbit.py +3 -3
- ccxt/async_support/gate.py +17 -2
- ccxt/async_support/gemini.py +1 -1
- ccxt/async_support/hashkey.py +2 -2
- ccxt/async_support/hibachi.py +1 -1
- ccxt/async_support/hitbtc.py +2 -2
- ccxt/async_support/hollaex.py +1 -1
- ccxt/async_support/htx.py +4 -3
- ccxt/async_support/hyperliquid.py +71 -29
- ccxt/async_support/independentreserve.py +1 -1
- ccxt/async_support/indodax.py +1 -1
- ccxt/async_support/kraken.py +1 -1
- ccxt/async_support/krakenfutures.py +2 -1
- ccxt/async_support/kucoin.py +2 -2
- ccxt/async_support/kucoinfutures.py +2 -1
- ccxt/async_support/lbank.py +2 -2
- ccxt/async_support/mercado.py +1 -1
- ccxt/async_support/mexc.py +9 -2
- ccxt/async_support/modetrade.py +93 -2
- ccxt/async_support/ndax.py +1 -1
- ccxt/async_support/novadax.py +1 -1
- ccxt/async_support/okcoin.py +1 -1
- ccxt/async_support/okx.py +2 -2
- ccxt/async_support/onetrading.py +33 -0
- ccxt/async_support/oxfun.py +1 -1
- ccxt/async_support/p2b.py +32 -0
- ccxt/async_support/paradex.py +2 -1
- ccxt/async_support/phemex.py +2 -2
- ccxt/async_support/poloniex.py +2 -2
- ccxt/async_support/probit.py +36 -1
- ccxt/async_support/tokocrypto.py +1 -1
- ccxt/async_support/upbit.py +1 -1
- ccxt/async_support/vertex.py +1 -1
- ccxt/async_support/wavesexchange.py +1 -1
- ccxt/async_support/whitebit.py +2 -2
- ccxt/async_support/woo.py +4 -4
- ccxt/async_support/woofipro.py +93 -2
- ccxt/async_support/xt.py +2 -2
- ccxt/async_support/yobit.py +1 -1
- ccxt/async_support/zaif.py +1 -1
- ccxt/async_support/zonda.py +1 -1
- ccxt/base/errors.py +6 -0
- ccxt/base/exchange.py +11 -9
- ccxt/base/types.py +1 -0
- ccxt/bigone.py +1 -1
- ccxt/binance.py +3 -2
- ccxt/bingx.py +33 -4
- ccxt/bitbank.py +1 -1
- ccxt/bitfinex.py +4 -1
- ccxt/bitflyer.py +1 -1
- ccxt/bitget.py +32 -14
- ccxt/bithumb.py +1 -1
- ccxt/bitmart.py +2 -2
- ccxt/bitmex.py +3 -2
- ccxt/bitopro.py +1 -1
- ccxt/bitrue.py +2 -2
- ccxt/bitso.py +1 -1
- ccxt/bitstamp.py +1 -1
- ccxt/bittrade.py +1 -1
- ccxt/bitvavo.py +1 -1
- ccxt/blockchaincom.py +1 -1
- ccxt/blofin.py +1 -1
- ccxt/btcmarkets.py +1 -1
- ccxt/bybit.py +2 -2
- ccxt/coinbase.py +1 -1
- ccxt/coinbaseexchange.py +1 -1
- ccxt/coinbaseinternational.py +1 -1
- ccxt/coincatch.py +2 -2
- ccxt/coinex.py +3 -3
- ccxt/coinmate.py +1 -1
- ccxt/coinsph.py +1 -1
- ccxt/cryptocom.py +1 -1
- ccxt/defx.py +2 -2
- ccxt/delta.py +1 -1
- ccxt/deribit.py +1 -1
- ccxt/digifinex.py +2 -2
- ccxt/ellipx.py +1 -1
- ccxt/exmo.py +1 -1
- ccxt/foxbit.py +3 -3
- ccxt/gate.py +17 -2
- ccxt/gemini.py +1 -1
- ccxt/hashkey.py +2 -2
- ccxt/hibachi.py +1 -1
- ccxt/hitbtc.py +2 -2
- ccxt/hollaex.py +1 -1
- ccxt/htx.py +4 -3
- ccxt/hyperliquid.py +71 -29
- ccxt/independentreserve.py +1 -1
- ccxt/indodax.py +1 -1
- ccxt/kraken.py +1 -1
- ccxt/krakenfutures.py +2 -1
- ccxt/kucoin.py +2 -2
- ccxt/kucoinfutures.py +2 -1
- ccxt/lbank.py +2 -2
- ccxt/mercado.py +1 -1
- ccxt/mexc.py +9 -2
- ccxt/modetrade.py +93 -2
- ccxt/ndax.py +1 -1
- ccxt/novadax.py +1 -1
- ccxt/okcoin.py +1 -1
- ccxt/okx.py +2 -2
- ccxt/onetrading.py +33 -0
- ccxt/oxfun.py +1 -1
- ccxt/p2b.py +32 -0
- ccxt/paradex.py +2 -1
- ccxt/phemex.py +2 -2
- ccxt/poloniex.py +2 -2
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +2 -1
- ccxt/pro/bitvavo.py +1 -1
- ccxt/pro/bybit.py +1 -0
- ccxt/pro/coinex.py +1 -1
- ccxt/pro/hyperliquid.py +99 -12
- ccxt/pro/kucoin.py +1 -1
- ccxt/pro/kucoinfutures.py +1 -1
- ccxt/pro/mexc.py +337 -149
- ccxt/pro/okx.py +2 -1
- ccxt/pro/oxfun.py +1 -1
- ccxt/probit.py +36 -1
- ccxt/protobuf/__init__.py +0 -0
- ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
- ccxt/protobuf/mexc/__init__.py +0 -0
- ccxt/tokocrypto.py +1 -1
- ccxt/upbit.py +1 -1
- ccxt/vertex.py +1 -1
- ccxt/wavesexchange.py +1 -1
- ccxt/whitebit.py +2 -2
- ccxt/woo.py +4 -4
- ccxt/woofipro.py +93 -2
- ccxt/xt.py +2 -2
- ccxt/yobit.py +1 -1
- ccxt/zaif.py +1 -1
- ccxt/zonda.py +1 -1
- {ccxt-4.4.99.dist-info → ccxt-4.5.0.dist-info}/METADATA +5 -5
- {ccxt-4.4.99.dist-info → ccxt-4.5.0.dist-info}/RECORD +198 -180
- {ccxt-4.4.99.dist-info → ccxt-4.5.0.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.99.dist-info → ccxt-4.5.0.dist-info}/WHEEL +0 -0
- {ccxt-4.4.99.dist-info → ccxt-4.5.0.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
|
-
|
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.
|
182
|
+
rawTicker = self.safe_dict_n(message, ['d', 'data', 'publicAggreBookTicker'])
|
188
183
|
marketId = self.safe_string_2(message, 's', 'symbol')
|
189
|
-
timestamp = self.
|
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
|
-
|
230
|
-
miniTicker
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
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": "
|
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.
|
389
|
-
'bidVolume': self.
|
390
|
-
'ask': self.
|
391
|
-
'askVolume': self.
|
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://
|
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
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
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.
|
662
|
-
self.
|
663
|
-
self.
|
664
|
-
self.
|
665
|
-
self.
|
666
|
-
self.safe_number_2(ohlcv, 'v', '
|
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://
|
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
|
-
|
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.
|
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.
|
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.
|
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,7 +852,7 @@ class mexc(ccxt.async_support.mexc):
|
|
781
852
|
return
|
782
853
|
try:
|
783
854
|
self.handle_delta(storedOrderBook, data)
|
784
|
-
timestamp = self.
|
855
|
+
timestamp = self.safe_integer_n(message, ['t', 'ts', 'sendTime'])
|
785
856
|
storedOrderBook['timestamp'] = timestamp
|
786
857
|
storedOrderBook['datetime'] = self.iso8601(timestamp)
|
787
858
|
except Exception as e:
|
@@ -801,13 +872,13 @@ class mexc(ccxt.async_support.mexc):
|
|
801
872
|
if isinstance(bidask, list):
|
802
873
|
bookside.storeArray(bidask)
|
803
874
|
else:
|
804
|
-
price = self.
|
805
|
-
amount = self.
|
875
|
+
price = self.safe_float_2(bidask, 'p', 'price')
|
876
|
+
amount = self.safe_float_2(bidask, 'v', 'quantity')
|
806
877
|
bookside.store(price, amount)
|
807
878
|
|
808
879
|
def handle_delta(self, orderbook, delta):
|
809
880
|
existingNonce = self.safe_integer(orderbook, 'nonce')
|
810
|
-
deltaNonce = self.
|
881
|
+
deltaNonce = self.safe_integer_n(delta, ['r', 'version', 'fromVersion'])
|
811
882
|
if deltaNonce < existingNonce:
|
812
883
|
# even when doing < comparison, self happens: https://app.travis-ci.com/github/ccxt/ccxt/builds/269234741#L1809
|
813
884
|
# so, we just skip old updates
|
@@ -823,7 +894,7 @@ class mexc(ccxt.async_support.mexc):
|
|
823
894
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
824
895
|
"""
|
825
896
|
|
826
|
-
https://
|
897
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-market-streams#trade-streams
|
827
898
|
https://mexcdevelop.github.io/apidocs/contract_v1_en/#public-channels
|
828
899
|
|
829
900
|
get the list of most recent trades for a particular symbol
|
@@ -839,7 +910,7 @@ class mexc(ccxt.async_support.mexc):
|
|
839
910
|
messageHash = 'trades:' + symbol
|
840
911
|
trades = None
|
841
912
|
if market['spot']:
|
842
|
-
channel = 'spot@public.deals.v3.api@' + market['id']
|
913
|
+
channel = 'spot@public.aggre.deals.v3.api.pb@100ms@' + market['id']
|
843
914
|
trades = await self.watch_spot_public(channel, messageHash, params)
|
844
915
|
else:
|
845
916
|
channel = 'sub.deal'
|
@@ -852,6 +923,23 @@ class mexc(ccxt.async_support.mexc):
|
|
852
923
|
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
853
924
|
|
854
925
|
def handle_trades(self, client: Client, message):
|
926
|
+
# protobuf
|
927
|
+
# {
|
928
|
+
# "channel": "spot@public.aggre.deals.v3.api.pb@100ms@BTCUSDT",
|
929
|
+
# "publicdeals": {
|
930
|
+
# "dealsList": [
|
931
|
+
# {
|
932
|
+
# "price": "93220.00", # Trade price
|
933
|
+
# "quantity": "0.04438243", # Trade quantity
|
934
|
+
# "tradetype": 2, # Trade type(1: Buy, 2: Sell)
|
935
|
+
# "time": 1736409765051 # Trade time
|
936
|
+
# }
|
937
|
+
# ],
|
938
|
+
# "eventtype": "spot@public.aggre.deals.v3.api.pb@100ms" # Event type
|
939
|
+
# },
|
940
|
+
# "symbol": "BTCUSDT", # Trading pair
|
941
|
+
# "sendtime": 1736409765052 # Event time
|
942
|
+
# }
|
855
943
|
#
|
856
944
|
# {
|
857
945
|
# "c": "spot@public.deals.v3.api@BTCUSDT",
|
@@ -892,8 +980,8 @@ class mexc(ccxt.async_support.mexc):
|
|
892
980
|
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
893
981
|
stored = ArrayCache(limit)
|
894
982
|
self.trades[symbol] = stored
|
895
|
-
d = self.
|
896
|
-
trades = self.
|
983
|
+
d = self.safe_dict_n(message, ['d', 'data', 'publicAggreDeals'])
|
984
|
+
trades = self.safe_list_2(d, 'deals', 'dealsList', [d])
|
897
985
|
for j in range(0, len(trades)):
|
898
986
|
parsedTrade = None
|
899
987
|
if market['spot']:
|
@@ -906,7 +994,7 @@ class mexc(ccxt.async_support.mexc):
|
|
906
994
|
async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
907
995
|
"""
|
908
996
|
|
909
|
-
https://
|
997
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-user-data-streams#spot-account-deals
|
910
998
|
https://mexcdevelop.github.io/apidocs/contract_v1_en/#private-channels
|
911
999
|
|
912
1000
|
watches information on multiple trades made by the user
|
@@ -927,7 +1015,7 @@ class mexc(ccxt.async_support.mexc):
|
|
927
1015
|
type, params = self.handle_market_type_and_params('watchMyTrades', market, params)
|
928
1016
|
trades = None
|
929
1017
|
if type == 'spot':
|
930
|
-
channel = 'spot@private.deals.v3.api'
|
1018
|
+
channel = 'spot@private.deals.v3.api.pb'
|
931
1019
|
trades = await self.watch_spot_private(channel, messageHash, params)
|
932
1020
|
else:
|
933
1021
|
trades = await self.watch_swap_private(messageHash, params)
|
@@ -953,11 +1041,27 @@ class mexc(ccxt.async_support.mexc):
|
|
953
1041
|
# "s": "BTCUSDT",
|
954
1042
|
# "t": 1678670940700
|
955
1043
|
# }
|
1044
|
+
# {
|
1045
|
+
# channel: "spot@private.deals.v3.api.pb",
|
1046
|
+
# symbol: "MXUSDT",
|
1047
|
+
# sendTime: 1736417034332,
|
1048
|
+
# privateDeals {
|
1049
|
+
# price: "3.6962",
|
1050
|
+
# quantity: "1",
|
1051
|
+
# amount: "3.6962",
|
1052
|
+
# tradeType: 2,
|
1053
|
+
# tradeId: "505979017439002624X1",
|
1054
|
+
# orderId: "C02__505979017439002624115",
|
1055
|
+
# feeAmount: "0.0003998377369698171",
|
1056
|
+
# feeCurrency: "MX",
|
1057
|
+
# time: 1736417034280
|
1058
|
+
# }
|
1059
|
+
# }
|
956
1060
|
#
|
957
1061
|
messageHash = 'myTrades'
|
958
|
-
data = self.
|
1062
|
+
data = self.safe_dict_n(message, ['d', 'data', 'privateDeals'])
|
959
1063
|
futuresMarketId = self.safe_string(data, 'symbol')
|
960
|
-
marketId = self.
|
1064
|
+
marketId = self.safe_string_2(message, 's', 'symbol', futuresMarketId)
|
961
1065
|
market = self.safe_market(marketId)
|
962
1066
|
symbol = market['symbol']
|
963
1067
|
trade = None
|
@@ -977,7 +1081,7 @@ class mexc(ccxt.async_support.mexc):
|
|
977
1081
|
|
978
1082
|
def parse_ws_trade(self, trade, market=None):
|
979
1083
|
#
|
980
|
-
# public trade
|
1084
|
+
# public trade(protobuf)
|
981
1085
|
# {
|
982
1086
|
# "p": "20382.70",
|
983
1087
|
# "v": "0.043800",
|
@@ -997,7 +1101,6 @@ class mexc(ccxt.async_support.mexc):
|
|
997
1101
|
# "v": "5"
|
998
1102
|
# }
|
999
1103
|
#
|
1000
|
-
#
|
1001
1104
|
# d: {
|
1002
1105
|
# p: '1.0005',
|
1003
1106
|
# v: '5.71',
|
@@ -1012,22 +1115,36 @@ class mexc(ccxt.async_support.mexc):
|
|
1012
1115
|
# n: '0.005712855',
|
1013
1116
|
# N: 'USDT'
|
1014
1117
|
# }
|
1015
|
-
|
1016
|
-
|
1118
|
+
# protobuf
|
1119
|
+
#
|
1120
|
+
# {
|
1121
|
+
# price: "3.6962",
|
1122
|
+
# quantity: "1",
|
1123
|
+
# amount: "3.6962",
|
1124
|
+
# tradeType: 2,
|
1125
|
+
# tradeId: "505979017439002624X1",
|
1126
|
+
# orderId: "C02__505979017439002624115",
|
1127
|
+
# feeAmount: "0.0003998377369698171",
|
1128
|
+
# feeCurrency: "MX",
|
1129
|
+
# time: 1736417034280
|
1130
|
+
# }
|
1131
|
+
#
|
1132
|
+
timestamp = self.safe_integer_2(trade, 'T', 'time')
|
1133
|
+
tradeId = self.safe_string_2(trade, 't', 'tradeId')
|
1017
1134
|
if timestamp is None:
|
1018
1135
|
timestamp = self.safe_integer(trade, 't')
|
1019
1136
|
tradeId = None
|
1020
|
-
priceString = self.
|
1021
|
-
amountString = self.
|
1022
|
-
rawSide = self.
|
1137
|
+
priceString = self.safe_string_2(trade, 'p', 'price')
|
1138
|
+
amountString = self.safe_string_2(trade, 'v', 'quantity')
|
1139
|
+
rawSide = self.safe_string_2(trade, 'S', 'tradeType')
|
1023
1140
|
side = 'buy' if (rawSide == '1') else 'sell'
|
1024
1141
|
isMaker = self.safe_integer(trade, 'm')
|
1025
|
-
feeAmount = self.
|
1026
|
-
feeCurrencyId = self.
|
1142
|
+
feeAmount = self.safe_string_2(trade, 'n', 'feeAmount')
|
1143
|
+
feeCurrencyId = self.safe_string_2(trade, 'N', 'feeCurrency')
|
1027
1144
|
return self.safe_trade({
|
1028
1145
|
'info': trade,
|
1029
1146
|
'id': tradeId,
|
1030
|
-
'order': self.
|
1147
|
+
'order': self.safe_string_2(trade, 'i', 'orderId'),
|
1031
1148
|
'timestamp': timestamp,
|
1032
1149
|
'datetime': self.iso8601(timestamp),
|
1033
1150
|
'symbol': self.safe_symbol(None, market),
|
@@ -1036,7 +1153,7 @@ class mexc(ccxt.async_support.mexc):
|
|
1036
1153
|
'takerOrMaker': 'maker' if (isMaker) else 'taker',
|
1037
1154
|
'price': priceString,
|
1038
1155
|
'amount': amountString,
|
1039
|
-
'cost':
|
1156
|
+
'cost': self.safe_string(trade, 'amount'),
|
1040
1157
|
'fee': {
|
1041
1158
|
'cost': feeAmount,
|
1042
1159
|
'currency': self.safe_currency_code(feeCurrencyId),
|
@@ -1046,7 +1163,7 @@ class mexc(ccxt.async_support.mexc):
|
|
1046
1163
|
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
1047
1164
|
"""
|
1048
1165
|
|
1049
|
-
https://
|
1166
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-user-data-streams#spot-account-orders
|
1050
1167
|
https://mexcdevelop.github.io/apidocs/spot_v3_en/#margin-account-orders
|
1051
1168
|
|
1052
1169
|
watches information on multiple orders made by the user
|
@@ -1068,7 +1185,7 @@ class mexc(ccxt.async_support.mexc):
|
|
1068
1185
|
type, params = self.handle_market_type_and_params('watchOrders', market, params)
|
1069
1186
|
orders = None
|
1070
1187
|
if type == 'spot':
|
1071
|
-
channel =
|
1188
|
+
channel = 'spot@private.orders.v3.api.pb'
|
1072
1189
|
orders = await self.watch_spot_private(channel, messageHash, params)
|
1073
1190
|
else:
|
1074
1191
|
orders = await self.watch_swap_private(messageHash, params)
|
@@ -1141,11 +1258,18 @@ class mexc(ccxt.async_support.mexc):
|
|
1141
1258
|
# "s": "MXUSDT",
|
1142
1259
|
# "t":1661938138193
|
1143
1260
|
# }
|
1261
|
+
# protobuf
|
1262
|
+
# {
|
1263
|
+
# channel: "spot@private.orders.v3.api.pb",
|
1264
|
+
# symbol: "MXUSDT",
|
1265
|
+
# sendTime: 1736417034281,
|
1266
|
+
# privateOrders {}
|
1267
|
+
# }
|
1144
1268
|
#
|
1145
1269
|
messageHash = 'orders'
|
1146
|
-
data = self.
|
1270
|
+
data = self.safe_dict_n(message, ['d', 'data', 'privateOrders'])
|
1147
1271
|
futuresMarketId = self.safe_string(data, 'symbol')
|
1148
|
-
marketId = self.
|
1272
|
+
marketId = self.safe_string_2(message, 's', 'symbol', futuresMarketId)
|
1149
1273
|
market = self.safe_market(marketId)
|
1150
1274
|
symbol = market['symbol']
|
1151
1275
|
parsed = None
|
@@ -1213,11 +1337,28 @@ class mexc(ccxt.async_support.mexc):
|
|
1213
1337
|
# "s":1,
|
1214
1338
|
# "i":"e03a5c7441e44ed899466a7140b71391",
|
1215
1339
|
# }
|
1340
|
+
# protofbuf spot order
|
1341
|
+
# {
|
1342
|
+
# "id":"C02__583905164440776704043",
|
1343
|
+
# "price":"0.001053",
|
1344
|
+
# "quantity":"2000",
|
1345
|
+
# "amount":"0",
|
1346
|
+
# "avgPrice":"0.001007",
|
1347
|
+
# "orderType":5,
|
1348
|
+
# "tradeType":1,
|
1349
|
+
# "remainAmount":"0.092",
|
1350
|
+
# "remainQuantity":"0",
|
1351
|
+
# "lastDealQuantity":"2000",
|
1352
|
+
# "cumulativeQuantity":"2000",
|
1353
|
+
# "cumulativeAmount":"2.014",
|
1354
|
+
# "status":2,
|
1355
|
+
# "createTime":"1754996075502"
|
1356
|
+
# }
|
1216
1357
|
#
|
1217
|
-
timestamp = self.safe_integer(order, '
|
1218
|
-
side = self.safe_string(order, '
|
1219
|
-
status = self.safe_string(order, '
|
1220
|
-
type = self.safe_string(order, '
|
1358
|
+
timestamp = self.safe_integer(order, 'createTime')
|
1359
|
+
side = self.safe_string(order, 'tradeType')
|
1360
|
+
status = self.safe_string(order, 'status')
|
1361
|
+
type = self.safe_string(order, 'orderType')
|
1221
1362
|
fee = None
|
1222
1363
|
feeCurrency = self.safe_string(order, 'N')
|
1223
1364
|
if feeCurrency is not None:
|
@@ -1226,8 +1367,8 @@ class mexc(ccxt.async_support.mexc):
|
|
1226
1367
|
'cost': None,
|
1227
1368
|
}
|
1228
1369
|
return self.safe_order({
|
1229
|
-
'id': self.safe_string(order, '
|
1230
|
-
'clientOrderId': self.safe_string(order, '
|
1370
|
+
'id': self.safe_string(order, 'id'),
|
1371
|
+
'clientOrderId': self.safe_string(order, 'clientOrderId'),
|
1231
1372
|
'timestamp': timestamp,
|
1232
1373
|
'datetime': self.iso8601(timestamp),
|
1233
1374
|
'lastTradeTimestamp': None,
|
@@ -1236,14 +1377,14 @@ class mexc(ccxt.async_support.mexc):
|
|
1236
1377
|
'type': self.parse_ws_order_type(type),
|
1237
1378
|
'timeInForce': self.parse_ws_time_in_force(type),
|
1238
1379
|
'side': 'buy' if (side == '1') else 'sell',
|
1239
|
-
'price': self.safe_string(order, '
|
1380
|
+
'price': self.safe_string(order, 'price'),
|
1240
1381
|
'stopPrice': None,
|
1241
|
-
'triggerPrice':
|
1242
|
-
'average': self.safe_string(order, '
|
1243
|
-
'amount': self.safe_string(order, '
|
1244
|
-
'cost': self.safe_string(order, '
|
1245
|
-
'filled': self.safe_string(order, '
|
1246
|
-
'remaining': self.safe_string(order, '
|
1382
|
+
'triggerPrice': None,
|
1383
|
+
'average': self.safe_string(order, 'avgPrice'),
|
1384
|
+
'amount': self.safe_string(order, 'quantity'),
|
1385
|
+
'cost': self.safe_string(order, 'amount'),
|
1386
|
+
'filled': self.safe_string(order, 'cumulativeQuantity'),
|
1387
|
+
'remaining': self.safe_string(order, 'remainQuantity'),
|
1247
1388
|
'fee': fee,
|
1248
1389
|
'trades': None,
|
1249
1390
|
'info': order,
|
@@ -1266,7 +1407,7 @@ class mexc(ccxt.async_support.mexc):
|
|
1266
1407
|
def parse_ws_order_type(self, type):
|
1267
1408
|
types: dict = {
|
1268
1409
|
'1': 'limit', # LIMIT_ORDER
|
1269
|
-
'2':
|
1410
|
+
'2': 'limit', # POST_ONLY
|
1270
1411
|
'3': None, # IMMEDIATE_OR_CANCEL
|
1271
1412
|
'4': None, # FILL_OR_KILL
|
1272
1413
|
'5': 'market', # MARKET_ORDER
|
@@ -1288,7 +1429,7 @@ class mexc(ccxt.async_support.mexc):
|
|
1288
1429
|
async def watch_balance(self, params={}) -> Balances:
|
1289
1430
|
"""
|
1290
1431
|
|
1291
|
-
https://
|
1432
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-user-data-streams#spot-account-update
|
1292
1433
|
|
1293
1434
|
watch balance and get the amount of funds available for trading or funds locked in orders
|
1294
1435
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1299,7 +1440,7 @@ class mexc(ccxt.async_support.mexc):
|
|
1299
1440
|
type, params = self.handle_market_type_and_params('watchBalance', None, params)
|
1300
1441
|
messageHash = 'balance:' + type
|
1301
1442
|
if type == 'spot':
|
1302
|
-
channel = 'spot@private.account.v3.api'
|
1443
|
+
channel = 'spot@private.account.v3.api.pb'
|
1303
1444
|
return await self.watch_spot_private(channel, messageHash, params)
|
1304
1445
|
else:
|
1305
1446
|
return await self.watch_swap_private(messageHash, params)
|
@@ -1336,22 +1477,22 @@ class mexc(ccxt.async_support.mexc):
|
|
1336
1477
|
# "ts": 1680059188190
|
1337
1478
|
# }
|
1338
1479
|
#
|
1339
|
-
c = self.
|
1480
|
+
c = self.safe_string_2(message, 'c', 'channel')
|
1340
1481
|
type = 'swap' if (c is None) else 'spot'
|
1341
1482
|
messageHash = 'balance:' + type
|
1342
|
-
data = self.
|
1483
|
+
data = self.safe_dict_n(message, ['d', 'data', 'privateAccount'])
|
1343
1484
|
futuresTimestamp = self.safe_integer(message, 'ts')
|
1344
|
-
timestamp = self.
|
1485
|
+
timestamp = self.safe_integer_2(data, 'c', 'time', futuresTimestamp)
|
1345
1486
|
if not (type in self.balance):
|
1346
1487
|
self.balance[type] = {}
|
1347
1488
|
self.balance[type]['info'] = data
|
1348
1489
|
self.balance[type]['timestamp'] = timestamp
|
1349
1490
|
self.balance[type]['datetime'] = self.iso8601(timestamp)
|
1350
|
-
currencyId = self.
|
1491
|
+
currencyId = self.safe_string_n(data, ['a', 'currency', 'vcoinName'])
|
1351
1492
|
code = self.safe_currency_code(currencyId)
|
1352
1493
|
account = self.account()
|
1353
|
-
account['
|
1354
|
-
account['used'] = self.
|
1494
|
+
account['total'] = self.safe_string_n(data, ['f', 'availableBalance', 'balanceAmount'])
|
1495
|
+
account['used'] = self.safe_string_n(data, ['l', 'frozenBalance', 'frozenAmount'])
|
1355
1496
|
self.balance[type][code] = account
|
1356
1497
|
self.balance[type] = self.safe_balance(self.balance[type])
|
1357
1498
|
client.resolve(self.balance[type], messageHash)
|
@@ -1369,22 +1510,17 @@ class mexc(ccxt.async_support.mexc):
|
|
1369
1510
|
url = None
|
1370
1511
|
channel = None
|
1371
1512
|
if market['spot']:
|
1372
|
-
|
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']
|
1513
|
+
channel = 'spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id']
|
1378
1514
|
url = self.urls['api']['ws']['spot']
|
1379
1515
|
params['unsubscribed'] = True
|
1380
|
-
|
1516
|
+
self.watch_spot_public(channel, messageHash, params)
|
1381
1517
|
else:
|
1382
1518
|
channel = 'unsub.ticker'
|
1383
1519
|
requestParams: dict = {
|
1384
1520
|
'symbol': market['id'],
|
1385
1521
|
}
|
1386
1522
|
url = self.urls['api']['ws']['swap']
|
1387
|
-
|
1523
|
+
self.watch_swap_public(channel, messageHash, requestParams, params)
|
1388
1524
|
client = self.client(url)
|
1389
1525
|
self.handle_unsubscriptions(client, [messageHash])
|
1390
1526
|
return None
|
@@ -1409,33 +1545,39 @@ class mexc(ccxt.async_support.mexc):
|
|
1409
1545
|
url = self.urls['api']['ws']['spot'] if (isSpot) else self.urls['api']['ws']['swap']
|
1410
1546
|
request: dict = {}
|
1411
1547
|
if isSpot:
|
1412
|
-
|
1413
|
-
miniTicker
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1548
|
+
raise NotSupported(self.id + ' watchTickers does not support spot markets')
|
1549
|
+
# miniTicker = False
|
1550
|
+
# miniTicker, params = self.handle_option_and_params(params, 'watchTickers', 'miniTicker')
|
1551
|
+
# topics = []
|
1552
|
+
# if not miniTicker:
|
1553
|
+
# if symbols is None:
|
1554
|
+
# raise ArgumentsRequired(self.id + ' watchTickers required symbols argument for the bookTicker channel')
|
1555
|
+
# }
|
1556
|
+
# marketIds = self.market_ids(symbols)
|
1557
|
+
# for i in range(0, len(marketIds)):
|
1558
|
+
# marketId = marketIds[i]
|
1559
|
+
# messageHashes.append('unsubscribe:ticker:' + symbols[i])
|
1560
|
+
# channel = 'spot@public.bookTicker.v3.api@' + marketId
|
1561
|
+
# topics.append(channel)
|
1562
|
+
# }
|
1563
|
+
# else:
|
1564
|
+
# topics.append('spot@public.miniTickers.v3.api@UTC+8')
|
1565
|
+
# if symbols is None:
|
1566
|
+
# messageHashes.append('unsubscribe:spot:ticker')
|
1567
|
+
# else:
|
1568
|
+
# for i in range(0, len(symbols)):
|
1569
|
+
# messageHashes.append('unsubscribe:ticker:' + symbols[i])
|
1570
|
+
# }
|
1571
|
+
# }
|
1572
|
+
# }
|
1573
|
+
# request['method'] = 'UNSUBSCRIPTION'
|
1574
|
+
# request['params'] = topics
|
1433
1575
|
else:
|
1434
1576
|
request['method'] = 'unsub.tickers'
|
1435
1577
|
request['params'] = {}
|
1436
1578
|
messageHashes.append('unsubscribe:ticker')
|
1437
1579
|
client = self.client(url)
|
1438
|
-
|
1580
|
+
self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
|
1439
1581
|
self.handle_unsubscriptions(client, messageHashes)
|
1440
1582
|
return None
|
1441
1583
|
|
@@ -1461,7 +1603,7 @@ class mexc(ccxt.async_support.mexc):
|
|
1461
1603
|
for i in range(0, len(symbols)):
|
1462
1604
|
if isSpot:
|
1463
1605
|
market = self.market(symbols[i])
|
1464
|
-
topics.append('spot@public.bookTicker.v3.api@' + market['id'])
|
1606
|
+
topics.append('spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id'])
|
1465
1607
|
messageHashes.append('unsubscribe:bidask:' + symbols[i])
|
1466
1608
|
url = self.urls['api']['ws']['spot']
|
1467
1609
|
request: dict = {
|
@@ -1469,7 +1611,7 @@ class mexc(ccxt.async_support.mexc):
|
|
1469
1611
|
'params': topics,
|
1470
1612
|
}
|
1471
1613
|
client = self.client(url)
|
1472
|
-
|
1614
|
+
self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
|
1473
1615
|
self.handle_unsubscriptions(client, messageHashes)
|
1474
1616
|
return None
|
1475
1617
|
|
@@ -1491,9 +1633,9 @@ class mexc(ccxt.async_support.mexc):
|
|
1491
1633
|
url = None
|
1492
1634
|
if market['spot']:
|
1493
1635
|
url = self.urls['api']['ws']['spot']
|
1494
|
-
channel = 'spot@public.kline.v3.api@' + market['id'] + '@' + timeframeId
|
1636
|
+
channel = 'spot@public.kline.v3.api.pb@' + market['id'] + '@' + timeframeId
|
1495
1637
|
params['unsubscribed'] = True
|
1496
|
-
|
1638
|
+
self.watch_spot_public(channel, messageHash, params)
|
1497
1639
|
else:
|
1498
1640
|
url = self.urls['api']['ws']['swap']
|
1499
1641
|
channel = 'unsub.kline'
|
@@ -1501,7 +1643,7 @@ class mexc(ccxt.async_support.mexc):
|
|
1501
1643
|
'symbol': market['id'],
|
1502
1644
|
'interval': timeframeId,
|
1503
1645
|
}
|
1504
|
-
|
1646
|
+
self.watch_swap_public(channel, messageHash, requestParams, params)
|
1505
1647
|
client = self.client(url)
|
1506
1648
|
self.handle_unsubscriptions(client, [messageHash])
|
1507
1649
|
return None
|
@@ -1511,6 +1653,7 @@ class mexc(ccxt.async_support.mexc):
|
|
1511
1653
|
unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
1512
1654
|
:param str symbol: unified array of symbols
|
1513
1655
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1656
|
+
:param str [params.frequency]: the frequency of the order book updates, default is '10ms', can be '100ms' or '10ms
|
1514
1657
|
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
1515
1658
|
"""
|
1516
1659
|
await self.load_markets()
|
@@ -1520,16 +1663,18 @@ class mexc(ccxt.async_support.mexc):
|
|
1520
1663
|
url = None
|
1521
1664
|
if market['spot']:
|
1522
1665
|
url = self.urls['api']['ws']['spot']
|
1523
|
-
|
1666
|
+
frequency = None
|
1667
|
+
frequency, params = self.handle_option_and_params(params, 'watchOrderBook', 'frequency', '100ms')
|
1668
|
+
channel = 'spot@public.aggre.depth.v3.api.pb@' + frequency + '@' + market['id']
|
1524
1669
|
params['unsubscribed'] = True
|
1525
|
-
|
1670
|
+
self.watch_spot_public(channel, messageHash, params)
|
1526
1671
|
else:
|
1527
1672
|
url = self.urls['api']['ws']['swap']
|
1528
1673
|
channel = 'unsub.depth'
|
1529
1674
|
requestParams: dict = {
|
1530
1675
|
'symbol': market['id'],
|
1531
1676
|
}
|
1532
|
-
|
1677
|
+
self.watch_swap_public(channel, messageHash, requestParams, params)
|
1533
1678
|
client = self.client(url)
|
1534
1679
|
self.handle_unsubscriptions(client, [messageHash])
|
1535
1680
|
return None
|
@@ -1549,16 +1694,16 @@ class mexc(ccxt.async_support.mexc):
|
|
1549
1694
|
url = None
|
1550
1695
|
if market['spot']:
|
1551
1696
|
url = self.urls['api']['ws']['spot']
|
1552
|
-
channel = 'spot@public.deals.v3.api@' + market['id']
|
1697
|
+
channel = 'spot@public.aggre.deals.v3.api.pb@100ms@' + market['id']
|
1553
1698
|
params['unsubscribed'] = True
|
1554
|
-
|
1699
|
+
self.watch_spot_public(channel, messageHash, params)
|
1555
1700
|
else:
|
1556
1701
|
url = self.urls['api']['ws']['swap']
|
1557
1702
|
channel = 'unsub.deal'
|
1558
1703
|
requestParams: dict = {
|
1559
1704
|
'symbol': market['id'],
|
1560
1705
|
}
|
1561
|
-
|
1706
|
+
self.watch_swap_public(channel, messageHash, requestParams, params)
|
1562
1707
|
client = self.client(url)
|
1563
1708
|
self.handle_unsubscriptions(client, [messageHash])
|
1564
1709
|
return None
|
@@ -1651,16 +1796,59 @@ class mexc(ccxt.async_support.mexc):
|
|
1651
1796
|
channel = self.safe_string(parts, 1)
|
1652
1797
|
methods: dict = {
|
1653
1798
|
'public.increase.depth.v3.api': self.handle_order_book_subscription,
|
1799
|
+
'public.aggre.depth.v3.api.pb': self.handle_order_book_subscription,
|
1654
1800
|
}
|
1655
1801
|
method = self.safe_value(methods, channel)
|
1656
1802
|
if method is not None:
|
1657
1803
|
method(client, message)
|
1658
1804
|
|
1805
|
+
def handle_protobuf_message(self, client: Client, message):
|
1806
|
+
# protobuf message decoded
|
1807
|
+
# {
|
1808
|
+
# "channel":"spot@public.kline.v3.api.pb@BTCUSDT@Min1",
|
1809
|
+
# "symbol":"BTCUSDT",
|
1810
|
+
# "symbolId":"2fb942154ef44a4ab2ef98c8afb6a4a7",
|
1811
|
+
# "createTime":"1754737941062",
|
1812
|
+
# "publicSpotKline":{
|
1813
|
+
# "interval":"Min1",
|
1814
|
+
# "windowStart":"1754737920",
|
1815
|
+
# "openingPrice":"117317.31",
|
1816
|
+
# "closingPrice":"117325.26",
|
1817
|
+
# "highestPrice":"117341",
|
1818
|
+
# "lowestPrice":"117317.3",
|
1819
|
+
# "volume":"3.12599854",
|
1820
|
+
# "amount":"366804.43",
|
1821
|
+
# "windowEnd":"1754737980"
|
1822
|
+
# }
|
1823
|
+
# }
|
1824
|
+
channel = self.safe_string(message, 'channel')
|
1825
|
+
channelParts = channel.split('@')
|
1826
|
+
channelId = self.safe_string(channelParts, 1)
|
1827
|
+
if channelId == 'public.kline.v3.api.pb':
|
1828
|
+
self.handle_ohlcv(client, message)
|
1829
|
+
elif channelId == 'public.aggre.deals.v3.api.pb':
|
1830
|
+
self.handle_trades(client, message)
|
1831
|
+
elif channelId == 'public.aggre.bookTicker.v3.api.pb':
|
1832
|
+
self.handle_ticker(client, message)
|
1833
|
+
elif channelId == 'public.aggre.depth.v3.api.pb':
|
1834
|
+
self.handle_order_book(client, message)
|
1835
|
+
elif channelId == 'private.account.v3.api.pb':
|
1836
|
+
self.handle_balance(client, message)
|
1837
|
+
elif channelId == 'private.deals.v3.api.pb':
|
1838
|
+
self.handle_my_trade(client, message)
|
1839
|
+
elif channelId == 'private.orders.v3.api.pb':
|
1840
|
+
self.handle_order(client, message)
|
1841
|
+
return True
|
1842
|
+
|
1659
1843
|
def handle_message(self, client: Client, message):
|
1660
1844
|
if isinstance(message, str):
|
1661
1845
|
if message == 'Invalid listen key':
|
1662
1846
|
error = AuthenticationError(self.id + ' invalid listen key')
|
1663
1847
|
client.reject(error)
|
1848
|
+
return
|
1849
|
+
if self.is_binary_message(message):
|
1850
|
+
message = self.decode_proto_msg(message)
|
1851
|
+
self.handle_protobuf_message(client, message)
|
1664
1852
|
return
|
1665
1853
|
if 'msg' in message:
|
1666
1854
|
self.handle_subscription_status(client, message)
|