ccxt 4.2.77__py2.py3-none-any.whl → 4.4.48__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 (546) hide show
  1. ccxt/__init__.py +36 -14
  2. ccxt/abstract/alpaca.py +4 -0
  3. ccxt/abstract/bigone.py +1 -1
  4. ccxt/abstract/binance.py +112 -48
  5. ccxt/abstract/binancecoinm.py +112 -48
  6. ccxt/abstract/binanceus.py +147 -83
  7. ccxt/abstract/binanceusdm.py +112 -48
  8. ccxt/abstract/bingx.py +133 -78
  9. ccxt/abstract/bitbank.py +5 -0
  10. ccxt/abstract/bitfinex.py +136 -65
  11. ccxt/abstract/bitfinex1.py +69 -0
  12. ccxt/abstract/bitflyer.py +1 -0
  13. ccxt/abstract/bitget.py +8 -1
  14. ccxt/abstract/bitmart.py +13 -1
  15. ccxt/abstract/bitopro.py +1 -0
  16. ccxt/abstract/bitpanda.py +0 -12
  17. ccxt/abstract/bitrue.py +3 -3
  18. ccxt/abstract/bitstamp.py +26 -3
  19. ccxt/abstract/blofin.py +24 -0
  20. ccxt/abstract/btcbox.py +1 -0
  21. ccxt/abstract/bybit.py +29 -14
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbase.py +6 -0
  24. ccxt/abstract/coinbaseadvanced.py +94 -0
  25. ccxt/abstract/{coinbasepro.py → coinbaseexchange.py} +1 -0
  26. ccxt/abstract/coinbaseinternational.py +1 -1
  27. ccxt/abstract/coincatch.py +94 -0
  28. ccxt/abstract/coinex.py +233 -123
  29. ccxt/abstract/coinmetro.py +1 -0
  30. ccxt/abstract/cryptocom.py +14 -0
  31. ccxt/abstract/defx.py +69 -0
  32. ccxt/abstract/deribit.py +1 -0
  33. ccxt/abstract/digifinex.py +1 -0
  34. ccxt/abstract/ellipx.py +25 -0
  35. ccxt/abstract/gate.py +20 -0
  36. ccxt/abstract/gateio.py +20 -0
  37. ccxt/abstract/gemini.py +1 -0
  38. ccxt/abstract/hashkey.py +67 -0
  39. ccxt/abstract/hyperliquid.py +1 -1
  40. ccxt/abstract/independentreserve.py +6 -0
  41. ccxt/abstract/kraken.py +4 -3
  42. ccxt/abstract/krakenfutures.py +4 -0
  43. ccxt/abstract/kucoin.py +24 -0
  44. ccxt/abstract/kucoinfutures.py +34 -0
  45. ccxt/abstract/luno.py +2 -0
  46. ccxt/abstract/mexc.py +4 -0
  47. ccxt/abstract/myokx.py +340 -0
  48. ccxt/abstract/oceanex.py +5 -0
  49. ccxt/abstract/okx.py +30 -0
  50. ccxt/abstract/onetrading.py +0 -12
  51. ccxt/abstract/oxfun.py +34 -0
  52. ccxt/abstract/paradex.py +40 -0
  53. ccxt/abstract/phemex.py +1 -0
  54. ccxt/abstract/upbit.py +4 -0
  55. ccxt/abstract/vertex.py +19 -0
  56. ccxt/abstract/whitebit.py +31 -1
  57. ccxt/abstract/woo.py +6 -2
  58. ccxt/abstract/woofipro.py +119 -0
  59. ccxt/abstract/xt.py +153 -0
  60. ccxt/abstract/zonda.py +6 -0
  61. ccxt/ace.py +164 -60
  62. ccxt/alpaca.py +727 -63
  63. ccxt/ascendex.py +395 -249
  64. ccxt/async_support/__init__.py +36 -14
  65. ccxt/async_support/ace.py +164 -60
  66. ccxt/async_support/alpaca.py +727 -63
  67. ccxt/async_support/ascendex.py +396 -249
  68. ccxt/async_support/base/exchange.py +531 -155
  69. ccxt/async_support/base/ws/aiohttp_client.py +28 -5
  70. ccxt/async_support/base/ws/cache.py +3 -2
  71. ccxt/async_support/base/ws/client.py +26 -5
  72. ccxt/async_support/base/ws/fast_client.py +4 -3
  73. ccxt/async_support/base/ws/functions.py +1 -1
  74. ccxt/async_support/base/ws/future.py +40 -31
  75. ccxt/async_support/base/ws/order_book_side.py +3 -0
  76. ccxt/async_support/bequant.py +1 -1
  77. ccxt/async_support/bigone.py +329 -202
  78. ccxt/async_support/binance.py +3030 -1087
  79. ccxt/async_support/binancecoinm.py +2 -1
  80. ccxt/async_support/binanceus.py +12 -1
  81. ccxt/async_support/binanceusdm.py +3 -1
  82. ccxt/async_support/bingx.py +3104 -880
  83. ccxt/async_support/bit2c.py +119 -38
  84. ccxt/async_support/bitbank.py +215 -76
  85. ccxt/async_support/bitbns.py +124 -53
  86. ccxt/async_support/bitfinex.py +3236 -1078
  87. ccxt/async_support/bitfinex1.py +1711 -0
  88. ccxt/async_support/bitflyer.py +238 -49
  89. ccxt/async_support/bitget.py +1513 -563
  90. ccxt/async_support/bithumb.py +199 -65
  91. ccxt/async_support/bitmart.py +1320 -435
  92. ccxt/async_support/bitmex.py +308 -111
  93. ccxt/async_support/bitopro.py +256 -96
  94. ccxt/async_support/bitrue.py +365 -233
  95. ccxt/async_support/bitso.py +201 -89
  96. ccxt/async_support/bitstamp.py +438 -269
  97. ccxt/async_support/bitteam.py +179 -73
  98. ccxt/async_support/bitvavo.py +180 -70
  99. ccxt/async_support/bl3p.py +92 -25
  100. ccxt/async_support/blockchaincom.py +193 -79
  101. ccxt/async_support/blofin.py +392 -148
  102. ccxt/async_support/btcalpha.py +161 -55
  103. ccxt/async_support/btcbox.py +250 -34
  104. ccxt/async_support/btcmarkets.py +232 -85
  105. ccxt/async_support/btcturk.py +159 -60
  106. ccxt/async_support/bybit.py +2231 -1193
  107. ccxt/async_support/cex.py +1409 -1329
  108. ccxt/async_support/coinbase.py +1454 -287
  109. ccxt/async_support/coinbaseadvanced.py +17 -0
  110. ccxt/async_support/{coinbasepro.py → coinbaseexchange.py} +233 -99
  111. ccxt/async_support/coinbaseinternational.py +428 -88
  112. ccxt/async_support/coincatch.py +5152 -0
  113. ccxt/async_support/coincheck.py +121 -38
  114. ccxt/async_support/coinex.py +4020 -3339
  115. ccxt/async_support/coinlist.py +273 -116
  116. ccxt/async_support/coinmate.py +204 -97
  117. ccxt/async_support/coinmetro.py +203 -110
  118. ccxt/async_support/coinone.py +142 -68
  119. ccxt/async_support/coinsph.py +206 -89
  120. ccxt/async_support/coinspot.py +137 -62
  121. ccxt/async_support/cryptocom.py +515 -185
  122. ccxt/async_support/currencycom.py +203 -85
  123. ccxt/async_support/defx.py +2066 -0
  124. ccxt/async_support/delta.py +404 -109
  125. ccxt/async_support/deribit.py +557 -323
  126. ccxt/async_support/digifinex.py +340 -223
  127. ccxt/async_support/ellipx.py +1826 -0
  128. ccxt/async_support/exmo.py +259 -128
  129. ccxt/async_support/gate.py +1472 -463
  130. ccxt/async_support/gemini.py +206 -84
  131. ccxt/async_support/hashkey.py +4164 -0
  132. ccxt/async_support/hitbtc.py +334 -178
  133. ccxt/async_support/hollaex.py +134 -83
  134. ccxt/async_support/htx.py +1095 -563
  135. ccxt/async_support/huobijp.py +105 -56
  136. ccxt/async_support/hyperliquid.py +1633 -268
  137. ccxt/async_support/idex.py +148 -95
  138. ccxt/async_support/independentreserve.py +236 -31
  139. ccxt/async_support/indodax.py +165 -62
  140. ccxt/async_support/kraken.py +871 -354
  141. ccxt/async_support/krakenfutures.py +324 -100
  142. ccxt/async_support/kucoin.py +917 -357
  143. ccxt/async_support/kucoinfutures.py +1004 -149
  144. ccxt/async_support/kuna.py +138 -106
  145. ccxt/async_support/latoken.py +135 -79
  146. ccxt/async_support/lbank.py +290 -113
  147. ccxt/async_support/luno.py +112 -62
  148. ccxt/async_support/lykke.py +104 -55
  149. ccxt/async_support/mercado.py +36 -29
  150. ccxt/async_support/mexc.py +995 -429
  151. ccxt/async_support/myokx.py +43 -0
  152. ccxt/async_support/ndax.py +163 -82
  153. ccxt/async_support/novadax.py +121 -75
  154. ccxt/async_support/oceanex.py +175 -59
  155. ccxt/async_support/okcoin.py +222 -163
  156. ccxt/async_support/okx.py +1776 -454
  157. ccxt/async_support/onetrading.py +132 -414
  158. ccxt/async_support/oxfun.py +2832 -0
  159. ccxt/async_support/p2b.py +79 -51
  160. ccxt/async_support/paradex.py +2017 -0
  161. ccxt/async_support/paymium.py +56 -32
  162. ccxt/async_support/phemex.py +572 -196
  163. ccxt/async_support/poloniex.py +218 -95
  164. ccxt/async_support/poloniexfutures.py +260 -92
  165. ccxt/async_support/probit.py +143 -110
  166. ccxt/async_support/timex.py +123 -70
  167. ccxt/async_support/tokocrypto.py +129 -93
  168. ccxt/async_support/tradeogre.py +39 -25
  169. ccxt/async_support/upbit.py +322 -113
  170. ccxt/async_support/vertex.py +2983 -0
  171. ccxt/async_support/wavesexchange.py +227 -173
  172. ccxt/async_support/wazirx.py +145 -65
  173. ccxt/async_support/whitebit.py +533 -138
  174. ccxt/async_support/woo.py +1137 -296
  175. ccxt/async_support/woofipro.py +2716 -0
  176. ccxt/async_support/xt.py +4628 -0
  177. ccxt/async_support/yobit.py +160 -92
  178. ccxt/async_support/zaif.py +80 -33
  179. ccxt/async_support/zonda.py +140 -69
  180. ccxt/base/errors.py +51 -20
  181. ccxt/base/exchange.py +1722 -480
  182. ccxt/base/precise.py +10 -0
  183. ccxt/base/types.py +223 -4
  184. ccxt/bequant.py +1 -1
  185. ccxt/bigone.py +329 -202
  186. ccxt/binance.py +3030 -1087
  187. ccxt/binancecoinm.py +2 -1
  188. ccxt/binanceus.py +12 -1
  189. ccxt/binanceusdm.py +3 -1
  190. ccxt/bingx.py +3104 -880
  191. ccxt/bit2c.py +119 -38
  192. ccxt/bitbank.py +215 -76
  193. ccxt/bitbns.py +124 -53
  194. ccxt/bitfinex.py +3235 -1078
  195. ccxt/bitfinex1.py +1710 -0
  196. ccxt/bitflyer.py +238 -49
  197. ccxt/bitget.py +1513 -563
  198. ccxt/bithumb.py +198 -65
  199. ccxt/bitmart.py +1320 -435
  200. ccxt/bitmex.py +308 -111
  201. ccxt/bitopro.py +256 -96
  202. ccxt/bitrue.py +365 -233
  203. ccxt/bitso.py +201 -89
  204. ccxt/bitstamp.py +438 -269
  205. ccxt/bitteam.py +179 -73
  206. ccxt/bitvavo.py +180 -70
  207. ccxt/bl3p.py +92 -25
  208. ccxt/blockchaincom.py +193 -79
  209. ccxt/blofin.py +392 -148
  210. ccxt/btcalpha.py +161 -55
  211. ccxt/btcbox.py +250 -34
  212. ccxt/btcmarkets.py +232 -85
  213. ccxt/btcturk.py +159 -60
  214. ccxt/bybit.py +2231 -1193
  215. ccxt/cex.py +1408 -1329
  216. ccxt/coinbase.py +1454 -287
  217. ccxt/coinbaseadvanced.py +17 -0
  218. ccxt/{coinbasepro.py → coinbaseexchange.py} +233 -99
  219. ccxt/coinbaseinternational.py +428 -88
  220. ccxt/coincatch.py +5152 -0
  221. ccxt/coincheck.py +121 -38
  222. ccxt/coinex.py +4020 -3339
  223. ccxt/coinlist.py +273 -116
  224. ccxt/coinmate.py +204 -97
  225. ccxt/coinmetro.py +203 -110
  226. ccxt/coinone.py +142 -68
  227. ccxt/coinsph.py +206 -89
  228. ccxt/coinspot.py +137 -62
  229. ccxt/cryptocom.py +515 -185
  230. ccxt/currencycom.py +203 -85
  231. ccxt/defx.py +2065 -0
  232. ccxt/delta.py +404 -109
  233. ccxt/deribit.py +557 -323
  234. ccxt/digifinex.py +340 -223
  235. ccxt/ellipx.py +1826 -0
  236. ccxt/exmo.py +259 -128
  237. ccxt/gate.py +1472 -463
  238. ccxt/gemini.py +206 -84
  239. ccxt/hashkey.py +4164 -0
  240. ccxt/hitbtc.py +334 -178
  241. ccxt/hollaex.py +134 -83
  242. ccxt/htx.py +1095 -563
  243. ccxt/huobijp.py +105 -56
  244. ccxt/hyperliquid.py +1632 -268
  245. ccxt/idex.py +148 -95
  246. ccxt/independentreserve.py +235 -31
  247. ccxt/indodax.py +165 -62
  248. ccxt/kraken.py +871 -354
  249. ccxt/krakenfutures.py +324 -100
  250. ccxt/kucoin.py +917 -357
  251. ccxt/kucoinfutures.py +1004 -149
  252. ccxt/kuna.py +138 -106
  253. ccxt/latoken.py +135 -79
  254. ccxt/lbank.py +290 -113
  255. ccxt/luno.py +112 -62
  256. ccxt/lykke.py +104 -55
  257. ccxt/mercado.py +36 -29
  258. ccxt/mexc.py +994 -429
  259. ccxt/myokx.py +43 -0
  260. ccxt/ndax.py +163 -82
  261. ccxt/novadax.py +121 -75
  262. ccxt/oceanex.py +175 -59
  263. ccxt/okcoin.py +222 -163
  264. ccxt/okx.py +1776 -454
  265. ccxt/onetrading.py +132 -414
  266. ccxt/oxfun.py +2831 -0
  267. ccxt/p2b.py +79 -51
  268. ccxt/paradex.py +2017 -0
  269. ccxt/paymium.py +56 -32
  270. ccxt/phemex.py +572 -196
  271. ccxt/poloniex.py +218 -95
  272. ccxt/poloniexfutures.py +260 -92
  273. ccxt/pro/__init__.py +29 -5
  274. ccxt/pro/alpaca.py +32 -17
  275. ccxt/pro/ascendex.py +62 -14
  276. ccxt/pro/bequant.py +4 -0
  277. ccxt/pro/binance.py +1596 -329
  278. ccxt/pro/binancecoinm.py +1 -0
  279. ccxt/pro/binanceus.py +2 -9
  280. ccxt/pro/binanceusdm.py +2 -0
  281. ccxt/pro/bingx.py +527 -134
  282. ccxt/pro/bitcoincom.py +4 -1
  283. ccxt/pro/bitfinex.py +731 -266
  284. ccxt/pro/bitfinex1.py +635 -0
  285. ccxt/pro/bitget.py +726 -357
  286. ccxt/pro/bithumb.py +380 -0
  287. ccxt/pro/bitmart.py +138 -39
  288. ccxt/pro/bitmex.py +199 -40
  289. ccxt/pro/bitopro.py +25 -13
  290. ccxt/pro/bitrue.py +31 -32
  291. ccxt/pro/bitstamp.py +7 -6
  292. ccxt/pro/bitvavo.py +203 -81
  293. ccxt/pro/blockchaincom.py +30 -17
  294. ccxt/pro/blofin.py +692 -0
  295. ccxt/pro/bybit.py +791 -82
  296. ccxt/pro/cex.py +99 -51
  297. ccxt/pro/coinbase.py +220 -30
  298. ccxt/{async_support/hitbtc3.py → pro/coinbaseadvanced.py} +5 -5
  299. ccxt/pro/{coinbasepro.py → coinbaseexchange.py} +19 -19
  300. ccxt/pro/coinbaseinternational.py +193 -30
  301. ccxt/pro/coincatch.py +1464 -0
  302. ccxt/pro/coincheck.py +11 -6
  303. ccxt/pro/coinex.py +965 -665
  304. ccxt/pro/coinone.py +17 -10
  305. ccxt/pro/cryptocom.py +446 -66
  306. ccxt/pro/currencycom.py +11 -10
  307. ccxt/pro/defx.py +832 -0
  308. ccxt/pro/deribit.py +167 -31
  309. ccxt/pro/exmo.py +252 -20
  310. ccxt/pro/gate.py +729 -64
  311. ccxt/pro/gemini.py +44 -26
  312. ccxt/pro/hashkey.py +802 -0
  313. ccxt/pro/hitbtc.py +208 -103
  314. ccxt/pro/hollaex.py +25 -9
  315. ccxt/pro/htx.py +83 -39
  316. ccxt/pro/huobijp.py +17 -16
  317. ccxt/pro/hyperliquid.py +502 -31
  318. ccxt/pro/idex.py +28 -13
  319. ccxt/pro/independentreserve.py +21 -16
  320. ccxt/pro/kraken.py +298 -51
  321. ccxt/pro/krakenfutures.py +166 -75
  322. ccxt/pro/kucoin.py +395 -77
  323. ccxt/pro/kucoinfutures.py +400 -99
  324. ccxt/pro/lbank.py +52 -31
  325. ccxt/pro/luno.py +12 -10
  326. ccxt/pro/mexc.py +400 -50
  327. ccxt/pro/myokx.py +28 -0
  328. ccxt/pro/ndax.py +25 -12
  329. ccxt/pro/okcoin.py +28 -9
  330. ccxt/pro/okx.py +935 -124
  331. ccxt/pro/onetrading.py +41 -24
  332. ccxt/pro/oxfun.py +1054 -0
  333. ccxt/pro/p2b.py +100 -24
  334. ccxt/pro/paradex.py +352 -0
  335. ccxt/pro/phemex.py +92 -33
  336. ccxt/pro/poloniex.py +128 -49
  337. ccxt/pro/poloniexfutures.py +53 -32
  338. ccxt/pro/probit.py +92 -85
  339. ccxt/pro/upbit.py +401 -8
  340. ccxt/pro/vertex.py +943 -0
  341. ccxt/pro/wazirx.py +46 -28
  342. ccxt/pro/whitebit.py +65 -12
  343. ccxt/pro/woo.py +437 -65
  344. ccxt/pro/woofipro.py +1271 -0
  345. ccxt/pro/xt.py +1067 -0
  346. ccxt/probit.py +143 -110
  347. ccxt/static_dependencies/__init__.py +1 -1
  348. ccxt/static_dependencies/lark/__init__.py +38 -0
  349. ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  350. ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  351. ccxt/static_dependencies/lark/ast_utils.py +59 -0
  352. ccxt/static_dependencies/lark/common.py +86 -0
  353. ccxt/static_dependencies/lark/exceptions.py +292 -0
  354. ccxt/static_dependencies/lark/grammar.py +130 -0
  355. ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  356. ccxt/static_dependencies/lark/indenter.py +143 -0
  357. ccxt/static_dependencies/lark/lark.py +658 -0
  358. ccxt/static_dependencies/lark/lexer.py +678 -0
  359. ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  360. ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  361. ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  362. ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  363. ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  364. ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  365. ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  366. ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  367. ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  368. ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  369. ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  370. ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  371. ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  372. ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  373. ccxt/static_dependencies/lark/py.typed +0 -0
  374. ccxt/static_dependencies/lark/reconstruct.py +107 -0
  375. ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  376. ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  377. ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  378. ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  379. ccxt/static_dependencies/lark/tree.py +267 -0
  380. ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  381. ccxt/static_dependencies/lark/tree_templates.py +180 -0
  382. ccxt/static_dependencies/lark/utils.py +343 -0
  383. ccxt/static_dependencies/lark/visitors.py +596 -0
  384. ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  385. ccxt/static_dependencies/marshmallow/base.py +65 -0
  386. ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  387. ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  388. ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  389. ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  390. ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  391. ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  392. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  393. ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  394. ccxt/static_dependencies/marshmallow/types.py +12 -0
  395. ccxt/static_dependencies/marshmallow/utils.py +378 -0
  396. ccxt/static_dependencies/marshmallow/validate.py +678 -0
  397. ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  398. ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  399. ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  400. ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  401. ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  402. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  403. ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  404. ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  405. ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  406. ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  407. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  408. ccxt/static_dependencies/starknet/__init__.py +0 -0
  409. ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  410. ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  411. ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  412. ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  413. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  414. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  415. ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  416. ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  417. ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  418. ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  419. ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  420. ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  421. ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  422. ccxt/static_dependencies/starknet/common.py +15 -0
  423. ccxt/static_dependencies/starknet/constants.py +39 -0
  424. ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  425. ccxt/static_dependencies/starknet/hash/address.py +79 -0
  426. ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  427. ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  428. ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  429. ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  430. ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  431. ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
  432. ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  433. ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  434. ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  435. ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  436. ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  437. ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  438. ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  439. ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  440. ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  441. ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  442. ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  443. ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  444. ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  445. ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  446. ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  447. ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  448. ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  449. ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  450. ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  451. ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  452. ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  453. ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  454. ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  455. ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  456. ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  457. ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  458. ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  459. ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  460. ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  461. ccxt/static_dependencies/starkware/__init__.py +0 -0
  462. ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  463. ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
  464. ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
  465. ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
  466. ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
  467. ccxt/static_dependencies/sympy/__init__.py +0 -0
  468. ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  469. ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
  470. ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  471. ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  472. ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  473. ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  474. ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  475. ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  476. ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  477. ccxt/test/{test_async.py → tests_async.py} +456 -391
  478. ccxt/test/tests_helpers.py +285 -0
  479. ccxt/test/tests_init.py +39 -0
  480. ccxt/test/{test_sync.py → tests_sync.py} +456 -393
  481. ccxt/timex.py +123 -70
  482. ccxt/tokocrypto.py +129 -93
  483. ccxt/tradeogre.py +39 -25
  484. ccxt/upbit.py +322 -113
  485. ccxt/vertex.py +2983 -0
  486. ccxt/wavesexchange.py +227 -173
  487. ccxt/wazirx.py +145 -65
  488. ccxt/whitebit.py +533 -138
  489. ccxt/woo.py +1137 -296
  490. ccxt/woofipro.py +2716 -0
  491. ccxt/xt.py +4627 -0
  492. ccxt/yobit.py +159 -92
  493. ccxt/zaif.py +80 -33
  494. ccxt/zonda.py +140 -69
  495. ccxt-4.4.48.dist-info/LICENSE.txt +21 -0
  496. ccxt-4.4.48.dist-info/METADATA +646 -0
  497. ccxt-4.4.48.dist-info/RECORD +669 -0
  498. {ccxt-4.2.77.dist-info → ccxt-4.4.48.dist-info}/WHEEL +1 -1
  499. ccxt/abstract/bitbay.py +0 -47
  500. ccxt/abstract/bitfinex2.py +0 -139
  501. ccxt/abstract/hitbtc3.py +0 -115
  502. ccxt/async_support/bitbay.py +0 -17
  503. ccxt/async_support/bitfinex2.py +0 -3496
  504. ccxt/async_support/flowbtc.py +0 -34
  505. ccxt/bitbay.py +0 -17
  506. ccxt/bitfinex2.py +0 -3496
  507. ccxt/flowbtc.py +0 -34
  508. ccxt/hitbtc3.py +0 -16
  509. ccxt/pro/bitfinex2.py +0 -1081
  510. ccxt/test/base/__init__.py +0 -28
  511. ccxt/test/base/test_account.py +0 -26
  512. ccxt/test/base/test_balance.py +0 -56
  513. ccxt/test/base/test_borrow_interest.py +0 -35
  514. ccxt/test/base/test_borrow_rate.py +0 -32
  515. ccxt/test/base/test_calculate_fee.py +0 -51
  516. ccxt/test/base/test_crypto.py +0 -127
  517. ccxt/test/base/test_currency.py +0 -76
  518. ccxt/test/base/test_datetime.py +0 -103
  519. ccxt/test/base/test_decimal_to_precision.py +0 -392
  520. ccxt/test/base/test_deep_extend.py +0 -68
  521. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  522. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  523. ccxt/test/base/test_funding_rate_history.py +0 -29
  524. ccxt/test/base/test_last_price.py +0 -32
  525. ccxt/test/base/test_ledger_entry.py +0 -45
  526. ccxt/test/base/test_ledger_item.py +0 -48
  527. ccxt/test/base/test_leverage_tier.py +0 -33
  528. ccxt/test/base/test_margin_mode.py +0 -24
  529. ccxt/test/base/test_margin_modification.py +0 -35
  530. ccxt/test/base/test_market.py +0 -190
  531. ccxt/test/base/test_number.py +0 -411
  532. ccxt/test/base/test_ohlcv.py +0 -32
  533. ccxt/test/base/test_open_interest.py +0 -32
  534. ccxt/test/base/test_order.py +0 -64
  535. ccxt/test/base/test_order_book.py +0 -63
  536. ccxt/test/base/test_position.py +0 -60
  537. ccxt/test/base/test_shared_methods.py +0 -345
  538. ccxt/test/base/test_status.py +0 -24
  539. ccxt/test/base/test_throttle.py +0 -126
  540. ccxt/test/base/test_ticker.py +0 -86
  541. ccxt/test/base/test_trade.py +0 -47
  542. ccxt/test/base/test_trading_fee.py +0 -26
  543. ccxt/test/base/test_transaction.py +0 -39
  544. ccxt-4.2.77.dist-info/METADATA +0 -626
  545. ccxt-4.2.77.dist-info/RECORD +0 -534
  546. {ccxt-4.2.77.dist-info → ccxt-4.4.48.dist-info}/top_level.txt +0 -0
