ccxt 4.4.98__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.
- ccxt/__init__.py +3 -1
- ccxt/abstract/bingx.py +1 -0
- ccxt/abstract/bitget.py +6 -0
- ccxt/abstract/hibachi.py +26 -0
- ccxt/alpaca.py +1 -1
- ccxt/apex.py +1 -1
- ccxt/ascendex.py +1 -1
- ccxt/async_support/__init__.py +3 -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 +10 -8
- 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 +2040 -561
- 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 +7 -3
- 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 +67 -6
- ccxt/async_support/coinmate.py +1 -1
- ccxt/async_support/coinsph.py +1 -1
- ccxt/async_support/cryptocom.py +2 -2
- 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 +18 -4
- ccxt/async_support/gemini.py +1 -1
- ccxt/async_support/hashkey.py +2 -2
- ccxt/async_support/hibachi.py +2080 -0
- 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 +35 -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 +0 -6
- ccxt/base/exchange.py +11 -9
- ccxt/base/types.py +1 -0
- ccxt/bigone.py +1 -1
- ccxt/binance.py +10 -8
- ccxt/bingx.py +33 -4
- ccxt/bitbank.py +1 -1
- ccxt/bitfinex.py +4 -1
- ccxt/bitflyer.py +1 -1
- ccxt/bitget.py +2040 -561
- 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 +7 -3
- ccxt/coinbase.py +1 -1
- ccxt/coinbaseexchange.py +1 -1
- ccxt/coinbaseinternational.py +1 -1
- ccxt/coincatch.py +2 -2
- ccxt/coinex.py +67 -6
- ccxt/coinmate.py +1 -1
- ccxt/coinsph.py +1 -1
- ccxt/cryptocom.py +2 -2
- 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 +18 -4
- ccxt/gemini.py +1 -1
- ccxt/hashkey.py +2 -2
- ccxt/hibachi.py +2079 -0
- 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 +35 -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/alpaca.py +2 -2
- ccxt/pro/apex.py +2 -2
- ccxt/pro/ascendex.py +2 -2
- ccxt/pro/binance.py +4 -5
- ccxt/pro/bitget.py +3 -3
- ccxt/pro/bithumb.py +2 -2
- ccxt/pro/bitmart.py +2 -2
- ccxt/pro/bitmex.py +3 -3
- ccxt/pro/bitstamp.py +3 -3
- ccxt/pro/bittrade.py +2 -2
- ccxt/pro/bitvavo.py +5 -3
- ccxt/pro/bybit.py +5 -4
- ccxt/pro/cex.py +3 -2
- ccxt/pro/coinbaseexchange.py +4 -4
- ccxt/pro/coinbaseinternational.py +2 -2
- ccxt/pro/coincatch.py +1 -1
- ccxt/pro/coinex.py +1 -1
- ccxt/pro/coinone.py +2 -2
- ccxt/pro/cryptocom.py +2 -2
- ccxt/pro/derive.py +2 -2
- ccxt/pro/gate.py +3 -3
- ccxt/pro/hollaex.py +2 -2
- ccxt/pro/htx.py +3 -3
- ccxt/pro/hyperliquid.py +101 -14
- ccxt/pro/kraken.py +2 -2
- ccxt/pro/krakenfutures.py +4 -3
- ccxt/pro/kucoin.py +4 -3
- ccxt/pro/kucoinfutures.py +4 -3
- ccxt/pro/mexc.py +328 -139
- ccxt/pro/modetrade.py +2 -2
- ccxt/pro/okcoin.py +2 -2
- ccxt/pro/okx.py +7 -6
- ccxt/pro/onetrading.py +2 -2
- ccxt/pro/oxfun.py +1 -1
- ccxt/pro/p2b.py +2 -2
- ccxt/pro/paradex.py +2 -2
- ccxt/pro/poloniex.py +2 -2
- ccxt/pro/probit.py +2 -2
- ccxt/pro/vertex.py +2 -2
- ccxt/pro/whitebit.py +2 -2
- ccxt/pro/woo.py +2 -2
- ccxt/pro/woofipro.py +2 -2
- 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/test/tests_async.py +1 -1
- ccxt/test/tests_sync.py +1 -1
- 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.98.dist-info → ccxt-4.4.100.dist-info}/METADATA +8 -7
- {ccxt-4.4.98.dist-info → ccxt-4.4.100.dist-info}/RECORD +234 -213
- {ccxt-4.4.98.dist-info → ccxt-4.4.100.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.98.dist-info → ccxt-4.4.100.dist-info}/WHEEL +0 -0
- {ccxt-4.4.98.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
|
-
|
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,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.
|
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.
|
805
|
-
amount = self.
|
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.
|
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://
|
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.
|
896
|
-
trades = self.
|
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://
|
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.
|
1063
|
+
data = self.safe_dict_n(message, ['d', 'data', 'privateDeals'])
|
959
1064
|
futuresMarketId = self.safe_string(data, 'symbol')
|
960
|
-
marketId = self.
|
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
|
-
|
1016
|
-
|
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.
|
1021
|
-
amountString = self.
|
1022
|
-
rawSide = self.
|
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.
|
1026
|
-
feeCurrencyId = self.
|
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.
|
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':
|
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://
|
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 =
|
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.
|
1271
|
+
data = self.safe_dict_n(message, ['d', 'data', 'privateOrders'])
|
1147
1272
|
futuresMarketId = self.safe_string(data, 'symbol')
|
1148
|
-
marketId = self.
|
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, '
|
1218
|
-
side = self.safe_string(order, '
|
1219
|
-
status = self.safe_string(order, '
|
1220
|
-
type = self.safe_string(order, '
|
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, '
|
1230
|
-
'clientOrderId': self.safe_string(order, '
|
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, '
|
1381
|
+
'price': self.safe_string(order, 'price'),
|
1240
1382
|
'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, '
|
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':
|
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://
|
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.
|
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.
|
1484
|
+
data = self.safe_dict_n(message, ['d', 'data', 'privateAccount'])
|
1343
1485
|
futuresTimestamp = self.safe_integer(message, 'ts')
|
1344
|
-
timestamp = self.
|
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.
|
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['
|
1354
|
-
account['used'] = self.
|
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
|
-
|
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
|
-
|
1413
|
-
miniTicker
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
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
|
-
|
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)
|