ccxt-ir 4.3.46.0.1__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (772) hide show
  1. ccxt/__init__.py +358 -0
  2. ccxt/abantether.py +316 -0
  3. ccxt/abstract/__init__.py +0 -0
  4. ccxt/abstract/abantether.py +5 -0
  5. ccxt/abstract/ace.py +15 -0
  6. ccxt/abstract/afratether.py +6 -0
  7. ccxt/abstract/alpaca.py +70 -0
  8. ccxt/abstract/arzinja.py +5 -0
  9. ccxt/abstract/arzplus.py +7 -0
  10. ccxt/abstract/ascendex.py +77 -0
  11. ccxt/abstract/bequant.py +115 -0
  12. ccxt/abstract/bigone.py +45 -0
  13. ccxt/abstract/binance.py +712 -0
  14. ccxt/abstract/binancecoinm.py +712 -0
  15. ccxt/abstract/binanceus.py +764 -0
  16. ccxt/abstract/binanceusdm.py +712 -0
  17. ccxt/abstract/bingx.py +113 -0
  18. ccxt/abstract/bit2c.py +27 -0
  19. ccxt/abstract/bitbank.py +27 -0
  20. ccxt/abstract/bitbay.py +53 -0
  21. ccxt/abstract/bitbns.py +40 -0
  22. ccxt/abstract/bitcoincom.py +115 -0
  23. ccxt/abstract/bitfinex.py +69 -0
  24. ccxt/abstract/bitfinex2.py +139 -0
  25. ccxt/abstract/bitflyer.py +38 -0
  26. ccxt/abstract/bitget.py +508 -0
  27. ccxt/abstract/bithumb.py +32 -0
  28. ccxt/abstract/bitimen.py +7 -0
  29. ccxt/abstract/bitir.py +7 -0
  30. ccxt/abstract/bitmart.py +99 -0
  31. ccxt/abstract/bitmex.py +97 -0
  32. ccxt/abstract/bitopro.py +29 -0
  33. ccxt/abstract/bitpanda.py +35 -0
  34. ccxt/abstract/bitpin.py +7 -0
  35. ccxt/abstract/bitrue.py +72 -0
  36. ccxt/abstract/bitso.py +43 -0
  37. ccxt/abstract/bitstamp.py +258 -0
  38. ccxt/abstract/bitteam.py +29 -0
  39. ccxt/abstract/bitvavo.py +27 -0
  40. ccxt/abstract/bl3p.py +19 -0
  41. ccxt/abstract/blockchaincom.py +28 -0
  42. ccxt/abstract/blofin.py +37 -0
  43. ccxt/abstract/btcalpha.py +18 -0
  44. ccxt/abstract/btcbox.py +13 -0
  45. ccxt/abstract/btcmarkets.py +39 -0
  46. ccxt/abstract/btcturk.py +20 -0
  47. ccxt/abstract/bybit.py +298 -0
  48. ccxt/abstract/cex.py +33 -0
  49. ccxt/abstract/coinbase.py +94 -0
  50. ccxt/abstract/coinbaseadvanced.py +94 -0
  51. ccxt/abstract/coinbaseexchange.py +67 -0
  52. ccxt/abstract/coinbaseinternational.py +39 -0
  53. ccxt/abstract/coincatch.py +94 -0
  54. ccxt/abstract/coincheck.py +33 -0
  55. ccxt/abstract/coinex.py +237 -0
  56. ccxt/abstract/coinlist.py +54 -0
  57. ccxt/abstract/coinmate.py +62 -0
  58. ccxt/abstract/coinmetro.py +34 -0
  59. ccxt/abstract/coinone.py +67 -0
  60. ccxt/abstract/coinsph.py +54 -0
  61. ccxt/abstract/coinspot.py +28 -0
  62. ccxt/abstract/cryptocom.py +107 -0
  63. ccxt/abstract/currencycom.py +68 -0
  64. ccxt/abstract/delta.py +50 -0
  65. ccxt/abstract/deribit.py +125 -0
  66. ccxt/abstract/digifinex.py +91 -0
  67. ccxt/abstract/eterex.py +5 -0
  68. ccxt/abstract/excoino.py +7 -0
  69. ccxt/abstract/exir.py +8 -0
  70. ccxt/abstract/exmo.py +55 -0
  71. ccxt/abstract/exnovin.py +6 -0
  72. ccxt/abstract/farhadexchange.py +5 -0
  73. ccxt/abstract/fmfwio.py +115 -0
  74. ccxt/abstract/gate.py +265 -0
  75. ccxt/abstract/gateio.py +265 -0
  76. ccxt/abstract/gemini.py +58 -0
  77. ccxt/abstract/hashkey.py +67 -0
  78. ccxt/abstract/hitbtc.py +115 -0
  79. ccxt/abstract/hitbtc3.py +115 -0
  80. ccxt/abstract/hitobit.py +8 -0
  81. ccxt/abstract/hollaex.py +33 -0
  82. ccxt/abstract/htx.py +548 -0
  83. ccxt/abstract/huobi.py +548 -0
  84. ccxt/abstract/huobijp.py +114 -0
  85. ccxt/abstract/hyperliquid.py +6 -0
  86. ccxt/abstract/idex.py +26 -0
  87. ccxt/abstract/independentreserve.py +37 -0
  88. ccxt/abstract/indodax.py +26 -0
  89. ccxt/abstract/jibitex.py +7 -0
  90. ccxt/abstract/kraken.py +57 -0
  91. ccxt/abstract/krakenfutures.py +38 -0
  92. ccxt/abstract/kucoin.py +214 -0
  93. ccxt/abstract/kucoinfutures.py +233 -0
  94. ccxt/abstract/kuna.py +182 -0
  95. ccxt/abstract/latoken.py +56 -0
  96. ccxt/abstract/lbank.py +61 -0
  97. ccxt/abstract/luno.py +37 -0
  98. ccxt/abstract/lykke.py +29 -0
  99. ccxt/abstract/mercado.py +25 -0
  100. ccxt/abstract/mexc.py +178 -0
  101. ccxt/abstract/ndax.py +97 -0
  102. ccxt/abstract/nobitex.py +7 -0
  103. ccxt/abstract/novadax.py +29 -0
  104. ccxt/abstract/oceanex.py +22 -0
  105. ccxt/abstract/okcoin.py +74 -0
  106. ccxt/abstract/okexchange.py +8 -0
  107. ccxt/abstract/okx.py +324 -0
  108. ccxt/abstract/ompfinex.py +7 -0
  109. ccxt/abstract/onetrading.py +35 -0
  110. ccxt/abstract/oxfun.py +34 -0
  111. ccxt/abstract/p2b.py +22 -0
  112. ccxt/abstract/paradex.py +40 -0
  113. ccxt/abstract/paymium.py +28 -0
  114. ccxt/abstract/phemex.py +115 -0
  115. ccxt/abstract/poloniex.py +69 -0
  116. ccxt/abstract/poloniexfutures.py +48 -0
  117. ccxt/abstract/probit.py +23 -0
  118. ccxt/abstract/ramzinex.py +7 -0
  119. ccxt/abstract/sarmayex.py +5 -0
  120. ccxt/abstract/sarrafex.py +7 -0
  121. ccxt/abstract/tabdeal.py +7 -0
  122. ccxt/abstract/tetherland.py +5 -0
  123. ccxt/abstract/timex.py +62 -0
  124. ccxt/abstract/tokocrypto.py +37 -0
  125. ccxt/abstract/tradeogre.py +16 -0
  126. ccxt/abstract/twox.py +5 -0
  127. ccxt/abstract/ubitex.py +7 -0
  128. ccxt/abstract/upbit.py +38 -0
  129. ccxt/abstract/vertex.py +19 -0
  130. ccxt/abstract/wallex.py +8 -0
  131. ccxt/abstract/wavesexchange.py +154 -0
  132. ccxt/abstract/wazirx.py +30 -0
  133. ccxt/abstract/whitebit.py +98 -0
  134. ccxt/abstract/woo.py +83 -0
  135. ccxt/abstract/woofipro.py +119 -0
  136. ccxt/abstract/xt.py +152 -0
  137. ccxt/abstract/yobit.py +16 -0
  138. ccxt/abstract/zaif.py +38 -0
  139. ccxt/abstract/zonda.py +53 -0
  140. ccxt/ace.py +1012 -0
  141. ccxt/afratether.py +293 -0
  142. ccxt/alpaca.py +1083 -0
  143. ccxt/arzinja.py +285 -0
  144. ccxt/arzplus.py +412 -0
  145. ccxt/ascendex.py +3330 -0
  146. ccxt/async_support/__init__.py +337 -0
  147. ccxt/async_support/abantether.py +316 -0
  148. ccxt/async_support/ace.py +1012 -0
  149. ccxt/async_support/afratether.py +293 -0
  150. ccxt/async_support/alpaca.py +1083 -0
  151. ccxt/async_support/arzinja.py +285 -0
  152. ccxt/async_support/arzplus.py +412 -0
  153. ccxt/async_support/ascendex.py +3330 -0
  154. ccxt/async_support/base/__init__.py +1 -0
  155. ccxt/async_support/base/exchange.py +1966 -0
  156. ccxt/async_support/base/throttler.py +50 -0
  157. ccxt/async_support/base/ws/__init__.py +38 -0
  158. ccxt/async_support/base/ws/aiohttp_client.py +125 -0
  159. ccxt/async_support/base/ws/cache.py +212 -0
  160. ccxt/async_support/base/ws/client.py +193 -0
  161. ccxt/async_support/base/ws/fast_client.py +96 -0
  162. ccxt/async_support/base/ws/functions.py +59 -0
  163. ccxt/async_support/base/ws/future.py +58 -0
  164. ccxt/async_support/base/ws/order_book.py +78 -0
  165. ccxt/async_support/base/ws/order_book_side.py +174 -0
  166. ccxt/async_support/bequant.py +33 -0
  167. ccxt/async_support/bigone.py +2113 -0
  168. ccxt/async_support/binance.py +12234 -0
  169. ccxt/async_support/binancecoinm.py +45 -0
  170. ccxt/async_support/binanceus.py +211 -0
  171. ccxt/async_support/binanceusdm.py +58 -0
  172. ccxt/async_support/bingx.py +4325 -0
  173. ccxt/async_support/bit2c.py +866 -0
  174. ccxt/async_support/bitbank.py +1001 -0
  175. ccxt/async_support/bitbay.py +17 -0
  176. ccxt/async_support/bitbns.py +1154 -0
  177. ccxt/async_support/bitcoincom.py +17 -0
  178. ccxt/async_support/bitfinex.py +1617 -0
  179. ccxt/async_support/bitfinex2.py +3552 -0
  180. ccxt/async_support/bitflyer.py +995 -0
  181. ccxt/async_support/bitget.py +8273 -0
  182. ccxt/async_support/bithumb.py +1061 -0
  183. ccxt/async_support/bitimen.py +401 -0
  184. ccxt/async_support/bitir.py +490 -0
  185. ccxt/async_support/bitmart.py +4415 -0
  186. ccxt/async_support/bitmex.py +2756 -0
  187. ccxt/async_support/bitopro.py +1630 -0
  188. ccxt/async_support/bitpanda.py +16 -0
  189. ccxt/async_support/bitpin.py +454 -0
  190. ccxt/async_support/bitrue.py +3027 -0
  191. ccxt/async_support/bitso.py +1670 -0
  192. ccxt/async_support/bitstamp.py +2203 -0
  193. ccxt/async_support/bitteam.py +2239 -0
  194. ccxt/async_support/bitvavo.py +1968 -0
  195. ccxt/async_support/bl3p.py +485 -0
  196. ccxt/async_support/blockchaincom.py +1104 -0
  197. ccxt/async_support/blofin.py +2066 -0
  198. ccxt/async_support/btcalpha.py +891 -0
  199. ccxt/async_support/btcbox.py +544 -0
  200. ccxt/async_support/btcmarkets.py +1221 -0
  201. ccxt/async_support/btcturk.py +911 -0
  202. ccxt/async_support/bybit.py +8159 -0
  203. ccxt/async_support/cex.py +1605 -0
  204. ccxt/async_support/coinbase.py +4475 -0
  205. ccxt/async_support/coinbaseadvanced.py +17 -0
  206. ccxt/async_support/coinbaseexchange.py +1734 -0
  207. ccxt/async_support/coinbaseinternational.py +1899 -0
  208. ccxt/async_support/coincatch.py +5069 -0
  209. ccxt/async_support/coincheck.py +815 -0
  210. ccxt/async_support/coinex.py +5526 -0
  211. ccxt/async_support/coinlist.py +2243 -0
  212. ccxt/async_support/coinmate.py +1067 -0
  213. ccxt/async_support/coinmetro.py +1797 -0
  214. ccxt/async_support/coinone.py +1127 -0
  215. ccxt/async_support/coinsph.py +1850 -0
  216. ccxt/async_support/coinspot.py +534 -0
  217. ccxt/async_support/cryptocom.py +2822 -0
  218. ccxt/async_support/currencycom.py +1950 -0
  219. ccxt/async_support/delta.py +3376 -0
  220. ccxt/async_support/deribit.py +3437 -0
  221. ccxt/async_support/digifinex.py +3960 -0
  222. ccxt/async_support/eterex.py +286 -0
  223. ccxt/async_support/excoino.py +399 -0
  224. ccxt/async_support/exir.py +375 -0
  225. ccxt/async_support/exmo.py +2462 -0
  226. ccxt/async_support/exnovin.py +360 -0
  227. ccxt/async_support/farhadexchange.py +266 -0
  228. ccxt/async_support/fmfwio.py +34 -0
  229. ccxt/async_support/gate.py +6976 -0
  230. ccxt/async_support/gateio.py +16 -0
  231. ccxt/async_support/gemini.py +1825 -0
  232. ccxt/async_support/hashkey.py +4150 -0
  233. ccxt/async_support/hitbtc.py +3423 -0
  234. ccxt/async_support/hitbtc3.py +16 -0
  235. ccxt/async_support/hitobit.py +391 -0
  236. ccxt/async_support/hollaex.py +1813 -0
  237. ccxt/async_support/htx.py +8506 -0
  238. ccxt/async_support/huobi.py +16 -0
  239. ccxt/async_support/huobijp.py +1801 -0
  240. ccxt/async_support/hyperliquid.py +2431 -0
  241. ccxt/async_support/idex.py +1766 -0
  242. ccxt/async_support/independentreserve.py +784 -0
  243. ccxt/async_support/indodax.py +1247 -0
  244. ccxt/async_support/jibitex.py +395 -0
  245. ccxt/async_support/kraken.py +2894 -0
  246. ccxt/async_support/krakenfutures.py +2601 -0
  247. ccxt/async_support/kucoin.py +4602 -0
  248. ccxt/async_support/kucoinfutures.py +2698 -0
  249. ccxt/async_support/kuna.py +1841 -0
  250. ccxt/async_support/latoken.py +1664 -0
  251. ccxt/async_support/lbank.py +2683 -0
  252. ccxt/async_support/luno.py +1067 -0
  253. ccxt/async_support/lykke.py +1270 -0
  254. ccxt/async_support/mercado.py +842 -0
  255. ccxt/async_support/mexc.py +5369 -0
  256. ccxt/async_support/ndax.py +2354 -0
  257. ccxt/async_support/nobitex.py +419 -0
  258. ccxt/async_support/novadax.py +1484 -0
  259. ccxt/async_support/oceanex.py +903 -0
  260. ccxt/async_support/okcoin.py +2936 -0
  261. ccxt/async_support/okexchange.py +349 -0
  262. ccxt/async_support/okx.py +7827 -0
  263. ccxt/async_support/ompfinex.py +472 -0
  264. ccxt/async_support/onetrading.py +1911 -0
  265. ccxt/async_support/oxfun.py +2773 -0
  266. ccxt/async_support/p2b.py +1194 -0
  267. ccxt/async_support/paradex.py +2015 -0
  268. ccxt/async_support/paymium.py +564 -0
  269. ccxt/async_support/phemex.py +4473 -0
  270. ccxt/async_support/poloniex.py +2232 -0
  271. ccxt/async_support/poloniexfutures.py +1717 -0
  272. ccxt/async_support/probit.py +1734 -0
  273. ccxt/async_support/ramzinex.py +476 -0
  274. ccxt/async_support/sarmayex.py +357 -0
  275. ccxt/async_support/sarrafex.py +478 -0
  276. ccxt/async_support/tabdeal.py +364 -0
  277. ccxt/async_support/tetherland.py +349 -0
  278. ccxt/async_support/timex.py +1593 -0
  279. ccxt/async_support/tokocrypto.py +2405 -0
  280. ccxt/async_support/tradeogre.py +608 -0
  281. ccxt/async_support/twox.py +326 -0
  282. ccxt/async_support/ubitex.py +409 -0
  283. ccxt/async_support/upbit.py +1833 -0
  284. ccxt/async_support/vertex.py +2922 -0
  285. ccxt/async_support/wallex.py +445 -0
  286. ccxt/async_support/wavesexchange.py +2473 -0
  287. ccxt/async_support/wazirx.py +1224 -0
  288. ccxt/async_support/whitebit.py +2469 -0
  289. ccxt/async_support/woo.py +3114 -0
  290. ccxt/async_support/woofipro.py +2533 -0
  291. ccxt/async_support/xt.py +4454 -0
  292. ccxt/async_support/yobit.py +1283 -0
  293. ccxt/async_support/zaif.py +725 -0
  294. ccxt/async_support/zonda.py +1828 -0
  295. ccxt/base/__init__.py +27 -0
  296. ccxt/base/decimal_to_precision.py +174 -0
  297. ccxt/base/errors.py +242 -0
  298. ccxt/base/exchange.py +5941 -0
  299. ccxt/base/precise.py +287 -0
  300. ccxt/base/types.py +502 -0
  301. ccxt/bequant.py +33 -0
  302. ccxt/bigone.py +2112 -0
  303. ccxt/binance.py +12233 -0
  304. ccxt/binancecoinm.py +45 -0
  305. ccxt/binanceus.py +211 -0
  306. ccxt/binanceusdm.py +58 -0
  307. ccxt/bingx.py +4324 -0
  308. ccxt/bit2c.py +866 -0
  309. ccxt/bitbank.py +1001 -0
  310. ccxt/bitbay.py +17 -0
  311. ccxt/bitbns.py +1154 -0
  312. ccxt/bitcoincom.py +17 -0
  313. ccxt/bitfinex.py +1617 -0
  314. ccxt/bitfinex2.py +3552 -0
  315. ccxt/bitflyer.py +995 -0
  316. ccxt/bitget.py +8272 -0
  317. ccxt/bithumb.py +1061 -0
  318. ccxt/bitimen.py +401 -0
  319. ccxt/bitir.py +490 -0
  320. ccxt/bitmart.py +4415 -0
  321. ccxt/bitmex.py +2756 -0
  322. ccxt/bitopro.py +1630 -0
  323. ccxt/bitpanda.py +16 -0
  324. ccxt/bitpin.py +454 -0
  325. ccxt/bitrue.py +3026 -0
  326. ccxt/bitso.py +1670 -0
  327. ccxt/bitstamp.py +2203 -0
  328. ccxt/bitteam.py +2239 -0
  329. ccxt/bitvavo.py +1968 -0
  330. ccxt/bl3p.py +485 -0
  331. ccxt/blockchaincom.py +1104 -0
  332. ccxt/blofin.py +2066 -0
  333. ccxt/btcalpha.py +891 -0
  334. ccxt/btcbox.py +544 -0
  335. ccxt/btcmarkets.py +1221 -0
  336. ccxt/btcturk.py +911 -0
  337. ccxt/bybit.py +8158 -0
  338. ccxt/cex.py +1605 -0
  339. ccxt/coinbase.py +4474 -0
  340. ccxt/coinbaseadvanced.py +17 -0
  341. ccxt/coinbaseexchange.py +1734 -0
  342. ccxt/coinbaseinternational.py +1899 -0
  343. ccxt/coincatch.py +5069 -0
  344. ccxt/coincheck.py +815 -0
  345. ccxt/coinex.py +5525 -0
  346. ccxt/coinlist.py +2243 -0
  347. ccxt/coinmate.py +1067 -0
  348. ccxt/coinmetro.py +1797 -0
  349. ccxt/coinone.py +1127 -0
  350. ccxt/coinsph.py +1850 -0
  351. ccxt/coinspot.py +534 -0
  352. ccxt/cryptocom.py +2822 -0
  353. ccxt/currencycom.py +1950 -0
  354. ccxt/delta.py +3376 -0
  355. ccxt/deribit.py +3437 -0
  356. ccxt/digifinex.py +3959 -0
  357. ccxt/eterex.py +286 -0
  358. ccxt/excoino.py +399 -0
  359. ccxt/exir.py +375 -0
  360. ccxt/exmo.py +2462 -0
  361. ccxt/exnovin.py +360 -0
  362. ccxt/farhadexchange.py +266 -0
  363. ccxt/fmfwio.py +34 -0
  364. ccxt/gate.py +6975 -0
  365. ccxt/gateio.py +16 -0
  366. ccxt/gemini.py +1824 -0
  367. ccxt/hashkey.py +4150 -0
  368. ccxt/hitbtc.py +3423 -0
  369. ccxt/hitbtc3.py +16 -0
  370. ccxt/hitobit.py +391 -0
  371. ccxt/hollaex.py +1813 -0
  372. ccxt/htx.py +8505 -0
  373. ccxt/huobi.py +16 -0
  374. ccxt/huobijp.py +1801 -0
  375. ccxt/hyperliquid.py +2430 -0
  376. ccxt/idex.py +1766 -0
  377. ccxt/independentreserve.py +784 -0
  378. ccxt/indodax.py +1247 -0
  379. ccxt/jibitex.py +395 -0
  380. ccxt/kraken.py +2894 -0
  381. ccxt/krakenfutures.py +2601 -0
  382. ccxt/kucoin.py +4601 -0
  383. ccxt/kucoinfutures.py +2698 -0
  384. ccxt/kuna.py +1841 -0
  385. ccxt/latoken.py +1664 -0
  386. ccxt/lbank.py +2682 -0
  387. ccxt/luno.py +1067 -0
  388. ccxt/lykke.py +1270 -0
  389. ccxt/mercado.py +842 -0
  390. ccxt/mexc.py +5369 -0
  391. ccxt/ndax.py +2354 -0
  392. ccxt/nobitex.py +419 -0
  393. ccxt/novadax.py +1484 -0
  394. ccxt/oceanex.py +903 -0
  395. ccxt/okcoin.py +2936 -0
  396. ccxt/okexchange.py +349 -0
  397. ccxt/okx.py +7826 -0
  398. ccxt/ompfinex.py +472 -0
  399. ccxt/onetrading.py +1911 -0
  400. ccxt/oxfun.py +2772 -0
  401. ccxt/p2b.py +1194 -0
  402. ccxt/paradex.py +2015 -0
  403. ccxt/paymium.py +564 -0
  404. ccxt/phemex.py +4473 -0
  405. ccxt/poloniex.py +2232 -0
  406. ccxt/poloniexfutures.py +1717 -0
  407. ccxt/pro/__init__.py +149 -0
  408. ccxt/pro/alpaca.py +685 -0
  409. ccxt/pro/ascendex.py +916 -0
  410. ccxt/pro/bequant.py +38 -0
  411. ccxt/pro/binance.py +3488 -0
  412. ccxt/pro/binancecoinm.py +28 -0
  413. ccxt/pro/binanceus.py +48 -0
  414. ccxt/pro/binanceusdm.py +31 -0
  415. ccxt/pro/bingx.py +1264 -0
  416. ccxt/pro/bitcoincom.py +34 -0
  417. ccxt/pro/bitfinex.py +621 -0
  418. ccxt/pro/bitfinex2.py +1083 -0
  419. ccxt/pro/bitget.py +1692 -0
  420. ccxt/pro/bithumb.py +368 -0
  421. ccxt/pro/bitmart.py +1449 -0
  422. ccxt/pro/bitmex.py +1656 -0
  423. ccxt/pro/bitopro.py +445 -0
  424. ccxt/pro/bitpanda.py +15 -0
  425. ccxt/pro/bitrue.py +447 -0
  426. ccxt/pro/bitstamp.py +522 -0
  427. ccxt/pro/bitvavo.py +1270 -0
  428. ccxt/pro/blockchaincom.py +738 -0
  429. ccxt/pro/blofin.py +692 -0
  430. ccxt/pro/bybit.py +2000 -0
  431. ccxt/pro/cex.py +1440 -0
  432. ccxt/pro/coinbase.py +678 -0
  433. ccxt/pro/coinbaseadvanced.py +16 -0
  434. ccxt/pro/coinbaseexchange.py +895 -0
  435. ccxt/pro/coinbaseinternational.py +620 -0
  436. ccxt/pro/coincatch.py +1464 -0
  437. ccxt/pro/coincheck.py +199 -0
  438. ccxt/pro/coinex.py +1061 -0
  439. ccxt/pro/coinone.py +395 -0
  440. ccxt/pro/cryptocom.py +947 -0
  441. ccxt/pro/currencycom.py +536 -0
  442. ccxt/pro/deribit.py +892 -0
  443. ccxt/pro/exmo.py +629 -0
  444. ccxt/pro/gate.py +1416 -0
  445. ccxt/pro/gateio.py +15 -0
  446. ccxt/pro/gemini.py +865 -0
  447. ccxt/pro/hashkey.py +802 -0
  448. ccxt/pro/hitbtc.py +1216 -0
  449. ccxt/pro/hollaex.py +563 -0
  450. ccxt/pro/htx.py +2215 -0
  451. ccxt/pro/huobi.py +15 -0
  452. ccxt/pro/huobijp.py +570 -0
  453. ccxt/pro/hyperliquid.py +525 -0
  454. ccxt/pro/idex.py +672 -0
  455. ccxt/pro/independentreserve.py +270 -0
  456. ccxt/pro/kraken.py +1356 -0
  457. ccxt/pro/krakenfutures.py +1492 -0
  458. ccxt/pro/kucoin.py +1133 -0
  459. ccxt/pro/kucoinfutures.py +1081 -0
  460. ccxt/pro/lbank.py +843 -0
  461. ccxt/pro/luno.py +303 -0
  462. ccxt/pro/mexc.py +1122 -0
  463. ccxt/pro/ndax.py +506 -0
  464. ccxt/pro/okcoin.py +698 -0
  465. ccxt/pro/okx.py +1851 -0
  466. ccxt/pro/onetrading.py +1275 -0
  467. ccxt/pro/oxfun.py +950 -0
  468. ccxt/pro/p2b.py +419 -0
  469. ccxt/pro/paradex.py +352 -0
  470. ccxt/pro/phemex.py +1441 -0
  471. ccxt/pro/poloniex.py +1166 -0
  472. ccxt/pro/poloniexfutures.py +990 -0
  473. ccxt/pro/probit.py +551 -0
  474. ccxt/pro/upbit.py +520 -0
  475. ccxt/pro/vertex.py +943 -0
  476. ccxt/pro/wazirx.py +749 -0
  477. ccxt/pro/whitebit.py +864 -0
  478. ccxt/pro/woo.py +1078 -0
  479. ccxt/pro/woofipro.py +1183 -0
  480. ccxt/pro/xt.py +1067 -0
  481. ccxt/probit.py +1734 -0
  482. ccxt/ramzinex.py +476 -0
  483. ccxt/sarmayex.py +357 -0
  484. ccxt/sarrafex.py +478 -0
  485. ccxt/static_dependencies/__init__.py +1 -0
  486. ccxt/static_dependencies/ecdsa/__init__.py +14 -0
  487. ccxt/static_dependencies/ecdsa/_version.py +520 -0
  488. ccxt/static_dependencies/ecdsa/curves.py +56 -0
  489. ccxt/static_dependencies/ecdsa/der.py +221 -0
  490. ccxt/static_dependencies/ecdsa/ecdsa.py +310 -0
  491. ccxt/static_dependencies/ecdsa/ellipticcurve.py +197 -0
  492. ccxt/static_dependencies/ecdsa/keys.py +332 -0
  493. ccxt/static_dependencies/ecdsa/numbertheory.py +531 -0
  494. ccxt/static_dependencies/ecdsa/rfc6979.py +100 -0
  495. ccxt/static_dependencies/ecdsa/util.py +266 -0
  496. ccxt/static_dependencies/ethereum/__init__.py +7 -0
  497. ccxt/static_dependencies/ethereum/abi/__init__.py +16 -0
  498. ccxt/static_dependencies/ethereum/abi/abi.py +19 -0
  499. ccxt/static_dependencies/ethereum/abi/base.py +152 -0
  500. ccxt/static_dependencies/ethereum/abi/codec.py +217 -0
  501. ccxt/static_dependencies/ethereum/abi/constants.py +3 -0
  502. ccxt/static_dependencies/ethereum/abi/decoding.py +565 -0
  503. ccxt/static_dependencies/ethereum/abi/encoding.py +720 -0
  504. ccxt/static_dependencies/ethereum/abi/exceptions.py +139 -0
  505. ccxt/static_dependencies/ethereum/abi/grammar.py +443 -0
  506. ccxt/static_dependencies/ethereum/abi/packed.py +13 -0
  507. ccxt/static_dependencies/ethereum/abi/py.typed +0 -0
  508. ccxt/static_dependencies/ethereum/abi/registry.py +643 -0
  509. ccxt/static_dependencies/ethereum/abi/tools/__init__.py +3 -0
  510. ccxt/static_dependencies/ethereum/abi/tools/_strategies.py +230 -0
  511. ccxt/static_dependencies/ethereum/abi/utils/__init__.py +0 -0
  512. ccxt/static_dependencies/ethereum/abi/utils/numeric.py +83 -0
  513. ccxt/static_dependencies/ethereum/abi/utils/padding.py +27 -0
  514. ccxt/static_dependencies/ethereum/abi/utils/string.py +19 -0
  515. ccxt/static_dependencies/ethereum/account/__init__.py +3 -0
  516. ccxt/static_dependencies/ethereum/account/encode_typed_data/__init__.py +4 -0
  517. ccxt/static_dependencies/ethereum/account/encode_typed_data/encoding_and_hashing.py +239 -0
  518. ccxt/static_dependencies/ethereum/account/encode_typed_data/helpers.py +40 -0
  519. ccxt/static_dependencies/ethereum/account/messages.py +263 -0
  520. ccxt/static_dependencies/ethereum/account/py.typed +0 -0
  521. ccxt/static_dependencies/ethereum/hexbytes/__init__.py +5 -0
  522. ccxt/static_dependencies/ethereum/hexbytes/_utils.py +54 -0
  523. ccxt/static_dependencies/ethereum/hexbytes/main.py +65 -0
  524. ccxt/static_dependencies/ethereum/hexbytes/py.typed +0 -0
  525. ccxt/static_dependencies/ethereum/typing/__init__.py +63 -0
  526. ccxt/static_dependencies/ethereum/typing/abi.py +6 -0
  527. ccxt/static_dependencies/ethereum/typing/bls.py +7 -0
  528. ccxt/static_dependencies/ethereum/typing/discovery.py +5 -0
  529. ccxt/static_dependencies/ethereum/typing/encoding.py +7 -0
  530. ccxt/static_dependencies/ethereum/typing/enums.py +17 -0
  531. ccxt/static_dependencies/ethereum/typing/ethpm.py +9 -0
  532. ccxt/static_dependencies/ethereum/typing/evm.py +20 -0
  533. ccxt/static_dependencies/ethereum/typing/networks.py +1122 -0
  534. ccxt/static_dependencies/ethereum/typing/py.typed +0 -0
  535. ccxt/static_dependencies/ethereum/utils/__init__.py +115 -0
  536. ccxt/static_dependencies/ethereum/utils/abi.py +72 -0
  537. ccxt/static_dependencies/ethereum/utils/address.py +171 -0
  538. ccxt/static_dependencies/ethereum/utils/applicators.py +151 -0
  539. ccxt/static_dependencies/ethereum/utils/conversions.py +190 -0
  540. ccxt/static_dependencies/ethereum/utils/currency.py +107 -0
  541. ccxt/static_dependencies/ethereum/utils/curried/__init__.py +269 -0
  542. ccxt/static_dependencies/ethereum/utils/debug.py +20 -0
  543. ccxt/static_dependencies/ethereum/utils/decorators.py +132 -0
  544. ccxt/static_dependencies/ethereum/utils/encoding.py +6 -0
  545. ccxt/static_dependencies/ethereum/utils/exceptions.py +4 -0
  546. ccxt/static_dependencies/ethereum/utils/functional.py +75 -0
  547. ccxt/static_dependencies/ethereum/utils/hexadecimal.py +74 -0
  548. ccxt/static_dependencies/ethereum/utils/humanize.py +188 -0
  549. ccxt/static_dependencies/ethereum/utils/logging.py +159 -0
  550. ccxt/static_dependencies/ethereum/utils/module_loading.py +31 -0
  551. ccxt/static_dependencies/ethereum/utils/numeric.py +43 -0
  552. ccxt/static_dependencies/ethereum/utils/py.typed +0 -0
  553. ccxt/static_dependencies/ethereum/utils/toolz.py +76 -0
  554. ccxt/static_dependencies/ethereum/utils/types.py +54 -0
  555. ccxt/static_dependencies/ethereum/utils/typing/__init__.py +18 -0
  556. ccxt/static_dependencies/ethereum/utils/typing/misc.py +14 -0
  557. ccxt/static_dependencies/ethereum/utils/units.py +31 -0
  558. ccxt/static_dependencies/keccak/__init__.py +3 -0
  559. ccxt/static_dependencies/keccak/keccak.py +197 -0
  560. ccxt/static_dependencies/lark/__init__.py +38 -0
  561. ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  562. ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  563. ccxt/static_dependencies/lark/ast_utils.py +59 -0
  564. ccxt/static_dependencies/lark/common.py +86 -0
  565. ccxt/static_dependencies/lark/exceptions.py +292 -0
  566. ccxt/static_dependencies/lark/grammar.py +130 -0
  567. ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  568. ccxt/static_dependencies/lark/indenter.py +143 -0
  569. ccxt/static_dependencies/lark/lark.py +658 -0
  570. ccxt/static_dependencies/lark/lexer.py +678 -0
  571. ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  572. ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  573. ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  574. ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  575. ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  576. ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  577. ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  578. ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  579. ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  580. ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  581. ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  582. ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  583. ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  584. ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  585. ccxt/static_dependencies/lark/reconstruct.py +107 -0
  586. ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  587. ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  588. ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  589. ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  590. ccxt/static_dependencies/lark/tree.py +267 -0
  591. ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  592. ccxt/static_dependencies/lark/tree_templates.py +180 -0
  593. ccxt/static_dependencies/lark/utils.py +343 -0
  594. ccxt/static_dependencies/lark/visitors.py +596 -0
  595. ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  596. ccxt/static_dependencies/marshmallow/base.py +65 -0
  597. ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  598. ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  599. ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  600. ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  601. ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  602. ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  603. ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  604. ccxt/static_dependencies/marshmallow/types.py +12 -0
  605. ccxt/static_dependencies/marshmallow/utils.py +378 -0
  606. ccxt/static_dependencies/marshmallow/validate.py +678 -0
  607. ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  608. ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  609. ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  610. ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  611. ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  612. ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  613. ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  614. ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  615. ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  616. ccxt/static_dependencies/msgpack/__init__.py +55 -0
  617. ccxt/static_dependencies/msgpack/exceptions.py +48 -0
  618. ccxt/static_dependencies/msgpack/ext.py +168 -0
  619. ccxt/static_dependencies/msgpack/fallback.py +951 -0
  620. ccxt/static_dependencies/parsimonious/__init__.py +10 -0
  621. ccxt/static_dependencies/parsimonious/exceptions.py +105 -0
  622. ccxt/static_dependencies/parsimonious/expressions.py +479 -0
  623. ccxt/static_dependencies/parsimonious/grammar.py +487 -0
  624. ccxt/static_dependencies/parsimonious/nodes.py +325 -0
  625. ccxt/static_dependencies/parsimonious/utils.py +40 -0
  626. ccxt/static_dependencies/starknet/__init__.py +0 -0
  627. ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  628. ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  629. ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  630. ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  631. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  632. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  633. ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  634. ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  635. ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  636. ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  637. ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  638. ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  639. ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  640. ccxt/static_dependencies/starknet/common.py +15 -0
  641. ccxt/static_dependencies/starknet/constants.py +39 -0
  642. ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  643. ccxt/static_dependencies/starknet/hash/address.py +79 -0
  644. ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  645. ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  646. ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  647. ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  648. ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  649. ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
  650. ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  651. ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  652. ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  653. ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  654. ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  655. ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  656. ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  657. ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  658. ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  659. ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  660. ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  661. ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  662. ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  663. ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  664. ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  665. ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  666. ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  667. ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  668. ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  669. ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  670. ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  671. ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  672. ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  673. ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  674. ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  675. ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  676. ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  677. ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  678. ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  679. ccxt/static_dependencies/starkware/__init__.py +0 -0
  680. ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  681. ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
  682. ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
  683. ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
  684. ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
  685. ccxt/static_dependencies/sympy/__init__.py +0 -0
  686. ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  687. ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
  688. ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  689. ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  690. ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  691. ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  692. ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  693. ccxt/static_dependencies/toolz/__init__.py +26 -0
  694. ccxt/static_dependencies/toolz/_signatures.py +784 -0
  695. ccxt/static_dependencies/toolz/_version.py +520 -0
  696. ccxt/static_dependencies/toolz/compatibility.py +30 -0
  697. ccxt/static_dependencies/toolz/curried/__init__.py +101 -0
  698. ccxt/static_dependencies/toolz/curried/exceptions.py +22 -0
  699. ccxt/static_dependencies/toolz/curried/operator.py +22 -0
  700. ccxt/static_dependencies/toolz/dicttoolz.py +339 -0
  701. ccxt/static_dependencies/toolz/functoolz.py +1049 -0
  702. ccxt/static_dependencies/toolz/itertoolz.py +1057 -0
  703. ccxt/static_dependencies/toolz/recipes.py +46 -0
  704. ccxt/static_dependencies/toolz/utils.py +9 -0
  705. ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  706. ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  707. ccxt/tabdeal.py +364 -0
  708. ccxt/test/__init__.py +3 -0
  709. ccxt/test/base/__init__.py +29 -0
  710. ccxt/test/base/test_account.py +26 -0
  711. ccxt/test/base/test_balance.py +56 -0
  712. ccxt/test/base/test_borrow_interest.py +35 -0
  713. ccxt/test/base/test_borrow_rate.py +32 -0
  714. ccxt/test/base/test_calculate_fee.py +51 -0
  715. ccxt/test/base/test_crypto.py +127 -0
  716. ccxt/test/base/test_currency.py +76 -0
  717. ccxt/test/base/test_datetime.py +109 -0
  718. ccxt/test/base/test_decimal_to_precision.py +392 -0
  719. ccxt/test/base/test_deep_extend.py +68 -0
  720. ccxt/test/base/test_deposit_withdrawal.py +50 -0
  721. ccxt/test/base/test_exchange_datetime_functions.py +76 -0
  722. ccxt/test/base/test_funding_rate_history.py +29 -0
  723. ccxt/test/base/test_last_price.py +31 -0
  724. ccxt/test/base/test_ledger_entry.py +45 -0
  725. ccxt/test/base/test_ledger_item.py +48 -0
  726. ccxt/test/base/test_leverage_tier.py +33 -0
  727. ccxt/test/base/test_liquidation.py +50 -0
  728. ccxt/test/base/test_margin_mode.py +24 -0
  729. ccxt/test/base/test_margin_modification.py +35 -0
  730. ccxt/test/base/test_market.py +193 -0
  731. ccxt/test/base/test_number.py +411 -0
  732. ccxt/test/base/test_ohlcv.py +33 -0
  733. ccxt/test/base/test_open_interest.py +32 -0
  734. ccxt/test/base/test_order.py +64 -0
  735. ccxt/test/base/test_order_book.py +69 -0
  736. ccxt/test/base/test_position.py +60 -0
  737. ccxt/test/base/test_shared_methods.py +353 -0
  738. ccxt/test/base/test_status.py +24 -0
  739. ccxt/test/base/test_throttle.py +126 -0
  740. ccxt/test/base/test_ticker.py +92 -0
  741. ccxt/test/base/test_trade.py +47 -0
  742. ccxt/test/base/test_trading_fee.py +26 -0
  743. ccxt/test/base/test_transaction.py +39 -0
  744. ccxt/test/test_async.py +1649 -0
  745. ccxt/test/test_sync.py +1648 -0
  746. ccxt/test/tests_async.py +1558 -0
  747. ccxt/test/tests_helpers.py +287 -0
  748. ccxt/test/tests_init.py +39 -0
  749. ccxt/test/tests_sync.py +1555 -0
  750. ccxt/tetherland.py +349 -0
  751. ccxt/timex.py +1593 -0
  752. ccxt/tokocrypto.py +2405 -0
  753. ccxt/tradeogre.py +608 -0
  754. ccxt/twox.py +326 -0
  755. ccxt/ubitex.py +409 -0
  756. ccxt/upbit.py +1833 -0
  757. ccxt/vertex.py +2922 -0
  758. ccxt/wallex.py +445 -0
  759. ccxt/wavesexchange.py +2472 -0
  760. ccxt/wazirx.py +1224 -0
  761. ccxt/whitebit.py +2469 -0
  762. ccxt/woo.py +3114 -0
  763. ccxt/woofipro.py +2533 -0
  764. ccxt/xt.py +4453 -0
  765. ccxt/yobit.py +1283 -0
  766. ccxt/zaif.py +725 -0
  767. ccxt/zonda.py +1828 -0
  768. ccxt_ir-4.3.46.0.1.dist-info/LICENSE.txt +21 -0
  769. ccxt_ir-4.3.46.0.1.dist-info/METADATA +655 -0
  770. ccxt_ir-4.3.46.0.1.dist-info/RECORD +772 -0
  771. ccxt_ir-4.3.46.0.1.dist-info/WHEEL +6 -0
  772. ccxt_ir-4.3.46.0.1.dist-info/top_level.txt +1 -0
