ccxt-ir 4.3.46.0.3__py2.py3-none-any.whl → 4.5.1__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (529) hide show
  1. ccxt/__init__.py +39 -35
  2. ccxt/abantether.py +8 -8
  3. ccxt/abstract/alpaca.py +4 -0
  4. ccxt/abstract/apex.py +31 -0
  5. ccxt/abstract/bigone.py +1 -1
  6. ccxt/abstract/binance.py +106 -48
  7. ccxt/abstract/binancecoinm.py +106 -48
  8. ccxt/abstract/binanceus.py +141 -83
  9. ccxt/abstract/binanceusdm.py +106 -48
  10. ccxt/abstract/bingx.py +50 -1
  11. ccxt/abstract/bitbank.py +5 -0
  12. ccxt/abstract/bitfinex.py +136 -65
  13. ccxt/abstract/bitflyer.py +1 -0
  14. ccxt/abstract/bitget.py +67 -0
  15. ccxt/abstract/bitmart.py +19 -1
  16. ccxt/abstract/bitopro.py +1 -0
  17. ccxt/abstract/bitrue.py +68 -68
  18. ccxt/abstract/bitstamp.py +1 -0
  19. ccxt/abstract/blofin.py +30 -0
  20. ccxt/abstract/btcbox.py +2 -0
  21. ccxt/abstract/bybit.py +28 -13
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbaseexchange.py +1 -0
  24. ccxt/abstract/coinbaseinternational.py +1 -1
  25. ccxt/abstract/cryptocom.py +16 -0
  26. ccxt/abstract/cryptomus.py +20 -0
  27. ccxt/abstract/defx.py +69 -0
  28. ccxt/abstract/deribit.py +1 -0
  29. ccxt/abstract/derive.py +117 -0
  30. ccxt/abstract/digifinex.py +1 -0
  31. ccxt/abstract/ellipx.py +25 -0
  32. ccxt/abstract/foxbit.py +26 -0
  33. ccxt/abstract/gate.py +19 -0
  34. ccxt/abstract/gateio.py +19 -0
  35. ccxt/abstract/gemini.py +1 -0
  36. ccxt/abstract/hibachi.py +26 -0
  37. ccxt/abstract/hyperliquid.py +1 -1
  38. ccxt/abstract/independentreserve.py +6 -0
  39. ccxt/abstract/kraken.py +1 -0
  40. ccxt/abstract/krakenfutures.py +4 -0
  41. ccxt/abstract/kucoin.py +10 -0
  42. ccxt/abstract/kucoinfutures.py +18 -0
  43. ccxt/abstract/lbank.py +2 -1
  44. ccxt/abstract/luno.py +1 -0
  45. ccxt/abstract/mexc.py +2 -0
  46. ccxt/abstract/modetrade.py +119 -0
  47. ccxt/abstract/myokx.py +349 -0
  48. ccxt/abstract/oceanex.py +5 -0
  49. ccxt/abstract/okx.py +25 -0
  50. ccxt/abstract/okxus.py +349 -0
  51. ccxt/abstract/onetrading.py +0 -12
  52. ccxt/abstract/paradex.py +23 -0
  53. ccxt/abstract/phemex.py +2 -0
  54. ccxt/abstract/poloniex.py +36 -0
  55. ccxt/abstract/tradeogre.py +3 -1
  56. ccxt/abstract/upbit.py +51 -34
  57. ccxt/abstract/whitebit.py +16 -0
  58. ccxt/abstract/woo.py +64 -6
  59. ccxt/abstract/xt.py +10 -5
  60. ccxt/afratether.py +8 -8
  61. ccxt/alpaca.py +828 -51
  62. ccxt/apex.py +1875 -0
  63. ccxt/arzinja.py +7 -7
  64. ccxt/arzplus.py +9 -9
  65. ccxt/ascendex.py +501 -306
  66. ccxt/async_support/__init__.py +39 -35
  67. ccxt/async_support/abantether.py +8 -8
  68. ccxt/async_support/afratether.py +10 -10
  69. ccxt/async_support/alpaca.py +828 -51
  70. ccxt/async_support/apex.py +1875 -0
  71. ccxt/async_support/arzinja.py +10 -10
  72. ccxt/async_support/arzplus.py +12 -12
  73. ccxt/async_support/ascendex.py +502 -306
  74. ccxt/async_support/base/exchange.py +303 -89
  75. ccxt/async_support/base/ws/cache.py +9 -3
  76. ccxt/async_support/base/ws/client.py +173 -38
  77. ccxt/async_support/base/ws/future.py +25 -37
  78. ccxt/async_support/bequant.py +5 -3
  79. ccxt/async_support/bigone.py +279 -144
  80. ccxt/async_support/binance.py +2347 -1158
  81. ccxt/async_support/binancecoinm.py +9 -3
  82. ccxt/async_support/binanceus.py +17 -3
  83. ccxt/async_support/binanceusdm.py +9 -4
  84. ccxt/async_support/bingx.py +2962 -920
  85. ccxt/async_support/bit2c.py +147 -27
  86. ccxt/async_support/bitbank.py +151 -23
  87. ccxt/async_support/bitbns.py +104 -30
  88. ccxt/async_support/bitfinex.py +3291 -1113
  89. ccxt/async_support/bitflyer.py +202 -27
  90. ccxt/async_support/bitget.py +3683 -1538
  91. ccxt/async_support/bithumb.py +195 -38
  92. ccxt/async_support/bitimen.py +12 -12
  93. ccxt/async_support/bitir.py +38 -38
  94. ccxt/async_support/bitmart.py +1288 -350
  95. ccxt/async_support/bitmex.py +260 -75
  96. ccxt/async_support/bitopro.py +262 -62
  97. ccxt/async_support/bitpin.py +17 -16
  98. ccxt/async_support/bitrue.py +459 -290
  99. ccxt/async_support/bitso.py +199 -54
  100. ccxt/async_support/bitstamp.py +230 -96
  101. ccxt/async_support/bitteam.py +167 -25
  102. ccxt/async_support/{huobijp.py → bittrade.py} +158 -30
  103. ccxt/async_support/bitvavo.py +213 -49
  104. ccxt/async_support/blockchaincom.py +160 -46
  105. ccxt/async_support/blofin.py +502 -120
  106. ccxt/async_support/btcalpha.py +169 -31
  107. ccxt/async_support/btcbox.py +292 -23
  108. ccxt/async_support/btcmarkets.py +211 -58
  109. ccxt/async_support/btcturk.py +161 -38
  110. ccxt/async_support/bybit.py +1775 -1030
  111. ccxt/async_support/cex.py +1440 -1303
  112. ccxt/async_support/coinbase.py +724 -212
  113. ccxt/async_support/coinbaseadvanced.py +2 -1
  114. ccxt/async_support/coinbaseexchange.py +388 -89
  115. ccxt/async_support/coinbaseinternational.py +412 -57
  116. ccxt/async_support/coincatch.py +177 -78
  117. ccxt/async_support/coincheck.py +135 -19
  118. ccxt/async_support/coinex.py +606 -232
  119. ccxt/async_support/coinmate.py +189 -63
  120. ccxt/async_support/coinmetro.py +195 -54
  121. ccxt/async_support/coinone.py +158 -51
  122. ccxt/async_support/coinsph.py +336 -61
  123. ccxt/async_support/coinspot.py +151 -52
  124. ccxt/async_support/cryptocom.py +661 -111
  125. ccxt/async_support/cryptomus.py +1137 -0
  126. ccxt/async_support/defx.py +2071 -0
  127. ccxt/async_support/delta.py +299 -99
  128. ccxt/async_support/deribit.py +348 -126
  129. ccxt/async_support/derive.py +2572 -0
  130. ccxt/async_support/digifinex.py +430 -214
  131. ccxt/async_support/ellipx.py +2029 -0
  132. ccxt/async_support/eterex.py +10 -10
  133. ccxt/async_support/excoino.py +31 -31
  134. ccxt/async_support/exir.py +14 -14
  135. ccxt/async_support/exmo.py +344 -131
  136. ccxt/async_support/exnovin.py +10 -10
  137. ccxt/async_support/farhadexchange.py +12 -12
  138. ccxt/async_support/fmfwio.py +2 -1
  139. ccxt/async_support/foxbit.py +1935 -0
  140. ccxt/async_support/gate.py +1351 -529
  141. ccxt/async_support/gateio.py +2 -1
  142. ccxt/async_support/gemini.py +144 -39
  143. ccxt/async_support/hashkey.py +152 -109
  144. ccxt/async_support/hibachi.py +2080 -0
  145. ccxt/async_support/hitbtc.py +395 -167
  146. ccxt/async_support/hitobit.py +12 -12
  147. ccxt/async_support/hollaex.py +307 -119
  148. ccxt/async_support/htx.py +851 -383
  149. ccxt/async_support/huobi.py +2 -1
  150. ccxt/async_support/hyperliquid.py +1848 -536
  151. ccxt/async_support/independentreserve.py +288 -15
  152. ccxt/async_support/indodax.py +190 -33
  153. ccxt/async_support/jibitex.py +12 -12
  154. ccxt/async_support/kraken.py +795 -351
  155. ccxt/async_support/krakenfutures.py +214 -62
  156. ccxt/async_support/kucoin.py +715 -396
  157. ccxt/async_support/kucoinfutures.py +652 -89
  158. ccxt/async_support/latoken.py +217 -113
  159. ccxt/async_support/lbank.py +425 -97
  160. ccxt/async_support/luno.py +382 -35
  161. ccxt/async_support/mercado.py +113 -6
  162. ccxt/async_support/mexc.py +874 -437
  163. ccxt/async_support/modetrade.py +2818 -0
  164. ccxt/async_support/myokx.py +54 -0
  165. ccxt/async_support/ndax.py +221 -64
  166. ccxt/async_support/nobitex.py +32 -38
  167. ccxt/async_support/novadax.py +190 -34
  168. ccxt/async_support/oceanex.py +217 -28
  169. ccxt/async_support/okcoin.py +253 -145
  170. ccxt/async_support/okexchange.py +11 -11
  171. ccxt/async_support/okx.py +1088 -351
  172. ccxt/async_support/okxus.py +54 -0
  173. ccxt/async_support/ompfinex.py +32 -27
  174. ccxt/async_support/onetrading.py +213 -392
  175. ccxt/async_support/oxfun.py +245 -166
  176. ccxt/async_support/p2b.py +151 -29
  177. ccxt/async_support/paradex.py +562 -49
  178. ccxt/async_support/paymium.py +82 -19
  179. ccxt/async_support/phemex.py +713 -172
  180. ccxt/async_support/poloniex.py +1602 -283
  181. ccxt/async_support/probit.py +224 -95
  182. ccxt/async_support/ramzinex.py +34 -30
  183. ccxt/async_support/sarmayex.py +9 -9
  184. ccxt/async_support/sarrafex.py +13 -13
  185. ccxt/async_support/tabdeal.py +15 -14
  186. ccxt/async_support/tetherland.py +9 -9
  187. ccxt/async_support/timex.py +210 -51
  188. ccxt/async_support/tokocrypto.py +167 -47
  189. ccxt/async_support/tradeogre.py +266 -31
  190. ccxt/async_support/twox.py +9 -9
  191. ccxt/async_support/ubitex.py +12 -12
  192. ccxt/async_support/upbit.py +568 -165
  193. ccxt/async_support/vertex.py +160 -32
  194. ccxt/async_support/wallex.py +12 -12
  195. ccxt/async_support/wavesexchange.py +165 -30
  196. ccxt/async_support/whitebit.py +975 -127
  197. ccxt/async_support/woo.py +1918 -1016
  198. ccxt/async_support/woofipro.py +433 -141
  199. ccxt/async_support/xt.py +649 -193
  200. ccxt/async_support/yobit.py +195 -70
  201. ccxt/async_support/zaif.py +91 -15
  202. ccxt/async_support/zonda.py +151 -36
  203. ccxt/base/decimal_to_precision.py +14 -10
  204. ccxt/base/errors.py +49 -18
  205. ccxt/base/exchange.py +1556 -450
  206. ccxt/base/precise.py +10 -0
  207. ccxt/base/types.py +114 -6
  208. ccxt/bequant.py +5 -3
  209. ccxt/bigone.py +279 -144
  210. ccxt/binance.py +2347 -1158
  211. ccxt/binancecoinm.py +9 -3
  212. ccxt/binanceus.py +17 -3
  213. ccxt/binanceusdm.py +9 -4
  214. ccxt/bingx.py +2962 -920
  215. ccxt/bit2c.py +147 -27
  216. ccxt/bitbank.py +151 -23
  217. ccxt/bitbns.py +104 -30
  218. ccxt/bitfinex.py +3290 -1113
  219. ccxt/bitflyer.py +202 -27
  220. ccxt/bitget.py +3683 -1538
  221. ccxt/bithumb.py +194 -38
  222. ccxt/bitimen.py +9 -9
  223. ccxt/bitir.py +35 -35
  224. ccxt/bitmart.py +1288 -350
  225. ccxt/bitmex.py +260 -75
  226. ccxt/bitopro.py +262 -62
  227. ccxt/bitpin.py +15 -14
  228. ccxt/bitrue.py +459 -290
  229. ccxt/bitso.py +199 -54
  230. ccxt/bitstamp.py +230 -96
  231. ccxt/bitteam.py +167 -25
  232. ccxt/{huobijp.py → bittrade.py} +158 -30
  233. ccxt/bitvavo.py +213 -49
  234. ccxt/blockchaincom.py +160 -46
  235. ccxt/blofin.py +502 -120
  236. ccxt/btcalpha.py +169 -31
  237. ccxt/btcbox.py +291 -23
  238. ccxt/btcmarkets.py +211 -58
  239. ccxt/btcturk.py +161 -38
  240. ccxt/bybit.py +1775 -1030
  241. ccxt/cex.py +1439 -1303
  242. ccxt/coinbase.py +724 -212
  243. ccxt/coinbaseadvanced.py +2 -1
  244. ccxt/coinbaseexchange.py +388 -89
  245. ccxt/coinbaseinternational.py +412 -57
  246. ccxt/coincatch.py +177 -78
  247. ccxt/coincheck.py +135 -19
  248. ccxt/coinex.py +606 -232
  249. ccxt/coinmate.py +189 -63
  250. ccxt/coinmetro.py +194 -54
  251. ccxt/coinone.py +158 -51
  252. ccxt/coinsph.py +336 -61
  253. ccxt/coinspot.py +151 -52
  254. ccxt/cryptocom.py +661 -111
  255. ccxt/cryptomus.py +1137 -0
  256. ccxt/defx.py +2070 -0
  257. ccxt/delta.py +299 -99
  258. ccxt/deribit.py +348 -126
  259. ccxt/derive.py +2571 -0
  260. ccxt/digifinex.py +430 -214
  261. ccxt/ellipx.py +2029 -0
  262. ccxt/eterex.py +7 -7
  263. ccxt/excoino.py +29 -29
  264. ccxt/exir.py +11 -11
  265. ccxt/exmo.py +343 -131
  266. ccxt/exnovin.py +8 -8
  267. ccxt/farhadexchange.py +10 -10
  268. ccxt/fmfwio.py +2 -1
  269. ccxt/foxbit.py +1935 -0
  270. ccxt/gate.py +1351 -529
  271. ccxt/gateio.py +2 -1
  272. ccxt/gemini.py +144 -39
  273. ccxt/hashkey.py +152 -109
  274. ccxt/hibachi.py +2079 -0
  275. ccxt/hitbtc.py +395 -167
  276. ccxt/hitobit.py +9 -9
  277. ccxt/hollaex.py +307 -119
  278. ccxt/htx.py +851 -383
  279. ccxt/huobi.py +2 -1
  280. ccxt/hyperliquid.py +1848 -536
  281. ccxt/independentreserve.py +287 -15
  282. ccxt/indodax.py +190 -33
  283. ccxt/jibitex.py +9 -9
  284. ccxt/kraken.py +794 -351
  285. ccxt/krakenfutures.py +214 -62
  286. ccxt/kucoin.py +715 -396
  287. ccxt/kucoinfutures.py +652 -89
  288. ccxt/latoken.py +217 -113
  289. ccxt/lbank.py +425 -97
  290. ccxt/luno.py +382 -35
  291. ccxt/mercado.py +113 -6
  292. ccxt/mexc.py +873 -437
  293. ccxt/modetrade.py +2818 -0
  294. ccxt/myokx.py +54 -0
  295. ccxt/ndax.py +221 -64
  296. ccxt/nobitex.py +30 -36
  297. ccxt/novadax.py +190 -34
  298. ccxt/oceanex.py +217 -28
  299. ccxt/okcoin.py +253 -145
  300. ccxt/okexchange.py +9 -9
  301. ccxt/okx.py +1088 -351
  302. ccxt/okxus.py +54 -0
  303. ccxt/ompfinex.py +29 -24
  304. ccxt/onetrading.py +213 -392
  305. ccxt/oxfun.py +245 -166
  306. ccxt/p2b.py +151 -29
  307. ccxt/paradex.py +562 -49
  308. ccxt/paymium.py +82 -19
  309. ccxt/phemex.py +712 -172
  310. ccxt/poloniex.py +1601 -283
  311. ccxt/pro/__init__.py +76 -17
  312. ccxt/pro/alpaca.py +21 -6
  313. ccxt/pro/apex.py +984 -0
  314. ccxt/pro/ascendex.py +58 -10
  315. ccxt/pro/bequant.py +6 -1
  316. ccxt/pro/binance.py +728 -156
  317. ccxt/pro/binancecoinm.py +6 -2
  318. ccxt/pro/binanceus.py +8 -4
  319. ccxt/pro/binanceusdm.py +7 -2
  320. ccxt/pro/bingx.py +333 -142
  321. ccxt/pro/bitfinex.py +727 -262
  322. ccxt/pro/bitget.py +570 -79
  323. ccxt/pro/bithumb.py +20 -6
  324. ccxt/pro/bitmart.py +216 -87
  325. ccxt/pro/bitmex.py +47 -9
  326. ccxt/pro/bitopro.py +26 -14
  327. ccxt/pro/bitrue.py +22 -22
  328. ccxt/pro/bitstamp.py +54 -21
  329. ccxt/pro/{huobijp.py → bittrade.py} +7 -6
  330. ccxt/pro/bitvavo.py +191 -67
  331. ccxt/pro/blockchaincom.py +21 -8
  332. ccxt/pro/blofin.py +9 -1
  333. ccxt/pro/bybit.py +632 -245
  334. ccxt/pro/cex.py +59 -24
  335. ccxt/pro/coinbase.py +102 -73
  336. ccxt/pro/coinbaseadvanced.py +2 -1
  337. ccxt/pro/coinbaseexchange.py +8 -8
  338. ccxt/pro/coinbaseinternational.py +181 -25
  339. ccxt/pro/coincatch.py +6 -7
  340. ccxt/pro/coincheck.py +11 -6
  341. ccxt/pro/coinex.py +967 -665
  342. ccxt/pro/coinone.py +16 -9
  343. ccxt/pro/cryptocom.py +448 -45
  344. ccxt/pro/defx.py +831 -0
  345. ccxt/pro/deribit.py +150 -14
  346. ccxt/pro/derive.py +704 -0
  347. ccxt/pro/exmo.py +239 -6
  348. ccxt/pro/gate.py +623 -65
  349. ccxt/pro/gateio.py +2 -1
  350. ccxt/pro/gemini.py +27 -11
  351. ccxt/pro/hashkey.py +2 -2
  352. ccxt/pro/hitbtc.py +196 -91
  353. ccxt/pro/hollaex.py +23 -7
  354. ccxt/pro/htx.py +51 -14
  355. ccxt/pro/huobi.py +2 -1
  356. ccxt/pro/hyperliquid.py +591 -27
  357. ccxt/pro/independentreserve.py +9 -6
  358. ccxt/pro/kraken.py +640 -320
  359. ccxt/pro/krakenfutures.py +62 -35
  360. ccxt/pro/kucoin.py +267 -46
  361. ccxt/pro/kucoinfutures.py +165 -21
  362. ccxt/pro/lbank.py +102 -21
  363. ccxt/pro/luno.py +12 -8
  364. ccxt/pro/mexc.py +877 -111
  365. ccxt/pro/modetrade.py +1271 -0
  366. ccxt/pro/myokx.py +38 -0
  367. ccxt/pro/ndax.py +15 -2
  368. ccxt/pro/okcoin.py +23 -4
  369. ccxt/pro/okx.py +573 -98
  370. ccxt/pro/okxus.py +38 -0
  371. ccxt/pro/onetrading.py +30 -13
  372. ccxt/pro/oxfun.py +131 -27
  373. ccxt/pro/p2b.py +88 -22
  374. ccxt/pro/paradex.py +3 -3
  375. ccxt/pro/phemex.py +75 -21
  376. ccxt/pro/poloniex.py +124 -41
  377. ccxt/pro/probit.py +87 -80
  378. ccxt/pro/tradeogre.py +272 -0
  379. ccxt/pro/upbit.py +152 -12
  380. ccxt/pro/vertex.py +8 -3
  381. ccxt/pro/whitebit.py +58 -5
  382. ccxt/pro/woo.py +228 -37
  383. ccxt/pro/woofipro.py +106 -18
  384. ccxt/pro/xt.py +111 -5
  385. ccxt/probit.py +224 -95
  386. ccxt/protobuf/__init__.py +0 -0
  387. ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
  388. ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
  389. ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
  390. ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
  391. ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
  392. ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
  393. ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
  394. ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
  395. ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
  396. ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
  397. ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
  398. ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
  399. ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
  400. ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
  401. ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
  402. ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
  403. ccxt/protobuf/mexc/__init__.py +0 -0
  404. ccxt/ramzinex.py +32 -28
  405. ccxt/sarmayex.py +7 -7
  406. ccxt/sarrafex.py +10 -10
  407. ccxt/static_dependencies/__init__.py +1 -1
  408. ccxt/static_dependencies/lark/py.typed +0 -0
  409. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  410. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  411. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  412. ccxt/tabdeal.py +13 -12
  413. ccxt/test/tests_async.py +261 -57
  414. ccxt/test/tests_helpers.py +1 -3
  415. ccxt/test/tests_init.py +4 -3
  416. ccxt/test/tests_sync.py +261 -57
  417. ccxt/tetherland.py +7 -7
  418. ccxt/timex.py +210 -51
  419. ccxt/tokocrypto.py +167 -47
  420. ccxt/tradeogre.py +266 -31
  421. ccxt/twox.py +7 -7
  422. ccxt/ubitex.py +9 -9
  423. ccxt/upbit.py +568 -165
  424. ccxt/vertex.py +160 -32
  425. ccxt/wallex.py +9 -9
  426. ccxt/wavesexchange.py +165 -30
  427. ccxt/whitebit.py +975 -127
  428. ccxt/woo.py +1917 -1016
  429. ccxt/woofipro.py +432 -141
  430. ccxt/xt.py +649 -193
  431. ccxt/yobit.py +194 -70
  432. ccxt/zaif.py +91 -15
  433. ccxt/zonda.py +151 -36
  434. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/METADATA +225 -73
  435. ccxt_ir-4.5.1.dist-info/RECORD +743 -0
  436. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/WHEEL +1 -1
  437. ccxt/__test__.py +0 -7
  438. ccxt/abstract/ace.py +0 -15
  439. ccxt/abstract/bitbay.py +0 -53
  440. ccxt/abstract/bitcoincom.py +0 -115
  441. ccxt/abstract/bitfinex2.py +0 -139
  442. ccxt/abstract/bitpanda.py +0 -35
  443. ccxt/abstract/bl3p.py +0 -19
  444. ccxt/abstract/coinlist.py +0 -54
  445. ccxt/abstract/currencycom.py +0 -68
  446. ccxt/abstract/hitbtc3.py +0 -115
  447. ccxt/abstract/idex.py +0 -26
  448. ccxt/abstract/kuna.py +0 -182
  449. ccxt/abstract/lykke.py +0 -29
  450. ccxt/abstract/poloniexfutures.py +0 -48
  451. ccxt/abstract/wazirx.py +0 -30
  452. ccxt/ace.py +0 -1012
  453. ccxt/async_support/ace.py +0 -1012
  454. ccxt/async_support/base/ws/aiohttp_client.py +0 -125
  455. ccxt/async_support/base/ws/fast_client.py +0 -96
  456. ccxt/async_support/bitbay.py +0 -17
  457. ccxt/async_support/bitcoincom.py +0 -17
  458. ccxt/async_support/bitfinex2.py +0 -3552
  459. ccxt/async_support/bitpanda.py +0 -16
  460. ccxt/async_support/bl3p.py +0 -485
  461. ccxt/async_support/coinlist.py +0 -2243
  462. ccxt/async_support/currencycom.py +0 -1950
  463. ccxt/async_support/hitbtc3.py +0 -16
  464. ccxt/async_support/idex.py +0 -1766
  465. ccxt/async_support/kuna.py +0 -1841
  466. ccxt/async_support/lykke.py +0 -1270
  467. ccxt/async_support/poloniexfutures.py +0 -1717
  468. ccxt/async_support/wazirx.py +0 -1224
  469. ccxt/bitbay.py +0 -17
  470. ccxt/bitcoincom.py +0 -17
  471. ccxt/bitfinex2.py +0 -3552
  472. ccxt/bitpanda.py +0 -16
  473. ccxt/bl3p.py +0 -485
  474. ccxt/coinlist.py +0 -2243
  475. ccxt/currencycom.py +0 -1950
  476. ccxt/hitbtc3.py +0 -16
  477. ccxt/idex.py +0 -1766
  478. ccxt/kuna.py +0 -1841
  479. ccxt/lykke.py +0 -1270
  480. ccxt/poloniexfutures.py +0 -1717
  481. ccxt/pro/bitcoincom.py +0 -34
  482. ccxt/pro/bitfinex2.py +0 -1083
  483. ccxt/pro/bitpanda.py +0 -15
  484. ccxt/pro/currencycom.py +0 -536
  485. ccxt/pro/idex.py +0 -672
  486. ccxt/pro/poloniexfutures.py +0 -990
  487. ccxt/pro/wazirx.py +0 -749
  488. ccxt/test/base/__init__.py +0 -29
  489. ccxt/test/base/test_account.py +0 -26
  490. ccxt/test/base/test_balance.py +0 -56
  491. ccxt/test/base/test_borrow_interest.py +0 -35
  492. ccxt/test/base/test_borrow_rate.py +0 -32
  493. ccxt/test/base/test_calculate_fee.py +0 -51
  494. ccxt/test/base/test_crypto.py +0 -127
  495. ccxt/test/base/test_currency.py +0 -76
  496. ccxt/test/base/test_datetime.py +0 -109
  497. ccxt/test/base/test_decimal_to_precision.py +0 -392
  498. ccxt/test/base/test_deep_extend.py +0 -68
  499. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  500. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  501. ccxt/test/base/test_funding_rate_history.py +0 -29
  502. ccxt/test/base/test_last_price.py +0 -31
  503. ccxt/test/base/test_ledger_entry.py +0 -45
  504. ccxt/test/base/test_ledger_item.py +0 -48
  505. ccxt/test/base/test_leverage_tier.py +0 -33
  506. ccxt/test/base/test_liquidation.py +0 -50
  507. ccxt/test/base/test_margin_mode.py +0 -24
  508. ccxt/test/base/test_margin_modification.py +0 -35
  509. ccxt/test/base/test_market.py +0 -193
  510. ccxt/test/base/test_number.py +0 -411
  511. ccxt/test/base/test_ohlcv.py +0 -33
  512. ccxt/test/base/test_open_interest.py +0 -32
  513. ccxt/test/base/test_order.py +0 -64
  514. ccxt/test/base/test_order_book.py +0 -69
  515. ccxt/test/base/test_position.py +0 -60
  516. ccxt/test/base/test_shared_methods.py +0 -353
  517. ccxt/test/base/test_status.py +0 -24
  518. ccxt/test/base/test_throttle.py +0 -126
  519. ccxt/test/base/test_ticker.py +0 -92
  520. ccxt/test/base/test_trade.py +0 -47
  521. ccxt/test/base/test_trading_fee.py +0 -26
  522. ccxt/test/base/test_transaction.py +0 -39
  523. ccxt/test/test_async.py +0 -1649
  524. ccxt/test/test_sync.py +0 -1648
  525. ccxt/wazirx.py +0 -1224
  526. ccxt_ir-4.3.46.0.3.dist-info/RECORD +0 -773
  527. /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
  528. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info/licenses}/LICENSE.txt +0 -0
  529. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/top_level.txt +0 -0
