ccxt 4.2.77__py2.py3-none-any.whl → 4.4.49__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 +3205 -937
  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 +1525 -573
  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 +223 -97
  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 +639 -323
  126. ccxt/async_support/digifinex.py +465 -233
  127. ccxt/async_support/ellipx.py +1887 -0
  128. ccxt/async_support/exmo.py +317 -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 +433 -178
  133. ccxt/async_support/hollaex.py +207 -83
  134. ccxt/async_support/htx.py +1095 -563
  135. ccxt/async_support/huobijp.py +178 -56
  136. ccxt/async_support/hyperliquid.py +1678 -292
  137. ccxt/async_support/idex.py +219 -95
  138. ccxt/async_support/independentreserve.py +300 -31
  139. ccxt/async_support/indodax.py +226 -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 +198 -107
  145. ccxt/async_support/latoken.py +199 -79
  146. ccxt/async_support/lbank.py +360 -113
  147. ccxt/async_support/luno.py +185 -62
  148. ccxt/async_support/lykke.py +168 -55
  149. ccxt/async_support/mercado.py +101 -29
  150. ccxt/async_support/mexc.py +995 -429
  151. ccxt/async_support/myokx.py +53 -0
  152. ccxt/async_support/ndax.py +234 -82
  153. ccxt/async_support/novadax.py +195 -75
  154. ccxt/async_support/oceanex.py +244 -59
  155. ccxt/async_support/okcoin.py +301 -165
  156. ccxt/async_support/okx.py +1776 -454
  157. ccxt/async_support/onetrading.py +198 -414
  158. ccxt/async_support/oxfun.py +2898 -0
  159. ccxt/async_support/p2b.py +142 -52
  160. ccxt/async_support/paradex.py +2085 -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 +3205 -937
  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 +1525 -573
  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 +223 -97
  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 +639 -323
  234. ccxt/digifinex.py +465 -233
  235. ccxt/ellipx.py +1887 -0
  236. ccxt/exmo.py +317 -128
  237. ccxt/gate.py +1472 -463
  238. ccxt/gemini.py +206 -84
  239. ccxt/hashkey.py +4164 -0
  240. ccxt/hitbtc.py +433 -178
  241. ccxt/hollaex.py +207 -83
  242. ccxt/htx.py +1095 -563
  243. ccxt/huobijp.py +178 -56
  244. ccxt/hyperliquid.py +1677 -292
  245. ccxt/idex.py +219 -95
  246. ccxt/independentreserve.py +299 -31
  247. ccxt/indodax.py +226 -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 +198 -107
  253. ccxt/latoken.py +199 -79
  254. ccxt/lbank.py +360 -113
  255. ccxt/luno.py +185 -62
  256. ccxt/lykke.py +168 -55
  257. ccxt/mercado.py +101 -29
  258. ccxt/mexc.py +994 -429
  259. ccxt/myokx.py +53 -0
  260. ccxt/ndax.py +234 -82
  261. ccxt/novadax.py +195 -75
  262. ccxt/oceanex.py +244 -59
  263. ccxt/okcoin.py +301 -165
  264. ccxt/okx.py +1776 -454
  265. ccxt/onetrading.py +198 -414
  266. ccxt/oxfun.py +2897 -0
  267. ccxt/p2b.py +142 -52
  268. ccxt/paradex.py +2085 -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 +143 -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.49.dist-info/LICENSE.txt +21 -0
  496. ccxt-4.4.49.dist-info/METADATA +646 -0
  497. ccxt-4.4.49.dist-info/RECORD +669 -0
  498. {ccxt-4.2.77.dist-info → ccxt-4.4.49.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.49.dist-info}/top_level.txt +0 -0
