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/blofin.py ADDED
@@ -0,0 +1,692 @@
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
+ import hashlib
9
+ from ccxt.base.types import Any, Balances, Int, Market, Order, OrderBook, Position, Str, Strings, Ticker, Tickers, Trade
10
+ from ccxt.async_support.base.ws.client import Client
11
+ from typing import List
12
+ from ccxt.base.errors import ExchangeError
13
+ from ccxt.base.errors import ArgumentsRequired
14
+ from ccxt.base.errors import NotSupported
15
+
16
+
17
+ class blofin(ccxt.async_support.blofin):
18
+
19
+ def describe(self):
20
+ return self.deep_extend(super(blofin, self).describe(), {
21
+ 'has': {
22
+ 'ws': True,
23
+ 'watchTrades': True,
24
+ 'watchTradesForSymbols': True,
25
+ 'watchOrderBook': True,
26
+ 'watchOrderBookForSymbols': True,
27
+ 'watchTicker': True,
28
+ 'watchTickers': True,
29
+ 'watchBidsAsks': True,
30
+ 'watchOHLCV': True,
31
+ 'watchOHLCVForSymbols': True,
32
+ 'watchOrders': True,
33
+ 'watchOrdersForSymbols': True,
34
+ 'watchPositions': True,
35
+ },
36
+ 'urls': {
37
+ 'api': {
38
+ 'ws': {
39
+ 'swap': {
40
+ 'public': 'wss://openapi.blofin.com/ws/public',
41
+ 'private': 'wss://openapi.blofin.com/ws/private',
42
+ },
43
+ },
44
+ },
45
+ },
46
+ 'options': {
47
+ 'defaultType': 'swap',
48
+ 'tradesLimit': 1000,
49
+ # orderbook channel can be one from:
50
+ # - "books": 200 depth levels will be pushed in the initial full snapshot. Incremental data will be pushed every 100 ms for the changes in the order book during that period of time.
51
+ # - "books5": 5 depth levels snapshot will be pushed every time. Snapshot data will be pushed every 100 ms when there are changes in the 5 depth levels snapshot.
52
+ 'watchOrderBook': {
53
+ 'channel': 'books',
54
+ },
55
+ 'watchOrderBookForSymbols': {
56
+ 'channel': 'books',
57
+ },
58
+ },
59
+ 'streaming': {
60
+ 'ping': self.ping,
61
+ 'keepAlive': 25000, # 30 seconds max
62
+ },
63
+ })
64
+
65
+ def ping(self, client):
66
+ return 'ping'
67
+
68
+ def handle_pong(self, client: Client, message):
69
+ #
70
+ # 'pong'
71
+ #
72
+ client.lastPong = self.milliseconds()
73
+
74
+ async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
75
+ """
76
+ get the list of most recent trades for a particular symbol
77
+
78
+ https://docs.blofin.com/index.html#ws-trades-channel
79
+
80
+ :param str symbol: unified symbol of the market to fetch trades for
81
+ :param int [since]: timestamp in ms of the earliest trade to fetch
82
+ :param int [limit]: the maximum amount of trades to fetch
83
+ :param dict [params]: extra parameters specific to the exchange API endpoint
84
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
85
+ """
86
+ params['callerMethodName'] = 'watchTrades'
87
+ return await self.watch_trades_for_symbols([symbol], since, limit, params)
88
+
89
+ async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
90
+ """
91
+ get the list of most recent trades for a list of symbols
92
+
93
+ https://docs.blofin.com/index.html#ws-trades-channel
94
+
95
+ :param str[] symbols: unified symbol of the market to fetch trades for
96
+ :param int [since]: timestamp in ms of the earliest trade to fetch
97
+ :param int [limit]: the maximum amount of trades to fetch
98
+ :param dict [params]: extra parameters specific to the exchange API endpoint
99
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
100
+ """
101
+ await self.load_markets()
102
+ trades = await self.watch_multiple_wrapper(True, 'trades', 'watchTradesForSymbols', symbols, params)
103
+ if self.newUpdates:
104
+ firstMarket = self.safe_dict(trades, 0)
105
+ firstSymbol = self.safe_string(firstMarket, 'symbol')
106
+ limit = trades.getLimit(firstSymbol, limit)
107
+ return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
108
+
109
+ def handle_trades(self, client: Client, message):
110
+ #
111
+ # {
112
+ # arg: {
113
+ # channel: "trades",
114
+ # instId: "DOGE-USDT",
115
+ # },
116
+ # data : [
117
+ # <same object in REST example>,
118
+ # ...
119
+ # ]
120
+ # }
121
+ #
122
+ arg = self.safe_dict(message, 'arg')
123
+ channelName = self.safe_string(arg, 'channel')
124
+ data = self.safe_list(message, 'data')
125
+ if data is None:
126
+ return
127
+ for i in range(0, len(data)):
128
+ rawTrade = data[i]
129
+ trade = self.parse_ws_trade(rawTrade)
130
+ symbol = trade['symbol']
131
+ stored = self.safe_value(self.trades, symbol)
132
+ if stored is None:
133
+ limit = self.safe_integer(self.options, 'tradesLimit', 1000)
134
+ stored = ArrayCache(limit)
135
+ self.trades[symbol] = stored
136
+ stored.append(trade)
137
+ messageHash = channelName + ':' + symbol
138
+ client.resolve(stored, messageHash)
139
+
140
+ def parse_ws_trade(self, trade, market: Market = None) -> Trade:
141
+ return self.parse_trade(trade, market)
142
+
143
+ async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
144
+ """
145
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
146
+
147
+ https://docs.blofin.com/index.html#ws-order-book-channel
148
+
149
+ :param str symbol: unified symbol of the market to fetch the order book for
150
+ :param int [limit]: the maximum amount of order book entries to return
151
+ :param dict [params]: extra parameters specific to the exchange API endpoint
152
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
153
+ """
154
+ params['callerMethodName'] = 'watchOrderBook'
155
+ return await self.watch_order_book_for_symbols([symbol], limit, params)
156
+
157
+ async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
158
+ """
159
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
160
+
161
+ https://docs.blofin.com/index.html#ws-order-book-channel
162
+
163
+ :param str[] symbols: unified array of symbols
164
+ :param int [limit]: the maximum amount of order book entries to return
165
+ :param dict [params]: extra parameters specific to the exchange API endpoint
166
+ :param str [params.depth]: the type of order book to subscribe to, default is 'depth/increase100', also accepts 'depth5' or 'depth20' or depth50
167
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
168
+ """
169
+ await self.load_markets()
170
+ callerMethodName = None
171
+ callerMethodName, params = self.handle_param_string(params, 'callerMethodName', 'watchOrderBookForSymbols')
172
+ channelName = None
173
+ channelName, params = self.handle_option_and_params(params, callerMethodName, 'channel', 'books')
174
+ # due to some problem, temporarily disable other channels
175
+ if channelName != 'books':
176
+ raise NotSupported(self.id + ' ' + callerMethodName + '() at self moment ' + channelName + ' is not supported, coming soon')
177
+ orderbook = await self.watch_multiple_wrapper(True, channelName, callerMethodName, symbols, params)
178
+ return orderbook.limit()
179
+
180
+ def handle_order_book(self, client: Client, message):
181
+ #
182
+ # {
183
+ # arg: {
184
+ # channel: "books",
185
+ # instId: "DOGE-USDT",
186
+ # },
187
+ # action: "snapshot", # can be 'snapshot' or 'update'
188
+ # data: {
189
+ # asks: [ [0.08096, 1], [0.08097, 123], ... ],
190
+ # bids: [ [0.08095, 4], [0.08094, 237], ... ],
191
+ # ts: "1707491587909",
192
+ # prevSeqId: "0", # in case of 'update' there will be some value, less then seqId
193
+ # seqId: "3374250786",
194
+ # },
195
+ # }
196
+ #
197
+ arg = self.safe_dict(message, 'arg')
198
+ channelName = self.safe_string(arg, 'channel')
199
+ data = self.safe_dict(message, 'data')
200
+ marketId = self.safe_string(arg, 'instId')
201
+ market = self.safe_market(marketId)
202
+ symbol = market['symbol']
203
+ messageHash = channelName + ':' + symbol
204
+ if not (symbol in self.orderbooks):
205
+ self.orderbooks[symbol] = self.order_book()
206
+ orderbook = self.orderbooks[symbol]
207
+ timestamp = self.safe_integer(data, 'ts')
208
+ action = self.safe_string(message, 'action')
209
+ if action == 'snapshot':
210
+ orderBookSnapshot = self.parse_order_book(data, symbol, timestamp)
211
+ orderBookSnapshot['nonce'] = self.safe_integer(data, 'seqId')
212
+ orderbook.reset(orderBookSnapshot)
213
+ else:
214
+ asks = self.safe_list(data, 'asks', [])
215
+ bids = self.safe_list(data, 'bids', [])
216
+ self.handle_deltas_with_keys(orderbook['asks'], asks)
217
+ self.handle_deltas_with_keys(orderbook['bids'], bids)
218
+ orderbook['timestamp'] = timestamp
219
+ orderbook['datetime'] = self.iso8601(timestamp)
220
+ self.orderbooks[symbol] = orderbook
221
+ client.resolve(orderbook, messageHash)
222
+
223
+ async def watch_ticker(self, symbol: str, params={}) -> Ticker:
224
+ """
225
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
226
+
227
+ https://docs.blofin.com/index.html#ws-tickers-channel
228
+
229
+ :param str symbol: unified symbol of the market to fetch the ticker for
230
+ :param dict [params]: extra parameters specific to the exchange API endpoint
231
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
232
+ """
233
+ params['callerMethodName'] = 'watchTicker'
234
+ market = self.market(symbol)
235
+ symbol = market['symbol']
236
+ result = await self.watch_tickers([symbol], params)
237
+ return result[symbol]
238
+
239
+ async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
240
+ """
241
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
242
+
243
+ https://docs.blofin.com/index.html#ws-tickers-channel
244
+
245
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
246
+ :param dict [params]: extra parameters specific to the exchange API endpoint
247
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
248
+ """
249
+ if symbols is None:
250
+ raise NotSupported(self.id + ' watchTickers() requires a list of symbols')
251
+ ticker = await self.watch_multiple_wrapper(True, 'tickers', 'watchTickers', symbols, params)
252
+ if self.newUpdates:
253
+ tickers = {}
254
+ tickers[ticker['symbol']] = ticker
255
+ return tickers
256
+ return self.filter_by_array(self.tickers, 'symbol', symbols)
257
+
258
+ def handle_ticker(self, client: Client, message):
259
+ #
260
+ # message
261
+ #
262
+ # {
263
+ # arg: {
264
+ # channel: "tickers",
265
+ # instId: "DOGE-USDT",
266
+ # },
267
+ # data: [
268
+ # <same object in REST example>
269
+ # ],
270
+ # }
271
+ #
272
+ self.handle_bid_ask(client, message)
273
+ arg = self.safe_dict(message, 'arg')
274
+ channelName = self.safe_string(arg, 'channel')
275
+ data = self.safe_list(message, 'data')
276
+ for i in range(0, len(data)):
277
+ ticker = self.parse_ws_ticker(data[i])
278
+ symbol = ticker['symbol']
279
+ messageHash = channelName + ':' + symbol
280
+ self.tickers[symbol] = ticker
281
+ client.resolve(self.tickers[symbol], messageHash)
282
+
283
+ def parse_ws_ticker(self, ticker, market: Market = None) -> Ticker:
284
+ return self.parse_ticker(ticker, market)
285
+
286
+ async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
287
+ """
288
+ watches best bid & ask for symbols
289
+
290
+ https://docs.blofin.com/index.html#ws-tickers-channel
291
+
292
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
293
+ :param dict [params]: extra parameters specific to the exchange API endpoint
294
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
295
+ """
296
+ await self.load_markets()
297
+ symbols = self.market_symbols(symbols, None, False)
298
+ firstMarket = self.market(symbols[0])
299
+ channel = 'tickers'
300
+ marketType = None
301
+ marketType, params = self.handle_market_type_and_params('watchBidsAsks', firstMarket, params)
302
+ url = self.implode_hostname(self.urls['api']['ws'][marketType]['public'])
303
+ messageHashes = []
304
+ args = []
305
+ for i in range(0, len(symbols)):
306
+ market = self.market(symbols[i])
307
+ messageHashes.append('bidask:' + market['symbol'])
308
+ args.append({
309
+ 'channel': channel,
310
+ 'instId': market['id'],
311
+ })
312
+ request = self.get_subscription_request(args)
313
+ ticker = await self.watch_multiple(url, messageHashes, self.deep_extend(request, params), messageHashes)
314
+ if self.newUpdates:
315
+ tickers = {}
316
+ tickers[ticker['symbol']] = ticker
317
+ return tickers
318
+ return self.filter_by_array(self.bidsasks, 'symbol', symbols)
319
+
320
+ def handle_bid_ask(self, client: Client, message):
321
+ data = self.safe_list(message, 'data')
322
+ for i in range(0, len(data)):
323
+ ticker = self.parse_ws_bid_ask(data[i])
324
+ symbol = ticker['symbol']
325
+ messageHash = 'bidask:' + symbol
326
+ self.bidsasks[symbol] = ticker
327
+ client.resolve(ticker, messageHash)
328
+
329
+ def parse_ws_bid_ask(self, ticker, market=None):
330
+ marketId = self.safe_string(ticker, 'instId')
331
+ market = self.safe_market(marketId, market, '-')
332
+ symbol = self.safe_string(market, 'symbol')
333
+ timestamp = self.safe_integer(ticker, 'ts')
334
+ return self.safe_ticker({
335
+ 'symbol': symbol,
336
+ 'timestamp': timestamp,
337
+ 'datetime': self.iso8601(timestamp),
338
+ 'ask': self.safe_string(ticker, 'askPrice'),
339
+ 'askVolume': self.safe_string(ticker, 'askSize'),
340
+ 'bid': self.safe_string(ticker, 'bidPrice'),
341
+ 'bidVolume': self.safe_string(ticker, 'bidSize'),
342
+ 'info': ticker,
343
+ }, market)
344
+
345
+ async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
346
+ """
347
+ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
348
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
349
+ :param str timeframe: the length of time each candle represents
350
+ :param int [since]: timestamp in ms of the earliest candle to fetch
351
+ :param int [limit]: the maximum amount of candles to fetch
352
+ :param dict [params]: extra parameters specific to the exchange API endpoint
353
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
354
+ """
355
+ params['callerMethodName'] = 'watchOHLCV'
356
+ result = await self.watch_ohlcv_for_symbols([[symbol, timeframe]], since, limit, params)
357
+ return result[symbol][timeframe]
358
+
359
+ async def watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], since: Int = None, limit: Int = None, params={}):
360
+ """
361
+ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
362
+
363
+ https://docs.blofin.com/index.html#ws-candlesticks-channel
364
+
365
+ :param str[][] symbolsAndTimeframes: array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
366
+ :param int [since]: timestamp in ms of the earliest candle to fetch
367
+ :param int [limit]: the maximum amount of candles to fetch
368
+ :param dict [params]: extra parameters specific to the exchange API endpoint
369
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
370
+ """
371
+ symbolsLength = len(symbolsAndTimeframes)
372
+ if symbolsLength == 0 or not isinstance(symbolsAndTimeframes[0], list):
373
+ raise ArgumentsRequired(self.id + " watchOHLCVForSymbols() requires a an array of symbols and timeframes, like [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]")
374
+ await self.load_markets()
375
+ symbol, timeframe, candles = await self.watch_multiple_wrapper(True, 'candle', 'watchOHLCVForSymbols', symbolsAndTimeframes, params)
376
+ if self.newUpdates:
377
+ limit = candles.getLimit(symbol, limit)
378
+ filtered = self.filter_by_since_limit(candles, since, limit, 0, True)
379
+ return self.create_ohlcv_object(symbol, timeframe, filtered)
380
+
381
+ def handle_ohlcv(self, client: Client, message):
382
+ #
383
+ # message
384
+ #
385
+ # {
386
+ # arg: {
387
+ # channel: "candle1m",
388
+ # instId: "DOGE-USDT",
389
+ # },
390
+ # data: [
391
+ # [same object in REST example]
392
+ # ],
393
+ # }
394
+ #
395
+ arg = self.safe_dict(message, 'arg')
396
+ channelName = self.safe_string(arg, 'channel')
397
+ data = self.safe_list(message, 'data')
398
+ marketId = self.safe_string(arg, 'instId')
399
+ market = self.safe_market(marketId)
400
+ symbol = market['symbol']
401
+ interval = channelName.replace('candle', '')
402
+ unifiedTimeframe = self.find_timeframe(interval)
403
+ self.ohlcvs[symbol] = self.safe_dict(self.ohlcvs, symbol, {})
404
+ stored = self.safe_value(self.ohlcvs[symbol], unifiedTimeframe)
405
+ if stored is None:
406
+ limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
407
+ stored = ArrayCacheByTimestamp(limit)
408
+ self.ohlcvs[symbol][unifiedTimeframe] = stored
409
+ for i in range(0, len(data)):
410
+ candle = data[i]
411
+ parsed = self.parse_ohlcv(candle, market)
412
+ stored.append(parsed)
413
+ resolveData = [symbol, unifiedTimeframe, stored]
414
+ messageHash = 'candle' + interval + ':' + symbol
415
+ client.resolve(resolveData, messageHash)
416
+
417
+ async def watch_balance(self, params={}) -> Balances:
418
+ """
419
+ query for balance and get the amount of funds available for trading or funds locked in orders
420
+
421
+ https://docs.blofin.com/index.html#ws-account-channel
422
+
423
+ :param dict [params]: extra parameters specific to the exchange API endpoint
424
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
425
+ """
426
+ await self.load_markets()
427
+ await self.authenticate()
428
+ marketType = None
429
+ marketType, params = self.handle_market_type_and_params('watchBalance', None, params)
430
+ if marketType == 'spot':
431
+ raise NotSupported(self.id + ' watchBalance() is not supported for spot markets yet')
432
+ messageHash = marketType + ':balance'
433
+ sub = {
434
+ 'channel': 'account',
435
+ }
436
+ request = self.get_subscription_request([sub])
437
+ url = self.implode_hostname(self.urls['api']['ws'][marketType]['private'])
438
+ return await self.watch(url, messageHash, self.deep_extend(request, params), messageHash)
439
+
440
+ def handle_balance(self, client: Client, message):
441
+ #
442
+ # {
443
+ # arg: {
444
+ # channel: "account",
445
+ # },
446
+ # data: <same object in REST example>,
447
+ # }
448
+ #
449
+ marketType = 'swap' # for now
450
+ if not (marketType in self.balance):
451
+ self.balance[marketType] = {}
452
+ self.balance[marketType] = self.parse_ws_balance(message)
453
+ messageHash = marketType + ':balance'
454
+ client.resolve(self.balance[marketType], messageHash)
455
+
456
+ def parse_ws_balance(self, message):
457
+ return self.parse_balance(message)
458
+
459
+ async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
460
+ """
461
+ watches information on multiple orders made by the user
462
+ :param str symbol: unified market symbol of the market orders were made in
463
+ :param int [since]: the earliest time in ms to fetch orders for
464
+ :param int [limit]: the maximum number of order structures to retrieve
465
+ :param dict [params]: extra parameters specific to the exchange API endpoint
466
+ :returns dict[]: a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure
467
+ """
468
+ params['callerMethodName'] = 'watchOrders'
469
+ symbolsArray = [symbol] if (symbol is not None) else []
470
+ return await self.watch_orders_for_symbols(symbolsArray, since, limit, params)
471
+
472
+ async def watch_orders_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Order]:
473
+ """
474
+ watches information on multiple orders made by the user across multiple symbols
475
+
476
+ https://docs.blofin.com/index.html#ws-order-channel
477
+
478
+ :param str[] symbols:
479
+ :param int [since]: the earliest time in ms to fetch orders for
480
+ :param int [limit]: the maximum number of order structures to retrieve
481
+ :param dict [params]: extra parameters specific to the exchange API endpoint
482
+ :returns dict[]: a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure
483
+ """
484
+ await self.authenticate()
485
+ await self.load_markets()
486
+ orders = await self.watch_multiple_wrapper(False, 'orders', 'watchOrdersForSymbols', symbols, params)
487
+ if self.newUpdates:
488
+ first = self.safe_value(orders, 0)
489
+ tradeSymbol = self.safe_string(first, 'symbol')
490
+ limit = orders.getLimit(tradeSymbol, limit)
491
+ return self.filter_by_since_limit(orders, since, limit, 'timestamp', True)
492
+
493
+ def handle_orders(self, client: Client, message):
494
+ #
495
+ # {
496
+ # action: 'update',
497
+ # arg: {channel: 'orders'},
498
+ # data: [
499
+ # <same object in REST example>
500
+ # ]
501
+ # }
502
+ #
503
+ if self.orders is None:
504
+ limit = self.safe_integer(self.options, 'ordersLimit', 1000)
505
+ self.orders = ArrayCacheBySymbolById(limit)
506
+ orders = self.orders
507
+ arg = self.safe_dict(message, 'arg')
508
+ channelName = self.safe_string(arg, 'channel')
509
+ data = self.safe_list(message, 'data')
510
+ for i in range(0, len(data)):
511
+ order = self.parse_ws_order(data[i])
512
+ symbol = order['symbol']
513
+ messageHash = channelName + ':' + symbol
514
+ orders.append(order)
515
+ client.resolve(orders, messageHash)
516
+ client.resolve(orders, channelName)
517
+
518
+ def parse_ws_order(self, order, market: Market = None) -> Order:
519
+ return self.parse_order(order, market)
520
+
521
+ async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
522
+ """
523
+
524
+ https://docs.blofin.com/index.html#ws-positions-channel
525
+
526
+ watch all open positions
527
+ :param str[]|None symbols: list of unified market symbols
528
+ :param int [since]: the earliest time in ms to fetch positions for
529
+ :param int [limit]: the maximum number of positions to retrieve
530
+ :param dict params: extra parameters specific to the exchange API endpoint
531
+ :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
532
+ """
533
+ await self.authenticate()
534
+ await self.load_markets()
535
+ newPositions = await self.watch_multiple_wrapper(False, 'positions', 'watchPositions', symbols, params)
536
+ if self.newUpdates:
537
+ return newPositions
538
+ return self.filter_by_symbols_since_limit(self.positions, symbols, since, limit)
539
+
540
+ def handle_positions(self, client: Client, message):
541
+ #
542
+ # {
543
+ # arg: {channel: 'positions'},
544
+ # data: [
545
+ # <same object in REST example>
546
+ # ]
547
+ # }
548
+ #
549
+ if self.positions is None:
550
+ self.positions = ArrayCacheBySymbolBySide()
551
+ cache = self.positions
552
+ arg = self.safe_dict(message, 'arg')
553
+ channelName = self.safe_string(arg, 'channel')
554
+ data = self.safe_list(message, 'data')
555
+ newPositions = []
556
+ for i in range(0, len(data)):
557
+ position = self.parse_ws_position(data[i])
558
+ newPositions.append(position)
559
+ cache.append(position)
560
+ messageHash = channelName + ':' + position['symbol']
561
+ client.resolve(position, messageHash)
562
+
563
+ def parse_ws_position(self, position, market: Market = None) -> Position:
564
+ return self.parse_position(position, market)
565
+
566
+ async def watch_multiple_wrapper(self, isPublic: bool, channelName: str, callerMethodName: str, symbolsArray: List[Any] = None, params={}):
567
+ # underlier method for all watch-multiple symbols
568
+ await self.load_markets()
569
+ callerMethodName, params = self.handle_param_string(params, 'callerMethodName', callerMethodName)
570
+ # if OHLCV method are being called, then symbols would be symbolsAndTimeframes(multi-dimensional) array
571
+ isOHLCV = (channelName == 'candle')
572
+ symbols = self.get_list_from_object_values(symbolsArray, 0) if isOHLCV else symbolsArray
573
+ symbols = self.market_symbols(symbols, None, True, True)
574
+ firstMarket = None
575
+ firstSymbol = self.safe_string(symbols, 0)
576
+ if firstSymbol is not None:
577
+ firstMarket = self.market(firstSymbol)
578
+ marketType = None
579
+ marketType, params = self.handle_market_type_and_params(callerMethodName, firstMarket, params)
580
+ if marketType != 'swap':
581
+ raise NotSupported(self.id + ' ' + callerMethodName + '() does not support ' + marketType + ' markets yet')
582
+ rawSubscriptions = []
583
+ messageHashes = []
584
+ if symbols is None:
585
+ symbols = []
586
+ symbolsLength = len(symbols)
587
+ if symbolsLength > 0:
588
+ for i in range(0, len(symbols)):
589
+ current = symbols[i]
590
+ market = None
591
+ channel = channelName
592
+ if isOHLCV:
593
+ market = self.market(current)
594
+ tfArray = symbolsArray[i]
595
+ tf = tfArray[1]
596
+ interval = self.safe_string(self.timeframes, tf, tf)
597
+ channel += interval
598
+ else:
599
+ market = self.market(current)
600
+ topic = {
601
+ 'channel': channel,
602
+ 'instId': market['id'],
603
+ }
604
+ rawSubscriptions.append(topic)
605
+ messageHashes.append(channel + ':' + market['symbol'])
606
+ else:
607
+ rawSubscriptions.append({'channel': channelName})
608
+ messageHashes.append(channelName)
609
+ # private channel are difference, they only need plural channel name for multiple symbols
610
+ if self.in_array(channelName, ['orders', 'positions']):
611
+ rawSubscriptions = [{'channel': channelName}]
612
+ request = self.get_subscription_request(rawSubscriptions)
613
+ privateOrPublic = 'public' if isPublic else 'private'
614
+ url = self.implode_hostname(self.urls['api']['ws'][marketType][privateOrPublic])
615
+ return await self.watch_multiple(url, messageHashes, self.deep_extend(request, params), messageHashes)
616
+
617
+ def get_subscription_request(self, args):
618
+ return {
619
+ 'op': 'subscribe',
620
+ 'args': args,
621
+ }
622
+
623
+ def handle_message(self, client: Client, message):
624
+ #
625
+ # message examples
626
+ #
627
+ # {
628
+ # arg: {
629
+ # channel: "trades",
630
+ # instId: "DOGE-USDT",
631
+ # },
632
+ # event: "subscribe"
633
+ # }
634
+ #
635
+ # incoming data updates' examples can be seen under each handler method
636
+ #
637
+ methods = {
638
+ # public
639
+ 'pong': self.handle_pong,
640
+ 'trades': self.handle_trades,
641
+ 'books': self.handle_order_book,
642
+ 'tickers': self.handle_ticker,
643
+ 'candle': self.handle_ohlcv, # candle1m, candle5m, etc
644
+ # private
645
+ 'account': self.handle_balance,
646
+ 'orders': self.handle_orders,
647
+ 'positions': self.handle_positions,
648
+ }
649
+ method = None
650
+ if message == 'pong':
651
+ method = self.safe_value(methods, 'pong')
652
+ else:
653
+ event = self.safe_string(message, 'event')
654
+ if event == 'subscribe':
655
+ return
656
+ elif event == 'login':
657
+ future = self.safe_value(client.futures, 'authenticate_hash')
658
+ future.resolve(True)
659
+ return
660
+ elif event == 'error':
661
+ raise ExchangeError(self.id + ' error: ' + self.json(message))
662
+ arg = self.safe_dict(message, 'arg')
663
+ channelName = self.safe_string(arg, 'channel')
664
+ method = self.safe_value(methods, channelName)
665
+ if not method and channelName.find('candle') >= 0:
666
+ method = methods['candle']
667
+ if method:
668
+ method(client, message)
669
+
670
+ async def authenticate(self, params={}):
671
+ self.check_required_credentials()
672
+ milliseconds = self.milliseconds()
673
+ messageHash = 'authenticate_hash'
674
+ timestamp = str(milliseconds)
675
+ nonce = 'n_' + timestamp
676
+ auth = '/users/self/verify' + 'GET' + timestamp + '' + nonce
677
+ signature = self.string_to_base64(self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256))
678
+ request = {
679
+ 'op': 'login',
680
+ 'args': [
681
+ {
682
+ 'apiKey': self.apiKey,
683
+ 'passphrase': self.password,
684
+ 'timestamp': timestamp,
685
+ 'nonce': nonce,
686
+ 'sign': signature,
687
+ },
688
+ ],
689
+ }
690
+ marketType = 'swap' # for now
691
+ url = self.implode_hostname(self.urls['api']['ws'][marketType]['private'])
692
+ await self.watch(url, messageHash, self.deep_extend(request, params), messageHash)