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/poloniex.py ADDED
@@ -0,0 +1,1166 @@
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 BadRequest
15
+ from ccxt.base.errors import InvalidOrder
16
+ from ccxt.base.precise import Precise
17
+
18
+
19
+ class poloniex(ccxt.async_support.poloniex):
20
+
21
+ def describe(self):
22
+ return self.deep_extend(super(poloniex, self).describe(), {
23
+ 'has': {
24
+ 'ws': True,
25
+ 'watchOHLCV': True,
26
+ 'watchOrderBook': True,
27
+ 'watchTicker': True,
28
+ 'watchTickers': True,
29
+ 'watchTrades': True,
30
+ 'watchBalance': True,
31
+ 'watchStatus': False,
32
+ 'watchOrders': True,
33
+ 'watchMyTrades': True,
34
+ 'createOrderWs': True,
35
+ 'editOrderWs': False,
36
+ 'fetchOpenOrdersWs': False,
37
+ 'fetchOrderWs': False,
38
+ 'cancelOrderWs': True,
39
+ 'cancelOrdersWs': True,
40
+ 'cancelAllOrdersWs': True,
41
+ 'fetchTradesWs': False,
42
+ 'fetchBalanceWs': False,
43
+ },
44
+ 'urls': {
45
+ 'api': {
46
+ 'ws': {
47
+ 'public': 'wss://ws.poloniex.com/ws/public',
48
+ 'private': 'wss://ws.poloniex.com/ws/private',
49
+ },
50
+ },
51
+ },
52
+ 'options': {
53
+ 'createMarketBuyOrderRequiresPrice': True,
54
+ 'tradesLimit': 1000,
55
+ 'ordersLimit': 1000,
56
+ 'OHLCVLimit': 1000,
57
+ 'watchOrderBook': {
58
+ 'name': 'book_lv2', # can also be 'book'
59
+ },
60
+ 'connectionsLimit': 2000, # 2000 public, 2000 private, 4000 total, only for subscribe events, unsubscribe not restricted
61
+ 'requestsLimit': 500, # per second, only for subscribe events, unsubscribe not restricted
62
+ 'timeframes': {
63
+ '1m': 'candles_minute_1',
64
+ '5m': 'candles_minute_5',
65
+ '10m': 'candles_minute_10',
66
+ '15m': 'candles_minute_15',
67
+ '30m': 'candles_minute_30',
68
+ '1h': 'candles_hour_1',
69
+ '2h': 'candles_hour_2',
70
+ '4h': 'candles_hour_4',
71
+ '6h': 'candles_hour_6',
72
+ '12h': 'candles_hour_12',
73
+ '1d': 'candles_day_1',
74
+ '3d': 'candles_day_3',
75
+ '1w': 'candles_week_1',
76
+ '1M': 'candles_month_1',
77
+ },
78
+ },
79
+ 'streaming': {
80
+ 'keepAlive': 15000,
81
+ 'ping': self.ping,
82
+ },
83
+ })
84
+
85
+ async def authenticate(self, params={}):
86
+ """
87
+ * @ignore
88
+ authenticates the user to access private web socket channels
89
+ :see: https://docs.poloniex.com/#authenticated-channels-market-data-authentication
90
+ :returns dict: response from exchange
91
+ """
92
+ self.check_required_credentials()
93
+ timestamp = self.number_to_string(self.milliseconds())
94
+ url = self.urls['api']['ws']['private']
95
+ messageHash = 'authenticated'
96
+ client = self.client(url)
97
+ future = self.safe_value(client.subscriptions, messageHash)
98
+ if future is None:
99
+ accessPath = '/ws'
100
+ requestString = 'GET\n' + accessPath + '\nsignTimestamp=' + timestamp
101
+ signature = self.hmac(self.encode(requestString), self.encode(self.secret), hashlib.sha256, 'base64')
102
+ request: dict = {
103
+ 'event': 'subscribe',
104
+ 'channel': ['auth'],
105
+ 'params': {
106
+ 'key': self.apiKey,
107
+ 'signTimestamp': timestamp,
108
+ 'signature': signature,
109
+ 'signatureMethod': 'HmacSHA256', # optional
110
+ 'signatureVersion': '2', # optional
111
+ },
112
+ }
113
+ message = self.extend(request, params)
114
+ future = await self.watch(url, messageHash, message, messageHash)
115
+ #
116
+ # {
117
+ # "data": {
118
+ # "success": True,
119
+ # "ts": 1645597033915
120
+ # },
121
+ # "channel": "auth"
122
+ # }
123
+ #
124
+ # # Failure to return results
125
+ #
126
+ # {
127
+ # "data": {
128
+ # "success": False,
129
+ # "message": "Authentication failed!",
130
+ # "ts": 1646276295075
131
+ # },
132
+ # "channel": "auth"
133
+ # }
134
+ #
135
+ client.subscriptions[messageHash] = future
136
+ return future
137
+
138
+ async def subscribe(self, name: str, messageHash: str, isPrivate: bool, symbols: Strings = None, params={}):
139
+ """
140
+ * @ignore
141
+ Connects to a websocket channel
142
+ :param str name: name of the channel
143
+ :param boolean isPrivate: True for the authenticated url, False for the public url
144
+ :param str[]|None symbols: CCXT market symbols
145
+ :param dict [params]: extra parameters specific to the poloniex api
146
+ :returns dict: data from the websocket stream
147
+ """
148
+ publicOrPrivate = 'private' if isPrivate else 'public'
149
+ url = self.urls['api']['ws'][publicOrPrivate]
150
+ subscribe: dict = {
151
+ 'event': 'subscribe',
152
+ 'channel': [
153
+ name,
154
+ ],
155
+ }
156
+ marketIds = []
157
+ if self.is_empty(symbols):
158
+ marketIds.append('all')
159
+ else:
160
+ messageHash = messageHash + '::' + ','.join(symbols)
161
+ marketIds = self.market_ids(symbols)
162
+ if name != 'balances':
163
+ subscribe['symbols'] = marketIds
164
+ request = self.extend(subscribe, params)
165
+ return await self.watch(url, messageHash, request, messageHash)
166
+
167
+ async def trade_request(self, name: str, params={}):
168
+ """
169
+ * @ignore
170
+ Connects to a websocket channel
171
+ :param str name: name of the channel
172
+ :param str[]|None symbols: CCXT market symbols
173
+ :param dict [params]: extra parameters specific to the poloniex api
174
+ :returns dict: data from the websocket stream
175
+ """
176
+ url = self.urls['api']['ws']['private']
177
+ messageHash = str(self.nonce())
178
+ subscribe: dict = {
179
+ 'id': messageHash,
180
+ 'event': name,
181
+ 'params': params,
182
+ }
183
+ return await self.watch(url, messageHash, subscribe, messageHash)
184
+
185
+ async def create_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
186
+ """
187
+ :see: https://docs.poloniex.com/#authenticated-channels-trade-requests-create-order
188
+ create a trade order
189
+ :param str symbol: unified symbol of the market to create an order in
190
+ :param str type: 'market' or 'limit'
191
+ :param str side: 'buy' or 'sell'
192
+ :param float amount: how much of currency you want to trade in units of base currency
193
+ :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
194
+ :param dict [params]: extra parameters specific to the poloniex api endpoint
195
+ :param str [params.timeInForce]: GTC(default), IOC, FOK
196
+ :param str [params.clientOrderId]: Maximum 64-character length.*
197
+ :param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
198
+ *
199
+ * EXCHANGE SPECIFIC PARAMETERS
200
+ :param str [params.amount]: quote units for the order
201
+ :param boolean [params.allowBorrow]: allow order to be placed by borrowing funds(Default: False)
202
+ :param str [params.stpMode]: self-trade prevention, defaults to expire_taker, none: enable self-trade; expire_taker: taker order will be canceled when self-trade happens
203
+ :param str [params.slippageTolerance]: used to control the maximum slippage ratio, the value range is greater than 0 and less than 1
204
+ :returns dict: an `order structure <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
205
+ """
206
+ await self.load_markets()
207
+ await self.authenticate()
208
+ market = self.market(symbol)
209
+ uppercaseType = type.upper()
210
+ uppercaseSide = side.upper()
211
+ isPostOnly = self.is_post_only(uppercaseType == 'MARKET', uppercaseType == 'LIMIT_MAKER', params)
212
+ if isPostOnly:
213
+ uppercaseType = 'LIMIT_MAKER'
214
+ request: dict = {
215
+ 'symbol': market['id'],
216
+ 'side': side.upper(),
217
+ 'type': type.upper(),
218
+ }
219
+ if (uppercaseType == 'MARKET') and (uppercaseSide == 'BUY'):
220
+ quoteAmount = None
221
+ createMarketBuyOrderRequiresPrice = True
222
+ createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
223
+ cost = self.safe_number(params, 'cost')
224
+ params = self.omit(params, 'cost')
225
+ if cost is not None:
226
+ quoteAmount = self.cost_to_precision(symbol, cost)
227
+ elif createMarketBuyOrderRequiresPrice:
228
+ if price is None:
229
+ raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend(quote quantity) in the amount argument')
230
+ else:
231
+ amountString = self.number_to_string(amount)
232
+ priceString = self.number_to_string(price)
233
+ costRequest = Precise.string_mul(amountString, priceString)
234
+ quoteAmount = self.cost_to_precision(symbol, costRequest)
235
+ else:
236
+ quoteAmount = self.cost_to_precision(symbol, amount)
237
+ request['amount'] = quoteAmount
238
+ else:
239
+ request['quantity'] = self.amount_to_precision(market['symbol'], amount)
240
+ if price is not None:
241
+ request['price'] = self.price_to_precision(symbol, price)
242
+ return await self.trade_request('createOrder', self.extend(request, params))
243
+
244
+ async def cancel_order_ws(self, id: str, symbol: Str = None, params={}):
245
+ """
246
+ :see: https://docs.poloniex.com/#authenticated-channels-trade-requests-cancel-multiple-orders
247
+ cancel multiple orders
248
+ :param str id: order id
249
+ :param str [symbol]: unified market symbol
250
+ :param dict [params]: extra parameters specific to the poloniex api endpoint
251
+ :param str [params.clientOrderId]: client order id
252
+ :returns dict: an list of `order structures <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
253
+ """
254
+ clientOrderId = self.safe_string(params, 'clientOrderId')
255
+ if clientOrderId is not None:
256
+ clientOrderIds = self.safe_value(params, 'clientOrderId', [])
257
+ params['clientOrderIds'] = self.array_concat(clientOrderIds, [clientOrderId])
258
+ return await self.cancel_orders_ws([id], symbol, params)
259
+
260
+ async def cancel_orders_ws(self, ids: List[str], symbol: Str = None, params={}):
261
+ """
262
+ :see: https://docs.poloniex.com/#authenticated-channels-trade-requests-cancel-multiple-orders
263
+ cancel multiple orders
264
+ :param str[] ids: order ids
265
+ :param str symbol: unified market symbol, default is None
266
+ :param dict [params]: extra parameters specific to the poloniex api endpoint
267
+ :param str[] [params.clientOrderIds]: client order ids
268
+ :returns dict: an list of `order structures <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
269
+ """
270
+ await self.load_markets()
271
+ await self.authenticate()
272
+ request: dict = {
273
+ 'orderIds': ids,
274
+ }
275
+ return await self.trade_request('cancelOrders', self.extend(request, params))
276
+
277
+ async def cancel_all_orders_ws(self, symbol: Str = None, params={}):
278
+ """
279
+ :see: https://docs.poloniex.com/#authenticated-channels-trade-requests-cancel-all-orders
280
+ cancel all open orders of a type. Only applicable to Option in Portfolio Margin mode, and MMP privilege is required.
281
+ :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
282
+ :param dict [params]: extra parameters specific to the poloniex api endpoint
283
+ :returns dict[]: a list of `order structures <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
284
+ """
285
+ await self.load_markets()
286
+ await self.authenticate()
287
+ return await self.trade_request('cancelAllOrders', params)
288
+
289
+ def handle_order_request(self, client: Client, message):
290
+ #
291
+ # {
292
+ # "id": "1234567",
293
+ # "data": [{
294
+ # "orderId": 205343650954092544,
295
+ # "clientOrderId": "",
296
+ # "message": "",
297
+ # "code": 200
298
+ # }]
299
+ # }
300
+ #
301
+ messageHash = self.safe_string(message, 'id')
302
+ data = self.safe_value(message, 'data', [])
303
+ orders = []
304
+ for i in range(0, len(data)):
305
+ order = data[i]
306
+ parsedOrder = self.parse_ws_order(order)
307
+ orders.append(parsedOrder)
308
+ client.resolve(orders, messageHash)
309
+
310
+ async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
311
+ """
312
+ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
313
+ :see: https://docs.poloniex.com/#public-channels-market-data-candlesticks
314
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
315
+ :param str timeframe: the length of time each candle represents
316
+ :param int [since]: timestamp in ms of the earliest candle to fetch
317
+ :param int [limit]: the maximum amount of candles to fetch
318
+ :param dict [params]: extra parameters specific to the exchange API endpoint
319
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
320
+ """
321
+ await self.load_markets()
322
+ timeframes = self.safe_value(self.options, 'timeframes', {})
323
+ channel = self.safe_string(timeframes, timeframe, timeframe)
324
+ if channel is None:
325
+ raise BadRequest(self.id + ' watchOHLCV cannot take a timeframe of ' + timeframe)
326
+ ohlcv = await self.subscribe(channel, channel, False, [symbol], params)
327
+ if self.newUpdates:
328
+ limit = ohlcv.getLimit(symbol, limit)
329
+ return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
330
+
331
+ async def watch_ticker(self, symbol: str, params={}) -> Ticker:
332
+ """
333
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
334
+ :see: https://docs.poloniex.com/#public-channels-market-data-ticker
335
+ :param str symbol: unified symbol of the market to fetch the ticker for
336
+ :param dict [params]: extra parameters specific to the exchange API endpoint
337
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
338
+ """
339
+ await self.load_markets()
340
+ symbol = self.symbol(symbol)
341
+ tickers = await self.watch_tickers([symbol], params)
342
+ return self.safe_value(tickers, symbol)
343
+
344
+ async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
345
+ """
346
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
347
+ :see: https://docs.poloniex.com/#public-channels-market-data-ticker
348
+ :param str symbol: unified symbol of the market to fetch the ticker for
349
+ :param dict [params]: extra parameters specific to the exchange API endpoint
350
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
351
+ """
352
+ await self.load_markets()
353
+ name = 'ticker'
354
+ symbols = self.market_symbols(symbols)
355
+ newTickers = await self.subscribe(name, name, False, symbols, params)
356
+ if self.newUpdates:
357
+ return newTickers
358
+ return self.filter_by_array(self.tickers, 'symbol', symbols)
359
+
360
+ async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
361
+ """
362
+ get the list of most recent trades for a particular symbol
363
+ :see: https://docs.poloniex.com/#public-channels-market-data-trades
364
+ :param str symbol: unified symbol of the market to fetch trades for
365
+ :param int [since]: timestamp in ms of the earliest trade to fetch
366
+ :param int [limit]: the maximum amount of trades to fetch
367
+ :param dict [params]: extra parameters specific to the exchange API endpoint
368
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
369
+ """
370
+ await self.load_markets()
371
+ symbol = self.symbol(symbol)
372
+ name = 'trades'
373
+ trades = await self.subscribe(name, name, False, [symbol], params)
374
+ if self.newUpdates:
375
+ limit = trades.getLimit(symbol, limit)
376
+ return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
377
+
378
+ async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
379
+ """
380
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
381
+ :see: https://docs.poloniex.com/#public-channels-market-data-book-level-2
382
+ :param str symbol: unified symbol of the market to fetch the order book for
383
+ :param int [limit]: not used by poloniex watchOrderBook
384
+ :param dict [params]: extra parameters specific to the exchange API endpoint
385
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
386
+ """
387
+ await self.load_markets()
388
+ watchOrderBookOptions = self.safe_value(self.options, 'watchOrderBook')
389
+ name = self.safe_string(watchOrderBookOptions, 'name', 'book_lv2')
390
+ name, params = self.handle_option_and_params(params, 'method', 'name', name)
391
+ orderbook = await self.subscribe(name, name, False, [symbol], params)
392
+ return orderbook.limit()
393
+
394
+ async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
395
+ """
396
+ watches information on multiple orders made by the user
397
+ :see: https://docs.poloniex.com/#authenticated-channels-market-data-orders
398
+ :param str symbol: unified market symbol of the market orders were made in
399
+ :param int [since]: not used by poloniex watchOrders
400
+ :param int [limit]: not used by poloniex watchOrders
401
+ :param dict [params]: extra parameters specific to the exchange API endpoint
402
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
403
+ """
404
+ await self.load_markets()
405
+ name = 'orders'
406
+ await self.authenticate()
407
+ if symbol is not None:
408
+ symbol = self.symbol(symbol)
409
+ symbols = None if (symbol is None) else [symbol]
410
+ orders = await self.subscribe(name, name, True, symbols, params)
411
+ if self.newUpdates:
412
+ limit = orders.getLimit(symbol, limit)
413
+ return self.filter_by_since_limit(orders, since, limit, 'timestamp', True)
414
+
415
+ async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
416
+ """
417
+ watches information on multiple trades made by the user using orders stream
418
+ :see: https://docs.poloniex.com/#authenticated-channels-market-data-orders
419
+ :param str symbol: unified market symbol of the market orders were made in
420
+ :param int [since]: not used by poloniex watchMyTrades
421
+ :param int [limit]: not used by poloniex watchMyTrades
422
+ :param dict [params]: extra parameters specific to the poloniex strean
423
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
424
+ """
425
+ await self.load_markets()
426
+ name = 'orders'
427
+ messageHash = 'myTrades'
428
+ await self.authenticate()
429
+ if symbol is not None:
430
+ symbol = self.symbol(symbol)
431
+ symbols = None if (symbol is None) else [symbol]
432
+ trades = await self.subscribe(name, messageHash, True, symbols, params)
433
+ if self.newUpdates:
434
+ limit = trades.getLimit(symbol, limit)
435
+ return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
436
+
437
+ async def watch_balance(self, params={}) -> Balances:
438
+ """
439
+ watch balance and get the amount of funds available for trading or funds locked in orders
440
+ :see: https://docs.poloniex.com/#authenticated-channels-market-data-balances
441
+ :param dict [params]: extra parameters specific to the exchange API endpoint
442
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
443
+ """
444
+ await self.load_markets()
445
+ name = 'balances'
446
+ await self.authenticate()
447
+ return await self.subscribe(name, name, True, None, params)
448
+
449
+ def parse_ws_ohlcv(self, ohlcv, market=None) -> list:
450
+ #
451
+ # {
452
+ # "symbol": "BTC_USDT",
453
+ # "amount": "840.7240416",
454
+ # "high": "24832.35",
455
+ # "quantity": "0.033856",
456
+ # "tradeCount": 1,
457
+ # "low": "24832.35",
458
+ # "closeTime": 1676942519999,
459
+ # "startTime": 1676942460000,
460
+ # "close": "24832.35",
461
+ # "open": "24832.35",
462
+ # "ts": 1676942492072
463
+ # }
464
+ #
465
+ return [
466
+ self.safe_integer(ohlcv, 'startTime'),
467
+ self.safe_number(ohlcv, 'open'),
468
+ self.safe_number(ohlcv, 'high'),
469
+ self.safe_number(ohlcv, 'low'),
470
+ self.safe_number(ohlcv, 'close'),
471
+ self.safe_number(ohlcv, 'quantity'),
472
+ ]
473
+
474
+ def handle_ohlcv(self, client: Client, message):
475
+ #
476
+ # {
477
+ # "channel": "candles_minute_1",
478
+ # "data": [
479
+ # {
480
+ # "symbol": "BTC_USDT",
481
+ # "amount": "840.7240416",
482
+ # "high": "24832.35",
483
+ # "quantity": "0.033856",
484
+ # "tradeCount": 1,
485
+ # "low": "24832.35",
486
+ # "closeTime": 1676942519999,
487
+ # "startTime": 1676942460000,
488
+ # "close": "24832.35",
489
+ # "open": "24832.35",
490
+ # "ts": 1676942492072
491
+ # }
492
+ # ]
493
+ # }
494
+ #
495
+ data = self.safe_value(message, 'data')
496
+ data = self.safe_value(data, 0)
497
+ channel = self.safe_string(message, 'channel')
498
+ marketId = self.safe_string(data, 'symbol')
499
+ symbol = self.safe_symbol(marketId)
500
+ market = self.safe_market(symbol)
501
+ timeframes = self.safe_value(self.options, 'timeframes', {})
502
+ timeframe = self.find_timeframe(channel, timeframes)
503
+ messageHash = channel + '::' + symbol
504
+ parsed = self.parse_ws_ohlcv(data, market)
505
+ self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
506
+ stored = self.safe_value(self.ohlcvs[symbol], timeframe)
507
+ if symbol is not None:
508
+ if stored is None:
509
+ limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
510
+ stored = ArrayCacheByTimestamp(limit)
511
+ self.ohlcvs[symbol][timeframe] = stored
512
+ stored.append(parsed)
513
+ client.resolve(stored, messageHash)
514
+ return message
515
+
516
+ def handle_trade(self, client: Client, message):
517
+ #
518
+ # {
519
+ # "channel": "trades",
520
+ # "data": [
521
+ # {
522
+ # "symbol": "BTC_USDT",
523
+ # "amount": "13.41634893",
524
+ # "quantity": "0.000537",
525
+ # "takerSide": "buy",
526
+ # "createTime": 1676950548834,
527
+ # "price": "24983.89",
528
+ # "id": "62486976",
529
+ # "ts": 1676950548839
530
+ # }
531
+ # ]
532
+ # }
533
+ #
534
+ data = self.safe_value(message, 'data', [])
535
+ for i in range(0, len(data)):
536
+ item = data[i]
537
+ marketId = self.safe_string(item, 'symbol')
538
+ if marketId is not None:
539
+ trade = self.parse_ws_trade(item)
540
+ symbol = trade['symbol']
541
+ type = 'trades'
542
+ messageHash = type + '::' + symbol
543
+ tradesArray = self.safe_value(self.trades, symbol)
544
+ if tradesArray is None:
545
+ tradesLimit = self.safe_integer(self.options, 'tradesLimit', 1000)
546
+ tradesArray = ArrayCache(tradesLimit)
547
+ self.trades[symbol] = tradesArray
548
+ tradesArray.append(trade)
549
+ client.resolve(tradesArray, messageHash)
550
+ return message
551
+
552
+ def parse_ws_trade(self, trade, market=None):
553
+ #
554
+ # handleTrade
555
+ #
556
+ # {
557
+ # "symbol": "BTC_USDT",
558
+ # "amount": "13.41634893",
559
+ # "quantity": "0.000537",
560
+ # "takerSide": "buy",
561
+ # "createTime": 1676950548834,
562
+ # "price": "24983.89",
563
+ # "id": "62486976",
564
+ # "ts": 1676950548839
565
+ # }
566
+ #
567
+ # private trade
568
+ # {
569
+ # "orderId":"186250258089635840",
570
+ # "tradeId":"62036513",
571
+ # "clientOrderId":"",
572
+ # "accountType":"SPOT",
573
+ # "eventType":"trade",
574
+ # "symbol":"ADA_USDT",
575
+ # "side":"SELL",
576
+ # "type":"MARKET",
577
+ # "price":"0",
578
+ # "quantity":"3",
579
+ # "state":"FILLED",
580
+ # "createTime":1685371921891,
581
+ # "tradeTime":1685371921908,
582
+ # "tradePrice":"0.37694",
583
+ # "tradeQty":"3",
584
+ # "feeCurrency":"USDT",
585
+ # "tradeFee":"0.00226164",
586
+ # "tradeAmount":"1.13082",
587
+ # "filledQuantity":"3",
588
+ # "filledAmount":"1.13082",
589
+ # "ts":1685371921945,
590
+ # "source":"WEB",
591
+ # "orderAmount":"0",
592
+ # "matchRole":"TAKER"
593
+ # }
594
+ #
595
+ marketId = self.safe_string(trade, 'symbol')
596
+ market = self.safe_market(marketId, market)
597
+ timestamp = self.safe_integer(trade, 'createTime')
598
+ takerMaker = self.safe_string_lower_2(trade, 'matchRole', 'taker')
599
+ return self.safe_trade({
600
+ 'info': trade,
601
+ 'id': self.safe_string_2(trade, 'id', 'tradeId'),
602
+ 'symbol': self.safe_string(market, 'symbol'),
603
+ 'timestamp': timestamp,
604
+ 'datetime': self.iso8601(timestamp),
605
+ 'order': self.safe_string(trade, 'orderId'),
606
+ 'type': self.safe_string_lower(trade, 'type'),
607
+ 'side': self.safe_string_lower_2(trade, 'takerSide', 'side'),
608
+ 'takerOrMaker': takerMaker,
609
+ 'price': self.omit_zero(self.safe_string_2(trade, 'tradePrice', 'price')),
610
+ 'amount': self.omit_zero(self.safe_string_2(trade, 'filledQuantity', 'quantity')),
611
+ 'cost': self.safe_string_2(trade, 'amount', 'filledAmount'),
612
+ 'fee': {
613
+ 'rate': None,
614
+ 'cost': self.safe_string(trade, 'tradeFee'),
615
+ 'currency': self.safe_string(trade, 'feeCurrency'),
616
+ },
617
+ }, market)
618
+
619
+ def parse_status(self, status):
620
+ statuses: dict = {
621
+ 'NEW': 'open',
622
+ 'PARTIALLY_FILLED': 'open',
623
+ 'FILLED': 'closed',
624
+ 'PENDING_CANCEL': 'open',
625
+ 'PARTIALLY_CANCELED': 'open',
626
+ 'CANCELED': 'canceled',
627
+ # FAILED
628
+ }
629
+ return self.safe_string(statuses, status, status)
630
+
631
+ def parse_ws_order_trade(self, trade, market=None):
632
+ #
633
+ # {
634
+ # "symbol": "BTC_USDT",
635
+ # "type": "LIMIT",
636
+ # "quantity": "1",
637
+ # "orderId": "32471407854219264",
638
+ # "tradeFee": "0",
639
+ # "clientOrderId": "",
640
+ # "accountType": "SPOT",
641
+ # "feeCurrency": "",
642
+ # "eventType": "place",
643
+ # "source": "API",
644
+ # "side": "BUY",
645
+ # "filledQuantity": "0",
646
+ # "filledAmount": "0",
647
+ # "matchRole": "MAKER",
648
+ # "state": "NEW",
649
+ # "tradeTime": 0,
650
+ # "tradeAmount": "0",
651
+ # "orderAmount": "0",
652
+ # "createTime": 1648708186922,
653
+ # "price": "47112.1",
654
+ # "tradeQty": "0",
655
+ # "tradePrice": "0",
656
+ # "tradeId": "0",
657
+ # "ts": 1648708187469
658
+ # }
659
+ #
660
+ timestamp = self.safe_integer(trade, 'tradeTime')
661
+ marketId = self.safe_string(trade, 'symbol')
662
+ return self.safe_trade({
663
+ 'info': trade,
664
+ 'id': self.safe_string(trade, 'tradeId'),
665
+ 'symbol': self.safe_symbol(marketId, market),
666
+ 'timestamp': timestamp,
667
+ 'datetime': self.iso8601(timestamp),
668
+ 'order': self.safe_string(trade, 'orderId'),
669
+ 'type': self.safe_string_lower(trade, 'type'),
670
+ 'side': self.safe_string(trade, 'side'),
671
+ 'takerOrMaker': self.safe_string_lower(trade, 'matchRole'),
672
+ 'price': self.safe_string(trade, 'price'),
673
+ 'amount': self.safe_string(trade, 'tradeAmount'),
674
+ 'cost': None,
675
+ 'fee': {
676
+ 'rate': None,
677
+ 'cost': self.safe_string(trade, 'tradeFee'),
678
+ 'currency': self.safe_string(trade, 'feeCurrency'),
679
+ },
680
+ }, market)
681
+
682
+ def handle_order(self, client: Client, message):
683
+ #
684
+ # Order is created
685
+ #
686
+ # {
687
+ # "channel": "orders",
688
+ # "data": [
689
+ # {
690
+ # "symbol": "BTC_USDT",
691
+ # "type": "LIMIT",
692
+ # "quantity": "1",
693
+ # "orderId": "32471407854219264",
694
+ # "tradeFee": "0",
695
+ # "clientOrderId": "",
696
+ # "accountType": "SPOT",
697
+ # "feeCurrency": "",
698
+ # "eventType": "place",
699
+ # "source": "API",
700
+ # "side": "BUY",
701
+ # "filledQuantity": "0",
702
+ # "filledAmount": "0",
703
+ # "matchRole": "MAKER",
704
+ # "state": "NEW",
705
+ # "tradeTime": 0,
706
+ # "tradeAmount": "0",
707
+ # "orderAmount": "0",
708
+ # "createTime": 1648708186922,
709
+ # "price": "47112.1",
710
+ # "tradeQty": "0",
711
+ # "tradePrice": "0",
712
+ # "tradeId": "0",
713
+ # "ts": 1648708187469
714
+ # }
715
+ # ]
716
+ # }
717
+ #
718
+ data = self.safe_value(message, 'data', [])
719
+ orders = self.orders
720
+ if orders is None:
721
+ limit = self.safe_integer(self.options, 'ordersLimit')
722
+ orders = ArrayCacheBySymbolById(limit)
723
+ self.orders = orders
724
+ marketIds = []
725
+ for i in range(0, len(data)):
726
+ order = self.safe_value(data, i)
727
+ marketId = self.safe_string(order, 'symbol')
728
+ eventType = self.safe_string(order, 'eventType')
729
+ if marketId is not None:
730
+ symbol = self.safe_symbol(marketId)
731
+ orderId = self.safe_string(order, 'orderId')
732
+ clientOrderId = self.safe_string(order, 'clientOrderId')
733
+ if eventType == 'place' or eventType == 'canceled':
734
+ parsed = self.parse_ws_order(order)
735
+ orders.append(parsed)
736
+ else:
737
+ previousOrders = self.safe_value(orders.hashmap, symbol, {})
738
+ previousOrder = self.safe_value_2(previousOrders, orderId, clientOrderId)
739
+ trade = self.parse_ws_trade(order)
740
+ self.handle_my_trades(client, trade)
741
+ if previousOrder['trades'] is None:
742
+ previousOrder['trades'] = []
743
+ previousOrder['trades'].append(trade)
744
+ previousOrder['lastTradeTimestamp'] = trade['timestamp']
745
+ totalCost = '0'
746
+ totalAmount = '0'
747
+ previousOrderTrades = previousOrder['trades']
748
+ for j in range(0, len(previousOrderTrades)):
749
+ previousOrderTrade = previousOrderTrades[j]
750
+ cost = self.number_to_string(previousOrderTrade['cost'])
751
+ amount = self.number_to_string(previousOrderTrade['amount'])
752
+ totalCost = Precise.string_add(totalCost, cost)
753
+ totalAmount = Precise.string_add(totalAmount, amount)
754
+ if Precise.string_gt(totalAmount, '0'):
755
+ previousOrder['average'] = self.parse_number(Precise.string_div(totalCost, totalAmount))
756
+ previousOrder['cost'] = self.parse_number(totalCost)
757
+ if previousOrder['filled'] is not None:
758
+ tradeAmount = self.number_to_string(trade['amount'])
759
+ previousOrderFilled = self.number_to_string(previousOrder['filled'])
760
+ previousOrderFilled = Precise.string_add(previousOrderFilled, tradeAmount)
761
+ previousOrder['filled'] = previousOrderFilled
762
+ if previousOrder['amount'] is not None:
763
+ previousOrderAmount = self.number_to_string(previousOrder['amount'])
764
+ previousOrder['remaining'] = self.parse_number(Precise.string_sub(previousOrderAmount, previousOrderFilled))
765
+ if previousOrder['fee'] is None:
766
+ previousOrder['fee'] = {
767
+ 'rate': None,
768
+ 'cost': 0,
769
+ 'currency': trade['fee']['currency'],
770
+ }
771
+ if (previousOrder['fee']['cost'] is not None) and (trade['fee']['cost'] is not None):
772
+ stringOrderCost = self.number_to_string(previousOrder['fee']['cost'])
773
+ stringTradeCost = self.number_to_string(trade['fee']['cost'])
774
+ previousOrder['fee']['cost'] = Precise.string_add(stringOrderCost, stringTradeCost)
775
+ rawState = self.safe_string(order, 'state')
776
+ state = self.parse_status(rawState)
777
+ previousOrder['status'] = state
778
+ # update the newUpdates count
779
+ orders.append(previousOrder)
780
+ marketIds.append(marketId)
781
+ for i in range(0, len(marketIds)):
782
+ marketId = marketIds[i]
783
+ market = self.market(marketId)
784
+ symbol = market['symbol']
785
+ messageHash = 'orders::' + symbol
786
+ client.resolve(orders, messageHash)
787
+ client.resolve(orders, 'orders')
788
+ return message
789
+
790
+ def parse_ws_order(self, order, market=None):
791
+ #
792
+ # {
793
+ # "symbol": "BTC_USDT",
794
+ # "type": "LIMIT",
795
+ # "quantity": "1",
796
+ # "orderId": "32471407854219264",
797
+ # "tradeFee": "0",
798
+ # "clientOrderId": "",
799
+ # "accountType": "SPOT",
800
+ # "feeCurrency": "",
801
+ # "eventType": "place",
802
+ # "source": "API",
803
+ # "side": "BUY",
804
+ # "filledQuantity": "0",
805
+ # "filledAmount": "0",
806
+ # "matchRole": "MAKER",
807
+ # "state": "NEW",
808
+ # "tradeTime": 0,
809
+ # "tradeAmount": "0",
810
+ # "orderAmount": "0",
811
+ # "createTime": 1648708186922,
812
+ # "price": "47112.1",
813
+ # "tradeQty": "0",
814
+ # "tradePrice": "0",
815
+ # "tradeId": "0",
816
+ # "ts": 1648708187469
817
+ # }
818
+ #
819
+ id = self.safe_string(order, 'orderId')
820
+ clientOrderId = self.safe_string(order, 'clientOrderId')
821
+ marketId = self.safe_string(order, 'symbol')
822
+ timestamp = self.safe_string(order, 'ts')
823
+ filledAmount = self.safe_string(order, 'filledAmount')
824
+ status = self.safe_string(order, 'state')
825
+ trades = None
826
+ if not Precise.string_eq(filledAmount, '0'):
827
+ trades = []
828
+ trade = self.parse_ws_order_trade(order)
829
+ trades.append(trade)
830
+ return self.safe_order({
831
+ 'info': order,
832
+ 'symbol': self.safe_symbol(marketId, market),
833
+ 'id': id,
834
+ 'clientOrderId': clientOrderId,
835
+ 'timestamp': timestamp,
836
+ 'datetime': self.iso8601(timestamp),
837
+ 'lastTradeTimestamp': None,
838
+ 'type': self.safe_string(order, 'type'),
839
+ 'timeInForce': None,
840
+ 'postOnly': None,
841
+ 'side': self.safe_string(order, 'side'),
842
+ 'price': self.safe_string(order, 'price'),
843
+ 'stopPrice': None,
844
+ 'triggerPrice': None,
845
+ 'amount': self.safe_string(order, 'quantity'),
846
+ 'cost': None,
847
+ 'average': None,
848
+ 'filled': filledAmount,
849
+ 'remaining': self.safe_string(order, 'remaining_size'),
850
+ 'status': self.parse_status(status),
851
+ 'fee': {
852
+ 'rate': None,
853
+ 'cost': self.safe_string(order, 'tradeFee'),
854
+ 'currency': self.safe_string(order, 'feeCurrency'),
855
+ },
856
+ 'trades': trades,
857
+ })
858
+
859
+ def handle_ticker(self, client: Client, message):
860
+ #
861
+ # {
862
+ # "channel": "ticker",
863
+ # "data": [
864
+ # {
865
+ # "symbol": "BTC_USDT",
866
+ # "startTime": 1677280800000,
867
+ # "open": "23154.32",
868
+ # "high": "23212.21",
869
+ # "low": "22761.01",
870
+ # "close": "23148.86",
871
+ # "quantity": "105.179566",
872
+ # "amount": "2423161.17436702",
873
+ # "tradeCount": 17582,
874
+ # "dailyChange": "-0.0002",
875
+ # "markPrice": "23151.09",
876
+ # "closeTime": 1677367197924,
877
+ # "ts": 1677367251090
878
+ # }
879
+ # ]
880
+ # }
881
+ #
882
+ data = self.safe_value(message, 'data', [])
883
+ newTickers: dict = {}
884
+ for i in range(0, len(data)):
885
+ item = data[i]
886
+ marketId = self.safe_string(item, 'symbol')
887
+ if marketId is not None:
888
+ ticker = self.parse_ticker(item)
889
+ symbol = ticker['symbol']
890
+ self.tickers[symbol] = ticker
891
+ newTickers[symbol] = ticker
892
+ messageHashes = self.find_message_hashes(client, 'ticker::')
893
+ for i in range(0, len(messageHashes)):
894
+ messageHash = messageHashes[i]
895
+ parts = messageHash.split('::')
896
+ symbolsString = parts[1]
897
+ symbols = symbolsString.split(',')
898
+ tickers = self.filter_by_array(newTickers, 'symbol', symbols)
899
+ if not self.is_empty(tickers):
900
+ client.resolve(tickers, messageHash)
901
+ client.resolve(newTickers, 'ticker')
902
+ return message
903
+
904
+ def handle_order_book(self, client: Client, message):
905
+ #
906
+ # snapshot
907
+ #
908
+ # {
909
+ # "channel": "book_lv2",
910
+ # "data": [
911
+ # {
912
+ # "symbol": "BTC_USDT",
913
+ # "createTime": 1677368876253,
914
+ # "asks": [
915
+ # ["5.65", "0.02"],
916
+ # ...
917
+ # ],
918
+ # "bids": [
919
+ # ["6.16", "0.6"],
920
+ # ...
921
+ # ],
922
+ # "lastId": 164148724,
923
+ # "id": 164148725,
924
+ # "ts": 1677368876316
925
+ # }
926
+ # ],
927
+ # "action": "snapshot"
928
+ # }
929
+ #
930
+ # update
931
+ #
932
+ # {
933
+ # "channel": "book_lv2",
934
+ # "data": [
935
+ # {
936
+ # "symbol": "BTC_USDT",
937
+ # "createTime": 1677368876882,
938
+ # "asks": [
939
+ # ["6.35", "3"]
940
+ # ],
941
+ # "bids": [
942
+ # ["5.65", "0.02"]
943
+ # ],
944
+ # "lastId": 164148725,
945
+ # "id": 164148726,
946
+ # "ts": 1677368876890
947
+ # }
948
+ # ],
949
+ # "action": "update"
950
+ # }
951
+ #
952
+ data = self.safe_value(message, 'data', [])
953
+ type = self.safe_string(message, 'action')
954
+ snapshot = type == 'snapshot'
955
+ update = type == 'update'
956
+ for i in range(0, len(data)):
957
+ item = data[i]
958
+ marketId = self.safe_string(item, 'symbol')
959
+ market = self.safe_market(marketId)
960
+ symbol = market['symbol']
961
+ name = 'book_lv2'
962
+ messageHash = name + '::' + symbol
963
+ subscription = self.safe_value(client.subscriptions, messageHash, {})
964
+ limit = self.safe_integer(subscription, 'limit')
965
+ timestamp = self.safe_integer(item, 'ts')
966
+ asks = self.safe_value(item, 'asks')
967
+ bids = self.safe_value(item, 'bids')
968
+ if snapshot or update:
969
+ if snapshot:
970
+ self.orderbooks[symbol] = self.order_book({}, limit)
971
+ orderbook = self.orderbooks[symbol]
972
+ if bids is not None:
973
+ for j in range(0, len(bids)):
974
+ bid = self.safe_value(bids, j)
975
+ price = self.safe_number(bid, 0)
976
+ amount = self.safe_number(bid, 1)
977
+ bidsSide = orderbook['bids']
978
+ bidsSide.store(price, amount)
979
+ if asks is not None:
980
+ for j in range(0, len(asks)):
981
+ ask = self.safe_value(asks, j)
982
+ price = self.safe_number(ask, 0)
983
+ amount = self.safe_number(ask, 1)
984
+ asksSide = orderbook['asks']
985
+ asksSide.store(price, amount)
986
+ orderbook['symbol'] = symbol
987
+ orderbook['timestamp'] = timestamp
988
+ orderbook['datetime'] = self.iso8601(timestamp)
989
+ client.resolve(orderbook, messageHash)
990
+
991
+ def handle_balance(self, client: Client, message):
992
+ #
993
+ # {
994
+ # "channel": "balances",
995
+ # "data": [
996
+ # {
997
+ # "changeTime": 1657312008411,
998
+ # "accountId": "1234",
999
+ # "accountType": "SPOT",
1000
+ # "eventType": "place_order",
1001
+ # "available": "9999999983.668",
1002
+ # "currency": "BTC",
1003
+ # "id": 60018450912695040,
1004
+ # "userId": 12345,
1005
+ # "hold": "16.332",
1006
+ # "ts": 1657312008443
1007
+ # }
1008
+ # ]
1009
+ # }
1010
+ #
1011
+ data = self.safe_value(message, 'data', [])
1012
+ messageHash = 'balances'
1013
+ self.balance = self.parse_ws_balance(data)
1014
+ client.resolve(self.balance, messageHash)
1015
+
1016
+ def parse_ws_balance(self, response):
1017
+ #
1018
+ # [
1019
+ # {
1020
+ # "changeTime": 1657312008411,
1021
+ # "accountId": "1234",
1022
+ # "accountType": "SPOT",
1023
+ # "eventType": "place_order",
1024
+ # "available": "9999999983.668",
1025
+ # "currency": "BTC",
1026
+ # "id": 60018450912695040,
1027
+ # "userId": 12345,
1028
+ # "hold": "16.332",
1029
+ # "ts": 1657312008443
1030
+ # }
1031
+ # ]
1032
+ #
1033
+ firstBalance = self.safe_value(response, 0, {})
1034
+ timestamp = self.safe_integer(firstBalance, 'ts')
1035
+ result: dict = {
1036
+ 'info': response,
1037
+ 'timestamp': timestamp,
1038
+ 'datetime': self.iso8601(timestamp),
1039
+ }
1040
+ for i in range(0, len(response)):
1041
+ balance = self.safe_value(response, i)
1042
+ currencyId = self.safe_string(balance, 'currency')
1043
+ code = self.safe_currency_code(currencyId)
1044
+ newAccount = self.account()
1045
+ newAccount['free'] = self.safe_string(balance, 'available')
1046
+ newAccount['used'] = self.safe_string(balance, 'hold')
1047
+ result[code] = newAccount
1048
+ return self.safe_balance(result)
1049
+
1050
+ def handle_my_trades(self, client: Client, parsedTrade):
1051
+ # emulated using the orders' stream
1052
+ messageHash = 'myTrades'
1053
+ symbol = parsedTrade['symbol']
1054
+ if self.myTrades is None:
1055
+ limit = self.safe_integer(self.options, 'tradesLimit', 1000)
1056
+ self.myTrades = ArrayCacheBySymbolById(limit)
1057
+ trades = self.myTrades
1058
+ trades.append(parsedTrade)
1059
+ client.resolve(trades, messageHash)
1060
+ symbolMessageHash = messageHash + ':' + symbol
1061
+ client.resolve(trades, symbolMessageHash)
1062
+
1063
+ def handle_pong(self, client: Client):
1064
+ client.lastPong = self.milliseconds()
1065
+
1066
+ def handle_message(self, client: Client, message):
1067
+ if self.handle_error_message(client, message):
1068
+ return
1069
+ type = self.safe_string(message, 'channel')
1070
+ event = self.safe_string(message, 'event')
1071
+ if event == 'pong':
1072
+ client.lastPong = self.milliseconds()
1073
+ methods: dict = {
1074
+ 'candles_minute_1': self.handle_ohlcv,
1075
+ 'candles_minute_5': self.handle_ohlcv,
1076
+ 'candles_minute_10': self.handle_ohlcv,
1077
+ 'candles_minute_15': self.handle_ohlcv,
1078
+ 'candles_minute_30': self.handle_ohlcv,
1079
+ 'candles_hour_1': self.handle_ohlcv,
1080
+ 'candles_hour_2': self.handle_ohlcv,
1081
+ 'candles_hour_4': self.handle_ohlcv,
1082
+ 'candles_hour_6': self.handle_ohlcv,
1083
+ 'candles_hour_12': self.handle_ohlcv,
1084
+ 'candles_day_1': self.handle_ohlcv,
1085
+ 'candles_day_3': self.handle_ohlcv,
1086
+ 'candles_week_1': self.handle_ohlcv,
1087
+ 'candles_month_1': self.handle_ohlcv,
1088
+ 'book': self.handle_order_book,
1089
+ 'book_lv2': self.handle_order_book,
1090
+ 'ticker': self.handle_ticker,
1091
+ 'trades': self.handle_trade,
1092
+ 'orders': self.handle_order,
1093
+ 'balances': self.handle_balance,
1094
+ 'createOrder': self.handle_order_request,
1095
+ 'cancelOrder': self.handle_order_request,
1096
+ 'cancelAllOrders': self.handle_order_request,
1097
+ 'auth': self.handle_authenticate,
1098
+ }
1099
+ method = self.safe_value(methods, type)
1100
+ if type == 'auth':
1101
+ self.handle_authenticate(client, message)
1102
+ elif type is None:
1103
+ data = self.safe_value(message, 'data')
1104
+ item = self.safe_value(data, 0)
1105
+ orderId = self.safe_string(item, 'orderId')
1106
+ if orderId == '0':
1107
+ self.handle_error_message(client, item)
1108
+ else:
1109
+ self.handle_order_request(client, message)
1110
+ else:
1111
+ data = self.safe_value(message, 'data', [])
1112
+ dataLength = len(data)
1113
+ if dataLength > 0:
1114
+ method(client, message)
1115
+
1116
+ def handle_error_message(self, client: Client, message):
1117
+ #
1118
+ # {
1119
+ # message: 'Invalid channel value ["ordersss"]',
1120
+ # event: 'error'
1121
+ # }
1122
+ #
1123
+ # {
1124
+ # "orderId": 0,
1125
+ # "clientOrderId": null,
1126
+ # "message": "Currency trade disabled",
1127
+ # "code": 21352
1128
+ # }
1129
+ #
1130
+ # {
1131
+ # "event": "error",
1132
+ # "message": "Platform in maintenance mode"
1133
+ # }
1134
+ #
1135
+ event = self.safe_string(message, 'event')
1136
+ orderId = self.safe_string(message, 'orderId')
1137
+ if (event == 'error') or (orderId == '0'):
1138
+ error = self.safe_string(message, 'message')
1139
+ raise ExchangeError(self.id + ' error: ' + self.json(error))
1140
+ return False
1141
+
1142
+ def handle_authenticate(self, client: Client, message):
1143
+ #
1144
+ # {
1145
+ # "success": True,
1146
+ # "ret_msg": '',
1147
+ # "op": "auth",
1148
+ # "conn_id": "ce3dpomvha7dha97tvp0-2xh"
1149
+ # }
1150
+ #
1151
+ data = self.safe_value(message, 'data')
1152
+ success = self.safe_value(data, 'success')
1153
+ messageHash = 'authenticated'
1154
+ if success:
1155
+ client.resolve(message, messageHash)
1156
+ else:
1157
+ error = AuthenticationError(self.id + ' ' + self.json(message))
1158
+ client.reject(error, messageHash)
1159
+ if messageHash in client.subscriptions:
1160
+ del client.subscriptions[messageHash]
1161
+ return message
1162
+
1163
+ def ping(self, client):
1164
+ return {
1165
+ 'event': 'ping',
1166
+ }