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/hitbtc.py ADDED
@@ -0,0 +1,1216 @@
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
+ import hashlib
9
+ from ccxt.base.types import Balances, Int, Num, Order, OrderBook, OrderSide, OrderType, 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 AuthenticationError
14
+ from ccxt.base.errors import NotSupported
15
+
16
+
17
+ class hitbtc(ccxt.async_support.hitbtc):
18
+
19
+ def describe(self):
20
+ return self.deep_extend(super(hitbtc, self).describe(), {
21
+ 'has': {
22
+ 'ws': True,
23
+ 'watchTicker': True,
24
+ 'watchTickers': True,
25
+ 'watchTrades': True,
26
+ 'watchOrderBook': True,
27
+ 'watchBalance': True,
28
+ 'watchOrders': True,
29
+ 'watchOHLCV': True,
30
+ 'watchMyTrades': False,
31
+ 'createOrderWs': True,
32
+ 'cancelOrderWs': True,
33
+ 'fetchOpenOrdersWs': True,
34
+ 'cancelAllOrdersWs': True,
35
+ },
36
+ 'urls': {
37
+ 'api': {
38
+ 'ws': {
39
+ 'public': 'wss://api.hitbtc.com/api/3/ws/public',
40
+ 'private': 'wss://api.hitbtc.com/api/3/ws/trading',
41
+ },
42
+ },
43
+ 'test': {
44
+ 'ws': {
45
+ 'public': 'wss://api.demo.hitbtc.com/api/3/ws/public',
46
+ 'private': 'wss://api.demo.hitbtc.com/api/3/ws/trading',
47
+ },
48
+ },
49
+ },
50
+ 'options': {
51
+ 'tradesLimit': 1000,
52
+ 'watchTicker': {
53
+ 'method': 'ticker/{speed}', # 'ticker/{speed}' or 'ticker/price/{speed}'
54
+ },
55
+ 'watchTickers': {
56
+ 'method': 'ticker/{speed}', # 'ticker/{speed}','ticker/price/{speed}', 'ticker/{speed}/batch', or 'ticker/{speed}/price/batch''
57
+ },
58
+ 'watchOrderBook': {
59
+ 'method': 'orderbook/full', # 'orderbook/full', 'orderbook/{depth}/{speed}', 'orderbook/{depth}/{speed}/batch', 'orderbook/top/{speed}', or 'orderbook/top/{speed}/batch'
60
+ },
61
+ },
62
+ 'timeframes': {
63
+ '1m': 'M1',
64
+ '3m': 'M3',
65
+ '5m': 'M5',
66
+ '15m': 'M15',
67
+ '30m': 'M30',
68
+ '1h': 'H1',
69
+ '4h': 'H4',
70
+ '1d': 'D1',
71
+ '1w': 'D7',
72
+ '1M': '1M',
73
+ },
74
+ 'streaming': {
75
+ 'keepAlive': 4000,
76
+ },
77
+ })
78
+
79
+ async def authenticate(self):
80
+ """
81
+ * @ignore
82
+ authenticates the user to access private web socket channels
83
+ :see: https://api.hitbtc.com/#socket-authentication
84
+ :returns dict: response from exchange
85
+ """
86
+ self.check_required_credentials()
87
+ url = self.urls['api']['ws']['private']
88
+ messageHash = 'authenticated'
89
+ client = self.client(url)
90
+ future = client.future(messageHash)
91
+ authenticated = self.safe_value(client.subscriptions, messageHash)
92
+ if authenticated is None:
93
+ timestamp = self.milliseconds()
94
+ signature = self.hmac(self.encode(self.number_to_string(timestamp)), self.encode(self.secret), hashlib.sha256, 'hex')
95
+ request: dict = {
96
+ 'method': 'login',
97
+ 'params': {
98
+ 'type': 'HS256',
99
+ 'api_key': self.apiKey,
100
+ 'timestamp': timestamp,
101
+ 'signature': signature,
102
+ },
103
+ }
104
+ self.watch(url, messageHash, request, messageHash)
105
+ #
106
+ # {
107
+ # "jsonrpc": "2.0",
108
+ # "result": True
109
+ # }
110
+ #
111
+ # # Failure to return results
112
+ #
113
+ # {
114
+ # "jsonrpc": "2.0",
115
+ # "error": {
116
+ # "code": 1002,
117
+ # "message": "Authorization is required or has been failed",
118
+ # "description": "invalid signature format"
119
+ # }
120
+ # }
121
+ #
122
+ return await future
123
+
124
+ async def subscribe_public(self, name: str, messageHashPrefix: str, symbols: Strings = None, params={}):
125
+ """
126
+ * @ignore
127
+ :param str name: websocket endpoint name
128
+ :param str[] [symbols]: unified CCXT symbol(s)
129
+ :param dict [params]: extra parameters specific to the hitbtc api
130
+ """
131
+ await self.load_markets()
132
+ url = self.urls['api']['ws']['public']
133
+ messageHash = messageHashPrefix
134
+ if symbols is not None:
135
+ messageHash = messageHash + '::' + ','.join(symbols)
136
+ subscribe: dict = {
137
+ 'method': 'subscribe',
138
+ 'id': self.nonce(),
139
+ 'ch': name,
140
+ }
141
+ request = self.extend(subscribe, params)
142
+ return await self.watch(url, messageHash, request, messageHash)
143
+
144
+ async def subscribe_private(self, name: str, symbol: Str = None, params={}):
145
+ """
146
+ * @ignore
147
+ :param str name: websocket endpoint name
148
+ :param str [symbol]: unified CCXT symbol
149
+ :param dict [params]: extra parameters specific to the hitbtc api
150
+ """
151
+ await self.load_markets()
152
+ await self.authenticate()
153
+ url = self.urls['api']['ws']['private']
154
+ splitName = name.split('_subscribe')
155
+ messageHash = self.safe_string(splitName, 0)
156
+ if symbol is not None:
157
+ messageHash = messageHash + '::' + symbol
158
+ subscribe: dict = {
159
+ 'method': name,
160
+ 'params': params,
161
+ 'id': self.nonce(),
162
+ }
163
+ return await self.watch(url, messageHash, subscribe, messageHash)
164
+
165
+ async def trade_request(self, name: str, params={}):
166
+ """
167
+ * @ignore
168
+ :param str name: websocket endpoint name
169
+ :param str [symbol]: unified CCXT symbol
170
+ :param dict [params]: extra parameters specific to the hitbtc api
171
+ """
172
+ await self.load_markets()
173
+ await self.authenticate()
174
+ url = self.urls['api']['ws']['private']
175
+ messageHash = str(self.nonce())
176
+ subscribe: dict = {
177
+ 'method': name,
178
+ 'params': params,
179
+ 'id': messageHash,
180
+ }
181
+ return await self.watch(url, messageHash, subscribe, messageHash)
182
+
183
+ async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
184
+ """
185
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
186
+ :see: https://api.hitbtc.com/#subscribe-to-full-order-book
187
+ :see: https://api.hitbtc.com/#subscribe-to-partial-order-book
188
+ :see: https://api.hitbtc.com/#subscribe-to-partial-order-book-in-batches
189
+ :see: https://api.hitbtc.com/#subscribe-to-top-of-book
190
+ :see: https://api.hitbtc.com/#subscribe-to-top-of-book-in-batches
191
+ :param str symbol: unified symbol of the market to fetch the order book for
192
+ :param int [limit]: the maximum amount of order book entries to return
193
+ :param dict [params]: extra parameters specific to the exchange API endpoint
194
+ :param str [params.method]: 'orderbook/full', 'orderbook/{depth}/{speed}', 'orderbook/{depth}/{speed}/batch', 'orderbook/top/{speed}', or 'orderbook/top/{speed}/batch'
195
+ :param int [params.depth]: 5 , 10, or 20(default)
196
+ :param int [params.speed]: 100(default), 500, or 1000
197
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
198
+ """
199
+ options = self.safe_value(self.options, 'watchOrderBook')
200
+ defaultMethod = self.safe_string(options, 'method', 'orderbook/full')
201
+ name = self.safe_string_2(params, 'method', 'defaultMethod', defaultMethod)
202
+ depth = self.safe_string(params, 'depth', '20')
203
+ speed = self.safe_string(params, 'depth', '100')
204
+ if name == 'orderbook/{depth}/{speed}':
205
+ name = 'orderbook/D' + depth + '/' + speed + 'ms'
206
+ elif name == 'orderbook/{depth}/{speed}/batch':
207
+ name = 'orderbook/D' + depth + '/' + speed + 'ms/batch'
208
+ elif name == 'orderbook/top/{speed}':
209
+ name = 'orderbook/top/' + speed + 'ms'
210
+ elif name == 'orderbook/top/{speed}/batch':
211
+ name = 'orderbook/top/' + speed + 'ms/batch'
212
+ market = self.market(symbol)
213
+ request: dict = {
214
+ 'params': {
215
+ 'symbols': [market['id']],
216
+ },
217
+ }
218
+ orderbook = await self.subscribe_public(name, 'orderbooks', [symbol], self.deep_extend(request, params))
219
+ return orderbook.limit()
220
+
221
+ def handle_order_book(self, client: Client, message):
222
+ #
223
+ # {
224
+ # "ch": "orderbook/full", # Channel
225
+ # "snapshot": {
226
+ # "ETHBTC": {
227
+ # "t": 1626866578796, # Timestamp in milliseconds
228
+ # "s": 27617207, # Sequence number
229
+ # "a": [ # Asks
230
+ # ["0.060506", "0"],
231
+ # ["0.060549", "12.6431"],
232
+ # ["0.060570", "0"],
233
+ # ["0.060612", "0"]
234
+ # ],
235
+ # "b": [ # Bids
236
+ # ["0.060439", "4.4095"],
237
+ # ["0.060414", "0"],
238
+ # ["0.060407", "7.3349"],
239
+ # ["0.060390", "0"]
240
+ # ]
241
+ # }
242
+ # }
243
+ # }
244
+ #
245
+ snapshot = self.safe_dict(message, 'snapshot')
246
+ update = self.safe_dict(message, 'update')
247
+ data = snapshot if snapshot else update
248
+ type = 'snapshot' if snapshot else 'update'
249
+ marketIds = list(data.keys())
250
+ for i in range(0, len(marketIds)):
251
+ marketId = marketIds[i]
252
+ market = self.safe_market(marketId)
253
+ symbol = market['symbol']
254
+ item = data[marketId]
255
+ messageHash = 'orderbooks::' + symbol
256
+ if not (symbol in self.orderbooks):
257
+ subscription = self.safe_dict(client.subscriptions, messageHash, {})
258
+ limit = self.safe_integer(subscription, 'limit')
259
+ self.orderbooks[symbol] = self.order_book({}, limit)
260
+ orderbook = self.orderbooks[symbol]
261
+ timestamp = self.safe_integer(item, 't')
262
+ nonce = self.safe_integer(item, 's')
263
+ if type == 'snapshot':
264
+ parsedSnapshot = self.parse_order_book(item, symbol, timestamp, 'b', 'a')
265
+ orderbook.reset(parsedSnapshot)
266
+ else:
267
+ asks = self.safe_list(item, 'a', [])
268
+ bids = self.safe_list(item, 'b', [])
269
+ self.handle_deltas(orderbook['asks'], asks)
270
+ self.handle_deltas(orderbook['bids'], bids)
271
+ orderbook['timestamp'] = timestamp
272
+ orderbook['datetime'] = self.iso8601(timestamp)
273
+ orderbook['nonce'] = nonce
274
+ orderbook['symbol'] = symbol
275
+ self.orderbooks[symbol] = orderbook
276
+ client.resolve(orderbook, messageHash)
277
+
278
+ def handle_delta(self, bookside, delta):
279
+ price = self.safe_number(delta, 0)
280
+ amount = self.safe_number(delta, 1)
281
+ bookside.store(price, amount)
282
+
283
+ def handle_deltas(self, bookside, deltas):
284
+ for i in range(0, len(deltas)):
285
+ self.handle_delta(bookside, deltas[i])
286
+
287
+ async def watch_ticker(self, symbol: str, params={}) -> Ticker:
288
+ """
289
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
290
+ :see: https://api.hitbtc.com/#subscribe-to-ticker
291
+ :see: https://api.hitbtc.com/#subscribe-to-ticker-in-batches
292
+ :see: https://api.hitbtc.com/#subscribe-to-mini-ticker
293
+ :see: https://api.hitbtc.com/#subscribe-to-mini-ticker-in-batches
294
+ :param str symbol: unified symbol of the market to fetch the ticker for
295
+ :param dict [params]: extra parameters specific to the exchange API endpoint
296
+ :param str [params.method]: 'ticker/{speed}'(default), or 'ticker/price/{speed}'
297
+ :param str [params.speed]: '1s'(default), or '3s'
298
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
299
+ """
300
+ options = self.safe_value(self.options, 'watchTicker')
301
+ defaultMethod = self.safe_string(options, 'method', 'ticker/{speed}')
302
+ method = self.safe_string_2(params, 'method', 'defaultMethod', defaultMethod)
303
+ speed = self.safe_string(params, 'speed', '1s')
304
+ name = self.implode_params(method, {'speed': speed})
305
+ params = self.omit(params, ['method', 'speed'])
306
+ market = self.market(symbol)
307
+ request: dict = {
308
+ 'params': {
309
+ 'symbols': [market['id']],
310
+ },
311
+ }
312
+ result = await self.subscribe_public(name, 'tickers', [symbol], self.deep_extend(request, params))
313
+ return self.safe_value(result, symbol)
314
+
315
+ async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
316
+ """
317
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
318
+ :param str symbol: unified symbol of the market to fetch the ticker for
319
+ :param dict params: extra parameters specific to the exchange API endpoint
320
+ :param str params['method']: 'ticker/{speed}'(default),'ticker/price/{speed}', 'ticker/{speed}/batch', or 'ticker/{speed}/price/batch''
321
+ :param str params['speed']: '1s'(default), or '3s'
322
+ :returns dict: a `ticker structure <https://docs.ccxt.com/en/latest/manual.html#ticker-structure>`
323
+ """
324
+ await self.load_markets()
325
+ options = self.safe_value(self.options, 'watchTicker')
326
+ defaultMethod = self.safe_string(options, 'method', 'ticker/{speed}')
327
+ method = self.safe_string_2(params, 'method', 'defaultMethod', defaultMethod)
328
+ speed = self.safe_string(params, 'speed', '1s')
329
+ name = self.implode_params(method, {'speed': speed})
330
+ params = self.omit(params, ['method', 'speed'])
331
+ marketIds = []
332
+ if symbols is None:
333
+ marketIds.append('*')
334
+ else:
335
+ for i in range(0, len(symbols)):
336
+ marketId = self.market_id(symbols[i])
337
+ marketIds.append(marketId)
338
+ request: dict = {
339
+ 'params': {
340
+ 'symbols': marketIds,
341
+ },
342
+ }
343
+ tickers = await self.subscribe_public(name, 'tickers', symbols, self.deep_extend(request, params))
344
+ if self.newUpdates:
345
+ return tickers
346
+ return self.filter_by_array(self.tickers, 'symbol', symbols)
347
+
348
+ def handle_ticker(self, client: Client, message):
349
+ #
350
+ # {
351
+ # "ch": "ticker/1s",
352
+ # "data": {
353
+ # "ETHBTC": {
354
+ # "t": 1614815872000, # Timestamp in milliseconds
355
+ # "a": "0.031175", # Best ask
356
+ # "A": "0.03329", # Best ask quantity
357
+ # "b": "0.031148", # Best bid
358
+ # "B": "0.10565", # Best bid quantity
359
+ # "c": "0.031210", # Last price
360
+ # "o": "0.030781", # Open price
361
+ # "h": "0.031788", # High price
362
+ # "l": "0.030733", # Low price
363
+ # "v": "62.587", # Base asset volume
364
+ # "q": "1.951420577", # Quote asset volume
365
+ # "p": "0.000429", # Price change
366
+ # "P": "1.39", # Price change percent
367
+ # "L": 1182694927 # Last trade identifier
368
+ # }
369
+ # }
370
+ # }
371
+ #
372
+ # {
373
+ # "ch": "ticker/price/1s",
374
+ # "data": {
375
+ # "BTCUSDT": {
376
+ # "t": 1614815872030,
377
+ # "o": "32636.79",
378
+ # "c": "32085.51",
379
+ # "h": "33379.92",
380
+ # "l": "30683.28",
381
+ # "v": "11.90667",
382
+ # "q": "384081.1955629"
383
+ # }
384
+ # }
385
+ # }
386
+ #
387
+ data = self.safe_value(message, 'data', {})
388
+ marketIds = list(data.keys())
389
+ newTickers: dict = {}
390
+ for i in range(0, len(marketIds)):
391
+ marketId = marketIds[i]
392
+ market = self.safe_market(marketId)
393
+ symbol = market['symbol']
394
+ ticker = self.parse_ws_ticker(data[marketId], market)
395
+ self.tickers[symbol] = ticker
396
+ newTickers[symbol] = ticker
397
+ client.resolve(newTickers, 'tickers')
398
+ messageHashes = self.find_message_hashes(client, 'tickers::')
399
+ for i in range(0, len(messageHashes)):
400
+ messageHash = messageHashes[i]
401
+ parts = messageHash.split('::')
402
+ symbolsString = parts[1]
403
+ symbols = symbolsString.split(',')
404
+ tickers = self.filter_by_array(newTickers, 'symbol', symbols)
405
+ tickersSymbols = list(tickers.keys())
406
+ numTickers = len(tickersSymbols)
407
+ if numTickers > 0:
408
+ client.resolve(tickers, messageHash)
409
+ return message
410
+
411
+ def parse_ws_ticker(self, ticker, market=None):
412
+ #
413
+ # {
414
+ # "t": 1614815872000, # Timestamp in milliseconds
415
+ # "a": "0.031175", # Best ask
416
+ # "A": "0.03329", # Best ask quantity
417
+ # "b": "0.031148", # Best bid
418
+ # "B": "0.10565", # Best bid quantity
419
+ # "c": "0.031210", # Last price
420
+ # "o": "0.030781", # Open price
421
+ # "h": "0.031788", # High price
422
+ # "l": "0.030733", # Low price
423
+ # "v": "62.587", # Base asset volume
424
+ # "q": "1.951420577", # Quote asset volume
425
+ # "p": "0.000429", # Price change
426
+ # "P": "1.39", # Price change percent
427
+ # "L": 1182694927 # Last trade identifier
428
+ # }
429
+ #
430
+ # {
431
+ # "t": 1614815872030,
432
+ # "o": "32636.79",
433
+ # "c": "32085.51",
434
+ # "h": "33379.92",
435
+ # "l": "30683.28",
436
+ # "v": "11.90667",
437
+ # "q": "384081.1955629"
438
+ # }
439
+ #
440
+ timestamp = self.safe_integer(ticker, 't')
441
+ symbol = self.safe_symbol(None, market)
442
+ last = self.safe_string(ticker, 'c')
443
+ return self.safe_ticker({
444
+ 'symbol': symbol,
445
+ 'timestamp': timestamp,
446
+ 'datetime': self.iso8601(timestamp),
447
+ 'high': self.safe_string(ticker, 'h'),
448
+ 'low': self.safe_string(ticker, 'l'),
449
+ 'bid': self.safe_string(ticker, 'b'),
450
+ 'bidVolume': self.safe_string(ticker, 'B'),
451
+ 'ask': self.safe_string(ticker, 'a'),
452
+ 'askVolume': self.safe_string(ticker, 'A'),
453
+ 'vwap': None,
454
+ 'open': self.safe_string(ticker, 'o'),
455
+ 'close': last,
456
+ 'last': last,
457
+ 'previousClose': None,
458
+ 'change': None,
459
+ 'percentage': None,
460
+ 'average': None,
461
+ 'baseVolume': self.safe_string(ticker, 'v'),
462
+ 'quoteVolume': self.safe_string(ticker, 'q'),
463
+ 'info': ticker,
464
+ }, market)
465
+
466
+ async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
467
+ """
468
+ get the list of most recent trades for a particular symbol
469
+ :see: https://api.hitbtc.com/#subscribe-to-trades
470
+ :param str symbol: unified symbol of the market to fetch trades for
471
+ :param int [since]: timestamp in ms of the earliest trade to fetch
472
+ :param int [limit]: the maximum amount of trades to fetch
473
+ :param dict [params]: extra parameters specific to the exchange API endpoint
474
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
475
+ """
476
+ await self.load_markets()
477
+ market = self.market(symbol)
478
+ request: dict = {
479
+ 'params': {
480
+ 'symbols': [market['id']],
481
+ },
482
+ }
483
+ if limit is not None:
484
+ request['limit'] = limit
485
+ name = 'trades'
486
+ trades = await self.subscribe_public(name, 'trades', [symbol], self.deep_extend(request, params))
487
+ if self.newUpdates:
488
+ limit = trades.getLimit(symbol, limit)
489
+ return self.filter_by_since_limit(trades, since, limit, 'timestamp')
490
+
491
+ def handle_trades(self, client: Client, message):
492
+ #
493
+ # {
494
+ # "result": {
495
+ # "ch": "trades", # Channel
496
+ # "subscriptions": ["ETHBTC", "BTCUSDT"]
497
+ # },
498
+ # "id": 123
499
+ # }
500
+ #
501
+ # Notification snapshot
502
+ #
503
+ # {
504
+ # "ch": "trades", # Channel
505
+ # "snapshot": {
506
+ # "BTCUSDT": [{
507
+ # "t": 1626861109494, # Timestamp in milliseconds
508
+ # "i": 1555634969, # Trade identifier
509
+ # "p": "30881.96", # Price
510
+ # "q": "12.66828", # Quantity
511
+ # "s": "buy" # Side
512
+ # }]
513
+ # }
514
+ # }
515
+ #
516
+ # Notification update
517
+ #
518
+ # {
519
+ # "ch": "trades",
520
+ # "update": {
521
+ # "BTCUSDT": [{
522
+ # "t": 1626861123552,
523
+ # "i": 1555634969,
524
+ # "p": "30877.68",
525
+ # "q": "0.00006",
526
+ # "s": "sell"
527
+ # }]
528
+ # }
529
+ # }
530
+ #
531
+ data = self.safe_value_2(message, 'snapshot', 'update', {})
532
+ marketIds = list(data.keys())
533
+ for i in range(0, len(marketIds)):
534
+ marketId = marketIds[i]
535
+ market = self.safe_market(marketId)
536
+ tradesLimit = self.safe_integer(self.options, 'tradesLimit', 1000)
537
+ symbol = market['symbol']
538
+ stored = self.safe_value(self.trades, symbol)
539
+ if stored is None:
540
+ stored = ArrayCache(tradesLimit)
541
+ self.trades[symbol] = stored
542
+ trades = self.parse_ws_trades(data[marketId], market)
543
+ for j in range(0, len(trades)):
544
+ stored.append(trades[j])
545
+ messageHash = 'trades::' + symbol
546
+ client.resolve(stored, messageHash)
547
+ return message
548
+
549
+ def parse_ws_trades(self, trades, market: object = None, since: Int = None, limit: Int = None, params={}):
550
+ trades = self.to_array(trades)
551
+ result = []
552
+ for i in range(0, len(trades)):
553
+ trade = self.extend(self.parse_ws_trade(trades[i], market), params)
554
+ result.append(trade)
555
+ result = self.sort_by_2(result, 'timestamp', 'id')
556
+ symbol = self.safe_string(market, 'symbol')
557
+ return self.filter_by_symbol_since_limit(result, symbol, since, limit)
558
+
559
+ def parse_ws_trade(self, trade, market=None):
560
+ #
561
+ # {
562
+ # "t": 1626861123552, # Timestamp in milliseconds
563
+ # "i": 1555634969, # Trade identifier
564
+ # "p": "30877.68", # Price
565
+ # "q": "0.00006", # Quantity
566
+ # "s": "sell" # Side
567
+ # }
568
+ #
569
+ timestamp = self.safe_integer(trade, 't')
570
+ return self.safe_trade({
571
+ 'info': trade,
572
+ 'id': self.safe_string(trade, 'i'),
573
+ 'order': None,
574
+ 'timestamp': timestamp,
575
+ 'datetime': self.iso8601(timestamp),
576
+ 'symbol': self.safe_string(market, 'symbol'),
577
+ 'type': None,
578
+ 'side': self.safe_string(trade, 's'),
579
+ 'takerOrMaker': None,
580
+ 'price': self.safe_string(trade, 'p'),
581
+ 'amount': self.safe_string(trade, 'q'),
582
+ 'cost': None,
583
+ 'fee': None,
584
+ }, market)
585
+
586
+ async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
587
+ """
588
+ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
589
+ :see: https://api.hitbtc.com/#subscribe-to-candles
590
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
591
+ :param str [timeframe]: the length of time each candle represents
592
+ :param int [since]: not used by hitbtc watchOHLCV
593
+ :param int [limit]: 0 – 1000, default value = 0(no history returned)
594
+ :param dict [params]: extra parameters specific to the exchange API endpoint
595
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
596
+ """
597
+ period = self.safe_string(self.timeframes, timeframe, timeframe)
598
+ name = 'candles/' + period
599
+ market = self.market(symbol)
600
+ request: dict = {
601
+ 'params': {
602
+ 'symbols': [market['id']],
603
+ },
604
+ }
605
+ if limit is not None:
606
+ request['params']['limit'] = limit
607
+ ohlcv = await self.subscribe_public(name, 'candles', [symbol], self.deep_extend(request, params))
608
+ if self.newUpdates:
609
+ limit = ohlcv.getLimit(symbol, limit)
610
+ return self.filter_by_since_limit(ohlcv, since, limit, 0)
611
+
612
+ def handle_ohlcv(self, client: Client, message):
613
+ #
614
+ # {
615
+ # "ch": "candles/M1", # Channel
616
+ # "snapshot": {
617
+ # "BTCUSDT": [{
618
+ # "t": 1626860340000, # Message timestamp
619
+ # "o": "30881.95", # Open price
620
+ # "c": "30890.96", # Last price
621
+ # "h": "30900.8", # High price
622
+ # "l": "30861.27", # Low price
623
+ # "v": "1.27852", # Base asset volume
624
+ # "q": "39493.9021811" # Quote asset volume
625
+ # }
626
+ # ...
627
+ # ]
628
+ # }
629
+ # }
630
+ #
631
+ # {
632
+ # "ch": "candles/M1",
633
+ # "update": {
634
+ # "ETHBTC": [{
635
+ # "t": 1626860880000,
636
+ # "o": "0.060711",
637
+ # "c": "0.060749",
638
+ # "h": "0.060749",
639
+ # "l": "0.060711",
640
+ # "v": "12.2800",
641
+ # "q": "0.7455339675"
642
+ # }]
643
+ # }
644
+ # }
645
+ #
646
+ data = self.safe_value_2(message, 'snapshot', 'update', {})
647
+ marketIds = list(data.keys())
648
+ channel = self.safe_string(message, 'ch')
649
+ splitChannel = channel.split('/')
650
+ period = self.safe_string(splitChannel, 1)
651
+ timeframe = self.find_timeframe(period)
652
+ for i in range(0, len(marketIds)):
653
+ marketId = marketIds[i]
654
+ market = self.safe_market(marketId)
655
+ symbol = market['symbol']
656
+ self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
657
+ stored = self.safe_value(self.ohlcvs[symbol], timeframe)
658
+ if stored is None:
659
+ limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
660
+ stored = ArrayCacheByTimestamp(limit)
661
+ self.ohlcvs[symbol][timeframe] = stored
662
+ ohlcvs = self.parse_ws_ohlcvs(data[marketId], market)
663
+ for j in range(0, len(ohlcvs)):
664
+ stored.append(ohlcvs[j])
665
+ messageHash = 'candles::' + symbol
666
+ client.resolve(stored, messageHash)
667
+ return message
668
+
669
+ def parse_ws_ohlcv(self, ohlcv, market=None) -> list:
670
+ #
671
+ # {
672
+ # "t": 1626860340000, # Message timestamp
673
+ # "o": "30881.95", # Open price
674
+ # "c": "30890.96", # Last price
675
+ # "h": "30900.8", # High price
676
+ # "l": "30861.27", # Low price
677
+ # "v": "1.27852", # Base asset volume
678
+ # "q": "39493.9021811" # Quote asset volume
679
+ # }
680
+ #
681
+ return [
682
+ self.safe_integer(ohlcv, 't'),
683
+ self.safe_number(ohlcv, 'o'),
684
+ self.safe_number(ohlcv, 'h'),
685
+ self.safe_number(ohlcv, 'l'),
686
+ self.safe_number(ohlcv, 'c'),
687
+ self.safe_number(ohlcv, 'v'),
688
+ ]
689
+
690
+ async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
691
+ """
692
+ watches information on multiple orders made by the user
693
+ :see: https://api.hitbtc.com/#subscribe-to-reports
694
+ :see: https://api.hitbtc.com/#subscribe-to-reports-2
695
+ :see: https://api.hitbtc.com/#subscribe-to-reports-3
696
+ :param str [symbol]: unified CCXT market symbol
697
+ :param int [since]: timestamp in ms of the earliest order to fetch
698
+ :param int [limit]: the maximum amount of orders to fetch
699
+ :param dict [params]: extra parameters specific to the exchange API endpoint
700
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/en/latest/manual.html#order-structure>`
701
+ """
702
+ await self.load_markets()
703
+ marketType = None
704
+ market = None
705
+ if symbol is not None:
706
+ market = self.market(symbol)
707
+ marketType, params = self.handle_market_type_and_params('watchOrders', market, params)
708
+ name = self.get_supported_mapping(marketType, {
709
+ 'spot': 'spot_subscribe',
710
+ 'margin': 'margin_subscribe',
711
+ 'swap': 'futures_subscribe',
712
+ 'future': 'futures_subscribe',
713
+ })
714
+ orders = await self.subscribe_private(name, symbol, params)
715
+ if self.newUpdates:
716
+ limit = orders.getLimit(symbol, limit)
717
+ return self.filter_by_since_limit(orders, since, limit, 'timestamp')
718
+
719
+ def handle_order(self, client: Client, message):
720
+ #
721
+ # {
722
+ # "jsonrpc": "2.0",
723
+ # "method": "spot_order", # "margin_order", "future_order"
724
+ # "params": {
725
+ # "id": 584244931496,
726
+ # "client_order_id": "b5acd79c0a854b01b558665bcf379456",
727
+ # "symbol": "BTCUSDT",
728
+ # "side": "buy",
729
+ # "status": "new",
730
+ # "type": "limit",
731
+ # "time_in_force": "GTC",
732
+ # "quantity": "0.01000",
733
+ # "quantity_cumulative": "0",
734
+ # "price": "0.01", # only updates and snapshots
735
+ # "post_only": False,
736
+ # "reduce_only": False, # only margin and contract
737
+ # "display_quantity": "0", # only updates and snapshot
738
+ # "created_at": "2021-07-02T22:52:32.864Z",
739
+ # "updated_at": "2021-07-02T22:52:32.864Z",
740
+ # "trade_id": 1361977606, # only trades
741
+ # "trade_quantity": "0.00001", # only trades
742
+ # "trade_price": "49595.04", # only trades
743
+ # "trade_fee": "0.001239876000", # only trades
744
+ # "trade_taker": True, # only trades, only spot
745
+ # "trade_position_id": 485308, # only trades, only margin
746
+ # "report_type": "new" # "trade", "status"(snapshot)
747
+ # }
748
+ # }
749
+ #
750
+ # {
751
+ # "jsonrpc": "2.0",
752
+ # "method": "spot_orders", # "margin_orders", "future_orders"
753
+ # "params": [
754
+ # {
755
+ # "id": 584244931496,
756
+ # "client_order_id": "b5acd79c0a854b01b558665bcf379456",
757
+ # "symbol": "BTCUSDT",
758
+ # "side": "buy",
759
+ # "status": "new",
760
+ # "type": "limit",
761
+ # "time_in_force": "GTC",
762
+ # "quantity": "0.01000",
763
+ # "quantity_cumulative": "0",
764
+ # "price": "0.01", # only updates and snapshots
765
+ # "post_only": False,
766
+ # "reduce_only": False, # only margin and contract
767
+ # "display_quantity": "0", # only updates and snapshot
768
+ # "created_at": "2021-07-02T22:52:32.864Z",
769
+ # "updated_at": "2021-07-02T22:52:32.864Z",
770
+ # "trade_id": 1361977606, # only trades
771
+ # "trade_quantity": "0.00001", # only trades
772
+ # "trade_price": "49595.04", # only trades
773
+ # "trade_fee": "0.001239876000", # only trades
774
+ # "trade_taker": True, # only trades, only spot
775
+ # "trade_position_id": 485308, # only trades, only margin
776
+ # "report_type": "new" # "trade", "status"(snapshot)
777
+ # }
778
+ # ]
779
+ # }
780
+ #
781
+ if self.orders is None:
782
+ limit = self.safe_integer(self.options, 'ordersLimit')
783
+ self.orders = ArrayCacheBySymbolById(limit)
784
+ data = self.safe_value(message, 'params', [])
785
+ if isinstance(data, list):
786
+ for i in range(0, len(data)):
787
+ order = data[i]
788
+ self.handle_order_helper(client, message, order)
789
+ else:
790
+ self.handle_order_helper(client, message, data)
791
+ return message
792
+
793
+ def handle_order_helper(self, client: Client, message, order):
794
+ orders = self.orders
795
+ marketId = self.safe_string_lower_2(order, 'instrument', 'symbol')
796
+ method = self.safe_string(message, 'method')
797
+ splitMethod = method.split('_order')
798
+ messageHash = self.safe_string(splitMethod, 0)
799
+ symbol = self.safe_symbol(marketId)
800
+ parsed = self.parse_order(order)
801
+ orders.append(parsed)
802
+ client.resolve(orders, messageHash)
803
+ client.resolve(orders, messageHash + '::' + symbol)
804
+
805
+ def parse_ws_order_trade(self, trade, market=None):
806
+ #
807
+ # {
808
+ # "id": 584244931496,
809
+ # "client_order_id": "b5acd79c0a854b01b558665bcf379456",
810
+ # "symbol": "BTCUSDT",
811
+ # "side": "buy",
812
+ # "status": "new",
813
+ # "type": "limit",
814
+ # "time_in_force": "GTC",
815
+ # "quantity": "0.01000",
816
+ # "quantity_cumulative": "0",
817
+ # "price": "0.01", # only updates and snapshots
818
+ # "post_only": False,
819
+ # "reduce_only": False, # only margin and contract
820
+ # "display_quantity": "0", # only updates and snapshot
821
+ # "created_at": "2021-07-02T22:52:32.864Z",
822
+ # "updated_at": "2021-07-02T22:52:32.864Z",
823
+ # "trade_id": 1361977606, # only trades
824
+ # "trade_quantity": "0.00001", # only trades
825
+ # "trade_price": "49595.04", # only trades
826
+ # "trade_fee": "0.001239876000", # only trades
827
+ # "trade_taker": True, # only trades, only spot
828
+ # "trade_position_id": 485308, # only trades, only margin
829
+ # "report_type": "new" # "trade", "status"(snapshot)
830
+ # }
831
+ #
832
+ timestamp = self.safe_integer(trade, 'created_at')
833
+ marketId = self.safe_string(trade, 'symbol')
834
+ return self.safe_trade({
835
+ 'info': trade,
836
+ 'id': self.safe_string(trade, 'trade_id'),
837
+ 'order': self.safe_string(trade, 'id'),
838
+ 'timestamp': timestamp,
839
+ 'datetime': self.iso8601(timestamp),
840
+ 'symbol': self.safe_market(marketId, market),
841
+ 'type': None,
842
+ 'side': self.safe_string(trade, 'side'),
843
+ 'takerOrMaker': self.safe_string(trade, 'trade_taker'),
844
+ 'price': self.safe_string(trade, 'trade_price'),
845
+ 'amount': self.safe_string(trade, 'trade_quantity'),
846
+ 'cost': None,
847
+ 'fee': {
848
+ 'cost': self.safe_string(trade, 'trade_fee'),
849
+ 'currency': None,
850
+ 'rate': None,
851
+ },
852
+ }, market)
853
+
854
+ def parse_ws_order(self, order, market=None):
855
+ #
856
+ # {
857
+ # "id": 584244931496,
858
+ # "client_order_id": "b5acd79c0a854b01b558665bcf379456",
859
+ # "symbol": "BTCUSDT",
860
+ # "side": "buy",
861
+ # "status": "new",
862
+ # "type": "limit",
863
+ # "time_in_force": "GTC",
864
+ # "quantity": "0.01000",
865
+ # "quantity_cumulative": "0",
866
+ # "price": "0.01", # only updates and snapshots
867
+ # "post_only": False,
868
+ # "reduce_only": False, # only margin and contract
869
+ # "display_quantity": "0", # only updates and snapshot
870
+ # "created_at": "2021-07-02T22:52:32.864Z",
871
+ # "updated_at": "2021-07-02T22:52:32.864Z",
872
+ # "trade_id": 1361977606, # only trades
873
+ # "trade_quantity": "0.00001", # only trades
874
+ # "trade_price": "49595.04", # only trades
875
+ # "trade_fee": "0.001239876000", # only trades
876
+ # "trade_taker": True, # only trades, only spot
877
+ # "trade_position_id": 485308, # only trades, only margin
878
+ # "report_type": "new" # "trade", "status"(snapshot)
879
+ # }
880
+ #
881
+ timestamp = self.safe_string(order, 'created_at')
882
+ marketId = self.safe_string(order, 'symbol')
883
+ market = self.safe_market(marketId, market)
884
+ tradeId = self.safe_string(order, 'trade_id')
885
+ trades = None
886
+ if tradeId is not None:
887
+ trade = self.parse_ws_order_trade(order, market)
888
+ trades = [trade]
889
+ rawStatus = self.safe_string(order, 'status')
890
+ report_type = self.safe_string(order, 'report_type')
891
+ parsedStatus = None
892
+ if report_type == 'canceled':
893
+ parsedStatus = self.parse_order_status(report_type)
894
+ else:
895
+ parsedStatus = self.parse_order_status(rawStatus)
896
+ return self.safe_order({
897
+ 'info': order,
898
+ 'id': self.safe_string(order, 'id'),
899
+ 'clientOrderId': self.safe_string(order, 'client_order_id'),
900
+ 'timestamp': timestamp,
901
+ 'datetime': self.iso8601(timestamp),
902
+ 'lastTradeTimestamp': None,
903
+ 'symbol': market['symbol'],
904
+ 'price': self.safe_string(order, 'price'),
905
+ 'amount': self.safe_string(order, 'quantity'),
906
+ 'type': self.safe_string(order, 'type'),
907
+ 'side': self.safe_string_upper(order, 'side'),
908
+ 'timeInForce': self.safe_string(order, 'time_in_force'),
909
+ 'postOnly': self.safe_string(order, 'post_only'),
910
+ 'reduceOnly': self.safe_value(order, 'reduce_only'),
911
+ 'filled': None,
912
+ 'remaining': None,
913
+ 'cost': None,
914
+ 'status': parsedStatus,
915
+ 'average': None,
916
+ 'trades': trades,
917
+ 'fee': None,
918
+ }, market)
919
+
920
+ async def watch_balance(self, params={}) -> Balances:
921
+ """
922
+ watches balance updates, cannot subscribe to margin account balances
923
+ :see: https://api.hitbtc.com/#subscribe-to-spot-balances
924
+ :see: https://api.hitbtc.com/#subscribe-to-futures-balances
925
+ :param dict [params]: extra parameters specific to the exchange API endpoint
926
+ :param str [params.type]: 'spot', 'swap', or 'future'
927
+ *
928
+ * EXCHANGE SPECIFIC PARAMETERS
929
+ :param str [params.mode]: 'updates' or 'batches'(default), 'updates' = messages arrive after balance updates, 'batches' = messages arrive at equal intervals if there were any updates
930
+ :returns dict[]: a list of `balance structures <https://docs.ccxt.com/#/?id=balance-structure>`
931
+ """
932
+ await self.load_markets()
933
+ type = None
934
+ type, params = self.handle_market_type_and_params('watchBalance', None, params)
935
+ name = self.get_supported_mapping(type, {
936
+ 'spot': 'spot_balance_subscribe',
937
+ 'swap': 'futures_balance_subscribe',
938
+ 'future': 'futures_balance_subscribe',
939
+ })
940
+ mode = self.safe_string(params, 'mode', 'batches')
941
+ params = self.omit(params, 'mode')
942
+ request: dict = {
943
+ 'mode': mode,
944
+ }
945
+ return await self.subscribe_private(name, None, self.extend(request, params))
946
+
947
+ async def create_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
948
+ """
949
+ create a trade order
950
+ :see: https://api.hitbtc.com/#create-new-spot-order
951
+ :see: https://api.hitbtc.com/#create-margin-order
952
+ :see: https://api.hitbtc.com/#create-futures-order
953
+ :param str symbol: unified symbol of the market to create an order in
954
+ :param str type: 'market' or 'limit'
955
+ :param str side: 'buy' or 'sell'
956
+ :param float amount: how much of currency you want to trade in units of base currency
957
+ :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
958
+ :param dict [params]: extra parameters specific to the exchange API endpoint
959
+ :param str [params.marginMode]: 'cross' or 'isolated' only 'isolated' is supported for spot-margin, swap supports both, default is 'cross'
960
+ :param bool [params.margin]: True for creating a margin order
961
+ :param float [params.triggerPrice]: The price at which a trigger order is triggered at
962
+ :param bool [params.postOnly]: if True, the order will only be posted to the order book and not executed immediately
963
+ :param str [params.timeInForce]: "GTC", "IOC", "FOK", "Day", "GTD"
964
+ :returns dict: an `order structure <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
965
+ """
966
+ await self.load_markets()
967
+ market = self.market(symbol)
968
+ request = None
969
+ marketType = None
970
+ marketType, params = self.handle_market_type_and_params('createOrder', market, params)
971
+ marginMode = None
972
+ marginMode, params = self.handle_margin_mode_and_params('createOrder', params)
973
+ request, params = self.create_order_request(market, marketType, type, side, amount, price, marginMode, params)
974
+ request = self.extend(request, params)
975
+ if marketType == 'swap':
976
+ return await self.trade_request('futures_new_order', request)
977
+ elif (marketType == 'margin') or (marginMode is not None):
978
+ return await self.trade_request('margin_new_order', request)
979
+ else:
980
+ return await self.trade_request('spot_new_order', request)
981
+
982
+ async def cancel_order_ws(self, id: str, symbol: Str = None, params={}) -> Order:
983
+ """
984
+ :see: https://api.hitbtc.com/#cancel-spot-order-2
985
+ :see: https://api.hitbtc.com/#cancel-futures-order-2
986
+ :see: https://api.hitbtc.com/#cancel-margin-order-2
987
+ cancels an open order
988
+ :param str id: order id
989
+ :param str symbol: unified symbol of the market the order was made in
990
+ :param dict [params]: extra parameters specific to the exchange API endpoint
991
+ :param str [params.marginMode]: 'cross' or 'isolated' only 'isolated' is supported
992
+ :param bool [params.margin]: True for canceling a margin order
993
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
994
+ """
995
+ await self.load_markets()
996
+ market = None
997
+ request = {
998
+ 'client_order_id': id,
999
+ }
1000
+ if symbol is not None:
1001
+ market = self.market(symbol)
1002
+ marketType = None
1003
+ marketType, params = self.handle_market_type_and_params('cancelOrderWs', market, params)
1004
+ marginMode, query = self.handle_margin_mode_and_params('cancelOrderWs', params)
1005
+ request = self.extend(request, query)
1006
+ if marketType == 'swap':
1007
+ return await self.trade_request('futures_cancel_order', request)
1008
+ elif (marketType == 'margin') or (marginMode is not None):
1009
+ return await self.trade_request('margin_cancel_order', request)
1010
+ else:
1011
+ return await self.trade_request('spot_cancel_order', request)
1012
+
1013
+ async def cancel_all_orders_ws(self, symbol: Str = None, params={}):
1014
+ """
1015
+ :see: https://api.hitbtc.com/#cancel-spot-orders
1016
+ :see: https://api.hitbtc.com/#cancel-futures-order-3
1017
+ cancel all open orders
1018
+ :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
1019
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1020
+ :param str [params.marginMode]: 'cross' or 'isolated' only 'isolated' is supported
1021
+ :param bool [params.margin]: True for canceling margin orders
1022
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1023
+ """
1024
+ await self.load_markets()
1025
+ market = None
1026
+ if symbol is not None:
1027
+ market = self.market(symbol)
1028
+ marketType = None
1029
+ marketType, params = self.handle_market_type_and_params('cancelAllOrdersWs', market, params)
1030
+ marginMode = None
1031
+ marginMode, params = self.handle_margin_mode_and_params('cancelAllOrdersWs', params)
1032
+ if marketType == 'swap':
1033
+ return await self.trade_request('futures_cancel_orders', params)
1034
+ elif (marketType == 'margin') or (marginMode is not None):
1035
+ raise NotSupported(self.id + ' cancelAllOrdersWs is not supported for margin orders')
1036
+ else:
1037
+ return await self.trade_request('spot_cancel_orders', params)
1038
+
1039
+ async def fetch_open_orders_ws(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1040
+ """
1041
+ :see: https://api.hitbtc.com/#get-active-futures-orders-2
1042
+ :see: https://api.hitbtc.com/#get-margin-orders
1043
+ :see: https://api.hitbtc.com/#get-active-spot-orders
1044
+ fetch all unfilled currently open orders
1045
+ :param str symbol: unified market symbol
1046
+ :param int [since]: the earliest time in ms to fetch open orders for
1047
+ :param int [limit]: the maximum number of open orders structures to retrieve
1048
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1049
+ :param str [params.marginMode]: 'cross' or 'isolated' only 'isolated' is supported
1050
+ :param bool [params.margin]: True for fetching open margin orders
1051
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1052
+ """
1053
+ await self.load_markets()
1054
+ market = None
1055
+ request: dict = {}
1056
+ if symbol is not None:
1057
+ market = self.market(symbol)
1058
+ request['symbol'] = market['id']
1059
+ marketType = None
1060
+ marketType, params = self.handle_market_type_and_params('fetchOpenOrdersWs', market, params)
1061
+ marginMode = None
1062
+ marginMode, params = self.handle_margin_mode_and_params('fetchOpenOrdersWs', params)
1063
+ if marketType == 'swap':
1064
+ return await self.trade_request('futures_get_orders', request)
1065
+ elif (marketType == 'margin') or (marginMode is not None):
1066
+ return await self.trade_request('margin_get_orders', request)
1067
+ else:
1068
+ return await self.trade_request('spot_get_orders', request)
1069
+
1070
+ def handle_balance(self, client: Client, message):
1071
+ #
1072
+ # {
1073
+ # "jsonrpc": "2.0",
1074
+ # "method": "futures_balance",
1075
+ # "params": [
1076
+ # {
1077
+ # "currency": "BCN",
1078
+ # "available": "100.000000000000",
1079
+ # "reserved": "0",
1080
+ # "reserved_margin": "0"
1081
+ # },
1082
+ # ...
1083
+ # ]
1084
+ # }
1085
+ #
1086
+ messageHash = self.safe_string(message, 'method')
1087
+ params = self.safe_value(message, 'params')
1088
+ balance = self.parse_balance(params)
1089
+ self.balance = self.deep_extend(self.balance, balance)
1090
+ client.resolve(self.balance, messageHash)
1091
+
1092
+ def handle_notification(self, client: Client, message):
1093
+ #
1094
+ # {jsonrpc: "2.0", result: True, id: null}
1095
+ #
1096
+ return message
1097
+
1098
+ def handle_order_request(self, client: Client, message):
1099
+ #
1100
+ # createOrderWs, cancelOrderWs
1101
+ #
1102
+ # {
1103
+ # "jsonrpc": "2.0",
1104
+ # "result": {
1105
+ # "id": 1130310696965,
1106
+ # "client_order_id": "OPC2oyHSkEBqIpPtniLqeW-597hUL3Yo",
1107
+ # "symbol": "ADAUSDT",
1108
+ # "side": "buy",
1109
+ # "status": "new",
1110
+ # "type": "limit",
1111
+ # "time_in_force": "GTC",
1112
+ # "quantity": "4",
1113
+ # "quantity_cumulative": "0",
1114
+ # "price": "0.3300000",
1115
+ # "post_only": False,
1116
+ # "created_at": "2023-11-17T14:58:15.903Z",
1117
+ # "updated_at": "2023-11-17T14:58:15.903Z",
1118
+ # "original_client_order_id": "d6b645556af740b1bd1683400fd9cbce", # spot_replace_order only
1119
+ # "report_type": "new"
1120
+ # "margin_mode": "isolated", # margin and future only
1121
+ # "reduce_only": False, # margin and future only
1122
+ # },
1123
+ # "id": 1700233093414
1124
+ # }
1125
+ #
1126
+ messageHash = self.safe_string(message, 'id')
1127
+ result = self.safe_value(message, 'result', {})
1128
+ if isinstance(result, list):
1129
+ parsedOrders = []
1130
+ for i in range(0, len(result)):
1131
+ parsedOrder = self.parse_ws_order(result[i])
1132
+ parsedOrders.append(parsedOrder)
1133
+ client.resolve(parsedOrders, messageHash)
1134
+ else:
1135
+ parsedOrder = self.parse_ws_order(result)
1136
+ client.resolve(parsedOrder, messageHash)
1137
+ return message
1138
+
1139
+ def handle_message(self, client: Client, message):
1140
+ self.handle_error(client, message)
1141
+ channel = self.safe_string_2(message, 'ch', 'method')
1142
+ if channel is not None:
1143
+ splitChannel = channel.split('/')
1144
+ channel = self.safe_string(splitChannel, 0)
1145
+ methods: dict = {
1146
+ 'candles': self.handle_ohlcv,
1147
+ 'ticker': self.handle_ticker,
1148
+ 'trades': self.handle_trades,
1149
+ 'orderbook': self.handle_order_book,
1150
+ 'spot_order': self.handle_order,
1151
+ 'spot_orders': self.handle_order,
1152
+ 'margin_order': self.handle_order,
1153
+ 'margin_orders': self.handle_order,
1154
+ 'futures_order': self.handle_order,
1155
+ 'futures_orders': self.handle_order,
1156
+ 'spot_balance': self.handle_balance,
1157
+ 'futures_balance': self.handle_balance,
1158
+ }
1159
+ method = self.safe_value(methods, channel)
1160
+ if method is not None:
1161
+ method(client, message)
1162
+ else:
1163
+ result = self.safe_value(message, 'result')
1164
+ clientOrderId = self.safe_string(result, 'client_order_id')
1165
+ if clientOrderId is not None:
1166
+ self.handle_order_request(client, message)
1167
+ if (result is True) and not ('id' in message):
1168
+ self.handle_authenticate(client, message)
1169
+ if isinstance(result, list):
1170
+ # to do improve self, not very reliable right now
1171
+ first = self.safe_value(result, 0, {})
1172
+ arrayLength = len(result)
1173
+ if (arrayLength == 0) or ('client_order_id' in first):
1174
+ self.handle_order_request(client, message)
1175
+
1176
+ def handle_authenticate(self, client: Client, message):
1177
+ #
1178
+ # {
1179
+ # "jsonrpc": "2.0",
1180
+ # "result": True
1181
+ # }
1182
+ #
1183
+ success = self.safe_value(message, 'result')
1184
+ messageHash = 'authenticated'
1185
+ if success:
1186
+ future = self.safe_value(client.futures, messageHash)
1187
+ future.resolve(True)
1188
+ else:
1189
+ error = AuthenticationError(self.id + ' ' + self.json(message))
1190
+ client.reject(error, messageHash)
1191
+ if messageHash in client.subscriptions:
1192
+ del client.subscriptions[messageHash]
1193
+ return message
1194
+
1195
+ def handle_error(self, client: Client, message):
1196
+ #
1197
+ # {
1198
+ # jsonrpc: '2.0',
1199
+ # error: {
1200
+ # code: 20001,
1201
+ # message: 'Insufficient funds',
1202
+ # description: 'Check that the funds are sufficient, given commissions'
1203
+ # },
1204
+ # id: 1700228604325
1205
+ # }
1206
+ #
1207
+ error = self.safe_value(message, 'error')
1208
+ if error is not None:
1209
+ code = self.safe_value(error, 'code')
1210
+ errorMessage = self.safe_string(error, 'message')
1211
+ description = self.safe_string(error, 'description')
1212
+ feedback = self.id + ' ' + description
1213
+ self.throw_exactly_matched_exception(self.exceptions['exact'], code, feedback)
1214
+ self.throw_broadly_matched_exception(self.exceptions['broad'], errorMessage, feedback)
1215
+ raise ExchangeError(feedback) # unknown message
1216
+ return None