@@ -9,7 +9,7 @@ import asyncio
9
9
  import hashlib
10
10
  import math
11
11
  import json
12
- from ccxt.base.types import Account, Balances, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
12
+ from ccxt.base.types import Account, Any, Balances, BorrowInterest, Bool, Currencies, Currency, DepositAddress, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
13
13
  from typing import List
14
14
  from ccxt.base.errors import ExchangeError
15
15
  from ccxt.base.errors import AuthenticationError
@@ -33,7 +33,7 @@ from ccxt.base.precise import Precise
33
33
 
34
34
  class kucoin(Exchange, ImplicitAPI):
35
35
 
36
- def describe(self):
36
+ def describe(self) -> Any:
37
37
  return self.deep_extend(super(kucoin, self).describe(), {
38
38
  'id': 'kucoin',
39
39
  'name': 'KuCoin',
@@ -79,6 +79,7 @@ class kucoin(Exchange, ImplicitAPI):
79
79
  'fetchCrossBorrowRates': False,
80
80
  'fetchCurrencies': True,
81
81
  'fetchDepositAddress': True,
82
+ 'fetchDepositAddresses': False,
82
83
  'fetchDepositAddressesByNetwork': True,
83
84
  'fetchDeposits': True,
84
85
  'fetchDepositWithdrawFee': True,
@@ -98,6 +99,8 @@ class kucoin(Exchange, ImplicitAPI):
98
99
  'fetchMarketLeverageTiers': False,
99
100
  'fetchMarkets': True,
100
101
  'fetchMarkOHLCV': False,
102
+ 'fetchMarkPrice': True,
103
+ 'fetchMarkPrices': True,
101
104
  'fetchMyTrades': True,
102
105
  'fetchOHLCV': True,
103
106
  'fetchOpenInterest': False,
@@ -124,7 +127,7 @@ class kucoin(Exchange, ImplicitAPI):
124
127
  'fetchWithdrawals': True,
125
128
  'repayCrossMargin': True,
126
129
  'repayIsolatedMargin': True,
127
- 'setLeverage': False,
130
+ 'setLeverage': True,
128
131
  'setMarginMode': False,
129
132
  'setPositionMode': False,
130
133
  'signIn': False,
@@ -179,7 +182,9 @@ class kucoin(Exchange, ImplicitAPI):
179
182
  'status': 4.5, # 3PW
180
183
  # margin trading
181
184
  'mark-price/{symbol}/current': 3, # 2PW
185
+ 'mark-price/all-symbols': 3,
182
186
  'margin/config': 25, # 25SW
187
+ 'announcements': 20, # 20W
183
188
  },
184
189
  'post': {
185
190
  # ws
@@ -218,8 +223,10 @@ class kucoin(Exchange, ImplicitAPI):
218
223
  'market/orderbook/level{level}': 3, # 3SW
219
224
  'market/orderbook/level2': 3, # 3SW
220
225
  'market/orderbook/level3': 3, # 3SW
226
+ 'hf/accounts/opened': 2, #
221
227
  'hf/orders/active': 2, # 2SW
222
228
  'hf/orders/active/symbols': 2, # 2SW
229
+ 'hf/margin/order/active/symbols': 2, # 2SW
223
230
  'hf/orders/done': 2, # 2SW
224
231
  'hf/orders/{orderId}': 2, # 2SW
225
232
  'hf/orders/client-order/{clientOid}': 2, # 2SW
@@ -248,6 +255,7 @@ class kucoin(Exchange, ImplicitAPI):
248
255
  'margin/currencies': 20, # 20SW
249
256
  'risk/limit/strategy': 20, # 20SW(Deprecate)
250
257
  'isolated/symbols': 20, # 20SW
258
+ 'margin/symbols': 5,
251
259
  'isolated/account/{symbol}': 50, # 50SW
252
260
  'margin/borrow': 15, # 15SW
253
261
  'margin/repay': 15, # 15SW
@@ -258,6 +266,9 @@ class kucoin(Exchange, ImplicitAPI):
258
266
  'purchase/orders': 10, # 10SW
259
267
  # broker
260
268
  'broker/api/rebase/download': 3,
269
+ 'migrate/user/account/status': 3,
270
+ # affiliate
271
+ 'affiliate/inviter/statistics': 30,
261
272
  },
262
273
  'post': {
263
274
  # account
@@ -297,6 +308,8 @@ class kucoin(Exchange, ImplicitAPI):
297
308
  'lend/purchase/update': 10, # 10SW
298
309
  # ws
299
310
  'bullet-private': 10, # 10SW
311
+ 'position/update-user-leverage': 5,
312
+ 'deposit-address/create': 20,
300
313
  },
301
314
  'delete': {
302
315
  # account
@@ -409,6 +422,7 @@ class kucoin(Exchange, ImplicitAPI):
409
422
  'broker/nd/account': 2,
410
423
  'broker/nd/account/apikey': 2,
411
424
  'broker/nd/rebase/download': 3,
425
+ 'asset/ndbroker/deposit/list': 1,
412
426
  'broker/nd/transfer/detail': 1,
413
427
  'broker/nd/deposit/detail': 1,
414
428
  'broker/nd/withdraw/detail': 1,
@@ -462,6 +476,7 @@ class kucoin(Exchange, ImplicitAPI):
462
476
  'precisionMode': TICK_SIZE,
463
477
  'exceptions': {
464
478
  'exact': {
479
+ 'The order does not exist.': OrderNotFound,
465
480
  'order not exist': OrderNotFound,
466
481
  'order not exist.': OrderNotFound, # duplicated error temporarily
467
482
  'order_not_exist': OrderNotFound, # {"code":"order_not_exist","msg":"order_not_exist"} ¯\_(ツ)_/¯
@@ -562,6 +577,7 @@ class kucoin(Exchange, ImplicitAPI):
562
577
  '400008': NotSupported,
563
578
  '400100': InsufficientFunds, # {"msg":"account.available.amount","code":"400100"} or {"msg":"Withdrawal amount is below the minimum requirement.","code":"400100"}
564
579
  '400200': InvalidOrder, # {"code":"400200","msg":"Forbidden to place an order"}
580
+ '400330': InvalidOrder, # {"msg":"Order price can't deviate from NAV by 50%","code":"400330"}
565
581
  '400350': InvalidOrder, # {"code":"400350","msg":"Upper limit for holding: 10,000USDT, you can still buy 10,000USDT worth of coin."}
566
582
  '400370': InvalidOrder, # {"code":"400370","msg":"Max. price: 0.02500000000000000000"}
567
583
  '400400': BadRequest, # Parameter error
@@ -576,6 +592,8 @@ class kucoin(Exchange, ImplicitAPI):
576
592
  '400303': PermissionDenied, # {"msg":"To enjoy the full range of our products and services, we kindly request you complete the identity verification process.","code":"400303"}
577
593
  '500000': ExchangeNotAvailable, # {"code":"500000","msg":"Internal Server Error"}
578
594
  '260220': InvalidAddress, # {"code": "260220", "msg": "deposit.address.not.exists"}
595
+ '600100': InsufficientFunds, # {"msg":"Funds below the minimum requirement.","code":"600100"}
596
+ '600101': InvalidOrder, # {"msg":"The order funds should more then 0.1 USDT.","code":"600101"}
579
597
  '900014': BadRequest, # {"code":"900014","msg":"Invalid chainId"}
580
598
  },
581
599
  'broad': {
@@ -635,11 +653,15 @@ class kucoin(Exchange, ImplicitAPI):
635
653
  'WAX': 'WAXP',
636
654
  'ALT': 'APTOSLAUNCHTOKEN',
637
655
  'KALT': 'ALT', # ALTLAYER
656
+ 'FUD': 'FTX Users\' Debt',
638
657
  },
639
658
  'options': {
659
+ 'hf': None, # would be auto set to `true/false` after first load
640
660
  'version': 'v1',
641
661
  'symbolSeparator': '-',
642
662
  'fetchMyTradesMethod': 'private_get_fills',
663
+ 'timeDifference': 0, # the difference between system clock and Binance clock
664
+ 'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
643
665
  'fetchCurrencies': {
644
666
  'webApiEnable': True, # fetches from WEB
645
667
  'webApiRetries': 1,
@@ -659,6 +681,8 @@ class kucoin(Exchange, ImplicitAPI):
659
681
  'currencies': 'v3',
660
682
  'currencies/{currency}': 'v3',
661
683
  'symbols': 'v2',
684
+ 'mark-price/all-symbols': 'v3',
685
+ 'announcements': 'v3',
662
686
  },
663
687
  },
664
688
  'private': {
@@ -683,6 +707,7 @@ class kucoin(Exchange, ImplicitAPI):
683
707
  'oco/orders': 'v3',
684
708
  # margin trading
685
709
  'hf/margin/orders/active': 'v3',
710
+ 'hf/margin/order/active/symbols': 'v3',
686
711
  'hf/margin/orders/done': 'v3',
687
712
  'hf/margin/orders/{orderId}': 'v3',
688
713
  'hf/margin/orders/client-order/{clientOid}': 'v3',
@@ -696,6 +721,10 @@ class kucoin(Exchange, ImplicitAPI):
696
721
  'project/marketInterestRate': 'v3',
697
722
  'redeem/orders': 'v3',
698
723
  'purchase/orders': 'v3',
724
+ 'migrate/user/account/status': 'v3',
725
+ 'margin/symbols': 'v3',
726
+ 'affiliate/inviter/statistics': 'v2',
727
+ 'asset/ndbroker/deposit/list': 'v1',
699
728
  },
700
729
  'POST': {
701
730
  # account
@@ -705,6 +734,7 @@ class kucoin(Exchange, ImplicitAPI):
705
734
  'accounts/sub-transfer': 'v2',
706
735
  'accounts/inner-transfer': 'v2',
707
736
  'transfer-out': 'v3',
737
+ 'deposit-address/create': 'v3',
708
738
  # spot trading
709
739
  'oco/order': 'v3',
710
740
  # margin trading
@@ -715,6 +745,8 @@ class kucoin(Exchange, ImplicitAPI):
715
745
  'purchase': 'v3',
716
746
  'redeem': 'v3',
717
747
  'lend/purchase/update': 'v3',
748
+ 'position/update-user-leverage': 'v3',
749
+ 'withdrawals': 'v3',
718
750
  },
719
751
  'DELETE': {
720
752
  # account
@@ -762,7 +794,7 @@ class kucoin(Exchange, ImplicitAPI):
762
794
  'hf': 'trade_hf',
763
795
  },
764
796
  'networks': {
765
- 'BTC': 'btc',
797
+ 'BRC20': 'btc',
766
798
  'BTCNATIVESEGWIT': 'bech32',
767
799
  'ERC20': 'eth',
768
800
  'TRC20': 'trx',
@@ -899,6 +931,8 @@ class kucoin(Exchange, ImplicitAPI):
899
931
  'TRUE': 'true',
900
932
  'CS': 'cs',
901
933
  'ORAI': 'orai',
934
+ 'BASE': 'base',
935
+ 'TARA': 'tara',
902
936
  # below will be uncommented after consensus
903
937
  # 'BITCOINDIAMON': 'bcd',
904
938
  # 'BITCOINGOLD': 'btg',
@@ -974,15 +1008,89 @@ class kucoin(Exchange, ImplicitAPI):
974
1008
  'spot': 'TRADE',
975
1009
  },
976
1010
  },
1011
+ 'features': {
1012
+ 'spot': {
1013
+ 'sandbox': False,
1014
+ 'createOrder': {
1015
+ 'marginMode': True,
1016
+ 'triggerPrice': True,
1017
+ 'triggerPriceType': None,
1018
+ 'triggerDirection': False,
1019
+ 'stopLossPrice': True,
1020
+ 'takeProfitPrice': True,
1021
+ 'attachedStopLossTakeProfit': None, # not supported
1022
+ 'timeInForce': {
1023
+ 'IOC': True,
1024
+ 'FOK': True,
1025
+ 'PO': True,
1026
+ 'GTD': True,
1027
+ },
1028
+ 'hedged': False,
1029
+ 'trailing': False,
1030
+ 'leverage': False,
1031
+ 'marketBuyByCost': True,
1032
+ 'marketBuyRequiresPrice': False,
1033
+ 'selfTradePrevention': True, # todo implement
1034
+ 'iceberg': True, # todo implement
1035
+ },
1036
+ 'createOrders': {
1037
+ 'max': 5,
1038
+ },
1039
+ 'fetchMyTrades': {
1040
+ 'marginMode': True,
1041
+ 'limit': None,
1042
+ 'daysBack': None,
1043
+ 'untilDays': 7, # per implementation comments
1044
+ 'symbolRequired': True,
1045
+ },
1046
+ 'fetchOrder': {
1047
+ 'marginMode': False,
1048
+ 'trigger': True,
1049
+ 'trailing': False,
1050
+ 'symbolRequired': True,
1051
+ },
1052
+ 'fetchOpenOrders': {
1053
+ 'marginMode': True,
1054
+ 'limit': 500,
1055
+ 'trigger': True,
1056
+ 'trailing': False,
1057
+ 'symbolRequired': True,
1058
+ },
1059
+ 'fetchOrders': None,
1060
+ 'fetchClosedOrders': {
1061
+ 'marginMode': True,
1062
+ 'limit': 500,
1063
+ 'daysBack': None,
1064
+ 'daysBackCanceled': None,
1065
+ 'untilDays': 7,
1066
+ 'trigger': True,
1067
+ 'trailing': False,
1068
+ 'symbolRequired': True,
1069
+ },
1070
+ 'fetchOHLCV': {
1071
+ 'limit': 1500,
1072
+ },
1073
+ },
1074
+ 'swap': {
1075
+ 'linear': None,
1076
+ 'inverse': None,
1077
+ },
1078
+ 'future': {
1079
+ 'linear': None,
1080
+ 'inverse': None,
1081
+ },
1082
+ },
977
1083
  })
