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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (772) hide show
  1. ccxt/__init__.py +358 -0
  2. ccxt/abantether.py +316 -0
  3. ccxt/abstract/__init__.py +0 -0
  4. ccxt/abstract/abantether.py +5 -0
  5. ccxt/abstract/ace.py +15 -0
  6. ccxt/abstract/afratether.py +6 -0
  7. ccxt/abstract/alpaca.py +70 -0
  8. ccxt/abstract/arzinja.py +5 -0
  9. ccxt/abstract/arzplus.py +7 -0
  10. ccxt/abstract/ascendex.py +77 -0
  11. ccxt/abstract/bequant.py +115 -0
  12. ccxt/abstract/bigone.py +45 -0
  13. ccxt/abstract/binance.py +712 -0
  14. ccxt/abstract/binancecoinm.py +712 -0
  15. ccxt/abstract/binanceus.py +764 -0
  16. ccxt/abstract/binanceusdm.py +712 -0
  17. ccxt/abstract/bingx.py +113 -0
  18. ccxt/abstract/bit2c.py +27 -0
  19. ccxt/abstract/bitbank.py +27 -0
  20. ccxt/abstract/bitbay.py +53 -0
  21. ccxt/abstract/bitbns.py +40 -0
  22. ccxt/abstract/bitcoincom.py +115 -0
  23. ccxt/abstract/bitfinex.py +69 -0
  24. ccxt/abstract/bitfinex2.py +139 -0
  25. ccxt/abstract/bitflyer.py +38 -0
  26. ccxt/abstract/bitget.py +508 -0
  27. ccxt/abstract/bithumb.py +32 -0
  28. ccxt/abstract/bitimen.py +7 -0
  29. ccxt/abstract/bitir.py +7 -0
  30. ccxt/abstract/bitmart.py +99 -0
  31. ccxt/abstract/bitmex.py +97 -0
  32. ccxt/abstract/bitopro.py +29 -0
  33. ccxt/abstract/bitpanda.py +35 -0
  34. ccxt/abstract/bitpin.py +7 -0
  35. ccxt/abstract/bitrue.py +72 -0
  36. ccxt/abstract/bitso.py +43 -0
  37. ccxt/abstract/bitstamp.py +258 -0
  38. ccxt/abstract/bitteam.py +29 -0
  39. ccxt/abstract/bitvavo.py +27 -0
  40. ccxt/abstract/bl3p.py +19 -0
  41. ccxt/abstract/blockchaincom.py +28 -0
  42. ccxt/abstract/blofin.py +37 -0
  43. ccxt/abstract/btcalpha.py +18 -0
  44. ccxt/abstract/btcbox.py +13 -0
  45. ccxt/abstract/btcmarkets.py +39 -0
  46. ccxt/abstract/btcturk.py +20 -0
  47. ccxt/abstract/bybit.py +298 -0
  48. ccxt/abstract/cex.py +33 -0
  49. ccxt/abstract/coinbase.py +94 -0
  50. ccxt/abstract/coinbaseadvanced.py +94 -0
  51. ccxt/abstract/coinbaseexchange.py +67 -0
  52. ccxt/abstract/coinbaseinternational.py +39 -0
  53. ccxt/abstract/coincatch.py +94 -0
  54. ccxt/abstract/coincheck.py +33 -0
  55. ccxt/abstract/coinex.py +237 -0
  56. ccxt/abstract/coinlist.py +54 -0
  57. ccxt/abstract/coinmate.py +62 -0
  58. ccxt/abstract/coinmetro.py +34 -0
  59. ccxt/abstract/coinone.py +67 -0
  60. ccxt/abstract/coinsph.py +54 -0
  61. ccxt/abstract/coinspot.py +28 -0
  62. ccxt/abstract/cryptocom.py +107 -0
  63. ccxt/abstract/currencycom.py +68 -0
  64. ccxt/abstract/delta.py +50 -0
  65. ccxt/abstract/deribit.py +125 -0
  66. ccxt/abstract/digifinex.py +91 -0
  67. ccxt/abstract/eterex.py +5 -0
  68. ccxt/abstract/excoino.py +7 -0
  69. ccxt/abstract/exir.py +8 -0
  70. ccxt/abstract/exmo.py +55 -0
  71. ccxt/abstract/exnovin.py +6 -0
  72. ccxt/abstract/farhadexchange.py +5 -0
  73. ccxt/abstract/fmfwio.py +115 -0
  74. ccxt/abstract/gate.py +265 -0
  75. ccxt/abstract/gateio.py +265 -0
  76. ccxt/abstract/gemini.py +58 -0
  77. ccxt/abstract/hashkey.py +67 -0
  78. ccxt/abstract/hitbtc.py +115 -0
  79. ccxt/abstract/hitbtc3.py +115 -0
  80. ccxt/abstract/hitobit.py +8 -0
  81. ccxt/abstract/hollaex.py +33 -0
  82. ccxt/abstract/htx.py +548 -0
  83. ccxt/abstract/huobi.py +548 -0
  84. ccxt/abstract/huobijp.py +114 -0
  85. ccxt/abstract/hyperliquid.py +6 -0
  86. ccxt/abstract/idex.py +26 -0
  87. ccxt/abstract/independentreserve.py +37 -0
  88. ccxt/abstract/indodax.py +26 -0
  89. ccxt/abstract/jibitex.py +7 -0
  90. ccxt/abstract/kraken.py +57 -0
  91. ccxt/abstract/krakenfutures.py +38 -0
  92. ccxt/abstract/kucoin.py +214 -0
  93. ccxt/abstract/kucoinfutures.py +233 -0
  94. ccxt/abstract/kuna.py +182 -0
  95. ccxt/abstract/latoken.py +56 -0
  96. ccxt/abstract/lbank.py +61 -0
  97. ccxt/abstract/luno.py +37 -0
  98. ccxt/abstract/lykke.py +29 -0
  99. ccxt/abstract/mercado.py +25 -0
  100. ccxt/abstract/mexc.py +178 -0
  101. ccxt/abstract/ndax.py +97 -0
  102. ccxt/abstract/nobitex.py +7 -0
  103. ccxt/abstract/novadax.py +29 -0
  104. ccxt/abstract/oceanex.py +22 -0
  105. ccxt/abstract/okcoin.py +74 -0
  106. ccxt/abstract/okexchange.py +8 -0
  107. ccxt/abstract/okx.py +324 -0
  108. ccxt/abstract/ompfinex.py +7 -0
  109. ccxt/abstract/onetrading.py +35 -0
  110. ccxt/abstract/oxfun.py +34 -0
  111. ccxt/abstract/p2b.py +22 -0
  112. ccxt/abstract/paradex.py +40 -0
  113. ccxt/abstract/paymium.py +28 -0
  114. ccxt/abstract/phemex.py +115 -0
  115. ccxt/abstract/poloniex.py +69 -0
  116. ccxt/abstract/poloniexfutures.py +48 -0
  117. ccxt/abstract/probit.py +23 -0
  118. ccxt/abstract/ramzinex.py +7 -0
  119. ccxt/abstract/sarmayex.py +5 -0
  120. ccxt/abstract/sarrafex.py +7 -0
  121. ccxt/abstract/tabdeal.py +7 -0
  122. ccxt/abstract/tetherland.py +5 -0
  123. ccxt/abstract/timex.py +62 -0
  124. ccxt/abstract/tokocrypto.py +37 -0
  125. ccxt/abstract/tradeogre.py +16 -0
  126. ccxt/abstract/twox.py +5 -0
  127. ccxt/abstract/ubitex.py +7 -0
  128. ccxt/abstract/upbit.py +38 -0
  129. ccxt/abstract/vertex.py +19 -0
  130. ccxt/abstract/wallex.py +8 -0
  131. ccxt/abstract/wavesexchange.py +154 -0
  132. ccxt/abstract/wazirx.py +30 -0
  133. ccxt/abstract/whitebit.py +98 -0
  134. ccxt/abstract/woo.py +83 -0
  135. ccxt/abstract/woofipro.py +119 -0
  136. ccxt/abstract/xt.py +152 -0
  137. ccxt/abstract/yobit.py +16 -0
  138. ccxt/abstract/zaif.py +38 -0
  139. ccxt/abstract/zonda.py +53 -0
  140. ccxt/ace.py +1012 -0
  141. ccxt/afratether.py +293 -0
  142. ccxt/alpaca.py +1083 -0
  143. ccxt/arzinja.py +285 -0
  144. ccxt/arzplus.py +412 -0
  145. ccxt/ascendex.py +3330 -0
  146. ccxt/async_support/__init__.py +337 -0
  147. ccxt/async_support/abantether.py +316 -0
  148. ccxt/async_support/ace.py +1012 -0
  149. ccxt/async_support/afratether.py +293 -0
  150. ccxt/async_support/alpaca.py +1083 -0
  151. ccxt/async_support/arzinja.py +285 -0
  152. ccxt/async_support/arzplus.py +412 -0
  153. ccxt/async_support/ascendex.py +3330 -0
  154. ccxt/async_support/base/__init__.py +1 -0
  155. ccxt/async_support/base/exchange.py +1966 -0
  156. ccxt/async_support/base/throttler.py +50 -0
  157. ccxt/async_support/base/ws/__init__.py +38 -0
  158. ccxt/async_support/base/ws/aiohttp_client.py +125 -0
  159. ccxt/async_support/base/ws/cache.py +212 -0
  160. ccxt/async_support/base/ws/client.py +193 -0
  161. ccxt/async_support/base/ws/fast_client.py +96 -0
  162. ccxt/async_support/base/ws/functions.py +59 -0
  163. ccxt/async_support/base/ws/future.py +58 -0
  164. ccxt/async_support/base/ws/order_book.py +78 -0
  165. ccxt/async_support/base/ws/order_book_side.py +174 -0
  166. ccxt/async_support/bequant.py +33 -0
  167. ccxt/async_support/bigone.py +2113 -0
  168. ccxt/async_support/binance.py +12234 -0
  169. ccxt/async_support/binancecoinm.py +45 -0
  170. ccxt/async_support/binanceus.py +211 -0
  171. ccxt/async_support/binanceusdm.py +58 -0
  172. ccxt/async_support/bingx.py +4325 -0
  173. ccxt/async_support/bit2c.py +866 -0
  174. ccxt/async_support/bitbank.py +1001 -0
  175. ccxt/async_support/bitbay.py +17 -0
  176. ccxt/async_support/bitbns.py +1154 -0
  177. ccxt/async_support/bitcoincom.py +17 -0
  178. ccxt/async_support/bitfinex.py +1617 -0
  179. ccxt/async_support/bitfinex2.py +3552 -0
  180. ccxt/async_support/bitflyer.py +995 -0
  181. ccxt/async_support/bitget.py +8273 -0
  182. ccxt/async_support/bithumb.py +1061 -0
  183. ccxt/async_support/bitimen.py +401 -0
  184. ccxt/async_support/bitir.py +490 -0
  185. ccxt/async_support/bitmart.py +4415 -0
  186. ccxt/async_support/bitmex.py +2756 -0
  187. ccxt/async_support/bitopro.py +1630 -0
  188. ccxt/async_support/bitpanda.py +16 -0
  189. ccxt/async_support/bitpin.py +454 -0
  190. ccxt/async_support/bitrue.py +3027 -0
  191. ccxt/async_support/bitso.py +1670 -0
  192. ccxt/async_support/bitstamp.py +2203 -0
  193. ccxt/async_support/bitteam.py +2239 -0
  194. ccxt/async_support/bitvavo.py +1968 -0
  195. ccxt/async_support/bl3p.py +485 -0
  196. ccxt/async_support/blockchaincom.py +1104 -0
  197. ccxt/async_support/blofin.py +2066 -0
  198. ccxt/async_support/btcalpha.py +891 -0
  199. ccxt/async_support/btcbox.py +544 -0
  200. ccxt/async_support/btcmarkets.py +1221 -0
  201. ccxt/async_support/btcturk.py +911 -0
  202. ccxt/async_support/bybit.py +8159 -0
  203. ccxt/async_support/cex.py +1605 -0
  204. ccxt/async_support/coinbase.py +4475 -0
  205. ccxt/async_support/coinbaseadvanced.py +17 -0
  206. ccxt/async_support/coinbaseexchange.py +1734 -0
  207. ccxt/async_support/coinbaseinternational.py +1899 -0
  208. ccxt/async_support/coincatch.py +5069 -0
  209. ccxt/async_support/coincheck.py +815 -0
  210. ccxt/async_support/coinex.py +5526 -0
  211. ccxt/async_support/coinlist.py +2243 -0
  212. ccxt/async_support/coinmate.py +1067 -0
  213. ccxt/async_support/coinmetro.py +1797 -0
  214. ccxt/async_support/coinone.py +1127 -0
  215. ccxt/async_support/coinsph.py +1850 -0
  216. ccxt/async_support/coinspot.py +534 -0
  217. ccxt/async_support/cryptocom.py +2822 -0
  218. ccxt/async_support/currencycom.py +1950 -0
  219. ccxt/async_support/delta.py +3376 -0
  220. ccxt/async_support/deribit.py +3437 -0
  221. ccxt/async_support/digifinex.py +3960 -0
  222. ccxt/async_support/eterex.py +286 -0
  223. ccxt/async_support/excoino.py +399 -0
  224. ccxt/async_support/exir.py +375 -0
  225. ccxt/async_support/exmo.py +2462 -0
  226. ccxt/async_support/exnovin.py +360 -0
  227. ccxt/async_support/farhadexchange.py +266 -0
  228. ccxt/async_support/fmfwio.py +34 -0
  229. ccxt/async_support/gate.py +6976 -0
  230. ccxt/async_support/gateio.py +16 -0
  231. ccxt/async_support/gemini.py +1825 -0
  232. ccxt/async_support/hashkey.py +4150 -0
  233. ccxt/async_support/hitbtc.py +3423 -0
  234. ccxt/async_support/hitbtc3.py +16 -0
  235. ccxt/async_support/hitobit.py +391 -0
  236. ccxt/async_support/hollaex.py +1813 -0
  237. ccxt/async_support/htx.py +8506 -0
  238. ccxt/async_support/huobi.py +16 -0
  239. ccxt/async_support/huobijp.py +1801 -0
  240. ccxt/async_support/hyperliquid.py +2431 -0
  241. ccxt/async_support/idex.py +1766 -0
  242. ccxt/async_support/independentreserve.py +784 -0
  243. ccxt/async_support/indodax.py +1247 -0
  244. ccxt/async_support/jibitex.py +395 -0
  245. ccxt/async_support/kraken.py +2894 -0
  246. ccxt/async_support/krakenfutures.py +2601 -0
  247. ccxt/async_support/kucoin.py +4602 -0
  248. ccxt/async_support/kucoinfutures.py +2698 -0
  249. ccxt/async_support/kuna.py +1841 -0
  250. ccxt/async_support/latoken.py +1664 -0
  251. ccxt/async_support/lbank.py +2683 -0
  252. ccxt/async_support/luno.py +1067 -0
  253. ccxt/async_support/lykke.py +1270 -0
  254. ccxt/async_support/mercado.py +842 -0
  255. ccxt/async_support/mexc.py +5369 -0
  256. ccxt/async_support/ndax.py +2354 -0
  257. ccxt/async_support/nobitex.py +419 -0
  258. ccxt/async_support/novadax.py +1484 -0
  259. ccxt/async_support/oceanex.py +903 -0
  260. ccxt/async_support/okcoin.py +2936 -0
  261. ccxt/async_support/okexchange.py +349 -0
  262. ccxt/async_support/okx.py +7827 -0
  263. ccxt/async_support/ompfinex.py +472 -0
  264. ccxt/async_support/onetrading.py +1911 -0
  265. ccxt/async_support/oxfun.py +2773 -0
  266. ccxt/async_support/p2b.py +1194 -0
  267. ccxt/async_support/paradex.py +2015 -0
  268. ccxt/async_support/paymium.py +564 -0
  269. ccxt/async_support/phemex.py +4473 -0
  270. ccxt/async_support/poloniex.py +2232 -0
  271. ccxt/async_support/poloniexfutures.py +1717 -0
  272. ccxt/async_support/probit.py +1734 -0
  273. ccxt/async_support/ramzinex.py +476 -0
  274. ccxt/async_support/sarmayex.py +357 -0
  275. ccxt/async_support/sarrafex.py +478 -0
  276. ccxt/async_support/tabdeal.py +364 -0
  277. ccxt/async_support/tetherland.py +349 -0
  278. ccxt/async_support/timex.py +1593 -0
  279. ccxt/async_support/tokocrypto.py +2405 -0
  280. ccxt/async_support/tradeogre.py +608 -0
  281. ccxt/async_support/twox.py +326 -0
  282. ccxt/async_support/ubitex.py +409 -0
  283. ccxt/async_support/upbit.py +1833 -0
  284. ccxt/async_support/vertex.py +2922 -0
  285. ccxt/async_support/wallex.py +445 -0
  286. ccxt/async_support/wavesexchange.py +2473 -0
  287. ccxt/async_support/wazirx.py +1224 -0
  288. ccxt/async_support/whitebit.py +2469 -0
  289. ccxt/async_support/woo.py +3114 -0
  290. ccxt/async_support/woofipro.py +2533 -0
  291. ccxt/async_support/xt.py +4454 -0
  292. ccxt/async_support/yobit.py +1283 -0
  293. ccxt/async_support/zaif.py +725 -0
  294. ccxt/async_support/zonda.py +1828 -0
  295. ccxt/base/__init__.py +27 -0
  296. ccxt/base/decimal_to_precision.py +174 -0
  297. ccxt/base/errors.py +242 -0
  298. ccxt/base/exchange.py +5941 -0
  299. ccxt/base/precise.py +287 -0
  300. ccxt/base/types.py +502 -0
  301. ccxt/bequant.py +33 -0
  302. ccxt/bigone.py +2112 -0
  303. ccxt/binance.py +12233 -0
  304. ccxt/binancecoinm.py +45 -0
  305. ccxt/binanceus.py +211 -0
  306. ccxt/binanceusdm.py +58 -0
  307. ccxt/bingx.py +4324 -0
  308. ccxt/bit2c.py +866 -0
  309. ccxt/bitbank.py +1001 -0
  310. ccxt/bitbay.py +17 -0
  311. ccxt/bitbns.py +1154 -0
  312. ccxt/bitcoincom.py +17 -0
  313. ccxt/bitfinex.py +1617 -0
  314. ccxt/bitfinex2.py +3552 -0
  315. ccxt/bitflyer.py +995 -0
  316. ccxt/bitget.py +8272 -0
  317. ccxt/bithumb.py +1061 -0
  318. ccxt/bitimen.py +401 -0
  319. ccxt/bitir.py +490 -0
  320. ccxt/bitmart.py +4415 -0
  321. ccxt/bitmex.py +2756 -0
  322. ccxt/bitopro.py +1630 -0
  323. ccxt/bitpanda.py +16 -0
  324. ccxt/bitpin.py +454 -0
  325. ccxt/bitrue.py +3026 -0
  326. ccxt/bitso.py +1670 -0
  327. ccxt/bitstamp.py +2203 -0
  328. ccxt/bitteam.py +2239 -0
  329. ccxt/bitvavo.py +1968 -0
  330. ccxt/bl3p.py +485 -0
  331. ccxt/blockchaincom.py +1104 -0
  332. ccxt/blofin.py +2066 -0
  333. ccxt/btcalpha.py +891 -0
  334. ccxt/btcbox.py +544 -0
  335. ccxt/btcmarkets.py +1221 -0
  336. ccxt/btcturk.py +911 -0
  337. ccxt/bybit.py +8158 -0
  338. ccxt/cex.py +1605 -0
  339. ccxt/coinbase.py +4474 -0
  340. ccxt/coinbaseadvanced.py +17 -0
  341. ccxt/coinbaseexchange.py +1734 -0
  342. ccxt/coinbaseinternational.py +1899 -0
  343. ccxt/coincatch.py +5069 -0
  344. ccxt/coincheck.py +815 -0
  345. ccxt/coinex.py +5525 -0
  346. ccxt/coinlist.py +2243 -0
  347. ccxt/coinmate.py +1067 -0
  348. ccxt/coinmetro.py +1797 -0
  349. ccxt/coinone.py +1127 -0
  350. ccxt/coinsph.py +1850 -0
  351. ccxt/coinspot.py +534 -0
  352. ccxt/cryptocom.py +2822 -0
  353. ccxt/currencycom.py +1950 -0
  354. ccxt/delta.py +3376 -0
  355. ccxt/deribit.py +3437 -0
  356. ccxt/digifinex.py +3959 -0
  357. ccxt/eterex.py +286 -0
  358. ccxt/excoino.py +399 -0
  359. ccxt/exir.py +375 -0
  360. ccxt/exmo.py +2462 -0
  361. ccxt/exnovin.py +360 -0
  362. ccxt/farhadexchange.py +266 -0
  363. ccxt/fmfwio.py +34 -0
  364. ccxt/gate.py +6975 -0
  365. ccxt/gateio.py +16 -0
  366. ccxt/gemini.py +1824 -0
  367. ccxt/hashkey.py +4150 -0
  368. ccxt/hitbtc.py +3423 -0
  369. ccxt/hitbtc3.py +16 -0
  370. ccxt/hitobit.py +391 -0
  371. ccxt/hollaex.py +1813 -0
  372. ccxt/htx.py +8505 -0
  373. ccxt/huobi.py +16 -0
  374. ccxt/huobijp.py +1801 -0
  375. ccxt/hyperliquid.py +2430 -0
  376. ccxt/idex.py +1766 -0
  377. ccxt/independentreserve.py +784 -0
  378. ccxt/indodax.py +1247 -0
  379. ccxt/jibitex.py +395 -0
  380. ccxt/kraken.py +2894 -0
  381. ccxt/krakenfutures.py +2601 -0
  382. ccxt/kucoin.py +4601 -0
  383. ccxt/kucoinfutures.py +2698 -0
  384. ccxt/kuna.py +1841 -0
  385. ccxt/latoken.py +1664 -0
  386. ccxt/lbank.py +2682 -0
  387. ccxt/luno.py +1067 -0
  388. ccxt/lykke.py +1270 -0
  389. ccxt/mercado.py +842 -0
  390. ccxt/mexc.py +5369 -0
  391. ccxt/ndax.py +2354 -0
  392. ccxt/nobitex.py +419 -0
  393. ccxt/novadax.py +1484 -0
  394. ccxt/oceanex.py +903 -0
  395. ccxt/okcoin.py +2936 -0
  396. ccxt/okexchange.py +349 -0
  397. ccxt/okx.py +7826 -0
  398. ccxt/ompfinex.py +472 -0
  399. ccxt/onetrading.py +1911 -0
  400. ccxt/oxfun.py +2772 -0
  401. ccxt/p2b.py +1194 -0
  402. ccxt/paradex.py +2015 -0
  403. ccxt/paymium.py +564 -0
  404. ccxt/phemex.py +4473 -0
  405. ccxt/poloniex.py +2232 -0
  406. ccxt/poloniexfutures.py +1717 -0
  407. ccxt/pro/__init__.py +149 -0
  408. ccxt/pro/alpaca.py +685 -0
  409. ccxt/pro/ascendex.py +916 -0
  410. ccxt/pro/bequant.py +38 -0
  411. ccxt/pro/binance.py +3488 -0
  412. ccxt/pro/binancecoinm.py +28 -0
  413. ccxt/pro/binanceus.py +48 -0
  414. ccxt/pro/binanceusdm.py +31 -0
  415. ccxt/pro/bingx.py +1264 -0
  416. ccxt/pro/bitcoincom.py +34 -0
  417. ccxt/pro/bitfinex.py +621 -0
  418. ccxt/pro/bitfinex2.py +1083 -0
  419. ccxt/pro/bitget.py +1692 -0
  420. ccxt/pro/bithumb.py +368 -0
  421. ccxt/pro/bitmart.py +1449 -0
  422. ccxt/pro/bitmex.py +1656 -0
  423. ccxt/pro/bitopro.py +445 -0
  424. ccxt/pro/bitpanda.py +15 -0
  425. ccxt/pro/bitrue.py +447 -0
  426. ccxt/pro/bitstamp.py +522 -0
  427. ccxt/pro/bitvavo.py +1270 -0
  428. ccxt/pro/blockchaincom.py +738 -0
  429. ccxt/pro/blofin.py +692 -0
  430. ccxt/pro/bybit.py +2000 -0
  431. ccxt/pro/cex.py +1440 -0
  432. ccxt/pro/coinbase.py +678 -0
  433. ccxt/pro/coinbaseadvanced.py +16 -0
  434. ccxt/pro/coinbaseexchange.py +895 -0
  435. ccxt/pro/coinbaseinternational.py +620 -0
  436. ccxt/pro/coincatch.py +1464 -0
  437. ccxt/pro/coincheck.py +199 -0
  438. ccxt/pro/coinex.py +1061 -0
  439. ccxt/pro/coinone.py +395 -0
  440. ccxt/pro/cryptocom.py +947 -0
  441. ccxt/pro/currencycom.py +536 -0
  442. ccxt/pro/deribit.py +892 -0
  443. ccxt/pro/exmo.py +629 -0
  444. ccxt/pro/gate.py +1416 -0
  445. ccxt/pro/gateio.py +15 -0
  446. ccxt/pro/gemini.py +865 -0
  447. ccxt/pro/hashkey.py +802 -0
  448. ccxt/pro/hitbtc.py +1216 -0
  449. ccxt/pro/hollaex.py +563 -0
  450. ccxt/pro/htx.py +2215 -0
  451. ccxt/pro/huobi.py +15 -0
  452. ccxt/pro/huobijp.py +570 -0
  453. ccxt/pro/hyperliquid.py +525 -0
  454. ccxt/pro/idex.py +672 -0
  455. ccxt/pro/independentreserve.py +270 -0
  456. ccxt/pro/kraken.py +1356 -0
  457. ccxt/pro/krakenfutures.py +1492 -0
  458. ccxt/pro/kucoin.py +1133 -0
  459. ccxt/pro/kucoinfutures.py +1081 -0
  460. ccxt/pro/lbank.py +843 -0
  461. ccxt/pro/luno.py +303 -0
  462. ccxt/pro/mexc.py +1122 -0
  463. ccxt/pro/ndax.py +506 -0
  464. ccxt/pro/okcoin.py +698 -0
  465. ccxt/pro/okx.py +1851 -0
  466. ccxt/pro/onetrading.py +1275 -0
  467. ccxt/pro/oxfun.py +950 -0
  468. ccxt/pro/p2b.py +419 -0
  469. ccxt/pro/paradex.py +352 -0
  470. ccxt/pro/phemex.py +1441 -0
  471. ccxt/pro/poloniex.py +1166 -0
  472. ccxt/pro/poloniexfutures.py +990 -0
  473. ccxt/pro/probit.py +551 -0
  474. ccxt/pro/upbit.py +520 -0
  475. ccxt/pro/vertex.py +943 -0
  476. ccxt/pro/wazirx.py +749 -0
  477. ccxt/pro/whitebit.py +864 -0
  478. ccxt/pro/woo.py +1078 -0
  479. ccxt/pro/woofipro.py +1183 -0
  480. ccxt/pro/xt.py +1067 -0
  481. ccxt/probit.py +1734 -0
  482. ccxt/ramzinex.py +476 -0
  483. ccxt/sarmayex.py +357 -0
  484. ccxt/sarrafex.py +478 -0
  485. ccxt/static_dependencies/__init__.py +1 -0
  486. ccxt/static_dependencies/ecdsa/__init__.py +14 -0
  487. ccxt/static_dependencies/ecdsa/_version.py +520 -0
  488. ccxt/static_dependencies/ecdsa/curves.py +56 -0
  489. ccxt/static_dependencies/ecdsa/der.py +221 -0
  490. ccxt/static_dependencies/ecdsa/ecdsa.py +310 -0
  491. ccxt/static_dependencies/ecdsa/ellipticcurve.py +197 -0
  492. ccxt/static_dependencies/ecdsa/keys.py +332 -0
  493. ccxt/static_dependencies/ecdsa/numbertheory.py +531 -0
  494. ccxt/static_dependencies/ecdsa/rfc6979.py +100 -0
  495. ccxt/static_dependencies/ecdsa/util.py +266 -0
  496. ccxt/static_dependencies/ethereum/__init__.py +7 -0
  497. ccxt/static_dependencies/ethereum/abi/__init__.py +16 -0
  498. ccxt/static_dependencies/ethereum/abi/abi.py +19 -0
  499. ccxt/static_dependencies/ethereum/abi/base.py +152 -0
  500. ccxt/static_dependencies/ethereum/abi/codec.py +217 -0
  501. ccxt/static_dependencies/ethereum/abi/constants.py +3 -0
  502. ccxt/static_dependencies/ethereum/abi/decoding.py +565 -0
  503. ccxt/static_dependencies/ethereum/abi/encoding.py +720 -0
  504. ccxt/static_dependencies/ethereum/abi/exceptions.py +139 -0
  505. ccxt/static_dependencies/ethereum/abi/grammar.py +443 -0
  506. ccxt/static_dependencies/ethereum/abi/packed.py +13 -0
  507. ccxt/static_dependencies/ethereum/abi/py.typed +0 -0
  508. ccxt/static_dependencies/ethereum/abi/registry.py +643 -0
  509. ccxt/static_dependencies/ethereum/abi/tools/__init__.py +3 -0
  510. ccxt/static_dependencies/ethereum/abi/tools/_strategies.py +230 -0
  511. ccxt/static_dependencies/ethereum/abi/utils/__init__.py +0 -0
  512. ccxt/static_dependencies/ethereum/abi/utils/numeric.py +83 -0
  513. ccxt/static_dependencies/ethereum/abi/utils/padding.py +27 -0
  514. ccxt/static_dependencies/ethereum/abi/utils/string.py +19 -0
  515. ccxt/static_dependencies/ethereum/account/__init__.py +3 -0
  516. ccxt/static_dependencies/ethereum/account/encode_typed_data/__init__.py +4 -0
  517. ccxt/static_dependencies/ethereum/account/encode_typed_data/encoding_and_hashing.py +239 -0
  518. ccxt/static_dependencies/ethereum/account/encode_typed_data/helpers.py +40 -0
  519. ccxt/static_dependencies/ethereum/account/messages.py +263 -0
  520. ccxt/static_dependencies/ethereum/account/py.typed +0 -0
  521. ccxt/static_dependencies/ethereum/hexbytes/__init__.py +5 -0
  522. ccxt/static_dependencies/ethereum/hexbytes/_utils.py +54 -0
  523. ccxt/static_dependencies/ethereum/hexbytes/main.py +65 -0
  524. ccxt/static_dependencies/ethereum/hexbytes/py.typed +0 -0
  525. ccxt/static_dependencies/ethereum/typing/__init__.py +63 -0
  526. ccxt/static_dependencies/ethereum/typing/abi.py +6 -0
  527. ccxt/static_dependencies/ethereum/typing/bls.py +7 -0
  528. ccxt/static_dependencies/ethereum/typing/discovery.py +5 -0
  529. ccxt/static_dependencies/ethereum/typing/encoding.py +7 -0
  530. ccxt/static_dependencies/ethereum/typing/enums.py +17 -0
  531. ccxt/static_dependencies/ethereum/typing/ethpm.py +9 -0
  532. ccxt/static_dependencies/ethereum/typing/evm.py +20 -0
  533. ccxt/static_dependencies/ethereum/typing/networks.py +1122 -0
  534. ccxt/static_dependencies/ethereum/typing/py.typed +0 -0
  535. ccxt/static_dependencies/ethereum/utils/__init__.py +115 -0
  536. ccxt/static_dependencies/ethereum/utils/abi.py +72 -0
  537. ccxt/static_dependencies/ethereum/utils/address.py +171 -0
  538. ccxt/static_dependencies/ethereum/utils/applicators.py +151 -0
  539. ccxt/static_dependencies/ethereum/utils/conversions.py +190 -0
  540. ccxt/static_dependencies/ethereum/utils/currency.py +107 -0
  541. ccxt/static_dependencies/ethereum/utils/curried/__init__.py +269 -0
  542. ccxt/static_dependencies/ethereum/utils/debug.py +20 -0
  543. ccxt/static_dependencies/ethereum/utils/decorators.py +132 -0
  544. ccxt/static_dependencies/ethereum/utils/encoding.py +6 -0
  545. ccxt/static_dependencies/ethereum/utils/exceptions.py +4 -0
  546. ccxt/static_dependencies/ethereum/utils/functional.py +75 -0
  547. ccxt/static_dependencies/ethereum/utils/hexadecimal.py +74 -0
  548. ccxt/static_dependencies/ethereum/utils/humanize.py +188 -0
  549. ccxt/static_dependencies/ethereum/utils/logging.py +159 -0
  550. ccxt/static_dependencies/ethereum/utils/module_loading.py +31 -0
  551. ccxt/static_dependencies/ethereum/utils/numeric.py +43 -0
  552. ccxt/static_dependencies/ethereum/utils/py.typed +0 -0
  553. ccxt/static_dependencies/ethereum/utils/toolz.py +76 -0
  554. ccxt/static_dependencies/ethereum/utils/types.py +54 -0
  555. ccxt/static_dependencies/ethereum/utils/typing/__init__.py +18 -0
  556. ccxt/static_dependencies/ethereum/utils/typing/misc.py +14 -0
  557. ccxt/static_dependencies/ethereum/utils/units.py +31 -0
  558. ccxt/static_dependencies/keccak/__init__.py +3 -0
  559. ccxt/static_dependencies/keccak/keccak.py +197 -0
  560. ccxt/static_dependencies/lark/__init__.py +38 -0
  561. ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  562. ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  563. ccxt/static_dependencies/lark/ast_utils.py +59 -0
  564. ccxt/static_dependencies/lark/common.py +86 -0
  565. ccxt/static_dependencies/lark/exceptions.py +292 -0
  566. ccxt/static_dependencies/lark/grammar.py +130 -0
  567. ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  568. ccxt/static_dependencies/lark/indenter.py +143 -0
  569. ccxt/static_dependencies/lark/lark.py +658 -0
  570. ccxt/static_dependencies/lark/lexer.py +678 -0
  571. ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  572. ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  573. ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  574. ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  575. ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  576. ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  577. ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  578. ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  579. ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  580. ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  581. ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  582. ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  583. ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  584. ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  585. ccxt/static_dependencies/lark/reconstruct.py +107 -0
  586. ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  587. ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  588. ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  589. ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  590. ccxt/static_dependencies/lark/tree.py +267 -0
  591. ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  592. ccxt/static_dependencies/lark/tree_templates.py +180 -0
  593. ccxt/static_dependencies/lark/utils.py +343 -0
  594. ccxt/static_dependencies/lark/visitors.py +596 -0
  595. ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  596. ccxt/static_dependencies/marshmallow/base.py +65 -0
  597. ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  598. ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  599. ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  600. ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  601. ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  602. ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  603. ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  604. ccxt/static_dependencies/marshmallow/types.py +12 -0
  605. ccxt/static_dependencies/marshmallow/utils.py +378 -0
  606. ccxt/static_dependencies/marshmallow/validate.py +678 -0
  607. ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  608. ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  609. ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  610. ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  611. ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  612. ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  613. ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  614. ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  615. ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  616. ccxt/static_dependencies/msgpack/__init__.py +55 -0
  617. ccxt/static_dependencies/msgpack/exceptions.py +48 -0
  618. ccxt/static_dependencies/msgpack/ext.py +168 -0
  619. ccxt/static_dependencies/msgpack/fallback.py +951 -0
  620. ccxt/static_dependencies/parsimonious/__init__.py +10 -0
  621. ccxt/static_dependencies/parsimonious/exceptions.py +105 -0
  622. ccxt/static_dependencies/parsimonious/expressions.py +479 -0
  623. ccxt/static_dependencies/parsimonious/grammar.py +487 -0
  624. ccxt/static_dependencies/parsimonious/nodes.py +325 -0
  625. ccxt/static_dependencies/parsimonious/utils.py +40 -0
  626. ccxt/static_dependencies/starknet/__init__.py +0 -0
  627. ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  628. ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  629. ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  630. ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  631. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  632. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  633. ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  634. ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  635. ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  636. ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  637. ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  638. ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  639. ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  640. ccxt/static_dependencies/starknet/common.py +15 -0
  641. ccxt/static_dependencies/starknet/constants.py +39 -0
  642. ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  643. ccxt/static_dependencies/starknet/hash/address.py +79 -0
  644. ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  645. ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  646. ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  647. ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  648. ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  649. ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
  650. ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  651. ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  652. ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  653. ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  654. ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  655. ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  656. ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  657. ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  658. ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  659. ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  660. ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  661. ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  662. ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  663. ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  664. ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  665. ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  666. ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  667. ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  668. ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  669. ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  670. ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  671. ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  672. ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  673. ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  674. ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  675. ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  676. ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  677. ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  678. ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  679. ccxt/static_dependencies/starkware/__init__.py +0 -0
  680. ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  681. ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
  682. ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
  683. ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
  684. ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
  685. ccxt/static_dependencies/sympy/__init__.py +0 -0
  686. ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  687. ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
  688. ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  689. ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  690. ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  691. ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  692. ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  693. ccxt/static_dependencies/toolz/__init__.py +26 -0
  694. ccxt/static_dependencies/toolz/_signatures.py +784 -0
  695. ccxt/static_dependencies/toolz/_version.py +520 -0
  696. ccxt/static_dependencies/toolz/compatibility.py +30 -0
  697. ccxt/static_dependencies/toolz/curried/__init__.py +101 -0
  698. ccxt/static_dependencies/toolz/curried/exceptions.py +22 -0
  699. ccxt/static_dependencies/toolz/curried/operator.py +22 -0
  700. ccxt/static_dependencies/toolz/dicttoolz.py +339 -0
  701. ccxt/static_dependencies/toolz/functoolz.py +1049 -0
  702. ccxt/static_dependencies/toolz/itertoolz.py +1057 -0
  703. ccxt/static_dependencies/toolz/recipes.py +46 -0
  704. ccxt/static_dependencies/toolz/utils.py +9 -0
  705. ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  706. ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  707. ccxt/tabdeal.py +364 -0
  708. ccxt/test/__init__.py +3 -0
  709. ccxt/test/base/__init__.py +29 -0
  710. ccxt/test/base/test_account.py +26 -0
  711. ccxt/test/base/test_balance.py +56 -0
  712. ccxt/test/base/test_borrow_interest.py +35 -0
  713. ccxt/test/base/test_borrow_rate.py +32 -0
  714. ccxt/test/base/test_calculate_fee.py +51 -0
  715. ccxt/test/base/test_crypto.py +127 -0
  716. ccxt/test/base/test_currency.py +76 -0
  717. ccxt/test/base/test_datetime.py +109 -0
  718. ccxt/test/base/test_decimal_to_precision.py +392 -0
  719. ccxt/test/base/test_deep_extend.py +68 -0
  720. ccxt/test/base/test_deposit_withdrawal.py +50 -0
  721. ccxt/test/base/test_exchange_datetime_functions.py +76 -0
  722. ccxt/test/base/test_funding_rate_history.py +29 -0
  723. ccxt/test/base/test_last_price.py +31 -0
  724. ccxt/test/base/test_ledger_entry.py +45 -0
  725. ccxt/test/base/test_ledger_item.py +48 -0
  726. ccxt/test/base/test_leverage_tier.py +33 -0
  727. ccxt/test/base/test_liquidation.py +50 -0
  728. ccxt/test/base/test_margin_mode.py +24 -0
  729. ccxt/test/base/test_margin_modification.py +35 -0
  730. ccxt/test/base/test_market.py +193 -0
  731. ccxt/test/base/test_number.py +411 -0
  732. ccxt/test/base/test_ohlcv.py +33 -0
  733. ccxt/test/base/test_open_interest.py +32 -0
  734. ccxt/test/base/test_order.py +64 -0
  735. ccxt/test/base/test_order_book.py +69 -0
  736. ccxt/test/base/test_position.py +60 -0
  737. ccxt/test/base/test_shared_methods.py +353 -0
  738. ccxt/test/base/test_status.py +24 -0
  739. ccxt/test/base/test_throttle.py +126 -0
  740. ccxt/test/base/test_ticker.py +92 -0
  741. ccxt/test/base/test_trade.py +47 -0
  742. ccxt/test/base/test_trading_fee.py +26 -0
  743. ccxt/test/base/test_transaction.py +39 -0
  744. ccxt/test/test_async.py +1649 -0
  745. ccxt/test/test_sync.py +1648 -0
  746. ccxt/test/tests_async.py +1558 -0
  747. ccxt/test/tests_helpers.py +287 -0
  748. ccxt/test/tests_init.py +39 -0
  749. ccxt/test/tests_sync.py +1555 -0
  750. ccxt/tetherland.py +349 -0
  751. ccxt/timex.py +1593 -0
  752. ccxt/tokocrypto.py +2405 -0
  753. ccxt/tradeogre.py +608 -0
  754. ccxt/twox.py +326 -0
  755. ccxt/ubitex.py +409 -0
  756. ccxt/upbit.py +1833 -0
  757. ccxt/vertex.py +2922 -0
  758. ccxt/wallex.py +445 -0
  759. ccxt/wavesexchange.py +2472 -0
  760. ccxt/wazirx.py +1224 -0
  761. ccxt/whitebit.py +2469 -0
  762. ccxt/woo.py +3114 -0
  763. ccxt/woofipro.py +2533 -0
  764. ccxt/xt.py +4453 -0
  765. ccxt/yobit.py +1283 -0
  766. ccxt/zaif.py +725 -0
  767. ccxt/zonda.py +1828 -0
  768. ccxt_ir-4.3.46.0.1.dist-info/LICENSE.txt +21 -0
  769. ccxt_ir-4.3.46.0.1.dist-info/METADATA +655 -0
  770. ccxt_ir-4.3.46.0.1.dist-info/RECORD +772 -0
  771. ccxt_ir-4.3.46.0.1.dist-info/WHEEL +6 -0
  772. ccxt_ir-4.3.46.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1797 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
+ # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
+
6
+ from ccxt.async_support.base.exchange import Exchange
7
+ from ccxt.abstract.coinmetro import ImplicitAPI
8
+ from ccxt.base.types import Balances, Currencies, Currency, IndexType, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade
9
+ from typing import List
10
+ from ccxt.base.errors import ExchangeError
11
+ from ccxt.base.errors import PermissionDenied
12
+ from ccxt.base.errors import ArgumentsRequired
13
+ from ccxt.base.errors import BadRequest
14
+ from ccxt.base.errors import BadSymbol
15
+ from ccxt.base.errors import InsufficientFunds
16
+ from ccxt.base.errors import InvalidOrder
17
+ from ccxt.base.errors import OrderNotFound
18
+ from ccxt.base.errors import RateLimitExceeded
19
+ from ccxt.base.decimal_to_precision import TICK_SIZE
20
+ from ccxt.base.precise import Precise
21
+
22
+
23
+ class coinmetro(Exchange, ImplicitAPI):
24
+
25
+ def describe(self):
26
+ return self.deep_extend(super(coinmetro, self).describe(), {
27
+ 'id': 'coinmetro',
28
+ 'name': 'Coinmetro',
29
+ 'countries': ['EE'], # Republic of Estonia
30
+ 'version': 'v1',
31
+ 'rateLimit': 200, # 1 request per 200 ms, 20 per minute, 300 per hour, 1k per day
32
+ 'certified': False,
33
+ 'pro': False,
34
+ 'has': {
35
+ 'CORS': None,
36
+ 'spot': True,
37
+ 'margin': True,
38
+ 'swap': False,
39
+ 'future': False,
40
+ 'option': False,
41
+ 'addMargin': False,
42
+ 'borrowCrossMargin': True,
43
+ 'borrowIsolatedMargin': False,
44
+ 'cancelAllOrders': False,
45
+ 'cancelOrder': True,
46
+ 'cancelOrders': False,
47
+ 'closeAllPositions': False,
48
+ 'closePosition': True,
49
+ 'createDepositAddress': False,
50
+ 'createOrder': True,
51
+ 'createPostOnlyOrder': False,
52
+ 'createReduceOnlyOrder': False,
53
+ 'createStopLimitOrder': True,
54
+ 'createStopMarketOrder': True,
55
+ 'createStopOrder': True,
56
+ 'deposit': False,
57
+ 'editOrder': False,
58
+ 'fetchAccounts': False,
59
+ 'fetchBalance': True,
60
+ 'fetchBidsAsks': True,
61
+ 'fetchBorrowInterest': False,
62
+ 'fetchBorrowRateHistories': False,
63
+ 'fetchBorrowRateHistory': False,
64
+ 'fetchCanceledAndClosedOrders': True,
65
+ 'fetchCanceledOrders': False,
66
+ 'fetchClosedOrder': False,
67
+ 'fetchClosedOrders': False,
68
+ 'fetchCrossBorrowRate': False,
69
+ 'fetchCrossBorrowRates': False,
70
+ 'fetchCurrencies': True,
71
+ 'fetchDeposit': False,
72
+ 'fetchDepositAddress': False,
73
+ 'fetchDepositAddresses': False,
74
+ 'fetchDepositAddressesByNetwork': False,
75
+ 'fetchDeposits': False,
76
+ 'fetchDepositsWithdrawals': False,
77
+ 'fetchDepositWithdrawFee': False,
78
+ 'fetchDepositWithdrawFees': False,
79
+ 'fetchFundingHistory': False,
80
+ 'fetchFundingRate': False,
81
+ 'fetchFundingRateHistory': False,
82
+ 'fetchFundingRates': False,
83
+ 'fetchIndexOHLCV': False,
84
+ 'fetchIsolatedBorrowRate': False,
85
+ 'fetchIsolatedBorrowRates': False,
86
+ 'fetchL3OrderBook': False,
87
+ 'fetchLedger': True,
88
+ 'fetchLeverage': False,
89
+ 'fetchLeverageTiers': False,
90
+ 'fetchMarketLeverageTiers': False,
91
+ 'fetchMarkets': True,
92
+ 'fetchMarkOHLCV': False,
93
+ 'fetchMyTrades': True,
94
+ 'fetchOHLCV': True,
95
+ 'fetchOpenInterestHistory': False,
96
+ 'fetchOpenOrder': False,
97
+ 'fetchOpenOrders': True,
98
+ 'fetchOrder': True,
99
+ 'fetchOrderBook': True,
100
+ 'fetchOrderBooks': False,
101
+ 'fetchOrders': False,
102
+ 'fetchOrderTrades': False,
103
+ 'fetchPosition': False,
104
+ 'fetchPositions': False,
105
+ 'fetchPositionsRisk': False,
106
+ 'fetchPremiumIndexOHLCV': False,
107
+ 'fetchStatus': False,
108
+ 'fetchTicker': False,
109
+ 'fetchTickers': True,
110
+ 'fetchTime': False,
111
+ 'fetchTrades': True,
112
+ 'fetchTradingFee': False,
113
+ 'fetchTradingFees': False,
114
+ 'fetchTradingLimits': False,
115
+ 'fetchTransactionFee': False,
116
+ 'fetchTransactionFees': False,
117
+ 'fetchTransactions': False,
118
+ 'fetchTransfers': False,
119
+ 'fetchWithdrawal': False,
120
+ 'fetchWithdrawals': False,
121
+ 'fetchWithdrawalWhitelist': False,
122
+ 'reduceMargin': False,
123
+ 'repayCrossMargin': False,
124
+ 'repayIsolatedMargin': False,
125
+ 'sandbox': True,
126
+ 'setLeverage': False,
127
+ 'setMargin': False,
128
+ 'setMarginMode': False,
129
+ 'setPositionMode': False,
130
+ 'signIn': False,
131
+ 'transfer': False,
132
+ 'withdraw': False,
133
+ 'ws': False,
134
+ },
135
+ 'timeframes': {
136
+ '1m': '60000',
137
+ '5m': '300000',
138
+ '30m': '1800000',
139
+ '4h': '14400000',
140
+ '1d': '86400000',
141
+ },
142
+ 'urls': {
143
+ 'logo': 'https://github.com/ccxt/ccxt/assets/43336371/e86f87ec-6ba3-4410-962b-f7988c5db539',
144
+ 'api': {
145
+ 'public': 'https://api.coinmetro.com',
146
+ 'private': 'https://api.coinmetro.com',
147
+ },
148
+ 'test': {
149
+ 'public': 'https://api.coinmetro.com/open',
150
+ 'private': 'https://api.coinmetro.com/open',
151
+ },
152
+ 'www': 'https://coinmetro.com/',
153
+ 'doc': [
154
+ 'https://documenter.getpostman.com/view/3653795/SVfWN6KS',
155
+ ],
156
+ 'fees': 'https://help.coinmetro.com/hc/en-gb/articles/6844007317789-What-are-the-fees-on-Coinmetro-',
157
+ 'referral': 'https://go.coinmetro.com/?ref=crypto24',
158
+ },
159
+ 'api': {
160
+ 'public': {
161
+ 'get': {
162
+ 'demo/temp': 1,
163
+ 'exchange/candles/{pair}/{timeframe}/{from}/{to}': 3,
164
+ 'exchange/prices': 1,
165
+ 'exchange/ticks/{pair}/{from}': 3,
166
+ 'assets': 1,
167
+ 'markets': 1,
168
+ 'exchange/book/{pair}': 3,
169
+ 'exchange/bookUpdates/{pair}/{from}': 1, # not unified
170
+ },
171
+ },
172
+ 'private': {
173
+ 'get': {
174
+ 'users/balances': 1,
175
+ 'users/wallets': 1,
176
+ 'users/wallets/history/{since}': 1.67,
177
+ 'exchange/orders/status/{orderID}': 1,
178
+ 'exchange/orders/active': 1,
179
+ 'exchange/orders/history/{since}': 1.67,
180
+ 'exchange/fills/{since}': 1.67,
181
+ 'exchange/margin': 1, # not unified
182
+ },
183
+ 'post': {
184
+ 'jwt': 1, # not unified
185
+ 'jwtDevice': 1, # not unified
186
+ 'devices': 1, # not unified
187
+ 'jwt-read-only': 1, # not unified
188
+ 'exchange/orders/create': 1,
189
+ 'exchange/orders/modify/{orderID}': 1, # not unified
190
+ 'exchange/swap': 1, # not unified
191
+ 'exchange/swap/confirm/{swapId}': 1, # not unified
192
+ 'exchange/orders/close/{orderID}': 1,
193
+ 'exchange/orders/hedge': 1, # not unified
194
+ },
195
+ 'put': {
196
+ 'jwt': 1, # not unified
197
+ 'exchange/orders/cancel/{orderID}': 1,
198
+ 'users/margin/collateral': 1,
199
+ 'users/margin/primary/{currency}': 1, # not unified
200
+ },
201
+ },
202
+ },
203
+ 'requiredCredentials': {
204
+ 'apiKey': False,
205
+ 'secret': False,
206
+ 'uid': True,
207
+ 'token': True,
208
+ },
209
+ 'fees': {
210
+ 'trading': {
211
+ 'feeSide': 'get',
212
+ 'tierBased': False,
213
+ 'percentage': True,
214
+ 'taker': self.parse_number('0.001'),
215
+ 'maker': self.parse_number('0'),
216
+ },
217
+ },
218
+ 'precisionMode': TICK_SIZE,
219
+ # exchange-specific options
220
+ 'options': {
221
+ 'currenciesByIdForParseMarket': None,
222
+ 'currencyIdsListForParseMarket': None,
223
+ },
224
+ 'exceptions': {
225
+ # https://trade-docs.coinmetro.co/?javascript--nodejs#message-codes
226
+ 'exact': {
227
+ 'Both buyingCurrency and sellingCurrency are required': InvalidOrder, # 422 - "Both buyingCurrency and sellingCurrency are required"
228
+ 'One and only one of buyingQty and sellingQty is required': InvalidOrder, # 422 - "One and only one of buyingQty and sellingQty is required"
229
+ 'Invalid buyingCurrency': InvalidOrder, # 422 - "Invalid buyingCurrency"
230
+ 'Invalid \'from\'': BadRequest, # 422 Unprocessable Entity {"message":"Invalid 'from'"}
231
+ 'Invalid sellingCurrency': InvalidOrder, # 422 - "Invalid sellingCurrency"
232
+ 'Invalid buyingQty': InvalidOrder, # 422 - "Invalid buyingQty"
233
+ 'Invalid sellingQty': InvalidOrder, # 422 - "Invalid sellingQty"
234
+ 'Insufficient balance': InsufficientFunds, # 422 - "Insufficient balance"
235
+ 'Expiration date is in the past or too near in the future': InvalidOrder, # 422 Unprocessable Entity {"message":"Expiration date is in the past or too near in the future"}
236
+ 'Forbidden': PermissionDenied, # 403 Forbidden {"message":"Forbidden"}
237
+ 'Order Not Found': OrderNotFound, # 404 Not Found {"message":"Order Not Found"}
238
+ 'since must be a millisecond timestamp': BadRequest, # 422 Unprocessable Entity {"message":"since must be a millisecond timestamp"}
239
+ 'This pair is disabled on margin': BadSymbol, # 422 Unprocessable Entity {"message":"This pair is disabled on margin"}
240
+ },
241
+ 'broad': {
242
+ 'accessing from a new IP': PermissionDenied, # 403 Forbidden {"message":"You're accessing from a new IP. Please check your email."}
243
+ 'available to allocate': InsufficientFunds, # 403 Forbidden {"message":"Insufficient EUR available to allocate"}
244
+ 'At least': BadRequest, # 422 Unprocessable Entity {"message":"At least 5 EUR per operation"}
245
+ 'collateral is not allowed': BadRequest, # 422 Unprocessable Entity {"message":"DOGE collateral is not allowed"}
246
+ 'Insufficient liquidity': InvalidOrder, # 503 Service Unavailable {"message":"Insufficient liquidity to fill the FOK order completely."}
247
+ 'Insufficient order size': InvalidOrder, # 422 Unprocessable Entity {"message":"Insufficient order size - min 0.002 ETH"}
248
+ 'Invalid quantity': InvalidOrder, # 422 Unprocessable Entity {"message":"Invalid quantity!"}
249
+ 'Invalid Stop Loss': InvalidOrder, # 422 Unprocessable Entity {"message":"Invalid Stop Loss!"}
250
+ 'Invalid stop price!': InvalidOrder, # 422 Unprocessable Entity {"message":"Invalid stop price!"}
251
+ 'Not enough balance': InsufficientFunds, # 422 Unprocessable Entity {"message":"Not enough balance!"}
252
+ 'Not enough margin': InsufficientFunds, # Unprocessable Entity {"message":"Not enough margin!"}
253
+ 'orderType missing': BadRequest, # 422 Unprocessable Entity {"message":"orderType missing!"}
254
+ 'Server Timeout': ExchangeError, # 503 Service Unavailable {"message":"Server Timeout!"}
255
+ 'Time in force has to be IOC or FOK for market orders': InvalidOrder, # 422 Unprocessable Entity {"message":"Time in force has to be IOC or FOK for market orders!"}
256
+ 'Too many attempts': RateLimitExceeded, # 429 Too Many Requests {"message":"Too many attempts. Try again in 3 seconds"}
257
+ },
258
+ },
259
+ })
260
+
261
+ async def fetch_currencies(self, params={}) -> Currencies:
262
+ """
263
+ fetches all available currencies on an exchange
264
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#d5876d43-a3fe-4479-8c58-24d0f044edfb
265
+ :param dict [params]: extra parameters specific to the exchange API endpoint
266
+ :returns dict: an associative dictionary of currencies
267
+ """
268
+ response = await self.publicGetAssets(params)
269
+ #
270
+ # [
271
+ # {
272
+ # "symbol": "BTC",
273
+ # "name": "Bitcoin",
274
+ # "color": "#FFA500",
275
+ # "type": "coin",
276
+ # "canDeposit": True,
277
+ # "canWithdraw": True,
278
+ # "canTrade": True,
279
+ # "notabeneDecimals": 8,
280
+ # "canMarket": True,
281
+ # "maxSwap": 10000,
282
+ # "digits": 6,
283
+ # "multiplier": 1000000,
284
+ # "bookDigits": 8,
285
+ # "bookMultiplier": 100000000,
286
+ # "sentimentData": {
287
+ # "sentiment": 51.59555555555555,
288
+ # "interest": 1.127511216044664
289
+ # },
290
+ # "minQty": 0.0001
291
+ # },
292
+ # {
293
+ # "symbol": "EUR",
294
+ # "name": "Euro",
295
+ # "color": "#1246FF",
296
+ # "type": "fiat",
297
+ # "canDeposit": True,
298
+ # "canWithdraw": True,
299
+ # "canTrade": True,
300
+ # "canMarket": True,
301
+ # "maxSwap": 10000,
302
+ # "digits": 2,
303
+ # "multiplier": 100,
304
+ # "bookDigits": 3,
305
+ # "bookMultiplier": 1000,
306
+ # "minQty": 5
307
+ # }
308
+ # ...
309
+ # ]
310
+ #
311
+ result: dict = {}
312
+ for i in range(0, len(response)):
313
+ currency = response[i]
314
+ id = self.safe_string(currency, 'symbol')
315
+ code = self.safe_currency_code(id)
316
+ withdraw = self.safe_value(currency, 'canWithdraw')
317
+ deposit = self.safe_value(currency, 'canDeposit')
318
+ canTrade = self.safe_value(currency, 'canTrade')
319
+ active = withdraw if canTrade else True
320
+ minAmount = self.safe_number(currency, 'minQty')
321
+ result[code] = self.safe_currency_structure({
322
+ 'id': id,
323
+ 'code': code,
324
+ 'name': code,
325
+ 'info': currency,
326
+ 'active': active,
327
+ 'deposit': deposit,
328
+ 'withdraw': withdraw,
329
+ 'fee': None,
330
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(currency, 'digits'))),
331
+ 'limits': {
332
+ 'amount': {'min': minAmount, 'max': None},
333
+ 'withdraw': {'min': None, 'max': None},
334
+ },
335
+ 'networks': {},
336
+ })
337
+ if self.safe_value(self.options, 'currenciesByIdForParseMarket') is None:
338
+ currenciesById = self.index_by(result, 'id')
339
+ self.options['currenciesByIdForParseMarket'] = currenciesById
340
+ self.options['currencyIdsListForParseMarket'] = list(currenciesById.keys())
341
+ return result
342
+
343
+ async def fetch_markets(self, params={}) -> List[Market]:
344
+ """
345
+ retrieves data on all markets for coinmetro
346
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#9fd18008-338e-4863-b07d-722878a46832
347
+ :param dict [params]: extra parameters specific to the exchange API endpoint
348
+ :returns dict[]: an array of objects representing market data
349
+ """
350
+ response = await self.publicGetMarkets(params)
351
+ if self.safe_value(self.options, 'currenciesByIdForParseMarket') is None:
352
+ await self.fetch_currencies()
353
+ #
354
+ # [
355
+ # {
356
+ # "pair": "YFIEUR",
357
+ # "precision": 5,
358
+ # "margin": False
359
+ # },
360
+ # {
361
+ # "pair": "BTCEUR",
362
+ # "precision": 2,
363
+ # "margin": True
364
+ # },
365
+ # ...
366
+ # ]
367
+ #
368
+ return self.parse_markets(response)
369
+
370
+ def parse_market(self, market: dict) -> Market:
371
+ id = self.safe_string(market, 'pair')
372
+ parsedMarketId = self.parse_market_id(id)
373
+ baseId = self.safe_string(parsedMarketId, 'baseId')
374
+ quoteId = self.safe_string(parsedMarketId, 'quoteId')
375
+ base = self.safe_currency_code(baseId)
376
+ quote = self.safe_currency_code(quoteId)
377
+ basePrecisionAndLimits = self.parse_market_precision_and_limits(baseId)
378
+ quotePrecisionAndLimits = self.parse_market_precision_and_limits(quoteId)
379
+ margin = self.safe_bool(market, 'margin', False)
380
+ tradingFees = self.safe_value(self.fees, 'trading', {})
381
+ return self.safe_market_structure({
382
+ 'id': id,
383
+ 'symbol': base + '/' + quote,
384
+ 'base': base,
385
+ 'quote': quote,
386
+ 'settle': None,
387
+ 'baseId': baseId,
388
+ 'quoteId': quoteId,
389
+ 'settleId': None,
390
+ 'type': 'spot',
391
+ 'spot': True,
392
+ 'margin': margin,
393
+ 'swap': False,
394
+ 'future': False,
395
+ 'option': False,
396
+ 'active': True,
397
+ 'contract': False,
398
+ 'linear': None,
399
+ 'inverse': None,
400
+ 'taker': self.safe_number(tradingFees, 'taker'),
401
+ 'maker': self.safe_number(tradingFees, 'maker'),
402
+ 'contractSize': None,
403
+ 'expiry': None,
404
+ 'expiryDatetime': None,
405
+ 'strike': None,
406
+ 'optionType': None,
407
+ 'precision': {
408
+ 'amount': basePrecisionAndLimits['precision'],
409
+ 'price': self.parse_number(self.parse_precision(self.safe_string(market, 'precision'))),
410
+ },
411
+ 'limits': {
412
+ 'leverage': {
413
+ 'min': None,
414
+ 'max': None,
415
+ },
416
+ 'amount': {
417
+ 'min': basePrecisionAndLimits['minLimit'],
418
+ 'max': None,
419
+ },
420
+ 'price': {
421
+ 'min': None,
422
+ 'max': None,
423
+ },
424
+ 'cost': {
425
+ 'min': quotePrecisionAndLimits['minLimit'],
426
+ 'max': None,
427
+ },
428
+ },
429
+ 'created': None,
430
+ 'info': market,
431
+ })
432
+
433
+ def parse_market_id(self, marketId):
434
+ baseId = None
435
+ quoteId = None
436
+ currencyIds = self.safe_value(self.options, 'currencyIdsListForParseMarket', [])
437
+ for i in range(0, len(currencyIds)):
438
+ currencyId = currencyIds[i]
439
+ entryIndex = marketId.find(currencyId)
440
+ if entryIndex != -1:
441
+ restId = marketId.replace(currencyId, '')
442
+ if self.in_array(restId, currencyIds):
443
+ if entryIndex == 0:
444
+ baseId = currencyId
445
+ quoteId = restId
446
+ else:
447
+ baseId = restId
448
+ quoteId = currencyId
449
+ break
450
+ result: dict = {
451
+ 'baseId': baseId,
452
+ 'quoteId': quoteId,
453
+ }
454
+ return result
455
+
456
+ def parse_market_precision_and_limits(self, currencyId):
457
+ currencies = self.safe_value(self.options, 'currenciesByIdForParseMarket', {})
458
+ currency = self.safe_value(currencies, currencyId, {})
459
+ limits = self.safe_value(currency, 'limits', {})
460
+ amountLimits = self.safe_value(limits, 'amount', {})
461
+ minLimit = self.safe_number(amountLimits, 'min')
462
+ result: dict = {
463
+ 'precision': self.safe_number(currency, 'precision'),
464
+ 'minLimit': minLimit,
465
+ }
466
+ return result
467
+
468
+ async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
469
+ """
470
+ fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
471
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#13cfb5bc-7bfb-4847-85e1-e0f35dfb3573
472
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
473
+ :param str timeframe: the length of time each candle represents
474
+ :param int [since]: timestamp in ms of the earliest candle to fetch
475
+ :param int [limit]: the maximum amount of candles to fetch
476
+ :param dict [params]: extra parameters specific to the exchange API endpoint
477
+ :param int [params.until]: the latest time in ms to fetch entries for
478
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
479
+ """
480
+ await self.load_markets()
481
+ market = self.market(symbol)
482
+ request: dict = {
483
+ 'pair': market['id'],
484
+ 'timeframe': self.safe_string(self.timeframes, timeframe, timeframe),
485
+ }
486
+ until = None
487
+ if since is not None:
488
+ request['from'] = since
489
+ if limit is not None:
490
+ duration = self.parse_timeframe(timeframe) * 1000
491
+ until = self.sum(since, duration * (limit))
492
+ else:
493
+ request['from'] = ':from' # self endpoint doesn't accept empty from and to params(setting them into the value described in the documentation)
494
+ until = self.safe_integer(params, 'until', until)
495
+ if until is not None:
496
+ params = self.omit(params, ['until'])
497
+ request['to'] = until
498
+ else:
499
+ request['to'] = ':to'
500
+ response = await self.publicGetExchangeCandlesPairTimeframeFromTo(self.extend(request, params))
501
+ #
502
+ # {
503
+ # "candleHistory": [
504
+ # {
505
+ # "pair": "ETHUSDT",
506
+ # "timeframe": 86400000,
507
+ # "timestamp": 1697673600000,
508
+ # "c": 1567.4409353098604,
509
+ # "h": 1566.7514068472303,
510
+ # "l": 1549.4563666936847,
511
+ # "o": 1563.4490341395904,
512
+ # "v": 0
513
+ # },
514
+ # {
515
+ # "pair": "ETHUSDT",
516
+ # "timeframe": 86400000,
517
+ # "timestamp": 1697760000000,
518
+ # "c": 1603.7831363339324,
519
+ # "h": 1625.0356823666407,
520
+ # "l": 1565.4629390011505,
521
+ # "o": 1566.8387619426028,
522
+ # "v": 0
523
+ # },
524
+ # ...
525
+ # ]
526
+ # }
527
+ #
528
+ candleHistory = self.safe_list(response, 'candleHistory', [])
529
+ return self.parse_ohlcvs(candleHistory, market, timeframe, since, limit)
530
+
531
+ def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
532
+ return [
533
+ self.safe_integer(ohlcv, 'timestamp'),
534
+ self.safe_number(ohlcv, 'o'),
535
+ self.safe_number(ohlcv, 'h'),
536
+ self.safe_number(ohlcv, 'l'),
537
+ self.safe_number(ohlcv, 'c'),
538
+ self.safe_number(ohlcv, 'v'),
539
+ ]
540
+
541
+ async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
542
+ """
543
+ get the list of most recent trades for a particular symbol
544
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#6ee5d698-06da-4570-8c84-914185e05065
545
+ :param str symbol: unified symbol of the market to fetch trades for
546
+ :param int [since]: timestamp in ms of the earliest trade to fetch
547
+ :param int [limit]: the maximum amount of trades to fetch(default 200, max 500)
548
+ :param dict [params]: extra parameters specific to the exchange API endpoint
549
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
550
+ """
551
+ await self.load_markets()
552
+ market = self.market(symbol)
553
+ request: dict = {
554
+ 'pair': market['id'],
555
+ }
556
+ if since is not None:
557
+ request['from'] = since
558
+ else:
559
+ # self endpoint accepts empty from param
560
+ request['from'] = ''
561
+ response = await self.publicGetExchangeTicksPairFrom(self.extend(request, params))
562
+ #
563
+ # {
564
+ # "tickHistory": [
565
+ # {
566
+ # "pair": "ETHUSDT",
567
+ # "price": 2077.5623,
568
+ # "qty": 0.002888,
569
+ # "timestamp": 1700684689420,
570
+ # "seqNum": 10644554718
571
+ # },
572
+ # {
573
+ # "pair": "ETHUSDT",
574
+ # "price": 2078.3848,
575
+ # "qty": 0.003368,
576
+ # "timestamp": 1700684738410,
577
+ # "seqNum": 10644559561
578
+ # },
579
+ # {
580
+ # "pair": "ETHUSDT",
581
+ # "price": 2077.1513,
582
+ # "qty": 0.00337,
583
+ # "timestamp": 1700684816853,
584
+ # "seqNum": 10644567113
585
+ # },
586
+ # ...
587
+ # ]
588
+ # }
589
+ #
590
+ tickHistory = self.safe_list(response, 'tickHistory', [])
591
+ return self.parse_trades(tickHistory, market, since, limit)
592
+
593
+ async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
594
+ """
595
+ fetch all trades made by the user
596
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#4d48ae69-8ee2-44d1-a268-71f84e557b7b
597
+ :param str symbol: unified market symbol
598
+ :param int [since]: the earliest time in ms to fetch trades for
599
+ :param int [limit]: the maximum number of trades structures to retrieve(default 500, max 1000)
600
+ :param dict [params]: extra parameters specific to the exchange API endpoint
601
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
602
+ """
603
+ await self.load_markets()
604
+ market = None
605
+ if symbol is not None:
606
+ market = self.market(symbol)
607
+ request: dict = {}
608
+ if since is not None:
609
+ request['since'] = since
610
+ else:
611
+ # the exchange requires a value for the since param
612
+ request['since'] = 0
613
+ response = await self.privateGetExchangeFillsSince(self.extend(request, params))
614
+ #
615
+ # [
616
+ # {
617
+ # "pair": "ETHUSDC",
618
+ # "seqNumber": 10873722343,
619
+ # "timestamp": 1702570610747,
620
+ # "qty": 0.002,
621
+ # "price": 2282,
622
+ # "side": "buy",
623
+ # "orderID": "65671262d93d9525ac009e36170257061073952c6423a8c5b4d6c"
624
+ # },
625
+ # ...
626
+ # ]
627
+ #
628
+ return self.parse_trades(response, market, since, limit)
629
+
630
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
631
+ #
632
+ # fetchTrades
633
+ # {
634
+ # "pair": "ETHUSDT",
635
+ # "price": 2077.1513,
636
+ # "qty": 0.00337,
637
+ # "timestamp": 1700684816853,
638
+ # "seqNum": 10644567113
639
+ # },
640
+ #
641
+ # fetchMyTrades
642
+ # {
643
+ # "pair": "ETHUSDC",
644
+ # "seqNumber": 10873722343,
645
+ # "timestamp": 1702570610747,
646
+ # "qty": 0.002,
647
+ # "price": 2282,
648
+ # "side": "buy",
649
+ # "orderID": "65671262d93d9525ac009e36170257061073952c6423a8c5b4d6c"
650
+ # }
651
+ #
652
+ # fetchOrders
653
+ # {
654
+ # "_id": "657b31d360a9542449381bdc",
655
+ # "seqNumber": 10873722343,
656
+ # "timestamp": 1702570610747,
657
+ # "qty": 0.002,
658
+ # "price": 2282,
659
+ # "side": "buy"
660
+ # }
661
+ #
662
+ # {
663
+ # "pair":"ETHUSDC",
664
+ # "seqNumber":"10873722343",
665
+ # "timestamp":"1702570610747",
666
+ # "qty":"0.002",
667
+ # "price":"2282",
668
+ # "side":"buy",
669
+ # "orderID":"65671262d93d9525ac009e36170257061073952c6423a8c5b4d6c",
670
+ # "userID":"65671262d93d9525ac009e36"
671
+ # }
672
+ #
673
+ marketId = self.safe_string_2(trade, 'symbol', 'pair')
674
+ market = self.safe_market(marketId, market)
675
+ symbol = market['symbol']
676
+ id = self.safe_string_n(trade, ['_id', 'seqNum', 'seqNumber'])
677
+ timestamp = self.safe_integer(trade, 'timestamp')
678
+ priceString = self.safe_string(trade, 'price')
679
+ amountString = self.safe_string(trade, 'qty')
680
+ order = self.safe_string(trade, 'orderID')
681
+ side = self.safe_string(trade, 'side')
682
+ return self.safe_trade({
683
+ 'id': id,
684
+ 'order': order,
685
+ 'timestamp': timestamp,
686
+ 'datetime': self.iso8601(timestamp),
687
+ 'symbol': symbol,
688
+ 'type': None,
689
+ 'side': side,
690
+ 'takerOrMaker': None,
691
+ 'price': priceString,
692
+ 'amount': amountString,
693
+ 'cost': None,
694
+ 'fee': None,
695
+ 'info': trade,
696
+ }, market)
697
+
698
+ async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
699
+ """
700
+ fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
701
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#26ad80d7-8c46-41b5-9208-386f439a8b87
702
+ :param str symbol: unified symbol of the market to fetch the order book for
703
+ :param int [limit]: the maximum amount of order book entries to return(default 100, max 200)
704
+ :param dict [params]: extra parameters specific to the exchange API endpoint
705
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
706
+ """
707
+ await self.load_markets()
708
+ market = self.market(symbol)
709
+ request: dict = {
710
+ 'pair': market['id'],
711
+ }
712
+ response = await self.publicGetExchangeBookPair(self.extend(request, params))
713
+ #
714
+ # {
715
+ # "book": {
716
+ # "pair": "ETHUSDT",
717
+ # "seqNumber": 10800409239,
718
+ # "ask": {
719
+ # "2354.2861": 3.75,
720
+ # "2354.3138": 19,
721
+ # "2354.7538": 80,
722
+ # "2355.5430": 260,
723
+ # "2356.4611": 950,
724
+ # "2361.7150": 1500,
725
+ # "206194.0000": 0.01
726
+ # },
727
+ # "bid": {
728
+ # "2352.6339": 3.75,
729
+ # "2352.6002": 19,
730
+ # "2352.2402": 80,
731
+ # "2351.4582": 260,
732
+ # "2349.3111": 950,
733
+ # "2343.8601": 1500,
734
+ # "1.0000": 5
735
+ # },
736
+ # "checksum": 2108177337
737
+ # }
738
+ # }
739
+ #
740
+ book = self.safe_value(response, 'book', {})
741
+ rawBids = self.safe_value(book, 'bid', {})
742
+ rawAsks = self.safe_value(book, 'ask', {})
743
+ rawOrderbook: dict = {
744
+ 'bids': rawBids,
745
+ 'asks': rawAsks,
746
+ }
747
+ orderbook = self.parse_order_book(rawOrderbook, symbol)
748
+ orderbook['nonce'] = self.safe_integer(book, 'seqNumber')
749
+ return orderbook
750
+
751
+ def parse_bids_asks(self, bidasks, priceKey: IndexType = 0, amountKey: IndexType = 1, countOrIdKey: IndexType = 2):
752
+ prices = list(bidasks.keys())
753
+ result = []
754
+ for i in range(0, len(prices)):
755
+ priceString = self.safe_string(prices, i)
756
+ price = self.safe_number(prices, i)
757
+ volume = self.safe_number(bidasks, priceString)
758
+ result.append([price, volume])
759
+ return result
760
+
761
+ async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
762
+ """
763
+ fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
764
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#6ecd1cd1-f162-45a3-8b3b-de690332a485
765
+ :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
766
+ :param dict [params]: extra parameters specific to the exchange API endpoint
767
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
768
+ """
769
+ await self.load_markets()
770
+ response = await self.publicGetExchangePrices(params)
771
+ #
772
+ # {
773
+ # "latestPrices": [
774
+ # {
775
+ # "pair": "PERPEUR",
776
+ # "timestamp": 1702549840393,
777
+ # "price": 0.7899997816001223,
778
+ # "qty": 1e-12,
779
+ # "ask": 0.8,
780
+ # "bid": 0.7799995632002446
781
+ # },
782
+ # {
783
+ # "pair": "PERPUSD",
784
+ # "timestamp": 1702549841973,
785
+ # "price": 0.8615317721366659,
786
+ # "qty": 1e-12,
787
+ # "ask": 0.8742333599999257,
788
+ # "bid": 0.8490376365388491
789
+ # },
790
+ # ...
791
+ # ],
792
+ # "24hInfo": [
793
+ # {
794
+ # "delta": 0.25396444229149906,
795
+ # "h": 0.78999978160012,
796
+ # "l": 0.630001740844,
797
+ # "v": 54.910000002833996,
798
+ # "pair": "PERPEUR",
799
+ # "sentimentData": {
800
+ # "sentiment": 36.71333333333333,
801
+ # "interest": 0.47430830039525695
802
+ # }
803
+ # },
804
+ # {
805
+ # "delta": 0.26915154078134096,
806
+ # "h": 0.86220315458898,
807
+ # "l": 0.67866757035154,
808
+ # "v": 2.835000000000001e-9,
809
+ # "pair": "PERPUSD",
810
+ # "sentimentData": {
811
+ # "sentiment": 36.71333333333333,
812
+ # "interest": 0.47430830039525695
813
+ # }
814
+ # },
815
+ # ...
816
+ # ]
817
+ # }
818
+ #
819
+ latestPrices = self.safe_value(response, 'latestPrices', [])
820
+ twentyFourHInfos = self.safe_value(response, '24hInfo', [])
821
+ tickersObject: dict = {}
822
+ # merging info from two lists into one
823
+ for i in range(0, len(latestPrices)):
824
+ latestPrice = latestPrices[i]
825
+ marketId = self.safe_string(latestPrice, 'pair')
826
+ if marketId is not None:
827
+ tickersObject[marketId] = latestPrice
828
+ for i in range(0, len(twentyFourHInfos)):
829
+ twentyFourHInfo = twentyFourHInfos[i]
830
+ marketId = self.safe_string(twentyFourHInfo, 'pair')
831
+ if marketId is not None:
832
+ latestPrice = self.safe_value(tickersObject, marketId, {})
833
+ tickersObject[marketId] = self.extend(twentyFourHInfo, latestPrice)
834
+ tickers = list(tickersObject.values())
835
+ return self.parse_tickers(tickers, symbols)
836
+
837
+ async def fetch_bids_asks(self, symbols: Strings = None, params={}):
838
+ """
839
+ fetches the bid and ask price and volume for multiple markets
840
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#6ecd1cd1-f162-45a3-8b3b-de690332a485
841
+ :param str[] [symbols]: unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned
842
+ :param dict [params]: extra parameters specific to the exchange API endpoint
843
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
844
+ """
845
+ await self.load_markets()
846
+ response = await self.publicGetExchangePrices(params)
847
+ latestPrices = self.safe_list(response, 'latestPrices', [])
848
+ return self.parse_tickers(latestPrices, symbols)
849
+
850
+ def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
851
+ #
852
+ # {
853
+ # "pair": "PERPUSD",
854
+ # "timestamp": 1702549841973,
855
+ # "price": 0.8615317721366659,
856
+ # "qty": 1e-12,
857
+ # "ask": 0.8742333599999257,
858
+ # "bid": 0.8490376365388491
859
+ # "delta": 0.26915154078134096,
860
+ # "h": 0.86220315458898,
861
+ # "l": 0.67866757035154,
862
+ # "v": 2.835000000000001e-9,
863
+ # "sentimentData": {
864
+ # "sentiment": 36.71333333333333,
865
+ # "interest": 0.47430830039525695
866
+ # }
867
+ # }
868
+ #
869
+ marketId = self.safe_string(ticker, 'pair')
870
+ market = self.safe_market(marketId, market)
871
+ timestamp = self.safe_integer(ticker, 'timestamp')
872
+ bid = self.safe_string(ticker, 'bid')
873
+ ask = self.safe_string(ticker, 'ask')
874
+ high = self.safe_string(ticker, 'h')
875
+ low = self.safe_string(ticker, 'l')
876
+ last = self.safe_string(ticker, 'price')
877
+ baseVolume = self.safe_string(ticker, 'v')
878
+ delta = self.safe_string(ticker, 'delta')
879
+ percentage = Precise.string_mul(delta, '100')
880
+ return self.safe_ticker({
881
+ 'symbol': market['symbol'],
882
+ 'timestamp': timestamp,
883
+ 'datetime': self.iso8601(timestamp),
884
+ 'open': None,
885
+ 'high': high,
886
+ 'low': low,
887
+ 'close': None,
888
+ 'last': last,
889
+ 'bid': bid,
890
+ 'bidVolume': None,
891
+ 'ask': ask,
892
+ 'askVolume': None,
893
+ 'vwap': None,
894
+ 'previousClose': None,
895
+ 'change': None,
896
+ 'percentage': percentage,
897
+ 'average': None,
898
+ 'baseVolume': baseVolume,
899
+ 'quoteVolume': None,
900
+ 'info': ticker,
901
+ }, market)
902
+
903
+ async def fetch_balance(self, params={}) -> Balances:
904
+ """
905
+ query for balance and get the amount of funds available for trading or funds locked in orders
906
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#741a1dcc-7307-40d0-acca-28d003d1506a
907
+ :param dict [params]: extra parameters specific to the exchange API endpoint
908
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
909
+ """
910
+ await self.load_markets()
911
+ response = await self.privateGetUsersWallets(params)
912
+ list = self.safe_list(response, 'list', [])
913
+ return self.parse_balance(list)
914
+
915
+ def parse_balance(self, balances) -> Balances:
916
+ #
917
+ # [
918
+ # {
919
+ # "xcmLocks": [],
920
+ # "xcmLockAmounts": [],
921
+ # "refList": [],
922
+ # "balanceHistory": [],
923
+ # "_id": "5fecd3c998e75c2e4d63f7c3",
924
+ # "currency": "BTC",
925
+ # "label": "BTC",
926
+ # "userId": "5fecd3c97fbfed1521db23bd",
927
+ # "__v": 0,
928
+ # "balance": 0.5,
929
+ # "createdAt": "2020-12-30T19:23:53.646Z",
930
+ # "disabled": False,
931
+ # "updatedAt": "2020-12-30T19:23:53.653Z",
932
+ # "reserved": 0,
933
+ # "id": "5fecd3c998e75c2e4d63f7c3"
934
+ # },
935
+ # ...
936
+ # ]
937
+ #
938
+ result: dict = {
939
+ 'info': balances,
940
+ }
941
+ for i in range(0, len(balances)):
942
+ balanceEntry = self.safe_dict(balances, i, {})
943
+ currencyId = self.safe_string(balanceEntry, 'currency')
944
+ code = self.safe_currency_code(currencyId)
945
+ account = self.account()
946
+ account['total'] = self.safe_string(balanceEntry, 'balance')
947
+ account['used'] = self.safe_string(balanceEntry, 'reserved')
948
+ result[code] = account
949
+ return self.safe_balance(result)
950
+
951
+ async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
952
+ """
953
+ fetch the history of changes, actions done by the user or operations that altered balance of the user
954
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#4e7831f7-a0e7-4c3e-9336-1d0e5dcb15cf
955
+ :param str code: unified currency code, default is None
956
+ :param int [since]: timestamp in ms of the earliest ledger entry, default is None
957
+ :param int [limit]: max number of ledger entrys to return(default 200, max 500)
958
+ :param dict [params]: extra parameters specific to the exchange API endpoint
959
+ :param int [params.until]: the latest time in ms to fetch entries for
960
+ :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
961
+ """
962
+ await self.load_markets()
963
+ request: dict = {}
964
+ if since is not None:
965
+ request['since'] = since
966
+ else:
967
+ # self endpoint accepts empty since param
968
+ request['since'] = ''
969
+ currency = None
970
+ if code is not None:
971
+ currency = self.currency(code)
972
+ response = await self.privateGetUsersWalletsHistorySince(self.extend(request, params))
973
+ #
974
+ # {
975
+ # "list": [
976
+ # {
977
+ # "currency": "USDC",
978
+ # "label": "USDC",
979
+ # "userId": "65671262d93d9525ac009e36",
980
+ # "balance": 0,
981
+ # "disabled": False,
982
+ # "balanceHistory": [
983
+ # {
984
+ # "description": "Deposit - 657973a9b6eadf0f33d70100",
985
+ # "JSONdata": {
986
+ # "fees": 0,
987
+ # "notes": "Via Crypto",
988
+ # "txHash": "0x2e4875185b0f312d8e24b2d26d46bf9877db798b608ad2ff97b2b8bc7d8134e5",
989
+ # "last4Digits": null,
990
+ # "IBAN": null,
991
+ # "alternativeChain": "polygon",
992
+ # "referenceId": "657973a9b6eadf0f33d70100",
993
+ # "status": "completed",
994
+ # "tracked": True
995
+ # },
996
+ # "amount": 99,
997
+ # "timestamp": "2023-12-13T09:04:51.270Z",
998
+ # "amountEUR": 91.79310117335974
999
+ # },
1000
+ # {
1001
+ # "description": "Order 65671262d93d9525ac009e36170257061073952c6423a8c5b4d6c SeqNum 10873722342",
1002
+ # "JSONdata": {
1003
+ # "price": "2282.00 ETH/USDC",
1004
+ # "fees": 0,
1005
+ # "notes": "Order 3a8c5b4d6c"
1006
+ # },
1007
+ # "amount": -4.564,
1008
+ # "timestamp": "2023-12-14T16:16:50.760Z",
1009
+ # "amountEUR": -4.150043849187587
1010
+ # },
1011
+ # ...
1012
+ # ]
1013
+ # },
1014
+ # {
1015
+ # "currency": "ETH",
1016
+ # "label": "ETH",
1017
+ # "userId": "65671262d93d9525ac009e36",
1018
+ # "balance": 0,
1019
+ # "disabled": False,
1020
+ # "balanceHistory": [
1021
+ # {
1022
+ # "description": "Order 65671262d93d9525ac009e36170257061073952c6423a8c5b4d6c SeqNum 10873722342",
1023
+ # "JSONdata": {
1024
+ # "price": "2282.00 ETH/USDC",
1025
+ # "fees": 0.000002,
1026
+ # "notes": "Order 3a8c5b4d6c"
1027
+ # },
1028
+ # "amount": 0.001998,
1029
+ # "timestamp": "2023-12-14T16:16:50.761Z",
1030
+ # "amountEUR": 4.144849415806856
1031
+ # },
1032
+ # ...
1033
+ # ]
1034
+ # },
1035
+ # {
1036
+ # "currency": "DOGE",
1037
+ # "label": "DOGE",
1038
+ # "userId": "65671262d93d9525ac009e36",
1039
+ # "balance": 0,
1040
+ # "disabled": False,
1041
+ # "balanceHistory": [
1042
+ # {
1043
+ # "description": "Order 65671262d93d9525ac009e361702905785319b5d9016dc20736034d13ca6a - Swap",
1044
+ # "JSONdata": {
1045
+ # "swap": True,
1046
+ # "subtype": "swap",
1047
+ # "fees": 0,
1048
+ # "price": "0.0905469 DOGE/USDC",
1049
+ # "notes": "Swap 034d13ca6a"
1050
+ # },
1051
+ # "amount": 70,
1052
+ # "timestamp": "2023-12-18T13:23:05.836Z",
1053
+ # "amountEUR": 5.643627624549227
1054
+ # }
1055
+ # ]
1056
+ # },
1057
+ # ...
1058
+ # ]
1059
+ # }
1060
+ #
1061
+ ledgerByCurrencies = self.safe_value(response, 'list', [])
1062
+ ledger = []
1063
+ for i in range(0, len(ledgerByCurrencies)):
1064
+ currencyLedger = ledgerByCurrencies[i]
1065
+ currencyId = self.safe_string(currencyLedger, 'currency')
1066
+ balanceHistory = self.safe_value(currencyLedger, 'balanceHistory', [])
1067
+ for j in range(0, len(balanceHistory)):
1068
+ rawLedgerEntry = balanceHistory[j]
1069
+ rawLedgerEntry['currencyId'] = currencyId
1070
+ ledger.append(rawLedgerEntry)
1071
+ return self.parse_ledger(ledger, currency, since, limit)
1072
+
1073
+ def parse_ledger_entry(self, item: dict, currency: Currency = None):
1074
+ datetime = self.safe_string(item, 'timestamp')
1075
+ currencyId = self.safe_string(item, 'currencyId')
1076
+ item = self.omit(item, 'currencyId')
1077
+ currency = self.safe_currency(currencyId, currency)
1078
+ description = self.safe_string(item, 'description', '')
1079
+ type, referenceId = self.parse_ledger_entry_description(description)
1080
+ JSONdata = self.safe_value(item, 'JSONdata', {})
1081
+ feeCost = self.safe_string(JSONdata, 'fees')
1082
+ fee = {
1083
+ 'cost': feeCost,
1084
+ 'currency': None,
1085
+ }
1086
+ amount = self.safe_string(item, 'amount')
1087
+ direction = None
1088
+ if amount is not None:
1089
+ if Precise.string_lt(amount, '0'):
1090
+ direction = 'out'
1091
+ amount = Precise.string_abs(amount)
1092
+ elif Precise.string_gt(amount, '0'):
1093
+ direction = 'in'
1094
+ return self.safe_ledger_entry({
1095
+ 'info': item,
1096
+ 'id': None,
1097
+ 'timestamp': self.parse8601(datetime),
1098
+ 'datetime': datetime,
1099
+ 'direction': direction,
1100
+ 'account': None,
1101
+ 'referenceId': referenceId,
1102
+ 'referenceAccount': None,
1103
+ 'type': type,
1104
+ 'currency': currency,
1105
+ 'amount': amount,
1106
+ 'before': None,
1107
+ 'after': None,
1108
+ 'status': None,
1109
+ 'fee': fee,
1110
+ }, currency)
1111
+
1112
+ def parse_ledger_entry_description(self, description):
1113
+ descriptionArray = []
1114
+ if description is not None:
1115
+ descriptionArray = description.split(' ')
1116
+ type = None
1117
+ referenceId = None
1118
+ length = len(descriptionArray)
1119
+ if length > 1:
1120
+ type = self.parse_ledger_entry_type(descriptionArray[0])
1121
+ if descriptionArray[1] != '-':
1122
+ referenceId = descriptionArray[1]
1123
+ else:
1124
+ referenceId = self.safe_string(descriptionArray, 2)
1125
+ return [type, referenceId]
1126
+
1127
+ def parse_ledger_entry_type(self, type):
1128
+ types: dict = {
1129
+ 'Deposit': 'transaction',
1130
+ 'Withdraw': 'transaction',
1131
+ 'Order': 'trade',
1132
+ }
1133
+ return self.safe_string(types, type, type)
1134
+
1135
+ async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1136
+ """
1137
+ create a trade order
1138
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#a4895a1d-3f50-40ae-8231-6962ef06c771
1139
+ :param str symbol: unified symbol of the market to create an order in
1140
+ :param str type: 'market' or 'limit'
1141
+ :param str side: 'buy' or 'sell'
1142
+ :param float amount: how much of currency you want to trade in units of base currency
1143
+ :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1144
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1145
+ :param float [params.cost]: the quote quantity that can be used alternative for the amount in market orders
1146
+ :param str [params.timeInForce]: "GTC", "IOC", "FOK", "GTD"
1147
+ :param number [params.expirationTime]: timestamp in millisecond, for GTD orders only
1148
+ :param float [params.triggerPrice]: the price at which a trigger order is triggered at
1149
+ :param float [params.stopLossPrice]: *margin only* The price at which a stop loss order is triggered at
1150
+ :param float [params.takeProfitPrice]: *margin only* The price at which a take profit order is triggered at
1151
+ :param bool [params.margin]: True for creating a margin order
1152
+ :param str [params.fillStyle]: fill style of the limit order: "sell" fulfills selling quantity "buy" fulfills buying quantity "base" fulfills base currency quantity "quote" fulfills quote currency quantity
1153
+ :param str [params.clientOrderId]: client's comment
1154
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1155
+ """
1156
+ await self.load_markets()
1157
+ market = self.market(symbol)
1158
+ request: dict = {
1159
+ }
1160
+ request['orderType'] = type
1161
+ precisedAmount = None
1162
+ if amount is not None:
1163
+ precisedAmount = self.amount_to_precision(symbol, amount)
1164
+ cost = self.safe_value(params, 'cost')
1165
+ params = self.omit(params, 'cost')
1166
+ if type == 'limit':
1167
+ if (price is None) and (cost is None):
1168
+ raise ArgumentsRequired(self.id + ' createOrder() requires a price or params.cost argument for a ' + type + ' order')
1169
+ elif (price is not None) and (amount is not None):
1170
+ costString = Precise.string_mul(self.number_to_string(price), self.number_to_string(precisedAmount))
1171
+ cost = self.parse_to_numeric(costString)
1172
+ precisedCost = None
1173
+ if cost is not None:
1174
+ precisedCost = self.cost_to_precision(symbol, cost)
1175
+ if side == 'sell':
1176
+ request = self.handle_create_order_side(market['baseId'], market['quoteId'], precisedAmount, precisedCost, request)
1177
+ elif side == 'buy':
1178
+ request = self.handle_create_order_side(market['quoteId'], market['baseId'], precisedCost, precisedAmount, request)
1179
+ timeInForce = self.safe_value(params, 'timeInForce')
1180
+ if timeInForce is not None:
1181
+ params = self.omit(params, 'timeInForce')
1182
+ request['timeInForce'] = self.encode_order_time_in_force(timeInForce)
1183
+ stopPrice = self.safe_string_2(params, 'triggerPrice', 'stopPrice')
1184
+ if stopPrice is not None:
1185
+ params = self.omit(params, ['triggerPrice'])
1186
+ request['stopPrice'] = self.price_to_precision(symbol, stopPrice)
1187
+ userData = self.safe_value(params, 'userData', {})
1188
+ comment = self.safe_string_2(params, 'clientOrderId', 'comment')
1189
+ if comment is not None:
1190
+ params = self.omit(params, ['clientOrderId'])
1191
+ userData['comment'] = comment
1192
+ stopLossPrice = self.safe_string(params, 'stopLossPrice')
1193
+ if stopLossPrice is not None:
1194
+ params = self.omit(params, 'stopLossPrice')
1195
+ userData['stopLoss'] = self.price_to_precision(symbol, stopLossPrice)
1196
+ takeProfitPrice = self.safe_string(params, 'takeProfitPrice')
1197
+ if takeProfitPrice is not None:
1198
+ params = self.omit(params, 'takeProfitPrice')
1199
+ userData['takeProfit'] = self.price_to_precision(symbol, takeProfitPrice)
1200
+ if not self.is_empty(userData):
1201
+ request['userData'] = userData
1202
+ response = await self.privatePostExchangeOrdersCreate(self.extend(request, params))
1203
+ #
1204
+ # {
1205
+ # "userID": "65671262d93d9525ac009e36",
1206
+ # "orderID": "65671262d93d9525ac009e36170257448481749b7ee2893bafec2",
1207
+ # "orderType": "market",
1208
+ # "buyingCurrency": "ETH",
1209
+ # "sellingCurrency": "USDC",
1210
+ # "buyingQty": 0.002,
1211
+ # "timeInForce": 4,
1212
+ # "boughtQty": 0.002,
1213
+ # "soldQty": 4.587,
1214
+ # "creationTime": 1702574484829,
1215
+ # "seqNumber": 10874285330,
1216
+ # "firstFillTime": 1702574484831,
1217
+ # "lastFillTime": 1702574484831,
1218
+ # "fills": [
1219
+ # {
1220
+ # "seqNumber": 10874285329,
1221
+ # "timestamp": 1702574484831,
1222
+ # "qty": 0.002,
1223
+ # "price": 2293.5,
1224
+ # "side": "buy"
1225
+ # }
1226
+ # ],
1227
+ # "completionTime": 1702574484831,
1228
+ # "takerQty": 0.002
1229
+ # }
1230
+ #
1231
+ return self.parse_order(response, market)
1232
+
1233
+ def handle_create_order_side(self, sellingCurrency, buyingCurrency, sellingQty, buyingQty, request={}):
1234
+ request['sellingCurrency'] = sellingCurrency
1235
+ request['buyingCurrency'] = buyingCurrency
1236
+ if sellingQty is not None:
1237
+ request['sellingQty'] = sellingQty
1238
+ if buyingQty is not None:
1239
+ request['buyingQty'] = buyingQty
1240
+ return request
1241
+
1242
+ def encode_order_time_in_force(self, timeInForce):
1243
+ timeInForceTypes: dict = {
1244
+ 'GTC': 1,
1245
+ 'IOC': 2,
1246
+ 'GTD': 3,
1247
+ 'FOK': 4,
1248
+ }
1249
+ return self.safe_value(timeInForceTypes, timeInForce, timeInForce)
1250
+
1251
+ async def cancel_order(self, id: str, symbol: Str = None, params={}):
1252
+ """
1253
+ cancels an open order
1254
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#eaea86da-16ca-4c56-9f00-5b1cb2ad89f8
1255
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#47f913fb-8cab-49f4-bc78-d980e6ced316
1256
+ :param str id: order id
1257
+ :param str symbol: not used by coinmetro cancelOrder()
1258
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1259
+ :param str [params.margin]: True for cancelling a margin order
1260
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1261
+ """
1262
+ await self.load_markets()
1263
+ request: dict = {
1264
+ 'orderID': id,
1265
+ }
1266
+ marginMode = None
1267
+ params, params = self.handle_margin_mode_and_params('cancelOrder', params)
1268
+ isMargin = self.safe_bool(params, 'margin', False)
1269
+ params = self.omit(params, 'margin')
1270
+ response = None
1271
+ if isMargin or (marginMode is not None):
1272
+ response = await self.privatePostExchangeOrdersCloseOrderID(self.extend(request, params))
1273
+ else:
1274
+ response = await self.privatePutExchangeOrdersCancelOrderID(self.extend(request, params))
1275
+ #
1276
+ # {
1277
+ # "userID": "65671262d93d9525ac009e36",
1278
+ # "orderID": "65671262d93d9525ac009e3617026635256739c996fe17d7cd5d4",
1279
+ # "orderType": "limit",
1280
+ # "buyingCurrency": "ETH",
1281
+ # "sellingCurrency": "USDC",
1282
+ # "fillStyle": "sell",
1283
+ # "orderPlatform": "trade-v3",
1284
+ # "timeInForce": 1,
1285
+ # "buyingQty": 0.005655,
1286
+ # "sellingQty": 11.31,
1287
+ # "boughtQty": 0,
1288
+ # "soldQty": 0,
1289
+ # "creationTime": 1702663525713,
1290
+ # "seqNumber": 10915220048,
1291
+ # "completionTime": 1702928369053
1292
+ # }
1293
+ #
1294
+ return self.parse_order(response)
1295
+
1296
+ async def close_position(self, symbol: str, side: OrderSide = None, params={}):
1297
+ """
1298
+ closes an open position
1299
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#47f913fb-8cab-49f4-bc78-d980e6ced316
1300
+ :param str symbol: not used by coinmetro closePosition()
1301
+ :param str [side]: not used by coinmetro closePosition()
1302
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1303
+ :param str [params.orderID]: order id
1304
+ :param number [params.fraction]: fraction of order to close, between 0 and 1(defaults to 1)
1305
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1306
+ """
1307
+ await self.load_markets()
1308
+ orderId = self.safe_string(params, 'orderId')
1309
+ if orderId is None:
1310
+ raise ArgumentsRequired(self.id + ' closePosition() requires a orderId parameter')
1311
+ request: dict = {
1312
+ 'orderID': orderId,
1313
+ }
1314
+ response = await self.privatePostExchangeOrdersCloseOrderID(self.extend(request, params))
1315
+ #
1316
+ # {
1317
+ # "userID": "65671262d93d9525ac009e36",
1318
+ # "orderID": "65671262d93d9525ac009e3617030152811996e5b352556d3d7d8_CL",
1319
+ # "orderType": "market",
1320
+ # "buyingCurrency": "ETH",
1321
+ # "sellingCurrency": "EUR",
1322
+ # "margin": True,
1323
+ # "buyingQty": 0.03,
1324
+ # "timeInForce": 4,
1325
+ # "boughtQty": 0.03,
1326
+ # "soldQty": 59.375,
1327
+ # "creationTime": 1703015488482,
1328
+ # "seqNumber": 10925321179,
1329
+ # "firstFillTime": 1703015488483,
1330
+ # "lastFillTime": 1703015488483,
1331
+ # "fills": [
1332
+ # {
1333
+ # "seqNumber": 10925321178,
1334
+ # "timestamp": 1703015488483,
1335
+ # "qty": 0.03,
1336
+ # "price": 1979.1666666666667,
1337
+ # "side": "buy"
1338
+ # }
1339
+ # ],
1340
+ # "completionTime": 1703015488483,
1341
+ # "takerQty": 0.03
1342
+ # }
1343
+ #
1344
+ return self.parse_order(response)
1345
+
1346
+ async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1347
+ """
1348
+ fetch all unfilled currently open orders
1349
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#518afd7a-4338-439c-a651-d4fdaa964138
1350
+ :param str symbol: unified market symbol
1351
+ :param int [since]: the earliest time in ms to fetch open orders for
1352
+ :param int [limit]: the maximum number of open order structures to retrieve
1353
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1354
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1355
+ """
1356
+ await self.load_markets()
1357
+ market = None
1358
+ if symbol is not None:
1359
+ market = self.market(symbol)
1360
+ response = await self.privateGetExchangeOrdersActive(params)
1361
+ orders = self.parse_orders(response, market, since, limit)
1362
+ for i in range(0, len(orders)):
1363
+ order = orders[i]
1364
+ order['status'] = 'open'
1365
+ return orders
1366
+
1367
+ async def fetch_canceled_and_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1368
+ """
1369
+ fetches information on multiple canceled and closed orders made by the user
1370
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#4d48ae69-8ee2-44d1-a268-71f84e557b7b
1371
+ :param str symbol: unified market symbol of the market orders were made in
1372
+ :param int [since]: the earliest time in ms to fetch orders for
1373
+ :param int [limit]: the maximum number of order structures to retrieve
1374
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1375
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1376
+ """
1377
+ await self.load_markets()
1378
+ market = None
1379
+ if symbol is not None:
1380
+ market = self.market(symbol)
1381
+ request: dict = {}
1382
+ if since is not None:
1383
+ request['since'] = since
1384
+ response = await self.privateGetExchangeOrdersHistorySince(self.extend(request, params))
1385
+ return self.parse_orders(response, market, since, limit)
1386
+
1387
+ async def fetch_order(self, id: str, symbol: Str = None, params={}):
1388
+ """
1389
+ fetches information on an order made by the user
1390
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#95bbed87-db1c-47a7-a03e-aa247e91d5a6
1391
+ :param int|str id: order id
1392
+ :param str symbol: not used by coinmetro fetchOrder()
1393
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1394
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1395
+ """
1396
+ await self.load_markets()
1397
+ request: dict = {
1398
+ 'orderID': id,
1399
+ }
1400
+ response = await self.privateGetExchangeOrdersStatusOrderID(self.extend(request, params))
1401
+ #
1402
+ # {
1403
+ # "_id": "657b4e6d60a954244939ac6f",
1404
+ # "userID": "65671262d93d9525ac009e36",
1405
+ # "orderID": "65671262d93d9525ac009e361702576531985b78465468b9cc544",
1406
+ # "orderType": "market",
1407
+ # "buyingCurrency": "ETH",
1408
+ # "sellingCurrency": "USDC",
1409
+ # "buyingQty": 0.004,
1410
+ # "timeInForce": 4,
1411
+ # "boughtQty": 0.004,
1412
+ # "soldQty": 9.236,
1413
+ # "creationTime": 1702576531995,
1414
+ # "seqNumber": 10874644062,
1415
+ # "firstFillTime": 1702576531995,
1416
+ # "lastFillTime": 1702576531995,
1417
+ # "fills": [
1418
+ # {
1419
+ # "_id": "657b4e6d60a954244939ac70",
1420
+ # "seqNumber": 10874644061,
1421
+ # "timestamp": 1702576531995,
1422
+ # "qty": 0.004,
1423
+ # "price": 2309,
1424
+ # "side": "buy"
1425
+ # }
1426
+ # ],
1427
+ # "completionTime": 1702576531995,
1428
+ # "takerQty": 0.004,
1429
+ # "fees": 0.000004,
1430
+ # "isAncillary": False,
1431
+ # "margin": False,
1432
+ # "trade": False,
1433
+ # "canceled": False
1434
+ # }
1435
+ #
1436
+ return self.parse_order(response)
1437
+
1438
+ def parse_order(self, order: dict, market: Market = None) -> Order:
1439
+ #
1440
+ # createOrder market
1441
+ # {
1442
+ # "userID": "65671262d93d9525ac009e36",
1443
+ # "orderID": "65671262d93d9525ac009e36170257448481749b7ee2893bafec2",
1444
+ # "orderType": "market",
1445
+ # "buyingCurrency": "ETH",
1446
+ # "sellingCurrency": "USDC",
1447
+ # "buyingQty": 0.002,
1448
+ # "timeInForce": 4,
1449
+ # "boughtQty": 0.002,
1450
+ # "soldQty": 4.587,
1451
+ # "creationTime": 1702574484829,
1452
+ # "seqNumber": 10874285330,
1453
+ # "firstFillTime": 1702574484831,
1454
+ # "lastFillTime": 1702574484831,
1455
+ # "fills": [
1456
+ # {
1457
+ # "seqNumber": 10874285329,
1458
+ # "timestamp": 1702574484831,
1459
+ # "qty": 0.002,
1460
+ # "price": 2293.5,
1461
+ # "side": "buy"
1462
+ # }
1463
+ # ],
1464
+ # "completionTime": 1702574484831,
1465
+ # "takerQty": 0.002
1466
+ # }
1467
+ #
1468
+ # createOrder limit
1469
+ # {
1470
+ # "userID": "65671262d93d9525ac009e36",
1471
+ # "orderID": "65671262d93d9525ac009e3617026635256739c996fe17d7cd5d4",
1472
+ # "orderType": "limit",
1473
+ # "buyingCurrency": "ETH",
1474
+ # "sellingCurrency": "USDC",
1475
+ # "fillStyle": "sell",
1476
+ # "orderPlatform": "trade-v3",
1477
+ # "timeInForce": 1,
1478
+ # "buyingQty": 0.005655,
1479
+ # "sellingQty": 11.31,
1480
+ # "boughtQty": 0,
1481
+ # "soldQty": 0,
1482
+ # "creationTime": 1702663525713,
1483
+ # "seqNumber": 10885528683,
1484
+ # "fees": 0,
1485
+ # "fills": [],
1486
+ # "isAncillary": False,
1487
+ # "margin": False,
1488
+ # "trade": False
1489
+ # }
1490
+ #
1491
+ # fetchOrders market
1492
+ # {
1493
+ # "userID": "65671262d93d9525ac009e36",
1494
+ # "orderID": "65671262d93d9525ac009e36170257061073952c6423a8c5b4d6c",
1495
+ # "orderType": "market",
1496
+ # "buyingCurrency": "ETH",
1497
+ # "sellingCurrency": "USDC",
1498
+ # "buyingQty": 0.002,
1499
+ # "timeInForce": 4,
1500
+ # "boughtQty": 0.002,
1501
+ # "soldQty": 4.564,
1502
+ # "creationTime": 1702570610746,
1503
+ # "seqNumber": 10873722344,
1504
+ # "firstFillTime": 1702570610747,
1505
+ # "lastFillTime": 1702570610747,
1506
+ # "fills": [
1507
+ # {
1508
+ # "_id": "657b31d360a9542449381bdc",
1509
+ # "seqNumber": 10873722343,
1510
+ # "timestamp": 1702570610747,
1511
+ # "qty": 0.002,
1512
+ # "price": 2282,
1513
+ # "side": "buy"
1514
+ # }
1515
+ # ],
1516
+ # "completionTime": 1702570610747,
1517
+ # "takerQty": 0.002,
1518
+ # "fees": 0.000002,
1519
+ # "isAncillary": False,
1520
+ # "margin": False,
1521
+ # "trade": False,
1522
+ # "canceled": False,
1523
+ # "__v": 0
1524
+ # }
1525
+ #
1526
+ # fetchOrders margin
1527
+ # {
1528
+ # "userData": {
1529
+ # "takeProfit": 1700,
1530
+ # "stopLoss": 2100
1531
+ # },
1532
+ # "_id": "658201d060a95424499394a2",
1533
+ # "seqNumber": 10925300213,
1534
+ # "orderType": "limit",
1535
+ # "buyingCurrency": "EUR",
1536
+ # "sellingCurrency": "ETH",
1537
+ # "userID": "65671262d93d9525ac009e36",
1538
+ # "closedQty": 0.03,
1539
+ # "sellingQty": 0.03,
1540
+ # "buyingQty": 58.8,
1541
+ # "creationTime": 1703015281205,
1542
+ # "margin": True,
1543
+ # "timeInForce": 1,
1544
+ # "boughtQty": 59.31,
1545
+ # "orderID": "65671262d93d9525ac009e3617030152811996e5b352556d3d7d8",
1546
+ # "lastFillTime": 1703015281206,
1547
+ # "soldQty": 0.03,
1548
+ # "closedTime": 1703015488488,
1549
+ # "closedVal": 59.375,
1550
+ # "trade": True,
1551
+ # "takerQty": 59.31,
1552
+ # "firstFillTime": 1703015281206,
1553
+ # "completionTime": 1703015281206,
1554
+ # "fills": [
1555
+ # {
1556
+ # "_id": "658201d060a95424499394a3",
1557
+ # "seqNumber": 10925300212,
1558
+ # "side": "sell",
1559
+ # "price": 1977,
1560
+ # "qty": 0.03,
1561
+ # "timestamp": 1703015281206
1562
+ # },
1563
+ # {
1564
+ # "_id": "658201d060a95424499394a4",
1565
+ # "seqNumber": 10925321178,
1566
+ # "timestamp": 1703015488483,
1567
+ # "qty": 0.03,
1568
+ # "price": 1979.1666666666667,
1569
+ # "side": "buy"
1570
+ # }
1571
+ # ],
1572
+ # "fees": 0.11875000200000001,
1573
+ # "settledQtys": {
1574
+ # "ETH": -0.000092842104710025
1575
+ # },
1576
+ # "isAncillary": False,
1577
+ # "canceled": False
1578
+ # }
1579
+ #
1580
+ # fetchOrder
1581
+ # {
1582
+ # "_id": "657b4e6d60a954244939ac6f",
1583
+ # "userID": "65671262d93d9525ac009e36",
1584
+ # "orderID": "65671262d93d9525ac009e361702576531985b78465468b9cc544",
1585
+ # "orderType": "market",
1586
+ # "buyingCurrency": "ETH",
1587
+ # "sellingCurrency": "USDC",
1588
+ # "buyingQty": 0.004,
1589
+ # "timeInForce": 4,
1590
+ # "boughtQty": 0.004,
1591
+ # "soldQty": 9.236,
1592
+ # "creationTime": 1702576531995,
1593
+ # "seqNumber": 10874644062,
1594
+ # "firstFillTime": 1702576531995,
1595
+ # "lastFillTime": 1702576531995,
1596
+ # "fills": [
1597
+ # {
1598
+ # "_id": "657b4e6d60a954244939ac70",
1599
+ # "seqNumber": 10874644061,
1600
+ # "timestamp": 1702576531995,
1601
+ # "qty": 0.004,
1602
+ # "price": 2309,
1603
+ # "side": "buy"
1604
+ # }
1605
+ # ],
1606
+ # "completionTime": 1702576531995,
1607
+ # "takerQty": 0.004,
1608
+ # "fees": 0.000004,
1609
+ # "isAncillary": False,
1610
+ # "margin": False,
1611
+ # "trade": False,
1612
+ # "canceled": False
1613
+ # }
1614
+ #
1615
+ timestamp = self.safe_integer(order, 'creationTime')
1616
+ isCanceled = self.safe_value(order, 'canceled')
1617
+ status = None
1618
+ if isCanceled is True:
1619
+ if timestamp is None:
1620
+ timestamp = self.safe_integer(order, 'completionTime') # market orders with bad price gain IOC - we mark them as 'rejected'?
1621
+ status = 'rejected' # these orders don't have the 'creationTime` param and have 'canceled': True
1622
+ else:
1623
+ status = 'canceled'
1624
+ else:
1625
+ status = self.safe_string(order, 'status')
1626
+ order = self.omit(order, 'status') # we mark orders from fetchOpenOrders with param 'status': 'open'
1627
+ type = self.safe_string(order, 'orderType')
1628
+ buyingQty = self.safe_string(order, 'buyingQty')
1629
+ sellingQty = self.safe_string(order, 'sellingQty')
1630
+ boughtQty = self.safe_string(order, 'boughtQty')
1631
+ soldQty = self.safe_string(order, 'soldQty')
1632
+ if type == 'market':
1633
+ if (buyingQty is None) and (boughtQty is not None) and (boughtQty != '0'):
1634
+ buyingQty = boughtQty
1635
+ if (sellingQty is None) and (soldQty is not None) and (soldQty != '0'):
1636
+ sellingQty = soldQty
1637
+ buyingCurrencyId = self.safe_string(order, 'buyingCurrency', '')
1638
+ sellingCurrencyId = self.safe_string(order, 'sellingCurrency', '')
1639
+ byuingIdPlusSellingId = buyingCurrencyId + sellingCurrencyId
1640
+ sellingIdPlusBuyingId = sellingCurrencyId + buyingCurrencyId
1641
+ side = None
1642
+ marketId = None
1643
+ baseAmount = buyingQty
1644
+ quoteAmount = buyingQty
1645
+ filled = None
1646
+ cost = None
1647
+ feeInBaseOrQuote = None
1648
+ marketsById = self.index_by(self.markets, 'id')
1649
+ if self.safe_value(marketsById, byuingIdPlusSellingId) is not None:
1650
+ side = 'buy'
1651
+ marketId = byuingIdPlusSellingId
1652
+ quoteAmount = sellingQty
1653
+ filled = boughtQty
1654
+ cost = soldQty
1655
+ feeInBaseOrQuote = 'base'
1656
+ elif self.safe_value(marketsById, sellingIdPlusBuyingId) is not None:
1657
+ side = 'sell'
1658
+ marketId = sellingIdPlusBuyingId
1659
+ baseAmount = sellingQty
1660
+ filled = soldQty
1661
+ cost = boughtQty
1662
+ feeInBaseOrQuote = 'quote'
1663
+ price = None
1664
+ if (baseAmount is not None) and (quoteAmount is not None):
1665
+ price = Precise.string_div(quoteAmount, baseAmount)
1666
+ market = self.safe_market(marketId, market)
1667
+ fee = None
1668
+ feeCost = self.safe_string(order, 'fees')
1669
+ if (feeCost is not None) and (feeInBaseOrQuote is not None):
1670
+ fee = {
1671
+ 'currency': market[feeInBaseOrQuote],
1672
+ 'cost': feeCost,
1673
+ 'rate': None,
1674
+ }
1675
+ trades = self.safe_value(order, 'fills', [])
1676
+ userData = self.safe_value(order, 'userData', {})
1677
+ triggerPrice = self.safe_string(order, 'stopPrice')
1678
+ clientOrderId = self.safe_string(userData, 'comment')
1679
+ takeProfitPrice = self.safe_string(userData, 'takeProfit')
1680
+ stopLossPrice = self.safe_string(userData, 'stopLoss')
1681
+ return self.safe_order({
1682
+ 'id': self.safe_string(order, 'orderID'),
1683
+ 'clientOrderId': clientOrderId,
1684
+ 'timestamp': timestamp,
1685
+ 'datetime': self.iso8601(timestamp),
1686
+ 'lastTradeTimestamp': self.safe_integer(order, 'lastFillTime'),
1687
+ 'status': status,
1688
+ 'symbol': market['symbol'],
1689
+ 'type': type,
1690
+ 'timeInForce': self.parse_order_time_in_force(self.safe_integer(order, 'timeInForce')),
1691
+ 'side': side,
1692
+ 'price': price,
1693
+ 'triggerPrice': triggerPrice,
1694
+ 'takeProfitPrice': takeProfitPrice,
1695
+ 'stopLossPrice': stopLossPrice,
1696
+ 'average': None,
1697
+ 'amount': baseAmount,
1698
+ 'cost': cost,
1699
+ 'filled': filled,
1700
+ 'remaining': None,
1701
+ 'fee': fee,
1702
+ 'fees': None,
1703
+ 'trades': trades,
1704
+ 'info': order,
1705
+ }, market)
1706
+
1707
+ def parse_order_time_in_force(self, timeInForce):
1708
+ timeInForceTypes = [
1709
+ None,
1710
+ 'GTC',
1711
+ 'IOC',
1712
+ 'GTD',
1713
+ 'FOK',
1714
+ ]
1715
+ return self.safe_value(timeInForceTypes, timeInForce, timeInForce)
1716
+
1717
+ async def borrow_cross_margin(self, code: str, amount: float, params={}):
1718
+ """
1719
+ create a loan to borrow margin
1720
+ :see: https://documenter.getpostman.com/view/3653795/SVfWN6KS#5b90b3b9-e5db-4d07-ac9d-d680a06fd110
1721
+ :param str code: unified currency code of the currency to borrow
1722
+ :param float amount: the amount to borrow
1723
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1724
+ :returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
1725
+ """
1726
+ await self.load_markets()
1727
+ currency = self.currency(code)
1728
+ currencyId = currency['id']
1729
+ request: dict = {}
1730
+ request[currencyId] = self.currency_to_precision(code, amount)
1731
+ response = await self.privatePutUsersMarginCollateral(self.extend(request, params))
1732
+ #
1733
+ # {"message": "OK"}
1734
+ #
1735
+ result = self.safe_value(response, 'result', {})
1736
+ transaction = self.parse_margin_loan(result, currency)
1737
+ return self.extend(transaction, {
1738
+ 'amount': amount,
1739
+ })
1740
+
1741
+ def parse_margin_loan(self, info, currency: Currency = None):
1742
+ currencyId = self.safe_string(info, 'coin')
1743
+ return {
1744
+ 'id': None,
1745
+ 'currency': self.safe_currency_code(currencyId, currency),
1746
+ 'amount': None,
1747
+ 'symbol': None,
1748
+ 'timestamp': None,
1749
+ 'datetime': None,
1750
+ 'info': info,
1751
+ }
1752
+
1753
+ def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
1754
+ request = self.omit(params, self.extract_params(path))
1755
+ endpoint = '/' + self.implode_params(path, params)
1756
+ url = self.urls['api'][api] + endpoint
1757
+ query = self.urlencode(request)
1758
+ if headers is None:
1759
+ headers = {}
1760
+ headers['CCXT'] = 'true'
1761
+ if api == 'private':
1762
+ if (self.uid is None) and (self.apiKey is not None):
1763
+ self.uid = self.apiKey
1764
+ if (self.token is None) and (self.secret is not None):
1765
+ self.token = self.secret
1766
+ if url == 'https://api.coinmetro.com/jwt': # handle with headers for login endpoint
1767
+ headers['X-Device-Id'] = 'bypass'
1768
+ if self.twofa is not None:
1769
+ headers['X-OTP'] = self.twofa
1770
+ elif url == 'https://api.coinmetro.com/jwtDevice': # handle with headers for long lived token login endpoint
1771
+ headers['X-Device-Id'] = self.uid
1772
+ if self.twofa is not None:
1773
+ headers['X-OTP'] = self.twofa
1774
+ else:
1775
+ headers['Authorization'] = 'Bearer ' + self.token
1776
+ if not url.startswith('https://api.coinmetro.com/open'): # if not sandbox endpoint
1777
+ self.check_required_credentials()
1778
+ headers['X-Device-Id'] = self.uid
1779
+ if (method == 'POST') or (method == 'PUT'):
1780
+ headers['Content-Type'] = 'application/x-www-form-urlencoded'
1781
+ body = self.urlencode(request)
1782
+ elif len(query) != 0:
1783
+ url += '?' + query
1784
+ while(url.endswith('/')):
1785
+ url = url[0:len(url) - 1]
1786
+ return {'url': url, 'method': method, 'body': body, 'headers': headers}
1787
+
1788
+ def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
1789
+ if response is None:
1790
+ return None
1791
+ if (code != 200) and (code != 201) and (code != 202):
1792
+ feedback = self.id + ' ' + body
1793
+ message = self.safe_string(response, 'message')
1794
+ self.throw_broadly_matched_exception(self.exceptions['broad'], message, feedback)
1795
+ self.throw_exactly_matched_exception(self.exceptions['exact'], message, feedback)
1796
+ raise ExchangeError(feedback)
1797
+ return None