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.
Files changed (529) hide show
  1. ccxt/__init__.py +39 -35
  2. ccxt/abantether.py +8 -8
  3. ccxt/abstract/alpaca.py +4 -0
  4. ccxt/abstract/apex.py +31 -0
  5. ccxt/abstract/bigone.py +1 -1
  6. ccxt/abstract/binance.py +106 -48
  7. ccxt/abstract/binancecoinm.py +106 -48
  8. ccxt/abstract/binanceus.py +141 -83
  9. ccxt/abstract/binanceusdm.py +106 -48
  10. ccxt/abstract/bingx.py +50 -1
  11. ccxt/abstract/bitbank.py +5 -0
  12. ccxt/abstract/bitfinex.py +136 -65
  13. ccxt/abstract/bitflyer.py +1 -0
  14. ccxt/abstract/bitget.py +67 -0
  15. ccxt/abstract/bitmart.py +19 -1
  16. ccxt/abstract/bitopro.py +1 -0
  17. ccxt/abstract/bitrue.py +68 -68
  18. ccxt/abstract/bitstamp.py +1 -0
  19. ccxt/abstract/blofin.py +30 -0
  20. ccxt/abstract/btcbox.py +2 -0
  21. ccxt/abstract/bybit.py +28 -13
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbaseexchange.py +1 -0
  24. ccxt/abstract/coinbaseinternational.py +1 -1
  25. ccxt/abstract/cryptocom.py +16 -0
  26. ccxt/abstract/cryptomus.py +20 -0
  27. ccxt/abstract/defx.py +69 -0
  28. ccxt/abstract/deribit.py +1 -0
  29. ccxt/abstract/derive.py +117 -0
  30. ccxt/abstract/digifinex.py +1 -0
  31. ccxt/abstract/ellipx.py +25 -0
  32. ccxt/abstract/foxbit.py +26 -0
  33. ccxt/abstract/gate.py +19 -0
  34. ccxt/abstract/gateio.py +19 -0
  35. ccxt/abstract/gemini.py +1 -0
  36. ccxt/abstract/hibachi.py +26 -0
  37. ccxt/abstract/hyperliquid.py +1 -1
  38. ccxt/abstract/independentreserve.py +6 -0
  39. ccxt/abstract/kraken.py +1 -0
  40. ccxt/abstract/krakenfutures.py +4 -0
  41. ccxt/abstract/kucoin.py +10 -0
  42. ccxt/abstract/kucoinfutures.py +18 -0
  43. ccxt/abstract/lbank.py +2 -1
  44. ccxt/abstract/luno.py +1 -0
  45. ccxt/abstract/mexc.py +2 -0
  46. ccxt/abstract/modetrade.py +119 -0
  47. ccxt/abstract/myokx.py +349 -0
  48. ccxt/abstract/oceanex.py +5 -0
  49. ccxt/abstract/okx.py +25 -0
  50. ccxt/abstract/okxus.py +349 -0
  51. ccxt/abstract/onetrading.py +0 -12
  52. ccxt/abstract/paradex.py +23 -0
  53. ccxt/abstract/phemex.py +2 -0
  54. ccxt/abstract/poloniex.py +36 -0
  55. ccxt/abstract/tradeogre.py +3 -1
  56. ccxt/abstract/upbit.py +51 -34
  57. ccxt/abstract/whitebit.py +16 -0
  58. ccxt/abstract/woo.py +64 -6
  59. ccxt/abstract/xt.py +10 -5
  60. ccxt/afratether.py +8 -8
  61. ccxt/alpaca.py +828 -51
  62. ccxt/apex.py +1875 -0
  63. ccxt/arzinja.py +7 -7
  64. ccxt/arzplus.py +9 -9
  65. ccxt/ascendex.py +501 -306
  66. ccxt/async_support/__init__.py +39 -35
  67. ccxt/async_support/abantether.py +8 -8
  68. ccxt/async_support/afratether.py +10 -10
  69. ccxt/async_support/alpaca.py +828 -51
  70. ccxt/async_support/apex.py +1875 -0
  71. ccxt/async_support/arzinja.py +10 -10
  72. ccxt/async_support/arzplus.py +12 -12
  73. ccxt/async_support/ascendex.py +502 -306
  74. ccxt/async_support/base/exchange.py +303 -89
  75. ccxt/async_support/base/ws/cache.py +9 -3
  76. ccxt/async_support/base/ws/client.py +173 -38
  77. ccxt/async_support/base/ws/future.py +25 -37
  78. ccxt/async_support/bequant.py +5 -3
  79. ccxt/async_support/bigone.py +279 -144
  80. ccxt/async_support/binance.py +2347 -1158
  81. ccxt/async_support/binancecoinm.py +9 -3
  82. ccxt/async_support/binanceus.py +17 -3
  83. ccxt/async_support/binanceusdm.py +9 -4
  84. ccxt/async_support/bingx.py +2962 -920
  85. ccxt/async_support/bit2c.py +147 -27
  86. ccxt/async_support/bitbank.py +151 -23
  87. ccxt/async_support/bitbns.py +104 -30
  88. ccxt/async_support/bitfinex.py +3291 -1113
  89. ccxt/async_support/bitflyer.py +202 -27
  90. ccxt/async_support/bitget.py +3683 -1538
  91. ccxt/async_support/bithumb.py +195 -38
  92. ccxt/async_support/bitimen.py +12 -12
  93. ccxt/async_support/bitir.py +38 -38
  94. ccxt/async_support/bitmart.py +1288 -350
  95. ccxt/async_support/bitmex.py +260 -75
  96. ccxt/async_support/bitopro.py +262 -62
  97. ccxt/async_support/bitpin.py +17 -16
  98. ccxt/async_support/bitrue.py +459 -290
  99. ccxt/async_support/bitso.py +199 -54
  100. ccxt/async_support/bitstamp.py +230 -96
  101. ccxt/async_support/bitteam.py +167 -25
  102. ccxt/async_support/{huobijp.py → bittrade.py} +158 -30
  103. ccxt/async_support/bitvavo.py +213 -49
  104. ccxt/async_support/blockchaincom.py +160 -46
  105. ccxt/async_support/blofin.py +502 -120
  106. ccxt/async_support/btcalpha.py +169 -31
  107. ccxt/async_support/btcbox.py +292 -23
  108. ccxt/async_support/btcmarkets.py +211 -58
  109. ccxt/async_support/btcturk.py +161 -38
  110. ccxt/async_support/bybit.py +1775 -1030
  111. ccxt/async_support/cex.py +1440 -1303
  112. ccxt/async_support/coinbase.py +724 -212
  113. ccxt/async_support/coinbaseadvanced.py +2 -1
  114. ccxt/async_support/coinbaseexchange.py +388 -89
  115. ccxt/async_support/coinbaseinternational.py +412 -57
  116. ccxt/async_support/coincatch.py +177 -78
  117. ccxt/async_support/coincheck.py +135 -19
  118. ccxt/async_support/coinex.py +606 -232
  119. ccxt/async_support/coinmate.py +189 -63
  120. ccxt/async_support/coinmetro.py +195 -54
  121. ccxt/async_support/coinone.py +158 -51
  122. ccxt/async_support/coinsph.py +336 -61
  123. ccxt/async_support/coinspot.py +151 -52
  124. ccxt/async_support/cryptocom.py +661 -111
  125. ccxt/async_support/cryptomus.py +1137 -0
  126. ccxt/async_support/defx.py +2071 -0
  127. ccxt/async_support/delta.py +299 -99
  128. ccxt/async_support/deribit.py +348 -126
  129. ccxt/async_support/derive.py +2572 -0
  130. ccxt/async_support/digifinex.py +430 -214
  131. ccxt/async_support/ellipx.py +2029 -0
  132. ccxt/async_support/eterex.py +10 -10
  133. ccxt/async_support/excoino.py +31 -31
  134. ccxt/async_support/exir.py +14 -14
  135. ccxt/async_support/exmo.py +344 -131
  136. ccxt/async_support/exnovin.py +10 -10
  137. ccxt/async_support/farhadexchange.py +12 -12
  138. ccxt/async_support/fmfwio.py +2 -1
  139. ccxt/async_support/foxbit.py +1935 -0
  140. ccxt/async_support/gate.py +1351 -529
  141. ccxt/async_support/gateio.py +2 -1
  142. ccxt/async_support/gemini.py +144 -39
  143. ccxt/async_support/hashkey.py +152 -109
  144. ccxt/async_support/hibachi.py +2080 -0
  145. ccxt/async_support/hitbtc.py +395 -167
  146. ccxt/async_support/hitobit.py +12 -12
  147. ccxt/async_support/hollaex.py +307 -119
  148. ccxt/async_support/htx.py +851 -383
  149. ccxt/async_support/huobi.py +2 -1
  150. ccxt/async_support/hyperliquid.py +1848 -536
  151. ccxt/async_support/independentreserve.py +288 -15
  152. ccxt/async_support/indodax.py +190 -33
  153. ccxt/async_support/jibitex.py +12 -12
  154. ccxt/async_support/kraken.py +795 -351
  155. ccxt/async_support/krakenfutures.py +214 -62
  156. ccxt/async_support/kucoin.py +715 -396
  157. ccxt/async_support/kucoinfutures.py +652 -89
  158. ccxt/async_support/latoken.py +217 -113
  159. ccxt/async_support/lbank.py +425 -97
  160. ccxt/async_support/luno.py +382 -35
  161. ccxt/async_support/mercado.py +113 -6
  162. ccxt/async_support/mexc.py +874 -437
  163. ccxt/async_support/modetrade.py +2818 -0
  164. ccxt/async_support/myokx.py +54 -0
  165. ccxt/async_support/ndax.py +221 -64
  166. ccxt/async_support/nobitex.py +32 -38
  167. ccxt/async_support/novadax.py +190 -34
  168. ccxt/async_support/oceanex.py +217 -28
  169. ccxt/async_support/okcoin.py +253 -145
  170. ccxt/async_support/okexchange.py +11 -11
  171. ccxt/async_support/okx.py +1088 -351
  172. ccxt/async_support/okxus.py +54 -0
  173. ccxt/async_support/ompfinex.py +32 -27
  174. ccxt/async_support/onetrading.py +213 -392
  175. ccxt/async_support/oxfun.py +245 -166
  176. ccxt/async_support/p2b.py +151 -29
  177. ccxt/async_support/paradex.py +562 -49
  178. ccxt/async_support/paymium.py +82 -19
  179. ccxt/async_support/phemex.py +713 -172
  180. ccxt/async_support/poloniex.py +1602 -283
  181. ccxt/async_support/probit.py +224 -95
  182. ccxt/async_support/ramzinex.py +34 -30
  183. ccxt/async_support/sarmayex.py +9 -9
  184. ccxt/async_support/sarrafex.py +13 -13
  185. ccxt/async_support/tabdeal.py +15 -14
  186. ccxt/async_support/tetherland.py +9 -9
  187. ccxt/async_support/timex.py +210 -51
  188. ccxt/async_support/tokocrypto.py +167 -47
  189. ccxt/async_support/tradeogre.py +266 -31
  190. ccxt/async_support/twox.py +9 -9
  191. ccxt/async_support/ubitex.py +12 -12
  192. ccxt/async_support/upbit.py +568 -165
  193. ccxt/async_support/vertex.py +160 -32
  194. ccxt/async_support/wallex.py +12 -12
  195. ccxt/async_support/wavesexchange.py +165 -30
  196. ccxt/async_support/whitebit.py +975 -127
  197. ccxt/async_support/woo.py +1918 -1016
  198. ccxt/async_support/woofipro.py +433 -141
  199. ccxt/async_support/xt.py +649 -193
  200. ccxt/async_support/yobit.py +195 -70
  201. ccxt/async_support/zaif.py +91 -15
  202. ccxt/async_support/zonda.py +151 -36
  203. ccxt/base/decimal_to_precision.py +14 -10
  204. ccxt/base/errors.py +49 -18
  205. ccxt/base/exchange.py +1556 -450
  206. ccxt/base/precise.py +10 -0
  207. ccxt/base/types.py +114 -6
  208. ccxt/bequant.py +5 -3
  209. ccxt/bigone.py +279 -144
  210. ccxt/binance.py +2347 -1158
  211. ccxt/binancecoinm.py +9 -3
  212. ccxt/binanceus.py +17 -3
  213. ccxt/binanceusdm.py +9 -4
  214. ccxt/bingx.py +2962 -920
  215. ccxt/bit2c.py +147 -27
  216. ccxt/bitbank.py +151 -23
  217. ccxt/bitbns.py +104 -30
  218. ccxt/bitfinex.py +3290 -1113
  219. ccxt/bitflyer.py +202 -27
  220. ccxt/bitget.py +3683 -1538
  221. ccxt/bithumb.py +194 -38
  222. ccxt/bitimen.py +9 -9
  223. ccxt/bitir.py +35 -35
  224. ccxt/bitmart.py +1288 -350
  225. ccxt/bitmex.py +260 -75
  226. ccxt/bitopro.py +262 -62
  227. ccxt/bitpin.py +15 -14
  228. ccxt/bitrue.py +459 -290
  229. ccxt/bitso.py +199 -54
  230. ccxt/bitstamp.py +230 -96
  231. ccxt/bitteam.py +167 -25
  232. ccxt/{huobijp.py → bittrade.py} +158 -30
  233. ccxt/bitvavo.py +213 -49
  234. ccxt/blockchaincom.py +160 -46
  235. ccxt/blofin.py +502 -120
  236. ccxt/btcalpha.py +169 -31
  237. ccxt/btcbox.py +291 -23
  238. ccxt/btcmarkets.py +211 -58
  239. ccxt/btcturk.py +161 -38
  240. ccxt/bybit.py +1775 -1030
  241. ccxt/cex.py +1439 -1303
  242. ccxt/coinbase.py +724 -212
  243. ccxt/coinbaseadvanced.py +2 -1
  244. ccxt/coinbaseexchange.py +388 -89
  245. ccxt/coinbaseinternational.py +412 -57
  246. ccxt/coincatch.py +177 -78
  247. ccxt/coincheck.py +135 -19
  248. ccxt/coinex.py +606 -232
  249. ccxt/coinmate.py +189 -63
  250. ccxt/coinmetro.py +194 -54
  251. ccxt/coinone.py +158 -51
  252. ccxt/coinsph.py +336 -61
  253. ccxt/coinspot.py +151 -52
  254. ccxt/cryptocom.py +661 -111
  255. ccxt/cryptomus.py +1137 -0
  256. ccxt/defx.py +2070 -0
  257. ccxt/delta.py +299 -99
  258. ccxt/deribit.py +348 -126
  259. ccxt/derive.py +2571 -0
  260. ccxt/digifinex.py +430 -214
  261. ccxt/ellipx.py +2029 -0
  262. ccxt/eterex.py +7 -7
  263. ccxt/excoino.py +29 -29
  264. ccxt/exir.py +11 -11
  265. ccxt/exmo.py +343 -131
  266. ccxt/exnovin.py +8 -8
  267. ccxt/farhadexchange.py +10 -10
  268. ccxt/fmfwio.py +2 -1
  269. ccxt/foxbit.py +1935 -0
  270. ccxt/gate.py +1351 -529
  271. ccxt/gateio.py +2 -1
  272. ccxt/gemini.py +144 -39
  273. ccxt/hashkey.py +152 -109
  274. ccxt/hibachi.py +2079 -0
  275. ccxt/hitbtc.py +395 -167
  276. ccxt/hitobit.py +9 -9
  277. ccxt/hollaex.py +307 -119
  278. ccxt/htx.py +851 -383
  279. ccxt/huobi.py +2 -1
  280. ccxt/hyperliquid.py +1848 -536
  281. ccxt/independentreserve.py +287 -15
  282. ccxt/indodax.py +190 -33
  283. ccxt/jibitex.py +9 -9
  284. ccxt/kraken.py +794 -351
  285. ccxt/krakenfutures.py +214 -62
  286. ccxt/kucoin.py +715 -396
  287. ccxt/kucoinfutures.py +652 -89
  288. ccxt/latoken.py +217 -113
  289. ccxt/lbank.py +425 -97
  290. ccxt/luno.py +382 -35
  291. ccxt/mercado.py +113 -6
  292. ccxt/mexc.py +873 -437
  293. ccxt/modetrade.py +2818 -0
  294. ccxt/myokx.py +54 -0
  295. ccxt/ndax.py +221 -64
  296. ccxt/nobitex.py +30 -36
  297. ccxt/novadax.py +190 -34
  298. ccxt/oceanex.py +217 -28
  299. ccxt/okcoin.py +253 -145
  300. ccxt/okexchange.py +9 -9
  301. ccxt/okx.py +1088 -351
  302. ccxt/okxus.py +54 -0
  303. ccxt/ompfinex.py +29 -24
  304. ccxt/onetrading.py +213 -392
  305. ccxt/oxfun.py +245 -166
  306. ccxt/p2b.py +151 -29
  307. ccxt/paradex.py +562 -49
  308. ccxt/paymium.py +82 -19
  309. ccxt/phemex.py +712 -172
  310. ccxt/poloniex.py +1601 -283
  311. ccxt/pro/__init__.py +76 -17
  312. ccxt/pro/alpaca.py +21 -6
  313. ccxt/pro/apex.py +984 -0
  314. ccxt/pro/ascendex.py +58 -10
  315. ccxt/pro/bequant.py +6 -1
  316. ccxt/pro/binance.py +728 -156
  317. ccxt/pro/binancecoinm.py +6 -2
  318. ccxt/pro/binanceus.py +8 -4
  319. ccxt/pro/binanceusdm.py +7 -2
  320. ccxt/pro/bingx.py +333 -142
  321. ccxt/pro/bitfinex.py +727 -262
  322. ccxt/pro/bitget.py +570 -79
  323. ccxt/pro/bithumb.py +20 -6
  324. ccxt/pro/bitmart.py +216 -87
  325. ccxt/pro/bitmex.py +47 -9
  326. ccxt/pro/bitopro.py +26 -14
  327. ccxt/pro/bitrue.py +22 -22
  328. ccxt/pro/bitstamp.py +54 -21
  329. ccxt/pro/{huobijp.py → bittrade.py} +7 -6
  330. ccxt/pro/bitvavo.py +191 -67
  331. ccxt/pro/blockchaincom.py +21 -8
  332. ccxt/pro/blofin.py +9 -1
  333. ccxt/pro/bybit.py +632 -245
  334. ccxt/pro/cex.py +59 -24
  335. ccxt/pro/coinbase.py +102 -73
  336. ccxt/pro/coinbaseadvanced.py +2 -1
  337. ccxt/pro/coinbaseexchange.py +8 -8
  338. ccxt/pro/coinbaseinternational.py +181 -25
  339. ccxt/pro/coincatch.py +6 -7
  340. ccxt/pro/coincheck.py +11 -6
  341. ccxt/pro/coinex.py +967 -665
  342. ccxt/pro/coinone.py +16 -9
  343. ccxt/pro/cryptocom.py +448 -45
  344. ccxt/pro/defx.py +831 -0
  345. ccxt/pro/deribit.py +150 -14
  346. ccxt/pro/derive.py +704 -0
  347. ccxt/pro/exmo.py +239 -6
  348. ccxt/pro/gate.py +623 -65
  349. ccxt/pro/gateio.py +2 -1
  350. ccxt/pro/gemini.py +27 -11
  351. ccxt/pro/hashkey.py +2 -2
  352. ccxt/pro/hitbtc.py +196 -91
  353. ccxt/pro/hollaex.py +23 -7
  354. ccxt/pro/htx.py +51 -14
  355. ccxt/pro/huobi.py +2 -1
  356. ccxt/pro/hyperliquid.py +591 -27
  357. ccxt/pro/independentreserve.py +9 -6
  358. ccxt/pro/kraken.py +640 -320
  359. ccxt/pro/krakenfutures.py +62 -35
  360. ccxt/pro/kucoin.py +267 -46
  361. ccxt/pro/kucoinfutures.py +165 -21
  362. ccxt/pro/lbank.py +102 -21
  363. ccxt/pro/luno.py +12 -8
  364. ccxt/pro/mexc.py +877 -111
  365. ccxt/pro/modetrade.py +1271 -0
  366. ccxt/pro/myokx.py +38 -0
  367. ccxt/pro/ndax.py +15 -2
  368. ccxt/pro/okcoin.py +23 -4
  369. ccxt/pro/okx.py +573 -98
  370. ccxt/pro/okxus.py +38 -0
  371. ccxt/pro/onetrading.py +30 -13
  372. ccxt/pro/oxfun.py +131 -27
  373. ccxt/pro/p2b.py +88 -22
  374. ccxt/pro/paradex.py +3 -3
  375. ccxt/pro/phemex.py +75 -21
  376. ccxt/pro/poloniex.py +124 -41
  377. ccxt/pro/probit.py +87 -80
  378. ccxt/pro/tradeogre.py +272 -0
  379. ccxt/pro/upbit.py +152 -12
  380. ccxt/pro/vertex.py +8 -3
  381. ccxt/pro/whitebit.py +58 -5
  382. ccxt/pro/woo.py +228 -37
  383. ccxt/pro/woofipro.py +106 -18
  384. ccxt/pro/xt.py +111 -5
  385. ccxt/probit.py +224 -95
  386. ccxt/protobuf/__init__.py +0 -0
  387. ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
  388. ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
  389. ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
  390. ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
  391. ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
  392. ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
  393. ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
  394. ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
  395. ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
  396. ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
  397. ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
  398. ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
  399. ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
  400. ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
  401. ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
  402. ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
  403. ccxt/protobuf/mexc/__init__.py +0 -0
  404. ccxt/ramzinex.py +32 -28
  405. ccxt/sarmayex.py +7 -7
  406. ccxt/sarrafex.py +10 -10
  407. ccxt/static_dependencies/__init__.py +1 -1
  408. ccxt/static_dependencies/lark/py.typed +0 -0
  409. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  410. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  411. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  412. ccxt/tabdeal.py +13 -12
  413. ccxt/test/tests_async.py +261 -57
  414. ccxt/test/tests_helpers.py +1 -3
  415. ccxt/test/tests_init.py +4 -3
  416. ccxt/test/tests_sync.py +261 -57
  417. ccxt/tetherland.py +7 -7
  418. ccxt/timex.py +210 -51
  419. ccxt/tokocrypto.py +167 -47
  420. ccxt/tradeogre.py +266 -31
  421. ccxt/twox.py +7 -7
  422. ccxt/ubitex.py +9 -9
  423. ccxt/upbit.py +568 -165
  424. ccxt/vertex.py +160 -32
  425. ccxt/wallex.py +9 -9
  426. ccxt/wavesexchange.py +165 -30
  427. ccxt/whitebit.py +975 -127
  428. ccxt/woo.py +1917 -1016
  429. ccxt/woofipro.py +432 -141
  430. ccxt/xt.py +649 -193
  431. ccxt/yobit.py +194 -70
  432. ccxt/zaif.py +91 -15
  433. ccxt/zonda.py +151 -36
  434. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/METADATA +225 -73
  435. ccxt_ir-4.5.1.dist-info/RECORD +743 -0
  436. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/WHEEL +1 -1
  437. ccxt/__test__.py +0 -7
  438. ccxt/abstract/ace.py +0 -15
  439. ccxt/abstract/bitbay.py +0 -53
  440. ccxt/abstract/bitcoincom.py +0 -115
  441. ccxt/abstract/bitfinex2.py +0 -139
  442. ccxt/abstract/bitpanda.py +0 -35
  443. ccxt/abstract/bl3p.py +0 -19
  444. ccxt/abstract/coinlist.py +0 -54
  445. ccxt/abstract/currencycom.py +0 -68
  446. ccxt/abstract/hitbtc3.py +0 -115
  447. ccxt/abstract/idex.py +0 -26
  448. ccxt/abstract/kuna.py +0 -182
  449. ccxt/abstract/lykke.py +0 -29
  450. ccxt/abstract/poloniexfutures.py +0 -48
  451. ccxt/abstract/wazirx.py +0 -30
  452. ccxt/ace.py +0 -1012
  453. ccxt/async_support/ace.py +0 -1012
  454. ccxt/async_support/base/ws/aiohttp_client.py +0 -125
  455. ccxt/async_support/base/ws/fast_client.py +0 -96
  456. ccxt/async_support/bitbay.py +0 -17
  457. ccxt/async_support/bitcoincom.py +0 -17
  458. ccxt/async_support/bitfinex2.py +0 -3552
  459. ccxt/async_support/bitpanda.py +0 -16
  460. ccxt/async_support/bl3p.py +0 -485
  461. ccxt/async_support/coinlist.py +0 -2243
  462. ccxt/async_support/currencycom.py +0 -1950
  463. ccxt/async_support/hitbtc3.py +0 -16
  464. ccxt/async_support/idex.py +0 -1766
  465. ccxt/async_support/kuna.py +0 -1841
  466. ccxt/async_support/lykke.py +0 -1270
  467. ccxt/async_support/poloniexfutures.py +0 -1717
  468. ccxt/async_support/wazirx.py +0 -1224
  469. ccxt/bitbay.py +0 -17
  470. ccxt/bitcoincom.py +0 -17
  471. ccxt/bitfinex2.py +0 -3552
  472. ccxt/bitpanda.py +0 -16
  473. ccxt/bl3p.py +0 -485
  474. ccxt/coinlist.py +0 -2243
  475. ccxt/currencycom.py +0 -1950
  476. ccxt/hitbtc3.py +0 -16
  477. ccxt/idex.py +0 -1766
  478. ccxt/kuna.py +0 -1841
  479. ccxt/lykke.py +0 -1270
  480. ccxt/poloniexfutures.py +0 -1717
  481. ccxt/pro/bitcoincom.py +0 -34
  482. ccxt/pro/bitfinex2.py +0 -1083
  483. ccxt/pro/bitpanda.py +0 -15
  484. ccxt/pro/currencycom.py +0 -536
  485. ccxt/pro/idex.py +0 -672
  486. ccxt/pro/poloniexfutures.py +0 -990
  487. ccxt/pro/wazirx.py +0 -749
  488. ccxt/test/base/__init__.py +0 -29
  489. ccxt/test/base/test_account.py +0 -26
  490. ccxt/test/base/test_balance.py +0 -56
  491. ccxt/test/base/test_borrow_interest.py +0 -35
  492. ccxt/test/base/test_borrow_rate.py +0 -32
  493. ccxt/test/base/test_calculate_fee.py +0 -51
  494. ccxt/test/base/test_crypto.py +0 -127
  495. ccxt/test/base/test_currency.py +0 -76
  496. ccxt/test/base/test_datetime.py +0 -109
  497. ccxt/test/base/test_decimal_to_precision.py +0 -392
  498. ccxt/test/base/test_deep_extend.py +0 -68
  499. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  500. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  501. ccxt/test/base/test_funding_rate_history.py +0 -29
  502. ccxt/test/base/test_last_price.py +0 -31
  503. ccxt/test/base/test_ledger_entry.py +0 -45
  504. ccxt/test/base/test_ledger_item.py +0 -48
  505. ccxt/test/base/test_leverage_tier.py +0 -33
  506. ccxt/test/base/test_liquidation.py +0 -50
  507. ccxt/test/base/test_margin_mode.py +0 -24
  508. ccxt/test/base/test_margin_modification.py +0 -35
  509. ccxt/test/base/test_market.py +0 -193
  510. ccxt/test/base/test_number.py +0 -411
  511. ccxt/test/base/test_ohlcv.py +0 -33
  512. ccxt/test/base/test_open_interest.py +0 -32
  513. ccxt/test/base/test_order.py +0 -64
  514. ccxt/test/base/test_order_book.py +0 -69
  515. ccxt/test/base/test_position.py +0 -60
  516. ccxt/test/base/test_shared_methods.py +0 -353
  517. ccxt/test/base/test_status.py +0 -24
  518. ccxt/test/base/test_throttle.py +0 -126
  519. ccxt/test/base/test_ticker.py +0 -92
  520. ccxt/test/base/test_trade.py +0 -47
  521. ccxt/test/base/test_trading_fee.py +0 -26
  522. ccxt/test/base/test_transaction.py +0 -39
  523. ccxt/test/test_async.py +0 -1649
  524. ccxt/test/test_sync.py +0 -1648
  525. ccxt/wazirx.py +0 -1224
  526. ccxt_ir-4.3.46.0.3.dist-info/RECORD +0 -773
  527. /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
  528. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info/licenses}/LICENSE.txt +0 -0
  529. {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': False,
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
- rawTicker = self.safe_value_2(message, 'd', 'data')
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.safe_integer(message, 't')
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 parse_ws_ticker(self, ticker, market=None):
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
- # "A": "4.70432",
131
- # "B": "6.714863",
132
- # "a": "20744.54",
133
- # "b": "20744.17"
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
- 'symbol': self.safe_symbol(None, market),
138
- 'timestamp': None,
139
- 'datetime': None,
385
+ 'info': ticker,
386
+ 'symbol': self.safe_symbol(marketId, market),
387
+ 'timestamp': timestamp,
388
+ 'datetime': self.iso8601(timestamp),
140
389
  'open': None,
141
- 'high': None,
142
- 'low': None,
143
- 'close': None,
144
- 'bid': self.safe_number(ticker, 'b'),
145
- 'bidVolume': self.safe_number(ticker, 'B'),
146
- 'ask': self.safe_number(ticker, 'a'),
147
- 'askVolume': self.safe_number(ticker, 'A'),
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': None,
401
+ 'percentage': self.safe_number(ticker, 'tr'),
152
402
  'average': None,
153
- 'baseVolume': None,
154
- 'quoteVolume': None,
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': 'SUBSCRIPTION',
491
+ 'method': method,
162
492
  'params': [channel],
163
493
  }