978
1084
 
979
1085
  def nonce(self):
980
- return self.milliseconds()
1086
+ return self.milliseconds() - self.options['timeDifference']
981
1087
 
982
- async def fetch_time(self, params={}):
1088
+ async def fetch_time(self, params={}) -> Int:
983
1089
  """
984
1090
  fetches the current integer timestamp in milliseconds from the exchange server
985
- :see: https://docs.kucoin.com/#server-time
1091
+
1092
+ https://docs.kucoin.com/#server-time
1093
+
986
1094
  :param dict [params]: extra parameters specific to the exchange API endpoint
987
1095
  :returns int: the current integer timestamp in milliseconds from the exchange server
988
1096
  """
@@ -999,7 +1107,9 @@ class kucoin(Exchange, ImplicitAPI):
999
1107
  async def fetch_status(self, params={}):
1000
1108
  """
1001
1109
  the latest known information on the availability of the exchange API
1002
- :see: https://docs.kucoin.com/#service-status
1110
+
1111
+ https://docs.kucoin.com/#service-status
1112
+
1003
1113
  :param dict [params]: extra parameters specific to the exchange API endpoint
1004
1114
  :returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
1005
1115
  """
@@ -1026,12 +1136,17 @@ class kucoin(Exchange, ImplicitAPI):
1026
1136
  async def fetch_markets(self, params={}) -> List[Market]:
1027
1137
  """
1028
1138
  retrieves data on all markets for kucoin
1029
- :see: https://docs.kucoin.com/#get-symbols-list-deprecated
1030
- :see: https://docs.kucoin.com/#get-all-tickers
1139
+
1140
+ https://docs.kucoin.com/#get-symbols-list-deprecated
1141
+ https://docs.kucoin.com/#get-all-tickers
1142
+
1031
1143
  :param dict [params]: extra parameters specific to the exchange API endpoint
1032
1144
  :returns dict[]: an array of objects representing market data
1033
1145
  """
1034
- response = await self.publicGetSymbols(params)
1146
+ fetchTickersFees = None
1147
+ fetchTickersFees, params = self.handle_option_and_params(params, 'fetchMarkets', 'fetchTickersFees', True)
1148
+ promises = []
1149
+ promises.append(self.publicGetSymbols(params))
1035
1150
  #
1036
1151
  # {
1037
1152
  # "code": "200000",
@@ -1054,59 +1169,102 @@ class kucoin(Exchange, ImplicitAPI):
1054
1169
  # "isMarginEnabled": True,
1055
1170
  # "enableTrading": True
1056
1171
  # },
1057
- # ]
1058
- # }
1059
1172
  #
1060
- data = self.safe_list(response, 'data')
1061
- options = self.safe_dict(self.options, 'fetchMarkets', {})
1062
- fetchTickersFees = self.safe_bool(options, 'fetchTickersFees', True)
1063
- tickersResponse: dict = {}
1173
+ credentialsSet = self.check_required_credentials(False)
1174
+ requestMarginables = credentialsSet and self.safe_bool(params, 'marginables', True)
1175
+ if requestMarginables:
1176
+ promises.append(self.privateGetMarginSymbols(params)) # cross margin symbols
1177
+ #
1178
+ # {
1179
+ # "code": "200000",
1180
+ # "data": {
1181
+ # "timestamp": 1719393213421,
1182
+ # "items": [
1183
+ # {
1184
+ # # same object market, with one additional field:
1185
+ # "minFunds": "0.1"
1186
+ # },
1187
+ #
1188
+ promises.append(self.privateGetIsolatedSymbols(params)) # isolated margin symbols
1189
+ #
1190
+ # {
1191
+ # "code": "200000",
1192
+ # "data": [
1193
+ # {
1194
+ # "symbol": "NKN-USDT",
1195
+ # "symbolName": "NKN-USDT",
1196
+ # "baseCurrency": "NKN",
1197
+ # "quoteCurrency": "USDT",
1198
+ # "maxLeverage": 5,
1199
+ # "flDebtRatio": "0.97",
1200
+ # "tradeEnable": True,
1201
+ # "autoRenewMaxDebtRatio": "0.96",
1202
+ # "baseBorrowEnable": True,
1203
+ # "quoteBorrowEnable": True,
1204
+ # "baseTransferInEnable": True,
1205
+ # "quoteTransferInEnable": True,
1206
+ # "baseBorrowCoefficient": "1",
1207
+ # "quoteBorrowCoefficient": "1"
1208
+ # },
1209
+ #
1064
1210
  if fetchTickersFees:
1065
- tickersResponse = await self.publicGetMarketAllTickers(params)
1066
- #
1067
- # {
1068
- # "code": "200000",
1069
- # "data": {
1070
- # "time":1602832092060,
1071
- # "ticker":[
1072
- # {
1073
- # "symbol": "BTC-USDT", # symbol
1074
- # "symbolName":"BTC-USDT", # Name of trading pairs, it would change after renaming
1075
- # "buy": "11328.9", # bestAsk
1076
- # "sell": "11329", # bestBid
1077
- # "changeRate": "-0.0055", # 24h change rate
1078
- # "changePrice": "-63.6", # 24h change price
1079
- # "high": "11610", # 24h highest price
1080
- # "low": "11200", # 24h lowest price
1081
- # "vol": "2282.70993217", # 24h volume,the aggregated trading volume in BTC
1082
- # "volValue": "25984946.157790431", # 24h total, the trading volume in quote currency of last 24 hours
1083
- # "last": "11328.9", # last price
1084
- # "averagePrice": "11360.66065903", # 24h average transaction price yesterday
1085
- # "takerFeeRate": "0.001", # Basic Taker Fee
1086
- # "makerFeeRate": "0.001", # Basic Maker Fee
1087
- # "takerCoefficient": "1", # Taker Fee Coefficient
1088
- # "makerCoefficient": "1" # Maker Fee Coefficient
1089
- # }
1090
- # ]
1091
- # }
1092
- # }
1093
- #
1094
- tickersData = self.safe_dict(tickersResponse, 'data', {})
1095
- tickers = self.safe_list(tickersData, 'ticker', [])
1096
- tickersByMarketId = self.index_by(tickers, 'symbol')
1211
+ promises.append(self.publicGetMarketAllTickers(params))
1212
+ #
1213
+ # {
1214
+ # "code": "200000",
1215
+ # "data": {
1216
+ # "time":1602832092060,
1217
+ # "ticker":[
1218
+ # {
1219
+ # "symbol": "BTC-USDT", # symbol
1220
+ # "symbolName":"BTC-USDT", # Name of trading pairs, it would change after renaming
1221
+ # "buy": "11328.9", # bestAsk
1222
+ # "sell": "11329", # bestBid
1223
+ # "changeRate": "-0.0055", # 24h change rate
1224
+ # "changePrice": "-63.6", # 24h change price
1225
+ # "high": "11610", # 24h highest price
1226
+ # "low": "11200", # 24h lowest price
1227
+ # "vol": "2282.70993217", # 24h volume,the aggregated trading volume in BTC
1228
+ # "volValue": "25984946.157790431", # 24h total, the trading volume in quote currency of last 24 hours
1229
+ # "last": "11328.9", # last price
1230
+ # "averagePrice": "11360.66065903", # 24h average transaction price yesterday
1231
+ # "takerFeeRate": "0.001", # Basic Taker Fee
1232
+ # "makerFeeRate": "0.001", # Basic Maker Fee
1233
+ # "takerCoefficient": "1", # Taker Fee Coefficient
1234
+ # "makerCoefficient": "1" # Maker Fee Coefficient
1235
+ # }
1236
+ #
1237
+ if credentialsSet:
1238
+ # load migration status for account
1239
+ promises.append(self.load_migration_status())
1240
+ responses = await asyncio.gather(*promises)
1241
+ symbolsData = self.safe_list(responses[0], 'data')
1242
+ crossData = self.safe_dict(responses[1], 'data', {}) if requestMarginables else {}
1243
+ crossItems = self.safe_list(crossData, 'items', [])
1244
+ crossById = self.index_by(crossItems, 'symbol')
1245
+ isolatedData = responses[2] if requestMarginables else {}
1246
+ isolatedItems = self.safe_list(isolatedData, 'data', [])
1247
+ isolatedById = self.index_by(isolatedItems, 'symbol')
1248
+ tickersIdx = 3 if requestMarginables else 1
1249
+ tickersResponse = self.safe_dict(responses, tickersIdx, {})
1250
+ tickerItems = self.safe_list(self.safe_dict(tickersResponse, 'data', {}), 'ticker', [])
1251
+ tickersById = self.index_by(tickerItems, 'symbol')
1097
1252
  result = []
1098
- for i in range(0, len(data)):
1099
- market = data[i]
1253
+ for i in range(0, len(symbolsData)):
1254
+ market = symbolsData[i]
1100
1255
  id = self.safe_string(market, 'symbol')
1101
1256
  baseId, quoteId = id.split('-')
1102
1257
  base = self.safe_currency_code(baseId)
1103
1258
  quote = self.safe_currency_code(quoteId)
1104
1259
  # quoteIncrement = self.safe_number(market, 'quoteIncrement')
1105
- ticker = self.safe_dict(tickersByMarketId, id, {})
1260
+ ticker = self.safe_dict(tickersById, id, {})
1106
1261
  makerFeeRate = self.safe_string(ticker, 'makerFeeRate')
1107
1262
  takerFeeRate = self.safe_string(ticker, 'takerFeeRate')
1108
1263
  makerCoefficient = self.safe_string(ticker, 'makerCoefficient')
1109
1264
  takerCoefficient = self.safe_string(ticker, 'takerCoefficient')
1265
+ hasCrossMargin = (id in crossById)
1266
+ hasIsolatedMargin = (id in isolatedById)
1267
+ isMarginable = self.safe_bool(market, 'isMarginEnabled', False) or hasCrossMargin or hasIsolatedMargin
1110
1268
  result.append({
1111
1269
  'id': id,
1112
1270
  'symbol': base + '/' + quote,
@@ -1118,7 +1276,11 @@ class kucoin(Exchange, ImplicitAPI):
1118
1276
  'settleId': None,
1119
1277
  'type': 'spot',
1120
1278
  'spot': True,
1121
- 'margin': self.safe_bool(market, 'isMarginEnabled'),
1279
+ 'margin': isMarginable,
1280
+ 'marginModes': {
1281
+ 'cross': hasCrossMargin,
1282
+ 'isolated': hasIsolatedMargin,
1283
+ },
1122
1284
  'swap': False,
1123
1285
  'future': False,
1124
1286
  'option': False,
@@ -1158,17 +1320,46 @@ class kucoin(Exchange, ImplicitAPI):
1158
1320
  'created': None,
1159
1321
  'info': market,
1160
1322
  })
1323
+ if self.options['adjustForTimeDifference']:
1324
+ await self.load_time_difference()
1161
1325
  return result
1162
1326
 
