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/kraken.py CHANGED
@@ -5,10 +5,11 @@
5
5
 
6
6
  import ccxt.async_support
7
7
  from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp
8
- from ccxt.base.types import Int, Num, Order, OrderBook, OrderSide, OrderType, Str, Ticker, Trade
8
+ from ccxt.base.types import Balances, Int, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade
9
9
  from ccxt.async_support.base.ws.client import Client
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
+ from ccxt.base.errors import AuthenticationError
12
13
  from ccxt.base.errors import PermissionDenied
13
14
  from ccxt.base.errors import AccountSuspended
14
15
  from ccxt.base.errors import BadRequest
@@ -19,8 +20,7 @@ from ccxt.base.errors import OrderNotFound
19
20
  from ccxt.base.errors import NotSupported
20
21
  from ccxt.base.errors import RateLimitExceeded
21
22
  from ccxt.base.errors import ExchangeNotAvailable
22
- from ccxt.base.errors import InvalidNonce
23
- from ccxt.base.errors import AuthenticationError
23
+ from ccxt.base.errors import ChecksumError
24
24
  from ccxt.base.precise import Precise
25
25
 
26
26
 
@@ -30,14 +30,17 @@ class kraken(ccxt.async_support.kraken):
30
30
  return self.deep_extend(super(kraken, self).describe(), {
31
31
  'has': {
32
32
  'ws': True,
33
- 'watchBalance': False, # no such type of subscription 2021-01-05
33
+ 'watchBalance': True,
34
34
  'watchMyTrades': True,
35
35
  'watchOHLCV': True,
36
36
  'watchOrderBook': True,
37
+ 'watchOrderBookForSymbols': True,
37
38
  'watchOrders': True,
38
39
  'watchTicker': True,
39
- 'watchTickers': False, # for now
40
+ 'watchTickers': True,
41
+ 'watchBidsAsks': True,
40
42
  'watchTrades': True,
43
+ 'watchTradesForSymbols': True,
41
44
  'createOrderWs': True,
42
45
  'editOrderWs': True,
43
46
  'cancelOrderWs': True,
@@ -51,6 +54,7 @@ class kraken(ccxt.async_support.kraken):
51
54
  'ws': {
52
55
  'public': 'wss://ws.kraken.com',
53
56
  'private': 'wss://ws-auth.kraken.com',
57
+ 'privateV2': 'wss://ws-auth.kraken.com/v2',
54
58
  'beta': 'wss://beta-ws.kraken.com',
55
59
  'beta-private': 'wss://beta-ws-auth.kraken.com',
56
60
  },
@@ -64,7 +68,9 @@ class kraken(ccxt.async_support.kraken):
64
68
  'OHLCVLimit': 1000,
65
69
  'ordersLimit': 1000,
66
70
  'symbolsByOrderId': {},
67
- 'checksum': True,
71
+ 'watchOrderBook': {
72
+ 'checksum': True,
73
+ },
68
74
  },
69
75
  'exceptions': {
70
76
  'ws': {
@@ -123,13 +129,15 @@ class kraken(ccxt.async_support.kraken):
123
129
 
124
130
  async def create_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
125
131
  """
126
- :see: https://docs.kraken.com/websockets/#message-addOrder
132
+
133
+ https://docs.kraken.com/api/docs/websocket-v1/addorder
134
+
127
135
  create a trade order
128
136
  :param str symbol: unified symbol of the market to create an order in
129
137
  :param str type: 'market' or 'limit'
130
138
  :param str side: 'buy' or 'sell'
131
139
  :param float amount: how much of currency you want to trade in units of base currency
132
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
140
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
133
141
  :param dict [params]: extra parameters specific to the exchange API endpoint
134
142
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
135
143
  """
@@ -139,7 +147,7 @@ class kraken(ccxt.async_support.kraken):
139
147
  url = self.urls['api']['ws']['private']
140
148
  requestId = self.request_id()
141
149
  messageHash = requestId
142
- request = {
150
+ request: dict = {
143
151
  'event': 'addOrder',
144
152
  'token': token,
145
153
  'reqid': requestId,
@@ -148,7 +156,7 @@ class kraken(ccxt.async_support.kraken):
148
156
  'pair': market['wsId'],
149
157
  'volume': self.amount_to_precision(symbol, amount),
150
158
  }
151
- request, params = self.orderRequest('createOrderWs()', symbol, type, request, price, params)
159
+ request, params = self.orderRequest('createOrderWs', symbol, type, request, amount, price, params)
152
160
  return await self.watch(url, messageHash, self.extend(request, params), messageHash)
153
161
 
154
162
  def handle_create_edit_order(self, client, message):
@@ -175,16 +183,18 @@ class kraken(ccxt.async_support.kraken):
175
183
  messageHash = self.safe_value(message, 'reqid')
176
184
  client.resolve(order, messageHash)
177
185
 
178
- async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
186
+ async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}) -> Order:
179
187
  """
180
188
  edit a trade order
181
- :see: https://docs.kraken.com/websockets/#message-editOrder
189
+
190
+ https://docs.kraken.com/api/docs/websocket-v1/editorder
191
+
182
192
  :param str id: order id
183
193
  :param str symbol: unified symbol of the market to create an order in
184
194
  :param str type: 'market' or 'limit'
185
195
  :param str side: 'buy' or 'sell'
186
196
  :param float amount: how much of the currency you want to trade in units of the base currency
187
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
197
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
188
198
  :param dict [params]: extra parameters specific to the exchange API endpoint
189
199
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
190
200
  """
@@ -194,20 +204,23 @@ class kraken(ccxt.async_support.kraken):
194
204
  url = self.urls['api']['ws']['private']
195
205
  requestId = self.request_id()
196
206
  messageHash = requestId
197
- request = {
207
+ request: dict = {
198
208
  'event': 'editOrder',
199
209
  'token': token,
200
210
  'reqid': requestId,
201
211
  'orderid': id,
202
212
  'pair': market['wsId'],
203
- 'volume': self.amount_to_precision(symbol, amount),
204
213
  }
205
- request, params = self.orderRequest('editOrderWs()', symbol, type, request, price, params)
214
+ if amount is not None:
215
+ request['volume'] = self.amount_to_precision(symbol, amount)
216
+ request, params = self.orderRequest('editOrderWs', symbol, type, request, amount, price, params)
206
217
  return await self.watch(url, messageHash, self.extend(request, params), messageHash)
207
218
 
208
219
  async def cancel_orders_ws(self, ids: List[str], symbol: Str = None, params={}):
209
220
  """
210
- :see: https://docs.kraken.com/websockets/#message-cancelOrder
221
+
222
+ https://docs.kraken.com/api/docs/websocket-v1/cancelorder
223
+
211
224
  cancel multiple orders
212
225
  :param str[] ids: order ids
213
226
  :param str symbol: unified market symbol, default is None
@@ -219,7 +232,7 @@ class kraken(ccxt.async_support.kraken):
219
232
  url = self.urls['api']['ws']['private']
220
233
  requestId = self.request_id()
221
234
  messageHash = requestId
222
- request = {
235
+ request: dict = {
223
236
  'event': 'cancelOrder',
224
237
  'token': token,
225
238
  'reqid': requestId,
@@ -229,7 +242,9 @@ class kraken(ccxt.async_support.kraken):
229
242
 
230
243
  async def cancel_order_ws(self, id: str, symbol: Str = None, params={}) -> Order:
231
244
  """
232
- :see: https://docs.kraken.com/websockets/#message-cancelOrder
245
+
246
+ https://docs.kraken.com/api/docs/websocket-v1/cancelorder
247
+
233
248
  cancels an open order
234
249
  :param str id: order id
235
250
  :param str symbol: unified symbol of the market the order was made in
@@ -243,7 +258,7 @@ class kraken(ccxt.async_support.kraken):
243
258
  messageHash = requestId
244
259
  clientOrderId = self.safe_value_2(params, 'userref', 'clientOrderId', id)
245
260
  params = self.omit(params, ['userref', 'clientOrderId'])
246
- request = {
261
+ request: dict = {
247
262
  'event': 'cancelOrder',
248
263
  'token': token,
249
264
  'reqid': requestId,
@@ -265,7 +280,9 @@ class kraken(ccxt.async_support.kraken):
265
280
 
266
281
  async def cancel_all_orders_ws(self, symbol: Str = None, params={}):
267
282
  """
268
- :see: https://docs.kraken.com/websockets/#message-cancelAll
283
+
284
+ https://docs.kraken.com/api/docs/websocket-v1/cancelall
285
+
269
286
  cancel all open orders
270
287
  :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
271
288
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -278,7 +295,7 @@ class kraken(ccxt.async_support.kraken):
278
295
  url = self.urls['api']['ws']['private']
279
296
  requestId = self.request_id()
280
297
  messageHash = requestId
281
- request = {
298
+ request: dict = {
282
299
  'event': 'cancelAll',
283
300
  'token': token,
284
301
  'reqid': requestId,
@@ -317,10 +334,9 @@ class kraken(ccxt.async_support.kraken):
317
334
  # ]
318
335
  #
319
336
  wsName = message[3]
320
- name = 'ticker'
321
- messageHash = name + ':' + wsName
322
337
  market = self.safe_value(self.options['marketsByWsName'], wsName)
323
338
  symbol = market['symbol']
339
+ messageHash = self.get_message_hash('ticker', None, symbol)
324
340
  ticker = message[1]
325
341
  vwap = self.safe_string(ticker['p'], 0)
326
342
  quoteVolume = None
@@ -350,9 +366,6 @@ class kraken(ccxt.async_support.kraken):
350
366
  'quoteVolume': quoteVolume,
351
367
  'info': ticker,
352
368
  })
353
- # todo add support for multiple tickers(may be tricky)
354
- # kraken confirms multi-pair subscriptions separately one by one
355
- # trigger correct watchTickers calls upon receiving any of symbols
356
369
  self.tickers[symbol] = result
357
370
  client.resolve(result, messageHash)
358
371
 
@@ -370,9 +383,9 @@ class kraken(ccxt.async_support.kraken):
370
383
  #
371
384
  wsName = self.safe_string(message, 3)
372
385
  name = self.safe_string(message, 2)
373
- messageHash = name + ':' + wsName
374
386
  market = self.safe_value(self.options['marketsByWsName'], wsName)
375
387
  symbol = market['symbol']
388
+ messageHash = self.get_message_hash(name, None, symbol)
376
389
  stored = self.safe_value(self.trades, symbol)
377
390
  if stored is None:
378
391
  limit = self.safe_integer(self.options, 'tradesLimit', 1000)
@@ -447,7 +460,7 @@ class kraken(ccxt.async_support.kraken):
447
460
  messageHash = name + ':' + wsName
448
461
  url = self.urls['api']['ws']['public']
449
462
  requestId = self.request_id()
450
- subscribe = {
463
+ subscribe: dict = {
451
464
  'event': 'subscribe',
452
465
  'reqid': requestId,
453
466
  'pair': [
@@ -463,52 +476,168 @@ class kraken(ccxt.async_support.kraken):
463
476
  async def watch_ticker(self, symbol: str, params={}) -> Ticker:
464
477
  """
465
478
  watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
479
+
480
+ https://docs.kraken.com/api/docs/websocket-v1/ticker
481
+
466
482
  :param str symbol: unified symbol of the market to fetch the ticker for
467
483
  :param dict [params]: extra parameters specific to the exchange API endpoint
468
484
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
469
485
  """
470
- return await self.watch_public('ticker', symbol, params)
486
+ await self.load_markets()
487
+ symbol = self.symbol(symbol)
488
+ tickers = await self.watch_tickers([symbol], params)
489
+ return tickers[symbol]
490
+
491
+ async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
492
+ """
493
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
494
+
495
+ https://docs.kraken.com/api/docs/websocket-v1/ticker
496
+
497
+ :param str[] symbols:
498
+ :param dict [params]: extra parameters specific to the exchange API endpoint
499
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
500
+ """
501
+ await self.load_markets()
502
+ symbols = self.market_symbols(symbols, None, False)
503
+ ticker = await self.watch_multi_helper('ticker', 'ticker', symbols, None, params)
504
+ if self.newUpdates:
505
+ result: dict = {}
506
+ result[ticker['symbol']] = ticker
507
+ return result
508
+ return self.filter_by_array(self.tickers, 'symbol', symbols)
509
+
510
+ async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
511
+ """
512
+
513
+ https://docs.kraken.com/api/docs/websocket-v1/spread
514
+
515
+ watches best bid & ask for symbols
516
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
517
+ :param dict [params]: extra parameters specific to the exchange API endpoint
518
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
519
+ """
520
+ await self.load_markets()
521
+ symbols = self.market_symbols(symbols, None, False)
522
+ ticker = await self.watch_multi_helper('bidask', 'spread', symbols, None, params)
523
+ if self.newUpdates:
524
+ result: dict = {}
525
+ result[ticker['symbol']] = ticker
526
+ return result
527
+ return self.filter_by_array(self.bidsasks, 'symbol', symbols)
528
+
529
+ def handle_bid_ask(self, client: Client, message, subscription):
530
+ #
531
+ # [
532
+ # 7208974, # channelID
533
+ # [
534
+ # "63758.60000", # bid
535
+ # "63759.10000", # ask
536
+ # "1726814731.089778", # timestamp
537
+ # "0.00057917", # bid_volume
538
+ # "0.15681688" # ask_volume
539
+ # ],
540
+ # "spread",
541
+ # "XBT/USDT"
542
+ # ]
543
+ #
544
+ parsedTicker = self.parse_ws_bid_ask(message)
545
+ symbol = parsedTicker['symbol']
546
+ self.bidsasks[symbol] = parsedTicker
547
+ messageHash = self.get_message_hash('bidask', None, symbol)
548
+ client.resolve(parsedTicker, messageHash)
549
+
550
+ def parse_ws_bid_ask(self, ticker, market=None):
551
+ data = self.safe_list(ticker, 1, [])
552
+ marketId = self.safe_string(ticker, 3)
553
+ market = self.safe_value(self.options['marketsByWsName'], marketId)
554
+ symbol = self.safe_string(market, 'symbol')
555
+ timestamp = self.parse_to_int(self.safe_integer(data, 2)) * 1000
556
+ return self.safe_ticker({
557
+ 'symbol': symbol,
558
+ 'timestamp': timestamp,
559
+ 'datetime': self.iso8601(timestamp),
560
+ 'ask': self.safe_string(data, 1),
561
+ 'askVolume': self.safe_string(data, 4),
562
+ 'bid': self.safe_string(data, 0),
563
+ 'bidVolume': self.safe_string(data, 3),
564
+ 'info': ticker,
565
+ }, market)
471
566
 
472
567
  async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
473
568
  """
474
569
  get the list of most recent trades for a particular symbol
570
+
571
+ https://docs.kraken.com/api/docs/websocket-v1/trade
572
+
475
573
  :param str symbol: unified symbol of the market to fetch trades for
476
574
  :param int [since]: timestamp in ms of the earliest trade to fetch
477
575
  :param int [limit]: the maximum amount of trades to fetch
478
576
  :param dict [params]: extra parameters specific to the exchange API endpoint
479
577
  :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
480
578
  """
481
- await self.load_markets()
482
- symbol = self.symbol(symbol)
483
- name = 'trade'
484
- trades = await self.watch_public(name, symbol, params)
579
+ return await self.watch_trades_for_symbols([symbol], since, limit, params)
580
+
581
+ async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
582
+ """
583
+
584
+ https://docs.kraken.com/api/docs/websocket-v1/trade
585
+
586
+ get the list of most recent trades for a list of symbols
587
+ :param str[] symbols: unified symbol of the market to fetch trades for
588
+ :param int [since]: timestamp in ms of the earliest trade to fetch
589
+ :param int [limit]: the maximum amount of trades to fetch
590
+ :param dict [params]: extra parameters specific to the exchange API endpoint
591
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
592
+ """
593
+ trades = await self.watch_multi_helper('trade', 'trade', symbols, None, params)
485
594
  if self.newUpdates:
486
- limit = trades.getLimit(symbol, limit)
595
+ first = self.safe_list(trades, 0)
596
+ tradeSymbol = self.safe_string(first, 'symbol')
597
+ limit = trades.getLimit(tradeSymbol, limit)
487
598
  return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
488
599
 
489
600
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
490
601
  """
491
602
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
603
+
604
+ https://docs.kraken.com/api/docs/websocket-v1/book
605
+
492
606
  :param str symbol: unified symbol of the market to fetch the order book for
493
607
  :param int [limit]: the maximum amount of order book entries to return
494
608
  :param dict [params]: extra parameters specific to the exchange API endpoint
495
609
  :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
496
610
  """
497
- name = 'book'
498
- request = {}
611
+ return await self.watch_order_book_for_symbols([symbol], limit, params)
612
+
613
+ async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
614
+ """
615
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
616
+
617
+ https://docs.kraken.com/api/docs/websocket-v1/book
618
+
619
+ :param str[] symbols: unified array of symbols
620
+ :param int [limit]: the maximum amount of order book entries to return
621
+ :param dict [params]: extra parameters specific to the exchange API endpoint
622
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
623
+ """
624
+ request: dict = {}
499
625
  if limit is not None:
500
- if (limit == 10) or (limit == 25) or (limit == 100) or (limit == 500) or (limit == 1000):
626
+ if self.in_array(limit, [10, 25, 100, 500, 1000]):
501
627
  request['subscription'] = {
502
628
  'depth': limit, # default 10, valid options 10, 25, 100, 500, 1000
503
629
  }
504
630
  else:
505
631
  raise NotSupported(self.id + ' watchOrderBook accepts limit values of 10, 25, 100, 500 and 1000 only')
506
- orderbook = await self.watch_public(name, symbol, self.extend(request, params))
632
+ orderbook = await self.watch_multi_helper('orderbook', 'book', symbols, {'limit': limit}, self.extend(request, params))
507
633
  return orderbook.limit()
508
634
 
509
635
  async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
510
636
  """
511
637
  watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
638
+
639
+ https://docs.kraken.com/api/docs/websocket-v1/ohlc
640
+
512
641
  :param str symbol: unified symbol of the market to fetch OHLCV data for
513
642
  :param str timeframe: the length of time each candle represents
514
643
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -524,7 +653,7 @@ class kraken(ccxt.async_support.kraken):
524
653
  messageHash = name + ':' + timeframe + ':' + wsName
525
654
  url = self.urls['api']['ws']['public']
526
655
  requestId = self.request_id()
527
- subscribe = {
656
+ subscribe: dict = {
528
657
  'event': 'subscribe',
529
658
  'reqid': requestId,
530
659
  'pair': [
@@ -625,13 +754,13 @@ class kraken(ccxt.async_support.kraken):
625
754
  market = self.safe_value(self.options['marketsByWsName'], wsName)
626
755
  symbol = market['symbol']
627
756
  timestamp = None
628
- messageHash = 'book:' + wsName
757
+ messageHash = self.get_message_hash('orderbook', None, symbol)
629
758
  # if self is a snapshot
630
759
  if 'as' in message[1]:
631
760
  # todo get depth from marketsByWsName
632
761
  self.orderbooks[symbol] = self.order_book({}, depth)
633
762
  orderbook = self.orderbooks[symbol]
634
- sides = {
763
+ sides: dict = {
635
764
  'as': 'asks',
636
765
  'bs': 'bids',
637
766
  }
@@ -674,7 +803,7 @@ class kraken(ccxt.async_support.kraken):
674
803
  example = self.safe_value(b, 0)
675
804
  # don't remove self line or I will poop on your face
676
805
  orderbook.limit()
677
- checksum = self.safe_bool(self.options, 'checksum', True)
806
+ checksum = self.handle_option('watchOrderBook', 'checksum', True)
678
807
  if checksum:
679
808
  priceString = self.safe_string(example, 0)
680
809
  amountString = self.safe_string(example, 1)
@@ -693,8 +822,11 @@ class kraken(ccxt.async_support.kraken):
693
822
  payload = ''.join(payloadArray)
694
823
  localChecksum = self.crc32(payload, False)
695
824
  if localChecksum != c:
696
- error = InvalidNonce(self.id + ' invalid checksum')
825
+ error = ChecksumError(self.id + ' ' + self.orderbook_checksum_message(symbol))
826
+ del client.subscriptions[messageHash]
827
+ del self.orderbooks[symbol]
697
828
  client.reject(error, messageHash)
829
+ return
698
830
  orderbook['symbol'] = symbol
699
831
  orderbook['timestamp'] = timestamp
700
832
  orderbook['datetime'] = self.iso8601(timestamp)
@@ -770,7 +902,7 @@ class kraken(ccxt.async_support.kraken):
770
902
  messageHash += ':' + symbol
771
903
  url = self.urls['api']['ws']['private']
772
904
  requestId = self.request_id()
773
- subscribe = {
905
+ subscribe: dict = {
774
906
  'event': 'subscribe',
775
907
  'reqid': requestId,
776
908
  'subscription': {
@@ -787,11 +919,14 @@ class kraken(ccxt.async_support.kraken):
787
919
  async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
788
920
  """
789
921
  watches information on multiple trades made by the user
922
+
923
+ https://docs.kraken.com/api/docs/websocket-v1/owntrades
924
+
790
925
  :param str symbol: unified market symbol of the market trades were made in
791
926
  :param int [since]: the earliest time in ms to fetch trades for
792
927
  :param int [limit]: the maximum number of trade structures to retrieve
793
928
  :param dict [params]: extra parameters specific to the exchange API endpoint
794
- :returns dict[]: a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
929
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
795
930
  """
796
931
  return await self.watch_private('ownTrades', symbol, since, limit, params)
797
932
 
@@ -841,7 +976,7 @@ class kraken(ccxt.async_support.kraken):
841
976
  limit = self.safe_integer(self.options, 'tradesLimit', 1000)
842
977
  self.myTrades = ArrayCache(limit)
843
978
  stored = self.myTrades
844
- symbols = {}
979
+ symbols: dict = {}
845
980
  for i in range(0, len(allTrades)):
846
981
  trades = self.safe_value(allTrades, i, {})
847
982
  ids = list(trades.keys())
@@ -935,7 +1070,9 @@ class kraken(ccxt.async_support.kraken):
935
1070
 
936
1071
  async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
937
1072
  """
938
- :see: https://docs.kraken.com/websockets/#message-openOrders
1073
+
1074
+ https://docs.kraken.com/api/docs/websocket-v1/openorders
1075
+
939
1076
  watches information on multiple orders made by the user
940
1077
  :param str symbol: unified market symbol of the market orders were made in
941
1078
  :param int [since]: the earliest time in ms to fetch orders for
@@ -1030,7 +1167,7 @@ class kraken(ccxt.async_support.kraken):
1030
1167
  if self.orders is None:
1031
1168
  self.orders = ArrayCacheBySymbolById(limit)
1032
1169
  stored = self.orders
1033
- symbols = {}
1170
+ symbols: dict = {}
1034
1171
  for i in range(0, len(allOrders)):
1035
1172
  orders = self.safe_value(allOrders, i, {})
1036
1173
  ids = list(orders.keys())
@@ -1179,6 +1316,107 @@ class kraken(ccxt.async_support.kraken):
1179
1316
  'trades': trades,
1180
1317
  })
1181
1318
 
1319
+ async def watch_multi_helper(self, unifiedName: str, channelName: str, symbols: Strings = None, subscriptionArgs=None, params={}):
1320
+ await self.load_markets()
1321
+ # symbols are required
1322
+ symbols = self.market_symbols(symbols, None, False, True, False)
1323
+ messageHashes = []
1324
+ for i in range(0, len(symbols)):
1325
+ messageHashes.append(self.get_message_hash(unifiedName, None, self.symbol(symbols[i])))
1326
+ # for WS subscriptions, we can't use .marketIds(symbols), instead a custom is field needed
1327
+ markets = self.markets_for_symbols(symbols)
1328
+ wsMarketIds = []
1329
+ for i in range(0, len(markets)):
1330
+ wsMarketId = self.safe_string(markets[i]['info'], 'wsname')
1331
+ wsMarketIds.append(wsMarketId)
1332
+ request: dict = {
1333
+ 'event': 'subscribe',
1334
+ 'reqid': self.request_id(),
1335
+ 'pair': wsMarketIds,
1336
+ 'subscription': {
1337
+ 'name': channelName,
1338
+ },
1339
+ }
1340
+ url = self.urls['api']['ws']['public']
1341
+ return await self.watch_multiple(url, messageHashes, self.deep_extend(request, params), messageHashes, subscriptionArgs)
1342
+
1343
+ async def watch_balance(self, params={}) -> Balances:
1344
+ """
1345
+ watch balance and get the amount of funds available for trading or funds locked in orders
1346
+
1347
+ https://docs.kraken.com/api/docs/websocket-v2/balances
1348
+
1349
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1350
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
1351
+ """
1352
+ await self.load_markets()
1353
+ token = await self.authenticate()
1354
+ messageHash = 'balances'
1355
+ url = self.urls['api']['ws']['privateV2']
1356
+ requestId = self.request_id()
1357
+ subscribe: dict = {
1358
+ 'method': 'subscribe',
1359
+ 'req_id': requestId,
1360
+ 'params': {
1361
+ 'channel': 'balances',
1362
+ 'token': token,
1363
+ },
1364
+ }
1365
+ request = self.deep_extend(subscribe, params)
1366
+ return await self.watch(url, messageHash, request, messageHash)
1367
+
1368
+ def handle_balance(self, client: Client, message):
1369
+ #
1370
+ # {
1371
+ # "channel": "balances",
1372
+ # "data": [
1373
+ # {
1374
+ # "asset": "BTC",
1375
+ # "asset_class": "currency",
1376
+ # "balance": 1.2,
1377
+ # "wallets": [
1378
+ # {
1379
+ # "type": "spot",
1380
+ # "id": "main",
1381
+ # "balance": 1.2
1382
+ # }
1383
+ # ]
1384
+ # }
1385
+ # ],
1386
+ # "type": "snapshot",
1387
+ # "sequence": 1
1388
+ # }
1389
+ #
1390
+ data = self.safe_list(message, 'data', [])
1391
+ result: dict = {'info': message}
1392
+ for i in range(0, len(data)):
1393
+ currencyId = self.safe_string(data[i], 'asset')
1394
+ code = self.safe_currency_code(currencyId)
1395
+ account = self.account()
1396
+ eq = self.safe_string(data[i], 'balance')
1397
+ account['total'] = eq
1398
+ result[code] = account
1399
+ type = 'spot'
1400
+ balance = self.safe_balance(result)
1401
+ oldBalance = self.safe_value(self.balance, type, {})
1402
+ newBalance = self.deep_extend(oldBalance, balance)
1403
+ self.balance[type] = self.safe_balance(newBalance)
1404
+ channel = self.safe_string(message, 'channel')
1405
+ client.resolve(self.balance[type], channel)
1406
+
1407
+ def get_message_hash(self, unifiedElementName: str, subChannelName: Str = None, symbol: Str = None):
1408
+ # unifiedElementName can be : orderbook, trade, ticker, bidask ...
1409
+ # subChannelName only applies to channel that needs specific variation(i.e. depth_50, depth_100..) to be selected
1410
+ withSymbol = symbol is not None
1411
+ messageHash = unifiedElementName
1412
+ if not withSymbol:
1413
+ messageHash += 's'
1414
+ else:
1415
+ messageHash += '@' + symbol
1416
+ if subChannelName is not None:
1417
+ messageHash += '#' + subChannelName
1418
+ return messageHash
1419
+
1182
1420
  def handle_subscription_status(self, client: Client, message):
1183
1421
  #
1184
1422
  # public
@@ -1245,11 +1483,12 @@ class kraken(ccxt.async_support.kraken):
1245
1483
  messageLength = len(message)
1246
1484
  channelName = self.safe_string(message, messageLength - 2)
1247
1485
  name = self.safe_string(info, 'name')
1248
- methods = {
1486
+ methods: dict = {
1249
1487
  # public
1250
1488
  'book': self.handle_order_book,
1251
1489
  'ohlc': self.handle_ohlcv,
1252
1490
  'ticker': self.handle_ticker,
1491
+ 'spread': self.handle_bid_ask,
1253
1492
  'trade': self.handle_trades,
1254
1493
  # private
1255
1494
  'openOrders': self.handle_orders,
@@ -1259,9 +1498,17 @@ class kraken(ccxt.async_support.kraken):
1259
1498
  if method is not None:
1260
1499
  method(client, message, subscription)
1261
1500
  else:
1501
+ channel = self.safe_string(message, 'channel')
1502
+ if channel is not None:
1503
+ methods: dict = {
1504
+ 'balances': self.handle_balance,
1505
+ }
1506
+ method = self.safe_value(methods, channel)
1507
+ if method is not None:
1508
+ method(client, message)
1262
1509
  if self.handle_error_message(client, message):
1263
1510
  event = self.safe_string(message, 'event')
1264
- methods = {
1511
+ methods: dict = {
1265
1512
  'heartbeat': self.handle_heartbeat,
1266
1513
  'systemStatus': self.handle_system_status,
1267
1514
  'subscriptionStatus': self.handle_subscription_status,