mexc-exchange-api 0.0.81__py3-none-any.whl → 0.0.83__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.
- mexc/ccxt/__init__.py +1 -1
- mexc/ccxt/async_support/__init__.py +1 -1
- mexc/ccxt/async_support/base/exchange.py +44 -9
- mexc/ccxt/async_support/base/ws/client.py +3 -1
- mexc/ccxt/async_support/mexc.py +9 -2
- mexc/ccxt/base/errors.py +6 -0
- mexc/ccxt/base/exchange.py +11 -9
- mexc/ccxt/base/types.py +1 -0
- mexc/ccxt/mexc.py +9 -2
- mexc/ccxt/pro/__init__.py +1 -1
- mexc/ccxt/pro/mexc.py +337 -149
- {mexc_exchange_api-0.0.81.dist-info → mexc_exchange_api-0.0.83.dist-info}/METADATA +3 -3
- {mexc_exchange_api-0.0.81.dist-info → mexc_exchange_api-0.0.83.dist-info}/RECORD +14 -14
- {mexc_exchange_api-0.0.81.dist-info → mexc_exchange_api-0.0.83.dist-info}/WHEEL +0 -0
mexc/ccxt/pro/mexc.py
CHANGED
@@ -52,13 +52,14 @@ class mexc(mexcAsync):
|
|
52
52
|
'urls': {
|
53
53
|
'api': {
|
54
54
|
'ws': {
|
55
|
-
'spot': 'wss://wbs.mexc.com/ws',
|
55
|
+
'spot': 'wss://wbs-api.mexc.com/ws',
|
56
56
|
'swap': 'wss://contract.mexc.com/edge',
|
57
57
|
},
|
58
58
|
},
|
59
59
|
},
|
60
60
|
'options': {
|
61
61
|
'listenKeyRefreshRate': 1200000,
|
62
|
+
'decompressBinary': False,
|
62
63
|
# TODO add reset connection after #16754 is merged
|
63
64
|
'timeframes': {
|
64
65
|
'1m': 'Min1',
|
@@ -103,13 +104,7 @@ class mexc(mexcAsync):
|
|
103
104
|
market = self.market(symbol)
|
104
105
|
messageHash = 'ticker:' + market['symbol']
|
105
106
|
if market['spot']:
|
106
|
-
|
107
|
-
miniTicker, params = self.handle_option_and_params(params, 'watchTicker', 'miniTicker')
|
108
|
-
channel = None
|
109
|
-
if miniTicker:
|
110
|
-
channel = 'spot@public.miniTicker.v3.api@' + market['id'] + '@UTC+8'
|
111
|
-
else:
|
112
|
-
channel = 'spot@public.bookTicker.v3.api@' + market['id']
|
107
|
+
channel = 'spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id']
|
113
108
|
return await self.watch_spot_public(channel, messageHash, params)
|
114
109
|
else:
|
115
110
|
channel = 'sub.ticker'
|
@@ -187,9 +182,9 @@ class mexc(mexcAsync):
|
|
187
182
|
# }
|
188
183
|
#
|
189
184
|
self.handle_bid_ask(client, message)
|
190
|
-
rawTicker = self.
|
185
|
+
rawTicker = self.safe_dict_n(message, ['d', 'data', 'publicAggreBookTicker'])
|
191
186
|
marketId = self.safe_string_2(message, 's', 'symbol')
|
192
|
-
timestamp = self.
|
187
|
+
timestamp = self.safe_integer_2(message, 't', 'sendtime')
|
193
188
|
market = self.safe_market(marketId)
|
194
189
|
symbol = market['symbol']
|
195
190
|
ticker = None
|
@@ -229,27 +224,33 @@ class mexc(mexcAsync):
|
|
229
224
|
url = self.urls['api']['ws']['spot'] if (isSpot) else self.urls['api']['ws']['swap']
|
230
225
|
request: dict = {}
|
231
226
|
if isSpot:
|
232
|
-
|
233
|
-
miniTicker
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
227
|
+
raise NotSupported(self.id + ' watchTickers does not support spot markets')
|
228
|
+
# miniTicker = False
|
229
|
+
# miniTicker, params = self.handle_option_and_params(params, 'watchTickers', 'miniTicker')
|
230
|
+
# topics = []
|
231
|
+
# if not miniTicker:
|
232
|
+
# if symbols is None:
|
233
|
+
# raise ArgumentsRequired(self.id + ' watchTickers required symbols argument for the bookTicker channel')
|
234
|
+
# }
|
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
|
+
# }
|
242
|
+
# else:
|
243
|
+
# topics.append('spot@public.miniTickers.v3.api@UTC+8')
|
244
|
+
# if symbols is None:
|
245
|
+
# messageHashes.append('spot:ticker')
|
246
|
+
# else:
|
247
|
+
# for i in range(0, len(symbols)):
|
248
|
+
# messageHashes.append('ticker:' + symbols[i])
|
249
|
+
# }
|
250
|
+
# }
|
251
|
+
# }
|
252
|
+
# request['method'] = 'SUBSCRIPTION'
|
253
|
+
# request['params'] = topics
|
253
254
|
else:
|
254
255
|
request['method'] = 'sub.tickers'
|
255
256
|
request['params'] = {}
|
@@ -348,6 +349,11 @@ class mexc(mexcAsync):
|
|
348
349
|
client.resolve(result, topic)
|
349
350
|
|
350
351
|
def parse_ws_ticker(self, ticker, market=None):
|
352
|
+
# protobuf ticker
|
353
|
+
# "bidprice": "93387.28", # Best bid price
|
354
|
+
# "bidquantity": "3.73485", # Best bid quantity
|
355
|
+
# "askprice": "93387.29", # Best ask price
|
356
|
+
# "askquantity": "7.669875" # Best ask quantity
|
351
357
|
#
|
352
358
|
# spot
|
353
359
|
#
|
@@ -362,7 +368,7 @@ class mexc(mexcAsync):
|
|
362
368
|
#
|
363
369
|
# {
|
364
370
|
# "s": "BTCUSDT",
|
365
|
-
# "p": "
|
371
|
+
# "p": "76521",
|
366
372
|
# "r": "0.0012",
|
367
373
|
# "tr": "0.0012",
|
368
374
|
# "h": "77196.3",
|
@@ -388,10 +394,10 @@ class mexc(mexcAsync):
|
|
388
394
|
'low': self.safe_number(ticker, 'l'),
|
389
395
|
'close': price,
|
390
396
|
'last': price,
|
391
|
-
'bid': self.
|
392
|
-
'bidVolume': self.
|
393
|
-
'ask': self.
|
394
|
-
'askVolume': self.
|
397
|
+
'bid': self.safe_number_2(ticker, 'b', 'bidPrice'),
|
398
|
+
'bidVolume': self.safe_number_2(ticker, 'B', 'bidQuantity'),
|
399
|
+
'ask': self.safe_number_2(ticker, 'a', 'askPrice'),
|
400
|
+
'askVolume': self.safe_number_2(ticker, 'A', 'askQuantity'),
|
395
401
|
'vwap': None,
|
396
402
|
'previousClose': None,
|
397
403
|
'change': None,
|
@@ -426,7 +432,7 @@ class mexc(mexcAsync):
|
|
426
432
|
for i in range(0, len(symbols)):
|
427
433
|
if isSpot:
|
428
434
|
market = self.market(symbols[i])
|
429
|
-
topics.append('spot@public.bookTicker.v3.api@' + market['id'])
|
435
|
+
topics.append('spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id'])
|
430
436
|
messageHashes.append('bidask:' + symbols[i])
|
431
437
|
url = self.urls['api']['ws']['spot']
|
432
438
|
request: dict = {
|
@@ -530,7 +536,7 @@ class mexc(mexcAsync):
|
|
530
536
|
async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
531
537
|
"""
|
532
538
|
|
533
|
-
https://
|
539
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-market-streams#trade-streams
|
534
540
|
|
535
541
|
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
536
542
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
@@ -548,7 +554,7 @@ class mexc(mexcAsync):
|
|
548
554
|
messageHash = 'candles:' + symbol + ':' + timeframe
|
549
555
|
ohlcv = None
|
550
556
|
if market['spot']:
|
551
|
-
channel = 'spot@public.kline.v3.api@' + market['id'] + '@' + timeframeId
|
557
|
+
channel = 'spot@public.kline.v3.api.pb@' + market['id'] + '@' + timeframeId
|
552
558
|
ohlcv = await self.watch_spot_public(channel, messageHash, params)
|
553
559
|
else:
|
554
560
|
channel = 'sub.kline'
|
@@ -607,17 +613,45 @@ class mexc(mexcAsync):
|
|
607
613
|
# "symbol": "BTC_USDT",
|
608
614
|
# "ts": 1651230713067
|
609
615
|
# }
|
616
|
+
# protobuf
|
617
|
+
# {
|
618
|
+
# "channel":"spot@public.kline.v3.api.pb@BTCUSDT@Min1",
|
619
|
+
# "symbol":"BTCUSDT",
|
620
|
+
# "symbolId":"2fb942154ef44a4ab2ef98c8afb6a4a7",
|
621
|
+
# "createTime":"1754737941062",
|
622
|
+
# "publicSpotKline":{
|
623
|
+
# "interval":"Min1",
|
624
|
+
# "windowStart":"1754737920",
|
625
|
+
# "openingPrice":"117317.31",
|
626
|
+
# "closingPrice":"117325.26",
|
627
|
+
# "highestPrice":"117341",
|
628
|
+
# "lowestPrice":"117317.3",
|
629
|
+
# "volume":"3.12599854",
|
630
|
+
# "amount":"366804.43",
|
631
|
+
# "windowEnd":"1754737980"
|
632
|
+
# }
|
633
|
+
# }
|
610
634
|
#
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
635
|
+
parsed: dict = None
|
636
|
+
symbol: Str = None
|
637
|
+
timeframe: Str = None
|
638
|
+
if 'publicSpotKline' in message:
|
639
|
+
symbol = self.symbol(self.safe_string(message, 'symbol'))
|
640
|
+
data = self.safe_dict(message, 'publicSpotKline', {})
|
641
|
+
timeframeId = self.safe_string(data, 'interval')
|
642
|
+
timeframe = self.find_timeframe(timeframeId, self.options['timeframes'])
|
643
|
+
parsed = self.parse_ws_ohlcv(data, self.safe_market(symbol))
|
644
|
+
else:
|
645
|
+
d = self.safe_value_2(message, 'd', 'data', {})
|
646
|
+
rawOhlcv = self.safe_value(d, 'k', d)
|
647
|
+
timeframeId = self.safe_string_2(rawOhlcv, 'i', 'interval')
|
648
|
+
timeframes = self.safe_value(self.options, 'timeframes', {})
|
649
|
+
timeframe = self.find_timeframe(timeframeId, timeframes)
|
650
|
+
marketId = self.safe_string_2(message, 's', 'symbol')
|
651
|
+
market = self.safe_market(marketId)
|
652
|
+
symbol = market['symbol']
|
653
|
+
parsed = self.parse_ws_ohlcv(rawOhlcv, market)
|
619
654
|
messageHash = 'candles:' + symbol + ':' + timeframe
|
620
|
-
parsed = self.parse_ws_ohlcv(rawOhlcv, market)
|
621
655
|
self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
|
622
656
|
stored = self.safe_value(self.ohlcvs[symbol], timeframe)
|
623
657
|
if stored is None:
|
@@ -659,26 +693,38 @@ class mexc(mexcAsync):
|
|
659
693
|
# "rh": 27301.8,
|
660
694
|
# "rl": 27301.8
|
661
695
|
# }
|
696
|
+
# protobuf
|
697
|
+
#
|
698
|
+
# "interval":"Min1",
|
699
|
+
# "windowStart":"1754737920",
|
700
|
+
# "openingPrice":"117317.31",
|
701
|
+
# "closingPrice":"117325.26",
|
702
|
+
# "highestPrice":"117341",
|
703
|
+
# "lowestPrice":"117317.3",
|
704
|
+
# "volume":"3.12599854",
|
705
|
+
# "amount":"366804.43",
|
706
|
+
# "windowEnd":"1754737980"
|
662
707
|
#
|
663
708
|
return [
|
664
|
-
self.
|
665
|
-
self.
|
666
|
-
self.
|
667
|
-
self.
|
668
|
-
self.
|
669
|
-
self.safe_number_2(ohlcv, 'v', '
|
709
|
+
self.safe_timestamp_2(ohlcv, 't', 'windowStart'),
|
710
|
+
self.safe_number_2(ohlcv, 'o', 'openingPrice'),
|
711
|
+
self.safe_number_2(ohlcv, 'h', 'highestPrice'),
|
712
|
+
self.safe_number_2(ohlcv, 'l', 'lowestPrice'),
|
713
|
+
self.safe_number_2(ohlcv, 'c', 'closingPrice'),
|
714
|
+
self.safe_number_2(ohlcv, 'v', 'volume'),
|
670
715
|
]
|
671
716
|
|
672
717
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
673
718
|
"""
|
674
719
|
|
675
|
-
https://
|
720
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-market-streams#trade-streams
|
676
721
|
https://mexcdevelop.github.io/apidocs/contract_v1_en/#public-channels
|
677
722
|
|
678
723
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
679
724
|
:param str symbol: unified symbol of the market to fetch the order book for
|
680
725
|
:param int [limit]: the maximum amount of order book entries to return
|
681
726
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
727
|
+
:param str [params.frequency]: the frequency of the order book updates, default is '10ms', can be '100ms' or '10ms
|
682
728
|
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
683
729
|
"""
|
684
730
|
await self.load_markets()
|
@@ -687,7 +733,9 @@ class mexc(mexcAsync):
|
|
687
733
|
messageHash = 'orderbook:' + symbol
|
688
734
|
orderbook = None
|
689
735
|
if market['spot']:
|
690
|
-
|
736
|
+
frequency = None
|
737
|
+
frequency, params = self.handle_option_and_params(params, 'watchOrderBook', 'frequency', '100ms')
|
738
|
+
channel = 'spot@public.aggre.depth.v3.api.pb@' + frequency + '@' + market['id']
|
691
739
|
orderbook = await self.watch_spot_public(channel, messageHash, params)
|
692
740
|
else:
|
693
741
|
channel = 'sub.depth'
|
@@ -711,12 +759,12 @@ class mexc(mexcAsync):
|
|
711
759
|
# return the first index of the cache that can be applied to the orderbook or -1 if not possible
|
712
760
|
nonce = self.safe_integer(orderbook, 'nonce')
|
713
761
|
firstDelta = self.safe_value(cache, 0)
|
714
|
-
firstDeltaNonce = self.
|
762
|
+
firstDeltaNonce = self.safe_integer_n(firstDelta, ['r', 'version', 'fromVersion'])
|
715
763
|
if nonce < firstDeltaNonce - 1:
|
716
764
|
return -1
|
717
765
|
for i in range(0, len(cache)):
|
718
766
|
delta = cache[i]
|
719
|
-
deltaNonce = self.
|
767
|
+
deltaNonce = self.safe_integer_n(delta, ['r', 'version', 'fromVersion'])
|
720
768
|
if deltaNonce >= nonce:
|
721
769
|
return i
|
722
770
|
return len(cache)
|
@@ -764,8 +812,31 @@ class mexc(mexcAsync):
|
|
764
812
|
# "symbol":"BTC_USDT",
|
765
813
|
# "ts":1651239652372
|
766
814
|
# }
|
815
|
+
# protofbuf
|
816
|
+
# {
|
817
|
+
# "channel":"spot@public.aggre.depth.v3.api.pb@100ms@BTCUSDT",
|
818
|
+
# "symbol":"BTCUSDT",
|
819
|
+
# "sendTime":"1754741322152",
|
820
|
+
# "publicAggreDepths":{
|
821
|
+
# "asks":[
|
822
|
+
# {
|
823
|
+
# "price":"117145.49",
|
824
|
+
# "quantity":"0"
|
825
|
+
# }
|
826
|
+
# ],
|
827
|
+
# "bids":[
|
828
|
+
# {
|
829
|
+
# "price":"117053.41",
|
830
|
+
# "quantity":"1.86837271"
|
831
|
+
# }
|
832
|
+
# ],
|
833
|
+
# "eventType":"spot@public.aggre.depth.v3.api.pb@100ms",
|
834
|
+
# "fromVersion":"43296363236",
|
835
|
+
# "toVersion":"43296363255"
|
836
|
+
# }
|
837
|
+
# }
|
767
838
|
#
|
768
|
-
data = self.
|
839
|
+
data = self.safe_dict_n(message, ['d', 'data', 'publicAggreDepths'])
|
769
840
|
marketId = self.safe_string_2(message, 's', 'symbol')
|
770
841
|
symbol = self.safe_symbol(marketId)
|
771
842
|
messageHash = 'orderbook:' + symbol
|
@@ -784,7 +855,7 @@ class mexc(mexcAsync):
|
|
784
855
|
return
|
785
856
|
try:
|
786
857
|
self.handle_delta(storedOrderBook, data)
|
787
|
-
timestamp = self.
|
858
|
+
timestamp = self.safe_integer_n(message, ['t', 'ts', 'sendTime'])
|
788
859
|
storedOrderBook['timestamp'] = timestamp
|
789
860
|
storedOrderBook['datetime'] = self.iso8601(timestamp)
|
790
861
|
except Exception as e:
|
@@ -804,13 +875,13 @@ class mexc(mexcAsync):
|
|
804
875
|
if isinstance(bidask, list):
|
805
876
|
bookside.storeArray(bidask)
|
806
877
|
else:
|
807
|
-
price = self.
|
808
|
-
amount = self.
|
878
|
+
price = self.safe_float_2(bidask, 'p', 'price')
|
879
|
+
amount = self.safe_float_2(bidask, 'v', 'quantity')
|
809
880
|
bookside.store(price, amount)
|
810
881
|
|
811
882
|
def handle_delta(self, orderbook, delta):
|
812
883
|
existingNonce = self.safe_integer(orderbook, 'nonce')
|
813
|
-
deltaNonce = self.
|
884
|
+
deltaNonce = self.safe_integer_n(delta, ['r', 'version', 'fromVersion'])
|
814
885
|
if deltaNonce < existingNonce:
|
815
886
|
# even when doing < comparison, self happens: https://app.travis-ci.com/github/ccxt/ccxt/builds/269234741#L1809
|
816
887
|
# so, we just skip old updates
|
@@ -826,7 +897,7 @@ class mexc(mexcAsync):
|
|
826
897
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
827
898
|
"""
|
828
899
|
|
829
|
-
https://
|
900
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-market-streams#trade-streams
|
830
901
|
https://mexcdevelop.github.io/apidocs/contract_v1_en/#public-channels
|
831
902
|
|
832
903
|
get the list of most recent trades for a particular symbol
|
@@ -842,7 +913,7 @@ class mexc(mexcAsync):
|
|
842
913
|
messageHash = 'trades:' + symbol
|
843
914
|
trades = None
|
844
915
|
if market['spot']:
|
845
|
-
channel = 'spot@public.deals.v3.api@' + market['id']
|
916
|
+
channel = 'spot@public.aggre.deals.v3.api.pb@100ms@' + market['id']
|
846
917
|
trades = await self.watch_spot_public(channel, messageHash, params)
|
847
918
|
else:
|
848
919
|
channel = 'sub.deal'
|
@@ -855,6 +926,23 @@ class mexc(mexcAsync):
|
|
855
926
|
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
856
927
|
|
857
928
|
def handle_trades(self, client: Client, message):
|
929
|
+
# protobuf
|
930
|
+
# {
|
931
|
+
# "channel": "spot@public.aggre.deals.v3.api.pb@100ms@BTCUSDT",
|
932
|
+
# "publicdeals": {
|
933
|
+
# "dealsList": [
|
934
|
+
# {
|
935
|
+
# "price": "93220.00", # Trade price
|
936
|
+
# "quantity": "0.04438243", # Trade quantity
|
937
|
+
# "tradetype": 2, # Trade type(1: Buy, 2: Sell)
|
938
|
+
# "time": 1736409765051 # Trade time
|
939
|
+
# }
|
940
|
+
# ],
|
941
|
+
# "eventtype": "spot@public.aggre.deals.v3.api.pb@100ms" # Event type
|
942
|
+
# },
|
943
|
+
# "symbol": "BTCUSDT", # Trading pair
|
944
|
+
# "sendtime": 1736409765052 # Event time
|
945
|
+
# }
|
858
946
|
#
|
859
947
|
# {
|
860
948
|
# "c": "spot@public.deals.v3.api@BTCUSDT",
|
@@ -895,8 +983,8 @@ class mexc(mexcAsync):
|
|
895
983
|
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
896
984
|
stored = ArrayCache(limit)
|
897
985
|
self.trades[symbol] = stored
|
898
|
-
d = self.
|
899
|
-
trades = self.
|
986
|
+
d = self.safe_dict_n(message, ['d', 'data', 'publicAggreDeals'])
|
987
|
+
trades = self.safe_list_2(d, 'deals', 'dealsList', [d])
|
900
988
|
for j in range(0, len(trades)):
|
901
989
|
parsedTrade = None
|
902
990
|
if market['spot']:
|
@@ -909,7 +997,7 @@ class mexc(mexcAsync):
|
|
909
997
|
async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
910
998
|
"""
|
911
999
|
|
912
|
-
https://
|
1000
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-user-data-streams#spot-account-deals
|
913
1001
|
https://mexcdevelop.github.io/apidocs/contract_v1_en/#private-channels
|
914
1002
|
|
915
1003
|
watches information on multiple trades made by the user
|
@@ -930,7 +1018,7 @@ class mexc(mexcAsync):
|
|
930
1018
|
type, params = self.handle_market_type_and_params('watchMyTrades', market, params)
|
931
1019
|
trades = None
|
932
1020
|
if type == 'spot':
|
933
|
-
channel = 'spot@private.deals.v3.api'
|
1021
|
+
channel = 'spot@private.deals.v3.api.pb'
|
934
1022
|
trades = await self.watch_spot_private(channel, messageHash, params)
|
935
1023
|
else:
|
936
1024
|
trades = await self.watch_swap_private(messageHash, params)
|
@@ -956,11 +1044,27 @@ class mexc(mexcAsync):
|
|
956
1044
|
# "s": "BTCUSDT",
|
957
1045
|
# "t": 1678670940700
|
958
1046
|
# }
|
1047
|
+
# {
|
1048
|
+
# channel: "spot@private.deals.v3.api.pb",
|
1049
|
+
# symbol: "MXUSDT",
|
1050
|
+
# sendTime: 1736417034332,
|
1051
|
+
# privateDeals {
|
1052
|
+
# price: "3.6962",
|
1053
|
+
# quantity: "1",
|
1054
|
+
# amount: "3.6962",
|
1055
|
+
# tradeType: 2,
|
1056
|
+
# tradeId: "505979017439002624X1",
|
1057
|
+
# orderId: "C02__505979017439002624115",
|
1058
|
+
# feeAmount: "0.0003998377369698171",
|
1059
|
+
# feeCurrency: "MX",
|
1060
|
+
# time: 1736417034280
|
1061
|
+
# }
|
1062
|
+
# }
|
959
1063
|
#
|
960
1064
|
messageHash = 'myTrades'
|
961
|
-
data = self.
|
1065
|
+
data = self.safe_dict_n(message, ['d', 'data', 'privateDeals'])
|
962
1066
|
futuresMarketId = self.safe_string(data, 'symbol')
|
963
|
-
marketId = self.
|
1067
|
+
marketId = self.safe_string_2(message, 's', 'symbol', futuresMarketId)
|
964
1068
|
market = self.safe_market(marketId)
|
965
1069
|
symbol = market['symbol']
|
966
1070
|
trade = None
|
@@ -980,7 +1084,7 @@ class mexc(mexcAsync):
|
|
980
1084
|
|
981
1085
|
def parse_ws_trade(self, trade, market=None):
|
982
1086
|
#
|
983
|
-
# public trade
|
1087
|
+
# public trade(protobuf)
|
984
1088
|
# {
|
985
1089
|
# "p": "20382.70",
|
986
1090
|
# "v": "0.043800",
|
@@ -1000,7 +1104,6 @@ class mexc(mexcAsync):
|
|
1000
1104
|
# "v": "5"
|
1001
1105
|
# }
|
1002
1106
|
#
|
1003
|
-
#
|
1004
1107
|
# d: {
|
1005
1108
|
# p: '1.0005',
|
1006
1109
|
# v: '5.71',
|
@@ -1015,22 +1118,36 @@ class mexc(mexcAsync):
|
|
1015
1118
|
# n: '0.005712855',
|
1016
1119
|
# N: 'USDT'
|
1017
1120
|
# }
|
1018
|
-
|
1019
|
-
|
1121
|
+
# protobuf
|
1122
|
+
#
|
1123
|
+
# {
|
1124
|
+
# price: "3.6962",
|
1125
|
+
# quantity: "1",
|
1126
|
+
# amount: "3.6962",
|
1127
|
+
# tradeType: 2,
|
1128
|
+
# tradeId: "505979017439002624X1",
|
1129
|
+
# orderId: "C02__505979017439002624115",
|
1130
|
+
# feeAmount: "0.0003998377369698171",
|
1131
|
+
# feeCurrency: "MX",
|
1132
|
+
# time: 1736417034280
|
1133
|
+
# }
|
1134
|
+
#
|
1135
|
+
timestamp = self.safe_integer_2(trade, 'T', 'time')
|
1136
|
+
tradeId = self.safe_string_2(trade, 't', 'tradeId')
|
1020
1137
|
if timestamp is None:
|
1021
1138
|
timestamp = self.safe_integer(trade, 't')
|
1022
1139
|
tradeId = None
|
1023
|
-
priceString = self.
|
1024
|
-
amountString = self.
|
1025
|
-
rawSide = self.
|
1140
|
+
priceString = self.safe_string_2(trade, 'p', 'price')
|
1141
|
+
amountString = self.safe_string_2(trade, 'v', 'quantity')
|
1142
|
+
rawSide = self.safe_string_2(trade, 'S', 'tradeType')
|
1026
1143
|
side = 'buy' if (rawSide == '1') else 'sell'
|
1027
1144
|
isMaker = self.safe_integer(trade, 'm')
|
1028
|
-
feeAmount = self.
|
1029
|
-
feeCurrencyId = self.
|
1145
|
+
feeAmount = self.safe_string_2(trade, 'n', 'feeAmount')
|
1146
|
+
feeCurrencyId = self.safe_string_2(trade, 'N', 'feeCurrency')
|
1030
1147
|
return self.safe_trade({
|
1031
1148
|
'info': trade,
|
1032
1149
|
'id': tradeId,
|
1033
|
-
'order': self.
|
1150
|
+
'order': self.safe_string_2(trade, 'i', 'orderId'),
|
1034
1151
|
'timestamp': timestamp,
|
1035
1152
|
'datetime': self.iso8601(timestamp),
|
1036
1153
|
'symbol': self.safe_symbol(None, market),
|
@@ -1039,7 +1156,7 @@ class mexc(mexcAsync):
|
|
1039
1156
|
'takerOrMaker': 'maker' if (isMaker) else 'taker',
|
1040
1157
|
'price': priceString,
|
1041
1158
|
'amount': amountString,
|
1042
|
-
'cost':
|
1159
|
+
'cost': self.safe_string(trade, 'amount'),
|
1043
1160
|
'fee': {
|
1044
1161
|
'cost': feeAmount,
|
1045
1162
|
'currency': self.safe_currency_code(feeCurrencyId),
|
@@ -1049,7 +1166,7 @@ class mexc(mexcAsync):
|
|
1049
1166
|
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
1050
1167
|
"""
|
1051
1168
|
|
1052
|
-
https://
|
1169
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-user-data-streams#spot-account-orders
|
1053
1170
|
https://mexcdevelop.github.io/apidocs/spot_v3_en/#margin-account-orders
|
1054
1171
|
|
1055
1172
|
watches information on multiple orders made by the user
|
@@ -1071,7 +1188,7 @@ class mexc(mexcAsync):
|
|
1071
1188
|
type, params = self.handle_market_type_and_params('watchOrders', market, params)
|
1072
1189
|
orders = None
|
1073
1190
|
if type == 'spot':
|
1074
|
-
channel =
|
1191
|
+
channel = 'spot@private.orders.v3.api.pb'
|
1075
1192
|
orders = await self.watch_spot_private(channel, messageHash, params)
|
1076
1193
|
else:
|
1077
1194
|
orders = await self.watch_swap_private(messageHash, params)
|
@@ -1144,11 +1261,18 @@ class mexc(mexcAsync):
|
|
1144
1261
|
# "s": "MXUSDT",
|
1145
1262
|
# "t":1661938138193
|
1146
1263
|
# }
|
1264
|
+
# protobuf
|
1265
|
+
# {
|
1266
|
+
# channel: "spot@private.orders.v3.api.pb",
|
1267
|
+
# symbol: "MXUSDT",
|
1268
|
+
# sendTime: 1736417034281,
|
1269
|
+
# privateOrders {}
|
1270
|
+
# }
|
1147
1271
|
#
|
1148
1272
|
messageHash = 'orders'
|
1149
|
-
data = self.
|
1273
|
+
data = self.safe_dict_n(message, ['d', 'data', 'privateOrders'])
|
1150
1274
|
futuresMarketId = self.safe_string(data, 'symbol')
|
1151
|
-
marketId = self.
|
1275
|
+
marketId = self.safe_string_2(message, 's', 'symbol', futuresMarketId)
|
1152
1276
|
market = self.safe_market(marketId)
|
1153
1277
|
symbol = market['symbol']
|
1154
1278
|
parsed = None
|
@@ -1216,11 +1340,28 @@ class mexc(mexcAsync):
|
|
1216
1340
|
# "s":1,
|
1217
1341
|
# "i":"e03a5c7441e44ed899466a7140b71391",
|
1218
1342
|
# }
|
1343
|
+
# protofbuf spot order
|
1344
|
+
# {
|
1345
|
+
# "id":"C02__583905164440776704043",
|
1346
|
+
# "price":"0.001053",
|
1347
|
+
# "quantity":"2000",
|
1348
|
+
# "amount":"0",
|
1349
|
+
# "avgPrice":"0.001007",
|
1350
|
+
# "orderType":5,
|
1351
|
+
# "tradeType":1,
|
1352
|
+
# "remainAmount":"0.092",
|
1353
|
+
# "remainQuantity":"0",
|
1354
|
+
# "lastDealQuantity":"2000",
|
1355
|
+
# "cumulativeQuantity":"2000",
|
1356
|
+
# "cumulativeAmount":"2.014",
|
1357
|
+
# "status":2,
|
1358
|
+
# "createTime":"1754996075502"
|
1359
|
+
# }
|
1219
1360
|
#
|
1220
|
-
timestamp = self.safe_integer(order, '
|
1221
|
-
side = self.safe_string(order, '
|
1222
|
-
status = self.safe_string(order, '
|
1223
|
-
type = self.safe_string(order, '
|
1361
|
+
timestamp = self.safe_integer(order, 'createTime')
|
1362
|
+
side = self.safe_string(order, 'tradeType')
|
1363
|
+
status = self.safe_string(order, 'status')
|
1364
|
+
type = self.safe_string(order, 'orderType')
|
1224
1365
|
fee = None
|
1225
1366
|
feeCurrency = self.safe_string(order, 'N')
|
1226
1367
|
if feeCurrency is not None:
|
@@ -1229,8 +1370,8 @@ class mexc(mexcAsync):
|
|
1229
1370
|
'cost': None,
|
1230
1371
|
}
|
1231
1372
|
return self.safe_order({
|
1232
|
-
'id': self.safe_string(order, '
|
1233
|
-
'clientOrderId': self.safe_string(order, '
|
1373
|
+
'id': self.safe_string(order, 'id'),
|
1374
|
+
'clientOrderId': self.safe_string(order, 'clientOrderId'),
|
1234
1375
|
'timestamp': timestamp,
|
1235
1376
|
'datetime': self.iso8601(timestamp),
|
1236
1377
|
'lastTradeTimestamp': None,
|
@@ -1239,14 +1380,14 @@ class mexc(mexcAsync):
|
|
1239
1380
|
'type': self.parse_ws_order_type(type),
|
1240
1381
|
'timeInForce': self.parse_ws_time_in_force(type),
|
1241
1382
|
'side': 'buy' if (side == '1') else 'sell',
|
1242
|
-
'price': self.safe_string(order, '
|
1383
|
+
'price': self.safe_string(order, 'price'),
|
1243
1384
|
'stopPrice': None,
|
1244
|
-
'triggerPrice':
|
1245
|
-
'average': self.safe_string(order, '
|
1246
|
-
'amount': self.safe_string(order, '
|
1247
|
-
'cost': self.safe_string(order, '
|
1248
|
-
'filled': self.safe_string(order, '
|
1249
|
-
'remaining': self.safe_string(order, '
|
1385
|
+
'triggerPrice': None,
|
1386
|
+
'average': self.safe_string(order, 'avgPrice'),
|
1387
|
+
'amount': self.safe_string(order, 'quantity'),
|
1388
|
+
'cost': self.safe_string(order, 'amount'),
|
1389
|
+
'filled': self.safe_string(order, 'cumulativeQuantity'),
|
1390
|
+
'remaining': self.safe_string(order, 'remainQuantity'),
|
1250
1391
|
'fee': fee,
|
1251
1392
|
'trades': None,
|
1252
1393
|
'info': order,
|
@@ -1269,7 +1410,7 @@ class mexc(mexcAsync):
|
|
1269
1410
|
def parse_ws_order_type(self, type):
|
1270
1411
|
types: dict = {
|
1271
1412
|
'1': 'limit', # LIMIT_ORDER
|
1272
|
-
'2':
|
1413
|
+
'2': 'limit', # POST_ONLY
|
1273
1414
|
'3': None, # IMMEDIATE_OR_CANCEL
|
1274
1415
|
'4': None, # FILL_OR_KILL
|
1275
1416
|
'5': 'market', # MARKET_ORDER
|
@@ -1291,7 +1432,7 @@ class mexc(mexcAsync):
|
|
1291
1432
|
async def watch_balance(self, params={}) -> Balances:
|
1292
1433
|
"""
|
1293
1434
|
|
1294
|
-
https://
|
1435
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-user-data-streams#spot-account-update
|
1295
1436
|
|
1296
1437
|
watch balance and get the amount of funds available for trading or funds locked in orders
|
1297
1438
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1302,7 +1443,7 @@ class mexc(mexcAsync):
|
|
1302
1443
|
type, params = self.handle_market_type_and_params('watchBalance', None, params)
|
1303
1444
|
messageHash = 'balance:' + type
|
1304
1445
|
if type == 'spot':
|
1305
|
-
channel = 'spot@private.account.v3.api'
|
1446
|
+
channel = 'spot@private.account.v3.api.pb'
|
1306
1447
|
return await self.watch_spot_private(channel, messageHash, params)
|
1307
1448
|
else:
|
1308
1449
|
return await self.watch_swap_private(messageHash, params)
|
@@ -1339,22 +1480,22 @@ class mexc(mexcAsync):
|
|
1339
1480
|
# "ts": 1680059188190
|
1340
1481
|
# }
|
1341
1482
|
#
|
1342
|
-
c = self.
|
1483
|
+
c = self.safe_string_2(message, 'c', 'channel')
|
1343
1484
|
type = 'swap' if (c is None) else 'spot'
|
1344
1485
|
messageHash = 'balance:' + type
|
1345
|
-
data = self.
|
1486
|
+
data = self.safe_dict_n(message, ['d', 'data', 'privateAccount'])
|
1346
1487
|
futuresTimestamp = self.safe_integer(message, 'ts')
|
1347
|
-
timestamp = self.
|
1488
|
+
timestamp = self.safe_integer_2(data, 'c', 'time', futuresTimestamp)
|
1348
1489
|
if not (type in self.balance):
|
1349
1490
|
self.balance[type] = {}
|
1350
1491
|
self.balance[type]['info'] = data
|
1351
1492
|
self.balance[type]['timestamp'] = timestamp
|
1352
1493
|
self.balance[type]['datetime'] = self.iso8601(timestamp)
|
1353
|
-
currencyId = self.
|
1494
|
+
currencyId = self.safe_string_n(data, ['a', 'currency', 'vcoinName'])
|
1354
1495
|
code = self.safe_currency_code(currencyId)
|
1355
1496
|
account = self.account()
|
1356
|
-
account['
|
1357
|
-
account['used'] = self.
|
1497
|
+
account['total'] = self.safe_string_n(data, ['f', 'availableBalance', 'balanceAmount'])
|
1498
|
+
account['used'] = self.safe_string_n(data, ['l', 'frozenBalance', 'frozenAmount'])
|
1358
1499
|
self.balance[type][code] = account
|
1359
1500
|
self.balance[type] = self.safe_balance(self.balance[type])
|
1360
1501
|
client.resolve(self.balance[type], messageHash)
|
@@ -1372,22 +1513,17 @@ class mexc(mexcAsync):
|
|
1372
1513
|
url = None
|
1373
1514
|
channel = None
|
1374
1515
|
if market['spot']:
|
1375
|
-
|
1376
|
-
miniTicker, params = self.handle_option_and_params(params, 'watchTicker', 'miniTicker')
|
1377
|
-
if miniTicker:
|
1378
|
-
channel = 'spot@public.miniTicker.v3.api@' + market['id'] + '@UTC+8'
|
1379
|
-
else:
|
1380
|
-
channel = 'spot@public.bookTicker.v3.api@' + market['id']
|
1516
|
+
channel = 'spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id']
|
1381
1517
|
url = self.urls['api']['ws']['spot']
|
1382
1518
|
params['unsubscribed'] = True
|
1383
|
-
|
1519
|
+
self.watch_spot_public(channel, messageHash, params)
|
1384
1520
|
else:
|
1385
1521
|
channel = 'unsub.ticker'
|
1386
1522
|
requestParams: dict = {
|
1387
1523
|
'symbol': market['id'],
|
1388
1524
|
}
|
1389
1525
|
url = self.urls['api']['ws']['swap']
|
1390
|
-
|
1526
|
+
self.watch_swap_public(channel, messageHash, requestParams, params)
|
1391
1527
|
client = self.client(url)
|
1392
1528
|
self.handle_unsubscriptions(client, [messageHash])
|
1393
1529
|
return None
|
@@ -1412,33 +1548,39 @@ class mexc(mexcAsync):
|
|
1412
1548
|
url = self.urls['api']['ws']['spot'] if (isSpot) else self.urls['api']['ws']['swap']
|
1413
1549
|
request: dict = {}
|
1414
1550
|
if isSpot:
|
1415
|
-
|
1416
|
-
miniTicker
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1551
|
+
raise NotSupported(self.id + ' watchTickers does not support spot markets')
|
1552
|
+
# miniTicker = False
|
1553
|
+
# miniTicker, params = self.handle_option_and_params(params, 'watchTickers', 'miniTicker')
|
1554
|
+
# topics = []
|
1555
|
+
# if not miniTicker:
|
1556
|
+
# if symbols is None:
|
1557
|
+
# raise ArgumentsRequired(self.id + ' watchTickers required symbols argument for the bookTicker channel')
|
1558
|
+
# }
|
1559
|
+
# marketIds = self.market_ids(symbols)
|
1560
|
+
# for i in range(0, len(marketIds)):
|
1561
|
+
# marketId = marketIds[i]
|
1562
|
+
# messageHashes.append('unsubscribe:ticker:' + symbols[i])
|
1563
|
+
# channel = 'spot@public.bookTicker.v3.api@' + marketId
|
1564
|
+
# topics.append(channel)
|
1565
|
+
# }
|
1566
|
+
# else:
|
1567
|
+
# topics.append('spot@public.miniTickers.v3.api@UTC+8')
|
1568
|
+
# if symbols is None:
|
1569
|
+
# messageHashes.append('unsubscribe:spot:ticker')
|
1570
|
+
# else:
|
1571
|
+
# for i in range(0, len(symbols)):
|
1572
|
+
# messageHashes.append('unsubscribe:ticker:' + symbols[i])
|
1573
|
+
# }
|
1574
|
+
# }
|
1575
|
+
# }
|
1576
|
+
# request['method'] = 'UNSUBSCRIPTION'
|
1577
|
+
# request['params'] = topics
|
1436
1578
|
else:
|
1437
1579
|
request['method'] = 'unsub.tickers'
|
1438
1580
|
request['params'] = {}
|
1439
1581
|
messageHashes.append('unsubscribe:ticker')
|
1440
1582
|
client = self.client(url)
|
1441
|
-
|
1583
|
+
self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
|
1442
1584
|
self.handle_unsubscriptions(client, messageHashes)
|
1443
1585
|
return None
|
1444
1586
|
|
@@ -1464,7 +1606,7 @@ class mexc(mexcAsync):
|
|
1464
1606
|
for i in range(0, len(symbols)):
|
1465
1607
|
if isSpot:
|
1466
1608
|
market = self.market(symbols[i])
|
1467
|
-
topics.append('spot@public.bookTicker.v3.api@' + market['id'])
|
1609
|
+
topics.append('spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id'])
|
1468
1610
|
messageHashes.append('unsubscribe:bidask:' + symbols[i])
|
1469
1611
|
url = self.urls['api']['ws']['spot']
|
1470
1612
|
request: dict = {
|
@@ -1472,7 +1614,7 @@ class mexc(mexcAsync):
|
|
1472
1614
|
'params': topics,
|
1473
1615
|
}
|
1474
1616
|
client = self.client(url)
|
1475
|
-
|
1617
|
+
self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
|
1476
1618
|
self.handle_unsubscriptions(client, messageHashes)
|
1477
1619
|
return None
|
1478
1620
|
|
@@ -1494,9 +1636,9 @@ class mexc(mexcAsync):
|
|
1494
1636
|
url = None
|
1495
1637
|
if market['spot']:
|
1496
1638
|
url = self.urls['api']['ws']['spot']
|
1497
|
-
channel = 'spot@public.kline.v3.api@' + market['id'] + '@' + timeframeId
|
1639
|
+
channel = 'spot@public.kline.v3.api.pb@' + market['id'] + '@' + timeframeId
|
1498
1640
|
params['unsubscribed'] = True
|
1499
|
-
|
1641
|
+
self.watch_spot_public(channel, messageHash, params)
|
1500
1642
|
else:
|
1501
1643
|
url = self.urls['api']['ws']['swap']
|
1502
1644
|
channel = 'unsub.kline'
|
@@ -1504,7 +1646,7 @@ class mexc(mexcAsync):
|
|
1504
1646
|
'symbol': market['id'],
|
1505
1647
|
'interval': timeframeId,
|
1506
1648
|
}
|
1507
|
-
|
1649
|
+
self.watch_swap_public(channel, messageHash, requestParams, params)
|
1508
1650
|
client = self.client(url)
|
1509
1651
|
self.handle_unsubscriptions(client, [messageHash])
|
1510
1652
|
return None
|
@@ -1514,6 +1656,7 @@ class mexc(mexcAsync):
|
|
1514
1656
|
unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
1515
1657
|
:param str symbol: unified array of symbols
|
1516
1658
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1659
|
+
:param str [params.frequency]: the frequency of the order book updates, default is '10ms', can be '100ms' or '10ms
|
1517
1660
|
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
1518
1661
|
"""
|
1519
1662
|
await self.load_markets()
|
@@ -1523,16 +1666,18 @@ class mexc(mexcAsync):
|
|
1523
1666
|
url = None
|
1524
1667
|
if market['spot']:
|
1525
1668
|
url = self.urls['api']['ws']['spot']
|
1526
|
-
|
1669
|
+
frequency = None
|
1670
|
+
frequency, params = self.handle_option_and_params(params, 'watchOrderBook', 'frequency', '100ms')
|
1671
|
+
channel = 'spot@public.aggre.depth.v3.api.pb@' + frequency + '@' + market['id']
|
1527
1672
|
params['unsubscribed'] = True
|
1528
|
-
|
1673
|
+
self.watch_spot_public(channel, messageHash, params)
|
1529
1674
|
else:
|
1530
1675
|
url = self.urls['api']['ws']['swap']
|
1531
1676
|
channel = 'unsub.depth'
|
1532
1677
|
requestParams: dict = {
|
1533
1678
|
'symbol': market['id'],
|
1534
1679
|
}
|
1535
|
-
|
1680
|
+
self.watch_swap_public(channel, messageHash, requestParams, params)
|
1536
1681
|
client = self.client(url)
|
1537
1682
|
self.handle_unsubscriptions(client, [messageHash])
|
1538
1683
|
return None
|
@@ -1552,16 +1697,16 @@ class mexc(mexcAsync):
|
|
1552
1697
|
url = None
|
1553
1698
|
if market['spot']:
|
1554
1699
|
url = self.urls['api']['ws']['spot']
|
1555
|
-
channel = 'spot@public.deals.v3.api@' + market['id']
|
1700
|
+
channel = 'spot@public.aggre.deals.v3.api.pb@100ms@' + market['id']
|
1556
1701
|
params['unsubscribed'] = True
|
1557
|
-
|
1702
|
+
self.watch_spot_public(channel, messageHash, params)
|
1558
1703
|
else:
|
1559
1704
|
url = self.urls['api']['ws']['swap']
|
1560
1705
|
channel = 'unsub.deal'
|
1561
1706
|
requestParams: dict = {
|
1562
1707
|
'symbol': market['id'],
|
1563
1708
|
}
|
1564
|
-
|
1709
|
+
self.watch_swap_public(channel, messageHash, requestParams, params)
|
1565
1710
|
client = self.client(url)
|
1566
1711
|
self.handle_unsubscriptions(client, [messageHash])
|
1567
1712
|
return None
|
@@ -1654,16 +1799,59 @@ class mexc(mexcAsync):
|
|
1654
1799
|
channel = self.safe_string(parts, 1)
|
1655
1800
|
methods: dict = {
|
1656
1801
|
'public.increase.depth.v3.api': self.handle_order_book_subscription,
|
1802
|
+
'public.aggre.depth.v3.api.pb': self.handle_order_book_subscription,
|
1657
1803
|
}
|
1658
1804
|
method = self.safe_value(methods, channel)
|
1659
1805
|
if method is not None:
|
1660
1806
|
method(client, message)
|
1661
1807
|
|
1808
|
+
def handle_protobuf_message(self, client: Client, message):
|
1809
|
+
# protobuf message decoded
|
1810
|
+
# {
|
1811
|
+
# "channel":"spot@public.kline.v3.api.pb@BTCUSDT@Min1",
|
1812
|
+
# "symbol":"BTCUSDT",
|
1813
|
+
# "symbolId":"2fb942154ef44a4ab2ef98c8afb6a4a7",
|
1814
|
+
# "createTime":"1754737941062",
|
1815
|
+
# "publicSpotKline":{
|
1816
|
+
# "interval":"Min1",
|
1817
|
+
# "windowStart":"1754737920",
|
1818
|
+
# "openingPrice":"117317.31",
|
1819
|
+
# "closingPrice":"117325.26",
|
1820
|
+
# "highestPrice":"117341",
|
1821
|
+
# "lowestPrice":"117317.3",
|
1822
|
+
# "volume":"3.12599854",
|
1823
|
+
# "amount":"366804.43",
|
1824
|
+
# "windowEnd":"1754737980"
|
1825
|
+
# }
|
1826
|
+
# }
|
1827
|
+
channel = self.safe_string(message, 'channel')
|
1828
|
+
channelParts = channel.split('@')
|
1829
|
+
channelId = self.safe_string(channelParts, 1)
|
1830
|
+
if channelId == 'public.kline.v3.api.pb':
|
1831
|
+
self.handle_ohlcv(client, message)
|
1832
|
+
elif channelId == 'public.aggre.deals.v3.api.pb':
|
1833
|
+
self.handle_trades(client, message)
|
1834
|
+
elif channelId == 'public.aggre.bookTicker.v3.api.pb':
|
1835
|
+
self.handle_ticker(client, message)
|
1836
|
+
elif channelId == 'public.aggre.depth.v3.api.pb':
|
1837
|
+
self.handle_order_book(client, message)
|
1838
|
+
elif channelId == 'private.account.v3.api.pb':
|
1839
|
+
self.handle_balance(client, message)
|
1840
|
+
elif channelId == 'private.deals.v3.api.pb':
|
1841
|
+
self.handle_my_trade(client, message)
|
1842
|
+
elif channelId == 'private.orders.v3.api.pb':
|
1843
|
+
self.handle_order(client, message)
|
1844
|
+
return True
|
1845
|
+
|
1662
1846
|
def handle_message(self, client: Client, message):
|
1663
1847
|
if isinstance(message, str):
|
1664
1848
|
if message == 'Invalid listen key':
|
1665
1849
|
error = AuthenticationError(self.id + ' invalid listen key')
|
1666
1850
|
client.reject(error)
|
1851
|
+
return
|
1852
|
+
if self.is_binary_message(message):
|
1853
|
+
message = self.decode_proto_msg(message)
|
1854
|
+
self.handle_protobuf_message(client, message)
|
1667
1855
|
return
|
1668
1856
|
if 'msg' in message:
|
1669
1857
|
self.handle_subscription_status(client, message)
|