ccxt/pro/cryptocom.py CHANGED
@@ -6,12 +6,14 @@
6
6
  import ccxt.async_support
7
7
  from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Int, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Trade
9
+ from ccxt.base.types import Balances, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade
10
10
  from ccxt.async_support.base.ws.client import Client
11
11
  from typing import List
12
- from ccxt.base.errors import NetworkError
13
- from ccxt.base.errors import InvalidNonce
12
+ from typing import Any
13
+ from ccxt.base.errors import ExchangeError
14
14
  from ccxt.base.errors import AuthenticationError
15
+ from ccxt.base.errors import NetworkError
16
+ from ccxt.base.errors import ChecksumError
15
17
 
16
18
 
17
19
  class cryptocom(ccxt.async_support.cryptocom):
@@ -22,7 +24,8 @@ class cryptocom(ccxt.async_support.cryptocom):
22
24
  'ws': True,
23
25
  'watchBalance': True,
24
26
  'watchTicker': True,
25
- 'watchTickers': False,
27
+ 'watchTickers': True,
28
+ 'watchBidsAsks': True,
26
29
  'watchMyTrades': True,
27
30
  'watchTrades': True,
28
31
  'watchTradesForSymbols': True,
@@ -52,6 +55,9 @@ class cryptocom(ccxt.async_support.cryptocom):
52
55
  'fetchPositionsSnapshot': True, # or False