ccxt/probit.py ADDED
@@ -0,0 +1,1734 @@
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.base.exchange import Exchange
7
+ from ccxt.abstract.probit import ImplicitAPI
8
+ import math
9
+ from ccxt.base.types import Balances, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
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 ArgumentsRequired
14
+ from ccxt.base.errors import BadRequest
15
+ from ccxt.base.errors import BadSymbol
16
+ from ccxt.base.errors import BadResponse
17
+ from ccxt.base.errors import InsufficientFunds
18
+ from ccxt.base.errors import InvalidAddress
19
+ from ccxt.base.errors import InvalidOrder
20
+ from ccxt.base.errors import DDoSProtection
21
+ from ccxt.base.errors import RateLimitExceeded
22
+ from ccxt.base.errors import ExchangeNotAvailable
23
+ from ccxt.base.decimal_to_precision import TRUNCATE
24
+ from ccxt.base.decimal_to_precision import TICK_SIZE
25
+ from ccxt.base.precise import Precise
26
+
27
+
28
+ class probit(Exchange, ImplicitAPI):
29
+
30
+ def describe(self):
31
+ return self.deep_extend(super(probit, self).describe(), {
32
+ 'id': 'probit',
33
+ 'name': 'ProBit',
34
+ 'countries': ['SC', 'KR'], # Seychelles, South Korea
35
+ 'rateLimit': 50, # ms
36
+ 'pro': True,
37
+ 'has': {
38
+ 'CORS': True,
39
+ 'spot': True,
40
+ 'margin': False,
41
+ 'swap': False,
42
+ 'future': False,
43
+ 'option': False,
44
+ 'addMargin': False,
45
+ 'cancelOrder': True,
46
+ 'createMarketBuyOrderWithCost': True,
47
+ 'createMarketOrder': True,
48
+ 'createMarketOrderWithCost': False,
49
+ 'createMarketSellOrderWithCost': False,
50
+ 'createOrder': True,
51
+ 'createReduceOnlyOrder': False,
52
+ 'createStopLimitOrder': False,
53
+ 'createStopMarketOrder': False,
54
+ 'createStopOrder': False,
55
+ 'fetchBalance': True,
56
+ 'fetchBorrowRateHistories': False,
57
+ 'fetchBorrowRateHistory': False,
58
+ 'fetchClosedOrders': True,
59
+ 'fetchCrossBorrowRate': False,
60
+ 'fetchCrossBorrowRates': False,
61
+ 'fetchCurrencies': True,
62
+ 'fetchDepositAddress': True,
63
+ 'fetchDepositAddresses': True,
64
+ 'fetchDeposits': True,
65
+ 'fetchDepositsWithdrawals': True,
66
+ 'fetchFundingHistory': False,
67
+ 'fetchFundingRate': False,
68
+ 'fetchFundingRateHistory': False,
69
+ 'fetchFundingRates': False,
70
+ 'fetchIndexOHLCV': False,
71
+ 'fetchIsolatedBorrowRate': False,
72
+ 'fetchIsolatedBorrowRates': False,
73
+ 'fetchLeverage': False,
74
+ 'fetchLeverageTiers': False,
75
+ 'fetchMarginMode': False,
76
+ 'fetchMarkets': True,
77
+ 'fetchMarkOHLCV': False,
78
+ 'fetchMyTrades': True,
79
+ 'fetchOHLCV': True,
80
+ 'fetchOpenInterestHistory': False,
81
+ 'fetchOpenOrders': True,
82
+ 'fetchOrder': True,
83
+ 'fetchOrderBook': True,
84
+ 'fetchPosition': False,
85
+ 'fetchPositionHistory': False,
86
+ 'fetchPositionMode': False,
87
+ 'fetchPositions': False,
88
+ 'fetchPositionsForSymbol': False,
89
+ 'fetchPositionsHistory': False,
90
+ 'fetchPositionsRisk': False,
91
+ 'fetchPremiumIndexOHLCV': False,
92
+ 'fetchTicker': True,
93
+ 'fetchTickers': True,
94
+ 'fetchTime': True,
95
+ 'fetchTrades': True,
96
+ 'fetchTradingFee': False,
97
+ 'fetchTradingFees': False,
98
+ 'fetchTransactions': 'emulated',
99
+ 'fetchTransfer': False,
100
+ 'fetchTransfers': False,
101
+ 'fetchWithdrawal': False,
102
+ 'fetchWithdrawals': True,
103
+ 'reduceMargin': False,
104
+ 'sandbox': True,
105
+ 'setLeverage': False,
106
+ 'setMarginMode': False,
107
+ 'setPositionMode': False,
108
+ 'signIn': True,
109
+ 'transfer': False,
110
+ 'withdraw': True,
111
+ },
112
+ 'timeframes': {
113
+ '1m': '1m',
114
+ '3m': '3m',
115
+ '5m': '5m',
116
+ '10m': '10m',
117
+ '15m': '15m',
118
+ '30m': '30m',
119
+ '1h': '1h',
120
+ '4h': '4h',
121
+ '6h': '6h',
122
+ '12h': '12h',
123
+ '1d': '1D',
124
+ '1w': '1W',
125
+ '1M': '1M',
126
+ },
127
+ 'version': 'v1',
128
+ 'urls': {
129
+ 'logo': 'https://user-images.githubusercontent.com/51840849/79268032-c4379480-7ea2-11ea-80b3-dd96bb29fd0d.jpg',
130
+ 'api': {
131
+ 'accounts': 'https://accounts.probit.com',
132
+ 'public': 'https://api.probit.com/api/exchange',
133
+ 'private': 'https://api.probit.com/api/exchange',
134
+ },
135
+ 'www': 'https://www.probit.com',
136
+ 'doc': [
137
+ 'https://docs-en.probit.com',
138
+ 'https://docs-ko.probit.com',
139
+ ],
140
+ 'fees': 'https://support.probit.com/hc/en-us/articles/360020968611-Trading-Fees',
141
+ 'referral': 'https://www.probit.com/r/34608773',
142
+ },
143
+ 'api': {
144
+ 'public': {
145
+ 'get': {
146
+ 'market': 1,
147
+ 'currency': 1,
148
+ 'currency_with_platform': 1,
149
+ 'time': 1,
150
+ 'ticker': 1,
151
+ 'order_book': 1,
152
+ 'trade': 1,
153
+ 'candle': 1,
154
+ },
155
+ },
156
+ 'private': {
157
+ 'post': {
158
+ 'new_order': 2,
159
+ 'cancel_order': 1,
160
+ 'withdrawal': 2,
161
+ },
162
+ 'get': {
163
+ 'balance': 1,
164
+ 'order': 1,
165
+ 'open_order': 1,
166
+ 'order_history': 1,
167
+ 'trade_history': 1,
168
+ 'deposit_address': 1,
169
+ 'transfer/payment': 1,
170
+ },
171
+ },
172
+ 'accounts': {
173
+ 'post': {
174
+ 'token': 1,
175
+ },
176
+ },
177
+ },
178
+ 'fees': {
179
+ 'trading': {
180
+ 'tierBased': False,
181
+ 'percentage': True,
182
+ 'maker': self.parse_number('0.002'),
183
+ 'taker': self.parse_number('0.002'),
184
+ },
185
+ },
186
+ 'exceptions': {
187
+ 'exact': {
188
+ 'UNAUTHORIZED': AuthenticationError,
189
+ 'INVALID_ARGUMENT': BadRequest, # Parameters are not a valid format, parameters are empty, or out of range, or a parameter was sent when not required.
190
+ 'TRADING_UNAVAILABLE': ExchangeNotAvailable,
191
+ 'NOT_ENOUGH_BALANCE': InsufficientFunds,
192
+ 'NOT_ALLOWED_COMBINATION': BadRequest,
193
+ 'INVALID_ORDER': InvalidOrder, # Requested order does not exist, or it is not your order
194
+ 'RATE_LIMIT_EXCEEDED': RateLimitExceeded, # You are sending requests too frequently. Please try it later.
195
+ 'MARKET_UNAVAILABLE': ExchangeNotAvailable, # Market is closed today
196
+ 'INVALID_MARKET': BadSymbol, # Requested market is not exist
197
+ 'MARKET_CLOSED': BadSymbol, # {"errorCode":"MARKET_CLOSED"}
198
+ 'MARKET_NOT_FOUND': BadSymbol, # {"errorCode":"MARKET_NOT_FOUND","message":"8e2b8496-0a1e-5beb-b990-a205b902eabe","details":{}}
199
+ 'INVALID_CURRENCY': BadRequest, # Requested currency is not exist on ProBit system
200
+ 'TOO_MANY_OPEN_ORDERS': DDoSProtection, # Too many open orders
201
+ 'DUPLICATE_ADDRESS': InvalidAddress, # Address already exists in withdrawal address list
202
+ 'invalid_grant': AuthenticationError, # {"error":"invalid_grant"}
203
+ },
204
+ },
205
+ 'requiredCredentials': {
206
+ 'apiKey': True,
207
+ 'secret': True,
208
+ },
209
+ 'precisionMode': TICK_SIZE,
210
+ 'options': {
211
+ 'createMarketBuyOrderRequiresPrice': True,
212
+ 'timeInForce': {
213
+ 'limit': 'gtc',
214
+ 'market': 'ioc',
215
+ },
216
+ 'networks': {
217
+ 'BEP20': 'BSC',
218
+ 'ERC20': 'ETH',
219
+ 'TRC20': 'TRON',
220
+ },
221
+ },
222
+ 'commonCurrencies': {
223
+ 'BB': 'Baby Bali',
224
+ 'CBC': 'CryptoBharatCoin',
225
+ 'CTK': 'Cryptyk',
226
+ 'CTT': 'Castweet',
227
+ 'DKT': 'DAKOTA',
228
+ 'EGC': 'EcoG9coin',
229
+ 'EPS': 'Epanus', # conflict with EPS Ellipsis https://github.com/ccxt/ccxt/issues/8909
230
+ 'FX': 'Fanzy',
231
+ 'GM': 'GM Holding',
232
+ 'GOGOL': 'GOL',
233
+ 'GOL': 'Goldofir',
234
+ 'HUSL': 'The Hustle App',
235
+ 'LAND': 'Landbox',
236
+ 'SST': 'SocialSwap',
237
+ 'TCT': 'Top Coin Token',
238
+ 'TOR': 'Torex',
239
+ 'UNI': 'UNICORN Token',
240
+ 'UNISWAP': 'UNI',
241
+ },
242
+ })
243
+
244
+ def fetch_markets(self, params={}) -> List[Market]:
245
+ """
246
+ :see: https://docs-en.probit.com/reference/market
247
+ retrieves data on all markets for probit
248
+ :param dict [params]: extra parameters specific to the exchange API endpoint
249
+ :returns dict[]: an array of objects representing market data
250
+ """
251
+ response = self.publicGetMarket(params)
252
+ #
253
+ # {
254
+ # "data":[
255
+ # {
256
+ # "id":"MONA-USDT",
257
+ # "base_currency_id":"MONA",
258
+ # "quote_currency_id":"USDT",
259
+ # "min_price":"0.001",
260
+ # "max_price":"9999999999999999",
261
+ # "price_increment":"0.001",
262
+ # "min_quantity":"0.0001",
263
+ # "max_quantity":"9999999999999999",
264
+ # "quantity_precision":4,
265
+ # "min_cost":"1",
266
+ # "max_cost":"9999999999999999",
267
+ # "cost_precision":8,
268
+ # "taker_fee_rate":"0.2",
269
+ # "maker_fee_rate":"0.2",
270
+ # "show_in_ui":true,
271
+ # "closed":false
272
+ # },
273
+ # ]
274
+ # }
275
+ #
276
+ markets = self.safe_value(response, 'data', [])
277
+ return self.parse_markets(markets)
278
+
279
+ def parse_market(self, market: dict) -> Market:
280
+ id = self.safe_string(market, 'id')
281
+ baseId = self.safe_string(market, 'base_currency_id')
282
+ quoteId = self.safe_string(market, 'quote_currency_id')
283
+ base = self.safe_currency_code(baseId)
284
+ quote = self.safe_currency_code(quoteId)
285
+ closed = self.safe_bool(market, 'closed', False)
286
+ takerFeeRate = self.safe_string(market, 'taker_fee_rate')
287
+ taker = Precise.string_div(takerFeeRate, '100')
288
+ makerFeeRate = self.safe_string(market, 'maker_fee_rate')
289
+ maker = Precise.string_div(makerFeeRate, '100')
290
+ return {
291
+ 'id': id,
292
+ 'symbol': base + '/' + quote,
293
+ 'base': base,
294
+ 'quote': quote,
295
+ 'settle': None,
296
+ 'baseId': baseId,
297
+ 'quoteId': quoteId,
298
+ 'settleId': None,
299
+ 'type': 'spot',
300
+ 'spot': True,
301
+ 'margin': False,
302
+ 'swap': False,
303
+ 'future': False,
304
+ 'option': False,
305
+ 'active': not closed,
306
+ 'contract': False,
307
+ 'linear': None,
308
+ 'inverse': None,
309
+ 'taker': self.parse_number(taker),
310
+ 'maker': self.parse_number(maker),
311
+ 'contractSize': None,
312
+ 'expiry': None,
313
+ 'expiryDatetime': None,
314
+ 'strike': None,
315
+ 'optionType': None,
316
+ 'precision': {
317
+ 'amount': self.parse_number(self.parse_precision(self.safe_string(market, 'quantity_precision'))),
318
+ 'price': self.safe_number(market, 'price_increment'),
319
+ 'cost': self.parse_number(self.parse_precision(self.safe_string(market, 'cost_precision'))),
320
+ },
321
+ 'limits': {
322
+ 'leverage': {
323
+ 'min': None,
324
+ 'max': None,
325
+ },
326
+ 'amount': {
327
+ 'min': self.safe_number(market, 'min_quantity'),
328
+ 'max': self.safe_number(market, 'max_quantity'),
329
+ },
330
+ 'price': {
331
+ 'min': self.safe_number(market, 'min_price'),
332
+ 'max': self.safe_number(market, 'max_price'),
333
+ },
334
+ 'cost': {
335
+ 'min': self.safe_number(market, 'min_cost'),
336
+ 'max': self.safe_number(market, 'max_cost'),
337
+ },
338
+ },
339
+ 'created': None,
340
+ 'info': market,
341
+ }
342
+
343
+ def fetch_currencies(self, params={}) -> Currencies:
344
+ """
345
+ :see: https://docs-en.probit.com/reference/currency
346
+ fetches all available currencies on an exchange
347
+ :param dict [params]: extra parameters specific to the exchange API endpoint
348
+ :returns dict: an associative dictionary of currencies
349
+ """
350
+ response = self.publicGetCurrencyWithPlatform(params)
351
+ #
352
+ # {
353
+ # "data":[
354
+ # {
355
+ # "id":"USDT",
356
+ # "display_name":{"ko-kr":"테더","en-us":"Tether"},
357
+ # "show_in_ui":true,
358
+ # "platform":[
359
+ # {
360
+ # "id":"ETH",
361
+ # "priority":1,
362
+ # "deposit":true,
363
+ # "withdrawal":true,
364
+ # "currency_id":"USDT",
365
+ # "precision":6,
366
+ # "min_confirmation_count":15,
367
+ # "require_destination_tag":false,
368
+ # "display_name":{"name":{"ko-kr":"ERC-20","en-us":"ERC-20"}},
369
+ # "min_deposit_amount":"0",
370
+ # "min_withdrawal_amount":"1",
371
+ # "withdrawal_fee":[
372
+ # {"amount":"0.01","priority":2,"currency_id":"ETH"},
373
+ # {"amount":"1.5","priority":1,"currency_id":"USDT"},
374
+ # ],
375
+ # "deposit_fee":{},
376
+ # "suspended_reason":"",
377
+ # "deposit_suspended":false,
378
+ # "withdrawal_suspended":false
379
+ # },
380
+ # {
381
+ # "id":"OMNI",
382
+ # "priority":2,
383
+ # "deposit":true,
384
+ # "withdrawal":true,
385
+ # "currency_id":"USDT",
386
+ # "precision":6,
387
+ # "min_confirmation_count":3,
388
+ # "require_destination_tag":false,
389
+ # "display_name":{"name":{"ko-kr":"OMNI","en-us":"OMNI"}},
390
+ # "min_deposit_amount":"0",
391
+ # "min_withdrawal_amount":"5",
392
+ # "withdrawal_fee":[{"amount":"5","priority":1,"currency_id":"USDT"}],
393
+ # "deposit_fee":{},
394
+ # "suspended_reason":"wallet_maintenance",
395
+ # "deposit_suspended":false,
396
+ # "withdrawal_suspended":false
397
+ # }
398
+ # ],
399
+ # "stakeable":false,
400
+ # "unstakeable":false,
401
+ # "auto_stake":false,
402
+ # "auto_stake_amount":"0"
403
+ # }
404
+ # ]
405
+ # }
406
+ #
407
+ currencies = self.safe_value(response, 'data', [])
408
+ result: dict = {}
409
+ for i in range(0, len(currencies)):
410
+ currency = currencies[i]
411
+ id = self.safe_string(currency, 'id')
412
+ code = self.safe_currency_code(id)
413
+ displayName = self.safe_value(currency, 'display_name')
414
+ name = self.safe_string(displayName, 'en-us')
415
+ platforms = self.safe_value(currency, 'platform', [])
416
+ platformsByPriority = self.sort_by(platforms, 'priority')
417
+ platform = None
418
+ networkList: dict = {}
419
+ for j in range(0, len(platformsByPriority)):
420
+ network = platformsByPriority[j]
421
+ idInner = self.safe_string(network, 'id')
422
+ networkCode = self.network_id_to_code(idInner)
423
+ currentDepositSuspended = self.safe_value(network, 'deposit_suspended')
424
+ currentWithdrawalSuspended = self.safe_value(network, 'withdrawal_suspended')
425
+ currentDeposit = not currentDepositSuspended
426
+ currentWithdraw = not currentWithdrawalSuspended
427
+ currentActive = currentDeposit and currentWithdraw
428
+ if currentActive:
429
+ platform = network
430
+ precision = self.parse_precision(self.safe_string(network, 'precision'))
431
+ withdrawFee = self.safe_value(network, 'withdrawal_fee', [])
432
+ networkFee = self.safe_value(withdrawFee, 0, {})
433
+ for k in range(0, len(withdrawFee)):
434
+ withdrawPlatform = withdrawFee[k]
435
+ feeCurrencyId = self.safe_string(withdrawPlatform, 'currency_id')
436
+ if feeCurrencyId == id:
437
+ networkFee = withdrawPlatform
438
+ break
439
+ networkList[networkCode] = {
440
+ 'id': idInner,
441
+ 'network': networkCode,
442
+ 'active': currentActive,
443
+ 'deposit': currentDeposit,
444
+ 'withdraw': currentWithdraw,
445
+ 'fee': self.safe_number(networkFee, 'amount'),
446
+ 'precision': self.parse_number(precision),
447
+ 'limits': {
448
+ 'withdraw': {
449
+ 'min': self.safe_number(network, 'min_withdrawal_amount'),
450
+ 'max': None,
451
+ },
452
+ 'deposit': {
453
+ 'min': self.safe_number(network, 'min_deposit_amount'),
454
+ 'max': None,
455
+ },
456
+ },
457
+ 'info': network,
458
+ }
459
+ if platform is None:
460
+ platform = self.safe_value(platformsByPriority, 0, {})
461
+ depositSuspended = self.safe_value(platform, 'deposit_suspended')
462
+ withdrawalSuspended = self.safe_value(platform, 'withdrawal_suspended')
463
+ deposit = not depositSuspended
464
+ withdraw = not withdrawalSuspended
465
+ active = deposit and withdraw
466
+ withdrawalFees = self.safe_value(platform, 'withdrawal_fee', {})
467
+ fees = []
468
+ # sometimes the withdrawal fee is an empty object
469
+ # [{'amount': '0.015', 'priority': 1, 'currency_id': 'ETH'}, {}]
470
+ for j in range(0, len(withdrawalFees)):
471
+ withdrawalFeeInner = withdrawalFees[j]
472
+ amount = self.safe_number(withdrawalFeeInner, 'amount')
473
+ priority = self.safe_integer(withdrawalFeeInner, 'priority')
474
+ if (amount is not None) and (priority is not None):
475
+ fees.append(withdrawalFeeInner)
476
+ withdrawalFeesByPriority = self.sort_by(fees, 'priority')
477
+ withdrawalFee = self.safe_value(withdrawalFeesByPriority, 0, {})
478
+ fee = self.safe_number(withdrawalFee, 'amount')
479
+ result[code] = {
480
+ 'id': id,
481
+ 'code': code,
482
+ 'info': currency,
483
+ 'name': name,
484
+ 'active': active,
485
+ 'deposit': deposit,
486
+ 'withdraw': withdraw,
487
+ 'fee': fee,
488
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(platform, 'precision'))),
489
+ 'limits': {
490
+ 'amount': {
491
+ 'min': None,
492
+ 'max': None,
493
+ },
494
+ 'deposit': {
495
+ 'min': self.safe_number(platform, 'min_deposit_amount'),
496
+ 'max': None,
497
+ },
498
+ 'withdraw': {
499
+ 'min': self.safe_number(platform, 'min_withdrawal_amount'),
500
+ 'max': None,
501
+ },
502
+ },
503
+ 'networks': networkList,
504
+ }
505
+ return result
506
+
507
+ def parse_balance(self, response) -> Balances:
508
+ result: dict = {
509
+ 'info': response,
510
+ 'timestamp': None,
511
+ 'datetime': None,
512
+ }
513
+ data = self.safe_value(response, 'data', [])
514
+ for i in range(0, len(data)):
515
+ balance = data[i]
516
+ currencyId = self.safe_string(balance, 'currency_id')
517
+ code = self.safe_currency_code(currencyId)
518
+ account = self.account()
519
+ account['total'] = self.safe_string(balance, 'total')
520
+ account['free'] = self.safe_string(balance, 'available')
521
+ result[code] = account
522
+ return self.safe_balance(result)
523
+
524
+ def fetch_balance(self, params={}) -> Balances:
525
+ """
526
+ :see: https://docs-en.probit.com/reference/balance
527
+ query for balance and get the amount of funds available for trading or funds locked in orders
528
+ :param dict [params]: extra parameters specific to the exchange API endpoint
529
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
530
+ """
531
+ self.load_markets()
532
+ response = self.privateGetBalance(params)
533
+ #
534
+ # {
535
+ # "data": [
536
+ # {
537
+ # "currency_id":"XRP",
538
+ # "total":"100",
539
+ # "available":"0",
540
+ # }
541
+ # ]
542
+ # }
543
+ #
544
+ return self.parse_balance(response)
545
+
546
+ def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
547
+ """
548
+ :see: https://docs-en.probit.com/reference/order_book
549
+ fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
550
+ :param str symbol: unified symbol of the market to fetch the order book for
551
+ :param int [limit]: the maximum amount of order book entries to return
552
+ :param dict [params]: extra parameters specific to the exchange API endpoint
553
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
554
+ """
555
+ self.load_markets()
556
+ market = self.market(symbol)
557
+ request: dict = {
558
+ 'market_id': market['id'],
559
+ }
560
+ response = self.publicGetOrderBook(self.extend(request, params))
561
+ #
562
+ # {
563
+ # data: [
564
+ # {side: 'buy', price: '0.000031', quantity: '10'},
565
+ # {side: 'buy', price: '0.00356007', quantity: '4.92156877'},
566
+ # {side: 'sell', price: '0.1857', quantity: '0.17'},
567
+ # ]
568
+ # }
569
+ #
570
+ data = self.safe_value(response, 'data', [])
571
+ dataBySide = self.group_by(data, 'side')
572
+ return self.parse_order_book(dataBySide, market['symbol'], None, 'buy', 'sell', 'price', 'quantity')
573
+
574
+ def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
575
+ """
576
+ :see: https://docs-en.probit.com/reference/ticker
577
+ fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
578
+ :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
579
+ :param dict [params]: extra parameters specific to the exchange API endpoint
580
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
581
+ """
582
+ self.load_markets()
583
+ request: dict = {}
584
+ if symbols is not None:
585
+ marketIds = self.market_ids(symbols)
586
+ request['market_ids'] = ','.join(marketIds)
587
+ response = self.publicGetTicker(self.extend(request, params))
588
+ #
589
+ # {
590
+ # "data":[
591
+ # {
592
+ # "last":"0.022902",
593
+ # "low":"0.021693",
594
+ # "high":"0.024093",
595
+ # "change":"-0.000047",
596
+ # "base_volume":"15681.986",
597
+ # "quote_volume":"360.514403624",
598
+ # "market_id":"ETH-BTC",
599
+ # "time":"2020-04-12T18:43:38.000Z"
600
+ # }
601
+ # ]
602
+ # }
603
+ #
604
+ data = self.safe_list(response, 'data', [])
605
+ return self.parse_tickers(data, symbols)
606
+
607
+ def fetch_ticker(self, symbol: str, params={}) -> Ticker:
608
+ """
609
+ :see: https://docs-en.probit.com/reference/ticker
610
+ fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
611
+ :param str symbol: unified symbol of the market to fetch the ticker for
612
+ :param dict [params]: extra parameters specific to the exchange API endpoint
613
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
614
+ """
615
+ self.load_markets()
616
+ market = self.market(symbol)
617
+ request: dict = {
618
+ 'market_ids': market['id'],
619
+ }
620
+ response = self.publicGetTicker(self.extend(request, params))
621
+ #
622
+ # {
623
+ # "data":[
624
+ # {
625
+ # "last":"0.022902",
626
+ # "low":"0.021693",
627
+ # "high":"0.024093",
628
+ # "change":"-0.000047",
629
+ # "base_volume":"15681.986",
630
+ # "quote_volume":"360.514403624",
631
+ # "market_id":"ETH-BTC",
632
+ # "time":"2020-04-12T18:43:38.000Z"
633
+ # }
634
+ # ]
635
+ # }
636
+ #
637
+ data = self.safe_value(response, 'data', [])
638
+ ticker = self.safe_value(data, 0)
639
+ if ticker is None:
640
+ raise BadResponse(self.id + ' fetchTicker() returned an empty response')
641
+ return self.parse_ticker(ticker, market)
642
+
643
+ def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
644
+ #
645
+ # {
646
+ # "last":"0.022902",
647
+ # "low":"0.021693",
648
+ # "high":"0.024093",
649
+ # "change":"-0.000047",
650
+ # "base_volume":"15681.986",
651
+ # "quote_volume":"360.514403624",
652
+ # "market_id":"ETH-BTC",
653
+ # "time":"2020-04-12T18:43:38.000Z"
654
+ # }
655
+ #
656
+ timestamp = self.parse8601(self.safe_string(ticker, 'time'))
657
+ marketId = self.safe_string(ticker, 'market_id')
658
+ symbol = self.safe_symbol(marketId, market, '-')
659
+ close = self.safe_string(ticker, 'last')
660
+ change = self.safe_string(ticker, 'change')
661
+ baseVolume = self.safe_string(ticker, 'base_volume')
662
+ quoteVolume = self.safe_string(ticker, 'quote_volume')
663
+ return self.safe_ticker({
664
+ 'symbol': symbol,
665
+ 'timestamp': timestamp,
666
+ 'datetime': self.iso8601(timestamp),
667
+ 'high': self.safe_string(ticker, 'high'),
668
+ 'low': self.safe_string(ticker, 'low'),
669
+ 'bid': None,
670
+ 'bidVolume': None,
671
+ 'ask': None,
672
+ 'askVolume': None,
673
+ 'vwap': None,
674
+ 'open': None,
675
+ 'close': close,
676
+ 'last': close,
677
+ 'previousClose': None, # previous day close
678
+ 'change': change,
679
+ 'percentage': None,
680
+ 'average': None,
681
+ 'baseVolume': baseVolume,
682
+ 'quoteVolume': quoteVolume,
683
+ 'info': ticker,
684
+ }, market)
685
+
686
+ def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
687
+ """
688
+ :see: https://docs-en.probit.com/reference/trade
689
+ fetch all trades made by the user
690
+ :param str symbol: unified market symbol
691
+ :param int [since]: the earliest time in ms to fetch trades for
692
+ :param int [limit]: the maximum number of trades structures to retrieve
693
+ :param dict [params]: extra parameters specific to the exchange API endpoint
694
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
695
+ """
696
+ self.load_markets()
697
+ market: Market = None
698
+ now = self.milliseconds()
699
+ request: dict = {
700
+ 'limit': 100,
701
+ 'start_time': self.iso8601(now - 31536000000), # -365 days
702
+ 'end_time': self.iso8601(now),
703
+ }
704
+ if symbol is not None:
705
+ market = self.market(symbol)
706
+ request['market_id'] = market['id']
707
+ if since is not None:
708
+ request['start_time'] = self.iso8601(since)
709
+ request['end_time'] = self.iso8601(min(now, since + 31536000000))
710
+ if limit is not None:
711
+ request['limit'] = limit
712
+ response = self.privateGetTradeHistory(self.extend(request, params))
713
+ #
714
+ # {
715
+ # "data": [
716
+ # {
717
+ # "id":"BTC-USDT:183566",
718
+ # "order_id":"17209376",
719
+ # "side":"sell",
720
+ # "fee_amount":"0.657396569175",
721
+ # "fee_currency_id":"USDT",
722
+ # "status":"settled",
723
+ # "price":"6573.96569175",
724
+ # "quantity":"0.1",
725
+ # "cost":"657.396569175",
726
+ # "time":"2018-08-10T06:06:46.000Z",
727
+ # "market_id":"BTC-USDT"
728
+ # }
729
+ # ]
730
+ # }
731
+ #
732
+ data = self.safe_list(response, 'data', [])
733
+ return self.parse_trades(data, market, since, limit)
734
+
735
+ def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
736
+ """
737
+ :see: https://docs-en.probit.com/reference/trade-1
738
+ get the list of most recent trades for a particular symbol
739
+ :param str symbol: unified symbol of the market to fetch trades for
740
+ :param int [since]: timestamp in ms of the earliest trade to fetch
741
+ :param int [limit]: the maximum amount of trades to fetch
742
+ :param dict [params]: extra parameters specific to the exchange API endpoint
743
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
744
+ """
745
+ self.load_markets()
746
+ market = self.market(symbol)
747
+ request: dict = {
748
+ 'market_id': market['id'],
749
+ 'start_time': '1970-01-01T00:00:00.000Z',
750
+ 'end_time': self.iso8601(self.milliseconds()),
751
+ }
752
+ if since is not None:
753
+ request['start_time'] = self.iso8601(since)
754
+ if limit is not None:
755
+ request['limit'] = min(limit, 1000)
756
+ else:
757
+ request['limit'] = 1000 # required to set any value
758
+ response = self.publicGetTrade(self.extend(request, params))
759
+ #
760
+ # {
761
+ # "data":[
762
+ # {
763
+ # "id":"ETH-BTC:3331886",
764
+ # "price":"0.022981",
765
+ # "quantity":"12.337",
766
+ # "time":"2020-04-12T20:55:42.371Z",
767
+ # "side":"sell",
768
+ # "tick_direction":"down"
769
+ # },
770
+ # {
771
+ # "id":"ETH-BTC:3331885",
772
+ # "price":"0.022982",
773
+ # "quantity":"6.472",
774
+ # "time":"2020-04-12T20:55:39.652Z",
775
+ # "side":"sell",
776
+ # "tick_direction":"down"
777
+ # }
778
+ # ]
779
+ # }
780
+ #
781
+ data = self.safe_list(response, 'data', [])
782
+ return self.parse_trades(data, market, since, limit)
783
+
784
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
785
+ #
786
+ # fetchTrades(public)
787
+ #
788
+ # {
789
+ # "id":"ETH-BTC:3331886",
790
+ # "price":"0.022981",
791
+ # "quantity":"12.337",
792
+ # "time":"2020-04-12T20:55:42.371Z",
793
+ # "side":"sell",
794
+ # "tick_direction":"down"
795
+ # }
796
+ #
797
+ # fetchMyTrades(private)
798
+ #
799
+ # {
800
+ # "id":"BTC-USDT:183566",
801
+ # "order_id":"17209376",
802
+ # "side":"sell",
803
+ # "fee_amount":"0.657396569175",
804
+ # "fee_currency_id":"USDT",
805
+ # "status":"settled",
806
+ # "price":"6573.96569175",
807
+ # "quantity":"0.1",
808
+ # "cost":"657.396569175",
809
+ # "time":"2018-08-10T06:06:46.000Z",
810
+ # "market_id":"BTC-USDT"
811
+ # }
812
+ #
813
+ timestamp = self.parse8601(self.safe_string(trade, 'time'))
814
+ id = self.safe_string(trade, 'id')
815
+ marketId: Str = None
816
+ if id is not None:
817
+ parts = id.split(':')
818
+ marketId = self.safe_string(parts, 0)
819
+ marketId = self.safe_string(trade, 'market_id', marketId)
820
+ symbol = self.safe_symbol(marketId, market, '-')
821
+ side = self.safe_string(trade, 'side')
822
+ priceString = self.safe_string(trade, 'price')
823
+ amountString = self.safe_string(trade, 'quantity')
824
+ orderId = self.safe_string(trade, 'order_id')
825
+ feeCostString = self.safe_string(trade, 'fee_amount')
826
+ fee = None
827
+ if feeCostString is not None:
828
+ feeCurrencyId = self.safe_string(trade, 'fee_currency_id')
829
+ feeCurrencyCode = self.safe_currency_code(feeCurrencyId)
830
+ fee = {
831
+ 'cost': feeCostString,
832
+ 'currency': feeCurrencyCode,
833
+ }
834
+ return self.safe_trade({
835
+ 'id': id,
836
+ 'info': trade,
837
+ 'timestamp': timestamp,
838
+ 'datetime': self.iso8601(timestamp),
839
+ 'symbol': symbol,
840
+ 'order': orderId,
841
+ 'type': None,
842
+ 'side': side,
843
+ 'takerOrMaker': None,
844
+ 'price': priceString,
845
+ 'amount': amountString,
846
+ 'cost': None,
847
+ 'fee': fee,
848
+ }, market)
849
+
850
+ def fetch_time(self, params={}):
851
+ """
852
+ :see: https://docs-en.probit.com/reference/time
853
+ fetches the current integer timestamp in milliseconds from the exchange server
854
+ :param dict [params]: extra parameters specific to the exchange API endpoint
855
+ :returns int: the current integer timestamp in milliseconds from the exchange server
856
+ """
857
+ response = self.publicGetTime(params)
858
+ #
859
+ # {"data":"2020-04-12T18:54:25.390Z"}
860
+ #
861
+ timestamp = self.parse8601(self.safe_string(response, 'data'))
862
+ return timestamp
863
+
864
+ def normalize_ohlcv_timestamp(self, timestamp, timeframe, after=False):
865
+ duration = self.parse_timeframe(timeframe)
866
+ if timeframe == '1M':
867
+ iso8601 = self.iso8601(timestamp)
868
+ parts = iso8601.split('-')
869
+ year = self.safe_string(parts, 0)
870
+ month = self.safe_integer(parts, 1)
871
+ monthString: Str = None
872
+ if after:
873
+ monthString = self.sum(month, str(1))
874
+ if month < 10:
875
+ monthString = '0' + str(month)
876
+ return year + '-' + monthString + '-01T00:00:00.000Z'
877
+ elif timeframe == '1w':
878
+ timestamp = self.parse_to_int(timestamp / 1000)
879
+ firstSunday = 259200 # 1970-01-04T00:00:00.000Z
880
+ difference = timestamp - firstSunday
881
+ numWeeks = int(math.floor(difference / duration))
882
+ previousSunday = self.sum(firstSunday, numWeeks * duration)
883
+ if after:
884
+ previousSunday = self.sum(previousSunday, duration)
885
+ return self.iso8601(previousSunday * 1000)
886
+ else:
887
+ timestamp = self.parse_to_int(timestamp / 1000)
888
+ timestamp = duration * self.parse_to_int(timestamp / duration)
889
+ if after:
890
+ timestamp = self.sum(timestamp, duration)
891
+ return self.iso8601(timestamp * 1000)
892
+
893
+ def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
894
+ """
895
+ :see: https://docs-en.probit.com/reference/candle
896
+ fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
897
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
898
+ :param str timeframe: the length of time each candle represents
899
+ :param int [since]: timestamp in ms of the earliest candle to fetch
900
+ :param int [limit]: the maximum amount of candles to fetch
901
+ :param dict [params]: extra parameters specific to the exchange API endpoint
902
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
903
+ """
904
+ self.load_markets()
905
+ market = self.market(symbol)
906
+ interval = self.safe_string(self.timeframes, timeframe, timeframe)
907
+ limit = 100 if (limit is None) else limit
908
+ requestLimit = self.sum(limit, 1)
909
+ requestLimit = min(1000, requestLimit) # max 1000
910
+ request: dict = {
911
+ 'market_ids': market['id'],
912
+ 'interval': interval,
913
+ 'sort': 'asc', # 'asc' will always include the start_time, 'desc' will always include end_time
914
+ 'limit': requestLimit, # max 1000
915
+ }
916
+ now = self.milliseconds()
917
+ duration = self.parse_timeframe(timeframe)
918
+ startTime = since
919
+ endTime = now
920
+ if since is None:
921
+ if limit is None:
922
+ limit = requestLimit
923
+ startTime = now - limit * duration * 1000
924
+ else:
925
+ if limit is None:
926
+ endTime = now
927
+ else:
928
+ endTime = self.sum(since, self.sum(limit, 1) * duration * 1000)
929
+ startTimeNormalized = self.normalize_ohlcv_timestamp(startTime, timeframe)
930
+ endTimeNormalized = self.normalize_ohlcv_timestamp(endTime, timeframe, True)
931
+ request['start_time'] = startTimeNormalized
932
+ request['end_time'] = endTimeNormalized
933
+ response = self.publicGetCandle(self.extend(request, params))
934
+ #
935
+ # {
936
+ # "data":[
937
+ # {
938
+ # "market_id":"ETH-BTC",
939
+ # "open":"0.02811",
940
+ # "close":"0.02811",
941
+ # "low":"0.02811",
942
+ # "high":"0.02811",
943
+ # "base_volume":"0.0005",
944
+ # "quote_volume":"0.000014055",
945
+ # "start_time":"2018-11-30T18:19:00.000Z",
946
+ # "end_time":"2018-11-30T18:20:00.000Z"
947
+ # },
948
+ # ]
949
+ # }
950
+ #
951
+ data = self.safe_list(response, 'data', [])
952
+ return self.parse_ohlcvs(data, market, timeframe, since, limit)
953
+
954
+ def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
955
+ #
956
+ # {
957
+ # "market_id":"ETH-BTC",
958
+ # "open":"0.02811",
959
+ # "close":"0.02811",
960
+ # "low":"0.02811",
961
+ # "high":"0.02811",
962
+ # "base_volume":"0.0005",
963
+ # "quote_volume":"0.000014055",
964
+ # "start_time":"2018-11-30T18:19:00.000Z",
965
+ # "end_time":"2018-11-30T18:20:00.000Z"
966
+ # }
967
+ #
968
+ return [
969
+ self.parse8601(self.safe_string(ohlcv, 'start_time')),
970
+ self.safe_number(ohlcv, 'open'),
971
+ self.safe_number(ohlcv, 'high'),
972
+ self.safe_number(ohlcv, 'low'),
973
+ self.safe_number(ohlcv, 'close'),
974
+ self.safe_number(ohlcv, 'base_volume'),
975
+ ]
976
+
977
+ def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
978
+ """
979
+ :see: https://docs-en.probit.com/reference/open_order-1
980
+ fetch all unfilled currently open orders
981
+ :param str symbol: unified market symbol
982
+ :param int [since]: the earliest time in ms to fetch open orders for
983
+ :param int [limit]: the maximum number of open orders structures to retrieve
984
+ :param dict [params]: extra parameters specific to the exchange API endpoint
985
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
986
+ """
987
+ self.load_markets()
988
+ since = self.parse8601(since)
989
+ request: dict = {}
990
+ market: Market = None
991
+ if symbol is not None:
992
+ market = self.market(symbol)
993
+ request['market_id'] = market['id']
994
+ response = self.privateGetOpenOrder(self.extend(request, params))
995
+ data = self.safe_list(response, 'data')
996
+ return self.parse_orders(data, market, since, limit)
997
+
998
+ def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
999
+ """
1000
+ :see: https://docs-en.probit.com/reference/order
1001
+ fetches information on multiple closed orders made by the user
1002
+ :param str symbol: unified market symbol of the market orders were made in
1003
+ :param int [since]: the earliest time in ms to fetch orders for
1004
+ :param int [limit]: the maximum number of order structures to retrieve
1005
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1006
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1007
+ """
1008
+ self.load_markets()
1009
+ request: dict = {
1010
+ 'start_time': self.iso8601(0),
1011
+ 'end_time': self.iso8601(self.milliseconds()),
1012
+ 'limit': 100,
1013
+ }
1014
+ market: Market = None
1015
+ if symbol is not None:
1016
+ market = self.market(symbol)
1017
+ request['market_id'] = market['id']
1018
+ if since:
1019
+ request['start_time'] = self.iso8601(since)
1020
+ if limit:
1021
+ request['limit'] = limit
1022
+ response = self.privateGetOrderHistory(self.extend(request, params))
1023
+ data = self.safe_list(response, 'data')
1024
+ return self.parse_orders(data, market, since, limit)
1025
+
1026
+ def fetch_order(self, id: str, symbol: Str = None, params={}):
1027
+ """
1028
+ :see: https://docs-en.probit.com/reference/order-3
1029
+ fetches information on an order made by the user
1030
+ :param str symbol: unified symbol of the market the order was made in
1031
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1032
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1033
+ """
1034
+ if symbol is None:
1035
+ raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol argument')
1036
+ self.load_markets()
1037
+ market = self.market(symbol)
1038
+ request: dict = {
1039
+ 'market_id': market['id'],
1040
+ }
1041
+ clientOrderId = self.safe_string_2(params, 'clientOrderId', 'client_order_id')
1042
+ if clientOrderId is not None:
1043
+ request['client_order_id'] = clientOrderId
1044
+ else:
1045
+ request['order_id'] = id
1046
+ query = self.omit(params, ['clientOrderId', 'client_order_id'])
1047
+ response = self.privateGetOrder(self.extend(request, query))
1048
+ data = self.safe_value(response, 'data', [])
1049
+ order = self.safe_dict(data, 0)
1050
+ return self.parse_order(order, market)
1051
+
1052
+ def parse_order_status(self, status: Str):
1053
+ statuses: dict = {
1054
+ 'open': 'open',
1055
+ 'cancelled': 'canceled',
1056
+ 'filled': 'closed',
1057
+ }
1058
+ return self.safe_string(statuses, status, status)
1059
+
1060
+ def parse_order(self, order: dict, market: Market = None) -> Order:
1061
+ #
1062
+ # {
1063
+ # id,
1064
+ # user_id,
1065
+ # market_id,
1066
+ # "type": "orderType",
1067
+ # "side": "side",
1068
+ # quantity,
1069
+ # limit_price,
1070
+ # "time_in_force": "timeInForce",
1071
+ # filled_cost,
1072
+ # filled_quantity,
1073
+ # open_quantity,
1074
+ # cancelled_quantity,
1075
+ # "status": "orderStatus",
1076
+ # "time": "date",
1077
+ # client_order_id,
1078
+ # }
1079
+ #
1080
+ status = self.parse_order_status(self.safe_string(order, 'status'))
1081
+ id = self.safe_string(order, 'id')
1082
+ type = self.safe_string(order, 'type')
1083
+ side = self.safe_string(order, 'side')
1084
+ marketId = self.safe_string(order, 'market_id')
1085
+ symbol = self.safe_symbol(marketId, market, '-')
1086
+ timestamp = self.parse8601(self.safe_string(order, 'time'))
1087
+ price = self.safe_string(order, 'limit_price')
1088
+ filled = self.safe_string(order, 'filled_quantity')
1089
+ remaining = self.safe_string(order, 'open_quantity')
1090
+ canceledAmount = self.safe_string(order, 'cancelled_quantity')
1091
+ if canceledAmount is not None:
1092
+ remaining = Precise.string_add(remaining, canceledAmount)
1093
+ amount = self.safe_string(order, 'quantity', Precise.string_add(filled, remaining))
1094
+ cost = self.safe_string_2(order, 'filled_cost', 'cost')
1095
+ if type == 'market':
1096
+ price = None
1097
+ clientOrderId = self.safe_string(order, 'client_order_id')
1098
+ timeInForce = self.safe_string_upper(order, 'time_in_force')
1099
+ return self.safe_order({
1100
+ 'id': id,
1101
+ 'info': order,
1102
+ 'clientOrderId': clientOrderId,
1103
+ 'timestamp': timestamp,
1104
+ 'datetime': self.iso8601(timestamp),
1105
+ 'lastTradeTimestamp': None,
1106
+ 'symbol': symbol,
1107
+ 'type': type,
1108
+ 'timeInForce': timeInForce,
1109
+ 'side': side,
1110
+ 'status': status,
1111
+ 'price': price,
1112
+ 'stopPrice': None,
1113
+ 'triggerPrice': None,
1114
+ 'amount': amount,
1115
+ 'filled': filled,
1116
+ 'remaining': remaining,
1117
+ 'average': None,
1118
+ 'cost': cost,
1119
+ 'fee': None,
1120
+ 'trades': None,
1121
+ }, market)
1122
+
1123
+ def cost_to_precision(self, symbol, cost):
1124
+ return self.decimal_to_precision(cost, TRUNCATE, self.markets[symbol]['precision']['cost'], self.precisionMode)
1125
+
1126
+ def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1127
+ """
1128
+ create a trade order
1129
+ :see: https://docs-en.probit.com/reference/order-1
1130
+ :param str symbol: unified symbol of the market to create an order in
1131
+ :param str type: 'market' or 'limit'
1132
+ :param str side: 'buy' or 'sell'
1133
+ :param float amount: how much you want to trade in units of the base currency
1134
+ :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1135
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1136
+ :param float [params.cost]: the quote quantity that can be used alternative for the amount for market buy orders
1137
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1138
+ """
1139
+ self.load_markets()
1140
+ market = self.market(symbol)
1141
+ options = self.safe_value(self.options, 'timeInForce')
1142
+ defaultTimeInForce = self.safe_value(options, type)
1143
+ timeInForce = self.safe_string_2(params, 'timeInForce', 'time_in_force', defaultTimeInForce)
1144
+ request: dict = {
1145
+ 'market_id': market['id'],
1146
+ 'type': type,
1147
+ 'side': side,
1148
+ 'time_in_force': timeInForce,
1149
+ }
1150
+ clientOrderId = self.safe_string_2(params, 'clientOrderId', 'client_order_id')
1151
+ if clientOrderId is not None:
1152
+ request['client_order_id'] = clientOrderId
1153
+ quoteAmount = None
1154
+ if type == 'limit':
1155
+ request['limit_price'] = self.price_to_precision(symbol, price)
1156
+ request['quantity'] = self.amount_to_precision(symbol, amount)
1157
+ elif type == 'market':
1158
+ # for market buy it requires the amount of quote currency to spend
1159
+ if side == 'buy':
1160
+ createMarketBuyOrderRequiresPrice = True
1161
+ createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
1162
+ cost = self.safe_string(params, 'cost')
1163
+ params = self.omit(params, 'cost')
1164
+ if cost is not None:
1165
+ quoteAmount = self.cost_to_precision(symbol, cost)
1166
+ elif createMarketBuyOrderRequiresPrice:
1167
+ if price is None:
1168
+ 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 in the amount argument')
1169
+ else:
1170
+ amountString = self.number_to_string(amount)
1171
+ priceString = self.number_to_string(price)
1172
+ costRequest = Precise.string_mul(amountString, priceString)
1173
+ quoteAmount = self.cost_to_precision(symbol, costRequest)
1174
+ else:
1175
+ quoteAmount = self.cost_to_precision(symbol, amount)
1176
+ request['cost'] = quoteAmount
1177
+ else:
1178
+ request['quantity'] = self.amount_to_precision(symbol, amount)
1179
+ query = self.omit(params, ['timeInForce', 'time_in_force', 'clientOrderId', 'client_order_id'])
1180
+ response = self.privatePostNewOrder(self.extend(request, query))
1181
+ #
1182
+ # {
1183
+ # "data": {
1184
+ # id,
1185
+ # user_id,
1186
+ # market_id,
1187
+ # "type": "orderType",
1188
+ # "side": "side",
1189
+ # quantity,
1190
+ # limit_price,
1191
+ # "time_in_force": "timeInForce",
1192
+ # filled_cost,
1193
+ # filled_quantity,
1194
+ # open_quantity,
1195
+ # cancelled_quantity,
1196
+ # "status": "orderStatus",
1197
+ # "time": "date",
1198
+ # client_order_id,
1199
+ # }
1200
+ # }
1201
+ #
1202
+ data = self.safe_value(response, 'data')
1203
+ order = self.parse_order(data, market)
1204
+ # a workaround for incorrect huge amounts
1205
+ # returned by the exchange on market buys
1206
+ if (type == 'market') and (side == 'buy'):
1207
+ order['amount'] = None
1208
+ order['cost'] = self.parse_number(quoteAmount)
1209
+ order['remaining'] = None
1210
+ return order
1211
+
1212
+ def cancel_order(self, id: str, symbol: Str = None, params={}):
1213
+ """
1214
+ :see: https://docs-en.probit.com/reference/order-2
1215
+ cancels an open order
1216
+ :param str id: order id
1217
+ :param str symbol: unified symbol of the market the order was made in
1218
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1219
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1220
+ """
1221
+ if symbol is None:
1222
+ raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument')
1223
+ self.load_markets()
1224
+ market = self.market(symbol)
1225
+ request: dict = {
1226
+ 'market_id': market['id'],
1227
+ 'order_id': id,
1228
+ }
1229
+ response = self.privatePostCancelOrder(self.extend(request, params))
1230
+ data = self.safe_dict(response, 'data')
1231
+ return self.parse_order(data)
1232
+
1233
+ def parse_deposit_address(self, depositAddress, currency: Currency = None):
1234
+ address = self.safe_string(depositAddress, 'address')
1235
+ tag = self.safe_string(depositAddress, 'destination_tag')
1236
+ currencyId = self.safe_string(depositAddress, 'currency_id')
1237
+ currency = self.safe_currency(currencyId, currency)
1238
+ code = currency['code']
1239
+ network = self.safe_string(depositAddress, 'platform_id')
1240
+ self.check_address(address)
1241
+ return {
1242
+ 'currency': code,
1243
+ 'address': address,
1244
+ 'tag': tag,
1245
+ 'network': network,
1246
+ 'info': depositAddress,
1247
+ }
1248
+
1249
+ def fetch_deposit_address(self, code: str, params={}):
1250
+ """
1251
+ :see: https://docs-en.probit.com/reference/deposit_address
1252
+ fetch the deposit address for a currency associated with self account
1253
+ :param str code: unified currency code
1254
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1255
+ :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
1256
+ """
1257
+ self.load_markets()
1258
+ currency = self.currency(code)
1259
+ request: dict = {
1260
+ 'currency_id': currency['id'],
1261
+ # 'platform_id': 'TRON',(undocumented)
1262
+ }
1263
+ networks = self.safe_value(self.options, 'networks', {})
1264
+ network = self.safe_string_upper(params, 'network') # self line allows the user to specify either ERC20 or ETH
1265
+ network = self.safe_string(networks, network, network) # handle ERC20>ETH alias
1266
+ if network is not None:
1267
+ request['platform_id'] = network
1268
+ params = self.omit(params, 'platform_id')
1269
+ response = self.privateGetDepositAddress(self.extend(request, params))
1270
+ #
1271
+ # without 'platform_id'
1272
+ # {
1273
+ # "data":[
1274
+ # {
1275
+ # "currency_id":"ETH",
1276
+ # "address":"0x12e2caf3c4051ba1146e612f532901a423a9898a",
1277
+ # "destination_tag":null
1278
+ # }
1279
+ # ]
1280
+ # }
1281
+ #
1282
+ # with 'platform_id'
1283
+ # {
1284
+ # "data":[
1285
+ # {
1286
+ # "platform_id":"TRON",
1287
+ # "address":"TDQLMxBTa6MzuoZ6deSGZkqET3Ek8v7uC6",
1288
+ # "destination_tag":null
1289
+ # }
1290
+ # ]
1291
+ # }
1292
+ #
1293
+ data = self.safe_value(response, 'data', [])
1294
+ firstAddress = self.safe_value(data, 0)
1295
+ if firstAddress is None:
1296
+ raise InvalidAddress(self.id + ' fetchDepositAddress() returned an empty response')
1297
+ return self.parse_deposit_address(firstAddress, currency)
1298
+
1299
+ def fetch_deposit_addresses(self, codes: Strings = None, params={}):
1300
+ """
1301
+ :see: https://docs-en.probit.com/reference/deposit_address
1302
+ fetch deposit addresses for multiple currencies and chain types
1303
+ :param str[]|None codes: list of unified currency codes, default is None
1304
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1305
+ :returns dict: a list of `address structures <https://docs.ccxt.com/#/?id=address-structure>`
1306
+ """
1307
+ self.load_markets()
1308
+ request: dict = {}
1309
+ if codes:
1310
+ currencyIds = []
1311
+ for i in range(0, len(codes)):
1312
+ currency = self.currency(codes[i])
1313
+ currencyIds.append(currency['id'])
1314
+ request['currency_id'] = ','.join(codes)
1315
+ response = self.privateGetDepositAddress(self.extend(request, params))
1316
+ data = self.safe_list(response, 'data', [])
1317
+ return self.parse_deposit_addresses(data, codes)
1318
+
1319
+ def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
1320
+ """
1321
+ :see: https://docs-en.probit.com/reference/withdrawal
1322
+ make a withdrawal
1323
+ :param str code: unified currency code
1324
+ :param float amount: the amount to withdraw
1325
+ :param str address: the address to withdraw to
1326
+ :param str tag:
1327
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1328
+ :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1329
+ """
1330
+ tag, params = self.handle_withdraw_tag_and_params(tag, params)
1331
+ # In order to use self method
1332
+ # you need to allow API withdrawal from the API Settings Page, and
1333
+ # and register the list of withdrawal addresses and destination tags on the API Settings page
1334
+ # you can only withdraw to the registered addresses using the API
1335
+ self.check_address(address)
1336
+ self.load_markets()
1337
+ currency = self.currency(code)
1338
+ if tag is None:
1339
+ tag = ''
1340
+ request: dict = {
1341
+ 'currency_id': currency['id'],
1342
+ # 'platform_id': 'ETH', # if omitted it will use the default platform for the currency
1343
+ 'address': address,
1344
+ 'destination_tag': tag,
1345
+ 'amount': self.number_to_string(amount),
1346
+ # which currency to pay the withdrawal fees
1347
+ # only applicable for currencies that accepts multiple withdrawal fee options
1348
+ # 'fee_currency_id': 'ETH', # if omitted it will use the default fee policy for each currency
1349
+ # whether the amount field includes fees
1350
+ # 'include_fee': False, # makes sense only when fee_currency_id is equal to currency_id
1351
+ }
1352
+ networks = self.safe_value(self.options, 'networks', {})
1353
+ network = self.safe_string_upper(params, 'network') # self line allows the user to specify either ERC20 or ETH
1354
+ network = self.safe_string(networks, network, network) # handle ERC20>ETH alias
1355
+ if network is not None:
1356
+ request['platform_id'] = network
1357
+ params = self.omit(params, 'network')
1358
+ response = self.privatePostWithdrawal(self.extend(request, params))
1359
+ data = self.safe_dict(response, 'data')
1360
+ return self.parse_transaction(data, currency)
1361
+
1362
+ def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1363
+ """
1364
+ fetch all deposits made to an account
1365
+ :param str code: unified currency code
1366
+ :param int [since]: the earliest time in ms to fetch deposits for
1367
+ :param int [limit]: the maximum number of transaction structures to retrieve
1368
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1369
+ :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
1370
+ """
1371
+ request: dict = {
1372
+ 'type': 'deposit',
1373
+ }
1374
+ result = self.fetch_transactions(code, since, limit, self.extend(request, params))
1375
+ return result
1376
+
1377
+ def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1378
+ """
1379
+ fetch all withdrawals made to an account
1380
+ :param str code: unified currency code
1381
+ :param int [since]: the earliest time in ms to fetch withdrawals for
1382
+ :param int [limit]: the maximum number of transaction structures to retrieve
1383
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1384
+ :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
1385
+ """
1386
+ request: dict = {
1387
+ 'type': 'withdrawal',
1388
+ }
1389
+ result = self.fetch_transactions(code, since, limit, self.extend(request, params))
1390
+ return result
1391
+
1392
+ def fetch_deposits_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
1393
+ """
1394
+ fetch history of deposits and withdrawals
1395
+ :see: https://docs-en.probit.com/reference/transferpayment
1396
+ :param str code: unified currency code
1397
+ :param int [since]: the earliest time in ms to fetch transactions for
1398
+ :param int [limit]: the maximum number of transaction structures to retrieve
1399
+ :param int [params.until]: the latest time in ms to fetch transactions for
1400
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1401
+ :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
1402
+ """
1403
+ self.load_markets()
1404
+ currency: Currency = None
1405
+ request: dict = {}
1406
+ if code is not None:
1407
+ currency = self.currency(code)
1408
+ request['currency_id'] = currency['id']
1409
+ if since is not None:
1410
+ request['start_time'] = self.iso8601(since)
1411
+ else:
1412
+ request['start_time'] = self.iso8601(1)
1413
+ until = self.safe_integer(params, 'until')
1414
+ if until is not None:
1415
+ request['end_time'] = self.iso8601(until)
1416
+ params = self.omit(params, ['until'])
1417
+ else:
1418
+ request['end_time'] = self.iso8601(self.milliseconds())
1419
+ if limit is not None:
1420
+ request['limit'] = limit
1421
+ else:
1422
+ request['limit'] = 100
1423
+ response = self.privateGetTransferPayment(self.extend(request, params))
1424
+ #
1425
+ # {
1426
+ # "data": [
1427
+ # {
1428
+ # "id": "01211d4b-0e68-41d6-97cb-298bfe2cab67",
1429
+ # "type": "deposit",
1430
+ # "status": "done",
1431
+ # "amount": "0.01",
1432
+ # "address": "0x9e7430fc0bdd14745bd00a1b92ed25133a7c765f",
1433
+ # "time": "2023-06-14T12:03:11.000Z",
1434
+ # "hash": "0x0ff5bedc9e378f9529acc6b9840fa8c2ef00fd0275e0bac7fa0589a9b5d1712e",
1435
+ # "currency_id": "ETH",
1436
+ # "confirmations":0,
1437
+ # "fee": "0",
1438
+ # "destination_tag": null,
1439
+ # "platform_id": "ETH",
1440
+ # "fee_currency_id": "ETH",
1441
+ # "payment_service_name":null,
1442
+ # "payment_service_display_name":null,
1443
+ # "crypto":null
1444
+ # }
1445
+ # ]
1446
+ # }
1447
+ #
1448
+ data = self.safe_list(response, 'data', [])
1449
+ return self.parse_transactions(data, currency, since, limit)
1450
+
1451
+ def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
1452
+ #
1453
+ # {
1454
+ # "id": "01211d4b-0e68-41d6-97cb-298bfe2cab67",
1455
+ # "type": "deposit",
1456
+ # "status": "done",
1457
+ # "amount": "0.01",
1458
+ # "address": "0x9e7430fc0bdd14745bd00a1b92ed25133a7c765f",
1459
+ # "time": "2023-06-14T12:03:11.000Z",
1460
+ # "hash": "0x0ff5bedc9e378f9529acc6b9840fa8c2ef00fd0275e0bac7fa0589a9b5d1712e",
1461
+ # "currency_id": "ETH",
1462
+ # "confirmations":0,
1463
+ # "fee": "0",
1464
+ # "destination_tag": null,
1465
+ # "platform_id": "ETH",
1466
+ # "fee_currency_id": "ETH",
1467
+ # "payment_service_name":null,
1468
+ # "payment_service_display_name":null,
1469
+ # "crypto":null
1470
+ # }
1471
+ #
1472
+ id = self.safe_string(transaction, 'id')
1473
+ networkId = self.safe_string(transaction, 'platform_id')
1474
+ networkCode = self.network_id_to_code(networkId)
1475
+ amount = self.safe_number(transaction, 'amount')
1476
+ address = self.safe_string(transaction, 'address')
1477
+ tag = self.safe_string(transaction, 'destination_tag')
1478
+ txid = self.safe_string(transaction, 'hash')
1479
+ timestamp = self.parse8601(self.safe_string(transaction, 'time'))
1480
+ type = self.safe_string(transaction, 'type')
1481
+ currencyId = self.safe_string(transaction, 'currency_id')
1482
+ code = self.safe_currency_code(currencyId)
1483
+ status = self.parse_transaction_status(self.safe_string(transaction, 'status'))
1484
+ feeCostString = self.safe_string(transaction, 'fee')
1485
+ fee = None
1486
+ if feeCostString is not None and feeCostString != '0':
1487
+ fee = {
1488
+ 'currency': code,
1489
+ 'cost': self.parse_number(feeCostString),
1490
+ }
1491
+ return {
1492
+ 'id': id,
1493
+ 'currency': code,
1494
+ 'amount': amount,
1495
+ 'network': networkCode,
1496
+ 'addressFrom': None,
1497
+ 'address': address,
1498
+ 'addressTo': address,
1499
+ 'tagFrom': None,
1500
+ 'tag': tag,
1501
+ 'tagTo': tag,
1502
+ 'status': status,
1503
+ 'type': type,
1504
+ 'txid': txid,
1505
+ 'timestamp': timestamp,
1506
+ 'datetime': self.iso8601(timestamp),
1507
+ 'updated': None,
1508
+ 'internal': None,
1509
+ 'comment': None,
1510
+ 'fee': fee,
1511
+ 'info': transaction,
1512
+ }
1513
+
1514
+ def parse_transaction_status(self, status: Str):
1515
+ statuses: dict = {
1516
+ 'requested': 'pending',
1517
+ 'pending': 'pending',
1518
+ 'confirming': 'pending',
1519
+ 'confirmed': 'pending',
1520
+ 'applying': 'pending',
1521
+ 'done': 'ok',
1522
+ 'cancelled': 'canceled',
1523
+ 'cancelling': 'canceled',
1524
+ }
1525
+ return self.safe_string(statuses, status, status)
1526
+
1527
+ def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
1528
+ """
1529
+ :see: https://docs-en.probit.com/reference/currency
1530
+ fetch deposit and withdraw fees
1531
+ :param str[]|None codes: list of unified currency codes
1532
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1533
+ :returns dict[]: a list of `fees structures <https://docs.ccxt.com/#/?id=fee-structure>`
1534
+ """
1535
+ self.load_markets()
1536
+ response = self.publicGetCurrencyWithPlatform(params)
1537
+ #
1538
+ # {
1539
+ # "data": [
1540
+ # {
1541
+ # "id": "AFX",
1542
+ # "display_name": {
1543
+ # "ko-kr": "아프릭스",
1544
+ # "en-us": "Afrix"
1545
+ # },
1546
+ # "show_in_ui": True,
1547
+ # "platform": [
1548
+ # {
1549
+ # "id": "ZYN",
1550
+ # "priority": 1,
1551
+ # "deposit": True,
1552
+ # "withdrawal": True,
1553
+ # "currency_id": "AFX",
1554
+ # "precision": 18,
1555
+ # "min_confirmation_count": 60,
1556
+ # "require_destination_tag": False,
1557
+ # "allow_withdrawal_destination_tag": False,
1558
+ # "display_name": {
1559
+ # "name": {
1560
+ # "ko-kr": "지네코인",
1561
+ # "en-us": "Wethio"
1562
+ # }
1563
+ # },
1564
+ # "min_deposit_amount": "0",
1565
+ # "min_withdrawal_amount": "0",
1566
+ # "withdrawal_fee": [
1567
+ # {
1568
+ # "currency_id": "ZYN",
1569
+ # "amount": "0.5",
1570
+ # "priority": 1
1571
+ # }
1572
+ # ],
1573
+ # "deposit_fee": {},
1574
+ # "suspended_reason": "",
1575
+ # "deposit_suspended": False,
1576
+ # "withdrawal_suspended": False,
1577
+ # "platform_currency_display_name": {}
1578
+ # }
1579
+ # ],
1580
+ # "internal_transfer": {
1581
+ # "suspended_reason": null,
1582
+ # "suspended": False
1583
+ # },
1584
+ # "stakeable": False,
1585
+ # "unstakeable": False,
1586
+ # "auto_stake": False,
1587
+ # "auto_stake_amount": "0"
1588
+ # },
1589
+ # ]
1590
+ # }
1591
+ #
1592
+ data = self.safe_list(response, 'data')
1593
+ return self.parse_deposit_withdraw_fees(data, codes, 'id')
1594
+
1595
+ def parse_deposit_withdraw_fee(self, fee, currency: Currency = None):
1596
+ #
1597
+ # {
1598
+ # "id": "USDT",
1599
+ # "display_name": {"ko-kr": '테더', "en-us": "Tether"},
1600
+ # "show_in_ui": True,
1601
+ # "platform": [
1602
+ # {
1603
+ # "id": "ETH",
1604
+ # "priority": "1",
1605
+ # "deposit": True,
1606
+ # "withdrawal": True,
1607
+ # "currency_id": "USDT",
1608
+ # "precision": "6",
1609
+ # "min_confirmation_count": "15",
1610
+ # "require_destination_tag": False,
1611
+ # "allow_withdrawal_destination_tag": False,
1612
+ # "display_name": [Object],
1613
+ # "min_deposit_amount": "0",
1614
+ # "min_withdrawal_amount": "1",
1615
+ # "withdrawal_fee": [Array],
1616
+ # "deposit_fee": {},
1617
+ # "suspended_reason": '',
1618
+ # "deposit_suspended": False,
1619
+ # "withdrawal_suspended": False,
1620
+ # "platform_currency_display_name": [Object]
1621
+ # },
1622
+ # ],
1623
+ # "internal_transfer": {suspended_reason: null, suspended: False},
1624
+ # "stakeable": False,
1625
+ # "unstakeable": False,
1626
+ # "auto_stake": False,
1627
+ # "auto_stake_amount": "0"
1628
+ # }
1629
+ #
1630
+ depositWithdrawFee = self.deposit_withdraw_fee({})
1631
+ platforms = self.safe_value(fee, 'platform', [])
1632
+ depositResult: dict = {
1633
+ 'fee': None,
1634
+ 'percentage': None,
1635
+ }
1636
+ for i in range(0, len(platforms)):
1637
+ network = platforms[i]
1638
+ networkId = self.safe_string(network, 'id')
1639
+ networkCode = self.network_id_to_code(networkId, currency['code'])
1640
+ withdrawalFees = self.safe_value(network, 'withdrawal_fee', {})
1641
+ withdrawFee = self.safe_number(withdrawalFees[0], 'amount')
1642
+ if len(withdrawalFees):
1643
+ withdrawResult: dict = {
1644
+ 'fee': withdrawFee,
1645
+ 'percentage': False if (withdrawFee is not None) else None,
1646
+ }
1647
+ if i == 0:
1648
+ depositWithdrawFee['withdraw'] = withdrawResult
1649
+ depositWithdrawFee['networks'][networkCode] = {
1650
+ 'withdraw': withdrawResult,
1651
+ 'deposit': depositResult,
1652
+ }
1653
+ depositWithdrawFee['info'] = fee
1654
+ return depositWithdrawFee
1655
+
1656
+ def nonce(self):
1657
+ return self.milliseconds()
1658
+
1659
+ def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
1660
+ url = self.urls['api'][api] + '/'
1661
+ query = self.omit(params, self.extract_params(path))
1662
+ if api == 'accounts':
1663
+ self.check_required_credentials()
1664
+ url += self.implode_params(path, params)
1665
+ auth = self.apiKey + ':' + self.secret
1666
+ auth64 = self.string_to_base64(auth)
1667
+ headers = {
1668
+ 'Authorization': 'Basic ' + auth64,
1669
+ 'Content-Type': 'application/json',
1670
+ }
1671
+ if query:
1672
+ body = self.json(query)
1673
+ else:
1674
+ url += self.version + '/'
1675
+ if api == 'public':
1676
+ url += self.implode_params(path, params)
1677
+ if query:
1678
+ url += '?' + self.urlencode(query)
1679
+ elif api == 'private':
1680
+ now = self.milliseconds()
1681
+ self.check_required_credentials()
1682
+ expires = self.safe_integer(self.options, 'expires')
1683
+ if (expires is None) or (expires < now):
1684
+ raise AuthenticationError(self.id + ' access token expired, call signIn() method')
1685
+ accessToken = self.safe_string(self.options, 'accessToken')
1686
+ headers = {
1687
+ 'Authorization': 'Bearer ' + accessToken,
1688
+ }
1689
+ url += self.implode_params(path, params)
1690
+ if method == 'GET':
1691
+ if query:
1692
+ url += '?' + self.urlencode(query)
1693
+ elif query:
1694
+ body = self.json(query)
1695
+ headers['Content-Type'] = 'application/json'
1696
+ return {'url': url, 'method': method, 'body': body, 'headers': headers}
1697
+
1698
+ def sign_in(self, params={}):
1699
+ """
1700
+ :see: https://docs-en.probit.com/reference/token
1701
+ sign in, must be called prior to using other authenticated methods
1702
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1703
+ :returns: response from exchange
1704
+ """
1705
+ self.check_required_credentials()
1706
+ request: dict = {
1707
+ 'grant_type': 'client_credentials', # the only supported value
1708
+ }
1709
+ response = self.accountsPostToken(self.extend(request, params))
1710
+ #
1711
+ # {
1712
+ # "access_token": "0ttDv/2hTTn3bLi8GP1gKaneiEQ6+0hOBenPrxNQt2s=",
1713
+ # "token_type": "bearer",
1714
+ # "expires_in": 900
1715
+ # }
1716
+ #
1717
+ expiresIn = self.safe_integer(response, 'expires_in')
1718
+ accessToken = self.safe_string(response, 'access_token')
1719
+ self.options['accessToken'] = accessToken
1720
+ self.options['expires'] = self.sum(self.milliseconds(), expiresIn * 1000)
1721
+ return response
1722
+
1723
+ def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
1724
+ if response is None:
1725
+ return None # fallback to default error handler
1726
+ if 'errorCode' in response:
1727
+ errorCode = self.safe_string(response, 'errorCode')
1728
+ message = self.safe_string(response, 'message')
1729
+ if errorCode is not None:
1730
+ feedback = self.id + ' ' + body
1731
+ self.throw_exactly_matched_exception(self.exceptions['exact'], message, feedback)
1732
+ self.throw_broadly_matched_exception(self.exceptions['exact'], errorCode, feedback)
1733
+ raise ExchangeError(feedback)
1734
+ return None