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/gate.py ADDED
@@ -0,0 +1,1416 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
+ # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
+
6
+ import ccxt.async_support
7
+ from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
8
+ import hashlib
9
+ from ccxt.base.types import Balances, Int, Liquidation, Order, OrderBook, Position, Str, Strings, Ticker, Tickers, Trade
10
+ from ccxt.async_support.base.ws.client import Client
11
+ from typing import List
12
+ from ccxt.base.errors import AuthenticationError
13
+ from ccxt.base.errors import ArgumentsRequired
14
+ from ccxt.base.errors import BadRequest
15
+ from ccxt.base.errors import InvalidNonce
16
+ from ccxt.base.precise import Precise
17
+
18
+
19
+ class gate(ccxt.async_support.gate):
20
+
21
+ def describe(self):
22
+ return self.deep_extend(super(gate, self).describe(), {
23
+ 'has': {
24
+ 'ws': True,
25
+ 'watchOrderBook': True,
26
+ 'watchTicker': True,
27
+ 'watchTickers': True,
28
+ 'watchTrades': True,
29
+ 'watchTradesForSymbols': True,
30
+ 'watchMyTrades': True,
31
+ 'watchOHLCV': True,
32
+ 'watchBalance': True,
33
+ 'watchOrders': True,
34
+ 'watchLiquidations': False,
35
+ 'watchLiquidationsForSymbols': False,
36
+ 'watchMyLiquidations': True,
37
+ 'watchMyLiquidationsForSymbols': True,
38
+ 'watchPositions': True,
39
+ },
40
+ 'urls': {
41
+ 'api': {
42
+ 'ws': 'wss://ws.gate.io/v4',
43
+ 'spot': 'wss://api.gateio.ws/ws/v4/',
44
+ 'swap': {
45
+ 'usdt': 'wss://fx-ws.gateio.ws/v4/ws/usdt',
46
+ 'btc': 'wss://fx-ws.gateio.ws/v4/ws/btc',
47
+ },
48
+ 'future': {
49
+ 'usdt': 'wss://fx-ws.gateio.ws/v4/ws/delivery/usdt',
50
+ 'btc': 'wss://fx-ws.gateio.ws/v4/ws/delivery/btc',
51
+ },
52
+ 'option': {
53
+ 'usdt': 'wss://op-ws.gateio.live/v4/ws/usdt',
54
+ 'btc': 'wss://op-ws.gateio.live/v4/ws/btc',
55
+ },
56
+ },
57
+ 'test': {
58
+ 'swap': {
59
+ 'usdt': 'wss://fx-ws-testnet.gateio.ws/v4/ws/usdt',
60
+ 'btc': 'wss://fx-ws-testnet.gateio.ws/v4/ws/btc',
61
+ },
62
+ 'future': {
63
+ 'usdt': 'wss://fx-ws-testnet.gateio.ws/v4/ws/usdt',
64
+ 'btc': 'wss://fx-ws-testnet.gateio.ws/v4/ws/btc',
65
+ },
66
+ 'option': {
67
+ 'usdt': 'wss://op-ws-testnet.gateio.live/v4/ws/usdt',
68
+ 'btc': 'wss://op-ws-testnet.gateio.live/v4/ws/btc',
69
+ },
70
+ },
71
+ },
72
+ 'options': {
73
+ 'tradesLimit': 1000,
74
+ 'OHLCVLimit': 1000,
75
+ 'watchTradesSubscriptions': {},
76
+ 'watchTickerSubscriptions': {},
77
+ 'watchOrderBookSubscriptions': {},
78
+ 'watchTicker': {
79
+ 'name': 'tickers', # or book_ticker
80
+ },
81
+ 'watchOrderBook': {
82
+ 'interval': '100ms',
83
+ 'snapshotDelay': 10, # how many deltas to cache before fetching a snapshot
84
+ 'snapshotMaxRetries': 3,
85
+ },
86
+ 'watchBalance': {
87
+ 'settle': 'usdt', # or btc
88
+ 'spot': 'spot.balances', # spot.margin_balances, spot.funding_balances or spot.cross_balances
89
+ },
90
+ 'watchPositions': {
91
+ 'fetchPositionsSnapshot': True, # or False
92
+ 'awaitPositionsSnapshot': True, # whether to wait for the positions snapshot before providing updates
93
+ },
94
+ },
95
+ 'exceptions': {
96
+ 'ws': {
97
+ 'exact': {
98
+ '2': BadRequest,
99
+ '4': AuthenticationError,
100
+ '6': AuthenticationError,
101
+ '11': AuthenticationError,
102
+ },
103
+ },
104
+ },
105
+ })
106
+
107
+ async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
108
+ """
109
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
110
+ :param str symbol: unified symbol of the market to fetch the order book for
111
+ :param int [limit]: the maximum amount of order book entries to return
112
+ :param dict [params]: extra parameters specific to the exchange API endpoint
113
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
114
+ """
115
+ await self.load_markets()
116
+ market = self.market(symbol)
117
+ symbol = market['symbol']
118
+ marketId = market['id']
119
+ interval, query = self.handle_option_and_params(params, 'watchOrderBook', 'interval', '100ms')
120
+ messageType = self.get_type_by_market(market)
121
+ channel = messageType + '.order_book_update'
122
+ messageHash = 'orderbook' + ':' + symbol
123
+ url = self.get_url_by_market(market)
124
+ payload = [marketId, interval]
125
+ if limit is None:
126
+ limit = 100
127
+ if market['contract']:
128
+ stringLimit = str(limit)
129
+ payload.append(stringLimit)
130
+ subscription: dict = {
131
+ 'symbol': symbol,
132
+ 'limit': limit,
133
+ }
134
+ orderbook = await self.subscribe_public(url, messageHash, payload, channel, query, subscription)
135
+ return orderbook.limit()
136
+
137
+ def handle_order_book_subscription(self, client: Client, message, subscription):
138
+ symbol = self.safe_string(subscription, 'symbol')
139
+ limit = self.safe_integer(subscription, 'limit')
140
+ self.orderbooks[symbol] = self.order_book({}, limit)
141
+
142
+ def handle_order_book(self, client: Client, message):
143
+ #
144
+ # spot
145
+ #
146
+ # {
147
+ # "time": 1650189272,
148
+ # "channel": "spot.order_book_update",
149
+ # "event": "update",
150
+ # "result": {
151
+ # "t": 1650189272515,
152
+ # "e": "depthUpdate",
153
+ # "E": 1650189272,
154
+ # "s": "GMT_USDT",
155
+ # "U": 140595902,
156
+ # "u": 140595902,
157
+ # "b": [
158
+ # ['2.51518', "228.119"],
159
+ # ['2.50587', "1510.11"],
160
+ # ['2.49944', "67.6"],
161
+ # ],
162
+ # "a": [
163
+ # ['2.5182', "4.199"],
164
+ # ["2.51926", "1874"],
165
+ # ['2.53528', "96.529"],
166
+ # ]
167
+ # }
168
+ # }
169
+ #
170
+ # swap
171
+ #
172
+ # {
173
+ # "id": null,
174
+ # "time": 1650188898,
175
+ # "channel": "futures.order_book_update",
176
+ # "event": "update",
177
+ # "error": null,
178
+ # "result": {
179
+ # "t": 1650188898938,
180
+ # "s": "GMT_USDT",
181
+ # "U": 1577718307,
182
+ # "u": 1577719254,
183
+ # "b": [
184
+ # {p: "2.5178", s: 0},
185
+ # {p: "2.5179", s: 0},
186
+ # {p: "2.518", s: 0},
187
+ # ],
188
+ # "a": [
189
+ # {p: "2.52", s: 0},
190
+ # {p: "2.5201", s: 0},
191
+ # {p: "2.5203", s: 0},
192
+ # ]
193
+ # }
194
+ # }
195
+ #
196
+ channel = self.safe_string(message, 'channel')
197
+ channelParts = channel.split('.')
198
+ rawMarketType = self.safe_string(channelParts, 0)
199
+ isSpot = rawMarketType == 'spot'
200
+ marketType = 'spot' if isSpot else 'contract'
201
+ delta = self.safe_value(message, 'result')
202
+ deltaStart = self.safe_integer(delta, 'U')
203
+ deltaEnd = self.safe_integer(delta, 'u')
204
+ marketId = self.safe_string(delta, 's')
205
+ symbol = self.safe_symbol(marketId, None, '_', marketType)
206
+ messageHash = 'orderbook:' + symbol
207
+ storedOrderBook = self.safe_value(self.orderbooks, symbol, self.order_book({}))
208
+ nonce = self.safe_integer(storedOrderBook, 'nonce')
209
+ if nonce is None:
210
+ cacheLength = 0
211
+ if storedOrderBook is not None:
212
+ cacheLength = len(storedOrderBook.cache)
213
+ snapshotDelay = self.handle_option('watchOrderBook', 'snapshotDelay', 10)
214
+ waitAmount = snapshotDelay if isSpot else 0
215
+ if cacheLength == waitAmount:
216
+ # max limit is 100
217
+ subscription = client.subscriptions[messageHash]
218
+ limit = self.safe_integer(subscription, 'limit')
219
+ self.spawn(self.load_order_book, client, messageHash, symbol, limit, {}) # needed for c#, number of args needs to match
220
+ storedOrderBook.cache.append(delta)
221
+ return
222
+ elif nonce >= deltaEnd:
223
+ return
224
+ elif nonce >= deltaStart - 1:
225
+ self.handle_delta(storedOrderBook, delta)
226
+ else:
227
+ error = InvalidNonce(self.id + ' orderbook update has a nonce bigger than u')
228
+ del client.subscriptions[messageHash]
229
+ del self.orderbooks[symbol]
230
+ client.reject(error, messageHash)
231
+ client.resolve(storedOrderBook, messageHash)
232
+
233
+ def get_cache_index(self, orderBook, cache):
234
+ nonce = self.safe_integer(orderBook, 'nonce')
235
+ firstDelta = cache[0]
236
+ firstDeltaStart = self.safe_integer(firstDelta, 'U')
237
+ if nonce < firstDeltaStart:
238
+ return -1
239
+ for i in range(0, len(cache)):
240
+ delta = cache[i]
241
+ deltaStart = self.safe_integer(delta, 'U')
242
+ deltaEnd = self.safe_integer(delta, 'u')
243
+ if (nonce >= deltaStart - 1) and (nonce < deltaEnd):
244
+ return i
245
+ return len(cache)
246
+
247
+ def handle_bid_asks(self, bookSide, bidAsks):
248
+ for i in range(0, len(bidAsks)):
249
+ bidAsk = bidAsks[i]
250
+ if isinstance(bidAsk, list):
251
+ bookSide.storeArray(self.parse_bid_ask(bidAsk))
252
+ else:
253
+ price = self.safe_float(bidAsk, 'p')
254
+ amount = self.safe_float(bidAsk, 's')
255
+ bookSide.store(price, amount)
256
+
257
+ def handle_delta(self, orderbook, delta):
258
+ timestamp = self.safe_integer(delta, 't')
259
+ orderbook['timestamp'] = timestamp
260
+ orderbook['datetime'] = self.iso8601(timestamp)
261
+ orderbook['nonce'] = self.safe_integer(delta, 'u')
262
+ bids = self.safe_value(delta, 'b', [])
263
+ asks = self.safe_value(delta, 'a', [])
264
+ storedBids = orderbook['bids']
265
+ storedAsks = orderbook['asks']
266
+ self.handle_bid_asks(storedBids, bids)
267
+ self.handle_bid_asks(storedAsks, asks)
268
+
269
+ async def watch_ticker(self, symbol: str, params={}) -> Ticker:
270
+ """
271
+ :see: https://www.gate.io/docs/developers/apiv4/ws/en/#tickers-channel
272
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
273
+ :param str symbol: unified symbol of the market to fetch the ticker for
274
+ :param dict [params]: extra parameters specific to the exchange API endpoint
275
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
276
+ """
277
+ await self.load_markets()
278
+ market = self.market(symbol)
279
+ symbol = market['symbol']
280
+ params['callerMethodName'] = 'watchTicker'
281
+ result = await self.watch_tickers([symbol], params)
282
+ return self.safe_value(result, symbol)
283
+
284
+ async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
285
+ """
286
+ :see: https://www.gate.io/docs/developers/apiv4/ws/en/#tickers-channel
287
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
288
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
289
+ :param dict [params]: extra parameters specific to the exchange API endpoint
290
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
291
+ """
292
+ return await self.subscribe_watch_tickers_and_bids_asks(symbols, 'watchTickers', self.extend({'method': 'tickers'}, params))
293
+
294
+ def handle_ticker(self, client: Client, message):
295
+ #
296
+ # {
297
+ # "time": 1649326221,
298
+ # "channel": "spot.tickers",
299
+ # "event": "update",
300
+ # "result": {
301
+ # "currency_pair": "BTC_USDT",
302
+ # "last": "43444.82",
303
+ # "lowest_ask": "43444.82",
304
+ # "highest_bid": "43444.81",
305
+ # "change_percentage": "-4.0036",
306
+ # "base_volume": "5182.5412425462",
307
+ # "quote_volume": "227267634.93123952",
308
+ # "high_24h": "47698",
309
+ # "low_24h": "42721.03"
310
+ # }
311
+ # }
312
+ #
313
+ self.handle_ticker_and_bid_ask('ticker', client, message)
314
+
315
+ async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
316
+ """
317
+ :see: https://www.gate.io/docs/developers/apiv4/ws/en/#best-bid-or-ask-price
318
+ :see: https://www.gate.io/docs/developers/apiv4/ws/en/#order-book-channel
319
+ watches best bid & ask for symbols
320
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
321
+ :param dict [params]: extra parameters specific to the exchange API endpoint
322
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
323
+ """
324
+ return await self.subscribe_watch_tickers_and_bids_asks(symbols, 'watchBidsAsks', self.extend({'method': 'book_ticker'}, params))
325
+
326
+ def handle_bid_ask(self, client: Client, message):
327
+ #
328
+ # {
329
+ # "time": 1671363004,
330
+ # "time_ms": 1671363004235,
331
+ # "channel": "spot.book_ticker",
332
+ # "event": "update",
333
+ # "result": {
334
+ # "t": 1671363004228,
335
+ # "u": 9793320464,
336
+ # "s": "BTC_USDT",
337
+ # "b": "16716.8",
338
+ # "B": "0.0134",
339
+ # "a": "16716.9",
340
+ # "A": "0.0353"
341
+ # }
342
+ # }
343
+ #
344
+ self.handle_ticker_and_bid_ask('bidask', client, message)
345
+
346
+ async def subscribe_watch_tickers_and_bids_asks(self, symbols: Strings = None, callerMethodName: Str = None, params={}) -> Tickers:
347
+ await self.load_markets()
348
+ callerMethodName, params = self.handle_param_string(params, 'callerMethodName', callerMethodName)
349
+ symbols = self.market_symbols(symbols, None, False)
350
+ market = self.market(symbols[0])
351
+ messageType = self.get_type_by_market(market)
352
+ marketIds = self.market_ids(symbols)
353
+ channelName = None
354
+ channelName, params = self.handle_option_and_params(params, callerMethodName, 'method')
355
+ url = self.get_url_by_market(market)
356
+ channel = messageType + '.' + channelName
357
+ isWatchTickers = callerMethodName.find('watchTicker') >= 0
358
+ prefix = 'ticker' if isWatchTickers else 'bidask'
359
+ messageHashes = []
360
+ for i in range(0, len(symbols)):
361
+ symbol = symbols[i]
362
+ messageHashes.append(prefix + ':' + symbol)
363
+ tickerOrBidAsk = await self.subscribe_public_multiple(url, messageHashes, marketIds, channel, params)
364
+ if self.newUpdates:
365
+ items: dict = {}
366
+ items[tickerOrBidAsk['symbol']] = tickerOrBidAsk
367
+ return items
368
+ result = self.tickers if isWatchTickers else self.bidsasks
369
+ return self.filter_by_array(result, 'symbol', symbols, True)
370
+
371
+ def handle_ticker_and_bid_ask(self, objectName: str, client: Client, message):
372
+ channel = self.safe_string(message, 'channel')
373
+ parts = channel.split('.')
374
+ rawMarketType = self.safe_string(parts, 0)
375
+ marketType = 'contract' if (rawMarketType == 'futures') else 'spot'
376
+ result = self.safe_value(message, 'result')
377
+ results = []
378
+ if isinstance(result, list):
379
+ results = self.safe_list(message, 'result', [])
380
+ else:
381
+ rawTicker = self.safe_dict(message, 'result', {})
382
+ results = [rawTicker]
383
+ isTicker = (objectName == 'ticker') # whether ticker or bid-ask
384
+ for i in range(0, len(results)):
385
+ rawTicker = results[i]
386
+ marketId = self.safe_string(rawTicker, 's')
387
+ market = self.safe_market(marketId, None, '_', marketType)
388
+ parsedItem = self.parse_ticker(rawTicker, market)
389
+ symbol = parsedItem['symbol']
390
+ if isTicker:
391
+ self.tickers[symbol] = parsedItem
392
+ else:
393
+ self.bidsasks[symbol] = parsedItem
394
+ messageHash = objectName + ':' + symbol
395
+ client.resolve(parsedItem, messageHash)
396
+
397
+ async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
398
+ """
399
+ get the list of most recent trades for a particular symbol
400
+ :param str symbol: unified symbol of the market to fetch trades for
401
+ :param int [since]: timestamp in ms of the earliest trade to fetch
402
+ :param int [limit]: the maximum amount of trades to fetch
403
+ :param dict [params]: extra parameters specific to the exchange API endpoint
404
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
405
+ """
406
+ return await self.watch_trades_for_symbols([symbol], since, limit, params)
407
+
408
+ async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
409
+ """
410
+ get the list of most recent trades for a particular symbol
411
+ :param str symbol: unified symbol of the market to fetch trades for
412
+ :param int [since]: timestamp in ms of the earliest trade to fetch
413
+ :param int [limit]: the maximum amount of trades to fetch
414
+ :param dict [params]: extra parameters specific to the exchange API endpoint
415
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
416
+ """
417
+ await self.load_markets()
418
+ symbols = self.market_symbols(symbols)
419
+ marketIds = self.market_ids(symbols)
420
+ market = self.market(symbols[0])
421
+ messageType = self.get_type_by_market(market)
422
+ channel = messageType + '.trades'
423
+ messageHashes = []
424
+ for i in range(0, len(symbols)):
425
+ symbol = symbols[i]
426
+ messageHashes.append('trades:' + symbol)
427
+ url = self.get_url_by_market(market)
428
+ trades = await self.subscribe_public_multiple(url, messageHashes, marketIds, channel, params)
429
+ if self.newUpdates:
430
+ first = self.safe_value(trades, 0)
431
+ tradeSymbol = self.safe_string(first, 'symbol')
432
+ limit = trades.getLimit(tradeSymbol, limit)
433
+ return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
434
+
435
+ def handle_trades(self, client: Client, message):
436
+ #
437
+ # {
438
+ # "time": 1648725035,
439
+ # "channel": "spot.trades",
440
+ # "event": "update",
441
+ # "result": [{
442
+ # "id": 3130257995,
443
+ # "create_time": 1648725035,
444
+ # "create_time_ms": "1648725035923.0",
445
+ # "side": "sell",
446
+ # "currency_pair": "LTC_USDT",
447
+ # "amount": "0.0116",
448
+ # "price": "130.11"
449
+ # }]
450
+ # }
451
+ #
452
+ result = self.safe_value(message, 'result')
453
+ if not isinstance(result, list):
454
+ result = [result]
455
+ parsedTrades = self.parse_trades(result)
456
+ for i in range(0, len(parsedTrades)):
457
+ trade = parsedTrades[i]
458
+ symbol = trade['symbol']
459
+ cachedTrades = self.safe_value(self.trades, symbol)
460
+ if cachedTrades is None:
461
+ limit = self.safe_integer(self.options, 'tradesLimit', 1000)
462
+ cachedTrades = ArrayCache(limit)
463
+ self.trades[symbol] = cachedTrades
464
+ cachedTrades.append(trade)
465
+ hash = 'trades:' + symbol
466
+ client.resolve(cachedTrades, hash)
467
+
468
+ async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
469
+ """
470
+ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
471
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
472
+ :param str timeframe: the length of time each candle represents
473
+ :param int [since]: timestamp in ms of the earliest candle to fetch
474
+ :param int [limit]: the maximum amount of candles to fetch
475
+ :param dict [params]: extra parameters specific to the exchange API endpoint
476
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
477
+ """
478
+ await self.load_markets()
479
+ market = self.market(symbol)
480
+ symbol = market['symbol']
481
+ marketId = market['id']
482
+ interval = self.safe_string(self.timeframes, timeframe, timeframe)
483
+ messageType = self.get_type_by_market(market)
484
+ channel = messageType + '.candlesticks'
485
+ messageHash = 'candles:' + interval + ':' + market['symbol']
486
+ url = self.get_url_by_market(market)
487
+ payload = [interval, marketId]
488
+ ohlcv = await self.subscribe_public(url, messageHash, payload, channel, params)
489
+ if self.newUpdates:
490
+ limit = ohlcv.getLimit(symbol, limit)
491
+ return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
492
+
493
+ def handle_ohlcv(self, client: Client, message):
494
+ #
495
+ # {
496
+ # "time": 1606292600,
497
+ # "channel": "spot.candlesticks",
498
+ # "event": "update",
499
+ # "result": {
500
+ # "t": "1606292580", # total volume
501
+ # "v": "2362.32035", # volume
502
+ # "c": "19128.1", # close
503
+ # "h": "19128.1", # high
504
+ # "l": "19128.1", # low
505
+ # "o": "19128.1", # open
506
+ # "n": "1m_BTC_USDT" # sub
507
+ # }
508
+ # }
509
+ #
510
+ channel = self.safe_string(message, 'channel')
511
+ channelParts = channel.split('.')
512
+ rawMarketType = self.safe_string(channelParts, 0)
513
+ marketType = 'spot' if (rawMarketType == 'spot') else 'contract'
514
+ result = self.safe_value(message, 'result')
515
+ if not isinstance(result, list):
516
+ result = [result]
517
+ marketIds: dict = {}
518
+ for i in range(0, len(result)):
519
+ ohlcv = result[i]
520
+ subscription = self.safe_string(ohlcv, 'n', '')
521
+ parts = subscription.split('_')
522
+ timeframe = self.safe_string(parts, 0)
523
+ timeframeId = self.find_timeframe(timeframe)
524
+ prefix = timeframe + '_'
525
+ marketId = subscription.replace(prefix, '')
526
+ symbol = self.safe_symbol(marketId, None, '_', marketType)
527
+ parsed = self.parse_ohlcv(ohlcv)
528
+ self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
529
+ stored = self.safe_value(self.ohlcvs[symbol], timeframe)
530
+ if stored is None:
531
+ limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
532
+ stored = ArrayCacheByTimestamp(limit)
533
+ self.ohlcvs[symbol][timeframeId] = stored
534
+ stored.append(parsed)
535
+ marketIds[symbol] = timeframe
536
+ keys = list(marketIds.keys())
537
+ for i in range(0, len(keys)):
538
+ symbol = keys[i]
539
+ timeframe = marketIds[symbol]
540
+ interval = self.find_timeframe(timeframe)
541
+ hash = 'candles' + ':' + interval + ':' + symbol
542
+ stored = self.safe_value(self.ohlcvs[symbol], interval)
543
+ client.resolve(stored, hash)
544
+
545
+ async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
546
+ """
547
+ watches information on multiple trades made by the user
548
+ :param str symbol: unified market symbol of the market trades were made in
549
+ :param int [since]: the earliest time in ms to fetch trades for
550
+ :param int [limit]: the maximum number of trade structures to retrieve
551
+ :param dict [params]: extra parameters specific to the exchange API endpoint
552
+ :returns dict[]: a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
553
+ """
554
+ await self.load_markets()
555
+ subType = None
556
+ type = None
557
+ marketId = '!' + 'all'
558
+ market = None
559
+ if symbol is not None:
560
+ market = self.market(symbol)
561
+ marketId = market['id']
562
+ type, params = self.handle_market_type_and_params('watchMyTrades', market, params)
563
+ subType, params = self.handle_sub_type_and_params('watchMyTrades', market, params)
564
+ messageType = self.get_supported_mapping(type, {
565
+ 'spot': 'spot',
566
+ 'margin': 'spot',
567
+ 'future': 'futures',
568
+ 'swap': 'futures',
569
+ 'option': 'options',
570
+ })
571
+ channel = messageType + '.usertrades'
572
+ messageHash = 'myTrades'
573
+ if symbol is not None:
574
+ messageHash += ':' + symbol
575
+ isInverse = (subType == 'inverse')
576
+ url = self.get_url_by_market_type(type, isInverse)
577
+ payload = [marketId]
578
+ # uid required for non spot markets
579
+ requiresUid = (type != 'spot')
580
+ trades = await self.subscribe_private(url, messageHash, payload, channel, params, requiresUid)
581
+ if self.newUpdates:
582
+ limit = trades.getLimit(symbol, limit)
583
+ return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
584
+
585
+ def handle_my_trades(self, client: Client, message):
586
+ #
587
+ # {
588
+ # "time": 1543205083,
589
+ # "channel": "futures.usertrades",
590
+ # "event": "update",
591
+ # "error": null,
592
+ # "result": [
593
+ # {
594
+ # "id": "3335259",
595
+ # "create_time": 1628736848,
596
+ # "create_time_ms": 1628736848321,
597
+ # "contract": "BTC_USD",
598
+ # "order_id": "4872460",
599
+ # "size": 1,
600
+ # "price": "40000.4",
601
+ # "role": "maker"
602
+ # }
603
+ # ]
604
+ # }
605
+ #
606
+ result = self.safe_value(message, 'result', [])
607
+ tradesLength = len(result)
608
+ if tradesLength == 0:
609
+ return
610
+ cachedTrades = self.myTrades
611
+ if cachedTrades is None:
612
+ limit = self.safe_integer(self.options, 'tradesLimit', 1000)
613
+ cachedTrades = ArrayCacheBySymbolById(limit)
614
+ self.myTrades = cachedTrades
615
+ parsed = self.parse_trades(result)
616
+ marketIds: dict = {}
617
+ for i in range(0, len(parsed)):
618
+ trade = parsed[i]
619
+ cachedTrades.append(trade)
620
+ symbol = trade['symbol']
621
+ marketIds[symbol] = True
622
+ keys = list(marketIds.keys())
623
+ for i in range(0, len(keys)):
624
+ market = keys[i]
625
+ hash = 'myTrades:' + market
626
+ client.resolve(cachedTrades, hash)
627
+ client.resolve(cachedTrades, 'myTrades')
628
+
629
+ async def watch_balance(self, params={}) -> Balances:
630
+ """
631
+ watch balance and get the amount of funds available for trading or funds locked in orders
632
+ :param dict [params]: extra parameters specific to the exchange API endpoint
633
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
634
+ """
635
+ await self.load_markets()
636
+ type = None
637
+ subType = None
638
+ type, params = self.handle_market_type_and_params('watchBalance', None, params)
639
+ subType, params = self.handle_sub_type_and_params('watchBalance', None, params)
640
+ isInverse = (subType == 'inverse')
641
+ url = self.get_url_by_market_type(type, isInverse)
642
+ requiresUid = (type != 'spot')
643
+ channelType = self.get_supported_mapping(type, {
644
+ 'spot': 'spot',
645
+ 'margin': 'spot',
646
+ 'future': 'futures',
647
+ 'swap': 'futures',
648
+ 'option': 'options',
649
+ })
650
+ channel = channelType + '.balances'
651
+ messageHash = type + '.balance'
652
+ return await self.subscribe_private(url, messageHash, None, channel, params, requiresUid)
653
+
654
+ def handle_balance(self, client: Client, message):
655
+ #
656
+ # spot order fill
657
+ # {
658
+ # "time": 1653664351,
659
+ # "channel": "spot.balances",
660
+ # "event": "update",
661
+ # "result": [
662
+ # {
663
+ # "timestamp": "1653664351",
664
+ # "timestamp_ms": "1653664351017",
665
+ # "user": "10406147",
666
+ # "currency": "LTC",
667
+ # "change": "-0.0002000000000000",
668
+ # "total": "0.09986000000000000000",
669
+ # "available": "0.09986000000000000000"
670
+ # }
671
+ # ]
672
+ # }
673
+ #
674
+ # account transfer
675
+ #
676
+ # {
677
+ # "id": null,
678
+ # "time": 1653665088,
679
+ # "channel": "futures.balances",
680
+ # "event": "update",
681
+ # "error": null,
682
+ # "result": [
683
+ # {
684
+ # "balance": 25.035008537,
685
+ # "change": 25,
686
+ # "text": "-",
687
+ # "time": 1653665088,
688
+ # "time_ms": 1653665088286,
689
+ # "type": "dnw",
690
+ # "user": "10406147"
691
+ # }
692
+ # ]
693
+ # }
694
+ #
695
+ # swap order fill
696
+ # {
697
+ # "id": null,
698
+ # "time": 1653665311,
699
+ # "channel": "futures.balances",
700
+ # "event": "update",
701
+ # "error": null,
702
+ # "result": [
703
+ # {
704
+ # "balance": 20.031873037,
705
+ # "change": -0.0031355,
706
+ # "text": "LTC_USDT:165551103273",
707
+ # "time": 1653665311,
708
+ # "time_ms": 1653665311437,
709
+ # "type": "fee",
710
+ # "user": "10406147"
711
+ # }
712
+ # ]
713
+ # }
714
+ #
715
+ result = self.safe_value(message, 'result', [])
716
+ timestamp = self.safe_integer(message, 'time_ms')
717
+ self.balance['info'] = result
718
+ self.balance['timestamp'] = timestamp
719
+ self.balance['datetime'] = self.iso8601(timestamp)
720
+ for i in range(0, len(result)):
721
+ rawBalance = result[i]
722
+ account = self.account()
723
+ currencyId = self.safe_string(rawBalance, 'currency', 'USDT') # when not present it is USDT
724
+ code = self.safe_currency_code(currencyId)
725
+ account['free'] = self.safe_string(rawBalance, 'available')
726
+ account['total'] = self.safe_string_2(rawBalance, 'total', 'balance')
727
+ self.balance[code] = account
728
+ channel = self.safe_string(message, 'channel')
729
+ parts = channel.split('.')
730
+ rawType = self.safe_string(parts, 0)
731
+ channelType = self.get_supported_mapping(rawType, {
732
+ 'spot': 'spot',
733
+ 'futures': 'swap',
734
+ 'options': 'option',
735
+ })
736
+ messageHash = channelType + '.balance'
737
+ self.balance = self.safe_balance(self.balance)
738
+ client.resolve(self.balance, messageHash)
739
+
740
+ async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
741
+ """
742
+ :see: https://www.gate.io/docs/developers/futures/ws/en/#positions-subscription
743
+ :see: https://www.gate.io/docs/developers/delivery/ws/en/#positions-subscription
744
+ :see: https://www.gate.io/docs/developers/options/ws/en/#positions-channel
745
+ watch all open positions
746
+ :param str[]|None symbols: list of unified market symbols
747
+ :param dict params: extra parameters specific to the exchange API endpoint
748
+ :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
749
+ """
750
+ await self.load_markets()
751
+ market = None
752
+ symbols = self.market_symbols(symbols)
753
+ payload = ['!' + 'all']
754
+ if not self.is_empty(symbols):
755
+ market = self.get_market_from_symbols(symbols)
756
+ type = None
757
+ query = None
758
+ type, query = self.handle_market_type_and_params('watchPositions', market, params)
759
+ if type == 'spot':
760
+ type = 'swap'
761
+ typeId = self.get_supported_mapping(type, {
762
+ 'future': 'futures',
763
+ 'swap': 'futures',
764
+ 'option': 'options',
765
+ })
766
+ messageHash = type + ':positions'
767
+ if not self.is_empty(symbols):
768
+ messageHash += '::' + ','.join(symbols)
769
+ channel = typeId + '.positions'
770
+ subType = None
771
+ subType, query = self.handle_sub_type_and_params('watchPositions', market, query)
772
+ isInverse = (subType == 'inverse')
773
+ url = self.get_url_by_market_type(type, isInverse)
774
+ client = self.client(url)
775
+ self.set_positions_cache(client, type, symbols)
776
+ fetchPositionsSnapshot = self.handle_option('watchPositions', 'fetchPositionsSnapshot', True)
777
+ awaitPositionsSnapshot = self.safe_bool('watchPositions', 'awaitPositionsSnapshot', True)
778
+ cache = self.safe_value(self.positions, type)
779
+ if fetchPositionsSnapshot and awaitPositionsSnapshot and cache is None:
780
+ return await client.future(type + ':fetchPositionsSnapshot')
781
+ positions = await self.subscribe_private(url, messageHash, payload, channel, query, True)
782
+ if self.newUpdates:
783
+ return positions
784
+ return self.filter_by_symbols_since_limit(self.positions[type], symbols, since, limit, True)
785
+
786
+ def set_positions_cache(self, client: Client, type, symbols: Strings = None):
787
+ if self.positions is None:
788
+ self.positions = {}
789
+ if type in self.positions:
790
+ return
791
+ fetchPositionsSnapshot = self.handle_option('watchPositions', 'fetchPositionsSnapshot', False)
792
+ if fetchPositionsSnapshot:
793
+ messageHash = type + ':fetchPositionsSnapshot'
794
+ if not (messageHash in client.futures):
795
+ client.future(messageHash)
796
+ self.spawn(self.load_positions_snapshot, client, messageHash, type)
797
+ else:
798
+ self.positions[type] = ArrayCacheBySymbolBySide()
799
+
800
+ async def load_positions_snapshot(self, client, messageHash, type):
801
+ positions = await self.fetch_positions(None, {'type': type})
802
+ self.positions[type] = ArrayCacheBySymbolBySide()
803
+ cache = self.positions[type]
804
+ for i in range(0, len(positions)):
805
+ position = positions[i]
806
+ cache.append(position)
807
+ # don't remove the future from the .futures cache
808
+ future = client.futures[messageHash]
809
+ future.resolve(cache)
810
+ client.resolve(cache, type + ':position')
811
+
812
+ def handle_positions(self, client, message):
813
+ #
814
+ # {
815
+ # time: 1693158497,
816
+ # time_ms: 1693158497204,
817
+ # channel: 'futures.positions',
818
+ # event: 'update',
819
+ # result: [{
820
+ # contract: 'XRP_USDT',
821
+ # cross_leverage_limit: 0,
822
+ # entry_price: 0.5253,
823
+ # history_pnl: 0,
824
+ # history_point: 0,
825
+ # last_close_pnl: 0,
826
+ # leverage: 0,
827
+ # leverage_max: 50,
828
+ # liq_price: 0.0361,
829
+ # maintenance_rate: 0.01,
830
+ # margin: 4.89609962852,
831
+ # mode: 'single',
832
+ # realised_pnl: -0.0026265,
833
+ # realised_point: 0,
834
+ # risk_limit: 500000,
835
+ # size: 1,
836
+ # time: 1693158497,
837
+ # time_ms: 1693158497195,
838
+ # update_id: 1,
839
+ # user: '10444586'
840
+ # }]
841
+ # }
842
+ #
843
+ type = self.get_market_type_by_url(client.url)
844
+ data = self.safe_value(message, 'result', [])
845
+ cache = self.positions[type]
846
+ newPositions = []
847
+ for i in range(0, len(data)):
848
+ rawPosition = data[i]
849
+ position = self.parse_position(rawPosition)
850
+ newPositions.append(position)
851
+ cache.append(position)
852
+ messageHashes = self.find_message_hashes(client, type + ':positions::')
853
+ for i in range(0, len(messageHashes)):
854
+ messageHash = messageHashes[i]
855
+ parts = messageHash.split('::')
856
+ symbolsString = parts[1]
857
+ symbols = symbolsString.split(',')
858
+ positions = self.filter_by_array(newPositions, 'symbol', symbols, False)
859
+ if not self.is_empty(positions):
860
+ client.resolve(positions, messageHash)
861
+ client.resolve(newPositions, type + ':positions')
862
+
863
+ async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
864
+ """
865
+ watches information on multiple orders made by the user
866
+ :param str symbol: unified market symbol of the market orders were made in
867
+ :param int [since]: the earliest time in ms to fetch orders for
868
+ :param int [limit]: the maximum number of order structures to retrieve
869
+ :param dict [params]: extra parameters specific to the exchange API endpoint
870
+ :param str [params.type]: spot, margin, swap, future, or option. Required if listening to all symbols.
871
+ :param boolean [params.isInverse]: if future, listen to inverse or linear contracts
872
+ :returns dict[]: a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure
873
+ """
874
+ await self.load_markets()
875
+ market = None
876
+ if symbol is not None:
877
+ market = self.market(symbol)
878
+ symbol = market['symbol']
879
+ type = None
880
+ query = None
881
+ type, query = self.handle_market_type_and_params('watchOrders', market, params)
882
+ typeId = self.get_supported_mapping(type, {
883
+ 'spot': 'spot',
884
+ 'margin': 'spot',
885
+ 'future': 'futures',
886
+ 'swap': 'futures',
887
+ 'option': 'options',
888
+ })
889
+ channel = typeId + '.orders'
890
+ messageHash = 'orders'
891
+ payload = ['!' + 'all']
892
+ if symbol is not None:
893
+ messageHash += ':' + market['id']
894
+ payload = [market['id']]
895
+ subType = None
896
+ subType, query = self.handle_sub_type_and_params('watchOrders', market, query)
897
+ isInverse = (subType == 'inverse')
898
+ url = self.get_url_by_market_type(type, isInverse)
899
+ # uid required for non spot markets
900
+ requiresUid = (type != 'spot')
901
+ orders = await self.subscribe_private(url, messageHash, payload, channel, query, requiresUid)
902
+ if self.newUpdates:
903
+ limit = orders.getLimit(symbol, limit)
904
+ return self.filter_by_since_limit(orders, since, limit, 'timestamp', True)
905
+
906
+ def handle_order(self, client: Client, message):
907
+ #
908
+ # {
909
+ # "time": 1605175506,
910
+ # "channel": "spot.orders",
911
+ # "event": "update",
912
+ # "result": [
913
+ # {
914
+ # "id": "30784435",
915
+ # "user": 123456,
916
+ # "text": "t-abc",
917
+ # "create_time": "1605175506",
918
+ # "create_time_ms": "1605175506123",
919
+ # "update_time": "1605175506",
920
+ # "update_time_ms": "1605175506123",
921
+ # "event": "put",
922
+ # "currency_pair": "BTC_USDT",
923
+ # "type": "limit",
924
+ # "account": "spot",
925
+ # "side": "sell",
926
+ # "amount": "1",
927
+ # "price": "10001",
928
+ # "time_in_force": "gtc",
929
+ # "left": "1",
930
+ # "filled_total": "0",
931
+ # "fee": "0",
932
+ # "fee_currency": "USDT",
933
+ # "point_fee": "0",
934
+ # "gt_fee": "0",
935
+ # "gt_discount": True,
936
+ # "rebated_fee": "0",
937
+ # "rebated_fee_currency": "USDT"
938
+ # }
939
+ # ]
940
+ # }
941
+ #
942
+ orders = self.safe_value(message, 'result', [])
943
+ limit = self.safe_integer(self.options, 'ordersLimit', 1000)
944
+ if self.orders is None:
945
+ self.orders = ArrayCacheBySymbolById(limit)
946
+ stored = self.orders
947
+ marketIds: dict = {}
948
+ parsedOrders = self.parse_orders(orders)
949
+ for i in range(0, len(parsedOrders)):
950
+ parsed = parsedOrders[i]
951
+ # inject order status
952
+ info = self.safe_value(parsed, 'info')
953
+ event = self.safe_string(info, 'event')
954
+ if event == 'put' or event == 'update':
955
+ parsed['status'] = 'open'
956
+ elif event == 'finish':
957
+ status = self.safe_string(parsed, 'status')
958
+ if status is None:
959
+ left = self.safe_number(info, 'left')
960
+ parsed['status'] = 'closed' if (left == 0) else 'canceled'
961
+ stored.append(parsed)
962
+ symbol = parsed['symbol']
963
+ market = self.market(symbol)
964
+ marketIds[market['id']] = True
965
+ keys = list(marketIds.keys())
966
+ for i in range(0, len(keys)):
967
+ messageHash = 'orders:' + keys[i]
968
+ client.resolve(self.orders, messageHash)
969
+ client.resolve(self.orders, 'orders')
970
+
971
+ async def watch_my_liquidations(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
972
+ """
973
+ watch the public liquidations of a trading pair
974
+ :see: https://www.gate.io/docs/developers/futures/ws/en/#liquidates-api
975
+ :see: https://www.gate.io/docs/developers/delivery/ws/en/#liquidates-api
976
+ :see: https://www.gate.io/docs/developers/options/ws/en/#liquidates-channel
977
+ :param str symbol: unified CCXT market symbol
978
+ :param int [since]: the earliest time in ms to fetch liquidations for
979
+ :param int [limit]: the maximum number of liquidation structures to retrieve
980
+ :param dict [params]: exchange specific parameters for the bitmex api endpoint
981
+ :returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
982
+ """
983
+ return self.watch_my_liquidations_for_symbols([symbol], since, limit, params)
984
+
985
+ async def watch_my_liquidations_for_symbols(self, symbols: List[str] = None, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
986
+ """
987
+ watch the private liquidations of a trading pair
988
+ :see: https://www.gate.io/docs/developers/futures/ws/en/#liquidates-api
989
+ :see: https://www.gate.io/docs/developers/delivery/ws/en/#liquidates-api
990
+ :see: https://www.gate.io/docs/developers/options/ws/en/#liquidates-channel
991
+ :param str symbol: unified CCXT market symbol
992
+ :param int [since]: the earliest time in ms to fetch liquidations for
993
+ :param int [limit]: the maximum number of liquidation structures to retrieve
994
+ :param dict [params]: exchange specific parameters for the gate api endpoint
995
+ :returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
996
+ """
997
+ await self.load_markets()
998
+ symbols = self.market_symbols(symbols, None, True, True)
999
+ market = self.get_market_from_symbols(symbols)
1000
+ type = None
1001
+ query = None
1002
+ type, query = self.handle_market_type_and_params('watchMyLiquidationsForSymbols', market, params)
1003
+ typeId = self.get_supported_mapping(type, {
1004
+ 'future': 'futures',
1005
+ 'swap': 'futures',
1006
+ 'option': 'options',
1007
+ })
1008
+ subType = None
1009
+ subType, query = self.handle_sub_type_and_params('watchMyLiquidationsForSymbols', market, query)
1010
+ isInverse = (subType == 'inverse')
1011
+ url = self.get_url_by_market_type(type, isInverse)
1012
+ payload = []
1013
+ messageHash = ''
1014
+ if self.is_empty(symbols):
1015
+ if typeId != 'futures' and not isInverse:
1016
+ raise BadRequest(self.id + ' watchMyLiquidationsForSymbols() does not support listening to all symbols, you must call watchMyLiquidations() instead for each symbol you wish to watch.')
1017
+ messageHash = 'myLiquidations'
1018
+ payload.append('not all')
1019
+ else:
1020
+ symbolsLength = len(symbols)
1021
+ if symbolsLength != 1:
1022
+ raise BadRequest(self.id + ' watchMyLiquidationsForSymbols() only allows one symbol at a time. To listen to several symbols call watchMyLiquidationsForSymbols() several times.')
1023
+ messageHash = 'myLiquidations::' + symbols[0]
1024
+ payload.append(market['id'])
1025
+ channel = typeId + '.liquidates'
1026
+ newLiquidations = await self.subscribe_private(url, messageHash, payload, channel, query, True)
1027
+ if self.newUpdates:
1028
+ return newLiquidations
1029
+ return self.filter_by_symbols_since_limit(self.liquidations, symbols, since, limit, True)
1030
+
1031
+ def handle_liquidation(self, client: Client, message):
1032
+ #
1033
+ # future / delivery
1034
+ # {
1035
+ # "channel":"futures.liquidates",
1036
+ # "event":"update",
1037
+ # "time":1541505434,
1038
+ # "time_ms":1541505434123,
1039
+ # "result":[
1040
+ # {
1041
+ # "entry_price":209,
1042
+ # "fill_price":215.1,
1043
+ # "left":0,
1044
+ # "leverage":0.0,
1045
+ # "liq_price":213,
1046
+ # "margin":0.007816722941,
1047
+ # "mark_price":213,
1048
+ # "order_id":4093362,
1049
+ # "order_price":215.1,
1050
+ # "size":-124,
1051
+ # "time":1541486601,
1052
+ # "time_ms":1541486601123,
1053
+ # "contract":"BTC_USD",
1054
+ # "user":"1040xxxx"
1055
+ # }
1056
+ # ]
1057
+ # }
1058
+ # option
1059
+ # {
1060
+ # "channel":"options.liquidates",
1061
+ # "event":"update",
1062
+ # "time":1630654851,
1063
+ # "result":[
1064
+ # {
1065
+ # "user":"1xxxx",
1066
+ # "init_margin":1190,
1067
+ # "maint_margin":1042.5,
1068
+ # "order_margin":0,
1069
+ # "time":1639051907,
1070
+ # "time_ms":1639051907000
1071
+ # }
1072
+ # ]
1073
+ # }
1074
+ #
1075
+ rawLiquidations = self.safe_list(message, 'result', [])
1076
+ newLiquidations = []
1077
+ for i in range(0, len(rawLiquidations)):
1078
+ rawLiquidation = rawLiquidations[i]
1079
+ liquidation = self.parse_ws_liquidation(rawLiquidation)
1080
+ symbol = self.safe_string(liquidation, 'symbol')
1081
+ liquidations = self.safe_value(self.liquidations, symbol)
1082
+ if liquidations is None:
1083
+ limit = self.safe_integer(self.options, 'liquidationsLimit', 1000)
1084
+ liquidations = ArrayCache(limit)
1085
+ liquidations.append(liquidation)
1086
+ self.liquidations[symbol] = liquidations
1087
+ client.resolve(liquidations, 'myLiquidations::' + symbol)
1088
+ client.resolve(newLiquidations, 'myLiquidations')
1089
+
1090
+ def parse_ws_liquidation(self, liquidation, market=None):
1091
+ #
1092
+ # future / delivery
1093
+ # {
1094
+ # "entry_price": 209,
1095
+ # "fill_price": 215.1,
1096
+ # "left": 0,
1097
+ # "leverage": 0.0,
1098
+ # "liq_price": 213,
1099
+ # "margin": 0.007816722941,
1100
+ # "mark_price": 213,
1101
+ # "order_id": 4093362,
1102
+ # "order_price": 215.1,
1103
+ # "size": -124,
1104
+ # "time": 1541486601,
1105
+ # "time_ms": 1541486601123,
1106
+ # "contract": "BTC_USD",
1107
+ # "user": "1040xxxx"
1108
+ # }
1109
+ # option
1110
+ # {
1111
+ # "user": "1xxxx",
1112
+ # "init_margin": 1190,
1113
+ # "maint_margin": 1042.5,
1114
+ # "order_margin": 0,
1115
+ # "time": 1639051907,
1116
+ # "time_ms": 1639051907000
1117
+ # }
1118
+ #
1119
+ marketId = self.safe_string(liquidation, 'contract')
1120
+ market = self.safe_market(marketId, market)
1121
+ timestamp = self.safe_integer(liquidation, 'time_ms')
1122
+ originalSize = self.safe_string(liquidation, 'size')
1123
+ left = self.safe_string(liquidation, 'left')
1124
+ amount = Precise.string_abs(Precise.string_sub(originalSize, left))
1125
+ return self.safe_liquidation({
1126
+ 'info': liquidation,
1127
+ 'symbol': self.safe_symbol(marketId, market),
1128
+ 'contracts': self.parse_number(amount),
1129
+ 'contractSize': self.safe_number(market, 'contractSize'),
1130
+ 'price': self.safe_number(liquidation, 'fill_price'),
1131
+ 'baseValue': None,
1132
+ 'quoteValue': None,
1133
+ 'timestamp': timestamp,
1134
+ 'datetime': self.iso8601(timestamp),
1135
+ })
1136
+
1137
+ def handle_error_message(self, client: Client, message):
1138
+ # {
1139
+ # "time": 1647274664,
1140
+ # "channel": "futures.orders",
1141
+ # "event": "subscribe",
1142
+ # "error": {code: 2, message: "unknown contract BTC_USDT_20220318"},
1143
+ # }
1144
+ # {
1145
+ # "time": 1647276473,
1146
+ # "channel": "futures.orders",
1147
+ # "event": "subscribe",
1148
+ # "error": {
1149
+ # "code": 4,
1150
+ # "message": "{"label":"INVALID_KEY","message":"Invalid key provided"}\n"
1151
+ # },
1152
+ # "result": null
1153
+ # }
1154
+ error = self.safe_value(message, 'error')
1155
+ code = self.safe_integer(error, 'code')
1156
+ id = self.safe_string(message, 'id')
1157
+ if id is None:
1158
+ return False
1159
+ if code is not None:
1160
+ messageHash = self.safe_string(client.subscriptions, id)
1161
+ if messageHash is not None:
1162
+ try:
1163
+ self.throw_exactly_matched_exception(self.exceptions['ws']['exact'], code, self.json(message))
1164
+ except Exception as e:
1165
+ client.reject(e, messageHash)
1166
+ if messageHash in client.subscriptions:
1167
+ del client.subscriptions[messageHash]
1168
+ del client.subscriptions[id]
1169
+ return True
1170
+ return False
1171
+
1172
+ def handle_balance_subscription(self, client: Client, message, subscription=None):
1173
+ self.balance = {}
1174
+
1175
+ def handle_subscription_status(self, client: Client, message):
1176
+ channel = self.safe_string(message, 'channel')
1177
+ methods: dict = {
1178
+ 'balance': self.handle_balance_subscription,
1179
+ 'spot.order_book_update': self.handle_order_book_subscription,
1180
+ 'futures.order_book_update': self.handle_order_book_subscription,
1181
+ }
1182
+ id = self.safe_string(message, 'id')
1183
+ if channel in methods:
1184
+ subscriptionHash = self.safe_string(client.subscriptions, id)
1185
+ subscription = self.safe_value(client.subscriptions, subscriptionHash)
1186
+ method = methods[channel]
1187
+ method(client, message, subscription)
1188
+ if id in client.subscriptions:
1189
+ del client.subscriptions[id]
1190
+
1191
+ def handle_message(self, client: Client, message):
1192
+ #
1193
+ # subscribe
1194
+ # {
1195
+ # "time": 1649062304,
1196
+ # "id": 1649062303,
1197
+ # "channel": "spot.candlesticks",
1198
+ # "event": "subscribe",
1199
+ # "result": {status: "success"}
1200
+ # }
1201
+ #
1202
+ # candlestick
1203
+ # {
1204
+ # "time": 1649063328,
1205
+ # "channel": "spot.candlesticks",
1206
+ # "event": "update",
1207
+ # "result": {
1208
+ # "t": "1649063280",
1209
+ # "v": "58932.23174896",
1210
+ # "c": "45966.47",
1211
+ # "h": "45997.24",
1212
+ # "l": "45966.47",
1213
+ # "o": "45975.18",
1214
+ # "n": "1m_BTC_USDT",
1215
+ # "a": "1.281699"
1216
+ # }
1217
+ # }
1218
+ #
1219
+ # orders
1220
+ # {
1221
+ # "time": 1630654851,
1222
+ # "channel": "options.orders", or futures.orders or spot.orders
1223
+ # "event": "update",
1224
+ # "result": [
1225
+ # {
1226
+ # "contract": "BTC_USDT-20211130-65000-C",
1227
+ # "create_time": 1637897000,
1228
+ # (...)
1229
+ # ]
1230
+ # }
1231
+ # orderbook
1232
+ # {
1233
+ # "time": 1649770525,
1234
+ # "channel": "spot.order_book_update",
1235
+ # "event": "update",
1236
+ # "result": {
1237
+ # "t": 1649770525653,
1238
+ # "e": "depthUpdate",
1239
+ # "E": 1649770525,
1240
+ # "s": "LTC_USDT",
1241
+ # "U": 2622525645,
1242
+ # "u": 2622525665,
1243
+ # "b": [
1244
+ # [Array], [Array],
1245
+ # [Array], [Array],
1246
+ # [Array], [Array],
1247
+ # [Array], [Array],
1248
+ # [Array], [Array],
1249
+ # [Array]
1250
+ # ],
1251
+ # "a": [
1252
+ # [Array], [Array],
1253
+ # [Array], [Array],
1254
+ # [Array], [Array],
1255
+ # [Array], [Array],
1256
+ # [Array], [Array],
1257
+ # [Array]
1258
+ # ]
1259
+ # }
1260
+ # }
1261
+ #
1262
+ # balance update
1263
+ #
1264
+ # {
1265
+ # "time": 1653664351,
1266
+ # "channel": "spot.balances",
1267
+ # "event": "update",
1268
+ # "result": [
1269
+ # {
1270
+ # "timestamp": "1653664351",
1271
+ # "timestamp_ms": "1653664351017",
1272
+ # "user": "10406147",
1273
+ # "currency": "LTC",
1274
+ # "change": "-0.0002000000000000",
1275
+ # "total": "0.09986000000000000000",
1276
+ # "available": "0.09986000000000000000"
1277
+ # }
1278
+ # ]
1279
+ # }
1280
+ #
1281
+ if self.handle_error_message(client, message):
1282
+ return
1283
+ event = self.safe_string(message, 'event')
1284
+ if event == 'subscribe':
1285
+ self.handle_subscription_status(client, message)
1286
+ return
1287
+ channel = self.safe_string(message, 'channel', '')
1288
+ channelParts = channel.split('.')
1289
+ channelType = self.safe_value(channelParts, 1)
1290
+ v4Methods: dict = {
1291
+ 'usertrades': self.handle_my_trades,
1292
+ 'candlesticks': self.handle_ohlcv,
1293
+ 'orders': self.handle_order,
1294
+ 'positions': self.handle_positions,
1295
+ 'tickers': self.handle_ticker,
1296
+ 'book_ticker': self.handle_bid_ask,
1297
+ 'trades': self.handle_trades,
1298
+ 'order_book_update': self.handle_order_book,
1299
+ 'balances': self.handle_balance,
1300
+ 'liquidates': self.handle_liquidation,
1301
+ }
1302
+ method = self.safe_value(v4Methods, channelType)
1303
+ if method is not None:
1304
+ method(client, message)
1305
+
1306
+ def get_url_by_market(self, market):
1307
+ baseUrl = self.urls['api'][market['type']]
1308
+ if market['contract']:
1309
+ return baseUrl['usdt'] if market['linear'] else baseUrl['btc']
1310
+ else:
1311
+ return baseUrl
1312
+
1313
+ def get_type_by_market(self, market):
1314
+ if market['spot']:
1315
+ return 'spot'
1316
+ elif market['option']:
1317
+ return 'options'
1318
+ else:
1319
+ return 'futures'
1320
+
1321
+ def get_url_by_market_type(self, type, isInverse=False):
1322
+ api = self.urls['api']
1323
+ url = api[type]
1324
+ if (type == 'swap') or (type == 'future'):
1325
+ return url['btc'] if isInverse else url['usdt']
1326
+ else:
1327
+ return url
1328
+
1329
+ def get_market_type_by_url(self, url: str):
1330
+ findBy: dict = {
1331
+ 'op-': 'option',
1332
+ 'delivery': 'future',
1333
+ 'fx': 'swap',
1334
+ }
1335
+ keys = list(findBy.keys())
1336
+ for i in range(0, len(keys)):
1337
+ key = keys[i]
1338
+ value = findBy[key]
1339
+ if url.find(key) >= 0:
1340
+ return value
1341
+ return 'spot'
1342
+
1343
+ def request_id(self):
1344
+ # their support said that reqid must be an int32, not documented
1345
+ reqid = self.sum(self.safe_integer(self.options, 'reqid', 0), 1)
1346
+ self.options['reqid'] = reqid
1347
+ return reqid
1348
+
1349
+ async def subscribe_public(self, url, messageHash, payload, channel, params={}, subscription=None):
1350
+ requestId = self.request_id()
1351
+ time = self.seconds()
1352
+ request: dict = {
1353
+ 'id': requestId,
1354
+ 'time': time,
1355
+ 'channel': channel,
1356
+ 'event': 'subscribe',
1357
+ 'payload': payload,
1358
+ }
1359
+ if subscription is not None:
1360
+ client = self.client(url)
1361
+ if not (messageHash in client.subscriptions):
1362
+ tempSubscriptionHash = str(requestId)
1363
+ client.subscriptions[tempSubscriptionHash] = messageHash
1364
+ message = self.extend(request, params)
1365
+ return await self.watch(url, messageHash, message, messageHash, subscription)
1366
+
1367
+ async def subscribe_public_multiple(self, url, messageHashes, payload, channel, params={}):
1368
+ requestId = self.request_id()
1369
+ time = self.seconds()
1370
+ request: dict = {
1371
+ 'id': requestId,
1372
+ 'time': time,
1373
+ 'channel': channel,
1374
+ 'event': 'subscribe',
1375
+ 'payload': payload,
1376
+ }
1377
+ message = self.extend(request, params)
1378
+ return await self.watch_multiple(url, messageHashes, message, messageHashes)
1379
+
1380
+ async def subscribe_private(self, url, messageHash, payload, channel, params, requiresUid=False):
1381
+ self.check_required_credentials()
1382
+ # uid is required for some subscriptions only so it's not a part of required credentials
1383
+ if requiresUid:
1384
+ if self.uid is None or len(self.uid) == 0:
1385
+ raise ArgumentsRequired(self.id + ' requires uid to subscribe')
1386
+ idArray = [self.uid]
1387
+ if payload is None:
1388
+ payload = idArray
1389
+ else:
1390
+ payload = self.array_concat(idArray, payload)
1391
+ time = self.seconds()
1392
+ event = 'subscribe'
1393
+ signaturePayload = 'channel=' + channel + '&' + 'event=' + event + '&' + 'time=' + str(time)
1394
+ signature = self.hmac(self.encode(signaturePayload), self.encode(self.secret), hashlib.sha512, 'hex')
1395
+ auth: dict = {
1396
+ 'method': 'api_key',
1397
+ 'KEY': self.apiKey,
1398
+ 'SIGN': signature,
1399
+ }
1400
+ requestId = self.request_id()
1401
+ request: dict = {
1402
+ 'id': requestId,
1403
+ 'time': time,
1404
+ 'channel': channel,
1405
+ 'event': 'subscribe',
1406
+ 'auth': auth,
1407
+ }
1408
+ if payload is not None:
1409
+ request['payload'] = payload
1410
+ client = self.client(url)
1411
+ if not (messageHash in client.subscriptions):
1412
+ tempSubscriptionHash = str(requestId)
1413
+ # in case of authenticationError we will throw
1414
+ client.subscriptions[tempSubscriptionHash] = messageHash
1415
+ message = self.extend(request, params)
1416
+ return await self.watch(url, messageHash, message, messageHash)