53
56
  'awaitPositionsSnapshot': True, # whether to wait for the positions snapshot before providing updates
54
57
  },
58
+ 'watchOrderBook': {
59
+ 'checksum': True,
60
+ },
55
61
  },
56
62
  'streaming': {
57
63
  },
@@ -72,7 +78,9 @@ class cryptocom(ccxt.async_support.cryptocom):
72
78
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
73
79
  """
74
80
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
75
- :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#book-instrument_name
81
+
82
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#book-instrument_name
83
+
76
84
  :param str symbol: unified symbol of the market to fetch the order book for
77
85
  :param int [limit]: the maximum amount of order book entries to return
78
86
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -82,10 +90,26 @@ class cryptocom(ccxt.async_support.cryptocom):
82
90
  """
83
91
  return await self.watch_order_book_for_symbols([symbol], limit, params)
84
92
 
93
+ async def un_watch_order_book(self, symbol: str, params={}) -> Any:
94
+ """
95
+ unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
96
+
97
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#book-instrument_name
98
+
99
+ :param str symbol: unified symbol of the market to fetch the order book for
100
+ :param dict [params]: extra parameters specific to the exchange API endpoint
101
+ :param str [params.bookSubscriptionType]: The subscription type. Allowed values: SNAPSHOT full snapshot. This is the default if not specified. SNAPSHOT_AND_UPDATE delta updates
102
+ :param int [params.bookUpdateFrequency]: Book update interval in ms. Allowed values: 100 for snapshot subscription 10 for delta subscription
103
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
104
+ """
105
+ return await self.un_watch_order_book_for_symbols([symbol], params)
106
+
85
107
  async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
