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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (772) hide show
  1. ccxt/__init__.py +358 -0
  2. ccxt/abantether.py +316 -0
  3. ccxt/abstract/__init__.py +0 -0
  4. ccxt/abstract/abantether.py +5 -0
  5. ccxt/abstract/ace.py +15 -0
  6. ccxt/abstract/afratether.py +6 -0
  7. ccxt/abstract/alpaca.py +70 -0
  8. ccxt/abstract/arzinja.py +5 -0
  9. ccxt/abstract/arzplus.py +7 -0
  10. ccxt/abstract/ascendex.py +77 -0
  11. ccxt/abstract/bequant.py +115 -0
  12. ccxt/abstract/bigone.py +45 -0
  13. ccxt/abstract/binance.py +712 -0
  14. ccxt/abstract/binancecoinm.py +712 -0
  15. ccxt/abstract/binanceus.py +764 -0
  16. ccxt/abstract/binanceusdm.py +712 -0
  17. ccxt/abstract/bingx.py +113 -0
  18. ccxt/abstract/bit2c.py +27 -0
  19. ccxt/abstract/bitbank.py +27 -0
  20. ccxt/abstract/bitbay.py +53 -0
  21. ccxt/abstract/bitbns.py +40 -0
  22. ccxt/abstract/bitcoincom.py +115 -0
  23. ccxt/abstract/bitfinex.py +69 -0
  24. ccxt/abstract/bitfinex2.py +139 -0
  25. ccxt/abstract/bitflyer.py +38 -0
  26. ccxt/abstract/bitget.py +508 -0
  27. ccxt/abstract/bithumb.py +32 -0
  28. ccxt/abstract/bitimen.py +7 -0
  29. ccxt/abstract/bitir.py +7 -0
  30. ccxt/abstract/bitmart.py +99 -0
  31. ccxt/abstract/bitmex.py +97 -0
  32. ccxt/abstract/bitopro.py +29 -0
  33. ccxt/abstract/bitpanda.py +35 -0
  34. ccxt/abstract/bitpin.py +7 -0
  35. ccxt/abstract/bitrue.py +72 -0
  36. ccxt/abstract/bitso.py +43 -0
  37. ccxt/abstract/bitstamp.py +258 -0
  38. ccxt/abstract/bitteam.py +29 -0
  39. ccxt/abstract/bitvavo.py +27 -0
  40. ccxt/abstract/bl3p.py +19 -0
  41. ccxt/abstract/blockchaincom.py +28 -0
  42. ccxt/abstract/blofin.py +37 -0
  43. ccxt/abstract/btcalpha.py +18 -0
  44. ccxt/abstract/btcbox.py +13 -0
  45. ccxt/abstract/btcmarkets.py +39 -0
  46. ccxt/abstract/btcturk.py +20 -0
  47. ccxt/abstract/bybit.py +298 -0
  48. ccxt/abstract/cex.py +33 -0
  49. ccxt/abstract/coinbase.py +94 -0
  50. ccxt/abstract/coinbaseadvanced.py +94 -0
  51. ccxt/abstract/coinbaseexchange.py +67 -0
  52. ccxt/abstract/coinbaseinternational.py +39 -0
  53. ccxt/abstract/coincatch.py +94 -0
  54. ccxt/abstract/coincheck.py +33 -0
  55. ccxt/abstract/coinex.py +237 -0
  56. ccxt/abstract/coinlist.py +54 -0
  57. ccxt/abstract/coinmate.py +62 -0
  58. ccxt/abstract/coinmetro.py +34 -0
  59. ccxt/abstract/coinone.py +67 -0
  60. ccxt/abstract/coinsph.py +54 -0
  61. ccxt/abstract/coinspot.py +28 -0
  62. ccxt/abstract/cryptocom.py +107 -0
  63. ccxt/abstract/currencycom.py +68 -0
  64. ccxt/abstract/delta.py +50 -0
  65. ccxt/abstract/deribit.py +125 -0
  66. ccxt/abstract/digifinex.py +91 -0
  67. ccxt/abstract/eterex.py +5 -0
  68. ccxt/abstract/excoino.py +7 -0
  69. ccxt/abstract/exir.py +8 -0
  70. ccxt/abstract/exmo.py +55 -0
  71. ccxt/abstract/exnovin.py +6 -0
  72. ccxt/abstract/farhadexchange.py +5 -0
  73. ccxt/abstract/fmfwio.py +115 -0
  74. ccxt/abstract/gate.py +265 -0
  75. ccxt/abstract/gateio.py +265 -0
  76. ccxt/abstract/gemini.py +58 -0
  77. ccxt/abstract/hashkey.py +67 -0
  78. ccxt/abstract/hitbtc.py +115 -0
  79. ccxt/abstract/hitbtc3.py +115 -0
  80. ccxt/abstract/hitobit.py +8 -0
  81. ccxt/abstract/hollaex.py +33 -0
  82. ccxt/abstract/htx.py +548 -0
  83. ccxt/abstract/huobi.py +548 -0
  84. ccxt/abstract/huobijp.py +114 -0
  85. ccxt/abstract/hyperliquid.py +6 -0
  86. ccxt/abstract/idex.py +26 -0
  87. ccxt/abstract/independentreserve.py +37 -0
  88. ccxt/abstract/indodax.py +26 -0
  89. ccxt/abstract/jibitex.py +7 -0
  90. ccxt/abstract/kraken.py +57 -0
  91. ccxt/abstract/krakenfutures.py +38 -0
  92. ccxt/abstract/kucoin.py +214 -0
  93. ccxt/abstract/kucoinfutures.py +233 -0
  94. ccxt/abstract/kuna.py +182 -0
  95. ccxt/abstract/latoken.py +56 -0
  96. ccxt/abstract/lbank.py +61 -0
  97. ccxt/abstract/luno.py +37 -0
  98. ccxt/abstract/lykke.py +29 -0
  99. ccxt/abstract/mercado.py +25 -0
  100. ccxt/abstract/mexc.py +178 -0
  101. ccxt/abstract/ndax.py +97 -0
  102. ccxt/abstract/nobitex.py +7 -0
  103. ccxt/abstract/novadax.py +29 -0
  104. ccxt/abstract/oceanex.py +22 -0
  105. ccxt/abstract/okcoin.py +74 -0
  106. ccxt/abstract/okexchange.py +8 -0
  107. ccxt/abstract/okx.py +324 -0
  108. ccxt/abstract/ompfinex.py +7 -0
  109. ccxt/abstract/onetrading.py +35 -0
  110. ccxt/abstract/oxfun.py +34 -0
  111. ccxt/abstract/p2b.py +22 -0
  112. ccxt/abstract/paradex.py +40 -0
  113. ccxt/abstract/paymium.py +28 -0
  114. ccxt/abstract/phemex.py +115 -0
  115. ccxt/abstract/poloniex.py +69 -0
  116. ccxt/abstract/poloniexfutures.py +48 -0
  117. ccxt/abstract/probit.py +23 -0
  118. ccxt/abstract/ramzinex.py +7 -0
  119. ccxt/abstract/sarmayex.py +5 -0
  120. ccxt/abstract/sarrafex.py +7 -0
  121. ccxt/abstract/tabdeal.py +7 -0
  122. ccxt/abstract/tetherland.py +5 -0
  123. ccxt/abstract/timex.py +62 -0
  124. ccxt/abstract/tokocrypto.py +37 -0
  125. ccxt/abstract/tradeogre.py +16 -0
  126. ccxt/abstract/twox.py +5 -0
  127. ccxt/abstract/ubitex.py +7 -0
  128. ccxt/abstract/upbit.py +38 -0
  129. ccxt/abstract/vertex.py +19 -0
  130. ccxt/abstract/wallex.py +8 -0
  131. ccxt/abstract/wavesexchange.py +154 -0
  132. ccxt/abstract/wazirx.py +30 -0
  133. ccxt/abstract/whitebit.py +98 -0
  134. ccxt/abstract/woo.py +83 -0
  135. ccxt/abstract/woofipro.py +119 -0
  136. ccxt/abstract/xt.py +152 -0
  137. ccxt/abstract/yobit.py +16 -0
  138. ccxt/abstract/zaif.py +38 -0
  139. ccxt/abstract/zonda.py +53 -0
  140. ccxt/ace.py +1012 -0
  141. ccxt/afratether.py +293 -0
  142. ccxt/alpaca.py +1083 -0
  143. ccxt/arzinja.py +285 -0
  144. ccxt/arzplus.py +412 -0
  145. ccxt/ascendex.py +3330 -0
  146. ccxt/async_support/__init__.py +337 -0
  147. ccxt/async_support/abantether.py +316 -0
  148. ccxt/async_support/ace.py +1012 -0
  149. ccxt/async_support/afratether.py +293 -0
  150. ccxt/async_support/alpaca.py +1083 -0
  151. ccxt/async_support/arzinja.py +285 -0
  152. ccxt/async_support/arzplus.py +412 -0
  153. ccxt/async_support/ascendex.py +3330 -0
  154. ccxt/async_support/base/__init__.py +1 -0
  155. ccxt/async_support/base/exchange.py +1966 -0
  156. ccxt/async_support/base/throttler.py +50 -0
  157. ccxt/async_support/base/ws/__init__.py +38 -0
  158. ccxt/async_support/base/ws/aiohttp_client.py +125 -0
  159. ccxt/async_support/base/ws/cache.py +212 -0
  160. ccxt/async_support/base/ws/client.py +193 -0
  161. ccxt/async_support/base/ws/fast_client.py +96 -0
  162. ccxt/async_support/base/ws/functions.py +59 -0
  163. ccxt/async_support/base/ws/future.py +58 -0
  164. ccxt/async_support/base/ws/order_book.py +78 -0
  165. ccxt/async_support/base/ws/order_book_side.py +174 -0
  166. ccxt/async_support/bequant.py +33 -0
  167. ccxt/async_support/bigone.py +2113 -0
  168. ccxt/async_support/binance.py +12234 -0
  169. ccxt/async_support/binancecoinm.py +45 -0
  170. ccxt/async_support/binanceus.py +211 -0
  171. ccxt/async_support/binanceusdm.py +58 -0
  172. ccxt/async_support/bingx.py +4325 -0
  173. ccxt/async_support/bit2c.py +866 -0
  174. ccxt/async_support/bitbank.py +1001 -0
  175. ccxt/async_support/bitbay.py +17 -0
  176. ccxt/async_support/bitbns.py +1154 -0
  177. ccxt/async_support/bitcoincom.py +17 -0
  178. ccxt/async_support/bitfinex.py +1617 -0
  179. ccxt/async_support/bitfinex2.py +3552 -0
  180. ccxt/async_support/bitflyer.py +995 -0
  181. ccxt/async_support/bitget.py +8273 -0
  182. ccxt/async_support/bithumb.py +1061 -0
  183. ccxt/async_support/bitimen.py +401 -0
  184. ccxt/async_support/bitir.py +490 -0
  185. ccxt/async_support/bitmart.py +4415 -0
  186. ccxt/async_support/bitmex.py +2756 -0
  187. ccxt/async_support/bitopro.py +1630 -0
  188. ccxt/async_support/bitpanda.py +16 -0
  189. ccxt/async_support/bitpin.py +454 -0
  190. ccxt/async_support/bitrue.py +3027 -0
  191. ccxt/async_support/bitso.py +1670 -0
  192. ccxt/async_support/bitstamp.py +2203 -0
  193. ccxt/async_support/bitteam.py +2239 -0
  194. ccxt/async_support/bitvavo.py +1968 -0
  195. ccxt/async_support/bl3p.py +485 -0
  196. ccxt/async_support/blockchaincom.py +1104 -0
  197. ccxt/async_support/blofin.py +2066 -0
  198. ccxt/async_support/btcalpha.py +891 -0
  199. ccxt/async_support/btcbox.py +544 -0
  200. ccxt/async_support/btcmarkets.py +1221 -0
  201. ccxt/async_support/btcturk.py +911 -0
  202. ccxt/async_support/bybit.py +8159 -0
  203. ccxt/async_support/cex.py +1605 -0
  204. ccxt/async_support/coinbase.py +4475 -0
  205. ccxt/async_support/coinbaseadvanced.py +17 -0
  206. ccxt/async_support/coinbaseexchange.py +1734 -0
  207. ccxt/async_support/coinbaseinternational.py +1899 -0
  208. ccxt/async_support/coincatch.py +5069 -0
  209. ccxt/async_support/coincheck.py +815 -0
  210. ccxt/async_support/coinex.py +5526 -0
  211. ccxt/async_support/coinlist.py +2243 -0
  212. ccxt/async_support/coinmate.py +1067 -0
  213. ccxt/async_support/coinmetro.py +1797 -0
  214. ccxt/async_support/coinone.py +1127 -0
  215. ccxt/async_support/coinsph.py +1850 -0
  216. ccxt/async_support/coinspot.py +534 -0
  217. ccxt/async_support/cryptocom.py +2822 -0
  218. ccxt/async_support/currencycom.py +1950 -0
  219. ccxt/async_support/delta.py +3376 -0
  220. ccxt/async_support/deribit.py +3437 -0
  221. ccxt/async_support/digifinex.py +3960 -0
  222. ccxt/async_support/eterex.py +286 -0
  223. ccxt/async_support/excoino.py +399 -0
  224. ccxt/async_support/exir.py +375 -0
  225. ccxt/async_support/exmo.py +2462 -0
  226. ccxt/async_support/exnovin.py +360 -0
  227. ccxt/async_support/farhadexchange.py +266 -0
  228. ccxt/async_support/fmfwio.py +34 -0
  229. ccxt/async_support/gate.py +6976 -0
  230. ccxt/async_support/gateio.py +16 -0
  231. ccxt/async_support/gemini.py +1825 -0
  232. ccxt/async_support/hashkey.py +4150 -0
  233. ccxt/async_support/hitbtc.py +3423 -0
  234. ccxt/async_support/hitbtc3.py +16 -0
  235. ccxt/async_support/hitobit.py +391 -0
  236. ccxt/async_support/hollaex.py +1813 -0
  237. ccxt/async_support/htx.py +8506 -0
  238. ccxt/async_support/huobi.py +16 -0
  239. ccxt/async_support/huobijp.py +1801 -0
  240. ccxt/async_support/hyperliquid.py +2431 -0
  241. ccxt/async_support/idex.py +1766 -0
  242. ccxt/async_support/independentreserve.py +784 -0
  243. ccxt/async_support/indodax.py +1247 -0
  244. ccxt/async_support/jibitex.py +395 -0
  245. ccxt/async_support/kraken.py +2894 -0
  246. ccxt/async_support/krakenfutures.py +2601 -0
  247. ccxt/async_support/kucoin.py +4602 -0
  248. ccxt/async_support/kucoinfutures.py +2698 -0
  249. ccxt/async_support/kuna.py +1841 -0
  250. ccxt/async_support/latoken.py +1664 -0
  251. ccxt/async_support/lbank.py +2683 -0
  252. ccxt/async_support/luno.py +1067 -0
  253. ccxt/async_support/lykke.py +1270 -0
  254. ccxt/async_support/mercado.py +842 -0
  255. ccxt/async_support/mexc.py +5369 -0
  256. ccxt/async_support/ndax.py +2354 -0
  257. ccxt/async_support/nobitex.py +419 -0
  258. ccxt/async_support/novadax.py +1484 -0
  259. ccxt/async_support/oceanex.py +903 -0
  260. ccxt/async_support/okcoin.py +2936 -0
  261. ccxt/async_support/okexchange.py +349 -0
  262. ccxt/async_support/okx.py +7827 -0
  263. ccxt/async_support/ompfinex.py +472 -0
  264. ccxt/async_support/onetrading.py +1911 -0
  265. ccxt/async_support/oxfun.py +2773 -0
  266. ccxt/async_support/p2b.py +1194 -0
  267. ccxt/async_support/paradex.py +2015 -0
  268. ccxt/async_support/paymium.py +564 -0
  269. ccxt/async_support/phemex.py +4473 -0
  270. ccxt/async_support/poloniex.py +2232 -0
  271. ccxt/async_support/poloniexfutures.py +1717 -0
  272. ccxt/async_support/probit.py +1734 -0
  273. ccxt/async_support/ramzinex.py +476 -0
  274. ccxt/async_support/sarmayex.py +357 -0
  275. ccxt/async_support/sarrafex.py +478 -0
  276. ccxt/async_support/tabdeal.py +364 -0
  277. ccxt/async_support/tetherland.py +349 -0
  278. ccxt/async_support/timex.py +1593 -0
  279. ccxt/async_support/tokocrypto.py +2405 -0
  280. ccxt/async_support/tradeogre.py +608 -0
  281. ccxt/async_support/twox.py +326 -0
  282. ccxt/async_support/ubitex.py +409 -0
  283. ccxt/async_support/upbit.py +1833 -0
  284. ccxt/async_support/vertex.py +2922 -0
  285. ccxt/async_support/wallex.py +445 -0
  286. ccxt/async_support/wavesexchange.py +2473 -0
  287. ccxt/async_support/wazirx.py +1224 -0
  288. ccxt/async_support/whitebit.py +2469 -0
  289. ccxt/async_support/woo.py +3114 -0
  290. ccxt/async_support/woofipro.py +2533 -0
  291. ccxt/async_support/xt.py +4454 -0
  292. ccxt/async_support/yobit.py +1283 -0
  293. ccxt/async_support/zaif.py +725 -0
  294. ccxt/async_support/zonda.py +1828 -0
  295. ccxt/base/__init__.py +27 -0
  296. ccxt/base/decimal_to_precision.py +174 -0
  297. ccxt/base/errors.py +242 -0
  298. ccxt/base/exchange.py +5941 -0
  299. ccxt/base/precise.py +287 -0
  300. ccxt/base/types.py +502 -0
  301. ccxt/bequant.py +33 -0
  302. ccxt/bigone.py +2112 -0
  303. ccxt/binance.py +12233 -0
  304. ccxt/binancecoinm.py +45 -0
  305. ccxt/binanceus.py +211 -0
  306. ccxt/binanceusdm.py +58 -0
  307. ccxt/bingx.py +4324 -0
  308. ccxt/bit2c.py +866 -0
  309. ccxt/bitbank.py +1001 -0
  310. ccxt/bitbay.py +17 -0
  311. ccxt/bitbns.py +1154 -0
  312. ccxt/bitcoincom.py +17 -0
  313. ccxt/bitfinex.py +1617 -0
  314. ccxt/bitfinex2.py +3552 -0
  315. ccxt/bitflyer.py +995 -0
  316. ccxt/bitget.py +8272 -0
  317. ccxt/bithumb.py +1061 -0
  318. ccxt/bitimen.py +401 -0
  319. ccxt/bitir.py +490 -0
  320. ccxt/bitmart.py +4415 -0
  321. ccxt/bitmex.py +2756 -0
  322. ccxt/bitopro.py +1630 -0
  323. ccxt/bitpanda.py +16 -0
  324. ccxt/bitpin.py +454 -0
  325. ccxt/bitrue.py +3026 -0
  326. ccxt/bitso.py +1670 -0
  327. ccxt/bitstamp.py +2203 -0
  328. ccxt/bitteam.py +2239 -0
  329. ccxt/bitvavo.py +1968 -0
  330. ccxt/bl3p.py +485 -0
  331. ccxt/blockchaincom.py +1104 -0
  332. ccxt/blofin.py +2066 -0
  333. ccxt/btcalpha.py +891 -0
  334. ccxt/btcbox.py +544 -0
  335. ccxt/btcmarkets.py +1221 -0
  336. ccxt/btcturk.py +911 -0
  337. ccxt/bybit.py +8158 -0
  338. ccxt/cex.py +1605 -0
  339. ccxt/coinbase.py +4474 -0
  340. ccxt/coinbaseadvanced.py +17 -0
  341. ccxt/coinbaseexchange.py +1734 -0
  342. ccxt/coinbaseinternational.py +1899 -0
  343. ccxt/coincatch.py +5069 -0
  344. ccxt/coincheck.py +815 -0
  345. ccxt/coinex.py +5525 -0
  346. ccxt/coinlist.py +2243 -0
  347. ccxt/coinmate.py +1067 -0
  348. ccxt/coinmetro.py +1797 -0
  349. ccxt/coinone.py +1127 -0
  350. ccxt/coinsph.py +1850 -0
  351. ccxt/coinspot.py +534 -0
  352. ccxt/cryptocom.py +2822 -0
  353. ccxt/currencycom.py +1950 -0
  354. ccxt/delta.py +3376 -0
  355. ccxt/deribit.py +3437 -0
  356. ccxt/digifinex.py +3959 -0
  357. ccxt/eterex.py +286 -0
  358. ccxt/excoino.py +399 -0
  359. ccxt/exir.py +375 -0
  360. ccxt/exmo.py +2462 -0
  361. ccxt/exnovin.py +360 -0
  362. ccxt/farhadexchange.py +266 -0
  363. ccxt/fmfwio.py +34 -0
  364. ccxt/gate.py +6975 -0
  365. ccxt/gateio.py +16 -0
  366. ccxt/gemini.py +1824 -0
  367. ccxt/hashkey.py +4150 -0
  368. ccxt/hitbtc.py +3423 -0
  369. ccxt/hitbtc3.py +16 -0
  370. ccxt/hitobit.py +391 -0
  371. ccxt/hollaex.py +1813 -0
  372. ccxt/htx.py +8505 -0
  373. ccxt/huobi.py +16 -0
  374. ccxt/huobijp.py +1801 -0
  375. ccxt/hyperliquid.py +2430 -0
  376. ccxt/idex.py +1766 -0
  377. ccxt/independentreserve.py +784 -0
  378. ccxt/indodax.py +1247 -0
  379. ccxt/jibitex.py +395 -0
  380. ccxt/kraken.py +2894 -0
  381. ccxt/krakenfutures.py +2601 -0
  382. ccxt/kucoin.py +4601 -0
  383. ccxt/kucoinfutures.py +2698 -0
  384. ccxt/kuna.py +1841 -0
  385. ccxt/latoken.py +1664 -0
  386. ccxt/lbank.py +2682 -0
  387. ccxt/luno.py +1067 -0
  388. ccxt/lykke.py +1270 -0
  389. ccxt/mercado.py +842 -0
  390. ccxt/mexc.py +5369 -0
  391. ccxt/ndax.py +2354 -0
  392. ccxt/nobitex.py +419 -0
  393. ccxt/novadax.py +1484 -0
  394. ccxt/oceanex.py +903 -0
  395. ccxt/okcoin.py +2936 -0
  396. ccxt/okexchange.py +349 -0
  397. ccxt/okx.py +7826 -0
  398. ccxt/ompfinex.py +472 -0
  399. ccxt/onetrading.py +1911 -0
  400. ccxt/oxfun.py +2772 -0
  401. ccxt/p2b.py +1194 -0
  402. ccxt/paradex.py +2015 -0
  403. ccxt/paymium.py +564 -0
  404. ccxt/phemex.py +4473 -0
  405. ccxt/poloniex.py +2232 -0
  406. ccxt/poloniexfutures.py +1717 -0
  407. ccxt/pro/__init__.py +149 -0
  408. ccxt/pro/alpaca.py +685 -0
  409. ccxt/pro/ascendex.py +916 -0
  410. ccxt/pro/bequant.py +38 -0
  411. ccxt/pro/binance.py +3488 -0
  412. ccxt/pro/binancecoinm.py +28 -0
  413. ccxt/pro/binanceus.py +48 -0
  414. ccxt/pro/binanceusdm.py +31 -0
  415. ccxt/pro/bingx.py +1264 -0
  416. ccxt/pro/bitcoincom.py +34 -0
  417. ccxt/pro/bitfinex.py +621 -0
  418. ccxt/pro/bitfinex2.py +1083 -0
  419. ccxt/pro/bitget.py +1692 -0
  420. ccxt/pro/bithumb.py +368 -0
  421. ccxt/pro/bitmart.py +1449 -0
  422. ccxt/pro/bitmex.py +1656 -0
  423. ccxt/pro/bitopro.py +445 -0
  424. ccxt/pro/bitpanda.py +15 -0
  425. ccxt/pro/bitrue.py +447 -0
  426. ccxt/pro/bitstamp.py +522 -0
  427. ccxt/pro/bitvavo.py +1270 -0
  428. ccxt/pro/blockchaincom.py +738 -0
  429. ccxt/pro/blofin.py +692 -0
  430. ccxt/pro/bybit.py +2000 -0
  431. ccxt/pro/cex.py +1440 -0
  432. ccxt/pro/coinbase.py +678 -0
  433. ccxt/pro/coinbaseadvanced.py +16 -0
  434. ccxt/pro/coinbaseexchange.py +895 -0
  435. ccxt/pro/coinbaseinternational.py +620 -0
  436. ccxt/pro/coincatch.py +1464 -0
  437. ccxt/pro/coincheck.py +199 -0
  438. ccxt/pro/coinex.py +1061 -0
  439. ccxt/pro/coinone.py +395 -0
  440. ccxt/pro/cryptocom.py +947 -0
  441. ccxt/pro/currencycom.py +536 -0
  442. ccxt/pro/deribit.py +892 -0
  443. ccxt/pro/exmo.py +629 -0
  444. ccxt/pro/gate.py +1416 -0
  445. ccxt/pro/gateio.py +15 -0
  446. ccxt/pro/gemini.py +865 -0
  447. ccxt/pro/hashkey.py +802 -0
  448. ccxt/pro/hitbtc.py +1216 -0
  449. ccxt/pro/hollaex.py +563 -0
  450. ccxt/pro/htx.py +2215 -0
  451. ccxt/pro/huobi.py +15 -0
  452. ccxt/pro/huobijp.py +570 -0
  453. ccxt/pro/hyperliquid.py +525 -0
  454. ccxt/pro/idex.py +672 -0
  455. ccxt/pro/independentreserve.py +270 -0
  456. ccxt/pro/kraken.py +1356 -0
  457. ccxt/pro/krakenfutures.py +1492 -0
  458. ccxt/pro/kucoin.py +1133 -0
  459. ccxt/pro/kucoinfutures.py +1081 -0
  460. ccxt/pro/lbank.py +843 -0
  461. ccxt/pro/luno.py +303 -0
  462. ccxt/pro/mexc.py +1122 -0
  463. ccxt/pro/ndax.py +506 -0
  464. ccxt/pro/okcoin.py +698 -0
  465. ccxt/pro/okx.py +1851 -0
  466. ccxt/pro/onetrading.py +1275 -0
  467. ccxt/pro/oxfun.py +950 -0
  468. ccxt/pro/p2b.py +419 -0
  469. ccxt/pro/paradex.py +352 -0
  470. ccxt/pro/phemex.py +1441 -0
  471. ccxt/pro/poloniex.py +1166 -0
  472. ccxt/pro/poloniexfutures.py +990 -0
  473. ccxt/pro/probit.py +551 -0
  474. ccxt/pro/upbit.py +520 -0
  475. ccxt/pro/vertex.py +943 -0
  476. ccxt/pro/wazirx.py +749 -0
  477. ccxt/pro/whitebit.py +864 -0
  478. ccxt/pro/woo.py +1078 -0
  479. ccxt/pro/woofipro.py +1183 -0
  480. ccxt/pro/xt.py +1067 -0
  481. ccxt/probit.py +1734 -0
  482. ccxt/ramzinex.py +476 -0
  483. ccxt/sarmayex.py +357 -0
  484. ccxt/sarrafex.py +478 -0
  485. ccxt/static_dependencies/__init__.py +1 -0
  486. ccxt/static_dependencies/ecdsa/__init__.py +14 -0
  487. ccxt/static_dependencies/ecdsa/_version.py +520 -0
  488. ccxt/static_dependencies/ecdsa/curves.py +56 -0
  489. ccxt/static_dependencies/ecdsa/der.py +221 -0
  490. ccxt/static_dependencies/ecdsa/ecdsa.py +310 -0
  491. ccxt/static_dependencies/ecdsa/ellipticcurve.py +197 -0
  492. ccxt/static_dependencies/ecdsa/keys.py +332 -0
  493. ccxt/static_dependencies/ecdsa/numbertheory.py +531 -0
  494. ccxt/static_dependencies/ecdsa/rfc6979.py +100 -0
  495. ccxt/static_dependencies/ecdsa/util.py +266 -0
  496. ccxt/static_dependencies/ethereum/__init__.py +7 -0
  497. ccxt/static_dependencies/ethereum/abi/__init__.py +16 -0
  498. ccxt/static_dependencies/ethereum/abi/abi.py +19 -0
  499. ccxt/static_dependencies/ethereum/abi/base.py +152 -0
  500. ccxt/static_dependencies/ethereum/abi/codec.py +217 -0
  501. ccxt/static_dependencies/ethereum/abi/constants.py +3 -0
  502. ccxt/static_dependencies/ethereum/abi/decoding.py +565 -0
  503. ccxt/static_dependencies/ethereum/abi/encoding.py +720 -0
  504. ccxt/static_dependencies/ethereum/abi/exceptions.py +139 -0
  505. ccxt/static_dependencies/ethereum/abi/grammar.py +443 -0
  506. ccxt/static_dependencies/ethereum/abi/packed.py +13 -0
  507. ccxt/static_dependencies/ethereum/abi/py.typed +0 -0
  508. ccxt/static_dependencies/ethereum/abi/registry.py +643 -0
  509. ccxt/static_dependencies/ethereum/abi/tools/__init__.py +3 -0
  510. ccxt/static_dependencies/ethereum/abi/tools/_strategies.py +230 -0
  511. ccxt/static_dependencies/ethereum/abi/utils/__init__.py +0 -0
  512. ccxt/static_dependencies/ethereum/abi/utils/numeric.py +83 -0
  513. ccxt/static_dependencies/ethereum/abi/utils/padding.py +27 -0
  514. ccxt/static_dependencies/ethereum/abi/utils/string.py +19 -0
  515. ccxt/static_dependencies/ethereum/account/__init__.py +3 -0
  516. ccxt/static_dependencies/ethereum/account/encode_typed_data/__init__.py +4 -0
  517. ccxt/static_dependencies/ethereum/account/encode_typed_data/encoding_and_hashing.py +239 -0
  518. ccxt/static_dependencies/ethereum/account/encode_typed_data/helpers.py +40 -0
  519. ccxt/static_dependencies/ethereum/account/messages.py +263 -0
  520. ccxt/static_dependencies/ethereum/account/py.typed +0 -0
  521. ccxt/static_dependencies/ethereum/hexbytes/__init__.py +5 -0
  522. ccxt/static_dependencies/ethereum/hexbytes/_utils.py +54 -0
  523. ccxt/static_dependencies/ethereum/hexbytes/main.py +65 -0
  524. ccxt/static_dependencies/ethereum/hexbytes/py.typed +0 -0
  525. ccxt/static_dependencies/ethereum/typing/__init__.py +63 -0
  526. ccxt/static_dependencies/ethereum/typing/abi.py +6 -0
  527. ccxt/static_dependencies/ethereum/typing/bls.py +7 -0
  528. ccxt/static_dependencies/ethereum/typing/discovery.py +5 -0
  529. ccxt/static_dependencies/ethereum/typing/encoding.py +7 -0
  530. ccxt/static_dependencies/ethereum/typing/enums.py +17 -0
  531. ccxt/static_dependencies/ethereum/typing/ethpm.py +9 -0
  532. ccxt/static_dependencies/ethereum/typing/evm.py +20 -0
  533. ccxt/static_dependencies/ethereum/typing/networks.py +1122 -0
  534. ccxt/static_dependencies/ethereum/typing/py.typed +0 -0
  535. ccxt/static_dependencies/ethereum/utils/__init__.py +115 -0
  536. ccxt/static_dependencies/ethereum/utils/abi.py +72 -0
  537. ccxt/static_dependencies/ethereum/utils/address.py +171 -0
  538. ccxt/static_dependencies/ethereum/utils/applicators.py +151 -0
  539. ccxt/static_dependencies/ethereum/utils/conversions.py +190 -0
  540. ccxt/static_dependencies/ethereum/utils/currency.py +107 -0
  541. ccxt/static_dependencies/ethereum/utils/curried/__init__.py +269 -0
  542. ccxt/static_dependencies/ethereum/utils/debug.py +20 -0
  543. ccxt/static_dependencies/ethereum/utils/decorators.py +132 -0
  544. ccxt/static_dependencies/ethereum/utils/encoding.py +6 -0
  545. ccxt/static_dependencies/ethereum/utils/exceptions.py +4 -0
  546. ccxt/static_dependencies/ethereum/utils/functional.py +75 -0
  547. ccxt/static_dependencies/ethereum/utils/hexadecimal.py +74 -0
  548. ccxt/static_dependencies/ethereum/utils/humanize.py +188 -0
  549. ccxt/static_dependencies/ethereum/utils/logging.py +159 -0
  550. ccxt/static_dependencies/ethereum/utils/module_loading.py +31 -0
  551. ccxt/static_dependencies/ethereum/utils/numeric.py +43 -0
  552. ccxt/static_dependencies/ethereum/utils/py.typed +0 -0
  553. ccxt/static_dependencies/ethereum/utils/toolz.py +76 -0
  554. ccxt/static_dependencies/ethereum/utils/types.py +54 -0
  555. ccxt/static_dependencies/ethereum/utils/typing/__init__.py +18 -0
  556. ccxt/static_dependencies/ethereum/utils/typing/misc.py +14 -0
  557. ccxt/static_dependencies/ethereum/utils/units.py +31 -0
  558. ccxt/static_dependencies/keccak/__init__.py +3 -0
  559. ccxt/static_dependencies/keccak/keccak.py +197 -0
  560. ccxt/static_dependencies/lark/__init__.py +38 -0
  561. ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  562. ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  563. ccxt/static_dependencies/lark/ast_utils.py +59 -0
  564. ccxt/static_dependencies/lark/common.py +86 -0
  565. ccxt/static_dependencies/lark/exceptions.py +292 -0
  566. ccxt/static_dependencies/lark/grammar.py +130 -0
  567. ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  568. ccxt/static_dependencies/lark/indenter.py +143 -0
  569. ccxt/static_dependencies/lark/lark.py +658 -0
  570. ccxt/static_dependencies/lark/lexer.py +678 -0
  571. ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  572. ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  573. ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  574. ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  575. ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  576. ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  577. ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  578. ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  579. ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  580. ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  581. ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  582. ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  583. ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  584. ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  585. ccxt/static_dependencies/lark/reconstruct.py +107 -0
  586. ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  587. ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  588. ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  589. ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  590. ccxt/static_dependencies/lark/tree.py +267 -0
  591. ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  592. ccxt/static_dependencies/lark/tree_templates.py +180 -0
  593. ccxt/static_dependencies/lark/utils.py +343 -0
  594. ccxt/static_dependencies/lark/visitors.py +596 -0
  595. ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  596. ccxt/static_dependencies/marshmallow/base.py +65 -0
  597. ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  598. ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  599. ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  600. ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  601. ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  602. ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  603. ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  604. ccxt/static_dependencies/marshmallow/types.py +12 -0
  605. ccxt/static_dependencies/marshmallow/utils.py +378 -0
  606. ccxt/static_dependencies/marshmallow/validate.py +678 -0
  607. ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  608. ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  609. ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  610. ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  611. ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  612. ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  613. ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  614. ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  615. ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  616. ccxt/static_dependencies/msgpack/__init__.py +55 -0
  617. ccxt/static_dependencies/msgpack/exceptions.py +48 -0
  618. ccxt/static_dependencies/msgpack/ext.py +168 -0
  619. ccxt/static_dependencies/msgpack/fallback.py +951 -0
  620. ccxt/static_dependencies/parsimonious/__init__.py +10 -0
  621. ccxt/static_dependencies/parsimonious/exceptions.py +105 -0
  622. ccxt/static_dependencies/parsimonious/expressions.py +479 -0
  623. ccxt/static_dependencies/parsimonious/grammar.py +487 -0
  624. ccxt/static_dependencies/parsimonious/nodes.py +325 -0
  625. ccxt/static_dependencies/parsimonious/utils.py +40 -0
  626. ccxt/static_dependencies/starknet/__init__.py +0 -0
  627. ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  628. ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  629. ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  630. ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  631. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  632. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  633. ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  634. ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  635. ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  636. ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  637. ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  638. ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  639. ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  640. ccxt/static_dependencies/starknet/common.py +15 -0
  641. ccxt/static_dependencies/starknet/constants.py +39 -0
  642. ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  643. ccxt/static_dependencies/starknet/hash/address.py +79 -0
  644. ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  645. ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  646. ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  647. ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  648. ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  649. ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
  650. ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  651. ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  652. ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  653. ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  654. ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  655. ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  656. ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  657. ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  658. ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  659. ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  660. ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  661. ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  662. ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  663. ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  664. ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  665. ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  666. ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  667. ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  668. ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  669. ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  670. ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  671. ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  672. ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  673. ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  674. ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  675. ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  676. ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  677. ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  678. ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  679. ccxt/static_dependencies/starkware/__init__.py +0 -0
  680. ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  681. ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
  682. ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
  683. ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
  684. ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
  685. ccxt/static_dependencies/sympy/__init__.py +0 -0
  686. ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  687. ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
  688. ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  689. ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  690. ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  691. ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  692. ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  693. ccxt/static_dependencies/toolz/__init__.py +26 -0
  694. ccxt/static_dependencies/toolz/_signatures.py +784 -0
  695. ccxt/static_dependencies/toolz/_version.py +520 -0
  696. ccxt/static_dependencies/toolz/compatibility.py +30 -0
  697. ccxt/static_dependencies/toolz/curried/__init__.py +101 -0
  698. ccxt/static_dependencies/toolz/curried/exceptions.py +22 -0
  699. ccxt/static_dependencies/toolz/curried/operator.py +22 -0
  700. ccxt/static_dependencies/toolz/dicttoolz.py +339 -0
  701. ccxt/static_dependencies/toolz/functoolz.py +1049 -0
  702. ccxt/static_dependencies/toolz/itertoolz.py +1057 -0
  703. ccxt/static_dependencies/toolz/recipes.py +46 -0
  704. ccxt/static_dependencies/toolz/utils.py +9 -0
  705. ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  706. ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  707. ccxt/tabdeal.py +364 -0
  708. ccxt/test/__init__.py +3 -0
  709. ccxt/test/base/__init__.py +29 -0
  710. ccxt/test/base/test_account.py +26 -0
  711. ccxt/test/base/test_balance.py +56 -0
  712. ccxt/test/base/test_borrow_interest.py +35 -0
  713. ccxt/test/base/test_borrow_rate.py +32 -0
  714. ccxt/test/base/test_calculate_fee.py +51 -0
  715. ccxt/test/base/test_crypto.py +127 -0
  716. ccxt/test/base/test_currency.py +76 -0
  717. ccxt/test/base/test_datetime.py +109 -0
  718. ccxt/test/base/test_decimal_to_precision.py +392 -0
  719. ccxt/test/base/test_deep_extend.py +68 -0
  720. ccxt/test/base/test_deposit_withdrawal.py +50 -0
  721. ccxt/test/base/test_exchange_datetime_functions.py +76 -0
  722. ccxt/test/base/test_funding_rate_history.py +29 -0
  723. ccxt/test/base/test_last_price.py +31 -0
  724. ccxt/test/base/test_ledger_entry.py +45 -0
  725. ccxt/test/base/test_ledger_item.py +48 -0
  726. ccxt/test/base/test_leverage_tier.py +33 -0
  727. ccxt/test/base/test_liquidation.py +50 -0
  728. ccxt/test/base/test_margin_mode.py +24 -0
  729. ccxt/test/base/test_margin_modification.py +35 -0
  730. ccxt/test/base/test_market.py +193 -0
  731. ccxt/test/base/test_number.py +411 -0
  732. ccxt/test/base/test_ohlcv.py +33 -0
  733. ccxt/test/base/test_open_interest.py +32 -0
  734. ccxt/test/base/test_order.py +64 -0
  735. ccxt/test/base/test_order_book.py +69 -0
  736. ccxt/test/base/test_position.py +60 -0
  737. ccxt/test/base/test_shared_methods.py +353 -0
  738. ccxt/test/base/test_status.py +24 -0
  739. ccxt/test/base/test_throttle.py +126 -0
  740. ccxt/test/base/test_ticker.py +92 -0
  741. ccxt/test/base/test_trade.py +47 -0
  742. ccxt/test/base/test_trading_fee.py +26 -0
  743. ccxt/test/base/test_transaction.py +39 -0
  744. ccxt/test/test_async.py +1649 -0
  745. ccxt/test/test_sync.py +1648 -0
  746. ccxt/test/tests_async.py +1558 -0
  747. ccxt/test/tests_helpers.py +287 -0
  748. ccxt/test/tests_init.py +39 -0
  749. ccxt/test/tests_sync.py +1555 -0
  750. ccxt/tetherland.py +349 -0
  751. ccxt/timex.py +1593 -0
  752. ccxt/tokocrypto.py +2405 -0
  753. ccxt/tradeogre.py +608 -0
  754. ccxt/twox.py +326 -0
  755. ccxt/ubitex.py +409 -0
  756. ccxt/upbit.py +1833 -0
  757. ccxt/vertex.py +2922 -0
  758. ccxt/wallex.py +445 -0
  759. ccxt/wavesexchange.py +2472 -0
  760. ccxt/wazirx.py +1224 -0
  761. ccxt/whitebit.py +2469 -0
  762. ccxt/woo.py +3114 -0
  763. ccxt/woofipro.py +2533 -0
  764. ccxt/xt.py +4453 -0
  765. ccxt/yobit.py +1283 -0
  766. ccxt/zaif.py +725 -0
  767. ccxt/zonda.py +1828 -0
  768. ccxt_ir-4.3.46.0.1.dist-info/LICENSE.txt +21 -0
  769. ccxt_ir-4.3.46.0.1.dist-info/METADATA +655 -0
  770. ccxt_ir-4.3.46.0.1.dist-info/RECORD +772 -0
  771. ccxt_ir-4.3.46.0.1.dist-info/WHEEL +6 -0
  772. ccxt_ir-4.3.46.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,2698 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
+ # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
+
6
+ from ccxt.async_support.kucoin import kucoin
7
+ from ccxt.abstract.kucoinfutures import ImplicitAPI
8
+ from ccxt.base.types import Balances, Currency, Int, LeverageTier, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
9
+ from typing import List
10
+ from ccxt.base.errors import AuthenticationError
11
+ from ccxt.base.errors import PermissionDenied
12
+ from ccxt.base.errors import AccountSuspended
13
+ from ccxt.base.errors import ArgumentsRequired
14
+ from ccxt.base.errors import BadRequest
15
+ from ccxt.base.errors import InsufficientFunds
16
+ from ccxt.base.errors import InvalidOrder
17
+ from ccxt.base.errors import OrderNotFound
18
+ from ccxt.base.errors import NotSupported
19
+ from ccxt.base.errors import RateLimitExceeded
20
+ from ccxt.base.errors import ExchangeNotAvailable
21
+ from ccxt.base.errors import InvalidNonce
22
+ from ccxt.base.decimal_to_precision import TICK_SIZE
23
+ from ccxt.base.precise import Precise
24
+
25
+
26
+ class kucoinfutures(kucoin, ImplicitAPI):
27
+
28
+ def describe(self):
29
+ return self.deep_extend(super(kucoinfutures, self).describe(), {
30
+ 'id': 'kucoinfutures',
31
+ 'name': 'KuCoin Futures',
32
+ 'countries': ['SC'],
33
+ 'rateLimit': 75,
34
+ 'version': 'v1',
35
+ 'certified': True,
36
+ 'pro': True,
37
+ 'comment': 'Platform 2.0',
38
+ 'quoteJsonNumbers': False,
39
+ 'has': {
40
+ 'CORS': None,
41
+ 'spot': False,
42
+ 'margin': False,
43
+ 'swap': True,
44
+ 'future': True,
45
+ 'option': False,
46
+ 'addMargin': True,
47
+ 'cancelAllOrders': True,
48
+ 'cancelOrder': True,
49
+ 'closeAllPositions': False,
50
+ 'closePosition': True,
51
+ 'closePositions': False,
52
+ 'createDepositAddress': True,
53
+ 'createOrder': True,
54
+ 'createOrders': True,
55
+ 'createReduceOnlyOrder': True,
56
+ 'createStopLimitOrder': True,
57
+ 'createStopLossOrder': True,
58
+ 'createStopMarketOrder': True,
59
+ 'createStopOrder': True,
60
+ 'createTakeProfitOrder': True,
61
+ 'createTriggerOrder': True,
62
+ 'fetchAccounts': True,
63
+ 'fetchBalance': True,
64
+ 'fetchBorrowRateHistories': False,
65
+ 'fetchBorrowRateHistory': False,
66
+ 'fetchClosedOrders': True,
67
+ 'fetchCrossBorrowRate': False,
68
+ 'fetchCrossBorrowRates': False,
69
+ 'fetchCurrencies': False,
70
+ 'fetchDepositAddress': True,
71
+ 'fetchDeposits': True,
72
+ 'fetchDepositWithdrawFee': False,
73
+ 'fetchDepositWithdrawFees': False,
74
+ 'fetchFundingHistory': True,
75
+ 'fetchFundingRate': True,
76
+ 'fetchFundingRateHistory': True,
77
+ 'fetchIndexOHLCV': False,
78
+ 'fetchIsolatedBorrowRate': False,
79
+ 'fetchIsolatedBorrowRates': False,
80
+ 'fetchL3OrderBook': True,
81
+ 'fetchLedger': True,
82
+ 'fetchLeverageTiers': False,
83
+ 'fetchMarginAdjustmentHistory': False,
84
+ 'fetchMarginMode': False,
85
+ 'fetchMarketLeverageTiers': True,
86
+ 'fetchMarkets': True,
87
+ 'fetchMarkOHLCV': False,
88
+ 'fetchMyTrades': True,
89
+ 'fetchOHLCV': True,
90
+ 'fetchOpenOrders': True,
91
+ 'fetchOrder': True,
92
+ 'fetchOrderBook': True,
93
+ 'fetchPosition': True,
94
+ 'fetchPositionHistory': False,
95
+ 'fetchPositionMode': False,
96
+ 'fetchPositions': True,
97
+ 'fetchPositionsHistory': True,
98
+ 'fetchPremiumIndexOHLCV': False,
99
+ 'fetchStatus': True,
100
+ 'fetchTicker': True,
101
+ 'fetchTickers': True,
102
+ 'fetchTime': True,
103
+ 'fetchTrades': True,
104
+ 'fetchTradingFee': True,
105
+ 'fetchTransactionFee': False,
106
+ 'fetchWithdrawals': True,
107
+ 'setLeverage': False,
108
+ 'setMarginMode': False,
109
+ 'transfer': True,
110
+ 'withdraw': None,
111
+ },
112
+ 'urls': {
113
+ 'logo': 'https://user-images.githubusercontent.com/1294454/147508995-9e35030a-d046-43a1-a006-6fabd981b554.jpg',
114
+ 'doc': [
115
+ 'https://docs.kucoin.com/futures',
116
+ 'https://docs.kucoin.com',
117
+ ],
118
+ 'www': 'https://futures.kucoin.com/',
119
+ 'referral': 'https://futures.kucoin.com/?rcode=E5wkqe',
120
+ 'api': {
121
+ 'public': 'https://openapi-v2.kucoin.com',
122
+ 'private': 'https://openapi-v2.kucoin.com',
123
+ 'futuresPrivate': 'https://api-futures.kucoin.com',
124
+ 'futuresPublic': 'https://api-futures.kucoin.com',
125
+ 'webExchange': 'https://futures.kucoin.com/_api/web-front',
126
+ },
127
+ },
128
+ 'requiredCredentials': {
129
+ 'apiKey': True,
130
+ 'secret': True,
131
+ 'password': True,
132
+ },
133
+ 'api': {
134
+ 'futuresPublic': {
135
+ 'get': {
136
+ 'contracts/active': 1,
137
+ 'contracts/{symbol}': 1,
138
+ 'contracts/risk-limit/{symbol}': 1,
139
+ 'ticker': 1,
140
+ 'level2/snapshot': 1.33,
141
+ 'level2/depth{limit}': 1,
142
+ 'level2/message/query': 1,
143
+ 'level3/message/query': 1, # deprecated,level3/snapshot is suggested
144
+ 'level3/snapshot': 1, # v2
145
+ 'trade/history': 1,
146
+ 'interest/query': 1,
147
+ 'index/query': 1,
148
+ 'mark-price/{symbol}/current': 1,
149
+ 'premium/query': 1,
150
+ 'funding-rate/{symbol}/current': 1,
151
+ 'timestamp': 1,
152
+ 'status': 1,
153
+ 'kline/query': 1,
154
+ },
155
+ 'post': {
156
+ 'bullet-public': 1,
157
+ },
158
+ },
159
+ 'futuresPrivate': {
160
+ 'get': {
161
+ 'account-overview': 1.33,
162
+ 'transaction-history': 4.44,
163
+ 'deposit-address': 1,
164
+ 'deposit-list': 1,
165
+ 'withdrawals/quotas': 1,
166
+ 'withdrawal-list': 1,
167
+ 'transfer-list': 1,
168
+ 'orders': 1.33,
169
+ 'stopOrders': 1,
170
+ 'recentDoneOrders': 1,
171
+ 'orders/{orderId}': 1, # ?clientOid={client-order-id} # get order by orderId
172
+ 'orders/byClientOid': 1, # ?clientOid=eresc138b21023a909e5ad59 # get order by clientOid
173
+ 'fills': 4.44,
174
+ 'recentFills': 4.44,
175
+ 'openOrderStatistics': 1,
176
+ 'position': 1,
177
+ 'positions': 4.44,
178
+ 'funding-history': 4.44,
179
+ 'sub/api-key': 1,
180
+ 'trade-statistics': 1,
181
+ 'trade-fees': 1,
182
+ 'history-positions': 1,
183
+ },
184
+ 'post': {
185
+ 'withdrawals': 1,
186
+ 'transfer-out': 1, # v2
187
+ 'transfer-in': 1,
188
+ 'orders': 1.33,
189
+ 'orders/test': 1.33,
190
+ 'position/margin/auto-deposit-status': 1,
191
+ 'position/margin/deposit-margin': 1,
192
+ 'position/risk-limit-level/change': 1,
193
+ 'bullet-private': 1,
194
+ 'sub/api-key': 1,
195
+ 'sub/api-key/update': 1,
196
+ },
197
+ 'delete': {
198
+ 'withdrawals/{withdrawalId}': 1,
199
+ 'cancel/transfer-out': 1,
200
+ 'orders/{orderId}': 1,
201
+ 'orders': 4.44,
202
+ 'stopOrders': 1,
203
+ 'sub/api-key': 1,
204
+ 'orders/client-order/{clientOid}': 1,
205
+ },
206
+ },
207
+ 'webExchange': {
208
+ 'get': {
209
+ 'contract/{symbol}/funding-rates': 1,
210
+ },
211
+ },
212
+ },
213
+ 'precisionMode': TICK_SIZE,
214
+ 'exceptions': {
215
+ 'exact': {
216
+ '400': BadRequest, # Bad Request -- Invalid request format
217
+ '401': AuthenticationError, # Unauthorized -- Invalid API Key
218
+ '403': NotSupported, # Forbidden -- The request is forbidden
219
+ '404': NotSupported, # Not Found -- The specified resource could not be found
220
+ '405': NotSupported, # Method Not Allowed -- You tried to access the resource with an invalid method.
221
+ '415': BadRequest, # Content-Type -- application/json
222
+ '429': RateLimitExceeded, # Too Many Requests -- Access limit breached
223
+ '500': ExchangeNotAvailable, # Internal Server Error -- We had a problem with our server. Try again later.
224
+ '503': ExchangeNotAvailable, # Service Unavailable -- We're temporarily offline for maintenance. Please try again later.
225
+ '100001': InvalidOrder, # {"code":"100001","msg":"Unavailable to enable both \"postOnly\" and \"hidden\""}
226
+ '100004': BadRequest, # {"code":"100004","msg":"Order is in not cancelable state"}
227
+ '101030': PermissionDenied, # {"code":"101030","msg":"You haven't yet enabled the margin trading"}
228
+ '200004': InsufficientFunds,
229
+ '230003': InsufficientFunds, # {"code":"230003","msg":"Balance insufficient!"}
230
+ '260100': InsufficientFunds, # {"code":"260100","msg":"account.noBalance"}
231
+ '300003': InsufficientFunds,
232
+ '300012': InvalidOrder,
233
+ '400001': AuthenticationError, # Any of KC-API-KEY, KC-API-SIGN, KC-API-TIMESTAMP, KC-API-PASSPHRASE is missing in your request header.
234
+ '400002': InvalidNonce, # KC-API-TIMESTAMP Invalid -- Time differs from server time by more than 5 seconds
235
+ '400003': AuthenticationError, # KC-API-KEY not exists
236
+ '400004': AuthenticationError, # KC-API-PASSPHRASE error
237
+ '400005': AuthenticationError, # Signature error -- Please check your signature
238
+ '400006': AuthenticationError, # The IP address is not in the API whitelist
239
+ '400007': AuthenticationError, # Access Denied -- Your API key does not have sufficient permissions to access the URI
240
+ '404000': NotSupported, # URL Not Found -- The requested resource could not be found
241
+ '400100': BadRequest, # Parameter Error -- You tried to access the resource with invalid parameters
242
+ '411100': AccountSuspended, # User is frozen -- Please contact us via support center
243
+ '500000': ExchangeNotAvailable, # Internal Server Error -- We had a problem with our server. Try again later.
244
+ },
245
+ 'broad': {
246
+ 'Position does not exist': OrderNotFound, # {"code":"200000", "msg":"Position does not exist"}
247
+ },
248
+ },
249
+ 'fees': {
250
+ 'trading': {
251
+ 'tierBased': True,
252
+ 'percentage': True,
253
+ 'taker': self.parse_number('0.0006'),
254
+ 'maker': self.parse_number('0.0002'),
255
+ 'tiers': {
256
+ 'taker': [
257
+ [self.parse_number('0'), self.parse_number('0.0006')],
258
+ [self.parse_number('50'), self.parse_number('0.0006')],
259
+ [self.parse_number('200'), self.parse_number('0.0006')],
260
+ [self.parse_number('500'), self.parse_number('0.0005')],
261
+ [self.parse_number('1000'), self.parse_number('0.0004')],
262
+ [self.parse_number('2000'), self.parse_number('0.0004')],
263
+ [self.parse_number('4000'), self.parse_number('0.00038')],
264
+ [self.parse_number('8000'), self.parse_number('0.00035')],
265
+ [self.parse_number('15000'), self.parse_number('0.00032')],
266
+ [self.parse_number('25000'), self.parse_number('0.0003')],
267
+ [self.parse_number('40000'), self.parse_number('0.0003')],
268
+ [self.parse_number('60000'), self.parse_number('0.0003')],
269
+ [self.parse_number('80000'), self.parse_number('0.0003')],
270
+ ],
271
+ 'maker': [
272
+ [self.parse_number('0'), self.parse_number('0.02')],
273
+ [self.parse_number('50'), self.parse_number('0.015')],
274
+ [self.parse_number('200'), self.parse_number('0.01')],
275
+ [self.parse_number('500'), self.parse_number('0.01')],
276
+ [self.parse_number('1000'), self.parse_number('0.01')],
277
+ [self.parse_number('2000'), self.parse_number('0')],
278
+ [self.parse_number('4000'), self.parse_number('0')],
279
+ [self.parse_number('8000'), self.parse_number('0')],
280
+ [self.parse_number('15000'), self.parse_number('-0.003')],
281
+ [self.parse_number('25000'), self.parse_number('-0.006')],
282
+ [self.parse_number('40000'), self.parse_number('-0.009')],
283
+ [self.parse_number('60000'), self.parse_number('-0.012')],
284
+ [self.parse_number('80000'), self.parse_number('-0.015')],
285
+ ],
286
+ },
287
+ },
288
+ 'funding': {
289
+ 'tierBased': False,
290
+ 'percentage': False,
291
+ 'withdraw': {},
292
+ 'deposit': {},
293
+ },
294
+ },
295
+ 'commonCurrencies': {
296
+ 'HOT': 'HOTNOW',
297
+ 'EDGE': 'DADI', # https://github.com/ccxt/ccxt/issues/5756
298
+ 'WAX': 'WAXP',
299
+ 'TRY': 'Trias',
300
+ 'VAI': 'VAIOT',
301
+ 'XBT': 'BTC',
302
+ },
303
+ 'timeframes': {
304
+ '1m': 1,
305
+ '3m': None,
306
+ '5m': 5,
307
+ '15m': 15,
308
+ '30m': 30,
309
+ '1h': 60,
310
+ '2h': 120,
311
+ '4h': 240,
312
+ '6h': None,
313
+ '8h': 480,
314
+ '12h': 720,
315
+ '1d': 1440,
316
+ '1w': 10080,
317
+ },
318
+ 'options': {
319
+ 'version': 'v1',
320
+ 'symbolSeparator': '-',
321
+ 'defaultType': 'swap',
322
+ 'code': 'USDT',
323
+ 'marginModes': {},
324
+ 'marginTypes': {},
325
+ # endpoint versions
326
+ 'versions': {
327
+ 'futuresPrivate': {
328
+ 'POST': {
329
+ 'transfer-out': 'v2',
330
+ },
331
+ },
332
+ 'futuresPublic': {
333
+ 'GET': {
334
+ 'level3/snapshot': 'v2',
335
+ },
336
+ },
337
+ },
338
+ 'networks': {
339
+ 'OMNI': 'omni',
340
+ 'ERC20': 'eth',
341
+ 'TRC20': 'trx',
342
+ },
343
+ # 'code': 'BTC',
344
+ # 'fetchBalance': {
345
+ # 'code': 'BTC',
346
+ # },
347
+ },
348
+ })
349
+
350
+ async def fetch_status(self, params={}):
351
+ """
352
+ the latest known information on the availability of the exchange API
353
+ :see: https://www.kucoin.com/docs/rest/futures-trading/market-data/get-service-status
354
+ :param dict [params]: extra parameters specific to the exchange API endpoint
355
+ :returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
356
+ """
357
+ response = await self.futuresPublicGetStatus(params)
358
+ #
359
+ # {
360
+ # "code":"200000",
361
+ # "data":{
362
+ # "status": "open", # open, close, cancelonly
363
+ # "msg": "upgrade match engine" # remark for operation when status not open
364
+ # }
365
+ # }
366
+ #
367
+ data = self.safe_value(response, 'data', {})
368
+ status = self.safe_string(data, 'status')
369
+ return {
370
+ 'status': 'ok' if (status == 'open') else 'maintenance',
371
+ 'updated': None,
372
+ 'eta': None,
373
+ 'url': None,
374
+ 'info': response,
375
+ }
376
+
377
+ async def fetch_markets(self, params={}) -> List[Market]:
378
+ """
379
+ retrieves data on all markets for kucoinfutures
380
+ :see: https://www.kucoin.com/docs/rest/futures-trading/market-data/get-symbols-list
381
+ :param dict [params]: extra parameters specific to the exchange api endpoint
382
+ :returns dict[]: an array of objects representing market data
383
+ """
384
+ response = await self.futuresPublicGetContractsActive(params)
385
+ #
386
+ # {
387
+ # "code": "200000",
388
+ # "data": {
389
+ # "symbol": "ETHUSDTM",
390
+ # "rootSymbol": "USDT",
391
+ # "type": "FFWCSX",
392
+ # "firstOpenDate": 1591086000000,
393
+ # "expireDate": null,
394
+ # "settleDate": null,
395
+ # "baseCurrency": "ETH",
396
+ # "quoteCurrency": "USDT",
397
+ # "settleCurrency": "USDT",
398
+ # "maxOrderQty": 1000000,
399
+ # "maxPrice": 1000000.0000000000,
400
+ # "lotSize": 1,
401
+ # "tickSize": 0.05,
402
+ # "indexPriceTickSize": 0.01,
403
+ # "multiplier": 0.01,
404
+ # "initialMargin": 0.01,
405
+ # "maintainMargin": 0.005,
406
+ # "maxRiskLimit": 1000000,
407
+ # "minRiskLimit": 1000000,
408
+ # "riskStep": 500000,
409
+ # "makerFeeRate": 0.00020,
410
+ # "takerFeeRate": 0.00060,
411
+ # "takerFixFee": 0.0000000000,
412
+ # "makerFixFee": 0.0000000000,
413
+ # "settlementFee": null,
414
+ # "isDeleverage": True,
415
+ # "isQuanto": True,
416
+ # "isInverse": False,
417
+ # "markMethod": "FairPrice",
418
+ # "fairMethod": "FundingRate",
419
+ # "fundingBaseSymbol": ".ETHINT8H",
420
+ # "fundingQuoteSymbol": ".USDTINT8H",
421
+ # "fundingRateSymbol": ".ETHUSDTMFPI8H",
422
+ # "indexSymbol": ".KETHUSDT",
423
+ # "settlementSymbol": "",
424
+ # "status": "Open",
425
+ # "fundingFeeRate": 0.000535,
426
+ # "predictedFundingFeeRate": 0.002197,
427
+ # "openInterest": "8724443",
428
+ # "turnoverOf24h": 341156641.03354263,
429
+ # "volumeOf24h": 74833.54000000,
430
+ # "markPrice": 4534.07,
431
+ # "indexPrice":4531.92,
432
+ # "lastTradePrice": 4545.4500000000,
433
+ # "nextFundingRateTime": 25481884,
434
+ # "maxLeverage": 100,
435
+ # "sourceExchanges": ["huobi", "Okex", "Binance", "Kucoin", "Poloniex", "Hitbtc"],
436
+ # "premiumsSymbol1M": ".ETHUSDTMPI",
437
+ # "premiumsSymbol8H": ".ETHUSDTMPI8H",
438
+ # "fundingBaseSymbol1M": ".ETHINT",
439
+ # "fundingQuoteSymbol1M": ".USDTINT",
440
+ # "lowPrice": 4456.90,
441
+ # "highPrice": 4674.25,
442
+ # "priceChgPct": 0.0046,
443
+ # "priceChg": 21.15
444
+ # }
445
+ # }
446
+ #
447
+ result = []
448
+ data = self.safe_value(response, 'data', [])
449
+ for i in range(0, len(data)):
450
+ market = data[i]
451
+ id = self.safe_string(market, 'symbol')
452
+ expiry = self.safe_integer(market, 'expireDate')
453
+ future = True if expiry else False
454
+ swap = not future
455
+ baseId = self.safe_string(market, 'baseCurrency')
456
+ quoteId = self.safe_string(market, 'quoteCurrency')
457
+ settleId = self.safe_string(market, 'settleCurrency')
458
+ base = self.safe_currency_code(baseId)
459
+ quote = self.safe_currency_code(quoteId)
460
+ settle = self.safe_currency_code(settleId)
461
+ symbol = base + '/' + quote + ':' + settle
462
+ type = 'swap'
463
+ if future:
464
+ symbol = symbol + '-' + self.yymmdd(expiry, '')
465
+ type = 'future'
466
+ inverse = self.safe_value(market, 'isInverse')
467
+ status = self.safe_string(market, 'status')
468
+ multiplier = self.safe_string(market, 'multiplier')
469
+ tickSize = self.safe_number(market, 'tickSize')
470
+ lotSize = self.safe_number(market, 'lotSize')
471
+ limitAmountMin = lotSize
472
+ if limitAmountMin is None:
473
+ limitAmountMin = self.safe_number(market, 'baseMinSize')
474
+ limitAmountMax = self.safe_number(market, 'maxOrderQty')
475
+ if limitAmountMax is None:
476
+ limitAmountMax = self.safe_number(market, 'baseMaxSize')
477
+ limitPriceMax = self.safe_number(market, 'maxPrice')
478
+ if limitPriceMax is None:
479
+ baseMinSizeString = self.safe_string(market, 'baseMinSize')
480
+ quoteMaxSizeString = self.safe_string(market, 'quoteMaxSize')
481
+ limitPriceMax = self.parse_number(Precise.string_div(quoteMaxSizeString, baseMinSizeString))
482
+ result.append({
483
+ 'id': id,
484
+ 'symbol': symbol,
485
+ 'base': base,
486
+ 'quote': quote,
487
+ 'settle': settle,
488
+ 'baseId': baseId,
489
+ 'quoteId': quoteId,
490
+ 'settleId': settleId,
491
+ 'type': type,
492
+ 'spot': False,
493
+ 'margin': False,
494
+ 'swap': swap,
495
+ 'future': future,
496
+ 'option': False,
497
+ 'active': (status == 'Open'),
498
+ 'contract': True,
499
+ 'linear': not inverse,
500
+ 'inverse': inverse,
501
+ 'taker': self.safe_number(market, 'takerFeeRate'),
502
+ 'maker': self.safe_number(market, 'makerFeeRate'),
503
+ 'contractSize': self.parse_number(Precise.string_abs(multiplier)),
504
+ 'expiry': expiry,
505
+ 'expiryDatetime': self.iso8601(expiry),
506
+ 'strike': None,
507
+ 'optionType': None,
508
+ 'precision': {
509
+ 'amount': lotSize,
510
+ 'price': tickSize,
511
+ },
512
+ 'limits': {
513
+ 'leverage': {
514
+ 'min': self.parse_number('1'),
515
+ 'max': self.safe_number(market, 'maxLeverage'),
516
+ },
517
+ 'amount': {
518
+ 'min': limitAmountMin,
519
+ 'max': limitAmountMax,
520
+ },
521
+ 'price': {
522
+ 'min': tickSize,
523
+ 'max': limitPriceMax,
524
+ },
525
+ 'cost': {
526
+ 'min': self.safe_number(market, 'quoteMinSize'),
527
+ 'max': self.safe_number(market, 'quoteMaxSize'),
528
+ },
529
+ },
530
+ 'created': self.safe_integer(market, 'firstOpenDate'),
531
+ 'info': market,
532
+ })
533
+ return result
534
+
535
+ async def fetch_time(self, params={}):
536
+ """
537
+ fetches the current integer timestamp in milliseconds from the exchange server
538
+ :see: https://www.kucoin.com/docs/rest/futures-trading/market-data/get-server-time
539
+ :param dict [params]: extra parameters specific to the exchange API endpoint
540
+ :returns int: the current integer timestamp in milliseconds from the exchange server
541
+ """
542
+ response = await self.futuresPublicGetTimestamp(params)
543
+ #
544
+ # {
545
+ # "code": "200000",
546
+ # "data": 1637385119302,
547
+ # }
548
+ #
549
+ return self.safe_integer(response, 'data')
550
+
551
+ async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
552
+ """
553
+ fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
554
+ :see: https://www.kucoin.com/docs/rest/futures-trading/market-data/get-klines
555
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
556
+ :param str timeframe: the length of time each candle represents
557
+ :param int [since]: timestamp in ms of the earliest candle to fetch
558
+ :param int [limit]: the maximum amount of candles to fetch
559
+ :param dict [params]: extra parameters specific to the exchange API endpoint
560
+ :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)
561
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
562
+ """
563
+ await self.load_markets()
564
+ paginate = False
565
+ paginate, params = self.handle_option_and_params(params, 'fetchOHLCV', 'paginate')
566
+ if paginate:
567
+ return await self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 200)
568
+ market = self.market(symbol)
569
+ marketId = market['id']
570
+ parsedTimeframe = self.safe_integer(self.timeframes, timeframe)
571
+ request: dict = {
572
+ 'symbol': marketId,
573
+ }
574
+ if parsedTimeframe is not None:
575
+ request['granularity'] = parsedTimeframe
576
+ else:
577
+ request['granularity'] = timeframe
578
+ duration = self.parse_timeframe(timeframe) * 1000
579
+ endAt = self.milliseconds()
580
+ if since is not None:
581
+ request['from'] = since
582
+ if limit is None:
583
+ limit = self.safe_integer(self.options, 'fetchOHLCVLimit', 200)
584
+ endAt = self.sum(since, limit * duration)
585
+ elif limit is not None:
586
+ since = endAt - limit * duration
587
+ request['from'] = since
588
+ request['to'] = endAt
589
+ response = await self.futuresPublicGetKlineQuery(self.extend(request, params))
590
+ #
591
+ # {
592
+ # "code": "200000",
593
+ # "data": [
594
+ # [1636459200000, 4779.3, 4792.1, 4768.7, 4770.3, 78051],
595
+ # [1636460100000, 4770.25, 4778.55, 4757.55, 4777.25, 80164],
596
+ # [1636461000000, 4777.25, 4791.45, 4774.5, 4791.3, 51555]
597
+ # ]
598
+ # }
599
+ #
600
+ data = self.safe_list(response, 'data', [])
601
+ return self.parse_ohlcvs(data, market, timeframe, since, limit)
602
+
603
+ def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
604
+ #
605
+ # [
606
+ # "1545904980000", # Start time of the candle cycle
607
+ # "0.058", # opening price
608
+ # "0.049", # closing price
609
+ # "0.058", # highest price
610
+ # "0.049", # lowest price
611
+ # "0.018", # base volume
612
+ # "0.000945", # quote volume
613
+ # ]
614
+ #
615
+ return [
616
+ self.safe_integer(ohlcv, 0),
617
+ self.safe_number(ohlcv, 1),
618
+ self.safe_number(ohlcv, 2),
619
+ self.safe_number(ohlcv, 3),
620
+ self.safe_number(ohlcv, 4),
621
+ self.safe_number(ohlcv, 5),
622
+ ]
623
+
624
+ async def fetch_deposit_address(self, code: str, params={}):
625
+ """
626
+ fetch the deposit address for a currency associated with self account
627
+ :see: https://www.kucoin.com/docs/rest/funding/deposit/get-deposit-address
628
+ :param str code: unified currency code
629
+ :param dict [params]: extra parameters specific to the exchange API endpoint
630
+ :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
631
+ """
632
+ await self.load_markets()
633
+ currency = self.currency(code)
634
+ currencyId = currency['id']
635
+ request: dict = {
636
+ 'currency': currencyId, # Currency,including XBT,USDT
637
+ }
638
+ response = await self.futuresPrivateGetDepositAddress(self.extend(request, params))
639
+ #
640
+ # {
641
+ # "code": "200000",
642
+ # "data": {
643
+ # "address": "0x78d3ad1c0aa1bf068e19c94a2d7b16c9c0fcd8b1",//Deposit address
644
+ # "memo": null//Address tag. If the returned value is null, it means that the requested token has no memo. If you are to transfer funds from another platform to KuCoin Futures and if the token to be #transferred has memo(tag), you need to fill in the memo to ensure the transferred funds will be sent #to the address you specified.
645
+ # }
646
+ # }
647
+ #
648
+ data = self.safe_value(response, 'data', {})
649
+ address = self.safe_string(data, 'address')
650
+ if currencyId != 'NIM':
651
+ # contains spaces
652
+ self.check_address(address)
653
+ return {
654
+ 'info': response,
655
+ 'currency': currencyId,
656
+ 'address': address,
657
+ 'tag': self.safe_string(data, 'memo'),
658
+ 'network': self.safe_string(data, 'chain'),
659
+ }
660
+
661
+ async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
662
+ """
663
+ fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
664
+ :see: https://www.kucoin.com/docs/rest/futures-trading/market-data/get-part-order-book-level-2
665
+ :param str symbol: unified symbol of the market to fetch the order book for
666
+ :param int [limit]: the maximum amount of order book entries to return
667
+ :param dict [params]: extra parameters specific to the exchange API endpoint
668
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
669
+ """
670
+ await self.load_markets()
671
+ level = self.safe_number(params, 'level')
672
+ if level != 2 and level is not None:
673
+ raise BadRequest(self.id + ' fetchOrderBook() can only return level 2')
674
+ market = self.market(symbol)
675
+ request: dict = {
676
+ 'symbol': market['id'],
677
+ }
678
+ if limit is not None:
679
+ if (limit == 20) or (limit == 100):
680
+ request['limit'] = limit
681
+ else:
682
+ raise BadRequest(self.id + ' fetchOrderBook() limit argument must be 20 or 100')
683
+ else:
684
+ request['limit'] = 20
685
+ response = await self.futuresPublicGetLevel2DepthLimit(self.extend(request, params))
686
+ #
687
+ # {
688
+ # "code": "200000",
689
+ # "data": {
690
+ # "symbol": "XBTUSDM", #Symbol
691
+ # "sequence": 100, #Ticker sequence number
692
+ # "asks": [
693
+ # ["5000.0", 1000], #Price, quantity
694
+ # ["6000.0", 1983] #Price, quantity
695
+ # ],
696
+ # "bids": [
697
+ # ["3200.0", 800], #Price, quantity
698
+ # ["3100.0", 100] #Price, quantity
699
+ # ],
700
+ # "ts": 1604643655040584408 # timestamp
701
+ # }
702
+ # }
703
+ #
704
+ data = self.safe_value(response, 'data', {})
705
+ timestamp = self.parse_to_int(self.safe_integer(data, 'ts') / 1000000)
706
+ orderbook = self.parse_order_book(data, market['symbol'], timestamp, 'bids', 'asks', 0, 1)
707
+ orderbook['nonce'] = self.safe_integer(data, 'sequence')
708
+ return orderbook
709
+
710
+ async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
711
+ """
712
+ fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
713
+ :see: https://www.kucoin.com/docs/rest/futures-trading/market-data/get-ticker
714
+ :param str symbol: unified symbol of the market to fetch the ticker for
715
+ :param dict [params]: extra parameters specific to the exchange API endpoint
716
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
717
+ """
718
+ await self.load_markets()
719
+ market = self.market(symbol)
720
+ request: dict = {
721
+ 'symbol': market['id'],
722
+ }
723
+ response = await self.futuresPublicGetTicker(self.extend(request, params))
724
+ #
725
+ # {
726
+ # "code": "200000",
727
+ # "data": {
728
+ # "sequence": 1638444978558,
729
+ # "symbol": "ETHUSDTM",
730
+ # "side": "sell",
731
+ # "size": 4,
732
+ # "price": "4229.35",
733
+ # "bestBidSize": 2160,
734
+ # "bestBidPrice": "4229.0",
735
+ # "bestAskPrice": "4229.05",
736
+ # "tradeId": "61aaa8b777a0c43055fe4851",
737
+ # "ts": 1638574296209786785,
738
+ # "bestAskSize": 36,
739
+ # }
740
+ # }
741
+ #
742
+ return self.parse_ticker(response['data'], market)
743
+
744
+ async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
745
+ """
746
+ fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
747
+ :see: https://www.kucoin.com/docs/rest/futures-trading/market-data/get-symbols-list
748
+ :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
749
+ :param dict [params]: extra parameters specific to the exchange API endpoint
750
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
751
+ """
752
+ await self.load_markets()
753
+ symbols = self.market_symbols(symbols)
754
+ response = await self.futuresPublicGetContractsActive(params)
755
+ #
756
+ # {
757
+ # "code": "200000",
758
+ # "data": {
759
+ # "symbol": "ETHUSDTM",
760
+ # "rootSymbol": "USDT",
761
+ # "type": "FFWCSX",
762
+ # "firstOpenDate": 1591086000000,
763
+ # "expireDate": null,
764
+ # "settleDate": null,
765
+ # "baseCurrency": "ETH",
766
+ # "quoteCurrency": "USDT",
767
+ # "settleCurrency": "USDT",
768
+ # "maxOrderQty": 1000000,
769
+ # "maxPrice": 1000000.0000000000,
770
+ # "lotSize": 1,
771
+ # "tickSize": 0.05,
772
+ # "indexPriceTickSize": 0.01,
773
+ # "multiplier": 0.01,
774
+ # "initialMargin": 0.01,
775
+ # "maintainMargin": 0.005,
776
+ # "maxRiskLimit": 1000000,
777
+ # "minRiskLimit": 1000000,
778
+ # "riskStep": 500000,
779
+ # "makerFeeRate": 0.00020,
780
+ # "takerFeeRate": 0.00060,
781
+ # "takerFixFee": 0.0000000000,
782
+ # "makerFixFee": 0.0000000000,
783
+ # "settlementFee": null,
784
+ # "isDeleverage": True,
785
+ # "isQuanto": True,
786
+ # "isInverse": False,
787
+ # "markMethod": "FairPrice",
788
+ # "fairMethod": "FundingRate",
789
+ # "fundingBaseSymbol": ".ETHINT8H",
790
+ # "fundingQuoteSymbol": ".USDTINT8H",
791
+ # "fundingRateSymbol": ".ETHUSDTMFPI8H",
792
+ # "indexSymbol": ".KETHUSDT",
793
+ # "settlementSymbol": "",
794
+ # "status": "Open",
795
+ # "fundingFeeRate": 0.000535,
796
+ # "predictedFundingFeeRate": 0.002197,
797
+ # "openInterest": "8724443",
798
+ # "turnoverOf24h": 341156641.03354263,
799
+ # "volumeOf24h": 74833.54000000,
800
+ # "markPrice": 4534.07,
801
+ # "indexPrice":4531.92,
802
+ # "lastTradePrice": 4545.4500000000,
803
+ # "nextFundingRateTime": 25481884,
804
+ # "maxLeverage": 100,
805
+ # "sourceExchanges": ["huobi", "Okex", "Binance", "Kucoin", "Poloniex", "Hitbtc"],
806
+ # "premiumsSymbol1M": ".ETHUSDTMPI",
807
+ # "premiumsSymbol8H": ".ETHUSDTMPI8H",
808
+ # "fundingBaseSymbol1M": ".ETHINT",
809
+ # "fundingQuoteSymbol1M": ".USDTINT",
810
+ # "lowPrice": 4456.90,
811
+ # "highPrice": 4674.25,
812
+ # "priceChgPct": 0.0046,
813
+ # "priceChg": 21.15
814
+ # }
815
+ # }
816
+ #
817
+ data = self.safe_list(response, 'data', [])
818
+ tickers = self.parse_tickers(data, symbols)
819
+ return self.filter_by_array_tickers(tickers, 'symbol', symbols)
820
+
821
+ def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
822
+ #
823
+ # {
824
+ # "code": "200000",
825
+ # "data": {
826
+ # "sequence": 1629930362547,
827
+ # "symbol": "ETHUSDTM",
828
+ # "side": "buy",
829
+ # "size": 130,
830
+ # "price": "4724.7",
831
+ # "bestBidSize": 5,
832
+ # "bestBidPrice": "4724.6",
833
+ # "bestAskPrice": "4724.65",
834
+ # "tradeId": "618d2a5a77a0c4431d2335f4",
835
+ # "ts": 1636641371963227600,
836
+ # "bestAskSize": 1789
837
+ # }
838
+ # }
839
+ #
840
+ # from fetchTickers
841
+ #
842
+ # {
843
+ # symbol: "XBTUSDTM",
844
+ # rootSymbol: "USDT",
845
+ # type: "FFWCSX",
846
+ # firstOpenDate: 1585555200000,
847
+ # expireDate: null,
848
+ # settleDate: null,
849
+ # baseCurrency: "XBT",
850
+ # quoteCurrency: "USDT",
851
+ # settleCurrency: "USDT",
852
+ # maxOrderQty: 1000000,
853
+ # maxPrice: 1000000,
854
+ # lotSize: 1,
855
+ # tickSize: 0.1,
856
+ # indexPriceTickSize: 0.01,
857
+ # multiplier: 0.001,
858
+ # initialMargin: 0.008,
859
+ # maintainMargin: 0.004,
860
+ # maxRiskLimit: 100000,
861
+ # minRiskLimit: 100000,
862
+ # riskStep: 50000,
863
+ # makerFeeRate: 0.0002,
864
+ # takerFeeRate: 0.0006,
865
+ # takerFixFee: 0,
866
+ # makerFixFee: 0,
867
+ # settlementFee: null,
868
+ # isDeleverage: True,
869
+ # isQuanto: True,
870
+ # isInverse: False,
871
+ # markMethod: "FairPrice",
872
+ # fairMethod: "FundingRate",
873
+ # fundingBaseSymbol: ".XBTINT8H",
874
+ # fundingQuoteSymbol: ".USDTINT8H",
875
+ # fundingRateSymbol: ".XBTUSDTMFPI8H",
876
+ # indexSymbol: ".KXBTUSDT",
877
+ # settlementSymbol: "",
878
+ # status: "Open",
879
+ # fundingFeeRate: 0.000297,
880
+ # predictedFundingFeeRate: 0.000327,
881
+ # fundingRateGranularity: 28800000,
882
+ # openInterest: "8033200",
883
+ # turnoverOf24h: 659795309.2524643,
884
+ # volumeOf24h: 9998.54,
885
+ # markPrice: 67193.51,
886
+ # indexPrice: 67184.81,
887
+ # lastTradePrice: 67191.8,
888
+ # nextFundingRateTime: 20022985,
889
+ # maxLeverage: 125,
890
+ # premiumsSymbol1M: ".XBTUSDTMPI",
891
+ # premiumsSymbol8H: ".XBTUSDTMPI8H",
892
+ # fundingBaseSymbol1M: ".XBTINT",
893
+ # fundingQuoteSymbol1M: ".USDTINT",
894
+ # lowPrice: 64041.6,
895
+ # highPrice: 67737.3,
896
+ # priceChgPct: 0.0447,
897
+ # priceChg: 2878.7
898
+ # }
899
+ #
900
+ marketId = self.safe_string(ticker, 'symbol')
901
+ market = self.safe_market(marketId, market, '-')
902
+ last = self.safe_string_2(ticker, 'price', 'lastTradePrice')
903
+ timestamp = self.safe_integer_product(ticker, 'ts', 0.000001)
904
+ return self.safe_ticker({
905
+ 'symbol': market['symbol'],
906
+ 'timestamp': timestamp,
907
+ 'datetime': self.iso8601(timestamp),
908
+ 'high': self.safe_string(ticker, 'highPrice'),
909
+ 'low': self.safe_string(ticker, 'lowPrice'),
910
+ 'bid': self.safe_string(ticker, 'bestBidPrice'),
911
+ 'bidVolume': self.safe_string(ticker, 'bestBidSize'),
912
+ 'ask': self.safe_string(ticker, 'bestAskPrice'),
913
+ 'askVolume': self.safe_string(ticker, 'bestAskSize'),
914
+ 'vwap': None,
915
+ 'open': None,
916
+ 'close': last,
917
+ 'last': last,
918
+ 'previousClose': None,
919
+ 'change': self.safe_string(ticker, 'priceChg'),
920
+ 'percentage': self.safe_string(ticker, 'priceChgPct'),
921
+ 'average': None,
922
+ 'baseVolume': self.safe_string(ticker, 'volumeOf24h'),
923
+ 'quoteVolume': self.safe_string(ticker, 'turnoverOf24h'),
924
+ 'info': ticker,
925
+ }, market)
926
+
927
+ async def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
928
+ """
929
+ fetch the history of funding payments paid and received on self account
930
+ :see: https://www.kucoin.com/docs/rest/futures-trading/funding-fees/get-funding-history
931
+ :param str symbol: unified market symbol
932
+ :param int [since]: the earliest time in ms to fetch funding history for
933
+ :param int [limit]: the maximum number of funding history structures to retrieve
934
+ :param dict [params]: extra parameters specific to the exchange API endpoint
935
+ :returns dict: a `funding history structure <https://docs.ccxt.com/#/?id=funding-history-structure>`
936
+ """
937
+ if symbol is None:
938
+ raise ArgumentsRequired(self.id + ' fetchFundingHistory() requires a symbol argument')
939
+ await self.load_markets()
940
+ market = self.market(symbol)
941
+ request: dict = {
942
+ 'symbol': market['id'],
943
+ }
944
+ if since is not None:
945
+ request['startAt'] = since
946
+ if limit is not None:
947
+ # * Since is ignored if limit is defined
948
+ request['maxCount'] = limit
949
+ response = await self.futuresPrivateGetFundingHistory(self.extend(request, params))
950
+ #
951
+ # {
952
+ # "code": "200000",
953
+ # "data": {
954
+ # "dataList": [
955
+ # {
956
+ # "id": 239471298749817,
957
+ # "symbol": "ETHUSDTM",
958
+ # "timePoint": 1638532800000,
959
+ # "fundingRate": 0.000100,
960
+ # "markPrice": 4612.8300000000,
961
+ # "positionQty": 12,
962
+ # "positionCost": 553.5396000000,
963
+ # "funding": -0.0553539600,
964
+ # "settleCurrency": "USDT"
965
+ # },
966
+ # ...
967
+ # ],
968
+ # "hasMore": True
969
+ # }
970
+ # }
971
+ #
972
+ data = self.safe_value(response, 'data')
973
+ dataList = self.safe_value(data, 'dataList', [])
974
+ fees = []
975
+ for i in range(0, len(dataList)):
976
+ listItem = dataList[i]
977
+ timestamp = self.safe_integer(listItem, 'timePoint')
978
+ fees.append({
979
+ 'info': listItem,
980
+ 'symbol': symbol,
981
+ 'code': self.safe_currency_code(self.safe_string(listItem, 'settleCurrency')),
982
+ 'timestamp': timestamp,
983
+ 'datetime': self.iso8601(timestamp),
984
+ 'id': self.safe_number(listItem, 'id'),
985
+ 'amount': self.safe_number(listItem, 'funding'),
986
+ 'fundingRate': self.safe_number(listItem, 'fundingRate'),
987
+ 'markPrice': self.safe_number(listItem, 'markPrice'),
988
+ 'positionQty': self.safe_number(listItem, 'positionQty'),
989
+ 'positionCost': self.safe_number(listItem, 'positionCost'),
990
+ })
991
+ return fees
992
+
993
+ async def fetch_position(self, symbol: str, params={}):
994
+ """
995
+ :see: https://docs.kucoin.com/futures/#get-position-details
996
+ fetch data on an open position
997
+ :param str symbol: unified market symbol of the market the position is held in
998
+ :param dict [params]: extra parameters specific to the exchange API endpoint
999
+ :returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
1000
+ """
1001
+ await self.load_markets()
1002
+ market = self.market(symbol)
1003
+ request: dict = {
1004
+ 'symbol': market['id'],
1005
+ }
1006
+ response = await self.futuresPrivateGetPosition(self.extend(request, params))
1007
+ #
1008
+ # {
1009
+ # "code": "200000",
1010
+ # "data": {
1011
+ # "id": "6505ee6eaff4070001f651c4",
1012
+ # "symbol": "XBTUSDTM",
1013
+ # "autoDeposit": False,
1014
+ # "maintMarginReq": 0,
1015
+ # "riskLimit": 200,
1016
+ # "realLeverage": 0.0,
1017
+ # "crossMode": False,
1018
+ # "delevPercentage": 0.0,
1019
+ # "currentTimestamp": 1694887534594,
1020
+ # "currentQty": 0,
1021
+ # "currentCost": 0.0,
1022
+ # "currentComm": 0.0,
1023
+ # "unrealisedCost": 0.0,
1024
+ # "realisedGrossCost": 0.0,
1025
+ # "realisedCost": 0.0,
1026
+ # "isOpen": False,
1027
+ # "markPrice": 26611.71,
1028
+ # "markValue": 0.0,
1029
+ # "posCost": 0.0,
1030
+ # "posCross": 0,
1031
+ # "posInit": 0.0,
1032
+ # "posComm": 0.0,
1033
+ # "posLoss": 0.0,
1034
+ # "posMargin": 0.0,
1035
+ # "posMaint": 0.0,
1036
+ # "maintMargin": 0.0,
1037
+ # "realisedGrossPnl": 0.0,
1038
+ # "realisedPnl": 0.0,
1039
+ # "unrealisedPnl": 0.0,
1040
+ # "unrealisedPnlPcnt": 0,
1041
+ # "unrealisedRoePcnt": 0,
1042
+ # "avgEntryPrice": 0.0,
1043
+ # "liquidationPrice": 0.0,
1044
+ # "bankruptPrice": 0.0,
1045
+ # "settleCurrency": "USDT",
1046
+ # "maintainMargin": 0,
1047
+ # "riskLimitLevel": 1
1048
+ # }
1049
+ # }
1050
+ #
1051
+ data = self.safe_dict(response, 'data', {})
1052
+ return self.parse_position(data, market)
1053
+
1054
+ async def fetch_positions(self, symbols: Strings = None, params={}):
1055
+ """
1056
+ fetch all open positions
1057
+ :see: https://docs.kucoin.com/futures/#get-position-list
1058
+ :param str[]|None symbols: list of unified market symbols
1059
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1060
+ :returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
1061
+ """
1062
+ await self.load_markets()
1063
+ response = await self.futuresPrivateGetPositions(params)
1064
+ #
1065
+ # {
1066
+ # "code": "200000",
1067
+ # "data": [
1068
+ # {
1069
+ # "id": "615ba79f83a3410001cde321",
1070
+ # "symbol": "ETHUSDTM",
1071
+ # "autoDeposit": False,
1072
+ # "maintMarginReq": 0.005,
1073
+ # "riskLimit": 1000000,
1074
+ # "realLeverage": 18.61,
1075
+ # "crossMode": False,
1076
+ # "delevPercentage": 0.86,
1077
+ # "openingTimestamp": 1638563515618,
1078
+ # "currentTimestamp": 1638576872774,
1079
+ # "currentQty": 2,
1080
+ # "currentCost": 83.64200000,
1081
+ # "currentComm": 0.05018520,
1082
+ # "unrealisedCost": 83.64200000,
1083
+ # "realisedGrossCost": 0.00000000,
1084
+ # "realisedCost": 0.05018520,
1085
+ # "isOpen": True,
1086
+ # "markPrice": 4225.01,
1087
+ # "markValue": 84.50020000,
1088
+ # "posCost": 83.64200000,
1089
+ # "posCross": 0.0000000000,
1090
+ # "posInit": 3.63660870,
1091
+ # "posComm": 0.05236717,
1092
+ # "posLoss": 0.00000000,
1093
+ # "posMargin": 3.68897586,
1094
+ # "posMaint": 0.50637594,
1095
+ # "maintMargin": 4.54717586,
1096
+ # "realisedGrossPnl": 0.00000000,
1097
+ # "realisedPnl": -0.05018520,
1098
+ # "unrealisedPnl": 0.85820000,
1099
+ # "unrealisedPnlPcnt": 0.0103,
1100
+ # "unrealisedRoePcnt": 0.2360,
1101
+ # "avgEntryPrice": 4182.10,
1102
+ # "liquidationPrice": 4023.00,
1103
+ # "bankruptPrice": 4000.25,
1104
+ # "settleCurrency": "USDT",
1105
+ # "isInverse": False
1106
+ # }
1107
+ # ]
1108
+ # }
1109
+ #
1110
+ data = self.safe_list(response, 'data')
1111
+ return self.parse_positions(data, symbols)
1112
+
1113
+ async def fetch_positions_history(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}):
1114
+ """
1115
+ fetches historical positions
1116
+ :see: https://www.kucoin.com/docs/rest/futures-trading/positions/get-positions-history
1117
+ :param str[] [symbols]: list of unified market symbols
1118
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1119
+ :param int [params.until]: closing end time
1120
+ :param int [params.pageId]: page id
1121
+ :returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
1122
+ """
1123
+ await self.load_markets()
1124
+ if limit is None:
1125
+ limit = 200
1126
+ request: dict = {
1127
+ 'limit': limit,
1128
+ }
1129
+ if since is not None:
1130
+ request['from'] = since
1131
+ until = self.safe_integer(params, 'until')
1132
+ if until is not None:
1133
+ params = self.omit(params, 'until')
1134
+ request['to'] = until
1135
+ response = await self.futuresPrivateGetHistoryPositions(self.extend(request, params))
1136
+ #
1137
+ # {
1138
+ # "success": True,
1139
+ # "code": "200",
1140
+ # "msg": "success",
1141
+ # "retry": False,
1142
+ # "data": {
1143
+ # "currentPage": 1,
1144
+ # "pageSize": 10,
1145
+ # "totalNum": 25,
1146
+ # "totalPage": 3,
1147
+ # "items": [
1148
+ # {
1149
+ # "closeId": "300000000000000030",
1150
+ # "positionId": "300000000000000009",
1151
+ # "uid": 99996908309485,
1152
+ # "userId": "6527d4fc8c7f3d0001f40f5f",
1153
+ # "symbol": "XBTUSDM",
1154
+ # "settleCurrency": "XBT",
1155
+ # "leverage": "0.0",
1156
+ # "type": "LIQUID_LONG",
1157
+ # "side": null,
1158
+ # "closeSize": null,
1159
+ # "pnl": "-1.0000003793999999",
1160
+ # "realisedGrossCost": "0.9993849748999999",
1161
+ # "withdrawPnl": "0.0",
1162
+ # "roe": null,
1163
+ # "tradeFee": "0.0006154045",
1164
+ # "fundingFee": "0.0",
1165
+ # "openTime": 1713785751181,
1166
+ # "closeTime": 1713785752784,
1167
+ # "openPrice": null,
1168
+ # "closePrice": null
1169
+ # }
1170
+ # ]
1171
+ # }
1172
+ # }
1173
+ #
1174
+ data = self.safe_dict(response, 'data')
1175
+ items = self.safe_list(data, 'items', [])
1176
+ return self.parse_positions(items, symbols)
1177
+
1178
+ def parse_position(self, position: dict, market: Market = None):
1179
+ #
1180
+ # {
1181
+ # "code": "200000",
1182
+ # "data": [
1183
+ # {
1184
+ # "id": "615ba79f83a3410001cde321", # Position ID
1185
+ # "symbol": "ETHUSDTM", # Symbol
1186
+ # "autoDeposit": False, # Auto deposit margin or not
1187
+ # "maintMarginReq": 0.005, # Maintenance margin requirement
1188
+ # "riskLimit": 1000000, # Risk limit
1189
+ # "realLeverage": 25.92, # Leverage of the order
1190
+ # "crossMode": False, # Cross mode or not
1191
+ # "delevPercentage": 0.76, # ADL ranking percentile
1192
+ # "openingTimestamp": 1638578546031, # Open time
1193
+ # "currentTimestamp": 1638578563580, # Current timestamp
1194
+ # "currentQty": 2, # Current postion quantity
1195
+ # "currentCost": 83.787, # Current postion value
1196
+ # "currentComm": 0.0167574, # Current commission
1197
+ # "unrealisedCost": 83.787, # Unrealised value
1198
+ # "realisedGrossCost": 0.0, # Accumulated realised gross profit value
1199
+ # "realisedCost": 0.0167574, # Current realised position value
1200
+ # "isOpen": True, # Opened position or not
1201
+ # "markPrice": 4183.38, # Mark price
1202
+ # "markValue": 83.6676, # Mark value
1203
+ # "posCost": 83.787, # Position value
1204
+ # "posCross": 0.0, # added margin
1205
+ # "posInit": 3.35148, # Leverage margin
1206
+ # "posComm": 0.05228309, # Bankruptcy cost
1207
+ # "posLoss": 0.0, # Funding fees paid out
1208
+ # "posMargin": 3.40376309, # Position margin
1209
+ # "posMaint": 0.50707892, # Maintenance margin
1210
+ # "maintMargin": 3.28436309, # Position margin
1211
+ # "realisedGrossPnl": 0.0, # Accumulated realised gross profit value
1212
+ # "realisedPnl": -0.0167574, # Realised profit and loss
1213
+ # "unrealisedPnl": -0.1194, # Unrealised profit and loss
1214
+ # "unrealisedPnlPcnt": -0.0014, # Profit-loss ratio of the position
1215
+ # "unrealisedRoePcnt": -0.0356, # Rate of return on investment
1216
+ # "avgEntryPrice": 4189.35, # Average entry price
1217
+ # "liquidationPrice": 4044.55, # Liquidation price
1218
+ # "bankruptPrice": 4021.75, # Bankruptcy price
1219
+ # "settleCurrency": "USDT", # Currency used to clear and settle the trades
1220
+ # "isInverse": False
1221
+ # }
1222
+ # ]
1223
+ # }
1224
+ # position history
1225
+ # {
1226
+ # "closeId": "300000000000000030",
1227
+ # "positionId": "300000000000000009",
1228
+ # "uid": 99996908309485,
1229
+ # "userId": "6527d4fc8c7f3d0001f40f5f",
1230
+ # "symbol": "XBTUSDM",
1231
+ # "settleCurrency": "XBT",
1232
+ # "leverage": "0.0",
1233
+ # "type": "LIQUID_LONG",
1234
+ # "side": null,
1235
+ # "closeSize": null,
1236
+ # "pnl": "-1.0000003793999999",
1237
+ # "realisedGrossCost": "0.9993849748999999",
1238
+ # "withdrawPnl": "0.0",
1239
+ # "roe": null,
1240
+ # "tradeFee": "0.0006154045",
1241
+ # "fundingFee": "0.0",
1242
+ # "openTime": 1713785751181,
1243
+ # "closeTime": 1713785752784,
1244
+ # "openPrice": null,
1245
+ # "closePrice": null
1246
+ # }
1247
+ #
1248
+ symbol = self.safe_string(position, 'symbol')
1249
+ market = self.safe_market(symbol, market)
1250
+ timestamp = self.safe_integer(position, 'currentTimestamp')
1251
+ size = self.safe_string(position, 'currentQty')
1252
+ side = None
1253
+ type = self.safe_string_lower(position, 'type')
1254
+ if size is not None:
1255
+ if Precise.string_gt(size, '0'):
1256
+ side = 'long'
1257
+ elif Precise.string_lt(size, '0'):
1258
+ side = 'short'
1259
+ elif type is not None:
1260
+ if type.find('long') > -1:
1261
+ side = 'long'
1262
+ else:
1263
+ side = 'short'
1264
+ notional = Precise.string_abs(self.safe_string(position, 'posCost'))
1265
+ initialMargin = self.safe_string(position, 'posInit')
1266
+ initialMarginPercentage = Precise.string_div(initialMargin, notional)
1267
+ # marginRatio = Precise.string_div(maintenanceRate, collateral)
1268
+ unrealisedPnl = self.safe_string(position, 'unrealisedPnl')
1269
+ crossMode = self.safe_value(position, 'crossMode')
1270
+ # currently crossMode is always set to False and only isolated positions are supported
1271
+ marginMode = None
1272
+ if crossMode is not None:
1273
+ marginMode = 'cross' if crossMode else 'isolated'
1274
+ return self.safe_position({
1275
+ 'info': position,
1276
+ 'id': self.safe_string_2(position, 'id', 'positionId'),
1277
+ 'symbol': self.safe_string(market, 'symbol'),
1278
+ 'timestamp': timestamp,
1279
+ 'datetime': self.iso8601(timestamp),
1280
+ 'lastUpdateTimestamp': self.safe_integer(position, 'closeTime'),
1281
+ 'initialMargin': self.parse_number(initialMargin),
1282
+ 'initialMarginPercentage': self.parse_number(initialMarginPercentage),
1283
+ 'maintenanceMargin': self.safe_number(position, 'posMaint'),
1284
+ 'maintenanceMarginPercentage': self.safe_number(position, 'maintMarginReq'),
1285
+ 'entryPrice': self.safe_number_2(position, 'avgEntryPrice', 'openPrice'),
1286
+ 'notional': self.parse_number(notional),
1287
+ 'leverage': self.safe_number_2(position, 'realLeverage', 'leverage'),
1288
+ 'unrealizedPnl': self.parse_number(unrealisedPnl),
1289
+ 'contracts': self.parse_number(Precise.string_abs(size)),
1290
+ 'contractSize': self.safe_value(market, 'contractSize'),
1291
+ 'realizedPnl': self.safe_number_2(position, 'realisedPnl', 'pnl'),
1292
+ 'marginRatio': None,
1293
+ 'liquidationPrice': self.safe_number(position, 'liquidationPrice'),
1294
+ 'markPrice': self.safe_number(position, 'markPrice'),
1295
+ 'lastPrice': None,
1296
+ 'collateral': self.safe_number(position, 'maintMargin'),
1297
+ 'marginMode': marginMode,
1298
+ 'side': side,
1299
+ 'percentage': None,
1300
+ 'stopLossPrice': None,
1301
+ 'takeProfitPrice': None,
1302
+ })
1303
+
1304
+ async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1305
+ """
1306
+ Create an order on the exchange
1307
+ :see: https://docs.kucoin.com/futures/#place-an-order
1308
+ :param str symbol: Unified CCXT market symbol
1309
+ :param str type: 'limit' or 'market'
1310
+ :param str side: 'buy' or 'sell'
1311
+ :param float amount: the amount of currency to trade
1312
+ :param float [price]: *ignored in "market" orders* the price at which the order is to be fullfilled at in units of the quote currency
1313
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1314
+ :param float [params.triggerPrice]: The price a trigger order is triggered at
1315
+ :param float [params.stopLossPrice]: price to trigger stop-loss orders
1316
+ :param float [params.takeProfitPrice]: price to trigger take-profit orders
1317
+ :param bool [params.reduceOnly]: A mark to reduce the position size only. Set to False by default. Need to set the position size when reduceOnly is True.
1318
+ :param str [params.timeInForce]: GTC, GTT, IOC, or FOK, default is GTC, limit orders only
1319
+ :param str [params.postOnly]: Post only flag, invalid when timeInForce is IOC or FOK
1320
+ * ----------------- Exchange Specific Parameters -----------------
1321
+ :param float [params.leverage]: Leverage size of the order
1322
+ :param str [params.clientOid]: client order id, defaults to uuid if not passed
1323
+ :param str [params.remark]: remark for the order, length cannot exceed 100 utf8 characters
1324
+ :param str [params.stop]: 'up' or 'down', the direction the stopPrice is triggered from, requires stopPrice. down: Triggers when the price reaches or goes below the stopPrice. up: Triggers when the price reaches or goes above the stopPrice.
1325
+ :param str [params.stopPriceType]: TP, IP or MP, defaults to MP: Mark Price
1326
+ :param bool [params.closeOrder]: set to True to close position
1327
+ :param bool [params.test]: set to True to use the test order endpoint(does not submit order, use to validate params)
1328
+ :param bool [params.forceHold]: A mark to forcely hold the funds for an order, even though it's an order to reduce the position size. This helps the order stay on the order book and not get canceled when the position size changes. Set to False by default.
1329
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1330
+ """
1331
+ await self.load_markets()
1332
+ market = self.market(symbol)
1333
+ testOrder = self.safe_bool(params, 'test', False)
1334
+ params = self.omit(params, 'test')
1335
+ orderRequest = self.create_contract_order_request(symbol, type, side, amount, price, params)
1336
+ response = None
1337
+ if testOrder:
1338
+ response = await self.futuresPrivatePostOrdersTest(orderRequest)
1339
+ else:
1340
+ response = await self.futuresPrivatePostOrders(orderRequest)
1341
+ #
1342
+ # {
1343
+ # "code": "200000",
1344
+ # "data": {
1345
+ # "orderId": "619717484f1d010001510cde",
1346
+ # },
1347
+ # }
1348
+ #
1349
+ data = self.safe_dict(response, 'data', {})
1350
+ return self.parse_order(data, market)
1351
+
1352
+ async def create_orders(self, orders: List[OrderRequest], params={}):
1353
+ """
1354
+ create a list of trade orders
1355
+ :see: https://www.kucoin.com/docs/rest/futures-trading/orders/place-multiple-orders
1356
+ :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
1357
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1358
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1359
+ """
1360
+ await self.load_markets()
1361
+ ordersRequests = []
1362
+ for i in range(0, len(orders)):
1363
+ rawOrder = orders[i]
1364
+ symbol = self.safe_string(rawOrder, 'symbol')
1365
+ market = self.market(symbol)
1366
+ type = self.safe_string(rawOrder, 'type')
1367
+ side = self.safe_string(rawOrder, 'side')
1368
+ amount = self.safe_value(rawOrder, 'amount')
1369
+ price = self.safe_value(rawOrder, 'price')
1370
+ orderParams = self.safe_value(rawOrder, 'params', {})
1371
+ orderRequest = self.create_contract_order_request(market['id'], type, side, amount, price, orderParams)
1372
+ ordersRequests.append(orderRequest)
1373
+ response = await self.futuresPrivatePostOrdersMulti(ordersRequests)
1374
+ #
1375
+ # {
1376
+ # "code": "200000",
1377
+ # "data": [
1378
+ # {
1379
+ # "orderId": "135241412609331200",
1380
+ # "clientOid": "3d8fcc13-0b13-447f-ad30-4b3441e05213",
1381
+ # "symbol": "LTCUSDTM",
1382
+ # "code": "200000",
1383
+ # "msg": "success"
1384
+ # },
1385
+ # {
1386
+ # "orderId": "135241412747743234",
1387
+ # "clientOid": "b878c7ee-ae3e-4d63-a20b-038acbb7306f",
1388
+ # "symbol": "LTCUSDTM",
1389
+ # "code": "200000",
1390
+ # "msg": "success"
1391
+ # }
1392
+ # ]
1393
+ # }
1394
+ #
1395
+ data = self.safe_list(response, 'data', [])
1396
+ return self.parse_orders(data)
1397
+
1398
+ def create_contract_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1399
+ market = self.market(symbol)
1400
+ # required param, cannot be used twice
1401
+ clientOrderId = self.safe_string_2(params, 'clientOid', 'clientOrderId', self.uuid())
1402
+ params = self.omit(params, ['clientOid', 'clientOrderId'])
1403
+ if amount < 1:
1404
+ raise InvalidOrder(self.id + ' createOrder() minimum contract order amount is 1')
1405
+ preciseAmount = int(self.amount_to_precision(symbol, amount))
1406
+ request: dict = {
1407
+ 'clientOid': clientOrderId,
1408
+ 'side': side,
1409
+ 'symbol': market['id'],
1410
+ 'type': type, # limit or market
1411
+ 'size': preciseAmount,
1412
+ 'leverage': 1,
1413
+ }
1414
+ triggerPrice, stopLossPrice, takeProfitPrice = self.handle_trigger_prices(params)
1415
+ triggerPriceTypes: dict = {
1416
+ 'mark': 'MP',
1417
+ 'last': 'TP',
1418
+ 'index': 'IP',
1419
+ }
1420
+ triggerPriceType = self.safe_string(params, 'triggerPriceType', 'mark')
1421
+ triggerPriceTypeValue = self.safe_string(triggerPriceTypes, triggerPriceType, triggerPriceType)
1422
+ params = self.omit(params, ['stopLossPrice', 'takeProfitPrice', 'triggerPrice', 'stopPrice'])
1423
+ if triggerPrice:
1424
+ request['stop'] = 'up' if (side == 'buy') else 'down'
1425
+ request['stopPrice'] = self.price_to_precision(symbol, triggerPrice)
1426
+ request['stopPriceType'] = triggerPriceTypeValue
1427
+ elif stopLossPrice or takeProfitPrice:
1428
+ if stopLossPrice:
1429
+ request['stop'] = 'up' if (side == 'buy') else 'down'
1430
+ request['stopPrice'] = self.price_to_precision(symbol, stopLossPrice)
1431
+ else:
1432
+ request['stop'] = 'down' if (side == 'buy') else 'up'
1433
+ request['stopPrice'] = self.price_to_precision(symbol, takeProfitPrice)
1434
+ request['reduceOnly'] = True
1435
+ request['stopPriceType'] = triggerPriceTypeValue
1436
+ uppercaseType = type.upper()
1437
+ timeInForce = self.safe_string_upper(params, 'timeInForce')
1438
+ if uppercaseType == 'LIMIT':
1439
+ if price is None:
1440
+ raise ArgumentsRequired(self.id + ' createOrder() requires a price argument for limit orders')
1441
+ else:
1442
+ request['price'] = self.price_to_precision(symbol, price)
1443
+ if timeInForce is not None:
1444
+ request['timeInForce'] = timeInForce
1445
+ postOnly = None
1446
+ postOnly, params = self.handle_post_only(type == 'market', False, params)
1447
+ if postOnly:
1448
+ request['postOnly'] = True
1449
+ hidden = self.safe_value(params, 'hidden')
1450
+ if postOnly and (hidden is not None):
1451
+ raise BadRequest(self.id + ' createOrder() does not support the postOnly parameter together with a hidden parameter')
1452
+ iceberg = self.safe_value(params, 'iceberg')
1453
+ if iceberg:
1454
+ visibleSize = self.safe_value(params, 'visibleSize')
1455
+ if visibleSize is None:
1456
+ raise ArgumentsRequired(self.id + ' createOrder() requires a visibleSize parameter for iceberg orders')
1457
+ params = self.omit(params, ['timeInForce', 'stopPrice', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice']) # Time in force only valid for limit orders, exchange error when gtc for market orders
1458
+ return self.extend(request, params)
1459
+
1460
+ async def cancel_order(self, id: str, symbol: Str = None, params={}):
1461
+ """
1462
+ cancels an open order
1463
+ :see: https://www.kucoin.com/docs/rest/futures-trading/orders/cancel-futures-order-by-orderid
1464
+ :param str id: order id
1465
+ :param str symbol: unified symbol of the market the order was made in
1466
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1467
+ :param str [params.clientOrderId]: cancel order by client order id
1468
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1469
+ """
1470
+ await self.load_markets()
1471
+ clientOrderId = self.safe_string_2(params, 'clientOid', 'clientOrderId')
1472
+ params = self.omit(params, ['clientOrderId'])
1473
+ request: dict = {}
1474
+ response = None
1475
+ if clientOrderId is not None:
1476
+ if symbol is None:
1477
+ raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument when cancelling by clientOrderId')
1478
+ market = self.market(symbol)
1479
+ request['symbol'] = market['id']
1480
+ request['clientOid'] = clientOrderId
1481
+ response = await self.futuresPrivateDeleteOrdersClientOrderClientOid(self.extend(request, params))
1482
+ else:
1483
+ request['orderId'] = id
1484
+ response = await self.futuresPrivateDeleteOrdersOrderId(self.extend(request, params))
1485
+ #
1486
+ # {
1487
+ # "code": "200000",
1488
+ # "data": {
1489
+ # "cancelledOrderIds": [
1490
+ # "619714b8b6353000014c505a",
1491
+ # ],
1492
+ # },
1493
+ # }
1494
+ #
1495
+ return self.safe_value(response, 'data')
1496
+
1497
+ async def cancel_all_orders(self, symbol: Str = None, params={}):
1498
+ """
1499
+ cancel all open orders
1500
+ :see: https://www.kucoin.com/docs/rest/futures-trading/orders/cancel-multiple-futures-limit-orders
1501
+ :see: https://www.kucoin.com/docs/rest/futures-trading/orders/cancel-multiple-futures-stop-orders
1502
+ :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
1503
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1504
+ :param dict [params.trigger]: When True, all the trigger orders will be cancelled
1505
+ :returns: Response from the exchange
1506
+ """
1507
+ await self.load_markets()
1508
+ request: dict = {}
1509
+ if symbol is not None:
1510
+ request['symbol'] = self.market_id(symbol)
1511
+ stop = self.safe_value_2(params, 'stop', 'trigger')
1512
+ params = self.omit(params, ['stop', 'trigger'])
1513
+ response = None
1514
+ if stop:
1515
+ response = await self.futuresPrivateDeleteStopOrders(self.extend(request, params))
1516
+ else:
1517
+ response = await self.futuresPrivateDeleteOrders(self.extend(request, params))
1518
+ #
1519
+ # {
1520
+ # "code": "200000",
1521
+ # "data": {
1522
+ # "cancelledOrderIds": [
1523
+ # "619714b8b6353000014c505a",
1524
+ # ],
1525
+ # },
1526
+ # }
1527
+ #
1528
+ return self.safe_value(response, 'data')
1529
+
1530
+ async def add_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
1531
+ """
1532
+ add margin
1533
+ :see: https://www.kucoin.com/docs/rest/futures-trading/positions/add-margin-manually
1534
+ :param str symbol: unified market symbol
1535
+ :param float amount: amount of margin to add
1536
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1537
+ :returns dict: a `margin structure <https://docs.ccxt.com/#/?id=add-margin-structure>`
1538
+ """
1539
+ await self.load_markets()
1540
+ market = self.market(symbol)
1541
+ uuid = self.uuid()
1542
+ request: dict = {
1543
+ 'symbol': market['id'],
1544
+ 'margin': self.amount_to_precision(symbol, amount),
1545
+ 'bizNo': uuid,
1546
+ }
1547
+ response = await self.futuresPrivatePostPositionMarginDepositMargin(self.extend(request, params))
1548
+ #
1549
+ # {
1550
+ # "code": "200000",
1551
+ # "data": {
1552
+ # "id": "62311d26064e8f00013f2c6d",
1553
+ # "symbol": "XRPUSDTM",
1554
+ # "autoDeposit": False,
1555
+ # "maintMarginReq": 0.01,
1556
+ # "riskLimit": 200000,
1557
+ # "realLeverage": 0.88,
1558
+ # "crossMode": False,
1559
+ # "delevPercentage": 0.4,
1560
+ # "openingTimestamp": 1647385894798,
1561
+ # "currentTimestamp": 1647414510672,
1562
+ # "currentQty": -1,
1563
+ # "currentCost": -7.658,
1564
+ # "currentComm": 0.0053561,
1565
+ # "unrealisedCost": -7.658,
1566
+ # "realisedGrossCost": 0,
1567
+ # "realisedCost": 0.0053561,
1568
+ # "isOpen": True,
1569
+ # "markPrice": 0.7635,
1570
+ # "markValue": -7.635,
1571
+ # "posCost": -7.658,
1572
+ # "posCross": 1.00016084,
1573
+ # "posInit": 7.658,
1574
+ # "posComm": 0.00979006,
1575
+ # "posLoss": 0,
1576
+ # "posMargin": 8.6679509,
1577
+ # "posMaint": 0.08637006,
1578
+ # "maintMargin": 8.6909509,
1579
+ # "realisedGrossPnl": 0,
1580
+ # "realisedPnl": -0.0038335,
1581
+ # "unrealisedPnl": 0.023,
1582
+ # "unrealisedPnlPcnt": 0.003,
1583
+ # "unrealisedRoePcnt": 0.003,
1584
+ # "avgEntryPrice": 0.7658,
1585
+ # "liquidationPrice": 1.6239,
1586
+ # "bankruptPrice": 1.6317,
1587
+ # "settleCurrency": "USDT"
1588
+ # }
1589
+ # }
1590
+ #
1591
+ #
1592
+ # {
1593
+ # "code":"200000",
1594
+ # "msg":"Position does not exist"
1595
+ # }
1596
+ #
1597
+ data = self.safe_value(response, 'data')
1598
+ return self.extend(self.parse_margin_modification(data, market), {
1599
+ 'amount': self.amount_to_precision(symbol, amount),
1600
+ 'direction': 'in',
1601
+ })
1602
+
1603
+ def parse_margin_modification(self, info, market: Market = None) -> MarginModification:
1604
+ #
1605
+ # {
1606
+ # "id": "62311d26064e8f00013f2c6d",
1607
+ # "symbol": "XRPUSDTM",
1608
+ # "autoDeposit": False,
1609
+ # "maintMarginReq": 0.01,
1610
+ # "riskLimit": 200000,
1611
+ # "realLeverage": 0.88,
1612
+ # "crossMode": False,
1613
+ # "delevPercentage": 0.4,
1614
+ # "openingTimestamp": 1647385894798,
1615
+ # "currentTimestamp": 1647414510672,
1616
+ # "currentQty": -1,
1617
+ # "currentCost": -7.658,
1618
+ # "currentComm": 0.0053561,
1619
+ # "unrealisedCost": -7.658,
1620
+ # "realisedGrossCost": 0,
1621
+ # "realisedCost": 0.0053561,
1622
+ # "isOpen": True,
1623
+ # "markPrice": 0.7635,
1624
+ # "markValue": -7.635,
1625
+ # "posCost": -7.658,
1626
+ # "posCross": 1.00016084,
1627
+ # "posInit": 7.658,
1628
+ # "posComm": 0.00979006,
1629
+ # "posLoss": 0,
1630
+ # "posMargin": 8.6679509,
1631
+ # "posMaint": 0.08637006,
1632
+ # "maintMargin": 8.6909509,
1633
+ # "realisedGrossPnl": 0,
1634
+ # "realisedPnl": -0.0038335,
1635
+ # "unrealisedPnl": 0.023,
1636
+ # "unrealisedPnlPcnt": 0.003,
1637
+ # "unrealisedRoePcnt": 0.003,
1638
+ # "avgEntryPrice": 0.7658,
1639
+ # "liquidationPrice": 1.6239,
1640
+ # "bankruptPrice": 1.6317,
1641
+ # "settleCurrency": "USDT"
1642
+ # }
1643
+ #
1644
+ # {
1645
+ # "code":"200000",
1646
+ # "msg":"Position does not exist"
1647
+ # }
1648
+ #
1649
+ id = self.safe_string(info, 'id')
1650
+ market = self.safe_market(id, market)
1651
+ currencyId = self.safe_string(info, 'settleCurrency')
1652
+ crossMode = self.safe_value(info, 'crossMode')
1653
+ mode = 'cross' if crossMode else 'isolated'
1654
+ marketId = self.safe_string(market, 'symbol')
1655
+ timestamp = self.safe_integer(info, 'currentTimestamp')
1656
+ return {
1657
+ 'info': info,
1658
+ 'symbol': self.safe_symbol(marketId, market),
1659
+ 'type': None,
1660
+ 'marginMode': mode,
1661
+ 'amount': None,
1662
+ 'total': None,
1663
+ 'code': self.safe_currency_code(currencyId),
1664
+ 'status': None,
1665
+ 'timestamp': timestamp,
1666
+ 'datetime': self.iso8601(timestamp),
1667
+ }
1668
+
1669
+ async def fetch_orders_by_status(self, status, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1670
+ """
1671
+ fetches a list of orders placed on the exchange
1672
+ :see: https://docs.kucoin.com/futures/#get-order-list
1673
+ :see: https://docs.kucoin.com/futures/#get-untriggered-stop-order-list
1674
+ :param str status: 'active' or 'closed', only 'active' is valid for stop orders
1675
+ :param str symbol: unified symbol for the market to retrieve orders from
1676
+ :param int [since]: timestamp in ms of the earliest order to retrieve
1677
+ :param int [limit]: The maximum number of orders to retrieve
1678
+ :param dict [params]: exchange specific parameters
1679
+ :param bool [params.trigger]: set to True to retrieve untriggered stop orders
1680
+ :param int [params.until]: End time in ms
1681
+ :param str [params.side]: buy or sell
1682
+ :param str [params.type]: limit or market
1683
+ :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)
1684
+ :returns: An `array of order structures <https://docs.ccxt.com/#/?id=order-structure>`
1685
+ """
1686
+ await self.load_markets()
1687
+ paginate = False
1688
+ paginate, params = self.handle_option_and_params(params, 'fetchOrdersByStatus', 'paginate')
1689
+ if paginate:
1690
+ return await self.fetch_paginated_call_dynamic('fetchOrdersByStatus', symbol, since, limit, params)
1691
+ stop = self.safe_value_2(params, 'stop', 'trigger')
1692
+ until = self.safe_integer(params, 'until')
1693
+ params = self.omit(params, ['stop', 'until', 'trigger'])
1694
+ if status == 'closed':
1695
+ status = 'done'
1696
+ elif status == 'open':
1697
+ status = 'active'
1698
+ request: dict = {}
1699
+ if not stop:
1700
+ request['status'] = status
1701
+ elif status != 'active':
1702
+ raise BadRequest(self.id + ' fetchOrdersByStatus() can only fetch untriggered stop orders')
1703
+ market = None
1704
+ if symbol is not None:
1705
+ market = self.market(symbol)
1706
+ request['symbol'] = market['id']
1707
+ if since is not None:
1708
+ request['startAt'] = since
1709
+ if until is not None:
1710
+ request['endAt'] = until
1711
+ response = None
1712
+ if stop:
1713
+ response = await self.futuresPrivateGetStopOrders(self.extend(request, params))
1714
+ else:
1715
+ response = await self.futuresPrivateGetOrders(self.extend(request, params))
1716
+ #
1717
+ # {
1718
+ # "code": "200000",
1719
+ # "data": {
1720
+ # "currentPage": 1,
1721
+ # "pageSize": 50,
1722
+ # "totalNum": 4,
1723
+ # "totalPage": 1,
1724
+ # "items": [
1725
+ # {
1726
+ # "id": "64507d02921f1c0001ff6892",
1727
+ # "symbol": "XBTUSDTM",
1728
+ # "type": "market",
1729
+ # "side": "buy",
1730
+ # "price": null,
1731
+ # "size": 1,
1732
+ # "value": "27.992",
1733
+ # "dealValue": "27.992",
1734
+ # "dealSize": 1,
1735
+ # "stp": "",
1736
+ # "stop": "",
1737
+ # "stopPriceType": "",
1738
+ # "stopTriggered": False,
1739
+ # "stopPrice": null,
1740
+ # "timeInForce": "GTC",
1741
+ # "postOnly": False,
1742
+ # "hidden": False,
1743
+ # "iceberg": False,
1744
+ # "leverage": "17",
1745
+ # "forceHold": False,
1746
+ # "closeOrder": False,
1747
+ # "visibleSize": null,
1748
+ # "clientOid": null,
1749
+ # "remark": null,
1750
+ # "tags": null,
1751
+ # "isActive": False,
1752
+ # "cancelExist": False,
1753
+ # "createdAt": 1682996482000,
1754
+ # "updatedAt": 1682996483062,
1755
+ # "endAt": 1682996483062,
1756
+ # "orderTime": 1682996482953900677,
1757
+ # "settleCurrency": "USDT",
1758
+ # "status": "done",
1759
+ # "filledValue": "27.992",
1760
+ # "filledSize": 1,
1761
+ # "reduceOnly": False
1762
+ # }
1763
+ # ]
1764
+ # }
1765
+ # }
1766
+ #
1767
+ responseData = self.safe_value(response, 'data', {})
1768
+ orders = self.safe_list(responseData, 'items', [])
1769
+ return self.parse_orders(orders, market, since, limit)
1770
+
1771
+ async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1772
+ """
1773
+ fetches information on multiple closed orders made by the user
1774
+ :see: https://docs.kucoin.com/futures/#get-order-list
1775
+ :param str symbol: unified market symbol of the market orders were made in
1776
+ :param int [since]: the earliest time in ms to fetch orders for
1777
+ :param int [limit]: the maximum number of order structures to retrieve
1778
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1779
+ :param int [params.until]: end time in ms
1780
+ :param str [params.side]: buy or sell
1781
+ :param str [params.type]: limit, or market
1782
+ :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)
1783
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1784
+ """
1785
+ await self.load_markets()
1786
+ paginate = False
1787
+ paginate, params = self.handle_option_and_params(params, 'fetchClosedOrders', 'paginate')
1788
+ if paginate:
1789
+ return await self.fetch_paginated_call_dynamic('fetchClosedOrders', symbol, since, limit, params)
1790
+ return await self.fetch_orders_by_status('done', symbol, since, limit, params)
1791
+
1792
+ async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1793
+ """
1794
+ fetches information on multiple open orders made by the user
1795
+ :see: https://docs.kucoin.com/futures/#get-order-list
1796
+ :see: https://docs.kucoin.com/futures/#get-untriggered-stop-order-list
1797
+ :param str symbol: unified market symbol of the market orders were made in
1798
+ :param int [since]: the earliest time in ms to fetch orders for
1799
+ :param int [limit]: the maximum number of order structures to retrieve
1800
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1801
+ :param int [params.until]: end time in ms
1802
+ :param str [params.side]: buy or sell
1803
+ :param str [params.type]: limit, or market
1804
+ :param boolean [params.trigger]: set to True to retrieve untriggered stop orders
1805
+ :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)
1806
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1807
+ """
1808
+ await self.load_markets()
1809
+ paginate = False
1810
+ paginate, params = self.handle_option_and_params(params, 'fetchOpenOrders', 'paginate')
1811
+ if paginate:
1812
+ return await self.fetch_paginated_call_dynamic('fetchOpenOrders', symbol, since, limit, params)
1813
+ return await self.fetch_orders_by_status('open', symbol, since, limit, params)
1814
+
1815
+ async def fetch_order(self, id: Str = None, symbol: Str = None, params={}):
1816
+ """
1817
+ fetches information on an order made by the user
1818
+ :see: https://docs.kucoin.com/futures/#get-details-of-a-single-order
1819
+ :param str symbol: unified symbol of the market the order was made in
1820
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1821
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1822
+ """
1823
+ await self.load_markets()
1824
+ request: dict = {}
1825
+ response = None
1826
+ if id is None:
1827
+ clientOrderId = self.safe_string_2(params, 'clientOid', 'clientOrderId')
1828
+ if clientOrderId is None:
1829
+ raise InvalidOrder(self.id + ' fetchOrder() requires parameter id or params.clientOid')
1830
+ request['clientOid'] = clientOrderId
1831
+ params = self.omit(params, ['clientOid', 'clientOrderId'])
1832
+ response = await self.futuresPrivateGetOrdersByClientOid(self.extend(request, params))
1833
+ else:
1834
+ request['orderId'] = id
1835
+ response = await self.futuresPrivateGetOrdersOrderId(self.extend(request, params))
1836
+ #
1837
+ # {
1838
+ # "code": "200000",
1839
+ # "data": {
1840
+ # "id": "64507d02921f1c0001ff6892",
1841
+ # "symbol": "XBTUSDTM",
1842
+ # "type": "market",
1843
+ # "side": "buy",
1844
+ # "price": null,
1845
+ # "size": 1,
1846
+ # "value": "27.992",
1847
+ # "dealValue": "27.992",
1848
+ # "dealSize": 1,
1849
+ # "stp": "",
1850
+ # "stop": "",
1851
+ # "stopPriceType": "",
1852
+ # "stopTriggered": False,
1853
+ # "stopPrice": null,
1854
+ # "timeInForce": "GTC",
1855
+ # "postOnly": False,
1856
+ # "hidden": False,
1857
+ # "iceberg": False,
1858
+ # "leverage": "17",
1859
+ # "forceHold": False,
1860
+ # "closeOrder": False,
1861
+ # "visibleSize": null,
1862
+ # "clientOid": null,
1863
+ # "remark": null,
1864
+ # "tags": null,
1865
+ # "isActive": False,
1866
+ # "cancelExist": False,
1867
+ # "createdAt": 1682996482000,
1868
+ # "updatedAt": 1682996483000,
1869
+ # "endAt": 1682996483000,
1870
+ # "orderTime": 1682996482953900677,
1871
+ # "settleCurrency": "USDT",
1872
+ # "status": "done",
1873
+ # "filledSize": 1,
1874
+ # "filledValue": "27.992",
1875
+ # "reduceOnly": False
1876
+ # }
1877
+ # }
1878
+ #
1879
+ market = self.market(symbol) if (symbol is not None) else None
1880
+ responseData = self.safe_dict(response, 'data')
1881
+ return self.parse_order(responseData, market)
1882
+
1883
+ def parse_order(self, order: dict, market: Market = None) -> Order:
1884
+ #
1885
+ # fetchOrder, fetchOrdersByStatus
1886
+ #
1887
+ # {
1888
+ # "id": "64507d02921f1c0001ff6892",
1889
+ # "symbol": "XBTUSDTM",
1890
+ # "type": "market",
1891
+ # "side": "buy",
1892
+ # "price": null,
1893
+ # "size": 1,
1894
+ # "value": "27.992",
1895
+ # "dealValue": "27.992",
1896
+ # "dealSize": 1,
1897
+ # "stp": "",
1898
+ # "stop": "",
1899
+ # "stopPriceType": "",
1900
+ # "stopTriggered": False,
1901
+ # "stopPrice": null,
1902
+ # "timeInForce": "GTC",
1903
+ # "postOnly": False,
1904
+ # "hidden": False,
1905
+ # "iceberg": False,
1906
+ # "leverage": "17",
1907
+ # "forceHold": False,
1908
+ # "closeOrder": False,
1909
+ # "visibleSize": null,
1910
+ # "clientOid": null,
1911
+ # "remark": null,
1912
+ # "tags": null,
1913
+ # "isActive": False,
1914
+ # "cancelExist": False,
1915
+ # "createdAt": 1682996482000,
1916
+ # "updatedAt": 1682996483062,
1917
+ # "endAt": 1682996483062,
1918
+ # "orderTime": 1682996482953900677,
1919
+ # "settleCurrency": "USDT",
1920
+ # "status": "done",
1921
+ # "filledValue": "27.992",
1922
+ # "filledSize": 1,
1923
+ # "reduceOnly": False
1924
+ # }
1925
+ #
1926
+ # createOrder
1927
+ #
1928
+ # {
1929
+ # "orderId": "619717484f1d010001510cde"
1930
+ # }
1931
+ #
1932
+ # createOrders
1933
+ #
1934
+ # {
1935
+ # "orderId": "80465574458560512",
1936
+ # "clientOid": "5c52e11203aa677f33e491",
1937
+ # "symbol": "ETHUSDTM",
1938
+ # "code": "200000",
1939
+ # "msg": "success"
1940
+ # }
1941
+ #
1942
+ marketId = self.safe_string(order, 'symbol')
1943
+ market = self.safe_market(marketId, market)
1944
+ symbol = market['symbol']
1945
+ orderId = self.safe_string_2(order, 'id', 'orderId')
1946
+ type = self.safe_string(order, 'type')
1947
+ timestamp = self.safe_integer(order, 'createdAt')
1948
+ datetime = self.iso8601(timestamp)
1949
+ price = self.safe_string(order, 'price')
1950
+ # price is zero for market order
1951
+ # omitZero is called in safeOrder2
1952
+ side = self.safe_string(order, 'side')
1953
+ feeCurrencyId = self.safe_string(order, 'feeCurrency')
1954
+ feeCurrency = self.safe_currency_code(feeCurrencyId)
1955
+ feeCost = self.safe_number(order, 'fee')
1956
+ amount = self.safe_string(order, 'size')
1957
+ filled = self.safe_string(order, 'filledSize')
1958
+ cost = self.safe_string(order, 'filledValue')
1959
+ average = None
1960
+ if Precise.string_gt(filled, '0'):
1961
+ contractSize = self.safe_string(market, 'contractSize')
1962
+ if market['linear']:
1963
+ average = Precise.string_div(cost, Precise.string_mul(contractSize, filled))
1964
+ else:
1965
+ average = Precise.string_div(Precise.string_mul(contractSize, filled), cost)
1966
+ # precision reported by their api is 8 d.p.
1967
+ # average = Precise.string_div(cost, Precise.string_mul(filled, market['contractSize']))
1968
+ # bool
1969
+ isActive = self.safe_value(order, 'isActive')
1970
+ cancelExist = self.safe_bool(order, 'cancelExist', False)
1971
+ status = None
1972
+ if isActive is not None:
1973
+ status = 'open' if isActive else 'closed'
1974
+ status = 'canceled' if cancelExist else status
1975
+ fee = None
1976
+ if feeCost is not None:
1977
+ fee = {
1978
+ 'currency': feeCurrency,
1979
+ 'cost': feeCost,
1980
+ }
1981
+ clientOrderId = self.safe_string(order, 'clientOid')
1982
+ timeInForce = self.safe_string(order, 'timeInForce')
1983
+ stopPrice = self.safe_number(order, 'stopPrice')
1984
+ postOnly = self.safe_value(order, 'postOnly')
1985
+ reduceOnly = self.safe_value(order, 'reduceOnly')
1986
+ lastUpdateTimestamp = self.safe_integer(order, 'updatedAt')
1987
+ return self.safe_order({
1988
+ 'id': orderId,
1989
+ 'clientOrderId': clientOrderId,
1990
+ 'symbol': symbol,
1991
+ 'type': type,
1992
+ 'timeInForce': timeInForce,
1993
+ 'postOnly': postOnly,
1994
+ 'reduceOnly': reduceOnly,
1995
+ 'side': side,
1996
+ 'amount': amount,
1997
+ 'price': price,
1998
+ 'stopPrice': stopPrice,
1999
+ 'triggerPrice': stopPrice,
2000
+ 'cost': cost,
2001
+ 'filled': filled,
2002
+ 'remaining': None,
2003
+ 'timestamp': timestamp,
2004
+ 'datetime': datetime,
2005
+ 'fee': fee,
2006
+ 'status': status,
2007
+ 'info': order,
2008
+ 'lastTradeTimestamp': None,
2009
+ 'lastUpdateTimestamp': lastUpdateTimestamp,
2010
+ 'average': average,
2011
+ 'trades': None,
2012
+ }, market)
2013
+
2014
+ async def fetch_funding_rate(self, symbol: str, params={}):
2015
+ """
2016
+ fetch the current funding rate
2017
+ :see: https://www.kucoin.com/docs/rest/futures-trading/funding-fees/get-current-funding-rate
2018
+ :param str symbol: unified market symbol
2019
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2020
+ :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
2021
+ """
2022
+ await self.load_markets()
2023
+ market = self.market(symbol)
2024
+ request: dict = {
2025
+ 'symbol': market['id'],
2026
+ }
2027
+ response = await self.futuresPublicGetFundingRateSymbolCurrent(self.extend(request, params))
2028
+ #
2029
+ # {
2030
+ # "code": "200000",
2031
+ # "data": {
2032
+ # "symbol": ".ETHUSDTMFPI8H",
2033
+ # "granularity": 28800000,
2034
+ # "timePoint": 1637380800000,
2035
+ # "value": 0.0001,
2036
+ # "predictedValue": 0.0001,
2037
+ # },
2038
+ # }
2039
+ #
2040
+ data = self.safe_value(response, 'data')
2041
+ fundingTimestamp = self.safe_integer(data, 'timePoint')
2042
+ # the website displayes the previous funding rate as "funding rate"
2043
+ return {
2044
+ 'info': data,
2045
+ 'symbol': market['symbol'],
2046
+ 'markPrice': None,
2047
+ 'indexPrice': None,
2048
+ 'interestRate': None,
2049
+ 'estimatedSettlePrice': None,
2050
+ 'timestamp': None,
2051
+ 'datetime': None,
2052
+ 'fundingRate': self.safe_number(data, 'value'),
2053
+ 'fundingTimestamp': fundingTimestamp,
2054
+ 'fundingDatetime': self.iso8601(fundingTimestamp),
2055
+ 'nextFundingRate': self.safe_number(data, 'predictedValue'),
2056
+ 'nextFundingTimestamp': None,
2057
+ 'nextFundingDatetime': None,
2058
+ 'previousFundingRate': None,
2059
+ 'previousFundingTimestamp': None,
2060
+ 'previousFundingDatetime': None,
2061
+ }
2062
+
2063
+ def parse_balance(self, response) -> Balances:
2064
+ result: dict = {
2065
+ 'info': response,
2066
+ 'timestamp': None,
2067
+ 'datetime': None,
2068
+ }
2069
+ data = self.safe_value(response, 'data')
2070
+ currencyId = self.safe_string(data, 'currency')
2071
+ code = self.safe_currency_code(currencyId)
2072
+ account = self.account()
2073
+ account['free'] = self.safe_string(data, 'availableBalance')
2074
+ account['total'] = self.safe_string(data, 'accountEquity')
2075
+ result[code] = account
2076
+ return self.safe_balance(result)
2077
+
2078
+ async def fetch_balance(self, params={}) -> Balances:
2079
+ """
2080
+ query for balance and get the amount of funds available for trading or funds locked in orders
2081
+ :see: https://www.kucoin.com/docs/rest/funding/funding-overview/get-account-detail-futures
2082
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2083
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
2084
+ """
2085
+ await self.load_markets()
2086
+ # only fetches one balance at a time
2087
+ defaultCode = self.safe_string(self.options, 'code')
2088
+ fetchBalanceOptions = self.safe_value(self.options, 'fetchBalance', {})
2089
+ defaultCode = self.safe_string(fetchBalanceOptions, 'code', defaultCode)
2090
+ code = self.safe_string(params, 'code', defaultCode)
2091
+ currency = self.currency(code)
2092
+ request: dict = {
2093
+ 'currency': currency['id'],
2094
+ }
2095
+ response = await self.futuresPrivateGetAccountOverview(self.extend(request, params))
2096
+ #
2097
+ # {
2098
+ # "code": "200000",
2099
+ # "data": {
2100
+ # "accountEquity": 0.00005,
2101
+ # "unrealisedPNL": 0,
2102
+ # "marginBalance": 0.00005,
2103
+ # "positionMargin": 0,
2104
+ # "orderMargin": 0,
2105
+ # "frozenFunds": 0,
2106
+ # "availableBalance": 0.00005,
2107
+ # "currency": "XBT"
2108
+ # }
2109
+ # }
2110
+ #
2111
+ return self.parse_balance(response)
2112
+
2113
+ async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
2114
+ """
2115
+ transfer currency internally between wallets on the same account
2116
+ :param str code: unified currency code
2117
+ :param float amount: amount to transfer
2118
+ :param str fromAccount: account to transfer from
2119
+ :param str toAccount: account to transfer to
2120
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2121
+ :returns dict: a `transfer structure <https://docs.ccxt.com/#/?id=transfer-structure>`
2122
+ """
2123
+ if (toAccount != 'main' and toAccount != 'funding') or (fromAccount != 'futures' and fromAccount != 'future' and fromAccount != 'contract'):
2124
+ raise BadRequest(self.id + ' transfer() only supports transfers from contract(future) account to main(funding) account')
2125
+ await self.load_markets()
2126
+ currency = self.currency(code)
2127
+ amountToPrecision = self.currency_to_precision(code, amount)
2128
+ request: dict = {
2129
+ 'currency': self.safe_string(currency, 'id'), # Currency,including XBT,USDT
2130
+ 'amount': amountToPrecision,
2131
+ }
2132
+ # transfer from usdm futures wallet to spot wallet
2133
+ response = await self.futuresPrivatePostTransferOut(self.extend(request, params))
2134
+ #
2135
+ # {
2136
+ # "code": "200000",
2137
+ # "data": {
2138
+ # "applyId": "5bffb63303aa675e8bbe18f9" # Transfer-out request ID
2139
+ # }
2140
+ # }
2141
+ #
2142
+ data = self.safe_value(response, 'data')
2143
+ return self.extend(self.parse_transfer(data, currency), {
2144
+ 'amount': self.parse_number(amountToPrecision),
2145
+ 'fromAccount': 'future',
2146
+ 'toAccount': 'spot',
2147
+ })
2148
+
2149
+ def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
2150
+ #
2151
+ # transfer
2152
+ #
2153
+ # {
2154
+ # "applyId": "5bffb63303aa675e8bbe18f9" # Transfer-out request ID
2155
+ # }
2156
+ #
2157
+ timestamp = self.safe_integer(transfer, 'updatedAt')
2158
+ return {
2159
+ 'id': self.safe_string(transfer, 'applyId'),
2160
+ 'timestamp': timestamp,
2161
+ 'datetime': self.iso8601(timestamp),
2162
+ 'currency': self.safe_currency_code(None, currency),
2163
+ 'amount': None,
2164
+ 'fromAccount': None,
2165
+ 'toAccount': None,
2166
+ 'status': self.safe_string(transfer, 'status'),
2167
+ 'info': transfer,
2168
+ }
2169
+
2170
+ def parse_transfer_status(self, status: Str) -> Str:
2171
+ statuses: dict = {
2172
+ 'PROCESSING': 'pending',
2173
+ }
2174
+ return self.safe_string(statuses, status, status)
2175
+
2176
+ async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2177
+ """
2178
+ :see: https://docs.kucoin.com/futures/#get-fills
2179
+ fetch all trades made by the user
2180
+ :param str symbol: unified market symbol
2181
+ :param int [since]: the earliest time in ms to fetch trades for
2182
+ :param int [limit]: the maximum number of trades structures to retrieve
2183
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2184
+ :param int [params.until]: End time in ms
2185
+ :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)
2186
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
2187
+ """
2188
+ await self.load_markets()
2189
+ paginate = False
2190
+ paginate, params = self.handle_option_and_params(params, 'fetchMyTrades', 'paginate')
2191
+ if paginate:
2192
+ return await self.fetch_paginated_call_dynamic('fetchMyTrades', symbol, since, limit, params)
2193
+ request: dict = {
2194
+ # orderId(str) [optional] Fills for a specific order(other parameters can be ignored if specified)
2195
+ # symbol(str) [optional] Symbol of the contract
2196
+ # side(str) [optional] buy or sell
2197
+ # type(str) [optional] limit, market, limit_stop or market_stop
2198
+ # startAt(long) [optional] Start time(millisecond)
2199
+ # endAt(long) [optional] End time(millisecond)
2200
+ }
2201
+ market = None
2202
+ if symbol is not None:
2203
+ market = self.market(symbol)
2204
+ request['symbol'] = market['id']
2205
+ if since is not None:
2206
+ request['startAt'] = since
2207
+ request, params = self.handle_until_option('endAt', request, params)
2208
+ response = await self.futuresPrivateGetFills(self.extend(request, params))
2209
+ #
2210
+ # {
2211
+ # "code": "200000",
2212
+ # "data": {
2213
+ # "currentPage": 1,
2214
+ # "pageSize": 1,
2215
+ # "totalNum": 251915,
2216
+ # "totalPage": 251915,
2217
+ # "items": [
2218
+ # {
2219
+ # "symbol": "XBTUSDM", # Ticker symbol of the contract
2220
+ # "tradeId": "5ce24c1f0c19fc3c58edc47c", # Trade ID
2221
+ # "orderId": "5ce24c16b210233c36ee321d", # Order ID
2222
+ # "side": "sell", # Transaction side
2223
+ # "liquidity": "taker", # Liquidity- taker or maker
2224
+ # "price": "8302", # Filled price
2225
+ # "size": 10, # Filled amount
2226
+ # "value": "0.001204529", # Order value
2227
+ # "feeRate": "0.0005", # Floating fees
2228
+ # "fixFee": "0.00000006", # Fixed fees
2229
+ # "feeCurrency": "XBT", # Charging currency
2230
+ # "stop": "", # A mark to the stop order type
2231
+ # "fee": "0.0000012022", # Transaction fee
2232
+ # "orderType": "limit", # Order type
2233
+ # "tradeType": "trade", # Trade type(trade, liquidation, ADL or settlement)
2234
+ # "createdAt": 1558334496000, # Time the order created
2235
+ # "settleCurrency": "XBT", # settlement currency
2236
+ # "tradeTime": 1558334496000000000 # trade time in nanosecond
2237
+ # }
2238
+ # ]
2239
+ # }
2240
+ # }
2241
+ #
2242
+ data = self.safe_dict(response, 'data', {})
2243
+ trades = self.safe_list(data, 'items', [])
2244
+ return self.parse_trades(trades, market, since, limit)
2245
+
2246
+ async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
2247
+ """
2248
+ get the list of most recent trades for a particular symbol
2249
+ :see: https://www.kucoin.com/docs/rest/futures-trading/market-data/get-transaction-history
2250
+ :param str symbol: unified symbol of the market to fetch trades for
2251
+ :param int [since]: timestamp in ms of the earliest trade to fetch
2252
+ :param int [limit]: the maximum amount of trades to fetch
2253
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2254
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
2255
+ """
2256
+ await self.load_markets()
2257
+ market = self.market(symbol)
2258
+ request: dict = {
2259
+ 'symbol': market['id'],
2260
+ }
2261
+ response = await self.futuresPublicGetTradeHistory(self.extend(request, params))
2262
+ #
2263
+ # {
2264
+ # "code": "200000",
2265
+ # "data": [
2266
+ # {
2267
+ # "sequence": 32114961,
2268
+ # "side": "buy",
2269
+ # "size": 39,
2270
+ # "price": "4001.6500000000",
2271
+ # "takerOrderId": "61c20742f172110001e0ebe4",
2272
+ # "makerOrderId": "61c2073fcfc88100010fcb5d",
2273
+ # "tradeId": "61c2074277a0c473e69029b8",
2274
+ # "ts": 1640105794099993896 # filled time
2275
+ # }
2276
+ # ]
2277
+ # }
2278
+ #
2279
+ trades = self.safe_list(response, 'data', [])
2280
+ return self.parse_trades(trades, market, since, limit)
2281
+
2282
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
2283
+ #
2284
+ # fetchTrades(public)
2285
+ #
2286
+ # {
2287
+ # "sequence": 32114961,
2288
+ # "side": "buy",
2289
+ # "size": 39,
2290
+ # "price": "4001.6500000000",
2291
+ # "takerOrderId": "61c20742f172110001e0ebe4",
2292
+ # "makerOrderId": "61c2073fcfc88100010fcb5d",
2293
+ # "tradeId": "61c2074277a0c473e69029b8",
2294
+ # "ts": 1640105794099993896 # filled time
2295
+ # }
2296
+ #
2297
+ # fetchMyTrades(private) v2
2298
+ #
2299
+ # {
2300
+ # "symbol":"BTC-USDT",
2301
+ # "tradeId":"5c35c02709e4f67d5266954e",
2302
+ # "orderId":"5c35c02703aa673ceec2a168",
2303
+ # "counterOrderId":"5c1ab46003aa676e487fa8e3",
2304
+ # "side":"buy",
2305
+ # "liquidity":"taker",
2306
+ # "forceTaker":true,
2307
+ # "price":"0.083",
2308
+ # "size":"0.8424304",
2309
+ # "funds":"0.0699217232",
2310
+ # "fee":"0",
2311
+ # "feeRate":"0",
2312
+ # "feeCurrency":"USDT",
2313
+ # "stop":"",
2314
+ # "type":"limit",
2315
+ # "createdAt":1547026472000
2316
+ # }
2317
+ #
2318
+ # fetchMyTrades(private) v1
2319
+ #
2320
+ # {
2321
+ # "symbol":"DOGEUSDTM",
2322
+ # "tradeId":"620ec41a96bab27b5f4ced56",
2323
+ # "orderId":"620ec41a0d1d8a0001560bd0",
2324
+ # "side":"sell",
2325
+ # "liquidity":"taker",
2326
+ # "forceTaker":true,
2327
+ # "price":"0.13969",
2328
+ # "size":1,
2329
+ # "value":"13.969",
2330
+ # "feeRate":"0.0006",
2331
+ # "fixFee":"0",
2332
+ # "feeCurrency":"USDT",
2333
+ # "stop":"",
2334
+ # "tradeTime":1645134874858018058,
2335
+ # "fee":"0.0083814",
2336
+ # "settleCurrency":"USDT",
2337
+ # "orderType":"market",
2338
+ # "tradeType":"trade",
2339
+ # "createdAt":1645134874858
2340
+ # }
2341
+ #
2342
+ # watchTrades
2343
+ #
2344
+ # {
2345
+ # "makerUserId": "62286a4d720edf0001e81961",
2346
+ # "symbol": "ADAUSDTM",
2347
+ # "sequence": 41320766,
2348
+ # "side": "sell",
2349
+ # "size": 2,
2350
+ # "price": 0.35904,
2351
+ # "takerOrderId": "636dd9da9857ba00010cfa44",
2352
+ # "makerOrderId": "636dd9c8df149d0001e62bc8",
2353
+ # "takerUserId": "6180be22b6ab210001fa3371",
2354
+ # "tradeId": "636dd9da0000d400d477eca7",
2355
+ # "ts": 1668143578987357700
2356
+ # }
2357
+ #
2358
+ marketId = self.safe_string(trade, 'symbol')
2359
+ market = self.safe_market(marketId, market, '-')
2360
+ id = self.safe_string_2(trade, 'tradeId', 'id')
2361
+ orderId = self.safe_string(trade, 'orderId')
2362
+ takerOrMaker = self.safe_string(trade, 'liquidity')
2363
+ timestamp = self.safe_integer(trade, 'ts')
2364
+ if timestamp is not None:
2365
+ timestamp = self.parse_to_int(timestamp / 1000000)
2366
+ else:
2367
+ timestamp = self.safe_integer(trade, 'createdAt')
2368
+ # if it's a historical v1 trade, the exchange returns timestamp in seconds
2369
+ if ('dealValue' in trade) and (timestamp is not None):
2370
+ timestamp = timestamp * 1000
2371
+ priceString = self.safe_string_2(trade, 'price', 'dealPrice')
2372
+ amountString = self.safe_string_2(trade, 'size', 'amount')
2373
+ side = self.safe_string(trade, 'side')
2374
+ fee = None
2375
+ feeCostString = self.safe_string(trade, 'fee')
2376
+ if feeCostString is not None:
2377
+ feeCurrencyId = self.safe_string(trade, 'feeCurrency')
2378
+ feeCurrency = self.safe_currency_code(feeCurrencyId)
2379
+ if feeCurrency is None:
2380
+ feeCurrency = market['quote'] if (side == 'sell') else market['base']
2381
+ fee = {
2382
+ 'cost': feeCostString,
2383
+ 'currency': feeCurrency,
2384
+ 'rate': self.safe_string(trade, 'feeRate'),
2385
+ }
2386
+ type = self.safe_string_2(trade, 'type', 'orderType')
2387
+ if type == 'match':
2388
+ type = None
2389
+ costString = self.safe_string_2(trade, 'funds', 'value')
2390
+ if costString is None:
2391
+ contractSize = self.safe_string(market, 'contractSize')
2392
+ contractCost = Precise.string_mul(priceString, amountString)
2393
+ costString = Precise.string_mul(contractCost, contractSize)
2394
+ return self.safe_trade({
2395
+ 'info': trade,
2396
+ 'id': id,
2397
+ 'order': orderId,
2398
+ 'timestamp': timestamp,
2399
+ 'datetime': self.iso8601(timestamp),
2400
+ 'symbol': market['symbol'],
2401
+ 'type': type,
2402
+ 'takerOrMaker': takerOrMaker,
2403
+ 'side': side,
2404
+ 'price': priceString,
2405
+ 'amount': amountString,
2406
+ 'cost': costString,
2407
+ 'fee': fee,
2408
+ }, market)
2409
+
2410
+ async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2411
+ """
2412
+ fetch all deposits made to an account
2413
+ :param str code: unified currency code
2414
+ :param int [since]: the earliest time in ms to fetch deposits for
2415
+ :param int [limit]: the maximum number of deposits structures to retrieve
2416
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2417
+ :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
2418
+ """
2419
+ await self.load_markets()
2420
+ request: dict = {}
2421
+ currency = None
2422
+ if code is not None:
2423
+ currency = self.currency(code)
2424
+ request['currency'] = currency['id']
2425
+ if limit is not None:
2426
+ request['pageSize'] = limit
2427
+ if since is not None:
2428
+ request['startAt'] = since
2429
+ response = await self.futuresPrivateGetDepositList(self.extend(request, params))
2430
+ #
2431
+ # {
2432
+ # "code": "200000",
2433
+ # "data": {
2434
+ # "currentPage": 1,
2435
+ # "pageSize": 5,
2436
+ # "totalNum": 2,
2437
+ # "totalPage": 1,
2438
+ # "items": [
2439
+ # {
2440
+ # "address": "0x5f047b29041bcfdbf0e4478cdfa753a336ba6989",
2441
+ # "memo": "5c247c8a03aa677cea2a251d",
2442
+ # "amount": 1,
2443
+ # "fee": 0.0001,
2444
+ # "currency": "KCS",
2445
+ # "isInner": False,
2446
+ # "walletTxId": "5bbb57386d99522d9f954c5a@test004",
2447
+ # "status": "SUCCESS",
2448
+ # "createdAt": 1544178843000,
2449
+ # "updatedAt": 1544178891000
2450
+ # "remark":"foobar"
2451
+ # },
2452
+ # ...
2453
+ # ]
2454
+ # }
2455
+ # }
2456
+ #
2457
+ responseData = response['data']['items']
2458
+ return self.parse_transactions(responseData, currency, since, limit, {'type': 'deposit'})
2459
+
2460
+ async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2461
+ """
2462
+ fetch all withdrawals made from an account
2463
+ :param str code: unified currency code
2464
+ :param int [since]: the earliest time in ms to fetch withdrawals for
2465
+ :param int [limit]: the maximum number of withdrawals structures to retrieve
2466
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2467
+ :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
2468
+ """
2469
+ await self.load_markets()
2470
+ request: dict = {}
2471
+ currency = None
2472
+ if code is not None:
2473
+ currency = self.currency(code)
2474
+ request['currency'] = currency['id']
2475
+ if limit is not None:
2476
+ request['pageSize'] = limit
2477
+ if since is not None:
2478
+ request['startAt'] = since
2479
+ response = await self.futuresPrivateGetWithdrawalList(self.extend(request, params))
2480
+ #
2481
+ # {
2482
+ # "code": "200000",
2483
+ # "data": {
2484
+ # "currentPage": 1,
2485
+ # "pageSize": 5,
2486
+ # "totalNum": 2,
2487
+ # "totalPage": 1,
2488
+ # "items": [
2489
+ # {
2490
+ # "id": "5c2dc64e03aa675aa263f1ac",
2491
+ # "address": "0x5bedb060b8eb8d823e2414d82acce78d38be7fe9",
2492
+ # "memo": "",
2493
+ # "currency": "ETH",
2494
+ # "amount": 1.0000000,
2495
+ # "fee": 0.0100000,
2496
+ # "walletTxId": "3e2414d82acce78d38be7fe9",
2497
+ # "isInner": False,
2498
+ # "status": "FAILURE",
2499
+ # "createdAt": 1546503758000,
2500
+ # "updatedAt": 1546504603000
2501
+ # },
2502
+ # ...
2503
+ # ]
2504
+ # }
2505
+ # }
2506
+ #
2507
+ responseData = response['data']['items']
2508
+ return self.parse_transactions(responseData, currency, since, limit, {'type': 'withdrawal'})
2509
+
2510
+ async def fetch_market_leverage_tiers(self, symbol: str, params={}) -> List[LeverageTier]:
2511
+ """
2512
+ retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes for a single market
2513
+ :see: https://www.kucoin.com/docs/rest/futures-trading/risk-limit/get-futures-risk-limit-level
2514
+ :param str symbol: unified market symbol
2515
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2516
+ :returns dict: a `leverage tiers structure <https://docs.ccxt.com/#/?id=leverage-tiers-structure>`
2517
+ """
2518
+ await self.load_markets()
2519
+ market = self.market(symbol)
2520
+ if not market['contract']:
2521
+ raise BadRequest(self.id + ' fetchMarketLeverageTiers() supports contract markets only')
2522
+ request: dict = {
2523
+ 'symbol': market['id'],
2524
+ }
2525
+ response = await self.futuresPublicGetContractsRiskLimitSymbol(self.extend(request, params))
2526
+ #
2527
+ # {
2528
+ # "code": "200000",
2529
+ # "data": [
2530
+ # {
2531
+ # "symbol": "ETHUSDTM",
2532
+ # "level": 1,
2533
+ # "maxRiskLimit": 300000,
2534
+ # "minRiskLimit": 0,
2535
+ # "maxLeverage": 100,
2536
+ # "initialMargin": 0.0100000000,
2537
+ # "maintainMargin": 0.0050000000
2538
+ # },
2539
+ # ...
2540
+ # ]
2541
+ # }
2542
+ #
2543
+ data = self.safe_value(response, 'data')
2544
+ return self.parse_market_leverage_tiers(data, market)
2545
+
2546
+ def parse_market_leverage_tiers(self, info, market: Market = None) -> List[LeverageTier]:
2547
+ """
2548
+ * @ignore
2549
+ :param dict info: Exchange market response for 1 market
2550
+ :param dict market: CCXT market
2551
+ """
2552
+ #
2553
+ # {
2554
+ # "symbol": "ETHUSDTM",
2555
+ # "level": 1,
2556
+ # "maxRiskLimit": 300000,
2557
+ # "minRiskLimit": 0,
2558
+ # "maxLeverage": 100,
2559
+ # "initialMargin": 0.0100000000,
2560
+ # "maintainMargin": 0.0050000000
2561
+ # }
2562
+ #
2563
+ tiers = []
2564
+ for i in range(0, len(info)):
2565
+ tier = info[i]
2566
+ tiers.append({
2567
+ 'tier': self.safe_number(tier, 'level'),
2568
+ 'currency': market['base'],
2569
+ 'minNotional': self.safe_number(tier, 'minRiskLimit'),
2570
+ 'maxNotional': self.safe_number(tier, 'maxRiskLimit'),
2571
+ 'maintenanceMarginRate': self.safe_number(tier, 'maintainMargin'),
2572
+ 'maxLeverage': self.safe_number(tier, 'maxLeverage'),
2573
+ 'info': tier,
2574
+ })
2575
+ return tiers
2576
+
2577
+ async def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2578
+ """
2579
+ :see: https://www.kucoin.com/docs/rest/futures-trading/funding-fees/get-public-funding-history#request-url
2580
+ fetches historical funding rate prices
2581
+ :param str symbol: unified symbol of the market to fetch the funding rate history for
2582
+ :param int [since]: not used by kucuoinfutures
2583
+ :param int [limit]: the maximum amount of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>` to fetch
2584
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2585
+ :param int [params.until]: end time in ms
2586
+ :returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>`
2587
+ """
2588
+ if symbol is None:
2589
+ raise ArgumentsRequired(self.id + ' fetchFundingRateHistory() requires a symbol argument')
2590
+ await self.load_markets()
2591
+ market = self.market(symbol)
2592
+ request: dict = {
2593
+ 'symbol': market['id'],
2594
+ 'from': 0,
2595
+ 'to': self.milliseconds(),
2596
+ }
2597
+ until = self.safe_integer(params, 'until')
2598
+ params = self.omit(params, ['until'])
2599
+ if since is not None:
2600
+ request['from'] = since
2601
+ if until is None:
2602
+ request['to'] = since + 1000 * 8 * 60 * 60 * 100
2603
+ if until is not None:
2604
+ request['to'] = until
2605
+ if since is None:
2606
+ request['to'] = until - 1000 * 8 * 60 * 60 * 100
2607
+ response = await self.futuresPublicGetContractFundingRates(self.extend(request, params))
2608
+ #
2609
+ # {
2610
+ # "code": "200000",
2611
+ # "data": [
2612
+ # {
2613
+ # "symbol": "IDUSDTM",
2614
+ # "fundingRate": 2.26E-4,
2615
+ # "timepoint": 1702296000000
2616
+ # }
2617
+ # ]
2618
+ # }
2619
+ #
2620
+ data = self.safe_value(response, 'data')
2621
+ return self.parse_funding_rate_histories(data, market, since, limit)
2622
+
2623
+ def parse_funding_rate_history(self, info, market: Market = None):
2624
+ timestamp = self.safe_integer(info, 'timepoint')
2625
+ marketId = self.safe_string(info, 'symbol')
2626
+ return {
2627
+ 'info': info,
2628
+ 'symbol': self.safe_symbol(marketId, market),
2629
+ 'fundingRate': self.safe_number(info, 'fundingRate'),
2630
+ 'timestamp': timestamp,
2631
+ 'datetime': self.iso8601(timestamp),
2632
+ }
2633
+
2634
+ async def close_position(self, symbol: str, side: OrderSide = None, params={}) -> Order:
2635
+ """
2636
+ closes open positions for a market
2637
+ :see: https://www.kucoin.com/docs/rest/futures-trading/orders/place-order
2638
+ :param str symbol: Unified CCXT market symbol
2639
+ :param str side: not used by kucoinfutures closePositions
2640
+ :param dict [params]: extra parameters specific to the okx api endpoint
2641
+ :param str [params.clientOrderId]: client order id of the order
2642
+ :returns dict[]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
2643
+ """
2644
+ await self.load_markets()
2645
+ market = self.market(symbol)
2646
+ clientOrderId = self.safe_string(params, 'clientOrderId')
2647
+ testOrder = self.safe_bool(params, 'test', False)
2648
+ params = self.omit(params, ['test', 'clientOrderId'])
2649
+ if clientOrderId is None:
2650
+ clientOrderId = self.number_to_string(self.nonce())
2651
+ request: dict = {
2652
+ 'symbol': market['id'],
2653
+ 'closeOrder': True,
2654
+ 'clientOid': clientOrderId,
2655
+ 'type': 'market',
2656
+ }
2657
+ response = None
2658
+ if testOrder:
2659
+ response = await self.futuresPrivatePostOrdersTest(self.extend(request, params))
2660
+ else:
2661
+ response = await self.futuresPrivatePostOrders(self.extend(request, params))
2662
+ return self.parse_order(response, market)
2663
+
2664
+ async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
2665
+ """
2666
+ fetch the trading fees for a market
2667
+ :see: https://www.kucoin.com/docs/rest/funding/trade-fee/trading-pair-actual-fee-futures
2668
+ :param str symbol: unified market symbol
2669
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2670
+ :returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
2671
+ """
2672
+ await self.load_markets()
2673
+ market = self.market(symbol)
2674
+ request: dict = {
2675
+ 'symbols': market['id'],
2676
+ }
2677
+ response = await self.privateGetTradeFees(self.extend(request, params))
2678
+ #
2679
+ # {
2680
+ # "code": "200000",
2681
+ # "data": {
2682
+ # "symbol": "XBTUSDTM",
2683
+ # "takerFeeRate": "0.0006",
2684
+ # "makerFeeRate": "0.0002"
2685
+ # }
2686
+ # }
2687
+ #
2688
+ data = self.safe_list(response, 'data', [])
2689
+ first = self.safe_dict(data, 0)
2690
+ marketId = self.safe_string(first, 'symbol')
2691
+ return {
2692
+ 'info': response,
2693
+ 'symbol': self.safe_symbol(marketId, market),
2694
+ 'maker': self.safe_number(first, 'makerFeeRate'),
2695
+ 'taker': self.safe_number(first, 'takerFeeRate'),
2696
+ 'percentage': True,
2697
+ 'tierBased': True,
2698
+ }