ccxt-ir 4.3.46.0.1__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 (772) hide show
  1. ccxt/__init__.py +358 -0
  2. ccxt/abantether.py +316 -0
  3. ccxt/abstract/__init__.py +0 -0
  4. ccxt/abstract/abantether.py +5 -0
  5. ccxt/abstract/ace.py +15 -0
  6. ccxt/abstract/afratether.py +6 -0
  7. ccxt/abstract/alpaca.py +70 -0
  8. ccxt/abstract/arzinja.py +5 -0
  9. ccxt/abstract/arzplus.py +7 -0
  10. ccxt/abstract/ascendex.py +77 -0
  11. ccxt/abstract/bequant.py +115 -0
  12. ccxt/abstract/bigone.py +45 -0
  13. ccxt/abstract/binance.py +712 -0
  14. ccxt/abstract/binancecoinm.py +712 -0
  15. ccxt/abstract/binanceus.py +764 -0
  16. ccxt/abstract/binanceusdm.py +712 -0
  17. ccxt/abstract/bingx.py +113 -0
  18. ccxt/abstract/bit2c.py +27 -0
  19. ccxt/abstract/bitbank.py +27 -0
  20. ccxt/abstract/bitbay.py +53 -0
  21. ccxt/abstract/bitbns.py +40 -0
  22. ccxt/abstract/bitcoincom.py +115 -0
  23. ccxt/abstract/bitfinex.py +69 -0
  24. ccxt/abstract/bitfinex2.py +139 -0
  25. ccxt/abstract/bitflyer.py +38 -0
  26. ccxt/abstract/bitget.py +508 -0
  27. ccxt/abstract/bithumb.py +32 -0
  28. ccxt/abstract/bitimen.py +7 -0
  29. ccxt/abstract/bitir.py +7 -0
  30. ccxt/abstract/bitmart.py +99 -0
  31. ccxt/abstract/bitmex.py +97 -0
  32. ccxt/abstract/bitopro.py +29 -0
  33. ccxt/abstract/bitpanda.py +35 -0
  34. ccxt/abstract/bitpin.py +7 -0
  35. ccxt/abstract/bitrue.py +72 -0
  36. ccxt/abstract/bitso.py +43 -0
  37. ccxt/abstract/bitstamp.py +258 -0
  38. ccxt/abstract/bitteam.py +29 -0
  39. ccxt/abstract/bitvavo.py +27 -0
  40. ccxt/abstract/bl3p.py +19 -0
  41. ccxt/abstract/blockchaincom.py +28 -0
  42. ccxt/abstract/blofin.py +37 -0
  43. ccxt/abstract/btcalpha.py +18 -0
  44. ccxt/abstract/btcbox.py +13 -0
  45. ccxt/abstract/btcmarkets.py +39 -0
  46. ccxt/abstract/btcturk.py +20 -0
  47. ccxt/abstract/bybit.py +298 -0
  48. ccxt/abstract/cex.py +33 -0
  49. ccxt/abstract/coinbase.py +94 -0
  50. ccxt/abstract/coinbaseadvanced.py +94 -0
  51. ccxt/abstract/coinbaseexchange.py +67 -0
  52. ccxt/abstract/coinbaseinternational.py +39 -0
  53. ccxt/abstract/coincatch.py +94 -0
  54. ccxt/abstract/coincheck.py +33 -0
  55. ccxt/abstract/coinex.py +237 -0
  56. ccxt/abstract/coinlist.py +54 -0
  57. ccxt/abstract/coinmate.py +62 -0
  58. ccxt/abstract/coinmetro.py +34 -0
  59. ccxt/abstract/coinone.py +67 -0
  60. ccxt/abstract/coinsph.py +54 -0
  61. ccxt/abstract/coinspot.py +28 -0
  62. ccxt/abstract/cryptocom.py +107 -0
  63. ccxt/abstract/currencycom.py +68 -0
  64. ccxt/abstract/delta.py +50 -0
  65. ccxt/abstract/deribit.py +125 -0
  66. ccxt/abstract/digifinex.py +91 -0
  67. ccxt/abstract/eterex.py +5 -0
  68. ccxt/abstract/excoino.py +7 -0
  69. ccxt/abstract/exir.py +8 -0
  70. ccxt/abstract/exmo.py +55 -0
  71. ccxt/abstract/exnovin.py +6 -0
  72. ccxt/abstract/farhadexchange.py +5 -0
  73. ccxt/abstract/fmfwio.py +115 -0
  74. ccxt/abstract/gate.py +265 -0
  75. ccxt/abstract/gateio.py +265 -0
  76. ccxt/abstract/gemini.py +58 -0
  77. ccxt/abstract/hashkey.py +67 -0
  78. ccxt/abstract/hitbtc.py +115 -0
  79. ccxt/abstract/hitbtc3.py +115 -0
  80. ccxt/abstract/hitobit.py +8 -0
  81. ccxt/abstract/hollaex.py +33 -0
  82. ccxt/abstract/htx.py +548 -0
  83. ccxt/abstract/huobi.py +548 -0
  84. ccxt/abstract/huobijp.py +114 -0
  85. ccxt/abstract/hyperliquid.py +6 -0
  86. ccxt/abstract/idex.py +26 -0
  87. ccxt/abstract/independentreserve.py +37 -0
  88. ccxt/abstract/indodax.py +26 -0
  89. ccxt/abstract/jibitex.py +7 -0
  90. ccxt/abstract/kraken.py +57 -0
  91. ccxt/abstract/krakenfutures.py +38 -0
  92. ccxt/abstract/kucoin.py +214 -0
  93. ccxt/abstract/kucoinfutures.py +233 -0
  94. ccxt/abstract/kuna.py +182 -0
  95. ccxt/abstract/latoken.py +56 -0
  96. ccxt/abstract/lbank.py +61 -0
  97. ccxt/abstract/luno.py +37 -0
  98. ccxt/abstract/lykke.py +29 -0
  99. ccxt/abstract/mercado.py +25 -0
  100. ccxt/abstract/mexc.py +178 -0
  101. ccxt/abstract/ndax.py +97 -0
  102. ccxt/abstract/nobitex.py +7 -0
  103. ccxt/abstract/novadax.py +29 -0
  104. ccxt/abstract/oceanex.py +22 -0
  105. ccxt/abstract/okcoin.py +74 -0
  106. ccxt/abstract/okexchange.py +8 -0
  107. ccxt/abstract/okx.py +324 -0
  108. ccxt/abstract/ompfinex.py +7 -0
  109. ccxt/abstract/onetrading.py +35 -0
  110. ccxt/abstract/oxfun.py +34 -0
  111. ccxt/abstract/p2b.py +22 -0
  112. ccxt/abstract/paradex.py +40 -0
  113. ccxt/abstract/paymium.py +28 -0
  114. ccxt/abstract/phemex.py +115 -0
  115. ccxt/abstract/poloniex.py +69 -0
  116. ccxt/abstract/poloniexfutures.py +48 -0
  117. ccxt/abstract/probit.py +23 -0
  118. ccxt/abstract/ramzinex.py +7 -0
  119. ccxt/abstract/sarmayex.py +5 -0
  120. ccxt/abstract/sarrafex.py +7 -0
  121. ccxt/abstract/tabdeal.py +7 -0
  122. ccxt/abstract/tetherland.py +5 -0
  123. ccxt/abstract/timex.py +62 -0
  124. ccxt/abstract/tokocrypto.py +37 -0
  125. ccxt/abstract/tradeogre.py +16 -0
  126. ccxt/abstract/twox.py +5 -0
  127. ccxt/abstract/ubitex.py +7 -0
  128. ccxt/abstract/upbit.py +38 -0
  129. ccxt/abstract/vertex.py +19 -0
  130. ccxt/abstract/wallex.py +8 -0
  131. ccxt/abstract/wavesexchange.py +154 -0
  132. ccxt/abstract/wazirx.py +30 -0
  133. ccxt/abstract/whitebit.py +98 -0
  134. ccxt/abstract/woo.py +83 -0
  135. ccxt/abstract/woofipro.py +119 -0
  136. ccxt/abstract/xt.py +152 -0
  137. ccxt/abstract/yobit.py +16 -0
  138. ccxt/abstract/zaif.py +38 -0
  139. ccxt/abstract/zonda.py +53 -0
  140. ccxt/ace.py +1012 -0
  141. ccxt/afratether.py +293 -0
  142. ccxt/alpaca.py +1083 -0
  143. ccxt/arzinja.py +285 -0
  144. ccxt/arzplus.py +412 -0
  145. ccxt/ascendex.py +3330 -0
  146. ccxt/async_support/__init__.py +337 -0
  147. ccxt/async_support/abantether.py +316 -0
  148. ccxt/async_support/ace.py +1012 -0
  149. ccxt/async_support/afratether.py +293 -0
  150. ccxt/async_support/alpaca.py +1083 -0
  151. ccxt/async_support/arzinja.py +285 -0
  152. ccxt/async_support/arzplus.py +412 -0
  153. ccxt/async_support/ascendex.py +3330 -0
  154. ccxt/async_support/base/__init__.py +1 -0
  155. ccxt/async_support/base/exchange.py +1966 -0
  156. ccxt/async_support/base/throttler.py +50 -0
  157. ccxt/async_support/base/ws/__init__.py +38 -0
  158. ccxt/async_support/base/ws/aiohttp_client.py +125 -0
  159. ccxt/async_support/base/ws/cache.py +212 -0
  160. ccxt/async_support/base/ws/client.py +193 -0
  161. ccxt/async_support/base/ws/fast_client.py +96 -0
  162. ccxt/async_support/base/ws/functions.py +59 -0
  163. ccxt/async_support/base/ws/future.py +58 -0
  164. ccxt/async_support/base/ws/order_book.py +78 -0
  165. ccxt/async_support/base/ws/order_book_side.py +174 -0
  166. ccxt/async_support/bequant.py +33 -0
  167. ccxt/async_support/bigone.py +2113 -0
  168. ccxt/async_support/binance.py +12234 -0
  169. ccxt/async_support/binancecoinm.py +45 -0
  170. ccxt/async_support/binanceus.py +211 -0
  171. ccxt/async_support/binanceusdm.py +58 -0
  172. ccxt/async_support/bingx.py +4325 -0
  173. ccxt/async_support/bit2c.py +866 -0
  174. ccxt/async_support/bitbank.py +1001 -0
  175. ccxt/async_support/bitbay.py +17 -0
  176. ccxt/async_support/bitbns.py +1154 -0
  177. ccxt/async_support/bitcoincom.py +17 -0
  178. ccxt/async_support/bitfinex.py +1617 -0
  179. ccxt/async_support/bitfinex2.py +3552 -0
  180. ccxt/async_support/bitflyer.py +995 -0
  181. ccxt/async_support/bitget.py +8273 -0
  182. ccxt/async_support/bithumb.py +1061 -0
  183. ccxt/async_support/bitimen.py +401 -0
  184. ccxt/async_support/bitir.py +490 -0
  185. ccxt/async_support/bitmart.py +4415 -0
  186. ccxt/async_support/bitmex.py +2756 -0
  187. ccxt/async_support/bitopro.py +1630 -0
  188. ccxt/async_support/bitpanda.py +16 -0
  189. ccxt/async_support/bitpin.py +454 -0
  190. ccxt/async_support/bitrue.py +3027 -0
  191. ccxt/async_support/bitso.py +1670 -0
  192. ccxt/async_support/bitstamp.py +2203 -0
  193. ccxt/async_support/bitteam.py +2239 -0
  194. ccxt/async_support/bitvavo.py +1968 -0
  195. ccxt/async_support/bl3p.py +485 -0
  196. ccxt/async_support/blockchaincom.py +1104 -0
  197. ccxt/async_support/blofin.py +2066 -0
  198. ccxt/async_support/btcalpha.py +891 -0
  199. ccxt/async_support/btcbox.py +544 -0
  200. ccxt/async_support/btcmarkets.py +1221 -0
  201. ccxt/async_support/btcturk.py +911 -0
  202. ccxt/async_support/bybit.py +8159 -0
  203. ccxt/async_support/cex.py +1605 -0
  204. ccxt/async_support/coinbase.py +4475 -0
  205. ccxt/async_support/coinbaseadvanced.py +17 -0
  206. ccxt/async_support/coinbaseexchange.py +1734 -0
  207. ccxt/async_support/coinbaseinternational.py +1899 -0
  208. ccxt/async_support/coincatch.py +5069 -0
  209. ccxt/async_support/coincheck.py +815 -0
  210. ccxt/async_support/coinex.py +5526 -0
  211. ccxt/async_support/coinlist.py +2243 -0
  212. ccxt/async_support/coinmate.py +1067 -0
  213. ccxt/async_support/coinmetro.py +1797 -0
  214. ccxt/async_support/coinone.py +1127 -0
  215. ccxt/async_support/coinsph.py +1850 -0
  216. ccxt/async_support/coinspot.py +534 -0
  217. ccxt/async_support/cryptocom.py +2822 -0
  218. ccxt/async_support/currencycom.py +1950 -0
  219. ccxt/async_support/delta.py +3376 -0
  220. ccxt/async_support/deribit.py +3437 -0
  221. ccxt/async_support/digifinex.py +3960 -0
  222. ccxt/async_support/eterex.py +286 -0
  223. ccxt/async_support/excoino.py +399 -0
  224. ccxt/async_support/exir.py +375 -0
  225. ccxt/async_support/exmo.py +2462 -0
  226. ccxt/async_support/exnovin.py +360 -0
  227. ccxt/async_support/farhadexchange.py +266 -0
  228. ccxt/async_support/fmfwio.py +34 -0
  229. ccxt/async_support/gate.py +6976 -0
  230. ccxt/async_support/gateio.py +16 -0
  231. ccxt/async_support/gemini.py +1825 -0
  232. ccxt/async_support/hashkey.py +4150 -0
  233. ccxt/async_support/hitbtc.py +3423 -0
  234. ccxt/async_support/hitbtc3.py +16 -0
  235. ccxt/async_support/hitobit.py +391 -0
  236. ccxt/async_support/hollaex.py +1813 -0
  237. ccxt/async_support/htx.py +8506 -0
  238. ccxt/async_support/huobi.py +16 -0
  239. ccxt/async_support/huobijp.py +1801 -0
  240. ccxt/async_support/hyperliquid.py +2431 -0
  241. ccxt/async_support/idex.py +1766 -0
  242. ccxt/async_support/independentreserve.py +784 -0
  243. ccxt/async_support/indodax.py +1247 -0
  244. ccxt/async_support/jibitex.py +395 -0
  245. ccxt/async_support/kraken.py +2894 -0
  246. ccxt/async_support/krakenfutures.py +2601 -0
  247. ccxt/async_support/kucoin.py +4602 -0
  248. ccxt/async_support/kucoinfutures.py +2698 -0
  249. ccxt/async_support/kuna.py +1841 -0
  250. ccxt/async_support/latoken.py +1664 -0
  251. ccxt/async_support/lbank.py +2683 -0
  252. ccxt/async_support/luno.py +1067 -0
  253. ccxt/async_support/lykke.py +1270 -0
  254. ccxt/async_support/mercado.py +842 -0
  255. ccxt/async_support/mexc.py +5369 -0
  256. ccxt/async_support/ndax.py +2354 -0
  257. ccxt/async_support/nobitex.py +419 -0
  258. ccxt/async_support/novadax.py +1484 -0
  259. ccxt/async_support/oceanex.py +903 -0
  260. ccxt/async_support/okcoin.py +2936 -0
  261. ccxt/async_support/okexchange.py +349 -0
  262. ccxt/async_support/okx.py +7827 -0
  263. ccxt/async_support/ompfinex.py +472 -0
  264. ccxt/async_support/onetrading.py +1911 -0
  265. ccxt/async_support/oxfun.py +2773 -0
  266. ccxt/async_support/p2b.py +1194 -0
  267. ccxt/async_support/paradex.py +2015 -0
  268. ccxt/async_support/paymium.py +564 -0
  269. ccxt/async_support/phemex.py +4473 -0
  270. ccxt/async_support/poloniex.py +2232 -0
  271. ccxt/async_support/poloniexfutures.py +1717 -0
  272. ccxt/async_support/probit.py +1734 -0
  273. ccxt/async_support/ramzinex.py +476 -0
  274. ccxt/async_support/sarmayex.py +357 -0
  275. ccxt/async_support/sarrafex.py +478 -0
  276. ccxt/async_support/tabdeal.py +364 -0
  277. ccxt/async_support/tetherland.py +349 -0
  278. ccxt/async_support/timex.py +1593 -0
  279. ccxt/async_support/tokocrypto.py +2405 -0
  280. ccxt/async_support/tradeogre.py +608 -0
  281. ccxt/async_support/twox.py +326 -0
  282. ccxt/async_support/ubitex.py +409 -0
  283. ccxt/async_support/upbit.py +1833 -0
  284. ccxt/async_support/vertex.py +2922 -0
  285. ccxt/async_support/wallex.py +445 -0
  286. ccxt/async_support/wavesexchange.py +2473 -0
  287. ccxt/async_support/wazirx.py +1224 -0
  288. ccxt/async_support/whitebit.py +2469 -0
  289. ccxt/async_support/woo.py +3114 -0
  290. ccxt/async_support/woofipro.py +2533 -0
  291. ccxt/async_support/xt.py +4454 -0
  292. ccxt/async_support/yobit.py +1283 -0
  293. ccxt/async_support/zaif.py +725 -0
  294. ccxt/async_support/zonda.py +1828 -0
  295. ccxt/base/__init__.py +27 -0
  296. ccxt/base/decimal_to_precision.py +174 -0
  297. ccxt/base/errors.py +242 -0
  298. ccxt/base/exchange.py +5941 -0
  299. ccxt/base/precise.py +287 -0
  300. ccxt/base/types.py +502 -0
  301. ccxt/bequant.py +33 -0
  302. ccxt/bigone.py +2112 -0
  303. ccxt/binance.py +12233 -0
  304. ccxt/binancecoinm.py +45 -0
  305. ccxt/binanceus.py +211 -0
  306. ccxt/binanceusdm.py +58 -0
  307. ccxt/bingx.py +4324 -0
  308. ccxt/bit2c.py +866 -0
  309. ccxt/bitbank.py +1001 -0
  310. ccxt/bitbay.py +17 -0
  311. ccxt/bitbns.py +1154 -0
  312. ccxt/bitcoincom.py +17 -0
  313. ccxt/bitfinex.py +1617 -0
  314. ccxt/bitfinex2.py +3552 -0
  315. ccxt/bitflyer.py +995 -0
  316. ccxt/bitget.py +8272 -0
  317. ccxt/bithumb.py +1061 -0
  318. ccxt/bitimen.py +401 -0
  319. ccxt/bitir.py +490 -0
  320. ccxt/bitmart.py +4415 -0
  321. ccxt/bitmex.py +2756 -0
  322. ccxt/bitopro.py +1630 -0
  323. ccxt/bitpanda.py +16 -0
  324. ccxt/bitpin.py +454 -0
  325. ccxt/bitrue.py +3026 -0
  326. ccxt/bitso.py +1670 -0
  327. ccxt/bitstamp.py +2203 -0
  328. ccxt/bitteam.py +2239 -0
  329. ccxt/bitvavo.py +1968 -0
  330. ccxt/bl3p.py +485 -0
  331. ccxt/blockchaincom.py +1104 -0
  332. ccxt/blofin.py +2066 -0
  333. ccxt/btcalpha.py +891 -0
  334. ccxt/btcbox.py +544 -0
  335. ccxt/btcmarkets.py +1221 -0
  336. ccxt/btcturk.py +911 -0
  337. ccxt/bybit.py +8158 -0
  338. ccxt/cex.py +1605 -0
  339. ccxt/coinbase.py +4474 -0
  340. ccxt/coinbaseadvanced.py +17 -0
  341. ccxt/coinbaseexchange.py +1734 -0
  342. ccxt/coinbaseinternational.py +1899 -0
  343. ccxt/coincatch.py +5069 -0
  344. ccxt/coincheck.py +815 -0
  345. ccxt/coinex.py +5525 -0
  346. ccxt/coinlist.py +2243 -0
  347. ccxt/coinmate.py +1067 -0
  348. ccxt/coinmetro.py +1797 -0
  349. ccxt/coinone.py +1127 -0
  350. ccxt/coinsph.py +1850 -0
  351. ccxt/coinspot.py +534 -0
  352. ccxt/cryptocom.py +2822 -0
  353. ccxt/currencycom.py +1950 -0
  354. ccxt/delta.py +3376 -0
  355. ccxt/deribit.py +3437 -0
  356. ccxt/digifinex.py +3959 -0
  357. ccxt/eterex.py +286 -0
  358. ccxt/excoino.py +399 -0
  359. ccxt/exir.py +375 -0
  360. ccxt/exmo.py +2462 -0
  361. ccxt/exnovin.py +360 -0
  362. ccxt/farhadexchange.py +266 -0
  363. ccxt/fmfwio.py +34 -0
  364. ccxt/gate.py +6975 -0
  365. ccxt/gateio.py +16 -0
  366. ccxt/gemini.py +1824 -0
  367. ccxt/hashkey.py +4150 -0
  368. ccxt/hitbtc.py +3423 -0
  369. ccxt/hitbtc3.py +16 -0
  370. ccxt/hitobit.py +391 -0
  371. ccxt/hollaex.py +1813 -0
  372. ccxt/htx.py +8505 -0
  373. ccxt/huobi.py +16 -0
  374. ccxt/huobijp.py +1801 -0
  375. ccxt/hyperliquid.py +2430 -0
  376. ccxt/idex.py +1766 -0
  377. ccxt/independentreserve.py +784 -0
  378. ccxt/indodax.py +1247 -0
  379. ccxt/jibitex.py +395 -0
  380. ccxt/kraken.py +2894 -0
  381. ccxt/krakenfutures.py +2601 -0
  382. ccxt/kucoin.py +4601 -0
  383. ccxt/kucoinfutures.py +2698 -0
  384. ccxt/kuna.py +1841 -0
  385. ccxt/latoken.py +1664 -0
  386. ccxt/lbank.py +2682 -0
  387. ccxt/luno.py +1067 -0
  388. ccxt/lykke.py +1270 -0
  389. ccxt/mercado.py +842 -0
  390. ccxt/mexc.py +5369 -0
  391. ccxt/ndax.py +2354 -0
  392. ccxt/nobitex.py +419 -0
  393. ccxt/novadax.py +1484 -0
  394. ccxt/oceanex.py +903 -0
  395. ccxt/okcoin.py +2936 -0
  396. ccxt/okexchange.py +349 -0
  397. ccxt/okx.py +7826 -0
  398. ccxt/ompfinex.py +472 -0
  399. ccxt/onetrading.py +1911 -0
  400. ccxt/oxfun.py +2772 -0
  401. ccxt/p2b.py +1194 -0
  402. ccxt/paradex.py +2015 -0
  403. ccxt/paymium.py +564 -0
  404. ccxt/phemex.py +4473 -0
  405. ccxt/poloniex.py +2232 -0
  406. ccxt/poloniexfutures.py +1717 -0
  407. ccxt/pro/__init__.py +149 -0
  408. ccxt/pro/alpaca.py +685 -0
  409. ccxt/pro/ascendex.py +916 -0
  410. ccxt/pro/bequant.py +38 -0
  411. ccxt/pro/binance.py +3488 -0
  412. ccxt/pro/binancecoinm.py +28 -0
  413. ccxt/pro/binanceus.py +48 -0
  414. ccxt/pro/binanceusdm.py +31 -0
  415. ccxt/pro/bingx.py +1264 -0
  416. ccxt/pro/bitcoincom.py +34 -0
  417. ccxt/pro/bitfinex.py +621 -0
  418. ccxt/pro/bitfinex2.py +1083 -0
  419. ccxt/pro/bitget.py +1692 -0
  420. ccxt/pro/bithumb.py +368 -0
  421. ccxt/pro/bitmart.py +1449 -0
  422. ccxt/pro/bitmex.py +1656 -0
  423. ccxt/pro/bitopro.py +445 -0
  424. ccxt/pro/bitpanda.py +15 -0
  425. ccxt/pro/bitrue.py +447 -0
  426. ccxt/pro/bitstamp.py +522 -0
  427. ccxt/pro/bitvavo.py +1270 -0
  428. ccxt/pro/blockchaincom.py +738 -0
  429. ccxt/pro/blofin.py +692 -0
  430. ccxt/pro/bybit.py +2000 -0
  431. ccxt/pro/cex.py +1440 -0
  432. ccxt/pro/coinbase.py +678 -0
  433. ccxt/pro/coinbaseadvanced.py +16 -0
  434. ccxt/pro/coinbaseexchange.py +895 -0
  435. ccxt/pro/coinbaseinternational.py +620 -0
  436. ccxt/pro/coincatch.py +1464 -0
  437. ccxt/pro/coincheck.py +199 -0
  438. ccxt/pro/coinex.py +1061 -0
  439. ccxt/pro/coinone.py +395 -0
  440. ccxt/pro/cryptocom.py +947 -0
  441. ccxt/pro/currencycom.py +536 -0
  442. ccxt/pro/deribit.py +892 -0
  443. ccxt/pro/exmo.py +629 -0
  444. ccxt/pro/gate.py +1416 -0
  445. ccxt/pro/gateio.py +15 -0
  446. ccxt/pro/gemini.py +865 -0
  447. ccxt/pro/hashkey.py +802 -0
  448. ccxt/pro/hitbtc.py +1216 -0
  449. ccxt/pro/hollaex.py +563 -0
  450. ccxt/pro/htx.py +2215 -0
  451. ccxt/pro/huobi.py +15 -0
  452. ccxt/pro/huobijp.py +570 -0
  453. ccxt/pro/hyperliquid.py +525 -0
  454. ccxt/pro/idex.py +672 -0
  455. ccxt/pro/independentreserve.py +270 -0
  456. ccxt/pro/kraken.py +1356 -0
  457. ccxt/pro/krakenfutures.py +1492 -0
  458. ccxt/pro/kucoin.py +1133 -0
  459. ccxt/pro/kucoinfutures.py +1081 -0
  460. ccxt/pro/lbank.py +843 -0
  461. ccxt/pro/luno.py +303 -0
  462. ccxt/pro/mexc.py +1122 -0
  463. ccxt/pro/ndax.py +506 -0
  464. ccxt/pro/okcoin.py +698 -0
  465. ccxt/pro/okx.py +1851 -0
  466. ccxt/pro/onetrading.py +1275 -0
  467. ccxt/pro/oxfun.py +950 -0
  468. ccxt/pro/p2b.py +419 -0
  469. ccxt/pro/paradex.py +352 -0
  470. ccxt/pro/phemex.py +1441 -0
  471. ccxt/pro/poloniex.py +1166 -0
  472. ccxt/pro/poloniexfutures.py +990 -0
  473. ccxt/pro/probit.py +551 -0
  474. ccxt/pro/upbit.py +520 -0
  475. ccxt/pro/vertex.py +943 -0
  476. ccxt/pro/wazirx.py +749 -0
  477. ccxt/pro/whitebit.py +864 -0
  478. ccxt/pro/woo.py +1078 -0
  479. ccxt/pro/woofipro.py +1183 -0
  480. ccxt/pro/xt.py +1067 -0
  481. ccxt/probit.py +1734 -0
  482. ccxt/ramzinex.py +476 -0
  483. ccxt/sarmayex.py +357 -0
  484. ccxt/sarrafex.py +478 -0
  485. ccxt/static_dependencies/__init__.py +1 -0
  486. ccxt/static_dependencies/ecdsa/__init__.py +14 -0
  487. ccxt/static_dependencies/ecdsa/_version.py +520 -0
  488. ccxt/static_dependencies/ecdsa/curves.py +56 -0
  489. ccxt/static_dependencies/ecdsa/der.py +221 -0
  490. ccxt/static_dependencies/ecdsa/ecdsa.py +310 -0
  491. ccxt/static_dependencies/ecdsa/ellipticcurve.py +197 -0
  492. ccxt/static_dependencies/ecdsa/keys.py +332 -0
  493. ccxt/static_dependencies/ecdsa/numbertheory.py +531 -0
  494. ccxt/static_dependencies/ecdsa/rfc6979.py +100 -0
  495. ccxt/static_dependencies/ecdsa/util.py +266 -0
  496. ccxt/static_dependencies/ethereum/__init__.py +7 -0
  497. ccxt/static_dependencies/ethereum/abi/__init__.py +16 -0
  498. ccxt/static_dependencies/ethereum/abi/abi.py +19 -0
  499. ccxt/static_dependencies/ethereum/abi/base.py +152 -0
  500. ccxt/static_dependencies/ethereum/abi/codec.py +217 -0
  501. ccxt/static_dependencies/ethereum/abi/constants.py +3 -0
  502. ccxt/static_dependencies/ethereum/abi/decoding.py +565 -0
  503. ccxt/static_dependencies/ethereum/abi/encoding.py +720 -0
  504. ccxt/static_dependencies/ethereum/abi/exceptions.py +139 -0
  505. ccxt/static_dependencies/ethereum/abi/grammar.py +443 -0
  506. ccxt/static_dependencies/ethereum/abi/packed.py +13 -0
  507. ccxt/static_dependencies/ethereum/abi/py.typed +0 -0
  508. ccxt/static_dependencies/ethereum/abi/registry.py +643 -0
  509. ccxt/static_dependencies/ethereum/abi/tools/__init__.py +3 -0
  510. ccxt/static_dependencies/ethereum/abi/tools/_strategies.py +230 -0
  511. ccxt/static_dependencies/ethereum/abi/utils/__init__.py +0 -0
  512. ccxt/static_dependencies/ethereum/abi/utils/numeric.py +83 -0
  513. ccxt/static_dependencies/ethereum/abi/utils/padding.py +27 -0
  514. ccxt/static_dependencies/ethereum/abi/utils/string.py +19 -0
  515. ccxt/static_dependencies/ethereum/account/__init__.py +3 -0
  516. ccxt/static_dependencies/ethereum/account/encode_typed_data/__init__.py +4 -0
  517. ccxt/static_dependencies/ethereum/account/encode_typed_data/encoding_and_hashing.py +239 -0
  518. ccxt/static_dependencies/ethereum/account/encode_typed_data/helpers.py +40 -0
  519. ccxt/static_dependencies/ethereum/account/messages.py +263 -0
  520. ccxt/static_dependencies/ethereum/account/py.typed +0 -0
  521. ccxt/static_dependencies/ethereum/hexbytes/__init__.py +5 -0
  522. ccxt/static_dependencies/ethereum/hexbytes/_utils.py +54 -0
  523. ccxt/static_dependencies/ethereum/hexbytes/main.py +65 -0
  524. ccxt/static_dependencies/ethereum/hexbytes/py.typed +0 -0
  525. ccxt/static_dependencies/ethereum/typing/__init__.py +63 -0
  526. ccxt/static_dependencies/ethereum/typing/abi.py +6 -0
  527. ccxt/static_dependencies/ethereum/typing/bls.py +7 -0
  528. ccxt/static_dependencies/ethereum/typing/discovery.py +5 -0
  529. ccxt/static_dependencies/ethereum/typing/encoding.py +7 -0
  530. ccxt/static_dependencies/ethereum/typing/enums.py +17 -0
  531. ccxt/static_dependencies/ethereum/typing/ethpm.py +9 -0
  532. ccxt/static_dependencies/ethereum/typing/evm.py +20 -0
  533. ccxt/static_dependencies/ethereum/typing/networks.py +1122 -0
  534. ccxt/static_dependencies/ethereum/typing/py.typed +0 -0
  535. ccxt/static_dependencies/ethereum/utils/__init__.py +115 -0
  536. ccxt/static_dependencies/ethereum/utils/abi.py +72 -0
  537. ccxt/static_dependencies/ethereum/utils/address.py +171 -0
  538. ccxt/static_dependencies/ethereum/utils/applicators.py +151 -0
  539. ccxt/static_dependencies/ethereum/utils/conversions.py +190 -0
  540. ccxt/static_dependencies/ethereum/utils/currency.py +107 -0
  541. ccxt/static_dependencies/ethereum/utils/curried/__init__.py +269 -0
  542. ccxt/static_dependencies/ethereum/utils/debug.py +20 -0
  543. ccxt/static_dependencies/ethereum/utils/decorators.py +132 -0
  544. ccxt/static_dependencies/ethereum/utils/encoding.py +6 -0
  545. ccxt/static_dependencies/ethereum/utils/exceptions.py +4 -0
  546. ccxt/static_dependencies/ethereum/utils/functional.py +75 -0
  547. ccxt/static_dependencies/ethereum/utils/hexadecimal.py +74 -0
  548. ccxt/static_dependencies/ethereum/utils/humanize.py +188 -0
  549. ccxt/static_dependencies/ethereum/utils/logging.py +159 -0
  550. ccxt/static_dependencies/ethereum/utils/module_loading.py +31 -0
  551. ccxt/static_dependencies/ethereum/utils/numeric.py +43 -0
  552. ccxt/static_dependencies/ethereum/utils/py.typed +0 -0
  553. ccxt/static_dependencies/ethereum/utils/toolz.py +76 -0
  554. ccxt/static_dependencies/ethereum/utils/types.py +54 -0
  555. ccxt/static_dependencies/ethereum/utils/typing/__init__.py +18 -0
  556. ccxt/static_dependencies/ethereum/utils/typing/misc.py +14 -0
  557. ccxt/static_dependencies/ethereum/utils/units.py +31 -0
  558. ccxt/static_dependencies/keccak/__init__.py +3 -0
  559. ccxt/static_dependencies/keccak/keccak.py +197 -0
  560. ccxt/static_dependencies/lark/__init__.py +38 -0
  561. ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  562. ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  563. ccxt/static_dependencies/lark/ast_utils.py +59 -0
  564. ccxt/static_dependencies/lark/common.py +86 -0
  565. ccxt/static_dependencies/lark/exceptions.py +292 -0
  566. ccxt/static_dependencies/lark/grammar.py +130 -0
  567. ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  568. ccxt/static_dependencies/lark/indenter.py +143 -0
  569. ccxt/static_dependencies/lark/lark.py +658 -0
  570. ccxt/static_dependencies/lark/lexer.py +678 -0
  571. ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  572. ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  573. ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  574. ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  575. ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  576. ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  577. ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  578. ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  579. ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  580. ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  581. ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  582. ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  583. ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  584. ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  585. ccxt/static_dependencies/lark/reconstruct.py +107 -0
  586. ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  587. ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  588. ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  589. ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  590. ccxt/static_dependencies/lark/tree.py +267 -0
  591. ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  592. ccxt/static_dependencies/lark/tree_templates.py +180 -0
  593. ccxt/static_dependencies/lark/utils.py +343 -0
  594. ccxt/static_dependencies/lark/visitors.py +596 -0
  595. ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  596. ccxt/static_dependencies/marshmallow/base.py +65 -0
  597. ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  598. ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  599. ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  600. ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  601. ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  602. ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  603. ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  604. ccxt/static_dependencies/marshmallow/types.py +12 -0
  605. ccxt/static_dependencies/marshmallow/utils.py +378 -0
  606. ccxt/static_dependencies/marshmallow/validate.py +678 -0
  607. ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  608. ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  609. ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  610. ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  611. ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  612. ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  613. ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  614. ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  615. ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  616. ccxt/static_dependencies/msgpack/__init__.py +55 -0
  617. ccxt/static_dependencies/msgpack/exceptions.py +48 -0
  618. ccxt/static_dependencies/msgpack/ext.py +168 -0
  619. ccxt/static_dependencies/msgpack/fallback.py +951 -0
  620. ccxt/static_dependencies/parsimonious/__init__.py +10 -0
  621. ccxt/static_dependencies/parsimonious/exceptions.py +105 -0
  622. ccxt/static_dependencies/parsimonious/expressions.py +479 -0
  623. ccxt/static_dependencies/parsimonious/grammar.py +487 -0
  624. ccxt/static_dependencies/parsimonious/nodes.py +325 -0
  625. ccxt/static_dependencies/parsimonious/utils.py +40 -0
  626. ccxt/static_dependencies/starknet/__init__.py +0 -0
  627. ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  628. ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  629. ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  630. ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  631. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  632. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  633. ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  634. ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  635. ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  636. ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  637. ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  638. ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  639. ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  640. ccxt/static_dependencies/starknet/common.py +15 -0
  641. ccxt/static_dependencies/starknet/constants.py +39 -0
  642. ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  643. ccxt/static_dependencies/starknet/hash/address.py +79 -0
  644. ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  645. ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  646. ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  647. ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  648. ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  649. ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
  650. ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  651. ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  652. ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  653. ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  654. ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  655. ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  656. ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  657. ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  658. ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  659. ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  660. ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  661. ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  662. ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  663. ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  664. ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  665. ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  666. ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  667. ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  668. ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  669. ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  670. ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  671. ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  672. ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  673. ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  674. ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  675. ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  676. ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  677. ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  678. ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  679. ccxt/static_dependencies/starkware/__init__.py +0 -0
  680. ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  681. ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
  682. ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
  683. ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
  684. ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
  685. ccxt/static_dependencies/sympy/__init__.py +0 -0
  686. ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  687. ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
  688. ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  689. ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  690. ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  691. ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  692. ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  693. ccxt/static_dependencies/toolz/__init__.py +26 -0
  694. ccxt/static_dependencies/toolz/_signatures.py +784 -0
  695. ccxt/static_dependencies/toolz/_version.py +520 -0
  696. ccxt/static_dependencies/toolz/compatibility.py +30 -0
  697. ccxt/static_dependencies/toolz/curried/__init__.py +101 -0
  698. ccxt/static_dependencies/toolz/curried/exceptions.py +22 -0
  699. ccxt/static_dependencies/toolz/curried/operator.py +22 -0
  700. ccxt/static_dependencies/toolz/dicttoolz.py +339 -0
  701. ccxt/static_dependencies/toolz/functoolz.py +1049 -0
  702. ccxt/static_dependencies/toolz/itertoolz.py +1057 -0
  703. ccxt/static_dependencies/toolz/recipes.py +46 -0
  704. ccxt/static_dependencies/toolz/utils.py +9 -0
  705. ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  706. ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  707. ccxt/tabdeal.py +364 -0
  708. ccxt/test/__init__.py +3 -0
  709. ccxt/test/base/__init__.py +29 -0
  710. ccxt/test/base/test_account.py +26 -0
  711. ccxt/test/base/test_balance.py +56 -0
  712. ccxt/test/base/test_borrow_interest.py +35 -0
  713. ccxt/test/base/test_borrow_rate.py +32 -0
  714. ccxt/test/base/test_calculate_fee.py +51 -0
  715. ccxt/test/base/test_crypto.py +127 -0
  716. ccxt/test/base/test_currency.py +76 -0
  717. ccxt/test/base/test_datetime.py +109 -0
  718. ccxt/test/base/test_decimal_to_precision.py +392 -0
  719. ccxt/test/base/test_deep_extend.py +68 -0
  720. ccxt/test/base/test_deposit_withdrawal.py +50 -0
  721. ccxt/test/base/test_exchange_datetime_functions.py +76 -0
  722. ccxt/test/base/test_funding_rate_history.py +29 -0
  723. ccxt/test/base/test_last_price.py +31 -0
  724. ccxt/test/base/test_ledger_entry.py +45 -0
  725. ccxt/test/base/test_ledger_item.py +48 -0
  726. ccxt/test/base/test_leverage_tier.py +33 -0
  727. ccxt/test/base/test_liquidation.py +50 -0
  728. ccxt/test/base/test_margin_mode.py +24 -0
  729. ccxt/test/base/test_margin_modification.py +35 -0
  730. ccxt/test/base/test_market.py +193 -0
  731. ccxt/test/base/test_number.py +411 -0
  732. ccxt/test/base/test_ohlcv.py +33 -0
  733. ccxt/test/base/test_open_interest.py +32 -0
  734. ccxt/test/base/test_order.py +64 -0
  735. ccxt/test/base/test_order_book.py +69 -0
  736. ccxt/test/base/test_position.py +60 -0
  737. ccxt/test/base/test_shared_methods.py +353 -0
  738. ccxt/test/base/test_status.py +24 -0
  739. ccxt/test/base/test_throttle.py +126 -0
  740. ccxt/test/base/test_ticker.py +92 -0
  741. ccxt/test/base/test_trade.py +47 -0
  742. ccxt/test/base/test_trading_fee.py +26 -0
  743. ccxt/test/base/test_transaction.py +39 -0
  744. ccxt/test/test_async.py +1649 -0
  745. ccxt/test/test_sync.py +1648 -0
  746. ccxt/test/tests_async.py +1558 -0
  747. ccxt/test/tests_helpers.py +287 -0
  748. ccxt/test/tests_init.py +39 -0
  749. ccxt/test/tests_sync.py +1555 -0
  750. ccxt/tetherland.py +349 -0
  751. ccxt/timex.py +1593 -0
  752. ccxt/tokocrypto.py +2405 -0
  753. ccxt/tradeogre.py +608 -0
  754. ccxt/twox.py +326 -0
  755. ccxt/ubitex.py +409 -0
  756. ccxt/upbit.py +1833 -0
  757. ccxt/vertex.py +2922 -0
  758. ccxt/wallex.py +445 -0
  759. ccxt/wavesexchange.py +2472 -0
  760. ccxt/wazirx.py +1224 -0
  761. ccxt/whitebit.py +2469 -0
  762. ccxt/woo.py +3114 -0
  763. ccxt/woofipro.py +2533 -0
  764. ccxt/xt.py +4453 -0
  765. ccxt/yobit.py +1283 -0
  766. ccxt/zaif.py +725 -0
  767. ccxt/zonda.py +1828 -0
  768. ccxt_ir-4.3.46.0.1.dist-info/LICENSE.txt +21 -0
  769. ccxt_ir-4.3.46.0.1.dist-info/METADATA +655 -0
  770. ccxt_ir-4.3.46.0.1.dist-info/RECORD +772 -0
  771. ccxt_ir-4.3.46.0.1.dist-info/WHEEL +6 -0
  772. ccxt_ir-4.3.46.0.1.dist-info/top_level.txt +1 -0