86
108
  """
87
109
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
88
- :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#book-instrument_name
110
+
111
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#book-instrument_name
112
+
89
113
  :param str[] symbols: unified array of symbols
90
114
  :param int [limit]: the maximum amount of order book entries to return
91
115
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -103,13 +127,16 @@ class cryptocom(ccxt.async_support.cryptocom):
103
127
  if topicParams is None:
104
128
  params['params'] = {}
105
129
  bookSubscriptionType = None
106
- bookSubscriptionType, params = self.handle_option_and_params_2(params, 'watchOrderBook', 'watchOrderBookForSymbols', 'bookSubscriptionType', 'SNAPSHOT_AND_UPDATE')
107
- if bookSubscriptionType is not None:
108
- params['params']['bookSubscriptionType'] = bookSubscriptionType
130
+ bookSubscriptionType2 = None
131
+ bookSubscriptionType, params = self.handle_option_and_params(params, 'watchOrderBook', 'bookSubscriptionType', 'SNAPSHOT_AND_UPDATE')
132
+ bookSubscriptionType2, params = self.handle_option_and_params(params, 'watchOrderBookForSymbols', 'bookSubscriptionType', bookSubscriptionType)
133
+ params['params']['bookSubscriptionType'] = bookSubscriptionType2
109
134
  bookUpdateFrequency = None
110
- bookUpdateFrequency, params = self.handle_option_and_params_2(params, 'watchOrderBook', 'watchOrderBookForSymbols', 'bookUpdateFrequency')
111
- if bookUpdateFrequency is not None:
112
- params['params']['bookSubscriptionType'] = bookSubscriptionType
135
+ bookUpdateFrequency2 = None
136
+ bookUpdateFrequency, params = self.handle_option_and_params(params, 'watchOrderBook', 'bookUpdateFrequency')
137
+ bookUpdateFrequency2, params = self.handle_option_and_params(params, 'watchOrderBookForSymbols', 'bookUpdateFrequency', bookUpdateFrequency)
138
+ if bookUpdateFrequency2 is not None:
139
+ params['params']['bookSubscriptionType'] = bookUpdateFrequency2
113
140
  for i in range(0, len(symbols)):
114
141
  symbol = symbols[i]
115
142
  market = self.market(symbol)
@@ -120,11 +147,54 @@ class cryptocom(ccxt.async_support.cryptocom):
120
147
  orderbook = await self.watch_public_multiple(messageHashes, topics, params)
121
148
  return orderbook.limit()
122
149
 
150
+ async def un_watch_order_book_for_symbols(self, symbols: List[str], params={}) -> OrderBook:
151
+ """
152
+ unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
153
+
154
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#book-instrument_name
155
+
156
+ :param str[] symbols: unified array of symbols
157
+ :param dict [params]: extra parameters specific to the exchange API endpoint
158
+ :param int [params.limit]: orderbook limit, default is 50
159
+ :param str [params.bookSubscriptionType]: The subscription type. Allowed values: SNAPSHOT full snapshot. This is the default if not specified. SNAPSHOT_AND_UPDATE delta updates
160
+ :param int [params.bookUpdateFrequency]: Book update interval in ms. Allowed values: 100 for snapshot subscription 10 for delta subscription
161
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
162
+ """
163
+ await self.load_markets()
164
+ symbols = self.market_symbols(symbols)
165
+ topics = []
166
+ subMessageHashes = []
167
+ messageHashes = []
168
+ limit = self.safe_integer(params, 'limit', 50)
169
+ topicParams = self.safe_value(params, 'params')
170
+ if topicParams is None:
171
+ params['params'] = {}
172
+ bookSubscriptionType = None
173
+ bookSubscriptionType2 = None
174
+ bookSubscriptionType, params = self.handle_option_and_params(params, 'watchOrderBook', 'bookSubscriptionType', 'SNAPSHOT_AND_UPDATE')
175
+ bookSubscriptionType2, params = self.handle_option_and_params(params, 'watchOrderBookForSymbols', 'bookSubscriptionType', bookSubscriptionType)
176
+ params['params']['bookSubscriptionType'] = bookSubscriptionType2
177
+ bookUpdateFrequency = None
178
+ bookUpdateFrequency2 = None
179
+ bookUpdateFrequency, params = self.handle_option_and_params(params, 'watchOrderBook', 'bookUpdateFrequency')
180
+ bookUpdateFrequency2, params = self.handle_option_and_params(params, 'watchOrderBookForSymbols', 'bookUpdateFrequency', bookUpdateFrequency)
181
+ if bookUpdateFrequency2 is not None:
182
+ params['params']['bookSubscriptionType'] = bookUpdateFrequency2
183
+ for i in range(0, len(symbols)):
184
+ symbol = symbols[i]
185
+ market = self.market(symbol)
186
+ currentTopic = 'book' + '.' + market['id'] + '.' + str(limit)
187
+ messageHash = 'orderbook:' + market['symbol']
188
+ subMessageHashes.append(messageHash)
189
+ messageHashes.append('unsubscribe:' + messageHash)
190
+ topics.append(currentTopic)
191
+ return await self.un_watch_public_multiple('orderbook', symbols, messageHashes, subMessageHashes, topics, params)
192
+
123
193
  def handle_delta(self, bookside, delta):
124
194
  price = self.safe_float(delta, 0)
125
195
  amount = self.safe_float(delta, 1)
126
196
  count = self.safe_integer(delta, 2)
127
- bookside.store(price, amount, count)
197
+ bookside.storeArray([price, amount, count])
128
198
 
129
199
  def handle_deltas(self, bookside, deltas):
130
200
  for i in range(0, len(deltas)):
@@ -192,10 +262,10 @@ class cryptocom(ccxt.async_support.cryptocom):
192
262
  data = self.safe_value(message, 'data')
193
263
  data = self.safe_value(data, 0)
194
264
  timestamp = self.safe_integer(data, 't')
195
- orderbook = self.safe_value(self.orderbooks, symbol)
196
- if orderbook is None:
265
+ if not (symbol in self.orderbooks):
197
266
  limit = self.safe_integer(message, 'depth')
198
- orderbook = self.counted_order_book({}, limit)
267
+ self.orderbooks[symbol] = self.counted_order_book({}, limit)
268
+ orderbook = self.orderbooks[symbol]
199
269
  channel = self.safe_string(message, 'channel')
200
270
  nonce = self.safe_integer_2(data, 'u', 's')
201
271
  books = data
@@ -210,7 +280,9 @@ class cryptocom(ccxt.async_support.cryptocom):
210
280
  previousNonce = self.safe_integer(data, 'pu')
211
281
  currentNonce = orderbook['nonce']
212
282
  if currentNonce != previousNonce:
213
- raise InvalidNonce(self.id + ' watchOrderBook() ' + symbol + ' ' + previousNonce + ' != ' + nonce)
283
+ checksum = self.handle_option('watchOrderBook', 'checksum', True)
284
+ if checksum:
285
+ raise ChecksumError(self.id + ' ' + self.orderbook_checksum_message(symbol))
214
286
  self.handle_deltas(orderbook['asks'], self.safe_value(books, 'asks', []))
215
287
  self.handle_deltas(orderbook['bids'], self.safe_value(books, 'bids', []))
216
288
  orderbook['nonce'] = nonce
@@ -221,7 +293,9 @@ class cryptocom(ccxt.async_support.cryptocom):
221
293
  async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
222
294
  """