164
- return await self.watch(url, messageHash, self.extend(request, params), channel)
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
- :see: https://mxcdevelop.github.io/apidocs/spot_v3_en/#kline-streams
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
- d = self.safe_value_2(message, 'd', 'data', {})
283
- rawOhlcv = self.safe_value(d, 'k', d)
284
- timeframeId = self.safe_string_2(rawOhlcv, 'i', 'interval')
285
- timeframes = self.safe_value(self.options, 'timeframes', {})
286
- timeframe = self.find_timeframe(timeframeId, timeframes)
287
- marketId = self.safe_string_2(message, 's', 'symbol')
288
- market = self.safe_market(marketId)
289
- symbol = market['symbol']
632
+ parsed: dict = None
633
+ symbol: Str = None
634
+ timeframe: Str = None
635
+ if 'publicSpotKline' in message:
636
+ symbol = self.symbol(self.safe_string(message, 'symbol'))
637
+ data = self.safe_dict(message, 'publicSpotKline', {})
638
+ timeframeId = self.safe_string(data, 'interval')
639
+ timeframe = self.find_timeframe(timeframeId, self.options['timeframes'])
640
+ parsed = self.parse_ws_ohlcv(data, self.safe_market(symbol))
641
+ else:
642
+ d = self.safe_value_2(message, 'd', 'data', {})
643
+ rawOhlcv = self.safe_value(d, 'k', d)
644
+ timeframeId = self.safe_string_2(rawOhlcv, 'i', 'interval')
645
+ timeframes = self.safe_value(self.options, 'timeframes', {})
646
+ timeframe = self.find_timeframe(timeframeId, timeframes)
647
+ marketId = self.safe_string_2(message, 's', 'symbol')
648
+ market = self.safe_market(marketId)
649
+ symbol = market['symbol']
650
+ parsed = self.parse_ws_ohlcv(rawOhlcv, market)
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.safe_timestamp(ohlcv, 't'),
336
- self.safe_number(ohlcv, 'o'),
337
- self.safe_number(ohlcv, 'h'),
338
- self.safe_number(ohlcv, 'l'),
339
- self.safe_number(ohlcv, 'c'),
340
- self.safe_number_2(ohlcv, 'v', 'q'),
706
+ self.safe_timestamp_2(ohlcv, 't', 'windowStart'),
707
+ self.safe_number_2(ohlcv, 'o', 'openingPrice'),
708
+ self.safe_number_2(ohlcv, 'h', 'highestPrice'),
709
+ self.safe_number_2(ohlcv, 'l', 'lowestPrice'),
710
+ self.safe_number_2(ohlcv, 'c', 'closingPrice'),
711
+ self.safe_number_2(ohlcv, 'v', 'volume'),
341
712
  ]