1327
+ async def load_migration_status(self, force: bool = False):
1328
+ """
1329
+ :param boolean force: load account state for non hf
1330
+ loads the migration status for the account(hf or not)
1331
+
1332
+ https://www.kucoin.com/docs/rest/spot-trading/spot-hf-trade-pro-account/get-user-type
1333
+
1334
+ :returns any: ignore
1335
+ """
1336
+ if not ('hf' in self.options) or (self.options['hf'] is None) or force:
1337
+ result: dict = await self.privateGetHfAccountsOpened()
1338
+ self.options['hf'] = self.safe_bool(result, 'data')
1339
+ return True
1340
+
1341
+ def handle_hf_and_params(self, params={}):
1342
+ migrated: Bool = self.safe_bool(self.options, 'hf', False)
1343
+ loadedHf: Bool = None
1344
+ if migrated is not None:
1345
+ if migrated:
1346
+ loadedHf = True
1347
+ else:
1348
+ loadedHf = False
1349
+ hf: Bool = self.safe_bool(params, 'hf', loadedHf)
1350
+ params = self.omit(params, 'hf')
1351
+ return [hf, params]
1352
+
1163
1353
  async def fetch_currencies(self, params={}) -> Currencies:
1164
1354
  """
1165
1355
  fetches all available currencies on an exchange
1166
- :see: https://docs.kucoin.com/#get-currencies
1356
+
1357
+ https://docs.kucoin.com/#get-currencies
1358
+
1167
1359
  :param dict params: extra parameters specific to the exchange API endpoint
1168
1360
  :returns dict: an associative dictionary of currencies
1169
1361
  """
1170
- promises = []
1171
- promises.append(self.publicGetCurrencies(params))
1362
+ response = await self.publicGetCurrencies(params)
1172
1363
  #
1173
1364
  # {
1174
1365
  # "code":"200000",
@@ -1194,130 +1385,82 @@ class kucoin(Exchange, ImplicitAPI):
1194
1385
  # "isDepositEnabled":false,
1195
1386
  # "confirms":12,
1196
1387
  # "preConfirms":12,
1388
+ # "withdrawPrecision": 8,
1389
+ # "maxWithdraw": null,
1390
+ # "maxDeposit": null,
1391
+ # "needTag": False,
1197
1392
  # "contractAddress":"0xa6446d655a0c34bc4f05042ee88170d056cbaf45",
1198
1393
  # "depositFeeRate": "0.001", # present for some currencies/networks
1199
1394
  # }
1200
1395
  # ]
1201
1396
  # },
1202
- # }
1203
- #
1204
- promises.append(self.fetch_web_endpoint('fetchCurrencies', 'webExchangeGetCurrencyCurrencyChainInfo', True))
1205
- #
1206
- # {
1207
- # "success": True,
1208
- # "code": "200",
1209
- # "msg": "success",
1210
- # "retry": False,
1211
- # "data": [
1212
- # {
1213
- # "status": "enabled",
1214
- # "currency": "BTC",
1215
- # "isChainEnabled": "true",
1216
- # "chain": "btc",
1217
- # "chainName": "BTC",
1218
- # "chainFullName": "Bitcoin",
1219
- # "walletPrecision": "8",
1220
- # "isDepositEnabled": "true",
1221
- # "depositMinSize": "0.00005",
1222
- # "confirmationCount": "2",
1223
- # "isWithdrawEnabled": "true",
1224
- # "withdrawMinSize": "0.001",
1225
- # "withdrawMinFee": "0.0005",
1226
- # "withdrawFeeRate": "0",
1227
- # "depositDisabledTip": "Wallet Maintenance",
1228
- # "preDepositTipEnabled": "true",
1229
- # "preDepositTip": "Do not transfer from ETH network directly",
1230
- # "withdrawDisabledTip": "",
1231
- # "preWithdrawTipEnabled": "false",
1232
- # "preWithdrawTip": "",
1233
- # "orgAddress": "",
1234
- # "userAddressName": "Memo",
1235
- # },
1236
1397
  # ]
1237
1398
  # }
1238
1399
  #
1239
- responses = await asyncio.gather(*promises)
1240
- currenciesResponse = self.safe_dict(responses, 0, {})
1241
- currenciesData = self.safe_list(currenciesResponse, 'data', [])
1242
- additionalResponse = self.safe_dict(responses, 1, {})
1243
- additionalData = self.safe_list(additionalResponse, 'data', [])
1244
- additionalDataGrouped = self.group_by(additionalData, 'currency')
1400
+ currenciesData = self.safe_list(response, 'data', [])
1401
+ brokenCurrencies = self.safe_list(self.options, 'brokenCurrencies', ['00', 'OPEN_ERROR', 'HUF', 'BDT'])
1402
+ otherFiats = self.safe_list(self.options, 'fiats', ['KWD', 'IRR', 'PKR'])
1245
1403
  result: dict = {}
1246
1404
  for i in range(0, len(currenciesData)):
1247
1405
  entry = currenciesData[i]
1248
1406
  id = self.safe_string(entry, 'currency')
1249
- name = self.safe_string(entry, 'fullName')
1407
+ if self.in_array(id, brokenCurrencies):
1408
+ continue # skip buggy entries: https://t.me/KuCoin_API/217798
1250
1409
  code = self.safe_currency_code(id)
1251
- isWithdrawEnabled = None
1252
- isDepositEnabled = None
1253
1410
  networks: dict = {}
1254
1411
  chains = self.safe_list(entry, 'chains', [])
1255
- extraChainsData = self.index_by(self.safe_list(additionalDataGrouped, id, []), 'chain')
1256
- rawPrecision = self.safe_string(entry, 'precision')
1257
- precision = self.parse_number(self.parse_precision(rawPrecision))
1258
1412
  chainsLength = len(chains)
1259
- if not chainsLength:
1260
- # https://t.me/KuCoin_API/173118
1261
- isWithdrawEnabled = False
1262
- isDepositEnabled = False
1263
1413
  for j in range(0, chainsLength):
1264
1414
  chain = chains[j]
1265
1415
  chainId = self.safe_string(chain, 'chainId')
1266
- networkCode = self.network_id_to_code(chainId)
1267
- chainWithdrawEnabled = self.safe_bool(chain, 'isWithdrawEnabled', False)
1268
- if isWithdrawEnabled is None:
1269
- isWithdrawEnabled = chainWithdrawEnabled
1270
- else:
1271
- isWithdrawEnabled = isWithdrawEnabled or chainWithdrawEnabled
1272
- chainDepositEnabled = self.safe_bool(chain, 'isDepositEnabled', False)
1273
- if isDepositEnabled is None:
1274
- isDepositEnabled = chainDepositEnabled
1275
- else:
1276
- isDepositEnabled = isDepositEnabled or chainDepositEnabled
1277
- chainExtraData = self.safe_dict(extraChainsData, chainId, {})
1416
+ networkCode = self.network_id_to_code(chainId, code)
1278
1417
  networks[networkCode] = {
1279
1418
  'info': chain,
1280
1419
  'id': chainId,
1281
1420
  'name': self.safe_string(chain, 'chainName'),
1282
1421
  'code': networkCode,
1283
- 'active': chainWithdrawEnabled and chainDepositEnabled,
1422
+ 'active': None,
1284
1423
  'fee': self.safe_number(chain, 'withdrawalMinFee'),
1285
- 'deposit': chainDepositEnabled,
1286
- 'withdraw': chainWithdrawEnabled,
1287
- 'precision': self.parse_number(self.parse_precision(self.safe_string(chainExtraData, 'walletPrecision'))),
1424
+ 'deposit': self.safe_bool(chain, 'isDepositEnabled'),
1425
+ 'withdraw': self.safe_bool(chain, 'isWithdrawEnabled'),
1426
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'withdrawPrecision'))),
1288
1427
  'limits': {
1289
1428
  'withdraw': {
1290
1429
  'min': self.safe_number(chain, 'withdrawalMinSize'),
1291
- 'max': None,
1430
+ 'max': self.safe_number(chain, 'maxWithdraw'),
1292
1431
  },
1293
1432
  'deposit': {
1294
1433
  'min': self.safe_number(chain, 'depositMinSize'),
1295
- 'max': None,
1434
+ 'max': self.safe_number(chain, 'maxDeposit'),
1296
1435
  },
1297
1436
  },
1298
1437
  }
1299
1438
  # kucoin has determined 'fiat' currencies with below logic
1300
- isFiat = (rawPrecision == '2') and (chainsLength == 0)
1301
- result[code] = {
1439
+ rawPrecision = self.safe_string(entry, 'precision')
1440
+ precision = self.parse_number(self.parse_precision(rawPrecision))
1441
+ isFiat = self.in_array(id, otherFiats) or ((rawPrecision == '2') and (chainsLength == 0))
1442
+ result[code] = self.safe_currency_structure({
1302
1443
  'id': id,
1303
- 'name': name,
1444
+ 'name': self.safe_string(entry, 'fullName'),
1304
1445
  'code': code,
1305
1446
  'type': 'fiat' if isFiat else 'crypto',
1306
1447
  'precision': precision,
1307
1448
  'info': entry,
1308
- 'active': (isDepositEnabled or isWithdrawEnabled),
1309
- 'deposit': isDepositEnabled,
1310
- 'withdraw': isWithdrawEnabled,
1311
- 'fee': None,
1312
- 'limits': self.limits,
1313
1449
  'networks': networks,
1314
- }
1450
+ 'deposit': None,
1451
+ 'withdraw': None,
1452
+ 'active': None,
1453
+ 'fee': None,
1454
+ 'limits': None,
1455
+ })
1315
1456
  return result
1316
1457
 
1317
1458
  async def fetch_accounts(self, params={}) -> List[Account]:
1318
1459
  """
1319
1460
  fetch all the accounts associated with a profile
1320
- :see: https://docs.kucoin.com/#list-accounts
1461
+
1462
+ https://docs.kucoin.com/#list-accounts
1463
+
1321
1464
  :param dict [params]: extra parameters specific to the exchange API endpoint
1322
1465
  :returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
1323
1466
  """
@@ -1365,7 +1508,9 @@ class kucoin(Exchange, ImplicitAPI):
1365
1508
  async def fetch_transaction_fee(self, code: str, params={}):
1366
1509
  """
1367
1510
  *DEPRECATED* please use fetchDepositWithdrawFee instead
1368
- :see: https://docs.kucoin.com/#get-withdrawal-quotas
1511
+
1512
+ https://docs.kucoin.com/#get-withdrawal-quotas
1513
+
1369
1514
  :param str code: unified currency code
1370
1515
  :param dict params: extra parameters specific to the exchange API endpoint
1371
1516
  :returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
@@ -1392,7 +1537,9 @@ class kucoin(Exchange, ImplicitAPI):
1392
1537
  async def fetch_deposit_withdraw_fee(self, code: str, params={}):
1393
1538
  """
1394
1539
  fetch the fee for deposits and withdrawals
1395
- :see: https://docs.kucoin.com/#get-withdrawal-quotas
1540
+
1541
+ https://docs.kucoin.com/#get-withdrawal-quotas
1542
+
1396
1543
  :param str code: unified currency code
1397
1544
  :param dict [params]: extra parameters specific to the exchange API endpoint
1398
1545
  :param str [params.network]: The chain of currency. This only apply for multi-chain currency, and there is no need for single chain currency; you can query the chain through the response of the GET /api/v2/currencies/{currency} interface
@@ -1445,32 +1592,57 @@ class kucoin(Exchange, ImplicitAPI):
1445
1592
  # "chain": "ERC20"
1446
1593
  # }
1447
1594
  #
1595
+ if 'chains' in fee:
1596
+ # if data obtained through `currencies` endpoint
1597
+ resultNew: dict = {
1598
+ 'info': fee,
1599
+ 'withdraw': {
1600
+ 'fee': None,
1601
+ 'percentage': False,
1602
+ },
1603
+ 'deposit': {
1604
+ 'fee': None,
1605
+ 'percentage': None,
1606
+ },
1607
+ 'networks': {},
1608
+ }
1609
+ chains = self.safe_list(fee, 'chains', [])
1610
+ for i in range(0, len(chains)):
1611
+ chain = chains[i]
1612
+ networkCodeNew = self.network_id_to_code(self.safe_string(chain, 'chainId'), self.safe_string(currency, 'code'))
1613
+ resultNew['networks'][networkCodeNew] = {
1614
+ 'withdraw': {
1615
+ 'fee': self.safe_number(chain, 'withdrawMinFee'),
1616
+ 'percentage': False,
1617
+ },
1618
+ 'deposit': {
1619
+ 'fee': None,
1620
+ 'percentage': None,
1621
+ },
1622
+ }
1623
+ return resultNew
1624
+ minWithdrawFee = self.safe_number(fee, 'withdrawMinFee')
1448
1625
  result: dict = {
1449
1626
  'info': fee,
1450
1627
  'withdraw': {
1628
+ 'fee': minWithdrawFee,
1629
+ 'percentage': False,
1630
+ },
1631
+ 'deposit': {
1451
1632
  'fee': None,
1452
1633
  'percentage': None,
1453
1634
  },
1635
+ 'networks': {},
1636
+ }
1637
+ networkId = self.safe_string(fee, 'chain')
1638
+ networkCode = self.network_id_to_code(networkId, self.safe_string(currency, 'code'))
1639
+ result['networks'][networkCode] = {
1640
+ 'withdraw': minWithdrawFee,
1454
1641
  'deposit': {
1455
1642
  'fee': None,
1456
1643
  'percentage': None,
1457
1644
  },
1458
- 'networks': {},
1459
1645
  }
1460
- isWithdrawEnabled = self.safe_bool(fee, 'isWithdrawEnabled')
1461
- if isWithdrawEnabled:
1462
- result['withdraw']['fee'] = self.safe_number_2(fee, 'withdrawalMinFee', 'withdrawMinFee')
1463
- result['withdraw']['percentage'] = False
1464
- networkId = self.safe_string(fee, 'chain')
1465
- if networkId:
1466
- networkCode = self.network_id_to_code(networkId, self.safe_string(currency, 'code'))
1467
- result['networks'][networkCode] = {
1468
- 'withdraw': result['withdraw'],
1469
- 'deposit': {
1470
- 'fee': None,
1471
- 'percentage': None,
1472
- },
1473
- }
1474
1646
  return result
1475
1647
 
1476
1648
  def is_futures_method(self, methodName, params):
@@ -1556,7 +1728,7 @@ class kucoin(Exchange, ImplicitAPI):
1556
1728
  symbol = market['symbol']
1557
1729
  baseVolume = self.safe_string(ticker, 'vol')
1558
1730
  quoteVolume = self.safe_string(ticker, 'volValue')
1559
- timestamp = self.safe_integer_2(ticker, 'time', 'datetime')
1731
+ timestamp = self.safe_integer_n(ticker, ['time', 'datetime', 'timePoint'])
1560
1732
  return self.safe_ticker({
1561
1733
  'symbol': symbol,
1562
1734
  'timestamp': timestamp,
@@ -1577,13 +1749,16 @@ class kucoin(Exchange, ImplicitAPI):
1577
1749
  'average': self.safe_string(ticker, 'averagePrice'),
1578
1750
  'baseVolume': baseVolume,
1579
1751
  'quoteVolume': quoteVolume,
1752
+ 'markPrice': self.safe_string(ticker, 'value'),
1580
1753
  'info': ticker,
1581
1754
  }, market)
1582
1755
 
1583
1756
  async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
1584
1757
  """
1585
1758
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1586
- :see: https://docs.kucoin.com/#get-all-tickers
1759
+
1760
+ https://docs.kucoin.com/#get-all-tickers
1761
+
1587
1762
  :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1588
1763
  :param dict [params]: extra parameters specific to the exchange API endpoint
1589
1764
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -1631,10 +1806,28 @@ class kucoin(Exchange, ImplicitAPI):
1631
1806
  result[symbol] = ticker
1632
1807
  return self.filter_by_array_tickers(result, 'symbol', symbols)
1633
1808
 
1809
+ async def fetch_mark_prices(self, symbols: Strings = None, params={}) -> Tickers:
1810
+ """
1811
+ fetches the mark price for multiple markets
1812
+
1813
+ https://www.kucoin.com/docs/rest/margin-trading/margin-info/get-all-margin-trading-pairs-mark-prices
1814
+
1815
+ :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1816
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1817
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
1818
+ """
1819
+ await self.load_markets()
1820
+ symbols = self.market_symbols(symbols)
1821
+ response = await self.publicGetMarkPriceAllSymbols(params)
1822
+ data = self.safe_list(response, 'data', [])
1823
+ return self.parse_tickers(data)
1824
+
1634
1825
  async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
1635
1826
  """
1636
1827
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
1637
- :see: https://docs.kucoin.com/#get-24hr-stats
1828
+
1829
+ https://docs.kucoin.com/#get-24hr-stats
1830
+
1638
1831
  :param str symbol: unified symbol of the market to fetch the ticker for
1639
1832
  :param dict [params]: extra parameters specific to the exchange API endpoint
1640
1833
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -1668,7 +1861,28 @@ class kucoin(Exchange, ImplicitAPI):
1668
1861
  # }
1669
1862
  # }
1670
1863
  #
1671
- return self.parse_ticker(response['data'], market)
1864
+ data = self.safe_dict(response, 'data', {})
1865
+ return self.parse_ticker(data, market)
1866
+
1867
+ async def fetch_mark_price(self, symbol: str, params={}) -> Ticker:
1868
+ """
1869
+ fetches the mark price for a specific market
1870
+
1871
+ https://www.kucoin.com/docs/rest/margin-trading/margin-info/get-mark-price
1872
+
1873
+ :param str symbol: unified symbol of the market to fetch the ticker for
1874
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1875
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
1876
+ """
1877
+ await self.load_markets()
1878
+ market = self.market(symbol)
1879
+ request: dict = {
1880
+ 'symbol': market['id'],
1881
+ }
1882
+ response = await self.publicGetMarkPriceSymbolCurrent(self.extend(request, params))
1883
+ #
1884
+ data = self.safe_dict(response, 'data', {})
1885
+ return self.parse_ticker(data, market)
1672
1886
 
1673
1887
  def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
1674
1888
  #
@@ -1694,7 +1908,9 @@ class kucoin(Exchange, ImplicitAPI):
1694
1908
  async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