223
295
  get the list of most recent trades for a particular symbol
224
- :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#trade-instrument_name
296
+
297
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#trade-instrument_name
298
+
225
299
  :param str symbol: unified symbol of the market to fetch trades for
226
300
  :param int [since]: timestamp in ms of the earliest trade to fetch
227
301
  :param int [limit]: the maximum amount of trades to fetch
@@ -230,11 +304,25 @@ class cryptocom(ccxt.async_support.cryptocom):
230
304
  """
231
305
  return await self.watch_trades_for_symbols([symbol], since, limit, params)
232
306
 
233
- async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
307
+ async def un_watch_trades(self, symbol: str, params={}) -> List[Trade]:
234
308
  """
235
309
  get the list of most recent trades for a particular symbol
236
- :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#trade-instrument_name
310
+
311
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#trade-instrument_name
312
+
237
313
  :param str symbol: unified symbol of the market to fetch trades for
314
+ :param dict [params]: extra parameters specific to the exchange API endpoint
315
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
316
+ """
317
+ return await self.un_watch_trades_for_symbols([symbol], params)
318
+
319
+ async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
320
+ """
321
+ get the list of most recent trades for a particular symbol
322
+
323
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#trade-instrument_name
324
+
325
+ :param str[] symbols: unified symbol of the market to fetch trades for
238
326
  :param int [since]: timestamp in ms of the earliest trade to fetch
239
327
  :param int [limit]: the maximum amount of trades to fetch
240
328
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -255,6 +343,28 @@ class cryptocom(ccxt.async_support.cryptocom):
255
343
  limit = trades.getLimit(tradeSymbol, limit)
256
344
  return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
257
345
 
346
+ async def un_watch_trades_for_symbols(self, symbols: List[str], params={}) -> Any:
347
+ """
348
+ get the list of most recent trades for a particular symbol
349
+
350
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#trade-instrument_name
351
+
352
+ :param str[] [symbols]: list of unified market symbols to unwatch trades for
353
+ :param dict [params]: extra parameters specific to the exchange API endpoint
354
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
355
+ """
356
+ await self.load_markets()
357
+ symbols = self.market_symbols(symbols)
358
+ topics = []
359
+ messageHashes = []
360
+ for i in range(0, len(symbols)):
361
+ symbol = symbols[i]
362
+ market = self.market(symbol)
363
+ currentTopic = 'trade' + '.' + market['id']
364
+ messageHashes.append('unsubscribe:trades:' + market['symbol'])
365
+ topics.append(currentTopic)
366
+ return await self.un_watch_public_multiple('trades', symbols, messageHashes, topics, topics, params)
367
+
258
368
  def handle_trades(self, client: Client, message):
259
369
  #
260
370
  # {
@@ -302,12 +412,14 @@ class cryptocom(ccxt.async_support.cryptocom):
302
412
  async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
303
413
  """
304
414
  watches information on multiple trades made by the user
305
- :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#user-trade-instrument_name
415
+
416
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#user-trade-instrument_name
417
+
306
418
  :param str symbol: unified market symbol of the market trades were made in
307
419
  :param int [since]: the earliest time in ms to fetch trades for
308
420
  :param int [limit]: the maximum number of trade structures to retrieve
309
421
  :param dict [params]: extra parameters specific to the exchange API endpoint
310
- :returns dict[]: a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
422
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
311
423
  """