ccxt/pro/hashkey.py ADDED
@@ -0,0 +1,802 @@
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, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
8
+ from ccxt.base.types import Balances, Bool, Int, Market, Order, OrderBook, Position, Str, Strings, Ticker, Trade
9
+ from ccxt.async_support.base.ws.client import Client
10
+ from typing import List
11
+
12
+
13
+ class hashkey(ccxt.async_support.hashkey):
14
+
15
+ def describe(self):
16
+ return self.deep_extend(super(hashkey, self).describe(), {
17
+ 'has': {
18
+ 'ws': True,
19
+ 'watchBalance': True,
20
+ 'watchMyTrades': True,
21
+ 'watchOHLCV': True,
22
+ 'watchOrderBook': True,
23
+ 'watchOrders': True,
24
+ 'watchTicker': True,
25
+ 'watchTrades': True,
26
+ 'watchTradesForSymbols': False,
27
+ 'watchPositions': False,
28
+ },
29
+ 'urls': {
30
+ 'api': {
31
+ 'ws': {
32
+ 'public': 'wss://stream-glb.hashkey.com/quote/ws/v1',
33
+ 'private': 'wss://stream-glb.hashkey.com/api/v1/ws',
34
+ },
35
+ 'test': {
36
+ 'ws': {
37
+ 'public': 'wss://stream-glb.sim.hashkeydev.com/quote/ws/v1',
38
+ 'private': 'wss://stream-glb.sim.hashkeydev.com/api/v1/ws',
39
+ },
40
+ },
41
+ },
42
+ },
43
+ 'options': {
44
+ 'listenKeyRefreshRate': 3600000,
45
+ 'listenKey': None,
46
+ 'watchBalance': {
47
+ 'fetchBalanceSnapshot': True, # or False
48
+ 'awaitBalanceSnapshot': False, # whether to wait for the balance snapshot before providing updates
49
+ },
50
+ },
51
+ 'streaming': {
52
+ 'keepAlive': 10000,
53
+ },
54
+ })
55
+
56
+ async def wath_public(self, market: Market, topic: str, messageHash: str, params={}):
57
+ request: dict = {
58
+ 'symbol': market['id'],
59
+ 'topic': topic,
60
+ 'event': 'sub',
61
+ }
62
+ url = self.urls['api']['ws']['public']
63
+ return await self.watch(url, messageHash, self.deep_extend(request, params), messageHash)
64
+
65
+ async def watch_private(self, messageHash):
66
+ listenKey = await self.authenticate()
67
+ url = self.get_private_url(listenKey)
68
+ return await self.watch(url, messageHash, None, messageHash)
69
+
70
+ def get_private_url(self, listenKey):
71
+ return self.urls['api']['ws']['private'] + '/' + listenKey
72
+
73
+ async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
74
+ """
75
+ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
76
+
77
+ https://hashkeyglobal-apidoc.readme.io/reference/websocket-api#public-stream
78
+
79
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
80
+ :param str timeframe: the length of time each candle represents
81
+ :param int [since]: timestamp in ms of the earliest candle to fetch
82
+ :param int [limit]: the maximum amount of candles to fetch
83
+ :param dict [params]: extra parameters specific to the exchange API endpoint
84
+ :param bool [params.binary]: True or False - default False
85
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
86
+ """
87
+ await self.load_markets()
88
+ market = self.market(symbol)
89
+ symbol = market['symbol']
90
+ interval = self.safe_string(self.timeframes, timeframe, timeframe)
91
+ topic = 'kline_' + interval
92
+ messageHash = 'ohlcv:' + symbol + ':' + timeframe
93
+ ohlcv = await self.wath_public(market, topic, messageHash, params)
94
+ if self.newUpdates:
95
+ limit = ohlcv.getLimit(symbol, limit)
96
+ return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
97
+
98
+ def handle_ohlcv(self, client: Client, message):
99
+ #
100
+ # {
101
+ # "symbol": "DOGEUSDT",
102
+ # "symbolName": "DOGEUSDT",
103
+ # "topic": "kline",
104
+ # "params": {
105
+ # "realtimeInterval": "24h",
106
+ # "klineType": "1m"
107
+ # },
108
+ # "data": [
109
+ # {
110
+ # "t": 1722861660000,
111
+ # "s": "DOGEUSDT",
112
+ # "sn": "DOGEUSDT",
113
+ # "c": "0.08389",
114
+ # "h": "0.08389",
115
+ # "l": "0.08389",
116
+ # "o": "0.08389",
117
+ # "v": "0"
118
+ # }
119
+ # ],
120
+ # "f": True,
121
+ # "sendTime": 1722861664258,
122
+ # "shared": False
123
+ # }
124
+ #
125
+ marketId = self.safe_string(message, 'symbol')
126
+ market = self.safe_market(marketId)
127
+ symbol = self.safe_symbol(marketId, market)
128
+ if not (symbol in self.ohlcvs):
129
+ self.ohlcvs[symbol] = {}
130
+ params = self.safe_dict(message, 'params')
131
+ klineType = self.safe_string(params, 'klineType')
132
+ timeframe = self.find_timeframe(klineType)
133
+ if not (timeframe in self.ohlcvs[symbol]):
134
+ limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
135
+ self.ohlcvs[symbol][timeframe] = ArrayCacheByTimestamp(limit)
136
+ data = self.safe_list(message, 'data', [])
137
+ stored = self.ohlcvs[symbol][timeframe]
138
+ for i in range(0, len(data)):
139
+ candle = self.safe_dict(data, i, {})
140
+ parsed = self.parse_ws_ohlcv(candle, market)
141
+ stored.append(parsed)
142
+ messageHash = 'ohlcv:' + symbol + ':' + timeframe
143
+ client.resolve(stored, messageHash)
144
+
145
+ def parse_ws_ohlcv(self, ohlcv, market: Market = None) -> list:
146
+ #
147
+ # {
148
+ # "t": 1722861660000,
149
+ # "s": "DOGEUSDT",
150
+ # "sn": "DOGEUSDT",
151
+ # "c": "0.08389",
152
+ # "h": "0.08389",
153
+ # "l": "0.08389",
154
+ # "o": "0.08389",
155
+ # "v": "0"
156
+ # }
157
+ #
158
+ return [
159
+ self.safe_integer(ohlcv, 't'),
160
+ self.safe_number(ohlcv, 'o'),
161
+ self.safe_number(ohlcv, 'h'),
162
+ self.safe_number(ohlcv, 'l'),
163
+ self.safe_number(ohlcv, 'c'),
164
+ self.safe_number(ohlcv, 'v'),
165
+ ]
166
+
167
+ async def watch_ticker(self, symbol: str, params={}) -> Ticker:
168
+ """
169
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
170
+
171
+ https://hashkeyglobal-apidoc.readme.io/reference/websocket-api#public-stream
172
+
173
+ :param str symbol: unified symbol of the market to fetch the ticker for
174
+ :param dict [params]: extra parameters specific to the exchange API endpoint
175
+ :param bool [params.binary]: True or False - default False
176
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
177
+ """
178
+ await self.load_markets()
179
+ market = self.market(symbol)
180
+ symbol = market['symbol']
181
+ topic = 'realtimes'
182
+ messageHash = 'ticker:' + symbol
183
+ return await self.wath_public(market, topic, messageHash, params)
184
+
185
+ def handle_ticker(self, client: Client, message):
186
+ #
187
+ # {
188
+ # "symbol": "ETHUSDT",
189
+ # "symbolName": "ETHUSDT",
190
+ # "topic": "realtimes",
191
+ # "params": {
192
+ # "realtimeInterval": "24h"
193
+ # },
194
+ # "data": [
195
+ # {
196
+ # "t": 1722864411064,
197
+ # "s": "ETHUSDT",
198
+ # "sn": "ETHUSDT",
199
+ # "c": "2195",
200
+ # "h": "2918.85",
201
+ # "l": "2135.5",
202
+ # "o": "2915.78",
203
+ # "v": "666.5019",
204
+ # "qv": "1586902.757079",
205
+ # "m": "-0.2472",
206
+ # "e": 301
207
+ # }
208
+ # ],
209
+ # "f": False,
210
+ # "sendTime": 1722864411086,
211
+ # "shared": False
212
+ # }
213
+ #
214
+ data = self.safe_list(message, 'data', [])
215
+ ticker = self.parse_ticker(self.safe_dict(data, 0))
216
+ symbol = ticker['symbol']
217
+ messageHash = 'ticker:' + symbol
218
+ self.tickers[symbol] = ticker
219
+ client.resolve(self.tickers[symbol], messageHash)
220
+
221
+ async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
222
+ """
223
+ watches information on multiple trades made in a market
224
+
225
+ https://hashkeyglobal-apidoc.readme.io/reference/websocket-api#public-stream
226
+
227
+ :param str symbol: unified market symbol of the market trades were made in
228
+ :param int [since]: the earliest time in ms to fetch orders for
229
+ :param int [limit]: the maximum number of trade structures to retrieve
230
+ :param dict [params]: extra parameters specific to the exchange API endpoint
231
+ :param bool [params.binary]: True or False - default False
232
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
233
+ """
234
+ await self.load_markets()
235
+ market = self.market(symbol)
236
+ symbol = market['symbol']
237
+ topic = 'trade'
238
+ messageHash = 'trades:' + symbol
239
+ trades = await self.wath_public(market, topic, messageHash, params)
240
+ if self.newUpdates:
241
+ limit = trades.getLimit(symbol, limit)
242
+ return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
243
+
244
+ def handle_trades(self, client: Client, message):
245
+ #
246
+ # {
247
+ # "symbol": "ETHUSDT",
248
+ # "symbolName": "ETHUSDT",
249
+ # "topic": "trade",
250
+ # "params": {
251
+ # "realtimeInterval": "24h"
252
+ # },
253
+ # "data": [
254
+ # {
255
+ # "v": "1745922896272048129",
256
+ # "t": 1722866228075,
257
+ # "p": "2340.41",
258
+ # "q": "0.0132",
259
+ # "m": True
260
+ # },
261
+ # ...
262
+ # ],
263
+ # "f": True,
264
+ # "sendTime": 1722869464248,
265
+ # "channelId": "668498fffeba4108-00000001-00113184-562e27d215e43f9c-c188b319",
266
+ # "shared": False
267
+ # }
268
+ #
269
+ marketId = self.safe_string(message, 'symbol')
270
+ market = self.safe_market(marketId)
271
+ symbol = market['symbol']
272
+ if not (symbol in self.trades):
273
+ limit = self.safe_integer(self.options, 'tradesLimit', 1000)
274
+ self.trades[symbol] = ArrayCache(limit)
275
+ stored = self.trades[symbol]
276
+ data = self.safe_list(message, 'data')
277
+ if data is not None:
278
+ data = self.sort_by(data, 't')
279
+ for i in range(0, len(data)):
280
+ trade = self.safe_dict(data, i)
281
+ parsed = self.parse_ws_trade(trade, market)
282
+ stored.append(parsed)
283
+ messageHash = 'trades' + ':' + symbol
284
+ client.resolve(stored, messageHash)
285
+
286
+ async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
287
+ """
288
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
289
+
290
+ https://hashkeyglobal-apidoc.readme.io/reference/websocket-api#public-stream
291
+
292
+ :param str symbol: unified symbol of the market to fetch the order book for
293
+ :param int [limit]: the maximum amount of order book entries to return.
294
+ :param dict [params]: extra parameters specific to the exchange API endpoint
295
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
296
+ """
297
+ await self.load_markets()
298
+ market = self.market(symbol)
299
+ symbol = market['symbol']
300
+ topic = 'depth'
301
+ messageHash = 'orderbook:' + symbol
302
+ orderbook = await self.wath_public(market, topic, messageHash, params)
303
+ return orderbook.limit()
304
+
305
+ def handle_order_book(self, client: Client, message):
306
+ #
307
+ # {
308
+ # "symbol": "ETHUSDT",
309
+ # "symbolName": "ETHUSDT",
310
+ # "topic": "depth",
311
+ # "params": {"realtimeInterval": "24h"},
312
+ # "data": [
313
+ # {
314
+ # "e": 301,
315
+ # "s": "ETHUSDT",
316
+ # "t": 1722873144371,
317
+ # "v": "84661262_18",
318
+ # "b": [
319
+ # ["1650", "0.0864"],
320
+ # ...
321
+ # ],
322
+ # "a": [
323
+ # ["4085", "0.0074"],
324
+ # ...
325
+ # ],
326
+ # "o": 0
327
+ # }
328
+ # ],
329
+ # "f": False,
330
+ # "sendTime": 1722873144589,
331
+ # "channelId": "2265aafffe68b588-00000001-0011510c-9e9ca710b1500854-551830bd",
332
+ # "shared": False
333
+ # }
334
+ #
335
+ marketId = self.safe_string(message, 'symbol')
336
+ symbol = self.safe_symbol(marketId)
337
+ messageHash = 'orderbook:' + symbol
338
+ if not (symbol in self.orderbooks):
339
+ self.orderbooks[symbol] = self.order_book({})
340
+ orderbook = self.orderbooks[symbol]
341
+ data = self.safe_list(message, 'data', [])
342
+ dataEntry = self.safe_dict(data, 0)
343
+ timestamp = self.safe_integer(dataEntry, 't')
344
+ snapshot = self.parse_order_book(dataEntry, symbol, timestamp, 'b', 'a')
345
+ orderbook.reset(snapshot)
346
+ orderbook['nonce'] = self.safe_integer(message, 'id')
347
+ self.orderbooks[symbol] = orderbook
348
+ client.resolve(orderbook, messageHash)
349
+
350
+ async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
351
+ """
352
+ watches information on multiple orders made by the user
353
+
354
+ https://hashkeyglobal-apidoc.readme.io/reference/websocket-api#private-stream
355
+
356
+ :param str symbol: unified market symbol of the market orders were made in
357
+ :param int [since]: the earliest time in ms to fetch orders for
358
+ :param int [limit]: the maximum number of order structures to retrieve
359
+ :param dict [params]: extra parameters specific to the exchange API endpoint
360
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
361
+ """
362
+ await self.load_markets()
363
+ messageHash = 'orders'
364
+ if symbol is not None:
365
+ symbol = self.symbol(symbol)
366
+ messageHash = messageHash + ':' + symbol
367
+ orders = await self.watch_private(messageHash)
368
+ if self.newUpdates:
369
+ limit = orders.getLimit(symbol, limit)
370
+ return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
371
+
372
+ def handle_order(self, client: Client, message):
373
+ #
374
+ # swap
375
+ # {
376
+ # "e": "contractExecutionReport",
377
+ # "E": "1723037391181",
378
+ # "s": "ETHUSDT-PERPETUAL",
379
+ # "c": "1723037389677",
380
+ # "S": "BUY_OPEN",
381
+ # "o": "LIMIT",
382
+ # "f": "IOC",
383
+ # "q": "1",
384
+ # "p": "2561.75",
385
+ # "X": "FILLED",
386
+ # "i": "1747358716129257216",
387
+ # "l": "1",
388
+ # "z": "1",
389
+ # "L": "2463.36",
390
+ # "n": "0.001478016",
391
+ # "N": "USDT",
392
+ # "u": True,
393
+ # "w": True,
394
+ # "m": False,
395
+ # "O": "1723037391140",
396
+ # "Z": "2463.36",
397
+ # "C": False,
398
+ # "v": "5",
399
+ # "reqAmt": "0",
400
+ # "d": "1747358716255075840",
401
+ # "r": "0",
402
+ # "V": "2463.36",
403
+ # "P": "0",
404
+ # "lo": False,
405
+ # "lt": ""
406
+ # }
407
+ #
408
+ if self.orders is None:
409
+ limit = self.safe_integer(self.options, 'ordersLimit', 1000)
410
+ self.orders = ArrayCacheBySymbolById(limit)
411
+ parsed = self.parse_ws_order(message)
412
+ orders = self.orders
413
+ orders.append(parsed)
414
+ messageHash = 'orders'
415
+ client.resolve(orders, messageHash)
416
+ symbol = parsed['symbol']
417
+ symbolSpecificMessageHash = messageHash + ':' + symbol
418
+ client.resolve(orders, symbolSpecificMessageHash)
419
+
420
+ def parse_ws_order(self, order: dict, market: Market = None) -> Order:
421
+ marketId = self.safe_string(order, 's')
422
+ market = self.safe_market(marketId, market)
423
+ timestamp = self.safe_integer(order, 'O')
424
+ side = self.safe_string_lower(order, 'S')
425
+ reduceOnly: Bool = None
426
+ side, reduceOnly = self.parseOrderSideAndReduceOnly(side)
427
+ type = self.parseOrderType(self.safe_string(order, 'o'))
428
+ timeInForce = self.safe_string(order, 'f')
429
+ postOnly: Bool = None
430
+ type, timeInForce, postOnly = self.parseOrderTypeTimeInForceAndPostOnly(type, timeInForce)
431
+ if market['contract']: # swap orders are always have type 'LIMIT', thus we can not define the correct type
432
+ type = None
433
+ return self.safe_order({
434
+ 'id': self.safe_string(order, 'i'),
435
+ 'clientOrderId': self.safe_string(order, 'c'),
436
+ 'datetime': self.iso8601(timestamp),
437
+ 'timestamp': timestamp,
438
+ 'lastTradeTimestamp': None,
439
+ 'lastUpdateTimestamp': None,
440
+ 'status': self.parse_order_status(self.safe_string(order, 'X')),
441
+ 'symbol': market['symbol'],
442
+ 'type': type,
443
+ 'timeInForce': timeInForce,
444
+ 'side': side,
445
+ 'price': self.safe_string(order, 'p'),
446
+ 'average': self.safe_string(order, 'V'),
447
+ 'amount': self.omit_zero(self.safe_string(order, 'q')),
448
+ 'filled': self.safe_string(order, 'z'),
449
+ 'remaining': self.safe_string(order, 'r'),
450
+ 'stopPrice': None,
451
+ 'triggerPrice': None,
452
+ 'takeProfitPrice': None,
453
+ 'stopLossPrice': None,
454
+ 'cost': self.omit_zero(self.safe_string(order, 'Z')),
455
+ 'trades': None,
456
+ 'fee': {
457
+ 'currency': self.safe_currency_code(self.safe_string(order, 'N')),
458
+ 'amount': self.omit_zero(self.safe_string(order, 'n')),
459
+ },
460
+ 'reduceOnly': reduceOnly,
461
+ 'postOnly': postOnly,
462
+ 'info': order,
463
+ }, market)
464
+
465
+ async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
466
+ """
467
+ watches information on multiple trades made by the user
468
+
469
+ https://hashkeyglobal-apidoc.readme.io/reference/websocket-api#private-stream
470
+
471
+ :param str symbol: unified market symbol of the market trades were made in
472
+ :param int [since]: the earliest time in ms to fetch trades for
473
+ :param int [limit]: the maximum number of trade structures to retrieve
474
+ :param dict [params]: extra parameters specific to the exchange API endpoint
475
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
476
+ """
477
+ await self.load_markets()
478
+ messageHash = 'myTrades'
479
+ if symbol is not None:
480
+ symbol = self.symbol(symbol)
481
+ messageHash += ':' + symbol
482
+ trades = await self.watch_private(messageHash)
483
+ if self.newUpdates:
484
+ limit = trades.getLimit(symbol, limit)
485
+ return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
486
+
487
+ def handle_my_trade(self, client: Client, message, subscription={}):
488
+ #
489
+ # {
490
+ # "e": "ticketInfo",
491
+ # "E": "1723037391156",
492
+ # "s": "ETHUSDT-PERPETUAL",
493
+ # "q": "1.00",
494
+ # "t": "1723037391147",
495
+ # "p": "2463.36",
496
+ # "T": "1747358716187197441",
497
+ # "o": "1747358716129257216",
498
+ # "c": "1723037389677",
499
+ # "a": "1735619524953226496",
500
+ # "m": False,
501
+ # "S": "BUY"
502
+ # }
503
+ #
504
+ if self.myTrades is None:
505
+ limit = self.safe_integer(self.options, 'tradesLimit', 1000)
506
+ self.myTrades = ArrayCacheBySymbolById(limit)
507
+ tradesArray = self.myTrades
508
+ parsed = self.parse_ws_trade(message)
509
+ tradesArray.append(parsed)
510
+ self.myTrades = tradesArray
511
+ messageHash = 'myTrades'
512
+ client.resolve(tradesArray, messageHash)
513
+ symbol = parsed['symbol']
514
+ symbolSpecificMessageHash = messageHash + ':' + symbol
515
+ client.resolve(tradesArray, symbolSpecificMessageHash)
516
+
517
+ def parse_ws_trade(self, trade, market=None) -> Trade:
518
+ #
519
+ # watchTrades
520
+ # {
521
+ # "v": "1745922896272048129",
522
+ # "t": 1722866228075,
523
+ # "p": "2340.41",
524
+ # "q": "0.0132",
525
+ # "m": True
526
+ # }
527
+ #
528
+ # watchMyTrades
529
+ # {
530
+ # "e": "ticketInfo",
531
+ # "E": "1723037391156",
532
+ # "s": "ETHUSDT-PERPETUAL",
533
+ # "q": "1.00",
534
+ # "t": "1723037391147",
535
+ # "p": "2463.36",
536
+ # "T": "1747358716187197441",
537
+ # "o": "1747358716129257216",
538
+ # "c": "1723037389677",
539
+ # "a": "1735619524953226496",
540
+ # "m": False,
541
+ # "S": "BUY"
542
+ # }
543
+ #
544
+ marketId = self.safe_string(trade, 's')
545
+ market = self.safe_market(marketId, market)
546
+ timestamp = self.safe_integer(trade, 't')
547
+ isMaker = self.safe_bool(trade, 'm')
548
+ takerOrMaker: Str = None
549
+ if isMaker is not None:
550
+ if isMaker:
551
+ takerOrMaker = 'maker'
552
+ else:
553
+ takerOrMaker = 'taker'
554
+ return self.safe_trade({
555
+ 'id': self.safe_string_2(trade, 'v', 'T'),
556
+ 'timestamp': timestamp,
557
+ 'datetime': self.iso8601(timestamp),
558
+ 'symbol': market['symbol'],
559
+ 'side': self.safe_string_lower(trade, 'S'),
560
+ 'price': self.safe_string(trade, 'p'),
561
+ 'amount': self.safe_string(trade, 'q'),
562
+ 'cost': None,
563
+ 'takerOrMaker': takerOrMaker,
564
+ 'type': None,
565
+ 'order': self.safe_string(trade, 'o'),
566
+ 'fee': None,
567
+ 'info': trade,
568
+ }, market)
569
+
570
+ async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
571
+ """
572
+
573
+ https://hashkeyglobal-apidoc.readme.io/reference/websocket-api#private-stream
574
+
575
+ watch all open positions
576
+ :param str[] [symbols]: list of unified market symbols to watch positions for
577
+ :param int [since]: the earliest time in ms to fetch positions for
578
+ :param int [limit]: the maximum number of positions to retrieve
579
+ :param dict params: extra parameters specific to the exchange API endpoint
580
+ :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
581
+ """
582
+ await self.load_markets()
583
+ listenKey = await self.authenticate()
584
+ symbols = self.market_symbols(symbols)
585
+ messageHash = 'positions'
586
+ messageHashes = []
587
+ if symbols is None:
588
+ messageHashes.append(messageHash)
589
+ else:
590
+ for i in range(0, len(symbols)):
591
+ symbol = symbols[i]
592
+ messageHashes.append(messageHash + ':' + symbol)
593
+ url = self.get_private_url(listenKey)
594
+ positions = await self.watch_multiple(url, messageHashes, None, messageHashes)
595
+ if self.newUpdates:
596
+ return positions
597
+ return self.filter_by_symbols_since_limit(self.positions, symbols, since, limit, True)
598
+
599
+ def handle_position(self, client: Client, message):
600
+ #
601
+ # {
602
+ # "e": "outboundContractPositionInfo",
603
+ # "E": "1723084699801",
604
+ # "A": "1735619524953226496",
605
+ # "s": "ETHUSDT-PERPETUAL",
606
+ # "S": "LONG",
607
+ # "p": "2429.6",
608
+ # "P": "2",
609
+ # "a": "2",
610
+ # "f": "10760.14",
611
+ # "m": "1.0085",
612
+ # "r": "-0.0029",
613
+ # "up": "0.0478",
614
+ # "pr": "0.0492",
615
+ # "pv": "4.8592",
616
+ # "v": "5.00",
617
+ # "mt": "CROSS",
618
+ # "mm": "0.0367"
619
+ # }
620
+ #
621
+ if self.positions is None:
622
+ self.positions = ArrayCacheBySymbolBySide()
623
+ positions = self.positions
624
+ parsed = self.parse_ws_position(message)
625
+ positions.append(parsed)
626
+ messageHash = 'positions'
627
+ client.resolve(parsed, messageHash)
628
+ symbol = parsed['symbol']
629
+ client.resolve(parsed, messageHash + ':' + symbol)
630
+
631
+ def parse_ws_position(self, position, market: Market = None) -> Position:
632
+ marketId = self.safe_string(position, 's')
633
+ market = self.safe_market(marketId)
634
+ timestamp = self.safe_integer(position, 'E')
635
+ return self.safe_position({
636
+ 'symbol': market['symbol'],
637
+ 'id': None,
638
+ 'timestamp': timestamp,
639
+ 'datetime': self.iso8601(timestamp),
640
+ 'contracts': self.safe_number(position, 'P'),
641
+ 'contractSize': None,
642
+ 'side': self.safe_string_lower(position, 'S'),
643
+ 'notional': self.safe_number(position, 'pv'),
644
+ 'leverage': self.safe_integer(position, 'v'),
645
+ 'unrealizedPnl': self.safe_number(position, 'up'),
646
+ 'realizedPnl': self.safe_number(position, 'r'),
647
+ 'collateral': None,
648
+ 'entryPrice': self.safe_number(position, 'p'),
649
+ 'markPrice': None,
650
+ 'liquidationPrice': self.safe_number(position, 'f'),
651
+ 'marginMode': self.safe_string_lower(position, 'mt'),
652
+ 'hedged': True,
653
+ 'maintenanceMargin': self.safe_number(position, 'mm'),
654
+ 'maintenanceMarginPercentage': None,
655
+ 'initialMargin': self.safe_number(position, 'm'), # todo check
656
+ 'initialMarginPercentage': None,
657
+ 'marginRatio': None,
658
+ 'lastUpdateTimestamp': None,
659
+ 'lastPrice': None,
660
+ 'stopLossPrice': None,
661
+ 'takeProfitPrice': None,
662
+ 'percentage': None,
663
+ 'info': position,
664
+ })
665
+
666
+ async def watch_balance(self, params={}) -> Balances:
667
+ """
668
+ watch balance and get the amount of funds available for trading or funds locked in orders
669
+
670
+ https://hashkeyglobal-apidoc.readme.io/reference/websocket-api#private-stream
671
+
672
+ :param dict [params]: extra parameters specific to the exchange API endpoint
673
+ :param str [params.type]: 'spot' or 'swap' - the type of the market to watch balance for(default 'spot')
674
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
675
+ """
676
+ listenKey = await self.authenticate()
677
+ await self.load_markets()
678
+ type = 'spot'
679
+ type, params = self.handle_market_type_and_params('watchBalance', None, params, type)
680
+ messageHash = 'balance:' + type
681
+ url = self.get_private_url(listenKey)
682
+ client = self.client(url)
683
+ self.set_balance_cache(client, type, messageHash)
684
+ fetchBalanceSnapshot = None
685
+ awaitBalanceSnapshot = None
686
+ fetchBalanceSnapshot, params = self.handle_option_and_params(self.options, 'watchBalance', 'fetchBalanceSnapshot', True)
687
+ awaitBalanceSnapshot, params = self.handle_option_and_params(self.options, 'watchBalance', 'awaitBalanceSnapshot', False)
688
+ if fetchBalanceSnapshot and awaitBalanceSnapshot:
689
+ await client.future(type + ':fetchBalanceSnapshot')
690
+ return await self.watch(url, messageHash, None, messageHash)
691
+
692
+ def set_balance_cache(self, client: Client, type, subscribeHash):
693
+ if subscribeHash in client.subscriptions:
694
+ return
695
+ options = self.safe_dict(self.options, 'watchBalance')
696
+ snapshot = self.safe_bool(options, 'fetchBalanceSnapshot', True)
697
+ if snapshot:
698
+ messageHash = type + ':' + 'fetchBalanceSnapshot'
699
+ if not (messageHash in client.futures):
700
+ client.future(messageHash)
701
+ self.spawn(self.load_balance_snapshot, client, messageHash, type)
702
+ self.balance[type] = {}
703
+ # without self comment, transpilation breaks for some reason...
704
+
705
+ async def load_balance_snapshot(self, client, messageHash, type):
706
+ response = await self.fetch_balance({'type': type})
707
+ self.balance[type] = self.extend(response, self.safe_value(self.balance, type, {}))
708
+ # don't remove the future from the .futures cache
709
+ future = client.futures[messageHash]
710
+ future.resolve()
711
+ client.resolve(self.balance[type], 'balance:' + type)
712
+
713
+ def handle_balance(self, client: Client, message):
714
+ #
715
+ # {
716
+ # "e": "outboundContractAccountInfo", # event type
717
+ # # outboundContractAccountInfo
718
+ # "E": "1714717314118", # event time
719
+ # "T": True, # can trade
720
+ # "W": True, # can withdraw
721
+ # "D": True, # can deposit
722
+ # "B": [ # balances changed
723
+ # {
724
+ # "a": "USDT", # asset
725
+ # "f": "474960.65", # free amount
726
+ # "l": "24835.178056020383226869", # locked amount
727
+ # "r": "" # to be released
728
+ # }
729
+ # ]
730
+ # }
731
+ #
732
+ event = self.safe_string(message, 'e')
733
+ data = self.safe_list(message, 'B', [])
734
+ balanceUpdate = self.safe_dict(data, 0)
735
+ isSpot = event == 'outboundAccountInfo'
736
+ type = 'spot' if isSpot else 'swap'
737
+ if not (type in self.balance):
738
+ self.balance[type] = {}
739
+ self.balance[type]['info'] = message
740
+ currencyId = self.safe_string(balanceUpdate, 'a')
741
+ code = self.safe_currency_code(currencyId)
742
+ account = self.account()
743
+ account['free'] = self.safe_string(balanceUpdate, 'f')
744
+ account['used'] = self.safe_string(balanceUpdate, 'l')
745
+ self.balance[type][code] = account
746
+ self.balance[type] = self.safe_balance(self.balance[type])
747
+ messageHash = 'balance:' + type
748
+ client.resolve(self.balance[type], messageHash)
749
+
750
+ async def authenticate(self, params={}):
751
+ listenKey = self.safe_string(self.options, 'listenKey')
752
+ if listenKey is not None:
753
+ return listenKey
754
+ response = await self.privatePostApiV1UserDataStream(params)
755
+ #
756
+ # {
757
+ # "listenKey": "atbNEcWnBqnmgkfmYQeTuxKTpTStlZzgoPLJsZhzAOZTbAlxbHqGNWiYaUQzMtDz"
758
+ # }
759
+ #
760
+ listenKey = self.safe_string(response, 'listenKey')
761
+ self.options['listenKey'] = listenKey
762
+ listenKeyRefreshRate = self.safe_integer(self.options, 'listenKeyRefreshRate', 3600000)
763
+ self.delay(listenKeyRefreshRate, self.keep_alive_listen_key, listenKey, params)
764
+ return listenKey
765
+
766
+ async def keep_alive_listen_key(self, listenKey, params={}):
767
+ if listenKey is None:
768
+ return
769
+ request: dict = {
770
+ 'listenKey': listenKey,
771
+ }
772
+ try:
773
+ await self.privatePutApiV1UserDataStream(self.extend(request, params))
774
+ listenKeyRefreshRate = self.safe_integer(self.options, 'listenKeyRefreshRate', 1200000)
775
+ self.delay(listenKeyRefreshRate, self.keep_alive_listen_key, listenKey, params)
776
+ except Exception as error:
777
+ url = self.get_private_url(listenKey)
778
+ client = self.client(url)
779
+ self.options['listenKey'] = None
780
+ client.reject(error)
781
+ del self.clients[url]
782
+
783
+ def handle_message(self, client: Client, message):
784
+ if isinstance(message, list):
785
+ message = self.safe_dict(message, 0, {})
786
+ topic = self.safe_string_2(message, 'topic', 'e')
787
+ if topic == 'kline':
788
+ self.handle_ohlcv(client, message)
789
+ elif topic == 'realtimes':
790
+ self.handle_ticker(client, message)
791
+ elif topic == 'trade':
792
+ self.handle_trades(client, message)
793
+ elif topic == 'depth':
794
+ self.handle_order_book(client, message)
795
+ elif (topic == 'contractExecutionReport') or (topic == 'executionReport'):
796
+ self.handle_order(client, message)
797
+ elif topic == 'ticketInfo':
798
+ self.handle_my_trade(client, message)
799
+ elif topic == 'outboundContractPositionInfo':
800
+ self.handle_position(client, message)
801
+ elif (topic == 'outboundAccountInfo') or (topic == 'outboundContractAccountInfo'):
802
+ self.handle_balance(client, message)