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/woo.py CHANGED
@@ -21,26 +21,28 @@ class woo(ccxt.async_support.woo):
21
21
  'has': {
22
22
  'ws': True,
23
23
  'watchBalance': True,
24
- 'watchMyTrades': False,
24
+ 'watchMyTrades': True,
25
25
  'watchOHLCV': True,
26
26
  'watchOrderBook': True,
27
27
  'watchOrders': True,
28
28
  'watchTicker': True,
29
29
  'watchTickers': True,
30
+ 'watchBidsAsks': True,
30
31
  'watchTrades': True,
32
+ 'watchTradesForSymbols': False,
31
33
  'watchPositions': True,
32
34
  },
33
35
  'urls': {
34
36
  'api': {
35
37
  'ws': {
36
- 'public': 'wss://wss.woo.org/ws/stream',
37
- 'private': 'wss://wss.woo.network/v2/ws/private/stream',
38
+ 'public': 'wss://wss.woox.io/ws/stream',
39
+ 'private': 'wss://wss.woox.io/v2/ws/private/stream',
38
40
  },
39
41
  },
40
42
  'test': {
41
43
  'ws': {
42
- 'public': 'wss://wss.staging.woo.org/ws/stream',
43
- 'private': 'wss://wss.staging.woo.org/v2/ws/private/stream',
44
+ 'public': 'wss://wss.staging.woox.io/ws/stream',
45
+ 'private': 'wss://wss.staging.woox.io/v2/ws/private/stream',
44
46
  },
45
47
  },
46
48
  },
@@ -60,7 +62,14 @@ class woo(ccxt.async_support.woo):
60
62
  },
61
63
  'streaming': {
62
64
  'ping': self.ping,
63
- 'keepAlive': 10000,
65
+ 'keepAlive': 9000,
66
+ },
67
+ 'exceptions': {
68
+ 'ws': {
69
+ 'exact': {
70
+ 'Auth is needed.': AuthenticationError,
71
+ },
72
+ },
64
73
  },
65
74
  })
66
75
 
@@ -72,35 +81,61 @@ class woo(ccxt.async_support.woo):
72
81
  return newValue
73
82
 
74
83
  async def watch_public(self, messageHash, message):
75
- self.check_required_uid()
76
- url = self.urls['api']['ws']['public'] + '/' + self.uid
84
+ urlUid = '/' + self.uid if (self.uid) else ''
85
+ url = self.urls['api']['ws']['public'] + urlUid
77
86
  requestId = self.request_id(url)