1695
1909
  """
1696
1910
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1697
- :see: https://docs.kucoin.com/#get-klines
1911
+
1912
+ https://docs.kucoin.com/#get-klines
1913
+
1698
1914
  :param str symbol: unified symbol of the market to fetch OHLCV data for
1699
1915
  :param str timeframe: the length of time each candle represents
1700
1916
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -1743,9 +1959,11 @@ class kucoin(Exchange, ImplicitAPI):
1743
1959
  data = self.safe_list(response, 'data', [])
1744
1960
  return self.parse_ohlcvs(data, market, timeframe, since, limit)
1745
1961
 
1746
- async def create_deposit_address(self, code: str, params={}):
1962
+ async def create_deposit_address(self, code: str, params={}) -> DepositAddress:
1747
1963
  """
1748
- :see: https://docs.kucoin.com/#create-deposit-address
1964
+
1965
+ https://www.kucoin.com/docs/rest/funding/deposit/create-deposit-address-v3-
1966
+
1749
1967
  create a currency deposit address
1750
1968
  :param str code: unified currency code of the currency for the deposit address
1751
1969
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -1760,18 +1978,32 @@ class kucoin(Exchange, ImplicitAPI):
1760
1978
  networkCode = None
1761
1979
  networkCode, params = self.handle_network_code_and_params(params)
1762
1980
  if networkCode is not None:
1763
- request['chain'] = self.network_code_to_id(networkCode).lower()
1764
- response = await self.privatePostDepositAddresses(self.extend(request, params))
1981
+ request['chain'] = self.network_code_to_id(networkCode) # docs mention "chain-name", but seems "chain-id" is used, like in "fetchDepositAddress"
1982
+ response = await self.privatePostDepositAddressCreate(self.extend(request, params))
1765
1983
  # {"code":"260000","msg":"Deposit address already exists."}
1766
- # BCH {"code":"200000","data":{"address":"bitcoincash:qza3m4nj9rx7l9r0cdadfqxts6f92shvhvr5ls4q7z","memo":""}}
1767
- # BTC {"code":"200000","data":{"address":"36SjucKqQpQSvsak9A7h6qzFjrVXpRNZhE","memo":""}}
1984
+ #
1985
+ # {
1986
+ # "code": "200000",
1987
+ # "data": {
1988
+ # "address": "0x2336d1834faab10b2dac44e468f2627138417431",
1989
+ # "memo": null,
1990
+ # "chainId": "bsc",
1991
+ # "to": "MAIN",
1992
+ # "expirationDate": 0,
1993
+ # "currency": "BNB",
1994
+ # "chainName": "BEP20"
1995
+ # }
1996
+ # }
1997
+ #
1768
1998
  data = self.safe_dict(response, 'data', {})
1769
1999
  return self.parse_deposit_address(data, currency)
1770
2000
 
1771
- async def fetch_deposit_address(self, code: str, params={}):
2001
+ async def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
1772
2002
  """
1773
2003
  fetch the deposit address for a currency associated with self account
1774
- :see: https://docs.kucoin.com/#get-deposit-addresses-v2
2004
+
2005
+ https://docs.kucoin.com/#get-deposit-addresses-v2
2006
+
1775
2007
  :param str code: unified currency code
1776
2008
  :param dict [params]: extra parameters specific to the exchange API endpoint
1777
2009
  :param str [params.network]: the blockchain network name
@@ -1800,7 +2032,7 @@ class kucoin(Exchange, ImplicitAPI):
1800
2032
  raise ExchangeError(self.id + ' fetchDepositAddress() returned an empty response, you might try to run createDepositAddress() first and try again')
1801
2033
  return self.parse_deposit_address(data, currency)
1802
2034
 
1803
- def parse_deposit_address(self, depositAddress, currency: Currency = None):
2035
+ def parse_deposit_address(self, depositAddress, currency: Currency = None) -> DepositAddress:
1804
2036
  address = self.safe_string(depositAddress, 'address')
1805
2037
  # BCH/BSV is returned with a "bitcoincash:" prefix, which we cut off here and only keep the address
1806
2038
  if address is not None:
@@ -1814,14 +2046,16 @@ class kucoin(Exchange, ImplicitAPI):
1814
2046
  return {
1815
2047
  'info': depositAddress,
1816
2048
  'currency': code,
2049
+ 'network': self.network_id_to_code(self.safe_string(depositAddress, 'chainId')),
1817
2050
  'address': address,
1818
2051
  'tag': self.safe_string(depositAddress, 'memo'),
1819
- 'network': self.network_id_to_code(self.safe_string(depositAddress, 'chain')),
1820
2052
  }
1821
2053
 
1822
- async def fetch_deposit_addresses_by_network(self, code: str, params={}):
2054
+ async def fetch_deposit_addresses_by_network(self, code: str, params={}) -> List[DepositAddress]:
1823
2055
  """
1824
- :see: https://docs.kucoin.com/#get-deposit-addresses-v2
2056
+
2057
+ https://docs.kucoin.com/#get-deposit-addresses-v2
2058
+
1825
2059
  fetch the deposit address for a currency associated with self account
1826
2060
  :param str code: unified currency code
1827
2061
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -1860,8 +2094,10 @@ class kucoin(Exchange, ImplicitAPI):
1860
2094
  async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
1861
2095
  """
1862
2096
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
1863
- :see: https://www.kucoin.com/docs/rest/spot-trading/market-data/get-part-order-book-aggregated-
1864
- :see: https://www.kucoin.com/docs/rest/spot-trading/market-data/get-full-order-book-aggregated-
2097
+
2098
+ https://www.kucoin.com/docs/rest/spot-trading/market-data/get-part-order-book-aggregated-
2099
+ https://www.kucoin.com/docs/rest/spot-trading/market-data/get-full-order-book-aggregated-
2100
+
1865
2101
  :param str symbol: unified symbol of the market to fetch the order book for
1866
2102
  :param int [limit]: the maximum amount of order book entries to return
1867
2103
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -1935,49 +2171,56 @@ class kucoin(Exchange, ImplicitAPI):
1935
2171
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1936
2172
  """
1937
2173
  Create an order on the exchange
1938
- :see: https://docs.kucoin.com/spot#place-a-new-order
1939
- :see: https://docs.kucoin.com/spot#place-a-new-order-2
1940
- :see: https://docs.kucoin.com/spot#place-a-margin-order
1941
- :see: https://docs.kucoin.com/spot-hf/#place-hf-order
1942
- :see: https://www.kucoin.com/docs/rest/spot-trading/orders/place-order-test
1943
- :see: https://www.kucoin.com/docs/rest/margin-trading/orders/place-margin-order-test
2174
+
2175
+ https://docs.kucoin.com/spot#place-a-new-order
2176
+ https://docs.kucoin.com/spot#place-a-new-order-2
2177
+ https://docs.kucoin.com/spot#place-a-margin-order
2178
+ https://docs.kucoin.com/spot-hf/#place-hf-order
2179
+ https://www.kucoin.com/docs/rest/spot-trading/orders/place-order-test
2180
+ https://www.kucoin.com/docs/rest/margin-trading/orders/place-margin-order-test
2181
+ https://www.kucoin.com/docs/rest/spot-trading/spot-hf-trade-pro-account/sync-place-hf-order
2182
+
1944
2183
  :param str symbol: Unified CCXT market symbol
1945
2184
  :param str type: 'limit' or 'market'
1946
2185
  :param str side: 'buy' or 'sell'
1947
2186
  :param float amount: the amount of currency to trade
1948
- :param float [price]: *ignored in "market" orders* the price at which the order is to be fullfilled at in units of the quote currency
2187
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1949
2188
  :param dict [params]: extra parameters specific to the exchange API endpoint
1950
2189
  :param float [params.triggerPrice]: The price at which a trigger order is triggered at
1951
2190
  :param str [params.marginMode]: 'cross', # cross(cross mode) and isolated(isolated mode), set to cross by default, the isolated mode will be released soon, stay tuned
1952
2191
  :param str [params.timeInForce]: GTC, GTT, IOC, or FOK, default is GTC, limit orders only
1953
2192
  :param str [params.postOnly]: Post only flag, invalid when timeInForce is IOC or FOK
1954
- *
1955
- * EXCHANGE SPECIFIC PARAMETERS
2193
+
2194
+ EXCHANGE SPECIFIC PARAMETERS
1956
2195
  :param str [params.clientOid]: client order id, defaults to uuid if not passed
1957
2196
  :param str [params.remark]: remark for the order, length cannot exceed 100 utf8 characters
1958
2197
  :param str [params.tradeType]: 'TRADE', # TRADE, MARGIN_TRADE # not used with margin orders
1959
- * limit orders ---------------------------------------------------
2198
+ limit orders ---------------------------------------------------
1960
2199
  :param float [params.cancelAfter]: long, # cancel after n seconds, requires timeInForce to be GTT
1961
2200
  :param bool [params.hidden]: False, # Order will not be displayed in the order book
1962
2201
  :param bool [params.iceberg]: False, # Only a portion of the order is displayed in the order book
1963
2202
  :param str [params.visibleSize]: self.amount_to_precision(symbol, visibleSize), # The maximum visible size of an iceberg order
1964
- * market orders --------------------------------------------------
2203
+ market orders --------------------------------------------------
1965
2204
  :param str [params.funds]: # Amount of quote currency to use
1966
- * stop orders ----------------------------------------------------
1967
- :param str [params.stop]: Either loss or entry, the default is loss. Requires stopPrice to be defined
1968
- * margin orders --------------------------------------------------
2205
+ stop orders ----------------------------------------------------
2206
+ :param str [params.stop]: Either loss or entry, the default is loss. Requires triggerPrice to be defined
2207
+ margin orders --------------------------------------------------
1969
2208
  :param float [params.leverage]: Leverage size of the order
1970
2209
  :param str [params.stp]: '', # self trade prevention, CN, CO, CB or DC
1971
2210
  :param bool [params.autoBorrow]: False, # The system will first borrow you funds at the optimal interest rate and then place an order for you
1972
2211
  :param bool [params.hf]: False, # True for hf order
1973
2212
  :param bool [params.test]: set to True to test an order, no order will be created but the request will be validated
2213
+ :param bool [params.sync]: set to True to use the hf sync call
1974
2214
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1975
2215
  """
1976
2216
  await self.load_markets()
1977
2217
  market = self.market(symbol)
1978
2218
  testOrder = self.safe_bool(params, 'test', False)
1979
2219
  params = self.omit(params, 'test')
1980
- isHf = self.safe_bool(params, 'hf', False)
2220
+ hf = None
2221
+ hf, params = self.handle_hf_and_params(params)
2222
+ useSync = False
2223
+ useSync, params = self.handle_option_and_params(params, 'createOrder', 'sync', False)
1981
2224
  triggerPrice, stopLossPrice, takeProfitPrice = self.handle_trigger_prices(params)
1982
2225
  tradeType = self.safe_string(params, 'tradeType') # keep it for backward compatibility
1983
2226
  isTriggerOrder = (triggerPrice or stopLossPrice or takeProfitPrice)
@@ -1990,14 +2233,18 @@ class kucoin(Exchange, ImplicitAPI):
1990
2233
  if testOrder:
1991
2234
  if isMarginOrder:
1992
2235
  response = await self.privatePostMarginOrderTest(orderRequest)
2236
+ elif hf:
2237
+ response = await self.privatePostHfOrdersTest(orderRequest)
1993
2238
  else:
1994
2239
  response = await self.privatePostOrdersTest(orderRequest)
1995
- elif isHf:
1996
- response = await self.privatePostHfOrders(orderRequest)
1997
2240
  elif isTriggerOrder:
1998
2241
  response = await self.privatePostStopOrder(orderRequest)
1999
2242
  elif isMarginOrder:
2000
2243
  response = await self.privatePostMarginOrder(orderRequest)
2244
+ elif useSync:
2245
+ response = await self.privatePostHfOrdersSync(orderRequest)
2246
+ elif hf:
2247
+ response = await self.privatePostHfOrders(orderRequest)
2001
2248
  else:
2002
2249
  response = await self.privatePostOrders(orderRequest)
2003
2250
  #
@@ -2014,7 +2261,9 @@ class kucoin(Exchange, ImplicitAPI):
2014
2261
  async def create_market_order_with_cost(self, symbol: str, side: OrderSide, cost: float, params={}):
2015
2262
  """
2016
2263
  create a market order by providing the symbol, side and cost
2017
- :see: https://www.kucoin.com/docs/rest/spot-trading/orders/place-order
2264
+
2265
+ https://www.kucoin.com/docs/rest/spot-trading/orders/place-order
2266
+
2018
2267
  :param str symbol: unified symbol of the market to create an order in
2019
2268
  :param str side: 'buy' or 'sell'
2020
2269
  :param float cost: how much you want to trade in units of the quote currency
@@ -2022,13 +2271,17 @@ class kucoin(Exchange, ImplicitAPI):
2022
2271
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2023
2272
  """
2024
2273
  await self.load_markets()
2025
- params['cost'] = cost
2026
- return await self.create_order(symbol, 'market', side, cost, None, params)
2274
+ req = {
2275
+ 'cost': cost,
2276
+ }
2277
+ return await self.create_order(symbol, 'market', side, cost, None, self.extend(req, params))
2027
2278
 
2028
2279
  async def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
2029
2280
  """
2030
2281
  create a market buy order by providing the symbol and cost
2031
- :see: https://www.kucoin.com/docs/rest/spot-trading/orders/place-order
2282
+
2283
+ https://www.kucoin.com/docs/rest/spot-trading/orders/place-order
2284
+
2032
2285
  :param str symbol: unified symbol of the market to create an order in
2033
2286
  :param float cost: how much you want to trade in units of the quote currency
2034
2287
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2040,7 +2293,9 @@ class kucoin(Exchange, ImplicitAPI):
2040
2293
  async def create_market_sell_order_with_cost(self, symbol: str, cost: float, params={}):
2041
2294
  """
2042
2295
  create a market sell order by providing the symbol and cost
2043
- :see: https://www.kucoin.com/docs/rest/spot-trading/orders/place-order
2296
+
2297
+ https://www.kucoin.com/docs/rest/spot-trading/orders/place-order
2298
+
2044
2299
  :param str symbol: unified symbol of the market to create an order in
2045
2300
  :param float cost: how much you want to trade in units of the quote currency
2046
2301
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2052,11 +2307,15 @@ class kucoin(Exchange, ImplicitAPI):
2052
2307
  async def create_orders(self, orders: List[OrderRequest], params={}):
2053
2308
  """
2054
2309
  create a list of trade orders
2055
- :see: https://www.kucoin.com/docs/rest/spot-trading/orders/place-multiple-orders
2056
- :see: https://www.kucoin.com/docs/rest/spot-trading/spot-hf-trade-pro-account/place-multiple-hf-orders
2310
+
2311
+ https://www.kucoin.com/docs/rest/spot-trading/orders/place-multiple-orders
2312
+ https://www.kucoin.com/docs/rest/spot-trading/spot-hf-trade-pro-account/place-multiple-hf-orders
2313
+ https://www.kucoin.com/docs/rest/spot-trading/spot-hf-trade-pro-account/sync-place-multiple-hf-orders
2314
+
2057
2315
  :param Array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
2058
2316
  :param dict [params]: extra parameters specific to the exchange API endpoint
2059
2317
  :param bool [params.hf]: False, # True for hf orders
2318
+ :param bool [params.sync]: False, # True to use the hf sync call
2060
2319
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2061
2320
  """
2062
2321
  await self.load_markets()
@@ -2084,10 +2343,14 @@ class kucoin(Exchange, ImplicitAPI):
2084
2343
  'symbol': market['id'],
2085
2344
  'orderList': ordersRequests,
2086
2345
  }
2087
- hf = self.safe_bool(params, 'hf', False)
2088
- params = self.omit(params, 'hf')
2346
+ hf = None
2347
+ hf, params = self.handle_hf_and_params(params)
2348
+ useSync = False
2349
+ useSync, params = self.handle_option_and_params(params, 'createOrders', 'sync', False)
2089
2350
  response = None
2090
- if hf:
2351
+ if useSync:
2352
+ response = await self.privatePostHfOrdersMultiSync(self.extend(request, params))
2353
+ elif hf:
2091
2354
  response = await self.privatePostHfOrdersMulti(self.extend(request, params))
2092
2355
  else:
2093
2356
  response = await self.privatePostOrdersMulti(self.extend(request, params))
@@ -2192,13 +2455,15 @@ class kucoin(Exchange, ImplicitAPI):
2192
2455
  async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
2193
2456
  """
2194
2457
  edit an order, kucoin currently only supports the modification of HF orders
2195
- :see: https://docs.kucoin.com/spot-hf/#modify-order
2458
+
2459
+ https://docs.kucoin.com/spot-hf/#modify-order
2460
+
2196
2461
  :param str id: order id
2197
2462
  :param str symbol: unified symbol of the market to create an order in
2198
2463
  :param str type: not used
2199
2464
  :param str side: not used
2200
2465
  :param float amount: how much of the currency you want to trade in units of the base currency
2201
- :param float [price]: the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
2466
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
2202
2467
  :param dict [params]: extra parameters specific to the exchange API endpoint
2203
2468
  :param str [params.clientOrderId]: client order id, defaults to id if not passed
2204
2469
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
@@ -2232,34 +2497,42 @@ class kucoin(Exchange, ImplicitAPI):
2232
2497
  async def cancel_order(self, id: str, symbol: Str = None, params={}):
