ccxt-ir 4.3.46.0.3__py2.py3-none-any.whl → 4.5.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 (529) hide show
  1. ccxt/__init__.py +39 -35
  2. ccxt/abantether.py +8 -8
  3. ccxt/abstract/alpaca.py +4 -0
  4. ccxt/abstract/apex.py +31 -0
  5. ccxt/abstract/bigone.py +1 -1
  6. ccxt/abstract/binance.py +106 -48
  7. ccxt/abstract/binancecoinm.py +106 -48
  8. ccxt/abstract/binanceus.py +141 -83
  9. ccxt/abstract/binanceusdm.py +106 -48
  10. ccxt/abstract/bingx.py +50 -1
  11. ccxt/abstract/bitbank.py +5 -0
  12. ccxt/abstract/bitfinex.py +136 -65
  13. ccxt/abstract/bitflyer.py +1 -0
  14. ccxt/abstract/bitget.py +67 -0
  15. ccxt/abstract/bitmart.py +19 -1
  16. ccxt/abstract/bitopro.py +1 -0
  17. ccxt/abstract/bitrue.py +68 -68
  18. ccxt/abstract/bitstamp.py +1 -0
  19. ccxt/abstract/blofin.py +30 -0
  20. ccxt/abstract/btcbox.py +2 -0
  21. ccxt/abstract/bybit.py +28 -13
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbaseexchange.py +1 -0
  24. ccxt/abstract/coinbaseinternational.py +1 -1
  25. ccxt/abstract/cryptocom.py +16 -0
  26. ccxt/abstract/cryptomus.py +20 -0
  27. ccxt/abstract/defx.py +69 -0
  28. ccxt/abstract/deribit.py +1 -0
  29. ccxt/abstract/derive.py +117 -0
  30. ccxt/abstract/digifinex.py +1 -0
  31. ccxt/abstract/ellipx.py +25 -0
  32. ccxt/abstract/foxbit.py +26 -0
  33. ccxt/abstract/gate.py +19 -0
  34. ccxt/abstract/gateio.py +19 -0
  35. ccxt/abstract/gemini.py +1 -0
  36. ccxt/abstract/hibachi.py +26 -0
  37. ccxt/abstract/hyperliquid.py +1 -1
  38. ccxt/abstract/independentreserve.py +6 -0
  39. ccxt/abstract/kraken.py +1 -0
  40. ccxt/abstract/krakenfutures.py +4 -0
  41. ccxt/abstract/kucoin.py +10 -0
  42. ccxt/abstract/kucoinfutures.py +18 -0
  43. ccxt/abstract/lbank.py +2 -1
  44. ccxt/abstract/luno.py +1 -0
  45. ccxt/abstract/mexc.py +2 -0
  46. ccxt/abstract/modetrade.py +119 -0
  47. ccxt/abstract/myokx.py +349 -0
  48. ccxt/abstract/oceanex.py +5 -0
  49. ccxt/abstract/okx.py +25 -0
  50. ccxt/abstract/okxus.py +349 -0
  51. ccxt/abstract/onetrading.py +0 -12
  52. ccxt/abstract/paradex.py +23 -0
  53. ccxt/abstract/phemex.py +2 -0
  54. ccxt/abstract/poloniex.py +36 -0
  55. ccxt/abstract/tradeogre.py +3 -1
  56. ccxt/abstract/upbit.py +51 -34
  57. ccxt/abstract/whitebit.py +16 -0
  58. ccxt/abstract/woo.py +64 -6
  59. ccxt/abstract/xt.py +10 -5
  60. ccxt/afratether.py +8 -8
  61. ccxt/alpaca.py +828 -51
  62. ccxt/apex.py +1875 -0
  63. ccxt/arzinja.py +7 -7
  64. ccxt/arzplus.py +9 -9
  65. ccxt/ascendex.py +501 -306
  66. ccxt/async_support/__init__.py +39 -35
  67. ccxt/async_support/abantether.py +8 -8
  68. ccxt/async_support/afratether.py +10 -10
  69. ccxt/async_support/alpaca.py +828 -51
  70. ccxt/async_support/apex.py +1875 -0
  71. ccxt/async_support/arzinja.py +10 -10
  72. ccxt/async_support/arzplus.py +12 -12
  73. ccxt/async_support/ascendex.py +502 -306
  74. ccxt/async_support/base/exchange.py +303 -89
  75. ccxt/async_support/base/ws/cache.py +9 -3
  76. ccxt/async_support/base/ws/client.py +173 -38
  77. ccxt/async_support/base/ws/future.py +25 -37
  78. ccxt/async_support/bequant.py +5 -3
  79. ccxt/async_support/bigone.py +279 -144
  80. ccxt/async_support/binance.py +2347 -1158
  81. ccxt/async_support/binancecoinm.py +9 -3
  82. ccxt/async_support/binanceus.py +17 -3
  83. ccxt/async_support/binanceusdm.py +9 -4
  84. ccxt/async_support/bingx.py +2962 -920
  85. ccxt/async_support/bit2c.py +147 -27
  86. ccxt/async_support/bitbank.py +151 -23
  87. ccxt/async_support/bitbns.py +104 -30
  88. ccxt/async_support/bitfinex.py +3291 -1113
  89. ccxt/async_support/bitflyer.py +202 -27
  90. ccxt/async_support/bitget.py +3683 -1538
  91. ccxt/async_support/bithumb.py +195 -38
  92. ccxt/async_support/bitimen.py +12 -12
  93. ccxt/async_support/bitir.py +38 -38
  94. ccxt/async_support/bitmart.py +1288 -350
  95. ccxt/async_support/bitmex.py +260 -75
  96. ccxt/async_support/bitopro.py +262 -62
  97. ccxt/async_support/bitpin.py +17 -16
  98. ccxt/async_support/bitrue.py +459 -290
  99. ccxt/async_support/bitso.py +199 -54
  100. ccxt/async_support/bitstamp.py +230 -96
  101. ccxt/async_support/bitteam.py +167 -25
  102. ccxt/async_support/{huobijp.py → bittrade.py} +158 -30
  103. ccxt/async_support/bitvavo.py +213 -49
  104. ccxt/async_support/blockchaincom.py +160 -46
  105. ccxt/async_support/blofin.py +502 -120
  106. ccxt/async_support/btcalpha.py +169 -31
  107. ccxt/async_support/btcbox.py +292 -23
  108. ccxt/async_support/btcmarkets.py +211 -58
  109. ccxt/async_support/btcturk.py +161 -38
  110. ccxt/async_support/bybit.py +1775 -1030
  111. ccxt/async_support/cex.py +1440 -1303
  112. ccxt/async_support/coinbase.py +724 -212
  113. ccxt/async_support/coinbaseadvanced.py +2 -1
  114. ccxt/async_support/coinbaseexchange.py +388 -89
  115. ccxt/async_support/coinbaseinternational.py +412 -57
  116. ccxt/async_support/coincatch.py +177 -78
  117. ccxt/async_support/coincheck.py +135 -19
  118. ccxt/async_support/coinex.py +606 -232
  119. ccxt/async_support/coinmate.py +189 -63
  120. ccxt/async_support/coinmetro.py +195 -54
  121. ccxt/async_support/coinone.py +158 -51
  122. ccxt/async_support/coinsph.py +336 -61
  123. ccxt/async_support/coinspot.py +151 -52
  124. ccxt/async_support/cryptocom.py +661 -111
  125. ccxt/async_support/cryptomus.py +1137 -0
  126. ccxt/async_support/defx.py +2071 -0
  127. ccxt/async_support/delta.py +299 -99
  128. ccxt/async_support/deribit.py +348 -126
  129. ccxt/async_support/derive.py +2572 -0
  130. ccxt/async_support/digifinex.py +430 -214
  131. ccxt/async_support/ellipx.py +2029 -0
  132. ccxt/async_support/eterex.py +10 -10
  133. ccxt/async_support/excoino.py +31 -31
  134. ccxt/async_support/exir.py +14 -14
  135. ccxt/async_support/exmo.py +344 -131
  136. ccxt/async_support/exnovin.py +10 -10
  137. ccxt/async_support/farhadexchange.py +12 -12
  138. ccxt/async_support/fmfwio.py +2 -1
  139. ccxt/async_support/foxbit.py +1935 -0
  140. ccxt/async_support/gate.py +1351 -529
  141. ccxt/async_support/gateio.py +2 -1
  142. ccxt/async_support/gemini.py +144 -39
  143. ccxt/async_support/hashkey.py +152 -109
  144. ccxt/async_support/hibachi.py +2080 -0
  145. ccxt/async_support/hitbtc.py +395 -167
  146. ccxt/async_support/hitobit.py +12 -12
  147. ccxt/async_support/hollaex.py +307 -119
  148. ccxt/async_support/htx.py +851 -383
  149. ccxt/async_support/huobi.py +2 -1
  150. ccxt/async_support/hyperliquid.py +1848 -536
  151. ccxt/async_support/independentreserve.py +288 -15
  152. ccxt/async_support/indodax.py +190 -33
  153. ccxt/async_support/jibitex.py +12 -12
  154. ccxt/async_support/kraken.py +795 -351
  155. ccxt/async_support/krakenfutures.py +214 -62
  156. ccxt/async_support/kucoin.py +715 -396
  157. ccxt/async_support/kucoinfutures.py +652 -89
  158. ccxt/async_support/latoken.py +217 -113
  159. ccxt/async_support/lbank.py +425 -97
  160. ccxt/async_support/luno.py +382 -35
  161. ccxt/async_support/mercado.py +113 -6
  162. ccxt/async_support/mexc.py +874 -437
  163. ccxt/async_support/modetrade.py +2818 -0
  164. ccxt/async_support/myokx.py +54 -0
  165. ccxt/async_support/ndax.py +221 -64
  166. ccxt/async_support/nobitex.py +32 -38
  167. ccxt/async_support/novadax.py +190 -34
  168. ccxt/async_support/oceanex.py +217 -28
  169. ccxt/async_support/okcoin.py +253 -145
  170. ccxt/async_support/okexchange.py +11 -11
  171. ccxt/async_support/okx.py +1088 -351
  172. ccxt/async_support/okxus.py +54 -0
  173. ccxt/async_support/ompfinex.py +32 -27
  174. ccxt/async_support/onetrading.py +213 -392
  175. ccxt/async_support/oxfun.py +245 -166
  176. ccxt/async_support/p2b.py +151 -29
  177. ccxt/async_support/paradex.py +562 -49
  178. ccxt/async_support/paymium.py +82 -19
  179. ccxt/async_support/phemex.py +713 -172
  180. ccxt/async_support/poloniex.py +1602 -283
  181. ccxt/async_support/probit.py +224 -95
  182. ccxt/async_support/ramzinex.py +34 -30
  183. ccxt/async_support/sarmayex.py +9 -9
  184. ccxt/async_support/sarrafex.py +13 -13
  185. ccxt/async_support/tabdeal.py +15 -14
  186. ccxt/async_support/tetherland.py +9 -9
  187. ccxt/async_support/timex.py +210 -51
  188. ccxt/async_support/tokocrypto.py +167 -47
  189. ccxt/async_support/tradeogre.py +266 -31
  190. ccxt/async_support/twox.py +9 -9
  191. ccxt/async_support/ubitex.py +12 -12
  192. ccxt/async_support/upbit.py +568 -165
  193. ccxt/async_support/vertex.py +160 -32
  194. ccxt/async_support/wallex.py +12 -12
  195. ccxt/async_support/wavesexchange.py +165 -30
  196. ccxt/async_support/whitebit.py +975 -127
  197. ccxt/async_support/woo.py +1918 -1016
  198. ccxt/async_support/woofipro.py +433 -141
  199. ccxt/async_support/xt.py +649 -193
  200. ccxt/async_support/yobit.py +195 -70
  201. ccxt/async_support/zaif.py +91 -15
  202. ccxt/async_support/zonda.py +151 -36
  203. ccxt/base/decimal_to_precision.py +14 -10
  204. ccxt/base/errors.py +49 -18
  205. ccxt/base/exchange.py +1556 -450
  206. ccxt/base/precise.py +10 -0
  207. ccxt/base/types.py +114 -6
  208. ccxt/bequant.py +5 -3
  209. ccxt/bigone.py +279 -144
  210. ccxt/binance.py +2347 -1158
  211. ccxt/binancecoinm.py +9 -3
  212. ccxt/binanceus.py +17 -3
  213. ccxt/binanceusdm.py +9 -4
  214. ccxt/bingx.py +2962 -920
  215. ccxt/bit2c.py +147 -27
  216. ccxt/bitbank.py +151 -23
  217. ccxt/bitbns.py +104 -30
  218. ccxt/bitfinex.py +3290 -1113
  219. ccxt/bitflyer.py +202 -27
  220. ccxt/bitget.py +3683 -1538
  221. ccxt/bithumb.py +194 -38
  222. ccxt/bitimen.py +9 -9
  223. ccxt/bitir.py +35 -35
  224. ccxt/bitmart.py +1288 -350
  225. ccxt/bitmex.py +260 -75
  226. ccxt/bitopro.py +262 -62
  227. ccxt/bitpin.py +15 -14
  228. ccxt/bitrue.py +459 -290
  229. ccxt/bitso.py +199 -54
  230. ccxt/bitstamp.py +230 -96
  231. ccxt/bitteam.py +167 -25
  232. ccxt/{huobijp.py → bittrade.py} +158 -30
  233. ccxt/bitvavo.py +213 -49
  234. ccxt/blockchaincom.py +160 -46
  235. ccxt/blofin.py +502 -120
  236. ccxt/btcalpha.py +169 -31
  237. ccxt/btcbox.py +291 -23
  238. ccxt/btcmarkets.py +211 -58
  239. ccxt/btcturk.py +161 -38
  240. ccxt/bybit.py +1775 -1030
  241. ccxt/cex.py +1439 -1303
  242. ccxt/coinbase.py +724 -212
  243. ccxt/coinbaseadvanced.py +2 -1
  244. ccxt/coinbaseexchange.py +388 -89
  245. ccxt/coinbaseinternational.py +412 -57
  246. ccxt/coincatch.py +177 -78
  247. ccxt/coincheck.py +135 -19
  248. ccxt/coinex.py +606 -232
  249. ccxt/coinmate.py +189 -63
  250. ccxt/coinmetro.py +194 -54
  251. ccxt/coinone.py +158 -51
  252. ccxt/coinsph.py +336 -61
  253. ccxt/coinspot.py +151 -52
  254. ccxt/cryptocom.py +661 -111
  255. ccxt/cryptomus.py +1137 -0
  256. ccxt/defx.py +2070 -0
  257. ccxt/delta.py +299 -99
  258. ccxt/deribit.py +348 -126
  259. ccxt/derive.py +2571 -0
  260. ccxt/digifinex.py +430 -214
  261. ccxt/ellipx.py +2029 -0
  262. ccxt/eterex.py +7 -7
  263. ccxt/excoino.py +29 -29
  264. ccxt/exir.py +11 -11
  265. ccxt/exmo.py +343 -131
  266. ccxt/exnovin.py +8 -8
  267. ccxt/farhadexchange.py +10 -10
  268. ccxt/fmfwio.py +2 -1
  269. ccxt/foxbit.py +1935 -0
  270. ccxt/gate.py +1351 -529
  271. ccxt/gateio.py +2 -1
  272. ccxt/gemini.py +144 -39
  273. ccxt/hashkey.py +152 -109
  274. ccxt/hibachi.py +2079 -0
  275. ccxt/hitbtc.py +395 -167
  276. ccxt/hitobit.py +9 -9
  277. ccxt/hollaex.py +307 -119
  278. ccxt/htx.py +851 -383
  279. ccxt/huobi.py +2 -1
  280. ccxt/hyperliquid.py +1848 -536
  281. ccxt/independentreserve.py +287 -15
  282. ccxt/indodax.py +190 -33
  283. ccxt/jibitex.py +9 -9
  284. ccxt/kraken.py +794 -351
  285. ccxt/krakenfutures.py +214 -62
  286. ccxt/kucoin.py +715 -396
  287. ccxt/kucoinfutures.py +652 -89
  288. ccxt/latoken.py +217 -113
  289. ccxt/lbank.py +425 -97
  290. ccxt/luno.py +382 -35
  291. ccxt/mercado.py +113 -6
  292. ccxt/mexc.py +873 -437
  293. ccxt/modetrade.py +2818 -0
  294. ccxt/myokx.py +54 -0
  295. ccxt/ndax.py +221 -64
  296. ccxt/nobitex.py +30 -36
  297. ccxt/novadax.py +190 -34
  298. ccxt/oceanex.py +217 -28
  299. ccxt/okcoin.py +253 -145
  300. ccxt/okexchange.py +9 -9
  301. ccxt/okx.py +1088 -351
  302. ccxt/okxus.py +54 -0
  303. ccxt/ompfinex.py +29 -24
  304. ccxt/onetrading.py +213 -392
  305. ccxt/oxfun.py +245 -166
  306. ccxt/p2b.py +151 -29
  307. ccxt/paradex.py +562 -49
  308. ccxt/paymium.py +82 -19
  309. ccxt/phemex.py +712 -172
  310. ccxt/poloniex.py +1601 -283
  311. ccxt/pro/__init__.py +76 -17
  312. ccxt/pro/alpaca.py +21 -6
  313. ccxt/pro/apex.py +984 -0
  314. ccxt/pro/ascendex.py +58 -10
  315. ccxt/pro/bequant.py +6 -1
  316. ccxt/pro/binance.py +728 -156
  317. ccxt/pro/binancecoinm.py +6 -2
  318. ccxt/pro/binanceus.py +8 -4
  319. ccxt/pro/binanceusdm.py +7 -2
  320. ccxt/pro/bingx.py +333 -142
  321. ccxt/pro/bitfinex.py +727 -262
  322. ccxt/pro/bitget.py +570 -79
  323. ccxt/pro/bithumb.py +20 -6
  324. ccxt/pro/bitmart.py +216 -87
  325. ccxt/pro/bitmex.py +47 -9
  326. ccxt/pro/bitopro.py +26 -14
  327. ccxt/pro/bitrue.py +22 -22
  328. ccxt/pro/bitstamp.py +54 -21
  329. ccxt/pro/{huobijp.py → bittrade.py} +7 -6
  330. ccxt/pro/bitvavo.py +191 -67
  331. ccxt/pro/blockchaincom.py +21 -8
  332. ccxt/pro/blofin.py +9 -1
  333. ccxt/pro/bybit.py +632 -245
  334. ccxt/pro/cex.py +59 -24
  335. ccxt/pro/coinbase.py +102 -73
  336. ccxt/pro/coinbaseadvanced.py +2 -1
  337. ccxt/pro/coinbaseexchange.py +8 -8
  338. ccxt/pro/coinbaseinternational.py +181 -25
  339. ccxt/pro/coincatch.py +6 -7
  340. ccxt/pro/coincheck.py +11 -6
  341. ccxt/pro/coinex.py +967 -665
  342. ccxt/pro/coinone.py +16 -9
  343. ccxt/pro/cryptocom.py +448 -45
  344. ccxt/pro/defx.py +831 -0
  345. ccxt/pro/deribit.py +150 -14
  346. ccxt/pro/derive.py +704 -0
  347. ccxt/pro/exmo.py +239 -6
  348. ccxt/pro/gate.py +623 -65
  349. ccxt/pro/gateio.py +2 -1
  350. ccxt/pro/gemini.py +27 -11
  351. ccxt/pro/hashkey.py +2 -2
  352. ccxt/pro/hitbtc.py +196 -91
  353. ccxt/pro/hollaex.py +23 -7
  354. ccxt/pro/htx.py +51 -14
  355. ccxt/pro/huobi.py +2 -1
  356. ccxt/pro/hyperliquid.py +591 -27
  357. ccxt/pro/independentreserve.py +9 -6
  358. ccxt/pro/kraken.py +640 -320
  359. ccxt/pro/krakenfutures.py +62 -35
  360. ccxt/pro/kucoin.py +267 -46
  361. ccxt/pro/kucoinfutures.py +165 -21
  362. ccxt/pro/lbank.py +102 -21
  363. ccxt/pro/luno.py +12 -8
  364. ccxt/pro/mexc.py +877 -111
  365. ccxt/pro/modetrade.py +1271 -0
  366. ccxt/pro/myokx.py +38 -0
  367. ccxt/pro/ndax.py +15 -2
  368. ccxt/pro/okcoin.py +23 -4
  369. ccxt/pro/okx.py +573 -98
  370. ccxt/pro/okxus.py +38 -0
  371. ccxt/pro/onetrading.py +30 -13
  372. ccxt/pro/oxfun.py +131 -27
  373. ccxt/pro/p2b.py +88 -22
  374. ccxt/pro/paradex.py +3 -3
  375. ccxt/pro/phemex.py +75 -21
  376. ccxt/pro/poloniex.py +124 -41
  377. ccxt/pro/probit.py +87 -80
  378. ccxt/pro/tradeogre.py +272 -0
  379. ccxt/pro/upbit.py +152 -12
  380. ccxt/pro/vertex.py +8 -3
  381. ccxt/pro/whitebit.py +58 -5
  382. ccxt/pro/woo.py +228 -37
  383. ccxt/pro/woofipro.py +106 -18
  384. ccxt/pro/xt.py +111 -5
  385. ccxt/probit.py +224 -95
  386. ccxt/protobuf/__init__.py +0 -0
  387. ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
  388. ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
  389. ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
  390. ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
  391. ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
  392. ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
  393. ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
  394. ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
  395. ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
  396. ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
  397. ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
  398. ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
  399. ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
  400. ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
  401. ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
  402. ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
  403. ccxt/protobuf/mexc/__init__.py +0 -0
  404. ccxt/ramzinex.py +32 -28
  405. ccxt/sarmayex.py +7 -7
  406. ccxt/sarrafex.py +10 -10
  407. ccxt/static_dependencies/__init__.py +1 -1
  408. ccxt/static_dependencies/lark/py.typed +0 -0
  409. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  410. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  411. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  412. ccxt/tabdeal.py +13 -12
  413. ccxt/test/tests_async.py +261 -57
  414. ccxt/test/tests_helpers.py +1 -3
  415. ccxt/test/tests_init.py +4 -3
  416. ccxt/test/tests_sync.py +261 -57
  417. ccxt/tetherland.py +7 -7
  418. ccxt/timex.py +210 -51
  419. ccxt/tokocrypto.py +167 -47
  420. ccxt/tradeogre.py +266 -31
  421. ccxt/twox.py +7 -7
  422. ccxt/ubitex.py +9 -9
  423. ccxt/upbit.py +568 -165
  424. ccxt/vertex.py +160 -32
  425. ccxt/wallex.py +9 -9
  426. ccxt/wavesexchange.py +165 -30
  427. ccxt/whitebit.py +975 -127
  428. ccxt/woo.py +1917 -1016
  429. ccxt/woofipro.py +432 -141
  430. ccxt/xt.py +649 -193
  431. ccxt/yobit.py +194 -70
  432. ccxt/zaif.py +91 -15
  433. ccxt/zonda.py +151 -36
  434. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/METADATA +225 -73
  435. ccxt_ir-4.5.1.dist-info/RECORD +743 -0
  436. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/WHEEL +1 -1
  437. ccxt/__test__.py +0 -7
  438. ccxt/abstract/ace.py +0 -15
  439. ccxt/abstract/bitbay.py +0 -53
  440. ccxt/abstract/bitcoincom.py +0 -115
  441. ccxt/abstract/bitfinex2.py +0 -139
  442. ccxt/abstract/bitpanda.py +0 -35
  443. ccxt/abstract/bl3p.py +0 -19
  444. ccxt/abstract/coinlist.py +0 -54
  445. ccxt/abstract/currencycom.py +0 -68
  446. ccxt/abstract/hitbtc3.py +0 -115
  447. ccxt/abstract/idex.py +0 -26
  448. ccxt/abstract/kuna.py +0 -182
  449. ccxt/abstract/lykke.py +0 -29
  450. ccxt/abstract/poloniexfutures.py +0 -48
  451. ccxt/abstract/wazirx.py +0 -30
  452. ccxt/ace.py +0 -1012
  453. ccxt/async_support/ace.py +0 -1012
  454. ccxt/async_support/base/ws/aiohttp_client.py +0 -125
  455. ccxt/async_support/base/ws/fast_client.py +0 -96
  456. ccxt/async_support/bitbay.py +0 -17
  457. ccxt/async_support/bitcoincom.py +0 -17
  458. ccxt/async_support/bitfinex2.py +0 -3552
  459. ccxt/async_support/bitpanda.py +0 -16
  460. ccxt/async_support/bl3p.py +0 -485
  461. ccxt/async_support/coinlist.py +0 -2243
  462. ccxt/async_support/currencycom.py +0 -1950
  463. ccxt/async_support/hitbtc3.py +0 -16
  464. ccxt/async_support/idex.py +0 -1766
  465. ccxt/async_support/kuna.py +0 -1841
  466. ccxt/async_support/lykke.py +0 -1270
  467. ccxt/async_support/poloniexfutures.py +0 -1717
  468. ccxt/async_support/wazirx.py +0 -1224
  469. ccxt/bitbay.py +0 -17
  470. ccxt/bitcoincom.py +0 -17
  471. ccxt/bitfinex2.py +0 -3552
  472. ccxt/bitpanda.py +0 -16
  473. ccxt/bl3p.py +0 -485
  474. ccxt/coinlist.py +0 -2243
  475. ccxt/currencycom.py +0 -1950
  476. ccxt/hitbtc3.py +0 -16
  477. ccxt/idex.py +0 -1766
  478. ccxt/kuna.py +0 -1841
  479. ccxt/lykke.py +0 -1270
  480. ccxt/poloniexfutures.py +0 -1717
  481. ccxt/pro/bitcoincom.py +0 -34
  482. ccxt/pro/bitfinex2.py +0 -1083
  483. ccxt/pro/bitpanda.py +0 -15
  484. ccxt/pro/currencycom.py +0 -536
  485. ccxt/pro/idex.py +0 -672
  486. ccxt/pro/poloniexfutures.py +0 -990
  487. ccxt/pro/wazirx.py +0 -749
  488. ccxt/test/base/__init__.py +0 -29
  489. ccxt/test/base/test_account.py +0 -26
  490. ccxt/test/base/test_balance.py +0 -56
  491. ccxt/test/base/test_borrow_interest.py +0 -35
  492. ccxt/test/base/test_borrow_rate.py +0 -32
  493. ccxt/test/base/test_calculate_fee.py +0 -51
  494. ccxt/test/base/test_crypto.py +0 -127
  495. ccxt/test/base/test_currency.py +0 -76
  496. ccxt/test/base/test_datetime.py +0 -109
  497. ccxt/test/base/test_decimal_to_precision.py +0 -392
  498. ccxt/test/base/test_deep_extend.py +0 -68
  499. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  500. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  501. ccxt/test/base/test_funding_rate_history.py +0 -29
  502. ccxt/test/base/test_last_price.py +0 -31
  503. ccxt/test/base/test_ledger_entry.py +0 -45
  504. ccxt/test/base/test_ledger_item.py +0 -48
  505. ccxt/test/base/test_leverage_tier.py +0 -33
  506. ccxt/test/base/test_liquidation.py +0 -50
  507. ccxt/test/base/test_margin_mode.py +0 -24
  508. ccxt/test/base/test_margin_modification.py +0 -35
  509. ccxt/test/base/test_market.py +0 -193
  510. ccxt/test/base/test_number.py +0 -411
  511. ccxt/test/base/test_ohlcv.py +0 -33
  512. ccxt/test/base/test_open_interest.py +0 -32
  513. ccxt/test/base/test_order.py +0 -64
  514. ccxt/test/base/test_order_book.py +0 -69
  515. ccxt/test/base/test_position.py +0 -60
  516. ccxt/test/base/test_shared_methods.py +0 -353
  517. ccxt/test/base/test_status.py +0 -24
  518. ccxt/test/base/test_throttle.py +0 -126
  519. ccxt/test/base/test_ticker.py +0 -92
  520. ccxt/test/base/test_trade.py +0 -47
  521. ccxt/test/base/test_trading_fee.py +0 -26
  522. ccxt/test/base/test_transaction.py +0 -39
  523. ccxt/test/test_async.py +0 -1649
  524. ccxt/test/test_sync.py +0 -1648
  525. ccxt/wazirx.py +0 -1224
  526. ccxt_ir-4.3.46.0.3.dist-info/RECORD +0 -773
  527. /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
  528. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info/licenses}/LICENSE.txt +0 -0
  529. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/top_level.txt +0 -0
@@ -1,1766 +0,0 @@
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.idex import ImplicitAPI
8
- import hashlib
9
- from ccxt.base.types import Balances, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees, Transaction
10
- from typing import List
11
- from ccxt.base.errors import ExchangeError
12
- from ccxt.base.errors import AuthenticationError
13
- from ccxt.base.errors import BadRequest
14
- from ccxt.base.errors import InsufficientFunds
15
- from ccxt.base.errors import InvalidAddress
16
- from ccxt.base.errors import InvalidOrder
17
- from ccxt.base.errors import NotSupported
18
- from ccxt.base.errors import DDoSProtection
19
- from ccxt.base.errors import ExchangeNotAvailable
20
- from ccxt.base.decimal_to_precision import ROUND
21
- from ccxt.base.decimal_to_precision import TRUNCATE
22
- from ccxt.base.decimal_to_precision import DECIMAL_PLACES
23
- from ccxt.base.decimal_to_precision import TICK_SIZE
24
- from ccxt.base.decimal_to_precision import PAD_WITH_ZERO
25
- from ccxt.base.precise import Precise
26
-
27
-
28
- class idex(Exchange, ImplicitAPI):
29
-
30
- def describe(self):
31
- return self.deep_extend(super(idex, self).describe(), {
32
- 'id': 'idex',
33
- 'name': 'IDEX',
34
- 'countries': ['US'],
35
- 'rateLimit': 1000,
36
- 'version': 'v3',
37
- 'pro': True,
38
- 'dex': True,
39
- 'certified': False,
40
- 'requiresWeb3': True,
41
- 'has': {
42
- 'CORS': None,
43
- 'spot': True,
44
- 'margin': False,
45
- 'swap': False,
46
- 'future': False,
47
- 'option': False,
48
- 'addMargin': False,
49
- 'cancelAllOrders': True,
50
- 'cancelOrder': True,
51
- 'cancelOrders': False,
52
- 'closeAllPositions': False,
53
- 'closePosition': False,
54
- 'createDepositAddress': False,
55
- 'createOrder': True,
56
- 'createReduceOnlyOrder': False,
57
- 'createStopLimitOrder': True,
58
- 'createStopMarketOrder': True,
59
- 'createStopOrder': True,
60
- 'fetchBalance': True,
61
- 'fetchBorrowRateHistories': False,
62
- 'fetchBorrowRateHistory': False,
63
- 'fetchClosedOrders': True,
64
- 'fetchCrossBorrowRate': False,
65
- 'fetchCrossBorrowRates': False,
66
- 'fetchCurrencies': True,
67
- 'fetchDeposit': True,
68
- 'fetchDepositAddress': True,
69
- 'fetchDepositAddresses': False,
70
- 'fetchDepositAddressesByNetwork': False,
71
- 'fetchDeposits': True,
72
- 'fetchFundingHistory': False,
73
- 'fetchFundingRate': False,
74
- 'fetchFundingRateHistory': False,
75
- 'fetchFundingRates': False,
76
- 'fetchIndexOHLCV': False,
77
- 'fetchIsolatedBorrowRate': False,
78
- 'fetchIsolatedBorrowRates': False,
79
- 'fetchLeverage': False,
80
- 'fetchLeverageTiers': False,
81
- 'fetchMarginMode': False,
82
- 'fetchMarkets': True,
83
- 'fetchMarkOHLCV': False,
84
- 'fetchMyTrades': True,
85
- 'fetchOHLCV': True,
86
- 'fetchOpenInterestHistory': False,
87
- 'fetchOpenOrders': True,
88
- 'fetchOrder': True,
89
- 'fetchOrderBook': True,
90
- 'fetchOrders': False,
91
- 'fetchPosition': False,
92
- 'fetchPositionHistory': False,
93
- 'fetchPositionMode': False,
94
- 'fetchPositions': False,
95
- 'fetchPositionsForSymbol': False,
96
- 'fetchPositionsHistory': False,
97
- 'fetchPositionsRisk': False,
98
- 'fetchPremiumIndexOHLCV': False,
99
- 'fetchStatus': True,
100
- 'fetchTicker': True,
101
- 'fetchTickers': True,
102
- 'fetchTime': True,
103
- 'fetchTrades': True,
104
- 'fetchTradingFee': False,
105
- 'fetchTradingFees': True,
106
- 'fetchTransactions': False,
107
- 'fetchWithdrawal': True,
108
- 'fetchWithdrawals': True,
109
- 'reduceMargin': False,
110
- 'sandbox': True,
111
- 'setLeverage': False,
112
- 'setMarginMode': False,
113
- 'setPositionMode': False,
114
- 'transfer': False,
115
- 'withdraw': True,
116
- },
117
- 'timeframes': {
118
- '1m': '1m',
119
- '5m': '5m',
120
- '15m': '15m',
121
- '30m': '30m',
122
- '1h': '1h',
123
- '6h': '6h',
124
- '1d': '1d',
125
- },
126
- 'urls': {
127
- 'test': {
128
- 'MATIC': 'https://api-sandbox-matic.idex.io',
129
- },
130
- 'logo': 'https://user-images.githubusercontent.com/51840849/94481303-2f222100-01e0-11eb-97dd-bc14c5943a86.jpg',
131
- 'api': {
132
- 'MATIC': 'https://api-matic.idex.io',
133
- },
134
- 'www': 'https://idex.io',
135
- 'doc': [
136
- 'https://api-docs-v3.idex.io/',
137
- ],
138
- },
139
- 'api': {
140
- 'public': {
141
- 'get': {
142
- 'ping': 1,
143
- 'time': 1,
144
- 'exchange': 1,
145
- 'assets': 1,
146
- 'markets': 1,
147
- 'tickers': 1,
148
- 'candles': 1,
149
- 'trades': 1,
150
- 'orderbook': 1,
151
- },
152
- },
153
- 'private': {
154
- 'get': {
155
- 'user': 1,
156
- 'wallets': 1,
157
- 'balances': 1,
158
- 'orders': 0.1,
159
- 'fills': 0.1,
160
- 'deposits': 1,
161
- 'withdrawals': 1,
162
- 'wsToken': 1,
163
- },
164
- 'post': {
165
- 'wallets': 1,
166
- 'orders': 0.1,
167
- 'orders/test': 0.1,
168
- 'withdrawals': 1,
169
- },
170
- 'delete': {
171
- 'orders': 0.1,
172
- },
173
- },
174
- },
175
- 'options': {
176
- 'defaultTimeInForce': 'gtc',
177
- 'defaultSelfTradePrevention': 'cn',
178
- 'network': 'MATIC',
179
- },
180
- 'exceptions': {
181
- 'exact': {
182
- 'INVALID_ORDER_QUANTITY': InvalidOrder,
183
- 'INSUFFICIENT_FUNDS': InsufficientFunds,
184
- 'SERVICE_UNAVAILABLE': ExchangeNotAvailable,
185
- 'EXCEEDED_RATE_LIMIT': DDoSProtection,
186
- 'INVALID_PARAMETER': BadRequest,
187
- 'WALLET_NOT_ASSOCIATED': InvalidAddress,
188
- 'INVALID_WALLET_SIGNATURE': AuthenticationError,
189
- },
190
- },
191
- 'requiredCredentials': {
192
- 'walletAddress': True,
193
- 'privateKey': True,
194
- 'apiKey': True,
195
- 'secret': True,
196
- },
197
- 'precisionMode': TICK_SIZE,
198
- 'paddingMode': PAD_WITH_ZERO,
199
- 'commonCurrencies': {},
200
- })
201
-
202
- def price_to_precision(self, symbol, price):
203
- #
204
- # we override priceToPrecision to fix the following issue
205
- # https://github.com/ccxt/ccxt/issues/13367
206
- # {"code":"INVALID_PARAMETER","message":"invalid value provided for request parameter \"price\": all quantities and prices must be below 100 billion, above 0, need to be provided, and always require 4 decimals ending with 4 zeroes"}
207
- #
208
- market = self.market(symbol)
209
- info = self.safe_value(market, 'info', {})
210
- quoteAssetPrecision = self.safe_integer(info, 'quoteAssetPrecision')
211
- price = self.decimal_to_precision(price, ROUND, market['precision']['price'], self.precisionMode)
212
- return self.decimal_to_precision(price, TRUNCATE, quoteAssetPrecision, DECIMAL_PLACES, PAD_WITH_ZERO)
213
-
214
- async def fetch_markets(self, params={}) -> List[Market]:
215
- """
216
- retrieves data on all markets for idex
217
- :see: https://api-docs-v3.idex.io/#get-markets
218
- :param dict [params]: extra parameters specific to the exchange API endpoint
219
- :returns dict[]: an array of objects representing market data
220
- """
221
- response = await self.publicGetMarkets(params)
222
- #
223
- # [
224
- # {
225
- # "market": "ETH-USDC",
226
- # "type": "hybrid",
227
- # "status": "activeHybrid",
228
- # "baseAsset": "ETH",
229
- # "baseAssetPrecision": "8",
230
- # "quoteAsset": "USDC",
231
- # "quoteAssetPrecision": "8",
232
- # "makerFeeRate": "0.0000",
233
- # "takerFeeRate": "0.2500",
234
- # "takerIdexFeeRate": "0.0500",
235
- # "takerLiquidityProviderFeeRate": "0.2000",
236
- # "tickSize": "0.01000000"
237
- # },
238
- # ]
239
- #
240
- response2 = await self.publicGetExchange()
241
- #
242
- # {
243
- # "timeZone": "UTC",
244
- # "serverTime": "1654460599952",
245
- # "maticDepositContractAddress": "0x3253a7e75539edaeb1db608ce6ef9aa1ac9126b6",
246
- # "maticCustodyContractAddress": "0x3bcc4eca0a40358558ca8d1bcd2d1dbde63eb468",
247
- # "maticUsdPrice": "0.60",
248
- # "gasPrice": "180",
249
- # "volume24hUsd": "10015814.46",
250
- # "totalVolumeUsd": "1589273533.28",
251
- # "totalTrades": "1534904",
252
- # "totalValueLockedUsd": "12041929.44",
253
- # "idexStakingValueLockedUsd": "20133816.98",
254
- # "idexTokenAddress": "0x9Cb74C8032b007466865f060ad2c46145d45553D",
255
- # "idexUsdPrice": "0.07",
256
- # "idexMarketCapUsd": "48012346.00",
257
- # "makerFeeRate": "0.0000",
258
- # "takerFeeRate": "0.0025",
259
- # "takerIdexFeeRate": "0.0005",
260
- # "takerLiquidityProviderFeeRate": "0.0020",
261
- # "makerTradeMinimum": "10.00000000",
262
- # "takerTradeMinimum": "1.00000000",
263
- # "withdrawMinimum": "0.50000000",
264
- # "liquidityAdditionMinimum": "0.50000000",
265
- # "liquidityRemovalMinimum": "0.40000000",
266
- # "blockConfirmationDelay": "64"
267
- # }
268
- #
269
- maker = self.safe_number(response2, 'makerFeeRate')
270
- taker = self.safe_number(response2, 'takerFeeRate')
271
- makerMin = self.safe_string(response2, 'makerTradeMinimum')
272
- takerMin = self.safe_string(response2, 'takerTradeMinimum')
273
- minCostETH = self.parse_number(Precise.string_min(makerMin, takerMin))
274
- result = []
275
- for i in range(0, len(response)):
276
- entry = response[i]
277
- marketId = self.safe_string(entry, 'market')
278
- baseId = self.safe_string(entry, 'baseAsset')
279
- quoteId = self.safe_string(entry, 'quoteAsset')
280
- base = self.safe_currency_code(baseId)
281
- quote = self.safe_currency_code(quoteId)
282
- basePrecision = self.parse_number(self.parse_precision(self.safe_string(entry, 'baseAssetPrecision')))
283
- quotePrecision = self.parse_number(self.parse_precision(self.safe_string(entry, 'quoteAssetPrecision')))
284
- status = self.safe_string(entry, 'status')
285
- minCost = None
286
- if quote == 'ETH':
287
- minCost = minCostETH
288
- result.append({
289
- 'id': marketId,
290
- 'symbol': base + '/' + quote,
291
- 'base': base,
292
- 'quote': quote,
293
- 'settle': None,
294
- 'baseId': baseId,
295
- 'quoteId': quoteId,
296
- 'settleId': None,
297
- 'type': 'spot',
298
- 'spot': True,
299
- 'margin': False,
300
- 'swap': False,
301
- 'future': False,
302
- 'option': False,
303
- 'active': (status != 'inactive'),
304
- 'contract': False,
305
- 'linear': None,
306
- 'inverse': None,
307
- 'taker': taker,
308
- 'maker': maker,
309
- 'contractSize': None,
310
- 'expiry': None,
311
- 'expiryDatetime': None,
312
- 'strike': None,
313
- 'optionType': None,
314
- 'precision': {
315
- 'amount': basePrecision,
316
- 'price': self.safe_number(entry, 'tickSize'),
317
- },
318
- 'limits': {
319
- 'leverage': {
320
- 'min': None,
321
- 'max': None,
322
- },
323
- 'amount': {
324
- 'min': basePrecision,
325
- 'max': None,
326
- },
327
- 'price': {
328
- 'min': quotePrecision,
329
- 'max': None,
330
- },
331
- 'cost': {
332
- 'min': minCost,
333
- 'max': None,
334
- },
335
- },
336
- 'created': None,
337
- 'info': entry,
338
- })
339
- return result
340
-
341
- async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
342
- """
343
- fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
344
- :see: https://api-docs-v3.idex.io/#get-tickers
345
- :param str symbol: unified symbol of the market to fetch the ticker for
346
- :param dict [params]: extra parameters specific to the exchange API endpoint
347
- :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
348
- """
349
- await self.load_markets()
350
- market = self.market(symbol)
351
- request: dict = {
352
- 'market': market['id'],
353
- }
354
- # [
355
- # {
356
- # "market": "DIL-ETH",
357
- # "time": 1598367493008,
358
- # "open": "0.09695361",
359
- # "high": "0.10245881",
360
- # "low": "0.09572507",
361
- # "close": "0.09917079",
362
- # "closeQuantity": "0.71320950",
363
- # "baseVolume": "309.17380612",
364
- # "quoteVolume": "30.57633981",
365
- # "percentChange": "2.28",
366
- # "numTrades": 205,
367
- # "ask": "0.09910476",
368
- # "bid": "0.09688340",
369
- # "sequence": 3902
370
- # }
371
- # ]
372
- response = await self.publicGetTickers(self.extend(request, params))
373
- ticker = self.safe_dict(response, 0)
374
- return self.parse_ticker(ticker, market)
375
-
376
- async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
377
- """
378
- fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
379
- :see: https://api-docs-v3.idex.io/#get-tickers
380
- :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
381
- :param dict [params]: extra parameters specific to the exchange API endpoint
382
- :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
383
- """
384
- await self.load_markets()
385
- # [
386
- # {
387
- # "market": "DIL-ETH",
388
- # "time": 1598367493008,
389
- # "open": "0.09695361",
390
- # "high": "0.10245881",
391
- # "low": "0.09572507",
392
- # "close": "0.09917079",
393
- # "closeQuantity": "0.71320950",
394
- # "baseVolume": "309.17380612",
395
- # "quoteVolume": "30.57633981",
396
- # "percentChange": "2.28",
397
- # "numTrades": 205,
398
- # "ask": "0.09910476",
399
- # "bid": "0.09688340",
400
- # "sequence": 3902
401
- # }, ...
402
- # ]
403
- response = await self.publicGetTickers(params)
404
- return self.parse_tickers(response, symbols)
405
-
406
- def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
407
- # {
408
- # "market": "DIL-ETH",
409
- # "time": 1598367493008,
410
- # "open": "0.09695361",
411
- # "high": "0.10245881",
412
- # "low": "0.09572507",
413
- # "close": "0.09917079",
414
- # "closeQuantity": "0.71320950",
415
- # "baseVolume": "309.17380612",
416
- # "quoteVolume": "30.57633981",
417
- # "percentChange": "2.28",
418
- # "numTrades": 205,
419
- # "ask": "0.09910476",
420
- # "bid": "0.09688340",
421
- # "sequence": 3902
422
- # }
423
- marketId = self.safe_string(ticker, 'market')
424
- market = self.safe_market(marketId, market, '-')
425
- symbol = market['symbol']
426
- timestamp = self.safe_integer(ticker, 'time')
427
- close = self.safe_string(ticker, 'close')
428
- return self.safe_ticker({
429
- 'symbol': symbol,
430
- 'timestamp': timestamp,
431
- 'datetime': self.iso8601(timestamp),
432
- 'high': self.safe_string(ticker, 'high'),
433
- 'low': self.safe_string(ticker, 'low'),
434
- 'bid': self.safe_string(ticker, 'bid'),
435
- 'bidVolume': None,
436
- 'ask': self.safe_string(ticker, 'ask'),
437
- 'askVolume': None,
438
- 'vwap': None,
439
- 'open': self.safe_string(ticker, 'open'),
440
- 'close': close,
441
- 'last': close,
442
- 'previousClose': None,
443
- 'change': None,
444
- 'percentage': self.safe_string(ticker, 'percentChange'),
445
- 'average': None,
446
- 'baseVolume': self.safe_string(ticker, 'baseVolume'),
447
- 'quoteVolume': self.safe_string(ticker, 'quoteVolume'),
448
- 'info': ticker,
449
- }, market)
450
-
451
- async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
452
- """
453
- fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
454
- :see: https://api-docs-v3.idex.io/#get-candles
455
- :param str symbol: unified symbol of the market to fetch OHLCV data for
456
- :param str timeframe: the length of time each candle represents
457
- :param int [since]: timestamp in ms of the earliest candle to fetch
458
- :param int [limit]: the maximum amount of candles to fetch
459
- :param dict [params]: extra parameters specific to the exchange API endpoint
460
- :returns int[][]: A list of candles ordered, open, high, low, close, volume
461
- """
462
- await self.load_markets()
463
- market = self.market(symbol)
464
- request: dict = {
465
- 'market': market['id'],
466
- 'interval': timeframe,
467
- }
468
- if since is not None:
469
- request['start'] = since
470
- if limit is not None:
471
- request['limit'] = min(limit, 1000)
472
- response = await self.publicGetCandles(self.extend(request, params))
473
- if isinstance(response, list):
474
- # [
475
- # {
476
- # "start": 1598345580000,
477
- # "open": "0.09771286",
478
- # "high": "0.09771286",
479
- # "low": "0.09771286",
480
- # "close": "0.09771286",
481
- # "volume": "1.45340410",
482
- # "sequence": 3853
483
- # }, ...
484
- # ]
485
- return self.parse_ohlcvs(response, market, timeframe, since, limit)
486
- else:
487
- # {"nextTime":1595536440000}
488
- return []
489
-
490
- def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
491
- # {
492
- # "start": 1598345580000,
493
- # "open": "0.09771286",
494
- # "high": "0.09771286",
495
- # "low": "0.09771286",
496
- # "close": "0.09771286",
497
- # "volume": "1.45340410",
498
- # "sequence": 3853
499
- # }
500
- timestamp = self.safe_integer(ohlcv, 'start')
501
- open = self.safe_number(ohlcv, 'open')
502
- high = self.safe_number(ohlcv, 'high')
503
- low = self.safe_number(ohlcv, 'low')
504
- close = self.safe_number(ohlcv, 'close')
505
- volume = self.safe_number(ohlcv, 'volume')
506
- return [timestamp, open, high, low, close, volume]
507
-
508
- async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
509
- """
510
- get the list of most recent trades for a particular symbol
511
- :see: https://api-docs-v3.idex.io/#get-trades
512
- :param str symbol: unified symbol of the market to fetch trades for
513
- :param int [since]: timestamp in ms of the earliest trade to fetch
514
- :param int [limit]: the maximum amount of trades to fetch
515
- :param dict [params]: extra parameters specific to the exchange API endpoint
516
- :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
517
- """
518
- await self.load_markets()
519
- market = self.market(symbol)
520
- request: dict = {
521
- 'market': market['id'],
522
- }
523
- if since is not None:
524
- request['start'] = since
525
- if limit is not None:
526
- request['limit'] = min(limit, 1000)
527
- # [
528
- # {
529
- # "fillId": "b5467d00-b13e-3fa9-8216-dd66735550fc",
530
- # "price": "0.09771286",
531
- # "quantity": "1.45340410",
532
- # "quoteQuantity": "0.14201627",
533
- # "time": 1598345638994,
534
- # "makerSide": "buy",
535
- # "sequence": 3853
536
- # }, ...
537
- # ]
538
- response = await self.publicGetTrades(self.extend(request, params))
539
- return self.parse_trades(response, market, since, limit)
540
-
541
- def parse_trade(self, trade: dict, market: Market = None) -> Trade:
542
- #
543
- # public trades
544
- # {
545
- # "fillId":"a4883704-850b-3c4b-8588-020b5e4c62f1",
546
- # "price":"0.20377008",
547
- # "quantity":"47.58448728",
548
- # "quoteQuantity":"9.69629509",
549
- # "time":1642091300873,
550
- # "makerSide":"buy",
551
- # "type":"hybrid", # one of either: "orderBook", "hybrid", or "pool"
552
- # "sequence":31876
553
- # }
554
- #
555
- # private trades
556
- # {
557
- # "fillId":"83429066-9334-3582-b710-78858b2f0d6b",
558
- # "price":"0.20717368",
559
- # "quantity":"15.00000000",
560
- # "quoteQuantity":"3.10760523",
561
- # "orderBookQuantity":"0.00000003",
562
- # "orderBookQuoteQuantity":"0.00000001",
563
- # "poolQuantity":"14.99999997",
564
- # "poolQuoteQuantity":"3.10760522",
565
- # "time":1642083351215,
566
- # "makerSide":"sell",
567
- # "sequence":31795,
568
- # "market":"IDEX-USDC",
569
- # "orderId":"4fe993f0-747b-11ec-bd08-79d4a0b6e47c",
570
- # "side":"buy",
571
- # "fee":"0.03749989",
572
- # "feeAsset":"IDEX",
573
- # "gas":"0.40507261",
574
- # "liquidity":"taker",
575
- # "type":"hybrid",
576
- # "txId":"0x69f6d82a762d12e3201efd0b3e9cc1969351e3c6ea3cf07c47c66bf24a459815",
577
- # "txStatus":"mined"
578
- # }
579
- #
580
- id = self.safe_string(trade, 'fillId')
581
- priceString = self.safe_string(trade, 'price')
582
- amountString = self.safe_string(trade, 'quantity')
583
- costString = self.safe_string(trade, 'quoteQuantity')
584
- timestamp = self.safe_integer(trade, 'time')
585
- marketId = self.safe_string(trade, 'market')
586
- symbol = self.safe_symbol(marketId, market, '-')
587
- # self code handles the duality of public vs private trades
588
- makerSide = self.safe_string(trade, 'makerSide')
589
- oppositeSide = 'sell' if (makerSide == 'buy') else 'buy'
590
- side = self.safe_string(trade, 'side', oppositeSide)
591
- takerOrMaker = self.safe_string(trade, 'liquidity', 'taker')
592
- feeCostString = self.safe_string(trade, 'fee')
593
- fee = None
594
- if feeCostString is not None:
595
- feeCurrencyId = self.safe_string(trade, 'feeAsset')
596
- fee = {
597
- 'cost': feeCostString,
598
- 'currency': self.safe_currency_code(feeCurrencyId),
599
- }
600
- orderId = self.safe_string(trade, 'orderId')
601
- return self.safe_trade({
602
- 'info': trade,
603
- 'timestamp': timestamp,
604
- 'datetime': self.iso8601(timestamp),
605
- 'symbol': symbol,
606
- 'id': id,
607
- 'order': orderId,
608
- 'type': 'limit',
609
- 'side': side,
610
- 'takerOrMaker': takerOrMaker,
611
- 'price': priceString,
612
- 'amount': amountString,
613
- 'cost': costString,
614
- 'fee': fee,
615
- }, market)
616
-
617
- async def fetch_trading_fees(self, params={}) -> TradingFees:
618
- """
619
- fetch the trading fees for multiple markets
620
- :see: https://api-docs-v3.idex.io/#get-api-account
621
- :param dict [params]: extra parameters specific to the exchange API endpoint
622
- :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
623
- """
624
- self.check_required_credentials()
625
- await self.load_markets()
626
- nonce = self.uuidv1()
627
- request: dict = {
628
- 'nonce': nonce,
629
- }
630
- response = None
631
- response = await self.privateGetUser(self.extend(request, params))
632
- #
633
- # {
634
- # "depositEnabled": True,
635
- # "orderEnabled": True,
636
- # "cancelEnabled": True,
637
- # "withdrawEnabled": True,
638
- # "totalPortfolioValueUsd": "0.00",
639
- # "makerFeeRate": "0.0000",
640
- # "takerFeeRate": "0.0025",
641
- # "takerIdexFeeRate": "0.0005",
642
- # "takerLiquidityProviderFeeRate": "0.0020"
643
- # }
644
- #
645
- maker = self.safe_number(response, 'makerFeeRate')
646
- taker = self.safe_number(response, 'takerFeeRate')
647
- result: dict = {}
648
- for i in range(0, len(self.symbols)):
649
- symbol = self.symbols[i]
650
- result[symbol] = {
651
- 'info': response,
652
- 'symbol': symbol,
653
- 'maker': maker,
654
- 'taker': taker,
655
- 'percentage': True,
656
- 'tierBased': False,
657
- }
658
- return result
659
-
660
- async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
661
- """
662
- fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
663
- :see: https://api-docs-v3.idex.io/#get-order-books
664
- :param str symbol: unified symbol of the market to fetch the order book for
665
- :param int [limit]: the maximum amount of order book entries to return
666
- :param dict [params]: extra parameters specific to the exchange API endpoint
667
- :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
668
- """
669
- await self.load_markets()
670
- market = self.market(symbol)
671
- request: dict = {
672
- 'market': market['id'],
673
- 'level': 2,
674
- }
675
- if limit is not None:
676
- request['limit'] = limit
677
- # {
678
- # "sequence": 36416753,
679
- # "bids": [
680
- # ['0.09672815', "8.22284267", 1],
681
- # ['0.09672814', "1.83685554", 1],
682
- # ['0.09672143', "4.10962617", 1],
683
- # ['0.09658884', "4.03863759", 1],
684
- # ['0.09653781', "3.35730684", 1],
685
- # ['0.09624660', "2.54163586", 1],
686
- # ['0.09617490', "1.93065030", 1]
687
- # ],
688
- # "asks": [
689
- # ['0.09910476', "3.22840154", 1],
690
- # ['0.09940587', "3.39796593", 1],
691
- # ['0.09948189', "4.25088898", 1],
692
- # ['0.09958362', "2.42195784", 1],
693
- # ['0.09974393', "4.25234367", 1],
694
- # ['0.09995250', "3.40192141", 1]
695
- # ]
696
- # }
697
- response = await self.publicGetOrderbook(self.extend(request, params))
698
- nonce = self.safe_integer(response, 'sequence')
699
- return {
700
- 'symbol': symbol,
701
- 'timestamp': None,
702
- 'datetime': None,
703
- 'nonce': nonce,
704
- 'bids': self.parse_side(response, 'bids'),
705
- 'asks': self.parse_side(response, 'asks'),
706
- }
707
-
708
- def parse_side(self, book, side):
709
- bookSide = self.safe_value(book, side, [])
710
- result = []
711
- for i in range(0, len(bookSide)):
712
- order = bookSide[i]
713
- price = self.safe_number(order, 0)
714
- amount = self.safe_number(order, 1)
715
- orderCount = self.safe_integer(order, 2)
716
- result.append([price, amount, orderCount])
717
- descending = side == 'bids'
718
- return self.sort_by(result, 0, descending)
719
-
720
- async def fetch_currencies(self, params={}) -> Currencies:
721
- """
722
- fetches all available currencies on an exchange
723
- :see: https://api-docs-v3.idex.io/#get-assets
724
- :param dict [params]: extra parameters specific to the exchange API endpoint
725
- :returns dict: an associative dictionary of currencies
726
- """
727
- response = await self.publicGetAssets(params)
728
- #
729
- # [
730
- # {
731
- # "name": "Ethereum",
732
- # "symbol": "ETH",
733
- # "contractAddress": "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619",
734
- # "assetDecimals": "18",
735
- # "exchangeDecimals": "8",
736
- # "maticPrice": "3029.38503483"
737
- # },
738
- # ]
739
- #
740
- result: dict = {}
741
- for i in range(0, len(response)):
742
- entry = response[i]
743
- name = self.safe_string(entry, 'name')
744
- currencyId = self.safe_string(entry, 'symbol')
745
- code = self.safe_currency_code(currencyId)
746
- precision = self.parse_number(self.parse_precision(self.safe_string(entry, 'exchangeDecimals')))
747
- result[code] = {
748
- 'id': currencyId,
749
- 'code': code,
750
- 'info': entry,
751
- 'type': None,
752
- 'name': name,
753
- 'active': None,
754
- 'deposit': None,
755
- 'withdraw': None,
756
- 'fee': None,
757
- 'precision': precision,
758
- 'limits': {
759
- 'amount': {'min': precision, 'max': None},
760
- 'withdraw': {'min': precision, 'max': None},
761
- },
762
- }
763
- return result
764
-
765
- def parse_balance(self, response) -> Balances:
766
- result: dict = {
767
- 'info': response,
768
- 'timestamp': None,
769
- 'datetime': None,
770
- }
771
- for i in range(0, len(response)):
772
- entry = response[i]
773
- currencyId = self.safe_string(entry, 'asset')
774
- code = self.safe_currency_code(currencyId)
775
- account = self.account()
776
- account['total'] = self.safe_string(entry, 'quantity')
777
- account['free'] = self.safe_string(entry, 'availableForTrade')
778
- account['used'] = self.safe_string(entry, 'locked')
779
- result[code] = account
780
- return self.safe_balance(result)
781
-
782
- async def fetch_balance(self, params={}) -> Balances:
783
- """
784
- query for balance and get the amount of funds available for trading or funds locked in orders
785
- :see: https://api-docs-v3.idex.io/#get-balances
786
- :param dict [params]: extra parameters specific to the exchange API endpoint
787
- :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
788
- """
789
- self.check_required_credentials()
790
- await self.load_markets()
791
- nonce1 = self.uuidv1()
792
- request: dict = {
793
- 'nonce': nonce1,
794
- 'wallet': self.walletAddress,
795
- }
796
- # [
797
- # {
798
- # "asset": "DIL",
799
- # "quantity": "0.00000000",
800
- # "availableForTrade": "0.00000000",
801
- # "locked": "0.00000000",
802
- # "usdValue": null
803
- # }, ...
804
- # ]
805
- extendedRequest = self.extend(request, params)
806
- if extendedRequest['wallet'] is None:
807
- raise BadRequest(self.id + ' fetchBalance() wallet is None, set self.walletAddress or "address" in params')
808
- response = None
809
- try:
810
- response = await self.privateGetBalances(extendedRequest)
811
- except Exception as e:
812
- if isinstance(e, InvalidAddress):
813
- walletAddress = extendedRequest['wallet']
814
- await self.associate_wallet(walletAddress)
815
- response = await self.privateGetBalances(extendedRequest)
816
- else:
817
- raise e
818
- return self.parse_balance(response)
819
-
820
- async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
821
- """
822
- fetch all trades made by the user
823
- :see: https://api-docs-v3.idex.io/#get-fills
824
- :param str symbol: unified market symbol
825
- :param int [since]: the earliest time in ms to fetch trades for
826
- :param int [limit]: the maximum number of trades structures to retrieve
827
- :param dict [params]: extra parameters specific to the exchange API endpoint
828
- :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
829
- """
830
- self.check_required_credentials()
831
- await self.load_markets()
832
- market = None
833
- request: dict = {
834
- 'nonce': self.uuidv1(),
835
- 'wallet': self.walletAddress,
836
- }
837
- if symbol is not None:
838
- market = self.market(symbol)
839
- request['market'] = market['id']
840
- if since is not None:
841
- request['start'] = since
842
- if limit is not None:
843
- request['limit'] = limit
844
- # [
845
- # {
846
- # "fillId": "48582d10-b9bb-3c4b-94d3-e67537cf2472",
847
- # "price": "0.09905990",
848
- # "quantity": "0.40000000",
849
- # "quoteQuantity": "0.03962396",
850
- # "time": 1598873478762,
851
- # "makerSide": "sell",
852
- # "sequence": 5053,
853
- # "market": "DIL-ETH",
854
- # "orderId": "7cdc8e90-eb7d-11ea-9e60-4118569f6e63",
855
- # "side": "buy",
856
- # "fee": "0.00080000",
857
- # "feeAsset": "DIL",
858
- # "gas": "0.00857497",
859
- # "liquidity": "taker",
860
- # "txId": "0xeaa02b112c0b8b61bc02fa1776a2b39d6c614e287c1af90df0a2e591da573e65",
861
- # "txStatus": "mined"
862
- # }
863
- # ]
864
- extendedRequest = self.extend(request, params)
865
- if extendedRequest['wallet'] is None:
866
- raise BadRequest(self.id + ' fetchMyTrades() walletAddress is None, set self.walletAddress or "address" in params')
867
- response = None
868
- try:
869
- response = await self.privateGetFills(extendedRequest)
870
- except Exception as e:
871
- if isinstance(e, InvalidAddress):
872
- walletAddress = extendedRequest['wallet']
873
- await self.associate_wallet(walletAddress)
874
- response = await self.privateGetFills(extendedRequest)
875
- else:
876
- raise e
877
- return self.parse_trades(response, market, since, limit)
878
-
879
- async def fetch_order(self, id: str, symbol: Str = None, params={}):
880
- """
881
- fetches information on an order made by the user
882
- :see: https://api-docs-v3.idex.io/#get-orders
883
- :param str symbol: unified symbol of the market the order was made in
884
- :param dict [params]: extra parameters specific to the exchange API endpoint
885
- :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
886
- """
887
- request: dict = {
888
- 'orderId': id,
889
- }
890
- return await self.fetch_orders_helper(symbol, None, None, self.extend(request, params))
891
-
892
- async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
893
- """
894
- fetch all unfilled currently open orders
895
- :see: https://api-docs-v3.idex.io/#get-orders
896
- :param str symbol: unified market symbol
897
- :param int [since]: the earliest time in ms to fetch open orders for
898
- :param int [limit]: the maximum number of open orders structures to retrieve
899
- :param dict [params]: extra parameters specific to the exchange API endpoint
900
- :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
901
- """
902
- request: dict = {
903
- 'closed': False,
904
- }
905
- return await self.fetch_orders_helper(symbol, since, limit, self.extend(request, params))
906
-
907
- async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
908
- """
909
- fetches information on multiple closed orders made by the user
910
- :see: https://api-docs-v3.idex.io/#get-orders
911
- :param str symbol: unified market symbol of the market orders were made in
912
- :param int [since]: the earliest time in ms to fetch orders for
913
- :param int [limit]: the maximum number of order structures to retrieve
914
- :param dict [params]: extra parameters specific to the exchange API endpoint
915
- :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
916
- """
917
- request: dict = {
918
- 'closed': True,
919
- }
920
- return await self.fetch_orders_helper(symbol, since, limit, self.extend(request, params))
921
-
922
- async def fetch_orders_helper(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
923
- await self.load_markets()
924
- request: dict = {
925
- 'nonce': self.uuidv1(),
926
- 'wallet': self.walletAddress,
927
- }
928
- market = None
929
- if symbol is not None:
930
- market = self.market(symbol)
931
- request['market'] = market['id']
932
- if since is not None:
933
- request['start'] = since
934
- if limit is not None:
935
- request['limit'] = limit
936
- response = await self.privateGetOrders(self.extend(request, params))
937
- # fetchClosedOrders / fetchOpenOrders
938
- # [
939
- # {
940
- # "market": "DIL-ETH",
941
- # "orderId": "7cdc8e90-eb7d-11ea-9e60-4118569f6e63",
942
- # "wallet": "0x0AB991497116f7F5532a4c2f4f7B1784488628e1",
943
- # "time": 1598873478650,
944
- # "status": "filled",
945
- # "type": "limit",
946
- # "side": "buy",
947
- # "originalQuantity": "0.40000000",
948
- # "executedQuantity": "0.40000000",
949
- # "cumulativeQuoteQuantity": "0.03962396",
950
- # "avgExecutionPrice": "0.09905990",
951
- # "price": "1.00000000",
952
- # "fills": [
953
- # {
954
- # "fillId": "48582d10-b9bb-3c4b-94d3-e67537cf2472",
955
- # "price": "0.09905990",
956
- # "quantity": "0.40000000",
957
- # "quoteQuantity": "0.03962396",
958
- # "time": 1598873478650,
959
- # "makerSide": "sell",
960
- # "sequence": 5053,
961
- # "fee": "0.00080000",
962
- # "feeAsset": "DIL",
963
- # "gas": "0.00857497",
964
- # "liquidity": "taker",
965
- # "txId": "0xeaa02b112c0b8b61bc02fa1776a2b39d6c614e287c1af90df0a2e591da573e65",
966
- # "txStatus": "mined"
967
- # }
968
- # ]
969
- # }
970
- # ]
971
- # fetchOrder
972
- # {market: "DIL-ETH",
973
- # "orderId": "7cdc8e90-eb7d-11ea-9e60-4118569f6e63",
974
- # "wallet": "0x0AB991497116f7F5532a4c2f4f7B1784488628e1",
975
- # "time": 1598873478650,
976
- # "status": "filled",
977
- # "type": "limit",
978
- # "side": "buy",
979
- # "originalQuantity": "0.40000000",
980
- # "executedQuantity": "0.40000000",
981
- # "cumulativeQuoteQuantity": "0.03962396",
982
- # "avgExecutionPrice": "0.09905990",
983
- # "price": "1.00000000",
984
- # "fills":
985
- # [{fillId: "48582d10-b9bb-3c4b-94d3-e67537cf2472",
986
- # "price": "0.09905990",
987
- # "quantity": "0.40000000",
988
- # "quoteQuantity": "0.03962396",
989
- # "time": 1598873478650,
990
- # "makerSide": "sell",
991
- # "sequence": 5053,
992
- # "fee": "0.00080000",
993
- # "feeAsset": "DIL",
994
- # "gas": "0.00857497",
995
- # "liquidity": "taker",
996
- # "txId": "0xeaa02b112c0b8b61bc02fa1776a2b39d6c614e287c1af90df0a2e591da573e65",
997
- # "txStatus": "mined"}]}
998
- if isinstance(response, list):
999
- return self.parse_orders(response, market, since, limit)
1000
- else:
1001
- return self.parse_order(response, market)
1002
-
1003
- def parse_order_status(self, status: Str):
1004
- # https://docs.idex.io/#order-states-amp-lifecycle
1005
- statuses: dict = {
1006
- 'active': 'open',
1007
- 'partiallyFilled': 'open',
1008
- 'rejected': 'canceled',
1009
- 'filled': 'closed',
1010
- }
1011
- return self.safe_string(statuses, status, status)
1012
-
1013
- def parse_order(self, order: dict, market: Market = None) -> Order:
1014
- #
1015
- # {
1016
- # "market": "DIL-ETH",
1017
- # "orderId": "7cdc8e90-eb7d-11ea-9e60-4118569f6e63",
1018
- # "wallet": "0x0AB991497116f7F5532a4c2f4f7B1784488628e1",
1019
- # "time": 1598873478650,
1020
- # "status": "filled",
1021
- # "type": "limit",
1022
- # "side": "buy",
1023
- # "originalQuantity": "0.40000000",
1024
- # "executedQuantity": "0.40000000",
1025
- # "cumulativeQuoteQuantity": "0.03962396",
1026
- # "avgExecutionPrice": "0.09905990",
1027
- # "price": "1.00000000",
1028
- # "fills": [
1029
- # {
1030
- # "fillId": "48582d10-b9bb-3c4b-94d3-e67537cf2472",
1031
- # "price": "0.09905990",
1032
- # "quantity": "0.40000000",
1033
- # "quoteQuantity": "0.03962396",
1034
- # "time": 1598873478650,
1035
- # "makerSide": "sell",
1036
- # "sequence": 5053,
1037
- # "fee": "0.00080000",
1038
- # "feeAsset": "DIL",
1039
- # "gas": "0.00857497",
1040
- # "liquidity": "taker",
1041
- # "txId": "0xeaa02b112c0b8b61bc02fa1776a2b39d6c614e287c1af90df0a2e591da573e65",
1042
- # "txStatus": "mined"
1043
- # }
1044
- # ]
1045
- # }
1046
- #
1047
- timestamp = self.safe_integer(order, 'time')
1048
- fills = self.safe_value(order, 'fills', [])
1049
- id = self.safe_string(order, 'orderId')
1050
- clientOrderId = self.safe_string(order, 'clientOrderId')
1051
- marketId = self.safe_string(order, 'market')
1052
- side = self.safe_string(order, 'side')
1053
- symbol = self.safe_symbol(marketId, market, '-')
1054
- type = self.safe_string(order, 'type')
1055
- amount = self.safe_string(order, 'originalQuantity')
1056
- filled = self.safe_string(order, 'executedQuantity')
1057
- average = self.safe_string(order, 'avgExecutionPrice')
1058
- price = self.safe_string(order, 'price')
1059
- rawStatus = self.safe_string(order, 'status')
1060
- timeInForce = self.safe_string_upper(order, 'timeInForce')
1061
- status = self.parse_order_status(rawStatus)
1062
- return self.safe_order({
1063
- 'info': order,
1064
- 'id': id,
1065
- 'clientOrderId': clientOrderId,
1066
- 'timestamp': timestamp,
1067
- 'datetime': self.iso8601(timestamp),
1068
- 'lastTradeTimestamp': None,
1069
- 'symbol': symbol,
1070
- 'type': type,
1071
- 'timeInForce': timeInForce,
1072
- 'postOnly': None,
1073
- 'side': side,
1074
- 'price': price,
1075
- 'stopPrice': None,
1076
- 'triggerPrice': None,
1077
- 'amount': amount,
1078
- 'cost': None,
1079
- 'average': average,
1080
- 'filled': filled,
1081
- 'remaining': None,
1082
- 'status': status,
1083
- 'fee': None,
1084
- 'trades': fills,
1085
- }, market)
1086
-
1087
- async def associate_wallet(self, walletAddress, params={}):
1088
- nonce = self.uuidv1()
1089
- noPrefix = self.remove0x_prefix(walletAddress)
1090
- byteArray = [
1091
- self.base16_to_binary(nonce),
1092
- self.base16_to_binary(noPrefix),
1093
- ]
1094
- binary = self.binary_concat_array(byteArray)
1095
- hash = self.hash(binary, 'keccak', 'hex')
1096
- signature = self.sign_message_string(hash, self.privateKey)
1097
- # {
1098
- # "address": "0x0AB991497116f7F5532a4c2f4f7B1784488628e1",
1099
- # "totalPortfolioValueUsd": "0.00",
1100
- # "time": 1598468353626
1101
- # }
1102
- request: dict = {
1103
- 'parameters': {
1104
- 'nonce': nonce,
1105
- 'wallet': walletAddress,
1106
- },
1107
- 'signature': signature,
1108
- }
1109
- result = await self.privatePostWallets(request)
1110
- return result
1111
-
1112
- async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1113
- """
1114
- create a trade order, https://docs.idex.io/#create-order
1115
- :see: https://api-docs-v3.idex.io/#create-order
1116
- :param str symbol: unified symbol of the market to create an order in
1117
- :param str type: 'market' or 'limit'
1118
- :param str side: 'buy' or 'sell'
1119
- :param float amount: how much of currency you want to trade in units of base currency
1120
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1121
- :param dict [params]: extra parameters specific to the exchange API endpoint
1122
- :param bool [params.test]: set to True to test an order, no order will be created but the request will be validated
1123
- :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1124
- """
1125
- self.check_required_credentials()
1126
- await self.load_markets()
1127
- testOrder = self.safe_bool(params, 'test', False)
1128
- params = self.omit(params, 'test')
1129
- market = self.market(symbol)
1130
- nonce = self.uuidv1()
1131
- typeEnum = None
1132
- stopLossTypeEnums: dict = {
1133
- 'stopLoss': 3,
1134
- 'stopLossLimit': 4,
1135
- 'takeProfit': 5,
1136
- 'takeProfitLimit': 6,
1137
- }
1138
- stopPriceString = None
1139
- if (type == 'stopLossLimit') or (type == 'takeProfitLimit') or ('stopPrice' in params):
1140
- if not ('stopPrice' in params):
1141
- raise BadRequest(self.id + ' createOrder() stopPrice is a required parameter for ' + type + 'orders')
1142
- stopPriceString = self.price_to_precision(symbol, params['stopPrice'])
1143
- limitTypeEnums: dict = {
1144
- 'limit': 1,
1145
- 'limitMaker': 2,
1146
- }
1147
- priceString = None
1148
- typeLower = type.lower()
1149
- limitOrder = typeLower.find('limit') >= 0
1150
- if type in limitTypeEnums:
1151
- typeEnum = limitTypeEnums[type]
1152
- priceString = self.price_to_precision(symbol, price)
1153
- elif type in stopLossTypeEnums:
1154
- typeEnum = stopLossTypeEnums[type]
1155
- priceString = self.price_to_precision(symbol, price)
1156
- elif type == 'market':
1157
- typeEnum = 0
1158
- else:
1159
- raise BadRequest(self.id + ' ' + type + ' is not a valid order type')
1160
- amountEnum = 0 # base quantity
1161
- if 'quoteOrderQuantity' in params:
1162
- if type != 'market':
1163
- raise NotSupported(self.id + ' createOrder() quoteOrderQuantity is not supported for ' + type + ' orders, only supported for market orders')
1164
- amountEnum = 1
1165
- amount = self.safe_number(params, 'quoteOrderQuantity')
1166
- sideEnum = 0 if (side == 'buy') else 1
1167
- walletBytes = self.remove0x_prefix(self.walletAddress)
1168
- network = self.safe_string(self.options, 'network', 'ETH')
1169
- orderVersion = self.get_supported_mapping(network, {
1170
- 'ETH': 1,
1171
- 'BSC': 2,
1172
- 'MATIC': 4,
1173
- })
1174
- amountString = self.amount_to_precision(symbol, amount)
1175
- # https://docs.idex.io/#time-in-force
1176
- timeInForceEnums: dict = {
1177
- 'gtc': 0,
1178
- 'ioc': 2,
1179
- 'fok': 3,
1180
- }
1181
- defaultTimeInForce = self.safe_string(self.options, 'defaultTimeInForce', 'gtc')
1182
- timeInForce = self.safe_string(params, 'timeInForce', defaultTimeInForce)
1183
- timeInForceEnum = None
1184
- if timeInForce in timeInForceEnums:
1185
- timeInForceEnum = timeInForceEnums[timeInForce]
1186
- else:
1187
- allOptions = list(timeInForceEnums.keys())
1188
- asString = ', '.join(allOptions)
1189
- raise BadRequest(self.id + ' ' + timeInForce + ' is not a valid timeInForce, please choose one of ' + asString)
1190
- # https://docs.idex.io/#self-trade-prevention
1191
- selfTradePreventionEnums: dict = {
1192
- 'dc': 0,
1193
- 'co': 1,
1194
- 'cn': 2,
1195
- 'cb': 3,
1196
- }
1197
- defaultSelfTradePrevention = self.safe_string(self.options, 'defaultSelfTradePrevention', 'cn')
1198
- selfTradePrevention = self.safe_string(params, 'selfTradePrevention', defaultSelfTradePrevention)
1199
- selfTradePreventionEnum = None
1200
- if selfTradePrevention in selfTradePreventionEnums:
1201
- selfTradePreventionEnum = selfTradePreventionEnums[selfTradePrevention]
1202
- else:
1203
- allOptions = list(selfTradePreventionEnums.keys())
1204
- asString = ', '.join(allOptions)
1205
- raise BadRequest(self.id + ' ' + selfTradePrevention + ' is not a valid selfTradePrevention, please choose one of ' + asString)
1206
- byteArray = [
1207
- self.number_to_be(orderVersion, 1),
1208
- self.base16_to_binary(nonce),
1209
- self.base16_to_binary(walletBytes),
1210
- self.encode(market['id']),
1211
- self.number_to_be(typeEnum, 1),
1212
- self.number_to_be(sideEnum, 1),
1213
- self.encode(amountString),
1214
- self.number_to_be(amountEnum, 1),
1215
- ]
1216
- if limitOrder:
1217
- encodedPrice = self.encode(priceString)
1218
- byteArray.append(encodedPrice)
1219
- if type in stopLossTypeEnums:
1220
- encodedPrice = self.encode(stopPriceString or priceString)
1221
- byteArray.append(encodedPrice)
1222
- clientOrderId = self.safe_string(params, 'clientOrderId')
1223
- if clientOrderId is not None:
1224
- byteArray.append(self.encode(clientOrderId))
1225
- after = [
1226
- self.number_to_be(timeInForceEnum, 1),
1227
- self.number_to_be(selfTradePreventionEnum, 1),
1228
- self.number_to_be(0, 8), # unused
1229
- ]
1230
- allBytes = self.array_concat(byteArray, after)
1231
- binary = self.binary_concat_array(allBytes)
1232
- hash = self.hash(binary, 'keccak', 'hex')
1233
- signature = self.sign_message_string(hash, self.privateKey)
1234
- request: dict = {
1235
- 'parameters': {
1236
- 'nonce': nonce,
1237
- 'market': market['id'],
1238
- 'side': side,
1239
- 'type': type,
1240
- 'wallet': self.walletAddress,
1241
- 'selfTradePrevention': selfTradePrevention,
1242
- },
1243
- 'signature': signature,
1244
- }
1245
- if type != 'market':
1246
- request['parameters']['timeInForce'] = timeInForce
1247
- if limitOrder:
1248
- request['parameters']['price'] = priceString
1249
- if type in stopLossTypeEnums:
1250
- request['parameters']['stopPrice'] = stopPriceString or priceString
1251
- if amountEnum == 0:
1252
- request['parameters']['quantity'] = amountString
1253
- else:
1254
- request['parameters']['quoteOrderQuantity'] = amountString
1255
- if clientOrderId is not None:
1256
- request['parameters']['clientOrderId'] = clientOrderId
1257
- # {
1258
- # "market": "DIL-ETH",
1259
- # "orderId": "7cdc8e90-eb7d-11ea-9e60-4118569f6e63",
1260
- # "wallet": "0x0AB991497116f7F5532a4c2f4f7B1784488628e1",
1261
- # "time": 1598873478650,
1262
- # "status": "filled",
1263
- # "type": "limit",
1264
- # "side": "buy",
1265
- # "originalQuantity": "0.40000000",
1266
- # "executedQuantity": "0.40000000",
1267
- # "cumulativeQuoteQuantity": "0.03962396",
1268
- # "price": "1.00000000",
1269
- # "fills": [
1270
- # {
1271
- # "fillId": "48582d10-b9bb-3c4b-94d3-e67537cf2472",
1272
- # "price": "0.09905990",
1273
- # "quantity": "0.40000000",
1274
- # "quoteQuantity": "0.03962396",
1275
- # "time": 1598873478650,
1276
- # "makerSide": "sell",
1277
- # "sequence": 5053,
1278
- # "fee": "0.00080000",
1279
- # "feeAsset": "DIL",
1280
- # "gas": "0.00857497",
1281
- # "liquidity": "taker",
1282
- # "txStatus": "pending"
1283
- # }
1284
- # ],
1285
- # "avgExecutionPrice": "0.09905990"
1286
- # }
1287
- # we don't use self.extend here because it is a signed endpoint
1288
- response = None
1289
- if testOrder:
1290
- response = await self.privatePostOrdersTest(request)
1291
- else:
1292
- response = await self.privatePostOrders(request)
1293
- return self.parse_order(response, market)
1294
-
1295
- async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
1296
- """
1297
- make a withdrawal
1298
- :see: https://api-docs-v3.idex.io/#withdraw-funds
1299
- :param str code: unified currency code
1300
- :param float amount: the amount to withdraw
1301
- :param str address: the address to withdraw to
1302
- :param str tag:
1303
- :param dict [params]: extra parameters specific to the exchange API endpoint
1304
- :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1305
- """
1306
- tag, params = self.handle_withdraw_tag_and_params(tag, params)
1307
- self.check_required_credentials()
1308
- await self.load_markets()
1309
- nonce = self.uuidv1()
1310
- amountString = self.currency_to_precision(code, amount)
1311
- currency = self.currency(code)
1312
- walletBytes = self.remove0x_prefix(self.walletAddress)
1313
- byteArray = [
1314
- self.base16_to_binary(nonce),
1315
- self.base16_to_binary(walletBytes),
1316
- self.encode(currency['id']),
1317
- self.encode(amountString),
1318
- self.number_to_be(1, 1), # bool set to True
1319
- ]
1320
- binary = self.binary_concat_array(byteArray)
1321
- hash = self.hash(binary, 'keccak', 'hex')
1322
- signature = self.sign_message_string(hash, self.privateKey)
1323
- request: dict = {
1324
- 'parameters': {
1325
- 'nonce': nonce,
1326
- 'wallet': address,
1327
- 'asset': currency['id'],
1328
- 'quantity': amountString,
1329
- },
1330
- 'signature': signature,
1331
- }
1332
- response = await self.privatePostWithdrawals(request)
1333
- #
1334
- # {
1335
- # "withdrawalId": "a61dcff0-ec4d-11ea-8b83-c78a6ecb3180",
1336
- # "asset": "ETH",
1337
- # "assetContractAddress": "0x0000000000000000000000000000000000000000",
1338
- # "quantity": "0.20000000",
1339
- # "time": 1598962883190,
1340
- # "fee": "0.00024000",
1341
- # "txStatus": "pending",
1342
- # "txId": null
1343
- # }
1344
- #
1345
- return self.parse_transaction(response, currency)
1346
-
1347
- async def cancel_all_orders(self, symbol: Str = None, params={}):
1348
- """
1349
- cancel all open orders
1350
- :see: https://api-docs-v3.idex.io/#cancel-order
1351
- :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
1352
- :param dict [params]: extra parameters specific to the exchange API endpoint
1353
- :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1354
- """
1355
- self.check_required_credentials()
1356
- await self.load_markets()
1357
- market = None
1358
- if symbol is not None:
1359
- market = self.market(symbol)
1360
- nonce = self.uuidv1()
1361
- request: dict = {
1362
- 'parameters': {
1363
- 'nonce': nonce,
1364
- 'wallet': self.walletAddress,
1365
- },
1366
- }
1367
- walletBytes = self.remove0x_prefix(self.walletAddress)
1368
- byteArray = [
1369
- self.base16_to_binary(nonce),
1370
- self.base16_to_binary(walletBytes),
1371
- ]
1372
- if market is not None:
1373
- byteArray.append(self.encode(market['id']))
1374
- request['parameters']['market'] = market['id']
1375
- binary = self.binary_concat_array(byteArray)
1376
- hash = self.hash(binary, 'keccak', 'hex')
1377
- signature = self.sign_message_string(hash, self.privateKey)
1378
- request['signature'] = signature
1379
- # [{orderId: "688336f0-ec50-11ea-9842-b332f8a34d0e"}]
1380
- response = await self.privateDeleteOrders(self.extend(request, params))
1381
- return self.parse_orders(response, market)
1382
-
1383
- async def cancel_order(self, id: str, symbol: Str = None, params={}):
1384
- """
1385
- cancels an open order
1386
- :see: https://api-docs-v3.idex.io/#cancel-order
1387
- :param str id: order id
1388
- :param str symbol: unified symbol of the market the order was made in
1389
- :param dict [params]: extra parameters specific to the exchange API endpoint
1390
- :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1391
- """
1392
- self.check_required_credentials()
1393
- await self.load_markets()
1394
- market = None
1395
- if symbol is not None:
1396
- market = self.market(symbol)
1397
- nonce = self.uuidv1()
1398
- walletBytes = self.remove0x_prefix(self.walletAddress)
1399
- byteArray = [
1400
- self.base16_to_binary(nonce),
1401
- self.base16_to_binary(walletBytes),
1402
- self.encode(id),
1403
- ]
1404
- binary = self.binary_concat_array(byteArray)
1405
- hash = self.hash(binary, 'keccak', 'hex')
1406
- signature = self.sign_message_string(hash, self.privateKey)
1407
- request: dict = {
1408
- 'parameters': {
1409
- 'nonce': nonce,
1410
- 'wallet': self.walletAddress,
1411
- 'orderId': id,
1412
- },
1413
- 'signature': signature,
1414
- }
1415
- # [{orderId: "688336f0-ec50-11ea-9842-b332f8a34d0e"}]
1416
- response = await self.privateDeleteOrders(self.extend(request, params))
1417
- canceledOrder = self.safe_dict(response, 0)
1418
- return self.parse_order(canceledOrder, market)
1419
-
1420
- def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
1421
- errorCode = self.safe_string(response, 'code')
1422
- message = self.safe_string(response, 'message')
1423
- if errorCode is not None:
1424
- self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, message)
1425
- raise ExchangeError(self.id + ' ' + message)
1426
- return None
1427
-
1428
- async def fetch_deposit(self, id: str, code: Str = None, params={}):
1429
- """
1430
- fetch information on a deposit
1431
- :see: https://api-docs-v3.idex.io/#get-deposits
1432
- :param str id: deposit id
1433
- :param str code: not used by idex fetchDeposit()
1434
- :param dict [params]: extra parameters specific to the exchange API endpoint
1435
- :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1436
- """
1437
- await self.load_markets()
1438
- nonce = self.uuidv1()
1439
- request: dict = {
1440
- 'nonce': nonce,
1441
- 'wallet': self.walletAddress,
1442
- 'depositId': id,
1443
- }
1444
- response = await self.privateGetDeposits(self.extend(request, params))
1445
- return self.parse_transaction(response)
1446
-
1447
- async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1448
- """
1449
- fetch all deposits made to an account
1450
- :see: https://api-docs-v3.idex.io/#get-deposits
1451
- :param str code: unified currency code
1452
- :param int [since]: the earliest time in ms to fetch deposits for
1453
- :param int [limit]: the maximum number of deposits structures to retrieve
1454
- :param dict [params]: extra parameters specific to the exchange API endpoint
1455
- :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
1456
- """
1457
- params = self.extend({
1458
- 'method': 'privateGetDeposits',
1459
- }, params)
1460
- return await self.fetch_transactions_helper(code, since, limit, params)
1461
-
1462
- async def fetch_status(self, params={}):
1463
- """
1464
- the latest known information on the availability of the exchange API
1465
- :see: https://api-docs-v3.idex.io/#get-ping
1466
- :param dict [params]: extra parameters specific to the exchange API endpoint
1467
- :returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
1468
- """
1469
- response = await self.publicGetPing(params)
1470
- return {
1471
- 'status': 'ok', # if there's no Errors, status = 'ok'
1472
- 'updated': None,
1473
- 'eta': None,
1474
- 'url': None,
1475
- 'info': response,
1476
- }
1477
-
1478
- async def fetch_time(self, params={}):
1479
- """
1480
- fetches the current integer timestamp in milliseconds from the exchange server
1481
- :see: https://api-docs-v3.idex.io/#get-time
1482
- :param dict [params]: extra parameters specific to the exchange API endpoint
1483
- :returns int: the current integer timestamp in milliseconds from the exchange server
1484
- """
1485
- response = await self.publicGetTime(params)
1486
- #
1487
- # {serverTime: "1655258263236"}
1488
- #
1489
- return self.safe_integer(response, 'serverTime')
1490
-
1491
- async def fetch_withdrawal(self, id: str, code: Str = None, params={}):
1492
- """
1493
- fetch data on a currency withdrawal via the withdrawal id
1494
- :see: https://api-docs-v3.idex.io/#get-withdrawals
1495
- :param str id: withdrawal id
1496
- :param str code: not used by idex.fetchWithdrawal
1497
- :param dict [params]: extra parameters specific to the exchange API endpoint
1498
- :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1499
- """
1500
- await self.load_markets()
1501
- nonce = self.uuidv1()
1502
- request: dict = {
1503
- 'nonce': nonce,
1504
- 'wallet': self.walletAddress,
1505
- 'withdrawalId': id,
1506
- }
1507
- response = await self.privateGetWithdrawals(self.extend(request, params))
1508
- return self.parse_transaction(response)
1509
-
1510
- async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1511
- """
1512
- fetch all withdrawals made from an account
1513
- :see: https://api-docs-v3.idex.io/#get-withdrawals
1514
- :param str code: unified currency code
1515
- :param int [since]: the earliest time in ms to fetch withdrawals for
1516
- :param int [limit]: the maximum number of withdrawals structures to retrieve
1517
- :param dict [params]: extra parameters specific to the exchange API endpoint
1518
- :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
1519
- """
1520
- params = self.extend({
1521
- 'method': 'privateGetWithdrawals',
1522
- }, params)
1523
- return await self.fetch_transactions_helper(code, since, limit, params)
1524
-
1525
- async def fetch_transactions_helper(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
1526
- await self.load_markets()
1527
- nonce = self.uuidv1()
1528
- request: dict = {
1529
- 'nonce': nonce,
1530
- 'wallet': self.walletAddress,
1531
- }
1532
- currency = None
1533
- if code is not None:
1534
- currency = self.currency(code)
1535
- request['asset'] = currency['id']
1536
- if since is not None:
1537
- request['start'] = since
1538
- if limit is not None:
1539
- request['limit'] = limit
1540
- # [
1541
- # {
1542
- # "depositId": "e9970cc0-eb6b-11ea-9e89-09a5ebc1f98e",
1543
- # "asset": "ETH",
1544
- # "quantity": "1.00000000",
1545
- # "txId": "0xcd4aac3171d7131cc9e795568c67938675185ac17641553ef54c8a7c294c8142",
1546
- # "txTime": 1598865853000,
1547
- # "confirmationTime": 1598865930231
1548
- # }
1549
- # ]
1550
- method = params['method']
1551
- params = self.omit(params, 'method')
1552
- response = None
1553
- if method == 'privateGetDeposits':
1554
- response = await self.privateGetDeposits(self.extend(request, params))
1555
- elif method == 'privateGetWithdrawals':
1556
- response = await self.privateGetWithdrawals(self.extend(request, params))
1557
- else:
1558
- raise NotSupported(self.id + ' fetchTransactionsHelper() not support self method')
1559
- return self.parse_transactions(response, currency, since, limit)
1560
-
1561
- def parse_transaction_status(self, status: Str):
1562
- statuses: dict = {
1563
- 'mined': 'ok',
1564
- }
1565
- return self.safe_string(statuses, status, status)
1566
-
1567
- def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
1568
- #
1569
- # fetchDeposits
1570
- #
1571
- # {
1572
- # "depositId": "e9970cc0-eb6b-11ea-9e89-09a5ebc1f98f",
1573
- # "asset": "ETH",
1574
- # "quantity": "1.00000000",
1575
- # "txId": "0xcd4aac3171d7131cc9e795568c67938675185ac17641553ef54c8a7c294c8142",
1576
- # "txTime": 1598865853000,
1577
- # "confirmationTime": 1598865930231
1578
- # }
1579
- #
1580
- # fetchWithdrwalas
1581
- #
1582
- # {
1583
- # "withdrawalId": "a62d8760-ec4d-11ea-9fa6-47904c19499b",
1584
- # "asset": "ETH",
1585
- # "assetContractAddress": "0x0000000000000000000000000000000000000000",
1586
- # "quantity": "0.20000000",
1587
- # "time": 1598962883288,
1588
- # "fee": "0.00024000",
1589
- # "txId": "0x305e9cdbaa85ad029f50578d13d31d777c085de573ed5334d95c19116d8c03ce",
1590
- # "txStatus": "mined"
1591
- # }
1592
- #
1593
- # withdraw
1594
- #
1595
- # {
1596
- # "withdrawalId": "a61dcff0-ec4d-11ea-8b83-c78a6ecb3180",
1597
- # "asset": "ETH",
1598
- # "assetContractAddress": "0x0000000000000000000000000000000000000000",
1599
- # "quantity": "0.20000000",
1600
- # "time": 1598962883190,
1601
- # "fee": "0.00024000",
1602
- # "txStatus": "pending",
1603
- # "txId": null
1604
- # }
1605
- #
1606
- type = None
1607
- if 'depositId' in transaction:
1608
- type = 'deposit'
1609
- elif ('withdrawId' in transaction) or ('withdrawalId' in transaction):
1610
- type = 'withdrawal'
1611
- id = self.safe_string_2(transaction, 'depositId', 'withdrawId')
1612
- id = self.safe_string(transaction, 'withdrawalId', id)
1613
- code = self.safe_currency_code(self.safe_string(transaction, 'asset'), currency)
1614
- amount = self.safe_number(transaction, 'quantity')
1615
- txid = self.safe_string(transaction, 'txId')
1616
- timestamp = self.safe_integer_2(transaction, 'txTime', 'time')
1617
- fee = None
1618
- if 'fee' in transaction:
1619
- fee = {
1620
- 'cost': self.safe_number(transaction, 'fee'),
1621
- 'currency': 'ETH',
1622
- }
1623
- rawStatus = self.safe_string(transaction, 'txStatus')
1624
- status = self.parse_transaction_status(rawStatus)
1625
- updated = self.safe_integer(transaction, 'confirmationTime')
1626
- return {
1627
- 'info': transaction,
1628
- 'id': id,
1629
- 'txid': txid,
1630
- 'timestamp': timestamp,
1631
- 'datetime': self.iso8601(timestamp),
1632
- 'network': None,
1633
- 'address': None,
1634
- 'addressTo': None,
1635
- 'addressFrom': None,
1636
- 'tag': None,
1637
- 'tagTo': None,
1638
- 'tagFrom': None,
1639
- 'type': type,
1640
- 'amount': amount,
1641
- 'currency': code,
1642
- 'status': status,
1643
- 'updated': updated,
1644
- 'comment': None,
1645
- 'internal': None,
1646
- 'fee': fee,
1647
- }
1648
-
1649
- def calculate_rate_limiter_cost(self, api, method, path, params, config={}):
1650
- hasApiKey = (self.apiKey is not None)
1651
- hasSecret = (self.secret is not None)
1652
- hasWalletAddress = (self.walletAddress is not None)
1653
- hasPrivateKey = (self.privateKey is not None)
1654
- defaultCost = self.safe_value(config, 'cost', 1)
1655
- authenticated = hasApiKey and hasSecret and hasWalletAddress and hasPrivateKey
1656
- return(defaultCost / 2) if authenticated else defaultCost
1657
-
1658
- async def fetch_deposit_address(self, code: Str = None, params={}):
1659
- """
1660
- fetch the Polygon address of the wallet
1661
- :see: https://api-docs-v3.idex.io/#get-wallets
1662
- :param str code: not used by idex
1663
- :param dict [params]: extra parameters specific to the exchange API endpoint
1664
- :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
1665
- """
1666
- request: dict = {}
1667
- request['nonce'] = self.uuidv1()
1668
- response = await self.privateGetWallets(self.extend(request, params))
1669
- #
1670
- # [
1671
- # {
1672
- # address: "0x37A1827CA64C94A26028bDCb43FBDCB0bf6DAf5B",
1673
- # totalPortfolioValueUsd: "0.00",
1674
- # time: "1678342148086"
1675
- # },
1676
- # {
1677
- # address: "0x0Ef3456E616552238B0c562d409507Ed6051A7b3",
1678
- # totalPortfolioValueUsd: "15.90",
1679
- # time: "1691697811659"
1680
- # }
1681
- # ]
1682
- #
1683
- return self.parse_deposit_address(response)
1684
-
1685
- def parse_deposit_address(self, depositAddress, currency: Currency = None):
1686
- #
1687
- # [
1688
- # {
1689
- # address: "0x37A1827CA64C94A26028bDCb43FBDCB0bf6DAf5B",
1690
- # totalPortfolioValueUsd: "0.00",
1691
- # time: "1678342148086"
1692
- # },
1693
- # {
1694
- # address: "0x0Ef3456E616552238B0c562d409507Ed6051A7b3",
1695
- # totalPortfolioValueUsd: "15.90",
1696
- # time: "1691697811659"
1697
- # }
1698
- # ]
1699
- #
1700
- length = len(depositAddress)
1701
- entry = self.safe_dict(depositAddress, length - 1)
1702
- address = self.safe_string(entry, 'address')
1703
- self.check_address(address)
1704
- return {
1705
- 'info': depositAddress,
1706
- 'currency': None,
1707
- 'address': address,
1708
- 'tag': None,
1709
- 'network': 'MATIC',
1710
- }
1711
-
1712
- def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
1713
- network = self.safe_string(self.options, 'network', 'ETH')
1714
- version = self.safe_string(self.options, 'version', 'v1')
1715
- url = self.urls['api'][network] + '/' + version + '/' + path
1716
- keys = list(params.keys())
1717
- length = len(keys)
1718
- query = None
1719
- if length > 0:
1720
- if method == 'GET':
1721
- query = self.urlencode(params)
1722
- url = url + '?' + query
1723
- else:
1724
- body = self.json(params)
1725
- headers = {
1726
- 'Content-Type': 'application/json',
1727
- }
1728
- if self.apiKey is not None:
1729
- headers['IDEX-API-Key'] = self.apiKey
1730
- if api == 'private':
1731
- payload = None
1732
- if method == 'GET':
1733
- payload = query
1734
- else:
1735
- payload = body
1736
- headers['IDEX-HMAC-Signature'] = self.hmac(self.encode(payload), self.encode(self.secret), hashlib.sha256, 'hex')
1737
- return {'url': url, 'method': method, 'body': body, 'headers': headers}
1738
-
1739
- def remove0x_prefix(self, hexData):
1740
- if hexData[0:2] == '0x':
1741
- return hexData[2:]
1742
- else:
1743
- return hexData
1744
-
1745
- def hash_message(self, message):
1746
- # takes a hex encoded message
1747
- binaryMessage = self.base16_to_binary(self.remove0x_prefix(message))
1748
- prefix = self.encode('\x19Ethereum Signed Message:\n' + binaryMessage.byteLength)
1749
- return '0x' + self.hash(self.binary_concat(prefix, binaryMessage), 'keccak', 'hex')
1750
-
1751
- def sign_hash(self, hash, privateKey):
1752
- signature = self.ecdsa(hash[-64:], privateKey[-64:], 'secp256k1', None)
1753
- return {
1754
- 'r': '0x' + signature['r'],
1755
- 's': '0x' + signature['s'],
1756
- 'v': 27 + signature['v'],
1757
- }
1758
-
1759
- def sign_message(self, message, privateKey):
1760
- return self.sign_hash(self.hash_message(message), privateKey[-64:])
1761
-
1762
- def sign_message_string(self, message, privateKey):
1763
- # still takes the input hex string
1764
- # same but returns a string instead of an object
1765
- signature = self.sign_message(message, privateKey)
1766
- return signature['r'] + self.remove0x_prefix(signature['s']) + self.binary_to_base16(self.number_to_be(signature['v'], 1))