ccxt-look 1.81.50

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 (264) hide show
  1. package/.cache/eslintcache +1 -0
  2. package/.dockerignore +6 -0
  3. package/.eslintignore +1 -0
  4. package/.gitattributes +5 -0
  5. package/.readthedocs.yaml +16 -0
  6. package/CONTRIBUTING.md +1049 -0
  7. package/LICENSE.txt +21 -0
  8. package/README.md +537 -0
  9. package/SECURITY.md +5 -0
  10. package/build/cleanup-old-tags.js +94 -0
  11. package/build/countries.js +256 -0
  12. package/build/export-exchanges.js +520 -0
  13. package/build/fs.js +51 -0
  14. package/build/transpile.js +1772 -0
  15. package/build/vss.js +78 -0
  16. package/ccxt.browser.js +7 -0
  17. package/ccxt.d.ts +692 -0
  18. package/ccxt.js +171 -0
  19. package/cleanup.sh +2 -0
  20. package/composer-install.sh +20 -0
  21. package/dist/ccxt.browser.js +208383 -0
  22. package/gource.sh +3 -0
  23. package/index.html +7 -0
  24. package/js/.eslintrc +87 -0
  25. package/js/aax.js +2686 -0
  26. package/js/ascendex.js +2584 -0
  27. package/js/base/.eslintrc.js +43 -0
  28. package/js/base/Exchange.js +2371 -0
  29. package/js/base/Precise.js +283 -0
  30. package/js/base/errorHierarchy.js +47 -0
  31. package/js/base/errors.js +55 -0
  32. package/js/base/functions/crypto.js +158 -0
  33. package/js/base/functions/encode.js +118 -0
  34. package/js/base/functions/generic.js +270 -0
  35. package/js/base/functions/misc.js +138 -0
  36. package/js/base/functions/number.js +329 -0
  37. package/js/base/functions/platform.js +38 -0
  38. package/js/base/functions/string.js +21 -0
  39. package/js/base/functions/throttle.js +79 -0
  40. package/js/base/functions/time.js +210 -0
  41. package/js/base/functions/type.js +66 -0
  42. package/js/base/functions.js +28 -0
  43. package/js/bequant.js +32 -0
  44. package/js/bibox.js +1407 -0
  45. package/js/bigone.js +1366 -0
  46. package/js/binance.js +5652 -0
  47. package/js/binancecoinm.js +46 -0
  48. package/js/binanceus.js +46 -0
  49. package/js/binanceusdm.js +49 -0
  50. package/js/bit2c.js +535 -0
  51. package/js/bitbank.js +842 -0
  52. package/js/bitbay.js +16 -0
  53. package/js/bitbns.js +1073 -0
  54. package/js/bitcoincom.js +15 -0
  55. package/js/bitfinex.js +1433 -0
  56. package/js/bitfinex2.js +2025 -0
  57. package/js/bitflyer.js +840 -0
  58. package/js/bitforex.js +614 -0
  59. package/js/bitget.js +2397 -0
  60. package/js/bithumb.js +980 -0
  61. package/js/bitmart.js +2516 -0
  62. package/js/bitmex.js +1809 -0
  63. package/js/bitopro.js +1443 -0
  64. package/js/bitpanda.js +1782 -0
  65. package/js/bitrue.js +1747 -0
  66. package/js/bitso.js +1062 -0
  67. package/js/bitstamp.js +1757 -0
  68. package/js/bitstamp1.js +343 -0
  69. package/js/bittrex.js +1876 -0
  70. package/js/bitvavo.js +1579 -0
  71. package/js/bkex.js +1233 -0
  72. package/js/bl3p.js +346 -0
  73. package/js/blockchaincom.js +969 -0
  74. package/js/btcalpha.js +680 -0
  75. package/js/btcbox.js +477 -0
  76. package/js/btcmarkets.js +1022 -0
  77. package/js/btctradeua.js +466 -0
  78. package/js/btcturk.js +734 -0
  79. package/js/buda.js +946 -0
  80. package/js/bw.js +1265 -0
  81. package/js/bybit.js +3372 -0
  82. package/js/bytetrade.js +1336 -0
  83. package/js/cdax.js +1646 -0
  84. package/js/cex.js +1410 -0
  85. package/js/coinbase.js +1342 -0
  86. package/js/coinbaseprime.js +31 -0
  87. package/js/coinbasepro.js +1466 -0
  88. package/js/coincheck.js +755 -0
  89. package/js/coinex.js +3400 -0
  90. package/js/coinfalcon.js +880 -0
  91. package/js/coinmate.js +794 -0
  92. package/js/coinone.js +816 -0
  93. package/js/coinspot.js +345 -0
  94. package/js/crex24.js +1636 -0
  95. package/js/cryptocom.js +1832 -0
  96. package/js/currencycom.js +1748 -0
  97. package/js/delta.js +1547 -0
  98. package/js/deribit.js +2148 -0
  99. package/js/digifinex.js +1585 -0
  100. package/js/eqonex.js +1660 -0
  101. package/js/exmo.js +1670 -0
  102. package/js/fairdesk.js +1231 -0
  103. package/js/flowbtc.js +35 -0
  104. package/js/fmfwio.js +34 -0
  105. package/js/ftx.js +2751 -0
  106. package/js/ftxus.js +38 -0
  107. package/js/gateio.js +4174 -0
  108. package/js/gemini.js +1397 -0
  109. package/js/hitbtc.js +1343 -0
  110. package/js/hitbtc3.js +2329 -0
  111. package/js/hollaex.js +1486 -0
  112. package/js/huobi.js +5706 -0
  113. package/js/huobijp.js +1710 -0
  114. package/js/huobipro.js +18 -0
  115. package/js/idex.js +1439 -0
  116. package/js/independentreserve.js +649 -0
  117. package/js/indodax.js +742 -0
  118. package/js/itbit.js +722 -0
  119. package/js/kraken.js +2179 -0
  120. package/js/kucoin.js +2571 -0
  121. package/js/kucoinfutures.js +1771 -0
  122. package/js/kuna.js +809 -0
  123. package/js/latoken.js +1445 -0
  124. package/js/lbank.js +760 -0
  125. package/js/liquid.js +1432 -0
  126. package/js/luno.js +873 -0
  127. package/js/lykke.js +1147 -0
  128. package/js/mercado.js +771 -0
  129. package/js/mexc.js +3151 -0
  130. package/js/ndax.js +2233 -0
  131. package/js/novadax.js +1318 -0
  132. package/js/oceanex.js +816 -0
  133. package/js/okcoin.js +3841 -0
  134. package/js/okex.js +16 -0
  135. package/js/okex5.js +16 -0
  136. package/js/okx.js +4795 -0
  137. package/js/paymium.js +498 -0
  138. package/js/phemex.js +2957 -0
  139. package/js/poloniex.js +1674 -0
  140. package/js/probit.js +1346 -0
  141. package/js/qtrade.js +1588 -0
  142. package/js/ripio.js +1061 -0
  143. package/js/static_dependencies/BN/bn.js +3526 -0
  144. package/js/static_dependencies/README.md +1 -0
  145. package/js/static_dependencies/crypto-js/crypto-js.js +5988 -0
  146. package/js/static_dependencies/elliptic/lib/elliptic/curve/base.js +375 -0
  147. package/js/static_dependencies/elliptic/lib/elliptic/curve/edwards.js +433 -0
  148. package/js/static_dependencies/elliptic/lib/elliptic/curve/index.js +8 -0
  149. package/js/static_dependencies/elliptic/lib/elliptic/curve/mont.js +180 -0
  150. package/js/static_dependencies/elliptic/lib/elliptic/curve/short.js +938 -0
  151. package/js/static_dependencies/elliptic/lib/elliptic/curves.js +204 -0
  152. package/js/static_dependencies/elliptic/lib/elliptic/ec/index.js +240 -0
  153. package/js/static_dependencies/elliptic/lib/elliptic/ec/key.js +119 -0
  154. package/js/static_dependencies/elliptic/lib/elliptic/ec/signature.js +24 -0
  155. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/index.js +145 -0
  156. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/key.js +100 -0
  157. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/signature.js +65 -0
  158. package/js/static_dependencies/elliptic/lib/elliptic/precomputed/secp256k1.js +780 -0
  159. package/js/static_dependencies/elliptic/lib/elliptic/utils.js +214 -0
  160. package/js/static_dependencies/elliptic/lib/elliptic.js +22 -0
  161. package/js/static_dependencies/elliptic/lib/hmac-drbg/hmac-drbg.js +114 -0
  162. package/js/static_dependencies/fetch-ponyfill/fetch-node.js +39 -0
  163. package/js/static_dependencies/node-fetch/index.js +1564 -0
  164. package/js/static_dependencies/node-rsa/NodeRSA.js +223 -0
  165. package/js/static_dependencies/node-rsa/asn1/ber/errors.js +13 -0
  166. package/js/static_dependencies/node-rsa/asn1/ber/index.js +21 -0
  167. package/js/static_dependencies/node-rsa/asn1/ber/reader.js +262 -0
  168. package/js/static_dependencies/node-rsa/asn1/ber/types.js +36 -0
  169. package/js/static_dependencies/node-rsa/asn1/index.js +17 -0
  170. package/js/static_dependencies/node-rsa/encryptEngines/js.js +34 -0
  171. package/js/static_dependencies/node-rsa/formats/components.js +71 -0
  172. package/js/static_dependencies/node-rsa/formats/formats.js +31 -0
  173. package/js/static_dependencies/node-rsa/formats/pkcs1.js +148 -0
  174. package/js/static_dependencies/node-rsa/formats/pkcs8.js +187 -0
  175. package/js/static_dependencies/node-rsa/libs/jsbn.js +1252 -0
  176. package/js/static_dependencies/node-rsa/libs/rsa.js +147 -0
  177. package/js/static_dependencies/node-rsa/schemes/pkcs1.js +176 -0
  178. package/js/static_dependencies/node-rsa/schemes/schemes.js +21 -0
  179. package/js/static_dependencies/node-rsa/utils.js +98 -0
  180. package/js/static_dependencies/qs/formats.js +18 -0
  181. package/js/static_dependencies/qs/index.js +11 -0
  182. package/js/static_dependencies/qs/parse.js +242 -0
  183. package/js/static_dependencies/qs/stringify.js +269 -0
  184. package/js/static_dependencies/qs/utils.js +230 -0
  185. package/js/stex.js +1925 -0
  186. package/js/test/.eslintrc.js +42 -0
  187. package/js/test/Exchange/test.balance.js +61 -0
  188. package/js/test/Exchange/test.borrowRate.js +32 -0
  189. package/js/test/Exchange/test.currency.js +52 -0
  190. package/js/test/Exchange/test.fetchBalance.js +23 -0
  191. package/js/test/Exchange/test.fetchBorrowInterest.js +59 -0
  192. package/js/test/Exchange/test.fetchBorrowRate.js +32 -0
  193. package/js/test/Exchange/test.fetchBorrowRates.js +28 -0
  194. package/js/test/Exchange/test.fetchClosedOrders.js +32 -0
  195. package/js/test/Exchange/test.fetchCurrencies.js +35 -0
  196. package/js/test/Exchange/test.fetchDeposits.js +31 -0
  197. package/js/test/Exchange/test.fetchFundingFees.js +19 -0
  198. package/js/test/Exchange/test.fetchFundingRateHistory.js +40 -0
  199. package/js/test/Exchange/test.fetchL2OrderBook.js +23 -0
  200. package/js/test/Exchange/test.fetchLedger.js +42 -0
  201. package/js/test/Exchange/test.fetchLeverageTiers.js +33 -0
  202. package/js/test/Exchange/test.fetchMarketLeverageTiers.js +22 -0
  203. package/js/test/Exchange/test.fetchMarkets.js +33 -0
  204. package/js/test/Exchange/test.fetchMyTrades.js +42 -0
  205. package/js/test/Exchange/test.fetchOHLCV.js +46 -0
  206. package/js/test/Exchange/test.fetchOpenOrders.js +36 -0
  207. package/js/test/Exchange/test.fetchOrderBook.js +25 -0
  208. package/js/test/Exchange/test.fetchOrderBooks.js +35 -0
  209. package/js/test/Exchange/test.fetchOrders.js +41 -0
  210. package/js/test/Exchange/test.fetchPositions.js +47 -0
  211. package/js/test/Exchange/test.fetchStatus.js +35 -0
  212. package/js/test/Exchange/test.fetchTicker.js +38 -0
  213. package/js/test/Exchange/test.fetchTickers.js +49 -0
  214. package/js/test/Exchange/test.fetchTrades.js +39 -0
  215. package/js/test/Exchange/test.fetchTradingFee.js +18 -0
  216. package/js/test/Exchange/test.fetchTradingFees.js +22 -0
  217. package/js/test/Exchange/test.fetchTransactions.js +31 -0
  218. package/js/test/Exchange/test.fetchWithdrawals.js +31 -0
  219. package/js/test/Exchange/test.ledgerItem.js +46 -0
  220. package/js/test/Exchange/test.leverageTier.js +33 -0
  221. package/js/test/Exchange/test.loadMarkets.js +35 -0
  222. package/js/test/Exchange/test.market.js +129 -0
  223. package/js/test/Exchange/test.ohlcv.js +33 -0
  224. package/js/test/Exchange/test.order.js +62 -0
  225. package/js/test/Exchange/test.orderbook.js +61 -0
  226. package/js/test/Exchange/test.position.js +21 -0
  227. package/js/test/Exchange/test.throttle.js +94 -0
  228. package/js/test/Exchange/test.ticker.js +95 -0
  229. package/js/test/Exchange/test.trade.js +68 -0
  230. package/js/test/Exchange/test.tradingFee.js +34 -0
  231. package/js/test/Exchange/test.transaction.js +35 -0
  232. package/js/test/base/.eslintrc +38 -0
  233. package/js/test/base/functions/test.crypto.js +110 -0
  234. package/js/test/base/functions/test.datetime.js +62 -0
  235. package/js/test/base/functions/test.generic.js +152 -0
  236. package/js/test/base/functions/test.number.js +362 -0
  237. package/js/test/base/functions/test.time.js +56 -0
  238. package/js/test/base/functions/test.type.js +53 -0
  239. package/js/test/base/test.base.js +193 -0
  240. package/js/test/errors/test.InsufficientFunds.js +86 -0
  241. package/js/test/errors/test.InvalidNonce.js +64 -0
  242. package/js/test/errors/test.InvalidOrder.js +35 -0
  243. package/js/test/errors/test.OrderNotFound.js +39 -0
  244. package/js/test/test.js +426 -0
  245. package/js/test/test.timeout_hang.js +12 -0
  246. package/js/therock.js +1431 -0
  247. package/js/tidebit.js +632 -0
  248. package/js/tidex.js +939 -0
  249. package/js/timex.js +1283 -0
  250. package/js/upbit.js +1622 -0
  251. package/js/vcc.js +1353 -0
  252. package/js/wavesexchange.js +2185 -0
  253. package/js/wazirx.js +732 -0
  254. package/js/whitebit.js +1352 -0
  255. package/js/woo.js +1577 -0
  256. package/js/xena.js +1948 -0
  257. package/js/yobit.js +1129 -0
  258. package/js/zaif.js +647 -0
  259. package/js/zb.js +4088 -0
  260. package/js/zipmex.js +40 -0
  261. package/js/zonda.js +1497 -0
  262. package/multilang.sh +159 -0
  263. package/package.json +591 -0
  264. package/postinstall.js +103 -0