312
424
  await self.load_markets()
313
425
  market = None
@@ -324,7 +436,9 @@ class cryptocom(ccxt.async_support.cryptocom):
324
436
  async def watch_ticker(self, symbol: str, params={}) -> Ticker:
325
437
  """
326
438
  watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
327
- :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#ticker-instrument_name
439
+
440
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#ticker-instrument_name
441
+
328
442
  :param str symbol: unified symbol of the market to fetch the ticker for
329
443
  :param dict [params]: extra parameters specific to the exchange API endpoint
330
444
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -334,44 +448,226 @@ class cryptocom(ccxt.async_support.cryptocom):
334
448
  messageHash = 'ticker' + '.' + market['id']
335
449
  return await self.watch_public(messageHash, params)
336
450
 
451
+ async def un_watch_ticker(self, symbol: str, params={}) -> Any:
452
+ """
453
+ unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
454
+
455
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#ticker-instrument_name
456
+
457
+ :param str symbol: unified symbol of the market to fetch the ticker for
458
+ :param dict [params]: extra parameters specific to the exchange API endpoint
459
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
460
+ """
461
+ await self.load_markets()
462
+ market = self.market(symbol)
463
+ subMessageHash = 'ticker' + '.' + market['id']
464
+ messageHash = 'unsubscribe:ticker:' + market['symbol']
465
+ return await self.un_watch_public_multiple('ticker', [market['symbol']], [messageHash], [subMessageHash], [subMessageHash], params)
466
+
467
+ async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
468
+ """
469
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
470
+
471
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#ticker-instrument_name
472
+
473
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
474
+ :param dict [params]: extra parameters specific to the exchange API endpoint
475
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
476
+ """
477
+ await self.load_markets()
478
+ symbols = self.market_symbols(symbols, None, False)
479
+ messageHashes = []
480
+ marketIds = self.market_ids(symbols)
481
+ for i in range(0, len(marketIds)):
482
+ marketId = marketIds[i]
483
+ messageHashes.append('ticker.' + marketId)
484
+ url = self.urls['api']['ws']['public']
485
+ id = self.nonce()
486
+ request: dict = {
487
+ 'method': 'subscribe',
488
+ 'params': {
489
+ 'channels': messageHashes,
490
+ },
491
+ 'nonce': id,
492
+ }
493
+ ticker = await self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
494
+ if self.newUpdates:
495
+ result: dict = {}
496
+ result[ticker['symbol']] = ticker
497
+ return result
498
+ return self.filter_by_array(self.tickers, 'symbol', symbols)
499
+
500
+ async def un_watch_tickers(self, symbols: Strings = None, params={}) -> Any:
501
+ """
502
+ unWatches a price ticker
503
+
504
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#ticker-instrument_name
505
+
506
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
507
+ :param dict [params]: extra parameters specific to the exchange API endpoint
508
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
509
+ """
510
+ await self.load_markets()
511
+ symbols = self.market_symbols(symbols, None, False)
512
+ messageHashes = []
513
+ subMessageHashes = []
514
+ marketIds = self.market_ids(symbols)
515
+ for i in range(0, len(marketIds)):
516
+ marketId = marketIds[i]
517
+ symbol = symbols[i]
518
+ subMessageHashes.append('ticker.' + marketId)
519
+ messageHashes.append('unsubscribe:ticker:' + symbol)
520
+ return await self.un_watch_public_multiple('ticker', symbols, messageHashes, subMessageHashes, subMessageHashes, params)
521
+
337
522
  def handle_ticker(self, client: Client, message):
338
523
  #
339
- # {
340
- # "info":{
341
- # "instrument_name":"BTC_USDT",
342
- # "subscription":"ticker.BTC_USDT",
343
- # "channel":"ticker",
344
- # "data":[
345
- # {
346
- # "i":"BTC_USDT",
347
- # "b":43063.19,
348
- # "k":43063.2,
349
- # "a":43063.19,
350
- # "t":1648121165658,
351
- # "v":43573.912409,
352
- # "h":43498.51,
353
- # "l":41876.58,
354
- # "c":1087.43
355
- # }
356
- # ]
524
+ # {
525
+ # "instrument_name": "ETHUSD-PERP",
526
+ # "subscription": "ticker.ETHUSD-PERP",
527
+ # "channel": "ticker",
528
+ # "data": [
529
+ # {
530
+ # "h": "2400.20",
531
+ # "l": "2277.10",
532
+ # "a": "2335.25",
533
+ # "c": "-0.0022",
534
+ # "b": "2335.10",
535
+ # "bs": "5.4000",
536
+ # "k": "2335.16",
537
+ # "ks": "1.9970",
538
+ # "i": "ETHUSD-PERP",
539
+ # "v": "1305697.6462",
540
+ # "vv": "3058704939.17",
541
+ # "oi": "161646.3614",
542
+ # "t": 1726069647560
543
+ # }
544
+ # ]
357
545
  # }
358
- # }
359
546
  #
547
+ self.handle_bid_ask(client, message)
360
548
  messageHash = self.safe_string(message, 'subscription')
361
549
  marketId = self.safe_string(message, 'instrument_name')
362
550
  market = self.safe_market(marketId)
363
551
  data = self.safe_value(message, 'data', [])
364
552
  for i in range(0, len(data)):
365
553
  ticker = data[i]
366
- parsed = self.parse_ticker(ticker, market)
554
+ parsed = self.parse_ws_ticker(ticker, market)
367
555
  symbol = parsed['symbol']
368
556
  self.tickers[symbol] = parsed
369
557
  client.resolve(parsed, messageHash)
370
558
 
559
+ def parse_ws_ticker(self, ticker: dict, market: Market = None) -> Ticker:
560
+ #
561
+ # {
562
+ # "h": "2400.20",
563
+ # "l": "2277.10",
564
+ # "a": "2335.25",
565
+ # "c": "-0.0022",
566
+ # "b": "2335.10",
567
+ # "bs": "5.4000",
568
+ # "k": "2335.16",
569
+ # "ks": "1.9970",
570
+ # "i": "ETHUSD-PERP",
571
+ # "v": "1305697.6462",
572
+ # "vv": "3058704939.17",
573
+ # "oi": "161646.3614",
574
+ # "t": 1726069647560
575
+ # }
576
+ #
577
+ timestamp = self.safe_integer(ticker, 't')
578
+ marketId = self.safe_string(ticker, 'i')
579
+ market = self.safe_market(marketId, market, '_')
580
+ quote = self.safe_string(market, 'quote')
581
+ last = self.safe_string(ticker, 'a')
582
+ return self.safe_ticker({
583
+ 'symbol': market['symbol'],
584
+ 'timestamp': timestamp,
585
+ 'datetime': self.iso8601(timestamp),
586
+ 'high': self.safe_number(ticker, 'h'),
587
+ 'low': self.safe_number(ticker, 'l'),
588
+ 'bid': self.safe_number(ticker, 'b'),
589
+ 'bidVolume': self.safe_number(ticker, 'bs'),
590
+ 'ask': self.safe_number(ticker, 'k'),
591
+ 'askVolume': self.safe_number(ticker, 'ks'),
592
+ 'vwap': None,
593
+ 'open': None,
594
+ 'close': last,
595
+ 'last': last,
596
+ 'previousClose': None,
597
+ 'change': None,
598
+ 'percentage': self.safe_string(ticker, 'c'),
599
+ 'average': None,
600
+ 'baseVolume': self.safe_string(ticker, 'v'),
601
+ 'quoteVolume': self.safe_string(ticker, 'vv') if (quote == 'USD') else None,
602
+ 'info': ticker,
603
+ }, market)
604
+
605
+ async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
606
+ """
607
+
608
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#ticker-instrument_name
609
+
610
+ watches best bid & ask for symbols
611
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
612
+ :param dict [params]: extra parameters specific to the exchange API endpoint
613
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
614
+ """
615
+ await self.load_markets()
616
+ symbols = self.market_symbols(symbols, None, False)
617
+ messageHashes = []
618
+ topics = []
619
+ marketIds = self.market_ids(symbols)
620
+ for i in range(0, len(marketIds)):
621
+ marketId = marketIds[i]
622
+ messageHashes.append('bidask.' + symbols[i])
623
+ topics.append('ticker.' + marketId)
624
+ url = self.urls['api']['ws']['public']
625
+ id = self.nonce()
626
+ request: dict = {
627
+ 'method': 'subscribe',
628
+ 'params': {
629
+ 'channels': topics,
630
+ },
631
+ 'nonce': id,
632
+ }
633
+ newTickers = await self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
634
+ if self.newUpdates:
635
+ tickers: dict = {}
636
+ tickers[newTickers['symbol']] = newTickers
637
+ return tickers
638
+ return self.filter_by_array(self.bidsasks, 'symbol', symbols)
639
+
640
+ def handle_bid_ask(self, client: Client, message):
641
+ data = self.safe_list(message, 'data', [])
642
+ ticker = self.safe_dict(data, 0, {})
643
+ parsedTicker = self.parse_ws_bid_ask(ticker)
644
+ symbol = parsedTicker['symbol']
645
+ self.bidsasks[symbol] = parsedTicker
646
+ messageHash = 'bidask.' + symbol
647
+ client.resolve(parsedTicker, messageHash)
648
+
649
+ def parse_ws_bid_ask(self, ticker, market=None):
650
+ marketId = self.safe_string(ticker, 'i')
651
+ market = self.safe_market(marketId, market)
652
+ symbol = self.safe_string(market, 'symbol')
653
+ timestamp = self.safe_integer(ticker, 't')
654
+ return self.safe_ticker({
655
+ 'symbol': symbol,
656
+ 'timestamp': timestamp,
657
+ 'datetime': self.iso8601(timestamp),
658
+ 'ask': self.safe_string(ticker, 'k'),
659
+ 'askVolume': self.safe_string(ticker, 'ks'),
660
+ 'bid': self.safe_string(ticker, 'b'),
661
+ 'bidVolume': self.safe_string(ticker, 'bs'),
662
+ 'info': ticker,
663
+ }, market)
664
+
371
665
  async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
372
666
  """
