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/cex.py ADDED
@@ -0,0 +1,1440 @@
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 ArgumentsRequired
14
+ from ccxt.base.errors import BadRequest
15
+ from ccxt.base.precise import Precise
16
+
17
+
18
+ class cex(ccxt.async_support.cex):
19
+
20
+ def describe(self):
21
+ return self.deep_extend(super(cex, self).describe(), {
22
+ 'has': {
23
+ 'ws': True,
24
+ 'watchBalance': True,
25
+ 'watchTicker': True,
26
+ 'watchTickers': True,
27
+ 'watchTrades': True,
28
+ 'watchMyTrades': True,
29
+ 'watchOrders': True,
30
+ 'watchOrderBook': True,
31
+ 'watchOHLCV': True,
32
+ 'watchPosition': None,
33
+ 'createOrderWs': True,
34
+ 'editOrderWs': True,
35
+ 'cancelOrderWs': True,
36
+ 'cancelOrdersWs': True,
37
+ 'fetchOrderWs': True,
38
+ 'fetchOpenOrdersWs': True,
39
+ 'fetchTickerWs': True,
40
+ 'fetchBalanceWs': True,
41
+ },
42
+ 'urls': {
43
+ 'api': {
44
+ 'ws': 'wss://ws.cex.io/ws',
45
+ },
46
+ },
47
+ 'options': {
48
+ 'orderbook': {},
49
+ },
50
+ 'streaming': {
51
+ },
52
+ 'exceptions': {
53
+ },
54
+ })
55
+
56
+ def request_id(self):
57
+ requestId = self.sum(self.safe_integer(self.options, 'requestId', 0), 1)
58
+ self.options['requestId'] = requestId
59
+ return str(requestId)
60
+
61
+ async def watch_balance(self, params={}) -> Balances:
62
+ """
63
+ watch balance and get the amount of funds available for trading or funds locked in orders
64
+ :see: https://cex.io/websocket-api#get-balance
65
+ :param dict [params]: extra parameters specific to the exchange API endpoint
66
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
67
+ """
68
+ await self.authenticate(params)
69
+ messageHash = self.request_id()
70
+ url = self.urls['api']['ws']
71
+ subscribe: dict = {
72
+ 'e': 'get-balance',
73
+ 'data': {},
74
+ 'oid': self.request_id(),
75
+ }
76
+ request = self.deep_extend(subscribe, params)
77
+ return await self.watch(url, messageHash, request, messageHash, request)
78
+
79
+ def handle_balance(self, client: Client, message):
80
+ #
81
+ # {
82
+ # "e": "get-balance",
83
+ # "data": {
84
+ # "balance": {
85
+ # "BTC": "0.00000000",
86
+ # "USD": "0.00",
87
+ # ...
88
+ # },
89
+ # "obalance": {
90
+ # "BTC": "0.00000000",
91
+ # "USD": "0.00",
92
+ # ...
93
+ # },
94
+ # "time": 1663761159605
95
+ # },
96
+ # "oid": 1,
97
+ # "ok": "ok"
98
+ # }
99
+ #
100
+ data = self.safe_value(message, 'data', {})
101
+ freeBalance = self.safe_value(data, 'balance', {})
102
+ usedBalance = self.safe_value(data, 'obalance', {})
103
+ result: dict = {
104
+ 'info': data,
105
+ }
106
+ currencyIds = list(freeBalance.keys())
107
+ for i in range(0, len(currencyIds)):
108
+ currencyId = currencyIds[i]
109
+ account = self.account()
110
+ account['free'] = self.safe_string(freeBalance, currencyId)
111
+ account['used'] = self.safe_string(usedBalance, currencyId)
112
+ code = self.safe_currency_code(currencyId)
113
+ result[code] = account
114
+ self.balance = self.safe_balance(result)
115
+ messageHash = self.safe_string(message, 'oid')
116
+ client.resolve(self.balance, messageHash)
117
+
118
+ async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
119
+ """
120
+ get the list of most recent trades for a particular symbol. Note: can only watch one symbol at a time.
121
+ :see: https://cex.io/websocket-api#old-pair-room
122
+ :param str symbol: unified symbol of the market to fetch trades for
123
+ :param int [since]: timestamp in ms of the earliest trade to fetch
124
+ :param int [limit]: the maximum amount of trades to fetch
125
+ :param dict [params]: extra parameters specific to the exchange API endpoint
126
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
127
+ """
128
+ await self.load_markets()
129
+ market = self.market(symbol)
130
+ symbol = market['symbol']
131
+ url = self.urls['api']['ws']
132
+ messageHash = 'trades'
133
+ subscriptionHash = 'old:' + symbol
134
+ self.options['currentWatchTradeSymbol'] = symbol # exchange supports only 1 symbol for self watchTrades channel
135
+ client = self.safe_value(self.clients, url)
136
+ if client is not None:
137
+ subscriptionKeys = list(client.subscriptions.keys())
138
+ for i in range(0, len(subscriptionKeys)):
139
+ subscriptionKey = subscriptionKeys[i]
140
+ if subscriptionKey == subscriptionHash:
141
+ continue
142
+ subscriptionKey = subscriptionKey[0:3]
143
+ if subscriptionKey == 'old':
144
+ raise ExchangeError(self.id + ' watchTrades() only supports watching one symbol at a time.')
145
+ message: dict = {
146
+ 'e': 'subscribe',
147
+ 'rooms': ['pair-' + market['base'] + '-' + market['quote']],
148
+ }
149
+ request = self.deep_extend(message, params)
150
+ trades = await self.watch(url, messageHash, request, subscriptionHash)
151
+ # assing symbol to the trades does not contain symbol information
152
+ for i in range(0, len(trades)):
153
+ trades[i]['symbol'] = symbol
154
+ return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
155
+
156
+ def handle_trades_snapshot(self, client: Client, message):
157
+ #
158
+ # {
159
+ # "e": "history",
160
+ # "data": [
161
+ # 'buy:1710255706095:444444:71222.2:14892622'
162
+ # 'sell:1710255658251:42530:71300:14892621'
163
+ # 'buy:1710252424241:87913:72800:14892620'
164
+ # ... timestamp descending
165
+ # ]
166
+ # }
167
+ #
168
+ data = self.safe_list(message, 'data', [])
169
+ limit = self.safe_integer(self.options, 'tradesLimit', 1000)
170
+ stored = ArrayCache(limit)
171
+ symbol = self.safe_string(self.options, 'currentWatchTradeSymbol')
172
+ if symbol is None:
173
+ return
174
+ market = self.market(symbol)
175
+ dataLength = len(data)
176
+ for i in range(0, dataLength):
177
+ index = dataLength - 1 - i
178
+ rawTrade = data[index]
179
+ parsed = self.parse_ws_old_trade(rawTrade, market)
180
+ stored.append(parsed)
181
+ messageHash = 'trades'
182
+ self.trades = stored # trades don't have symbol
183
+ client.resolve(self.trades, messageHash)
184
+
185
+ def parse_ws_old_trade(self, trade, market=None):
186
+ #
187
+ # snapshot trade
188
+ # "sell:1665467367741:3888551:19058.8:14541219"
189
+ # update trade
190
+ # ['buy', '1665467516704', '98070', "19057.7", "14541220"]
191
+ #
192
+ if not isinstance(trade, list):
193
+ trade = trade.split(':')
194
+ side = self.safe_string(trade, 0)
195
+ timestamp = self.safe_integer(trade, 1)
196
+ amount = self.safe_string(trade, 2)
197
+ price = self.safe_string(trade, 3)
198
+ id = self.safe_string(trade, 4)
199
+ return self.safe_trade({
200
+ 'info': trade,
201
+ 'id': id,
202
+ 'timestamp': timestamp,
203
+ 'datetime': self.iso8601(timestamp),
204
+ 'symbol': self.safe_string(market, 'symbol'),
205
+ 'type': None,
206
+ 'side': side,
207
+ 'order': None,
208
+ 'takerOrMaker': None,
209
+ 'price': price,
210
+ 'amount': amount,
211
+ 'cost': None,
212
+ 'fee': None,
213
+ }, market)
214
+
215
+ def handle_trade(self, client: Client, message):
216
+ #
217
+ # {
218
+ # "e": "history-update",
219
+ # "data": [
220
+ # ['buy', '1665467516704', '98070', "19057.7", "14541220"]
221
+ # ]
222
+ # }
223
+ #
224
+ data = self.safe_value(message, 'data', [])
225
+ stored = self.trades # to do fix self, self.trades is not meant to be used like self
226
+ dataLength = len(data)
227
+ for i in range(0, dataLength):
228
+ index = dataLength - 1 - i
229
+ rawTrade = data[index]
230
+ parsed = self.parse_ws_old_trade(rawTrade)
231
+ stored.append(parsed)
232
+ messageHash = 'trades'
233
+ self.trades = stored
234
+ client.resolve(self.trades, messageHash)
235
+
236
+ async def watch_ticker(self, symbol: str, params={}) -> Ticker:
237
+ """
238
+ :see: https://cex.io/websocket-api#ticker-subscription
239
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
240
+ :param str symbol: unified symbol of the market to fetch the ticker for
241
+ :param dict [params]: extra parameters specific to the exchange API endpoint
242
+ :param str [params.method]: public or private
243
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
244
+ """
245
+ await self.load_markets()
246
+ market = self.market(symbol)
247
+ symbol = market['symbol']
248
+ url = self.urls['api']['ws']
249
+ messageHash = 'ticker:' + symbol
250
+ method = self.safe_string(params, 'method', 'private') # default to private because the specified ticker is received quicker
251
+ message = {
252
+ 'e': 'subscribe',
253
+ 'rooms': [
254
+ 'tickers',
255
+ ],
256
+ }
257
+ subscriptionHash = 'tickers'
258
+ if method == 'private':
259
+ await self.authenticate()
260
+ message = {
261
+ 'e': 'ticker',
262
+ 'data': [
263
+ market['baseId'], market['quoteId'],
264
+ ],
265
+ 'oid': self.request_id(),
266
+ }
267
+ subscriptionHash = 'ticker:' + symbol
268
+ request = self.deep_extend(message, params)
269
+ return await self.watch(url, messageHash, request, subscriptionHash)
270
+
271
+ async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
272
+ """
273
+ :see: https://cex.io/websocket-api#ticker-subscription
274
+ watches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
275
+ :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
276
+ :param dict [params]: extra parameters specific to the exchange API endpoint
277
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
278
+ """
279
+ await self.load_markets()
280
+ symbols = self.market_symbols(symbols)
281
+ url = self.urls['api']['ws']
282
+ messageHash = 'tickers'
283
+ message: dict = {
284
+ 'e': 'subscribe',
285
+ 'rooms': [
286
+ 'tickers',
287
+ ],
288
+ }
289
+ request = self.deep_extend(message, params)
290
+ ticker = await self.watch(url, messageHash, request, messageHash)
291
+ tickerSymbol = ticker['symbol']
292
+ if symbols is not None and not self.in_array(tickerSymbol, symbols):
293
+ return await self.watch_tickers(symbols, params)
294
+ if self.newUpdates:
295
+ result: dict = {}
296
+ result[tickerSymbol] = ticker
297
+ return result
298
+ return self.filter_by_array(self.tickers, 'symbol', symbols)
299
+
300
+ async def fetch_ticker_ws(self, symbol: str, params={}) -> Ticker:
301
+ """
302
+ :see: https://docs.cex.io/#ws-api-ticker-deprecated
303
+ fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
304
+ :param str symbol: unified symbol of the market to fetch the ticker for
305
+ :param dict [params]: extra parameters specific to the cex api endpoint
306
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
307
+ """
308
+ await self.load_markets()
309
+ market = self.market(symbol)
310
+ url = self.urls['api']['ws']
311
+ messageHash = self.request_id()
312
+ request = self.extend({
313
+ 'e': 'ticker',
314
+ 'oid': messageHash,
315
+ 'data': [market['base'], market['quote']],
316
+ }, params)
317
+ return await self.watch(url, messageHash, request, messageHash)
318
+
319
+ def handle_ticker(self, client: Client, message):
320
+ #
321
+ # {
322
+ # "e": "tick",
323
+ # "data": {
324
+ # "symbol1": "LRC",
325
+ # "symbol2": "USD",
326
+ # "price": "0.305",
327
+ # "open24": "0.301",
328
+ # "volume": "241421.641700"
329
+ # }
330
+ # }
331
+ #
332
+ data = self.safe_value(message, 'data', {})
333
+ ticker = self.parse_ws_ticker(data)
334
+ symbol = ticker['symbol']
335
+ if symbol is None:
336
+ return
337
+ self.tickers[symbol] = ticker
338
+ messageHash = 'ticker:' + symbol
339
+ client.resolve(ticker, messageHash)
340
+ client.resolve(ticker, 'tickers')
341
+ messageHash = self.safe_string(message, 'oid')
342
+ if messageHash is not None:
343
+ client.resolve(ticker, messageHash)
344
+
345
+ def parse_ws_ticker(self, ticker, market=None):
346
+ #
347
+ # public
348
+ # {
349
+ # "symbol1": "LRC",
350
+ # "symbol2": "USD",
351
+ # "price": "0.305",
352
+ # "open24": "0.301",
353
+ # "volume": "241421.641700"
354
+ # }
355
+ # private
356
+ # {
357
+ # "timestamp": "1663764969",
358
+ # "low": "18756.3",
359
+ # "high": "19200",
360
+ # "last": "19200",
361
+ # "volume": "0.94735907",
362
+ # "volume30d": "64.61299999",
363
+ # "bid": 19217.2,
364
+ # "ask": 19247.5,
365
+ # "priceChange": "44.3",
366
+ # "priceChangePercentage": "0.23",
367
+ # "pair": ["BTC", "USDT"]
368
+ # }
369
+ pair = self.safe_value(ticker, 'pair', [])
370
+ baseId = self.safe_string(ticker, 'symbol1')
371
+ if baseId is None:
372
+ baseId = self.safe_string(pair, 0)
373
+ quoteId = self.safe_string(ticker, 'symbol2')
374
+ if quoteId is None:
375
+ quoteId = self.safe_string(pair, 1)
376
+ base = self.safe_currency_code(baseId)
377
+ quote = self.safe_currency_code(quoteId)
378
+ symbol = base + '/' + quote
379
+ timestamp = self.safe_integer(ticker, 'timestamp')
380
+ if timestamp is not None:
381
+ timestamp = timestamp * 1000
382
+ return self.safe_ticker({
383
+ 'symbol': symbol,
384
+ 'timestamp': timestamp,
385
+ 'datetime': self.iso8601(timestamp),
386
+ 'high': self.safe_string(ticker, 'high'),
387
+ 'low': self.safe_string(ticker, 'low'),
388
+ 'bid': self.safe_string(ticker, 'bid'),
389
+ 'bidVolume': None,
390
+ 'ask': self.safe_string(ticker, 'ask'),
391
+ 'askVolume': None,
392
+ 'vwap': None,
393
+ 'open': self.safe_string(ticker, 'open24'),
394
+ 'close': None,
395
+ 'last': self.safe_string_2(ticker, 'price', 'last'),
396
+ 'previousClose': None,
397
+ 'change': self.safe_string(ticker, 'priceChange'),
398
+ 'percentage': self.safe_string(ticker, 'priceChangePercentage'),
399
+ 'average': None,
400
+ 'baseVolume': None,
401
+ 'quoteVolume': self.safe_string(ticker, 'volume'),
402
+ 'info': ticker,
403
+ }, market)
404
+
405
+ async def fetch_balance_ws(self, params={}) -> Balances:
406
+ """
407
+ :see: https://docs.cex.io/#ws-api-get-balance
408
+ query for balance and get the amount of funds available for trading or funds locked in orders
409
+ :param dict [params]: extra parameters specific to the cex api endpoint
410
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
411
+ """
412
+ await self.load_markets()
413
+ await self.authenticate()
414
+ url = self.urls['api']['ws']
415
+ messageHash = self.request_id()
416
+ request = self.extend({
417
+ 'e': 'get-balance',
418
+ 'oid': messageHash,
419
+ }, params)
420
+ return await self.watch(url, messageHash, request, messageHash)
421
+
422
+ async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
423
+ """
424
+ get the list of orders associated with the user. Note: In CEX.IO system, orders can be present in trade engine or in archive database. There can be time periods(~2 seconds or more), when order is done/canceled, but still not moved to archive database. That means, you cannot see it using calls: archived-orders/open-orders.
425
+ :see: https://docs.cex.io/#ws-api-open-orders
426
+ :param str symbol: unified symbol of the market to fetch trades for
427
+ :param int [since]: timestamp in ms of the earliest trade to fetch
428
+ :param int [limit]: the maximum amount of trades to fetch
429
+ :param dict [params]: extra parameters specific to the exchange API endpoint
430
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
431
+ """
432
+ if symbol is None:
433
+ raise ArgumentsRequired(self.id + ' watchOrders() requires a symbol argument')
434
+ await self.load_markets()
435
+ await self.authenticate(params)
436
+ url = self.urls['api']['ws']
437
+ market = self.market(symbol)
438
+ symbol = market['symbol']
439
+ messageHash = 'orders:' + symbol
440
+ message: dict = {
441
+ 'e': 'open-orders',
442
+ 'data': {
443
+ 'pair': [
444
+ market['baseId'],
445
+ market['quoteId'],
446
+ ],
447
+ },
448
+ 'oid': symbol,
449
+ }
450
+ request = self.deep_extend(message, params)
451
+ orders = await self.watch(url, messageHash, request, messageHash, request)
452
+ if self.newUpdates:
453
+ limit = orders.getLimit(symbol, limit)
454
+ return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
455
+
456
+ async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
457
+ """
458
+ get the list of trades associated with the user. Note: In CEX.IO system, orders can be present in trade engine or in archive database. There can be time periods(~2 seconds or more), when order is done/canceled, but still not moved to archive database. That means, you cannot see it using calls: archived-orders/open-orders.
459
+ :see: https://docs.cex.io/#ws-api-open-orders
460
+ :param str symbol: unified symbol of the market to fetch trades for
461
+ :param int [since]: timestamp in ms of the earliest trade to fetch
462
+ :param int [limit]: the maximum amount of trades to fetch
463
+ :param dict [params]: extra parameters specific to the exchange API endpoint
464
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
465
+ """
466
+ if symbol is None:
467
+ raise ArgumentsRequired(self.id + ' watchMyTrades() requires a symbol argument')
468
+ await self.load_markets()
469
+ await self.authenticate(params)
470
+ url = self.urls['api']['ws']
471
+ market = self.market(symbol)
472
+ messageHash = 'myTrades:' + market['symbol']
473
+ subscriptionHash = 'orders:' + market['symbol']
474
+ message: dict = {
475
+ 'e': 'open-orders',
476
+ 'data': {
477
+ 'pair': [
478
+ market['baseId'],
479
+ market['quoteId'],
480
+ ],
481
+ },
482
+ 'oid': market['symbol'],
483
+ }
484
+ request = self.deep_extend(message, params)
485
+ orders = await self.watch(url, messageHash, request, subscriptionHash, request)
486
+ return self.filter_by_symbol_since_limit(orders, market['symbol'], since, limit)
487
+
488
+ def handle_transaction(self, client: Client, message):
489
+ data = self.safe_value(message, 'data')
490
+ symbol2 = self.safe_string(data, 'symbol2')
491
+ if symbol2 is None:
492
+ return
493
+ self.handle_order_update(client, message)
494
+ self.handle_my_trades(client, message)
495
+
496
+ def handle_my_trades(self, client: Client, message):
497
+ #
498
+ # {
499
+ # "e": "tx",
500
+ # "data": {
501
+ # "d": "order:59091012956:a:USD",
502
+ # "c": "user:up105393824:a:USD",
503
+ # "a": "0.01",
504
+ # "ds": 0,
505
+ # "cs": "15.27",
506
+ # "user": "up105393824",
507
+ # "symbol": "USD",
508
+ # "order": 59091012956,
509
+ # "amount": "-18.49",
510
+ # "type": "buy",
511
+ # "time": "2022-09-24T19:36:18.466Z",
512
+ # "balance": "15.27",
513
+ # "id": "59091012966"
514
+ # }
515
+ # }
516
+ # {
517
+ # "e": "tx",
518
+ # "data": {
519
+ # "d": "order:59091012956:a:BTC",
520
+ # "c": "user:up105393824:a:BTC",
521
+ # "a": "0.00096420",
522
+ # "ds": 0,
523
+ # "cs": "0.00096420",
524
+ # "user": "up105393824",
525
+ # "symbol": "BTC",
526
+ # "symbol2": "USD",
527
+ # "amount": "0.00096420",
528
+ # "buy": 59091012956,
529
+ # "order": 59091012956,
530
+ # "sell": 59090796005,
531
+ # "price": 19135,
532
+ # "type": "buy",
533
+ # "time": "2022-09-24T19:36:18.466Z",
534
+ # "balance": "0.00096420",
535
+ # "fee_amount": "0.05",
536
+ # "id": "59091012962"
537
+ # }
538
+ # }
539
+ data = self.safe_value(message, 'data', {})
540
+ stored = self.myTrades
541
+ if stored is None:
542
+ limit = self.safe_integer(self.options, 'tradesLimit', 1000)
543
+ stored = ArrayCacheBySymbolById(limit)
544
+ self.myTrades = stored
545
+ trade = self.parse_ws_trade(data)
546
+ stored.append(trade)
547
+ messageHash = 'myTrades:' + trade['symbol']
548
+ client.resolve(stored, messageHash)
549
+
550
+ def parse_ws_trade(self, trade, market=None):
551
+ #
552
+ # {
553
+ # "d": "order:59091012956:a:BTC",
554
+ # "c": "user:up105393824:a:BTC",
555
+ # "a": "0.00096420",
556
+ # "ds": 0,
557
+ # "cs": "0.00096420",
558
+ # "user": "up105393824",
559
+ # "symbol": "BTC",
560
+ # "symbol2": "USD",
561
+ # "amount": "0.00096420",
562
+ # "buy": 59091012956,
563
+ # "order": 59091012956,
564
+ # "sell": 59090796005,
565
+ # "price": 19135,
566
+ # "type": "buy",
567
+ # "time": "2022-09-24T19:36:18.466Z",
568
+ # "balance": "0.00096420",
569
+ # "fee_amount": "0.05",
570
+ # "id": "59091012962"
571
+ # }
572
+ # Note symbol and symbol2 are inverse on sell and ammount is in symbol currency.
573
+ #
574
+ side = self.safe_string(trade, 'type')
575
+ price = self.safe_string(trade, 'price')
576
+ datetime = self.safe_string(trade, 'time')
577
+ baseId = self.safe_string(trade, 'symbol')
578
+ quoteId = self.safe_string(trade, 'symbol2')
579
+ base = self.safe_currency_code(baseId)
580
+ quote = self.safe_currency_code(quoteId)
581
+ symbol = base + '/' + quote
582
+ amount = self.safe_string(trade, 'amount')
583
+ if side == 'sell':
584
+ symbol = quote + '/' + base
585
+ amount = Precise.string_div(amount, price) # due to rounding errors amount in not exact to trade
586
+ parsedTrade: dict = {
587
+ 'id': self.safe_string(trade, 'id'),
588
+ 'order': self.safe_string(trade, 'order'),
589
+ 'info': trade,
590
+ 'timestamp': self.parse8601(datetime),
591
+ 'datetime': datetime,
592
+ 'symbol': symbol,
593
+ 'type': None,
594
+ 'side': side,
595
+ 'takerOrMaker': None,
596
+ 'price': price,
597
+ 'cost': None,
598
+ 'amount': amount,
599
+ 'fee': None,
600
+ }
601
+ fee = self.safe_string(trade, 'fee_amount')
602
+ if fee is not None:
603
+ parsedTrade['fee'] = {
604
+ 'cost': fee,
605
+ 'currency': quote,
606
+ 'rate': None,
607
+ }
608
+ return self.safe_trade(parsedTrade, market)
609
+
610
+ def handle_order_update(self, client: Client, message):
611
+ #
612
+ # partialExecution
613
+ # {
614
+ # "e": "order",
615
+ # "data": {
616
+ # "id": "150714937",
617
+ # "remains": "1000000",
618
+ # "price": "17513",
619
+ # "amount": 2000000, As Precision
620
+ # "time": "1654506118448",
621
+ # "type": "buy",
622
+ # "pair": {
623
+ # "symbol1": "BTC",
624
+ # "symbol2": "USD"
625
+ # },
626
+ # "fee": "0.15"
627
+ # }
628
+ # }
629
+ # canceled order
630
+ # {
631
+ # "e": "order",
632
+ # "data": {
633
+ # "id": "6310857",
634
+ # "remains": "200000000"
635
+ # "fremains": "2.00000000"
636
+ # "cancel": True,
637
+ # "pair": {
638
+ # "symbol1": "BTC",
639
+ # "symbol2": "USD"
640
+ # }
641
+ # }
642
+ # }
643
+ # fullfilledOrder
644
+ # {
645
+ # "e": "order",
646
+ # "data": {
647
+ # "id": "59098421630",
648
+ # "remains": "0",
649
+ # "pair": {
650
+ # "symbol1": "BTC",
651
+ # "symbol2": "USD"
652
+ # }
653
+ # }
654
+ # }
655
+ # {
656
+ # "e": "tx",
657
+ # "data": {
658
+ # "d": "order:59425993014:a:BTC",
659
+ # "c": "user:up105393824:a:BTC",
660
+ # "a": "0.00098152",
661
+ # "ds": 0,
662
+ # "cs": "0.00098152",
663
+ # "user": "up105393824",
664
+ # "symbol": "BTC",
665
+ # "symbol2": "USD",
666
+ # "amount": "0.00098152",
667
+ # "buy": 59425993014,
668
+ # "order": 59425993014,
669
+ # "sell": 59425986168,
670
+ # "price": 19306.6,
671
+ # "type": "buy",
672
+ # "time": "2022-10-02T01:11:15.148Z",
673
+ # "balance": "0.00098152",
674
+ # "fee_amount": "0.05",
675
+ # "id": "59425993020"
676
+ # }
677
+ # }
678
+ #
679
+ data = self.safe_value(message, 'data', {})
680
+ isTransaction = self.safe_string(message, 'e') == 'tx'
681
+ orderId = self.safe_string_2(data, 'id', 'order')
682
+ remains = self.safe_string(data, 'remains')
683
+ baseId = self.safe_string(data, 'symbol')
684
+ quoteId = self.safe_string(data, 'symbol2')
685
+ pair = self.safe_value(data, 'pair')
686
+ if pair is not None:
687
+ baseId = self.safe_string(pair, 'symbol1')
688
+ quoteId = self.safe_string(pair, 'symbol2')
689
+ base = self.safe_currency_code(baseId)
690
+ quote = self.safe_currency_code(quoteId)
691
+ symbol = base + '/' + quote
692
+ market = self.safe_market(symbol)
693
+ remains = self.currency_from_precision(base, remains)
694
+ if self.orders is None:
695
+ limit = self.safe_integer(self.options, 'ordersLimit', 1000)
696
+ self.orders = ArrayCacheBySymbolById(limit)
697
+ storedOrders = self.orders
698
+ ordersBySymbol = self.safe_value(storedOrders.hashmap, symbol, {})
699
+ order = self.safe_value(ordersBySymbol, orderId)
700
+ if order is None:
701
+ order = self.parse_ws_order_update(data, market)
702
+ order['remaining'] = remains
703
+ canceled = self.safe_bool(data, 'cancel', False)
704
+ if canceled:
705
+ order['status'] = 'canceled'
706
+ if isTransaction:
707
+ order['status'] = 'closed'
708
+ fee = self.safe_number(data, 'fee')
709
+ if fee is not None:
710
+ order['fee'] = {
711
+ 'cost': fee,
712
+ 'currency': quote,
713
+ 'rate': None,
714
+ }
715
+ timestamp = self.safe_integer(data, 'time')
716
+ order['timestamp'] = timestamp
717
+ order['datetime'] = self.iso8601(timestamp)
718
+ order = self.safe_order(order)
719
+ storedOrders.append(order)
720
+ messageHash = 'orders:' + symbol
721
+ client.resolve(storedOrders, messageHash)
722
+
723
+ def parse_ws_order_update(self, order, market=None):
724
+ #
725
+ # {
726
+ # "id": "150714937",
727
+ # "remains": "1000000",
728
+ # "price": "17513",
729
+ # "amount": 2000000, As Precision
730
+ # "time": "1654506118448",
731
+ # "type": "buy",
732
+ # "pair": {
733
+ # "symbol1": "BTC",
734
+ # "symbol2": "USD"
735
+ # },
736
+ # "fee": "0.15"
737
+ # }
738
+ # transaction
739
+ # {
740
+ # "d": "order:59425993014:a:BTC",
741
+ # "c": "user:up105393824:a:BTC",
742
+ # "a": "0.00098152",
743
+ # "ds": 0,
744
+ # "cs": "0.00098152",
745
+ # "user": "up105393824",
746
+ # "symbol": "BTC",
747
+ # "symbol2": "USD",
748
+ # "amount": "0.00098152",
749
+ # "buy": 59425993014,
750
+ # "order": 59425993014,
751
+ # "sell": 59425986168,
752
+ # "price": 19306.6,
753
+ # "type": "buy",
754
+ # "time": "2022-10-02T01:11:15.148Z",
755
+ # "balance": "0.00098152",
756
+ # "fee_amount": "0.05",
757
+ # "id": "59425993020"
758
+ # }
759
+ #
760
+ isTransaction = self.safe_value(order, 'd') is not None
761
+ remainsPrecision = self.safe_string(order, 'remains')
762
+ remaining = None
763
+ if remainsPrecision is not None:
764
+ remaining = self.currency_from_precision(market['base'], remainsPrecision)
765
+ amount = self.safe_string(order, 'amount')
766
+ if not isTransaction:
767
+ self.currency_from_precision(market['base'], amount)
768
+ baseId = self.safe_string(order, 'symbol')
769
+ quoteId = self.safe_string(order, 'symbol2')
770
+ pair = self.safe_value(order, 'pair')
771
+ if pair is not None:
772
+ baseId = self.safe_string(order, 'symbol1')
773
+ quoteId = self.safe_string(order, 'symbol2')
774
+ base = self.safe_currency_code(baseId)
775
+ quote = self.safe_currency_code(quoteId)
776
+ symbol = None
777
+ if base is not None and quote is not None:
778
+ symbol = base + '/' + quote
779
+ market = self.safe_market(symbol, market)
780
+ time = self.safe_integer(order, 'time', self.milliseconds())
781
+ timestamp = time
782
+ if isTransaction:
783
+ timestamp = self.parse8601(time)
784
+ canceled = self.safe_bool(order, 'cancel', False)
785
+ status = 'open'
786
+ if canceled:
787
+ status = 'canceled'
788
+ elif isTransaction:
789
+ status = 'closed'
790
+ parsedOrder: dict = {
791
+ 'id': self.safe_string_2(order, 'id', 'order'),
792
+ 'clientOrderId': None,
793
+ 'info': order,
794
+ 'timestamp': timestamp,
795
+ 'datetime': self.iso8601(timestamp),
796
+ 'lastTradeTimestamp': None,
797
+ 'status': status,
798
+ 'symbol': symbol,
799
+ 'type': None,
800
+ 'timeInForce': None,
801
+ 'postOnly': None,
802
+ 'side': self.safe_string(order, 'type'),
803
+ 'price': self.safe_number(order, 'price'),
804
+ 'stopPrice': None,
805
+ 'triggerPrice': None,
806
+ 'average': None,
807
+ 'cost': None,
808
+ 'amount': amount,
809
+ 'filled': None,
810
+ 'remaining': remaining,
811
+ 'fee': {
812
+ 'cost': self.safe_number_2(order, 'fee', 'fee_amount'),
813
+ 'currency': quote,
814
+ 'rate': None,
815
+ },
816
+ 'trades': None,
817
+ }
818
+ if isTransaction:
819
+ parsedOrder['trades'] = self.parse_ws_trade(order, market)
820
+ return self.safe_order(parsedOrder, market)
821
+
822
+ def from_precision(self, amount, scale):
823
+ if amount is None:
824
+ return None
825
+ precise = Precise(amount)
826
+ precise.decimals = self.sum(precise.decimals, scale)
827
+ precise.reduce()
828
+ return str(precise)
829
+
830
+ def currency_from_precision(self, currency, amount):
831
+ scale = self.safe_integer(self.currencies[currency], 'precision', 0)
832
+ return self.from_precision(amount, scale)
833
+
834
+ def handle_orders_snapshot(self, client: Client, message):
835
+ #
836
+ # {
837
+ # "e": "open-orders",
838
+ # "data": [{
839
+ # "id": "59098421630",
840
+ # "time": "1664062285425",
841
+ # "type": "buy",
842
+ # "price": "18920",
843
+ # "amount": "0.00100000",
844
+ # "pending": "0.00100000"
845
+ # }],
846
+ # "oid": 1,
847
+ # "ok": "ok"
848
+ # }
849
+ #
850
+ symbol = self.safe_string(message, 'oid') # symbol is set in watchOrders
851
+ rawOrders = self.safe_value(message, 'data', [])
852
+ myOrders = self.orders
853
+ if self.orders is None:
854
+ limit = self.safe_integer(self.options, 'ordersLimit', 1000)
855
+ myOrders = ArrayCacheBySymbolById(limit)
856
+ for i in range(0, len(rawOrders)):
857
+ rawOrder = rawOrders[i]
858
+ market = self.safe_market(symbol)
859
+ order = self.parse_order(rawOrder, market)
860
+ order['status'] = 'open'
861
+ myOrders.append(order)
862
+ self.orders = myOrders
863
+ messageHash = 'orders:' + symbol
864
+ ordersLength = len(myOrders)
865
+ if ordersLength > 0:
866
+ client.resolve(myOrders, messageHash)
867
+
868
+ async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
869
+ """
870
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
871
+ :see: https://cex.io/websocket-api#orderbook-subscribe
872
+ :param str symbol: unified symbol of the market to fetch the order book for
873
+ :param int [limit]: the maximum amount of order book entries to return
874
+ :param dict [params]: extra parameters specific to the exchange API endpoint
875
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
876
+ """
877
+ await self.load_markets()
878
+ await self.authenticate()
879
+ market = self.market(symbol)
880
+ symbol = market['symbol']
881
+ url = self.urls['api']['ws']
882
+ messageHash = 'orderbook:' + symbol
883
+ depth = 0 if (limit is None) else limit
884
+ subscribe: dict = {
885
+ 'e': 'order-book-subscribe',
886
+ 'data': {
887
+ 'pair': [
888
+ market['baseId'],
889
+ market['quoteId'],
890
+ ],
891
+ 'subscribe': True,
892
+ 'depth': depth,
893
+ },
894
+ 'oid': self.request_id(),
895
+ }
896
+ request = self.deep_extend(subscribe, params)
897
+ orderbook = await self.watch(url, messageHash, request, messageHash)
898
+ return orderbook.limit()
899
+
900
+ def handle_order_book_snapshot(self, client: Client, message):
901
+ #
902
+ # {
903
+ # "e": "order-book-subscribe",
904
+ # "data": {
905
+ # "timestamp": 1663762032,
906
+ # "timestamp_ms": 1663762031680,
907
+ # "bids": [
908
+ # [241.947, 155.91626],
909
+ # [241, 154],
910
+ # ],
911
+ # "asks": [
912
+ # [242.947, 155.91626],
913
+ # [243, 154], ],
914
+ # "pair": "BTC:USDT",
915
+ # "id": 616267120,
916
+ # "sell_total": "13.59066946",
917
+ # "buy_total": "163553.625948"
918
+ # },
919
+ # "oid": "1",
920
+ # "ok": "ok"
921
+ # }
922
+ #
923
+ data = self.safe_value(message, 'data', {})
924
+ pair = self.safe_string(data, 'pair')
925
+ symbol = self.pair_to_symbol(pair)
926
+ messageHash = 'orderbook:' + symbol
927
+ timestamp = self.safe_integer_2(data, 'timestamp_ms', 'timestamp')
928
+ incrementalId = self.safe_integer(data, 'id')
929
+ orderbook = self.order_book({})
930
+ snapshot = self.parse_order_book(data, symbol, timestamp, 'bids', 'asks')
931
+ snapshot['nonce'] = incrementalId
932
+ orderbook.reset(snapshot)
933
+ self.options['orderbook'][symbol] = {
934
+ 'incrementalId': incrementalId,
935
+ }
936
+ self.orderbooks[symbol] = orderbook
937
+ client.resolve(orderbook, messageHash)
938
+
939
+ def pair_to_symbol(self, pair):
940
+ parts = pair.split(':')
941
+ baseId = self.safe_string(parts, 0)
942
+ quoteId = self.safe_string(parts, 1)
943
+ base = self.safe_currency_code(baseId)
944
+ quote = self.safe_currency_code(quoteId)
945
+ symbol = base + '/' + quote
946
+ return symbol
947
+
948
+ def handle_order_book_update(self, client: Client, message):
949
+ #
950
+ # {
951
+ # "e": "md_update",
952
+ # "data": {
953
+ # "id": 616267121,
954
+ # "pair": "BTC:USDT",
955
+ # "time": 1663762031719,
956
+ # "bids": [],
957
+ # "asks": [
958
+ # [122, 23]
959
+ # ]
960
+ # }
961
+ # }
962
+ #
963
+ data = self.safe_value(message, 'data', {})
964
+ incrementalId = self.safe_number(data, 'id')
965
+ pair = self.safe_string(data, 'pair', '')
966
+ symbol = self.pair_to_symbol(pair)
967
+ storedOrderBook = self.safe_value(self.orderbooks, symbol)
968
+ messageHash = 'orderbook:' + symbol
969
+ if incrementalId != storedOrderBook['nonce'] + 1:
970
+ del client.subscriptions[messageHash]
971
+ client.reject(self.id + ' watchOrderBook() skipped a message', messageHash)
972
+ timestamp = self.safe_integer(data, 'time')
973
+ asks = self.safe_value(data, 'asks', [])
974
+ bids = self.safe_value(data, 'bids', [])
975
+ self.handle_deltas(storedOrderBook['asks'], asks)
976
+ self.handle_deltas(storedOrderBook['bids'], bids)
977
+ storedOrderBook['timestamp'] = timestamp
978
+ storedOrderBook['datetime'] = self.iso8601(timestamp)
979
+ storedOrderBook['nonce'] = incrementalId
980
+ client.resolve(storedOrderBook, messageHash)
981
+
982
+ def handle_delta(self, bookside, delta):
983
+ bidAsk = self.parse_bid_ask(delta, 0, 1)
984
+ bookside.storeArray(bidAsk)
985
+
986
+ def handle_deltas(self, bookside, deltas):
987
+ for i in range(0, len(deltas)):
988
+ self.handle_delta(bookside, deltas[i])
989
+
990
+ async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
991
+ """
992
+ :see: https://cex.io/websocket-api#minute-data
993
+ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market. It will return the last 120 minutes with the selected timeframe and then 1m candle updates after that.
994
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
995
+ :param str timeframe: the length of time each candle represents.
996
+ :param int [since]: timestamp in ms of the earliest candle to fetch
997
+ :param int [limit]: the maximum amount of candles to fetch
998
+ :param dict [params]: extra parameters specific to the exchange API endpoint
999
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
1000
+ """
1001
+ await self.load_markets()
1002
+ market = self.market(symbol)
1003
+ symbol = market['symbol']
1004
+ messageHash = 'ohlcv:' + symbol
1005
+ url = self.urls['api']['ws']
1006
+ request: dict = {
1007
+ 'e': 'init-ohlcv',
1008
+ 'i': timeframe,
1009
+ 'rooms': [
1010
+ 'pair-' + market['baseId'] + '-' + market['quoteId'],
1011
+ ],
1012
+ }
1013
+ ohlcv = await self.watch(url, messageHash, self.extend(request, params), messageHash)
1014
+ if self.newUpdates:
1015
+ limit = ohlcv.getLimit(symbol, limit)
1016
+ return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
1017
+
1018
+ def handle_init_ohlcv(self, client: Client, message):
1019
+ #
1020
+ # {
1021
+ # "e": "init-ohlcv-data",
1022
+ # "data": [
1023
+ # [
1024
+ # 1663660680,
1025
+ # "19396.4",
1026
+ # "19396.4",
1027
+ # "19396.4",
1028
+ # "19396.4",
1029
+ # "1262861"
1030
+ # ],
1031
+ # ...
1032
+ # ],
1033
+ # "pair": "BTC:USDT"
1034
+ # }
1035
+ #
1036
+ pair = self.safe_string(message, 'pair')
1037
+ parts = pair.split(':')
1038
+ baseId = self.safe_string(parts, 0)
1039
+ quoteId = self.safe_string(parts, 1)
1040
+ base = self.safe_currency_code(baseId)
1041
+ quote = self.safe_currency_code(quoteId)
1042
+ symbol = base + '/' + quote
1043
+ market = self.safe_market(symbol)
1044
+ messageHash = 'ohlcv:' + symbol
1045
+ data = self.safe_value(message, 'data', [])
1046
+ limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
1047
+ stored = ArrayCacheByTimestamp(limit)
1048
+ sorted = self.sort_by(data, 0)
1049
+ for i in range(0, len(sorted)):
1050
+ stored.append(self.parse_ohlcv(sorted[i], market))
1051
+ if not (symbol in self.ohlcvs):
1052
+ self.ohlcvs[symbol] = {}
1053
+ self.ohlcvs[symbol]['unknown'] = stored
1054
+ client.resolve(stored, messageHash)
1055
+
1056
+ def handle_ohlcv24(self, client: Client, message):
1057
+ #
1058
+ # {
1059
+ # "e": "ohlcv24",
1060
+ # "data": ['18793.2', '19630', '18793.2', "19104.1", "314157273"],
1061
+ # "pair": "BTC:USDT"
1062
+ # }
1063
+ #
1064
+ return message
1065
+
1066
+ def handle_ohlcv1m(self, client: Client, message):
1067
+ #
1068
+ # {
1069
+ # "e": "ohlcv1m",
1070
+ # "data": {
1071
+ # "pair": "BTC:USD",
1072
+ # "time": "1665436800",
1073
+ # "o": "19279.6",
1074
+ # "h": "19279.6",
1075
+ # "l": "19266.7",
1076
+ # "c": "19266.7",
1077
+ # "v": 3343884,
1078
+ # "d": 3343884
1079
+ # }
1080
+ # }
1081
+ #
1082
+ data = self.safe_value(message, 'data', {})
1083
+ pair = self.safe_string(data, 'pair')
1084
+ symbol = self.pair_to_symbol(pair)
1085
+ messageHash = 'ohlcv:' + symbol
1086
+ ohlcv = [
1087
+ self.safe_timestamp(data, 'time'),
1088
+ self.safe_number(data, 'o'),
1089
+ self.safe_number(data, 'h'),
1090
+ self.safe_number(data, 'l'),
1091
+ self.safe_number(data, 'c'),
1092
+ self.safe_number(data, 'v'),
1093
+ ]
1094
+ stored = self.safe_value(self.ohlcvs, symbol)
1095
+ stored.append(ohlcv)
1096
+ client.resolve(stored, messageHash)
1097
+
1098
+ def handle_ohlcv(self, client: Client, message):
1099
+ #
1100
+ # {
1101
+ # "e": "ohlcv",
1102
+ # "data": [
1103
+ # [1665461100, '19068.2', '19068.2', '19068.2', "19068.2", 268478]
1104
+ # ],
1105
+ # "pair": "BTC:USD"
1106
+ # }
1107
+ #
1108
+ data = self.safe_value(message, 'data', [])
1109
+ pair = self.safe_string(message, 'pair')
1110
+ symbol = self.pair_to_symbol(pair)
1111
+ messageHash = 'ohlcv:' + symbol
1112
+ # stored = self.safe_value(self.ohlcvs, symbol)
1113
+ stored = self.ohlcvs[symbol]['unknown']
1114
+ for i in range(0, len(data)):
1115
+ ohlcv = [
1116
+ self.safe_timestamp(data[i], 0),
1117
+ self.safe_number(data[i], 1),
1118
+ self.safe_number(data[i], 2),
1119
+ self.safe_number(data[i], 3),
1120
+ self.safe_number(data[i], 4),
1121
+ self.safe_number(data[i], 5),
1122
+ ]
1123
+ stored.append(ohlcv)
1124
+ dataLength = len(data)
1125
+ if dataLength > 0:
1126
+ client.resolve(stored, messageHash)
1127
+
1128
+ async def fetch_order_ws(self, id: str, symbol: Str = None, params={}):
1129
+ """
1130
+ fetches information on an order made by the user
1131
+ :see: https://docs.cex.io/#ws-api-get-order
1132
+ :param str symbol: not used by cex fetchOrder
1133
+ :param dict [params]: extra parameters specific to the cex api endpoint
1134
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1135
+ """
1136
+ await self.load_markets()
1137
+ await self.authenticate()
1138
+ market = None
1139
+ if symbol is not None:
1140
+ market = self.market(symbol)
1141
+ data = self.extend({
1142
+ 'order_id': str(id),
1143
+ }, params)
1144
+ url = self.urls['api']['ws']
1145
+ messageHash = self.request_id()
1146
+ request: dict = {
1147
+ 'e': 'get-order',
1148
+ 'oid': messageHash,
1149
+ 'data': data,
1150
+ }
1151
+ response = await self.watch(url, messageHash, request, messageHash)
1152
+ return self.parse_order(response, market)
1153
+
1154
+ async def fetch_open_orders_ws(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1155
+ """
1156
+ :see: https://docs.cex.io/#ws-api-open-orders
1157
+ fetch all unfilled currently open orders
1158
+ :param str symbol: unified market symbol
1159
+ :param int [since]: the earliest time in ms to fetch open orders for
1160
+ :param int [limit]: the maximum number of open orders structures to retrieve
1161
+ :param dict [params]: extra parameters specific to the cex api endpoint
1162
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1163
+ """
1164
+ if symbol is None:
1165
+ raise ArgumentsRequired(self.id + 'fetchOpenOrdersWs requires a symbol.')
1166
+ await self.load_markets()
1167
+ await self.authenticate()
1168
+ market = self.market(symbol)
1169
+ url = self.urls['api']['ws']
1170
+ messageHash = self.request_id()
1171
+ data = self.extend({
1172
+ 'pair': [market['baseId'], market['quoteId']],
1173
+ }, params)
1174
+ request: dict = {
1175
+ 'e': 'open-orders',
1176
+ 'oid': messageHash,
1177
+ 'data': data,
1178
+ }
1179
+ response = await self.watch(url, messageHash, request, messageHash)
1180
+ return self.parse_orders(response, market, since, limit, params)
1181
+
1182
+ async def create_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
1183
+ """
1184
+ :see: https://docs.cex.io/#ws-api-order-placement
1185
+ create a trade order
1186
+ :param str symbol: unified symbol of the market to create an order in
1187
+ :param str type: 'market' or 'limit'
1188
+ :param str side: 'buy' or 'sell'
1189
+ :param float amount: how much of currency you want to trade in units of base currency
1190
+ :param float price: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1191
+ :param dict [params]: extra parameters specific to the kraken api endpoint
1192
+ :param boolean [params.maker_only]: Optional, maker only places an order only if offers best sell(<= max) or buy(>= max) price for self pair, if not order placement will be rejected with an error - "Order is not maker"
1193
+ :returns dict: an `order structure <https://docs.ccxt.com/en/latest/manual.html#order-structure>`
1194
+ """
1195
+ if price is None:
1196
+ raise BadRequest(self.id + ' createOrderWs requires a price argument')
1197
+ await self.load_markets()
1198
+ await self.authenticate()
1199
+ market = self.market(symbol)
1200
+ url = self.urls['api']['ws']
1201
+ messageHash = self.request_id()
1202
+ data = self.extend({
1203
+ 'pair': [market['baseId'], market['quoteId']],
1204
+ 'amount': amount,
1205
+ 'price': price,
1206
+ 'type': side,
1207
+ }, params)
1208
+ request: dict = {
1209
+ 'e': 'place-order',
1210
+ 'oid': messageHash,
1211
+ 'data': data,
1212
+ }
1213
+ rawOrder = await self.watch(url, messageHash, request, messageHash)
1214
+ return self.parse_order(rawOrder, market)
1215
+
1216
+ async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}) -> Order:
1217
+ """
1218
+ edit a trade order
1219
+ :see: https://docs.cex.io/#ws-api-cancel-replace
1220
+ :param str id: order id
1221
+ :param str symbol: unified symbol of the market to create an order in
1222
+ :param str type: 'market' or 'limit'
1223
+ :param str side: 'buy' or 'sell'
1224
+ :param float amount: how much of the currency you want to trade in units of the base currency
1225
+ :param float|None [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1226
+ :param dict [params]: extra parameters specific to the cex api endpoint
1227
+ :returns dict: an `order structure <https://docs.ccxt.com/en/latest/manual.html#order-structure>`
1228
+ """
1229
+ if amount is None:
1230
+ raise ArgumentsRequired(self.id + ' editOrder() requires a amount argument')
1231
+ if price is None:
1232
+ raise ArgumentsRequired(self.id + ' editOrder() requires a price argument')
1233
+ await self.load_markets()
1234
+ await self.authenticate()
1235
+ market = self.market(symbol)
1236
+ data = self.extend({
1237
+ 'pair': [market['baseId'], market['quoteId']],
1238
+ 'type': side,
1239
+ 'amount': amount,
1240
+ 'price': price,
1241
+ 'order_id': id,
1242
+ }, params)
1243
+ messageHash = self.request_id()
1244
+ url = self.urls['api']['ws']
1245
+ request: dict = {
1246
+ 'e': 'cancel-replace-order',
1247
+ 'oid': messageHash,
1248
+ 'data': data,
1249
+ }
1250
+ response = await self.watch(url, messageHash, request, messageHash, messageHash)
1251
+ return self.parse_order(response, market)
1252
+
1253
+ async def cancel_order_ws(self, id: str, symbol: Str = None, params={}):
1254
+ """
1255
+ :see: https://docs.cex.io/#ws-api-order-cancel
1256
+ cancels an open order
1257
+ :param str id: order id
1258
+ :param str symbol: not used by cex cancelOrder()
1259
+ :param dict [params]: extra parameters specific to the cex api endpoint
1260
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1261
+ """
1262
+ await self.load_markets()
1263
+ await self.authenticate()
1264
+ market = None
1265
+ if symbol is not None:
1266
+ market = self.market(symbol)
1267
+ data = self.extend({
1268
+ 'order_id': id,
1269
+ }, params)
1270
+ messageHash = self.request_id()
1271
+ url = self.urls['api']['ws']
1272
+ request: dict = {
1273
+ 'e': 'cancel-order',
1274
+ 'oid': messageHash,
1275
+ 'data': data,
1276
+ }
1277
+ response = await self.watch(url, messageHash, request, messageHash, messageHash)
1278
+ return self.parse_order(response, market)
1279
+
1280
+ async def cancel_orders_ws(self, ids: List[str], symbol: Str = None, params={}):
1281
+ """
1282
+ cancel multiple orders
1283
+ :see: https://docs.cex.io/#ws-api-mass-cancel-place
1284
+ :param str[] ids: order ids
1285
+ :param str symbol: not used by cex cancelOrders()
1286
+ :param dict [params]: extra parameters specific to the cex api endpoint
1287
+ :returns dict: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1288
+ """
1289
+ if symbol is not None:
1290
+ raise BadRequest(self.id + ' cancelOrderWs does not allow filtering by symbol')
1291
+ await self.load_markets()
1292
+ await self.authenticate()
1293
+ messageHash = self.request_id()
1294
+ data = self.extend({
1295
+ 'cancel-orders': ids,
1296
+ }, params)
1297
+ url = self.urls['api']['ws']
1298
+ request: dict = {
1299
+ 'e': 'mass-cancel-place-orders',
1300
+ 'oid': messageHash,
1301
+ 'data': data,
1302
+ }
1303
+ response = await self.watch(url, messageHash, request, messageHash, messageHash)
1304
+ #
1305
+ # {
1306
+ # "cancel-orders": [{
1307
+ # "order_id": 69202557979,
1308
+ # "fremains": "0.15000000"
1309
+ # }],
1310
+ # "place-orders": [],
1311
+ # "placed-cancelled": []
1312
+ # }
1313
+ #
1314
+ canceledOrders = self.safe_value(response, 'cancel-orders')
1315
+ return self.parse_orders(canceledOrders, None, None, None, params)
1316
+
1317
+ def resolve_data(self, client: Client, message):
1318
+ #
1319
+ # "e": "open-orders",
1320
+ # "data": [
1321
+ # {
1322
+ # "id": "2477098",
1323
+ # "time": "1435927928618",
1324
+ # "type": "buy",
1325
+ # "price": "241.9477",
1326
+ # "amount": "0.02000000",
1327
+ # "pending": "0.02000000"
1328
+ # },
1329
+ # ...
1330
+ # ],
1331
+ # "oid": "1435927928274_9_open-orders",
1332
+ # "ok": "ok"
1333
+ # }
1334
+ #
1335
+ data = self.safe_value(message, 'data')
1336
+ messageHash = self.safe_string(message, 'oid')
1337
+ client.resolve(data, messageHash)
1338
+
1339
+ def handle_connected(self, client: Client, message):
1340
+ #
1341
+ # {
1342
+ # "e": "connected"
1343
+ # }
1344
+ #
1345
+ return message
1346
+
1347
+ def handle_error_message(self, client: Client, message):
1348
+ #
1349
+ # {
1350
+ # "e": "get-balance",
1351
+ # "data": {error: "Please Login"},
1352
+ # "oid": 1,
1353
+ # "ok": "error"
1354
+ # }
1355
+ #
1356
+ try:
1357
+ data = self.safe_value(message, 'data', {})
1358
+ error = self.safe_string(data, 'error')
1359
+ event = self.safe_string(message, 'e', '')
1360
+ feedback = self.id + ' ' + event + ' ' + error
1361
+ self.throw_exactly_matched_exception(self.exceptions['exact'], error, feedback)
1362
+ self.throw_broadly_matched_exception(self.exceptions['broad'], error, feedback)
1363
+ raise ExchangeError(feedback)
1364
+ except Exception as error:
1365
+ messageHash = self.safe_string(message, 'oid')
1366
+ future = self.safe_value(client['futures'], messageHash)
1367
+ if future is not None:
1368
+ client.reject(error, messageHash)
1369
+ else:
1370
+ raise error
1371
+
1372
+ def handle_message(self, client: Client, message):
1373
+ ok = self.safe_string(message, 'ok')
1374
+ if ok == 'error':
1375
+ self.handle_error_message(client, message)
1376
+ return
1377
+ event = self.safe_string(message, 'e')
1378
+ handlers: dict = {
1379
+ 'auth': self.handle_authentication_message,
1380
+ 'connected': self.handle_connected,
1381
+ 'tick': self.handle_ticker,
1382
+ 'ticker': self.handle_ticker,
1383
+ 'init-ohlcv-data': self.handle_init_ohlcv,
1384
+ 'ohlcv24': self.handle_ohlcv24,
1385
+ 'ohlcv1m': self.handle_ohlcv1m,
1386
+ 'ohlcv': self.handle_ohlcv,
1387
+ 'get-balance': self.handle_balance,
1388
+ 'order-book-subscribe': self.handle_order_book_snapshot,
1389
+ 'md_update': self.handle_order_book_update,
1390
+ 'open-orders': self.resolve_data,
1391
+ 'order': self.handle_order_update,
1392
+ 'history-update': self.handle_trade,
1393
+ 'history': self.handle_trades_snapshot,
1394
+ 'tx': self.handle_transaction,
1395
+ 'place-order': self.resolve_data,
1396
+ 'cancel-replace-order': self.resolve_data,
1397
+ 'cancel-order': self.resolve_data,
1398
+ 'mass-cancel-place-orders': self.resolve_data,
1399
+ 'get-order': self.resolve_data,
1400
+ }
1401
+ handler = self.safe_value(handlers, event)
1402
+ if handler is not None:
1403
+ handler(client, message)
1404
+
1405
+ def handle_authentication_message(self, client: Client, message):
1406
+ #
1407
+ # {
1408
+ # "e": "auth",
1409
+ # "data": {
1410
+ # "ok": "ok"
1411
+ # },
1412
+ # "ok": "ok",
1413
+ # "timestamp":1448034593
1414
+ # }
1415
+ #
1416
+ future = self.safe_value(client.futures, 'authenticated')
1417
+ if future is not None:
1418
+ future.resolve(True)
1419
+
1420
+ async def authenticate(self, params={}):
1421
+ url = self.urls['api']['ws']
1422
+ client = self.client(url)
1423
+ messageHash = 'authenticated'
1424
+ future = client.future('authenticated')
1425
+ authenticated = self.safe_value(client.subscriptions, messageHash)
1426
+ if authenticated is None:
1427
+ self.check_required_credentials()
1428
+ nonce = str(self.seconds())
1429
+ auth = nonce + self.apiKey
1430
+ signature = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256)
1431
+ request: dict = {
1432
+ 'e': 'auth',
1433
+ 'auth': {
1434
+ 'key': self.apiKey,
1435
+ 'signature': signature.upper(),
1436
+ 'timestamp': nonce,
1437
+ },
1438
+ }
1439
+ await self.watch(url, messageHash, self.extend(request, params), messageHash)
1440
+ return await future