342
713
 
343
714
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
344
715
  """
345
- :see: https://mxcdevelop.github.io/apidocs/spot_v3_en/#diff-depth-stream
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
- channel = 'spot@public.increase.depth.v3.api@' + market['id']
733
+ frequency = None
734
+ frequency, params = self.handle_option_and_params(params, 'watchOrderBook', 'frequency', '100ms')
735
+ channel = 'spot@public.aggre.depth.v3.api.pb@' + frequency + '@' + market['id']
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.safe_integer_2(firstDelta, 'r', 'version')
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.safe_integer_2(delta, 'r', 'version')
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.safe_value_2(message, 'd', 'data')
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 subscription is True:
443
- # we set client.subscriptions[messageHash] to 1
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.safe_integer_2(message, 't', 'ts')
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.safe_float(bidask, 'p')
479
- amount = self.safe_float(bidask, 'v')
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.safe_integer_2(delta, 'r', 'version')
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
- :see: https://mxcdevelop.github.io/apidocs/spot_v3_en/#trade-streams
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.safe_value_2(message, 'd', 'data')
567
- trades = self.safe_value(d, 'deals', [d])
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
- :see: https://mxcdevelop.github.io/apidocs/spot_v3_en/#spot-account-deals
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 [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
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.safe_value_2(message, 'd', 'data')
1062
+ data = self.safe_dict_n(message, ['d', 'data', 'privateDeals'])
627
1063
  futuresMarketId = self.safe_string(data, 'symbol')
628
- marketId = self.safe_string(message, 's', futuresMarketId)
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
- timestamp = self.safe_integer(trade, 'T')
684
- tradeId = self.safe_string(trade, 't')
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.safe_string(trade, 'p')
689
- amountString = self.safe_string(trade, 'v')
690
- rawSide = self.safe_string(trade, 'S')
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.safe_number(trade, 'n')
694
- feeCurrencyId = self.safe_string(trade, 'N')
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.safe_string(trade, 'i'),
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': None,
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
- :see: https://mxcdevelop.github.io/apidocs/spot_v3_en/#spot-account-orders
717
- :see: https://mxcdevelop.github.io/apidocs/spot_v3_en/#margin-account-orders
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 = type + '@private.orders.v3.api'
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.safe_value_2(message, 'd', 'data')
1270
+ data = self.safe_dict_n(message, ['d', 'data', 'privateOrders'])
814
1271
  futuresMarketId = self.safe_string(data, 'symbol')
815
- marketId = self.safe_string(message, 's', futuresMarketId)
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, 'O')
885
- side = self.safe_string(order, 'S')
886
- status = self.safe_string(order, 's')
887
- type = self.safe_string(order, 'o')
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, 'i'),
897
- 'clientOrderId': self.safe_string(order, 'c'),
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, 'p'),
1380
+ 'price': self.safe_string(order, 'price'),
907
1381
  'stopPrice': None,
908
- 'triggerPrice': self.safe_number(order, 'P'),
909
- 'average': self.safe_string(order, 'ap'),
910
- 'amount': self.safe_string(order, 'v'),
911
- 'cost': self.safe_string(order, 'a'),
912
- 'filled': self.safe_string(order, 'cv'),
913
- 'remaining': self.safe_string(order, 'V'),
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': 'open', # order partially filled
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': None, # POST_ONLY
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
- :see: https://mxcdevelop.github.io/apidocs/spot_v3_en/#spot-account-upadte
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.safe_string(message, 'c')
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.safe_value_2(message, 'd', 'data')
1483
+ data = self.safe_dict_n(message, ['d', 'data', 'privateAccount'])
1009
1484
  futuresTimestamp = self.safe_integer(message, 'ts')
1010
- timestamp = self.safe_integer(data, 'c', futuresTimestamp)
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.safe_string_2(data, 'a', 'currency')
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['free'] = self.safe_string_2(data, 'f', 'availableBalance')
1020
- account['used'] = self.safe_string_2(data, 'l', 'frozenBalance')
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'}