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/xt.py ADDED
@@ -0,0 +1,1067 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
+ # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
+
6
+ import ccxt.async_support
7
+ from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp
8
+ from ccxt.base.types import Balances, Int, Market, Order, OrderBook, Str, Strings, Ticker, Tickers, Trade
9
+ from ccxt.async_support.base.ws.client import Client
10
+ from typing import List
11
+
12
+
13
+ class xt(ccxt.async_support.xt):
14
+
15
+ def describe(self):
16
+ return self.deep_extend(super(xt, self).describe(), {
17
+ 'has': {
18
+ 'ws': True,
19
+ 'watchOHLCV': True,
20
+ 'watchOrderBook': True,
21
+ 'watchTicker': True,
22
+ 'watchTickers': True,
23
+ 'watchTrades': True,
24
+ 'watchTradesForSymbols': False,
25
+ 'watchBalance': True,
26
+ 'watchOrders': True,
27
+ 'watchMyTrades': True,
28
+ 'watchPositions': None, # TODO https://doc.xt.com/#futures_user_websocket_v2position
29
+ },
30
+ 'urls': {
31
+ 'api': {
32
+ 'ws': {
33
+ 'spot': 'wss://stream.xt.com',
34
+ 'contract': 'wss://fstream.xt.com/ws',
35
+ },
36
+ },
37
+ },
38
+ 'options': {
39
+ 'tradesLimit': 1000,
40
+ 'ordersLimit': 1000,
41
+ 'OHLCVLimit': 1000,
42
+ 'watchTicker': {
43
+ 'method': 'ticker', # agg_ticker(contract only)
44
+ },
45
+ 'watchTickers': {
46
+ 'method': 'tickers', # agg_tickers(contract only)
47
+ },
48
+ },
49
+ 'streaming': {
50
+ 'keepAlive': 20000,
51
+ 'ping': self.ping,
52
+ },
53
+ 'token': None,
54
+ })
55
+
56
+ async def get_listen_key(self, isContract: bool):
57
+ """
58
+ @ignore
59
+ required for private endpoints
60
+ :param str isContract: True for contract trades
61
+
62
+ https://doc.xt.com/#websocket_privategetToken
63
+ https://doc.xt.com/#futures_user_websocket_v2base
64
+
65
+ :returns str: listen key / access token
66
+ """
67
+ self.check_required_credentials()
68
+ tradeType = 'contract' if isContract else 'spot'
69
+ url = self.urls['api']['ws'][tradeType]
70
+ if not isContract:
71
+ url = url + '/private'
72
+ client = self.client(url)
73
+ token = self.safe_string(client.subscriptions, 'token')
74
+ if token is None:
75
+ if isContract:
76
+ response = await self.privateLinearGetFutureUserV1UserListenKey()
77
+ #
78
+ # {
79
+ # returnCode: '0',
80
+ # msgInfo: 'success',
81
+ # error: null,
82
+ # result: '3BC1D71D6CF96DA3458FC35B05B633351684511731128'
83
+ # }
84
+ #
85
+ client.subscriptions['token'] = self.safe_string(response, 'result')
86
+ else:
87
+ response = await self.privateSpotPostWsToken()
88
+ #
89
+ # {
90
+ # "rc": 0,
91
+ # "mc": "SUCCESS",
92
+ # "ma": [],
93
+ # "result": {
94
+ # "token": "eyJhbqGciOiJSUzI1NiJ9.eyJhY2NvdW50SWQiOiIyMTQ2Mjg1MzIyNTU5Iiwic3ViIjoibGh4dDRfMDAwMUBzbmFwbWFpbC5jYyIsInNjb3BlIjoiYXV0aCIsImlzcyI6Inh0LmNvbSIsImxhc3RBdXRoVGltZSI6MTY2MzgxMzY5MDk1NSwic2lnblR5cGUiOiJBSyIsInVzZXJOYW1lIjoibGh4dDRfMDAwMUBzbmFwbWFpbC5jYyIsImV4cCI6MTY2NjQwNTY5MCwiZGV2aWNlIjoidW5rbm93biIsInVzZXJJZCI6MjE0NjI4NTMyMjU1OX0.h3zJlJBQrK2x1HvUxsKivnn6PlSrSDXXXJ7WqHAYSrN2CG5XPTKc4zKnTVoYFbg6fTS0u1fT8wH7wXqcLWXX71vm0YuP8PCvdPAkUIq4-HyzltbPr5uDYd0UByx0FPQtq1exvsQGe7evXQuDXx3SEJXxEqUbq_DNlXPTq_JyScI",
95
+ # "refreshToken": "eyJhbGciOiqJSUzI1NiJ9.eyJhY2NvdW50SWQiOiIyMTQ2Mjg1MzIyNTU5Iiwic3ViIjoibGh4dDRfMDAwMUBzbmFwbWFpbC5jYyIsInNjb3BlIjoicmVmcmVzaCIsImlzcyI6Inh0LmNvbSIsImxhc3RBdXRoVGltZSI6MTY2MzgxMzY5MDk1NSwic2lnblR5cGUiOiJBSyIsInVzZXJOYW1lIjoibGh4dDRfMDAwMUBzbmFwbWFpbC5jYyIsImV4cCI6MTY2NjQwNTY5MCwiZGV2aWNlIjoidW5rbm93biIsInVzZXJJZCI6MjE0NjI4NTMyMjU1OX0.Fs3YVm5YrEOzzYOSQYETSmt9iwxUHBovh2u73liv1hLUec683WGfktA_s28gMk4NCpZKFeQWFii623FvdfNoteXR0v1yZ2519uNvNndtuZICDdv3BQ4wzW1wIHZa1skxFfqvsDnGdXpjqu9UFSbtHwxprxeYfnxChNk4ssei430"
96
+ # }
97
+ # }
98
+ #
99
+ result = self.safe_dict(response, 'result')
100
+ client.subscriptions['token'] = self.safe_string(result, 'accessToken')
101
+ return client.subscriptions['token']
102
+
103
+ def get_cache_index(self, orderbook, cache):
104
+ # return the first index of the cache that can be applied to the orderbook or -1 if not possible
105
+ nonce = self.safe_integer(orderbook, 'nonce')
106
+ firstDelta = self.safe_value(cache, 0)
107
+ firstDeltaNonce = self.safe_integer_2(firstDelta, 'i', 'u')
108
+ if nonce < firstDeltaNonce - 1:
109
+ return -1
110
+ for i in range(0, len(cache)):
111
+ delta = cache[i]
112
+ deltaNonce = self.safe_integer_2(delta, 'i', 'u')
113
+ if deltaNonce >= nonce:
114
+ return i
115
+ return len(cache)
116
+
117
+ def handle_delta(self, orderbook, delta):
118
+ orderbook['nonce'] = self.safe_integer_2(delta, 'i', 'u')
119
+ obAsks = self.safe_list(delta, 'a', [])
120
+ obBids = self.safe_list(delta, 'b', [])
121
+ bids = orderbook['bids']
122
+ asks = orderbook['asks']
123
+ for i in range(0, len(obBids)):
124
+ bid = obBids[i]
125
+ price = self.safe_number(bid, 0)
126
+ quantity = self.safe_number(bid, 1)
127
+ bids.store(price, quantity)
128
+ for i in range(0, len(obAsks)):
129
+ ask = obAsks[i]
130
+ price = self.safe_number(ask, 0)
131
+ quantity = self.safe_number(ask, 1)
132
+ asks.store(price, quantity)
133
+ # self.handleBidAsks(storedBids, bids)
134
+ # self.handleBidAsks(storedAsks, asks)
135
+
136
+ async def subscribe(self, name: str, access: str, methodName: str, market: Market = None, symbols: List[str] = None, params={}):
137
+ """
138
+ @ignore
139
+ Connects to a websocket channel
140
+
141
+ https://doc.xt.com/#websocket_privaterequestFormat
142
+ https://doc.xt.com/#futures_market_websocket_v2base
143
+
144
+ :param str name: name of the channel
145
+ :param str access: public or private
146
+ :param str methodName: the name of the CCXT class method
147
+ :param dict [market]: CCXT market
148
+ :param str[] [symbols]: unified market symbols
149
+ :param dict params: extra parameters specific to the xt api
150
+ :returns dict: data from the websocket stream
151
+ """
152
+ privateAccess = access == 'private'
153
+ type = None
154
+ type, params = self.handle_market_type_and_params(methodName, market, params)
155
+ isContract = (type != 'spot')
156
+ subscribe = {
157
+ 'method': 'SUBSCRIBE' if isContract else 'subscribe',
158
+ 'id': self.number_to_string(self.milliseconds()) + name, # call back ID
159
+ }
160
+ if privateAccess:
161
+ if not isContract:
162
+ subscribe['params'] = [name]
163
+ subscribe['listenKey'] = await self.get_listen_key(isContract)
164
+ else:
165
+ listenKey = await self.get_listen_key(isContract)
166
+ param = name + '@' + listenKey
167
+ subscribe['params'] = [param]
168
+ else:
169
+ subscribe['params'] = [name]
170
+ tradeType = 'contract' if isContract else 'spot'
171
+ messageHash = name + '::' + tradeType
172
+ if symbols is not None:
173
+ messageHash = messageHash + '::' + ','.join(symbols)
174
+ request = self.extend(subscribe, params)
175
+ tail = access
176
+ if isContract:
177
+ tail = 'user' if privateAccess else 'market'
178
+ url = self.urls['api']['ws'][tradeType] + '/' + tail
179
+ return await self.watch(url, messageHash, request, messageHash)
180
+
181
+ async def watch_ticker(self, symbol: str, params={}) -> Ticker:
182
+ """
183
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
184
+
185
+ https://doc.xt.com/#websocket_publictickerRealTime
186
+ https://doc.xt.com/#futures_market_websocket_v2tickerRealTime
187
+ https://doc.xt.com/#futures_market_websocket_v2aggTickerRealTime
188
+
189
+ :param str symbol: unified symbol of the market to fetch the ticker for
190
+ :param dict params: extra parameters specific to the xt api endpoint
191
+ :param str [params.method]: 'agg_ticker'(contract only) or 'ticker', default = 'ticker' - the endpoint that will be streamed
192
+ :returns dict: a `ticker structure <https://docs.ccxt.com/en/latest/manual.html#ticker-structure>`
193
+ """
194
+ await self.load_markets()
195
+ market = self.market(symbol)
196
+ options = self.safe_dict(self.options, 'watchTicker')
197
+ defaultMethod = self.safe_string(options, 'method', 'ticker')
198
+ method = self.safe_string(params, 'method', defaultMethod)
199
+ name = method + '@' + market['id']
200
+ return await self.subscribe(name, 'public', 'watchTicker', market, None, params)
201
+
202
+ async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
203
+ """
204
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
205
+
206
+ https://doc.xt.com/#websocket_publicallTicker
207
+ https://doc.xt.com/#futures_market_websocket_v2allTicker
208
+ https://doc.xt.com/#futures_market_websocket_v2allAggTicker
209
+
210
+ :param str [symbols]: unified market symbols
211
+ :param dict params: extra parameters specific to the xt api endpoint
212
+ :param str [params.method]: 'agg_tickers'(contract only) or 'tickers', default = 'tickers' - the endpoint that will be streamed
213
+ :returns dict: a `ticker structure <https://docs.ccxt.com/en/latest/manual.html#ticker-structure>`
214
+ """
215
+ await self.load_markets()
216
+ options = self.safe_dict(self.options, 'watchTickers')
217
+ defaultMethod = self.safe_string(options, 'method', 'tickers')
218
+ name = self.safe_string(params, 'method', defaultMethod)
219
+ market = None
220
+ if symbols is not None:
221
+ market = self.market(symbols[0])
222
+ tickers = await self.subscribe(name, 'public', 'watchTickers', market, symbols, params)
223
+ if self.newUpdates:
224
+ return tickers
225
+ return self.filter_by_array(self.tickers, 'symbol', symbols)
226
+
227
+ async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
228
+ """
229
+ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
230
+
231
+ https://doc.xt.com/#websocket_publicsymbolKline
232
+ https://doc.xt.com/#futures_market_websocket_v2symbolKline
233
+
234
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
235
+ :param str timeframe: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, or 1M
236
+ :param int [since]: not used by xt watchOHLCV
237
+ :param int [limit]: not used by xt watchOHLCV
238
+ :param dict params: extra parameters specific to the xt api endpoint
239
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
240
+ """
241
+ await self.load_markets()
242
+ market = self.market(symbol)
243
+ name = 'kline@' + market['id'] + ',' + timeframe
244
+ ohlcv = await self.subscribe(name, 'public', 'watchOHLCV', market, None, params)
245
+ if self.newUpdates:
246
+ limit = ohlcv.getLimit(symbol, limit)
247
+ return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
248
+
249
+ async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
250
+ """
251
+ get the list of most recent trades for a particular symbol
252
+
253
+ https://doc.xt.com/#websocket_publicdealRecord
254
+ https://doc.xt.com/#futures_market_websocket_v2dealRecord
255
+
256
+ :param str symbol: unified symbol of the market to fetch trades for
257
+ :param int [since]: timestamp in ms of the earliest trade to fetch
258
+ :param int [limit]: the maximum amount of trades to fetch
259
+ :param dict params: extra parameters specific to the xt api endpoint
260
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/en/latest/manual.html?#public-trades>`
261
+ """
262
+ await self.load_markets()
263
+ market = self.market(symbol)
264
+ name = 'trade@' + market['id']
265
+ trades = await self.subscribe(name, 'public', 'watchTrades', market, None, params)
266
+ if self.newUpdates:
267
+ limit = trades.getLimit(symbol, limit)
268
+ return self.filter_by_since_limit(trades, since, limit, 'timestamp')
269
+
270
+ async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
271
+ """
272
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
273
+
274
+ https://doc.xt.com/#websocket_publiclimitDepth
275
+ https://doc.xt.com/#websocket_publicincreDepth
276
+ https://doc.xt.com/#futures_market_websocket_v2limitDepth
277
+ https://doc.xt.com/#futures_market_websocket_v2increDepth
278
+
279
+ :param str symbol: unified symbol of the market to fetch the order book for
280
+ :param int [limit]: not used by xt watchOrderBook
281
+ :param dict params: extra parameters specific to the xt api endpoint
282
+ :param int [params.levels]: 5, 10, 20, or 50
283
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/en/latest/manual.html#order-book-structure>` indexed by market symbols
284
+ """
285
+ await self.load_markets()
286
+ market = self.market(symbol)
287
+ levels = self.safe_string(params, 'levels')
288
+ params = self.omit(params, 'levels')
289
+ name = 'depth_update@' + market['id']
290
+ if levels is not None:
291
+ name = 'depth@' + market['id'] + ',' + levels
292
+ orderbook = await self.subscribe(name, 'public', 'watchOrderBook', market, None, params)
293
+ return orderbook.limit()
294
+
295
+ async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
296
+ """
297
+ watches information on multiple orders made by the user
298
+
299
+ https://doc.xt.com/#websocket_privateorderChange
300
+ https://doc.xt.com/#futures_user_websocket_v2order
301
+
302
+ :param str [symbol]: unified market symbol
303
+ :param int [since]: not used by xt watchOrders
304
+ :param int [limit]: the maximum number of orders to return
305
+ :param dict params: extra parameters specific to the xt api endpoint
306
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/en/latest/manual.html#order-structure>`
307
+ """
308
+ await self.load_markets()
309
+ name = 'order'
310
+ market = None
311
+ if symbol is not None:
312
+ market = self.market(symbol)
313
+ orders = await self.subscribe(name, 'private', 'watchOrders', market, None, params)
314
+ if self.newUpdates:
315
+ limit = orders.getLimit(symbol, limit)
316
+ return self.filter_by_since_limit(orders, since, limit, 'timestamp')
317
+
318
+ async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
319
+ """
320
+ watches information on multiple trades made by the user
321
+
322
+ https://doc.xt.com/#websocket_privateorderDeal
323
+ https://doc.xt.com/#futures_user_websocket_v2trade
324
+
325
+ :param str symbol: unified market symbol of the market orders were made in
326
+ :param int [since]: the earliest time in ms to fetch orders for
327
+ :param int [limit]: the maximum number of orde structures to retrieve
328
+ :param dict params: extra parameters specific to the kucoin api endpoint
329
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
330
+ """
331
+ await self.load_markets()
332
+ name = 'trade'
333
+ market = None
334
+ if symbol is not None:
335
+ market = self.market(symbol)
336
+ trades = await self.subscribe(name, 'private', 'watchMyTrades', market, None, params)
337
+ if self.newUpdates:
338
+ limit = trades.getLimit(symbol, limit)
339
+ return self.filter_by_since_limit(trades, since, limit, 'timestamp')
340
+
341
+ async def watch_balance(self, params={}) -> Balances:
342
+ """
343
+ watches information on multiple orders made by the user
344
+
345
+ https://doc.xt.com/#websocket_privatebalanceChange
346
+ https://doc.xt.com/#futures_user_websocket_v2balance
347
+
348
+ :param dict params: extra parameters specific to the xt api endpoint
349
+ :returns dict[]: a list of `balance structures <https://docs.ccxt.com/#/?id=balance-structure>`
350
+ """
351
+ await self.load_markets()
352
+ name = 'balance'
353
+ return await self.subscribe(name, 'private', 'watchBalance', None, None, params)
354
+
355
+ def handle_ticker(self, client: Client, message: dict):
356
+ #
357
+ # spot
358
+ #
359
+ # {
360
+ # topic: 'ticker',
361
+ # event: 'ticker@btc_usdt',
362
+ # data: {
363
+ # s: 'btc_usdt', # symbol
364
+ # t: 1683501935877, # time(Last transaction time)
365
+ # cv: '-82.67', # priceChangeValue(24 hour price change)
366
+ # cr: '-0.0028', # priceChangeRate 24-hour price change(percentage)
367
+ # o: '28823.87', # open price
368
+ # c: '28741.20', # close price
369
+ # h: '29137.64', # highest price
370
+ # l: '28660.93', # lowest price
371
+ # q: '6372.601573', # quantity
372
+ # v: '184086075.2772391' # volume
373
+ # }
374
+ # }
375
+ #
376
+ # contract
377
+ #
378
+ # {
379
+ # "topic": "ticker",
380
+ # "event": "ticker@btc_usdt",
381
+ # "data": {
382
+ # "s": "btc_index", # trading pair
383
+ # "o": "49000", # opening price
384
+ # "c": "50000", # closing price
385
+ # "h": "0.1", # highest price
386
+ # "l": "0.1", # lowest price
387
+ # "a": "0.1", # volume
388
+ # "v": "0.1", # turnover
389
+ # "ch": "0.21", # quote change
390
+ # "t": 123124124 # timestamp
391
+ # }
392
+ # }
393
+ #
394
+ # agg_ticker(contract)
395
+ #
396
+ # {
397
+ # "topic": "agg_ticker",
398
+ # "event": "agg_ticker@btc_usdt",
399
+ # "data": {
400
+ # "s": "btc_index", # trading pair
401
+ # "o": "49000", # opening price
402
+ # "c": "50000", # closing price
403
+ # "h": "0.1", # highest price
404
+ # "l": "0.1", # lowest price
405
+ # "a": "0.1", # volume
406
+ # "v": "0.1", # turnover
407
+ # "ch": "0.21", # quote change
408
+ # "i": "0.21" , # index price
409
+ # "m": "0.21", # mark price
410
+ # "bp": "0.21", # bid price
411
+ # "ap": "0.21" , # ask price
412
+ # "t": 123124124 # timestamp
413
+ # }
414
+ # }
415
+ #
416
+ data = self.safe_dict(message, 'data')
417
+ marketId = self.safe_string(data, 's')
418
+ if marketId is not None:
419
+ cv = self.safe_string(data, 'cv')
420
+ isSpot = cv is not None
421
+ ticker = self.parse_ticker(data)
422
+ symbol = ticker['symbol']
423
+ self.tickers[symbol] = ticker
424
+ event = self.safe_string(message, 'event')
425
+ messageHashTail = 'spot' if isSpot else 'contract'
426
+ messageHash = event + '::' + messageHashTail
427
+ client.resolve(ticker, messageHash)
428
+ return message
429
+
430
+ def handle_tickers(self, client: Client, message: dict):
431
+ #
432
+ # spot
433
+ #
434
+ # {
435
+ # topic: 'tickers',
436
+ # event: 'tickers',
437
+ # data: [
438
+ # {
439
+ # s: 'elon_usdt',
440
+ # t: 1683502958381,
441
+ # cv: '-0.0000000125',
442
+ # cr: '-0.0495',
443
+ # o: '0.0000002522',
444
+ # c: '0.0000002397',
445
+ # h: '0.0000002690',
446
+ # l: '0.0000002371',
447
+ # q: '3803783034.0000000000',
448
+ # v: '955.3260820022'
449
+ # },
450
+ # ...
451
+ # ]
452
+ # }
453
+ #
454
+ # contract
455
+ #
456
+ # {
457
+ # "topic": "tickers",
458
+ # "event": "tickers",
459
+ # "data": [
460
+ # {
461
+ # "s": "btc_index", # trading pair
462
+ # "o": "49000", # opening price
463
+ # "c": "50000", # closing price
464
+ # "h": "0.1", # highest price
465
+ # "l": "0.1", # lowest price
466
+ # "a": "0.1", # volume
467
+ # "v": "0.1", # turnover
468
+ # "ch": "0.21", # quote change
469
+ # "t": 123124124 # timestamp
470
+ # }
471
+ # ]
472
+ # }
473
+ #
474
+ # agg_ticker(contract)
475
+ #
476
+ # {
477
+ # "topic": "agg_tickers",
478
+ # "event": "agg_tickers",
479
+ # "data": [
480
+ # {
481
+ # "s": "btc_index", # trading pair
482
+ # "o": "49000", # opening price
483
+ # "c": "50000", # closing price
484
+ # "h": "0.1", # highest price
485
+ # "l": "0.1", # lowest price
486
+ # "a": "0.1", # volume
487
+ # "v": "0.1", # turnover
488
+ # "ch": "0.21", # quote change
489
+ # "i": "0.21" , # index price
490
+ # "m": "0.21", # mark price
491
+ # "bp": "0.21", # bid price
492
+ # "ap": "0.21" , # ask price
493
+ # "t": 123124124 # timestamp
494
+ # }
495
+ # ]
496
+ # }
497
+ #
498
+ data = self.safe_list(message, 'data', [])
499
+ firstTicker = self.safe_dict(data, 0)
500
+ spotTest = self.safe_string_2(firstTicker, 'cv', 'aq')
501
+ tradeType = 'spot' if (spotTest is not None) else 'contract'
502
+ newTickers = []
503
+ for i in range(0, len(data)):
504
+ tickerData = data[i]
505
+ ticker = self.parse_ticker(tickerData)
506
+ symbol = ticker['symbol']
507
+ self.tickers[symbol] = ticker
508
+ newTickers.append(ticker)
509
+ messageHashStart = self.safe_string(message, 'topic') + '::' + tradeType
510
+ messageHashes = self.find_message_hashes(client, messageHashStart + '::')
511
+ for i in range(0, len(messageHashes)):
512
+ messageHash = messageHashes[i]
513
+ parts = messageHash.split('::')
514
+ symbolsString = parts[2]
515
+ symbols = symbolsString.split(',')
516
+ tickers = self.filter_by_array(newTickers, 'symbol', symbols)
517
+ tickersSymbols = list(tickers.keys())
518
+ numTickers = len(tickersSymbols)
519
+ if numTickers > 0:
520
+ client.resolve(tickers, messageHash)
521
+ client.resolve(self.tickers, messageHashStart)
522
+ return message
523
+
524
+ def handle_ohlcv(self, client: Client, message: dict):
525
+ #
526
+ # spot
527
+ #
528
+ # {
529
+ # "topic": "kline",
530
+ # "event": "kline@btc_usdt,5m",
531
+ # "data": {
532
+ # "s": "btc_usdt", # symbol
533
+ # "t": 1656043200000, # time
534
+ # "i": "5m", # interval
535
+ # "o": "44000", # open price
536
+ # "c": "50000", # close price
537
+ # "h": "52000", # highest price
538
+ # "l": "36000", # lowest price
539
+ # "q": "34.2", # qty(quantity)
540
+ # "v": "230000" # volume
541
+ # }
542
+ # }
543
+ #
544
+ # contract
545
+ #
546
+ # {
547
+ # "topic": "kline",
548
+ # "event": "kline@btc_usdt,5m",
549
+ # "data": {
550
+ # "s": "btc_index", # trading pair
551
+ # "o": "49000", # opening price
552
+ # "c": "50000", # closing price
553
+ # "h": "0.1", # highest price
554
+ # "l": "0.1", # lowest price
555
+ # "a": "0.1", # volume
556
+ # "v": "0.1", # turnover
557
+ # "ch": "0.21", # quote change
558
+ # "t": 123124124 # timestamp
559
+ # }
560
+ # }
561
+ #
562
+ data = self.safe_dict(message, 'data', {})
563
+ marketId = self.safe_string(data, 's')
564
+ if marketId is not None:
565
+ timeframe = self.safe_string(data, 'i')
566
+ tradeType = 'spot' if ('q' in data) else 'contract'
567
+ market = self.safe_market(marketId, None, None, tradeType)
568
+ symbol = market['symbol']
569
+ parsed = self.parse_ohlcv(data, market)
570
+ self.ohlcvs[symbol] = self.safe_dict(self.ohlcvs, symbol, {})
571
+ stored = self.safe_value(self.ohlcvs[symbol], timeframe)
572
+ if stored is None:
573
+ limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
574
+ stored = ArrayCacheByTimestamp(limit)
575
+ self.ohlcvs[symbol][timeframe] = stored
576
+ stored.append(parsed)
577
+ event = self.safe_string(message, 'event')
578
+ messageHash = event + '::' + tradeType
579
+ client.resolve(stored, messageHash)
580
+ return message
581
+
582
+ def handle_trade(self, client: Client, message: dict):
583
+ #
584
+ # spot
585
+ #
586
+ # {
587
+ # topic: 'trade',
588
+ # event: 'trade@btc_usdt',
589
+ # data: {
590
+ # s: 'btc_usdt',
591
+ # i: '228825383103928709',
592
+ # t: 1684258222702,
593
+ # p: '27003.65',
594
+ # q: '0.000796',
595
+ # b: True
596
+ # }
597
+ # }
598
+ #
599
+ # contract
600
+ #
601
+ # {
602
+ # "topic": "trade",
603
+ # "event": "trade@btc_usdt",
604
+ # "data": {
605
+ # "s": "btc_index", # trading pair
606
+ # "p": "50000", # price
607
+ # "a": "0.1" # Quantity
608
+ # "m": "BID" # Deal side BID:Buy ASK:Sell
609
+ # "t": 123124124 # timestamp
610
+ # }
611
+ # }
612
+ #
613
+ data = self.safe_dict(message, 'data')
614
+ marketId = self.safe_string_lower(data, 's')
615
+ if marketId is not None:
616
+ trade = self.parse_trade(data)
617
+ i = self.safe_string(data, 'i')
618
+ tradeType = 'spot' if (i is not None) else 'contract'
619
+ market = self.safe_market(marketId, None, None, tradeType)
620
+ symbol = market['symbol']
621
+ event = self.safe_string(message, 'event')
622
+ tradesArray = self.safe_value(self.trades, symbol)
623
+ if tradesArray is None:
624
+ tradesLimit = self.safe_integer(self.options, 'tradesLimit', 1000)
625
+ tradesArray = ArrayCache(tradesLimit)
626
+ self.trades[symbol] = tradesArray
627
+ tradesArray.append(trade)
628
+ messageHash = event + '::' + tradeType
629
+ client.resolve(tradesArray, messageHash)
630
+ return message
631
+
632
+ def handle_order_book(self, client: Client, message: dict):
633
+ #
634
+ # spot
635
+ #
636
+ # {
637
+ # "topic": "depth",
638
+ # "event": "depth@btc_usdt,20",
639
+ # "data": {
640
+ # "s": "btc_usdt", # symbol
641
+ # "fi": 1681433733351, # firstUpdateId = previous lastUpdateId + 1
642
+ # "i": 1681433733371, # updateId
643
+ # "a": [ # asks(sell order)
644
+ # [ # [0]price, [1]quantity
645
+ # "34000", # price
646
+ # "1.2" # quantity
647
+ # ],
648
+ # [
649
+ # "34001",
650
+ # "2.3"
651
+ # ]
652
+ # ],
653
+ # "b": [ # bids(buy order)
654
+ # [
655
+ # "32000",
656
+ # "0.2"
657
+ # ],
658
+ # [
659
+ # "31000",
660
+ # "0.5"
661
+ # ]
662
+ # ]
663
+ # }
664
+ # }
665
+ #
666
+ # contract
667
+ #
668
+ # {
669
+ # "topic": "depth",
670
+ # "event": "depth@btc_usdt,20",
671
+ # "data": {
672
+ # s: "btc_usdt",
673
+ # pu: "548111455664",
674
+ # fu: "548111455665",
675
+ # u: "548111455667",
676
+ # a: [
677
+ # [
678
+ # "26841.5",
679
+ # "50210",
680
+ # ],
681
+ # ],
682
+ # b: [
683
+ # [
684
+ # "26841",
685
+ # "67075",
686
+ # ],
687
+ # ],
688
+ # t: 1684530667083,
689
+ # }
690
+ # }
691
+ #
692
+ data = self.safe_dict(message, 'data')
693
+ marketId = self.safe_string(data, 's')
694
+ if marketId is not None:
695
+ event = self.safe_string(message, 'event')
696
+ splitEvent = event.split(',')
697
+ event = self.safe_string(splitEvent, 0)
698
+ tradeType = 'contract' if ('fu' in data) else 'spot'
699
+ market = self.safe_market(marketId, None, None, tradeType)
700
+ symbol = market['symbol']
701
+ obAsks = self.safe_list(data, 'a')
702
+ obBids = self.safe_list(data, 'b')
703
+ messageHash = event + '::' + tradeType
704
+ if not (symbol in self.orderbooks):
705
+ subscription = self.safe_dict(client.subscriptions, messageHash, {})
706
+ limit = self.safe_integer(subscription, 'limit')
707
+ self.orderbooks[symbol] = self.order_book({}, limit)
708
+ orderbook = self.orderbooks[symbol]
709
+ nonce = self.safe_integer(orderbook, 'nonce')
710
+ if nonce is None:
711
+ cacheLength = len(orderbook.cache)
712
+ snapshotDelay = self.handle_option('watchOrderBook', 'snapshotDelay', 25)
713
+ if cacheLength == snapshotDelay:
714
+ self.spawn(self.load_order_book, client, messageHash, symbol)
715
+ orderbook.cache.append(data)
716
+ return
717
+ if obAsks is not None:
718
+ asks = orderbook['asks']
719
+ for i in range(0, len(obAsks)):
720
+ ask = obAsks[i]
721
+ price = self.safe_number(ask, 0)
722
+ quantity = self.safe_number(ask, 1)
723
+ asks.store(price, quantity)
724
+ if obBids is not None:
725
+ bids = orderbook['bids']
726
+ for i in range(0, len(obBids)):
727
+ bid = obBids[i]
728
+ price = self.safe_number(bid, 0)
729
+ quantity = self.safe_number(bid, 1)
730
+ bids.store(price, quantity)
731
+ timestamp = self.safe_integer(data, 't')
732
+ orderbook['nonce'] = self.safe_integer_2(data, 'i', 'u')
733
+ orderbook['timestamp'] = timestamp
734
+ orderbook['datetime'] = self.iso8601(timestamp)
735
+ orderbook['symbol'] = symbol
736
+ client.resolve(orderbook, messageHash)
737
+
738
+ def parse_ws_order_trade(self, trade: dict, market: Market = None):
739
+ #
740
+ # {
741
+ # "s": "btc_usdt", # symbol
742
+ # "t": 1656043204763, # time happened time
743
+ # "i": "6216559590087220004", # orderId,
744
+ # "ci": "test123", # clientOrderId
745
+ # "st": "PARTIALLY_FILLED", # state
746
+ # "sd": "BUY", # side BUY/SELL
747
+ # "eq": "2", # executedQty executed quantity
748
+ # "ap": "30000", # avg price
749
+ # "f": "0.002" # fee
750
+ # }
751
+ #
752
+ # contract
753
+ #
754
+ # {
755
+ # "symbol": "btc_usdt", # Trading pair
756
+ # "orderId": "1234", # Order Id
757
+ # "origQty": "34244", # Original Quantity
758
+ # "avgPrice": "123", # Quantity
759
+ # "price": "1111", # Average price
760
+ # "executedQty": "34244", # Volume(Cont)
761
+ # "orderSide": "BUY", # BUY, SELL
762
+ # "positionSide": "LONG", # LONG, SHORT
763
+ # "marginFrozen": "123", # Occupied margin
764
+ # "sourceType": "default", # DEFAULT:normal order,ENTRUST:plan commission,PROFIR:Take Profit and Stop Loss
765
+ # "sourceId" : "1231231", # Triggering conditions ID
766
+ # "state": "", # state:NEW:New order(unfilled);PARTIALLY_FILLED:Partial deal;PARTIALLY_CANCELED:Partial revocation;FILLED:Filled;CANCELED:Cancled;REJECTED:Order failed;EXPIRED:Expired
767
+ # "createTime": 1731231231, # CreateTime
768
+ # "clientOrderId": "204788317630342726"
769
+ # }
770
+ #
771
+ marketId = self.safe_string(trade, 's')
772
+ tradeType = 'contract' if ('symbol' in trade) else 'spot'
773
+ market = self.safe_market(marketId, market, None, tradeType)
774
+ timestamp = self.safe_string(trade, 't')
775
+ return self.safe_trade({
776
+ 'info': trade,
777
+ 'id': None,
778
+ 'timestamp': timestamp,
779
+ 'datetime': self.iso8601(timestamp),
780
+ 'symbol': market['symbol'],
781
+ 'order': self.safe_string(trade, 'i', 'orderId'),
782
+ 'type': self.parse_order_status(self.safe_string(trade, 'st', 'state')),
783
+ 'side': self.safe_string_lower(trade, 'sd', 'orderSide'),
784
+ 'takerOrMaker': None,
785
+ 'price': self.safe_number(trade, 'price'),
786
+ 'amount': self.safe_string(trade, 'origQty'),
787
+ 'cost': None,
788
+ 'fee': {
789
+ 'currency': None,
790
+ 'cost': self.safe_number(trade, 'f'),
791
+ 'rate': None,
792
+ },
793
+ }, market)
794
+
795
+ def parse_ws_order(self, order: dict, market: Market = None):
796
+ #
797
+ # spot
798
+ #
799
+ # {
800
+ # "s": "btc_usdt", # symbol
801
+ # "bc": "btc", # base currency
802
+ # "qc": "usdt", # quotation currency
803
+ # "t": 1656043204763, # happened time
804
+ # "ct": 1656043204663, # create time
805
+ # "i": "6216559590087220004", # order id,
806
+ # "ci": "test123", # client order id
807
+ # "st": "PARTIALLY_FILLED", # state NEW/PARTIALLY_FILLED/FILLED/CANCELED/REJECTED/EXPIRED
808
+ # "sd": "BUY", # side BUY/SELL
809
+ # "tp": "LIMIT", # type LIMIT/MARKET
810
+ # "oq": "4" # original quantity
811
+ # "oqq": 48000, # original quotation quantity
812
+ # "eq": "2", # executed quantity
813
+ # "lq": "2", # remaining quantity
814
+ # "p": "4000", # price
815
+ # "ap": "30000", # avg price
816
+ # "f":"0.002" # fee
817
+ # }
818
+ #
819
+ # contract
820
+ #
821
+ # {
822
+ # "symbol": "btc_usdt", # Trading pair
823
+ # "orderId": "1234", # Order Id
824
+ # "origQty": "34244", # Original Quantity
825
+ # "avgPrice": "123", # Quantity
826
+ # "price": "1111", # Average price
827
+ # "executedQty": "34244", # Volume(Cont)
828
+ # "orderSide": "BUY", # BUY, SELL
829
+ # "positionSide": "LONG", # LONG, SHORT
830
+ # "marginFrozen": "123", # Occupied margin
831
+ # "sourceType": "default", # DEFAULT:normal order,ENTRUST:plan commission,PROFIR:Take Profit and Stop Loss
832
+ # "sourceId" : "1231231", # Triggering conditions ID
833
+ # "state": "", # state:NEW:New order(unfilled);PARTIALLY_FILLED:Partial deal;PARTIALLY_CANCELED:Partial revocation;FILLED:Filled;CANCELED:Cancled;REJECTED:Order failed;EXPIRED:Expired
834
+ # "createTime": 1731231231, # CreateTime
835
+ # "clientOrderId": "204788317630342726"
836
+ # }
837
+ #
838
+ marketId = self.safe_string_2(order, 's', 'symbol')
839
+ tradeType = 'contract' if ('symbol' in order) else 'spot'
840
+ market = self.safe_market(marketId, market, None, tradeType)
841
+ timestamp = self.safe_integer_2(order, 'ct', 'createTime')
842
+ return self.safe_order({
843
+ 'info': order,
844
+ 'id': self.safe_string_2(order, 'i', 'orderId'),
845
+ 'clientOrderId': self.safe_string_2(order, 'ci', 'clientOrderId'),
846
+ 'timestamp': timestamp,
847
+ 'datetime': self.iso8601(timestamp),
848
+ 'lastTradeTimestamp': None,
849
+ 'symbol': market['symbol'],
850
+ 'type': market['type'],
851
+ 'timeInForce': None,
852
+ 'postOnly': None,
853
+ 'side': self.safe_string_lower_2(order, 'sd', 'orderSide'),
854
+ 'price': self.safe_number_2(order, 'p', 'price'),
855
+ 'stopPrice': None,
856
+ 'stopLoss': None,
857
+ 'takeProfit': None,
858
+ 'amount': self.safe_string_2(order, 'oq', 'origQty'),
859
+ 'filled': self.safe_string_2(order, 'eq', 'executedQty'),
860
+ 'remaining': self.safe_string(order, 'lq'),
861
+ 'cost': None,
862
+ 'average': self.safe_string_2(order, 'ap', 'avgPrice'),
863
+ 'status': self.parse_order_status(self.safe_string(order, 'st', 'state')),
864
+ 'fee': {
865
+ 'currency': None,
866
+ 'cost': self.safe_number(order, 'f'),
867
+ },
868
+ 'trades': None,
869
+ }, market)
870
+
871
+ def handle_order(self, client: Client, message: dict):
872
+ #
873
+ # spot
874
+ #
875
+ # {
876
+ # "topic": "order",
877
+ # "event": "order",
878
+ # "data": {
879
+ # "s": "btc_usdt", # symbol
880
+ # "t": 1656043204763, # time happened time
881
+ # "i": "6216559590087220004", # orderId,
882
+ # "ci": "test123", # clientOrderId
883
+ # "st": "PARTIALLY_FILLED", # state
884
+ # "sd": "BUY", # side BUY/SELL
885
+ # "eq": "2", # executedQty executed quantity
886
+ # "ap": "30000", # avg price
887
+ # "f": "0.002" # fee
888
+ # }
889
+ # }
890
+ #
891
+ # contract
892
+ #
893
+ # {
894
+ # "topic": "order",
895
+ # "event": "order@123456",
896
+ # "data": {
897
+ # "symbol": "btc_usdt", # Trading pair
898
+ # "orderId": "1234", # Order Id
899
+ # "origQty": "34244", # Original Quantity
900
+ # "avgPrice": "123", # Quantity
901
+ # "price": "1111", # Average price
902
+ # "executedQty": "34244", # Volume(Cont)
903
+ # "orderSide": "BUY", # BUY, SELL
904
+ # "positionSide": "LONG", # LONG, SHORT
905
+ # "marginFrozen": "123", # Occupied margin
906
+ # "sourceType": "default", # DEFAULT:normal order,ENTRUST:plan commission,PROFIR:Take Profit and Stop Loss
907
+ # "sourceId" : "1231231", # Triggering conditions ID
908
+ # "state": "", # state:NEW:New order(unfilled);PARTIALLY_FILLED:Partial deal;PARTIALLY_CANCELED:Partial revocation;FILLED:Filled;CANCELED:Cancled;REJECTED:Order failed;EXPIRED:Expired
909
+ # "createTime": 1731231231, # CreateTime
910
+ # "clientOrderId": "204788317630342726"
911
+ # }
912
+ # }
913
+ #
914
+ orders = self.orders
915
+ if orders is None:
916
+ limit = self.safe_integer(self.options, 'ordersLimit')
917
+ orders = ArrayCacheBySymbolById(limit)
918
+ self.orders = orders
919
+ order = self.safe_dict(message, 'data', {})
920
+ marketId = self.safe_string_2(order, 's', 'symbol')
921
+ if marketId is not None:
922
+ tradeType = 'contract' if ('symbol' in order) else 'spot'
923
+ market = self.safe_market(marketId, None, None, tradeType)
924
+ parsed = self.parse_ws_order(order, market)
925
+ orders.append(parsed)
926
+ client.resolve(orders, 'order::' + tradeType)
927
+ return message
928
+
929
+ def handle_balance(self, client: Client, message: dict):
930
+ #
931
+ # spot
932
+ #
933
+ # {
934
+ # topic: 'balance',
935
+ # event: 'balance',
936
+ # data: {
937
+ # a: 3513677381884,
938
+ # t: 1684250056775,
939
+ # c: 'usdt',
940
+ # b: '7.71000000',
941
+ # f: '0.00000000',
942
+ # z: 'SPOT'
943
+ # }
944
+ # }
945
+ #
946
+ # contract
947
+ #
948
+ # {
949
+ # "topic": "balance",
950
+ # "event": "balance@123456",
951
+ # "data": {
952
+ # "coin": "usdt",
953
+ # "underlyingType": 1, # 1:Coin-M,2:USDT-M
954
+ # "walletBalance": "123", # Balance
955
+ # "openOrderMarginFrozen": "123", # Frozen order
956
+ # "isolatedMargin": "213", # Isolated Margin
957
+ # "crossedMargin": "0" # Crossed Margin
958
+ # "availableBalance": '2.256114450000000000',
959
+ # "coupon": '0',
960
+ # "bonus": '0'
961
+ # }
962
+ # }
963
+ #
964
+ data = self.safe_dict(message, 'data', {})
965
+ currencyId = self.safe_string_2(data, 'c', 'coin')
966
+ code = self.safe_currency_code(currencyId)
967
+ account = self.account()
968
+ account['free'] = self.safe_string(data, 'availableBalance')
969
+ account['used'] = self.safe_string(data, 'f')
970
+ account['total'] = self.safe_string_2(data, 'b', 'walletBalance')
971
+ self.balance[code] = account
972
+ self.balance = self.safe_balance(self.balance)
973
+ tradeType = 'contract' if ('coin' in data) else 'spot'
974
+ client.resolve(self.balance, 'balance::' + tradeType)
975
+
976
+ def handle_my_trades(self, client: Client, message: dict):
977
+ #
978
+ # spot
979
+ #
980
+ # {
981
+ # "topic": "trade",
982
+ # "event": "trade",
983
+ # "data": {
984
+ # "s": "btc_usdt", # symbol
985
+ # "t": 1656043204763, # time
986
+ # "i": "6316559590087251233", # tradeId
987
+ # "oi": "6216559590087220004", # orderId
988
+ # "p": "30000", # trade price
989
+ # "q": "3", # qty quantity
990
+ # "v": "90000" # volume trade amount
991
+ # }
992
+ # }
993
+ #
994
+ # contract
995
+ #
996
+ # {
997
+ # "topic": "trade",
998
+ # "event": "trade@123456",
999
+ # "data": {
1000
+ # "symbol": 'btc_usdt',
1001
+ # "orderSide": 'SELL',
1002
+ # "positionSide": 'LONG',
1003
+ # "orderId": '231485367663419328',
1004
+ # "price": '27152.7',
1005
+ # "quantity": '33',
1006
+ # "marginUnfrozen": '2.85318000',
1007
+ # "timestamp": 1684892412565
1008
+ # }
1009
+ # }
1010
+ #
1011
+ data = self.safe_dict(message, 'data', {})
1012
+ stored = self.myTrades
1013
+ if stored is None:
1014
+ limit = self.safe_integer(self.options, 'tradesLimit', 1000)
1015
+ stored = ArrayCacheBySymbolById(limit)
1016
+ self.myTrades = stored
1017
+ parsedTrade = self.parse_trade(data)
1018
+ market = self.market(parsedTrade['symbol'])
1019
+ stored.append(parsedTrade)
1020
+ tradeType = 'contract' if market['contract'] else 'spot'
1021
+ client.resolve(stored, 'trade::' + tradeType)
1022
+
1023
+ def handle_message(self, client: Client, message):
1024
+ event = self.safe_string(message, 'event')
1025
+ if event == 'pong':
1026
+ client.onPong()
1027
+ elif event is not None:
1028
+ topic = self.safe_string(message, 'topic')
1029
+ methods = {
1030
+ 'kline': self.handle_ohlcv,
1031
+ 'depth': self.handle_order_book,
1032
+ 'depth_update': self.handle_order_book,
1033
+ 'ticker': self.handle_ticker,
1034
+ 'agg_ticker': self.handle_ticker,
1035
+ 'tickers': self.handle_tickers,
1036
+ 'agg_tickers': self.handle_tickers,
1037
+ 'balance': self.handle_balance,
1038
+ 'order': self.handle_order,
1039
+ }
1040
+ method = self.safe_value(methods, topic)
1041
+ if topic == 'trade':
1042
+ data = self.safe_dict(message, 'data')
1043
+ if ('oi' in data) or ('orderId' in data):
1044
+ method = self.handle_my_trades
1045
+ else:
1046
+ method = self.handle_trade
1047
+ if method is not None:
1048
+ method(client, message)
1049
+
1050
+ def ping(self, client: Client):
1051
+ client.lastPong = self.milliseconds()
1052
+ return 'ping'
1053
+
1054
+ def handle_error_message(self, client: Client, message: dict):
1055
+ #
1056
+ # {
1057
+ # "id": "123",
1058
+ # "code": 401,
1059
+ # "msg": "token expire"
1060
+ # }
1061
+ #
1062
+ msg = self.safe_string(message, 'msg')
1063
+ if (msg == 'invalid_listen_key') or (msg == 'token expire'):
1064
+ client.subscriptions['token'] = None
1065
+ self.get_listen_key(True)
1066
+ return
1067
+ client.reject(message)