2233
2498
  """
2234
2499
  cancels an open order
2235
- :see: https://docs.kucoin.com/spot#cancel-an-order
2236
- :see: https://docs.kucoin.com/spot#cancel-an-order-2
2237
- :see: https://docs.kucoin.com/spot#cancel-single-order-by-clientoid
2238
- :see: https://docs.kucoin.com/spot#cancel-single-order-by-clientoid-2
2239
- :see: https://docs.kucoin.com/spot-hf/#cancel-orders-by-orderid
2240
- :see: https://docs.kucoin.com/spot-hf/#cancel-order-by-clientoid
2500
+
2501
+ https://docs.kucoin.com/spot#cancel-an-order
2502
+ https://docs.kucoin.com/spot#cancel-an-order-2
2503
+ https://docs.kucoin.com/spot#cancel-single-order-by-clientoid
2504
+ https://docs.kucoin.com/spot#cancel-single-order-by-clientoid-2
2505
+ https://docs.kucoin.com/spot-hf/#cancel-orders-by-orderid
2506
+ https://docs.kucoin.com/spot-hf/#cancel-order-by-clientoid
2507
+ https://www.kucoin.com/docs/rest/spot-trading/spot-hf-trade-pro-account/sync-cancel-hf-order-by-orderid
2508
+ https://www.kucoin.com/docs/rest/spot-trading/spot-hf-trade-pro-account/sync-cancel-hf-order-by-clientoid
2509
+
2241
2510
  :param str id: order id
2242
2511
  :param str symbol: unified symbol of the market the order was made in
2243
2512
  :param dict [params]: extra parameters specific to the exchange API endpoint
2244
- :param bool [params.stop]: True if cancelling a stop order
2513
+ :param bool [params.trigger]: True if cancelling a stop order
2245
2514
  :param bool [params.hf]: False, # True for hf order
2515
+ :param bool [params.sync]: False, # True to use the hf sync call
2246
2516
  :returns: Response from the exchange
2247
2517
  """
2248
2518
  await self.load_markets()
2249
2519
  request: dict = {}
2250
2520
  clientOrderId = self.safe_string_2(params, 'clientOid', 'clientOrderId')
2251
- stop = self.safe_bool_2(params, 'stop', 'trigger', False)
2252
- hf = self.safe_bool(params, 'hf', False)
2253
- if hf:
2521
+ trigger = self.safe_bool_2(params, 'stop', 'trigger', False)
2522
+ hf = None
2523
+ hf, params = self.handle_hf_and_params(params)
2524
+ useSync = False
2525
+ useSync, params = self.handle_option_and_params(params, 'cancelOrder', 'sync', False)
2526
+ if hf or useSync:
2254
2527
  if symbol is None:
2255
2528
  raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol parameter for hf orders')
2256
2529
  market = self.market(symbol)
2257
2530
  request['symbol'] = market['id']
2258
2531
  response = None
2259
- params = self.omit(params, ['clientOid', 'clientOrderId', 'stop', 'hf', 'trigger'])
2532
+ params = self.omit(params, ['clientOid', 'clientOrderId', 'stop', 'trigger'])
2260
2533
  if clientOrderId is not None:
2261
2534
  request['clientOid'] = clientOrderId
2262
- if stop:
2535
+ if trigger:
2263
2536
  response = await self.privateDeleteStopOrderCancelOrderByClientOid(self.extend(request, params))
2264
2537
  #
2265
2538
  # {
@@ -2270,6 +2543,8 @@ class kucoin(Exchange, ImplicitAPI):
2270
2543
  # }
2271
2544
  # }
2272
2545
  #
2546
+ elif useSync:
2547
+ response = await self.privateDeleteHfOrdersSyncClientOrderClientOid(self.extend(request, params))
2273
2548
  elif hf:
2274
2549
  response = await self.privateDeleteHfOrdersClientOrderClientOid(self.extend(request, params))
2275
2550
  #
@@ -2296,7 +2571,7 @@ class kucoin(Exchange, ImplicitAPI):
2296
2571
  return self.parse_order(response)
2297
2572
  else:
2298
2573
  request['orderId'] = id
2299
- if stop:
2574
+ if trigger:
2300
2575
  response = await self.privateDeleteStopOrderOrderId(self.extend(request, params))
2301
2576
  #
2302
2577
  # {
@@ -2304,6 +2579,8 @@ class kucoin(Exchange, ImplicitAPI):
2304
2579
  # data: {cancelledOrderIds: ['vs8lgpiuaco91qk8003vebu9']}
2305
2580
  # }
2306
2581
  #
2582
+ elif useSync:
2583
+ response = await self.privateDeleteHfOrdersSyncOrderId(self.extend(request, params))
2307
2584
  elif hf:
2308
2585
  response = await self.privateDeleteHfOrdersOrderId(self.extend(request, params))
2309
2586
  #
@@ -2335,32 +2612,34 @@ class kucoin(Exchange, ImplicitAPI):
2335
2612
  async def cancel_all_orders(self, symbol: Str = None, params={}):
2336
2613
  """
2337
2614
  cancel all open orders
2338
- :see: https://docs.kucoin.com/spot#cancel-all-orders
2339
- :see: https://docs.kucoin.com/spot#cancel-orders
2340
- :see: https://docs.kucoin.com/spot-hf/#cancel-all-hf-orders-by-symbol
2615
+
2616
+ https://docs.kucoin.com/spot#cancel-all-orders
2617
+ https://docs.kucoin.com/spot#cancel-orders
2618
+ https://docs.kucoin.com/spot-hf/#cancel-all-hf-orders-by-symbol
2619
+
2341
2620
  :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
2342
2621
  :param dict [params]: extra parameters specific to the exchange API endpoint
2343
- :param bool [params.stop]: *invalid for isolated margin* True if cancelling all stop orders
2622
+ :param bool [params.trigger]: *invalid for isolated margin* True if cancelling all stop orders
2344
2623
  :param str [params.marginMode]: 'cross' or 'isolated'
2345
2624
  :param str [params.orderIds]: *stop orders only* Comma seperated order IDs
2346
- :param bool [params.stop]: True if cancelling a stop order
2347
2625
  :param bool [params.hf]: False, # True for hf order
2348
2626
  :returns: Response from the exchange
2349
2627
  """
2350
2628
  await self.load_markets()
2351
2629
  request: dict = {}
2352
- stop = self.safe_bool(params, 'stop', False)
2353
- hf = self.safe_bool(params, 'hf', False)
2354
- params = self.omit(params, ['stop', 'hf'])
2630
+ trigger = self.safe_bool_2(params, 'trigger', 'stop', False)
2631
+ hf = None
2632
+ hf, params = self.handle_hf_and_params(params)
2633
+ params = self.omit(params, 'stop')
2355
2634
  marginMode, query = self.handle_margin_mode_and_params('cancelAllOrders', params)
2356
2635
  if symbol is not None:
2357
2636
  request['symbol'] = self.market_id(symbol)
2358
2637
  if marginMode is not None:
2359
2638
  request['tradeType'] = self.options['marginModes'][marginMode]
2360
- if marginMode == 'isolated' and stop:
2639
+ if marginMode == 'isolated' and trigger:
2361
2640
  raise BadRequest(self.id + ' cancelAllOrders does not support isolated margin for stop orders')
2362
2641
  response = None
2363
- if stop:
2642
+ if trigger:
2364
2643
  response = await self.privateDeleteStopOrderCancel(self.extend(request, query))
2365
2644
  elif hf:
2366
2645
  if symbol is None:
@@ -2369,37 +2648,41 @@ class kucoin(Exchange, ImplicitAPI):
2369
2648
  response = await self.privateDeleteHfOrders(self.extend(request, query))
2370
2649
  else:
2371
2650
  response = await self.privateDeleteOrders(self.extend(request, query))
2372
- return response
2651
+ return [self.safe_order({'info': response})]
2373
2652
 