373
667
  watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
374
- :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#candlestick-time_frame-instrument_name
668
+
669
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#candlestick-time_frame-instrument_name
670
+
375
671
  :param str symbol: unified symbol of the market to fetch OHLCV data for
376
672
  :param str timeframe: the length of time each candle represents
377
673
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -389,6 +685,28 @@ class cryptocom(ccxt.async_support.cryptocom):
389
685
  limit = ohlcv.getLimit(symbol, limit)
390
686
  return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
391
687
 
688
+ async def un_watch_ohlcv(self, symbol: str, timeframe='1m', params={}) -> Any:
689
+ """
690
+ unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
691
+
692
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#candlestick-time_frame-instrument_name
693
+
694
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
695
+ :param str timeframe: the length of time each candle represents
696
+ :param dict [params]: extra parameters specific to the exchange API endpoint
697
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
698
+ """
699
+ await self.load_markets()
700
+ market = self.market(symbol)
701
+ symbol = market['symbol']
702
+ interval = self.safe_string(self.timeframes, timeframe, timeframe)
703
+ subMessageHash = 'candlestick' + '.' + interval + '.' + market['id']
704
+ messageHash = 'unsubscribe:ohlcv:' + market['symbol'] + ':' + timeframe
705
+ subExtend = {
706
+ 'symbolsAndTimeframes': [[market['symbol'], timeframe]],
707
+ }
708
+ return await self.un_watch_public_multiple('ohlcv', [market['symbol']], [messageHash], [subMessageHash], [subMessageHash], params, subExtend)
709
+
392
710
  def handle_ohlcv(self, client: Client, message):
393
711
  #
394
712
  # {
@@ -422,7 +740,9 @@ class cryptocom(ccxt.async_support.cryptocom):
422
740
  async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
423
741
  """
424
742
  watches information on multiple orders made by the user
425
- :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#user-order-instrument_name
743
+
744
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#user-order-instrument_name
745
+
426
746
  :param str symbol: unified market symbol of the market orders were made in
427
747
  :param int [since]: the earliest time in ms to fetch orders for
428
748
  :param int [limit]: the maximum number of order structures to retrieve
@@ -492,8 +812,12 @@ class cryptocom(ccxt.async_support.cryptocom):
492
812
  async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
493
813
  """
494
814
  watch all open positions
495
- :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#user-position_balance
496
- :param str[]|None symbols: list of unified market symbols
815
+
816
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#user-position_balance
817
+
818
+ :param str[] [symbols]: list of unified market symbols to watch positions for
819
+ :param int [since]: the earliest time in ms to fetch positions for
820
+ :param int [limit]: the maximum number of positions to retrieve
497
821
  :param dict params: extra parameters specific to the exchange API endpoint
498
822
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
499
823
  """
@@ -501,7 +825,7 @@ class cryptocom(ccxt.async_support.cryptocom):
501
825
  await self.authenticate()
502
826
  url = self.urls['api']['ws']['private']
503
827
  id = self.nonce()
504
- request = {
828
+ request: dict = {
505
829
  'method': 'subscribe',
506
830
  'params': {
507
831
  'channels': ['user.position_balance'],
@@ -515,7 +839,7 @@ class cryptocom(ccxt.async_support.cryptocom):
515
839
  client = self.client(url)
516
840
  self.set_positions_cache(client, symbols)
517
841
  fetchPositionsSnapshot = self.handle_option('watchPositions', 'fetchPositionsSnapshot', True)
518
- awaitPositionsSnapshot = self.safe_bool('watchPositions', 'awaitPositionsSnapshot', True)
842
+ awaitPositionsSnapshot = self.handle_option('watchPositions', 'awaitPositionsSnapshot', True)
519
843
  if fetchPositionsSnapshot and awaitPositionsSnapshot and self.positions is None:
520
844
  snapshot = await client.future('fetchPositionsSnapshot')
521
845
  return self.filter_by_symbols_since_limit(snapshot, symbols, since, limit, True)
@@ -601,7 +925,9 @@ class cryptocom(ccxt.async_support.cryptocom):
601
925
  async def watch_balance(self, params={}) -> Balances:
602
926
  """
603
927
  watch balance and get the amount of funds available for trading or funds locked in orders
604
- :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#user-balance
928
+
929
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#user-balance
930
+
605
931
  :param dict [params]: extra parameters specific to the exchange API endpoint
606
932
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
607
933
  """
@@ -673,19 +999,21 @@ class cryptocom(ccxt.async_support.cryptocom):
673
999
 
674
1000
  async def create_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
675
1001
  """
676
- :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-create-order
1002
+
1003
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-create-order
1004
+
677
1005
  create a trade order
678
1006
  :param str symbol: unified symbol of the market to create an order in
679
1007
  :param str type: 'market' or 'limit'
680
1008
  :param str side: 'buy' or 'sell'
681
1009
  :param float amount: how much of currency you want to trade in units of base currency
682
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1010
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
683
1011
  :param dict [params]: extra parameters specific to the exchange API endpoint
684
1012
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
685
1013
  """
686
1014
  await self.load_markets()
687
1015
  params = self.create_order_request(symbol, type, side, amount, price, params)
688
- request = {
1016
+ request: dict = {
689
1017
  'method': 'private/create-order',
690
1018
  'params': params,
691
1019
  }
@@ -712,7 +1040,9 @@ class cryptocom(ccxt.async_support.cryptocom):
712
1040
  async def cancel_order_ws(self, id: str, symbol: Str = None, params={}) -> Order:
713
1041
  """
714
1042
  cancels an open order
715
- :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-cancel-order
1043
+
1044
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-cancel-order
1045
+
716
1046
  :param str id: the order id of the order to cancel
717
1047
  :param str [symbol]: unified symbol of the market the order was made in
718
1048
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -722,7 +1052,7 @@ class cryptocom(ccxt.async_support.cryptocom):
722
1052
  params = self.extend({
723
1053
  'order_id': id,
724
1054
  }, params)
725
- request = {
1055
+ request: dict = {
726
1056
  'method': 'private/cancel-order',
727
1057
  'params': params,
728
1058
  }
@@ -732,14 +1062,16 @@ class cryptocom(ccxt.async_support.cryptocom):
732
1062
  async def cancel_all_orders_ws(self, symbol: Str = None, params={}):
733
1063
  """
734
1064
  cancel all open orders
735
- :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-cancel-all-orders
1065
+
1066
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-cancel-all-orders
1067
+
736
1068
  :param str symbol: unified market symbol of the orders to cancel
737
1069
  :param dict [params]: extra parameters specific to the exchange API endpoint
738
1070
  :returns dict} Returns exchange raw message {@link https://docs.ccxt.com/#/?id=order-structure:
739
1071
  """
740
1072
  await self.load_markets()
741
1073
  market = None
742
- request = {
1074
+ request: dict = {
743
1075
  'method': 'private/cancel-all-orders',
744
1076
  'params': self.extend({}, params),
745
1077
  }
@@ -763,7 +1095,7 @@ class cryptocom(ccxt.async_support.cryptocom):
763
1095
  async def watch_public(self, messageHash, params={}):
764
1096
  url = self.urls['api']['ws']['public']
765
1097
  id = self.nonce()
766
- request = {
1098
+ request: dict = {
767
1099
  'method': 'subscribe',
768
1100
  'params': {
769
1101
  'channels': [messageHash],
@@ -776,7 +1108,7 @@ class cryptocom(ccxt.async_support.cryptocom):
776
1108
  async def watch_public_multiple(self, messageHashes, topics, params={}):
777
1109
  url = self.urls['api']['ws']['public']
778
1110
  id = self.nonce()
779
- request = {
1111
+ request: dict = {
780
1112
  'method': 'subscribe',
781
1113
  'params': {
782
1114
  'channels': topics,
@@ -786,10 +1118,31 @@ class cryptocom(ccxt.async_support.cryptocom):
786
1118
  message = self.deep_extend(request, params)
787
1119
  return await self.watch_multiple(url, messageHashes, message, messageHashes)
788
1120
 
1121
+ async def un_watch_public_multiple(self, topic: str, symbols: List[str], messageHashes: List[str], subMessageHashes: List[str], topics: List[str], params={}, subExtend={}):
1122
+ url = self.urls['api']['ws']['public']
1123
+ id = self.nonce()
1124
+ request: dict = {
1125
+ 'method': 'unsubscribe',
1126
+ 'params': {
1127
+ 'channels': topics,
1128
+ },
1129
+ 'nonce': id,
1130
+ 'id': str(id),
1131
+ }
1132
+ subscription = {
1133
+ 'id': str(id),
1134
+ 'topic': topic,
1135
+ 'symbols': symbols,
1136
+ 'subMessageHashes': subMessageHashes,
1137
+ 'messageHashes': messageHashes,
1138
+ }
1139
+ message = self.deep_extend(request, params)
1140
+ return await self.watch_multiple(url, messageHashes, message, messageHashes, self.extend(subscription, subExtend))
1141
+
789
1142
  async def watch_private_request(self, nonce, params={}):
790
1143
  await self.authenticate()
791
1144
  url = self.urls['api']['ws']['private']
792
- request = {
1145
+ request: dict = {
793
1146
  'id': nonce,
794
1147
  'nonce': nonce,
795
1148
  }
@@ -800,7 +1153,7 @@ class cryptocom(ccxt.async_support.cryptocom):
800
1153
  await self.authenticate()
801
1154
  url = self.urls['api']['ws']['private']
802
1155
  id = self.nonce()
803
- request = {
1156
+ request: dict = {
804
1157
  'method': 'subscribe',
805
1158
  'params': {
806
1159
  'channels': [messageHash],
@@ -819,6 +1172,7 @@ class cryptocom(ccxt.async_support.cryptocom):
819
1172
  # "message": "invalid channel {"channels":["trade.BTCUSD-PERP"]}"
820
1173
  # }
821
1174
  #
1175
+ id = self.safe_string(message, 'id')
822
1176
  errorCode = self.safe_string(message, 'code')
823
1177
  try:
824
1178
  if errorCode and errorCode != '0':
@@ -827,6 +1181,7 @@ class cryptocom(ccxt.async_support.cryptocom):
827
1181
  messageString = self.safe_value(message, 'message')
828
1182
  if messageString is not None:
829
1183
  self.throw_broadly_matched_exception(self.exceptions['broad'], messageString, feedback)
1184
+ raise ExchangeError(feedback)
830
1185
  return False
831
1186
  except Exception as e:
832
1187
  if isinstance(e, AuthenticationError):
@@ -835,11 +1190,11 @@ class cryptocom(ccxt.async_support.cryptocom):
835
1190
  if messageHash in client.subscriptions:
836
1191
  del client.subscriptions[messageHash]
837
1192
  else:
838
- client.reject(e)
1193
+ client.reject(e, id)
839
1194
  return True
840
1195
 
841
1196
  def handle_subscribe(self, client: Client, message):
842
- methods = {
1197
+ methods: dict = {
843
1198
  'candlestick': self.handle_ohlcv,
844
1199
  'ticker': self.handle_ticker,
845
1200
  'trade': self.handle_trades,
@@ -893,10 +1248,13 @@ class cryptocom(ccxt.async_support.cryptocom):
893
1248
  # "channel":"ticker",
894
1249
  # "data":[{}]
895
1250
  #
1251
+ # handle unsubscribe
1252
+ # {"id":1725448572836,"method":"unsubscribe","code":0}
1253
+ #
896
1254
  if self.handle_error_message(client, message):
897
1255
  return
898
1256
  method = self.safe_string(message, 'method')
899
- methods = {
1257
+ methods: dict = {
900
1258
  '': self.handle_ping,
901
1259
  'public/heartbeat': self.handle_ping,
902
1260
  'public/auth': self.handle_authenticate,
@@ -905,6 +1263,7 @@ class cryptocom(ccxt.async_support.cryptocom):
905
1263
  'private/cancel-all-orders': self.handle_cancel_all_orders,
906
1264
  'private/close-position': self.handle_order,
907
1265
  'subscribe': self.handle_subscribe,
1266
+ 'unsubscribe': self.handle_unsubscribe,
908
1267
  }
909
1268
  callMethod = self.safe_value(methods, method)
910
1269
  if callMethod is not None:
@@ -922,7 +1281,7 @@ class cryptocom(ccxt.async_support.cryptocom):
922
1281
  nonce = str(self.nonce())
923
1282
  auth = method + nonce + self.apiKey + nonce
924
1283
  signature = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256)
925
- request = {
1284
+ request: dict = {
926
1285
  'id': nonce,
927
1286
  'nonce': nonce,
928
1287
  'method': method,
@@ -931,7 +1290,7 @@ class cryptocom(ccxt.async_support.cryptocom):
931
1290
  }
932
1291
  message = self.extend(request, params)
933
1292
  self.watch(url, messageHash, message, messageHash)
934
- return future
1293
+ return await future
935
1294
 
936
1295
  def handle_ping(self, client: Client, message):
937
1296
  self.spawn(self.pong, client, message)
@@ -942,3 +1301,24 @@ class cryptocom(ccxt.async_support.cryptocom):
942
1301
  #
943
1302
  future = self.safe_value(client.futures, 'authenticated')
944
1303
  future.resolve(True)
1304
+
1305
+ def handle_unsubscribe(self, client: Client, message):
1306
+ id = self.safe_string(message, 'id')
1307
+ keys = list(client.subscriptions.keys())
1308
+ for i in range(0, len(keys)):
1309
+ messageHash = keys[i]
1310
+ if not (messageHash in client.subscriptions):
1311
+ continue
1312
+ # the previous iteration can have deleted the messageHash from the subscriptions
1313
+ if messageHash.startswith('unsubscribe'):
1314
+ subscription = client.subscriptions[messageHash]
1315
+ subId = self.safe_string(subscription, 'id')
1316
+ if id != subId:
1317
+ continue
1318
+ messageHashes = self.safe_list(subscription, 'messageHashes', [])
1319
+ subMessageHashes = self.safe_list(subscription, 'subMessageHashes', [])
1320
+ for j in range(0, len(messageHashes)):
1321
+ unsubHash = messageHashes[j]
1322
+ subHash = subMessageHashes[j]
1323
+ self.clean_unsubscription(client, subHash, unsubHash)
1324
+ self.clean_cache(subscription)