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/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,7 @@ class woo(ccxt.async_support.woo):
60
62
  },
61
63
  'streaming': {
62
64
  'ping': self.ping,
63
- 'keepAlive': 10000,
65
+ 'keepAlive': 9000,
64
66
  },
65
67
  'exceptions': {
66
68
  'ws': {
@@ -79,35 +81,61 @@ class woo(ccxt.async_support.woo):
79
81
  return newValue
80
82
 
81
83
  async def watch_public(self, messageHash, message):
82
- self.check_required_uid()
83
- url = self.urls['api']['ws']['public'] + '/' + self.uid
84
+ urlUid = '/' + self.uid if (self.uid) else ''
85
+ url = self.urls['api']['ws']['public'] + urlUid
84
86
  requestId = self.request_id(url)
85
- subscribe = {
87
+ subscribe: dict = {
86
88
  'id': requestId,
87
89
  }
88
90
  request = self.extend(subscribe, message)
89
91
  return await self.watch(url, messageHash, request, messageHash, subscribe)
90
92
 
91
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
+ """
92
106
  await self.load_markets()
93
- name = 'orderbook'
107
+ method = None
108
+ method, params = self.handle_option_and_params(params, 'watchOrderBook', 'method', 'orderbook')
94
109
  market = self.market(symbol)
95
- topic = market['id'] + '@' + name
96
- 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 = {
97
115
  'event': 'subscribe',
98
116
  'topic': topic,
117
+ 'id': requestId,
99
118
  }
100
- message = self.extend(request, params)
101
- 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)
102
129
  return orderbook.limit()
103
130
 
104
131
  def handle_order_book(self, client: Client, message):
105
132
  #
106
133
  # {
107
- # "topic": "PERP_BTC_USDT@orderbook",
108
- # "ts": 1650121915308,
134
+ # "topic": "PERP_BTC_USDT@orderbookupdate",
135
+ # "ts": 1722500373999,
109
136
  # "data": {
110
137
  # "symbol": "PERP_BTC_USDT",
138
+ # "prevTs": 1722500373799,
111
139
  # "bids": [
112
140
  # [
113
141
  # 0.30891,
@@ -123,25 +151,108 @@ class woo(ccxt.async_support.woo):
123
151
  # }
124
152
  # }
125
153
  #
126
- data = self.safe_value(message, 'data')
154
+ data = self.safe_dict(message, 'data')
127
155
  marketId = self.safe_string(data, 'symbol')
128
156
  market = self.safe_market(marketId)
129
157
  symbol = market['symbol']
130
158
  topic = self.safe_string(message, 'topic')
131
- orderbook = self.safe_value(self.orderbooks, symbol)
132
- if orderbook is None:
133
- 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', []))
134
229
  timestamp = self.safe_integer(message, 'ts')
135
- snapshot = self.parse_order_book(data, symbol, timestamp, 'bids', 'asks')
136
- orderbook.reset(snapshot)
137
- 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])
138
242
 
139
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
+ """
140
250
  await self.load_markets()
141
251
  name = 'ticker'
142
252
  market = self.market(symbol)
253
+ symbol = market['symbol']
143
254
  topic = market['id'] + '@' + name
144
- request = {
255
+ request: dict = {
145
256
  'event': 'subscribe',
146
257
  'topic': topic,
147
258
  }
@@ -214,10 +325,20 @@ class woo(ccxt.async_support.woo):
214
325
  return message
215
326
 
216
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
+ """
217
337
  await self.load_markets()
338
+ symbols = self.market_symbols(symbols)
218
339
  name = 'tickers'
219
340
  topic = name
220
- request = {
341
+ request: dict = {
221
342
  'event': 'subscribe',
222
343
  'topic': topic,
223
344
  }
@@ -267,7 +388,88 @@ class woo(ccxt.async_support.woo):
267
388
  result.append(ticker)
268
389
  client.resolve(result, topic)
269
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
+
270
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
+ """
271
473
  await self.load_markets()
272
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'):
273
475
  raise ExchangeError(self.id + ' watchOHLCV timeframe argument must be 1m, 5m, 15m, 30m, 1h, 1d, 1w, 1M')
@@ -275,7 +477,7 @@ class woo(ccxt.async_support.woo):
275
477
  interval = self.safe_string(self.timeframes, timeframe, timeframe)
276
478
  name = 'kline'
277
479
  topic = market['id'] + '@' + name + '_' + interval
278
- request = {
480
+ request: dict = {
279
481
  'event': 'subscribe',
280
482
  'topic': topic,
281
483
  }
@@ -329,10 +531,22 @@ class woo(ccxt.async_support.woo):
329
531
  client.resolve(stored, topic)
330
532
 
331
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
+ """
332
545
  await self.load_markets()
333
546
  market = self.market(symbol)
547
+ symbol = market['symbol']
334
548
  topic = market['id'] + '@trade'
335
- request = {
549
+ request: dict = {
336
550
  'event': 'subscribe',
337
551
  'topic': topic,
338
552
  }
@@ -381,17 +595,58 @@ class woo(ccxt.async_support.woo):
381
595
  # "side":"BUY",
382
596
  # "source":0
383
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
+ # }
384
627
  #
385
628
  marketId = self.safe_string(trade, 'symbol')
386
629
  market = self.safe_market(marketId, market)
387
630
  symbol = market['symbol']
388
- price = self.safe_string(trade, 'price')
389
- amount = self.safe_string(trade, 'size')
631
+ price = self.safe_string_2(trade, 'executedPrice', 'price')
632
+ amount = self.safe_string_2(trade, 'executedQuantity', 'size')
390
633
  cost = Precise.string_mul(price, amount)
391
634
  side = self.safe_string_lower(trade, 'side')
392
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
+ }
393
648
  return self.safe_trade({
394
- 'id': None,
649
+ 'id': self.safe_string(trade, 'tradeId'),
395
650
  'timestamp': timestamp,
396
651
  'datetime': self.iso8601(timestamp),
397
652
  'symbol': symbol,
@@ -399,17 +654,17 @@ class woo(ccxt.async_support.woo):
399
654
  'price': price,
400
655
  'amount': amount,
401
656
  'cost': cost,
402
- 'order': None,
403
- 'takerOrMaker': None,
404
- 'type': None,
405
- 'fee': None,
657
+ 'order': self.safe_string(trade, 'orderId'),
658
+ 'takerOrMaker': takerOrMaker,
659
+ 'type': type,
660
+ 'fee': fee,
406
661
  'info': trade,
407
662
  }, market)
408
663
 
409
664
  def check_required_uid(self, error=True):
410
665
  if not self.uid:
411
666
  if error:
412
- raise AuthenticationError(self.id + ' requires `uid` credential')
667
+ raise AuthenticationError(self.id + ' requires `uid` credential(woox calls it `application_id`)')
413
668
  else:
414
669
  return False
415
670
  return True
@@ -426,7 +681,7 @@ class woo(ccxt.async_support.woo):
426
681
  ts = str(self.nonce())
427
682
  auth = '|' + ts
428
683
  signature = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256)
429
- request = {
684
+ request: dict = {
430
685
  'event': event,
431
686
  'params': {
432
687
  'apikey': self.apiKey,
@@ -435,36 +690,53 @@ class woo(ccxt.async_support.woo):
435
690
  },
436
691
  }
437
692
  message = self.extend(request, params)
438
- self.watch(url, messageHash, message, messageHash)
693
+ self.watch(url, messageHash, message, messageHash, message)
439
694
  return await future
440
695
 
441
696
  async def watch_private(self, messageHash, message, params={}):
442
697
  await self.authenticate(params)
443
698
  url = self.urls['api']['ws']['private'] + '/' + self.uid
444
699
  requestId = self.request_id(url)
445
- subscribe = {
700
+ subscribe: dict = {
446
701
  'id': requestId,
447
702
  }
448
703
  request = self.extend(subscribe, message)
449
704
  return await self.watch(url, messageHash, request, messageHash, subscribe)
450
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
+
451
716
  async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
452
717
  """
718
+
719
+ https://docs.woox.io/#executionreport
720
+ https://docs.woox.io/#algoexecutionreportv2
721
+
453
722
  watches information on multiple orders made by the user
454
723
  :param str symbol: unified market symbol of the market orders were made in
455
724
  :param int [since]: the earliest time in ms to fetch orders for
456
725
  :param int [limit]: the maximum number of order structures to retrieve
457
726
  :param dict [params]: extra parameters specific to the exchange API endpoint
727
+ :param bool [params.trigger]: True if trigger order
458
728
  :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
459
729
  """
460
730
  await self.load_markets()
461
- 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'])
462
734
  messageHash = topic
463
735
  if symbol is not None:
464
736
  market = self.market(symbol)
465
737
  symbol = market['symbol']
466
738
  messageHash += ':' + symbol
467
- request = {
739
+ request: dict = {
468
740
  'event': 'subscribe',
469
741
  'topic': topic,
470
742
  }
@@ -474,6 +746,39 @@ class woo(ccxt.async_support.woo):
474
746
  limit = orders.getLimit(symbol, limit)
475
747
  return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
476
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
+
477
782
  def parse_ws_order(self, order, market=None):
478
783
  #
479
784
  # {
@@ -509,9 +814,10 @@ class woo(ccxt.async_support.woo):
509
814
  'cost': self.safe_string(order, 'totalFee'),
510
815
  'currency': self.safe_string(order, 'feeAsset'),
511
816
  }
817
+ priceString = self.safe_string(order, 'price')
512
818
  price = self.safe_number(order, 'price')
513
819
  avgPrice = self.safe_number(order, 'avgPrice')
514
- if (price == 0) and (avgPrice is not None):
820
+ if Precise.string_eq(priceString, '0') and (avgPrice is not None):
515
821
  price = avgPrice
516
822
  amount = self.safe_float(order, 'quantity')
517
823
  side = self.safe_string_lower(order, 'side')
@@ -542,7 +848,7 @@ class woo(ccxt.async_support.woo):
542
848
  'triggerPrice': None,
543
849
  'amount': amount,
544
850
  'cost': None,
545
- 'average': None,
851
+ 'average': avgPrice,
546
852
  'filled': filled,
547
853
  'remaining': remaining,
548
854
  'status': status,
@@ -580,11 +886,24 @@ class woo(ccxt.async_support.woo):
580
886
  # }
581
887
  # }
582
888
  #
583
- order = self.safe_value(message, 'data')
584
- 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)
585
905
 
586
- def handle_order(self, client: Client, message):
587
- topic = 'executionreport'
906
+ def handle_order(self, client: Client, message, topic):
588
907
  parsed = self.parse_ws_order(message)
589
908
  symbol = self.safe_string(parsed, 'symbol')
590
909
  orderId = self.safe_string(parsed, 'id')
@@ -610,33 +929,82 @@ class woo(ccxt.async_support.woo):
610
929
  messageHashSymbol = topic + ':' + symbol
611
930
  client.resolve(self.orders, messageHashSymbol)
612
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
+
613
974
  async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
614
975
  """
615
- :see: https://docs.woo.org/#position-push
976
+
977
+ https://docs.woox.io/#position-push
978
+
616
979
  watch all open positions
617
980
  :param str[]|None symbols: list of unified market symbols
981
+ @param since
982
+ @param limit
618
983
  :param dict params: extra parameters specific to the exchange API endpoint
619
984
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
620
985
  """
621
986
  await self.load_markets()
622
- messageHash = ''
987
+ messageHashes = []
623
988
  symbols = self.market_symbols(symbols)
624
989
  if not self.is_empty(symbols):
625
- messageHash = '::' + ','.join(symbols)
626
- 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')
627
995
  url = self.urls['api']['ws']['private'] + '/' + self.uid
628
996
  client = self.client(url)
629
997
  self.set_positions_cache(client, symbols)
630
998
  fetchPositionsSnapshot = self.handle_option('watchPositions', 'fetchPositionsSnapshot', True)
631
- awaitPositionsSnapshot = self.safe_bool('watchPositions', 'awaitPositionsSnapshot', True)
999
+ awaitPositionsSnapshot = self.handle_option('watchPositions', 'awaitPositionsSnapshot', True)
632
1000
  if fetchPositionsSnapshot and awaitPositionsSnapshot and self.positions is None:
633
1001
  snapshot = await client.future('fetchPositionsSnapshot')
634
1002
  return self.filter_by_symbols_since_limit(snapshot, symbols, since, limit, True)
635
- request = {
1003
+ request: dict = {
636
1004
  'event': 'subscribe',
637
1005
  'topic': 'position',
638
1006
  }
639
- newPositions = await self.watch_private(messageHash, request, params)
1007
+ newPositions = await self.watch_private_multiple(messageHashes, request, params)
640
1008
  if self.newUpdates:
641
1009
  return newPositions
642
1010
  return self.filter_by_symbols_since_limit(self.positions, symbols, since, limit, True)
@@ -705,20 +1073,15 @@ class woo(ccxt.async_support.woo):
705
1073
  position = self.parse_position(rawPosition, market)
706
1074
  newPositions.append(position)
707
1075
  cache.append(position)
708
- messageHashes = self.find_message_hashes(client, 'positions::')
709
- for i in range(0, len(messageHashes)):
710
- messageHash = messageHashes[i]
711
- parts = messageHash.split('::')
712
- symbolsString = parts[1]
713
- symbols = symbolsString.split(',')
714
- positions = self.filter_by_array(newPositions, 'symbol', symbols, False)
715
- if not self.is_empty(positions):
716
- client.resolve(positions, messageHash)
1076
+ messageHash = 'positions::' + market['symbol']
1077
+ client.resolve(position, messageHash)
717
1078
  client.resolve(newPositions, 'positions')
718
1079
 
719
1080
  async def watch_balance(self, params={}) -> Balances:
720
1081
  """
721
- :see: https://docs.woo.org/#balance
1082
+
1083
+ https://docs.woox.io/#balance
1084
+
722
1085
  watch balance and get the amount of funds available for trading or funds locked in orders
723
1086
  :param dict [params]: extra parameters specific to the exchange API endpoint
724
1087
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
@@ -726,7 +1089,7 @@ class woo(ccxt.async_support.woo):
726
1089
  await self.load_markets()
727
1090
  topic = 'balance'
728
1091
  messageHash = topic
729
- request = {
1092
+ request: dict = {
730
1093
  'event': 'subscribe',
731
1094
  'topic': topic,
732
1095
  }
@@ -811,19 +1174,22 @@ class woo(ccxt.async_support.woo):
811
1174
  def handle_message(self, client: Client, message):
812
1175
  if self.handle_error_message(client, message):
813
1176
  return
814
- methods = {
1177
+ methods: dict = {
815
1178
  'ping': self.handle_ping,
816
1179
  'pong': self.handle_pong,
817
1180
  'subscribe': self.handle_subscribe,
818
1181
  'orderbook': self.handle_order_book,
1182
+ 'orderbookupdate': self.handle_order_book,
819
1183
  'ticker': self.handle_ticker,
820
1184
  'tickers': self.handle_tickers,
821
1185
  'kline': self.handle_ohlcv,
822
1186
  'auth': self.handle_auth,
823
1187
  'executionreport': self.handle_order_update,
1188
+ 'algoexecutionreportv2': self.handle_order_update,
824
1189
  'trade': self.handle_trade,
825
1190
  'balance': self.handle_balance,
826
1191
  'position': self.handle_positions,
1192
+ 'bbos': self.handle_bid_ask,
827
1193
  }
828
1194
  event = self.safe_string(message, 'event')
829
1195
  method = self.safe_value(methods, event)
@@ -873,6 +1239,12 @@ class woo(ccxt.async_support.woo):
873
1239
  # "ts": 1657117712212
874
1240
  # }
875
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)
876
1248
  return message
877
1249
 
878
1250
  def handle_auth(self, client: Client, message):