78
- subscribe = {
87
+ subscribe: dict = {
79
88
  'id': requestId,
80
89
  }
81
90
  request = self.extend(subscribe, message)
82
91
  return await self.watch(url, messageHash, request, messageHash, subscribe)
83
92
 
84
93
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
94
+ """
95
+
96
+ https://docs.woox.io/#orderbookupdate
97
+ https://docs.woox.io/#orderbook
98
+
99
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
100
+ :param str symbol: unified symbol of the market to fetch the order book for
101
+ :param int [limit]: the maximum amount of order book entries to return.
102
+ :param dict [params]: extra parameters specific to the exchange API endpoint
103
+ :param str [params.method]: either(default) 'orderbook' or 'orderbookupdate', default is 'orderbook'
104
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
105
+ """
85
106
  await self.load_markets()
86
- name = 'orderbook'
107
+ method = None
108
+ method, params = self.handle_option_and_params(params, 'watchOrderBook', 'method', 'orderbook')
87
109
  market = self.market(symbol)
88
- topic = market['id'] + '@' + name
89
- request = {
110
+ topic = market['id'] + '@' + method
111
+ urlUid = '/' + self.uid if (self.uid) else ''
112
+ url = self.urls['api']['ws']['public'] + urlUid
113
+ requestId = self.request_id(url)
114
+ request: dict = {
90
115
  'event': 'subscribe',
91
116
  'topic': topic,
117
+ 'id': requestId,
92
118
  }
93
- message = self.extend(request, params)
94
- orderbook = await self.watch_public(topic, message)
119
+ subscription: dict = {
120
+ 'id': str(requestId),
121
+ 'name': method,
122
+ 'symbol': symbol,
123
+ 'limit': limit,
124
+ 'params': params,
125
+ }
126
+ if method == 'orderbookupdate':
127
+ subscription['method'] = self.handle_order_book_subscription
128
+ orderbook = await self.watch(url, topic, self.extend(request, params), topic, subscription)
95
129
  return orderbook.limit()
96
130
 
97
131
  def handle_order_book(self, client: Client, message):
98
132
  #
99
133
  # {
100
- # "topic": "PERP_BTC_USDT@orderbook",
101
- # "ts": 1650121915308,
134
+ # "topic": "PERP_BTC_USDT@orderbookupdate",
135
+ # "ts": 1722500373999,
102
136
  # "data": {
103
137
  # "symbol": "PERP_BTC_USDT",
138
+ # "prevTs": 1722500373799,
104
139
  # "bids": [
105
140
  # [
106
141
  # 0.30891,
@@ -116,25 +151,108 @@ class woo(ccxt.async_support.woo):
116
151
  # }
117
152
  # }
118
153
  #
119
- data = self.safe_value(message, 'data')
154
+ data = self.safe_dict(message, 'data')
120
155
  marketId = self.safe_string(data, 'symbol')
121
156
  market = self.safe_market(marketId)
122
157
  symbol = market['symbol']
123
158
  topic = self.safe_string(message, 'topic')
124
- orderbook = self.safe_value(self.orderbooks, symbol)
125
- if orderbook is None:
126
- orderbook = self.order_book({})
159
+ method = self.safe_string(topic.split('@'), 1)
160
+ if method == 'orderbookupdate':
161
+ if not (symbol in self.orderbooks):
162
+ return
163
+ orderbook = self.orderbooks[symbol]
164
+ timestamp = self.safe_integer(orderbook, 'timestamp')
165
+ if timestamp is None:
166
+ orderbook.cache.append(message)
167
+ else:
168
+ try:
169
+ ts = self.safe_integer(message, 'ts')
170
+ if ts > timestamp:
171
+ self.handle_order_book_message(client, message, orderbook)
172
+ client.resolve(orderbook, topic)
173
+ except Exception as e:
174
+ del self.orderbooks[symbol]
175
+ del client.subscriptions[topic]
176
+ client.reject(e, topic)
177
+ else:
178
+ if not (symbol in self.orderbooks):
179
+ defaultLimit = self.safe_integer(self.options, 'watchOrderBookLimit', 1000)
180
+ subscription = client.subscriptions[topic]
181
+ limit = self.safe_integer(subscription, 'limit', defaultLimit)
182
+ self.orderbooks[symbol] = self.order_book({}, limit)
183
+ orderbook = self.orderbooks[symbol]
184
+ timestamp = self.safe_integer(message, 'ts')
185
+ snapshot = self.parse_order_book(data, symbol, timestamp, 'bids', 'asks')
186
+ orderbook.reset(snapshot)
187
+ client.resolve(orderbook, topic)
188
+
189
+ def handle_order_book_subscription(self, client: Client, message, subscription):
190
+ defaultLimit = self.safe_integer(self.options, 'watchOrderBookLimit', 1000)
191
+ limit = self.safe_integer(subscription, 'limit', defaultLimit)
192
+ symbol = self.safe_string(subscription, 'symbol') # watchOrderBook
193
+ if symbol in self.orderbooks:
194
+ del self.orderbooks[symbol]
195
+ self.orderbooks[symbol] = self.order_book({}, limit)
196
+ self.spawn(self.fetch_order_book_snapshot, client, message, subscription)
197
+
198
+ async def fetch_order_book_snapshot(self, client, message, subscription):
199
+ symbol = self.safe_string(subscription, 'symbol')
200
+ messageHash = self.safe_string(message, 'topic')
201
+ try:
202
+ defaultLimit = self.safe_integer(self.options, 'watchOrderBookLimit', 1000)
203
+ limit = self.safe_integer(subscription, 'limit', defaultLimit)
204
+ params = self.safe_value(subscription, 'params')
205
+ snapshot = await self.fetch_rest_order_book_safe(symbol, limit, params)
206
+ if self.safe_value(self.orderbooks, symbol) is None:
207
+ # if the orderbook is dropped before the snapshot is received
208
+ return
209
+ orderbook = self.orderbooks[symbol]
210
+ orderbook.reset(snapshot)
211
+ messages = orderbook.cache
212
+ for i in range(0, len(messages)):
213
+ messageItem = messages[i]
214
+ ts = self.safe_integer(messageItem, 'ts')
215
+ if ts < orderbook['timestamp']:
216
+ continue
217
+ else:
218
+ self.handle_order_book_message(client, messageItem, orderbook)
219
+ self.orderbooks[symbol] = orderbook
220
+ client.resolve(orderbook, messageHash)
221
+ except Exception as e:
222
+ del client.subscriptions[messageHash]
223
+ client.reject(e, messageHash)
224
+
225
+ def handle_order_book_message(self, client: Client, message, orderbook):
226
+ data = self.safe_dict(message, 'data')
227
+ self.handle_deltas(orderbook['asks'], self.safe_value(data, 'asks', []))
228
+ self.handle_deltas(orderbook['bids'], self.safe_value(data, 'bids', []))
127
229
  timestamp = self.safe_integer(message, 'ts')
128
- snapshot = self.parse_order_book(data, symbol, timestamp, 'bids', 'asks')
129
- orderbook.reset(snapshot)
130
- client.resolve(orderbook, topic)
230
+ orderbook['timestamp'] = timestamp
231
+ orderbook['datetime'] = self.iso8601(timestamp)
232
+ return orderbook
233
+
234
+ def handle_delta(self, bookside, delta):
235
+ price = self.safe_float_2(delta, 'price', 0)
236
+ amount = self.safe_float_2(delta, 'quantity', 1)
237
+ bookside.store(price, amount)
238
+
239
+ def handle_deltas(self, bookside, deltas):
240
+ for i in range(0, len(deltas)):
241
+ self.handle_delta(bookside, deltas[i])
131
242
 
132
243
  async def watch_ticker(self, symbol: str, params={}) -> Ticker:
244
+ """
245
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
246
+ :param str symbol: unified symbol of the market to fetch the ticker for
247
+ :param dict [params]: extra parameters specific to the exchange API endpoint
248
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
249
+ """
133
250
  await self.load_markets()
134
251
  name = 'ticker'
135
252
  market = self.market(symbol)
253
+ symbol = market['symbol']
136
254
  topic = market['id'] + '@' + name
137
- request = {
255
+ request: dict = {
138
256
  'event': 'subscribe',
139
257
  'topic': topic,
140
258
  }
@@ -207,10 +325,20 @@ class woo(ccxt.async_support.woo):
207
325
  return message
208
326
 
209
327
  async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
328
+ """
329
+
330
+ https://docs.woox.io/#24h-tickers
331
+
332
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
333
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
334
+ :param dict [params]: extra parameters specific to the exchange API endpoint
335
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
336
+ """
210
337
  await self.load_markets()
338
+ symbols = self.market_symbols(symbols)
211
339
  name = 'tickers'
212
340
  topic = name
213
- request = {
341
+ request: dict = {
214
342
  'event': 'subscribe',
215
343
  'topic': topic,
216
344
  }
@@ -260,7 +388,88 @@ class woo(ccxt.async_support.woo):
260
388
  result.append(ticker)
261
389
  client.resolve(result, topic)
262
390
 
391
+ async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
392
+ """
393
+
394
+ https://docs.woox.io/#bbos
395
+
396
+ watches best bid & ask for symbols
397
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
398
+ :param dict [params]: extra parameters specific to the exchange API endpoint
399
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
400
+ """
401
+ await self.load_markets()
402
+ symbols = self.market_symbols(symbols, None, False)
403
+ name = 'bbos'
404
+ topic = name
405
+ request: dict = {
406
+ 'event': 'subscribe',
407
+ 'topic': topic,
408
+ }
409
+ message = self.extend(request, params)
410
+ tickers = await self.watch_public(topic, message)
411
+ if self.newUpdates:
412
+ return tickers
413
+ return self.filter_by_array(self.bidsasks, 'symbol', symbols)
414
+
415
+ def handle_bid_ask(self, client: Client, message):
416
+ #
417
+ # {
418
+ # "topic": "bbos",
419
+ # "ts": 1618822376000,
420
+ # "data": [
421
+ # {
422
+ # "symbol": "SPOT_FIL_USDT",
423
+ # "ask": 159.0318,
424
+ # "askSize": 370.43,
425
+ # "bid": 158.9158,
426
+ # "bidSize": 16
427
+ # }
428
+ # ]
429
+ # }
430
+ #
431
+ topic = self.safe_string(message, 'topic')
432
+ data = self.safe_list(message, 'data', [])
433
+ timestamp = self.safe_integer(message, 'ts')
434
+ result: dict = {}
435
+ for i in range(0, len(data)):
436
+ ticker = self.safe_dict(data, i)
437
+ ticker['ts'] = timestamp
438
+ parsedTicker = self.parse_ws_bid_ask(ticker)
439
+ symbol = parsedTicker['symbol']
440
+ self.bidsasks[symbol] = parsedTicker
441
+ result[symbol] = parsedTicker
442
+ client.resolve(result, topic)
443
+
444
+ def parse_ws_bid_ask(self, ticker, market=None):
445
+ marketId = self.safe_string(ticker, 'symbol')
446
+ market = self.safe_market(marketId, market)
447
+ symbol = self.safe_string(market, 'symbol')
448
+ timestamp = self.safe_integer(ticker, 'ts')
449
+ return self.safe_ticker({
450
+ 'symbol': symbol,
451
+ 'timestamp': timestamp,
452
+ 'datetime': self.iso8601(timestamp),
453
+ 'ask': self.safe_string(ticker, 'ask'),
454
+ 'askVolume': self.safe_string(ticker, 'askSize'),
455
+ 'bid': self.safe_string(ticker, 'bid'),
456
+ 'bidVolume': self.safe_string(ticker, 'bidSize'),
457
+ 'info': ticker,
458
+ }, market)
459
+
263
460
  async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
461
+ """
462
+ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
463
+
464
+ https://docs.woox.io/#k-line
465
+
466
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
467
+ :param str timeframe: the length of time each candle represents
468
+ :param int [since]: timestamp in ms of the earliest candle to fetch
469
+ :param int [limit]: the maximum amount of candles to fetch
470
+ :param dict [params]: extra parameters specific to the exchange API endpoint
471
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
472
+ """
264
473
  await self.load_markets()
265
474
  if (timeframe != '1m') and (timeframe != '5m') and (timeframe != '15m') and (timeframe != '30m') and (timeframe != '1h') and (timeframe != '1d') and (timeframe != '1w') and (timeframe != '1M'):
266
475
  raise ExchangeError(self.id + ' watchOHLCV timeframe argument must be 1m, 5m, 15m, 30m, 1h, 1d, 1w, 1M')
@@ -268,7 +477,7 @@ class woo(ccxt.async_support.woo):
268
477
  interval = self.safe_string(self.timeframes, timeframe, timeframe)
269
478
  name = 'kline'
270
479
  topic = market['id'] + '@' + name + '_' + interval
271
- request = {
480
+ request: dict = {
272
481
  'event': 'subscribe',
273
482
  'topic': topic,
274
483
  }
@@ -322,10 +531,22 @@ class woo(ccxt.async_support.woo):
322
531
  client.resolve(stored, topic)
323
532
 
324
533
  async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
534
+ """
535
+ watches information on multiple trades made in a market
536
+
537
+ https://docs.woox.io/#trade
538
+
539
+ :param str symbol: unified market symbol of the market trades were made in
540
+ :param int [since]: the earliest time in ms to fetch trades for
541
+ :param int [limit]: the maximum number of trade structures to retrieve
542
+ :param dict [params]: extra parameters specific to the exchange API endpoint
543
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
544
+ """
325
545
  await self.load_markets()
326
546
  market = self.market(symbol)
547
+ symbol = market['symbol']
327
548
  topic = market['id'] + '@trade'
328
- request = {
549
+ request: dict = {
329
550
  'event': 'subscribe',
330
551
  'topic': topic,
331
552
  }
@@ -374,17 +595,58 @@ class woo(ccxt.async_support.woo):
374
595
  # "side":"BUY",
375
596
  # "source":0
376
597
  # }
598
+ # private trade
599
+ # {
600
+ # "msgType": 0, # execution report
601
+ # "symbol": "SPOT_BTC_USDT",
602
+ # "clientOrderId": 0,
603
+ # "orderId": 54774393,
604
+ # "type": "MARKET",
605
+ # "side": "BUY",
606
+ # "quantity": 0.0,
607
+ # "price": 0.0,
608
+ # "tradeId": 56201985,
609
+ # "executedPrice": 23534.06,
610
+ # "executedQuantity": 0.00040791,
611
+ # "fee": 2.1E-7,
612
+ # "feeAsset": "BTC",
613
+ # "totalExecutedQuantity": 0.00040791,
614
+ # "avgPrice": 23534.06,
615
+ # "status": "FILLED",
616
+ # "reason": "",
617
+ # "orderTag": "default",
618
+ # "totalFee": 2.1E-7,
619
+ # "feeCurrency": "BTC",
620
+ # "totalRebate": 0,
621
+ # "rebateCurrency": "USDT",
622
+ # "visible": 0.0,
623
+ # "timestamp": 1675406261689,
624
+ # "reduceOnly": False,
625
+ # "maker": False
626
+ # }
377
627
  #
378
628
  marketId = self.safe_string(trade, 'symbol')
379
629
  market = self.safe_market(marketId, market)
380
630
  symbol = market['symbol']
381
- price = self.safe_string(trade, 'price')
382
- amount = self.safe_string(trade, 'size')
631
+ price = self.safe_string_2(trade, 'executedPrice', 'price')
632
+ amount = self.safe_string_2(trade, 'executedQuantity', 'size')
383
633
  cost = Precise.string_mul(price, amount)
384
634
  side = self.safe_string_lower(trade, 'side')
385
635
  timestamp = self.safe_integer(trade, 'timestamp')
636
+ maker = self.safe_bool(trade, 'marker')
637
+ takerOrMaker = None
638
+ if maker is not None:
639
+ takerOrMaker = 'maker' if maker else 'taker'
640
+ type = self.safe_string_lower(trade, 'type')
641
+ fee = None
642
+ feeCost = self.safe_number(trade, 'fee')
643
+ if feeCost is not None:
644
+ fee = {
645
+ 'cost': feeCost,
646
+ 'currency': self.safe_currency_code(self.safe_string(trade, 'feeCurrency')),
647
+ }
386
648
  return self.safe_trade({
387
- 'id': None,
649
+ 'id': self.safe_string(trade, 'tradeId'),
388
650
  'timestamp': timestamp,
389
651
  'datetime': self.iso8601(timestamp),
390
652
  'symbol': symbol,
@@ -392,17 +654,17 @@ class woo(ccxt.async_support.woo):
392
654
  'price': price,
393
655
  'amount': amount,
394
656
  'cost': cost,
395
- 'order': None,
396
- 'takerOrMaker': None,
397
- 'type': None,
398
- 'fee': None,
657
+ 'order': self.safe_string(trade, 'orderId'),
658
+ 'takerOrMaker': takerOrMaker,
659
+ 'type': type,
660
+ 'fee': fee,
399
661
  'info': trade,
400
662
  }, market)
401
663
 
402
664
  def check_required_uid(self, error=True):
403
665
  if not self.uid:
404
666
  if error:
405
- raise AuthenticationError(self.id + ' requires `uid` credential')
667
+ raise AuthenticationError(self.id + ' requires `uid` credential(woox calls it `application_id`)')
406
668
  else:
407
669
  return False
408
670
  return True
@@ -413,12 +675,13 @@ class woo(ccxt.async_support.woo):
413
675
  client = self.client(url)
414
676
  messageHash = 'authenticated'
415
677
  event = 'auth'
416
- future = self.safe_value(client.subscriptions, messageHash)
417
- if future is None:
678
+ future = client.future(messageHash)
679
+ authenticated = self.safe_value(client.subscriptions, messageHash)
680
+ if authenticated is None:
418
681
  ts = str(self.nonce())
419
682
  auth = '|' + ts
420
683
  signature = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256)
421
- request = {
684
+ request: dict = {
422
685
  'event': event,
423
686
  'params': {
424
687
  'apikey': self.apiKey,
@@ -427,29 +690,53 @@ class woo(ccxt.async_support.woo):
427
690
  },
428
691
  }
429
692
  message = self.extend(request, params)
430
- future = self.watch(url, messageHash, message)
431
- client.subscriptions[messageHash] = future
432
- return future
693
+ self.watch(url, messageHash, message, messageHash, message)
694
+ return await future
433
695
 
434
696
  async def watch_private(self, messageHash, message, params={}):
435
697
  await self.authenticate(params)
436
698
  url = self.urls['api']['ws']['private'] + '/' + self.uid
437
699
  requestId = self.request_id(url)
438
- subscribe = {
700
+ subscribe: dict = {
439
701
  'id': requestId,
440
702
  }
441
703
  request = self.extend(subscribe, message)
442
704
  return await self.watch(url, messageHash, request, messageHash, subscribe)
443
705
 
706
+ async def watch_private_multiple(self, messageHashes, message, params={}):
707
+ await self.authenticate(params)
708
+ url = self.urls['api']['ws']['private'] + '/' + self.uid
709
+ requestId = self.request_id(url)
710
+ subscribe: dict = {
711
+ 'id': requestId,
712
+ }
713
+ request = self.extend(subscribe, message)
714
+ return await self.watch_multiple(url, messageHashes, request, messageHashes, subscribe)
715
+
444
716
  async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
717
+ """
718
+
719
+ https://docs.woox.io/#executionreport
720
+ https://docs.woox.io/#algoexecutionreportv2
721
+
722
+ watches information on multiple orders made by the user
723
+ :param str symbol: unified market symbol of the market orders were made in
724
+ :param int [since]: the earliest time in ms to fetch orders for
725
+ :param int [limit]: the maximum number of order structures to retrieve
726
+ :param dict [params]: extra parameters specific to the exchange API endpoint
727
+ :param bool [params.trigger]: True if trigger order
728
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
729
+ """
445
730
  await self.load_markets()
446
- topic = 'executionreport'
731
+ trigger = self.safe_bool_2(params, 'stop', 'trigger', False)
732
+ topic = 'algoexecutionreportv2' if (trigger) else 'executionreport'
733
+ params = self.omit(params, ['stop', 'trigger'])
447
734
  messageHash = topic
448
735
  if symbol is not None:
449
736
  market = self.market(symbol)
450
737
  symbol = market['symbol']
451
738
  messageHash += ':' + symbol
452
- request = {
739
+ request: dict = {
453
740
  'event': 'subscribe',
454
741
  'topic': topic,
455
742
  }
@@ -459,6 +746,39 @@ class woo(ccxt.async_support.woo):
459
746
  limit = orders.getLimit(symbol, limit)
460
747
  return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
461
748
 
749
+ async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
750
+ """
751
+
752
+ https://docs.woox.io/#executionreport
753
+ https://docs.woox.io/#algoexecutionreportv2
754
+
755
+ watches information on multiple trades made by the user
756
+ :param str symbol: unified market symbol of the market orders were made in
757
+ :param int [since]: the earliest time in ms to fetch orders for
758
+ :param int [limit]: the maximum number of order structures to retrieve
759
+ :param dict [params]: extra parameters specific to the exchange API endpoint
760
+ :param bool [params.trigger]: True if trigger order
761
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
762
+ """
763
+ await self.load_markets()
764
+ trigger = self.safe_bool_2(params, 'stop', 'trigger', False)
765
+ topic = 'algoexecutionreportv2' if (trigger) else 'executionreport'
766
+ params = self.omit(params, ['stop', 'trigger'])
767
+ messageHash = 'myTrades'
768
+ if symbol is not None:
769
+ market = self.market(symbol)
770
+ symbol = market['symbol']
771
+ messageHash += ':' + symbol
772
+ request: dict = {
773
+ 'event': 'subscribe',
774
+ 'topic': topic,
775
+ }
776
+ message = self.extend(request, params)
777
+ trades = await self.watch_private(messageHash, message)
778
+ if self.newUpdates:
779
+ limit = trades.getLimit(symbol, limit)
780
+ return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
781
+
462
782
  def parse_ws_order(self, order, market=None):
463
783
  #
464
784
  # {
@@ -494,9 +814,10 @@ class woo(ccxt.async_support.woo):
494
814
  'cost': self.safe_string(order, 'totalFee'),
495
815
  'currency': self.safe_string(order, 'feeAsset'),
496
816
  }
817
+ priceString = self.safe_string(order, 'price')
497
818
  price = self.safe_number(order, 'price')
498
819
  avgPrice = self.safe_number(order, 'avgPrice')
499
- if (price == 0) and (avgPrice is not None):
820
+ if Precise.string_eq(priceString, '0') and (avgPrice is not None):
500
821
  price = avgPrice
501
822
  amount = self.safe_float(order, 'quantity')
502
823
  side = self.safe_string_lower(order, 'side')
@@ -527,7 +848,7 @@ class woo(ccxt.async_support.woo):
527
848
  'triggerPrice': None,
528
849
  'amount': amount,
529
850
  'cost': None,
530
- 'average': None,
851
+ 'average': avgPrice,
531
852
  'filled': filled,
532
853
  'remaining': remaining,
533
854
  'status': status,
@@ -565,11 +886,24 @@ class woo(ccxt.async_support.woo):
565
886
  # }
566
887
  # }
567
888
  #
568
- order = self.safe_value(message, 'data')
569
- self.handle_order(client, order)
889
+ topic = self.safe_string(message, 'topic')
890
+ data = self.safe_value(message, 'data')
891
+ if isinstance(data, list):
892
+ # algoexecutionreportv2
893
+ for i in range(0, len(data)):
894
+ order = data[i]
895
+ tradeId = self.omit_zero(self.safe_string(data, 'tradeId'))
896
+ if tradeId is not None:
897
+ self.handle_my_trade(client, order)
898
+ self.handle_order(client, order, topic)
899
+ else:
900
+ # executionreport
901
+ tradeId = self.omit_zero(self.safe_string(data, 'tradeId'))
902
+ if tradeId is not None:
903
+ self.handle_my_trade(client, data)
904
+ self.handle_order(client, data, topic)
570
905
 
571
- def handle_order(self, client: Client, message):
572
- topic = 'executionreport'
906
+ def handle_order(self, client: Client, message, topic):
573
907
  parsed = self.parse_ws_order(message)
574
908
  symbol = self.safe_string(parsed, 'symbol')
575
909
  orderId = self.safe_string(parsed, 'id')
@@ -595,33 +929,82 @@ class woo(ccxt.async_support.woo):
595
929
  messageHashSymbol = topic + ':' + symbol
596
930
  client.resolve(self.orders, messageHashSymbol)
597
931
 
932
+ def handle_my_trade(self, client: Client, message):
933
+ #
934
+ # {
935
+ # "msgType": 0, # execution report
936
+ # "symbol": "SPOT_BTC_USDT",
937
+ # "clientOrderId": 0,
938
+ # "orderId": 54774393,
939
+ # "type": "MARKET",
940
+ # "side": "BUY",
941
+ # "quantity": 0.0,
942
+ # "price": 0.0,
943
+ # "tradeId": 56201985,
944
+ # "executedPrice": 23534.06,
945
+ # "executedQuantity": 0.00040791,
946
+ # "fee": 2.1E-7,
947
+ # "feeAsset": "BTC",
948
+ # "totalExecutedQuantity": 0.00040791,
949
+ # "avgPrice": 23534.06,
950
+ # "status": "FILLED",
951
+ # "reason": "",
952
+ # "orderTag": "default",
953
+ # "totalFee": 2.1E-7,
954
+ # "feeCurrency": "BTC",
955
+ # "totalRebate": 0,
956
+ # "rebateCurrency": "USDT",
957
+ # "visible": 0.0,
958
+ # "timestamp": 1675406261689,
959
+ # "reduceOnly": False,
960
+ # "maker": False
961
+ # }
962
+ #
963
+ myTrades = self.myTrades
964
+ if myTrades is None:
965
+ limit = self.safe_integer(self.options, 'tradesLimit', 1000)
966
+ myTrades = ArrayCacheBySymbolById(limit)
967
+ trade = self.parse_ws_trade(message)
968
+ myTrades.append(trade)
969
+ messageHash = 'myTrades:' + trade['symbol']
970
+ client.resolve(myTrades, messageHash)
971
+ messageHash = 'myTrades'
972
+ client.resolve(myTrades, messageHash)
973
+
598
974
  async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
599
975
  """
600
- :see: https://docs.woo.org/#position-push
976
+
977
+ https://docs.woox.io/#position-push
978
+
601
979
  watch all open positions
602
980
  :param str[]|None symbols: list of unified market symbols
981
+ @param since
982
+ @param limit
603
983
  :param dict params: extra parameters specific to the exchange API endpoint
604
984
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
605
985
  """
606
986
  await self.load_markets()
607
- messageHash = ''
987
+ messageHashes = []
608
988
  symbols = self.market_symbols(symbols)
609
989
  if not self.is_empty(symbols):
610
- messageHash = '::' + ','.join(symbols)
611
- messageHash = 'positions' + messageHash
990
+ for i in range(0, len(symbols)):
991
+ symbol = symbols[i]
992
+ messageHashes.append('positions::' + symbol)
993
+ else:
994
+ messageHashes.append('positions')
612
995
  url = self.urls['api']['ws']['private'] + '/' + self.uid
613
996
  client = self.client(url)
614
997
  self.set_positions_cache(client, symbols)
615
998
  fetchPositionsSnapshot = self.handle_option('watchPositions', 'fetchPositionsSnapshot', True)
616
- awaitPositionsSnapshot = self.safe_bool('watchPositions', 'awaitPositionsSnapshot', True)
999
+ awaitPositionsSnapshot = self.handle_option('watchPositions', 'awaitPositionsSnapshot', True)
617
1000
  if fetchPositionsSnapshot and awaitPositionsSnapshot and self.positions is None:
618
1001
  snapshot = await client.future('fetchPositionsSnapshot')
619
1002
  return self.filter_by_symbols_since_limit(snapshot, symbols, since, limit, True)
620
- request = {
1003
+ request: dict = {
621
1004
  'event': 'subscribe',
622
1005
  'topic': 'position',
623
1006
  }
624
- newPositions = await self.watch_private(messageHash, request, params)
1007
+ newPositions = await self.watch_private_multiple(messageHashes, request, params)
625
1008
  if self.newUpdates:
626
1009
  return newPositions
627
1010
  return self.filter_by_symbols_since_limit(self.positions, symbols, since, limit, True)
@@ -690,20 +1073,15 @@ class woo(ccxt.async_support.woo):
690
1073
  position = self.parse_position(rawPosition, market)
691
1074
  newPositions.append(position)
692
1075
  cache.append(position)
693
- messageHashes = self.find_message_hashes(client, 'positions::')
694
- for i in range(0, len(messageHashes)):
695
- messageHash = messageHashes[i]
696
- parts = messageHash.split('::')
697
- symbolsString = parts[1]
698
- symbols = symbolsString.split(',')
699
- positions = self.filter_by_array(newPositions, 'symbol', symbols, False)
700
- if not self.is_empty(positions):
701
- client.resolve(positions, messageHash)
1076
+ messageHash = 'positions::' + market['symbol']
1077
+ client.resolve(position, messageHash)
702
1078
  client.resolve(newPositions, 'positions')
703
1079
 
704
1080
  async def watch_balance(self, params={}) -> Balances:
705
1081
  """
706
- :see: https://docs.woo.org/#balance
1082
+
1083
+ https://docs.woox.io/#balance
1084
+
707
1085
  watch balance and get the amount of funds available for trading or funds locked in orders
708
1086
  :param dict [params]: extra parameters specific to the exchange API endpoint
709
1087
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
@@ -711,7 +1089,7 @@ class woo(ccxt.async_support.woo):
711
1089
  await self.load_markets()
712
1090
  topic = 'balance'
713
1091
  messageHash = topic
714
- request = {
1092
+ request: dict = {
715
1093
  'event': 'subscribe',
716
1094
  'topic': topic,
717
1095
  }
@@ -768,20 +1146,50 @@ class woo(ccxt.async_support.woo):
768
1146
  self.balance = self.safe_balance(self.balance)
769
1147
  client.resolve(self.balance, 'balance')
770
1148
 
1149
+ def handle_error_message(self, client: Client, message):
1150
+ #
1151
+ # {"id":"1","event":"subscribe","success":false,"ts":1710780997216,"errorMsg":"Auth is needed."}
1152
+ #
1153
+ if not ('success' in message):
1154
+ return False
1155
+ success = self.safe_bool(message, 'success')
1156
+ if success:
1157
+ return False
1158
+ errorMessage = self.safe_string(message, 'errorMsg')
1159
+ try:
1160
+ if errorMessage is not None:
1161
+ feedback = self.id + ' ' + self.json(message)
1162
+ self.throw_exactly_matched_exception(self.exceptions['exact'], errorMessage, feedback)
1163
+ return False
1164
+ except Exception as error:
1165
+ if isinstance(error, AuthenticationError):
1166
+ messageHash = 'authenticated'
1167
+ client.reject(error, messageHash)
1168
+ if messageHash in client.subscriptions:
1169
+ del client.subscriptions[messageHash]
1170
+ else:
1171
+ client.reject(error)
1172
+ return True
1173
+
771
1174
  def handle_message(self, client: Client, message):
772
- methods = {
1175
+ if self.handle_error_message(client, message):
1176
+ return
1177
+ methods: dict = {
773
1178
  'ping': self.handle_ping,
774
1179
  'pong': self.handle_pong,
775
1180
  'subscribe': self.handle_subscribe,
776
1181
  'orderbook': self.handle_order_book,
1182
+ 'orderbookupdate': self.handle_order_book,
777
1183
  'ticker': self.handle_ticker,
778
1184
  'tickers': self.handle_tickers,
779
1185
  'kline': self.handle_ohlcv,
780
1186
  'auth': self.handle_auth,
781
1187
  'executionreport': self.handle_order_update,
1188
+ 'algoexecutionreportv2': self.handle_order_update,
782
1189
  'trade': self.handle_trade,
783
1190
  'balance': self.handle_balance,
784
1191
  'position': self.handle_positions,
1192
+ 'bbos': self.handle_bid_ask,
785
1193
  }
786
1194
  event = self.safe_string(message, 'event')
787
1195
  method = self.safe_value(methods, event)
@@ -831,6 +1239,12 @@ class woo(ccxt.async_support.woo):
831
1239
  # "ts": 1657117712212
832
1240
  # }
833
1241
  #
1242
+ id = self.safe_string(message, 'id')
1243
+ subscriptionsById = self.index_by(client.subscriptions, 'id')
1244
+ subscription = self.safe_value(subscriptionsById, id, {})
1245
+ method = self.safe_value(subscription, 'method')
1246
+ if method is not None:
1247
+ method(client, message, subscription)
834
1248
  return message
835
1249
 
836
1250
  def handle_auth(self, client: Client, message):
@@ -844,7 +1258,9 @@ class woo(ccxt.async_support.woo):
844
1258
  messageHash = 'authenticated'
845
1259
  success = self.safe_value(message, 'success')
846
1260
  if success:
847
- client.resolve(message, messageHash)
1261
+ # client.resolve(message, messageHash)
1262
+ future = self.safe_value(client.futures, 'authenticated')
1263
+ future.resolve(True)
848
1264
  else:
849
1265
  error = AuthenticationError(self.json(message))
850
1266
  client.reject(error, messageHash)