ccxt-ir 4.3.46.0.3__py2.py3-none-any.whl → 4.5.1__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 +39 -35
- ccxt/abantether.py +8 -8
- ccxt/abstract/alpaca.py +4 -0
- ccxt/abstract/apex.py +31 -0
- ccxt/abstract/bigone.py +1 -1
- ccxt/abstract/binance.py +106 -48
- ccxt/abstract/binancecoinm.py +106 -48
- ccxt/abstract/binanceus.py +141 -83
- ccxt/abstract/binanceusdm.py +106 -48
- ccxt/abstract/bingx.py +50 -1
- ccxt/abstract/bitbank.py +5 -0
- ccxt/abstract/bitfinex.py +136 -65
- ccxt/abstract/bitflyer.py +1 -0
- ccxt/abstract/bitget.py +67 -0
- ccxt/abstract/bitmart.py +19 -1
- ccxt/abstract/bitopro.py +1 -0
- ccxt/abstract/bitrue.py +68 -68
- ccxt/abstract/bitstamp.py +1 -0
- ccxt/abstract/blofin.py +30 -0
- ccxt/abstract/btcbox.py +2 -0
- ccxt/abstract/bybit.py +28 -13
- ccxt/abstract/cex.py +28 -29
- ccxt/abstract/coinbaseexchange.py +1 -0
- ccxt/abstract/coinbaseinternational.py +1 -1
- ccxt/abstract/cryptocom.py +16 -0
- ccxt/abstract/cryptomus.py +20 -0
- ccxt/abstract/defx.py +69 -0
- ccxt/abstract/deribit.py +1 -0
- ccxt/abstract/derive.py +117 -0
- ccxt/abstract/digifinex.py +1 -0
- ccxt/abstract/ellipx.py +25 -0
- ccxt/abstract/foxbit.py +26 -0
- ccxt/abstract/gate.py +19 -0
- ccxt/abstract/gateio.py +19 -0
- ccxt/abstract/gemini.py +1 -0
- ccxt/abstract/hibachi.py +26 -0
- ccxt/abstract/hyperliquid.py +1 -1
- ccxt/abstract/independentreserve.py +6 -0
- ccxt/abstract/kraken.py +1 -0
- ccxt/abstract/krakenfutures.py +4 -0
- ccxt/abstract/kucoin.py +10 -0
- ccxt/abstract/kucoinfutures.py +18 -0
- ccxt/abstract/lbank.py +2 -1
- ccxt/abstract/luno.py +1 -0
- ccxt/abstract/mexc.py +2 -0
- ccxt/abstract/modetrade.py +119 -0
- ccxt/abstract/myokx.py +349 -0
- ccxt/abstract/oceanex.py +5 -0
- ccxt/abstract/okx.py +25 -0
- ccxt/abstract/okxus.py +349 -0
- ccxt/abstract/onetrading.py +0 -12
- ccxt/abstract/paradex.py +23 -0
- ccxt/abstract/phemex.py +2 -0
- ccxt/abstract/poloniex.py +36 -0
- ccxt/abstract/tradeogre.py +3 -1
- ccxt/abstract/upbit.py +51 -34
- ccxt/abstract/whitebit.py +16 -0
- ccxt/abstract/woo.py +64 -6
- ccxt/abstract/xt.py +10 -5
- ccxt/afratether.py +8 -8
- ccxt/alpaca.py +828 -51
- ccxt/apex.py +1875 -0
- ccxt/arzinja.py +7 -7
- ccxt/arzplus.py +9 -9
- ccxt/ascendex.py +501 -306
- ccxt/async_support/__init__.py +39 -35
- ccxt/async_support/abantether.py +8 -8
- ccxt/async_support/afratether.py +10 -10
- ccxt/async_support/alpaca.py +828 -51
- ccxt/async_support/apex.py +1875 -0
- ccxt/async_support/arzinja.py +10 -10
- ccxt/async_support/arzplus.py +12 -12
- ccxt/async_support/ascendex.py +502 -306
- ccxt/async_support/base/exchange.py +303 -89
- ccxt/async_support/base/ws/cache.py +9 -3
- ccxt/async_support/base/ws/client.py +173 -38
- ccxt/async_support/base/ws/future.py +25 -37
- ccxt/async_support/bequant.py +5 -3
- ccxt/async_support/bigone.py +279 -144
- ccxt/async_support/binance.py +2347 -1158
- ccxt/async_support/binancecoinm.py +9 -3
- ccxt/async_support/binanceus.py +17 -3
- ccxt/async_support/binanceusdm.py +9 -4
- ccxt/async_support/bingx.py +2962 -920
- ccxt/async_support/bit2c.py +147 -27
- ccxt/async_support/bitbank.py +151 -23
- ccxt/async_support/bitbns.py +104 -30
- ccxt/async_support/bitfinex.py +3291 -1113
- ccxt/async_support/bitflyer.py +202 -27
- ccxt/async_support/bitget.py +3683 -1538
- ccxt/async_support/bithumb.py +195 -38
- ccxt/async_support/bitimen.py +12 -12
- ccxt/async_support/bitir.py +38 -38
- ccxt/async_support/bitmart.py +1288 -350
- ccxt/async_support/bitmex.py +260 -75
- ccxt/async_support/bitopro.py +262 -62
- ccxt/async_support/bitpin.py +17 -16
- ccxt/async_support/bitrue.py +459 -290
- ccxt/async_support/bitso.py +199 -54
- ccxt/async_support/bitstamp.py +230 -96
- ccxt/async_support/bitteam.py +167 -25
- ccxt/async_support/{huobijp.py → bittrade.py} +158 -30
- ccxt/async_support/bitvavo.py +213 -49
- ccxt/async_support/blockchaincom.py +160 -46
- ccxt/async_support/blofin.py +502 -120
- ccxt/async_support/btcalpha.py +169 -31
- ccxt/async_support/btcbox.py +292 -23
- ccxt/async_support/btcmarkets.py +211 -58
- ccxt/async_support/btcturk.py +161 -38
- ccxt/async_support/bybit.py +1775 -1030
- ccxt/async_support/cex.py +1440 -1303
- ccxt/async_support/coinbase.py +724 -212
- ccxt/async_support/coinbaseadvanced.py +2 -1
- ccxt/async_support/coinbaseexchange.py +388 -89
- ccxt/async_support/coinbaseinternational.py +412 -57
- ccxt/async_support/coincatch.py +177 -78
- ccxt/async_support/coincheck.py +135 -19
- ccxt/async_support/coinex.py +606 -232
- ccxt/async_support/coinmate.py +189 -63
- ccxt/async_support/coinmetro.py +195 -54
- ccxt/async_support/coinone.py +158 -51
- ccxt/async_support/coinsph.py +336 -61
- ccxt/async_support/coinspot.py +151 -52
- ccxt/async_support/cryptocom.py +661 -111
- ccxt/async_support/cryptomus.py +1137 -0
- ccxt/async_support/defx.py +2071 -0
- ccxt/async_support/delta.py +299 -99
- ccxt/async_support/deribit.py +348 -126
- ccxt/async_support/derive.py +2572 -0
- ccxt/async_support/digifinex.py +430 -214
- ccxt/async_support/ellipx.py +2029 -0
- ccxt/async_support/eterex.py +10 -10
- ccxt/async_support/excoino.py +31 -31
- ccxt/async_support/exir.py +14 -14
- ccxt/async_support/exmo.py +344 -131
- ccxt/async_support/exnovin.py +10 -10
- ccxt/async_support/farhadexchange.py +12 -12
- ccxt/async_support/fmfwio.py +2 -1
- ccxt/async_support/foxbit.py +1935 -0
- ccxt/async_support/gate.py +1351 -529
- ccxt/async_support/gateio.py +2 -1
- ccxt/async_support/gemini.py +144 -39
- ccxt/async_support/hashkey.py +152 -109
- ccxt/async_support/hibachi.py +2080 -0
- ccxt/async_support/hitbtc.py +395 -167
- ccxt/async_support/hitobit.py +12 -12
- ccxt/async_support/hollaex.py +307 -119
- ccxt/async_support/htx.py +851 -383
- ccxt/async_support/huobi.py +2 -1
- ccxt/async_support/hyperliquid.py +1848 -536
- ccxt/async_support/independentreserve.py +288 -15
- ccxt/async_support/indodax.py +190 -33
- ccxt/async_support/jibitex.py +12 -12
- ccxt/async_support/kraken.py +795 -351
- ccxt/async_support/krakenfutures.py +214 -62
- ccxt/async_support/kucoin.py +715 -396
- ccxt/async_support/kucoinfutures.py +652 -89
- ccxt/async_support/latoken.py +217 -113
- ccxt/async_support/lbank.py +425 -97
- ccxt/async_support/luno.py +382 -35
- ccxt/async_support/mercado.py +113 -6
- ccxt/async_support/mexc.py +874 -437
- ccxt/async_support/modetrade.py +2818 -0
- ccxt/async_support/myokx.py +54 -0
- ccxt/async_support/ndax.py +221 -64
- ccxt/async_support/nobitex.py +32 -38
- ccxt/async_support/novadax.py +190 -34
- ccxt/async_support/oceanex.py +217 -28
- ccxt/async_support/okcoin.py +253 -145
- ccxt/async_support/okexchange.py +11 -11
- ccxt/async_support/okx.py +1088 -351
- ccxt/async_support/okxus.py +54 -0
- ccxt/async_support/ompfinex.py +32 -27
- ccxt/async_support/onetrading.py +213 -392
- ccxt/async_support/oxfun.py +245 -166
- ccxt/async_support/p2b.py +151 -29
- ccxt/async_support/paradex.py +562 -49
- ccxt/async_support/paymium.py +82 -19
- ccxt/async_support/phemex.py +713 -172
- ccxt/async_support/poloniex.py +1602 -283
- ccxt/async_support/probit.py +224 -95
- ccxt/async_support/ramzinex.py +34 -30
- ccxt/async_support/sarmayex.py +9 -9
- ccxt/async_support/sarrafex.py +13 -13
- ccxt/async_support/tabdeal.py +15 -14
- ccxt/async_support/tetherland.py +9 -9
- ccxt/async_support/timex.py +210 -51
- ccxt/async_support/tokocrypto.py +167 -47
- ccxt/async_support/tradeogre.py +266 -31
- ccxt/async_support/twox.py +9 -9
- ccxt/async_support/ubitex.py +12 -12
- ccxt/async_support/upbit.py +568 -165
- ccxt/async_support/vertex.py +160 -32
- ccxt/async_support/wallex.py +12 -12
- ccxt/async_support/wavesexchange.py +165 -30
- ccxt/async_support/whitebit.py +975 -127
- ccxt/async_support/woo.py +1918 -1016
- ccxt/async_support/woofipro.py +433 -141
- ccxt/async_support/xt.py +649 -193
- ccxt/async_support/yobit.py +195 -70
- ccxt/async_support/zaif.py +91 -15
- ccxt/async_support/zonda.py +151 -36
- ccxt/base/decimal_to_precision.py +14 -10
- ccxt/base/errors.py +49 -18
- ccxt/base/exchange.py +1556 -450
- ccxt/base/precise.py +10 -0
- ccxt/base/types.py +114 -6
- ccxt/bequant.py +5 -3
- ccxt/bigone.py +279 -144
- ccxt/binance.py +2347 -1158
- ccxt/binancecoinm.py +9 -3
- ccxt/binanceus.py +17 -3
- ccxt/binanceusdm.py +9 -4
- ccxt/bingx.py +2962 -920
- ccxt/bit2c.py +147 -27
- ccxt/bitbank.py +151 -23
- ccxt/bitbns.py +104 -30
- ccxt/bitfinex.py +3290 -1113
- ccxt/bitflyer.py +202 -27
- ccxt/bitget.py +3683 -1538
- ccxt/bithumb.py +194 -38
- ccxt/bitimen.py +9 -9
- ccxt/bitir.py +35 -35
- ccxt/bitmart.py +1288 -350
- ccxt/bitmex.py +260 -75
- ccxt/bitopro.py +262 -62
- ccxt/bitpin.py +15 -14
- ccxt/bitrue.py +459 -290
- ccxt/bitso.py +199 -54
- ccxt/bitstamp.py +230 -96
- ccxt/bitteam.py +167 -25
- ccxt/{huobijp.py → bittrade.py} +158 -30
- ccxt/bitvavo.py +213 -49
- ccxt/blockchaincom.py +160 -46
- ccxt/blofin.py +502 -120
- ccxt/btcalpha.py +169 -31
- ccxt/btcbox.py +291 -23
- ccxt/btcmarkets.py +211 -58
- ccxt/btcturk.py +161 -38
- ccxt/bybit.py +1775 -1030
- ccxt/cex.py +1439 -1303
- ccxt/coinbase.py +724 -212
- ccxt/coinbaseadvanced.py +2 -1
- ccxt/coinbaseexchange.py +388 -89
- ccxt/coinbaseinternational.py +412 -57
- ccxt/coincatch.py +177 -78
- ccxt/coincheck.py +135 -19
- ccxt/coinex.py +606 -232
- ccxt/coinmate.py +189 -63
- ccxt/coinmetro.py +194 -54
- ccxt/coinone.py +158 -51
- ccxt/coinsph.py +336 -61
- ccxt/coinspot.py +151 -52
- ccxt/cryptocom.py +661 -111
- ccxt/cryptomus.py +1137 -0
- ccxt/defx.py +2070 -0
- ccxt/delta.py +299 -99
- ccxt/deribit.py +348 -126
- ccxt/derive.py +2571 -0
- ccxt/digifinex.py +430 -214
- ccxt/ellipx.py +2029 -0
- ccxt/eterex.py +7 -7
- ccxt/excoino.py +29 -29
- ccxt/exir.py +11 -11
- ccxt/exmo.py +343 -131
- ccxt/exnovin.py +8 -8
- ccxt/farhadexchange.py +10 -10
- ccxt/fmfwio.py +2 -1
- ccxt/foxbit.py +1935 -0
- ccxt/gate.py +1351 -529
- ccxt/gateio.py +2 -1
- ccxt/gemini.py +144 -39
- ccxt/hashkey.py +152 -109
- ccxt/hibachi.py +2079 -0
- ccxt/hitbtc.py +395 -167
- ccxt/hitobit.py +9 -9
- ccxt/hollaex.py +307 -119
- ccxt/htx.py +851 -383
- ccxt/huobi.py +2 -1
- ccxt/hyperliquid.py +1848 -536
- ccxt/independentreserve.py +287 -15
- ccxt/indodax.py +190 -33
- ccxt/jibitex.py +9 -9
- ccxt/kraken.py +794 -351
- ccxt/krakenfutures.py +214 -62
- ccxt/kucoin.py +715 -396
- ccxt/kucoinfutures.py +652 -89
- ccxt/latoken.py +217 -113
- ccxt/lbank.py +425 -97
- ccxt/luno.py +382 -35
- ccxt/mercado.py +113 -6
- ccxt/mexc.py +873 -437
- ccxt/modetrade.py +2818 -0
- ccxt/myokx.py +54 -0
- ccxt/ndax.py +221 -64
- ccxt/nobitex.py +30 -36
- ccxt/novadax.py +190 -34
- ccxt/oceanex.py +217 -28
- ccxt/okcoin.py +253 -145
- ccxt/okexchange.py +9 -9
- ccxt/okx.py +1088 -351
- ccxt/okxus.py +54 -0
- ccxt/ompfinex.py +29 -24
- ccxt/onetrading.py +213 -392
- ccxt/oxfun.py +245 -166
- ccxt/p2b.py +151 -29
- ccxt/paradex.py +562 -49
- ccxt/paymium.py +82 -19
- ccxt/phemex.py +712 -172
- ccxt/poloniex.py +1601 -283
- ccxt/pro/__init__.py +76 -17
- ccxt/pro/alpaca.py +21 -6
- ccxt/pro/apex.py +984 -0
- ccxt/pro/ascendex.py +58 -10
- ccxt/pro/bequant.py +6 -1
- ccxt/pro/binance.py +728 -156
- ccxt/pro/binancecoinm.py +6 -2
- ccxt/pro/binanceus.py +8 -4
- ccxt/pro/binanceusdm.py +7 -2
- ccxt/pro/bingx.py +333 -142
- ccxt/pro/bitfinex.py +727 -262
- ccxt/pro/bitget.py +570 -79
- ccxt/pro/bithumb.py +20 -6
- ccxt/pro/bitmart.py +216 -87
- ccxt/pro/bitmex.py +47 -9
- ccxt/pro/bitopro.py +26 -14
- ccxt/pro/bitrue.py +22 -22
- ccxt/pro/bitstamp.py +54 -21
- ccxt/pro/{huobijp.py → bittrade.py} +7 -6
- ccxt/pro/bitvavo.py +191 -67
- ccxt/pro/blockchaincom.py +21 -8
- ccxt/pro/blofin.py +9 -1
- ccxt/pro/bybit.py +632 -245
- ccxt/pro/cex.py +59 -24
- ccxt/pro/coinbase.py +102 -73
- ccxt/pro/coinbaseadvanced.py +2 -1
- ccxt/pro/coinbaseexchange.py +8 -8
- ccxt/pro/coinbaseinternational.py +181 -25
- ccxt/pro/coincatch.py +6 -7
- ccxt/pro/coincheck.py +11 -6
- ccxt/pro/coinex.py +967 -665
- ccxt/pro/coinone.py +16 -9
- ccxt/pro/cryptocom.py +448 -45
- ccxt/pro/defx.py +831 -0
- ccxt/pro/deribit.py +150 -14
- ccxt/pro/derive.py +704 -0
- ccxt/pro/exmo.py +239 -6
- ccxt/pro/gate.py +623 -65
- ccxt/pro/gateio.py +2 -1
- ccxt/pro/gemini.py +27 -11
- ccxt/pro/hashkey.py +2 -2
- ccxt/pro/hitbtc.py +196 -91
- ccxt/pro/hollaex.py +23 -7
- ccxt/pro/htx.py +51 -14
- ccxt/pro/huobi.py +2 -1
- ccxt/pro/hyperliquid.py +591 -27
- ccxt/pro/independentreserve.py +9 -6
- ccxt/pro/kraken.py +640 -320
- ccxt/pro/krakenfutures.py +62 -35
- ccxt/pro/kucoin.py +267 -46
- ccxt/pro/kucoinfutures.py +165 -21
- ccxt/pro/lbank.py +102 -21
- ccxt/pro/luno.py +12 -8
- ccxt/pro/mexc.py +877 -111
- ccxt/pro/modetrade.py +1271 -0
- ccxt/pro/myokx.py +38 -0
- ccxt/pro/ndax.py +15 -2
- ccxt/pro/okcoin.py +23 -4
- ccxt/pro/okx.py +573 -98
- ccxt/pro/okxus.py +38 -0
- ccxt/pro/onetrading.py +30 -13
- ccxt/pro/oxfun.py +131 -27
- ccxt/pro/p2b.py +88 -22
- ccxt/pro/paradex.py +3 -3
- ccxt/pro/phemex.py +75 -21
- ccxt/pro/poloniex.py +124 -41
- ccxt/pro/probit.py +87 -80
- ccxt/pro/tradeogre.py +272 -0
- ccxt/pro/upbit.py +152 -12
- ccxt/pro/vertex.py +8 -3
- ccxt/pro/whitebit.py +58 -5
- ccxt/pro/woo.py +228 -37
- ccxt/pro/woofipro.py +106 -18
- ccxt/pro/xt.py +111 -5
- ccxt/probit.py +224 -95
- 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/ramzinex.py +32 -28
- ccxt/sarmayex.py +7 -7
- ccxt/sarrafex.py +10 -10
- ccxt/static_dependencies/__init__.py +1 -1
- ccxt/static_dependencies/lark/py.typed +0 -0
- ccxt/static_dependencies/marshmallow/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- ccxt/tabdeal.py +13 -12
- ccxt/test/tests_async.py +261 -57
- ccxt/test/tests_helpers.py +1 -3
- ccxt/test/tests_init.py +4 -3
- ccxt/test/tests_sync.py +261 -57
- ccxt/tetherland.py +7 -7
- ccxt/timex.py +210 -51
- ccxt/tokocrypto.py +167 -47
- ccxt/tradeogre.py +266 -31
- ccxt/twox.py +7 -7
- ccxt/ubitex.py +9 -9
- ccxt/upbit.py +568 -165
- ccxt/vertex.py +160 -32
- ccxt/wallex.py +9 -9
- ccxt/wavesexchange.py +165 -30
- ccxt/whitebit.py +975 -127
- ccxt/woo.py +1917 -1016
- ccxt/woofipro.py +432 -141
- ccxt/xt.py +649 -193
- ccxt/yobit.py +194 -70
- ccxt/zaif.py +91 -15
- ccxt/zonda.py +151 -36
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/METADATA +225 -73
- ccxt_ir-4.5.1.dist-info/RECORD +743 -0
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/WHEEL +1 -1
- ccxt/__test__.py +0 -7
- ccxt/abstract/ace.py +0 -15
- ccxt/abstract/bitbay.py +0 -53
- ccxt/abstract/bitcoincom.py +0 -115
- ccxt/abstract/bitfinex2.py +0 -139
- ccxt/abstract/bitpanda.py +0 -35
- ccxt/abstract/bl3p.py +0 -19
- ccxt/abstract/coinlist.py +0 -54
- ccxt/abstract/currencycom.py +0 -68
- ccxt/abstract/hitbtc3.py +0 -115
- ccxt/abstract/idex.py +0 -26
- ccxt/abstract/kuna.py +0 -182
- ccxt/abstract/lykke.py +0 -29
- ccxt/abstract/poloniexfutures.py +0 -48
- ccxt/abstract/wazirx.py +0 -30
- ccxt/ace.py +0 -1012
- ccxt/async_support/ace.py +0 -1012
- ccxt/async_support/base/ws/aiohttp_client.py +0 -125
- ccxt/async_support/base/ws/fast_client.py +0 -96
- ccxt/async_support/bitbay.py +0 -17
- ccxt/async_support/bitcoincom.py +0 -17
- ccxt/async_support/bitfinex2.py +0 -3552
- ccxt/async_support/bitpanda.py +0 -16
- ccxt/async_support/bl3p.py +0 -485
- ccxt/async_support/coinlist.py +0 -2243
- ccxt/async_support/currencycom.py +0 -1950
- ccxt/async_support/hitbtc3.py +0 -16
- ccxt/async_support/idex.py +0 -1766
- ccxt/async_support/kuna.py +0 -1841
- ccxt/async_support/lykke.py +0 -1270
- ccxt/async_support/poloniexfutures.py +0 -1717
- ccxt/async_support/wazirx.py +0 -1224
- ccxt/bitbay.py +0 -17
- ccxt/bitcoincom.py +0 -17
- ccxt/bitfinex2.py +0 -3552
- ccxt/bitpanda.py +0 -16
- ccxt/bl3p.py +0 -485
- ccxt/coinlist.py +0 -2243
- ccxt/currencycom.py +0 -1950
- ccxt/hitbtc3.py +0 -16
- ccxt/idex.py +0 -1766
- ccxt/kuna.py +0 -1841
- ccxt/lykke.py +0 -1270
- ccxt/poloniexfutures.py +0 -1717
- ccxt/pro/bitcoincom.py +0 -34
- ccxt/pro/bitfinex2.py +0 -1083
- ccxt/pro/bitpanda.py +0 -15
- ccxt/pro/currencycom.py +0 -536
- ccxt/pro/idex.py +0 -672
- ccxt/pro/poloniexfutures.py +0 -990
- ccxt/pro/wazirx.py +0 -749
- ccxt/test/base/__init__.py +0 -29
- ccxt/test/base/test_account.py +0 -26
- ccxt/test/base/test_balance.py +0 -56
- ccxt/test/base/test_borrow_interest.py +0 -35
- ccxt/test/base/test_borrow_rate.py +0 -32
- ccxt/test/base/test_calculate_fee.py +0 -51
- ccxt/test/base/test_crypto.py +0 -127
- ccxt/test/base/test_currency.py +0 -76
- ccxt/test/base/test_datetime.py +0 -109
- ccxt/test/base/test_decimal_to_precision.py +0 -392
- ccxt/test/base/test_deep_extend.py +0 -68
- ccxt/test/base/test_deposit_withdrawal.py +0 -50
- ccxt/test/base/test_exchange_datetime_functions.py +0 -76
- ccxt/test/base/test_funding_rate_history.py +0 -29
- ccxt/test/base/test_last_price.py +0 -31
- ccxt/test/base/test_ledger_entry.py +0 -45
- ccxt/test/base/test_ledger_item.py +0 -48
- ccxt/test/base/test_leverage_tier.py +0 -33
- ccxt/test/base/test_liquidation.py +0 -50
- ccxt/test/base/test_margin_mode.py +0 -24
- ccxt/test/base/test_margin_modification.py +0 -35
- ccxt/test/base/test_market.py +0 -193
- ccxt/test/base/test_number.py +0 -411
- ccxt/test/base/test_ohlcv.py +0 -33
- ccxt/test/base/test_open_interest.py +0 -32
- ccxt/test/base/test_order.py +0 -64
- ccxt/test/base/test_order_book.py +0 -69
- ccxt/test/base/test_position.py +0 -60
- ccxt/test/base/test_shared_methods.py +0 -353
- ccxt/test/base/test_status.py +0 -24
- ccxt/test/base/test_throttle.py +0 -126
- ccxt/test/base/test_ticker.py +0 -92
- ccxt/test/base/test_trade.py +0 -47
- ccxt/test/base/test_trading_fee.py +0 -26
- ccxt/test/base/test_transaction.py +0 -39
- ccxt/test/test_async.py +0 -1649
- ccxt/test/test_sync.py +0 -1648
- ccxt/wazirx.py +0 -1224
- ccxt_ir-4.3.46.0.3.dist-info/RECORD +0 -773
- /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info/licenses}/LICENSE.txt +0 -0
- {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/top_level.txt +0 -0
ccxt/pro/mexc.py
CHANGED
|
@@ -6,15 +6,17 @@
|
|
|
6
6
|
import ccxt.async_support
|
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp
|
|
8
8
|
import hashlib
|
|
9
|
-
from ccxt.base.types import Balances, Int, Order, OrderBook, Str, Ticker, Trade
|
|
9
|
+
from ccxt.base.types import Any, Balances, Int, Order, OrderBook, Str, Strings, Ticker, Tickers, Trade
|
|
10
10
|
from ccxt.async_support.base.ws.client import Client
|
|
11
11
|
from typing import List
|
|
12
12
|
from ccxt.base.errors import AuthenticationError
|
|
13
|
+
from ccxt.base.errors import ArgumentsRequired
|
|
14
|
+
from ccxt.base.errors import NotSupported
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
class mexc(ccxt.async_support.mexc):
|
|
16
18
|
|
|
17
|
-
def describe(self):
|
|
19
|
+
def describe(self) -> Any:
|
|
18
20
|
return self.deep_extend(super(mexc, self).describe(), {
|
|
19
21
|
'has': {
|
|
20
22
|
'ws': True,
|
|
@@ -33,19 +35,28 @@ class mexc(ccxt.async_support.mexc):
|
|
|
33
35
|
'watchOrderBook': True,
|
|
34
36
|
'watchOrders': True,
|
|
35
37
|
'watchTicker': True,
|
|
36
|
-
'watchTickers':
|
|
38
|
+
'watchTickers': True,
|
|
39
|
+
'watchBidsAsks': True,
|
|
37
40
|
'watchTrades': True,
|
|
41
|
+
'watchTradesForSymbols': False,
|
|
42
|
+
'unWatchTicker': True,
|
|
43
|
+
'unWatchTickers': True,
|
|
44
|
+
'unWatchBidsAsks': True,
|
|
45
|
+
'unWatchOHLCV': True,
|
|
46
|
+
'unWatchOrderBook': True,
|
|
47
|
+
'unWatchTrades': True,
|
|
38
48
|
},
|
|
39
49
|
'urls': {
|
|
40
50
|
'api': {
|
|
41
51
|
'ws': {
|
|
42
|
-
'spot': 'wss://wbs.mexc.com/ws',
|
|
52
|
+
'spot': 'wss://wbs-api.mexc.com/ws',
|
|
43
53
|
'swap': 'wss://contract.mexc.com/edge',
|
|
44
54
|
},
|
|
45
55
|
},
|
|
46
56
|
},
|
|
47
57
|
'options': {
|
|
48
58
|
'listenKeyRefreshRate': 1200000,
|
|
59
|
+
'decompressBinary': False,
|
|
49
60
|
# TODO add reset connection after #16754 is merged
|
|
50
61
|
'timeframes': {
|
|
51
62
|
'1m': 'Min1',
|
|
@@ -76,15 +87,21 @@ class mexc(ccxt.async_support.mexc):
|
|
|
76
87
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
|
77
88
|
"""
|
|
78
89
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
90
|
+
|
|
91
|
+
https://mexcdevelop.github.io/apidocs/spot_v3_en/#individual-symbol-book-ticker-streams
|
|
92
|
+
https://mexcdevelop.github.io/apidocs/contract_v1_en/#public-channels
|
|
93
|
+
https://mexcdevelop.github.io/apidocs/spot_v3_en/#miniticker
|
|
94
|
+
|
|
79
95
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
|
80
96
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
97
|
+
:param boolean [params.miniTicker]: set to True for using the miniTicker endpoint
|
|
81
98
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
82
99
|
"""
|
|
83
100
|
await self.load_markets()
|
|
84
101
|
market = self.market(symbol)
|
|
85
102
|
messageHash = 'ticker:' + market['symbol']
|
|
86
103
|
if market['spot']:
|
|
87
|
-
channel = 'spot@public.bookTicker.v3.api@' + market['id']
|
|
104
|
+
channel = 'spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id']
|
|
88
105
|
return await self.watch_spot_public(channel, messageHash, params)
|
|
89
106
|
else:
|
|
90
107
|
channel = 'sub.ticker'
|
|
@@ -94,6 +111,38 @@ class mexc(ccxt.async_support.mexc):
|
|
|
94
111
|
return await self.watch_swap_public(channel, messageHash, requestParams, params)
|
|
95
112
|
|
|
96
113
|
def handle_ticker(self, client: Client, message):
|
|
114
|
+
#
|
|
115
|
+
# swap
|
|
116
|
+
#
|
|
117
|
+
# {
|
|
118
|
+
# "symbol": "BTC_USDT",
|
|
119
|
+
# "data": {
|
|
120
|
+
# "symbol": "BTC_USDT",
|
|
121
|
+
# "lastPrice": 76376.2,
|
|
122
|
+
# "riseFallRate": -0.0006,
|
|
123
|
+
# "fairPrice": 76374.4,
|
|
124
|
+
# "indexPrice": 76385.8,
|
|
125
|
+
# "volume24": 962062810,
|
|
126
|
+
# "amount24": 7344207079.96768,
|
|
127
|
+
# "maxBidPrice": 84024.3,
|
|
128
|
+
# "minAskPrice": 68747.2,
|
|
129
|
+
# "lower24Price": 75620.2,
|
|
130
|
+
# "high24Price": 77210,
|
|
131
|
+
# "timestamp": 1731137509138,
|
|
132
|
+
# "bid1": 76376.2,
|
|
133
|
+
# "ask1": 76376.3,
|
|
134
|
+
# "holdVol": 95479623,
|
|
135
|
+
# "riseFallValue": -46.5,
|
|
136
|
+
# "fundingRate": 0.0001,
|
|
137
|
+
# "zone": "UTC+8",
|
|
138
|
+
# "riseFallRates": [-0.0006, 0.1008, 0.2262, 0.2628, 0.2439, 1.0564],
|
|
139
|
+
# "riseFallRatesOfTimezone": [0.0065, -0.0013, -0.0006]
|
|
140
|
+
# },
|
|
141
|
+
# "channel": "push.ticker",
|
|
142
|
+
# "ts": 1731137509138
|
|
143
|
+
# }
|
|
144
|
+
#
|
|
145
|
+
# spot
|
|
97
146
|
#
|
|
98
147
|
# {
|
|
99
148
|
# "c": "spot@public.bookTicker.v3.api@BTCUSDT",
|
|
@@ -107,9 +156,32 @@ class mexc(ccxt.async_support.mexc):
|
|
|
107
156
|
# "t": 1678643605721
|
|
108
157
|
# }
|
|
109
158
|
#
|
|
110
|
-
|
|
159
|
+
# spot miniTicker
|
|
160
|
+
#
|
|
161
|
+
# {
|
|
162
|
+
# "d": {
|
|
163
|
+
# "s": "BTCUSDT",
|
|
164
|
+
# "p": "76522",
|
|
165
|
+
# "r": "0.0012",
|
|
166
|
+
# "tr": "0.0012",
|
|
167
|
+
# "h": "77196.3",
|
|
168
|
+
# "l": "75630.77",
|
|
169
|
+
# "v": "584664223.92",
|
|
170
|
+
# "q": "7666.720258",
|
|
171
|
+
# "lastRT": "-1",
|
|
172
|
+
# "MT": "0",
|
|
173
|
+
# "NV": "--",
|
|
174
|
+
# "t": "1731135533126"
|
|
175
|
+
# },
|
|
176
|
+
# "c": "spot@public.miniTicker.v3.api@BTCUSDT@UTC+8",
|
|
177
|
+
# "t": 1731135533126,
|
|
178
|
+
# "s": "BTCUSDT"
|
|
179
|
+
# }
|
|
180
|
+
#
|
|
181
|
+
self.handle_bid_ask(client, message)
|
|
182
|
+
rawTicker = self.safe_dict_n(message, ['d', 'data', 'publicAggreBookTicker'])
|
|
111
183
|
marketId = self.safe_string_2(message, 's', 'symbol')
|
|
112
|
-
timestamp = self.
|
|
184
|
+
timestamp = self.safe_integer_2(message, 't', 'sendtime')
|
|
113
185
|
market = self.safe_market(marketId)
|
|
114
186
|
symbol = market['symbol']
|
|
115
187
|
ticker = None
|
|
@@ -123,45 +195,303 @@ class mexc(ccxt.async_support.mexc):
|
|
|
123
195
|
messageHash = 'ticker:' + symbol
|
|
124
196
|
client.resolve(ticker, messageHash)
|
|
125
197
|
|
|
126
|
-
def
|
|
198
|
+
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
|
199
|
+
"""
|
|
200
|
+
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
201
|
+
|
|
202
|
+
https://mexcdevelop.github.io/apidocs/spot_v3_en/#individual-symbol-book-ticker-streams
|
|
203
|
+
https://mexcdevelop.github.io/apidocs/contract_v1_en/#public-channels
|
|
204
|
+
https://mexcdevelop.github.io/apidocs/spot_v3_en/#minitickers
|
|
205
|
+
|
|
206
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
|
207
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
208
|
+
:param boolean [params.miniTicker]: set to True for using the miniTicker endpoint
|
|
209
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
210
|
+
"""
|
|
211
|
+
await self.load_markets()
|
|
212
|
+
symbols = self.market_symbols(symbols, None)
|
|
213
|
+
messageHashes = []
|
|
214
|
+
firstSymbol = self.safe_string(symbols, 0)
|
|
215
|
+
market = None
|
|
216
|
+
if firstSymbol is not None:
|
|
217
|
+
market = self.market(firstSymbol)
|
|
218
|
+
type = None
|
|
219
|
+
type, params = self.handle_market_type_and_params('watchTickers', market, params)
|
|
220
|
+
isSpot = (type == 'spot')
|
|
221
|
+
url = self.urls['api']['ws']['spot'] if (isSpot) else self.urls['api']['ws']['swap']
|
|
222
|
+
request: dict = {}
|
|
223
|
+
if isSpot:
|
|
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
|
|
251
|
+
else:
|
|
252
|
+
request['method'] = 'sub.tickers'
|
|
253
|
+
request['params'] = {}
|
|
254
|
+
messageHashes.append('ticker')
|
|
255
|
+
ticker = await self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
|
|
256
|
+
if isSpot and self.newUpdates:
|
|
257
|
+
result: dict = {}
|
|
258
|
+
result[ticker['symbol']] = ticker
|
|
259
|
+
return result
|
|
260
|
+
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
|
261
|
+
|
|
262
|
+
def handle_tickers(self, client: Client, message):
|
|
263
|
+
#
|
|
264
|
+
# swap
|
|
265
|
+
#
|
|
266
|
+
# {
|
|
267
|
+
# "channel": "push.tickers",
|
|
268
|
+
# "data": [
|
|
269
|
+
# {
|
|
270
|
+
# "symbol": "ETH_USDT",
|
|
271
|
+
# "lastPrice": 2324.5,
|
|
272
|
+
# "riseFallRate": 0.0356,
|
|
273
|
+
# "fairPrice": 2324.32,
|
|
274
|
+
# "indexPrice": 2325.44,
|
|
275
|
+
# "volume24": 25868309,
|
|
276
|
+
# "amount24": 591752573.9792,
|
|
277
|
+
# "maxBidPrice": 2557.98,
|
|
278
|
+
# "minAskPrice": 2092.89,
|
|
279
|
+
# "lower24Price": 2239.39,
|
|
280
|
+
# "high24Price": 2332.59,
|
|
281
|
+
# "timestamp": 1725872514111
|
|
282
|
+
# }
|
|
283
|
+
# ],
|
|
284
|
+
# "ts": 1725872514111
|
|
285
|
+
# }
|
|
127
286
|
#
|
|
128
287
|
# spot
|
|
288
|
+
#
|
|
129
289
|
# {
|
|
130
|
-
# "
|
|
131
|
-
# "
|
|
132
|
-
#
|
|
133
|
-
#
|
|
290
|
+
# "c": "spot@public.bookTicker.v3.api@BTCUSDT",
|
|
291
|
+
# "d": {
|
|
292
|
+
# "A": "4.70432",
|
|
293
|
+
# "B": "6.714863",
|
|
294
|
+
# "a": "20744.54",
|
|
295
|
+
# "b": "20744.17"
|
|
296
|
+
# },
|
|
297
|
+
# "s": "BTCUSDT",
|
|
298
|
+
# "t": 1678643605721
|
|
134
299
|
# }
|
|
135
300
|
#
|
|
301
|
+
# spot miniTicker
|
|
302
|
+
#
|
|
303
|
+
# {
|
|
304
|
+
# "d": {
|
|
305
|
+
# "s": "BTCUSDT",
|
|
306
|
+
# "p": "76522",
|
|
307
|
+
# "r": "0.0012",
|
|
308
|
+
# "tr": "0.0012",
|
|
309
|
+
# "h": "77196.3",
|
|
310
|
+
# "l": "75630.77",
|
|
311
|
+
# "v": "584664223.92",
|
|
312
|
+
# "q": "7666.720258",
|
|
313
|
+
# "lastRT": "-1",
|
|
314
|
+
# "MT": "0",
|
|
315
|
+
# "NV": "--",
|
|
316
|
+
# "t": "1731135533126"
|
|
317
|
+
# },
|
|
318
|
+
# "c": "spot@public.miniTicker.v3.api@BTCUSDT@UTC+8",
|
|
319
|
+
# "t": 1731135533126,
|
|
320
|
+
# "s": "BTCUSDT"
|
|
321
|
+
# }
|
|
322
|
+
#
|
|
323
|
+
data = self.safe_list_2(message, 'data', 'd')
|
|
324
|
+
channel = self.safe_string(message, 'c', '')
|
|
325
|
+
marketId = self.safe_string(message, 's')
|
|
326
|
+
market = self.safe_market(marketId)
|
|
327
|
+
channelStartsWithSpot = channel.startswith('spot')
|
|
328
|
+
marketIdIsUndefined = marketId is None
|
|
329
|
+
isSpot = channelStartsWithSpot if marketIdIsUndefined else market['spot']
|
|
330
|
+
spotPrefix = 'spot:'
|
|
331
|
+
messageHashPrefix = spotPrefix if isSpot else ''
|
|
332
|
+
topic = messageHashPrefix + 'ticker'
|
|
333
|
+
result = []
|
|
334
|
+
for i in range(0, len(data)):
|
|
335
|
+
entry = data[i]
|
|
336
|
+
ticker = None
|
|
337
|
+
if isSpot:
|
|
338
|
+
ticker = self.parse_ws_ticker(entry, market)
|
|
339
|
+
else:
|
|
340
|
+
ticker = self.parse_ticker(entry)
|
|
341
|
+
symbol = ticker['symbol']
|
|
342
|
+
self.tickers[symbol] = ticker
|
|
343
|
+
result.append(ticker)
|
|
344
|
+
messageHash = 'ticker:' + symbol
|
|
345
|
+
client.resolve(ticker, messageHash)
|
|
346
|
+
client.resolve(result, topic)
|
|
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
|
|
354
|
+
#
|
|
355
|
+
# spot
|
|
356
|
+
#
|
|
357
|
+
# {
|
|
358
|
+
# "A": "4.70432",
|
|
359
|
+
# "B": "6.714863",
|
|
360
|
+
# "a": "20744.54",
|
|
361
|
+
# "b": "20744.17"
|
|
362
|
+
# }
|
|
363
|
+
#
|
|
364
|
+
# spot miniTicker
|
|
365
|
+
#
|
|
366
|
+
# {
|
|
367
|
+
# "s": "BTCUSDT",
|
|
368
|
+
# "p": "76521",
|
|
369
|
+
# "r": "0.0012",
|
|
370
|
+
# "tr": "0.0012",
|
|
371
|
+
# "h": "77196.3",
|
|
372
|
+
# "l": "75630.77",
|
|
373
|
+
# "v": "584664223.92",
|
|
374
|
+
# "q": "7666.720258",
|
|
375
|
+
# "lastRT": "-1",
|
|
376
|
+
# "MT": "0",
|
|
377
|
+
# "NV": "--",
|
|
378
|
+
# "t": "1731135533126"
|
|
379
|
+
# }
|
|
380
|
+
#
|
|
381
|
+
marketId = self.safe_string(ticker, 's')
|
|
382
|
+
timestamp = self.safe_integer(ticker, 't')
|
|
383
|
+
price = self.safe_string(ticker, 'p')
|
|
136
384
|
return self.safe_ticker({
|
|
137
|
-
'
|
|
138
|
-
'
|
|
139
|
-
'
|
|
385
|
+
'info': ticker,
|
|
386
|
+
'symbol': self.safe_symbol(marketId, market),
|
|
387
|
+
'timestamp': timestamp,
|
|
388
|
+
'datetime': self.iso8601(timestamp),
|
|
140
389
|
'open': None,
|
|
141
|
-
'high':
|
|
142
|
-
'low':
|
|
143
|
-
'close':
|
|
144
|
-
'
|
|
145
|
-
'
|
|
146
|
-
'
|
|
147
|
-
'
|
|
390
|
+
'high': self.safe_number(ticker, 'h'),
|
|
391
|
+
'low': self.safe_number(ticker, 'l'),
|
|
392
|
+
'close': price,
|
|
393
|
+
'last': price,
|
|
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'),
|
|
148
398
|
'vwap': None,
|
|
149
399
|
'previousClose': None,
|
|
150
400
|
'change': None,
|
|
151
|
-
'percentage':
|
|
401
|
+
'percentage': self.safe_number(ticker, 'tr'),
|
|
152
402
|
'average': None,
|
|
153
|
-
'baseVolume':
|
|
154
|
-
'quoteVolume':
|
|
403
|
+
'baseVolume': self.safe_number(ticker, 'v'),
|
|
404
|
+
'quoteVolume': self.safe_number(ticker, 'q'),
|
|
405
|
+
}, market)
|
|
406
|
+
|
|
407
|
+
async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
|
|
408
|
+
"""
|
|
409
|
+
|
|
410
|
+
https://mexcdevelop.github.io/apidocs/spot_v3_en/#individual-symbol-book-ticker-streams
|
|
411
|
+
|
|
412
|
+
watches best bid & ask for symbols
|
|
413
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
|
414
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
415
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
416
|
+
"""
|
|
417
|
+
await self.load_markets()
|
|
418
|
+
symbols = self.market_symbols(symbols, None, True, False, True)
|
|
419
|
+
marketType = None
|
|
420
|
+
if symbols is None:
|
|
421
|
+
raise ArgumentsRequired(self.id + ' watchBidsAsks required symbols argument')
|
|
422
|
+
markets = self.markets_for_symbols(symbols)
|
|
423
|
+
marketType, params = self.handle_market_type_and_params('watchBidsAsks', markets[0], params)
|
|
424
|
+
isSpot = marketType == 'spot'
|
|
425
|
+
if not isSpot:
|
|
426
|
+
raise NotSupported(self.id + ' watchBidsAsks only support spot market')
|
|
427
|
+
messageHashes = []
|
|
428
|
+
topics = []
|
|
429
|
+
for i in range(0, len(symbols)):
|
|
430
|
+
if isSpot:
|
|
431
|
+
market = self.market(symbols[i])
|
|
432
|
+
topics.append('spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id'])
|
|
433
|
+
messageHashes.append('bidask:' + symbols[i])
|
|
434
|
+
url = self.urls['api']['ws']['spot']
|
|
435
|
+
request: dict = {
|
|
436
|
+
'method': 'SUBSCRIPTION',
|
|
437
|
+
'params': topics,
|
|
438
|
+
}
|
|
439
|
+
ticker = await self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
|
|
440
|
+
if self.newUpdates:
|
|
441
|
+
tickers: dict = {}
|
|
442
|
+
tickers[ticker['symbol']] = ticker
|
|
443
|
+
return tickers
|
|
444
|
+
return self.filter_by_array(self.bidsasks, 'symbol', symbols)
|
|
445
|
+
|
|
446
|
+
def handle_bid_ask(self, client: Client, message):
|
|
447
|
+
#
|
|
448
|
+
# {
|
|
449
|
+
# "c": "spot@public.bookTicker.v3.api@BTCUSDT",
|
|
450
|
+
# "d": {
|
|
451
|
+
# "A": "4.70432",
|
|
452
|
+
# "B": "6.714863",
|
|
453
|
+
# "a": "20744.54",
|
|
454
|
+
# "b": "20744.17"
|
|
455
|
+
# },
|
|
456
|
+
# "s": "BTCUSDT",
|
|
457
|
+
# "t": 1678643605721
|
|
458
|
+
# }
|
|
459
|
+
#
|
|
460
|
+
parsedTicker = self.parse_ws_bid_ask(message)
|
|
461
|
+
symbol = self.safe_string(parsedTicker, 'symbol')
|
|
462
|
+
if symbol is None:
|
|
463
|
+
return
|
|
464
|
+
self.bidsasks[symbol] = parsedTicker
|
|
465
|
+
messageHash = 'bidask:' + symbol
|
|
466
|
+
client.resolve(parsedTicker, messageHash)
|
|
467
|
+
|
|
468
|
+
def parse_ws_bid_ask(self, ticker, market=None):
|
|
469
|
+
data = self.safe_dict(ticker, 'd')
|
|
470
|
+
marketId = self.safe_string(ticker, 's')
|
|
471
|
+
market = self.safe_market(marketId, market)
|
|
472
|
+
symbol = self.safe_string(market, 'symbol')
|
|
473
|
+
timestamp = self.safe_integer(ticker, 't')
|
|
474
|
+
return self.safe_ticker({
|
|
475
|
+
'symbol': symbol,
|
|
476
|
+
'timestamp': timestamp,
|
|
477
|
+
'datetime': self.iso8601(timestamp),
|
|
478
|
+
'ask': self.safe_number(data, 'a'),
|
|
479
|
+
'askVolume': self.safe_number(data, 'A'),
|
|
480
|
+
'bid': self.safe_number(data, 'b'),
|
|
481
|
+
'bidVolume': self.safe_number(data, 'B'),
|
|
155
482
|
'info': ticker,
|
|
156
483
|
}, market)
|
|
157
484
|
|
|
158
485
|
async def watch_spot_public(self, channel, messageHash, params={}):
|
|
486
|
+
unsubscribed = self.safe_bool(params, 'unsubscribed', False)
|
|
487
|
+
params = self.omit(params, ['unsubscribed'])
|
|
159
488
|
url = self.urls['api']['ws']['spot']
|
|
489
|
+
method = 'UNSUBSCRIPTION' if (unsubscribed) else 'SUBSCRIPTION'
|
|
160
490
|
request: dict = {
|
|
161
|
-
'method':
|
|
491
|
+
'method': method,
|
|
162
492
|
'params': [channel],
|
|
163
493
|
}
|
|
164
|
-
return await self.watch(url, messageHash, self.extend(request, params),
|
|
494
|
+
return await self.watch(url, messageHash, self.extend(request, params), messageHash)
|
|
165
495
|
|
|
166
496
|
async def watch_spot_private(self, channel, messageHash, params={}):
|
|
167
497
|
self.check_required_credentials()
|
|
@@ -202,7 +532,9 @@ class mexc(ccxt.async_support.mexc):
|
|
|
202
532
|
|
|
203
533
|
async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
|
204
534
|
"""
|
|
205
|
-
|
|
535
|
+
|
|
536
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-market-streams#trade-streams
|
|
537
|
+
|
|
206
538
|
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
207
539
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
|
208
540
|
:param str timeframe: the length of time each candle represents
|
|
@@ -219,7 +551,7 @@ class mexc(ccxt.async_support.mexc):
|
|
|
219
551
|
messageHash = 'candles:' + symbol + ':' + timeframe
|
|
220
552
|
ohlcv = None
|
|
221
553
|
if market['spot']:
|
|
222
|
-
channel = 'spot@public.kline.v3.api@' + market['id'] + '@' + timeframeId
|
|
554
|
+
channel = 'spot@public.kline.v3.api.pb@' + market['id'] + '@' + timeframeId
|
|
223
555
|
ohlcv = await self.watch_spot_public(channel, messageHash, params)
|
|
224
556
|
else:
|
|
225
557
|
channel = 'sub.kline'
|
|
@@ -278,17 +610,45 @@ class mexc(ccxt.async_support.mexc):
|
|
|
278
610
|
# "symbol": "BTC_USDT",
|
|
279
611
|
# "ts": 1651230713067
|
|
280
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
|
+
# }
|
|
281
631
|
#
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
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)
|
|
290
651
|
messageHash = 'candles:' + symbol + ':' + timeframe
|
|
291
|
-
parsed = self.parse_ws_ohlcv(rawOhlcv, market)
|
|
292
652
|
self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
|
|
293
653
|
stored = self.safe_value(self.ohlcvs[symbol], timeframe)
|
|
294
654
|
if stored is None:
|
|
@@ -330,23 +690,38 @@ class mexc(ccxt.async_support.mexc):
|
|
|
330
690
|
# "rh": 27301.8,
|
|
331
691
|
# "rl": 27301.8
|
|
332
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"
|
|
333
704
|
#
|
|
334
705
|
return [
|
|
335
|
-
self.
|
|
336
|
-
self.
|
|
337
|
-
self.
|
|
338
|
-
self.
|
|
339
|
-
self.
|
|
340
|
-
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'),
|
|
341
712
|
]
|
|
342
713
|
|
|
343
714
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
|
344
715
|
"""
|
|
345
|
-
|
|
716
|
+
|
|
717
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-market-streams#trade-streams
|
|
718
|
+
https://mexcdevelop.github.io/apidocs/contract_v1_en/#public-channels
|
|
719
|
+
|
|
346
720
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
|
347
721
|
:param str symbol: unified symbol of the market to fetch the order book for
|
|
348
722
|
:param int [limit]: the maximum amount of order book entries to return
|
|
349
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
|
|
350
725
|
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
|
351
726
|
"""
|
|
352
727
|
await self.load_markets()
|
|
@@ -355,7 +730,9 @@ class mexc(ccxt.async_support.mexc):
|
|
|
355
730
|
messageHash = 'orderbook:' + symbol
|
|
356
731
|
orderbook = None
|
|
357
732
|
if market['spot']:
|
|
358
|
-
|
|
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']
|
|
359
736
|
orderbook = await self.watch_spot_public(channel, messageHash, params)
|
|
360
737
|
else:
|
|
361
738
|
channel = 'sub.depth'
|
|
@@ -379,12 +756,12 @@ class mexc(ccxt.async_support.mexc):
|
|
|
379
756
|
# return the first index of the cache that can be applied to the orderbook or -1 if not possible
|
|
380
757
|
nonce = self.safe_integer(orderbook, 'nonce')
|
|
381
758
|
firstDelta = self.safe_value(cache, 0)
|
|
382
|
-
firstDeltaNonce = self.
|
|
759
|
+
firstDeltaNonce = self.safe_integer_n(firstDelta, ['r', 'version', 'fromVersion'])
|
|
383
760
|
if nonce < firstDeltaNonce - 1:
|
|
384
761
|
return -1
|
|
385
762
|
for i in range(0, len(cache)):
|
|
386
763
|
delta = cache[i]
|
|
387
|
-
deltaNonce = self.
|
|
764
|
+
deltaNonce = self.safe_integer_n(delta, ['r', 'version', 'fromVersion'])
|
|
388
765
|
if deltaNonce >= nonce:
|
|
389
766
|
return i
|
|
390
767
|
return len(cache)
|
|
@@ -432,18 +809,38 @@ class mexc(ccxt.async_support.mexc):
|
|
|
432
809
|
# "symbol":"BTC_USDT",
|
|
433
810
|
# "ts":1651239652372
|
|
434
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
|
+
# }
|
|
435
835
|
#
|
|
436
|
-
data = self.
|
|
836
|
+
data = self.safe_dict_n(message, ['d', 'data', 'publicAggreDepths'])
|
|
437
837
|
marketId = self.safe_string_2(message, 's', 'symbol')
|
|
438
838
|
symbol = self.safe_symbol(marketId)
|
|
439
839
|
messageHash = 'orderbook:' + symbol
|
|
440
840
|
subscription = self.safe_value(client.subscriptions, messageHash)
|
|
441
841
|
limit = self.safe_integer(subscription, 'limit')
|
|
442
|
-
if
|
|
443
|
-
|
|
444
|
-
# once we have received the first delta and initialized the orderbook
|
|
445
|
-
client.subscriptions[messageHash] = 1
|
|
446
|
-
self.orderbooks[symbol] = self.counted_order_book({})
|
|
842
|
+
if not (symbol in self.orderbooks):
|
|
843
|
+
self.orderbooks[symbol] = self.order_book()
|
|
447
844
|
storedOrderBook = self.orderbooks[symbol]
|
|
448
845
|
nonce = self.safe_integer(storedOrderBook, 'nonce')
|
|
449
846
|
if nonce is None:
|
|
@@ -455,7 +852,7 @@ class mexc(ccxt.async_support.mexc):
|
|
|
455
852
|
return
|
|
456
853
|
try:
|
|
457
854
|
self.handle_delta(storedOrderBook, data)
|
|
458
|
-
timestamp = self.
|
|
855
|
+
timestamp = self.safe_integer_n(message, ['t', 'ts', 'sendTime'])
|
|
459
856
|
storedOrderBook['timestamp'] = timestamp
|
|
460
857
|
storedOrderBook['datetime'] = self.iso8601(timestamp)
|
|
461
858
|
except Exception as e:
|
|
@@ -475,13 +872,13 @@ class mexc(ccxt.async_support.mexc):
|
|
|
475
872
|
if isinstance(bidask, list):
|
|
476
873
|
bookside.storeArray(bidask)
|
|
477
874
|
else:
|
|
478
|
-
price = self.
|
|
479
|
-
amount = self.
|
|
875
|
+
price = self.safe_float_2(bidask, 'p', 'price')
|
|
876
|
+
amount = self.safe_float_2(bidask, 'v', 'quantity')
|
|
480
877
|
bookside.store(price, amount)
|
|
481
878
|
|
|
482
879
|
def handle_delta(self, orderbook, delta):
|
|
483
880
|
existingNonce = self.safe_integer(orderbook, 'nonce')
|
|
484
|
-
deltaNonce = self.
|
|
881
|
+
deltaNonce = self.safe_integer_n(delta, ['r', 'version', 'fromVersion'])
|
|
485
882
|
if deltaNonce < existingNonce:
|
|
486
883
|
# even when doing < comparison, self happens: https://app.travis-ci.com/github/ccxt/ccxt/builds/269234741#L1809
|
|
487
884
|
# so, we just skip old updates
|
|
@@ -496,7 +893,10 @@ class mexc(ccxt.async_support.mexc):
|
|
|
496
893
|
|
|
497
894
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
|
498
895
|
"""
|
|
499
|
-
|
|
896
|
+
|
|
897
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-market-streams#trade-streams
|
|
898
|
+
https://mexcdevelop.github.io/apidocs/contract_v1_en/#public-channels
|
|
899
|
+
|
|
500
900
|
get the list of most recent trades for a particular symbol
|
|
501
901
|
:param str symbol: unified symbol of the market to fetch trades for
|
|
502
902
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
|
@@ -510,7 +910,7 @@ class mexc(ccxt.async_support.mexc):
|
|
|
510
910
|
messageHash = 'trades:' + symbol
|
|
511
911
|
trades = None
|
|
512
912
|
if market['spot']:
|
|
513
|
-
channel = 'spot@public.deals.v3.api@' + market['id']
|
|
913
|
+
channel = 'spot@public.aggre.deals.v3.api.pb@100ms@' + market['id']
|
|
514
914
|
trades = await self.watch_spot_public(channel, messageHash, params)
|
|
515
915
|
else:
|
|
516
916
|
channel = 'sub.deal'
|
|
@@ -523,6 +923,23 @@ class mexc(ccxt.async_support.mexc):
|
|
|
523
923
|
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
|
524
924
|
|
|
525
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
|
+
# }
|
|
526
943
|
#
|
|
527
944
|
# {
|
|
528
945
|
# "c": "spot@public.deals.v3.api@BTCUSDT",
|
|
@@ -563,8 +980,8 @@ class mexc(ccxt.async_support.mexc):
|
|
|
563
980
|
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
|
564
981
|
stored = ArrayCache(limit)
|
|
565
982
|
self.trades[symbol] = stored
|
|
566
|
-
d = self.
|
|
567
|
-
trades = self.
|
|
983
|
+
d = self.safe_dict_n(message, ['d', 'data', 'publicAggreDeals'])
|
|
984
|
+
trades = self.safe_list_2(d, 'deals', 'dealsList', [d])
|
|
568
985
|
for j in range(0, len(trades)):
|
|
569
986
|
parsedTrade = None
|
|
570
987
|
if market['spot']:
|
|
@@ -576,13 +993,16 @@ class mexc(ccxt.async_support.mexc):
|
|
|
576
993
|
|
|
577
994
|
async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
|
578
995
|
"""
|
|
579
|
-
|
|
996
|
+
|
|
997
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-user-data-streams#spot-account-deals
|
|
998
|
+
https://mexcdevelop.github.io/apidocs/contract_v1_en/#private-channels
|
|
999
|
+
|
|
580
1000
|
watches information on multiple trades made by the user
|
|
581
1001
|
:param str symbol: unified market symbol of the market trades were made in
|
|
582
1002
|
:param int [since]: the earliest time in ms to fetch trades for
|
|
583
1003
|
:param int [limit]: the maximum number of trade structures to retrieve
|
|
584
1004
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
585
|
-
:returns dict[]: a list of
|
|
1005
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
|
586
1006
|
"""
|
|
587
1007
|
await self.load_markets()
|
|
588
1008
|
messageHash = 'myTrades'
|
|
@@ -595,7 +1015,7 @@ class mexc(ccxt.async_support.mexc):
|
|
|
595
1015
|
type, params = self.handle_market_type_and_params('watchMyTrades', market, params)
|
|
596
1016
|
trades = None
|
|
597
1017
|
if type == 'spot':
|
|
598
|
-
channel = 'spot@private.deals.v3.api'
|
|
1018
|
+
channel = 'spot@private.deals.v3.api.pb'
|
|
599
1019
|
trades = await self.watch_spot_private(channel, messageHash, params)
|
|
600
1020
|
else:
|
|
601
1021
|
trades = await self.watch_swap_private(messageHash, params)
|
|
@@ -621,11 +1041,27 @@ class mexc(ccxt.async_support.mexc):
|
|
|
621
1041
|
# "s": "BTCUSDT",
|
|
622
1042
|
# "t": 1678670940700
|
|
623
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
|
+
# }
|
|
624
1060
|
#
|
|
625
1061
|
messageHash = 'myTrades'
|
|
626
|
-
data = self.
|
|
1062
|
+
data = self.safe_dict_n(message, ['d', 'data', 'privateDeals'])
|
|
627
1063
|
futuresMarketId = self.safe_string(data, 'symbol')
|
|
628
|
-
marketId = self.
|
|
1064
|
+
marketId = self.safe_string_2(message, 's', 'symbol', futuresMarketId)
|
|
629
1065
|
market = self.safe_market(marketId)
|
|
630
1066
|
symbol = market['symbol']
|
|
631
1067
|
trade = None
|
|
@@ -645,7 +1081,7 @@ class mexc(ccxt.async_support.mexc):
|
|
|
645
1081
|
|
|
646
1082
|
def parse_ws_trade(self, trade, market=None):
|
|
647
1083
|
#
|
|
648
|
-
# public trade
|
|
1084
|
+
# public trade(protobuf)
|
|
649
1085
|
# {
|
|
650
1086
|
# "p": "20382.70",
|
|
651
1087
|
# "v": "0.043800",
|
|
@@ -665,7 +1101,6 @@ class mexc(ccxt.async_support.mexc):
|
|
|
665
1101
|
# "v": "5"
|
|
666
1102
|
# }
|
|
667
1103
|
#
|
|
668
|
-
#
|
|
669
1104
|
# d: {
|
|
670
1105
|
# p: '1.0005',
|
|
671
1106
|
# v: '5.71',
|
|
@@ -680,22 +1115,36 @@ class mexc(ccxt.async_support.mexc):
|
|
|
680
1115
|
# n: '0.005712855',
|
|
681
1116
|
# N: 'USDT'
|
|
682
1117
|
# }
|
|
683
|
-
|
|
684
|
-
|
|
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')
|
|
685
1134
|
if timestamp is None:
|
|
686
1135
|
timestamp = self.safe_integer(trade, 't')
|
|
687
1136
|
tradeId = None
|
|
688
|
-
priceString = self.
|
|
689
|
-
amountString = self.
|
|
690
|
-
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')
|
|
691
1140
|
side = 'buy' if (rawSide == '1') else 'sell'
|
|
692
1141
|
isMaker = self.safe_integer(trade, 'm')
|
|
693
|
-
feeAmount = self.
|
|
694
|
-
feeCurrencyId = self.
|
|
1142
|
+
feeAmount = self.safe_string_2(trade, 'n', 'feeAmount')
|
|
1143
|
+
feeCurrencyId = self.safe_string_2(trade, 'N', 'feeCurrency')
|
|
695
1144
|
return self.safe_trade({
|
|
696
1145
|
'info': trade,
|
|
697
1146
|
'id': tradeId,
|
|
698
|
-
'order': self.
|
|
1147
|
+
'order': self.safe_string_2(trade, 'i', 'orderId'),
|
|
699
1148
|
'timestamp': timestamp,
|
|
700
1149
|
'datetime': self.iso8601(timestamp),
|
|
701
1150
|
'symbol': self.safe_symbol(None, market),
|
|
@@ -704,7 +1153,7 @@ class mexc(ccxt.async_support.mexc):
|
|
|
704
1153
|
'takerOrMaker': 'maker' if (isMaker) else 'taker',
|
|
705
1154
|
'price': priceString,
|
|
706
1155
|
'amount': amountString,
|
|
707
|
-
'cost':
|
|
1156
|
+
'cost': self.safe_string(trade, 'amount'),
|
|
708
1157
|
'fee': {
|
|
709
1158
|
'cost': feeAmount,
|
|
710
1159
|
'currency': self.safe_currency_code(feeCurrencyId),
|
|
@@ -713,8 +1162,10 @@ class mexc(ccxt.async_support.mexc):
|
|
|
713
1162
|
|
|
714
1163
|
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
|
715
1164
|
"""
|
|
716
|
-
|
|
717
|
-
|
|
1165
|
+
|
|
1166
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-user-data-streams#spot-account-orders
|
|
1167
|
+
https://mexcdevelop.github.io/apidocs/spot_v3_en/#margin-account-orders
|
|
1168
|
+
|
|
718
1169
|
watches information on multiple orders made by the user
|
|
719
1170
|
:param str symbol: unified market symbol of the market orders were made in
|
|
720
1171
|
:param int [since]: the earliest time in ms to fetch orders for
|
|
@@ -724,7 +1175,6 @@ class mexc(ccxt.async_support.mexc):
|
|
|
724
1175
|
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
725
1176
|
"""
|
|
726
1177
|
await self.load_markets()
|
|
727
|
-
params = self.omit(params, 'type')
|
|
728
1178
|
messageHash = 'orders'
|
|
729
1179
|
market = None
|
|
730
1180
|
if symbol is not None:
|
|
@@ -735,7 +1185,7 @@ class mexc(ccxt.async_support.mexc):
|
|
|
735
1185
|
type, params = self.handle_market_type_and_params('watchOrders', market, params)
|
|
736
1186
|
orders = None
|
|
737
1187
|
if type == 'spot':
|
|
738
|
-
channel =
|
|
1188
|
+
channel = 'spot@private.orders.v3.api.pb'
|
|
739
1189
|
orders = await self.watch_spot_private(channel, messageHash, params)
|
|
740
1190
|
else:
|
|
741
1191
|
orders = await self.watch_swap_private(messageHash, params)
|
|
@@ -808,11 +1258,18 @@ class mexc(ccxt.async_support.mexc):
|
|
|
808
1258
|
# "s": "MXUSDT",
|
|
809
1259
|
# "t":1661938138193
|
|
810
1260
|
# }
|
|
1261
|
+
# protobuf
|
|
1262
|
+
# {
|
|
1263
|
+
# channel: "spot@private.orders.v3.api.pb",
|
|
1264
|
+
# symbol: "MXUSDT",
|
|
1265
|
+
# sendTime: 1736417034281,
|
|
1266
|
+
# privateOrders {}
|
|
1267
|
+
# }
|
|
811
1268
|
#
|
|
812
1269
|
messageHash = 'orders'
|
|
813
|
-
data = self.
|
|
1270
|
+
data = self.safe_dict_n(message, ['d', 'data', 'privateOrders'])
|
|
814
1271
|
futuresMarketId = self.safe_string(data, 'symbol')
|
|
815
|
-
marketId = self.
|
|
1272
|
+
marketId = self.safe_string_2(message, 's', 'symbol', futuresMarketId)
|
|
816
1273
|
market = self.safe_market(marketId)
|
|
817
1274
|
symbol = market['symbol']
|
|
818
1275
|
parsed = None
|
|
@@ -880,11 +1337,28 @@ class mexc(ccxt.async_support.mexc):
|
|
|
880
1337
|
# "s":1,
|
|
881
1338
|
# "i":"e03a5c7441e44ed899466a7140b71391",
|
|
882
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
|
+
# }
|
|
883
1357
|
#
|
|
884
|
-
timestamp = self.safe_integer(order, '
|
|
885
|
-
side = self.safe_string(order, '
|
|
886
|
-
status = self.safe_string(order, '
|
|
887
|
-
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')
|
|
888
1362
|
fee = None
|
|
889
1363
|
feeCurrency = self.safe_string(order, 'N')
|
|
890
1364
|
if feeCurrency is not None:
|
|
@@ -893,8 +1367,8 @@ class mexc(ccxt.async_support.mexc):
|
|
|
893
1367
|
'cost': None,
|
|
894
1368
|
}
|
|
895
1369
|
return self.safe_order({
|
|
896
|
-
'id': self.safe_string(order, '
|
|
897
|
-
'clientOrderId': self.safe_string(order, '
|
|
1370
|
+
'id': self.safe_string(order, 'id'),
|
|
1371
|
+
'clientOrderId': self.safe_string(order, 'clientId'),
|
|
898
1372
|
'timestamp': timestamp,
|
|
899
1373
|
'datetime': self.iso8601(timestamp),
|
|
900
1374
|
'lastTradeTimestamp': None,
|
|
@@ -903,14 +1377,14 @@ class mexc(ccxt.async_support.mexc):
|
|
|
903
1377
|
'type': self.parse_ws_order_type(type),
|
|
904
1378
|
'timeInForce': self.parse_ws_time_in_force(type),
|
|
905
1379
|
'side': 'buy' if (side == '1') else 'sell',
|
|
906
|
-
'price': self.safe_string(order, '
|
|
1380
|
+
'price': self.safe_string(order, 'price'),
|
|
907
1381
|
'stopPrice': None,
|
|
908
|
-
'triggerPrice':
|
|
909
|
-
'average': self.safe_string(order, '
|
|
910
|
-
'amount': self.safe_string(order, '
|
|
911
|
-
'cost': self.safe_string(order, '
|
|
912
|
-
'filled': self.safe_string(order, '
|
|
913
|
-
'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'),
|
|
914
1388
|
'fee': fee,
|
|
915
1389
|
'trades': None,
|
|
916
1390
|
'info': order,
|
|
@@ -922,8 +1396,7 @@ class mexc(ccxt.async_support.mexc):
|
|
|
922
1396
|
'2': 'closed', # filled
|
|
923
1397
|
'3': 'open', # partially filled
|
|
924
1398
|
'4': 'canceled', # canceled
|
|
925
|
-
'5': '
|
|
926
|
-
'6': 'closed', # partially filled then canceled
|
|
1399
|
+
'5': 'closed', # partially filled then canceled
|
|
927
1400
|
'NEW': 'open',
|
|
928
1401
|
'CANCELED': 'canceled',
|
|
929
1402
|
'EXECUTED': 'closed',
|
|
@@ -934,7 +1407,7 @@ class mexc(ccxt.async_support.mexc):
|
|
|
934
1407
|
def parse_ws_order_type(self, type):
|
|
935
1408
|
types: dict = {
|
|
936
1409
|
'1': 'limit', # LIMIT_ORDER
|
|
937
|
-
'2':
|
|
1410
|
+
'2': 'limit', # POST_ONLY
|
|
938
1411
|
'3': None, # IMMEDIATE_OR_CANCEL
|
|
939
1412
|
'4': None, # FILL_OR_KILL
|
|
940
1413
|
'5': 'market', # MARKET_ORDER
|
|
@@ -955,7 +1428,9 @@ class mexc(ccxt.async_support.mexc):
|
|
|
955
1428
|
|
|
956
1429
|
async def watch_balance(self, params={}) -> Balances:
|
|
957
1430
|
"""
|
|
958
|
-
|
|
1431
|
+
|
|
1432
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-user-data-streams#spot-account-update
|
|
1433
|
+
|
|
959
1434
|
watch balance and get the amount of funds available for trading or funds locked in orders
|
|
960
1435
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
961
1436
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
|
@@ -965,7 +1440,7 @@ class mexc(ccxt.async_support.mexc):
|
|
|
965
1440
|
type, params = self.handle_market_type_and_params('watchBalance', None, params)
|
|
966
1441
|
messageHash = 'balance:' + type
|
|
967
1442
|
if type == 'spot':
|
|
968
|
-
channel = 'spot@private.account.v3.api'
|
|
1443
|
+
channel = 'spot@private.account.v3.api.pb'
|
|
969
1444
|
return await self.watch_spot_private(channel, messageHash, params)
|
|
970
1445
|
else:
|
|
971
1446
|
return await self.watch_swap_private(messageHash, params)
|
|
@@ -1002,26 +1477,271 @@ class mexc(ccxt.async_support.mexc):
|
|
|
1002
1477
|
# "ts": 1680059188190
|
|
1003
1478
|
# }
|
|
1004
1479
|
#
|
|
1005
|
-
c = self.
|
|
1480
|
+
c = self.safe_string_2(message, 'c', 'channel')
|
|
1006
1481
|
type = 'swap' if (c is None) else 'spot'
|
|
1007
1482
|
messageHash = 'balance:' + type
|
|
1008
|
-
data = self.
|
|
1483
|
+
data = self.safe_dict_n(message, ['d', 'data', 'privateAccount'])
|
|
1009
1484
|
futuresTimestamp = self.safe_integer(message, 'ts')
|
|
1010
|
-
timestamp = self.
|
|
1485
|
+
timestamp = self.safe_integer_2(data, 'c', 'time', futuresTimestamp)
|
|
1011
1486
|
if not (type in self.balance):
|
|
1012
1487
|
self.balance[type] = {}
|
|
1013
1488
|
self.balance[type]['info'] = data
|
|
1014
1489
|
self.balance[type]['timestamp'] = timestamp
|
|
1015
1490
|
self.balance[type]['datetime'] = self.iso8601(timestamp)
|
|
1016
|
-
currencyId = self.
|
|
1491
|
+
currencyId = self.safe_string_n(data, ['a', 'currency', 'vcoinName'])
|
|
1017
1492
|
code = self.safe_currency_code(currencyId)
|
|
1018
1493
|
account = self.account()
|
|
1019
|
-
account['
|
|
1020
|
-
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'])
|
|
1021
1496
|
self.balance[type][code] = account
|
|
1022
1497
|
self.balance[type] = self.safe_balance(self.balance[type])
|
|
1023
1498
|
client.resolve(self.balance[type], messageHash)
|
|
1024
1499
|
|
|
1500
|
+
async def un_watch_ticker(self, symbol: str, params={}) -> Any:
|
|
1501
|
+
"""
|
|
1502
|
+
unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
1503
|
+
:param str symbol: unified symbol of the market to fetch the ticker for
|
|
1504
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1505
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
1506
|
+
"""
|
|
1507
|
+
await self.load_markets()
|
|
1508
|
+
market = self.market(symbol)
|
|
1509
|
+
messageHash = 'unsubscribe:ticker:' + market['symbol']
|
|
1510
|
+
url = None
|
|
1511
|
+
channel = None
|
|
1512
|
+
if market['spot']:
|
|
1513
|
+
channel = 'spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id']
|
|
1514
|
+
url = self.urls['api']['ws']['spot']
|
|
1515
|
+
params['unsubscribed'] = True
|
|
1516
|
+
self.watch_spot_public(channel, messageHash, params)
|
|
1517
|
+
else:
|
|
1518
|
+
channel = 'unsub.ticker'
|
|
1519
|
+
requestParams: dict = {
|
|
1520
|
+
'symbol': market['id'],
|
|
1521
|
+
}
|
|
1522
|
+
url = self.urls['api']['ws']['swap']
|
|
1523
|
+
self.watch_swap_public(channel, messageHash, requestParams, params)
|
|
1524
|
+
client = self.client(url)
|
|
1525
|
+
self.handle_unsubscriptions(client, [messageHash])
|
|
1526
|
+
return None
|
|
1527
|
+
|
|
1528
|
+
async def un_watch_tickers(self, symbols: Strings = None, params={}) -> Any:
|
|
1529
|
+
"""
|
|
1530
|
+
unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
1531
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
|
1532
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1533
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
1534
|
+
"""
|
|
1535
|
+
await self.load_markets()
|
|
1536
|
+
symbols = self.market_symbols(symbols, None)
|
|
1537
|
+
messageHashes = []
|
|
1538
|
+
firstSymbol = self.safe_string(symbols, 0)
|
|
1539
|
+
market = None
|
|
1540
|
+
if firstSymbol is not None:
|
|
1541
|
+
market = self.market(firstSymbol)
|
|
1542
|
+
type = None
|
|
1543
|
+
type, params = self.handle_market_type_and_params('watchTickers', market, params)
|
|
1544
|
+
isSpot = (type == 'spot')
|
|
1545
|
+
url = self.urls['api']['ws']['spot'] if (isSpot) else self.urls['api']['ws']['swap']
|
|
1546
|
+
request: dict = {}
|
|
1547
|
+
if isSpot:
|
|
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
|
|
1575
|
+
else:
|
|
1576
|
+
request['method'] = 'unsub.tickers'
|
|
1577
|
+
request['params'] = {}
|
|
1578
|
+
messageHashes.append('unsubscribe:ticker')
|
|
1579
|
+
client = self.client(url)
|
|
1580
|
+
self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
|
|
1581
|
+
self.handle_unsubscriptions(client, messageHashes)
|
|
1582
|
+
return None
|
|
1583
|
+
|
|
1584
|
+
async def un_watch_bids_asks(self, symbols: Strings = None, params={}) -> Any:
|
|
1585
|
+
"""
|
|
1586
|
+
unWatches best bid & ask for symbols
|
|
1587
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
|
1588
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1589
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
1590
|
+
"""
|
|
1591
|
+
await self.load_markets()
|
|
1592
|
+
symbols = self.market_symbols(symbols, None, True, False, True)
|
|
1593
|
+
marketType = None
|
|
1594
|
+
if symbols is None:
|
|
1595
|
+
raise ArgumentsRequired(self.id + ' watchBidsAsks required symbols argument')
|
|
1596
|
+
markets = self.markets_for_symbols(symbols)
|
|
1597
|
+
marketType, params = self.handle_market_type_and_params('watchBidsAsks', markets[0], params)
|
|
1598
|
+
isSpot = marketType == 'spot'
|
|
1599
|
+
if not isSpot:
|
|
1600
|
+
raise NotSupported(self.id + ' watchBidsAsks only support spot market')
|
|
1601
|
+
messageHashes = []
|
|
1602
|
+
topics = []
|
|
1603
|
+
for i in range(0, len(symbols)):
|
|
1604
|
+
if isSpot:
|
|
1605
|
+
market = self.market(symbols[i])
|
|
1606
|
+
topics.append('spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id'])
|
|
1607
|
+
messageHashes.append('unsubscribe:bidask:' + symbols[i])
|
|
1608
|
+
url = self.urls['api']['ws']['spot']
|
|
1609
|
+
request: dict = {
|
|
1610
|
+
'method': 'UNSUBSCRIPTION',
|
|
1611
|
+
'params': topics,
|
|
1612
|
+
}
|
|
1613
|
+
client = self.client(url)
|
|
1614
|
+
self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
|
|
1615
|
+
self.handle_unsubscriptions(client, messageHashes)
|
|
1616
|
+
return None
|
|
1617
|
+
|
|
1618
|
+
async def un_watch_ohlcv(self, symbol: str, timeframe='1m', params={}) -> Any:
|
|
1619
|
+
"""
|
|
1620
|
+
unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1621
|
+
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
|
1622
|
+
:param str timeframe: the length of time each candle represents
|
|
1623
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1624
|
+
:param dict [params.timezone]: if provided, kline intervals are interpreted in that timezone instead of UTC, example '+08:00'
|
|
1625
|
+
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
|
1626
|
+
"""
|
|
1627
|
+
await self.load_markets()
|
|
1628
|
+
market = self.market(symbol)
|
|
1629
|
+
symbol = market['symbol']
|
|
1630
|
+
timeframes = self.safe_value(self.options, 'timeframes', {})
|
|
1631
|
+
timeframeId = self.safe_string(timeframes, timeframe)
|
|
1632
|
+
messageHash = 'unsubscribe:candles:' + symbol + ':' + timeframe
|
|
1633
|
+
url = None
|
|
1634
|
+
if market['spot']:
|
|
1635
|
+
url = self.urls['api']['ws']['spot']
|
|
1636
|
+
channel = 'spot@public.kline.v3.api.pb@' + market['id'] + '@' + timeframeId
|
|
1637
|
+
params['unsubscribed'] = True
|
|
1638
|
+
self.watch_spot_public(channel, messageHash, params)
|
|
1639
|
+
else:
|
|
1640
|
+
url = self.urls['api']['ws']['swap']
|
|
1641
|
+
channel = 'unsub.kline'
|
|
1642
|
+
requestParams: dict = {
|
|
1643
|
+
'symbol': market['id'],
|
|
1644
|
+
'interval': timeframeId,
|
|
1645
|
+
}
|
|
1646
|
+
self.watch_swap_public(channel, messageHash, requestParams, params)
|
|
1647
|
+
client = self.client(url)
|
|
1648
|
+
self.handle_unsubscriptions(client, [messageHash])
|
|
1649
|
+
return None
|
|
1650
|
+
|
|
1651
|
+
async def un_watch_order_book(self, symbol: str, params={}) -> Any:
|
|
1652
|
+
"""
|
|
1653
|
+
unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
|
1654
|
+
:param str symbol: unified array of symbols
|
|
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
|
|
1657
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
|
1658
|
+
"""
|
|
1659
|
+
await self.load_markets()
|
|
1660
|
+
market = self.market(symbol)
|
|
1661
|
+
symbol = market['symbol']
|
|
1662
|
+
messageHash = 'unsubscribe:orderbook:' + symbol
|
|
1663
|
+
url = None
|
|
1664
|
+
if market['spot']:
|
|
1665
|
+
url = self.urls['api']['ws']['spot']
|
|
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']
|
|
1669
|
+
params['unsubscribed'] = True
|
|
1670
|
+
self.watch_spot_public(channel, messageHash, params)
|
|
1671
|
+
else:
|
|
1672
|
+
url = self.urls['api']['ws']['swap']
|
|
1673
|
+
channel = 'unsub.depth'
|
|
1674
|
+
requestParams: dict = {
|
|
1675
|
+
'symbol': market['id'],
|
|
1676
|
+
}
|
|
1677
|
+
self.watch_swap_public(channel, messageHash, requestParams, params)
|
|
1678
|
+
client = self.client(url)
|
|
1679
|
+
self.handle_unsubscriptions(client, [messageHash])
|
|
1680
|
+
return None
|
|
1681
|
+
|
|
1682
|
+
async def un_watch_trades(self, symbol: str, params={}) -> Any:
|
|
1683
|
+
"""
|
|
1684
|
+
unsubscribes from the trades channel
|
|
1685
|
+
:param str symbol: unified symbol of the market to fetch trades for
|
|
1686
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1687
|
+
:param str [params.name]: the name of the method to call, 'trade' or 'aggTrade', default is 'trade'
|
|
1688
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
|
1689
|
+
"""
|
|
1690
|
+
await self.load_markets()
|
|
1691
|
+
market = self.market(symbol)
|
|
1692
|
+
symbol = market['symbol']
|
|
1693
|
+
messageHash = 'unsubscribe:trades:' + symbol
|
|
1694
|
+
url = None
|
|
1695
|
+
if market['spot']:
|
|
1696
|
+
url = self.urls['api']['ws']['spot']
|
|
1697
|
+
channel = 'spot@public.aggre.deals.v3.api.pb@100ms@' + market['id']
|
|
1698
|
+
params['unsubscribed'] = True
|
|
1699
|
+
self.watch_spot_public(channel, messageHash, params)
|
|
1700
|
+
else:
|
|
1701
|
+
url = self.urls['api']['ws']['swap']
|
|
1702
|
+
channel = 'unsub.deal'
|
|
1703
|
+
requestParams: dict = {
|
|
1704
|
+
'symbol': market['id'],
|
|
1705
|
+
}
|
|
1706
|
+
self.watch_swap_public(channel, messageHash, requestParams, params)
|
|
1707
|
+
client = self.client(url)
|
|
1708
|
+
self.handle_unsubscriptions(client, [messageHash])
|
|
1709
|
+
return None
|
|
1710
|
+
|
|
1711
|
+
def handle_unsubscriptions(self, client: Client, messageHashes: List[str]):
|
|
1712
|
+
for i in range(0, len(messageHashes)):
|
|
1713
|
+
messageHash = messageHashes[i]
|
|
1714
|
+
subMessageHash = messageHash.replace('unsubscribe:', '')
|
|
1715
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
|
1716
|
+
if messageHash.find('ticker') >= 0:
|
|
1717
|
+
symbol = messageHash.replace('unsubscribe:ticker:', '')
|
|
1718
|
+
if symbol.find('unsubscribe') >= 0:
|
|
1719
|
+
# unWatchTickers
|
|
1720
|
+
symbols = list(self.tickers.keys())
|
|
1721
|
+
for j in range(0, len(symbols)):
|
|
1722
|
+
del self.tickers[symbols[j]]
|
|
1723
|
+
elif symbol in self.tickers:
|
|
1724
|
+
del self.tickers[symbol]
|
|
1725
|
+
elif messageHash.find('bidask') >= 0:
|
|
1726
|
+
symbol = messageHash.replace('unsubscribe:bidask:', '')
|
|
1727
|
+
if symbol in self.bidsasks:
|
|
1728
|
+
del self.bidsasks[symbol]
|
|
1729
|
+
elif messageHash.find('candles') >= 0:
|
|
1730
|
+
splitHashes = messageHash.split(':')
|
|
1731
|
+
symbol = self.safe_string(splitHashes, 2)
|
|
1732
|
+
if len(splitHashes) > 4:
|
|
1733
|
+
symbol += ':' + self.safe_string(splitHashes, 3)
|
|
1734
|
+
if symbol in self.ohlcvs:
|
|
1735
|
+
del self.ohlcvs[symbol]
|
|
1736
|
+
elif messageHash.find('orderbook') >= 0:
|
|
1737
|
+
symbol = messageHash.replace('unsubscribe:orderbook:', '')
|
|
1738
|
+
if symbol in self.orderbooks:
|
|
1739
|
+
del self.orderbooks[symbol]
|
|
1740
|
+
elif messageHash.find('trades') >= 0:
|
|
1741
|
+
symbol = messageHash.replace('unsubscribe:trades:', '')
|
|
1742
|
+
if symbol in self.trades:
|
|
1743
|
+
del self.trades[symbol]
|
|
1744
|
+
|
|
1025
1745
|
async def authenticate(self, subscriptionHash, params={}):
|
|
1026
1746
|
# we only need one listenKey since ccxt shares connections
|
|
1027
1747
|
listenKey = self.safe_string(self.options, 'listenKey')
|
|
@@ -1067,8 +1787,8 @@ class mexc(ccxt.async_support.mexc):
|
|
|
1067
1787
|
# "code": 0,
|
|
1068
1788
|
# "msg": "spot@public.increase.depth.v3.api@BTCUSDT"
|
|
1069
1789
|
# }
|
|
1070
|
-
#
|
|
1071
|
-
msg = self.safe_string(message, 'msg')
|
|
1790
|
+
# Set the default to an empty string if the message is empty during the test.
|
|
1791
|
+
msg = self.safe_string(message, 'msg', '')
|
|
1072
1792
|
if msg == 'PONG':
|
|
1073
1793
|
self.handle_pong(client, message)
|
|
1074
1794
|
elif msg.find('@') > -1:
|
|
@@ -1076,16 +1796,59 @@ class mexc(ccxt.async_support.mexc):
|
|
|
1076
1796
|
channel = self.safe_string(parts, 1)
|
|
1077
1797
|
methods: dict = {
|
|
1078
1798
|
'public.increase.depth.v3.api': self.handle_order_book_subscription,
|
|
1799
|
+
'public.aggre.depth.v3.api.pb': self.handle_order_book_subscription,
|
|
1079
1800
|
}
|
|
1080
1801
|
method = self.safe_value(methods, channel)
|
|
1081
1802
|
if method is not None:
|
|
1082
1803
|
method(client, message)
|
|
1083
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
|
+
|
|
1084
1843
|
def handle_message(self, client: Client, message):
|
|
1085
1844
|
if isinstance(message, str):
|
|
1086
1845
|
if message == 'Invalid listen key':
|
|
1087
1846
|
error = AuthenticationError(self.id + ' invalid listen key')
|
|
1088
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)
|
|
1089
1852
|
return
|
|
1090
1853
|
if 'msg' in message:
|
|
1091
1854
|
self.handle_subscription_status(client, message)
|
|
@@ -1103,7 +1866,10 @@ class mexc(ccxt.async_support.mexc):
|
|
|
1103
1866
|
'public.kline.v3.api': self.handle_ohlcv,
|
|
1104
1867
|
'push.kline': self.handle_ohlcv,
|
|
1105
1868
|
'public.bookTicker.v3.api': self.handle_ticker,
|
|
1869
|
+
'public.miniTicker.v3.api': self.handle_ticker,
|
|
1870
|
+
'public.miniTickers.v3.api': self.handle_tickers,
|
|
1106
1871
|
'push.ticker': self.handle_ticker,
|
|
1872
|
+
'push.tickers': self.handle_tickers,
|
|
1107
1873
|
'public.increase.depth.v3.api': self.handle_order_book,
|
|
1108
1874
|
'push.depth': self.handle_order_book,
|
|
1109
1875
|
'private.orders.v3.api': self.handle_order,
|
|
@@ -1118,5 +1884,5 @@ class mexc(ccxt.async_support.mexc):
|
|
|
1118
1884
|
method = methods[channel]
|
|
1119
1885
|
method(client, message)
|
|
1120
1886
|
|
|
1121
|
-
def ping(self, client):
|
|
1887
|
+
def ping(self, client: Client):
|
|
1122
1888
|
return {'method': 'ping'}
|