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
@@ -0,0 +1,2232 @@
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
+ from ccxt.async_support.base.exchange import Exchange
7
+ from ccxt.abstract.poloniex import ImplicitAPI
8
+ import hashlib
9
+ from ccxt.base.types import Balances, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees, Transaction, TransferEntry
10
+ from typing import List
11
+ from ccxt.base.errors import ExchangeError
12
+ from ccxt.base.errors import AuthenticationError
13
+ from ccxt.base.errors import PermissionDenied
14
+ from ccxt.base.errors import AccountSuspended
15
+ from ccxt.base.errors import ArgumentsRequired
16
+ from ccxt.base.errors import BadRequest
17
+ from ccxt.base.errors import BadSymbol
18
+ from ccxt.base.errors import InsufficientFunds
19
+ from ccxt.base.errors import InvalidOrder
20
+ from ccxt.base.errors import OrderNotFound
21
+ from ccxt.base.errors import NotSupported
22
+ from ccxt.base.errors import ExchangeNotAvailable
23
+ from ccxt.base.errors import OnMaintenance
24
+ from ccxt.base.errors import RequestTimeout
25
+ from ccxt.base.decimal_to_precision import TICK_SIZE
26
+ from ccxt.base.precise import Precise
27
+
28
+
29
+ class poloniex(Exchange, ImplicitAPI):
30
+
31
+ def describe(self):
32
+ return self.deep_extend(super(poloniex, self).describe(), {
33
+ 'id': 'poloniex',
34
+ 'name': 'Poloniex',
35
+ 'countries': ['US'],
36
+ # 200 requests per second for some unauthenticated market endpoints => 1000ms / 200 = 5ms between requests
37
+ 'rateLimit': 5,
38
+ 'certified': False,
39
+ 'pro': True,
40
+ 'has': {
41
+ 'CORS': None,
42
+ 'spot': True,
43
+ 'margin': None, # has but not fully implemented
44
+ 'swap': False,
45
+ 'future': False,
46
+ 'option': False,
47
+ 'cancelAllOrders': True,
48
+ 'cancelOrder': True,
49
+ 'createDepositAddress': True,
50
+ 'createMarketBuyOrderWithCost': True,
51
+ 'createMarketOrderWithCost': False,
52
+ 'createMarketSellOrderWithCost': False,
53
+ 'createOrder': True,
54
+ 'editOrder': True,
55
+ 'fetchBalance': True,
56
+ 'fetchClosedOrder': False,
57
+ 'fetchCurrencies': True,
58
+ 'fetchDepositAddress': True,
59
+ 'fetchDeposits': True,
60
+ 'fetchDepositsWithdrawals': True,
61
+ 'fetchDepositWithdrawFee': 'emulated',
62
+ 'fetchDepositWithdrawFees': True,
63
+ 'fetchFundingRate': False,
64
+ 'fetchMarginMode': False,
65
+ 'fetchMarkets': True,
66
+ 'fetchMyTrades': True,
67
+ 'fetchOHLCV': True,
68
+ 'fetchOpenInterestHistory': False,
69
+ 'fetchOpenOrder': False,
70
+ 'fetchOpenOrders': True, # True endpoint for open orders
71
+ 'fetchOrder': True,
72
+ 'fetchOrderBook': True,
73
+ 'fetchOrderBooks': False,
74
+ 'fetchOrderTrades': True, # True endpoint for trades of a single open or closed order
75
+ 'fetchPosition': False,
76
+ 'fetchPositionMode': False,
77
+ 'fetchTicker': True,
78
+ 'fetchTickers': True,
79
+ 'fetchTime': True,
80
+ 'fetchTrades': True,
81
+ 'fetchTradingFee': False,
82
+ 'fetchTradingFees': True,
83
+ 'fetchTransactions': 'emulated',
84
+ 'fetchTransfer': False,
85
+ 'fetchTransfers': False,
86
+ 'fetchWithdrawals': True,
87
+ 'sandbox': True,
88
+ 'transfer': True,
89
+ 'withdraw': True,
90
+ },
91
+ 'timeframes': {
92
+ '1m': 'MINUTE_1',
93
+ '5m': 'MINUTE_5',
94
+ '10m': 'MINUTE_10',
95
+ '15m': 'MINUTE_15',
96
+ '30m': 'MINUTE_30',
97
+ '1h': 'HOUR_1',
98
+ '2h': 'HOUR_2',
99
+ '4h': 'HOUR_4',
100
+ '6h': 'HOUR_6',
101
+ '12h': 'HOUR_12',
102
+ '1d': 'DAY_1',
103
+ '3d': 'DAY_3',
104
+ '1w': 'WEEK_1',
105
+ '1M': 'MONTH_1',
106
+ },
107
+ 'urls': {
108
+ 'logo': 'https://user-images.githubusercontent.com/1294454/27766817-e9456312-5ee6-11e7-9b3c-b628ca5626a5.jpg',
109
+ 'api': {
110
+ 'rest': 'https://api.poloniex.com',
111
+ },
112
+ 'test': {
113
+ 'rest': 'https://sand-spot-api-gateway.poloniex.com',
114
+ },
115
+ 'www': 'https://www.poloniex.com',
116
+ 'doc': 'https://docs.poloniex.com',
117
+ 'fees': 'https://poloniex.com/fees',
118
+ 'referral': 'https://poloniex.com/signup?c=UBFZJRPJ',
119
+ },
120
+ 'api': {
121
+ 'public': {
122
+ 'get': {
123
+ 'markets': 20,
124
+ 'markets/{symbol}': 1,
125
+ 'currencies': 20,
126
+ 'currencies/{currency}': 20,
127
+ 'v2/currencies': 20,
128
+ 'v2/currencies/{currency}': 20,
129
+ 'timestamp': 1,
130
+ 'markets/price': 1,
131
+ 'markets/{symbol}/price': 1,
132
+ 'markets/markPrice': 1,
133
+ 'markets/{symbol}/markPrice': 1,
134
+ 'markets/{symbol}/markPriceComponents': 1,
135
+ 'markets/{symbol}/orderBook': 1,
136
+ 'markets/{symbol}/candles': 1,
137
+ 'markets/{symbol}/trades': 20,
138
+ 'markets/ticker24h': 20,
139
+ 'markets/{symbol}/ticker24h': 20,
140
+ 'markets/collateralInfo': 1,
141
+ 'markets/{currency}/collateralInfo': 1,
142
+ 'markets/borrowRatesInfo': 1,
143
+ },
144
+ },
145
+ 'private': {
146
+ 'get': {
147
+ 'accounts': 4,
148
+ 'accounts/balances': 4,
149
+ 'accounts/{id}/balances': 4,
150
+ 'accounts/activity': 20,
151
+ 'accounts/transfer': 20,
152
+ 'accounts/transfer/{id}': 4,
153
+ 'feeinfo': 20,
154
+ 'accounts/interest/history': 1,
155
+ 'subaccounts': 4,
156
+ 'subaccounts/balances': 20,
157
+ 'subaccounts/{id}/balances': 4,
158
+ 'subaccounts/transfer': 20,
159
+ 'subaccounts/transfer/{id}': 4,
160
+ 'wallets/addresses': 20,
161
+ 'wallets/addresses/{currency}': 20,
162
+ 'wallets/activity': 20,
163
+ 'margin/accountMargin': 4,
164
+ 'margin/borrowStatus': 4,
165
+ 'margin/maxSize': 4,
166
+ 'orders': 20,
167
+ 'orders/{id}': 4,
168
+ 'orders/killSwitchStatus': 4,
169
+ 'smartorders': 20,
170
+ 'smartorders/{id}': 4,
171
+ 'orders/history': 20,
172
+ 'smartorders/history': 20,
173
+ 'trades': 20,
174
+ 'orders/{id}/trades': 4,
175
+ },
176
+ 'post': {
177
+ 'accounts/transfer': 4,
178
+ 'subaccounts/transfer': 20,
179
+ 'wallets/address': 20,
180
+ 'wallets/withdraw': 20,
181
+ 'v2/wallets/withdraw': 20,
182
+ 'orders': 4,
183
+ 'orders/batch': 20,
184
+ 'orders/killSwitch': 4,
185
+ 'smartorders': 4,
186
+ },
187
+ 'delete': {
188
+ 'orders/{id}': 4,
189
+ 'orders/cancelByIds': 20,
190
+ 'orders': 20,
191
+ 'smartorders/{id}': 4,
192
+ 'smartorders/cancelByIds': 20,
193
+ 'smartorders': 20,
194
+ },
195
+ 'put': {
196
+ 'orders/{id}': 20,
197
+ 'smartorders/{id}': 20,
198
+ },
199
+ },
200
+ },
201
+ 'fees': {
202
+ 'trading': {
203
+ 'feeSide': 'get',
204
+ # starting from Jan 8 2020
205
+ 'maker': self.parse_number('0.0009'),
206
+ 'taker': self.parse_number('0.0009'),
207
+ },
208
+ 'funding': {},
209
+ },
210
+ 'commonCurrencies': {
211
+ 'AIR': 'AirCoin',
212
+ 'APH': 'AphroditeCoin',
213
+ 'BCC': 'BTCtalkcoin',
214
+ 'BCHABC': 'BCHABC',
215
+ 'BDG': 'Badgercoin',
216
+ 'BTM': 'Bitmark',
217
+ 'CON': 'Coino',
218
+ 'ETHTRON': 'ETH',
219
+ 'GOLD': 'GoldEagles',
220
+ 'GPUC': 'GPU',
221
+ 'HOT': 'Hotcoin',
222
+ 'ITC': 'Information Coin',
223
+ 'KEY': 'KEYCoin',
224
+ 'MASK': 'NFTX Hashmasks Index', # conflict with Mask Network
225
+ 'MEME': 'Degenerator Meme', # Degenerator Meme migrated to Meme Inu, self exchange still has the old price
226
+ 'PLX': 'ParallaxCoin',
227
+ 'REPV2': 'REP',
228
+ 'STR': 'XLM',
229
+ 'SOC': 'SOCC',
230
+ 'TRADE': 'Unitrade',
231
+ 'TRXETH': 'TRX',
232
+ 'XAP': 'API Coin',
233
+ # self is not documented in the API docs for Poloniex
234
+ # https://github.com/ccxt/ccxt/issues/7084
235
+ # when the user calls withdraw('USDT', amount, address, tag, params)
236
+ # with params = {'currencyToWithdrawAs': 'USDTTRON'}
237
+ # or params = {'currencyToWithdrawAs': 'USDTETH'}
238
+ # fetchWithdrawals('USDT') returns the corresponding withdrawals
239
+ # with a USDTTRON or a USDTETH currency id, respectfully
240
+ # therefore we have map them back to the original code USDT
241
+ # otherwise the returned withdrawals are filtered out
242
+ 'USDTBSC': 'USDT',
243
+ 'USDTTRON': 'USDT',
244
+ 'USDTETH': 'USDT',
245
+ 'UST': 'USTC',
246
+ },
247
+ 'options': {
248
+ 'createMarketBuyOrderRequiresPrice': True,
249
+ 'networks': {
250
+ 'BEP20': 'BSC',
251
+ 'ERC20': 'ETH',
252
+ 'TRC20': 'TRON',
253
+ },
254
+ 'limits': {
255
+ 'cost': {
256
+ 'min': {
257
+ 'BTC': 0.0001,
258
+ 'ETH': 0.0001,
259
+ 'USDT': 1.0,
260
+ 'TRX': 100,
261
+ 'BNB': 0.06,
262
+ 'USDC': 1.0,
263
+ 'USDJ': 1.0,
264
+ 'TUSD': 0.0001,
265
+ 'DAI': 1.0,
266
+ 'PAX': 1.0,
267
+ 'BUSD': 1.0,
268
+ },
269
+ },
270
+ },
271
+ 'accountsByType': {
272
+ 'spot': 'spot',
273
+ 'future': 'futures',
274
+ },
275
+ 'accountsById': {
276
+ 'exchange': 'spot',
277
+ 'futures': 'future',
278
+ },
279
+ },
280
+ 'precisionMode': TICK_SIZE,
281
+ 'exceptions': {
282
+ 'exact': {
283
+ # General
284
+ '500': ExchangeNotAvailable, # Internal System Error
285
+ '603': RequestTimeout, # Internal Request Timeout
286
+ '601': BadRequest, # Invalid Parameter
287
+ '415': ExchangeError, # System Error
288
+ '602': ArgumentsRequired, # Missing Required Parameters
289
+ # Accounts
290
+ '21604': BadRequest, # Invalid UserId
291
+ '21600': AuthenticationError, # Account Not Found
292
+ '21605': AuthenticationError, # Invalid Account Type
293
+ '21102': ExchangeError, # Invalid Currency
294
+ '21100': AuthenticationError, # Invalid account
295
+ '21704': AuthenticationError, # Missing UserId and/or AccountId
296
+ '21700': BadRequest, # Error updating accounts
297
+ '21705': BadRequest, # Invalid currency type
298
+ '21707': ExchangeError, # Internal accounts Error
299
+ '21708': BadRequest, # Currency not available to User
300
+ '21601': AccountSuspended, # Account locked. Contact support
301
+ '21711': ExchangeError, # Currency locked. Contact support
302
+ '21709': InsufficientFunds, # Insufficient balance
303
+ '250000': ExchangeError, # Transfer error. Try again later
304
+ '250001': BadRequest, # Invalid toAccount for transfer
305
+ '250002': BadRequest, # Invalid fromAccount for transfer
306
+ '250003': BadRequest, # Invalid transfer amount
307
+ '250004': BadRequest, # Transfer is not supported
308
+ '250005': InsufficientFunds, # Insufficient transfer balance
309
+ '250008': BadRequest, # Invalid transfer currency
310
+ '250012': ExchangeError, # Futures account is not valid
311
+ # Trading
312
+ '21110': BadRequest, # Invalid quote currency
313
+ '10040': BadSymbol, # Invalid symbol
314
+ '10060': ExchangeError, # Symbol setup error
315
+ '10020': BadSymbol, # Invalid currency
316
+ '10041': BadSymbol, # Symbol frozen for trading
317
+ '21340': OnMaintenance, # No order creation/cancelation is allowed is in Maintenane Mode
318
+ '21341': InvalidOrder, # Post-only orders type allowed is in Post Only Mode
319
+ '21342': InvalidOrder, # Price is higher than highest bid is in Maintenance Mode
320
+ '21343': InvalidOrder, # Price is lower than lowest bid is in Maintenance Mode
321
+ '21351': AccountSuspended, # Trading for self account is frozen. Contact support
322
+ '21352': BadSymbol, # Trading for self currency is frozen
323
+ '21353': PermissionDenied, # Trading for US customers is not supported
324
+ '21354': PermissionDenied, # Account needs to be verified via email before trading is enabled. Contact support
325
+ '21359': OrderNotFound, # {"code" : 21359, "message" : "Order was already canceled or filled."}
326
+ '21360': InvalidOrder, # {"code" : 21360, "message" : "Order size exceeds the limit.Please enter a smaller amount and try again."}
327
+ '24106': BadRequest, # Invalid market depth
328
+ '24201': ExchangeNotAvailable, # Service busy. Try again later
329
+ # Orders
330
+ '21301': OrderNotFound, # Order not found
331
+ '21302': ExchangeError, # Batch cancel order error
332
+ '21304': ExchangeError, # Order is filled
333
+ '21305': OrderNotFound, # Order is canceled
334
+ '21307': ExchangeError, # Error during Order Cancelation
335
+ '21309': InvalidOrder, # Order price must be greater than 0
336
+ '21310': InvalidOrder, # Order price must be less than max price
337
+ '21311': InvalidOrder, # Order price must be greater than min price
338
+ '21312': InvalidOrder, # Client orderId already exists
339
+ '21314': InvalidOrder, # Max limit of open orders(2000) exceeded
340
+ '21315': InvalidOrder, # Client orderId exceeded max length of 17 digits
341
+ '21317': InvalidOrder, # Amount must be greater than 0
342
+ '21319': InvalidOrder, # Invalid order side
343
+ '21320': InvalidOrder, # Invalid order type
344
+ '21321': InvalidOrder, # Invalid timeInForce value
345
+ '21322': InvalidOrder, # Amount is less than minAmount trade limit
346
+ '21324': BadRequest, # Invalid account type
347
+ '21327': InvalidOrder, # Order pice must be greater than 0
348
+ '21328': InvalidOrder, # Order quantity must be greater than 0
349
+ '21330': InvalidOrder, # Quantity is less than minQuantity trade limit
350
+ '21335': InvalidOrder, # Invalid priceScale for self symbol
351
+ '21336': InvalidOrder, # Invalid quantityScale for self symbol
352
+ '21337': InvalidOrder, # Invalid amountScale for self symbol
353
+ '21344': InvalidOrder, # Value of limit param is greater than max value of 100
354
+ '21345': InvalidOrder, # Value of limit param value must be greater than 0
355
+ '21346': InvalidOrder, # Order Id must be of type Long
356
+ '21348': InvalidOrder, # Order type must be LIMIT_MAKER
357
+ '21347': InvalidOrder, # Stop price must be greater than 0
358
+ '21349': InvalidOrder, # Order value is too large
359
+ '21350': InvalidOrder, # Amount must be greater than 1 USDT
360
+ '21355': ExchangeError, # Interval between startTime and endTime in trade/order history has exceeded 7 day limit
361
+ '21356': BadRequest, # Order size would cause too much price movement. Reduce order size.
362
+ '24101': BadSymbol, # Invalid symbol
363
+ '24102': InvalidOrder, # Invalid K-line type
364
+ '24103': InvalidOrder, # Invalid endTime
365
+ '24104': InvalidOrder, # Invalid amount
366
+ '24105': InvalidOrder, # Invalid startTime
367
+ '25020': InvalidOrder, # No active kill switch
368
+ # Smartorders
369
+ '25000': InvalidOrder, # Invalid userId
370
+ '25001': InvalidOrder, # Invalid parameter
371
+ '25002': InvalidOrder, # Invalid userId.
372
+ '25003': ExchangeError, # Unable to place order
373
+ '25004': InvalidOrder, # Client orderId already exists
374
+ '25005': ExchangeError, # Unable to place smart order
375
+ '25006': InvalidOrder, # OrderId and clientOrderId already exists
376
+ '25007': InvalidOrder, # Invalid orderid
377
+ '25008': InvalidOrder, # Both orderId and clientOrderId are required
378
+ '25009': ExchangeError, # Failed to cancel order
379
+ '25010': PermissionDenied, # Unauthorized to cancel order
380
+ '25011': InvalidOrder, # Failed to cancel due to invalid paramters
381
+ '25012': ExchangeError, # Failed to cancel
382
+ '25013': OrderNotFound, # Failed to cancel were not found
383
+ '25014': OrderNotFound, # Failed to cancel were not found
384
+ '25015': OrderNotFound, # Failed to cancel orders exist
385
+ '25016': ExchangeError, # Failed to cancel to release funds
386
+ '25017': ExchangeError, # No orders were canceled
387
+ '25018': BadRequest, # Invalid accountType
388
+ '25019': BadSymbol, # Invalid symbol
389
+ },
390
+ 'broad': {
391
+ },
392
+ },
393
+ })
394
+
395
+ def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
396
+ #
397
+ # [
398
+ # [
399
+ # "22814.01",
400
+ # "22937.42",
401
+ # "22832.57",
402
+ # "22937.42",
403
+ # "3916.58764051",
404
+ # "0.171199",
405
+ # "2982.64647063",
406
+ # "0.130295",
407
+ # 33,
408
+ # 0,
409
+ # "22877.449915304470460711",
410
+ # "MINUTE_5",
411
+ # 1659664800000,
412
+ # 1659665099999
413
+ # ]
414
+ # ]
415
+ #
416
+ return [
417
+ self.safe_integer(ohlcv, 12),
418
+ self.safe_number(ohlcv, 2),
419
+ self.safe_number(ohlcv, 1),
420
+ self.safe_number(ohlcv, 0),
421
+ self.safe_number(ohlcv, 3),
422
+ self.safe_number(ohlcv, 5),
423
+ ]
424
+
425
+ async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
426
+ """
427
+ fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
428
+ :see: https://docs.poloniex.com/#public-endpoints-market-data-candles
429
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
430
+ :param str timeframe: the length of time each candle represents
431
+ :param int [since]: timestamp in ms of the earliest candle to fetch
432
+ :param int [limit]: the maximum amount of candles to fetch
433
+ :param dict [params]: extra parameters specific to the exchange API endpoint
434
+ :param int [params.until]: timestamp in ms
435
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
436
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
437
+ """
438
+ await self.load_markets()
439
+ paginate = False
440
+ paginate, params = self.handle_option_and_params(params, 'fetchOHLCV', 'paginate', False)
441
+ if paginate:
442
+ return await self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 500)
443
+ market = self.market(symbol)
444
+ request: dict = {
445
+ 'symbol': market['id'],
446
+ 'interval': self.safe_string(self.timeframes, timeframe, timeframe),
447
+ }
448
+ if since is not None:
449
+ request['startTime'] = since
450
+ if limit is not None:
451
+ # limit should in between 100 and 500
452
+ request['limit'] = limit
453
+ request, params = self.handle_until_option('endTime', request, params)
454
+ response = await self.publicGetMarketsSymbolCandles(self.extend(request, params))
455
+ #
456
+ # [
457
+ # [
458
+ # "22814.01",
459
+ # "22937.42",
460
+ # "22832.57",
461
+ # "22937.42",
462
+ # "3916.58764051",
463
+ # "0.171199",
464
+ # "2982.64647063",
465
+ # "0.130295",
466
+ # 33,
467
+ # 0,
468
+ # "22877.449915304470460711",
469
+ # "MINUTE_5",
470
+ # 1659664800000,
471
+ # 1659665099999
472
+ # ]
473
+ # ]
474
+ #
475
+ return self.parse_ohlcvs(response, market, timeframe, since, limit)
476
+
477
+ async def load_markets(self, reload=False, params={}):
478
+ markets = await super(poloniex, self).load_markets(reload, params)
479
+ currenciesByNumericId = self.safe_value(self.options, 'currenciesByNumericId')
480
+ if (currenciesByNumericId is None) or reload:
481
+ self.options['currenciesByNumericId'] = self.index_by(self.currencies, 'numericId')
482
+ return markets
483
+
484
+ async def fetch_markets(self, params={}) -> List[Market]:
485
+ """
486
+ retrieves data on all markets for poloniex
487
+ :see: https://docs.poloniex.com/#public-endpoints-reference-data-symbol-information
488
+ :param dict [params]: extra parameters specific to the exchange API endpoint
489
+ :returns dict[]: an array of objects representing market data
490
+ """
491
+ markets = await self.publicGetMarkets(params)
492
+ #
493
+ # [
494
+ # {
495
+ # "symbol" : "BTS_BTC",
496
+ # "baseCurrencyName" : "BTS",
497
+ # "quoteCurrencyName" : "BTC",
498
+ # "displayName" : "BTS/BTC",
499
+ # "state" : "NORMAL",
500
+ # "visibleStartTime" : 1659018816626,
501
+ # "tradableStartTime" : 1659018816626,
502
+ # "symbolTradeLimit" : {
503
+ # "symbol" : "BTS_BTC",
504
+ # "priceScale" : 10,
505
+ # "quantityScale" : 0,
506
+ # "amountScale" : 8,
507
+ # "minQuantity" : "100",
508
+ # "minAmount" : "0.00001",
509
+ # "highestBid" : "0",
510
+ # "lowestAsk" : "0"
511
+ # }
512
+ # }
513
+ # ]
514
+ #
515
+ return self.parse_markets(markets)
516
+
517
+ def parse_market(self, market: dict) -> Market:
518
+ id = self.safe_string(market, 'symbol')
519
+ baseId = self.safe_string(market, 'baseCurrencyName')
520
+ quoteId = self.safe_string(market, 'quoteCurrencyName')
521
+ base = self.safe_currency_code(baseId)
522
+ quote = self.safe_currency_code(quoteId)
523
+ state = self.safe_string(market, 'state')
524
+ active = state == 'NORMAL'
525
+ symbolTradeLimit = self.safe_value(market, 'symbolTradeLimit')
526
+ # these are known defaults
527
+ return {
528
+ 'id': id,
529
+ 'symbol': base + '/' + quote,
530
+ 'base': base,
531
+ 'quote': quote,
532
+ 'settle': None,
533
+ 'baseId': baseId,
534
+ 'quoteId': quoteId,
535
+ 'settleId': None,
536
+ 'type': 'spot',
537
+ 'spot': True,
538
+ 'margin': False,
539
+ 'swap': False,
540
+ 'future': False,
541
+ 'option': False,
542
+ 'active': active,
543
+ 'contract': False,
544
+ 'linear': None,
545
+ 'inverse': None,
546
+ 'contractSize': None,
547
+ 'expiry': None,
548
+ 'expiryDatetime': None,
549
+ 'strike': None,
550
+ 'optionType': None,
551
+ 'precision': {
552
+ 'amount': self.parse_number(self.parse_precision(self.safe_string(symbolTradeLimit, 'quantityScale'))),
553
+ 'price': self.parse_number(self.parse_precision(self.safe_string(symbolTradeLimit, 'priceScale'))),
554
+ },
555
+ 'limits': {
556
+ 'amount': {
557
+ 'min': self.safe_number(symbolTradeLimit, 'minQuantity'),
558
+ 'max': None,
559
+ },
560
+ 'price': {
561
+ 'min': None,
562
+ 'max': None,
563
+ },
564
+ 'cost': {
565
+ 'min': self.safe_number(symbolTradeLimit, 'minAmount'),
566
+ 'max': None,
567
+ },
568
+ },
569
+ 'created': self.safe_integer(market, 'tradableStartTime'),
570
+ 'info': market,
571
+ }
572
+
573
+ async def fetch_time(self, params={}):
574
+ """
575
+ fetches the current integer timestamp in milliseconds from the exchange server
576
+ :see: https://docs.poloniex.com/#public-endpoints-reference-data-system-timestamp
577
+ :param dict [params]: extra parameters specific to the exchange API endpoint
578
+ :returns int: the current integer timestamp in milliseconds from the exchange server
579
+ """
580
+ response = await self.publicGetTimestamp(params)
581
+ return self.safe_integer(response, 'serverTime')
582
+
583
+ def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
584
+ #
585
+ # {
586
+ # "symbol" : "BTC_USDT",
587
+ # "open" : "26053.33",
588
+ # "low" : "26053.33",
589
+ # "high" : "26798.02",
590
+ # "close" : "26447.58",
591
+ # "quantity" : "6116.210188",
592
+ # "amount" : "161082122.88450926",
593
+ # "tradeCount" : "134709",
594
+ # "startTime" : "1692784440000",
595
+ # "closeTime" : "1692870839630",
596
+ # "displayName" : "BTC/USDT",
597
+ # "dailyChange" : "0.0151",
598
+ # "bid" : "26447.57",
599
+ # "bidQuantity" : "0.016313",
600
+ # "ask" : "26447.58",
601
+ # "askQuantity" : "0.068307",
602
+ # "ts" : "1692870845446",
603
+ # "markPrice" : "26444.11"
604
+ # }
605
+ #
606
+ timestamp = self.safe_integer(ticker, 'ts')
607
+ marketId = self.safe_string(ticker, 'symbol')
608
+ market = self.safe_market(marketId)
609
+ close = self.safe_string(ticker, 'close')
610
+ relativeChange = self.safe_string(ticker, 'dailyChange')
611
+ percentage = Precise.string_mul(relativeChange, '100')
612
+ bidVolume = self.safe_string(ticker, 'bidQuantity')
613
+ askVolume = self.safe_string(ticker, 'askQuantity')
614
+ return self.safe_ticker({
615
+ 'id': marketId,
616
+ 'symbol': market['symbol'],
617
+ 'timestamp': timestamp,
618
+ 'datetime': self.iso8601(timestamp),
619
+ 'high': self.safe_string(ticker, 'high'),
620
+ 'low': self.safe_string(ticker, 'low'),
621
+ 'bid': self.safe_string(ticker, 'bid'),
622
+ 'bidVolume': bidVolume,
623
+ 'ask': self.safe_string(ticker, 'ask'),
624
+ 'askVolume': askVolume,
625
+ 'vwap': None,
626
+ 'open': self.safe_string(ticker, 'open'),
627
+ 'close': close,
628
+ 'last': close,
629
+ 'previousClose': None,
630
+ 'change': None,
631
+ 'percentage': percentage,
632
+ 'average': None,
633
+ 'baseVolume': self.safe_string(ticker, 'quantity'),
634
+ 'quoteVolume': self.safe_string(ticker, 'amount'),
635
+ 'info': ticker,
636
+ }, market)
637
+
638
+ async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
639
+ """
640
+ fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
641
+ :see: https://docs.poloniex.com/#public-endpoints-market-data-ticker
642
+ :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
643
+ :param dict [params]: extra parameters specific to the exchange API endpoint
644
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
645
+ """
646
+ await self.load_markets()
647
+ symbols = self.market_symbols(symbols)
648
+ response = await self.publicGetMarketsTicker24h(params)
649
+ #
650
+ # [
651
+ # {
652
+ # "symbol" : "BTC_USDT",
653
+ # "open" : "26053.33",
654
+ # "low" : "26053.33",
655
+ # "high" : "26798.02",
656
+ # "close" : "26447.58",
657
+ # "quantity" : "6116.210188",
658
+ # "amount" : "161082122.88450926",
659
+ # "tradeCount" : "134709",
660
+ # "startTime" : "1692784440000",
661
+ # "closeTime" : "1692870839630",
662
+ # "displayName" : "BTC/USDT",
663
+ # "dailyChange" : "0.0151",
664
+ # "bid" : "26447.57",
665
+ # "bidQuantity" : "0.016313",
666
+ # "ask" : "26447.58",
667
+ # "askQuantity" : "0.068307",
668
+ # "ts" : "1692870845446",
669
+ # "markPrice" : "26444.11"
670
+ # }
671
+ # ]
672
+ #
673
+ return self.parse_tickers(response, symbols)
674
+
675
+ async def fetch_currencies(self, params={}) -> Currencies:
676
+ """
677
+ fetches all available currencies on an exchange
678
+ :see: https://docs.poloniex.com/#public-endpoints-reference-data-currency-information
679
+ :param dict [params]: extra parameters specific to the exchange API endpoint
680
+ :returns dict: an associative dictionary of currencies
681
+ """
682
+ response = await self.publicGetCurrencies(self.extend(params, {'includeMultiChainCurrencies': True}))
683
+ #
684
+ # [
685
+ # {
686
+ # "1CR": {
687
+ # "id": 1,
688
+ # "name": "1CRedit",
689
+ # "description": "BTC Clone",
690
+ # "type": "address",
691
+ # "withdrawalFee": "0.01000000",
692
+ # "minConf": 10000,
693
+ # "depositAddress": null,
694
+ # "blockchain": "1CR",
695
+ # "delisted": False,
696
+ # "tradingState": "NORMAL",
697
+ # "walletState": "DISABLED",
698
+ # "walletDepositState": "DISABLED",
699
+ # "walletWithdrawalState": "DISABLED",
700
+ # "parentChain": null,
701
+ # "isMultiChain": False,
702
+ # "isChildChain": False,
703
+ # "childChains": []
704
+ # }
705
+ # }
706
+ # ]
707
+ #
708
+ result: dict = {}
709
+ for i in range(0, len(response)):
710
+ item = self.safe_value(response, i)
711
+ ids = list(item.keys())
712
+ id = self.safe_value(ids, 0)
713
+ currency = self.safe_value(item, id)
714
+ code = self.safe_currency_code(id)
715
+ name = self.safe_string(currency, 'name')
716
+ networkId = self.safe_string(currency, 'blockchain')
717
+ networkCode = None
718
+ if networkId is not None:
719
+ networkCode = self.network_id_to_code(networkId, code)
720
+ delisted = self.safe_value(currency, 'delisted')
721
+ walletEnabled = self.safe_string(currency, 'walletState') == 'ENABLED'
722
+ depositEnabled = self.safe_string(currency, 'walletDepositState') == 'ENABLED'
723
+ withdrawEnabled = self.safe_string(currency, 'walletWithdrawalState') == 'ENABLED'
724
+ active = not delisted and walletEnabled and depositEnabled and withdrawEnabled
725
+ numericId = self.safe_integer(currency, 'id')
726
+ feeString = self.safe_string(currency, 'withdrawalFee')
727
+ parentChain = self.safe_value(currency, 'parentChain')
728
+ noParentChain = parentChain is None
729
+ if self.safe_value(result, code) is None:
730
+ result[code] = {
731
+ 'id': id,
732
+ 'code': code,
733
+ 'info': None,
734
+ 'name': name,
735
+ 'active': active,
736
+ 'deposit': depositEnabled,
737
+ 'withdraw': withdrawEnabled,
738
+ 'fee': self.parse_number(feeString),
739
+ 'precision': None,
740
+ 'limits': {
741
+ 'amount': {
742
+ 'min': None,
743
+ 'max': None,
744
+ },
745
+ 'deposit': {
746
+ 'min': None,
747
+ 'max': None,
748
+ },
749
+ 'withdraw': {
750
+ 'min': None,
751
+ 'max': None,
752
+ },
753
+ },
754
+ }
755
+ minFeeString = self.safe_string(result[code], 'fee')
756
+ if feeString is not None:
757
+ minFeeString = feeString if (minFeeString is None) else Precise.string_min(feeString, minFeeString)
758
+ depositAvailable = self.safe_value(result[code], 'deposit')
759
+ depositAvailable = depositEnabled if (depositEnabled) else depositAvailable
760
+ withdrawAvailable = self.safe_value(result[code], 'withdraw')
761
+ withdrawAvailable = withdrawEnabled if (withdrawEnabled) else withdrawAvailable
762
+ networks = self.safe_value(result[code], 'networks', {})
763
+ if networkCode is not None:
764
+ networks[networkCode] = {
765
+ 'info': currency,
766
+ 'id': networkId,
767
+ 'network': networkCode,
768
+ 'currencyId': id,
769
+ 'numericId': numericId,
770
+ 'deposit': depositEnabled,
771
+ 'withdraw': withdrawEnabled,
772
+ 'active': active,
773
+ 'fee': self.parse_number(feeString),
774
+ 'precision': None,
775
+ 'limits': {
776
+ 'amount': {
777
+ 'min': None,
778
+ 'max': None,
779
+ },
780
+ 'withdraw': {
781
+ 'min': None,
782
+ 'max': None,
783
+ },
784
+ 'deposit': {
785
+ 'min': None,
786
+ 'max': None,
787
+ },
788
+ },
789
+ }
790
+ result[code]['networks'] = networks
791
+ info = self.safe_value(result[code], 'info', [])
792
+ rawInfo: dict = {}
793
+ rawInfo[id] = currency
794
+ info.append(rawInfo)
795
+ result[code]['info'] = info
796
+ if noParentChain:
797
+ result[code]['id'] = id
798
+ result[code]['name'] = name
799
+ result[code]['active'] = depositAvailable and withdrawAvailable
800
+ result[code]['deposit'] = depositAvailable
801
+ result[code]['withdraw'] = withdrawAvailable
802
+ result[code]['fee'] = self.parse_number(minFeeString)
803
+ return result
804
+
805
+ async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
806
+ """
807
+ fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
808
+ :see: https://docs.poloniex.com/#public-endpoints-market-data-ticker
809
+ :param str symbol: unified symbol of the market to fetch the ticker for
810
+ :param dict [params]: extra parameters specific to the exchange API endpoint
811
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
812
+ """
813
+ await self.load_markets()
814
+ market = self.market(symbol)
815
+ request: dict = {
816
+ 'symbol': market['id'],
817
+ }
818
+ response = await self.publicGetMarketsSymbolTicker24h(self.extend(request, params))
819
+ #
820
+ # {
821
+ # "symbol" : "BTC_USDT",
822
+ # "open" : "26053.33",
823
+ # "low" : "26053.33",
824
+ # "high" : "26798.02",
825
+ # "close" : "26447.58",
826
+ # "quantity" : "6116.210188",
827
+ # "amount" : "161082122.88450926",
828
+ # "tradeCount" : "134709",
829
+ # "startTime" : "1692784440000",
830
+ # "closeTime" : "1692870839630",
831
+ # "displayName" : "BTC/USDT",
832
+ # "dailyChange" : "0.0151",
833
+ # "bid" : "26447.57",
834
+ # "bidQuantity" : "0.016313",
835
+ # "ask" : "26447.58",
836
+ # "askQuantity" : "0.068307",
837
+ # "ts" : "1692870845446",
838
+ # "markPrice" : "26444.11"
839
+ # }
840
+ #
841
+ return self.parse_ticker(response, market)
842
+
843
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
844
+ #
845
+ # fetchTrades
846
+ #
847
+ # {
848
+ # "id" : "60014521",
849
+ # "price" : "23162.94",
850
+ # "quantity" : "0.00009",
851
+ # "amount" : "2.0846646",
852
+ # "takerSide" : "SELL",
853
+ # "ts" : 1659684602042,
854
+ # "createTime" : 1659684602036
855
+ # }
856
+ #
857
+ # fetchMyTrades
858
+ #
859
+ # {
860
+ # "id": "32164924331503616",
861
+ # "symbol": "LINK_USDT",
862
+ # "accountType": "SPOT",
863
+ # "orderId": "32164923987566592",
864
+ # "side": "SELL",
865
+ # "type": "MARKET",
866
+ # "matchRole": "TAKER",
867
+ # "createTime": 1648635115525,
868
+ # "price": "11",
869
+ # "quantity": "0.5",
870
+ # "amount": "5.5",
871
+ # "feeCurrency": "USDT",
872
+ # "feeAmount": "0.007975",
873
+ # "pageId": "32164924331503616",
874
+ # "clientOrderId": "myOwnId-321"
875
+ # }
876
+ #
877
+ # fetchOrderTrades(taker trades)
878
+ #
879
+ # {
880
+ # "id": "30341456333942784",
881
+ # "symbol": "LINK_USDT",
882
+ # "accountType": "SPOT",
883
+ # "orderId": "30249408733945856",
884
+ # "side": "BUY",
885
+ # "type": "LIMIT",
886
+ # "matchRole": "MAKER",
887
+ # "createTime": 1648200366864,
888
+ # "price": "3.1",
889
+ # "quantity": "1",
890
+ # "amount": "3.1",
891
+ # "feeCurrency": "LINK",
892
+ # "feeAmount": "0.00145",
893
+ # "pageId": "30341456333942784",
894
+ # "clientOrderId": ""
895
+ # }
896
+ #
897
+ #
898
+ id = self.safe_string_2(trade, 'id', 'tradeID')
899
+ orderId = self.safe_string(trade, 'orderId')
900
+ timestamp = self.safe_integer_2(trade, 'ts', 'createTime')
901
+ marketId = self.safe_string(trade, 'symbol')
902
+ market = self.safe_market(marketId, market, '_')
903
+ symbol = market['symbol']
904
+ side = self.safe_string_lower_2(trade, 'side', 'takerSide')
905
+ fee = None
906
+ priceString = self.safe_string(trade, 'price')
907
+ amountString = self.safe_string(trade, 'quantity')
908
+ costString = self.safe_string(trade, 'amount')
909
+ feeCurrencyId = self.safe_string(trade, 'feeCurrency')
910
+ feeCostString = self.safe_string(trade, 'feeAmount')
911
+ if feeCostString is not None:
912
+ feeCurrencyCode = self.safe_currency_code(feeCurrencyId)
913
+ fee = {
914
+ 'cost': feeCostString,
915
+ 'currency': feeCurrencyCode,
916
+ }
917
+ return self.safe_trade({
918
+ 'id': id,
919
+ 'info': trade,
920
+ 'timestamp': timestamp,
921
+ 'datetime': self.iso8601(timestamp),
922
+ 'symbol': symbol,
923
+ 'order': orderId,
924
+ 'type': self.safe_string_lower(trade, 'type'),
925
+ 'side': side,
926
+ 'takerOrMaker': self.safe_string_lower(trade, 'matchRole'),
927
+ 'price': priceString,
928
+ 'amount': amountString,
929
+ 'cost': costString,
930
+ 'fee': fee,
931
+ }, market)
932
+
933
+ async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
934
+ """
935
+ get the list of most recent trades for a particular symbol
936
+ :see: https://docs.poloniex.com/#public-endpoints-market-data-trades
937
+ :param str symbol: unified symbol of the market to fetch trades for
938
+ :param int [since]: timestamp in ms of the earliest trade to fetch
939
+ :param int [limit]: the maximum amount of trades to fetch
940
+ :param dict [params]: extra parameters specific to the exchange API endpoint
941
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
942
+ """
943
+ await self.load_markets()
944
+ market = self.market(symbol)
945
+ request: dict = {
946
+ 'symbol': market['id'],
947
+ }
948
+ if limit is not None:
949
+ request['limit'] = limit
950
+ trades = await self.publicGetMarketsSymbolTrades(self.extend(request, params))
951
+ #
952
+ # [
953
+ # {
954
+ # "id" : "60014521",
955
+ # "price" : "23162.94",
956
+ # "quantity" : "0.00009",
957
+ # "amount" : "2.0846646",
958
+ # "takerSide" : "SELL",
959
+ # "ts" : 1659684602042,
960
+ # "createTime" : 1659684602036
961
+ # }
962
+ # ]
963
+ #
964
+ return self.parse_trades(trades, market, since, limit)
965
+
966
+ async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
967
+ """
968
+ fetch all trades made by the user
969
+ :see: https://docs.poloniex.com/#authenticated-endpoints-trades-trade-history
970
+ :param str symbol: unified market symbol
971
+ :param int [since]: the earliest time in ms to fetch trades for
972
+ :param int [limit]: the maximum number of trades structures to retrieve
973
+ :param dict [params]: extra parameters specific to the exchange API endpoint
974
+ :param int [params.until]: the latest time in ms to fetch entries for
975
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
976
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
977
+ """
978
+ await self.load_markets()
979
+ paginate = False
980
+ paginate, params = self.handle_option_and_params(params, 'fetchMyTrades', 'paginate')
981
+ if paginate:
982
+ return await self.fetch_paginated_call_dynamic('fetchMyTrades', symbol, since, limit, params)
983
+ market: Market = None
984
+ if symbol is not None:
985
+ market = self.market(symbol)
986
+ request: dict = {
987
+ # 'from': 12345678, # A 'trade Id'. The query begins at ‘from'.
988
+ # 'direction': 'PRE', # PRE, NEXT The direction before or after ‘from'.
989
+ }
990
+ if since is not None:
991
+ request['startTime'] = since
992
+ if limit is not None:
993
+ request['limit'] = limit
994
+ request, params = self.handle_until_option('endTime', request, params)
995
+ response = await self.privateGetTrades(self.extend(request, params))
996
+ #
997
+ # [
998
+ # {
999
+ # "id": "32164924331503616",
1000
+ # "symbol": "LINK_USDT",
1001
+ # "accountType": "SPOT",
1002
+ # "orderId": "32164923987566592",
1003
+ # "side": "SELL",
1004
+ # "type": "MARKET",
1005
+ # "matchRole": "TAKER",
1006
+ # "createTime": 1648635115525,
1007
+ # "price": "11",
1008
+ # "quantity": "0.5",
1009
+ # "amount": "5.5",
1010
+ # "feeCurrency": "USDT",
1011
+ # "feeAmount": "0.007975",
1012
+ # "pageId": "32164924331503616",
1013
+ # "clientOrderId": "myOwnId-321"
1014
+ # }
1015
+ # ]
1016
+ #
1017
+ result = self.parse_trades(response, market, since, limit)
1018
+ return result
1019
+
1020
+ def parse_order_status(self, status: Str):
1021
+ statuses: dict = {
1022
+ 'NEW': 'open',
1023
+ 'PARTIALLY_FILLED': 'open',
1024
+ 'FILLED': 'closed',
1025
+ 'PENDING_CANCEL': 'canceled',
1026
+ 'PARTIALLY_CANCELED': 'canceled',
1027
+ 'CANCELED': 'canceled',
1028
+ 'FAILED': 'canceled',
1029
+ }
1030
+ return self.safe_string(statuses, status, status)
1031
+
1032
+ def parse_order(self, order: dict, market: Market = None) -> Order:
1033
+ #
1034
+ # fetchOpenOrder
1035
+ #
1036
+ # {
1037
+ # "id" : "7xxxxxxxxxxxxxxx6",
1038
+ # "clientOrderId" : "",
1039
+ # "symbol" : "ETH_USDT",
1040
+ # "state" : "NEW",
1041
+ # "accountType" : "SPOT",
1042
+ # "side" : "BUY",
1043
+ # "type" : "LIMIT",
1044
+ # "timeInForce" : "GTC",
1045
+ # "quantity" : "0.001",
1046
+ # "price" : "1600",
1047
+ # "avgPrice" : "0",
1048
+ # "amount" : "0",
1049
+ # "filledQuantity" : "0",
1050
+ # "filledAmount" : "0",
1051
+ # "createTime" : 16xxxxxxxxx26,
1052
+ # "updateTime" : 16xxxxxxxxx36
1053
+ # }
1054
+ #
1055
+ # fetchOpenOrders
1056
+ #
1057
+ # {
1058
+ # "id": "24993088082542592",
1059
+ # "clientOrderId": "",
1060
+ # "symbol": "ELON_USDC",
1061
+ # "state": "NEW",
1062
+ # "accountType": "SPOT",
1063
+ # "side": "SELL",
1064
+ # "type": "MARKET",
1065
+ # "timeInForce": "GTC",
1066
+ # "quantity": "1.00",
1067
+ # "price": "0.00",
1068
+ # "avgPrice": "0.00",
1069
+ # "amount": "0.00",
1070
+ # "filledQuantity": "0.00",
1071
+ # "filledAmount": "0.00",
1072
+ # "createTime": 1646925216548,
1073
+ # "updateTime": 1646925216548
1074
+ # }
1075
+ #
1076
+ # createOrder, editOrder
1077
+ #
1078
+ # {
1079
+ # "id": "29772698821328896",
1080
+ # "clientOrderId": "1234Abc"
1081
+ # }
1082
+ #
1083
+ timestamp = self.safe_integer_2(order, 'timestamp', 'createTime')
1084
+ if timestamp is None:
1085
+ timestamp = self.parse8601(self.safe_string(order, 'date'))
1086
+ marketId = self.safe_string(order, 'symbol')
1087
+ market = self.safe_market(marketId, market, '_')
1088
+ symbol = market['symbol']
1089
+ resultingTrades = self.safe_value(order, 'resultingTrades')
1090
+ if not isinstance(resultingTrades, list):
1091
+ resultingTrades = self.safe_value(resultingTrades, self.safe_string(market, 'id', marketId))
1092
+ price = self.safe_string_2(order, 'price', 'rate')
1093
+ amount = self.safe_string(order, 'quantity')
1094
+ filled = self.safe_string(order, 'filledQuantity')
1095
+ status = self.parse_order_status(self.safe_string(order, 'state'))
1096
+ side = self.safe_string_lower(order, 'side')
1097
+ rawType = self.safe_string(order, 'type')
1098
+ type = self.parse_order_type(rawType)
1099
+ id = self.safe_string_n(order, ['orderNumber', 'id', 'orderId'])
1100
+ fee = None
1101
+ feeCurrency = self.safe_string(order, 'tokenFeeCurrency')
1102
+ feeCost: Str = None
1103
+ feeCurrencyCode: Str = None
1104
+ rate = self.safe_string(order, 'fee')
1105
+ if feeCurrency is None:
1106
+ feeCurrencyCode = market['base'] if (side == 'buy') else market['quote']
1107
+ else:
1108
+ # poloniex accepts a 30% discount to pay fees in TRX
1109
+ feeCurrencyCode = self.safe_currency_code(feeCurrency)
1110
+ feeCost = self.safe_string(order, 'tokenFee')
1111
+ if feeCost is not None:
1112
+ fee = {
1113
+ 'rate': rate,
1114
+ 'cost': feeCost,
1115
+ 'currency': feeCurrencyCode,
1116
+ }
1117
+ clientOrderId = self.safe_string(order, 'clientOrderId')
1118
+ triggerPrice = self.safe_string_2(order, 'triggerPrice', 'stopPrice')
1119
+ return self.safe_order({
1120
+ 'info': order,
1121
+ 'id': id,
1122
+ 'clientOrderId': clientOrderId,
1123
+ 'timestamp': timestamp,
1124
+ 'datetime': self.iso8601(timestamp),
1125
+ 'lastTradeTimestamp': self.safe_integer(order, 'updateTime'),
1126
+ 'status': status,
1127
+ 'symbol': symbol,
1128
+ 'type': type,
1129
+ 'timeInForce': self.safe_string(order, 'timeInForce'),
1130
+ 'postOnly': None,
1131
+ 'side': side,
1132
+ 'price': price,
1133
+ 'stopPrice': triggerPrice,
1134
+ 'triggerPrice': triggerPrice,
1135
+ 'cost': None,
1136
+ 'average': self.safe_string(order, 'avgPrice'),
1137
+ 'amount': amount,
1138
+ 'filled': filled,
1139
+ 'remaining': None,
1140
+ 'trades': resultingTrades,
1141
+ 'fee': fee,
1142
+ }, market)
1143
+
1144
+ def parse_order_type(self, status):
1145
+ statuses: dict = {
1146
+ 'MARKET': 'market',
1147
+ 'LIMIT': 'limit',
1148
+ 'STOP-LIMIT': 'limit',
1149
+ 'STOP-MARKET': 'market',
1150
+ }
1151
+ return self.safe_string(statuses, status, status)
1152
+
1153
+ def parse_open_orders(self, orders, market, result):
1154
+ for i in range(0, len(orders)):
1155
+ order = orders[i]
1156
+ extended = self.extend(order, {
1157
+ 'status': 'open',
1158
+ 'type': 'limit',
1159
+ 'side': order['type'],
1160
+ 'price': order['rate'],
1161
+ })
1162
+ result.append(self.parse_order(extended, market))
1163
+ return result
1164
+
1165
+ async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1166
+ """
1167
+ fetch all unfilled currently open orders
1168
+ :see: https://docs.poloniex.com/#authenticated-endpoints-orders-open-orders
1169
+ :see: https://docs.poloniex.com/#authenticated-endpoints-smart-orders-open-orders # trigger orders
1170
+ :param str symbol: unified market symbol
1171
+ :param int [since]: the earliest time in ms to fetch open orders for
1172
+ :param int [limit]: the maximum number of open orders structures to retrieve
1173
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1174
+ :param boolean [params.stop]: set True to fetch trigger orders instead of regular orders
1175
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1176
+ """
1177
+ await self.load_markets()
1178
+ market: Market = None
1179
+ request: dict = {}
1180
+ if symbol is not None:
1181
+ market = self.market(symbol)
1182
+ request['symbol'] = market['id']
1183
+ if limit is not None:
1184
+ request['limit'] = limit
1185
+ isTrigger = self.safe_value_2(params, 'trigger', 'stop')
1186
+ params = self.omit(params, ['trigger', 'stop'])
1187
+ response = None
1188
+ if isTrigger:
1189
+ response = await self.privateGetSmartorders(self.extend(request, params))
1190
+ else:
1191
+ response = await self.privateGetOrders(self.extend(request, params))
1192
+ #
1193
+ # [
1194
+ # {
1195
+ # "id" : "7xxxxxxxxxxxxxxx6",
1196
+ # "clientOrderId" : "",
1197
+ # "symbol" : "ETH_USDT",
1198
+ # "state" : "NEW",
1199
+ # "accountType" : "SPOT",
1200
+ # "side" : "BUY",
1201
+ # "type" : "LIMIT",
1202
+ # "timeInForce" : "GTC",
1203
+ # "quantity" : "0.001",
1204
+ # "price" : "1600",
1205
+ # "avgPrice" : "0",
1206
+ # "amount" : "0",
1207
+ # "filledQuantity" : "0",
1208
+ # "filledAmount" : "0",
1209
+ # "stopPrice": "3750.00", # for trigger orders
1210
+ # "createTime" : 16xxxxxxxxx26,
1211
+ # "updateTime" : 16xxxxxxxxx36
1212
+ # }
1213
+ # ]
1214
+ #
1215
+ extension: dict = {'status': 'open'}
1216
+ return self.parse_orders(response, market, since, limit, extension)
1217
+
1218
+ async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1219
+ """
1220
+ create a trade order
1221
+ :see: https://docs.poloniex.com/#authenticated-endpoints-orders-create-order
1222
+ :see: https://docs.poloniex.com/#authenticated-endpoints-smart-orders-create-order # trigger orders
1223
+ :param str symbol: unified symbol of the market to create an order in
1224
+ :param str type: 'market' or 'limit'
1225
+ :param str side: 'buy' or 'sell'
1226
+ :param float amount: how much of currency you want to trade in units of base currency
1227
+ :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1228
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1229
+ :param float [params.triggerPrice]: *spot only* The price at which a trigger order is triggered at
1230
+ :param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
1231
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1232
+ """
1233
+ await self.load_markets()
1234
+ market = self.market(symbol)
1235
+ if not market['spot']:
1236
+ raise NotSupported(self.id + ' createOrder() does not support ' + market['type'] + ' orders, only spot orders are accepted')
1237
+ request: dict = {
1238
+ 'symbol': market['id'],
1239
+ 'side': side,
1240
+ # 'timeInForce': timeInForce,
1241
+ # 'accountType': 'SPOT',
1242
+ # 'amount': amount,
1243
+ }
1244
+ triggerPrice = self.safe_number_2(params, 'stopPrice', 'triggerPrice')
1245
+ request, params = self.order_request(symbol, type, side, amount, request, price, params)
1246
+ response = None
1247
+ if triggerPrice is not None:
1248
+ response = await self.privatePostSmartorders(self.extend(request, params))
1249
+ else:
1250
+ response = await self.privatePostOrders(self.extend(request, params))
1251
+ #
1252
+ # {
1253
+ # "id" : "78923648051920896",
1254
+ # "clientOrderId" : ""
1255
+ # }
1256
+ #
1257
+ response = self.extend(response, {
1258
+ 'type': side,
1259
+ })
1260
+ return self.parse_order(response, market)
1261
+
1262
+ def order_request(self, symbol, type, side, amount, request, price=None, params={}):
1263
+ upperCaseType = type.upper()
1264
+ isMarket = upperCaseType == 'MARKET'
1265
+ isPostOnly = self.is_post_only(isMarket, upperCaseType == 'LIMIT_MAKER', params)
1266
+ triggerPrice = self.safe_number_2(params, 'stopPrice', 'triggerPrice')
1267
+ params = self.omit(params, ['postOnly', 'triggerPrice', 'stopPrice'])
1268
+ if triggerPrice is not None:
1269
+ upperCaseType = 'STOP' if (price is None) else 'STOP_LIMIT'
1270
+ request['stopPrice'] = triggerPrice
1271
+ elif isPostOnly:
1272
+ upperCaseType = 'LIMIT_MAKER'
1273
+ request['type'] = upperCaseType
1274
+ if isMarket:
1275
+ if side == 'buy':
1276
+ quoteAmount = None
1277
+ createMarketBuyOrderRequiresPrice = True
1278
+ createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
1279
+ cost = self.safe_number(params, 'cost')
1280
+ params = self.omit(params, 'cost')
1281
+ if cost is not None:
1282
+ quoteAmount = self.cost_to_precision(symbol, cost)
1283
+ elif createMarketBuyOrderRequiresPrice:
1284
+ if price is None:
1285
+ 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')
1286
+ else:
1287
+ amountString = self.number_to_string(amount)
1288
+ priceString = self.number_to_string(price)
1289
+ costRequest = Precise.string_mul(amountString, priceString)
1290
+ quoteAmount = self.cost_to_precision(symbol, costRequest)
1291
+ else:
1292
+ quoteAmount = self.cost_to_precision(symbol, amount)
1293
+ request['amount'] = quoteAmount
1294
+ else:
1295
+ request['quantity'] = self.amount_to_precision(symbol, amount)
1296
+ else:
1297
+ request['quantity'] = self.amount_to_precision(symbol, amount)
1298
+ request['price'] = self.price_to_precision(symbol, price)
1299
+ clientOrderId = self.safe_string(params, 'clientOrderId')
1300
+ if clientOrderId is not None:
1301
+ request['clientOrderId'] = clientOrderId
1302
+ params = self.omit(params, 'clientOrderId')
1303
+ # remember the timestamp before issuing the request
1304
+ return [request, params]
1305
+
1306
+ async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
1307
+ """
1308
+ edit a trade order
1309
+ :see: https://docs.poloniex.com/#authenticated-endpoints-orders-cancel-replace-order
1310
+ :see: https://docs.poloniex.com/#authenticated-endpoints-smart-orders-cancel-replace-order
1311
+ :param str id: order id
1312
+ :param str symbol: unified symbol of the market to create an order in
1313
+ :param str type: 'market' or 'limit'
1314
+ :param str side: 'buy' or 'sell'
1315
+ :param float [amount]: how much of the currency you want to trade in units of the base currency
1316
+ :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1317
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1318
+ :param float [params.triggerPrice]: The price at which a trigger order is triggered at
1319
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1320
+ """
1321
+ await self.load_markets()
1322
+ market = self.market(symbol)
1323
+ if not market['spot']:
1324
+ raise NotSupported(self.id + ' editOrder() does not support ' + market['type'] + ' orders, only spot orders are accepted')
1325
+ request: dict = {
1326
+ 'id': id,
1327
+ # 'timeInForce': timeInForce,
1328
+ }
1329
+ triggerPrice = self.safe_number_2(params, 'stopPrice', 'triggerPrice')
1330
+ request, params = self.order_request(symbol, type, side, amount, request, price, params)
1331
+ response = None
1332
+ if triggerPrice is not None:
1333
+ response = await self.privatePutSmartordersId(self.extend(request, params))
1334
+ else:
1335
+ response = await self.privatePutOrdersId(self.extend(request, params))
1336
+ #
1337
+ # {
1338
+ # "id" : "78923648051920896",
1339
+ # "clientOrderId" : ""
1340
+ # }
1341
+ #
1342
+ response = self.extend(response, {
1343
+ 'type': side,
1344
+ })
1345
+ return self.parse_order(response, market)
1346
+
1347
+ async def cancel_order(self, id: str, symbol: Str = None, params={}):
1348
+ #
1349
+ # @method
1350
+ # @name poloniex#cancelOrder
1351
+ # @description cancels an open order
1352
+ # @see https://docs.poloniex.com/#authenticated-endpoints-orders-cancel-order-by-id
1353
+ # @see https://docs.poloniex.com/#authenticated-endpoints-smart-orders-cancel-order-by-id # trigger orders
1354
+ # @param {string} id order id
1355
+ # @param {string} symbol unified symbol of the market the order was made in
1356
+ # @param {object} [params] extra parameters specific to the exchange API endpoint
1357
+ # @param {boolean} [params.trigger] True if canceling a trigger order
1358
+ # @returns {object} An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1359
+ #
1360
+ await self.load_markets()
1361
+ request: dict = {}
1362
+ clientOrderId = self.safe_value(params, 'clientOrderId')
1363
+ if clientOrderId is not None:
1364
+ id = clientOrderId
1365
+ request['id'] = id
1366
+ isTrigger = self.safe_value_2(params, 'trigger', 'stop')
1367
+ params = self.omit(params, ['clientOrderId', 'trigger', 'stop'])
1368
+ response = None
1369
+ if isTrigger:
1370
+ response = await self.privateDeleteSmartordersId(self.extend(request, params))
1371
+ else:
1372
+ response = await self.privateDeleteOrdersId(self.extend(request, params))
1373
+ #
1374
+ # {
1375
+ # "orderId":"210832697138888704",
1376
+ # "clientOrderId":"",
1377
+ # "state":"PENDING_CANCEL",
1378
+ # "code":200,
1379
+ # "message":""
1380
+ # }
1381
+ #
1382
+ return self.parse_order(response)
1383
+
1384
+ async def cancel_all_orders(self, symbol: Str = None, params={}):
1385
+ """
1386
+ cancel all open orders
1387
+ :see: https://docs.poloniex.com/#authenticated-endpoints-orders-cancel-all-orders
1388
+ :see: https://docs.poloniex.com/#authenticated-endpoints-smart-orders-cancel-all-orders # trigger orders
1389
+ :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
1390
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1391
+ :param boolean [params.trigger]: True if canceling trigger orders
1392
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1393
+ """
1394
+ await self.load_markets()
1395
+ request: dict = {
1396
+ # 'accountTypes': 'SPOT',
1397
+ 'symbols': [],
1398
+ }
1399
+ market: Market = None
1400
+ if symbol is not None:
1401
+ market = self.market(symbol)
1402
+ request['symbols'] = [
1403
+ market['id'],
1404
+ ]
1405
+ isTrigger = self.safe_value_2(params, 'trigger', 'stop')
1406
+ params = self.omit(params, ['trigger', 'stop'])
1407
+ response = None
1408
+ if isTrigger:
1409
+ response = await self.privateDeleteSmartorders(self.extend(request, params))
1410
+ else:
1411
+ response = await self.privateDeleteOrders(self.extend(request, params))
1412
+ #
1413
+ # [
1414
+ # {
1415
+ # "orderId" : "78xxxxxxxx80",
1416
+ # "clientOrderId" : "",
1417
+ # "state" : "NEW",
1418
+ # "code" : 200,
1419
+ # "message" : ""
1420
+ # }, {
1421
+ # "orderId" : "78xxxxxxxxx80",
1422
+ # "clientOrderId" : "",
1423
+ # "state" : "NEW",
1424
+ # "code" : 200,
1425
+ # "message" : ""
1426
+ # }
1427
+ # ]
1428
+ #
1429
+ return self.parse_orders(response, market)
1430
+
1431
+ async def fetch_order(self, id: str, symbol: Str = None, params={}):
1432
+ """
1433
+ fetch an order by it's id
1434
+ :see: https://docs.poloniex.com/#authenticated-endpoints-orders-order-details
1435
+ :see: https://docs.poloniex.com/#authenticated-endpoints-smart-orders-open-orders # trigger orders
1436
+ :param str id: order id
1437
+ :param str symbol: unified market symbol, default is None
1438
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1439
+ :param boolean [params.trigger]: True if fetching a trigger order
1440
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1441
+ """
1442
+ await self.load_markets()
1443
+ id = str(id)
1444
+ request: dict = {
1445
+ 'id': id,
1446
+ }
1447
+ isTrigger = self.safe_value_2(params, 'trigger', 'stop')
1448
+ params = self.omit(params, ['trigger', 'stop'])
1449
+ response = None
1450
+ if isTrigger:
1451
+ response = await self.privateGetSmartordersId(self.extend(request, params))
1452
+ response = self.safe_value(response, 0)
1453
+ else:
1454
+ response = await self.privateGetOrdersId(self.extend(request, params))
1455
+ #
1456
+ # {
1457
+ # "id": "21934611974062080",
1458
+ # "clientOrderId": "123",
1459
+ # "symbol": "TRX_USDC",
1460
+ # "state": "NEW",
1461
+ # "accountType": "SPOT",
1462
+ # "side": "SELL",
1463
+ # "type": "LIMIT",
1464
+ # "timeInForce": "GTC",
1465
+ # "quantity": "1.00",
1466
+ # "price": "10.00",
1467
+ # "avgPrice": "0.00",
1468
+ # "amount": "0.00",
1469
+ # "filledQuantity": "0.00",
1470
+ # "filledAmount": "0.00",
1471
+ # "stopPrice": "3750.00", # for trigger orders
1472
+ # "createTime": 1646196019020,
1473
+ # "updateTime": 1646196019020
1474
+ # }
1475
+ #
1476
+ order = self.parse_order(response)
1477
+ order['id'] = id
1478
+ return order
1479
+
1480
+ async def fetch_order_status(self, id: str, symbol: Str = None, params={}):
1481
+ await self.load_markets()
1482
+ orders = await self.fetch_open_orders(symbol, None, None, params)
1483
+ indexed = self.index_by(orders, 'id')
1484
+ return 'open' if (id in indexed) else 'closed'
1485
+
1486
+ async def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1487
+ """
1488
+ fetch all the trades made from a single order
1489
+ :see: https://docs.poloniex.com/#authenticated-endpoints-trades-trades-by-order-id
1490
+ :param str id: order id
1491
+ :param str symbol: unified market symbol
1492
+ :param int [since]: the earliest time in ms to fetch trades for
1493
+ :param int [limit]: the maximum number of trades to retrieve
1494
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1495
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
1496
+ """
1497
+ await self.load_markets()
1498
+ request: dict = {
1499
+ 'id': id,
1500
+ }
1501
+ trades = await self.privateGetOrdersIdTrades(self.extend(request, params))
1502
+ #
1503
+ # [
1504
+ # {
1505
+ # "id": "30341456333942784",
1506
+ # "symbol": "LINK_USDT",
1507
+ # "accountType": "SPOT",
1508
+ # "orderId": "30249408733945856",
1509
+ # "side": "BUY",
1510
+ # "type": "LIMIT",
1511
+ # "matchRole": "MAKER",
1512
+ # "createTime": 1648200366864,
1513
+ # "price": "3.1",
1514
+ # "quantity": "1",
1515
+ # "amount": "3.1",
1516
+ # "feeCurrency": "LINK",
1517
+ # "feeAmount": "0.00145",
1518
+ # "pageId": "30341456333942784",
1519
+ # "clientOrderId": ""
1520
+ # }
1521
+ # ]
1522
+ #
1523
+ return self.parse_trades(trades)
1524
+
1525
+ def parse_balance(self, response) -> Balances:
1526
+ result: dict = {
1527
+ 'info': response,
1528
+ 'timestamp': None,
1529
+ 'datetime': None,
1530
+ }
1531
+ for i in range(0, len(response)):
1532
+ account = self.safe_value(response, i, {})
1533
+ balances = self.safe_value(account, 'balances')
1534
+ for j in range(0, len(balances)):
1535
+ balance = self.safe_value(balances, j)
1536
+ currencyId = self.safe_string(balance, 'currency')
1537
+ code = self.safe_currency_code(currencyId)
1538
+ newAccount = self.account()
1539
+ newAccount['free'] = self.safe_string(balance, 'available')
1540
+ newAccount['used'] = self.safe_string(balance, 'hold')
1541
+ result[code] = newAccount
1542
+ return self.safe_balance(result)
1543
+
1544
+ async def fetch_balance(self, params={}) -> Balances:
1545
+ """
1546
+ query for balance and get the amount of funds available for trading or funds locked in orders
1547
+ :see: https://docs.poloniex.com/#authenticated-endpoints-accounts-all-account-balances
1548
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1549
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
1550
+ """
1551
+ await self.load_markets()
1552
+ request: dict = {
1553
+ 'accountType': 'SPOT',
1554
+ }
1555
+ response = await self.privateGetAccountsBalances(self.extend(request, params))
1556
+ #
1557
+ # [
1558
+ # {
1559
+ # "accountId" : "7xxxxxxxxxx8",
1560
+ # "accountType" : "SPOT",
1561
+ # "balances" : [
1562
+ # {
1563
+ # "currencyId" : "214",
1564
+ # "currency" : "USDT",
1565
+ # "available" : "2.00",
1566
+ # "hold" : "0.00"
1567
+ # }
1568
+ # ]
1569
+ # }
1570
+ # ]
1571
+ #
1572
+ return self.parse_balance(response)
1573
+
1574
+ async def fetch_trading_fees(self, params={}) -> TradingFees:
1575
+ """
1576
+ fetch the trading fees for multiple markets
1577
+ :see: https://docs.poloniex.com/#authenticated-endpoints-accounts-fee-info
1578
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1579
+ :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
1580
+ """
1581
+ await self.load_markets()
1582
+ response = await self.privateGetFeeinfo(params)
1583
+ #
1584
+ # {
1585
+ # "trxDiscount" : False,
1586
+ # "makerRate" : "0.00145",
1587
+ # "takerRate" : "0.00155",
1588
+ # "volume30D" : "0.00"
1589
+ # }
1590
+ #
1591
+ result: dict = {}
1592
+ for i in range(0, len(self.symbols)):
1593
+ symbol = self.symbols[i]
1594
+ result[symbol] = {
1595
+ 'info': response,
1596
+ 'symbol': symbol,
1597
+ 'maker': self.safe_number(response, 'makerRate'),
1598
+ 'taker': self.safe_number(response, 'takerRate'),
1599
+ 'percentage': True,
1600
+ 'tierBased': True,
1601
+ }
1602
+ return result
1603
+
1604
+ async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
1605
+ """
1606
+ fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
1607
+ :see: https://docs.poloniex.com/#public-endpoints-market-data-order-book
1608
+ :param str symbol: unified symbol of the market to fetch the order book for
1609
+ :param int [limit]: the maximum amount of order book entries to return
1610
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1611
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
1612
+ """
1613
+ await self.load_markets()
1614
+ market = self.market(symbol)
1615
+ request: dict = {
1616
+ 'symbol': market['id'],
1617
+ }
1618
+ if limit is not None:
1619
+ request['limit'] = limit # The default value of limit is 10. Valid limit values are: 5, 10, 20, 50, 100, 150.
1620
+ response = await self.publicGetMarketsSymbolOrderBook(self.extend(request, params))
1621
+ #
1622
+ # {
1623
+ # "time" : 1659695219507,
1624
+ # "scale" : "-1",
1625
+ # "asks" : ["23139.82", "0.317981", "23140", "0.191091", "23170.06", "0.01", "23200", "0.107758", "23230.55", "0.01", "23247.2", "0.154", "23254", "0.005121", "23263", "0.038", "23285.4", "0.308", "23300", "0.108896"],
1626
+ # "bids" : ["23139.74", "0.432092", "23139.73", "0.198592", "23123.21", "0.000886", "23123.2", "0.308", "23121.4", "0.154", "23105", "0.000789", "23100", "0.078175", "23069.1", "0.026276", "23068.83", "0.001329", "23051", "0.000048"],
1627
+ # "ts" : 1659695219513
1628
+ # }
1629
+ #
1630
+ timestamp = self.safe_integer(response, 'time')
1631
+ asks = self.safe_value(response, 'asks')
1632
+ bids = self.safe_value(response, 'bids')
1633
+ asksResult = []
1634
+ bidsResult = []
1635
+ for i in range(0, len(asks)):
1636
+ if (i % 2) < 1:
1637
+ price = self.safe_number(asks, i)
1638
+ amount = self.safe_number(asks, self.sum(i, 1))
1639
+ asksResult.append([price, amount])
1640
+ for i in range(0, len(bids)):
1641
+ if (i % 2) < 1:
1642
+ price = self.safe_number(bids, i)
1643
+ amount = self.safe_number(bids, self.sum(i, 1))
1644
+ bidsResult.append([price, amount])
1645
+ return {
1646
+ 'symbol': market['symbol'],
1647
+ 'bids': self.sort_by(bidsResult, 0, True),
1648
+ 'asks': self.sort_by(asksResult, 0),
1649
+ 'timestamp': timestamp,
1650
+ 'datetime': self.iso8601(timestamp),
1651
+ 'nonce': None,
1652
+ }
1653
+
1654
+ async def create_deposit_address(self, code: str, params={}):
1655
+ """
1656
+ create a currency deposit address
1657
+ :see: https://docs.poloniex.com/#authenticated-endpoints-wallets-deposit-addresses
1658
+ :param str code: unified currency code of the currency for the deposit address
1659
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1660
+ :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
1661
+ """
1662
+ await self.load_markets()
1663
+ currency = self.currency(code)
1664
+ request: dict = {
1665
+ 'currency': currency['id'],
1666
+ }
1667
+ networks = self.safe_value(self.options, 'networks', {})
1668
+ network = self.safe_string_upper(params, 'network') # self line allows the user to specify either ERC20 or ETH
1669
+ network = self.safe_string(networks, network, network) # handle ERC20>ETH alias
1670
+ if network is not None:
1671
+ request['currency'] += network # when network the currency need to be changed to currency+network https://docs.poloniex.com/#withdraw on MultiChain Currencies section
1672
+ params = self.omit(params, 'network')
1673
+ else:
1674
+ if currency['id'] == 'USDT':
1675
+ raise ArgumentsRequired(self.id + ' createDepositAddress requires a network parameter for ' + code + '.')
1676
+ response = await self.privatePostWalletsAddress(self.extend(request, params))
1677
+ #
1678
+ # {
1679
+ # "address" : "0xfxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxf"
1680
+ # }
1681
+ #
1682
+ address = self.safe_string(response, 'address')
1683
+ tag: Str = None
1684
+ self.check_address(address)
1685
+ if currency is not None:
1686
+ depositAddress = self.safe_string(currency['info'], 'depositAddress')
1687
+ if depositAddress is not None:
1688
+ tag = address
1689
+ address = depositAddress
1690
+ return {
1691
+ 'currency': code,
1692
+ 'address': address,
1693
+ 'tag': tag,
1694
+ 'network': network,
1695
+ 'info': response,
1696
+ }
1697
+
1698
+ async def fetch_deposit_address(self, code: str, params={}):
1699
+ """
1700
+ fetch the deposit address for a currency associated with self account
1701
+ :see: https://docs.poloniex.com/#authenticated-endpoints-wallets-deposit-addresses
1702
+ :param str code: unified currency code
1703
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1704
+ :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
1705
+ """
1706
+ await self.load_markets()
1707
+ currency = self.currency(code)
1708
+ request: dict = {
1709
+ 'currency': currency['id'],
1710
+ }
1711
+ networks = self.safe_value(self.options, 'networks', {})
1712
+ network = self.safe_string_upper(params, 'network') # self line allows the user to specify either ERC20 or ETH
1713
+ network = self.safe_string(networks, network, network) # handle ERC20>ETH alias
1714
+ if network is not None:
1715
+ request['currency'] += network # when network the currency need to be changed to currency+network https://docs.poloniex.com/#withdraw on MultiChain Currencies section
1716
+ params = self.omit(params, 'network')
1717
+ else:
1718
+ if currency['id'] == 'USDT':
1719
+ raise ArgumentsRequired(self.id + ' fetchDepositAddress requires a network parameter for ' + code + '.')
1720
+ response = await self.privateGetWalletsAddresses(self.extend(request, params))
1721
+ #
1722
+ # {
1723
+ # "USDTTRON" : "Txxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxp"
1724
+ # }
1725
+ #
1726
+ address = self.safe_string(response, request['currency'])
1727
+ tag: Str = None
1728
+ self.check_address(address)
1729
+ if currency is not None:
1730
+ depositAddress = self.safe_string(currency['info'], 'depositAddress')
1731
+ if depositAddress is not None:
1732
+ tag = address
1733
+ address = depositAddress
1734
+ return {
1735
+ 'currency': code,
1736
+ 'address': address,
1737
+ 'tag': tag,
1738
+ 'network': network,
1739
+ 'info': response,
1740
+ }
1741
+
1742
+ async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
1743
+ """
1744
+ transfer currency internally between wallets on the same account
1745
+ :see: https://docs.poloniex.com/#authenticated-endpoints-accounts-accounts-transfer
1746
+ :param str code: unified currency code
1747
+ :param float amount: amount to transfer
1748
+ :param str fromAccount: account to transfer from
1749
+ :param str toAccount: account to transfer to
1750
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1751
+ :returns dict: a `transfer structure <https://docs.ccxt.com/#/?id=transfer-structure>`
1752
+ """
1753
+ await self.load_markets()
1754
+ currency = self.currency(code)
1755
+ accountsByType = self.safe_value(self.options, 'accountsByType', {})
1756
+ fromId = self.safe_string(accountsByType, fromAccount, fromAccount)
1757
+ toId = self.safe_string(accountsByType, toAccount, fromAccount)
1758
+ request: dict = {
1759
+ 'amount': self.currency_to_precision(code, amount),
1760
+ 'currency': currency['id'],
1761
+ 'fromAccount': fromId,
1762
+ 'toAccount': toId,
1763
+ }
1764
+ response = await self.privatePostAccountsTransfer(self.extend(request, params))
1765
+ #
1766
+ # {
1767
+ # "transferId" : "168041074"
1768
+ # }
1769
+ #
1770
+ return self.parse_transfer(response, currency)
1771
+
1772
+ def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
1773
+ #
1774
+ # {
1775
+ # "transferId" : "168041074"
1776
+ # }
1777
+ #
1778
+ return {
1779
+ 'info': transfer,
1780
+ 'id': self.safe_string(transfer, 'transferId'),
1781
+ 'timestamp': None,
1782
+ 'datetime': None,
1783
+ 'currency': self.safe_string(currency, 'id'),
1784
+ 'amount': None,
1785
+ 'fromAccount': None,
1786
+ 'toAccount': None,
1787
+ 'status': None,
1788
+ }
1789
+
1790
+ async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
1791
+ """
1792
+ make a withdrawal
1793
+ :see: https://docs.poloniex.com/#authenticated-endpoints-wallets-withdraw-currency
1794
+ :param str code: unified currency code
1795
+ :param float amount: the amount to withdraw
1796
+ :param str address: the address to withdraw to
1797
+ :param str tag:
1798
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1799
+ :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1800
+ """
1801
+ tag, params = self.handle_withdraw_tag_and_params(tag, params)
1802
+ self.check_address(address)
1803
+ await self.load_markets()
1804
+ currency = self.currency(code)
1805
+ request: dict = {
1806
+ 'currency': currency['id'],
1807
+ 'amount': amount,
1808
+ 'address': address,
1809
+ }
1810
+ if tag is not None:
1811
+ request['paymentId'] = tag
1812
+ networks = self.safe_value(self.options, 'networks', {})
1813
+ network = self.safe_string_upper(params, 'network') # self line allows the user to specify either ERC20 or ETH
1814
+ network = self.safe_string(networks, network, network) # handle ERC20>ETH alias
1815
+ if network is not None:
1816
+ request['currency'] += network # when network the currency need to be changed to currency+network https://docs.poloniex.com/#withdraw on MultiChain Currencies section
1817
+ params = self.omit(params, 'network')
1818
+ response = await self.privatePostWalletsWithdraw(self.extend(request, params))
1819
+ #
1820
+ # {
1821
+ # "response": "Withdrew 1.00000000 USDT.",
1822
+ # "email2FA": False,
1823
+ # "withdrawalNumber": 13449869
1824
+ # }
1825
+ #
1826
+ return self.parse_transaction(response, currency)
1827
+
1828
+ async def fetch_transactions_helper(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
1829
+ await self.load_markets()
1830
+ year = 31104000 # 60 * 60 * 24 * 30 * 12 = one year of history, why not
1831
+ now = self.seconds()
1832
+ start = self.parse_to_int(since / 1000) if (since is not None) else now - 10 * year
1833
+ request: dict = {
1834
+ 'start': start, # UNIX timestamp, required
1835
+ 'end': now, # UNIX timestamp, required
1836
+ }
1837
+ response = await self.privateGetWalletsActivity(self.extend(request, params))
1838
+ #
1839
+ # {
1840
+ # "adjustments":[],
1841
+ # "deposits":[
1842
+ # {
1843
+ # "currency": "BTC",
1844
+ # "address": "1MEtiqJWru53FhhHrfJPPvd2tC3TPDVcmW",
1845
+ # "amount": "0.01063000",
1846
+ # "confirmations": 1,
1847
+ # "txid": "952b0e1888d6d491591facc0d37b5ebec540ac1efb241fdbc22bcc20d1822fb6",
1848
+ # "timestamp": 1507916888,
1849
+ # "status": "COMPLETE"
1850
+ # },
1851
+ # {
1852
+ # "currency": "ETH",
1853
+ # "address": "0x20108ba20b65c04d82909e91df06618107460197",
1854
+ # "amount": "4.00000000",
1855
+ # "confirmations": 38,
1856
+ # "txid": "0x4be260073491fe63935e9e0da42bd71138fdeb803732f41501015a2d46eb479d",
1857
+ # "timestamp": 1525060430,
1858
+ # "status": "COMPLETE"
1859
+ # }
1860
+ # ],
1861
+ # "withdrawals":[
1862
+ # {
1863
+ # "withdrawalNumber":13449869,
1864
+ # "currency":"USDTTRON", # not documented in API docs, see commonCurrencies in describe()
1865
+ # "address":"TXGaqPW23JdRWhsVwS2mRsGsegbdnAd3Rw",
1866
+ # "amount":"1.00000000",
1867
+ # "fee":"0.00000000",
1868
+ # "timestamp":1591573420,
1869
+ # "status":"COMPLETE: dadf427224b3d44b38a2c13caa4395e4666152556ca0b2f67dbd86a95655150f",
1870
+ # "ipAddress":"x.x.x.x",
1871
+ # "canCancel":0,
1872
+ # "canResendEmail":0,
1873
+ # "paymentID":null,
1874
+ # "scope":"crypto"
1875
+ # },
1876
+ # {
1877
+ # "withdrawalNumber": 8224394,
1878
+ # "currency": "EMC2",
1879
+ # "address": "EYEKyCrqTNmVCpdDV8w49XvSKRP9N3EUyF",
1880
+ # "amount": "63.10796020",
1881
+ # "fee": "0.01000000",
1882
+ # "timestamp": 1510819838,
1883
+ # "status": "COMPLETE: d37354f9d02cb24d98c8c4fc17aa42f475530b5727effdf668ee5a43ce667fd6",
1884
+ # "ipAddress": "x.x.x.x"
1885
+ # },
1886
+ # {
1887
+ # "withdrawalNumber": 9290444,
1888
+ # "currency": "ETH",
1889
+ # "address": "0x191015ff2e75261d50433fbd05bd57e942336149",
1890
+ # "amount": "0.15500000",
1891
+ # "fee": "0.00500000",
1892
+ # "timestamp": 1514099289,
1893
+ # "status": "COMPLETE: 0x12d444493b4bca668992021fd9e54b5292b8e71d9927af1f076f554e4bea5b2d",
1894
+ # "ipAddress": "x.x.x.x"
1895
+ # },
1896
+ # {
1897
+ # "withdrawalNumber": 11518260,
1898
+ # "currency": "BTC",
1899
+ # "address": "8JoDXAmE1GY2LRK8jD1gmAmgRPq54kXJ4t",
1900
+ # "amount": "0.20000000",
1901
+ # "fee": "0.00050000",
1902
+ # "timestamp": 1527918155,
1903
+ # "status": "COMPLETE: 1864f4ebb277d90b0b1ff53259b36b97fa1990edc7ad2be47c5e0ab41916b5ff",
1904
+ # "ipAddress": "x.x.x.x"
1905
+ # }
1906
+ # ]
1907
+ # }
1908
+ #
1909
+ return response
1910
+
1911
+ async def fetch_deposits_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1912
+ """
1913
+ fetch history of deposits and withdrawals
1914
+ :see: https://docs.poloniex.com/#authenticated-endpoints-wallets-wallets-activity-records
1915
+ :param str [code]: unified currency code for the currency of the deposit/withdrawals, default is None
1916
+ :param int [since]: timestamp in ms of the earliest deposit/withdrawal, default is None
1917
+ :param int [limit]: max number of deposit/withdrawals to return, default is None
1918
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1919
+ :returns dict: a list of `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1920
+ """
1921
+ await self.load_markets()
1922
+ response = await self.fetch_transactions_helper(code, since, limit, params)
1923
+ currency: Currency = None
1924
+ if code is not None:
1925
+ currency = self.currency(code)
1926
+ withdrawals = self.safe_value(response, 'withdrawals', [])
1927
+ deposits = self.safe_value(response, 'deposits', [])
1928
+ withdrawalTransactions = self.parse_transactions(withdrawals, currency, since, limit)
1929
+ depositTransactions = self.parse_transactions(deposits, currency, since, limit)
1930
+ transactions = self.array_concat(depositTransactions, withdrawalTransactions)
1931
+ return self.filter_by_currency_since_limit(self.sort_by(transactions, 'timestamp'), code, since, limit)
1932
+
1933
+ async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1934
+ """
1935
+ fetch all withdrawals made from an account
1936
+ :see: https://docs.poloniex.com/#authenticated-endpoints-wallets-wallets-activity-records
1937
+ :param str code: unified currency code
1938
+ :param int [since]: the earliest time in ms to fetch withdrawals for
1939
+ :param int [limit]: the maximum number of withdrawals structures to retrieve
1940
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1941
+ :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
1942
+ """
1943
+ response = await self.fetch_transactions_helper(code, since, limit, params)
1944
+ currency: Currency = None
1945
+ if code is not None:
1946
+ currency = self.currency(code)
1947
+ withdrawals = self.safe_value(response, 'withdrawals', [])
1948
+ transactions = self.parse_transactions(withdrawals, currency, since, limit)
1949
+ return self.filter_by_currency_since_limit(transactions, code, since, limit)
1950
+
1951
+ async def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
1952
+ """
1953
+ fetch deposit and withdraw fees
1954
+ :see: https://docs.poloniex.com/#public-endpoints-reference-data-currency-information
1955
+ :param str[]|None codes: list of unified currency codes
1956
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1957
+ :returns dict[]: a list of `fees structures <https://docs.ccxt.com/#/?id=fee-structure>`
1958
+ """
1959
+ await self.load_markets()
1960
+ response = await self.publicGetCurrencies(self.extend(params, {'includeMultiChainCurrencies': True}))
1961
+ #
1962
+ # [
1963
+ # {
1964
+ # "1CR": {
1965
+ # "id": 1,
1966
+ # "name": "1CRedit",
1967
+ # "description": "BTC Clone",
1968
+ # "type": "address",
1969
+ # "withdrawalFee": "0.01000000",
1970
+ # "minConf": 10000,
1971
+ # "depositAddress": null,
1972
+ # "blockchain": "1CR",
1973
+ # "delisted": False,
1974
+ # "tradingState": "NORMAL",
1975
+ # "walletState": "DISABLED",
1976
+ # "parentChain": null,
1977
+ # "isMultiChain": False,
1978
+ # "isChildChain": False,
1979
+ # "childChains": []
1980
+ # }
1981
+ # }
1982
+ # ]
1983
+ #
1984
+ data: dict = {}
1985
+ for i in range(0, len(response)):
1986
+ entry = response[i]
1987
+ currencies = list(entry.keys())
1988
+ currencyId = self.safe_string(currencies, 0)
1989
+ data[currencyId] = entry[currencyId]
1990
+ return self.parse_deposit_withdraw_fees(data, codes)
1991
+
1992
+ def parse_deposit_withdraw_fees(self, response, codes=None, currencyIdKey=None):
1993
+ #
1994
+ # {
1995
+ # "1CR": {
1996
+ # "id": 1,
1997
+ # "name": "1CRedit",
1998
+ # "description": "BTC Clone",
1999
+ # "type": "address",
2000
+ # "withdrawalFee": "0.01000000",
2001
+ # "minConf": 10000,
2002
+ # "depositAddress": null,
2003
+ # "blockchain": "1CR",
2004
+ # "delisted": False,
2005
+ # "tradingState": "NORMAL",
2006
+ # "walletState": "DISABLED",
2007
+ # "parentChain": null,
2008
+ # "isMultiChain": False,
2009
+ # "isChildChain": False,
2010
+ # "childChains": []
2011
+ # },
2012
+ # }
2013
+ #
2014
+ depositWithdrawFees: dict = {}
2015
+ codes = self.market_codes(codes)
2016
+ responseKeys = list(response.keys())
2017
+ for i in range(0, len(responseKeys)):
2018
+ currencyId = responseKeys[i]
2019
+ code = self.safe_currency_code(currencyId)
2020
+ feeInfo = response[currencyId]
2021
+ if (codes is None) or (self.in_array(code, codes)):
2022
+ currency = self.currency(code)
2023
+ depositWithdrawFees[code] = self.parse_deposit_withdraw_fee(feeInfo, currency)
2024
+ childChains = self.safe_value(feeInfo, 'childChains')
2025
+ chainsLength = len(childChains)
2026
+ if chainsLength > 0:
2027
+ for j in range(0, len(childChains)):
2028
+ networkId = childChains[j]
2029
+ networkId = networkId.replace(code, '')
2030
+ networkCode = self.network_id_to_code(networkId)
2031
+ networkInfo = self.safe_value(response, networkId)
2032
+ networkObject: dict = {}
2033
+ withdrawFee = self.safe_number(networkInfo, 'withdrawalFee')
2034
+ networkObject[networkCode] = {
2035
+ 'withdraw': {
2036
+ 'fee': withdrawFee,
2037
+ 'percentage': False if (withdrawFee is not None) else None,
2038
+ },
2039
+ 'deposit': {
2040
+ 'fee': None,
2041
+ 'percentage': None,
2042
+ },
2043
+ }
2044
+ depositWithdrawFees[code]['networks'] = self.extend(depositWithdrawFees[code]['networks'], networkObject)
2045
+ return depositWithdrawFees
2046
+
2047
+ def parse_deposit_withdraw_fee(self, fee, currency: Currency = None):
2048
+ depositWithdrawFee = self.deposit_withdraw_fee({})
2049
+ depositWithdrawFee['info'][currency['code']] = fee
2050
+ networkId = self.safe_string(fee, 'blockchain')
2051
+ withdrawFee = self.safe_number(fee, 'withdrawalFee')
2052
+ withdrawResult: dict = {
2053
+ 'fee': withdrawFee,
2054
+ 'percentage': False if (withdrawFee is not None) else None,
2055
+ }
2056
+ depositResult: dict = {
2057
+ 'fee': None,
2058
+ 'percentage': None,
2059
+ }
2060
+ depositWithdrawFee['withdraw'] = withdrawResult
2061
+ depositWithdrawFee['deposit'] = depositResult
2062
+ networkCode = self.network_id_to_code(networkId)
2063
+ depositWithdrawFee['networks'][networkCode] = {
2064
+ 'withdraw': withdrawResult,
2065
+ 'deposit': depositResult,
2066
+ }
2067
+ return depositWithdrawFee
2068
+
2069
+ async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2070
+ """
2071
+ fetch all deposits made to an account
2072
+ :see: https://docs.poloniex.com/#authenticated-endpoints-wallets-wallets-activity-records
2073
+ :param str code: unified currency code
2074
+ :param int [since]: the earliest time in ms to fetch deposits for
2075
+ :param int [limit]: the maximum number of deposits structures to retrieve
2076
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2077
+ :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
2078
+ """
2079
+ response = await self.fetch_transactions_helper(code, since, limit, params)
2080
+ currency = None
2081
+ if code is not None:
2082
+ currency = self.currency(code)
2083
+ deposits = self.safe_value(response, 'deposits', [])
2084
+ transactions = self.parse_transactions(deposits, currency, since, limit)
2085
+ return self.filter_by_currency_since_limit(transactions, code, since, limit)
2086
+
2087
+ def parse_transaction_status(self, status: Str):
2088
+ statuses: dict = {
2089
+ 'COMPLETE': 'ok',
2090
+ 'COMPLETED': 'ok',
2091
+ 'AWAITING APPROVAL': 'pending',
2092
+ 'AWAITING_APPROVAL': 'pending',
2093
+ 'PENDING': 'pending',
2094
+ 'PROCESSING': 'pending',
2095
+ 'COMPLETE ERROR': 'failed',
2096
+ 'COMPLETE_ERROR': 'failed',
2097
+ }
2098
+ return self.safe_string(statuses, status, status)
2099
+
2100
+ def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
2101
+ #
2102
+ # deposits
2103
+ #
2104
+ # {
2105
+ # "txid": "f49d489616911db44b740612d19464521179c76ebe9021af85b6de1e2f8d68cd",
2106
+ # "amount": "49798.01987021",
2107
+ # "status": "COMPLETE",
2108
+ # "address": "DJVJZ58tJC8UeUv9Tqcdtn6uhWobouxFLT",
2109
+ # "currency": "DOGE",
2110
+ # "timestamp": 1524321838,
2111
+ # "confirmations": 3371,
2112
+ # "depositNumber": 134587098
2113
+ # }
2114
+ #
2115
+ # withdrawals
2116
+ #
2117
+ # {
2118
+ # "withdrawalRequestsId": 7397527,
2119
+ # "currency": "ETC",
2120
+ # "address": "0x26419a62055af459d2cd69bb7392f5100b75e304",
2121
+ # "amount": "13.19951600",
2122
+ # "fee": "0.01000000",
2123
+ # "timestamp": 1506010932,
2124
+ # "status": "COMPLETED",
2125
+ # "txid": "343346392f82ac16e8c2604f2a604b7b2382d0e9d8030f673821f8de4b5f5bk",
2126
+ # "ipAddress": "1.2.3.4",
2127
+ # "paymentID": null
2128
+ # }
2129
+ #
2130
+ # withdraw
2131
+ #
2132
+ # {
2133
+ # "withdrawalRequestsId": 33485231
2134
+ # }
2135
+ #
2136
+ timestamp = self.safe_timestamp(transaction, 'timestamp')
2137
+ currencyId = self.safe_string(transaction, 'currency')
2138
+ code = self.safe_currency_code(currencyId)
2139
+ status = self.safe_string(transaction, 'status', 'pending')
2140
+ status = self.parse_transaction_status(status)
2141
+ txid = self.safe_string(transaction, 'txid')
2142
+ type = 'withdrawal' if ('withdrawalRequestsId' in transaction) else 'deposit'
2143
+ id = self.safe_string_2(transaction, 'withdrawalRequestsId', 'depositNumber')
2144
+ address = self.safe_string(transaction, 'address')
2145
+ tag = self.safe_string(transaction, 'paymentID')
2146
+ amountString = self.safe_string(transaction, 'amount')
2147
+ feeCostString = self.safe_string(transaction, 'fee')
2148
+ if type == 'withdrawal':
2149
+ amountString = Precise.string_sub(amountString, feeCostString)
2150
+ return {
2151
+ 'info': transaction,
2152
+ 'id': id,
2153
+ 'currency': code,
2154
+ 'amount': self.parse_number(amountString),
2155
+ 'network': None,
2156
+ 'address': address,
2157
+ 'addressTo': None,
2158
+ 'addressFrom': None,
2159
+ 'tag': tag,
2160
+ 'tagTo': None,
2161
+ 'tagFrom': None,
2162
+ 'status': status,
2163
+ 'type': type,
2164
+ 'updated': None,
2165
+ 'txid': txid,
2166
+ 'timestamp': timestamp,
2167
+ 'datetime': self.iso8601(timestamp),
2168
+ 'comment': None,
2169
+ 'internal': None,
2170
+ 'fee': {
2171
+ 'currency': code,
2172
+ 'cost': self.parse_number(feeCostString),
2173
+ 'rate': None,
2174
+ },
2175
+ }
2176
+
2177
+ def nonce(self):
2178
+ return self.milliseconds()
2179
+
2180
+ def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
2181
+ url = self.urls['api']['rest']
2182
+ query = self.omit(params, self.extract_params(path))
2183
+ implodedPath = self.implode_params(path, params)
2184
+ if api == 'public':
2185
+ url += '/' + implodedPath
2186
+ if query:
2187
+ url += '?' + self.urlencode(query)
2188
+ else:
2189
+ self.check_required_credentials()
2190
+ timestamp = str(self.nonce())
2191
+ auth = method + "\n" # eslint-disable-line quotes
2192
+ url += '/' + implodedPath
2193
+ auth += '/' + implodedPath
2194
+ if (method == 'POST') or (method == 'PUT') or (method == 'DELETE'):
2195
+ auth += "\n" # eslint-disable-line quotes
2196
+ if query:
2197
+ body = self.json(query)
2198
+ auth += 'requestBody=' + body + '&'
2199
+ auth += 'signTimestamp=' + timestamp
2200
+ else:
2201
+ sortedQuery = self.extend({'signTimestamp': timestamp}, query)
2202
+ sortedQuery = self.keysort(sortedQuery)
2203
+ auth += "\n" + self.urlencode(sortedQuery) # eslint-disable-line quotes
2204
+ if query:
2205
+ url += '?' + self.urlencode(query)
2206
+ signature = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256, 'base64')
2207
+ headers = {
2208
+ 'Content-Type': 'application/json',
2209
+ 'key': self.apiKey,
2210
+ 'signTimestamp': timestamp,
2211
+ 'signature': signature,
2212
+ }
2213
+ return {'url': url, 'method': method, 'body': body, 'headers': headers}
2214
+
2215
+ def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
2216
+ if response is None:
2217
+ return None
2218
+ #
2219
+ # {
2220
+ # "code" : 21709,
2221
+ # "message" : "Low available balance"
2222
+ # }
2223
+ #
2224
+ responseCode = self.safe_string(response, 'code')
2225
+ if (responseCode is not None) and (responseCode != '200'):
2226
+ codeInner = response['code']
2227
+ message = self.safe_string(response, 'message')
2228
+ feedback = self.id + ' ' + body
2229
+ self.throw_exactly_matched_exception(self.exceptions['exact'], codeInner, feedback)
2230
+ self.throw_broadly_matched_exception(self.exceptions['broad'], message, feedback)
2231
+ raise ExchangeError(feedback) # unknown message
2232
+ return None