ccxt 4.2.76__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 +25 -0
  44. ccxt/abstract/kucoinfutures.py +35 -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 +3513 -1511
  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 +3105 -881
  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 +239 -50
  89. ccxt/async_support/bitget.py +1513 -563
  90. ccxt/async_support/bithumb.py +201 -67
  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 +403 -150
  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 +2326 -1255
  107. ccxt/async_support/cex.py +1409 -1329
  108. ccxt/async_support/coinbase.py +1455 -288
  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 +467 -158
  125. ccxt/async_support/deribit.py +558 -324
  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 +1473 -464
  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 +1634 -269
  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 +1050 -355
  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 +1777 -455
  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 +1155 -295
  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 +1729 -482
  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 +3513 -1511
  187. ccxt/binancecoinm.py +2 -1
  188. ccxt/binanceus.py +12 -1
  189. ccxt/binanceusdm.py +3 -1
  190. ccxt/bingx.py +3105 -881
  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 +239 -50
  197. ccxt/bitget.py +1513 -563
  198. ccxt/bithumb.py +200 -67
  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 +403 -150
  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 +2326 -1255
  215. ccxt/cex.py +1408 -1329
  216. ccxt/coinbase.py +1455 -288
  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 +467 -158
  233. ccxt/deribit.py +558 -324
  234. ccxt/digifinex.py +340 -223
  235. ccxt/ellipx.py +1826 -0
  236. ccxt/exmo.py +259 -128
  237. ccxt/gate.py +1473 -464
  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 +1633 -269
  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 +1050 -355
  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 +1777 -455
  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 +63 -15
  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 +204 -82
  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 +967 -661
  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 +168 -32
  309. ccxt/pro/exmo.py +253 -21
  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 +93 -34
  336. ccxt/pro/poloniex.py +129 -50
  337. ccxt/pro/poloniexfutures.py +53 -32
  338. ccxt/pro/probit.py +93 -86
  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 +486 -70
  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} +465 -407
  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} +465 -409
  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 +1155 -295
  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.76.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.76.dist-info/METADATA +0 -626
  545. ccxt-4.2.76.dist-info/RECORD +0 -534
  546. {ccxt-4.2.76.dist-info → ccxt-4.4.48.dist-info}/top_level.txt +0 -0
ccxt/pro/kucoinfutures.py CHANGED
@@ -4,10 +4,11 @@
4
4
  # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
5
 
6
6
  import ccxt.async_support
7
- from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById
8
- from ccxt.base.types import Balances, Int, Order, OrderBook, Position, Str, Ticker, Trade
7
+ from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp
8
+ from ccxt.base.types import Balances, Int, Order, OrderBook, Position, Str, Strings, Ticker, Tickers, Trade
9
9
  from ccxt.async_support.base.ws.client import Client
10
10
  from typing import List
11
+ from typing import Any
11
12
  from ccxt.base.errors import ExchangeError
12
13
  from ccxt.base.errors import ArgumentsRequired
13
14
 