ccxt/pro/bingx.py ADDED
@@ -0,0 +1,1264 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
+ # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
+
6
+ import ccxt.async_support
7
+ from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp
8
+ from ccxt.base.types import Balances, Int, Order, OrderBook, Str, Strings, Ticker, Tickers, Trade
9
+ from ccxt.async_support.base.ws.client import Client
10
+ from typing import List
11
+ from ccxt.base.errors import ArgumentsRequired
12
+ from ccxt.base.errors import BadRequest
13
+ from ccxt.base.errors import NotSupported
14
+ from ccxt.base.errors import NetworkError
15
+ from ccxt.base.precise import Precise
16
+
17
+
18
+ class bingx(ccxt.async_support.bingx):
19
+
20
+ def describe(self):
21
+ return self.deep_extend(super(bingx, self).describe(), {
22
+ 'has': {
23
+ 'ws': True,
24
+ 'watchTrades': True,
25
+ 'watchOrderBook': True,
26
+ 'watchOrderBookForSymbols': True,
27
+ 'watchOHLCV': True,
28
+ 'watchOHLCVForSymbols': True,
29
+ 'watchOrders': True,
30
+ 'watchMyTrades': True,
31
+ 'watchTicker': True,
32
+ 'watchTickers': True,
33
+ 'watchBalance': True,
34
+ },
35
+ 'urls': {
36
+ 'api': {
37
+ 'ws': {
38
+ 'spot': 'wss://open-api-ws.bingx.com/market',
39
+ 'swap': 'wss://open-api-swap.bingx.com/swap-market',
40
+ },
41
+ },
42
+ },
43
+ 'options': {
44
+ 'listenKeyRefreshRate': 3540000, # 1 hour(59 mins so we have 1min to renew the token)
45
+ 'ws': {
46
+ 'gunzip': True,
47
+ },
48
+ 'swap': {
49
+ 'timeframes': {
50
+ '1m': '1m',
51
+ '3m': '3m',
52
+ '5m': '5m',
53
+ '15m': '15m',
54
+ '30m': '30m',
55
+ '1h': '1h',
56
+ '2h': '2h',
57
+ '4h': '4h',
58
+ '6h': '6h',
59
+ '12h': '12h',
60
+ '1d': '1d',
61
+ '3d': '3d',
62
+ '1w': '1w',
63
+ '1M': '1M',
64
+ },
65
+ },
66
+ 'spot': {
67
+ 'timeframes': {
68
+ '1m': '1min',
69
+ '5m': '5min',
70
+ '15m': '15min',
71
+ '30m': '30min',
72
+ '1h': '60min',
73
+ '1d': '1day',
74
+ },
75
+ },
76
+ 'watchBalance': {
77
+ 'fetchBalanceSnapshot': True, # needed to be True to keep track of used and free balance
78
+ 'awaitBalanceSnapshot': False, # whether to wait for the balance snapshot before providing updates
79
+ },
80
+ 'watchOrderBook': {
81
+ 'depth': 100, # 5, 10, 20, 50, 100
82
+ 'interval': 500, # 100, 200, 500, 1000
83
+ },
84
+ 'watchOrderBookForSymbols': {
85
+ 'depth': 100, # 5, 10, 20, 50, 100
86
+ 'interval': 500, # 100, 200, 500, 1000
87
+ },
88
+ },
89
+ 'streaming': {
90
+ 'keepAlive': 1800000, # 30 minutes
91
+ },
92
+ })
93
+
94
+ async def watch_ticker(self, symbol: str, params={}) -> Ticker:
95
+ """
96
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
97
+ :see: https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20to%2024-hour%20price%20changes
98
+ :param str symbol: unified symbol of the market to fetch the ticker for
99
+ :param dict [params]: extra parameters specific to the exchange API endpoint
100
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
101
+ """
102
+ await self.load_markets()
103
+ market = self.market(symbol)
104
+ marketType, query = self.handle_market_type_and_params('watchTrades', market, params)
105
+ url = self.safe_value(self.urls['api']['ws'], marketType)
106
+ if url is None:
107
+ raise BadRequest(self.id + ' watchTrades is not supported for ' + marketType + ' markets.')
108
+ subscriptionHash = market['id'] + '@ticker'
109
+ messageHash = self.get_message_hash('ticker', market['symbol'])
110
+ uuid = self.uuid()
111
+ request: dict = {
112
+ 'id': uuid,
113
+ 'dataType': subscriptionHash,
114
+ }
115
+ if marketType == 'swap':
116
+ request['reqType'] = 'sub'
117
+ return await self.watch(url, messageHash, self.extend(request, query), subscriptionHash)
118
+
119
+ def handle_ticker(self, client: Client, message):
120
+ #
121
+ # swap
122
+ #
123
+ # {
124
+ # "code": 0,
125
+ # "dataType": "BTC-USDT@ticker",
126
+ # "data": {
127
+ # "e": "24hTicker",
128
+ # "E": 1706498923556,
129
+ # "s": "BTC-USDT",
130
+ # "p": "346.4",
131
+ # "P": "0.82",
132
+ # "c": "42432.5",
133
+ # "L": "0.0529",
134
+ # "h": "42855.4",
135
+ # "l": "41578.3",
136
+ # "v": "64310.9754",
137
+ # "q": "2728360284.15",
138
+ # "o": "42086.1",
139
+ # "O": 1706498922655,
140
+ # "C": 1706498883023,
141
+ # "A": "42437.8",
142
+ # "a": "1.4160",
143
+ # "B": "42437.1",
144
+ # "b": "2.5747"
145
+ # }
146
+ # }
147
+ #
148
+ # spot
149
+ #
150
+ # {
151
+ # "code": 0,
152
+ # "timestamp": 1706506795473,
153
+ # "data": {
154
+ # "e": "24hTicker",
155
+ # "E": 1706506795472,
156
+ # "s": "BTC-USDT",
157
+ # "p": -372.12,
158
+ # "P": "-0.87%",
159
+ # "o": 42548.95,
160
+ # "h": 42696.1,
161
+ # "l": 41621.29,
162
+ # "c": 42176.83,
163
+ # "v": 4943.33,
164
+ # "q": 208842236.5,
165
+ # "O": 1706420395472,
166
+ # "C": 1706506795472,
167
+ # "A": 42177.23,
168
+ # "a": 5.14484,
169
+ # "B": 42176.38,
170
+ # "b": 5.36117
171
+ # }
172
+ # }
173
+ #
174
+ data = self.safe_value(message, 'data', {})
175
+ marketId = self.safe_string(data, 's')
176
+ # marketId = messageHash.split('@')[0]
177
+ isSwap = client.url.find('swap') >= 0
178
+ marketType = 'swap' if isSwap else 'spot'
179
+ market = self.safe_market(marketId, None, None, marketType)
180
+ symbol = market['symbol']
181
+ ticker = self.parse_ws_ticker(data, market)
182
+ self.tickers[symbol] = ticker
183
+ client.resolve(ticker, self.get_message_hash('ticker', symbol))
184
+ if self.safe_string(message, 'dataType') == 'all@ticker':
185
+ client.resolve(ticker, self.get_message_hash('ticker'))
186
+
187
+ def parse_ws_ticker(self, message, market=None):
188
+ #
189
+ # {
190
+ # "e": "24hTicker",
191
+ # "E": 1706498923556,
192
+ # "s": "BTC-USDT",
193
+ # "p": "346.4",
194
+ # "P": "0.82",
195
+ # "c": "42432.5",
196
+ # "L": "0.0529",
197
+ # "h": "42855.4",
198
+ # "l": "41578.3",
199
+ # "v": "64310.9754",
200
+ # "q": "2728360284.15",
201
+ # "o": "42086.1",
202
+ # "O": 1706498922655,
203
+ # "C": 1706498883023,
204
+ # "A": "42437.8",
205
+ # "a": "1.4160",
206
+ # "B": "42437.1",
207
+ # "b": "2.5747"
208
+ # }
209
+ #
210
+ timestamp = self.safe_integer(message, 'C')
211
+ marketId = self.safe_string(message, 's')
212
+ market = self.safe_market(marketId, market)
213
+ close = self.safe_string(message, 'c')
214
+ return self.safe_ticker({
215
+ 'symbol': market['symbol'],
216
+ 'timestamp': timestamp,
217
+ 'datetime': self.iso8601(timestamp),
218
+ 'high': self.safe_string(message, 'h'),
219
+ 'low': self.safe_string(message, 'l'),
220
+ 'bid': self.safe_string(message, 'B'),
221
+ 'bidVolume': self.safe_string(message, 'b'),
222
+ 'ask': self.safe_string(message, 'A'),
223
+ 'askVolume': self.safe_string(message, 'a'),
224
+ 'vwap': None,
225
+ 'open': self.safe_string(message, 'o'),
226
+ 'close': close,
227
+ 'last': close,
228
+ 'previousClose': None,
229
+ 'change': self.safe_string(message, 'p'),
230
+ 'percentage': None,
231
+ 'average': None,
232
+ 'baseVolume': self.safe_string(message, 'v'),
233
+ 'quoteVolume': self.safe_string(message, 'q'),
234
+ 'info': message,
235
+ }, market)
236
+
237
+ async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
238
+ """
239
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
240
+ :see: https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20to%2024-hour%20price%20changes%20of%20all%20trading%20pairs
241
+ :param str[] symbols: unified symbol of the market to watch the tickers for
242
+ :param dict [params]: extra parameters specific to the exchange API endpoint
243
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
244
+ """
245
+ await self.load_markets()
246
+ symbols = self.market_symbols(symbols, None, True, True, False)
247
+ firstMarket = None
248
+ marketType = None
249
+ symbolsDefined = (symbols is not None)
250
+ if symbolsDefined:
251
+ firstMarket = self.market(symbols[0])
252
+ marketType, params = self.handle_market_type_and_params('watchTickers', firstMarket, params)
253
+ if marketType == 'spot':
254
+ raise NotSupported(self.id + ' watchTickers is not supported for spot markets yet')
255
+ messageHashes = []
256
+ subscriptionHashes = ['all@ticker']
257
+ if symbolsDefined:
258
+ for i in range(0, len(symbols)):
259
+ symbol = symbols[i]
260
+ market = self.market(symbol)
261
+ messageHashes.append(self.get_message_hash('ticker', market['symbol']))
262
+ else:
263
+ messageHashes.append(self.get_message_hash('ticker'))
264
+ url = self.safe_string(self.urls['api']['ws'], marketType)
265
+ uuid = self.uuid()
266
+ request: dict = {
267
+ 'id': uuid,
268
+ 'dataType': 'all@ticker',
269
+ }
270
+ if marketType == 'swap':
271
+ request['reqType'] = 'sub'
272
+ result = await self.watch_multiple(url, messageHashes, self.deep_extend(request, params), subscriptionHashes)
273
+ if self.newUpdates:
274
+ newDict: dict = {}
275
+ newDict[result['symbol']] = result
276
+ return newDict
277
+ return self.tickers
278
+
279
+ async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
280
+ """
281
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
282
+ :see: https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20Market%20Depth%20Data%20of%20all%20trading%20pairs
283
+ :param str[] symbols: unified array of symbols
284
+ :param int [limit]: the maximum amount of order book entries to return
285
+ :param dict [params]: extra parameters specific to the exchange API endpoint
286
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
287
+ """
288
+ symbols = self.market_symbols(symbols, None, True, True, False)
289
+ firstMarket = None
290
+ marketType = None
291
+ symbolsDefined = (symbols is not None)
292
+ if symbolsDefined:
293
+ firstMarket = self.market(symbols[0])
294
+ marketType, params = self.handle_market_type_and_params('watchOrderBookForSymbols', firstMarket, params)
295
+ if marketType == 'spot':
296
+ raise NotSupported(self.id + ' watchOrderBookForSymbols is not supported for spot markets yet')
297
+ limit = self.get_order_book_limit_by_market_type(marketType, limit)
298
+ interval = None
299
+ interval, params = self.handle_option_and_params(params, 'watchOrderBookForSymbols', 'interval', 500)
300
+ self.check_required_argument('watchOrderBookForSymbols', interval, 'interval', [100, 200, 500, 1000])
301
+ channelName = 'depth' + str(limit) + '@' + str(interval) + 'ms'
302
+ subscriptionHash = 'all@' + channelName
303
+ messageHashes = []
304
+ if symbolsDefined:
305
+ for i in range(0, len(symbols)):
306
+ symbol = symbols[i]
307
+ market = self.market(symbol)
308
+ messageHashes.append(self.get_message_hash('orderbook', market['symbol']))
309
+ else:
310
+ messageHashes.append(self.get_message_hash('orderbook'))
311
+ url = self.safe_string(self.urls['api']['ws'], marketType)
312
+ uuid = self.uuid()
313
+ request: dict = {
314
+ 'id': uuid,
315
+ 'dataType': subscriptionHash,
316
+ }
317
+ if marketType == 'swap':
318
+ request['reqType'] = 'sub'
319
+ subscriptionArgs: dict = {
320
+ 'symbols': symbols,
321
+ 'limit': limit,
322
+ 'interval': interval,
323
+ 'params': params,
324
+ }
325
+ orderbook = await self.watch_multiple(url, messageHashes, self.deep_extend(request, params), [subscriptionHash], subscriptionArgs)
326
+ return orderbook.limit()
327
+
328
+ async def watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], since: Int = None, limit: Int = None, params={}):
329
+ """
330
+ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
331
+ :param str[][] symbolsAndTimeframes: array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
332
+ :param int [since]: timestamp in ms of the earliest candle to fetch
333
+ :param int [limit]: the maximum amount of candles to fetch
334
+ :param dict [params]: extra parameters specific to the exchange API endpoint
335
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
336
+ """
337
+ symbolsLength = len(symbolsAndTimeframes)
338
+ if symbolsLength != 0 and not isinstance(symbolsAndTimeframes[0], list):
339
+ raise ArgumentsRequired(self.id + " watchOHLCVForSymbols() requires a an array like [['BTC/USDT:USDT', '1m'], ['LTC/USDT:USDT', '5m']]")
340
+ await self.load_markets()
341
+ messageHashes = []
342
+ marketType = None
343
+ chosenTimeframe = None
344
+ if symbolsLength != 0:
345
+ symbols = self.get_list_from_object_values(symbolsAndTimeframes, 0)
346
+ symbols = self.market_symbols(symbols, None, True, True, False)
347
+ firstMarket = self.market(symbols[0])
348
+ marketType, params = self.handle_market_type_and_params('watchOrderBookForSymbols', firstMarket, params)
349
+ if marketType == 'spot':
350
+ raise NotSupported(self.id + ' watchOrderBookForSymbols is not supported for spot markets yet')
351
+ marketOptions = self.safe_dict(self.options, marketType)
352
+ timeframes = self.safe_dict(marketOptions, 'timeframes', {})
353
+ for i in range(0, len(symbolsAndTimeframes)):
354
+ symbolAndTimeframe = symbolsAndTimeframes[i]
355
+ sym = symbolAndTimeframe[0]
356
+ tf = symbolAndTimeframe[1]
357
+ market = self.market(sym)
358
+ rawTimeframe = self.safe_string(timeframes, tf, tf)
359
+ if chosenTimeframe is None:
360
+ chosenTimeframe = rawTimeframe
361
+ elif chosenTimeframe != rawTimeframe:
362
+ raise BadRequest(self.id + ' watchOHLCVForSymbols requires all timeframes to be the same')
363
+ messageHashes.append(self.get_message_hash('ohlcv', market['symbol'], chosenTimeframe))
364
+ subscriptionHash = 'all@kline_' + chosenTimeframe
365
+ url = self.safe_string(self.urls['api']['ws'], marketType)
366
+ uuid = self.uuid()
367
+ request: dict = {
368
+ 'id': uuid,
369
+ 'dataType': subscriptionHash,
370
+ }
371
+ if marketType == 'swap':
372
+ request['reqType'] = 'sub'
373
+ subscriptionArgs: dict = {
374
+ 'limit': limit,
375
+ 'params': params,
376
+ }
377
+ symbol, timeframe, candles = await self.watch_multiple(url, messageHashes, request, [subscriptionHash], subscriptionArgs)
378
+ if self.newUpdates:
379
+ limit = candles.getLimit(symbol, limit)
380
+ filtered = self.filter_by_since_limit(candles, since, limit, 0, True)
381
+ return self.create_ohlcv_object(symbol, timeframe, filtered)
382
+
383
+ def get_order_book_limit_by_market_type(self, marketType: str, limit: Int = None):
384
+ if limit is None:
385
+ limit = 100
386
+ else:
387
+ if marketType == 'swap' or marketType == 'future':
388
+ limit = self.find_nearest_ceiling([5, 10, 20, 50, 100], limit)
389
+ elif marketType == 'spot':
390
+ limit = self.find_nearest_ceiling([20, 100], limit)
391
+ return limit
392
+
393
+ def get_message_hash(self, unifiedChannel: str, symbol: Str = None, extra: Str = None):
394
+ hash = unifiedChannel
395
+ if symbol is not None:
396
+ hash += '::' + symbol
397
+ else:
398
+ hash += 's' # tickers, orderbooks, ohlcvs ...
399
+ if extra is not None:
400
+ hash += '::' + extra
401
+ return hash
402
+
403
+ async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
404
+ """
405
+ watches information on multiple trades made in a market
406
+ :see: https://bingx-api.github.io/docs/#/spot/socket/market.html#Subscribe%20to%20tick-by-tick
407
+ :see: https://bingx-api.github.io/docs/#/swapV2/socket/market.html#Subscribe%20the%20Latest%20Trade%20Detail
408
+ :param str symbol: unified market symbol of the market orders were made in
409
+ :param int [since]: the earliest time in ms to fetch orders for
410
+ :param int [limit]: the maximum number of order structures to retrieve
411
+ :param dict [params]: extra parameters specific to the exchange API endpoint
412
+ :returns dict[]: a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure
413
+ """
414
+ await self.load_markets()
415
+ market = self.market(symbol)
416
+ marketType, query = self.handle_market_type_and_params('watchTrades', market, params)
417
+ url = self.safe_value(self.urls['api']['ws'], marketType)
418
+ if url is None:
419
+ raise BadRequest(self.id + ' watchTrades is not supported for ' + marketType + ' markets.')
420
+ messageHash = market['id'] + '@trade'
421
+ uuid = self.uuid()
422
+ request: dict = {
423
+ 'id': uuid,
424
+ 'dataType': messageHash,
425
+ }
426
+ if marketType == 'swap':
427
+ request['reqType'] = 'sub'
428
+ trades = await self.watch(url, messageHash, self.extend(request, query), messageHash)
429
+ if self.newUpdates:
430
+ limit = trades.getLimit(symbol, limit)
431
+ return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
432
+
433
+ def handle_trades(self, client: Client, message):
434
+ #
435
+ # spot
436
+ # first snapshot
437
+ #
438
+ # {
439
+ # "id": "d83b78ce-98be-4dc2-b847-12fe471b5bc5",
440
+ # "code": 0,
441
+ # "msg": "SUCCESS",
442
+ # "timestamp": 1690214699854
443
+ # }
444
+ #
445
+ # subsequent updates
446
+ #
447
+ # {
448
+ # "code": 0,
449
+ # "data": {
450
+ # "E": 1690214529432,
451
+ # "T": 1690214529386,
452
+ # "e": "trade",
453
+ # "m": True,
454
+ # "p": "29110.19",
455
+ # "q": "0.1868",
456
+ # "s": "BTC-USDT",
457
+ # "t": "57903921"
458
+ # },
459
+ # "dataType": "BTC-USDT@trade",
460
+ # "success": True
461
+ # }
462
+ #
463
+ #
464
+ # swap
465
+ # first snapshot
466
+ #
467
+ # {
468
+ # "id": "2aed93b1-6e1e-4038-aeba-f5eeaec2ca48",
469
+ # "code": 0,
470
+ # "msg": '',
471
+ # "dataType": '',
472
+ # "data": null
473
+ # }
474
+ #
475
+ # subsequent updates
476
+ #
477
+ #
478
+ # {
479
+ # "code": 0,
480
+ # "dataType": "BTC-USDT@trade",
481
+ # "data": [
482
+ # {
483
+ # "q": "0.0421",
484
+ # "p": "29023.5",
485
+ # "T": 1690221401344,
486
+ # "m": False,
487
+ # "s": "BTC-USDT"
488
+ # },
489
+ # ...
490
+ # ]
491
+ # }
492
+ #
493
+ data = self.safe_value(message, 'data', [])
494
+ messageHash = self.safe_string(message, 'dataType')
495
+ marketId = messageHash.split('@')[0]
496
+ isSwap = client.url.find('swap') >= 0
497
+ marketType = 'swap' if isSwap else 'spot'
498
+ market = self.safe_market(marketId, None, None, marketType)
499
+ symbol = market['symbol']
500
+ trades = None
501
+ if isinstance(data, list):
502
+ trades = self.parse_trades(data, market)
503
+ else:
504
+ trades = [self.parse_trade(data, market)]
505
+ stored = self.safe_value(self.trades, symbol)
506
+ if stored is None:
507
+ limit = self.safe_integer(self.options, 'tradesLimit', 1000)
508
+ stored = ArrayCache(limit)
509
+ self.trades[symbol] = stored
510
+ for j in range(0, len(trades)):
511
+ stored.append(trades[j])
512
+ client.resolve(stored, messageHash)
513
+
514
+ async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
515
+ """
516
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
517
+ :see: https://bingx-api.github.io/docs/#/spot/socket/market.html#Subscribe%20Market%20Depth%20Data
518
+ :see: https://bingx-api.github.io/docs/#/swapV2/socket/market.html#Subscribe%20Market%20Depth%20Data
519
+ :param str symbol: unified symbol of the market to fetch the order book for
520
+ :param int [limit]: the maximum amount of order book entries to return
521
+ :param dict [params]: extra parameters specific to the exchange API endpoint
522
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
523
+ """
524
+ await self.load_markets()
525
+ market = self.market(symbol)
526
+ marketType, query = self.handle_market_type_and_params('watchOrderBook', market, params)
527
+ limit = self.get_order_book_limit_by_market_type(marketType, limit)
528
+ channelName = 'depth' + str(limit)
529
+ url = self.safe_value(self.urls['api']['ws'], marketType)
530
+ if url is None:
531
+ raise BadRequest(self.id + ' watchOrderBook is not supported for ' + marketType + ' markets.')
532
+ interval = None
533
+ if marketType != 'spot':
534
+ interval, params = self.handle_option_and_params(params, 'watchOrderBook', 'interval', 500)
535
+ self.check_required_argument('watchOrderBook', interval, 'interval', [100, 200, 500, 1000])
536
+ channelName = channelName + '@' + str(interval) + 'ms'
537
+ subscriptionHash = market['id'] + '@' + channelName
538
+ messageHash = self.get_message_hash('orderbook', market['symbol'])
539
+ uuid = self.uuid()
540
+ request: dict = {
541
+ 'id': uuid,
542
+ 'dataType': subscriptionHash,
543
+ }
544
+ if marketType == 'swap':
545
+ request['reqType'] = 'sub'
546
+ subscriptionArgs: dict = {
547
+ 'limit': limit,
548
+ 'interval': interval,
549
+ 'params': params,
550
+ }
551
+ orderbook = await self.watch(url, messageHash, self.deep_extend(request, query), subscriptionHash, subscriptionArgs)
552
+ return orderbook.limit()
553
+
554
+ def handle_delta(self, bookside, delta):
555
+ price = self.safe_float(delta, 0)
556
+ amount = self.safe_float(delta, 1)
557
+ bookside.store(price, amount)
558
+
559
+ def handle_order_book(self, client: Client, message):
560
+ #
561
+ # spot
562
+ #
563
+ #
564
+ # {
565
+ # "code": 0,
566
+ # "dataType": "BTC-USDT@depth20",
567
+ # "data": {
568
+ # "bids": [
569
+ # ['28852.9', "34.2621"],
570
+ # ...
571
+ # ],
572
+ # "asks": [
573
+ # ['28864.9', "23.4079"],
574
+ # ...
575
+ # ]
576
+ # },
577
+ # "dataType": "BTC-USDT@depth20",
578
+ # "success": True
579
+ # }
580
+ #
581
+ # swap
582
+ #
583
+ #
584
+ # {
585
+ # "code": 0,
586
+ # "dataType": "BTC-USDT@depth20@100ms", #or "all@depth20@100ms"
587
+ # "data": {
588
+ # "bids": [
589
+ # ['28852.9', "34.2621"],
590
+ # ...
591
+ # ],
592
+ # "asks": [
593
+ # ['28864.9', "23.4079"],
594
+ # ...
595
+ # ],
596
+ # "symbol": "BTC-USDT", # self key exists only in "all" subscription
597
+ # }
598
+ # }
599
+ #
600
+ data = self.safe_dict(message, 'data', {})
601
+ dataType = self.safe_string(message, 'dataType')
602
+ parts = dataType.split('@')
603
+ firstPart = parts[0]
604
+ isAllEndpoint = (firstPart == 'all')
605
+ marketId = self.safe_string(data, 'symbol', firstPart)
606
+ isSwap = client.url.find('swap') >= 0
607
+ marketType = 'swap' if isSwap else 'spot'
608
+ market = self.safe_market(marketId, None, None, marketType)
609
+ symbol = market['symbol']
610
+ if self.safe_value(self.orderbooks, symbol) is None:
611
+ # limit = [5, 10, 20, 50, 100]
612
+ subscriptionHash = dataType
613
+ subscription = client.subscriptions[subscriptionHash]
614
+ limit = self.safe_integer(subscription, 'limit')
615
+ self.orderbooks[symbol] = self.order_book({}, limit)
616
+ orderbook = self.orderbooks[symbol]
617
+ snapshot = self.parse_order_book(data, symbol, None, 'bids', 'asks', 0, 1)
618
+ orderbook.reset(snapshot)
619
+ self.orderbooks[symbol] = orderbook
620
+ messageHash = self.get_message_hash('orderbook', symbol)
621
+ client.resolve(orderbook, messageHash)
622
+ # resolve for "all"
623
+ if isAllEndpoint:
624
+ messageHashForAll = self.get_message_hash('orderbook')
625
+ client.resolve(orderbook, messageHashForAll)
626
+
627
+ def parse_ws_ohlcv(self, ohlcv, market=None) -> list:
628
+ #
629
+ # {
630
+ # "c": "28909.0",
631
+ # "o": "28915.4",
632
+ # "h": "28915.4",
633
+ # "l": "28896.1",
634
+ # "v": "27.6919",
635
+ # "T": 1696687499999,
636
+ # "t": 1696687440000
637
+ # }
638
+ #
639
+ # for spot, opening-time(t) is used instead of closing-time(T), to be compatible with fetchOHLCV
640
+ # for swap,(T) is the opening time
641
+ timestamp = 't' if (market['spot']) else 'T'
642
+ return [
643
+ self.safe_integer(ohlcv, timestamp),
644
+ self.safe_number(ohlcv, 'o'),
645
+ self.safe_number(ohlcv, 'h'),
646
+ self.safe_number(ohlcv, 'l'),
647
+ self.safe_number(ohlcv, 'c'),
648
+ self.safe_number(ohlcv, 'v'),
649
+ ]
650
+
651
+ def handle_ohlcv(self, client: Client, message):
652
+ #
653
+ # spot
654
+ #
655
+ # {
656
+ # "code": 0,
657
+ # "data": {
658
+ # "E": 1696687498608,
659
+ # "K": {
660
+ # "T": 1696687499999,
661
+ # "c": "27917.829",
662
+ # "h": "27918.427",
663
+ # "i": "1min",
664
+ # "l": "27917.7",
665
+ # "n": 262,
666
+ # "o": "27917.91",
667
+ # "q": "25715.359197",
668
+ # "s": "BTC-USDT",
669
+ # "t": 1696687440000,
670
+ # "v": "0.921100"
671
+ # },
672
+ # "e": "kline",
673
+ # "s": "BTC-USDT"
674
+ # },
675
+ # "dataType": "BTC-USDT@kline_1min",
676
+ # "success": True
677
+ # }
678
+ #
679
+ # swap
680
+ # {
681
+ # "code": 0,
682
+ # "dataType": "BTC-USDT@kline_1m",
683
+ # "s": "BTC-USDT",
684
+ # "data": [
685
+ # {
686
+ # "c": "28909.0",
687
+ # "o": "28915.4",
688
+ # "h": "28915.4",
689
+ # "l": "28896.1",
690
+ # "v": "27.6919",
691
+ # "T": 1690907580000
692
+ # }
693
+ # ]
694
+ # }
695
+ #
696
+ data = self.safe_list(message, 'data', [])
697
+ candles = None
698
+ if isinstance(data, list):
699
+ candles = data
700
+ else:
701
+ candles = [self.safe_list(data, 'K', [])]
702
+ dataType = self.safe_string(message, 'dataType')
703
+ isSwap = client.url.find('swap') >= 0
704
+ parts = dataType.split('@')
705
+ firstPart = parts[0]
706
+ isAllEndpoint = (firstPart == 'all')
707
+ marketId = self.safe_string(message, 's', firstPart)
708
+ marketType = 'swap' if isSwap else 'spot'
709
+ market = self.safe_market(marketId, None, None, marketType)
710
+ symbol = market['symbol']
711
+ self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
712
+ rawTimeframe = dataType.split('_')[1]
713
+ marketOptions = self.safe_dict(self.options, marketType)
714
+ timeframes = self.safe_dict(marketOptions, 'timeframes', {})
715
+ unifiedTimeframe = self.find_timeframe(rawTimeframe, timeframes)
716
+ if self.safe_value(self.ohlcvs[symbol], rawTimeframe) is None:
717
+ subscriptionHash = dataType
718
+ subscription = client.subscriptions[subscriptionHash]
719
+ limit = self.safe_integer(subscription, 'limit')
720
+ self.ohlcvs[symbol][unifiedTimeframe] = ArrayCacheByTimestamp(limit)
721
+ stored = self.ohlcvs[symbol][unifiedTimeframe]
722
+ for i in range(0, len(candles)):
723
+ candle = candles[i]
724
+ parsed = self.parse_ws_ohlcv(candle, market)
725
+ stored.append(parsed)
726
+ resolveData = [symbol, unifiedTimeframe, stored]
727
+ messageHash = self.get_message_hash('ohlcv', symbol, unifiedTimeframe)
728
+ client.resolve(resolveData, messageHash)
729
+ # resolve for "all"
730
+ if isAllEndpoint:
731
+ messageHashForAll = self.get_message_hash('ohlcv', None, unifiedTimeframe)
732
+ client.resolve(resolveData, messageHashForAll)
733
+
734
+ async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
735
+ """
736
+ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
737
+ :see: https://bingx-api.github.io/docs/#/spot/socket/market.html#K%E7%BA%BF%20Streams
738
+ :see: https://bingx-api.github.io/docs/#/swapV2/socket/market.html#Subscribe%20K-Line%20Data
739
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
740
+ :param str timeframe: the length of time each candle represents
741
+ :param int [since]: timestamp in ms of the earliest candle to fetch
742
+ :param int [limit]: the maximum amount of candles to fetch
743
+ :param dict [params]: extra parameters specific to the exchange API endpoint
744
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
745
+ """
746
+ await self.load_markets()
747
+ market = self.market(symbol)
748
+ marketType, query = self.handle_market_type_and_params('watchOHLCV', market, params)
749
+ url = self.safe_value(self.urls['api']['ws'], marketType)
750
+ if url is None:
751
+ raise BadRequest(self.id + ' watchOHLCV is not supported for ' + marketType + ' markets.')
752
+ options = self.safe_value(self.options, marketType, {})
753
+ timeframes = self.safe_value(options, 'timeframes', {})
754
+ rawTimeframe = self.safe_string(timeframes, timeframe, timeframe)
755
+ messageHash = self.get_message_hash('ohlcv', market['symbol'], timeframe)
756
+ subscriptionHash = market['id'] + '@kline_' + rawTimeframe
757
+ uuid = self.uuid()
758
+ request: dict = {
759
+ 'id': uuid,
760
+ 'dataType': subscriptionHash,
761
+ }
762
+ if marketType == 'swap':
763
+ request['reqType'] = 'sub'
764
+ subscriptionArgs: dict = {
765
+ 'limit': limit,
766
+ 'params': params,
767
+ }
768
+ result = await self.watch(url, messageHash, self.extend(request, query), subscriptionHash, subscriptionArgs)
769
+ ohlcv = result[2]
770
+ if self.newUpdates:
771
+ limit = ohlcv.getLimit(symbol, limit)
772
+ return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
773
+
774
+ async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
775
+ """
776
+ :see: https://bingx-api.github.io/docs/#/spot/socket/account.html#Subscription%20order%20update%20data
777
+ :see: https://bingx-api.github.io/docs/#/swapV2/socket/account.html#Account%20balance%20and%20position%20update%20push
778
+ watches information on multiple orders made by the user
779
+ :param str symbol: unified market symbol of the market orders were made in
780
+ :param int [since]: the earliest time in ms to fetch orders for
781
+ :param int [limit]: the maximum number of order structures to retrieve
782
+ :param dict [params]: extra parameters specific to the exchange API endpoint
783
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
784
+ """
785
+ await self.load_markets()
786
+ await self.authenticate()
787
+ type = None
788
+ market = None
789
+ if symbol is not None:
790
+ market = self.market(symbol)
791
+ symbol = market['symbol']
792
+ type, params = self.handle_market_type_and_params('watchOrders', market, params)
793
+ isSpot = (type == 'spot')
794
+ spotHash = 'spot:private'
795
+ swapHash = 'swap:private'
796
+ subscriptionHash = spotHash if isSpot else swapHash
797
+ spotMessageHash = 'spot:order'
798
+ swapMessageHash = 'swap:order'
799
+ messageHash = spotMessageHash if isSpot else swapMessageHash
800
+ if market is not None:
801
+ messageHash += ':' + symbol
802
+ url = self.urls['api']['ws'][type] + '?listenKey=' + self.options['listenKey']
803
+ request = None
804
+ uuid = self.uuid()
805
+ if isSpot:
806
+ request = {
807
+ 'id': uuid,
808
+ 'dataType': 'spot.executionReport',
809
+ }
810
+ orders = await self.watch(url, messageHash, request, subscriptionHash)
811
+ if self.newUpdates:
812
+ limit = orders.getLimit(symbol, limit)
813
+ return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
814
+
815
+ async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
816
+ """
817
+ :see: https://bingx-api.github.io/docs/#/spot/socket/account.html#Subscription%20order%20update%20data
818
+ :see: https://bingx-api.github.io/docs/#/swapV2/socket/account.html#Account%20balance%20and%20position%20update%20push
819
+ watches information on multiple trades made by the user
820
+ :param str symbol: unified market symbol of the market trades were made in
821
+ :param int [since]: the earliest time in ms to trades orders for
822
+ :param int [limit]: the maximum number of trades structures to retrieve
823
+ :param dict [params]: extra parameters specific to the exchange API endpoint
824
+ :returns dict[]: a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
825
+ """
826
+ await self.load_markets()
827
+ await self.authenticate()
828
+ type = None
829
+ market = None
830
+ if symbol is not None:
831
+ market = self.market(symbol)
832
+ symbol = market['symbol']
833
+ type, params = self.handle_market_type_and_params('watchOrders', market, params)
834
+ isSpot = (type == 'spot')
835
+ spotSubHash = 'spot:private'
836
+ swapSubHash = 'swap:private'
837
+ subscriptionHash = spotSubHash if isSpot else swapSubHash
838
+ spotMessageHash = 'spot:mytrades'
839
+ swapMessageHash = 'swap:mytrades'
840
+ messageHash = spotMessageHash if isSpot else swapMessageHash
841
+ if market is not None:
842
+ messageHash += ':' + symbol
843
+ url = self.urls['api']['ws'][type] + '?listenKey=' + self.options['listenKey']
844
+ request = None
845
+ uuid = self.uuid()
846
+ if isSpot:
847
+ request = {
848
+ 'id': uuid,
849
+ 'dataType': 'spot.executionReport',
850
+ }
851
+ trades = await self.watch(url, messageHash, request, subscriptionHash)
852
+ if self.newUpdates:
853
+ limit = trades.getLimit(symbol, limit)
854
+ return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
855
+
856
+ async def watch_balance(self, params={}) -> Balances:
857
+ """
858
+ :see: https://bingx-api.github.io/docs/#/spot/socket/account.html#Subscription%20order%20update%20data
859
+ :see: https://bingx-api.github.io/docs/#/swapV2/socket/account.html#Account%20balance%20and%20position%20update%20push
860
+ query for balance and get the amount of funds available for trading or funds locked in orders
861
+ :param dict [params]: extra parameters specific to the exchange API endpoint
862
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
863
+ """
864
+ await self.load_markets()
865
+ await self.authenticate()
866
+ type = None
867
+ type, params = self.handle_market_type_and_params('watchBalance', None, params)
868
+ isSpot = (type == 'spot')
869
+ spotSubHash = 'spot:balance'
870
+ swapSubHash = 'swap:private'
871
+ spotMessageHash = 'spot:balance'
872
+ swapMessageHash = 'swap:balance'
873
+ messageHash = spotMessageHash if isSpot else swapMessageHash
874
+ subscriptionHash = spotSubHash if isSpot else swapSubHash
875
+ url = self.urls['api']['ws'][type] + '?listenKey=' + self.options['listenKey']
876
+ request = None
877
+ uuid = self.uuid()
878
+ if type == 'spot':
879
+ request = {
880
+ 'id': uuid,
881
+ 'dataType': 'ACCOUNT_UPDATE',
882
+ }
883
+ client = self.client(url)
884
+ self.set_balance_cache(client, type, subscriptionHash, params)
885
+ fetchBalanceSnapshot = None
886
+ awaitBalanceSnapshot = None
887
+ fetchBalanceSnapshot, params = self.handle_option_and_params(params, 'watchBalance', 'fetchBalanceSnapshot', True)
888
+ awaitBalanceSnapshot, params = self.handle_option_and_params(params, 'watchBalance', 'awaitBalanceSnapshot', False)
889
+ if fetchBalanceSnapshot and awaitBalanceSnapshot:
890
+ await client.future(type + ':fetchBalanceSnapshot')
891
+ return await self.watch(url, messageHash, request, subscriptionHash)
892
+
893
+ def set_balance_cache(self, client: Client, type, subscriptionHash, params):
894
+ if subscriptionHash in client.subscriptions:
895
+ return
896
+ fetchBalanceSnapshot = self.handle_option_and_params(params, 'watchBalance', 'fetchBalanceSnapshot', True)
897
+ if fetchBalanceSnapshot:
898
+ messageHash = type + ':fetchBalanceSnapshot'
899
+ if not (messageHash in client.futures):
900
+ client.future(messageHash)
901
+ self.spawn(self.load_balance_snapshot, client, messageHash, type)
902
+ else:
903
+ self.balance[type] = {}
904
+
905
+ async def load_balance_snapshot(self, client, messageHash, type):
906
+ response = await self.fetch_balance({'type': type})
907
+ self.balance[type] = self.extend(response, self.safe_value(self.balance, type, {}))
908
+ # don't remove the future from the .futures cache
909
+ future = client.futures[messageHash]
910
+ future.resolve()
911
+ client.resolve(self.balance[type], type + ':balance')
912
+
913
+ def handle_error_message(self, client, message):
914
+ #
915
+ # {code: 100400, msg: '', timestamp: 1696245808833}
916
+ #
917
+ # {
918
+ # "code": 100500,
919
+ # "id": "9cd37d32-da98-440b-bd04-37e7dbcf51ad",
920
+ # "msg": '',
921
+ # "timestamp": 1696245842307
922
+ # }
923
+ code = self.safe_string(message, 'code')
924
+ try:
925
+ if code is not None:
926
+ feedback = self.id + ' ' + self.json(message)
927
+ self.throw_exactly_matched_exception(self.exceptions['exact'], code, feedback)
928
+ except Exception as e:
929
+ client.reject(e)
930
+ return True
931
+
932
+ async def keep_alive_listen_key(self, params={}):
933
+ listenKey = self.safe_string(self.options, 'listenKey')
934
+ if listenKey is None:
935
+ # A network error happened: we can't renew a listen key that does not exist.
936
+ return
937
+ try:
938
+ await self.userAuthPrivatePutUserDataStream({'listenKey': listenKey}) # self.extend the expiry
939
+ except Exception as error:
940
+ types = ['spot', 'swap']
941
+ for i in range(0, len(types)):
942
+ type = types[i]
943
+ url = self.urls['api']['ws'][type] + '?listenKey=' + listenKey
944
+ client = self.client(url)
945
+ messageHashes = list(client.futures.keys())
946
+ for j in range(0, len(messageHashes)):
947
+ messageHash = messageHashes[j]
948
+ client.reject(error, messageHash)
949
+ self.options['listenKey'] = None
950
+ self.options['lastAuthenticatedTime'] = 0
951
+ return
952
+ # whether or not to schedule another listenKey keepAlive request
953
+ listenKeyRefreshRate = self.safe_integer(self.options, 'listenKeyRefreshRate', 3600000)
954
+ self.delay(listenKeyRefreshRate, self.keep_alive_listen_key, params)
955
+
956
+ async def authenticate(self, params={}):
957
+ time = self.milliseconds()
958
+ lastAuthenticatedTime = self.safe_integer(self.options, 'lastAuthenticatedTime', 0)
959
+ listenKeyRefreshRate = self.safe_integer(self.options, 'listenKeyRefreshRate', 3600000) # 1 hour
960
+ if time - lastAuthenticatedTime > listenKeyRefreshRate:
961
+ response = await self.userAuthPrivatePostUserDataStream()
962
+ self.options['listenKey'] = self.safe_string(response, 'listenKey')
963
+ self.options['lastAuthenticatedTime'] = time
964
+ self.delay(listenKeyRefreshRate, self.keep_alive_listen_key, params)
965
+
966
+ async def pong(self, client, message):
967
+ #
968
+ # spot
969
+ # {
970
+ # "ping": "5963ba3db76049b2870f9a686b2ebaac",
971
+ # "time": "2023-10-02T18:51:55.089+0800"
972
+ # }
973
+ # swap
974
+ # Ping
975
+ #
976
+ try:
977
+ if message == 'Ping':
978
+ await client.send('Pong')
979
+ else:
980
+ ping = self.safe_string(message, 'ping')
981
+ time = self.safe_string(message, 'time')
982
+ await client.send({
983
+ 'pong': ping,
984
+ 'time': time,
985
+ })
986
+ except Exception as e:
987
+ error = NetworkError(self.id + ' pong failed with error ' + self.json(e))
988
+ client.reset(error)
989
+
990
+ def handle_order(self, client, message):
991
+ #
992
+ # {
993
+ # "code": 0,
994
+ # "dataType": "spot.executionReport",
995
+ # "data": {
996
+ # "e": "executionReport",
997
+ # "E": 1694680212947,
998
+ # "s": "LTC-USDT",
999
+ # "S": "BUY",
1000
+ # "o": "LIMIT",
1001
+ # "q": 0.1,
1002
+ # "p": 50,
1003
+ # "x": "NEW",
1004
+ # "X": "PENDING",
1005
+ # "i": 1702238305204043800,
1006
+ # "l": 0,
1007
+ # "z": 0,
1008
+ # "L": 0,
1009
+ # "n": 0,
1010
+ # "N": "",
1011
+ # "T": 0,
1012
+ # "t": 0,
1013
+ # "O": 1694680212676,
1014
+ # "Z": 0,
1015
+ # "Y": 0,
1016
+ # "Q": 0,
1017
+ # "m": False
1018
+ # }
1019
+ # }
1020
+ #
1021
+ # {
1022
+ # "code": 0,
1023
+ # "dataType": "spot.executionReport",
1024
+ # "data": {
1025
+ # "e": "executionReport",
1026
+ # "E": 1694681809302,
1027
+ # "s": "LTC-USDT",
1028
+ # "S": "BUY",
1029
+ # "o": "MARKET",
1030
+ # "q": 0,
1031
+ # "p": 62.29,
1032
+ # "x": "TRADE",
1033
+ # "X": "FILLED",
1034
+ # "i": "1702245001712369664",
1035
+ # "l": 0.0802,
1036
+ # "z": 0.0802,
1037
+ # "L": 62.308,
1038
+ # "n": -0.0000802,
1039
+ # "N": "LTC",
1040
+ # "T": 1694681809256,
1041
+ # "t": 38259147,
1042
+ # "O": 1694681809248,
1043
+ # "Z": 4.9971016,
1044
+ # "Y": 4.9971016,
1045
+ # "Q": 5,
1046
+ # "m": False
1047
+ # }
1048
+ # }
1049
+ # swap
1050
+ # {
1051
+ # "e": "ORDER_TRADE_UPDATE",
1052
+ # "E": 1696843635475,
1053
+ # "o": {
1054
+ # "s": "LTC-USDT",
1055
+ # "c": "",
1056
+ # "i": "1711312357852147712",
1057
+ # "S": "BUY",
1058
+ # "o": "MARKET",
1059
+ # "q": "0.10000000",
1060
+ # "p": "64.35010000",
1061
+ # "ap": "64.36000000",
1062
+ # "x": "TRADE",
1063
+ # "X": "FILLED",
1064
+ # "N": "USDT",
1065
+ # "n": "-0.00321800",
1066
+ # "T": 0,
1067
+ # "wt": "MARK_PRICE",
1068
+ # "ps": "LONG",
1069
+ # "rp": "0.00000000",
1070
+ # "z": "0.10000000"
1071
+ # }
1072
+ # }
1073
+ #
1074
+ isSpot = ('dataType' in message)
1075
+ data = self.safe_value_2(message, 'data', 'o', {})
1076
+ if self.orders is None:
1077
+ limit = self.safe_integer(self.options, 'ordersLimit', 1000)
1078
+ self.orders = ArrayCacheBySymbolById(limit)
1079
+ stored = self.orders
1080
+ parsedOrder = self.parse_order(data)
1081
+ stored.append(parsedOrder)
1082
+ symbol = parsedOrder['symbol']
1083
+ spotHash = 'spot:order'
1084
+ swapHash = 'swap:order'
1085
+ messageHash = spotHash if (isSpot) else swapHash
1086
+ client.resolve(stored, messageHash)
1087
+ client.resolve(stored, messageHash + ':' + symbol)
1088
+
1089
+ def handle_my_trades(self, client: Client, message):
1090
+ #
1091
+ #
1092
+ # {
1093
+ # "code": 0,
1094
+ # "dataType": "spot.executionReport",
1095
+ # "data": {
1096
+ # "e": "executionReport",
1097
+ # "E": 1694681809302,
1098
+ # "s": "LTC-USDT",
1099
+ # "S": "BUY",
1100
+ # "o": "MARKET",
1101
+ # "q": 0,
1102
+ # "p": 62.29,
1103
+ # "x": "TRADE",
1104
+ # "X": "FILLED",
1105
+ # "i": "1702245001712369664",
1106
+ # "l": 0.0802,
1107
+ # "z": 0.0802,
1108
+ # "L": 62.308,
1109
+ # "n": -0.0000802,
1110
+ # "N": "LTC",
1111
+ # "T": 1694681809256,
1112
+ # "t": 38259147,
1113
+ # "O": 1694681809248,
1114
+ # "Z": 4.9971016,
1115
+ # "Y": 4.9971016,
1116
+ # "Q": 5,
1117
+ # "m": False
1118
+ # }
1119
+ # }
1120
+ #
1121
+ # swap
1122
+ # {
1123
+ # "e": "ORDER_TRADE_UPDATE",
1124
+ # "E": 1696843635475,
1125
+ # "o": {
1126
+ # "s": "LTC-USDT",
1127
+ # "c": "",
1128
+ # "i": "1711312357852147712",
1129
+ # "S": "BUY",
1130
+ # "o": "MARKET",
1131
+ # "q": "0.10000000",
1132
+ # "p": "64.35010000",
1133
+ # "ap": "64.36000000",
1134
+ # "x": "TRADE",
1135
+ # "X": "FILLED",
1136
+ # "N": "USDT",
1137
+ # "n": "-0.00321800",
1138
+ # "T": 0,
1139
+ # "wt": "MARK_PRICE",
1140
+ # "ps": "LONG",
1141
+ # "rp": "0.00000000",
1142
+ # "z": "0.10000000"
1143
+ # }
1144
+ # }
1145
+ #
1146
+ isSpot = ('dataType' in message)
1147
+ result = self.safe_dict_2(message, 'data', 'o', {})
1148
+ cachedTrades = self.myTrades
1149
+ if cachedTrades is None:
1150
+ limit = self.safe_integer(self.options, 'tradesLimit', 1000)
1151
+ cachedTrades = ArrayCacheBySymbolById(limit)
1152
+ self.myTrades = cachedTrades
1153
+ type = 'spot' if isSpot else 'swap'
1154
+ marketId = self.safe_string(result, 's')
1155
+ market = self.safe_market(marketId, None, '-', type)
1156
+ parsed = self.parse_trade(result, market)
1157
+ symbol = parsed['symbol']
1158
+ spotHash = 'spot:mytrades'
1159
+ swapHash = 'swap:mytrades'
1160
+ messageHash = spotHash if isSpot else swapHash
1161
+ cachedTrades.append(parsed)
1162
+ client.resolve(cachedTrades, messageHash)
1163
+ client.resolve(cachedTrades, messageHash + ':' + symbol)
1164
+
1165
+ def handle_balance(self, client: Client, message):
1166
+ # spot
1167
+ # {
1168
+ # "e":"ACCOUNT_UPDATE",
1169
+ # "E":1696242817000,
1170
+ # "T":1696242817142,
1171
+ # "a":{
1172
+ # "B":[
1173
+ # {
1174
+ # "a":"USDT",
1175
+ # "bc":"-1.00000000000000000000",
1176
+ # "cw":"86.59497382000000050000",
1177
+ # "wb":"86.59497382000000050000"
1178
+ # }
1179
+ # ],
1180
+ # "m":"ASSET_TRANSFER"
1181
+ # }
1182
+ # }
1183
+ # swap
1184
+ # {
1185
+ # "e":"ACCOUNT_UPDATE",
1186
+ # "E":1696244249320,
1187
+ # "a":{
1188
+ # "m":"WITHDRAW",
1189
+ # "B":[
1190
+ # {
1191
+ # "a":"USDT",
1192
+ # "wb":"49.81083984",
1193
+ # "cw":"49.81083984",
1194
+ # "bc":"-1.00000000"
1195
+ # }
1196
+ # ],
1197
+ # "P":[
1198
+ # ]
1199
+ # }
1200
+ # }
1201
+ #
1202
+ a = self.safe_dict(message, 'a', {})
1203
+ data = self.safe_list(a, 'B', [])
1204
+ timestamp = self.safe_integer_2(message, 'T', 'E')
1205
+ type = 'swap' if ('P' in a) else 'spot'
1206
+ if not (type in self.balance):
1207
+ self.balance[type] = {}
1208
+ self.balance[type]['info'] = data
1209
+ self.balance[type]['timestamp'] = timestamp
1210
+ self.balance[type]['datetime'] = self.iso8601(timestamp)
1211
+ for i in range(0, len(data)):
1212
+ balance = data[i]
1213
+ currencyId = self.safe_string(balance, 'a')
1214
+ code = self.safe_currency_code(currencyId)
1215
+ account = self.balance[type][code] if (code in self.balance[type]) else self.account()
1216
+ account['free'] = self.safe_string(balance, 'wb')
1217
+ balanceChange = self.safe_string(balance, 'bc')
1218
+ if account['used'] is not None:
1219
+ account['used'] = Precise.string_sub(self.safe_string(account, 'used'), balanceChange)
1220
+ self.balance[type][code] = account
1221
+ self.balance[type] = self.safe_balance(self.balance[type])
1222
+ client.resolve(self.balance[type], type + ':balance')
1223
+
1224
+ def handle_message(self, client: Client, message):
1225
+ if not self.handle_error_message(client, message):
1226
+ return
1227
+ # public subscriptions
1228
+ if (message == 'Ping') or ('ping' in message):
1229
+ self.spawn(self.pong, client, message)
1230
+ return
1231
+ dataType = self.safe_string(message, 'dataType', '')
1232
+ if dataType.find('@depth') >= 0:
1233
+ self.handle_order_book(client, message)
1234
+ return
1235
+ if dataType.find('@ticker') >= 0:
1236
+ self.handle_ticker(client, message)
1237
+ return
1238
+ if dataType.find('@trade') >= 0:
1239
+ self.handle_trades(client, message)
1240
+ return
1241
+ if dataType.find('@kline') >= 0:
1242
+ self.handle_ohlcv(client, message)
1243
+ return
1244
+ if dataType.find('executionReport') >= 0:
1245
+ data = self.safe_value(message, 'data', {})
1246
+ type = self.safe_string(data, 'x')
1247
+ if type == 'TRADE':
1248
+ self.handle_my_trades(client, message)
1249
+ self.handle_order(client, message)
1250
+ return
1251
+ e = self.safe_string(message, 'e')
1252
+ if e == 'ACCOUNT_UPDATE':
1253
+ self.handle_balance(client, message)
1254
+ if e == 'ORDER_TRADE_UPDATE':
1255
+ self.handle_order(client, message)
1256
+ data = self.safe_value(message, 'o', {})
1257
+ type = self.safe_string(data, 'x')
1258
+ status = self.safe_string(data, 'X')
1259
+ if (type == 'TRADE') and (status == 'FILLED'):
1260
+ self.handle_my_trades(client, message)
1261
+ msgData = self.safe_value(message, 'data')
1262
+ msgEvent = self.safe_string(msgData, 'e')
1263
+ if msgEvent == '24hTicker':
1264
+ self.handle_ticker(client, message)