@@ -0,0 +1,1771 @@
1
+ 'use strict';
2
+
3
+ // ---------------------------------------------------------------------------
4
+
5
+ const { ArgumentsRequired, ExchangeNotAvailable, InvalidOrder, InsufficientFunds, AccountSuspended, InvalidNonce, NotSupported, BadRequest, AuthenticationError, RateLimitExceeded, PermissionDenied } = require ('./base/errors');
6
+ const Precise = require ('./base/Precise');
7
+ const kucoin = require ('./kucoin.js');
8
+ const { TICK_SIZE } = require ('./base/functions/number');
9
+
10
+ // ---------------------------------------------------------------------------
11
+
12
+ module.exports = class kucoinfutures extends kucoin {
13
+ describe () {
14
+ return this.deepExtend (super.describe (), {
15
+ 'id': 'kucoinfutures',
16
+ 'name': 'KuCoin Futures',
17
+ 'countries': [ 'SC' ],
18
+ 'rateLimit': 75,
19
+ 'version': 'v1',
20
+ 'certified': false,
21
+ 'pro': false,
22
+ 'comment': 'Platform 2.0',
23
+ 'quoteJsonNumbers': false,
24
+ 'has': {
25
+ 'CORS': undefined,
26
+ 'spot': false,
27
+ 'margin': false,
28
+ 'swap': true,
29
+ 'future': true,
30
+ 'option': false,
31
+ 'addMargin': true,
32
+ 'cancelAllOrders': true,
33
+ 'cancelOrder': true,
34
+ 'createDepositAddress': true,
35
+ 'createOrder': true,
36
+ 'createStopLimitOrder': true,
37
+ 'createStopMarketOrder': true,
38
+ 'createStopOrder': true,
39
+ 'fetchAccounts': true,
40
+ 'fetchBalance': true,
41
+ 'fetchBorrowRate': false,
42
+ 'fetchBorrowRateHistories': false,
43
+ 'fetchBorrowRateHistory': false,
44
+ 'fetchBorrowRates': false,
45
+ 'fetchBorrowRatesPerSymbol': false,
46
+ 'fetchClosedOrders': true,
47
+ 'fetchCurrencies': false,
48
+ 'fetchDepositAddress': true,
49
+ 'fetchDeposits': true,
50
+ 'fetchFundingFee': true,
51
+ 'fetchFundingHistory': true,
52
+ 'fetchFundingRate': true,
53
+ 'fetchFundingRateHistory': false,
54
+ 'fetchIndexOHLCV': false,
55
+ 'fetchL3OrderBook': true,
56
+ 'fetchLedger': true,
57
+ 'fetchLeverageTiers': false,
58
+ 'fetchMarketLeverageTiers': true,
59
+ 'fetchMarkets': true,
60
+ 'fetchMarkOHLCV': false,
61
+ 'fetchMyTrades': true,
62
+ 'fetchOHLCV': true,
63
+ 'fetchOpenOrders': true,
64
+ 'fetchOrder': true,
65
+ 'fetchOrderBook': true,
66
+ 'fetchPositions': true,
67
+ 'fetchPremiumIndexOHLCV': false,
68
+ 'fetchStatus': true,
69
+ 'fetchTicker': true,
70
+ 'fetchTickers': false,
71
+ 'fetchTime': true,
72
+ 'fetchTrades': true,
73
+ 'fetchWithdrawals': true,
74
+ 'setMarginMode': false,
75
+ 'transfer': true,
76
+ 'withdraw': undefined,
77
+ },
78
+ 'urls': {
79
+ 'logo': 'https://user-images.githubusercontent.com/1294454/147508995-9e35030a-d046-43a1-a006-6fabd981b554.jpg',
80
+ 'doc': [
81
+ 'https://docs.kucoin.com/futures',
82
+ 'https://docs.kucoin.com',
83
+ ],
84
+ 'www': 'https://futures.kucoin.com/',
85
+ 'referral': 'https://futures.kucoin.com/?rcode=E5wkqe',
86
+ 'api': {
87
+ 'public': 'https://openapi-v2.kucoin.com',
88
+ 'private': 'https://openapi-v2.kucoin.com',
89
+ 'futuresPrivate': 'https://api-futures.kucoin.com',
90
+ 'futuresPublic': 'https://api-futures.kucoin.com',
91
+ },
92
+ 'test': {
93
+ 'public': 'https://openapi-sandbox.kucoin.com',
94
+ 'private': 'https://openapi-sandbox.kucoin.com',
95
+ 'futuresPrivate': 'https://api-sandbox-futures.kucoin.com',
96
+ 'futuresPublic': 'https://api-sandbox-futures.kucoin.com',
97
+ },
98
+ },
99
+ 'requiredCredentials': {
100
+ 'apiKey': true,
101
+ 'secret': true,
102
+ 'password': true,
103
+ },
104
+ 'api': {
105
+ 'futuresPublic': {
106
+ 'get': {
107
+ 'contracts/active': 1,
108
+ 'contracts/{symbol}': 1,
109
+ 'contracts/risk-limit/{symbol}': 1,
110
+ 'ticker': 1,
111
+ 'level2/snapshot': 1.33,
112
+ 'level2/depth{limit}': 1,
113
+ 'level2/message/query': 1,
114
+ 'level3/message/query': 1, // deprecated,level3/snapshot is suggested
115
+ 'level3/snapshot': 1, // v2
116
+ 'trade/history': 1,
117
+ 'interest/query': 1,
118
+ 'index/query': 1,
119
+ 'mark-price/{symbol}/current': 1,
120
+ 'premium/query': 1,
121
+ 'funding-rate/{symbol}/current': 1,
122
+ 'timestamp': 1,
123
+ 'status': 1,
124
+ 'kline/query': 1,
125
+ },
126
+ 'post': {
127
+ 'bullet-public': 1,
128
+ },
129
+ },
130
+ 'futuresPrivate': {
131
+ 'get': {
132
+ 'account-overview': 1.33,
133
+ 'transaction-history': 4.44,
134
+ 'deposit-address': 1,
135
+ 'deposit-list': 1,
136
+ 'withdrawals/quotas': 1,
137
+ 'withdrawal-list': 1,
138
+ 'transfer-list': 1,
139
+ 'orders': 1.33,
140
+ 'stopOrders': 1,
141
+ 'recentDoneOrders': 1,
142
+ 'orders/{orderId}': 1, // ?clientOid={client-order-id} // get order by orderId
143
+ 'orders/byClientOid': 1, // ?clientOid=eresc138b21023a909e5ad59 // get order by clientOid
144
+ 'fills': 4.44,
145
+ 'recentFills': 4.44,
146
+ 'openOrderStatistics': 1,
147
+ 'position': 1,
148
+ 'positions': 4.44,
149
+ 'funding-history': 4.44,
150
+ },
151
+ 'post': {
152
+ 'withdrawals': 1,
153
+ 'transfer-out': 1, // v2
154
+ 'orders': 1.33,
155
+ 'position/margin/auto-deposit-status': 1,
156
+ 'position/margin/deposit-margin': 1,
157
+ 'bullet-private': 1,
158
+ },
159
+ 'delete': {
160
+ 'withdrawals/{withdrawalId}': 1,
161
+ 'cancel/transfer-out': 1,
162
+ 'orders/{orderId}': 1,
163
+ 'orders': 4.44,
164
+ 'stopOrders': 1,
165
+ },
166
+ },
167
+ },
168
+ 'precisionMode': TICK_SIZE,
169
+ 'exceptions': {
170
+ 'exact': {
171
+ '400': BadRequest, // Bad Request -- Invalid request format
172
+ '401': AuthenticationError, // Unauthorized -- Invalid API Key
173
+ '403': NotSupported, // Forbidden -- The request is forbidden
174
+ '404': NotSupported, // Not Found -- The specified resource could not be found
175
+ '405': NotSupported, // Method Not Allowed -- You tried to access the resource with an invalid method.
176
+ '415': BadRequest, // Content-Type -- application/json
177
+ '429': RateLimitExceeded, // Too Many Requests -- Access limit breached
178
+ '500': ExchangeNotAvailable, // Internal Server Error -- We had a problem with our server. Try again later.
179
+ '503': ExchangeNotAvailable, // Service Unavailable -- We're temporarily offline for maintenance. Please try again later.
180
+ '100001': InvalidOrder, // {"code":"100001","msg":"Unavailable to enable both \"postOnly\" and \"hidden\""}
181
+ '100004': BadRequest, // {"code":"100004","msg":"Order is in not cancelable state"}
182
+ '101030': PermissionDenied, // {"code":"101030","msg":"You haven't yet enabled the margin trading"}
183
+ '200004': InsufficientFunds,
184
+ '230003': InsufficientFunds, // {"code":"230003","msg":"Balance insufficient!"}
185
+ '260100': InsufficientFunds, // {"code":"260100","msg":"account.noBalance"}
186
+ '300003': InsufficientFunds,
187
+ '300012': InvalidOrder,
188
+ '400001': AuthenticationError, // Any of KC-API-KEY, KC-API-SIGN, KC-API-TIMESTAMP, KC-API-PASSPHRASE is missing in your request header.
189
+ '400002': InvalidNonce, // KC-API-TIMESTAMP Invalid -- Time differs from server time by more than 5 seconds
190
+ '400003': AuthenticationError, // KC-API-KEY not exists
191
+ '400004': AuthenticationError, // KC-API-PASSPHRASE error
192
+ '400005': AuthenticationError, // Signature error -- Please check your signature
193
+ '400006': AuthenticationError, // The IP address is not in the API whitelist
194
+ '400007': AuthenticationError, // Access Denied -- Your API key does not have sufficient permissions to access the URI
195
+ '404000': NotSupported, // URL Not Found -- The requested resource could not be found
196
+ '400100': BadRequest, // Parameter Error -- You tried to access the resource with invalid parameters
197
+ '411100': AccountSuspended, // User is frozen -- Please contact us via support center
198
+ '500000': ExchangeNotAvailable, // Internal Server Error -- We had a problem with our server. Try again later.
199
+ },
200
+ },
201
+ 'fees': {
202
+ 'trading': {
203
+ 'tierBased': true,
204
+ 'percentage': true,
205
+ 'taker': this.parseNumber ('0.0006'),
206
+ 'maker': this.parseNumber ('0.0002'),
207
+ 'tiers': {
208
+ 'taker': [
209
+ [ this.parseNumber ('0'), this.parseNumber ('0.0006') ],
210
+ [ this.parseNumber ('50'), this.parseNumber ('0.0006') ],
211
+ [ this.parseNumber ('200'), this.parseNumber ('0.0006') ],
212
+ [ this.parseNumber ('500'), this.parseNumber ('0.0005') ],
213
+ [ this.parseNumber ('1000'), this.parseNumber ('0.0004') ],
214
+ [ this.parseNumber ('2000'), this.parseNumber ('0.0004') ],
215
+ [ this.parseNumber ('4000'), this.parseNumber ('0.00038') ],
216
+ [ this.parseNumber ('8000'), this.parseNumber ('0.00035') ],
217
+ [ this.parseNumber ('15000'), this.parseNumber ('0.00032') ],
218
+ [ this.parseNumber ('25000'), this.parseNumber ('0.0003') ],
219
+ [ this.parseNumber ('40000'), this.parseNumber ('0.0003') ],
220
+ [ this.parseNumber ('60000'), this.parseNumber ('0.0003') ],
221
+ [ this.parseNumber ('80000'), this.parseNumber ('0.0003') ],
222
+ ],
223
+ 'maker': [
224
+ [ this.parseNumber ('0'), this.parseNumber ('0.02') ],
225
+ [ this.parseNumber ('50'), this.parseNumber ('0.015') ],
226
+ [ this.parseNumber ('200'), this.parseNumber ('0.01') ],
227
+ [ this.parseNumber ('500'), this.parseNumber ('0.01') ],
228
+ [ this.parseNumber ('1000'), this.parseNumber ('0.01') ],
229
+ [ this.parseNumber ('2000'), this.parseNumber ('0') ],
230
+ [ this.parseNumber ('4000'), this.parseNumber ('0') ],
231
+ [ this.parseNumber ('8000'), this.parseNumber ('0') ],
232
+ [ this.parseNumber ('15000'), this.parseNumber ('-0.003') ],
233
+ [ this.parseNumber ('25000'), this.parseNumber ('-0.006') ],
234
+ [ this.parseNumber ('40000'), this.parseNumber ('-0.009') ],
235
+ [ this.parseNumber ('60000'), this.parseNumber ('-0.012') ],
236
+ [ this.parseNumber ('80000'), this.parseNumber ('-0.015') ],
237
+ ],
238
+ },
239
+ },
240
+ 'funding': {
241
+ 'tierBased': false,
242
+ 'percentage': false,
243
+ 'withdraw': {},
244
+ 'deposit': {},
245
+ },
246
+ },
247
+ 'commonCurrencies': {
248
+ 'HOT': 'HOTNOW',
249
+ 'EDGE': 'DADI', // https://github.com/ccxt/ccxt/issues/5756
250
+ 'WAX': 'WAXP',
251
+ 'TRY': 'Trias',
252
+ 'VAI': 'VAIOT',
253
+ 'XBT': 'BTC',
254
+ },
255
+ 'timeframes': {
256
+ '1m': 1,
257
+ '3m': undefined,
258
+ '5m': 5,
259
+ '15m': 15,
260
+ '30m': 30,
261
+ '1h': 60,
262
+ '2h': 120,
263
+ '4h': 240,
264
+ '6h': undefined,
265
+ '8h': 480,
266
+ '12h': 720,
267
+ '1d': 1440,
268
+ '1w': 10080,
269
+ },
270
+ 'options': {
271
+ 'version': 'v1',
272
+ 'symbolSeparator': '-',
273
+ 'defaultType': 'swap',
274
+ 'code': 'USDT',
275
+ 'marginTypes': {},
276
+ // endpoint versions
277
+ 'versions': {
278
+ 'futuresPrivate': {
279
+ 'POST': {
280
+ 'transfer-out': 'v2',
281
+ },
282
+ },
283
+ 'futuresPublic': {
284
+ 'GET': {
285
+ 'level3/snapshot': 'v2',
286
+ },
287
+ },
288
+ },
289
+ 'networks': {
290
+ 'OMNI': 'omni',
291
+ 'ERC20': 'eth',
292
+ 'TRC20': 'trx',
293
+ },
294
+ // 'code': 'BTC',
295
+ // 'fetchBalance': {
296
+ // 'code': 'BTC',
297
+ // },
298
+ },
299
+ });
300
+ }
301
+
302
+ async fetchAccounts (params = {}) {
303
+ throw new BadRequest (this.id + ' fetchAccounts() is not supported yet');
304
+ }
305
+
306
+ async fetchStatus (params = {}) {
307
+ const response = await this.futuresPublicGetStatus (params);
308
+ //
309
+ // {
310
+ // "code":"200000",
311
+ // "data":{
312
+ // "status": "open", // open, close, cancelonly
313
+ // "msg": "upgrade match engine" // remark for operation when status not open
314
+ // }
315
+ // }
316
+ //
317
+ const data = this.safeValue (response, 'data', {});
318
+ const status = this.safeString (data, 'status');
319
+ return {
320
+ 'status': (status === 'open') ? 'ok' : 'maintenance',
321
+ 'updated': this.milliseconds (),
322
+ 'eta': undefined,
323
+ 'url': undefined,
324
+ 'info': response,
325
+ };
326
+ }
327
+
328
+ async fetchMarkets (params = {}) {
329
+ const response = await this.futuresPublicGetContractsActive (params);
330
+ //
331
+ // {
332
+ // "code": "200000",
333
+ // "data": {
334
+ // "symbol": "ETHUSDTM",
335
+ // "rootSymbol": "USDT",
336
+ // "type": "FFWCSX",
337
+ // "firstOpenDate": 1591086000000,
338
+ // "expireDate": null,
339
+ // "settleDate": null,
340
+ // "baseCurrency": "ETH",
341
+ // "quoteCurrency": "USDT",
342
+ // "settleCurrency": "USDT",
343
+ // "maxOrderQty": 1000000,
344
+ // "maxPrice": 1000000.0000000000,
345
+ // "lotSize": 1,
346
+ // "tickSize": 0.05,
347
+ // "indexPriceTickSize": 0.01,
348
+ // "multiplier": 0.01,
349
+ // "initialMargin": 0.01,
350
+ // "maintainMargin": 0.005,
351
+ // "maxRiskLimit": 1000000,
352
+ // "minRiskLimit": 1000000,
353
+ // "riskStep": 500000,
354
+ // "makerFeeRate": 0.00020,
355
+ // "takerFeeRate": 0.00060,
356
+ // "takerFixFee": 0.0000000000,
357
+ // "makerFixFee": 0.0000000000,
358
+ // "settlementFee": null,
359
+ // "isDeleverage": true,
360
+ // "isQuanto": true,
361
+ // "isInverse": false,
362
+ // "markMethod": "FairPrice",
363
+ // "fairMethod": "FundingRate",
364
+ // "fundingBaseSymbol": ".ETHINT8H",
365
+ // "fundingQuoteSymbol": ".USDTINT8H",
366
+ // "fundingRateSymbol": ".ETHUSDTMFPI8H",
367
+ // "indexSymbol": ".KETHUSDT",
368
+ // "settlementSymbol": "",
369
+ // "status": "Open",
370
+ // "fundingFeeRate": 0.000535,
371
+ // "predictedFundingFeeRate": 0.002197,
372
+ // "openInterest": "8724443",
373
+ // "turnoverOf24h": 341156641.03354263,
374
+ // "volumeOf24h": 74833.54000000,
375
+ // "markPrice": 4534.07,
376
+ // "indexPrice":4531.92,
377
+ // "lastTradePrice": 4545.4500000000,
378
+ // "nextFundingRateTime": 25481884,
379
+ // "maxLeverage": 100,
380
+ // "sourceExchanges": [
381
+ // "huobi",
382
+ // "Okex",
383
+ // "Binance",
384
+ // "Kucoin",
385
+ // "Poloniex",
386
+ // "Hitbtc"
387
+ // ],
388
+ // "premiumsSymbol1M": ".ETHUSDTMPI",
389
+ // "premiumsSymbol8H": ".ETHUSDTMPI8H",
390
+ // "fundingBaseSymbol1M": ".ETHINT",
391
+ // "fundingQuoteSymbol1M": ".USDTINT",
392
+ // "lowPrice": 4456.90,
393
+ // "highPrice": 4674.25,
394
+ // "priceChgPct": 0.0046,
395
+ // "priceChg": 21.15
396
+ // }
397
+ // }
398
+ //
399
+ const result = [];
400
+ const data = this.safeValue (response, 'data');
401
+ for (let i = 0; i < data.length; i++) {
402
+ const market = data[i];
403
+ const id = this.safeString (market, 'symbol');
404
+ const expiry = this.safeInteger (market, 'expireDate');
405
+ const future = expiry ? true : false;
406
+ const swap = !future;
407
+ const baseId = this.safeString (market, 'baseCurrency');
408
+ const quoteId = this.safeString (market, 'quoteCurrency');
409
+ const settleId = this.safeString (market, 'settleCurrency');
410
+ const base = this.safeCurrencyCode (baseId);
411
+ const quote = this.safeCurrencyCode (quoteId);
412
+ const settle = this.safeCurrencyCode (settleId);
413
+ let symbol = base + '/' + quote + ':' + settle;
414
+ let type = 'swap';
415
+ if (future) {
416
+ symbol = symbol + '-' + this.yymmdd (expiry, '');
417
+ type = 'future';
418
+ }
419
+ const baseMaxSize = this.safeNumber (market, 'baseMaxSize');
420
+ const baseMinSizeString = this.safeString (market, 'baseMinSize');
421
+ const quoteMaxSizeString = this.safeString (market, 'quoteMaxSize');
422
+ const baseMinSize = this.parseNumber (baseMinSizeString);
423
+ const quoteMaxSize = this.parseNumber (quoteMaxSizeString);
424
+ const quoteMinSize = this.safeNumber (market, 'quoteMinSize');
425
+ const inverse = this.safeValue (market, 'isInverse');
426
+ const status = this.safeString (market, 'status');
427
+ const multiplier = this.safeString (market, 'multiplier');
428
+ result.push ({
429
+ 'id': id,
430
+ 'symbol': symbol,
431
+ 'base': base,
432
+ 'quote': quote,
433
+ 'settle': settle,
434
+ 'baseId': baseId,
435
+ 'quoteId': quoteId,
436
+ 'settleId': settleId,
437
+ 'type': type,
438
+ 'spot': false,
439
+ 'margin': false,
440
+ 'swap': swap,
441
+ 'future': future,
442
+ 'option': false,
443
+ 'active': (status === 'Open'),
444
+ 'contract': true,
445
+ 'linear': !inverse,
446
+ 'inverse': inverse,
447
+ 'taker': this.safeNumber (market, 'takerFeeRate'),
448
+ 'maker': this.safeNumber (market, 'makerFeeRate'),
449
+ 'contractSize': this.parseNumber (Precise.stringAbs (multiplier)),
450
+ 'expiry': expiry,
451
+ 'expiryDatetime': this.iso8601 (expiry),
452
+ 'strike': undefined,
453
+ 'optionType': undefined,
454
+ 'precision': {
455
+ 'amount': this.safeNumber (market, 'lotSize'),
456
+ 'price': this.safeNumber (market, 'tickSize'),
457
+ },
458
+ 'limits': {
459
+ 'leverage': {
460
+ 'min': this.parseNumber ('1'),
461
+ 'max': this.safeNumber (market, 'maxLeverage'),
462
+ },
463
+ 'amount': {
464
+ 'min': baseMinSize,
465
+ 'max': baseMaxSize,
466
+ },
467
+ 'price': {
468
+ 'min': undefined,
469
+ 'max': this.parseNumber (Precise.stringDiv (quoteMaxSizeString, baseMinSizeString)),
470
+ },
471
+ 'cost': {
472
+ 'min': quoteMinSize,
473
+ 'max': quoteMaxSize,
474
+ },
475
+ },
476
+ 'info': market,
477
+ });
478
+ }
479
+ return result;
480
+ }
481
+
482
+ async fetchTime (params = {}) {
483
+ const response = await this.futuresPublicGetTimestamp (params);
484
+ //
485
+ // {
486
+ // code: "200000",
487
+ // data: 1637385119302,
488
+ // }
489
+ //
490
+ return this.safeNumber (response, 'data');
491
+ }
492
+
493
+ async fetchOHLCV (symbol, timeframe = '15m', since = undefined, limit = undefined, params = {}) {
494
+ await this.loadMarkets ();
495
+ const market = this.market (symbol);
496
+ const marketId = market['id'];
497
+ const request = {
498
+ 'symbol': marketId,
499
+ 'granularity': this.timeframes[timeframe],
500
+ };
501
+ const duration = this.parseTimeframe (timeframe) * 1000;
502
+ let endAt = this.milliseconds ();
503
+ if (since !== undefined) {
504
+ request['from'] = since;
505
+ if (limit === undefined) {
506
+ limit = this.safeInteger (this.options, 'fetchOHLCVLimit', 200);
507
+ }
508
+ endAt = this.sum (since, limit * duration);
509
+ } else if (limit !== undefined) {
510
+ since = endAt - limit * duration;
511
+ request['from'] = since;
512
+ }
513
+ request['to'] = endAt;
514
+ const response = await this.futuresPublicGetKlineQuery (this.extend (request, params));
515
+ //
516
+ // {
517
+ // "code": "200000",
518
+ // "data": [
519
+ // [1636459200000, 4779.3, 4792.1, 4768.7, 4770.3, 78051],
520
+ // [1636460100000, 4770.25, 4778.55, 4757.55, 4777.25, 80164],
521
+ // [1636461000000, 4777.25, 4791.45, 4774.5, 4791.3, 51555]
522
+ // ]
523
+ // }
524
+ //
525
+ const data = this.safeValue (response, 'data', []);
526
+ return this.parseOHLCVs (data, market, timeframe, since, limit);
527
+ }
528
+
529
+ parseOHLCV (ohlcv, market = undefined) {
530
+ //
531
+ // [
532
+ // "1545904980000", // Start time of the candle cycle
533
+ // "0.058", // opening price
534
+ // "0.049", // closing price
535
+ // "0.058", // highest price
536
+ // "0.049", // lowest price
537
+ // "0.018", // base volume
538
+ // "0.000945", // quote volume
539
+ // ]
540
+ //
541
+ return [
542
+ this.safeInteger (ohlcv, 0),
543
+ this.safeNumber (ohlcv, 1),
544
+ this.safeNumber (ohlcv, 2),
545
+ this.safeNumber (ohlcv, 3),
546
+ this.safeNumber (ohlcv, 4),
547
+ this.safeNumber (ohlcv, 5),
548
+ ];
549
+ }
550
+
551
+ async createDepositAddress (code, params = {}) {
552
+ throw new BadRequest (this.id + ' createDepositAddress() is not supported yet');
553
+ }
554
+
555
+ async fetchDepositAddress (code, params = {}) {
556
+ await this.loadMarkets ();
557
+ const currency = this.currency (code);
558
+ const currencyId = currency['id'];
559
+ const request = {
560
+ 'currency': currencyId, // Currency,including XBT,USDT
561
+ };
562
+ const response = await this.futuresPrivateGetDepositAddress (this.extend (request, params));
563
+ //
564
+ // {
565
+ // "code": "200000",
566
+ // "data": {
567
+ // "address": "0x78d3ad1c0aa1bf068e19c94a2d7b16c9c0fcd8b1",//Deposit address
568
+ // "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.
569
+ // }
570
+ // }
571
+ //
572
+ const data = this.safeValue (response, 'data', {});
573
+ const address = this.safeString (data, 'address');
574
+ if (currencyId !== 'NIM') {
575
+ // contains spaces
576
+ this.checkAddress (address);
577
+ }
578
+ return {
579
+ 'info': response,
580
+ 'currency': currencyId,
581
+ 'address': address,
582
+ 'tag': this.safeString (data, 'memo'),
583
+ 'network': this.safeString (data, 'chain'),
584
+ };
585
+ }
586
+
587
+ async fetchOrderBook (symbol, limit = undefined, params = {}) {
588
+ await this.loadMarkets ();
589
+ const level = this.safeNumber (params, 'level');
590
+ if (level !== 2 && level !== undefined) {
591
+ throw new BadRequest (this.id + ' fetchOrderBook() can only return level 2');
592
+ }
593
+ const market = this.market (symbol);
594
+ const request = {
595
+ 'symbol': market['id'],
596
+ };
597
+ if (limit !== undefined) {
598
+ if ((limit === 20) || (limit === 100)) {
599
+ request['limit'] = limit;
600
+ } else {
601
+ throw new BadRequest (this.id + ' fetchOrderBook() limit argument must be 20 or 100');
602
+ }
603
+ } else {
604
+ request['limit'] = 20;
605
+ }
606
+ const response = await this.futuresPublicGetLevel2DepthLimit (this.extend (request, params));
607
+ //
608
+ // {
609
+ // "code": "200000",
610
+ // "data": {
611
+ // "symbol": "XBTUSDM", //Symbol
612
+ // "sequence": 100, //Ticker sequence number
613
+ // "asks": [
614
+ // ["5000.0", 1000], //Price, quantity
615
+ // ["6000.0", 1983] //Price, quantity
616
+ // ],
617
+ // "bids": [
618
+ // ["3200.0", 800], //Price, quantity
619
+ // ["3100.0", 100] //Price, quantity
620
+ // ],
621
+ // "ts": 1604643655040584408 // timestamp
622
+ // }
623
+ // }
624
+ //
625
+ const data = this.safeValue (response, 'data', {});
626
+ const timestamp = parseInt (this.safeInteger (data, 'ts') / 1000000);
627
+ const orderbook = this.parseOrderBook (data, symbol, timestamp, 'bids', 'asks', 0, 1);
628
+ orderbook['nonce'] = this.safeInteger (data, 'sequence');
629
+ return orderbook;
630
+ }
631
+
632
+ async fetchL3OrderBook (symbol, limit = undefined, params = {}) {
633
+ throw new BadRequest (this.id + ' fetchL3OrderBook() is not supported yet');
634
+ }
635
+
636
+ async fetchTicker (symbol, params = {}) {
637
+ await this.loadMarkets ();
638
+ const market = this.market (symbol);
639
+ const request = {
640
+ 'symbol': market['id'],
641
+ };
642
+ const response = await this.futuresPublicGetTicker (this.extend (request, params));
643
+ //
644
+ // {
645
+ // "code": "200000",
646
+ // "data": {
647
+ // "sequence": 1638444978558,
648
+ // "symbol": "ETHUSDTM",
649
+ // "side": "sell",
650
+ // "size": 4,
651
+ // "price": "4229.35",
652
+ // "bestBidSize": 2160,
653
+ // "bestBidPrice": "4229.0",
654
+ // "bestAskPrice": "4229.05",
655
+ // "tradeId": "61aaa8b777a0c43055fe4851",
656
+ // "ts": 1638574296209786785,
657
+ // "bestAskSize": 36,
658
+ // }
659
+ // }
660
+ //
661
+ return this.parseTicker (response['data'], market);
662
+ }
663
+
664
+ parseTicker (ticker, market = undefined) {
665
+ //
666
+ // {
667
+ // "code": "200000",
668
+ // "data": {
669
+ // "sequence": 1629930362547,
670
+ // "symbol": "ETHUSDTM",
671
+ // "side": "buy",
672
+ // "size": 130,
673
+ // "price": "4724.7",
674
+ // "bestBidSize": 5,
675
+ // "bestBidPrice": "4724.6",
676
+ // "bestAskPrice": "4724.65",
677
+ // "tradeId": "618d2a5a77a0c4431d2335f4",
678
+ // "ts": 1636641371963227600,
679
+ // "bestAskSize": 1789
680
+ // }
681
+ // }
682
+ //
683
+ const last = this.safeString (ticker, 'price');
684
+ const marketId = this.safeString (ticker, 'symbol');
685
+ market = this.safeMarket (marketId, market, '-');
686
+ const timestamp = Precise.stringDiv (this.safeString (ticker, 'ts'), '1000000');
687
+ return this.safeTicker ({
688
+ 'symbol': market['symbol'],
689
+ 'timestamp': timestamp,
690
+ 'datetime': this.iso8601 (timestamp),
691
+ 'high': undefined,
692
+ 'low': undefined,
693
+ 'bid': this.safeString (ticker, 'bestBidPrice'),
694
+ 'bidVolume': this.safeString (ticker, 'bestBidSize'),
695
+ 'ask': this.safeString (ticker, 'bestAskPrice'),
696
+ 'askVolume': this.safeString (ticker, 'bestAskSize'),
697
+ 'vwap': undefined,
698
+ 'open': undefined,
699
+ 'close': last,
700
+ 'last': last,
701
+ 'previousClose': undefined,
702
+ 'change': undefined,
703
+ 'percentage': undefined,
704
+ 'average': undefined,
705
+ 'baseVolume': undefined,
706
+ 'quoteVolume': undefined,
707
+ 'info': ticker,
708
+ }, market, false);
709
+ }
710
+
711
+ async fetchFundingHistory (symbol = undefined, since = undefined, limit = undefined, params = {}) {
712
+ //
713
+ // Private
714
+ // @param symbol (string): The pair for which the contract was traded
715
+ // @param since (number): The unix start time of the first funding payment requested
716
+ // @param limit (number): The number of results to return
717
+ // @param params (dict): Additional parameters to send to the API
718
+ // @param return: Data for the history of the accounts funding payments for futures contracts
719
+ //
720
+ if (symbol === undefined) {
721
+ throw new ArgumentsRequired (this.id + ' fetchFundingHistory() requires a symbol argument');
722
+ }
723
+ await this.loadMarkets ();
724
+ const market = this.market (symbol);
725
+ const request = {
726
+ 'symbol': market['id'],
727
+ };
728
+ if (since !== undefined) {
729
+ request['startAt'] = since;
730
+ }
731
+ if (limit !== undefined) {
732
+ // * Since is ignored if limit is defined
733
+ request['maxCount'] = limit;
734
+ }
735
+ const response = await this.futuresPrivateGetFundingHistory (this.extend (request, params));
736
+ //
737
+ // {
738
+ // "code": "200000",
739
+ // "data": {
740
+ // "dataList": [
741
+ // {
742
+ // "id": 239471298749817,
743
+ // "symbol": "ETHUSDTM",
744
+ // "timePoint": 1638532800000,
745
+ // "fundingRate": 0.000100,
746
+ // "markPrice": 4612.8300000000,
747
+ // "positionQty": 12,
748
+ // "positionCost": 553.5396000000,
749
+ // "funding": -0.0553539600,
750
+ // "settleCurrency": "USDT"
751
+ // },
752
+ // ...
753
+ // ],
754
+ // "hasMore": true
755
+ // }
756
+ // }
757
+ //
758
+ const data = this.safeValue (response, 'data');
759
+ const dataList = this.safeValue (data, 'dataList');
760
+ const fees = [];
761
+ for (let i = 0; i < dataList.length; i++) {
762
+ const listItem = dataList[i];
763
+ const timestamp = this.safeInteger (listItem, 'timePoint');
764
+ fees.push ({
765
+ 'info': listItem,
766
+ 'symbol': symbol,
767
+ 'code': this.safeCurrencyCode (this.safeString (listItem, 'settleCurrency')),
768
+ 'timestamp': timestamp,
769
+ 'datetime': this.iso8601 (timestamp),
770
+ 'id': this.safeNumber (listItem, 'id'),
771
+ 'amount': this.safeNumber (listItem, 'funding'),
772
+ 'fundingRate': this.safeNumber (listItem, 'fundingRate'),
773
+ 'markPrice': this.safeNumber (listItem, 'markPrice'),
774
+ 'positionQty': this.safeNumber (listItem, 'positionQty'),
775
+ 'positionCost': this.safeNumber (listItem, 'positionCost'),
776
+ });
777
+ }
778
+ return fees;
779
+ }
780
+
781
+ async fetchPositions (symbols = undefined, params = {}) {
782
+ await this.loadMarkets ();
783
+ const response = await this.futuresPrivateGetPositions (params);
784
+ //
785
+ // {
786
+ // "code": "200000",
787
+ // "data": [
788
+ // {
789
+ // "id": "615ba79f83a3410001cde321",
790
+ // "symbol": "ETHUSDTM",
791
+ // "autoDeposit": false,
792
+ // "maintMarginReq": 0.005,
793
+ // "riskLimit": 1000000,
794
+ // "realLeverage": 18.61,
795
+ // "crossMode": false,
796
+ // "delevPercentage": 0.86,
797
+ // "openingTimestamp": 1638563515618,
798
+ // "currentTimestamp": 1638576872774,
799
+ // "currentQty": 2,
800
+ // "currentCost": 83.64200000,
801
+ // "currentComm": 0.05018520,
802
+ // "unrealisedCost": 83.64200000,
803
+ // "realisedGrossCost": 0.00000000,
804
+ // "realisedCost": 0.05018520,
805
+ // "isOpen": true,
806
+ // "markPrice": 4225.01,
807
+ // "markValue": 84.50020000,
808
+ // "posCost": 83.64200000,
809
+ // "posCross": 0.0000000000,
810
+ // "posInit": 3.63660870,
811
+ // "posComm": 0.05236717,
812
+ // "posLoss": 0.00000000,
813
+ // "posMargin": 3.68897586,
814
+ // "posMaint": 0.50637594,
815
+ // "maintMargin": 4.54717586,
816
+ // "realisedGrossPnl": 0.00000000,
817
+ // "realisedPnl": -0.05018520,
818
+ // "unrealisedPnl": 0.85820000,
819
+ // "unrealisedPnlPcnt": 0.0103,
820
+ // "unrealisedRoePcnt": 0.2360,
821
+ // "avgEntryPrice": 4182.10,
822
+ // "liquidationPrice": 4023.00,
823
+ // "bankruptPrice": 4000.25,
824
+ // "settleCurrency": "USDT",
825
+ // "isInverse": false
826
+ // }
827
+ // ]
828
+ // }
829
+ //
830
+ return this.parsePositions (this.safeValue (response, 'data'));
831
+ }
832
+
833
+ parsePositions (positions) {
834
+ const result = [];
835
+ for (let i = 0; i < positions.length; i++) {
836
+ result.push (this.parsePosition (positions[i]));
837
+ }
838
+ return result;
839
+ }
840
+
841
+ parsePosition (position, market = undefined) {
842
+ //
843
+ // {
844
+ // "code": "200000",
845
+ // "data": [
846
+ // {
847
+ // "id": "615ba79f83a3410001cde321", // Position ID
848
+ // "symbol": "ETHUSDTM", // Symbol
849
+ // "autoDeposit": false, // Auto deposit margin or not
850
+ // "maintMarginReq": 0.005, // Maintenance margin requirement
851
+ // "riskLimit": 1000000, // Risk limit
852
+ // "realLeverage": 25.92, // Leverage of the order
853
+ // "crossMode": false, // Cross mode or not
854
+ // "delevPercentage": 0.76, // ADL ranking percentile
855
+ // "openingTimestamp": 1638578546031, // Open time
856
+ // "currentTimestamp": 1638578563580, // Current timestamp
857
+ // "currentQty": 2, // Current postion quantity
858
+ // "currentCost": 83.787, // Current postion value
859
+ // "currentComm": 0.0167574, // Current commission
860
+ // "unrealisedCost": 83.787, // Unrealised value
861
+ // "realisedGrossCost": 0.0, // Accumulated realised gross profit value
862
+ // "realisedCost": 0.0167574, // Current realised position value
863
+ // "isOpen": true, // Opened position or not
864
+ // "markPrice": 4183.38, // Mark price
865
+ // "markValue": 83.6676, // Mark value
866
+ // "posCost": 83.787, // Position value
867
+ // "posCross": 0.0, // added margin
868
+ // "posInit": 3.35148, // Leverage margin
869
+ // "posComm": 0.05228309, // Bankruptcy cost
870
+ // "posLoss": 0.0, // Funding fees paid out
871
+ // "posMargin": 3.40376309, // Position margin
872
+ // "posMaint": 0.50707892, // Maintenance margin
873
+ // "maintMargin": 3.28436309, // Position margin
874
+ // "realisedGrossPnl": 0.0, // Accumulated realised gross profit value
875
+ // "realisedPnl": -0.0167574, // Realised profit and loss
876
+ // "unrealisedPnl": -0.1194, // Unrealised profit and loss
877
+ // "unrealisedPnlPcnt": -0.0014, // Profit-loss ratio of the position
878
+ // "unrealisedRoePcnt": -0.0356, // Rate of return on investment
879
+ // "avgEntryPrice": 4189.35, // Average entry price
880
+ // "liquidationPrice": 4044.55, // Liquidation price
881
+ // "bankruptPrice": 4021.75, // Bankruptcy price
882
+ // "settleCurrency": "USDT", // Currency used to clear and settle the trades
883
+ // "isInverse": false
884
+ // }
885
+ // ]
886
+ // }
887
+ //
888
+ const symbol = this.safeString (position, 'symbol');
889
+ market = this.safeMarket (symbol, market);
890
+ const timestamp = this.safeNumber (position, 'currentTimestamp');
891
+ const size = this.safeString (position, 'currentQty');
892
+ let side = undefined;
893
+ if (Precise.stringGt (size, '0')) {
894
+ side = 'long';
895
+ } else if (Precise.stringLt (size, '0')) {
896
+ side = 'short';
897
+ }
898
+ const notional = Precise.stringAbs (this.safeString (position, 'posCost'));
899
+ const initialMargin = this.safeString (position, 'posInit');
900
+ const initialMarginPercentage = Precise.stringDiv (initialMargin, notional);
901
+ // const marginRatio = Precise.stringDiv (maintenanceRate, collateral);
902
+ const unrealisedPnl = this.safeString (position, 'unrealisedPnl');
903
+ const crossMode = this.safeValue (position, 'crossMode');
904
+ // currently crossMode is always set to false and only isolated positions are supported
905
+ const marginType = crossMode ? 'cross' : 'isolated';
906
+ return {
907
+ 'info': position,
908
+ 'symbol': this.safeString (market, 'symbol'),
909
+ 'timestamp': timestamp,
910
+ 'datetime': this.iso8601 (timestamp),
911
+ 'initialMargin': this.parseNumber (initialMargin),
912
+ 'initialMarginPercentage': this.parseNumber (initialMarginPercentage),
913
+ 'maintenanceMargin': this.safeNumber (position, 'posMaint'),
914
+ 'maintenanceMarginPercentage': this.safeNumber (position, 'maintMarginReq'),
915
+ 'entryPrice': this.safeNumber (position, 'avgEntryPrice'),
916
+ 'notional': this.parseNumber (notional),
917
+ 'leverage': this.safeNumber (position, 'realLeverage'),
918
+ 'unrealizedPnl': this.parseNumber (unrealisedPnl),
919
+ 'contracts': this.parseNumber (Precise.stringAbs (size)),
920
+ 'contractSize': this.safeValue (market, 'contractSize'),
921
+ // realisedPnl: position['realised_pnl'],
922
+ 'marginRatio': undefined,
923
+ 'liquidationPrice': this.safeNumber (position, 'liquidationPrice'),
924
+ 'markPrice': this.safeNumber (position, 'markPrice'),
925
+ 'collateral': this.safeNumber (position, 'maintMargin'),
926
+ 'marginType': marginType,
927
+ 'side': side,
928
+ 'percentage': this.parseNumber (Precise.stringDiv (unrealisedPnl, initialMargin)),
929
+ };
930
+ }
931
+
932
+ async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
933
+ /**
934
+ * @method
935
+ * @name kucoinfutures#createOrder
936
+ * @description Create an order on the exchange
937
+ * @param {str} symbol Unified CCXT market symbol
938
+ * @param {str} type "limit" or "market"
939
+ * @param {str} side "buy" or "sell"
940
+ * @param {float} amount the amount of currency to trade
941
+ * @param {float} price *ignored in "market" orders* the price at which the order is to be fullfilled at in units of the quote currency
942
+ * @param {dict} params Extra parameters specific to the exchange API endpoint
943
+ * @param {float} params.leverage Leverage size of the order
944
+ * @param {float} params.stopPrice The price at which a trigger order is triggered at
945
+ * @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.
946
+ * @param {str} params.timeInForce GTC, GTT, IOC, or FOK, default is GTC, limit orders only
947
+ * @param {str} params.postOnly Post only flag, invalid when timeInForce is IOC or FOK
948
+ * @param {str} params.clientOid client order id, defaults to uuid if not passed
949
+ * @param {str} params.remark remark for the order, length cannot exceed 100 utf8 characters
950
+ * @param {str} params.stop 'up' or 'down', defaults to 'up' if side is sell and 'down' if side is buy, requires stopPrice
951
+ * @param {str} params.stopPriceType TP, IP or MP, defaults to TP
952
+ * @param {bool} params.closeOrder set to true to close position
953
+ * @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.
954
+ * @returns an [order structure]{@link https://docs.ccxt.com/en/latest/manual.html#order-structure}
955
+ */
956
+ await this.loadMarkets ();
957
+ const market = this.market (symbol);
958
+ // required param, cannot be used twice
959
+ const clientOrderId = this.safeString2 (params, 'clientOid', 'clientOrderId', this.uuid ());
960
+ params = this.omit (params, [ 'clientOid', 'clientOrderId' ]);
961
+ if (amount < 1) {
962
+ throw new InvalidOrder (this.id + ' createOrder() minimum contract order amount is 1');
963
+ }
964
+ const preciseAmount = parseInt (this.amountToPrecision (symbol, amount));
965
+ const request = {
966
+ 'clientOid': clientOrderId,
967
+ 'side': side,
968
+ 'symbol': market['id'],
969
+ 'type': type, // limit or market
970
+ 'size': preciseAmount,
971
+ 'leverage': 1,
972
+ };
973
+ const stopPrice = this.safeNumber (params, 'stopPrice');
974
+ if (stopPrice) {
975
+ request['stop'] = (side === 'buy') ? 'up' : 'down';
976
+ const stopPriceType = this.safeString (params, 'stopPriceType', 'TP');
977
+ request['stopPriceType'] = stopPriceType;
978
+ }
979
+ const uppercaseType = type.toUpperCase ();
980
+ let timeInForce = this.safeString (params, 'timeInForce');
981
+ if (uppercaseType === 'LIMIT') {
982
+ if (price === undefined) {
983
+ throw new ArgumentsRequired (this.id + ' createOrder() requires a price argument for limit orders');
984
+ } else {
985
+ request['price'] = this.priceToPrecision (symbol, price);
986
+ }
987
+ if (timeInForce !== undefined) {
988
+ timeInForce = timeInForce.toUpperCase ();
989
+ request['timeInForce'] = timeInForce;
990
+ }
991
+ }
992
+ const postOnly = this.safeValue (params, 'postOnly', false);
993
+ const hidden = this.safeValue (params, 'hidden');
994
+ if (postOnly && hidden !== undefined) {
995
+ throw new BadRequest (this.id + ' createOrder() does not support the postOnly parameter together with a hidden parameter');
996
+ }
997
+ const iceberg = this.safeValue (params, 'iceberg');
998
+ if (iceberg) {
999
+ const visibleSize = this.safeValue (params, 'visibleSize');
1000
+ if (visibleSize === undefined) {
1001
+ throw new ArgumentsRequired (this.id + ' createOrder() requires a visibleSize parameter for iceberg orders');
1002
+ }
1003
+ }
1004
+ params = this.omit (params, 'timeInForce'); // Time in force only valid for limit orders, exchange error when gtc for market orders
1005
+ const response = await this.futuresPrivatePostOrders (this.extend (request, params));
1006
+ //
1007
+ // {
1008
+ // code: "200000",
1009
+ // data: {
1010
+ // orderId: "619717484f1d010001510cde",
1011
+ // },
1012
+ // }
1013
+ //
1014
+ const data = this.safeValue (response, 'data', {});
1015
+ return {
1016
+ 'id': this.safeString (data, 'orderId'),
1017
+ 'clientOrderId': undefined,
1018
+ 'timestamp': undefined,
1019
+ 'datetime': undefined,
1020
+ 'lastTradeTimestamp': undefined,
1021
+ 'symbol': undefined,
1022
+ 'type': undefined,
1023
+ 'side': undefined,
1024
+ 'price': undefined,
1025
+ 'amount': undefined,
1026
+ 'cost': undefined,
1027
+ 'average': undefined,
1028
+ 'filled': undefined,
1029
+ 'remaining': undefined,
1030
+ 'status': undefined,
1031
+ 'fee': undefined,
1032
+ 'trades': undefined,
1033
+ 'timeInForce': undefined,
1034
+ 'postOnly': undefined,
1035
+ 'stopPrice': undefined,
1036
+ 'info': response,
1037
+ };
1038
+ }
1039
+
1040
+ async cancelOrder (id, symbol = undefined, params = {}) {
1041
+ await this.loadMarkets ();
1042
+ const request = {
1043
+ 'orderId': id,
1044
+ };
1045
+ const response = await this.futuresPrivateDeleteOrdersOrderId (this.extend (request, params));
1046
+ //
1047
+ // {
1048
+ // code: "200000",
1049
+ // data: {
1050
+ // cancelledOrderIds: [
1051
+ // "619714b8b6353000014c505a",
1052
+ // ],
1053
+ // },
1054
+ // }
1055
+ //
1056
+ return this.safeValue (response, 'data');
1057
+ }
1058
+
1059
+ async cancelAllOrders (symbol = undefined, params = {}) {
1060
+ /**
1061
+ * @method
1062
+ * @name kucoinfutures#cancelAllOrders
1063
+ * @description Cancels all orders in one api call
1064
+ * @param {str} symbol Assign to cancel only the orders in the market matching the unified symbol
1065
+ * @param {dict} params Exchange specific parameters
1066
+ * @param {dict} params.stop When true, all the trigger orders will be cancelled
1067
+ * @returns Response from the exchange
1068
+ */
1069
+ await this.loadMarkets ();
1070
+ const request = {};
1071
+ if (symbol !== undefined) {
1072
+ request['symbol'] = this.marketId (symbol);
1073
+ }
1074
+ const stop = this.safeValue (params, 'stop');
1075
+ const method = stop ? 'futuresPrivateDeleteStopOrders' : 'futuresPrivateDeleteOrders';
1076
+ const response = await this[method] (this.extend (request, params));
1077
+ //
1078
+ // {
1079
+ // code: "200000",
1080
+ // data: {
1081
+ // cancelledOrderIds: [
1082
+ // "619714b8b6353000014c505a",
1083
+ // ],
1084
+ // },
1085
+ // }
1086
+ //
1087
+ return this.safeValue (response, 'data');
1088
+ }
1089
+
1090
+ async addMargin (symbol, amount, params = {}) {
1091
+ await this.loadMarkets ();
1092
+ const market = this.market (symbol);
1093
+ const uuid = this.uuid ();
1094
+ const request = {
1095
+ 'symbol': market['id'],
1096
+ 'margin': amount,
1097
+ 'bizNo': uuid,
1098
+ };
1099
+ return await this.futuresPrivatePostPositionMarginDepositMargin (this.extend (request, params));
1100
+ }
1101
+
1102
+ async fetchOrdersByStatus (status, symbol = undefined, since = undefined, limit = undefined, params = {}) {
1103
+ /**
1104
+ * @method
1105
+ * @name kucoinfutures#fetchOrdersByStatus
1106
+ * @description fetches a list of orders placed on the exchange
1107
+ * @param {str} status 'active' or 'closed', only 'active' is valid for stop orders
1108
+ * @param {str} symbol unified symbol for the market to retrieve orders from
1109
+ * @param {int} since timestamp in ms of the earliest order to retrieve
1110
+ * @param {int} limit The maximum number of orders to retrieve
1111
+ * @param {dict} params exchange specific parameters
1112
+ * @param {bool} params.stop set to true to retrieve untriggered stop orders
1113
+ * @param {int} params.till End time in ms
1114
+ * @param {str} params.side buy or sell
1115
+ * @param {str} params.type limit or market
1116
+ * @returns An [array of order structures]{@link https://docs.ccxt.com/en/latest/manual.html#order-structure}
1117
+ */
1118
+ await this.loadMarkets ();
1119
+ const stop = this.safeValue (params, 'stop');
1120
+ params = this.omit (params, 'stop');
1121
+ if (status === 'closed') {
1122
+ status = 'done';
1123
+ } else if (status === 'open') {
1124
+ status = 'active';
1125
+ }
1126
+ const request = {};
1127
+ if (!stop) {
1128
+ request['status'] = status;
1129
+ } else if (status !== 'active') {
1130
+ throw new BadRequest (this.id + ' fetchOrdersByStatus() can only fetch untriggered stop orders');
1131
+ }
1132
+ let market = undefined;
1133
+ if (symbol !== undefined) {
1134
+ market = this.market (symbol);
1135
+ request['symbol'] = market['id'];
1136
+ }
1137
+ if (since !== undefined) {
1138
+ request['startAt'] = since;
1139
+ }
1140
+ const till = this.safeInteger (params, 'till', 'endAt');
1141
+ if (till !== undefined) {
1142
+ request['endAt'] = till;
1143
+ }
1144
+ const method = stop ? 'futuresPrivateGetStopOrders' : 'futuresPrivateGetOrders';
1145
+ const response = await this[method] (this.extend (request, params));
1146
+ const responseData = this.safeValue (response, 'data', {});
1147
+ const orders = this.safeValue (responseData, 'items', []);
1148
+ return this.parseOrders (orders, market, since, limit);
1149
+ }
1150
+
1151
+ async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1152
+ /**
1153
+ * @method
1154
+ * @name kucoinfutures#fetchClosedOrders
1155
+ * @description fetch a list of orders
1156
+ * @param {str} symbol unified market symbol
1157
+ * @param {int} since timestamp in ms of the earliest order
1158
+ * @param {int} limit max number of orders to return
1159
+ * @param {dict} params exchange specific params
1160
+ * @param {int} params.till end time in ms
1161
+ * @param {str} params.side buy or sell
1162
+ * @param {str} params.type limit, or market
1163
+ * @returns An [array of order structures]{@link https://docs.ccxt.com/en/latest/manual.html#order-structure}
1164
+ */
1165
+ return await this.fetchOrdersByStatus ('done', symbol, since, limit, params);
1166
+ }
1167
+
1168
+ async fetchOrder (id = undefined, symbol = undefined, params = {}) {
1169
+ await this.loadMarkets ();
1170
+ const request = {};
1171
+ let method = 'futuresPrivateGetOrdersOrderId';
1172
+ if (id === undefined) {
1173
+ const clientOrderId = this.safeString2 (params, 'clientOid', 'clientOrderId');
1174
+ if (clientOrderId === undefined) {
1175
+ throw new InvalidOrder (this.id + ' fetchOrder() requires parameter id or params.clientOid');
1176
+ }
1177
+ request['clientOid'] = clientOrderId;
1178
+ method = 'futuresPrivateGetOrdersByClientOid';
1179
+ params = this.omit (params, [ 'clientOid', 'clientOrderId' ]);
1180
+ } else {
1181
+ request['orderId'] = id;
1182
+ }
1183
+ const response = await this[method] (this.extend (request, params));
1184
+ const market = (symbol !== undefined) ? this.market (symbol) : undefined;
1185
+ const responseData = this.safeValue (response, 'data');
1186
+ return this.parseOrder (responseData, market);
1187
+ }
1188
+
1189
+ parseOrder (order, market = undefined) {
1190
+ const marketId = this.safeString (order, 'symbol');
1191
+ market = this.safeMarket (marketId, market);
1192
+ const symbol = market['symbol'];
1193
+ const orderId = this.safeString (order, 'id');
1194
+ const type = this.safeString (order, 'type');
1195
+ const timestamp = this.safeInteger (order, 'createdAt');
1196
+ const datetime = this.iso8601 (timestamp);
1197
+ const price = this.safeString (order, 'price');
1198
+ // price is zero for market order
1199
+ // omitZero is called in safeOrder2
1200
+ const side = this.safeString (order, 'side');
1201
+ const feeCurrencyId = this.safeString (order, 'feeCurrency');
1202
+ const feeCurrency = this.safeCurrencyCode (feeCurrencyId);
1203
+ const feeCost = this.safeNumber (order, 'fee');
1204
+ const amount = this.safeString (order, 'size');
1205
+ const filled = this.safeString (order, 'dealSize');
1206
+ const rawCost = this.safeString2 (order, 'dealFunds', 'filledValue');
1207
+ const leverage = this.safeString (order, 'leverage');
1208
+ const cost = Precise.stringDiv (rawCost, leverage);
1209
+ let average = undefined;
1210
+ if (Precise.stringGt (filled, '0')) {
1211
+ const contractSize = this.safeString (market, 'contractSize');
1212
+ if (market['linear']) {
1213
+ average = Precise.stringDiv (rawCost, Precise.stringMul (contractSize, filled));
1214
+ } else {
1215
+ average = Precise.stringDiv (Precise.stringMul (contractSize, filled), rawCost);
1216
+ }
1217
+ }
1218
+ // precision reported by their api is 8 d.p.
1219
+ // const average = Precise.stringDiv (rawCost, Precise.stringMul (filled, market['contractSize']));
1220
+ // bool
1221
+ const isActive = this.safeValue (order, 'isActive', false);
1222
+ const cancelExist = this.safeValue (order, 'cancelExist', false);
1223
+ let status = isActive ? 'open' : 'closed';
1224
+ status = cancelExist ? 'canceled' : status;
1225
+ const fee = {
1226
+ 'currency': feeCurrency,
1227
+ 'cost': feeCost,
1228
+ };
1229
+ const clientOrderId = this.safeString (order, 'clientOid');
1230
+ const timeInForce = this.safeString (order, 'timeInForce');
1231
+ const stopPrice = this.safeNumber (order, 'stopPrice');
1232
+ const postOnly = this.safeValue (order, 'postOnly');
1233
+ return this.safeOrder ({
1234
+ 'id': orderId,
1235
+ 'clientOrderId': clientOrderId,
1236
+ 'symbol': symbol,
1237
+ 'type': type,
1238
+ 'timeInForce': timeInForce,
1239
+ 'postOnly': postOnly,
1240
+ 'side': side,
1241
+ 'amount': amount,
1242
+ 'price': price,
1243
+ 'stopPrice': stopPrice,
1244
+ 'cost': cost,
1245
+ 'filled': filled,
1246
+ 'remaining': undefined,
1247
+ 'timestamp': timestamp,
1248
+ 'datetime': datetime,
1249
+ 'fee': fee,
1250
+ 'status': status,
1251
+ 'info': order,
1252
+ 'lastTradeTimestamp': undefined,
1253
+ 'average': average,
1254
+ 'trades': undefined,
1255
+ }, market);
1256
+ }
1257
+
1258
+ async fetchFundingRate (symbol, params = {}) {
1259
+ await this.loadMarkets ();
1260
+ const request = {
1261
+ 'symbol': this.marketId (symbol),
1262
+ };
1263
+ const response = await this.futuresPublicGetFundingRateSymbolCurrent (this.extend (request, params));
1264
+ //
1265
+ // {
1266
+ // code: "200000",
1267
+ // data: {
1268
+ // symbol: ".ETHUSDTMFPI8H",
1269
+ // granularity: 28800000,
1270
+ // timePoint: 1637380800000,
1271
+ // value: 0.0001,
1272
+ // predictedValue: 0.0001,
1273
+ // },
1274
+ // }
1275
+ //
1276
+ const data = this.safeValue (response, 'data');
1277
+ const fundingTimestamp = this.safeNumber (data, 'timePoint');
1278
+ return {
1279
+ 'info': data,
1280
+ 'symbol': symbol,
1281
+ 'markPrice': undefined,
1282
+ 'indexPrice': undefined,
1283
+ 'interestRate': undefined,
1284
+ 'estimatedSettlePrice': undefined,
1285
+ 'timestamp': undefined,
1286
+ 'datetime': undefined,
1287
+ 'fundingRate': this.safeNumber (data, 'value'),
1288
+ 'fundingTimestamp': fundingTimestamp,
1289
+ 'fundingDatetime': this.iso8601 (fundingTimestamp),
1290
+ 'nextFundingRate': this.safeNumber (data, 'predictedValue'),
1291
+ 'nextFundingTimestamp': undefined,
1292
+ 'nextFundingDatetime': undefined,
1293
+ 'previousFundingRate': undefined,
1294
+ 'previousFundingTimestamp': undefined,
1295
+ 'previousFundingDatetime': undefined,
1296
+ };
1297
+ }
1298
+
1299
+ parseBalance (response) {
1300
+ const result = {
1301
+ 'info': response,
1302
+ 'timestamp': undefined,
1303
+ 'datetime': undefined,
1304
+ };
1305
+ const data = this.safeValue (response, 'data');
1306
+ const currencyId = this.safeString (data, 'currency');
1307
+ const code = this.safeCurrencyCode (currencyId);
1308
+ const account = this.account ();
1309
+ account['free'] = this.safeString (data, 'availableBalance');
1310
+ account['total'] = this.safeString (data, 'accountEquity');
1311
+ result[code] = account;
1312
+ return this.safeBalance (result);
1313
+ }
1314
+
1315
+ async fetchBalance (params = {}) {
1316
+ await this.loadMarkets ();
1317
+ // only fetches one balance at a time
1318
+ let defaultCode = this.safeString (this.options, 'code');
1319
+ const fetchBalanceOptions = this.safeValue (this.options, 'fetchBalance', {});
1320
+ defaultCode = this.safeString (fetchBalanceOptions, 'code', defaultCode);
1321
+ const code = this.safeString (params, 'code', defaultCode);
1322
+ const currency = this.currency (code);
1323
+ const request = {
1324
+ 'currency': currency['id'],
1325
+ };
1326
+ const response = await this.futuresPrivateGetAccountOverview (this.extend (request, params));
1327
+ //
1328
+ // {
1329
+ // code: '200000',
1330
+ // data: {
1331
+ // accountEquity: 0.00005,
1332
+ // unrealisedPNL: 0,
1333
+ // marginBalance: 0.00005,
1334
+ // positionMargin: 0,
1335
+ // orderMargin: 0,
1336
+ // frozenFunds: 0,
1337
+ // availableBalance: 0.00005,
1338
+ // currency: 'XBT'
1339
+ // }
1340
+ // }
1341
+ //
1342
+ return this.parseBalance (response);
1343
+ }
1344
+
1345
+ async transfer (code, amount, fromAccount, toAccount, params = {}) {
1346
+ if ((toAccount !== 'main' && toAccount !== 'funding') || (fromAccount !== 'futures' && fromAccount !== 'future' && fromAccount !== 'contract')) {
1347
+ throw new BadRequest (this.id + ' transfer() only supports transfers from contract(future) account to main(funding) account');
1348
+ }
1349
+ await this.loadMarkets ();
1350
+ const currency = this.currency (code);
1351
+ const amountToPrecision = this.currencyToPrecision (code, amount);
1352
+ const request = {
1353
+ 'currency': this.safeString (currency, 'id'), // Currency,including XBT,USDT
1354
+ 'amount': amountToPrecision,
1355
+ };
1356
+ // transfer from usdm futures wallet to spot wallet
1357
+ const response = await this.futuresPrivatePostTransferOut (this.extend (request, params));
1358
+ //
1359
+ // {
1360
+ // "code": "200000",
1361
+ // "data": {
1362
+ // "applyId": "5bffb63303aa675e8bbe18f9" // Transfer-out request ID
1363
+ // }
1364
+ // }
1365
+ //
1366
+ const data = this.safeValue (response, 'data');
1367
+ return this.extend (this.parseTransfer (data, currency), {
1368
+ 'amount': this.parseNumber (amountToPrecision),
1369
+ 'fromAccount': 'future',
1370
+ 'toAccount': 'spot',
1371
+ });
1372
+ }
1373
+
1374
+ parseTransfer (transfer, currency = undefined) {
1375
+ //
1376
+ // transfer
1377
+ //
1378
+ // {
1379
+ // "applyId": "5bffb63303aa675e8bbe18f9" // Transfer-out request ID
1380
+ // }
1381
+ //
1382
+ const timestamp = this.safeString (transfer, 'updatedAt');
1383
+ return {
1384
+ 'id': this.safeString (transfer, 'applyId'),
1385
+ 'timestamp': timestamp,
1386
+ 'datetime': this.iso8601 (timestamp),
1387
+ 'currency': this.safeCurrencyCode (undefined, currency),
1388
+ 'amount': undefined,
1389
+ 'fromAccount': undefined,
1390
+ 'toAccount': undefined,
1391
+ 'status': this.safeString (transfer, 'status'),
1392
+ 'info': transfer,
1393
+ };
1394
+ }
1395
+
1396
+ parseTransferStatus (status) {
1397
+ const statuses = {
1398
+ 'PROCESSING': 'pending',
1399
+ };
1400
+ return this.safeString (statuses, status, status);
1401
+ }
1402
+
1403
+ async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1404
+ await this.loadMarkets ();
1405
+ const request = {
1406
+ // orderId (String) [optional] Fills for a specific order (other parameters can be ignored if specified)
1407
+ // symbol (String) [optional] Symbol of the contract
1408
+ // side (String) [optional] buy or sell
1409
+ // type (String) [optional] limit, market, limit_stop or market_stop
1410
+ // startAt (long) [optional] Start time (milisecond)
1411
+ // endAt (long) [optional] End time (milisecond)
1412
+ };
1413
+ let market = undefined;
1414
+ if (symbol !== undefined) {
1415
+ market = this.market (symbol);
1416
+ request['symbol'] = market['id'];
1417
+ }
1418
+ if (since !== undefined) {
1419
+ request['startAt'] = since;
1420
+ }
1421
+ const response = await this.futuresPrivateGetFills (this.extend (request, params));
1422
+ //
1423
+ // {
1424
+ // "code": "200000",
1425
+ // "data": {
1426
+ // "currentPage": 1,
1427
+ // "pageSize": 1,
1428
+ // "totalNum": 251915,
1429
+ // "totalPage": 251915,
1430
+ // "items": [
1431
+ // {
1432
+ // "symbol": "XBTUSDM", // Ticker symbol of the contract
1433
+ // "tradeId": "5ce24c1f0c19fc3c58edc47c", // Trade ID
1434
+ // "orderId": "5ce24c16b210233c36ee321d", // Order ID
1435
+ // "side": "sell", // Transaction side
1436
+ // "liquidity": "taker", // Liquidity- taker or maker
1437
+ // "price": "8302", // Filled price
1438
+ // "size": 10, // Filled amount
1439
+ // "value": "0.001204529", // Order value
1440
+ // "feeRate": "0.0005", // Floating fees
1441
+ // "fixFee": "0.00000006", // Fixed fees
1442
+ // "feeCurrency": "XBT", // Charging currency
1443
+ // "stop": "", // A mark to the stop order type
1444
+ // "fee": "0.0000012022", // Transaction fee
1445
+ // "orderType": "limit", // Order type
1446
+ // "tradeType": "trade", // Trade type (trade, liquidation, ADL or settlement)
1447
+ // "createdAt": 1558334496000, // Time the order created
1448
+ // "settleCurrency": "XBT", // settlement currency
1449
+ // "tradeTime": 1558334496000000000 // trade time in nanosecond
1450
+ // }
1451
+ // ]
1452
+ // }
1453
+ // }
1454
+ //
1455
+ const data = this.safeValue (response, 'data', {});
1456
+ const trades = this.safeValue (data, 'items', {});
1457
+ return this.parseTrades (trades, market, since, limit);
1458
+ }
1459
+
1460
+ async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
1461
+ await this.loadMarkets ();
1462
+ const market = this.market (symbol);
1463
+ const request = {
1464
+ 'symbol': market['id'],
1465
+ };
1466
+ const response = await this.futuresPublicGetTradeHistory (this.extend (request, params));
1467
+ //
1468
+ // {
1469
+ // "code": "200000",
1470
+ // "data": [
1471
+ // {
1472
+ // "sequence": 32114961,
1473
+ // "side": "buy",
1474
+ // "size": 39,
1475
+ // "price": "4001.6500000000",
1476
+ // "takerOrderId": "61c20742f172110001e0ebe4",
1477
+ // "makerOrderId": "61c2073fcfc88100010fcb5d",
1478
+ // "tradeId": "61c2074277a0c473e69029b8",
1479
+ // "ts": 1640105794099993896 // filled time
1480
+ // }
1481
+ // ]
1482
+ // }
1483
+ //
1484
+ const trades = this.safeValue (response, 'data', []);
1485
+ return this.parseTrades (trades, market, since, limit);
1486
+ }
1487
+
1488
+ parseTrade (trade, market = undefined) {
1489
+ //
1490
+ // fetchTrades (public)
1491
+ //
1492
+ // {
1493
+ // "sequence": 32114961,
1494
+ // "side": "buy",
1495
+ // "size": 39,
1496
+ // "price": "4001.6500000000",
1497
+ // "takerOrderId": "61c20742f172110001e0ebe4",
1498
+ // "makerOrderId": "61c2073fcfc88100010fcb5d",
1499
+ // "tradeId": "61c2074277a0c473e69029b8",
1500
+ // "ts": 1640105794099993896 // filled time
1501
+ // }
1502
+ //
1503
+ // fetchMyTrades (private) v2
1504
+ //
1505
+ // {
1506
+ // "symbol":"BTC-USDT",
1507
+ // "tradeId":"5c35c02709e4f67d5266954e",
1508
+ // "orderId":"5c35c02703aa673ceec2a168",
1509
+ // "counterOrderId":"5c1ab46003aa676e487fa8e3",
1510
+ // "side":"buy",
1511
+ // "liquidity":"taker",
1512
+ // "forceTaker":true,
1513
+ // "price":"0.083",
1514
+ // "size":"0.8424304",
1515
+ // "funds":"0.0699217232",
1516
+ // "fee":"0",
1517
+ // "feeRate":"0",
1518
+ // "feeCurrency":"USDT",
1519
+ // "stop":"",
1520
+ // "type":"limit",
1521
+ // "createdAt":1547026472000
1522
+ // }
1523
+ //
1524
+ // fetchMyTrades (private) v1
1525
+ //
1526
+ // {
1527
+ // "symbol":"DOGEUSDTM",
1528
+ // "tradeId":"620ec41a96bab27b5f4ced56",
1529
+ // "orderId":"620ec41a0d1d8a0001560bd0",
1530
+ // "side":"sell",
1531
+ // "liquidity":"taker",
1532
+ // "forceTaker":true,
1533
+ // "price":"0.13969",
1534
+ // "size":1,
1535
+ // "value":"13.969",
1536
+ // "feeRate":"0.0006",
1537
+ // "fixFee":"0",
1538
+ // "feeCurrency":"USDT",
1539
+ // "stop":"",
1540
+ // "tradeTime":1645134874858018058,
1541
+ // "fee":"0.0083814",
1542
+ // "settleCurrency":"USDT",
1543
+ // "orderType":"market",
1544
+ // "tradeType":"trade",
1545
+ // "createdAt":1645134874858
1546
+ // }
1547
+ //
1548
+ const marketId = this.safeString (trade, 'symbol');
1549
+ market = this.safeMarket (marketId, market, '-');
1550
+ const id = this.safeString2 (trade, 'tradeId', 'id');
1551
+ const orderId = this.safeString (trade, 'orderId');
1552
+ const takerOrMaker = this.safeString (trade, 'liquidity');
1553
+ let timestamp = this.safeInteger (trade, 'time');
1554
+ if (timestamp !== undefined) {
1555
+ timestamp = parseInt (timestamp / 1000000);
1556
+ } else {
1557
+ timestamp = this.safeInteger (trade, 'createdAt');
1558
+ // if it's a historical v1 trade, the exchange returns timestamp in seconds
1559
+ if (('dealValue' in trade) && (timestamp !== undefined)) {
1560
+ timestamp = timestamp * 1000;
1561
+ }
1562
+ }
1563
+ const priceString = this.safeString2 (trade, 'price', 'dealPrice');
1564
+ const amountString = this.safeString2 (trade, 'size', 'amount');
1565
+ const side = this.safeString (trade, 'side');
1566
+ let fee = undefined;
1567
+ const feeCostString = this.safeString (trade, 'fee');
1568
+ if (feeCostString !== undefined) {
1569
+ const feeCurrencyId = this.safeString (trade, 'feeCurrency');
1570
+ let feeCurrency = this.safeCurrencyCode (feeCurrencyId);
1571
+ if (feeCurrency === undefined) {
1572
+ feeCurrency = (side === 'sell') ? market['quote'] : market['base'];
1573
+ }
1574
+ fee = {
1575
+ 'cost': feeCostString,
1576
+ 'currency': feeCurrency,
1577
+ 'rate': this.safeString (trade, 'feeRate'),
1578
+ };
1579
+ }
1580
+ let type = this.safeString2 (trade, 'type', 'orderType');
1581
+ if (type === 'match') {
1582
+ type = undefined;
1583
+ }
1584
+ let costString = this.safeString2 (trade, 'funds', 'value');
1585
+ if (costString === undefined) {
1586
+ const contractSize = this.safeString (market, 'contractSize');
1587
+ const contractCost = Precise.stringMul (priceString, amountString);
1588
+ costString = Precise.stringMul (contractCost, contractSize);
1589
+ }
1590
+ return this.safeTrade ({
1591
+ 'info': trade,
1592
+ 'id': id,
1593
+ 'order': orderId,
1594
+ 'timestamp': timestamp,
1595
+ 'datetime': this.iso8601 (timestamp),
1596
+ 'symbol': market['symbol'],
1597
+ 'type': type,
1598
+ 'takerOrMaker': takerOrMaker,
1599
+ 'side': side,
1600
+ 'price': priceString,
1601
+ 'amount': amountString,
1602
+ 'cost': costString,
1603
+ 'fee': fee,
1604
+ }, market);
1605
+ }
1606
+
1607
+ async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
1608
+ await this.loadMarkets ();
1609
+ const request = {};
1610
+ let currency = undefined;
1611
+ if (code !== undefined) {
1612
+ currency = this.currency (code);
1613
+ request['currency'] = currency['id'];
1614
+ }
1615
+ if (limit !== undefined) {
1616
+ request['pageSize'] = limit;
1617
+ }
1618
+ if (since !== undefined) {
1619
+ request['startAt'] = since;
1620
+ }
1621
+ const response = await this.futuresPrivateGetDepositList (this.extend (request, params));
1622
+ //
1623
+ // {
1624
+ // code: '200000',
1625
+ // data: {
1626
+ // "currentPage": 1,
1627
+ // "pageSize": 5,
1628
+ // "totalNum": 2,
1629
+ // "totalPage": 1,
1630
+ // "items": [
1631
+ // {
1632
+ // "address": "0x5f047b29041bcfdbf0e4478cdfa753a336ba6989",
1633
+ // "memo": "5c247c8a03aa677cea2a251d",
1634
+ // "amount": 1,
1635
+ // "fee": 0.0001,
1636
+ // "currency": "KCS",
1637
+ // "isInner": false,
1638
+ // "walletTxId": "5bbb57386d99522d9f954c5a@test004",
1639
+ // "status": "SUCCESS",
1640
+ // "createdAt": 1544178843000,
1641
+ // "updatedAt": 1544178891000
1642
+ // "remark":"foobar"
1643
+ // },
1644
+ // ...
1645
+ // ]
1646
+ // }
1647
+ // }
1648
+ //
1649
+ const responseData = response['data']['items'];
1650
+ return this.parseTransactions (responseData, currency, since, limit, { 'type': 'deposit' });
1651
+ }
1652
+
1653
+ async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
1654
+ await this.loadMarkets ();
1655
+ const request = {};
1656
+ let currency = undefined;
1657
+ if (code !== undefined) {
1658
+ currency = this.currency (code);
1659
+ request['currency'] = currency['id'];
1660
+ }
1661
+ if (limit !== undefined) {
1662
+ request['pageSize'] = limit;
1663
+ }
1664
+ if (since !== undefined) {
1665
+ request['startAt'] = since;
1666
+ }
1667
+ const response = await this.futuresPrivateGetWithdrawalList (this.extend (request, params));
1668
+ //
1669
+ // {
1670
+ // code: '200000',
1671
+ // data: {
1672
+ // "currentPage": 1,
1673
+ // "pageSize": 5,
1674
+ // "totalNum": 2,
1675
+ // "totalPage": 1,
1676
+ // "items": [
1677
+ // {
1678
+ // "id": "5c2dc64e03aa675aa263f1ac",
1679
+ // "address": "0x5bedb060b8eb8d823e2414d82acce78d38be7fe9",
1680
+ // "memo": "",
1681
+ // "currency": "ETH",
1682
+ // "amount": 1.0000000,
1683
+ // "fee": 0.0100000,
1684
+ // "walletTxId": "3e2414d82acce78d38be7fe9",
1685
+ // "isInner": false,
1686
+ // "status": "FAILURE",
1687
+ // "createdAt": 1546503758000,
1688
+ // "updatedAt": 1546504603000
1689
+ // },
1690
+ // ...
1691
+ // ]
1692
+ // }
1693
+ // }
1694
+ //
1695
+ const responseData = response['data']['items'];
1696
+ return this.parseTransactions (responseData, currency, since, limit, { 'type': 'withdrawal' });
1697
+ }
1698
+
1699
+ async fetchFundingFee (code, params = {}) {
1700
+ throw new BadRequest (this.id + ' fetchFundingFee() is not supported yet');
1701
+ }
1702
+
1703
+ async fetchLedger (code = undefined, since = undefined, limit = undefined, params = {}) {
1704
+ throw new BadRequest (this.id + ' fetchLedger() is not supported yet');
1705
+ }
1706
+
1707
+ async fetchMarketLeverageTiers (symbol, params = {}) {
1708
+ await this.loadMarkets ();
1709
+ const market = this.market (symbol);
1710
+ if (!market['contract']) {
1711
+ throw new BadRequest (this.id + ' fetchLeverageTiers() supports contract markets only');
1712
+ }
1713
+ const request = {
1714
+ 'symbol': market['id'],
1715
+ };
1716
+ const response = await this.futuresPublicGetContractsRiskLimitSymbol (this.extend (request, params));
1717
+ //
1718
+ // {
1719
+ // "code": "200000",
1720
+ // "data": [
1721
+ // {
1722
+ // "symbol": "ETHUSDTM",
1723
+ // "level": 1,
1724
+ // "maxRiskLimit": 300000,
1725
+ // "minRiskLimit": 0,
1726
+ // "maxLeverage": 100,
1727
+ // "initialMargin": 0.0100000000,
1728
+ // "maintainMargin": 0.0050000000
1729
+ // },
1730
+ // ...
1731
+ // ]
1732
+ // }
1733
+ //
1734
+ const data = this.safeValue (response, 'data');
1735
+ return this.parseMarketLeverageTiers (data, market);
1736
+ }
1737
+
1738
+ parseMarketLeverageTiers (info, market) {
1739
+ /**
1740
+ * @ignore
1741
+ * @method
1742
+ * @param {dict} info Exchange market response for 1 market
1743
+ * @param {dict} market CCXT market
1744
+ */
1745
+ //
1746
+ // {
1747
+ // "symbol": "ETHUSDTM",
1748
+ // "level": 1,
1749
+ // "maxRiskLimit": 300000,
1750
+ // "minRiskLimit": 0,
1751
+ // "maxLeverage": 100,
1752
+ // "initialMargin": 0.0100000000,
1753
+ // "maintainMargin": 0.0050000000
1754
+ // }
1755
+ //
1756
+ const tiers = [];
1757
+ for (let i = 0; i < info.length; i++) {
1758
+ const tier = info[i];
1759
+ tiers.push ({
1760
+ 'tier': this.safeNumber (tier, 'level'),
1761
+ 'currency': market['base'],
1762
+ 'minNotional': this.safeNumber (tier, 'minRiskLimit'),
1763
+ 'maxNotional': this.safeNumber (tier, 'maxRiskLimit'),
1764
+ 'maintenanceMarginRate': this.safeNumber (tier, 'maintainMargin'),
1765
+ 'maxLeverage': this.safeNumber (tier, 'maxLeverage'),
1766
+ 'info': tier,
1767
+ });
1768
+ }
1769
+ return tiers;
1770
+ }
1771
+ };