@@ -18,8 +19,15 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
18
19
  return self.deep_extend(super(kucoinfutures, self).describe(), {
19
20
  'has': {
20
21
  'ws': True,
22
+ 'watchLiquidations': False,
23
+ 'watchLiquidatinsForSymbols': False,
24
+ 'watchMyLiquidations': None,
25
+ 'watchMyLiquidationsForSymbols': None,
21
26
  'watchTicker': True,
27
+ 'watchTickers': True,
28
+ 'watchBidsAsks': True,
22
29
  'watchTrades': True,
30
+ 'watchOHLCV': True,
23
31
  'watchOrderBook': True,
24
32
  'watchOrders': True,
25
33
  'watchBalance': True,
@@ -30,6 +38,21 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
30
38
  'watchOrderBookForSymbols': True,
31
39
  },
32
40
  'options': {
41
+ 'timeframes': {
42
+ '1m': '1min',
43
+ '3m': '1min',
44
+ '5m': '5min',
45
+ '15m': '15min',
46
+ '30m': '30min',
47
+ '1h': '1hour',
48
+ '2h': '2hour',
49
+ '4h': '4hour',
50
+ '8h': '8hour',
51
+ '12h': '12hour',
52
+ '1d': '1day',
53
+ '1w': '1week',
54
+ '1M': '1month',
55
+ },
33
56
  'accountsByType': {
34
57
  'swap': 'future',
35
58
  'cross': 'margin',
@@ -48,9 +71,6 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
48
71
  'snapshotDelay': 20,
49
72
  'snapshotMaxRetries': 3,
50
73
  },
51
- 'watchTicker': {
52
- 'name': 'contractMarket/tickerV2', # market/ticker
53
- },
54
74
  'watchPosition': {
55
75
  'fetchPositionSnapshot': True, # or False
56
76
  'awaitPositionSnapshot': True, # whether to wait for the position snapshot before providing updates
@@ -130,14 +150,14 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
130
150
 
131
151
  async def subscribe(self, url, messageHash, subscriptionHash, subscription, params={}):
132
152
  requestId = str(self.request_id())
133
- request = {
153
+ request: dict = {
134
154
  'id': requestId,
135
155
  'type': 'subscribe',
136
156
  'topic': subscriptionHash,
137
157
  'response': True,
138
158
  }
139
159
  message = self.extend(request, params)
140
- subscriptionRequest = {
160
+ subscriptionRequest: dict = {
141
161
  'id': requestId,
142
162
  }
143
163
  if subscription is None:
@@ -146,28 +166,40 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
146
166
  subscription = self.extend(subscriptionRequest, subscription)
147
167
  return await self.watch(url, messageHash, message, subscriptionHash, subscription)
148
168
 
149
- async def subscribe_multiple(self, url, messageHashes, topic, subscriptionHashes, subscription, params={}):
169
+ async def subscribe_multiple(self, url, messageHashes, topic, subscriptionHashes, subscriptionArgs, params={}):
150
170
  requestId = str(self.request_id())
151
- request = {
171
+ request: dict = {
152
172
  'id': requestId,
153
173
  'type': 'subscribe',
154
174
  'topic': topic,
155
175
  'response': True,
156
176
  }
157
- message = self.extend(request, params)
158
- subscriptionRequest = {
177
+ return await self.watch_multiple(url, messageHashes, self.extend(request, params), subscriptionHashes, subscriptionArgs)
178
+
179
+ async def un_subscribe_multiple(self, url, messageHashes, topic, subscriptionHashes, params={}, subscription: dict = None):
180
+ requestId = str(self.request_id())
181
+ request: dict = {
159
182
  'id': requestId,
183
+ 'type': 'unsubscribe',
184
+ 'topic': topic,
185
+ 'response': True,
160
186
  }
161
- if subscription is None:
162
- subscription = subscriptionRequest
163
- else:
164
- subscription = self.extend(subscriptionRequest, subscription)
187
+ message = self.extend(request, params)
188
+ if subscription is not None:
189
+ subscription[requestId] = requestId
190
+ client = self.client(url)
191
+ for i in range(0, len(subscriptionHashes)):
192
+ subscriptionHash = subscriptionHashes[i]
193
+ if not (subscriptionHash in client.subscriptions):
194
+ client.subscriptions[requestId] = subscriptionHash
165
195
  return await self.watch_multiple(url, messageHashes, message, subscriptionHashes, subscription)
166
196
 
167
197
  async def watch_ticker(self, symbol: str, params={}) -> Ticker:
168
198
  """
169
199
  watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
170
- :see: https://docs.kucoin.com/futures/#get-real-time-symbol-ticker-v2
200
+
201
+ https://www.kucoin.com/docs/websocket/futures-trading/public-channels/get-ticker
202
+
171
203
  :param str symbol: unified symbol of the market to fetch the ticker for
172
204
  :param dict [params]: extra parameters specific to the exchange API endpoint
173
205
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -175,30 +207,45 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
175
207
  await self.load_markets()
176
208
  market = self.market(symbol)
177
209
  symbol = market['symbol']
178
- url = await self.negotiate(False)
179
- options = self.safe_value(self.options, 'watchTicker', {})
180
- channel = self.safe_string(options, 'name', 'contractMarket/tickerV2')
181
- topic = '/' + channel + ':' + market['id']
182
- messageHash = 'ticker:' + symbol
183
- return await self.subscribe(url, messageHash, topic, None, params)
210
+ params['callerMethodName'] = 'watchTicker'
211
+ tickers = await self.watch_tickers([symbol], params)
212
+ return tickers[symbol]
213
+
214
+ async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
215
+ """
216
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
217
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
218
+ :param dict [params]: extra parameters specific to the exchange API endpoint
219
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
220
+ """
221
+ await self.load_markets()
222
+ ticker = await self.watch_multi_request('watchTickers', '/contractMarket/ticker:', symbols, params)
223
+ if self.newUpdates:
224
+ tickers: dict = {}
225
+ tickers[ticker['symbol']] = ticker
226
+ return tickers
227
+ return self.filter_by_array(self.tickers, 'symbol', symbols)
184
228
 
185
229
  def handle_ticker(self, client: Client, message):
186
230
  #
187
- # market/tickerV2
231
+ # ticker(v1)
188
232
  #
189
233
  # {
190
- # "type": "message",
191
- # "topic": "/contractMarket/tickerV2:ADAUSDTM",
192
- # "subject": "tickerV2",
193
- # "data": {
194
- # "symbol": "ADAUSDTM",
195
- # "sequence": 1668007800439,
196
- # "bestBidSize": 178,
197
- # "bestBidPrice": "0.35959",
198
- # "bestAskPrice": "0.35981",
199
- # "ts": "1668141430037124460",
200
- # "bestAskSize": 134
201
- # }
234
+ # "subject": "ticker",
235
+ # "topic": "/contractMarket/ticker:XBTUSDM",
236
+ # "data": {
237
+ # "symbol": "XBTUSDM", #Market of the symbol
238
+ # "sequence": 45, #Sequence number which is used to judge the continuity of the pushed messages
239
+ # "side": "sell", #Transaction side of the last traded taker order
240
+ # "price": "3600.0", #Filled price
241
+ # "size": 16, #Filled quantity
242
+ # "tradeId": "5c9dcf4170744d6f5a3d32fb", #Order ID
243
+ # "bestBidSize": 795, #Best bid size
244
+ # "bestBidPrice": "3200.0", #Best bid
245
+ # "bestAskPrice": "3600.0", #Best ask size
246
+ # "bestAskSize": 284, #Best ask
247
+ # "ts": 1553846081210004941 #Filled time - nanosecond
248
+ # }
202
249
  # }
203
250
  #
204
251
  data = self.safe_value(message, 'data', {})
@@ -206,14 +253,99 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
206
253
  market = self.safe_market(marketId, None, '-')
207
254
  ticker = self.parse_ticker(data, market)
208
255
  self.tickers[market['symbol']] = ticker
209
- messageHash = 'ticker:' + market['symbol']
210
- client.resolve(ticker, messageHash)
211
- return message
256
+ client.resolve(ticker, self.get_message_hash('ticker', market['symbol']))
257
+
258
+ async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
259
+ """
260
+
261
+ https://www.kucoin.com/docs/websocket/futures-trading/public-channels/get-ticker-v2
262
+
263
+ watches best bid & ask for symbols
264
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
265
+ :param dict [params]: extra parameters specific to the exchange API endpoint
266
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
267
+ """
268
+ ticker = await self.watch_multi_request('watchBidsAsks', '/contractMarket/tickerV2:', symbols, params)
269
+ if self.newUpdates:
270
+ tickers: dict = {}
271
+ tickers[ticker['symbol']] = ticker
272
+ return tickers
273
+ return self.filter_by_array(self.bidsasks, 'symbol', symbols)
274
+
275
+ async def watch_multi_request(self, methodName, channelName: str, symbols: Strings = None, params={}):
276
+ await self.load_markets()
277
+ methodName, params = self.handle_param_string(params, 'callerMethodName', methodName)
278
+ isBidsAsks = (methodName == 'watchBidsAsks')
279
+ symbols = self.market_symbols(symbols, None, False, True, False)
280
+ length = len(symbols)
281
+ if length > 100:
282
+ raise ArgumentsRequired(self.id + ' ' + methodName + '() accepts a maximum of 100 symbols')
283
+ messageHashes = []
284
+ for i in range(0, len(symbols)):
285
+ symbol = symbols[i]
286
+ market = self.market(symbol)
287
+ prefix = 'bidask' if isBidsAsks else 'ticker'
288
+ messageHashes.append(self.get_message_hash(prefix, market['symbol']))
289
+ url = await self.negotiate(False)
290
+ marketIds = self.market_ids(symbols)
291
+ joined = ','.join(marketIds)
292
+ requestId = str(self.request_id())
293
+ request: dict = {
294
+ 'id': requestId,
295
+ 'type': 'subscribe',
296
+ 'topic': channelName + joined,
297
+ 'response': True,
298
+ }
299
+ subscription: dict = {
300
+ 'id': requestId,
301
+ }
302
+ return await self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes, subscription)
303
+
304
+ def handle_bid_ask(self, client: Client, message):
305
+ #
306
+ # arrives one symbol dict
307
+ #
308
+ # {
309
+ # "subject": "tickerV2",
310
+ # "topic": "/contractMarket/tickerV2:XBTUSDM",
311
+ # "data": {
312
+ # "symbol": "XBTUSDM", #Market of the symbol
313
+ # "bestBidSize": 795, # Best bid size
314
+ # "bestBidPrice": 3200.0, # Best bid
315
+ # "bestAskPrice": 3600.0, # Best ask
316
+ # "bestAskSize": 284, # Best ask size
317
+ # "ts": 1553846081210004941 # Filled time - nanosecond
318
+ # }
319
+ # }
320
+ #
321
+ parsedTicker = self.parse_ws_bid_ask(message)
322
+ symbol = parsedTicker['symbol']
323
+ self.bidsasks[symbol] = parsedTicker
324
+ client.resolve(parsedTicker, self.get_message_hash('bidask', symbol))
325
+
326
+ def parse_ws_bid_ask(self, ticker, market=None):
327
+ data = self.safe_dict(ticker, 'data', {})
328
+ marketId = self.safe_string(data, 'symbol')
329
+ market = self.safe_market(marketId, market)
330
+ symbol = self.safe_string(market, 'symbol')
331
+ timestamp = self.safe_integer_product(data, 'ts', 0.000001)
332
+ return self.safe_ticker({
333
+ 'symbol': symbol,
334
+ 'timestamp': timestamp,
335
+ 'datetime': self.iso8601(timestamp),
336
+ 'ask': self.safe_number(data, 'bestAskPrice'),
337
+ 'askVolume': self.safe_number(data, 'bestAskSize'),
338
+ 'bid': self.safe_number(data, 'bestBidPrice'),
339
+ 'bidVolume': self.safe_number(data, 'bestBidSize'),
340
+ 'info': ticker,
341
+ }, market)
212
342
 
213
343
  async def watch_position(self, symbol: Str = None, params={}) -> Position:
214
344
  """
215
345
  watch open positions for a specific symbol
216
- :see: https://docs.kucoin.com/futures/#position-change-events
346
+
347
+ https://docs.kucoin.com/futures/#position-change-events
348
+
217
349
  :param str|None symbol: unified market symbol
218
350
  :param dict params: extra parameters specific to the exchange API endpoint
219
351
  :returns dict: a `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
@@ -224,14 +356,14 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
224
356
  url = await self.negotiate(True)
225
357
  market = self.market(symbol)
226
358
  topic = '/contract/position:' + market['id']
227
- request = {
359
+ request: dict = {
228
360
  'privateChannel': True,
229
361
  }
230
362
  messageHash = 'position:' + market['symbol']
231
363
  client = self.client(url)
232
364
  self.set_position_cache(client, symbol)
233
365
  fetchPositionSnapshot = self.handle_option('watchPosition', 'fetchPositionSnapshot', True)
234
- awaitPositionSnapshot = self.safe_bool('watchPosition', 'awaitPositionSnapshot', True)
366
+ awaitPositionSnapshot = self.handle_option('watchPosition', 'awaitPositionSnapshot', True)
235
367
  currentPosition = self.get_current_position(symbol)
236
368
  if fetchPositionSnapshot and awaitPositionSnapshot and currentPosition is None:
237
369
  snapshot = await client.future('fetchPositionSnapshot:' + symbol)
@@ -378,7 +510,9 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
378
510
  async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
379
511
  """
380
512
  get the list of most recent trades for a particular symbol
381
- :see: https://docs.kucoin.com/futures/#execution-data
513
+
514
+ https://docs.kucoin.com/futures/#execution-data
515
+
382
516
  :param str symbol: unified symbol of the market to fetch trades for
383
517
  :param int [since]: timestamp in ms of the earliest trade to fetch
384
518
  :param int [limit]: the maximum amount of trades to fetch
@@ -390,7 +524,7 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
390
524
  async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
391
525
  """
392
526
  get the list of most recent trades for a particular symbol
393
- :param str symbol: unified symbol of the market to fetch trades for
527
+ :param str[] symbols:
394
528
  :param int [since]: timestamp in ms of the earliest trade to fetch
395
529
  :param int [limit]: the maximum amount of trades to fetch
396
530
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -412,13 +546,53 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
412
546
  marketId = marketIds[i]
413
547
  messageHashes.append('trades:' + symbol)
414
548
  subscriptionHashes.append('/contractMarket/execution:' + marketId)
415
- trades = await self.subscribe_multiple(url, messageHashes, topic, subscriptionHashes, params)
549
+ trades = await self.subscribe_multiple(url, messageHashes, topic, subscriptionHashes, None, params)
416
550
  if self.newUpdates:
417
551
  first = self.safe_value(trades, 0)
418
552
  tradeSymbol = self.safe_string(first, 'symbol')
419
553
  limit = trades.getLimit(tradeSymbol, limit)
420
554
  return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
421
555
 
556
+ async def un_watch_trades(self, symbol: str, params={}) -> Any:
557
+ """
558
+ unWatches trades stream
559
+
560
+ https://docs.kucoin.com/futures/#execution-data
561
+
562
+ :param str symbol: unified symbol of the market to fetch trades for
563
+ :param dict [params]: extra parameters specific to the exchange API endpoint
564
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
565
+ """
566
+ return await self.un_watch_trades_for_symbols([symbol], params)
567
+
568
+ async def un_watch_trades_for_symbols(self, symbols: List[str], params={}) -> Any:
569
+ """
570
+ get the list of most recent trades for a particular symbol
571
+ :param str[] symbols:
572
+ :param dict [params]: extra parameters specific to the exchange API endpoint
573
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
574
+ """
575
+ await self.load_markets()
576
+ symbols = self.market_symbols(symbols, None, False)
577
+ url = await self.negotiate(False)
578
+ symbols = self.market_symbols(symbols)
579
+ marketIds = self.market_ids(symbols)
580
+ topic = '/contractMarket/execution:' + ','.join(marketIds)
581
+ subscriptionHashes = []
582
+ messageHashes = []
583
+ for i in range(0, len(symbols)):
584
+ symbol = symbols[i]
585
+ messageHashes.append('unsubscribe:trades:' + symbol)
586
+ subscriptionHashes.append('trades:' + symbol)
587
+ subscription = {
588
+ 'messageHashes': messageHashes,
589
+ 'subMessageHashes': subscriptionHashes,
590
+ 'topic': 'trades',
591
+ 'unsubscribe': True,
592
+ 'symbols': symbols,
593
+ }
594
+ return await self.un_subscribe_multiple(url, messageHashes, topic, messageHashes, params, subscription)
595
+
422
596
  def handle_trade(self, client: Client, message):
423
597
  #
424
598
  # {
@@ -453,16 +627,91 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
453
627
  client.resolve(trades, messageHash)
454
628
  return message
455
629
 
630
+ async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
631
+ """
632
+
633
+ https://www.kucoin.com/docs/websocket/futures-trading/public-channels/klines
634
+
635
+ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
636
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
637
+ :param str timeframe: the length of time each candle represents
638
+ :param int [since]: timestamp in ms of the earliest candle to fetch
639
+ :param int [limit]: the maximum amount of candles to fetch
640
+ :param dict [params]: extra parameters specific to the exchange API endpoint
641
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
642
+ """
643
+ await self.load_markets()
644
+ symbol = self.symbol(symbol)
645
+ url = await self.negotiate(False)
646
+ marketId = self.market_id(symbol)
647
+ timeframes = self.safe_dict(self.options, 'timeframes')
648
+ timeframeId = self.safe_string(timeframes, timeframe, timeframe)
649
+ topic = '/contractMarket/limitCandle:' + marketId + '_' + timeframeId
650
+ messageHash = 'ohlcv::' + symbol + '_' + timeframe
651
+ ohlcv = await self.subscribe(url, messageHash, topic, None, params)
652
+ if self.newUpdates:
653
+ limit = ohlcv.getLimit(symbol, limit)
654
+ return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
655
+
656
+ def handle_ohlcv(self, client: Client, message):
657
+ #
658
+ # {
659
+ # "topic":"/contractMarket/limitCandle:LTCUSDTM_1min",
660
+ # "type":"message",
661
+ # "data":{
662
+ # "symbol":"LTCUSDTM",
663
+ # "candles":[
664
+ # "1715470980",
665
+ # "81.38",
666
+ # "81.38",
667
+ # "81.38",
668
+ # "81.38",
669
+ # "61.0",
670
+ # "61"
671
+ # ],
672
+ # "time":1715470994801
673
+ # },
674
+ # "subject":"candle.stick"
675
+ # }
676
+ #
677
+ topic = self.safe_string(message, 'topic')
678
+ parts = topic.split('_')
679
+ timeframeId = self.safe_string(parts, 1)
680
+ data = self.safe_dict(message, 'data')
681
+ timeframes = self.safe_dict(self.options, 'timeframes')
682
+ timeframe = self.find_timeframe(timeframeId, timeframes)
683
+ marketId = self.safe_string(data, 'symbol')
684
+ symbol = self.safe_symbol(marketId)
685
+ messageHash = 'ohlcv::' + symbol + '_' + timeframe
686
+ ohlcv = self.safe_list(data, 'candles')
687
+ parsed = [
688
+ self.safe_integer(ohlcv, 0),
689
+ self.safe_number(ohlcv, 1),
690
+ self.safe_number(ohlcv, 2),
691
+ self.safe_number(ohlcv, 3),
692
+ self.safe_number(ohlcv, 4),
693
+ self.safe_number(ohlcv, 6), # Note value 5 is incorrect and will be fixed in subsequent versions of kucoin
694
+ ]
695
+ self.ohlcvs[symbol] = self.safe_dict(self.ohlcvs, symbol, {})
696
+ if not (timeframe in self.ohlcvs[symbol]):
697
+ limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
698
+ self.ohlcvs[symbol][timeframe] = ArrayCacheByTimestamp(limit)
699
+ stored = self.ohlcvs[symbol][timeframe]
700
+ stored.append(parsed)
701
+ client.resolve(stored, messageHash)
702
+
456
703
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
457
704
  """
458
705
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
459
- * 1. After receiving the websocket Level 2 data flow, cache the data.
460
- * 2. Initiate a REST request to get the snapshot data of Level 2 order book.
461
- * 3. Playback the cached Level 2 data flow.
462
- * 4. Apply the new Level 2 data flow to the local snapshot to ensure that the sequence of the new Level 2 update lines up with the sequence of the previous Level 2 data. Discard all the message prior to that sequence, and then playback the change to snapshot.
463
- * 5. Update the level2 full data based on sequence according to the size. If the price is 0, ignore the messages and update the sequence. If the size=0, update the sequence and remove the price of which the size is 0 out of level 2. For other cases, please update the price.
464
- * 6. If the sequence of the newly pushed message does not line up to the sequence of the last message, you could pull through REST Level 2 message request to get the updated messages. Please note that the difference between the start and end parameters cannot exceed 500.
465
- :see: https://docs.kucoin.com/futures/#level-2-market-data
706
+ 1. After receiving the websocket Level 2 data flow, cache the data.
707
+ 2. Initiate a REST request to get the snapshot data of Level 2 order book.
708
+ 3. Playback the cached Level 2 data flow.
709
+ 4. Apply the new Level 2 data flow to the local snapshot to ensure that the sequence of the new Level 2 update lines up with the sequence of the previous Level 2 data. Discard all the message prior to that sequence, and then playback the change to snapshot.
710
+ 5. Update the level2 full data based on sequence according to the size. If the price is 0, ignore the messages and update the sequence. If the size=0, update the sequence and remove the price of which the size is 0 out of level 2. For other cases, please update the price.
711
+ 6. If the sequence of the newly pushed message does not line up to the sequence of the last message, you could pull through REST Level 2 message request to get the updated messages. Please note that the difference between the start and end parameters cannot exceed 500.
712
+
713
+ https://docs.kucoin.com/futures/#level-2-market-data
714
+
466
715
  :param str symbol: unified symbol of the market to fetch the order book for
467
716
  :param int [limit]: the maximum amount of order book entries to return
468
717
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -473,6 +722,9 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
473
722
  async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
474
723
  """
475
724
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
725
+
726
+ https://docs.kucoin.com/futures/#level-2-market-data
727
+
476
728
  :param str[] symbols: unified array of symbols
477
729
  :param int [limit]: the maximum amount of order book entries to return
478
730
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -489,9 +741,7 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
489
741
  marketIds = self.market_ids(symbols)
490
742
  url = await self.negotiate(False)
491
743
  topic = '/contractMarket/level2:' + ','.join(marketIds)
492
- subscription = {
493
- 'method': self.handle_order_book_subscription,
494
- 'symbols': symbols,
744
+ subscriptionArgs: dict = {
495
745
  'limit': limit,
496
746
  }
497
747
  subscriptionHashes = []
@@ -501,9 +751,48 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
501
751
  marketId = marketIds[i]
502
752
  messageHashes.append('orderbook:' + symbol)
503
753
  subscriptionHashes.append('/contractMarket/level2:' + marketId)
504
- orderbook = await self.subscribe_multiple(url, messageHashes, topic, subscriptionHashes, subscription, params)
754
+ orderbook = await self.subscribe_multiple(url, messageHashes, topic, subscriptionHashes, subscriptionArgs, params)
505
755
  return orderbook.limit()
506
756
 
757
+ async def un_watch_order_book(self, symbol: str, params={}) -> Any:
758
+ """
759
+ unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
760
+
761
+ https://docs.kucoin.com/futures/#level-2-market-data
762
+
763
+ :param str symbol: unified symbol of the market to fetch the order book for
764
+ :param dict [params]: extra parameters specific to the exchange API endpoint
765
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
766
+ """
767
+ return await self.un_watch_order_book_for_symbols([symbol], params)
768
+
769
+ async def un_watch_order_book_for_symbols(self, symbols: List[str], params={}) -> Any:
770
+ """
771
+ unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
772
+ :param str[] symbols: unified array of symbols
773
+ :param dict [params]: extra parameters specific to the exchange API endpoint
774
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
775
+ """
776
+ await self.load_markets()
777
+ symbols = self.market_symbols(symbols)
778
+ marketIds = self.market_ids(symbols)
779
+ url = await self.negotiate(False)
780
+ topic = '/contractMarket/level2:' + ','.join(marketIds)
781
+ subscriptionHashes = []
782
+ messageHashes = []
783
+ for i in range(0, len(symbols)):
784
+ symbol = symbols[i]
785
+ messageHashes.append('unsubscribe:orderbook:' + symbol)
786
+ subscriptionHashes.append('orderbook:' + symbol)
787
+ subscription = {
788
+ 'messageHashes': messageHashes,
789
+ 'symbols': symbols,
790
+ 'unsubscribe': True,
791
+ 'topic': 'orderbook',
792
+ 'subMessageHashes': subscriptionHashes,
793
+ }
794
+ return await self.un_subscribe_multiple(url, messageHashes, topic, messageHashes, params, subscription)
795
+
507
796
  def handle_delta(self, orderbook, delta):
508
797
  orderbook['nonce'] = self.safe_integer(delta, 'sequence')
509
798
  timestamp = self.safe_integer(delta, 'timestamp')
@@ -549,10 +838,12 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
549
838
  marketId = self.safe_string(topicParts, 1)
550
839
  symbol = self.safe_symbol(marketId, None, '-')
551
840
  messageHash = 'orderbook:' + symbol
552
- storedOrderBook = self.safe_value(self.orderbooks, symbol)
841
+ if not (symbol in self.orderbooks):
842
+ subscriptionArgs = self.safe_dict(client.subscriptions, topic, {})
843
+ limit = self.safe_integer(subscriptionArgs, 'limit')
844
+ self.orderbooks[symbol] = self.order_book({}, limit)
845
+ storedOrderBook = self.orderbooks[symbol]
553
846
  nonce = self.safe_integer(storedOrderBook, 'nonce')
554
- if storedOrderBook is None:
555
- return # self shouldn't be needed, but for some reason sometimes self runs before handleOrderBookSubscription in c#
556
847
  deltaEnd = self.safe_integer(data, 'sequence')
557
848
  if nonce is None:
558
849
  cacheLength = len(storedOrderBook.cache)
@@ -590,35 +881,6 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
590
881
  return i
591
882
  return len(cache)
592
883
 
593
- def handle_order_book_subscription(self, client: Client, message, subscription):
594
- limit = self.safe_integer(subscription, 'limit')
595
- symbols = self.safe_value(subscription, 'symbols')
596
- if symbols is None:
597
- symbol = self.safe_string(subscription, 'symbol')
598
- self.orderbooks[symbol] = self.order_book({}, limit)
599
- else:
600
- for i in range(0, len(symbols)):
601
- symbol = symbols[i]
602
- self.orderbooks[symbol] = self.order_book({}, limit)
603
- # moved snapshot initialization to handleOrderBook to fix
604
- # https://github.com/ccxt/ccxt/issues/6820
605
- # the general idea is to fetch the snapshot after the first delta
606
- # but not before, because otherwise we cannot synchronize the feed
607
-
608
- def handle_subscription_status(self, client: Client, message):
609
- #
610
- # {
611
- # "id": "1578090438322",
612
- # "type": "ack"
613
- # }
614
- #
615
- id = self.safe_string(message, 'id')
616
- subscriptionsById = self.index_by(client.subscriptions, 'id')
617
- subscription = self.safe_value(subscriptionsById, id, {})
618
- method = self.safe_value(subscription, 'method')
619
- if method is not None:
620
- method(client, message, subscription)
621
-
622
884
  def handle_system_status(self, client: Client, message):
623
885
  #
624
886
  # todo: answer the question whether handleSystemStatus should be renamed
@@ -635,7 +897,9 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
635
897
  async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
636
898
  """
637
899
  watches information on multiple orders made by the user
638
- :see: https://docs.kucoin.com/futures/#trade-orders-according-to-the-market
900
+
901
+ https://docs.kucoin.com/futures/#trade-orders-according-to-the-market
902
+
639
903
  :param str symbol: unified market symbol of the market orders were made in
640
904
  :param int [since]: the earliest time in ms to fetch orders for
641
905
  :param int [limit]: the maximum number of order structures to retrieve
@@ -645,7 +909,7 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
645
909
  await self.load_markets()
646
910
  url = await self.negotiate(True)
647
911
  topic = '/contractMarket/tradeOrders'
648
- request = {
912
+ request: dict = {
649
913
  'privateChannel': True,
650
914
  }
651
915
  messageHash = 'orders'
@@ -659,7 +923,7 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
659
923
  return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
660
924
 
661
925
  def parse_ws_order_status(self, status):
662
- statuses = {
926
+ statuses: dict = {
663
927
  'open': 'open',
664
928
  'filled': 'closed',
665
929
  'match': 'open',
@@ -751,17 +1015,19 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
751
1015
  async def watch_balance(self, params={}) -> Balances:
752
1016
  """
753
1017
  watch balance and get the amount of funds available for trading or funds locked in orders
754
- :see: https://docs.kucoin.com/futures/#account-balance-events
1018
+
1019
+ https://docs.kucoin.com/futures/#account-balance-events
1020
+
755
1021
  :param dict [params]: extra parameters specific to the exchange API endpoint
756
1022
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
757
1023
  """
758
1024
  await self.load_markets()
759
1025
  url = await self.negotiate(True)
760
1026
  topic = '/contractAccount/wallet'
761
- request = {
1027
+ request: dict = {
762
1028
  'privateChannel': True,
763
1029
  }
764
- subscription = {
1030
+ subscription: dict = {
765
1031
  'method': self.handle_balance_subscription,
766
1032
  }
767
1033
  messageHash = 'balance'
@@ -803,7 +1069,7 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
803
1069
  self.check_required_credentials()
804
1070
  messageHash = 'balance'
805
1071
  selectedType = self.safe_string_2(self.options, 'watchBalance', 'defaultType', 'swap') # spot, margin, main, funding, future, mining, trade, contract, pool
806
- params = {
1072
+ params: dict = {
807
1073
  'type': selectedType,
808
1074
  }
809
1075
  snapshot = await self.fetch_balance(params)
@@ -862,9 +1128,11 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
862
1128
  # }
863
1129
  #
864
1130
  subject = self.safe_string(message, 'subject')
865
- methods = {
1131
+ methods: dict = {
866
1132
  'level2': self.handle_order_book,
867
- 'tickerV2': self.handle_ticker,
1133
+ 'ticker': self.handle_ticker,
1134
+ 'candle.stick': self.handle_ohlcv,
1135
+ 'tickerV2': self.handle_bid_ask,
868
1136
  'availableBalance.change': self.handle_balance,
869
1137
  'match': self.handle_trade,
870
1138
  'orderChange': self.handle_order,
@@ -877,7 +1145,14 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
877
1145
  if method is not None:
878
1146
  method(client, message)
879
1147
 
880
- def ping(self, client):
1148
+ def get_message_hash(self, elementName: str, symbol: Str = None):
1149
+ # elementName can be 'ticker', 'bidask', ...
1150
+ if symbol is not None:
1151
+ return elementName + '@' + symbol
1152
+ else:
1153
+ return elementName + 's@all'
1154
+
1155
+ def ping(self, client: Client):
881
1156
  # kucoin does not support built-in ws protocol-level ping-pong
882
1157
  # instead it requires a custom json-based text ping-pong
883
1158
  # https://docs.kucoin.com/#ping
@@ -909,15 +1184,41 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
909
1184
  self.options['urls'][type] = None
910
1185
  self.handle_errors(None, None, client.url, None, None, data, message, None, None)
911
1186
 
1187
+ def handle_subscription_status(self, client: Client, message):
1188
+ #
1189
+ # {
1190
+ # "id": "1578090438322",
1191
+ # "type": "ack"
1192
+ # }
1193
+ #
1194
+ id = self.safe_string(message, 'id')
1195
+ if not (id in client.subscriptions):
1196
+ return
1197
+ subscriptionHash = self.safe_string(client.subscriptions, id)
1198
+ subscription = self.safe_value(client.subscriptions, subscriptionHash)
1199
+ del client.subscriptions[id]
1200
+ method = self.safe_value(subscription, 'method')
1201
+ if method is not None:
1202
+ method(client, message, subscription)
1203
+ isUnSub = self.safe_bool(subscription, 'unsubscribe', False)
1204
+ if isUnSub:
1205
+ messageHashes = self.safe_list(subscription, 'messageHashes', [])
1206
+ subMessageHashes = self.safe_list(subscription, 'subMessageHashes', [])
1207
+ for i in range(0, len(messageHashes)):
1208
+ messageHash = messageHashes[i]
1209
+ subHash = subMessageHashes[i]
1210
+ self.clean_unsubscription(client, subHash, messageHash)
1211
+ self.clean_cache(subscription)
1212
+
912
1213
  def handle_message(self, client: Client, message):
913
1214
  type = self.safe_string(message, 'type')
914
- methods = {
1215
+ methods: dict = {
915
1216
  # 'heartbeat': self.handleHeartbeat,
916
1217
  'welcome': self.handle_system_status,
917
- 'ack': self.handle_subscription_status,
918
1218
  'message': self.handle_subject,
919
1219
  'pong': self.handle_pong,
920
1220
  'error': self.handle_error_message,
1221
+ 'ack': self.handle_subscription_status,
921
1222
  }
922
1223
  method = self.safe_value(methods, type)
923
1224
  if method is not None: