ccxt-ir 4.3.46.0.2__py2.py3-none-any.whl → 4.5.0__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 (528) hide show
  1. ccxt/__init__.py +39 -35
  2. ccxt/abantether.py +9 -9
  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 +7 -7
  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 +10 -10
  68. ccxt/async_support/afratether.py +9 -9
  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 +31 -37
  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 +25 -24
  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 +30 -27
  183. ccxt/async_support/sarmayex.py +9 -9
  184. ccxt/async_support/sarrafex.py +13 -13
  185. ccxt/async_support/tabdeal.py +14 -13
  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 +29 -35
  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 +22 -21
  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 +28 -25
  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 +12 -11
  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.2.dist-info → ccxt_ir-4.5.0.dist-info}/METADATA +225 -73
  435. ccxt_ir-4.5.0.dist-info/RECORD +743 -0
  436. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/WHEEL +1 -1
  437. ccxt/abstract/ace.py +0 -15
  438. ccxt/abstract/bitbay.py +0 -53
  439. ccxt/abstract/bitcoincom.py +0 -115
  440. ccxt/abstract/bitfinex2.py +0 -139
  441. ccxt/abstract/bitpanda.py +0 -35
  442. ccxt/abstract/bl3p.py +0 -19
  443. ccxt/abstract/coinlist.py +0 -54
  444. ccxt/abstract/currencycom.py +0 -68
  445. ccxt/abstract/hitbtc3.py +0 -115
  446. ccxt/abstract/idex.py +0 -26
  447. ccxt/abstract/kuna.py +0 -182
  448. ccxt/abstract/lykke.py +0 -29
  449. ccxt/abstract/poloniexfutures.py +0 -48
  450. ccxt/abstract/wazirx.py +0 -30
  451. ccxt/ace.py +0 -1012
  452. ccxt/async_support/ace.py +0 -1012
  453. ccxt/async_support/base/ws/aiohttp_client.py +0 -125
  454. ccxt/async_support/base/ws/fast_client.py +0 -96
  455. ccxt/async_support/bitbay.py +0 -17
  456. ccxt/async_support/bitcoincom.py +0 -17
  457. ccxt/async_support/bitfinex2.py +0 -3552
  458. ccxt/async_support/bitpanda.py +0 -16
  459. ccxt/async_support/bl3p.py +0 -485
  460. ccxt/async_support/coinlist.py +0 -2243
  461. ccxt/async_support/currencycom.py +0 -1950
  462. ccxt/async_support/hitbtc3.py +0 -16
  463. ccxt/async_support/idex.py +0 -1766
  464. ccxt/async_support/kuna.py +0 -1841
  465. ccxt/async_support/lykke.py +0 -1270
  466. ccxt/async_support/poloniexfutures.py +0 -1717
  467. ccxt/async_support/wazirx.py +0 -1224
  468. ccxt/bitbay.py +0 -17
  469. ccxt/bitcoincom.py +0 -17
  470. ccxt/bitfinex2.py +0 -3552
  471. ccxt/bitpanda.py +0 -16
  472. ccxt/bl3p.py +0 -485
  473. ccxt/coinlist.py +0 -2243
  474. ccxt/currencycom.py +0 -1950
  475. ccxt/hitbtc3.py +0 -16
  476. ccxt/idex.py +0 -1766
  477. ccxt/kuna.py +0 -1841
  478. ccxt/lykke.py +0 -1270
  479. ccxt/poloniexfutures.py +0 -1717
  480. ccxt/pro/bitcoincom.py +0 -34
  481. ccxt/pro/bitfinex2.py +0 -1083
  482. ccxt/pro/bitpanda.py +0 -15
  483. ccxt/pro/currencycom.py +0 -536
  484. ccxt/pro/idex.py +0 -672
  485. ccxt/pro/poloniexfutures.py +0 -990
  486. ccxt/pro/wazirx.py +0 -749
  487. ccxt/test/base/__init__.py +0 -29
  488. ccxt/test/base/test_account.py +0 -26
  489. ccxt/test/base/test_balance.py +0 -56
  490. ccxt/test/base/test_borrow_interest.py +0 -35
  491. ccxt/test/base/test_borrow_rate.py +0 -32
  492. ccxt/test/base/test_calculate_fee.py +0 -51
  493. ccxt/test/base/test_crypto.py +0 -127
  494. ccxt/test/base/test_currency.py +0 -76
  495. ccxt/test/base/test_datetime.py +0 -109
  496. ccxt/test/base/test_decimal_to_precision.py +0 -392
  497. ccxt/test/base/test_deep_extend.py +0 -68
  498. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  499. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  500. ccxt/test/base/test_funding_rate_history.py +0 -29
  501. ccxt/test/base/test_last_price.py +0 -31
  502. ccxt/test/base/test_ledger_entry.py +0 -45
  503. ccxt/test/base/test_ledger_item.py +0 -48
  504. ccxt/test/base/test_leverage_tier.py +0 -33
  505. ccxt/test/base/test_liquidation.py +0 -50
  506. ccxt/test/base/test_margin_mode.py +0 -24
  507. ccxt/test/base/test_margin_modification.py +0 -35
  508. ccxt/test/base/test_market.py +0 -193
  509. ccxt/test/base/test_number.py +0 -411
  510. ccxt/test/base/test_ohlcv.py +0 -33
  511. ccxt/test/base/test_open_interest.py +0 -32
  512. ccxt/test/base/test_order.py +0 -64
  513. ccxt/test/base/test_order_book.py +0 -69
  514. ccxt/test/base/test_position.py +0 -60
  515. ccxt/test/base/test_shared_methods.py +0 -353
  516. ccxt/test/base/test_status.py +0 -24
  517. ccxt/test/base/test_throttle.py +0 -126
  518. ccxt/test/base/test_ticker.py +0 -92
  519. ccxt/test/base/test_trade.py +0 -47
  520. ccxt/test/base/test_trading_fee.py +0 -26
  521. ccxt/test/base/test_transaction.py +0 -39
  522. ccxt/test/test_async.py +0 -1649
  523. ccxt/test/test_sync.py +0 -1648
  524. ccxt/wazirx.py +0 -1224
  525. ccxt_ir-4.3.46.0.2.dist-info/RECORD +0 -772
  526. /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
  527. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info/licenses}/LICENSE.txt +0 -0
  528. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/top_level.txt +0 -0
ccxt/coinlist.py DELETED
@@ -1,2243 +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.base.exchange import Exchange
7
- from ccxt.abstract.coinlist import ImplicitAPI
8
- import hashlib
9
- import math
10
- from ccxt.base.types import Account, Balances, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees, Transaction, TransferEntry, TransferEntries
11
- from typing import List
12
- from ccxt.base.errors import ExchangeError
13
- from ccxt.base.errors import AuthenticationError
14
- from ccxt.base.errors import PermissionDenied
15
- from ccxt.base.errors import ArgumentsRequired
16
- from ccxt.base.errors import BadRequest
17
- from ccxt.base.errors import BadSymbol
18
- from ccxt.base.errors import InsufficientFunds
19
- from ccxt.base.errors import InvalidAddress
20
- from ccxt.base.errors import InvalidOrder
21
- from ccxt.base.errors import OrderNotFound
22
- from ccxt.base.errors import NotSupported
23
- from ccxt.base.errors import OnMaintenance
24
- from ccxt.base.decimal_to_precision import TICK_SIZE
25
- from ccxt.base.precise import Precise
26
-
27
-
28
- class coinlist(Exchange, ImplicitAPI):
29
-
30
- def describe(self):
31
- return self.deep_extend(super(coinlist, self).describe(), {
32
- 'id': 'coinlist',
33
- 'name': 'Coinlist',
34
- 'countries': ['US'], # United States
35
- 'version': 'v1',
36
- 'rateLimit': 300, # 1000 per 5 minutes
37
- 'certified': False,
38
- 'pro': False,
39
- 'has': {
40
- 'CORS': None,
41
- 'spot': True,
42
- 'margin': False,
43
- 'swap': False,
44
- 'future': False,
45
- 'option': False,
46
- 'addMargin': False,
47
- 'cancelAllOrders': True,
48
- 'cancelOrder': True,
49
- 'cancelOrders': True,
50
- 'closeAllPositions': False,
51
- 'closePosition': False,
52
- 'createDepositAddress': False,
53
- 'createOrder': True,
54
- 'createPostOnlyOrder': True,
55
- 'createReduceOnlyOrder': False,
56
- 'createStopLimitOrder': True,
57
- 'createStopMarketOrder': True,
58
- 'createStopOrder': True,
59
- 'deposit': False,
60
- 'editOrder': True,
61
- 'fetchAccounts': True,
62
- 'fetchBalance': True,
63
- 'fetchBidsAsks': False,
64
- 'fetchBorrowInterest': False,
65
- 'fetchBorrowRateHistories': False,
66
- 'fetchBorrowRateHistory': False,
67
- 'fetchCanceledOrders': True,
68
- 'fetchClosedOrder': False,
69
- 'fetchClosedOrders': True,
70
- 'fetchCrossBorrowRate': False,
71
- 'fetchCrossBorrowRates': False,
72
- 'fetchCurrencies': True,
73
- 'fetchDeposit': False,
74
- 'fetchDepositAddress': False,
75
- 'fetchDepositAddresses': False,
76
- 'fetchDepositAddressesByNetwork': False,
77
- 'fetchDeposits': False,
78
- 'fetchDepositsWithdrawals': True,
79
- 'fetchDepositWithdrawFee': False,
80
- 'fetchDepositWithdrawFees': False,
81
- 'fetchFundingHistory': False,
82
- 'fetchFundingRate': False,
83
- 'fetchFundingRateHistory': False,
84
- 'fetchFundingRates': False,
85
- 'fetchIndexOHLCV': False,
86
- 'fetchIsolatedBorrowRate': False,
87
- 'fetchIsolatedBorrowRates': False,
88
- 'fetchL3OrderBook': False,
89
- 'fetchLedger': True,
90
- 'fetchLeverage': False,
91
- 'fetchLeverageTiers': False,
92
- 'fetchMarketLeverageTiers': False,
93
- 'fetchMarkets': True,
94
- 'fetchMarkOHLCV': False,
95
- 'fetchMyTrades': True,
96
- 'fetchOHLCV': True,
97
- 'fetchOpenInterestHistory': False,
98
- 'fetchOpenOrder': False,
99
- 'fetchOpenOrders': True,
100
- 'fetchOrder': True,
101
- 'fetchOrderBook': True,
102
- 'fetchOrderBooks': False,
103
- 'fetchOrders': True,
104
- 'fetchOrderTrades': True,
105
- 'fetchPosition': False,
106
- 'fetchPositionHistory': False,
107
- 'fetchPositionMode': False,
108
- 'fetchPositions': False,
109
- 'fetchPositionsForSymbol': False,
110
- 'fetchPositionsHistory': False,
111
- 'fetchPositionsRisk': False,
112
- 'fetchPremiumIndexOHLCV': False,
113
- 'fetchStatus': False,
114
- 'fetchTicker': True,
115
- 'fetchTickers': True,
116
- 'fetchTime': True,
117
- 'fetchTrades': True,
118
- 'fetchTradingFee': False,
119
- 'fetchTradingFees': True,
120
- 'fetchTradingLimits': False,
121
- 'fetchTransactionFee': False,
122
- 'fetchTransactionFees': False,
123
- 'fetchTransactions': True,
124
- 'fetchTransfers': True,
125
- 'fetchWithdrawal': False,
126
- 'fetchWithdrawals': False,
127
- 'fetchWithdrawalWhitelist': False,
128
- 'reduceMargin': False,
129
- 'repayCrossMargin': False,
130
- 'repayIsolatedMargin': False,
131
- 'setLeverage': False,
132
- 'setMargin': False,
133
- 'setMarginMode': False,
134
- 'setPositionMode': False,
135
- 'signIn': False,
136
- 'transfer': True,
137
- 'withdraw': True,
138
- 'ws': False,
139
- },
140
- 'timeframes': {
141
- '1m': '1m',
142
- '5m': '5m',
143
- '30m': '30m',
144
- },
145
- 'urls': {
146
- 'logo': 'https://github-production-user-asset-6210df.s3.amazonaws.com/1294454/281108917-eff2ae1d-ce8a-4b2a-950d-8678b12da965.jpg',
147
- 'api': {
148
- 'public': 'https://trade-api.coinlist.co',
149
- 'private': 'https://trade-api.coinlist.co',
150
- },
151
- 'www': 'https://coinlist.co',
152
- 'doc': [
153
- 'https://trade-docs.coinlist.co',
154
- ],
155
- 'fees': 'https://coinlist.co/fees',
156
- },
157
- 'api': {
158
- 'public': {
159
- 'get': {
160
- 'v1/symbols': 1,
161
- 'v1/symbols/summary': 1,
162
- 'v1/symbols/{symbol}': 1, # not unified
163
- 'v1/symbols/{symbol}/summary': 1,
164
- 'v1/symbols/{symbol}/book': 1,
165
- 'v1/symbols/{symbol}/quote': 1, # not unified
166
- 'v1/symbols/{symbol}/candles': 1,
167
- 'v1/symbols/{symbol}/auctions': 1,
168
- 'v1/symbols/{symbol}/auctions/{auction_code}': 1, # not unified
169
- 'v1/time': 1,
170
- 'v1/assets': 1,
171
- 'v1/leaderboard': 1,
172
- 'v1/affiliate/{competition_code}': 1,
173
- 'v1/competition/{competition_id}': 1,
174
- },
175
- },
176
- 'private': {
177
- 'get': {
178
- 'v1/fees': 1,
179
- 'v1/accounts': 1,
180
- 'v1/accounts/{trader_id}': 1, # not unified
181
- 'v1/accounts/{trader_id}/alias': 1,
182
- 'v1/accounts/{trader_id}/ledger': 1,
183
- 'v1/accounts/{trader_id}/wallets': 1, # not unified
184
- 'v1/accounts/{trader_id}/wallet-ledger': 1,
185
- 'v1/accounts/{trader_id}/ledger-summary': 1, # not unified
186
- 'v1/keys': 1, # not unified
187
- 'v1/fills': 1,
188
- 'v1/orders': 1,
189
- 'v1/orders/{order_id}': 1,
190
- 'v1/reports': 1, # not unified
191
- 'v1/balances': 1,
192
- 'v1/transfers': 1,
193
- 'v1/user': 1, # not unified
194
- 'v1/credits': 1, # not unified
195
- 'v1/positions': 1,
196
- 'v1/accounts/{trader_id}/competitions': 1,
197
- },
198
- 'post': {
199
- 'v1/keys': 1, # not unified
200
- 'v1/orders': 1,
201
- 'v1/orders/cancel-all-after': 1, # not unified
202
- 'v1/reports': 1, # not unified
203
- 'v1/transfers/to-wallet': 1,
204
- 'v1/transfers/from-wallet': 1,
205
- 'v1/transfers/internal-transfer': 1,
206
- 'v1/transfers/withdrawal-request': 1,
207
- 'v1/orders/bulk': 1, # not unified
208
- 'v1/accounts/{trader_id}/competitions': 1,
209
- 'v1/accounts/{trader_id}/create-competition': 1,
210
- },
211
- 'patch': {
212
- 'v1/orders/{order_id}': 1,
213
- 'v1/orders/bulk': 1, # not unified
214
- },
215
- 'delete': {
216
- 'v1/keys/{key}': 1, # not unified
217
- 'v1/orders': 1,
218
- 'v1/orders/{order_id}': 1,
219
- 'v1/orders/bulk': 1,
220
- },
221
- },
222
- },
223
- 'fees': {
224
- 'trading': {
225
- 'feeSide': 'get',
226
- 'tierBased': True,
227
- 'percentage': True,
228
- 'taker': self.parse_number('0.0045'),
229
- 'maker': self.parse_number('0.0025'),
230
- 'tiers': {
231
- 'taker': [
232
- [self.parse_number('0'), self.parse_number('0.0045')],
233
- [self.parse_number('20000'), self.parse_number('0.003')],
234
- [self.parse_number('50000'), self.parse_number('0.0025')],
235
- [self.parse_number('100000'), self.parse_number('0.002')],
236
- [self.parse_number('500000'), self.parse_number('0.0018')],
237
- [self.parse_number('750000'), self.parse_number('0.0018')],
238
- [self.parse_number('1000000'), self.parse_number('0.0016')],
239
- [self.parse_number('2500000'), self.parse_number('0.0013')],
240
- [self.parse_number('5000000'), self.parse_number('0.0012')],
241
- [self.parse_number('10000000'), self.parse_number('0.001')],
242
- [self.parse_number('50000000'), self.parse_number('0.0005')],
243
- [self.parse_number('100000000'), self.parse_number('0.0005')],
244
- ],
245
- 'maker': [
246
- [self.parse_number('0'), self.parse_number('0.0025')],
247
- [self.parse_number('20000'), self.parse_number('0.0025')],
248
- [self.parse_number('50000'), self.parse_number('0.0025')],
249
- [self.parse_number('100000'), self.parse_number('0.002')],
250
- [self.parse_number('500000'), self.parse_number('0.0015')],
251
- [self.parse_number('750000'), self.parse_number('0.0012')],
252
- [self.parse_number('1000000'), self.parse_number('0.001')],
253
- [self.parse_number('2500000'), self.parse_number('0.0008')],
254
- [self.parse_number('5000000'), self.parse_number('0.0007')],
255
- [self.parse_number('10000000'), self.parse_number('0.0006')],
256
- [self.parse_number('50000000'), self.parse_number('0.0000')],
257
- [self.parse_number('100000000'), self.parse_number('0.00')],
258
- ],
259
- },
260
- },
261
- },
262
- 'precisionMode': TICK_SIZE,
263
- # exchange-specific options
264
- 'options': {
265
- 'accountsByType': {
266
- 'CoinList Pro': 'trading',
267
- 'CoinList Pro trading account': 'trading',
268
- 'Pro': 'trading',
269
- 'pro': 'trading',
270
- 'trade': 'trading',
271
- 'trading': 'trading',
272
- 'CoinList': 'funding',
273
- 'CoinList wallet': 'funding',
274
- 'Wallet': 'funding',
275
- 'wallet': 'funding',
276
- 'fund': 'funding',
277
- 'funding': 'funding',
278
- },
279
- },
280
- 'exceptions': {
281
- # https://trade-docs.coinlist.co/?javascript--nodejs#message-codes
282
- 'exact': {
283
- 'AUTH_SIG_INVALID': AuthenticationError, # {"status":400,"message":"invalid signature","message_code":"AUTH_SIG_INVALID"}
284
- 'DENIED_MAINTENANCE': OnMaintenance, # The system is under active maintenance.
285
- 'ORDER_REJECT_BAD_STATUS': InvalidOrder, # The order has a status that makes it not cancelable or modifyable.
286
- 'ORDER_REJECT_INVALID_POST_ONLY': InvalidOrder,
287
- 'ORDER_REJECT_INVALID_CLOSE_ONLY': InvalidOrder,
288
- 'ORDER_REJECT_POST_ONLY_REQUIRED': InvalidOrder, # The market currently allows only post-only orders.
289
- 'ORDER_REJECT_FROZEN_ORDER': InvalidOrder, # This operation is currently not allowed on self order at self time.
290
- 'ORDER_REJECT_LIMIT_PRICE_PROTECTION_VIOLATION': InvalidOrder, # The limit price violates the price protection range for self symbol.
291
- 'ORDER_REJECT_CLOSED': NotSupported, # The market is closed for order operations.
292
- 'ORDER_REJECT_MAX_ORDERS': BadRequest, # You have violated the 25 orders per symbol limit.
293
- 'ORDER_REJECT_NOT_FOUND': OrderNotFound, # The order to modify or cancel was not found.
294
- 'ORDER_REJECT_PARSE_ERROR': BadRequest, # The request failed to parse. Check data types.(strings vs. numbers)
295
- 'ORDER_REJECT_PRICE_INVALID': InvalidOrder, # Prices must be positive and aligned with the tick size defined for the symbol.
296
- 'ORDER_REJECT_QUANTITY_ZERO': InvalidOrder, # Quantity may not be zero.
297
- 'ORDER_REJECT_TOKEN_LIMIT': InsufficientFunds, # Your current token balance is not enough to back self order.
298
- 'ORDER_REJECT_TOKEN_LIMIT_OTHER': InvalidOrder,
299
- 'ORDER_REJECT_SELF_TRADE': InvalidOrder, # This order would have been involved in a self-trade.
300
- 'ORDER_VALIDATE_BAD_SIZE_ALIGNMENT': InvalidOrder, # {"message":"size is not aligned to 0.0001 minimum increment","message_code":"ORDER_VALIDATE_BAD_SIZE_ALIGNMENT","message_details":{"minimum_size_increment":"0.0001"}}
301
- 'ORDER_VALIDATE_BAD_TICK_ALIGNMENT': InvalidOrder, # {"message":"price is not aligned to 0.01 tick size","message_code":"ORDER_VALIDATE_BAD_TICK_ALIGNMENT","message_details":{"minimum_price_increment":{"s":1,"e":-2,"c":[1000000000000]}}}
302
- 'ORDER_VALIDATE_SYMBOL_NOT_FOUND': BadSymbol, # {"message":"symbol asdfsdfs not found","message_code":"ORDER_VALIDATE_SYMBOL_NOT_FOUND"}
303
- 'TRANSFERS_WITHDRAWAL_REQUEST_TOO_LARGE': InsufficientFunds, # {"message":"Withdrawal request too large. 0.000000000000000000 ETH available for withdrawal.","message_code":"TRANSFERS_WITHDRAWAL_REQUEST_TOO_LARGE","message_details":{"token_code":"ETH","amount":"0.010000000000000000","withdrawable_balance":"0.000000000000000000"}}
304
- 'WITHDRAWAL_REQUEST_NOT_ALLOWED': PermissionDenied, # {"message":"Withdrawal from CoinList not allowed for trader.","message_code":"WITHDRAWAL_REQUEST_NOT_ALLOWED","message_details":{"asset":"USDT","amount":"5","trader_id":"9c6f737e-a829-4843-87b1-b1ce86f2853b","destination_address":"0x9050dfA063D1bE7cA711c750b18D51fDD13e90Ee"}}
305
- },
306
- 'broad': {
307
- 'A destinationAddress is required for non-USD withdrawals': InvalidAddress, # {"status":400,"message":"400 - {\"message\":\"A destinationAddress is required for non-USD withdrawals.\"}"}
308
- 'fails to match the JsonSchema date-time format pattern': BadRequest, # {"status":401,"message":"\"end_time\" with value \"1698862680000\" fails to match the JsonSchema date-time format pattern"}
309
- 'is required': ArgumentsRequired, # {"status":400,"message":"\"type\" is required"}
310
- 'must be a string': BadRequest, # {"status":400,"message":"\"destination_address\" must be a string"}
311
- 'must be a valid GUID': BadRequest, # {"status":400,"message":"\"order_id\" must be a valid GUID"}
312
- 'must be greater than or equal to': BadRequest, # {"status":401,"message":"\"count\" must be greater than or equal to 1"}
313
- 'must be less than or equal to': BadRequest, # {"status":401,"message":"\"count\" must be less than or equal to 500"}
314
- 'must be one of': BadRequest, # {"status":401,"message":"\"granularity\" must be one of [1m, 5m, 30m]"}
315
- 'Symbol not found': BadSymbol, # {"message":"Symbol not found: {symbol}"}
316
- },
317
- },
318
- })
319
-
320
- def calculate_rate_limiter_cost(self, api, method, path, params, config={}):
321
- if isinstance(params, list):
322
- length = len(params)
323
- return int(math.ceil(length / 2))
324
- return 1
325
-
326
- def fetch_time(self, params={}):
327
- """
328
- fetches the current integer timestamp in milliseconds from the exchange server
329
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#get-system-time
330
- :param dict [params]: extra parameters specific to the exchange API endpoint
331
- :returns int: the current integer timestamp in milliseconds from the exchange server
332
- """
333
- response = self.publicGetV1Time(params)
334
- #
335
- # {
336
- # "epoch": 1698087996.039,
337
- # "iso": "2023-10-23T19:06:36.039Z"
338
- # }
339
- #
340
- string = self.safe_string(response, 'iso')
341
- return self.parse8601(string)
342
-
343
- def fetch_currencies(self, params={}) -> Currencies:
344
- """
345
- fetches all available currencies on an exchange
346
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#list-supported-assets
347
- :param dict [params]: extra parameters specific to the exchange API endpoint
348
- :returns dict: an associative dictionary of currencies
349
- """
350
- response = self.publicGetV1Assets(params)
351
- #
352
- # {
353
- # "assets": [
354
- # {
355
- # "asset": "AAVE",
356
- # "index_code": ".AAVEUSD",
357
- # "decimal_places": 18,
358
- # "min_withdrawal": "1.0000",
359
- # "is_transferable": True,
360
- # "is_visible": True
361
- # },
362
- # {
363
- # "asset": "ALGO",
364
- # "index_code": ".ALGOUSD",
365
- # "decimal_places": 6,
366
- # "min_withdrawal": "1.0000",
367
- # "is_transferable": True,
368
- # "is_visible": True
369
- # }
370
- # ]
371
- # }
372
- #
373
- currencies = self.safe_value(response, 'assets', [])
374
- result: dict = {}
375
- for i in range(0, len(currencies)):
376
- currency = currencies[i]
377
- id = self.safe_string(currency, 'asset')
378
- code = self.safe_currency_code(id)
379
- isTransferable = self.safe_bool(currency, 'is_transferable', False)
380
- withdrawEnabled = isTransferable
381
- depositEnabled = isTransferable
382
- active = isTransferable
383
- decimalPlaces = self.safe_string(currency, 'decimal_places')
384
- precision = self.parse_number(self.parse_precision(decimalPlaces))
385
- minWithdrawal = self.safe_string(currency, 'min_withdrawal')
386
- result[code] = {
387
- 'id': id,
388
- 'code': code,
389
- 'name': code,
390
- 'info': currency,
391
- 'active': active,
392
- 'deposit': depositEnabled,
393
- 'withdraw': withdrawEnabled,
394
- 'fee': None,
395
- 'precision': precision,
396
- 'limits': {
397
- 'amount': {'min': None, 'max': None},
398
- 'withdraw': {'min': minWithdrawal, 'max': None},
399
- },
400
- 'networks': {},
401
- }
402
- return result
403
-
404
- def fetch_markets(self, params={}) -> List[Market]:
405
- """
406
- retrieves data on all markets for coinlist
407
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#list-symbols
408
- :param dict [params]: extra parameters specific to the exchange API endpoint
409
- :returns dict[]: an array of objects representing market data
410
- """
411
- response = self.publicGetV1Symbols(params)
412
- #
413
- # {
414
- # "symbols": [
415
- # {
416
- # "symbol": "CQT-USDT",
417
- # "base_currency": "CQT",
418
- # "is_trader_geofenced": False,
419
- # "list_time": "2021-06-15T00:00:00.000Z",
420
- # "type": "spot",
421
- # "series_code": "CQT-USDT-SPOT",
422
- # "long_name": "Covalent",
423
- # "asset_class": "CRYPTO",
424
- # "minimum_price_increment": "0.0001",
425
- # "minimum_size_increment": "0.0001",
426
- # "quote_currency": "USDT",
427
- # "index_code": null,
428
- # "price_band_threshold_market": "0.05",
429
- # "price_band_threshold_limit": "0.25",
430
- # "last_price": "0.12160000",
431
- # "fair_price": "0.12300000",
432
- # "index_price": null
433
- # },
434
- # ]
435
- # }
436
- #
437
- markets = self.safe_value(response, 'symbols', [])
438
- return self.parse_markets(markets)
439
-
440
- def parse_market(self, market: dict) -> Market:
441
- id = self.safe_string(market, 'symbol')
442
- baseId = self.safe_string(market, 'base_currency')
443
- quoteId = self.safe_string(market, 'quote_currency')
444
- base = self.safe_currency_code(baseId)
445
- quote = self.safe_currency_code(quoteId)
446
- amountPrecision = self.safe_string(market, 'minimum_size_increment')
447
- pricePrecision = self.safe_string(market, 'minimum_price_increment')
448
- created = self.safe_string(market, 'list_time')
449
- return {
450
- 'id': id,
451
- 'symbol': base + '/' + quote,
452
- 'base': base,
453
- 'quote': quote,
454
- 'settle': None,
455
- 'baseId': baseId,
456
- 'quoteId': quoteId,
457
- 'settleId': None,
458
- 'type': 'spot',
459
- 'spot': True,
460
- 'margin': False,
461
- 'swap': False,
462
- 'future': False,
463
- 'option': False,
464
- 'active': True,
465
- 'contract': False,
466
- 'linear': None,
467
- 'inverse': None,
468
- 'contractSize': None,
469
- 'expiry': None,
470
- 'expiryDatetime': None,
471
- 'strike': None,
472
- 'optionType': None,
473
- 'precision': {
474
- 'amount': self.parse_number(amountPrecision),
475
- 'price': self.parse_number(pricePrecision),
476
- },
477
- 'limits': {
478
- 'leverage': {
479
- 'min': None,
480
- 'max': None,
481
- },
482
- 'amount': {
483
- 'min': None,
484
- 'max': None,
485
- },
486
- 'price': {
487
- 'min': None,
488
- 'max': None,
489
- },
490
- 'cost': {
491
- 'min': None,
492
- 'max': None,
493
- },
494
- },
495
- 'created': self.parse8601(created),
496
- 'info': market,
497
- }
498
-
499
- def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
500
- """
501
- fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
502
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#get-symbol-summaries
503
- :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
504
- :param dict [params]: extra parameters specific to the exchange API endpoint
505
- :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
506
- """
507
- self.load_markets()
508
- request: dict = {}
509
- tickers = self.publicGetV1SymbolsSummary(self.extend(request, params))
510
- #
511
- # {
512
- # "MATIC-USD": {
513
- # "type":"spot",
514
- # "last_price":"0.60990000",
515
- # "lowest_ask":"0.61190000",
516
- # "highest_bid":"0.60790000",
517
- # "last_trade": {
518
- # "price":"0.60000000",
519
- # "volume":"2.0000",
520
- # "imbalance":"198.0000",
521
- # "logicalTime":"2023-10-22T23:02:25.000Z",
522
- # "auctionCode":"MATIC-USD-2023-10-22T23:02:25.000Z"
523
- # },
524
- # "volume_base_24h":"34.0555",
525
- # "volume_quote_24h":"19.9282",
526
- # "price_change_percent_24h":"7.50925436",
527
- # "highest_price_24h":"0.68560000",
528
- # "lowest_price_24h":"0.55500000"
529
- # },
530
- # }
531
- #
532
- return self.parse_tickers(tickers, symbols, params)
533
-
534
- def fetch_ticker(self, symbol: str, params={}) -> Ticker:
535
- """
536
- fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
537
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#get-market-summary
538
- :param str symbol: unified symbol of the market to fetch the ticker for
539
- :param dict [params]: extra parameters specific to the exchange API endpoint
540
- :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
541
- """
542
- self.load_markets()
543
- market = self.market(symbol)
544
- request: dict = {
545
- 'symbol': market['id'],
546
- }
547
- ticker = self.publicGetV1SymbolsSymbolSummary(self.extend(request, params))
548
- #
549
- # {
550
- # "type":"spot",
551
- # "last_price":"31125.00000000",
552
- # "lowest_ask":"31349.99000000",
553
- # "highest_bid":"30900.00000000",
554
- # "last_trade": {
555
- # "price":"31000.00000000",
556
- # "volume":"0.0003",
557
- # "imbalance":"0.0000",
558
- # "logicalTime":"2023-10-23T16:57:15.000Z",
559
- # "auctionCode":"BTC-USDT-2023-10-23T16:57:15.000Z"
560
- # },
561
- # "volume_base_24h":"0.3752",
562
- # "volume_quote_24h":"11382.7181",
563
- # "price_change_percent_24h":"3.66264694",
564
- # "highest_price_24h":"31225.12000000",
565
- # "lowest_price_24h":"29792.81000000"
566
- # }
567
- #
568
- return self.parse_ticker(ticker, market)
569
-
570
- def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
571
- #
572
- # {
573
- # "type":"spot",
574
- # "last_price":"0.60990000",
575
- # "lowest_ask":"0.61190000",
576
- # "highest_bid":"0.60790000",
577
- # "last_trade": {
578
- # "price":"0.60000000",
579
- # "volume":"2.0000",
580
- # "imbalance":"198.0000",
581
- # "logicalTime":"2023-10-22T23:02:25.000Z",
582
- # "auctionCode":"MATIC-USD-2023-10-22T23:02:25.000Z"
583
- # },
584
- # "volume_base_24h":"34.0555",
585
- # "volume_quote_24h":"19.9282",
586
- # "price_change_percent_24h":"7.50925436",
587
- # "highest_price_24h":"0.68560000",
588
- # "lowest_price_24h":"0.55500000"
589
- # }
590
- #
591
- lastTrade = self.safe_value(ticker, 'last_trade', {})
592
- timestamp = self.parse8601(self.safe_string(lastTrade, 'logicalTime'))
593
- bid = self.safe_string(ticker, 'highest_bid')
594
- ask = self.safe_string(ticker, 'lowest_ask')
595
- baseVolume = self.safe_string(ticker, 'volume_base_24h')
596
- quoteVolume = self.safe_string(ticker, 'volume_quote_24h')
597
- high = self.safe_string(ticker, 'highest_price_24h')
598
- low = self.safe_string(ticker, 'lowest_price_24h')
599
- close = self.safe_string(ticker, 'last_price')
600
- changePcnt = self.safe_string(ticker, 'price_change_percent_24h')
601
- return self.safe_ticker({
602
- 'symbol': market['symbol'],
603
- 'timestamp': timestamp,
604
- 'datetime': self.iso8601(timestamp),
605
- 'open': None,
606
- 'high': high,
607
- 'low': low,
608
- 'close': close,
609
- 'bid': bid,
610
- 'bidVolume': None,
611
- 'ask': ask,
612
- 'askVolume': None,
613
- 'vwap': None,
614
- 'previousClose': None,
615
- 'change': None,
616
- 'percentage': changePcnt,
617
- 'average': None,
618
- 'baseVolume': baseVolume,
619
- 'quoteVolume': quoteVolume,
620
- 'info': ticker,
621
- }, market)
622
-
623
- def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
624
- """
625
- fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
626
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#get-order-book-level-2
627
- :param str symbol: unified symbol of the market to fetch the order book for
628
- :param int [limit]: the maximum amount of order book entries to return(default 100, max 200)
629
- :param dict [params]: extra parameters specific to the exchange API endpoint
630
- :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
631
- """
632
- self.load_markets()
633
- market = self.market(symbol)
634
- request: dict = {
635
- 'symbol': market['id'],
636
- }
637
- response = self.publicGetV1SymbolsSymbolBook(self.extend(request, params))
638
- #
639
- # {
640
- # "bids": [
641
- # ["30900.00000000", "0.0001"],
642
- # ["30664.21000000", "0.0172"],
643
- # ["30664.20000000", "0.0906"],
644
- # ],
645
- # "asks": [
646
- # ["31349.99000000", "0.0003"],
647
- # ["31350.00000000", "0.0023"],
648
- # ["31359.33000000", "0.0583"],
649
- # ],
650
- # "after_auction_code": "BTC-USDT-2023-10-23T18:40:51.000Z",
651
- # "call_time": "2023-10-23T18:40:51.068Z",
652
- # "logical_time": "2023-10-23T18:40:51.000Z"
653
- # }
654
- #
655
- logical_time = self.parse8601(self.safe_string(response, 'logical_time'))
656
- orderbook = self.parse_order_book(response, symbol, logical_time)
657
- orderbook['nonce'] = None
658
- return orderbook
659
-
660
- def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
661
- """
662
- fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
663
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#get-candles
664
- :param str symbol: unified symbol of the market to fetch OHLCV data for
665
- :param str timeframe: the length of time each candle represents
666
- :param int [since]: timestamp in ms of the earliest candle to fetch
667
- :param int [limit]: the maximum amount of candles to fetch
668
- :param dict [params]: extra parameters specific to the exchange API endpoint
669
- :param int [params.until]: the latest time in ms to fetch entries for
670
- :returns int[][]: A list of candles ordered, open, high, low, close, volume
671
- """
672
- self.load_markets()
673
- market = self.market(symbol)
674
- granularity = self.safe_string(self.timeframes, timeframe)
675
- request: dict = {
676
- 'symbol': market['id'],
677
- 'granularity': granularity,
678
- }
679
- if since is not None:
680
- request['start_time'] = self.iso8601(since)
681
- if limit is not None:
682
- duration = self.parse_timeframe(timeframe) * 1000
683
- request['end_time'] = self.iso8601(self.sum(since, duration * (limit)))
684
- else:
685
- request['end_time'] = self.iso8601(self.milliseconds())
686
- until = self.safe_integer(params, 'until')
687
- if until is not None:
688
- params = self.omit(params, ['until'])
689
- request['end_time'] = self.iso8601(until)
690
- response = self.publicGetV1SymbolsSymbolCandles(self.extend(request, params))
691
- #
692
- # {
693
- # "candles": [
694
- # [
695
- # "2023-10-17T15:00:00.000Z",
696
- # "28522.96000000",
697
- # "28522.96000000",
698
- # "28522.96000000",
699
- # "28522.96000000",
700
- # "0.1881",
701
- # null
702
- # ],
703
- # [
704
- # "2023-10-17T15:30:00.000Z",
705
- # "28582.64000000",
706
- # "28582.64000000",
707
- # "28582.64000000",
708
- # "28582.64000000",
709
- # "0.0050",
710
- # null
711
- # ]
712
- # ]
713
- # }
714
- #
715
- candles = self.safe_list(response, 'candles', [])
716
- return self.parse_ohlcvs(candles, market, timeframe, since, limit)
717
-
718
- def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
719
- #
720
- # [
721
- # "2023-10-17T15:30:00.000Z",
722
- # "28582.64000000",
723
- # "28582.64000000",
724
- # "28582.64000000",
725
- # "28582.64000000",
726
- # "0.0050",
727
- # null
728
- # ]
729
- #
730
- return [
731
- self.parse8601(self.safe_string(ohlcv, 0)),
732
- self.safe_number(ohlcv, 1),
733
- self.safe_number(ohlcv, 2),
734
- self.safe_number(ohlcv, 3),
735
- self.safe_number(ohlcv, 4),
736
- self.safe_number(ohlcv, 5),
737
- ]
738
-
739
- def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
740
- """
741
- get the list of most recent trades for a particular symbol
742
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#list-auctions
743
- :param str symbol: unified symbol of the market to fetch trades for
744
- :param int [since]: timestamp in ms of the earliest trade to fetch
745
- :param int [limit]: the maximum amount of trades to fetch(default 200, max 500)
746
- :param dict [params]: extra parameters specific to the exchange API endpoint
747
- :param int [params.until]: the latest time in ms to fetch entries for
748
- :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
749
- """
750
- self.load_markets()
751
- market = self.market(symbol)
752
- request: dict = {
753
- 'symbol': market['id'],
754
- }
755
- if since is not None:
756
- request['start_time'] = self.iso8601(since)
757
- if limit is not None:
758
- request['count'] = min(limit, 500)
759
- until = self.safe_integer(params, 'until')
760
- if until is not None:
761
- params = self.omit(params, ['until'])
762
- request['end_time'] = self.iso8601(until)
763
- response = self.publicGetV1SymbolsSymbolAuctions(self.extend(request, params))
764
- #
765
- # {
766
- # "auctions": [
767
- # {
768
- # "symbol":"BTC-USDT",
769
- # "auction_code":"BTC-USDT-2023-10-01T08:05:56.000Z",
770
- # "price":"27241.53000000",
771
- # "volume":"0.0052",
772
- # "imbalance":"-1.0983",
773
- # "logical_time":"2023-10-01T08:05:56.000Z",
774
- # "call_time":"2023-10-01T08:05:56.068Z"
775
- # },
776
- # {
777
- # "symbol":"BTC-USDT",
778
- # "auction_code":"BTC-USDT-2023-10-01T08:09:09.000Z",
779
- # "price":"27236.83000000",
780
- # "volume":"0.0283",
781
- # "imbalance":"-1.0754",
782
- # "logical_time":"2023-10-01T08:09:09.000Z",
783
- # "call_time":"2023-10-01T08:09:09.078Z"
784
- # }
785
- # ]
786
- # }
787
- #
788
- auctions = self.safe_list(response, 'auctions', [])
789
- return self.parse_trades(auctions, market, since, limit)
790
-
791
- def parse_trade(self, trade: dict, market: Market = None) -> Trade:
792
- #
793
- # fetchTrades
794
- # {
795
- # "symbol": "BTC-USDT",
796
- # "auction_code": "BTC-USDT-2023-10-01T08:05:56.000Z",
797
- # "price": "27241.53000000",
798
- # "volume": "0.0052",
799
- # "imbalance": "-1.0983",
800
- # "logical_time": "2023-10-01T08:05:56.000Z",
801
- # "call_time": "2023-10-01T08:05:56.068Z"
802
- # }
803
- #
804
- # fetchMyTrades
805
- # {
806
- # "symbol": "ETH-USDT",
807
- # "auction_code": "ETH-USDT-2023-10-20T13:22:14.000Z",
808
- # "order_id": "83ed365f-497d-433b-96c1-9d08c1a12842",
809
- # "quantity": "0.0008",
810
- # "price": "1615.24000000",
811
- # "fee": "0.005815",
812
- # "fee_type": "taker",
813
- # "fee_currency": "USDT",
814
- # "logical_time": "2023-10-20T13:22:14.000Z"
815
- # }
816
- #
817
- marketId = self.safe_string(trade, 'symbol')
818
- market = self.safe_market(marketId, market)
819
- symbol = market['symbol']
820
- id = self.safe_string(trade, 'auction_code')
821
- timestamp = self.parse8601(self.safe_string(trade, 'logical_time'))
822
- priceString = self.safe_string(trade, 'price')
823
- amountString = self.safe_string_2(trade, 'volume', 'quantity')
824
- order = self.safe_string(trade, 'order_id')
825
- fee = None
826
- side = None
827
- feeCost = self.safe_string(trade, 'fee')
828
- if feeCost is not None:
829
- # only in fetchMyTrades
830
- amountIsNegative = Precise.string_lt(amountString, '0')
831
- if amountIsNegative:
832
- side = 'sell'
833
- amountString = Precise.string_neg(amountString)
834
- else:
835
- side = 'buy'
836
- fee = {
837
- 'cost': feeCost,
838
- 'currency': self.safe_string(trade, 'fee_currency'),
839
- }
840
- else:
841
- imbalance = self.safe_string(trade, 'imbalance')
842
- if Precise.string_lt(imbalance, '0'):
843
- side = 'buy'
844
- else:
845
- side = 'sell'
846
- takerOrMaker = self.safe_string(trade, 'fee_type')
847
- return self.safe_trade({
848
- 'id': id,
849
- 'order': order,
850
- 'timestamp': timestamp,
851
- 'datetime': self.iso8601(timestamp),
852
- 'symbol': symbol,
853
- 'type': None,
854
- 'side': side,
855
- 'takerOrMaker': takerOrMaker,
856
- 'price': priceString,
857
- 'amount': amountString,
858
- 'cost': None,
859
- 'fee': fee,
860
- 'info': trade,
861
- }, market)
862
-
863
- def fetch_trading_fees(self, params={}) -> TradingFees:
864
- """
865
- fetch the trading fees for multiple markets
866
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#list-fees
867
- :param dict [params]: extra parameters specific to the exchange API endpoint
868
- :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
869
- """
870
- self.load_markets()
871
- response = self.privateGetV1Fees(params)
872
- #
873
- # {
874
- # fees_by_symbols: {
875
- # 'BTC-USD,BTC-USDT,ETH-USD,ETH-USDT,ETH-BTC,AAVE-USD,AAVE-USDT,ALGO-USD,ALGO-USDT,AVAX-USD,AVAX-USDT,BICO-USD,BICO-USDT,BLD-USD,BLD-USDT,BTRST-USDT,BZZ-USDT,CELO-USD,CELO-BTC,CFG-USD,CFG-USDT,CLV-USDT,COMP-USD,COMP-USDT,CYBER-USDT,CQT-USDT,CSPR-USD,CSPR-USDT,CUSD-USD,CUSD-USDC,DOGE-USD,DOGE-USDT,DOT-USD,DOT-USDT,EFI-USDT,FIL-USD,FIL-USDT,FLOW-USD,FLOW-USDT,GAL-USD,GAL-USDT,GODS-USDT,GOG-USDT,HMT-USD,HMT-USDT,ICP-USD,ICP-USDT,IMX-USD,IMX-USDT,LINK-USD,LINK-USDT,MATIC-USD,MATIC-USDT,MINA-USD,MINA-USDT,MKR-USD,MKR-USDT,NEON-USDT,NYM-USD,NYM-USDT,OCEAN-USD,OXT-USD,ROSE-USD,ROSE-USDT,SKL-USD,SKL-USDT,SOL-USD,SOL-USDT,STX-USDT,SUI-USDT,T-USDT,UNI-USD,UNI-USDT,USDT-USD,VEGA-USDT,WAXL-USD,WAXL-USDT,WBTC-BTC,WCFG-USD,WCFG-USDT,XTZ-USD': {
876
- # base: {
877
- # fees: {maker: '0', taker: '0.0045', liquidation: '0'},
878
- # floors: {maker: null, taker: null}
879
- # },
880
- # volume_tier_1: {
881
- # fees: {maker: '0', taker: '0.003', liquidation: '0'},
882
- # floors: {maker: null, taker: null}
883
- # },
884
- # volume_tier_2: {
885
- # fees: {maker: '0', taker: '0.0025', liquidation: '0'},
886
- # floors: {maker: null, taker: null}
887
- # },
888
- # volume_tier_3: {
889
- # fees: {maker: '0', taker: '0.002', liquidation: '0'},
890
- # floors: {maker: null, taker: null}
891
- # },
892
- # volume_tier_4: {
893
- # fees: {maker: '0', taker: '0.0018', liquidation: '0'},
894
- # floors: {maker: null, taker: null}
895
- # },
896
- # volume_tier_5: {
897
- # fees: {maker: '0', taker: '0.0018', liquidation: '0'},
898
- # floors: {maker: null, taker: null}
899
- # },
900
- # volume_tier_6: {
901
- # fees: {maker: '0', taker: '0.0016', liquidation: '0'},
902
- # floors: {maker: null, taker: null}
903
- # },
904
- # volume_tier_7: {
905
- # fees: {maker: '0', taker: '0.0013', liquidation: '0'},
906
- # floors: {maker: null, taker: null}
907
- # },
908
- # volume_tier_8: {
909
- # fees: {maker: '0', taker: '0.0012', liquidation: '0'},
910
- # floors: {maker: null, taker: null}
911
- # },
912
- # volume_tier_9: {
913
- # fees: {maker: '0', taker: '0.001', liquidation: '0'},
914
- # floors: {maker: null, taker: null}
915
- # }
916
- # volume_tier_10: {
917
- # fees: {maker: '0', taker: '0.0005', liquidation: '0'},
918
- # floors: {maker: null, taker: null}
919
- # },
920
- # volume_tier_11: {
921
- # fees: {maker: '0', taker: '0.0005', liquidation: '0'},
922
- # floors: {maker: null, taker: null}
923
- # },
924
- # }
925
- # }
926
- # }
927
- #
928
- fees = self.safe_value(response, 'fees_by_symbols', {})
929
- result: dict = {}
930
- groupsOfSymbols = list(fees.keys())
931
- for i in range(0, len(groupsOfSymbols)):
932
- group = groupsOfSymbols[i]
933
- feeTiers = self.safe_value(fees, group, {})
934
- tiers = self.parse_fee_tiers(feeTiers)
935
- firstTier = self.safe_value(feeTiers, 'base', {})
936
- firstTierFees = self.safe_value(firstTier, 'fees', {})
937
- ids = group.split(',')
938
- for j in range(0, len(ids)):
939
- id = ids[j]
940
- market = self.safe_market(id)
941
- symbol = market['symbol']
942
- info: dict = {}
943
- info[group] = feeTiers
944
- result[symbol] = {
945
- 'info': info,
946
- 'symbol': symbol,
947
- 'maker': self.safe_number(firstTierFees, 'maker'),
948
- 'taker': self.safe_number(firstTierFees, 'taker'),
949
- 'percentage': True,
950
- 'tierBased': True,
951
- 'tiers': tiers,
952
- }
953
- return result
954
-
955
- def parse_fee_tiers(self, feeTiers, market: Market = None):
956
- #
957
- # base: {
958
- # fees: {maker: '0', taker: '0.0045', liquidation: '0'},
959
- # floors: {maker: null, taker: null}
960
- # },
961
- # volume_tier_1: {
962
- # fees: {maker: '0', taker: '0.003', liquidation: '0'},
963
- # floors: {maker: null, taker: null}
964
- # },
965
- # volume_tier_2: {
966
- # fees: {maker: '0', taker: '0.0025', liquidation: '0'},
967
- # floors: {maker: null, taker: null}
968
- # },
969
- # volume_tier_3: {
970
- # fees: {maker: '0', taker: '0.002', liquidation: '0'},
971
- # floors: {maker: null, taker: null}
972
- # },
973
- # volume_tier_4: {
974
- # fees: {maker: '0', taker: '0.0018', liquidation: '0'},
975
- # floors: {maker: null, taker: null}
976
- # },
977
- # volume_tier_5: {
978
- # fees: {maker: '0', taker: '0.0018', liquidation: '0'},
979
- # floors: {maker: null, taker: null}
980
- # },
981
- # volume_tier_6: {
982
- # fees: {maker: '0', taker: '0.0016', liquidation: '0'},
983
- # floors: {maker: null, taker: null}
984
- # },
985
- # volume_tier_7: {
986
- # fees: {maker: '0', taker: '0.0013', liquidation: '0'},
987
- # floors: {maker: null, taker: null}
988
- # },
989
- # volume_tier_8: {
990
- # fees: {maker: '0', taker: '0.0012', liquidation: '0'},
991
- # floors: {maker: null, taker: null}
992
- # },
993
- # volume_tier_9: {
994
- # fees: {maker: '0', taker: '0.001', liquidation: '0'},
995
- # floors: {maker: null, taker: null}
996
- # }
997
- # volume_tier_10: {
998
- # fees: {maker: '0', taker: '0.0005', liquidation: '0'},
999
- # floors: {maker: null, taker: null}
1000
- # },
1001
- # volume_tier_11: {
1002
- # fees: {maker: '0', taker: '0.0005', liquidation: '0'},
1003
- # floors: {maker: null, taker: null}
1004
- # },
1005
- #
1006
- takerFees = []
1007
- makerFees = []
1008
- keys = list(feeTiers.keys())
1009
- keysLength = len(keys)
1010
- if keysLength > 0:
1011
- for i in range(0, keysLength):
1012
- key = keys[i]
1013
- tier = self.safe_value(feeTiers, key, {})
1014
- tierFees = self.safe_value(tier, 'fees', {})
1015
- taker = self.safe_string(tierFees, 'taker')
1016
- maker = self.safe_string(tierFees, 'maker')
1017
- makerFees.append([None, self.parse_number(maker)])
1018
- takerFees.append([None, self.parse_number(taker)])
1019
- takerFees = self.sort_by(takerFees, 1, True)
1020
- makerFees = self.sort_by(makerFees, 1, True)
1021
- firstTier = self.safe_dict(takerFees, 0, [])
1022
- exchangeFees = self.safe_dict(self, 'fees', {})
1023
- exchangeFeesTrading = self.safe_dict(exchangeFees, 'trading', {})
1024
- exchangeFeesTradingTiers = self.safe_dict(exchangeFeesTrading, 'tiers', {})
1025
- exchangeFeesTradingTiersTaker = self.safe_list(exchangeFeesTradingTiers, 'taker', [])
1026
- exchangeFeesTradingTiersMaker = self.safe_list(exchangeFeesTradingTiers, 'maker', [])
1027
- exchangeFeesTradingTiersTakerLength = len(exchangeFeesTradingTiersTaker)
1028
- firstTierLength = len(firstTier)
1029
- if (keysLength == exchangeFeesTradingTiersTakerLength) and (firstTierLength > 0):
1030
- for i in range(0, keysLength):
1031
- takerFees[i][0] = exchangeFeesTradingTiersTaker[i][0]
1032
- makerFees[i][0] = exchangeFeesTradingTiersMaker[i][0]
1033
- return {
1034
- 'maker': makerFees,
1035
- 'taker': takerFees,
1036
- }
1037
-
1038
- def fetch_accounts(self, params={}) -> List[Account]:
1039
- """
1040
- fetch all the accounts associated with a profile
1041
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#list-accounts
1042
- :param dict [params]: extra parameters specific to the exchange API endpoint
1043
- :returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
1044
- """
1045
- self.load_markets()
1046
- response = self.privateGetV1Accounts(params)
1047
- #
1048
- # {
1049
- # "accounts": [
1050
- # {
1051
- # "trader_id": "b18507ce-7d55-4bf1-b12a-0ccca5b90936",
1052
- # "name": "string"
1053
- # }
1054
- # ]
1055
- # }
1056
- #
1057
- accounts = self.safe_value(response, 'accounts', [])
1058
- return self.parse_accounts(accounts, params)
1059
-
1060
- def parse_account(self, account):
1061
- #
1062
- # {
1063
- # "trader_id": "b18507ce-7d55-4bf1-b12a-0ccca5b90936",
1064
- # "name": "string"
1065
- # }
1066
- #
1067
- return {
1068
- 'id': self.safe_string(account, 'trader_id'),
1069
- 'type': 'trading',
1070
- 'code': None,
1071
- 'info': account,
1072
- }
1073
-
1074
- def fetch_balance(self, params={}) -> Balances:
1075
- """
1076
- query for balance and get the amount of funds available for trading or funds locked in orders
1077
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#list-balances
1078
- :param dict [params]: extra parameters specific to the exchange API endpoint
1079
- :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
1080
- """
1081
- self.load_markets()
1082
- response = self.privateGetV1Balances(params)
1083
- return self.parse_balance(response)
1084
-
1085
- def parse_balance(self, response) -> Balances:
1086
- #
1087
- # {
1088
- # "asset_balances": {
1089
- # "BTC": "0.00308696",
1090
- # "ETH": "20.000000000000000000"
1091
- # },
1092
- # "asset_holds": {
1093
- # "BTC": "0.00000000",
1094
- # "ETH": "1.000000000000000000"
1095
- # },
1096
- # "net_liquidation_value_usd": "string"
1097
- # }
1098
- #
1099
- result: dict = {
1100
- 'info': response,
1101
- 'timestamp': None,
1102
- 'datetime': None,
1103
- }
1104
- totalBalances = self.safe_value(response, 'asset_balances', {})
1105
- usedBalances = self.safe_value(response, 'asset_holds', {})
1106
- currencyIds = list(totalBalances.keys())
1107
- for i in range(0, len(currencyIds)):
1108
- currencyId = currencyIds[i]
1109
- code = self.safe_currency_code(currencyId)
1110
- account = self.account()
1111
- account['total'] = self.safe_string(totalBalances, currencyId)
1112
- account['used'] = self.safe_string(usedBalances, currencyId, '0')
1113
- result[code] = account
1114
- return self.safe_balance(result)
1115
-
1116
- def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1117
- """
1118
- fetch all trades made by the user
1119
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#list-fills
1120
- :param str symbol: unified market symbol
1121
- :param int [since]: the earliest time in ms to fetch trades for
1122
- :param int [limit]: the maximum number of trades structures to retrieve(default 200, max 500)
1123
- :param dict [params]: extra parameters specific to the exchange API endpoint
1124
- :param int [params.until]: the latest time in ms to fetch entries for
1125
- :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
1126
- """
1127
- self.load_markets()
1128
- request: dict = {}
1129
- market = None
1130
- if symbol is not None:
1131
- market = self.market(symbol)
1132
- request['symbol'] = market['id']
1133
- if since is not None:
1134
- request['start_time'] = self.iso8601(since)
1135
- if limit is not None:
1136
- request['count'] = limit
1137
- until = self.safe_integer(params, 'until')
1138
- if until is not None:
1139
- params = self.omit(params, ['until'])
1140
- request['end_time'] = self.iso8601(until)
1141
- response = self.privateGetV1Fills(self.extend(request, params))
1142
- #
1143
- # {
1144
- # "fills": [
1145
- # {
1146
- # "symbol": "ETH-USDT",
1147
- # "auction_code": "ETH-USDT-2023-10-20T13:16:30.000Z",
1148
- # "order_id": "39911d5f-c789-4a7d-ad34-820a804d1da6",
1149
- # "quantity": "-0.0009",
1150
- # "price": "1608.83000000",
1151
- # "fee": "0.006516",
1152
- # "fee_type": "taker",
1153
- # "fee_currency": "USDT",
1154
- # "logical_time": "2023-10-20T13:16:30.000Z"
1155
- # },
1156
- # {
1157
- # "symbol": "ETH-USDT",
1158
- # "auction_code": "ETH-USDT-2023-10-20T13:22:14.000Z",
1159
- # "order_id": "83ed365f-497d-433b-96c1-9d08c1a12842",
1160
- # "quantity": "0.0008",
1161
- # "price": "1615.24000000",
1162
- # "fee": "0.005815",
1163
- # "fee_type": "taker",
1164
- # "fee_currency": "USDT",
1165
- # "logical_time": "2023-10-20T13:22:14.000Z"
1166
- # },
1167
- # ]
1168
- # }
1169
- #
1170
- fills = self.safe_list(response, 'fills', [])
1171
- return self.parse_trades(fills, market, since, limit)
1172
-
1173
- def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
1174
- """
1175
- fetch all the trades made from a single order
1176
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#list-fills
1177
- :param str id: order id
1178
- :param str symbol: unified market symbol
1179
- :param int [since]: the earliest time in ms to fetch trades for
1180
- :param int [limit]: the maximum number of trades to retrieve
1181
- :param dict [params]: extra parameters specific to the exchange API endpoint
1182
- :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
1183
- """
1184
- request: dict = {
1185
- 'order_id': id,
1186
- }
1187
- return self.fetch_my_trades(symbol, since, limit, self.extend(request, params))
1188
-
1189
- def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1190
- """
1191
- fetches information on multiple orders made by the user
1192
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#list-orders
1193
- :param str symbol: unified market symbol of the market orders were made in
1194
- :param int [since]: the earliest time in ms to fetch orders for
1195
- :param int [limit]: the maximum number of order structures to retrieve(default 200, max 500)
1196
- :param dict [params]: extra parameters specific to the exchange API endpoint
1197
- :param int [params.until]: the latest time in ms to fetch entries for
1198
- :param string|str[] [params.status]: the status of the order - 'accepted', 'done', 'canceled', 'rejected', 'pending'(default ['accepted', 'done', 'canceled', 'rejected', 'pending'])
1199
- :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1200
- """
1201
- self.load_markets()
1202
- status = self.safe_string(params, 'status')
1203
- if status is None:
1204
- status = ['accepted', 'done', 'canceled', 'rejected', 'pending']
1205
- request: dict = {
1206
- 'status': status,
1207
- }
1208
- market = None
1209
- if symbol is not None:
1210
- market = self.market(symbol)
1211
- request['symbol'] = market['id']
1212
- if since is not None:
1213
- request['start_time'] = self.iso8601(since)
1214
- if limit is not None:
1215
- request['count'] = limit
1216
- until = self.safe_integer(params, 'until')
1217
- if until is not None:
1218
- params = self.omit(params, ['until'])
1219
- request['end_time'] = self.iso8601(until)
1220
- response = self.privateGetV1Orders(self.extend(request, params))
1221
- #
1222
- # {
1223
- # "orders":[
1224
- # {
1225
- # "order_id":"913ea6e7-9fc9-43fb-9db1-f195d3baa93f",
1226
- # "price":"35800.00000000",
1227
- # "stop_price":null,
1228
- # "cost":"0.00000000",
1229
- # "fill_fees":"0.00000000",
1230
- # "trader_id":"9c6f737e-a829-4843-87b1-b1ce86f2853b",
1231
- # "status":"accepted",
1232
- # "epoch_timestamp":"2023-10-26T08:20:56.307Z",
1233
- # "origin":"web",
1234
- # "self_trade_prevention":null,
1235
- # "client_id":null,
1236
- # "created_at":"2023-10-26T08:20:56.307Z",
1237
- # "symbol":"BTC-USDT",
1238
- # "size":"0.0003",
1239
- # "side":"sell",
1240
- # "type":"limit",
1241
- # "post_only":false,
1242
- # "size_filled":"0.0000"
1243
- # }
1244
- # ]
1245
- # }
1246
- #
1247
- orders = self.safe_list(response, 'orders', [])
1248
- return self.parse_orders(orders, market, since, limit)
1249
-
1250
- def fetch_order(self, id: str, symbol: Str = None, params={}):
1251
- """
1252
- fetches information on an order made by the user
1253
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#get-specific-order-by-id
1254
- :param int|str id: order id
1255
- :param str symbol: not used by coinlist fetchOrder()
1256
- :param dict [params]: extra parameters specific to the exchange API endpoint
1257
- :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1258
- """
1259
- self.load_markets()
1260
- request: dict = {
1261
- 'order_id': id,
1262
- }
1263
- response = self.privateGetV1OrdersOrderId(self.extend(request, params))
1264
- #
1265
- # {
1266
- # "order_id": "93101167-9065-4b9c-b98b-5d789a3ed9fe",
1267
- # "client_id": "string",
1268
- # "symbol": "string",
1269
- # "type": "market",
1270
- # "side": "buy",
1271
- # "size": "string",
1272
- # "price": "string",
1273
- # "stop_price": "string",
1274
- # "stop_trigger": "last",
1275
- # "self_trade_prevention": "keep-newest",
1276
- # "average_fill_price": "string",
1277
- # "fill_fees": "string",
1278
- # "size_filled": "string",
1279
- # "created_at": "2019-08-24T14:15:22Z",
1280
- # "epoch_timestamp": "2019-08-24T14:15:22Z",
1281
- # "post_only": True,
1282
- # "peg_price_type": "trailing-stop",
1283
- # "peg_offset_value": "string",
1284
- # "origin": "web",
1285
- # "status": "pending"
1286
- # }
1287
- #
1288
- return self.parse_order(response)
1289
-
1290
- def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1291
- """
1292
- fetch all unfilled currently open orders
1293
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#list-orders
1294
- :param str symbol: unified market symbol
1295
- :param int [since]: the earliest time in ms to fetch open orders for
1296
- :param int [limit]: the maximum number of open order structures to retrieve(default 200, max 500)
1297
- :param dict [params]: extra parameters specific to the exchange API endpoint
1298
- :param int [params.until]: the latest time in ms to fetch entries for
1299
- :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1300
- """
1301
- self.load_markets()
1302
- request: dict = {
1303
- 'status': 'accepted',
1304
- }
1305
- return self.fetch_orders(symbol, since, limit, self.extend(request, params))
1306
-
1307
- def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1308
- """
1309
- fetches information on multiple closed orders made by the user
1310
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#list-orders
1311
- :param str symbol: unified market symbol of the market orders were made in
1312
- :param int [since]: the earliest time in ms to fetch orders for
1313
- :param int [limit]: the maximum number of closed order structures to retrieve(default 200, max 500)
1314
- :param dict [params]: extra parameters specific to the exchange API endpoint
1315
- :param int [params.until]: the latest time in ms to fetch entries for
1316
- :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1317
- """
1318
- self.load_markets()
1319
- request: dict = {
1320
- 'status': 'done',
1321
- }
1322
- return self.fetch_orders(symbol, since, limit, self.extend(request, params))
1323
-
1324
- def fetch_canceled_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1325
- """
1326
- fetches information on multiple canceled orders made by the user
1327
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#list-orders
1328
- :param str symbol: unified market symbol of the market orders were made in
1329
- :param int [since]: the earliest time in ms to fetch orders for
1330
- :param int [limit]: the maximum number of canceled order structures to retrieve(default 200, max 500)
1331
- :param dict [params]: extra parameters specific to the exchange API endpoint
1332
- :param int [params.until]: the latest time in ms to fetch entries for
1333
- :returns dict: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1334
- """
1335
- self.load_markets()
1336
- request: dict = {
1337
- 'status': 'canceled',
1338
- }
1339
- return self.fetch_orders(symbol, since, limit, self.extend(request, params))
1340
-
1341
- def cancel_all_orders(self, symbol: Str = None, params={}):
1342
- """
1343
- cancel open orders of market
1344
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#cancel-all-orders
1345
- :param str symbol: unified market symbol
1346
- :param dict [params]: extra parameters specific to the exchange API endpoint
1347
- :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1348
- """
1349
- self.load_markets()
1350
- market = None
1351
- request: dict = {}
1352
- if symbol is not None:
1353
- market = self.market(symbol)
1354
- request['symbol'] = market['id']
1355
- response = self.privateDeleteV1Orders(self.extend(request, params))
1356
- #
1357
- # {
1358
- # "message": "Order cancellation request received.",
1359
- # "timestamp": "2023-10-26T10:29:28.652Z"
1360
- # }
1361
- #
1362
- orders = [response]
1363
- return self.parse_orders(orders, market)
1364
-
1365
- def cancel_order(self, id: str, symbol: Str = None, params={}):
1366
- """
1367
- cancels an open order
1368
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#cancel-specific-order-by-id
1369
- :param str id: order id
1370
- :param str symbol: not used by coinlist cancelOrder()
1371
- :param dict [params]: extra parameters specific to the exchange API endpoint
1372
- :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1373
- """
1374
- self.load_markets()
1375
- request: dict = {
1376
- 'order_id': id,
1377
- }
1378
- response = self.privateDeleteV1OrdersOrderId(self.extend(request, params))
1379
- #
1380
- # {
1381
- # "message": "Cancel order request received.",
1382
- # "order_id": "d36e7588-6525-485c-b768-8ad8b3f745f9",
1383
- # "timestamp": "2023-10-26T14:36:37.559Z"
1384
- # }
1385
- #
1386
- return self.parse_order(response)
1387
-
1388
- def cancel_orders(self, ids, symbol: Str = None, params={}):
1389
- """
1390
- cancel multiple orders
1391
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#cancel-specific-orders
1392
- :param str[] ids: order ids
1393
- :param str symbol: not used by coinlist cancelOrders()
1394
- :param dict [params]: extra parameters specific to the exchange API endpoint
1395
- :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1396
- """
1397
- self.load_markets()
1398
- params = ids
1399
- response = self.privateDeleteV1OrdersBulk(params)
1400
- #
1401
- # {
1402
- # "message": "Cancel order requests received.",
1403
- # "order_ids": [
1404
- # "ff132955-43bc-4fe5-9d9c-5ba226cc89a0"
1405
- # ],
1406
- # "timestamp": "2024-06-01T02:32:30.305Z"
1407
- # }
1408
- #
1409
- orderIds = self.safe_list(response, 'order_ids', [])
1410
- orders = []
1411
- datetime = self.safe_string(response, 'timestamp')
1412
- for i in range(0, len(orderIds)):
1413
- orders.append(self.safe_order({
1414
- 'info': orderIds[i],
1415
- 'id': orderIds[i],
1416
- 'lastUpdateTimestamp': self.parse8601(datetime),
1417
- }))
1418
- return orders
1419
-
1420
- def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1421
- """
1422
- create a trade order
1423
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#create-new-order
1424
- :param str symbol: unified symbol of the market to create an order in
1425
- :param str type: 'market' or 'limit' or 'stop_market' or 'stop_limit' or 'take_market' or 'take_limit'
1426
- :param str side: 'buy' or 'sell'
1427
- :param float amount: how much of currency you want to trade in units of base currency
1428
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1429
- :param dict [params]: extra parameters specific to the exchange API endpoint
1430
- :param bool [params.postOnly]: if True, the order will only be posted to the order book and not executed immediately(default False)
1431
- :param float [params.triggerPrice]: only for the 'stop_market', 'stop_limit', 'take_market' or 'take_limit' orders(the price at which an order is triggered)
1432
- :param str [params.clientOrderId]: client order id(default None)
1433
- :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1434
- """
1435
- self.load_markets()
1436
- market = self.market(symbol)
1437
- request: dict = {
1438
- 'symbol': market['id'],
1439
- 'type': type,
1440
- 'side': side,
1441
- 'size': self.amount_to_precision(symbol, amount),
1442
- }
1443
- isMarket = False
1444
- if (type == 'limit') or (type == 'stop_limit') or (type == 'take_limit'):
1445
- if price is None:
1446
- raise ArgumentsRequired(self.id + ' createOrder() requires a price argument for a ' + type + ' order')
1447
- request['price'] = self.price_to_precision(symbol, price)
1448
- else:
1449
- isMarket = True
1450
- postOnly = None
1451
- postOnly, params = self.handle_post_only(isMarket, False, params)
1452
- if postOnly:
1453
- request['post_only'] = True
1454
- triggerPrice = self.safe_number_n(params, ['triggerPrice', 'trigger_price', 'stopPrice', 'stop_price'])
1455
- if triggerPrice is not None:
1456
- params = self.omit(params, ['triggerPrice', 'trigger_price', 'stopPrice'])
1457
- request['stop_price'] = self.price_to_precision(symbol, triggerPrice)
1458
- if type == 'market':
1459
- request['type'] = 'stop_market'
1460
- elif type == 'limit':
1461
- request['type'] = 'stop_limit'
1462
- elif (type == 'stop_market') or (type == 'stop_limit') or (type == 'take_market') or (type == 'take_limit'):
1463
- raise ArgumentsRequired(self.id + ' createOrder() requires a stopPrice parameter for stop-loss and take-profit orders')
1464
- clientOrderId = self.safe_string_2(params, 'clientOrderId', 'client_id')
1465
- if clientOrderId is not None:
1466
- request['client_id'] = clientOrderId
1467
- params = self.omit(params, ['clientOrderId', 'client_id'])
1468
- response = self.privatePostV1Orders(self.extend(request, params))
1469
- #
1470
- # {
1471
- # "message": "New order request received.",
1472
- # "order": {
1473
- # "symbol": "BTC-USDT",
1474
- # "type": "market",
1475
- # "side": "sell",
1476
- # "size": "0.0003",
1477
- # "order_id": "cad67c0f-9aec-4ac8-ac03-aaf5db299ff7",
1478
- # "trader_id": "9c6f737e-a829-4843-87b1-b1ce86f2853b"
1479
- # },
1480
- # "timestamp": "2023-10-26T11:30:55.376Z"
1481
- # }
1482
- #
1483
- order = self.safe_dict(response, 'order', {})
1484
- return self.parse_order(order, market)
1485
-
1486
- def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
1487
- """
1488
- create a trade order
1489
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#modify-existing-order
1490
- :param str symbol: unified symbol of the market to create an order in
1491
- :param str type: 'market' or 'limit' or 'stop_market' or 'stop_limit' or 'take_market' or 'take_limit'
1492
- :param str side: 'buy' or 'sell'
1493
- :param float amount: how much of currency you want to trade in units of base currency
1494
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1495
- :param dict [params]: extra parameters specific to the exchange API endpoint
1496
- :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1497
- """
1498
- self.load_markets()
1499
- if amount is None:
1500
- raise ArgumentsRequired(self.id + ' editOrder() requires an amount argument')
1501
- market = self.market(symbol)
1502
- request: dict = {
1503
- 'order_id': id,
1504
- 'type': type,
1505
- 'side': side,
1506
- 'size': self.amount_to_precision(symbol, amount),
1507
- }
1508
- if price is not None:
1509
- request['price'] = self.price_to_precision(symbol, price)
1510
- response = self.privatePatchV1OrdersOrderId(self.extend(request, params))
1511
- return self.parse_order(response, market)
1512
-
1513
- def parse_order(self, order: dict, market: Market = None) -> Order:
1514
- #
1515
- # fetchOrder
1516
- # {
1517
- # "order_id": "913ea6e7-9fc9-43fb-9db1-f195d3baa93f",
1518
- # "price": "35800.00000000",
1519
- # "stop_price":null,
1520
- # "cost": "0.00000000",
1521
- # "fill_fees": "0.00000000",
1522
- # "trader_id": "9c6f737e-a829-4843-87b1-b1ce86f2853b",
1523
- # "status": "canceled",
1524
- # "epoch_timestamp": "2023-10-26T08:20:56.307Z",
1525
- # "origin": "web",
1526
- # "self_trade_prevention":null,
1527
- # "client_id":null,
1528
- # "symbol": "BTC-USDT",
1529
- # "size": "0.0003",
1530
- # "side": "sell",
1531
- # "type": "limit",
1532
- # "post_only":false,
1533
- # "size_filled": "0.0000"
1534
- # }
1535
- #
1536
- # fetchOrders
1537
- # {
1538
- # "order_id":"913ea6e7-9fc9-43fb-9db1-f195d3baa93f",
1539
- # "price":"35800.00000000",
1540
- # "stop_price":null,
1541
- # "cost":"0.00000000",
1542
- # "fill_fees":"0.00000000",
1543
- # "trader_id":"9c6f737e-a829-4843-87b1-b1ce86f2853b",
1544
- # "status":"accepted",
1545
- # "epoch_timestamp":"2023-10-26T08:20:56.307Z",
1546
- # "origin":"web",
1547
- # "self_trade_prevention":null,
1548
- # "client_id":null,
1549
- # "created_at":"2023-10-26T08:20:56.307Z",
1550
- # "symbol":"BTC-USDT",
1551
- # "size":"0.0003",
1552
- # "side":"sell",
1553
- # "type":"limit",
1554
- # "post_only":false,
1555
- # "size_filled":"0.0000"
1556
- # }
1557
- #
1558
- # createOrder
1559
- # {
1560
- # "symbol": "BTC-USDT",
1561
- # "type": "market",
1562
- # "side": "sell",
1563
- # "size": "0.0003",
1564
- # "order_id": "cad67c0f-9aec-4ac8-ac03-aaf5db299ff7",
1565
- # "trader_id": "9c6f737e-a829-4843-87b1-b1ce86f2853b"
1566
- # },
1567
- #
1568
- # cancelOrder
1569
- # {
1570
- # "message": "Cancel order request received.",
1571
- # "order_id": "d36e7588-6525-485c-b768-8ad8b3f745f9",
1572
- # "timestamp": "2023-10-26T14:36:37.559Z"
1573
- # }
1574
- #
1575
- # cancelOrders
1576
- # {
1577
- # "message": "Order cancellation request received.",
1578
- # "timestamp": "2023-10-26T10:29:28.652Z"
1579
- # }
1580
- #
1581
- # cancelAllOrders
1582
- # {
1583
- # "message": "Order cancellation request received.",
1584
- # "timestamp": "2023-10-26T10:29:28.652Z"
1585
- # }
1586
- #
1587
- id = self.safe_string(order, 'order_id')
1588
- marketId = self.safe_string(order, 'symbol')
1589
- market = self.safe_market(marketId, market)
1590
- clientOrderId = self.safe_string(order, 'client_id')
1591
- timestampString = self.safe_string_2(order, 'created_at', 'epoch_timestamp')
1592
- if timestampString is None:
1593
- timestampString = self.safe_string(order, 'timestamp')
1594
- timestamp = self.parse8601(timestampString)
1595
- status = self.parse_order_status(self.safe_string(order, 'status'))
1596
- type = self.parse_order_type(self.safe_string(order, 'type'))
1597
- side = self.safe_string(order, 'side')
1598
- price = self.safe_string(order, 'price')
1599
- stopPrice = self.safe_string(order, 'stop_price')
1600
- average = self.safe_string(order, 'average_fill_price') # from documentation
1601
- amount = self.safe_string(order, 'size')
1602
- filled = self.safe_string(order, 'size_filled')
1603
- feeCost = self.safe_string(order, 'fill_fees')
1604
- postOnly = self.safe_value(order, 'post_only')
1605
- fee = None
1606
- if feeCost is not None:
1607
- fee = {
1608
- 'currency': market['quote'],
1609
- 'cost': feeCost,
1610
- 'rate': None,
1611
- }
1612
- return self.safe_order({
1613
- 'id': id,
1614
- 'clientOrderId': clientOrderId,
1615
- 'timestamp': timestamp,
1616
- 'datetime': self.iso8601(timestamp),
1617
- 'lastTradeTimestamp': None,
1618
- 'status': status,
1619
- 'symbol': market['symbol'],
1620
- 'type': type,
1621
- 'timeInForce': 'GTC',
1622
- 'side': side,
1623
- 'price': price,
1624
- 'stopPrice': stopPrice,
1625
- 'triggerPrice': stopPrice,
1626
- 'average': average,
1627
- 'amount': amount,
1628
- 'cost': None,
1629
- 'filled': filled,
1630
- 'remaining': None,
1631
- 'fee': fee,
1632
- 'trades': None,
1633
- 'info': order,
1634
- 'postOnly': postOnly,
1635
- }, market)
1636
-
1637
- def parse_order_status(self, status: Str):
1638
- statuses: dict = {
1639
- 'pending': 'open',
1640
- 'accepted': 'open',
1641
- 'rejected': 'rejected',
1642
- 'done': 'closed',
1643
- 'canceled': 'canceled',
1644
- }
1645
- return self.safe_string(statuses, status, status)
1646
-
1647
- def parse_order_type(self, status):
1648
- statuses: dict = {
1649
- 'market': 'market',
1650
- 'limit': 'limit',
1651
- 'stop_market': 'market',
1652
- 'stop_limit': 'limit',
1653
- 'take_market': 'market',
1654
- 'take_limit': 'limit',
1655
- }
1656
- return self.safe_string(statuses, status, status)
1657
-
1658
- def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
1659
- """
1660
- transfer currency internally between wallets on the same account
1661
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#transfer-funds-between-entities
1662
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#transfer-funds-from-wallet-to-pro
1663
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#transfer-funds-from-pro-to-wallet
1664
- :param str code: unified currency code
1665
- :param float amount: amount to transfer
1666
- :param str fromAccount: account to transfer from
1667
- :param str toAccount: account to transfer to
1668
- :param dict [params]: extra parameters specific to the exchange API endpoint
1669
- :returns dict: a `transfer structure <https://docs.ccxt.com/#/?id=transfer-structure>`
1670
- """
1671
- self.load_markets()
1672
- currency = self.currency(code)
1673
- request: dict = {
1674
- 'asset': currency['id'],
1675
- 'amount': self.currency_to_precision(code, amount),
1676
- }
1677
- accountsByType = self.safe_value(self.options, 'accountsByType', {})
1678
- fromAcc = self.safe_string(accountsByType, fromAccount, fromAccount)
1679
- toAcc = self.safe_string(accountsByType, toAccount, toAccount)
1680
- response = None
1681
- if (fromAcc == 'funding') and (toAcc == 'trading'):
1682
- response = self.privatePostV1TransfersFromWallet(self.extend(request, params))
1683
- elif (fromAcc == 'trading') and (toAcc == 'funding'):
1684
- response = self.privatePostV1TransfersToWallet(self.extend(request, params))
1685
- else:
1686
- request['from_trader_id'] = fromAcc
1687
- request['to_trader_id'] = toAcc
1688
- response = self.privatePostV1TransfersInternalTransfer(self.extend(request, params))
1689
- #
1690
- # privatePostV1TransfersInternalTransfer
1691
- # {
1692
- # "from_trader_id": "1f494ace-b3ed-4324-b202-55526ed06381",
1693
- # "to_trader_id": "d32c7a40-cc24-44b0-8597-f9edb3da989f",
1694
- # "asset": "string",
1695
- # "amount": "string"
1696
- # }
1697
- #
1698
- # privatePostV1TransfersFromWallet, privatePostV1TransfersToWallet
1699
- # {
1700
- # "transfer_id": "bb34f528-d9b0-47c6-b11f-4d4840b86ee3"
1701
- # }
1702
- #
1703
- transfer = self.parse_transfer(response, currency)
1704
- return transfer
1705
-
1706
- def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> TransferEntries:
1707
- """
1708
- fetch a history of internal transfers between CoinList.co and CoinList Pro. It does not return external deposits or withdrawals
1709
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#list-transfers
1710
- :param str code: unified currency code
1711
- :param int [since]: the earliest time in ms to fetch transfers for
1712
- :param int [limit]: the maximum number of transfer structures to retrieve(default 200, max 500)
1713
- :param dict [params]: extra parameters specific to the exchange API endpoint
1714
- :param int [params.until]: the latest time in ms to fetch entries for
1715
- :returns dict[]: a list of `transfer structures <https://docs.ccxt.com/#/?id=transfer-structure>`
1716
- """
1717
- self.load_markets()
1718
- currency = None
1719
- if code is not None:
1720
- currency = self.currency(code)
1721
- request: dict = {}
1722
- if since is not None:
1723
- request['start_time'] = self.iso8601(since)
1724
- if limit is not None:
1725
- request['count'] = limit
1726
- until = self.safe_integer(params, 'until')
1727
- if until is not None:
1728
- params = self.omit(params, ['until'])
1729
- request['end_time'] = self.iso8601(until)
1730
- response = self.privateGetV1Transfers(self.extend(request, params))
1731
- #
1732
- # {
1733
- # "transfers": [
1734
- # {
1735
- # "transfer_id": "2c02db25-e8f2-4271-8222-e110bfd0aa2a",
1736
- # "created_at": "2023-10-20T13:15:37.000Z",
1737
- # "confirmed_at": "2023-10-20T13:15:37.000Z",
1738
- # "asset": "ETH",
1739
- # "amount": "0.010000000000000000",
1740
- # "status": "confirmed"
1741
- # },
1742
- # {
1743
- # "transfer_id": "890694db-156c-4e93-a3ef-4db61685aca7",
1744
- # "created_at": "2023-10-26T14:32:22.000Z",
1745
- # "confirmed_at": "2023-10-26T14:32:22.000Z",
1746
- # "asset": "USD",
1747
- # "amount": "-3.00",
1748
- # "status": "confirmed"
1749
- # }
1750
- # ]
1751
- # }
1752
- #
1753
- transfers = self.safe_list(response, 'transfers', [])
1754
- return self.parse_transfers(transfers, currency, since, limit)
1755
-
1756
- def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
1757
- #
1758
- # fetchTransfers
1759
- # {
1760
- # "transfer_id": "890694db-156c-4e93-a3ef-4db61685aca7",
1761
- # "created_at": "2023-10-26T14:32:22.000Z",
1762
- # "confirmed_at": "2023-10-26T14:32:22.000Z",
1763
- # "asset": "USD",
1764
- # "amount": "-3.00",
1765
- # "status": "confirmed"
1766
- # }
1767
- #
1768
- # transfer - privatePostV1TransfersInternalTransfer
1769
- # {
1770
- # "from_trader_id": "1f494ace-b3ed-4324-b202-55526ed06381",
1771
- # "to_trader_id": "d32c7a40-cc24-44b0-8597-f9edb3da989f",
1772
- # "asset": "string",
1773
- # "amount": "string"
1774
- # }
1775
- #
1776
- # transfer - privatePostV1TransfersFromWallet, privatePostV1TransfersToWallet
1777
- # {
1778
- # "transfer_id": "bb34f528-d9b0-47c6-b11f-4d4840b86ee3"
1779
- # }
1780
- #
1781
- currencyId = self.safe_string(transfer, 'asset')
1782
- confirmedAt = self.safe_string(transfer, 'confirmed_at')
1783
- timetstamp = self.parse8601(confirmedAt)
1784
- status = self.safe_string(transfer, 'status')
1785
- amountString = self.safe_string(transfer, 'amount')
1786
- fromAccount = None
1787
- toAccount = None
1788
- amount = None
1789
- if amountString is not None:
1790
- amountIsNegative = Precise.string_lt(amountString, '0')
1791
- if amountIsNegative:
1792
- fromAccount = 'trading'
1793
- toAccount = 'funding'
1794
- amountString = Precise.string_neg(amountString)
1795
- else:
1796
- fromAccount = 'funding'
1797
- toAccount = 'trading'
1798
- amount = self.parse_number(amountString)
1799
- return {
1800
- 'info': transfer,
1801
- 'id': self.safe_string(transfer, 'transfer_id'),
1802
- 'timestamp': timetstamp,
1803
- 'datetime': self.iso8601(timetstamp),
1804
- 'currency': self.safe_currency_code(currencyId, currency),
1805
- 'amount': amount,
1806
- 'fromAccount': fromAccount,
1807
- 'toAccount': toAccount,
1808
- 'status': self.parse_transfer_status(status),
1809
- }
1810
-
1811
- def parse_transfer_status(self, status: Str) -> Str:
1812
- statuses: dict = {
1813
- 'confirmed': 'ok',
1814
- }
1815
- return self.safe_string(statuses, status, status)
1816
-
1817
- def fetch_deposits_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1818
- """
1819
- fetch history of deposits and withdrawals from external wallets and between CoinList Pro trading account and CoinList wallet
1820
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#get-coinlist-wallet-ledger
1821
- :param str [code]: unified currency code for the currency of the deposit/withdrawals
1822
- :param int [since]: timestamp in ms of the earliest deposit/withdrawal
1823
- :param int [limit]: max number of deposit/withdrawals to return(default 200, max 500)
1824
- :param dict [params]: extra parameters specific to the exchange API endpoint
1825
- :returns dict: a list of `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1826
- """
1827
- if code is None:
1828
- raise ArgumentsRequired(self.id + ' fetchDepositsWithdrawals() requires a code argument')
1829
- traderId = self.safe_string_2(params, 'trader_id', 'traderId')
1830
- if traderId is None:
1831
- raise ArgumentsRequired(self.id + ' fetchDepositsWithdrawals() requires a traderId argument in the params')
1832
- self.load_markets()
1833
- currency = self.currency(code)
1834
- request: dict = {
1835
- 'asset': currency['id'],
1836
- 'trader_id': traderId,
1837
- }
1838
- if limit is not None:
1839
- request['count'] = limit
1840
- params = self.omit(params, ['trader_id', 'traderId'])
1841
- response = self.privateGetV1AccountsTraderIdWalletLedger(self.extend(request, params))
1842
- #
1843
- # [
1844
- # {
1845
- # "id": "2c02db25-e8f2-4271-8222-e110bfd0aa2a",
1846
- # "asset": "ETH",
1847
- # "amount": "0.01",
1848
- # "created_at": "2023-10-20T13:15:37.000Z",
1849
- # "description": "Transfer to CoinList Pro",
1850
- # "type": "PRO_TRANSFER",
1851
- # "delta": "-0.010000000000000000"
1852
- # },
1853
- # {
1854
- # "id": "7139384d-6cec-479e-a19c-d498647ccb47",
1855
- # "asset": "ETH",
1856
- # "amount": "0.01",
1857
- # "created_at": "2023-10-20T13:10:55.000Z",
1858
- # "description": "CRYPTO_DEPOSIT",
1859
- # "type": "CRYPTO_DEPOSIT",
1860
- # "delta": "0.010000000000000000"
1861
- # },
1862
- #
1863
- # ...
1864
- #
1865
- # {
1866
- # "id": "91bbbb22-5ede-4e9a-81ef-3f9318aa83d2",
1867
- # "asset": "USDT",
1868
- # "amount": "4.169654",
1869
- # "withdrawal_fee_amount": "8.830346000000000000",
1870
- # "created_at": "2023-10-27T16:14:11.000Z",
1871
- # "description": "CRYPTO_WITHDRAWAL",
1872
- # "type": "CRYPTO_WITHDRAWAL",
1873
- # "delta": "-4.169654000000000000"
1874
- # },
1875
- # {
1876
- # "id": "830261bd-cda9-401f-b6df-105f4da3b37c",
1877
- # "asset": "USDT",
1878
- # "amount": "13",
1879
- # "created_at": "2023-10-27T14:52:05.000Z",
1880
- # "description": "Transfer from CoinList Pro",
1881
- # "type": "PRO_TRANSFER",
1882
- # "delta": "13.000000000000000000"
1883
- # }
1884
- # ]
1885
- #
1886
- # coinlist returns both internal transfers and blockchain transactions
1887
- return self.parse_transactions(response, currency, since, limit)
1888
-
1889
- def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
1890
- """
1891
- request a withdrawal from CoinList wallet.(Disabled by default. Contact CoinList to apply for an exception.)
1892
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#request-withdrawal-from-wallet
1893
- :param str code: unified currency code
1894
- :param float amount: the amount to withdraw
1895
- :param str address: the address to withdraw to
1896
- :param str tag:
1897
- :param dict [params]: extra parameters specific to the exchange API endpoint
1898
- :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1899
- """
1900
- self.load_markets()
1901
- currency = self.currency(code)
1902
- request: dict = {
1903
- 'asset': currency['id'],
1904
- 'amount': self.currency_to_precision(code, amount),
1905
- 'destination_address': address,
1906
- }
1907
- response = self.privatePostV1TransfersWithdrawalRequest(self.extend(request, params))
1908
- #
1909
- # {
1910
- # "transfer_id": "d4a2d8dd-7def-4545-a062-761683b9aa05"
1911
- # }
1912
- #
1913
- data = self.safe_dict(response, 'data', {})
1914
- return self.parse_transaction(data, currency)
1915
-
1916
- def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
1917
- # withdraw
1918
- #
1919
- # {
1920
- # "transfer_id": "d4a2d8dd-7def-4545-a062-761683b9aa05"
1921
- # }
1922
- #
1923
- # fetchDepositsWithdrawals
1924
- # {
1925
- # "id": "91bbbb22-5ede-4e9a-81ef-3f9318aa83d2",
1926
- # "asset": "USDT",
1927
- # "amount": "4.169654",
1928
- # "withdrawal_fee_amount": "8.830346000000000000",
1929
- # "created_at": "2023-10-27T16:14:11.000Z",
1930
- # "description": "CRYPTO_WITHDRAWAL",
1931
- # "type": "CRYPTO_WITHDRAWAL",
1932
- # "delta": "-4.169654000000000000"
1933
- # },
1934
- #
1935
- currencyId = self.safe_string(transaction, 'asset')
1936
- code = self.safe_currency_code(currencyId, currency)
1937
- id = self.safe_string_2(transaction, 'id', 'transfer_id')
1938
- amount = self.safe_number(transaction, 'amount')
1939
- timestamp = self.parse8601(self.safe_string(transaction, 'created_at'))
1940
- type = self.safe_string(transaction, 'type', None)
1941
- if type is None:
1942
- type = 'withdrawal' # None only in withdraw() method
1943
- else:
1944
- type = self.parse_transaction_type(type)
1945
- fee = None
1946
- feeCost = self.safe_string(transaction, 'withdrawal_fee_amount')
1947
- if feeCost is not None:
1948
- fee = {
1949
- 'cost': feeCost,
1950
- 'currency': code,
1951
- }
1952
- return {
1953
- 'info': transaction,
1954
- 'id': id,
1955
- 'txid': None,
1956
- 'timestamp': timestamp,
1957
- 'datetime': self.iso8601(timestamp),
1958
- 'network': None,
1959
- 'addressFrom': None,
1960
- 'address': None,
1961
- 'addressTo': None,
1962
- 'tagFrom': None,
1963
- 'tag': None,
1964
- 'tagTo': None,
1965
- 'type': type,
1966
- 'amount': amount,
1967
- 'currency': code,
1968
- 'status': None,
1969
- 'updated': None,
1970
- 'fee': fee,
1971
- 'comment': self.safe_string(transaction, 'description'),
1972
- 'internal': None,
1973
- }
1974
-
1975
- def parse_transaction_type(self, type):
1976
- types: dict = {
1977
- 'CRYPTO_DEPOSIT': 'deposit',
1978
- 'CRYPTO_WITHDRAWAL': 'withdrawal',
1979
- 'PRO_TRANSFER': 'transfer',
1980
- }
1981
- return self.safe_string(types, type, type)
1982
-
1983
- def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
1984
- """
1985
- fetch the history of changes, actions done by the user or operations that altered balance of the user
1986
- :see: https://trade-docs.coinlist.co/?javascript--nodejs#get-account-history
1987
- :param str code: unified currency code, default is None
1988
- :param int [since]: timestamp in ms of the earliest ledger entry, default is None
1989
- :param int [limit]: max number of ledger entrys to return(default 200, max 500)
1990
- :param dict [params]: extra parameters specific to the exchange API endpoint
1991
- :param int [params.until]: the latest time in ms to fetch entries for
1992
- :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
1993
- """
1994
- traderId = self.safe_string_2(params, 'trader_id', 'traderId')
1995
- if traderId is None:
1996
- raise ArgumentsRequired(self.id + ' fetchLedger() requires a traderId argument in the params')
1997
- self.load_markets()
1998
- request: dict = {
1999
- 'trader_id': traderId,
2000
- }
2001
- currency = None
2002
- if code is not None:
2003
- currency = self.currency(code)
2004
- if since is not None:
2005
- request['start_time'] = self.iso8601(since)
2006
- if limit is not None:
2007
- request['count'] = limit
2008
- until = self.safe_integer(params, 'until')
2009
- if until is not None:
2010
- params = self.omit(params, ['until'])
2011
- request['end_time'] = self.iso8601(until)
2012
- params = self.omit(params, ['trader_id', 'traderId'])
2013
- response = self.privateGetV1AccountsTraderIdLedger(self.extend(request, params))
2014
- #
2015
- # {
2016
- # "transactions": [
2017
- # {
2018
- # "transaction_id": "0288634e-49bd-494d-b04a-18fd1832d394",
2019
- # "transaction_type": "XFER",
2020
- # "type": "deposit",
2021
- # "asset": "ETH",
2022
- # "symbol": null,
2023
- # "amount": "0.010000000000000000",
2024
- # "details": null,
2025
- # "created_at": "2023-10-20T13:15:39.443Z"
2026
- # },
2027
- # {
2028
- # "transaction_id": "47a45928-abcd-4c12-8bd6-587c3028025f",
2029
- # "transaction_type": "SWAP",
2030
- # "type": "atomic token swap",
2031
- # "asset": "USDT",
2032
- # "symbol": "ETH-USDT",
2033
- # "amount": "1.447947",
2034
- # "details": null,
2035
- # "created_at": "2023-10-20T13:16:30.373Z"
2036
- # },
2037
- # {
2038
- # "transaction_id": "1ffe3a54-916e-41f0-b957-3a01309eb009",
2039
- # "transaction_type": "FEE",
2040
- # "type": "fee",
2041
- # "asset": "USDT",
2042
- # "symbol": "ETH-USDT",
2043
- # "amount": "-0.006516",
2044
- # "details": {
2045
- # "fee_details": [
2046
- # {
2047
- # "insurance_fee": "0",
2048
- # "order_id": "39911d5f-c789-4a7d-ad34-820a804d1da6",
2049
- # "fee_type": "taker",
2050
- # "fee_currency": "USDT"
2051
- # }
2052
- # ]
2053
- # },
2054
- # "created_at": "2023-10-20T13:16:30.373Z"
2055
- # },
2056
- # {
2057
- # "transaction_id": "3930e8a3-2218-481f-8c3c-2219287e205e",
2058
- # "transaction_type": "SWAP",
2059
- # "type": "atomic token swap",
2060
- # "asset": "ETH",
2061
- # "symbol": "ETH-USDT",
2062
- # "amount": "-0.000900000000000000",
2063
- # "details": null,
2064
- # "created_at": "2023-10-20T13:16:30.373Z"
2065
- # },
2066
- # {
2067
- # "transaction_id": "a6c65cb3-95d0-44e2-8202-f70581d6e55c",
2068
- # "transaction_type": "XFER",
2069
- # "type": "withdrawal",
2070
- # "asset": "USD",
2071
- # "symbol": null,
2072
- # "amount": "-3.00",
2073
- # "details": null,
2074
- # "created_at": "2023-10-26T14:32:24.887Z"
2075
- # }
2076
- # ]
2077
- # }
2078
- #
2079
- ledger = self.safe_value(response, 'transactions', [])
2080
- return self.parse_ledger(ledger, currency, since, limit)
2081
-
2082
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
2083
- #
2084
- # deposit transaction from wallet(funding) to pro(trading)
2085
- # {
2086
- # "transaction_id": "0288634e-49bd-494d-b04a-18fd1832d394",
2087
- # "transaction_type": "XFER",
2088
- # "type": "deposit",
2089
- # "asset": "ETH",
2090
- # "symbol": null,
2091
- # "amount": "0.010000000000000000",
2092
- # "details": null,
2093
- # "created_at": "2023-10-20T13:15:39.443Z"
2094
- # }
2095
- #
2096
- # withdrawal transaction from pro(trading) to wallet(funding)
2097
- # {
2098
- # "transaction_id": "a6c65cb3-95d0-44e2-8202-f70581d6e55c",
2099
- # "transaction_type": "XFER",
2100
- # "type": "withdrawal",
2101
- # "asset": "USD",
2102
- # "symbol": null,
2103
- # "amount": "-3.00",
2104
- # "details": null,
2105
- # "created_at": "2023-10-26T14:32:24.887Z"
2106
- # }
2107
- #
2108
- # sell trade
2109
- # {
2110
- # "transaction_id": "47a45928-abcd-4c12-8bd6-587c3028025f",
2111
- # "transaction_type": "SWAP",
2112
- # "type": "atomic token swap",
2113
- # "asset": "USDT",
2114
- # "symbol": "ETH-USDT",
2115
- # "amount": "1.447947",
2116
- # "details": null,
2117
- # "created_at": "2023-10-20T13:16:30.373Z"
2118
- # }
2119
- #
2120
- # buy trade
2121
- # {
2122
- # "transaction_id": "46d20a93-45c4-4441-a238-f89602eb8c8c",
2123
- # "transaction_type": "SWAP",
2124
- # "type": "atomic token swap",
2125
- # "asset": "ETH",
2126
- # "symbol": "ETH-USDT",
2127
- # "amount": "0.000800000000000000",
2128
- # "details": null,
2129
- # "created_at": "2023-10-20T13:22:14.256Z"
2130
- # },
2131
- #
2132
- # fee
2133
- # {
2134
- # "transaction_id": "57fd526c-36b1-4721-83ce-42aadcb1e953",
2135
- # "transaction_type": "FEE",
2136
- # "type": "fee",
2137
- # "asset": "USDT",
2138
- # "symbol": "BTC-USDT",
2139
- # "amount": "-0.047176",
2140
- # "details": {
2141
- # "fee_details": [
2142
- # {
2143
- # "insurance_fee": "0",
2144
- # "order_id": "c0bc33cd-eeb9-40a0-ab5f-2d99f323ef58",
2145
- # "fee_type": "taker",
2146
- # "fee_currency": "USDT"
2147
- # }
2148
- # ]
2149
- # },
2150
- # "created_at": "2023-10-25T16:46:24.294Z"
2151
- # }
2152
- #
2153
- id = self.safe_string(item, 'transaction_id')
2154
- createdAt = self.safe_string(item, 'created_at')
2155
- timestamp = self.parse8601(createdAt)
2156
- amount = self.safe_string(item, 'amount')
2157
- amountIsNegative = Precise.string_lt(amount, '0')
2158
- direction = None
2159
- if amountIsNegative:
2160
- direction = 'out'
2161
- amount = Precise.string_neg(amount)
2162
- else:
2163
- direction = 'in'
2164
- currencyId = self.safe_string(item, 'asset')
2165
- code = self.safe_currency_code(currencyId, currency)
2166
- type = self.parse_ledger_entry_type(self.safe_string(item, 'type'))
2167
- return {
2168
- 'info': item,
2169
- 'id': id,
2170
- 'timestamp': timestamp,
2171
- 'datetime': self.iso8601(timestamp),
2172
- 'direction': direction,
2173
- 'account': 'trading',
2174
- 'referenceId': None,
2175
- 'referenceAccount': None,
2176
- 'type': type,
2177
- 'currency': code,
2178
- 'amount': self.parse_number(amount),
2179
- 'before': None,
2180
- 'after': None,
2181
- 'status': 'ok',
2182
- 'fee': None,
2183
- }
2184
-
2185
- def parse_ledger_entry_type(self, type):
2186
- types: dict = {
2187
- 'atomic token swap': 'trade',
2188
- 'fee': 'fee',
2189
- 'deposit': 'transfer',
2190
- 'withdrawal': 'transfer',
2191
- }
2192
- return self.safe_string(types, type, type)
2193
-
2194
- def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
2195
- request = self.omit(params, self.extract_params(path))
2196
- endpoint = '/' + self.implode_params(path, params)
2197
- url = self.urls['api'][api] + endpoint
2198
- isBulk = isinstance(params, list)
2199
- query: Str = None
2200
- if not isBulk:
2201
- query = self.urlencode(request)
2202
- if api == 'private':
2203
- self.check_required_credentials()
2204
- timestamp = str(self.seconds())
2205
- auth = timestamp + method + endpoint
2206
- if (method == 'POST') or (method == 'PATCH') or isBulk:
2207
- body = self.json(request)
2208
- auth += body
2209
- elif query is not None and len(query) != 0:
2210
- auth += '?' + query
2211
- url += '?' + query
2212
- signature = self.hmac(self.encode(auth), self.base64_to_binary(self.secret), hashlib.sha256, 'base64')
2213
- headers = {
2214
- 'CL-ACCESS-KEY': self.apiKey,
2215
- 'CL-ACCESS-SIG': signature,
2216
- 'CL-ACCESS-TIMESTAMP': timestamp,
2217
- 'Content-Type': 'application/json',
2218
- }
2219
- elif query is not None and len(query) != 0:
2220
- url += '?' + query
2221
- return {'url': url, 'method': method, 'body': body, 'headers': headers}
2222
-
2223
- def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
2224
- if response is None:
2225
- # In some cases the exchange returns 202 Accepted for bad orders.
2226
- # The body of that response contains order_id of the order.
2227
- # Some bad orders will get status 'rejected' and could be fetched later(by using fetchOrders() or fetchOrder(order_id)).
2228
- # While others don't get any status, they simply disappear, but the response is still 202 Accepted and contains their order_id.
2229
- # When using fechOrder(order_id) for such disappeared orders, the exchange returns an empty response with code 404.
2230
- if (code == 404) and (url.find('/orders/') >= 0) and (method == 'GET'):
2231
- parts = url.split('/orders/')
2232
- orderId = self.safe_string(parts, 1)
2233
- raise OrderNotFound(self.id + ' order ' + orderId + ' not found(or rejected on the exchange side)')
2234
- return None
2235
- responseCode = self.safe_string(response, 'status')
2236
- messageCode = self.safe_string(response, 'message_code')
2237
- if (messageCode is not None) or ((responseCode is not None) and (code != 200) and (code != 202) and (responseCode != '200') and (responseCode != '202')):
2238
- feedback = self.id + ' ' + body
2239
- message = self.safe_string(response, 'message')
2240
- self.throw_broadly_matched_exception(self.exceptions['broad'], message, feedback)
2241
- self.throw_exactly_matched_exception(self.exceptions['exact'], messageCode, feedback)
2242
- raise ExchangeError(feedback)
2243
- return None