2374
2653
  async def fetch_orders_by_status(self, status, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2375
2654
  """
2376
2655
  fetch a list of orders
2377
- :see: https://docs.kucoin.com/spot#list-orders
2378
- :see: https://docs.kucoin.com/spot#list-stop-orders
2379
- :see: https://docs.kucoin.com/spot-hf/#obtain-list-of-active-hf-orders
2380
- :see: https://docs.kucoin.com/spot-hf/#obtain-list-of-filled-hf-orders
2656
+
2657
+ https://docs.kucoin.com/spot#list-orders
2658
+ https://docs.kucoin.com/spot#list-stop-orders
2659
+ https://docs.kucoin.com/spot-hf/#obtain-list-of-active-hf-orders
2660
+ https://docs.kucoin.com/spot-hf/#obtain-list-of-filled-hf-orders
2661
+
2381
2662
  :param str status: *not used for stop orders* 'open' or 'closed'
2382
2663
  :param str symbol: unified market symbol
2383
2664
  :param int [since]: timestamp in ms of the earliest order
2384
2665
  :param int [limit]: max number of orders to return
2385
2666
  :param dict [params]: exchange specific params
2386
2667
  :param int [params.until]: end time in ms
2387
- :param bool [params.stop]: True if fetching stop orders
2388
2668
  :param str [params.side]: buy or sell
2389
2669
  :param str [params.type]: limit, market, limit_stop or market_stop
2390
2670
  :param str [params.tradeType]: TRADE for spot trading, MARGIN_TRADE for Margin Trading
2391
- :param int [params.currentPage]: *stop orders only* current page
2392
- :param str [params.orderIds]: *stop orders only* comma seperated order ID list
2393
- :param bool [params.stop]: True if fetching a stop order
2671
+ :param int [params.currentPage]: *trigger orders only* current page
2672
+ :param str [params.orderIds]: *trigger orders only* comma seperated order ID list
2673
+ :param bool [params.trigger]: True if fetching a trigger order
2394
2674
  :param bool [params.hf]: False, # True for hf order
2395
2675
  :returns: An `array of order structures <https://docs.ccxt.com/#/?id=order-structure>`
2396
2676
  """
2397
2677
  await self.load_markets()
2398
2678
  lowercaseStatus = status.lower()
2399
2679
  until = self.safe_integer(params, 'until')
2400
- stop = self.safe_bool(params, 'stop', False)
2401
- hf = self.safe_bool(params, 'hf', False)
2402
- params = self.omit(params, ['stop', 'hf', 'until'])
2680
+ trigger = self.safe_bool_2(params, 'stop', 'trigger', False)
2681
+ hf = None
2682
+ hf, params = self.handle_hf_and_params(params)
2683
+ if hf and (symbol is None):
2684
+ raise ArgumentsRequired(self.id + ' fetchOrdersByStatus() requires a symbol parameter for hf orders')
2685
+ params = self.omit(params, ['stop', 'trigger', 'till', 'until'])
2403
2686
  marginMode, query = self.handle_margin_mode_and_params('fetchOrdersByStatus', params)
2404
2687
  if lowercaseStatus == 'open':
2405
2688
  lowercaseStatus = 'active'
@@ -2420,7 +2703,7 @@ class kucoin(Exchange, ImplicitAPI):
2420
2703
  request['endAt'] = until
2421
2704
  request['tradeType'] = self.safe_string(self.options['marginModes'], marginMode, 'TRADE')
2422
2705
  response = None
2423
- if stop:
2706
+ if trigger:
2424
2707
  response = await self.privateGetStopOrder(self.extend(request, query))
2425
2708
  elif hf:
2426
2709
  if lowercaseStatus == 'active':
@@ -2482,10 +2765,12 @@ class kucoin(Exchange, ImplicitAPI):
2482
2765
  async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
2483
2766
  """
2484
2767
  fetches information on multiple closed orders made by the user
2485
- :see: https://docs.kucoin.com/spot#list-orders
2486
- :see: https://docs.kucoin.com/spot#list-stop-orders
2487
- :see: https://docs.kucoin.com/spot-hf/#obtain-list-of-active-hf-orders
2488
- :see: https://docs.kucoin.com/spot-hf/#obtain-list-of-filled-hf-orders
2768
+
2769
+ https://docs.kucoin.com/spot#list-orders
2770
+ https://docs.kucoin.com/spot#list-stop-orders
2771
+ https://docs.kucoin.com/spot-hf/#obtain-list-of-active-hf-orders
2772
+ https://docs.kucoin.com/spot-hf/#obtain-list-of-filled-hf-orders
2773
+
2489
2774
  :param str symbol: unified market symbol of the market orders were made in
2490
2775
  :param int [since]: the earliest time in ms to fetch orders for
2491
2776
  :param int [limit]: the maximum number of order structures to retrieve
@@ -2494,7 +2779,7 @@ class kucoin(Exchange, ImplicitAPI):
2494
2779
  :param str [params.side]: buy or sell
2495
2780
  :param str [params.type]: limit, market, limit_stop or market_stop
2496
2781
  :param str [params.tradeType]: TRADE for spot trading, MARGIN_TRADE for Margin Trading
2497
- :param bool [params.stop]: True if fetching a stop order
2782
+ :param bool [params.trigger]: True if fetching a trigger order
2498
2783
  :param bool [params.hf]: False, # True for hf order
2499
2784
  :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
2500
2785
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
@@ -2509,22 +2794,23 @@ class kucoin(Exchange, ImplicitAPI):
2509
2794
  async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
2510
2795
  """
2511
2796
  fetch all unfilled currently open orders
2512
- :see: https://docs.kucoin.com/spot#list-orders
2513
- :see: https://docs.kucoin.com/spot#list-stop-orders
2514
- :see: https://docs.kucoin.com/spot-hf/#obtain-list-of-active-hf-orders
2515
- :see: https://docs.kucoin.com/spot-hf/#obtain-list-of-filled-hf-orders
2797
+
2798
+ https://docs.kucoin.com/spot#list-orders
2799
+ https://docs.kucoin.com/spot#list-stop-orders
2800
+ https://docs.kucoin.com/spot-hf/#obtain-list-of-active-hf-orders
2801
+ https://docs.kucoin.com/spot-hf/#obtain-list-of-filled-hf-orders
2802
+
2516
2803
  :param str symbol: unified market symbol
2517
2804
  :param int [since]: the earliest time in ms to fetch open orders for
2518
2805
  :param int [limit]: the maximum number of open orders structures to retrieve
2519
2806
  :param dict [params]: extra parameters specific to the exchange API endpoint
2520
2807
  :param int [params.until]: end time in ms
2521
- :param bool [params.stop]: True if fetching stop orders
2808
+ :param bool [params.trigger]: True if fetching trigger orders
2522
2809
  :param str [params.side]: buy or sell
2523
2810
  :param str [params.type]: limit, market, limit_stop or market_stop
2524
2811
  :param str [params.tradeType]: TRADE for spot trading, MARGIN_TRADE for Margin Trading
2525
- :param int [params.currentPage]: *stop orders only* current page
2526
- :param str [params.orderIds]: *stop orders only* comma seperated order ID list
2527
- :param bool [params.stop]: True if fetching a stop order
2812
+ :param int [params.currentPage]: *trigger orders only* current page
2813
+ :param str [params.orderIds]: *trigger orders only* comma seperated order ID list
2528
2814
  :param bool [params.hf]: False, # True for hf order
2529
2815
  :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
2530
2816
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
@@ -2539,16 +2825,18 @@ class kucoin(Exchange, ImplicitAPI):
2539
2825
  async def fetch_order(self, id: str, symbol: Str = None, params={}):
2540
2826
  """
2541
2827
  fetch an order
2542
- :see: https://docs.kucoin.com/spot#get-an-order
2543
- :see: https://docs.kucoin.com/spot#get-single-active-order-by-clientoid
2544
- :see: https://docs.kucoin.com/spot#get-single-order-info
2545
- :see: https://docs.kucoin.com/spot#get-single-order-by-clientoid
2546
- :see: https://docs.kucoin.com/spot-hf/#details-of-a-single-hf-order
2547
- :see: https://docs.kucoin.com/spot-hf/#obtain-details-of-a-single-hf-order-using-clientoid
2828
+
2829
+ https://docs.kucoin.com/spot#get-an-order
2830
+ https://docs.kucoin.com/spot#get-single-active-order-by-clientoid
2831
+ https://docs.kucoin.com/spot#get-single-order-info
2832
+ https://docs.kucoin.com/spot#get-single-order-by-clientoid
2833
+ https://docs.kucoin.com/spot-hf/#details-of-a-single-hf-order
2834
+ https://docs.kucoin.com/spot-hf/#obtain-details-of-a-single-hf-order-using-clientoid
2835
+
2548
2836
  :param str id: Order id
2549
- :param str symbol: not sent to exchange except for stop orders with clientOid, but used internally by CCXT to filter
2837
+ :param str symbol: not sent to exchange except for trigger orders with clientOid, but used internally by CCXT to filter
2550
2838
  :param dict [params]: exchange specific parameters
2551
- :param bool [params.stop]: True if fetching a stop order
2839
+ :param bool [params.trigger]: True if fetching a trigger order
2552
2840
  :param bool [params.hf]: False, # True for hf order
2553
2841
  :param bool [params.clientOid]: unique order id created by users to identify their orders
2554
2842
  :returns: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
@@ -2556,8 +2844,9 @@ class kucoin(Exchange, ImplicitAPI):
2556
2844
  await self.load_markets()
2557
2845
  request: dict = {}
2558
2846
  clientOrderId = self.safe_string_2(params, 'clientOid', 'clientOrderId')
2559
- stop = self.safe_bool(params, 'stop', False)
2560
- hf = self.safe_bool(params, 'hf', False)
2847
+ trigger = self.safe_bool_2(params, 'stop', 'trigger', False)
2848
+ hf = None
2849
+ hf, params = self.handle_hf_and_params(params)
2561
2850
  market = None
2562
2851
  if symbol is not None:
2563
2852
  market = self.market(symbol)
@@ -2565,11 +2854,11 @@ class kucoin(Exchange, ImplicitAPI):
2565
2854
  if symbol is None:
2566
2855
  raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol parameter for hf orders')
2567
2856
  request['symbol'] = market['id']
2568
- params = self.omit(params, ['stop', 'hf', 'clientOid', 'clientOrderId'])
2857
+ params = self.omit(params, ['stop', 'clientOid', 'clientOrderId', 'trigger'])
2569
2858
  response = None
2570
2859
  if clientOrderId is not None:
2571
2860
  request['clientOid'] = clientOrderId
2572
- if stop:
2861
+ if trigger:
2573
2862
  if symbol is not None:
2574
2863
  request['symbol'] = market['id']
2575
2864
  response = await self.privateGetStopOrderQueryOrderByClientOid(self.extend(request, params))
@@ -2584,7 +2873,7 @@ class kucoin(Exchange, ImplicitAPI):
2584
2873
  if id is None:
2585
2874
  raise InvalidOrder(self.id + ' fetchOrder() requires an order id')
2586
2875
  request['orderId'] = id
2587
- if stop:
2876
+ if trigger:
2588
2877
  response = await self.privateGetStopOrderOrderId(self.extend(request, params))
2589
2878
  elif hf:
2590
2879
  response = await self.privateGetHfOrdersOrderId(self.extend(request, params))
@@ -2722,7 +3011,7 @@ class kucoin(Exchange, ImplicitAPI):
2722
3011
  feeCurrencyId = self.safe_string(order, 'feeCurrency')
2723
3012
  cancelExist = self.safe_bool(order, 'cancelExist', False)
2724
3013
  responseStop = self.safe_string(order, 'stop')
2725
- stop = responseStop is not None
3014
+ trigger = responseStop is not None
2726
3015
  stopTriggered = self.safe_bool(order, 'stopTriggered', False)
2727
3016
  isActive = self.safe_bool_2(order, 'isActive', 'active')
2728
3017
  responseStatus = self.safe_string(order, 'status')
@@ -2732,7 +3021,7 @@ class kucoin(Exchange, ImplicitAPI):
2732
3021
  status = 'open'
2733
3022
  else:
2734
3023
  status = 'closed'
2735
- if stop:
3024
+ if trigger:
2736
3025
  if responseStatus == 'NEW':
2737
3026
  status = 'open'
2738
3027
  elif not isActive and not stopTriggered:
@@ -2741,7 +3030,6 @@ class kucoin(Exchange, ImplicitAPI):
2741
3030
  status = 'canceled'
2742
3031
  if responseStatus == 'fail':
2743
3032
  status = 'rejected'
2744
- stopPrice = self.safe_number(order, 'stopPrice')
2745
3033
  return self.safe_order({
2746
3034
  'info': order,
2747
3035
  'id': self.safe_string_n(order, ['id', 'orderId', 'newOrderId', 'cancelledOrderId']),
@@ -2753,8 +3041,7 @@ class kucoin(Exchange, ImplicitAPI):
2753
3041
  'side': self.safe_string(order, 'side'),
2754
3042
  'amount': self.safe_string(order, 'size'),
2755
3043
  'price': self.safe_string(order, 'price'), # price is zero for market order, omitZero is called in safeOrder2
2756
- 'stopPrice': stopPrice,
2757
- 'triggerPrice': stopPrice,
3044
+ 'triggerPrice': self.safe_number(order, 'stopPrice'),
2758
3045
  'cost': self.safe_string(order, 'dealFunds'),
2759
3046
  'filled': self.safe_string(order, 'dealSize'),
2760
3047
  'remaining': None,
@@ -2766,15 +3053,17 @@ class kucoin(Exchange, ImplicitAPI):
2766
3053
  },
2767
3054
  'status': status,
2768
3055
  'lastTradeTimestamp': None,
2769
- 'average': None,
3056
+ 'average': self.safe_string(order, 'avgDealPrice'),
2770
3057
  'trades': None,
2771
3058
  }, market)
2772
3059
 
2773
3060
  async def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2774
3061
  """
2775
3062
  fetch all the trades made from a single order
2776
- :see: https://docs.kucoin.com/#list-fills
2777
- :see: https://docs.kucoin.com/spot-hf/#transaction-details
3063
+
3064
+ https://docs.kucoin.com/#list-fills
3065
+ https://docs.kucoin.com/spot-hf/#transaction-details
3066
+
2778
3067
  :param str id: order id
2779
3068
  :param str symbol: unified market symbol
2780
3069
  :param int [since]: the earliest time in ms to fetch trades for
@@ -2789,8 +3078,10 @@ class kucoin(Exchange, ImplicitAPI):
2789
3078
 
2790
3079
  async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2791
3080
  """
2792
- :see: https://docs.kucoin.com/#list-fills
2793
- :see: https://docs.kucoin.com/spot-hf/#transaction-details
3081
+
3082
+ https://docs.kucoin.com/#list-fills
3083
+ https://docs.kucoin.com/spot-hf/#transaction-details
3084
+
2794
3085
  fetch all trades made by the user
2795
3086
  :param str symbol: unified market symbol
2796
3087
  :param int [since]: the earliest time in ms to fetch trades for
@@ -2807,20 +3098,25 @@ class kucoin(Exchange, ImplicitAPI):
2807
3098
  if paginate:
2808
3099
  return await self.fetch_paginated_call_dynamic('fetchMyTrades', symbol, since, limit, params)
2809
3100
  request: dict = {}
2810
- hf = self.safe_bool(params, 'hf', False)
3101
+ hf = None
3102
+ hf, params = self.handle_hf_and_params(params)
2811
3103
  if hf and symbol is None:
2812
3104
  raise ArgumentsRequired(self.id + ' fetchMyTrades() requires a symbol parameter for hf orders')
2813
3105
  market = None
2814
3106
  if symbol is not None:
2815
3107
  market = self.market(symbol)
2816
3108
  request['symbol'] = market['id']
2817
- if limit is not None:
2818
- request['pageSize'] = limit
2819
3109
  method = self.options['fetchMyTradesMethod']
2820
3110
  parseResponseData = False
2821
3111
  response = None
2822
3112
  request, params = self.handle_until_option('endAt', request, params)
2823
3113
  if hf:
3114
+ # does not return trades earlier than 2019-02-18T00:00:00Z
3115
+ if limit is not None:
3116
+ request['limit'] = limit
3117
+ if since is not None:
3118
+ # only returns trades up to one week after the since param
3119
+ request['startAt'] = since
2824
3120
  response = await self.privateGetHfFills(self.extend(request, params))
2825
3121
  elif method == 'private_get_fills':
2826
3122
  # does not return trades earlier than 2019-02-18T00:00:00Z
@@ -2887,7 +3183,9 @@ class kucoin(Exchange, ImplicitAPI):
2887
3183
  async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
2888
3184
  """
2889
3185
  get the list of most recent trades for a particular symbol
2890
- :see: https://www.kucoin.com/docs/rest/spot-trading/market-data/get-trade-histories
3186
+
3187
+ https://www.kucoin.com/docs/rest/spot-trading/market-data/get-trade-histories
3188
+
2891
3189
  :param str symbol: unified symbol of the market to fetch trades for
2892
3190
  :param int [since]: timestamp in ms of the earliest trade to fetch
2893
3191
  :param int [limit]: the maximum amount of trades to fetch
@@ -3052,7 +3350,9 @@ class kucoin(Exchange, ImplicitAPI):
3052
3350
  async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
3053
3351
  """
3054
3352
  fetch the trading fees for a market
3055
- :see: https://www.kucoin.com/docs/rest/funding/trade-fee/trading-pair-actual-fee-spot-margin-trade_hf
3353
+
3354
+ https://www.kucoin.com/docs/rest/funding/trade-fee/trading-pair-actual-fee-spot-margin-trade_hf
3355
+
3056
3356
  :param str symbol: unified market symbol
3057
3357
  :param dict [params]: extra parameters specific to the exchange API endpoint
3058
3358
  :returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
@@ -3087,10 +3387,12 @@ class kucoin(Exchange, ImplicitAPI):
3087
3387
  'tierBased': True,
3088
3388
  }
3089
3389
 
3090
- async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
3390
+ async def withdraw(self, code: str, amount: float, address: str, tag: Str = None, params={}) -> Transaction:
3091
3391
  """
3092
3392
  make a withdrawal
3093
- :see: https://www.kucoin.com/docs/rest/funding/withdrawals/apply-withdraw
3393
+
3394
+ https://www.kucoin.com/docs/rest/funding/withdrawals/apply-withdraw-v3-
3395
+
3094
3396
  :param str code: unified currency code
3095
3397
  :param float amount: the amount to withdraw
3096
3398
  :param str address: the address to withdraw to
@@ -3104,7 +3406,8 @@ class kucoin(Exchange, ImplicitAPI):
3104
3406
  currency = self.currency(code)
3105
3407
  request: dict = {
3106
3408
  'currency': currency['id'],
3107
- 'address': address,
3409
+ 'toAddress': address,
3410
+ 'withdrawType': 'ADDRESS',
3108
3411
  # 'memo': tag,
3109
3412
  # 'isInner': False, # internal transfer or external withdrawal
3110
3413
  # 'remark': 'optional',
@@ -3116,15 +3419,14 @@ class kucoin(Exchange, ImplicitAPI):
3116
3419
  networkCode, params = self.handle_network_code_and_params(params)
3117
3420
  if networkCode is not None:
3118
3421
  request['chain'] = self.network_code_to_id(networkCode).lower()
3119
- await self.load_currency_precision(currency, networkCode)
3120
- request['amount'] = self.currency_to_precision(code, amount, networkCode)
3422
+ request['amount'] = float(self.currency_to_precision(code, amount, networkCode))
3121
3423
  includeFee = None
3122
3424
  includeFee, params = self.handle_option_and_params(params, 'withdraw', 'includeFee', False)
3123
3425
  if includeFee:
3124
3426
  request['feeDeductType'] = 'INTERNAL'
3125
3427
  response = await self.privatePostWithdrawals(self.extend(request, params))
3126
3428
  #
3127
- # https://github.com/ccxt/ccxt/issues/5558
3429
+ # the id is inside "data"
3128
3430
  #
3129
3431
  # {
3130
3432
  # "code": 200000,
@@ -3136,51 +3438,6 @@ class kucoin(Exchange, ImplicitAPI):
3136
3438
  data = self.safe_dict(response, 'data', {})
3137
3439
  return self.parse_transaction(data, currency)
3138
3440
 
3139
- async def load_currency_precision(self, currency, networkCode: Str = None):
3140
- # might not have network specific precisions defined in fetchCurrencies(because of webapi failure)
3141
- # we should check and refetch precision once-per-instance for that specific currency & network
3142
- # so avoids thorwing exceptions and burden to users
3143
- # Note: self needs to be executed only if networkCode was provided
3144
- if networkCode is not None:
3145
- networks = currency['networks']
3146
- network = self.safe_dict(networks, networkCode)
3147
- if self.safe_number(network, 'precision') is not None:
3148
- # if precision exists, no need to refetch
3149
- return
3150
- # otherwise try to fetch and store in instance
3151
- request: dict = {
3152
- 'currency': currency['id'],
3153
- 'chain': self.network_code_to_id(networkCode).lower(),
3154
- }
3155
- response = await self.privateGetWithdrawalsQuotas(request)
3156
- #
3157
- # {
3158
- # "code": "200000",
3159
- # "data": {
3160
- # "currency": "USDT",
3161
- # "limitBTCAmount": "14.24094850",
3162
- # "usedBTCAmount": "0.00000000",
3163
- # "quotaCurrency": "USDT",
3164
- # "limitQuotaCurrencyAmount": "999999.00000000",
3165
- # "usedQuotaCurrencyAmount": "0",
3166
- # "remainAmount": "999999.0000",
3167
- # "availableAmount": "10.77545071",
3168
- # "withdrawMinFee": "1",
3169
- # "innerWithdrawMinFee": "0",
3170
- # "withdrawMinSize": "10",
3171
- # "isWithdrawEnabled": True,
3172
- # "precision": 4,
3173
- # "chain": "EOS",
3174
- # "reason": null,
3175
- # "lockedAmount": "0"
3176
- # }
3177
- # }
3178
- #
3179
- data = self.safe_dict(response, 'data', {})
3180
- precision = self.parse_number(self.parse_precision(self.safe_string(data, 'precision')))
3181
- code = currency['code']
3182
- self.currencies[code]['networks'][networkCode]['precision'] = precision
3183
-
3184
3441
  def parse_transaction_status(self, status: Str):
3185
3442
  statuses: dict = {
3186
3443
  'SUCCESS': 'ok',
@@ -3297,8 +3554,10 @@ class kucoin(Exchange, ImplicitAPI):
3297
3554
  async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
3298
3555
  """
3299
3556
  fetch all deposits made to an account
3300
- :see: https://www.kucoin.com/docs/rest/funding/deposit/get-deposit-list
3301
- :see: https://www.kucoin.com/docs/rest/funding/deposit/get-v1-historical-deposits-list
3557
+
3558
+ https://www.kucoin.com/docs/rest/funding/deposit/get-deposit-list
3559
+ https://www.kucoin.com/docs/rest/funding/deposit/get-v1-historical-deposits-list
3560
+
3302
3561
  :param str code: unified currency code
3303
3562
  :param int [since]: the earliest time in ms to fetch deposits for
3304
3563
  :param int [limit]: the maximum number of deposits structures to retrieve
@@ -3367,14 +3626,17 @@ class kucoin(Exchange, ImplicitAPI):
3367
3626
  # }
3368
3627
  # }
3369
3628
  #
3370
- responseData = response['data']['items']
3371
- return self.parse_transactions(responseData, currency, since, limit, {'type': 'deposit'})
3629
+ data = self.safe_dict(response, 'data', {})
3630
+ items = self.safe_list(data, 'items', [])
3631
+ return self.parse_transactions(items, currency, since, limit, {'type': 'deposit'})
3372
3632
 
3373
3633
  async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
3374
3634
  """
3375
3635
  fetch all withdrawals made from an account
3376
- :see: https://www.kucoin.com/docs/rest/funding/withdrawals/get-withdrawals-list
3377
- :see: https://www.kucoin.com/docs/rest/funding/withdrawals/get-v1-historical-withdrawals-list
3636
+
3637
+ https://www.kucoin.com/docs/rest/funding/withdrawals/get-withdrawals-list
3638
+ https://www.kucoin.com/docs/rest/funding/withdrawals/get-v1-historical-withdrawals-list
3639
+
3378
3640
  :param str code: unified currency code
3379
3641
  :param int [since]: the earliest time in ms to fetch withdrawals for
3380
3642
  :param int [limit]: the maximum number of withdrawals structures to retrieve
@@ -3444,8 +3706,9 @@ class kucoin(Exchange, ImplicitAPI):
3444
3706
  # }
3445
3707
  # }
3446
3708
  #
3447
- responseData = response['data']['items']
3448
- return self.parse_transactions(responseData, currency, since, limit, {'type': 'withdrawal'})
3709
+ data = self.safe_dict(response, 'data', {})
3710
+ items = self.safe_list(data, 'items', [])
3711
+ return self.parse_transactions(items, currency, since, limit, {'type': 'withdrawal'})
3449
3712
 
3450
3713
  def parse_balance_helper(self, entry):
3451
3714
  account = self.account()
@@ -3460,9 +3723,11 @@ class kucoin(Exchange, ImplicitAPI):
3460
3723
  async def fetch_balance(self, params={}) -> Balances:
3461
3724
  """
3462
3725
  query for balance and get the amount of funds available for trading or funds locked in orders
3463
- :see: https://www.kucoin.com/docs/rest/account/basic-info/get-account-list-spot-margin-trade_hf
3464
- :see: https://www.kucoin.com/docs/rest/funding/funding-overview/get-account-detail-margin
3465
- :see: https://www.kucoin.com/docs/rest/funding/funding-overview/get-account-detail-isolated-margin
3726
+
3727
+ https://www.kucoin.com/docs/rest/account/basic-info/get-account-list-spot-margin-trade_hf
3728
+ https://www.kucoin.com/docs/rest/funding/funding-overview/get-account-detail-margin
3729
+ https://www.kucoin.com/docs/rest/funding/funding-overview/get-account-detail-isolated-margin
3730
+
3466
3731
  :param dict [params]: extra parameters specific to the exchange API endpoint
3467
3732
  :param dict [params.marginMode]: 'cross' or 'isolated', margin type for fetching margin balance
3468
3733
  :param dict [params.type]: extra parameters specific to the exchange API endpoint
@@ -3479,10 +3744,10 @@ class kucoin(Exchange, ImplicitAPI):
3479
3744
  accountsByType = self.safe_dict(self.options, 'accountsByType')
3480
3745
  type = self.safe_string(accountsByType, requestedType, requestedType)
3481
3746
  params = self.omit(params, 'type')
3482
- isHf = self.safe_bool(params, 'hf', False)
3483
- if isHf:
3747
+ hf = None
3748
+ hf, params = self.handle_hf_and_params(params)
3749
+ if hf and (type != 'main'):
3484
3750
  type = 'trade_hf'
3485
- params = self.omit(params, 'hf')
3486
3751
  marginMode, query = self.handle_margin_mode_and_params('fetchBalance', params)
3487
3752
  response = None
3488
3753
  request: dict = {}
@@ -3618,15 +3883,19 @@ class kucoin(Exchange, ImplicitAPI):
3618
3883
  account['free'] = self.safe_string(balance, 'available')
3619
3884
  account['used'] = self.safe_string(balance, 'holds')
3620
3885
  result[codeInner2] = account
3621
- returnType = result if isolated else self.safe_balance(result)
3886
+ returnType = result
3887
+ if not isolated:
3888
+ returnType = self.safe_balance(result)
3622
3889
  return returnType
3623
3890
 
3624
3891
  async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
3625
3892
  """
3626
3893
  transfer currency internally between wallets on the same account
3627
- :see: https://www.kucoin.com/docs/rest/funding/transfer/inner-transfer
3628
- :see: https://docs.kucoin.com/futures/#transfer-funds-to-kucoin-main-account-2
3629
- :see: https://docs.kucoin.com/spot-hf/#internal-funds-transfers-in-high-frequency-trading-accounts
3894
+
3895
+ https://www.kucoin.com/docs/rest/funding/transfer/inner-transfer
3896
+ https://docs.kucoin.com/futures/#transfer-funds-to-kucoin-main-account-2
3897
+ https://docs.kucoin.com/spot-hf/#internal-funds-transfers-in-high-frequency-trading-accounts
3898
+
3630
3899
  :param str code: unified currency code
3631
3900
  :param float amount: amount to transfer
3632
3901
  :param str fromAccount: account to transfer from
@@ -3811,7 +4080,7 @@ class kucoin(Exchange, ImplicitAPI):
3811
4080
  }
3812
4081
  return self.safe_string(types, type, type)
3813
4082
 
3814
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
4083
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
3815
4084
  #
3816
4085
  # {
3817
4086
  # "id": "611a1e7c6a053300067a88d9", #unique key for each ledger entry
@@ -3829,6 +4098,7 @@ class kucoin(Exchange, ImplicitAPI):
3829
4098
  id = self.safe_string(item, 'id')
3830
4099
  currencyId = self.safe_string(item, 'currency')
3831
4100
  code = self.safe_currency_code(currencyId, currency)
4101
+ currency = self.safe_currency(currencyId, currency)
3832
4102
  amount = self.safe_number(item, 'amount')
3833
4103
  balanceAfter = None
3834
4104
  # balanceAfter = self.safe_number(item, 'balance'); only returns zero string
@@ -3871,7 +4141,8 @@ class kucoin(Exchange, ImplicitAPI):
3871
4141
  if feeCost != '0':
3872
4142
  feeCurrency = code
3873
4143
  fee = {'cost': self.parse_number(feeCost), 'currency': feeCurrency}
3874
- return {
4144
+ return self.safe_ledger_entry({
4145
+ 'info': item,
3875
4146
  'id': id,
3876
4147
  'direction': direction,
3877
4148
  'account': account,
@@ -3886,30 +4157,31 @@ class kucoin(Exchange, ImplicitAPI):
3886
4157
  'after': balanceAfter, # None
3887
4158
  'status': None,
3888
4159
  'fee': fee,
3889
- 'info': item,
3890
- }
4160
+ }, currency)
3891
4161
 
3892
- async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
4162
+ async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
3893
4163
  """
3894
- :see: https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-spot-margin
3895
- :see: https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-trade_hf
3896
- :see: https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-margin_hf
3897
- fetch the history of changes, actions done by the user or operations that altered balance of the user
3898
- :param str code: unified currency code, default is None
4164
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
4165
+
4166
+ https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-spot-margin
4167
+ https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-trade_hf
4168
+ https://www.kucoin.com/docs/rest/account/basic-info/get-account-ledgers-margin_hf
4169
+
4170
+ :param str [code]: unified currency code, default is None
3899
4171
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
3900
- :param int [limit]: max number of ledger entrys to return, default is None
4172
+ :param int [limit]: max number of ledger entries to return, default is None
3901
4173
  :param dict [params]: extra parameters specific to the exchange API endpoint
3902
4174
  :param boolean [params.hf]: default False, when True will fetch ledger entries for the high frequency trading account
3903
4175
  :param int [params.until]: the latest time in ms to fetch entries for
3904
- :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
3905
- :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
4176
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
4177
+ :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
3906
4178
  """
3907
4179
  await self.load_markets()
3908
4180
  await self.load_accounts()
3909
4181
  paginate = False
3910
4182
  paginate, params = self.handle_option_and_params(params, 'fetchLedger', 'paginate')
3911
- isHf = self.safe_bool(params, 'hf')
3912
- params = self.omit(params, 'hf')
4183
+ hf = None
4184
+ hf, params = self.handle_hf_and_params(params)
3913
4185
  if paginate:
3914
4186
  return await self.fetch_paginated_call_dynamic('fetchLedger', code, since, limit, params)
3915
4187
  request: dict = {
@@ -3930,7 +4202,7 @@ class kucoin(Exchange, ImplicitAPI):
3930
4202
  marginMode = None
3931
4203
  marginMode, params = self.handle_margin_mode_and_params('fetchLedger', params)
3932
4204
  response = None
3933
- if isHf:
4205
+ if hf:
3934
4206
  if marginMode is not None:
3935
4207
  response = await self.privateGetHfMarginAccountLedgers(self.extend(request, params))
3936
4208
  else:
@@ -3995,15 +4267,6 @@ class kucoin(Exchange, ImplicitAPI):
3995
4267
  return config['v1']
3996
4268
  return self.safe_value(config, 'cost', 1)
3997
4269
 
3998
- def parse_borrow_rate_history(self, response, code, since, limit):
3999
- result = []
4000
- for i in range(0, len(response)):
4001
- item = response[i]
4002
- borrowRate = self.parse_borrow_rate(item)
4003
- result.append(borrowRate)
4004
- sorted = self.sort_by(result, 'timestamp')
4005
- return self.filter_by_currency_since_limit(sorted, code, since, limit)
4006
-
4007
4270
  def parse_borrow_rate(self, info, currency: Currency = None):
4008
4271
  #
4009
4272
  # {
@@ -4034,13 +4297,15 @@ class kucoin(Exchange, ImplicitAPI):
4034
4297
  'info': info,
4035
4298
  }
4036
4299
 
4037
- async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4300
+ async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
4038
4301
  """
4039
4302
  fetch the interest owed by the user for borrowing currency for margin trading
4040
- :see: https://docs.kucoin.com/#get-repay-record
4041
- :see: https://docs.kucoin.com/#query-isolated-margin-account-info
4042
- :param str code: unified currency code
4043
- :param str symbol: unified market symbol, required for isolated margin
4303
+
4304
+ https://docs.kucoin.com/#get-repay-record
4305
+ https://docs.kucoin.com/#query-isolated-margin-account-info
4306
+
4307
+ :param str [code]: unified currency code
4308
+ :param str [symbol]: unified market symbol, required for isolated margin
4044
4309
  :param int [since]: the earliest time in ms to fetch borrrow interest for
4045
4310
  :param int [limit]: the maximum number of structures to retrieve
4046
4311
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -4049,14 +4314,19 @@ class kucoin(Exchange, ImplicitAPI):
4049
4314
  """
4050
4315
  await self.load_markets()
4051
4316
  marginMode = None
4052
- marginMode, params = self.handle_margin_mode_and_params('fetchBorrowInterest', params)
4053
- if marginMode is None:
4054
- marginMode = 'cross' # cross marginMode
4317
+ marginMode, params = self.handle_margin_mode_and_params('fetchBorrowInterest', params, 'cross')
4055
4318
  request: dict = {}
4056
- response = None
4319
+ currency = None
4057
4320
  if code is not None:
4058
4321
  currency = self.currency(code)
4059
- request['quoteCurrency'] = currency['id']
4322
+ if marginMode == 'isolated':
4323
+ request['balanceCurrency'] = currency['id']
4324
+ else:
4325
+ request['quoteCurrency'] = currency['id']
4326
+ market = None
4327
+ if symbol is not None:
4328
+ market = self.market(symbol)
4329
+ response = None
4060
4330
  if marginMode == 'isolated':
4061
4331
  response = await self.privateGetIsolatedAccounts(self.extend(request, params))
4062
4332
  else:
@@ -4127,9 +4397,11 @@ class kucoin(Exchange, ImplicitAPI):
4127
4397
  #
4128
4398
  data = self.safe_dict(response, 'data', {})
4129
4399
  assets = self.safe_list(data, 'assets', []) if (marginMode == 'isolated') else self.safe_list(data, 'accounts', [])
4130
- return self.parse_borrow_interests(assets, None)
4400
+ interest = self.parse_borrow_interests(assets, market)
4401
+ filteredByCurrency = self.filter_by_currency_since_limit(interest, code, since, limit)
4402
+ return self.filter_by_symbol_since_limit(filteredByCurrency, symbol, since, limit)
4131
4403
 
4132
- def parse_borrow_interest(self, info: dict, market: Market = None):
4404
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
4133
4405
  #
4134
4406
  # Cross
4135
4407
  #
@@ -4192,21 +4464,23 @@ class kucoin(Exchange, ImplicitAPI):
4192
4464
  interest = self.safe_number(info, 'accruedInterest')
4193
4465
  currencyId = self.safe_string(info, 'currency')
4194
4466
  return {
4467
+ 'info': info,
4195
4468
  'symbol': symbol,
4196
- 'marginMode': marginMode,
4197
4469
  'currency': self.safe_currency_code(currencyId),
4198
4470
  'interest': interest,
4199
4471
  'interestRate': self.safe_number(info, 'dailyIntRate'),
4200
4472
  'amountBorrowed': amountBorrowed,
4473
+ 'marginMode': marginMode,
4201
4474
  'timestamp': timestamp, # create time
4202
4475
  'datetime': self.iso8601(timestamp),
4203
- 'info': info,
4204
4476
  }
4205
4477
 
4206
4478
  async def fetch_borrow_rate_histories(self, codes=None, since: Int = None, limit: Int = None, params={}):
4207
4479
  """
4208
4480
  retrieves a history of a multiple currencies borrow interest rate at specific time slots, returns all currencies if no symbols passed, default is None
4209
- :see: https://www.kucoin.com/docs/rest/margin-trading/margin-trading-v3-/get-cross-isolated-margin-interest-records
4481
+
4482
+ https://www.kucoin.com/docs/rest/margin-trading/margin-trading-v3-/get-cross-isolated-margin-interest-records
4483
+
4210
4484
  :param str[]|None codes: list of unified currency codes, default is None
4211
4485
  :param int [since]: timestamp in ms of the earliest borrowRate, default is None
4212
4486
  :param int [limit]: max number of borrow rate prices to return, default is None
@@ -4249,13 +4523,15 @@ class kucoin(Exchange, ImplicitAPI):
4249
4523
  # }
4250
4524
  #
4251
4525
  data = self.safe_dict(response, 'data')
4252
- rows = self.safe_list(data, 'items')
4526
+ rows = self.safe_list(data, 'items', [])
4253
4527
  return self.parse_borrow_rate_histories(rows, codes, since, limit)
4254
4528
 
4255
4529
  async def fetch_borrow_rate_history(self, code: str, since: Int = None, limit: Int = None, params={}):
4256
4530
  """
4257
4531
  retrieves a history of a currencies borrow interest rate at specific time slots
4258
- :see: https://www.kucoin.com/docs/rest/margin-trading/margin-trading-v3-/get-cross-isolated-margin-interest-records
4532
+
4533
+ https://www.kucoin.com/docs/rest/margin-trading/margin-trading-v3-/get-cross-isolated-margin-interest-records
4534
+
4259
4535
  :param str code: unified currency code
4260
4536
  :param int [since]: timestamp for the earliest borrow rate
4261
4537
  :param int [limit]: the maximum number of `borrow rate structures <https://docs.ccxt.com/#/?id=borrow-rate-structure>` to retrieve
@@ -4300,7 +4576,7 @@ class kucoin(Exchange, ImplicitAPI):
4300
4576
  # }
4301
4577
  #
4302
4578
  data = self.safe_dict(response, 'data')
4303
- rows = self.safe_list(data, 'items')
4579
+ rows = self.safe_list(data, 'items', [])
4304
4580
  return self.parse_borrow_rate_history(rows, code, since, limit)
4305
4581
 
4306
4582
  def parse_borrow_rate_histories(self, response, codes, since, limit):
@@ -4322,7 +4598,8 @@ class kucoin(Exchange, ImplicitAPI):
4322
4598
  if not (code in borrowRateHistories):
4323
4599
  borrowRateHistories[code] = []
4324
4600
  borrowRateStructure = self.parse_borrow_rate(item)
4325
- borrowRateHistories[code].append(borrowRateStructure)
4601
+ borrowRateHistoriesCode = borrowRateHistories[code]
4602
+ borrowRateHistoriesCode.append(borrowRateStructure)
4326
4603
  keys = list(borrowRateHistories.keys())
4327
4604
  for i in range(0, len(keys)):
4328
4605
  code = keys[i]
@@ -4332,7 +4609,9 @@ class kucoin(Exchange, ImplicitAPI):
4332
4609
  async def borrow_cross_margin(self, code: str, amount: float, params={}):
4333
4610
  """
4334
4611
  create a loan to borrow margin
4335
- :see: https://docs.kucoin.com/#1-margin-borrowing
4612
+
4613
+ https://docs.kucoin.com/#1-margin-borrowing
4614
+
4336
4615
  :param str code: unified currency code of the currency to borrow
4337
4616
  :param float amount: the amount to borrow
4338
4617
  :param dict [params]: extra parameters specific to the exchange API endpoints
@@ -4365,7 +4644,9 @@ class kucoin(Exchange, ImplicitAPI):
4365
4644
  async def borrow_isolated_margin(self, symbol: str, code: str, amount: float, params={}):
4366
4645
  """
4367
4646
  create a loan to borrow margin
4368
- :see: https://docs.kucoin.com/#1-margin-borrowing
4647
+
4648
+ https://docs.kucoin.com/#1-margin-borrowing
4649
+
4369
4650
  :param str symbol: unified market symbol, required for isolated margin
4370
4651
  :param str code: unified currency code of the currency to borrow
4371
4652
  :param float amount: the amount to borrow
@@ -4402,7 +4683,9 @@ class kucoin(Exchange, ImplicitAPI):
4402
4683
  async def repay_cross_margin(self, code: str, amount, params={}):
4403
4684
  """
4404
4685
  repay borrowed margin and interest
4405
- :see: https://docs.kucoin.com/#2-repayment
4686
+
4687
+ https://docs.kucoin.com/#2-repayment
4688
+
4406
4689
  :param str code: unified currency code of the currency to repay
4407
4690
  :param float amount: the amount to repay
4408
4691
  :param dict [params]: extra parameters specific to the exchange API endpoints
@@ -4433,7 +4716,9 @@ class kucoin(Exchange, ImplicitAPI):
4433
4716
  async def repay_isolated_margin(self, symbol: str, code: str, amount, params={}):
4434
4717
  """
4435
4718
  repay borrowed margin and interest
4436
- :see: https://docs.kucoin.com/#2-repayment
4719
+
4720
+ https://docs.kucoin.com/#2-repayment
4721
+
4437
4722
  :param str symbol: unified market symbol
4438
4723
  :param str code: unified currency code of the currency to repay
4439
4724
  :param float amount: the amount to repay
@@ -4487,7 +4772,9 @@ class kucoin(Exchange, ImplicitAPI):
4487
4772
  async def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
4488
4773
  """
4489
4774
  fetch deposit and withdraw fees - *IMPORTANT* use fetchDepositWithdrawFee to get more in-depth info
4490
- :see: https://docs.kucoin.com/#get-currencies
4775
+
4776
+ https://docs.kucoin.com/#get-currencies
4777
+
4491
4778
  :param str[]|None codes: list of unified currency codes
4492
4779
  :param dict [params]: extra parameters specific to the exchange API endpoint
4493
4780
  :returns dict: a list of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>`
@@ -4515,6 +4802,38 @@ class kucoin(Exchange, ImplicitAPI):
4515
4802
  data = self.safe_list(response, 'data', [])
4516
4803
  return self.parse_deposit_withdraw_fees(data, codes, 'currency')
4517
4804
 
4805
+ async def set_leverage(self, leverage: int, symbol: Str = None, params={}):
4806
+ """
4807
+ set the level of leverage for a market
4808
+
4809
+ https://www.kucoin.com/docs/rest/margin-trading/margin-trading-v3-/modify-leverage-multiplier
4810
+
4811
+ :param int [leverage]: New leverage multiplier. Must be greater than 1 and up to two decimal places, and cannot be less than the user's current debt leverage or greater than the system's maximum leverage
4812
+ :param str [symbol]: unified market symbol
4813
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4814
+ :returns dict: response from the exchange
4815
+ """
4816
+ await self.load_markets()
4817
+ market = None
4818
+ marketType: Str = None
4819
+ marketType, params = self.handle_market_type_and_params('setLeverage', None, params)
4820
+ if (symbol is not None) or marketType != 'spot':
4821
+ market = self.market(symbol)
4822
+ if market['contract']:
4823
+ raise NotSupported(self.id + ' setLeverage currently supports only spot margin')
4824
+ marginMode: Str = None
4825
+ marginMode, params = self.handle_margin_mode_and_params('setLeverage', params)
4826
+ if marginMode is None:
4827
+ raise ArgumentsRequired(self.id + ' setLeverage requires a marginMode parameter')
4828
+ request: dict = {}
4829
+ if marginMode == 'isolated' and symbol is None:
4830
+ raise ArgumentsRequired(self.id + ' setLeverage requires a symbol parameter for isolated margin')
4831
+ if symbol is not None:
4832
+ request['symbol'] = market['id']
4833
+ request['leverage'] = str(leverage)
4834
+ request['isIsolated'] = (marginMode == 'isolated')
4835
+ return await self.privatePostPositionUpdateUserLeverage(self.extend(request, params))
4836
+
4518
4837
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
4519
4838
  #
4520
4839
  # the v2 URL is https://openapi-v2.kucoin.com/api/v1/endpoint
@@ -4537,7 +4856,7 @@ class kucoin(Exchange, ImplicitAPI):
4537
4856
  headers = headers if (headers is not None) else {}
4538
4857
  url = self.urls['api'][api]
4539
4858
  if not self.is_empty(query):
4540
- if (method == 'GET') or (method == 'DELETE'):
4859
+ if ((method == 'GET') or (method == 'DELETE')) and (path != 'orders/multi-cancel'):
4541
4860
  endpoint += '?' + self.rawencode(query)
4542
4861
  else:
4543
4862
  body = self.json(query)
@@ -4593,7 +4912,7 @@ class kucoin(Exchange, ImplicitAPI):
4593
4912
  #
4594
4913
  errorCode = self.safe_string(response, 'code')
4595
4914
  message = self.safe_string_2(response, 'msg', 'data', '')
4596
- feedback = self.id + ' ' + message
4915
+ feedback = self.id + ' ' + body
4597
4916
  self.throw_exactly_matched_exception(self.exceptions['exact'], message, feedback)
4598
4917
  self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
4599
4918
  self.throw_broadly_matched_exception(self.exceptions['broad'], body, feedback)