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
package/js/coinex.js ADDED
@@ -0,0 +1,3400 @@
1
+ 'use strict';
2
+
3
+ // ---------------------------------------------------------------------------
4
+
5
+ const Exchange = require ('./base/Exchange');
6
+ const { ExchangeError, ArgumentsRequired, BadRequest, BadSymbol, InsufficientFunds, OrderNotFound, InvalidOrder, AuthenticationError, PermissionDenied, ExchangeNotAvailable, RequestTimeout } = require ('./base/errors');
7
+ const Precise = require ('./base/Precise');
8
+
9
+ // ---------------------------------------------------------------------------
10
+
11
+ module.exports = class coinex extends Exchange {
12
+ describe () {
13
+ return this.deepExtend (super.describe (), {
14
+ 'id': 'coinex',
15
+ 'name': 'CoinEx',
16
+ 'version': 'v1',
17
+ 'countries': [ 'CN' ],
18
+ 'rateLimit': 50, // Normal limit frequency is single IP:200 times / 10 seconds
19
+ 'has': {
20
+ 'CORS': undefined,
21
+ 'spot': true,
22
+ 'margin': undefined, // has but unimplemented
23
+ 'swap': true,
24
+ 'future': false,
25
+ 'option': false,
26
+ 'addMargin': true,
27
+ 'cancelAllOrders': true,
28
+ 'cancelOrder': true,
29
+ 'createOrder': true,
30
+ 'createReduceOnlyOrder': true,
31
+ 'fetchBalance': true,
32
+ 'fetchClosedOrders': true,
33
+ 'fetchDeposits': true,
34
+ 'fetchFundingHistory': true,
35
+ 'fetchFundingRate': true,
36
+ 'fetchFundingRateHistory': true,
37
+ 'fetchFundingRates': false,
38
+ 'fetchIndexOHLCV': false,
39
+ 'fetchLeverage': undefined,
40
+ 'fetchLeverageTiers': undefined,
41
+ 'fetchMarketLeverageTiers': undefined,
42
+ 'fetchMarkets': true,
43
+ 'fetchMarkOHLCV': false,
44
+ 'fetchMyTrades': true,
45
+ 'fetchOHLCV': true,
46
+ 'fetchOpenOrders': true,
47
+ 'fetchOrder': true,
48
+ 'fetchOrderBook': true,
49
+ 'fetchPosition': true,
50
+ 'fetchPositions': true,
51
+ 'fetchPositionsRisk': false,
52
+ 'fetchPremiumIndexOHLCV': false,
53
+ 'fetchTicker': true,
54
+ 'fetchTickers': true,
55
+ 'fetchTrades': true,
56
+ 'fetchTradingFee': true,
57
+ 'fetchTradingFees': true,
58
+ 'fetchTransfers': true,
59
+ 'fetchWithdrawals': true,
60
+ 'reduceMargin': true,
61
+ 'setLeverage': true,
62
+ 'setMarginMode': true,
63
+ 'setPositionMode': false,
64
+ 'transfer': true,
65
+ 'withdraw': true,
66
+ },
67
+ 'timeframes': {
68
+ '1m': '1min',
69
+ '3m': '3min',
70
+ '5m': '5min',
71
+ '15m': '15min',
72
+ '30m': '30min',
73
+ '1h': '1hour',
74
+ '2h': '2hour',
75
+ '4h': '4hour',
76
+ '6h': '6hour',
77
+ '12h': '12hour',
78
+ '1d': '1day',
79
+ '3d': '3day',
80
+ '1w': '1week',
81
+ },
82
+ 'urls': {
83
+ 'logo': 'https://user-images.githubusercontent.com/51840849/87182089-1e05fa00-c2ec-11ea-8da9-cc73b45abbbc.jpg',
84
+ 'api': {
85
+ 'public': 'https://api.coinex.com',
86
+ 'private': 'https://api.coinex.com',
87
+ 'perpetualPublic': 'https://api.coinex.com/perpetual',
88
+ 'perpetualPrivate': 'https://api.coinex.com/perpetual',
89
+ },
90
+ 'www': 'https://www.coinex.com',
91
+ 'doc': 'https://github.com/coinexcom/coinex_exchange_api/wiki',
92
+ 'fees': 'https://www.coinex.com/fees',
93
+ 'referral': 'https://www.coinex.com/register?refer_code=yw5fz',
94
+ },
95
+ 'api': {
96
+ 'public': {
97
+ 'get': {
98
+ 'amm/market': 1,
99
+ 'common/currency/rate': 1,
100
+ 'common/asset/config': 1,
101
+ 'common/maintain/info': 1,
102
+ 'common/temp-maintain/info': 1,
103
+ 'margin/market': 1,
104
+ 'market/info': 1,
105
+ 'market/list': 1,
106
+ 'market/ticker': 1,
107
+ 'market/ticker/all': 1,
108
+ 'market/depth': 1,
109
+ 'market/deals': 1,
110
+ 'market/kline': 1,
111
+ 'market/detail': 1,
112
+ },
113
+ },
114
+ 'private': {
115
+ 'get': {
116
+ 'account/amm/balance': 1,
117
+ 'account/investment/balance': 1,
118
+ 'account/balance/history': 1,
119
+ 'account/market/fee': 1,
120
+ 'balance/coin/deposit': 1,
121
+ 'balance/coin/withdraw': 1,
122
+ 'balance/info': 1,
123
+ 'balance/deposit/address/{coin_type}': 1,
124
+ 'contract/transfer/history': 1,
125
+ 'credit/info': 1,
126
+ 'credit/balance': 1,
127
+ 'investment/transfer/history': 1,
128
+ 'margin/account': 1,
129
+ 'margin/config': 1,
130
+ 'margin/loan/history': 1,
131
+ 'margin/transfer/history': 1,
132
+ 'order': 1,
133
+ 'order/deals': 1,
134
+ 'order/finished': 1,
135
+ 'order/pending': 1,
136
+ 'order/status': 1,
137
+ 'order/status/batch': 1,
138
+ 'order/user/deals': 1,
139
+ 'order/stop/finished': 1,
140
+ 'order/stop/pending': 1,
141
+ 'order/user/trade/fee': 1,
142
+ 'order/market/trade/info': 1,
143
+ 'sub_account/balance': 1,
144
+ 'sub_account/transfer/history': 1,
145
+ 'sub_account/auth/api/{user_auth_id}': 1,
146
+ },
147
+ 'post': {
148
+ 'balance/coin/withdraw': 1,
149
+ 'contract/balance/transfer': 1,
150
+ 'margin/flat': 1,
151
+ 'margin/loan': 1,
152
+ 'margin/transfer': 1,
153
+ 'order/limit/batch': 1,
154
+ 'order/ioc': 1,
155
+ 'order/limit': 1,
156
+ 'order/market': 1,
157
+ 'order/stop/limit': 1,
158
+ 'order/stop/market': 1,
159
+ 'sub_account/transfer': 1,
160
+ 'sub_account/register': 1,
161
+ 'sub_account/unfrozen': 1,
162
+ 'sub_account/frozen': 1,
163
+ 'sub_account/auth/api': 1,
164
+ },
165
+ 'put': {
166
+ 'balance/deposit/address/{coin_type}': 1,
167
+ 'sub_account/auth/api/{user_auth_id}': 1,
168
+ 'v1/account/settings': 1,
169
+ },
170
+ 'delete': {
171
+ 'balance/coin/withdraw': 1,
172
+ 'order/pending/batch': 1,
173
+ 'order/pending': 1,
174
+ 'order/stop/pending': 1,
175
+ 'order/stop/pending/{id}': 1,
176
+ 'sub_account/auth/api/{user_auth_id}': 1,
177
+ },
178
+ },
179
+ 'perpetualPublic': {
180
+ 'get': {
181
+ 'ping': 1,
182
+ 'time': 1,
183
+ 'market/list': 1,
184
+ 'market/limit_config': 1,
185
+ 'market/ticker': 1,
186
+ 'market/ticker/all': 1,
187
+ 'market/depth': 1,
188
+ 'market/deals': 1,
189
+ 'market/funding_history': 1,
190
+ 'market/user_deals': 1,
191
+ 'market/kline': 1,
192
+ },
193
+ },
194
+ 'perpetualPrivate': {
195
+ 'get': {
196
+ 'asset/query': 1,
197
+ 'order/pending': 1,
198
+ 'order/finished': 1,
199
+ 'order/stop_pending': 1,
200
+ 'order/status': 1,
201
+ 'order/stop_status': 1,
202
+ 'position/pending': 1,
203
+ 'position/funding': 1,
204
+ },
205
+ 'post': {
206
+ 'market/adjust_leverage': 1,
207
+ 'market/position_expect': 1,
208
+ 'order/put_limit': 1,
209
+ 'order/put_market': 1,
210
+ 'order/put_stop_limit': 1,
211
+ 'order/put_stop_market': 1,
212
+ 'order/cancel': 1,
213
+ 'order/cancel_all': 1,
214
+ 'order/cancel_stop': 1,
215
+ 'order/cancel_stop_all': 1,
216
+ 'order/close_limit': 1,
217
+ 'order/close_market': 1,
218
+ 'position/adjust_margin': 1,
219
+ },
220
+ },
221
+ },
222
+ 'fees': {
223
+ 'trading': {
224
+ 'maker': 0.001,
225
+ 'taker': 0.001,
226
+ },
227
+ 'funding': {
228
+ 'withdraw': {
229
+ 'BCH': 0.0,
230
+ 'BTC': 0.001,
231
+ 'LTC': 0.001,
232
+ 'ETH': 0.001,
233
+ 'ZEC': 0.0001,
234
+ 'DASH': 0.0001,
235
+ },
236
+ },
237
+ },
238
+ 'limits': {
239
+ 'amount': {
240
+ 'min': 0.001,
241
+ 'max': undefined,
242
+ },
243
+ },
244
+ 'precision': {
245
+ 'amount': 8,
246
+ 'price': 8,
247
+ },
248
+ 'options': {
249
+ 'createMarketBuyOrderRequiresPrice': true,
250
+ 'defaultType': 'spot', // spot, swap, margin
251
+ 'defaultSubType': 'linear', // linear, inverse
252
+ 'defaultMarginType': 'isolated', // isolated, cross
253
+ },
254
+ 'commonCurrencies': {
255
+ 'ACM': 'Actinium',
256
+ },
257
+ });
258
+ }
259
+
260
+ async fetchMarkets (params = {}) {
261
+ let result = [];
262
+ const [ type, query ] = this.handleMarketTypeAndParams ('fetchMarkets', undefined, params);
263
+ if (type === 'spot' || type === 'margin') {
264
+ result = await this.fetchSpotMarkets (query);
265
+ } else if (type === 'swap') {
266
+ result = await this.fetchContractMarkets (query);
267
+ } else {
268
+ throw new ExchangeError (this.id + " does not support the '" + type + "' market type, set exchange.options['defaultType'] to 'spot', 'margin' or 'swap'");
269
+ }
270
+ return result;
271
+ }
272
+
273
+ async fetchSpotMarkets (params) {
274
+ const response = await this.publicGetMarketInfo (params);
275
+ //
276
+ // {
277
+ // "code": 0,
278
+ // "data": {
279
+ // "WAVESBTC": {
280
+ // "name": "WAVESBTC",
281
+ // "min_amount": "1",
282
+ // "maker_fee_rate": "0.001",
283
+ // "taker_fee_rate": "0.001",
284
+ // "pricing_name": "BTC",
285
+ // "pricing_decimal": 8,
286
+ // "trading_name": "WAVES",
287
+ // "trading_decimal": 8
288
+ // }
289
+ // }
290
+ // }
291
+ //
292
+ const markets = this.safeValue (response, 'data', {});
293
+ const result = [];
294
+ const keys = Object.keys (markets);
295
+ for (let i = 0; i < keys.length; i++) {
296
+ const key = keys[i];
297
+ const market = markets[key];
298
+ const id = this.safeString (market, 'name');
299
+ const tradingName = this.safeString (market, 'trading_name');
300
+ const baseId = tradingName;
301
+ const quoteId = this.safeString (market, 'pricing_name');
302
+ const base = this.safeCurrencyCode (baseId);
303
+ const quote = this.safeCurrencyCode (quoteId);
304
+ let symbol = base + '/' + quote;
305
+ if (tradingName === id) {
306
+ symbol = id;
307
+ }
308
+ result.push ({
309
+ 'id': id,
310
+ 'symbol': symbol,
311
+ 'base': base,
312
+ 'quote': quote,
313
+ 'settle': undefined,
314
+ 'baseId': baseId,
315
+ 'quoteId': quoteId,
316
+ 'settleId': undefined,
317
+ 'type': 'spot',
318
+ 'spot': true,
319
+ 'margin': undefined,
320
+ 'swap': false,
321
+ 'future': false,
322
+ 'option': false,
323
+ 'active': undefined,
324
+ 'contract': false,
325
+ 'linear': undefined,
326
+ 'inverse': undefined,
327
+ 'taker': this.safeNumber (market, 'taker_fee_rate'),
328
+ 'maker': this.safeNumber (market, 'maker_fee_rate'),
329
+ 'contractSize': undefined,
330
+ 'expiry': undefined,
331
+ 'expiryDatetime': undefined,
332
+ 'strike': undefined,
333
+ 'optionType': undefined,
334
+ 'precision': {
335
+ 'amount': this.safeInteger (market, 'trading_decimal'),
336
+ 'price': this.safeInteger (market, 'pricing_decimal'),
337
+ },
338
+ 'limits': {
339
+ 'leverage': {
340
+ 'min': undefined,
341
+ 'max': undefined,
342
+ },
343
+ 'amount': {
344
+ 'min': this.safeNumber (market, 'min_amount'),
345
+ 'max': undefined,
346
+ },
347
+ 'price': {
348
+ 'min': undefined,
349
+ 'max': undefined,
350
+ },
351
+ 'cost': {
352
+ 'min': undefined,
353
+ 'max': undefined,
354
+ },
355
+ },
356
+ 'info': market,
357
+ });
358
+ }
359
+ return result;
360
+ }
361
+
362
+ async fetchContractMarkets (params) {
363
+ const response = await this.perpetualPublicGetMarketList (params);
364
+ //
365
+ // {
366
+ // "code": 0,
367
+ // "data": [
368
+ // {
369
+ // "name": "BTCUSD",
370
+ // "type": 2, // 1: USDT-M Contracts, 2: Coin-M Contracts
371
+ // "leverages": ["3", "5", "8", "10", "15", "20", "30", "50", "100"],
372
+ // "stock": "BTC",
373
+ // "money": "USD",
374
+ // "fee_prec": 5,
375
+ // "stock_prec": 8,
376
+ // "money_prec": 1,
377
+ // "amount_prec": 0,
378
+ // "amount_min": "10",
379
+ // "multiplier": "1",
380
+ // "tick_size": "0.1", // Min. Price Increment
381
+ // "available": true
382
+ // },
383
+ // ],
384
+ // "message": "OK"
385
+ // }
386
+ //
387
+ const markets = this.safeValue (response, 'data', []);
388
+ const result = [];
389
+ for (let i = 0; i < markets.length; i++) {
390
+ const entry = markets[i];
391
+ const fees = this.fees;
392
+ const leverages = this.safeValue (entry, 'leverages', []);
393
+ const subType = this.safeInteger (entry, 'type');
394
+ const linear = (subType === 1) ? true : false;
395
+ const inverse = (subType === 2) ? true : false;
396
+ const id = this.safeString (entry, 'name');
397
+ const baseId = this.safeString (entry, 'stock');
398
+ const quoteId = this.safeString (entry, 'money');
399
+ const base = this.safeCurrencyCode (baseId);
400
+ const quote = this.safeCurrencyCode (quoteId);
401
+ const settleId = (subType === 1) ? 'USDT' : baseId;
402
+ const settle = this.safeCurrencyCode (settleId);
403
+ const symbol = base + '/' + quote + ':' + settle;
404
+ result.push ({
405
+ 'id': id,
406
+ 'symbol': symbol,
407
+ 'base': base,
408
+ 'quote': quote,
409
+ 'settle': settle,
410
+ 'baseId': baseId,
411
+ 'quoteId': quoteId,
412
+ 'settleId': settleId,
413
+ 'type': 'swap',
414
+ 'spot': false,
415
+ 'margin': false,
416
+ 'swap': true,
417
+ 'future': false,
418
+ 'option': false,
419
+ 'active': this.safeString (entry, 'available'),
420
+ 'contract': true,
421
+ 'linear': linear,
422
+ 'inverse': inverse,
423
+ 'taker': fees['trading']['taker'],
424
+ 'maker': fees['trading']['maker'],
425
+ 'contractSize': undefined,
426
+ 'expiry': undefined,
427
+ 'expiryDatetime': undefined,
428
+ 'strike': undefined,
429
+ 'optionType': undefined,
430
+ 'precision': {
431
+ 'amount': this.safeInteger (entry, 'stock_prec'),
432
+ 'price': this.safeInteger (entry, 'money_prec'),
433
+ },
434
+ 'limits': {
435
+ 'leverage': {
436
+ 'min': this.safeString (leverages, 0),
437
+ 'max': this.safeString (leverages, leverages.length - 1),
438
+ },
439
+ 'amount': {
440
+ 'min': this.safeString (entry, 'amount_min'),
441
+ 'max': undefined,
442
+ },
443
+ 'price': {
444
+ 'min': undefined,
445
+ 'max': undefined,
446
+ },
447
+ 'cost': {
448
+ 'min': undefined,
449
+ 'max': undefined,
450
+ },
451
+ },
452
+ 'info': entry,
453
+ });
454
+ }
455
+ return result;
456
+ }
457
+
458
+ parseTicker (ticker, market = undefined) {
459
+ //
460
+ // Spot fetchTicker, fetchTickers
461
+ //
462
+ // {
463
+ // "vol": "293.19415130",
464
+ // "low": "38200.00",
465
+ // "open": "39514.99",
466
+ // "high": "39530.00",
467
+ // "last": "38649.57",
468
+ // "buy": "38640.20",
469
+ // "buy_amount": "0.22800000",
470
+ // "sell": "38640.21",
471
+ // "sell_amount": "0.02828439"
472
+ // }
473
+ //
474
+ // Swap fetchTicker, fetchTickers
475
+ //
476
+ // {
477
+ // "vol": "7714.2175",
478
+ // "low": "38200.00",
479
+ // "open": "39569.23",
480
+ // "high": "39569.23",
481
+ // "last": "38681.37",
482
+ // "buy": "38681.36",
483
+ // "period": 86400,
484
+ // "funding_time": 462,
485
+ // "position_amount": "296.7552",
486
+ // "funding_rate_last": "0.00009395",
487
+ // "funding_rate_next": "0.00000649",
488
+ // "funding_rate_predict": "-0.00007176",
489
+ // "insurance": "16464465.09431942163278132918",
490
+ // "sign_price": "38681.93",
491
+ // "index_price": "38681.69500000",
492
+ // "sell_total": "16.6039",
493
+ // "buy_total": "19.8481",
494
+ // "buy_amount": "4.6315",
495
+ // "sell": "38681.37",
496
+ // "sell_amount": "11.4044"
497
+ // }
498
+ //
499
+ const timestamp = this.safeInteger (ticker, 'date');
500
+ const symbol = this.safeSymbol (undefined, market);
501
+ ticker = this.safeValue (ticker, 'ticker', {});
502
+ const last = this.safeString (ticker, 'last');
503
+ return this.safeTicker ({
504
+ 'symbol': symbol,
505
+ 'timestamp': timestamp,
506
+ 'datetime': this.iso8601 (timestamp),
507
+ 'high': this.safeString (ticker, 'high'),
508
+ 'low': this.safeString (ticker, 'low'),
509
+ 'bid': this.safeString (ticker, 'buy'),
510
+ 'bidVolume': undefined,
511
+ 'ask': this.safeString (ticker, 'sell'),
512
+ 'askVolume': undefined,
513
+ 'vwap': undefined,
514
+ 'open': this.safeString (ticker, 'open'),
515
+ 'close': last,
516
+ 'last': last,
517
+ 'previousClose': undefined,
518
+ 'change': undefined,
519
+ 'percentage': undefined,
520
+ 'average': undefined,
521
+ 'baseVolume': this.safeString2 (ticker, 'vol', 'volume'),
522
+ 'quoteVolume': undefined,
523
+ 'info': ticker,
524
+ }, market, false);
525
+ }
526
+
527
+ async fetchTicker (symbol, params = {}) {
528
+ await this.loadMarkets ();
529
+ const market = this.market (symbol);
530
+ const request = {
531
+ 'market': market['id'],
532
+ };
533
+ const method = market['swap'] ? 'perpetualPublicGetMarketTicker' : 'publicGetMarketTicker';
534
+ const response = await this[method] (this.extend (request, params));
535
+ //
536
+ // Spot
537
+ //
538
+ // {
539
+ // "code": 0,
540
+ // "data": {
541
+ // "date": 1651306913414,
542
+ // "ticker": {
543
+ // "vol": "293.19415130",
544
+ // "low": "38200.00",
545
+ // "open": "39514.99",
546
+ // "high": "39530.00",
547
+ // "last": "38649.57",
548
+ // "buy": "38640.20",
549
+ // "buy_amount": "0.22800000",
550
+ // "sell": "38640.21",
551
+ // "sell_amount": "0.02828439"
552
+ // }
553
+ // },
554
+ // "message": "OK"
555
+ // }
556
+ //
557
+ // Swap
558
+ //
559
+ // {
560
+ // "code": 0,
561
+ // "data": {
562
+ // "date": 1651306641500,
563
+ // "ticker": {
564
+ // "vol": "7714.2175",
565
+ // "low": "38200.00",
566
+ // "open": "39569.23",
567
+ // "high": "39569.23",
568
+ // "last": "38681.37",
569
+ // "buy": "38681.36",
570
+ // "period": 86400,
571
+ // "funding_time": 462,
572
+ // "position_amount": "296.7552",
573
+ // "funding_rate_last": "0.00009395",
574
+ // "funding_rate_next": "0.00000649",
575
+ // "funding_rate_predict": "-0.00007176",
576
+ // "insurance": "16464465.09431942163278132918",
577
+ // "sign_price": "38681.93",
578
+ // "index_price": "38681.69500000",
579
+ // "sell_total": "16.6039",
580
+ // "buy_total": "19.8481",
581
+ // "buy_amount": "4.6315",
582
+ // "sell": "38681.37",
583
+ // "sell_amount": "11.4044"
584
+ // }
585
+ // },
586
+ // "message": "OK"
587
+ // }
588
+ //
589
+ return this.parseTicker (response['data'], market);
590
+ }
591
+
592
+ async fetchTickers (symbols = undefined, params = {}) {
593
+ await this.loadMarkets ();
594
+ const [ marketType, query ] = this.handleMarketTypeAndParams ('fetchTickers', undefined, params);
595
+ const method = (marketType === 'swap') ? 'perpetualPublicGetMarketTickerAll' : 'publicGetMarketTickerAll';
596
+ const response = await this[method] (query);
597
+ //
598
+ // Spot
599
+ //
600
+ // {
601
+ // "code": 0,
602
+ // "data": {
603
+ // "date": 1651519857284,
604
+ // "ticker": {
605
+ // "PSPUSDT": {
606
+ // "vol": "127131.55227034",
607
+ // "low": "0.0669",
608
+ // "open": "0.0688",
609
+ // "high": "0.0747",
610
+ // "last": "0.0685",
611
+ // "buy": "0.0676",
612
+ // "buy_amount": "702.70117866",
613
+ // "sell": "0.0690",
614
+ // "sell_amount": "686.76861562"
615
+ // },
616
+ // }
617
+ // },
618
+ // "message": "Ok"
619
+ // }
620
+ //
621
+ // Swap
622
+ //
623
+ // {
624
+ // "code": 0,
625
+ // "data": {
626
+ // "date": 1651520268644,
627
+ // "ticker": {
628
+ // "KAVAUSDT": {
629
+ // "vol": "834924",
630
+ // "low": "3.9418",
631
+ // "open": "4.1834",
632
+ // "high": "4.4328",
633
+ // "last": "4.0516",
634
+ // "buy": "4.0443",
635
+ // "period": 86400,
636
+ // "funding_time": 262,
637
+ // "position_amount": "16111",
638
+ // "funding_rate_last": "-0.00069514",
639
+ // "funding_rate_next": "-0.00061009",
640
+ // "funding_rate_predict": "-0.00055812",
641
+ // "insurance": "16532425.53026084124483989548",
642
+ // "sign_price": "4.0516",
643
+ // "index_price": "4.0530",
644
+ // "sell_total": "59446",
645
+ // "buy_total": "62423",
646
+ // "buy_amount": "959",
647
+ // "sell": "4.0466",
648
+ // "sell_amount": "141"
649
+ // },
650
+ // }
651
+ // },
652
+ // "message": "Ok"
653
+ // }
654
+ //
655
+ const data = this.safeValue (response, 'data');
656
+ const timestamp = this.safeInteger (data, 'date');
657
+ const tickers = this.safeValue (data, 'ticker');
658
+ const marketIds = Object.keys (tickers);
659
+ const result = {};
660
+ for (let i = 0; i < marketIds.length; i++) {
661
+ const marketId = marketIds[i];
662
+ const market = this.safeMarket (marketId);
663
+ const symbol = market['symbol'];
664
+ const ticker = this.parseTicker ({
665
+ 'date': timestamp,
666
+ 'ticker': tickers[marketId],
667
+ }, market);
668
+ ticker['symbol'] = symbol;
669
+ result[symbol] = ticker;
670
+ }
671
+ return this.filterByArray (result, 'symbol', symbols);
672
+ }
673
+
674
+ async fetchOrderBook (symbol, limit = 20, params = {}) {
675
+ if (symbol === undefined) {
676
+ throw new ArgumentsRequired (this.id + ' fetchOrderBook() requires a symbol argument');
677
+ }
678
+ await this.loadMarkets ();
679
+ const market = this.market (symbol);
680
+ if (limit === undefined) {
681
+ limit = 20; // default
682
+ }
683
+ const request = {
684
+ 'market': this.marketId (symbol),
685
+ 'merge': '0.0000000001',
686
+ 'limit': limit.toString (),
687
+ };
688
+ const method = market['swap'] ? 'perpetualPublicGetMarketDepth' : 'publicGetMarketDepth';
689
+ const response = await this[method] (this.extend (request, params));
690
+ //
691
+ // Spot
692
+ //
693
+ // {
694
+ // "code": 0,
695
+ // "data": {
696
+ // "asks": [
697
+ // ["41056.33", "0.31727613"],
698
+ // ["41056.34", "1.05657294"],
699
+ // ["41056.35", "0.02346648"]
700
+ // ],
701
+ // "bids": [
702
+ // ["41050.61", "0.40618608"],
703
+ // ["41046.98", "0.13800000"],
704
+ // ["41046.56", "0.22579234"]
705
+ // ],
706
+ // "last": "41050.61",
707
+ // "time": 1650573220346
708
+ // },
709
+ // "message": "OK"
710
+ // }
711
+ //
712
+ // Swap
713
+ //
714
+ // {
715
+ // "code": 0,
716
+ // "data": {
717
+ // "asks": [
718
+ // ["40620.90", "0.0384"],
719
+ // ["40625.50", "0.0219"],
720
+ // ["40625.90", "0.3506"]
721
+ // ],
722
+ // "bids": [
723
+ // ["40620.89", "19.6861"],
724
+ // ["40620.80", "0.0012"],
725
+ // ["40619.87", "0.0365"]
726
+ // ],
727
+ // "last": "40620.89",
728
+ // "time": 1650587672406,
729
+ // "sign_price": "40619.32",
730
+ // "index_price": "40609.93"
731
+ // },
732
+ // "message": "OK"
733
+ // }
734
+ //
735
+ const result = this.safeValue (response, 'data', {});
736
+ const timestamp = this.safeInteger (result, 'time');
737
+ return this.parseOrderBook (result, symbol, timestamp);
738
+ }
739
+
740
+ parseTrade (trade, market = undefined) {
741
+ //
742
+ // Spot and Swap fetchTrades (public)
743
+ //
744
+ // {
745
+ // "id": 2611511379,
746
+ // "type": "buy",
747
+ // "price": "192.63",
748
+ // "amount": "0.02266931",
749
+ // "date": 1638990110,
750
+ // "date_ms": 1638990110518
751
+ // },
752
+ //
753
+ // Spot fetchMyTrades (private)
754
+ //
755
+ // {
756
+ // "id": 2611520950,
757
+ // "order_id": 63286573298,
758
+ // "account_id": 0,
759
+ // "create_time": 1638990636,
760
+ // "type": "sell",
761
+ // "role": "taker",
762
+ // "price": "192.29",
763
+ // "amount": "0.098",
764
+ // "fee": "0.03768884",
765
+ // "fee_asset": "USDT",
766
+ // "market": "AAVEUSDT",
767
+ // "deal_money": "18.84442"
768
+ // }
769
+ //
770
+ // Swap fetchMyTrades (private)
771
+ //
772
+ // {
773
+ // "amount": "0.0012",
774
+ // "deal_fee": "0.0237528",
775
+ // "deal_insurance": "0",
776
+ // "deal_margin": "15.8352",
777
+ // "deal_order_id": 17797031903,
778
+ // "deal_profit": "0",
779
+ // "deal_stock": "47.5056",
780
+ // "deal_type": 1,
781
+ // "deal_user_id": 2969195,
782
+ // "fee_asset": "",
783
+ // "fee_discount": "0",
784
+ // "fee_price": "0",
785
+ // "fee_rate": "0.0005",
786
+ // "fee_real_rate": "0.0005",
787
+ // "id": 379044296,
788
+ // "leverage": "3",
789
+ // "margin_amount": "15.8352",
790
+ // "market": "BTCUSDT",
791
+ // "open_price": "39588",
792
+ // "order_id": 17797092987,
793
+ // "position_amount": "0.0012",
794
+ // "position_id": 62052321,
795
+ // "position_type": 1,
796
+ // "price": "39588",
797
+ // "role": 2,
798
+ // "side": 2,
799
+ // "time": 1650675936.016103,
800
+ // "user_id": 3620173
801
+ // }
802
+ //
803
+ let timestamp = this.safeTimestamp2 (trade, 'create_time', 'time');
804
+ if (timestamp === undefined) {
805
+ timestamp = this.safeInteger (trade, 'date_ms');
806
+ }
807
+ const tradeId = this.safeString (trade, 'id');
808
+ const orderId = this.safeString (trade, 'order_id');
809
+ const priceString = this.safeString (trade, 'price');
810
+ const amountString = this.safeString (trade, 'amount');
811
+ const marketId = this.safeString (trade, 'market');
812
+ const symbol = this.safeSymbol (marketId, market);
813
+ const costString = this.safeString (trade, 'deal_money');
814
+ let fee = undefined;
815
+ const feeCostString = this.safeString2 (trade, 'fee', 'deal_fee');
816
+ if (feeCostString !== undefined) {
817
+ const feeCurrencyId = this.safeString (trade, 'fee_asset');
818
+ const feeCurrencyCode = this.safeCurrencyCode (feeCurrencyId);
819
+ fee = {
820
+ 'cost': feeCostString,
821
+ 'currency': feeCurrencyCode,
822
+ };
823
+ }
824
+ let takerOrMaker = this.safeString (trade, 'role');
825
+ if (takerOrMaker === '1') {
826
+ takerOrMaker = 'maker';
827
+ } else if (takerOrMaker === '2') {
828
+ takerOrMaker = 'taker';
829
+ }
830
+ let side = undefined;
831
+ if (market['type'] === 'swap') {
832
+ side = this.safeInteger (trade, 'side');
833
+ if (side === 1) {
834
+ side = 'sell';
835
+ } else if (side === 2) {
836
+ side = 'buy';
837
+ }
838
+ if (side === undefined) {
839
+ side = this.safeString (trade, 'type');
840
+ }
841
+ } else {
842
+ side = this.safeString (trade, 'type');
843
+ }
844
+ return this.safeTrade ({
845
+ 'info': trade,
846
+ 'timestamp': timestamp,
847
+ 'datetime': this.iso8601 (timestamp),
848
+ 'symbol': symbol,
849
+ 'id': tradeId,
850
+ 'order': orderId,
851
+ 'type': undefined,
852
+ 'side': side,
853
+ 'takerOrMaker': takerOrMaker,
854
+ 'price': priceString,
855
+ 'amount': amountString,
856
+ 'cost': costString,
857
+ 'fee': fee,
858
+ }, market);
859
+ }
860
+
861
+ async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
862
+ await this.loadMarkets ();
863
+ const market = this.market (symbol);
864
+ const request = {
865
+ 'market': market['id'],
866
+ // 'last_id': 0,
867
+ };
868
+ if (limit !== undefined) {
869
+ request['limit'] = limit;
870
+ }
871
+ const method = market['swap'] ? 'perpetualPublicGetMarketDeals' : 'publicGetMarketDeals';
872
+ const response = await this[method] (this.extend (request, params));
873
+ //
874
+ // Spot and Swap
875
+ //
876
+ // {
877
+ // "code": 0,
878
+ // "data": [
879
+ // {
880
+ // "id": 2611511379,
881
+ // "type": "buy",
882
+ // "price": "192.63",
883
+ // "amount": "0.02266931",
884
+ // "date": 1638990110,
885
+ // "date_ms": 1638990110518
886
+ // },
887
+ // ],
888
+ // "message": "OK"
889
+ // }
890
+ //
891
+ return this.parseTrades (response['data'], market, since, limit);
892
+ }
893
+
894
+ async fetchTradingFee (symbol, params = {}) {
895
+ await this.loadMarkets ();
896
+ const market = this.market (symbol);
897
+ const request = {
898
+ 'market': market['id'],
899
+ };
900
+ const response = await this.publicGetMarketDetail (this.extend (request, params));
901
+ //
902
+ // {
903
+ // "code": 0,
904
+ // "data": {
905
+ // "name": "BTCUSDC",
906
+ // "min_amount": "0.0005",
907
+ // "maker_fee_rate": "0.002",
908
+ // "taker_fee_rate": "0.002",
909
+ // "pricing_name": "USDC",
910
+ // "pricing_decimal": 2,
911
+ // "trading_name": "BTC",
912
+ // "trading_decimal": 8
913
+ // },
914
+ // "message": "OK"
915
+ // }
916
+ //
917
+ const data = this.safeValue (response, 'data', {});
918
+ return this.parseTradingFee (data);
919
+ }
920
+
921
+ async fetchTradingFees (params = {}) {
922
+ await this.loadMarkets ();
923
+ const response = await this.publicGetMarketInfo (params);
924
+ //
925
+ // {
926
+ // "code": 0,
927
+ // "data": {
928
+ // "WAVESBTC": {
929
+ // "name": "WAVESBTC",
930
+ // "min_amount": "1",
931
+ // "maker_fee_rate": "0.001",
932
+ // "taker_fee_rate": "0.001",
933
+ // "pricing_name": "BTC",
934
+ // "pricing_decimal": 8,
935
+ // "trading_name": "WAVES",
936
+ // "trading_decimal": 8
937
+ // }
938
+ // ...
939
+ // }
940
+ // }
941
+ //
942
+ const data = this.safeValue (response, 'data', {});
943
+ const result = {};
944
+ for (let i = 0; i < this.symbols.length; i++) {
945
+ const symbol = this.symbols[i];
946
+ const market = this.market (symbol);
947
+ const fee = this.safeValue (data, market['id'], {});
948
+ result[symbol] = this.parseTradingFee (fee, market);
949
+ }
950
+ return result;
951
+ }
952
+
953
+ parseTradingFee (fee, market = undefined) {
954
+ const marketId = this.safeValue (fee, 'name');
955
+ const symbol = this.safeSymbol (marketId, market);
956
+ return {
957
+ 'info': fee,
958
+ 'symbol': symbol,
959
+ 'maker': this.safeNumber (fee, 'maker_fee_rate'),
960
+ 'taker': this.safeNumber (fee, 'taker_fee_rate'),
961
+ 'percentage': true,
962
+ 'tierBased': true,
963
+ };
964
+ }
965
+
966
+ parseOHLCV (ohlcv, market = undefined) {
967
+ //
968
+ // [
969
+ // 1591484400,
970
+ // "0.02505349",
971
+ // "0.02506988",
972
+ // "0.02507000",
973
+ // "0.02505304",
974
+ // "343.19716223",
975
+ // "8.6021323866383196",
976
+ // "ETHBTC"
977
+ // ]
978
+ //
979
+ return [
980
+ this.safeTimestamp (ohlcv, 0),
981
+ this.safeNumber (ohlcv, 1),
982
+ this.safeNumber (ohlcv, 3),
983
+ this.safeNumber (ohlcv, 4),
984
+ this.safeNumber (ohlcv, 2),
985
+ this.safeNumber (ohlcv, 5),
986
+ ];
987
+ }
988
+
989
+ async fetchOHLCV (symbol, timeframe = '5m', since = undefined, limit = undefined, params = {}) {
990
+ await this.loadMarkets ();
991
+ const market = this.market (symbol);
992
+ const request = {
993
+ 'market': market['id'],
994
+ 'type': this.timeframes[timeframe],
995
+ };
996
+ if (limit !== undefined) {
997
+ request['limit'] = limit;
998
+ }
999
+ const method = market['swap'] ? 'perpetualPublicGetMarketKline' : 'publicGetMarketKline';
1000
+ const response = await this[method] (this.extend (request, params));
1001
+ //
1002
+ // Spot
1003
+ //
1004
+ // {
1005
+ // "code": 0,
1006
+ // "data": [
1007
+ // [1591484400, "0.02505349", "0.02506988", "0.02507000", "0.02505304", "343.19716223", "8.6021323866383196", "ETHBTC"],
1008
+ // [1591484700, "0.02506990", "0.02508109", "0.02508109", "0.02506979", "91.59841581", "2.2972047780447000", "ETHBTC"],
1009
+ // [1591485000, "0.02508106", "0.02507996", "0.02508106", "0.02507500", "65.15307697", "1.6340597822306000", "ETHBTC"],
1010
+ // ],
1011
+ // "message": "OK"
1012
+ // }
1013
+ //
1014
+ // Swap
1015
+ //
1016
+ // {
1017
+ // "code": 0,
1018
+ // "data": [
1019
+ // [1650569400, "41524.64", "41489.31", "41564.61", "41480.58", "29.7060", "1233907.099562"],
1020
+ // [1650569700, "41489.31", "41438.29", "41489.31", "41391.87", "42.4115", "1756154.189061"],
1021
+ // [1650570000, "41438.29", "41482.21", "41485.05", "41427.31", "22.2892", "924000.317861"]
1022
+ // ],
1023
+ // "message": "OK"
1024
+ // }
1025
+ //
1026
+ const data = this.safeValue (response, 'data', []);
1027
+ return this.parseOHLCVs (data, market, timeframe, since, limit);
1028
+ }
1029
+
1030
+ async fetchMarginBalance (params = {}) {
1031
+ await this.loadMarkets ();
1032
+ const symbol = this.safeString (params, 'symbol');
1033
+ let marketId = this.safeString (params, 'market');
1034
+ let market = undefined;
1035
+ if (symbol !== undefined) {
1036
+ market = this.market (symbol);
1037
+ marketId = market['id'];
1038
+ } else if (marketId === undefined) {
1039
+ throw new ArgumentsRequired (this.id + ' fetchMarginBalance() fetching a margin account requires a market parameter or a symbol parameter');
1040
+ }
1041
+ params = this.omit (params, [ 'symbol', 'market' ]);
1042
+ const request = {
1043
+ 'market': marketId,
1044
+ };
1045
+ const response = await this.privateGetMarginAccount (this.extend (request, params));
1046
+ //
1047
+ // {
1048
+ // "code": 0,
1049
+ // "data": {
1050
+ // "account_id": 126,
1051
+ // "leverage": 3,
1052
+ // "market_type": "AAVEUSDT",
1053
+ // "sell_asset_type": "AAVE",
1054
+ // "buy_asset_type": "USDT",
1055
+ // "balance": {
1056
+ // "sell_type": "0.3", // borrowed
1057
+ // "buy_type": "30"
1058
+ // },
1059
+ // "frozen": {
1060
+ // "sell_type": "0",
1061
+ // "buy_type": "0"
1062
+ // },
1063
+ // "loan": {
1064
+ // "sell_type": "0.3", // loan
1065
+ // "buy_type": "0"
1066
+ // },
1067
+ // "interest": {
1068
+ // "sell_type": "0.0000125",
1069
+ // "buy_type": "0"
1070
+ // },
1071
+ // "can_transfer": {
1072
+ // "sell_type": "0.02500646",
1073
+ // "buy_type": "4.28635738"
1074
+ // },
1075
+ // "warn_rate": "",
1076
+ // "liquidation_price": ""
1077
+ // },
1078
+ // "message": "Success"
1079
+ // }
1080
+ //
1081
+ const result = { 'info': response };
1082
+ const data = this.safeValue (response, 'data', {});
1083
+ const free = this.safeValue (data, 'can_transfer', {});
1084
+ const total = this.safeValue (data, 'balance', {});
1085
+ //
1086
+ const sellAccount = this.account ();
1087
+ const sellCurrencyId = this.safeString (data, 'sell_asset_type');
1088
+ const sellCurrencyCode = this.safeCurrencyCode (sellCurrencyId);
1089
+ sellAccount['free'] = this.safeString (free, 'sell_type');
1090
+ sellAccount['total'] = this.safeString (total, 'sell_type');
1091
+ result[sellCurrencyCode] = sellAccount;
1092
+ //
1093
+ const buyAccount = this.account ();
1094
+ const buyCurrencyId = this.safeString (data, 'buy_asset_type');
1095
+ const buyCurrencyCode = this.safeCurrencyCode (buyCurrencyId);
1096
+ buyAccount['free'] = this.safeString (free, 'buy_type');
1097
+ buyAccount['total'] = this.safeString (total, 'buy_type');
1098
+ result[buyCurrencyCode] = buyAccount;
1099
+ //
1100
+ return this.safeBalance (result);
1101
+ }
1102
+
1103
+ async fetchSpotBalance (params = {}) {
1104
+ await this.loadMarkets ();
1105
+ const response = await this.privateGetBalanceInfo (params);
1106
+ //
1107
+ // {
1108
+ // "code": 0,
1109
+ // "data": {
1110
+ // "BCH": { # BCH account
1111
+ // "available": "13.60109", # Available BCH
1112
+ // "frozen": "0.00000" # Frozen BCH
1113
+ // },
1114
+ // "BTC": { # BTC account
1115
+ // "available": "32590.16", # Available BTC
1116
+ // "frozen": "7000.00" # Frozen BTC
1117
+ // },
1118
+ // "ETH": { # ETH account
1119
+ // "available": "5.06000", # Available ETH
1120
+ // "frozen": "0.00000" # Frozen ETH
1121
+ // }
1122
+ // },
1123
+ // "message": "Ok"
1124
+ // }
1125
+ //
1126
+ const result = { 'info': response };
1127
+ const balances = this.safeValue (response, 'data', {});
1128
+ const currencyIds = Object.keys (balances);
1129
+ for (let i = 0; i < currencyIds.length; i++) {
1130
+ const currencyId = currencyIds[i];
1131
+ const code = this.safeCurrencyCode (currencyId);
1132
+ const balance = this.safeValue (balances, currencyId, {});
1133
+ const account = this.account ();
1134
+ account['free'] = this.safeString (balance, 'available');
1135
+ account['used'] = this.safeString (balance, 'frozen');
1136
+ result[code] = account;
1137
+ }
1138
+ return this.safeBalance (result);
1139
+ }
1140
+
1141
+ async fetchSwapBalance (params = {}) {
1142
+ await this.loadMarkets ();
1143
+ const response = await this.perpetualPrivateGetAssetQuery (params);
1144
+ //
1145
+ // {
1146
+ // "code": 0,
1147
+ // "data": {
1148
+ // "USDT": {
1149
+ // "available": "37.24817690383456000000",
1150
+ // "balance_total": "37.24817690383456000000",
1151
+ // "frozen": "0.00000000000000000000",
1152
+ // "margin": "0.00000000000000000000",
1153
+ // "profit_unreal": "0.00000000000000000000",
1154
+ // "transfer": "37.24817690383456000000"
1155
+ // }
1156
+ // },
1157
+ // "message": "OK"
1158
+ // }
1159
+ //
1160
+ const result = { 'info': response };
1161
+ const balances = this.safeValue (response, 'data', {});
1162
+ const currencyIds = Object.keys (balances);
1163
+ for (let i = 0; i < currencyIds.length; i++) {
1164
+ const currencyId = currencyIds[i];
1165
+ const code = this.safeCurrencyCode (currencyId);
1166
+ const balance = this.safeValue (balances, currencyId, {});
1167
+ const account = this.account ();
1168
+ account['free'] = this.safeString (balance, 'available');
1169
+ account['used'] = this.safeString (balance, 'frozen');
1170
+ account['total'] = this.safeString (balance, 'balance_total');
1171
+ result[code] = account;
1172
+ }
1173
+ return this.safeBalance (result);
1174
+ }
1175
+
1176
+ async fetchBalance (params = {}) {
1177
+ const accountType = this.safeString (params, 'type', 'main');
1178
+ params = this.omit (params, 'type');
1179
+ if (accountType === 'margin') {
1180
+ return await this.fetchMarginBalance (params);
1181
+ } else if (accountType === 'swap') {
1182
+ return await this.fetchSwapBalance (params);
1183
+ } else {
1184
+ return await this.fetchSpotBalance (params);
1185
+ }
1186
+ }
1187
+
1188
+ parseOrderStatus (status) {
1189
+ const statuses = {
1190
+ 'not_deal': 'open',
1191
+ 'part_deal': 'open',
1192
+ 'done': 'closed',
1193
+ 'cancel': 'canceled',
1194
+ };
1195
+ return this.safeString (statuses, status, status);
1196
+ }
1197
+
1198
+ parseOrder (order, market = undefined) {
1199
+ //
1200
+ // fetchOrder
1201
+ //
1202
+ // {
1203
+ // "amount": "0.1",
1204
+ // "asset_fee": "0.22736197736197736197",
1205
+ // "avg_price": "196.85000000000000000000",
1206
+ // "create_time": 1537270135,
1207
+ // "deal_amount": "0.1",
1208
+ // "deal_fee": "0",
1209
+ // "deal_money": "19.685",
1210
+ // "fee_asset": "CET",
1211
+ // "fee_discount": "0.5",
1212
+ // "id": 1788259447,
1213
+ // "left": "0",
1214
+ // "maker_fee_rate": "0",
1215
+ // "market": "ETHUSDT",
1216
+ // "order_type": "limit",
1217
+ // "price": "170.00000000",
1218
+ // "status": "done",
1219
+ // "taker_fee_rate": "0.0005",
1220
+ // "type": "sell",
1221
+ // }
1222
+ //
1223
+ // Spot createOrder, cancelOrder, fetchOrder
1224
+ //
1225
+ // {
1226
+ // "amount":"1.5",
1227
+ // "asset_fee":"0",
1228
+ // "avg_price":"0.14208538",
1229
+ // "client_id":"",
1230
+ // "create_time":1650993819,
1231
+ // "deal_amount":"10.55703267",
1232
+ // "deal_fee":"0.0029999999971787292",
1233
+ // "deal_money":"1.4999999985893646",
1234
+ // "fee_asset":null,
1235
+ // "fee_discount":"1",
1236
+ // "finished_time":null,
1237
+ // "id":74556296907,
1238
+ // "left":"0.0000000014106354",
1239
+ // "maker_fee_rate":"0",
1240
+ // "market":"DOGEUSDT",
1241
+ // "money_fee":"0.0029999999971787292",
1242
+ // "order_type":"market",
1243
+ // "price":"0",
1244
+ // "status":"done",
1245
+ // "stock_fee":"0",
1246
+ // "taker_fee_rate":"0.002",
1247
+ // "type":"buy"
1248
+ // }
1249
+ //
1250
+ // Swap createOrder, cancelOrder, fetchOrder
1251
+ //
1252
+ // {
1253
+ // "amount": "0.0005",
1254
+ // "client_id": "",
1255
+ // "create_time": 1651004578.618224,
1256
+ // "deal_asset_fee": "0.00000000000000000000",
1257
+ // "deal_fee": "0.00000000000000000000",
1258
+ // "deal_profit": "0.00000000000000000000",
1259
+ // "deal_stock": "0.00000000000000000000",
1260
+ // "effect_type": 1,
1261
+ // "fee_asset": "",
1262
+ // "fee_discount": "0.00000000000000000000",
1263
+ // "last_deal_amount": "0.00000000000000000000",
1264
+ // "last_deal_id": 0,
1265
+ // "last_deal_price": "0.00000000000000000000",
1266
+ // "last_deal_role": 0,
1267
+ // "last_deal_time": 0,
1268
+ // "last_deal_type": 0,
1269
+ // "left": "0.0005",
1270
+ // "leverage": "3",
1271
+ // "maker_fee": "0.00030",
1272
+ // "market": "BTCUSDT",
1273
+ // "order_id": 18221659097,
1274
+ // "position_id": 0,
1275
+ // "position_type": 1,
1276
+ // "price": "30000.00",
1277
+ // "side": 2,
1278
+ // "source": "api.v1",
1279
+ // "stop_id": 0,
1280
+ // "taker_fee": "0.00050",
1281
+ // "target": 0,
1282
+ // "type": 1,
1283
+ // "update_time": 1651004578.618224,
1284
+ // "user_id": 3620173
1285
+ // }
1286
+ //
1287
+ // Stop order createOrder
1288
+ //
1289
+ // {"status":"success"}
1290
+ //
1291
+ // Swap Stop cancelOrder, fetchOrder
1292
+ //
1293
+ // {
1294
+ // "amount": "0.0005",
1295
+ // "client_id": "",
1296
+ // "create_time": 1651034023.008771,
1297
+ // "effect_type": 1,
1298
+ // "fee_asset": "",
1299
+ // "fee_discount": "0.00000000000000000000",
1300
+ // "maker_fee": "0.00030",
1301
+ // "market": "BTCUSDT",
1302
+ // "order_id": 18256915101,
1303
+ // "price": "31000.00",
1304
+ // "side": 2,
1305
+ // "source": "api.v1",
1306
+ // "state": 1,
1307
+ // "stop_price": "31500.00",
1308
+ // "stop_type": 1,
1309
+ // "taker_fee": "0.00050",
1310
+ // "target": 0,
1311
+ // "type": 1,
1312
+ // "update_time": 1651034397.193624,
1313
+ // "user_id": 3620173
1314
+ // }
1315
+ //
1316
+ //
1317
+ // Spot fetchOpenOrders, fetchClosedOrders
1318
+ //
1319
+ // {
1320
+ // "account_id": 0,
1321
+ // "amount": "0.0005",
1322
+ // "asset_fee": "0",
1323
+ // "avg_price": "0.00",
1324
+ // "client_id": "",
1325
+ // "create_time": 1651089247,
1326
+ // "deal_amount": "0",
1327
+ // "deal_fee": "0",
1328
+ // "deal_money": "0",
1329
+ // "fee_asset": null,
1330
+ // "fee_discount": "1",
1331
+ // "finished_time": 0,
1332
+ // "id": 74660190839,
1333
+ // "left": "0.0005",
1334
+ // "maker_fee_rate": "0.002",
1335
+ // "market": "BTCUSDT",
1336
+ // "money_fee": "0",
1337
+ // "order_type": "limit",
1338
+ // "price": "31000",
1339
+ // "status": "not_deal",
1340
+ // "stock_fee": "0",
1341
+ // "taker_fee_rate": "0.002",
1342
+ // "type": "buy"
1343
+ // }
1344
+ //
1345
+ // Swap fetchOpenOrders, fetchClosedOrders
1346
+ //
1347
+ // {
1348
+ // "amount": "0.0005",
1349
+ // "client_id": "",
1350
+ // "create_time": 1651030414.088431,
1351
+ // "deal_asset_fee": "0",
1352
+ // "deal_fee": "0.00960069",
1353
+ // "deal_profit": "0.009825",
1354
+ // "deal_stock": "19.20138",
1355
+ // "effect_type": 0,
1356
+ // "fee_asset": "",
1357
+ // "fee_discount": "0",
1358
+ // "left": "0",
1359
+ // "leverage": "3",
1360
+ // "maker_fee": "0",
1361
+ // "market": "BTCUSDT",
1362
+ // "order_id": 18253447431,
1363
+ // "position_id": 0,
1364
+ // "position_type": 1,
1365
+ // "price": "0",
1366
+ // "side": 1,
1367
+ // "source": "web",
1368
+ // "stop_id": 0,
1369
+ // "taker_fee": "0.0005",
1370
+ // "target": 0,
1371
+ // "type": 2,
1372
+ // "update_time": 1651030414.08847,
1373
+ // "user_id": 3620173
1374
+ // }
1375
+ //
1376
+ // Spot Stop fetchOpenOrders, fetchClosedOrders
1377
+ //
1378
+ // {
1379
+ // "account_id": 0,
1380
+ // "amount": "155",
1381
+ // "client_id": "",
1382
+ // "create_time": 1651089182,
1383
+ // "fee_asset": null,
1384
+ // "fee_discount": "1",
1385
+ // "maker_fee": "0.002",
1386
+ // "market": "BTCUSDT",
1387
+ // "order_id": 74660111965,
1388
+ // "order_type": "market",
1389
+ // "price": "0",
1390
+ // "state": 0,
1391
+ // "stop_price": "31500",
1392
+ // "taker_fee": "0.002",
1393
+ // "type": "buy"
1394
+ // }
1395
+ //
1396
+ // Swap Stop fetchOpenOrders
1397
+ //
1398
+ // {
1399
+ // "amount": "0.0005",
1400
+ // "client_id": "",
1401
+ // "create_time": 1651089147.321691,
1402
+ // "effect_type": 1,
1403
+ // "fee_asset": "",
1404
+ // "fee_discount": "0.00000000000000000000",
1405
+ // "maker_fee": "0.00030",
1406
+ // "market": "BTCUSDT",
1407
+ // "order_id": 18332143848,
1408
+ // "price": "31000.00",
1409
+ // "side": 2,
1410
+ // "source": "api.v1",
1411
+ // "state": 1,
1412
+ // "stop_price": "31500.00",
1413
+ // "stop_type": 1,
1414
+ // "taker_fee": "0.00050",
1415
+ // "target": 0,
1416
+ // "type": 1,
1417
+ // "update_time": 1651089147.321691,
1418
+ // "user_id": 3620173
1419
+ // }
1420
+ //
1421
+ const timestamp = this.safeTimestamp (order, 'create_time');
1422
+ const priceString = this.safeString (order, 'price');
1423
+ const costString = this.safeString (order, 'deal_money');
1424
+ const amountString = this.safeString (order, 'amount');
1425
+ const filledString = this.safeString (order, 'deal_amount');
1426
+ const averageString = this.safeString (order, 'avg_price');
1427
+ const remainingString = this.safeString (order, 'left');
1428
+ const marketId = this.safeString (order, 'market');
1429
+ market = this.safeMarket (marketId, market);
1430
+ const feeCurrencyId = this.safeString (order, 'fee_asset');
1431
+ let feeCurrency = this.safeCurrencyCode (feeCurrencyId);
1432
+ if (feeCurrency === undefined) {
1433
+ feeCurrency = market['quote'];
1434
+ }
1435
+ const status = this.parseOrderStatus (this.safeString (order, 'status'));
1436
+ let side = this.safeInteger (order, 'side');
1437
+ if (side === 1) {
1438
+ side = 'sell';
1439
+ } else if (side === 2) {
1440
+ side = 'buy';
1441
+ } else {
1442
+ side = this.safeString (order, 'type');
1443
+ }
1444
+ let type = this.safeString (order, 'order_type');
1445
+ if (type === undefined) {
1446
+ type = this.safeInteger (order, 'type');
1447
+ if (type === 1) {
1448
+ type = 'limit';
1449
+ } else if (type === 2) {
1450
+ type = 'market';
1451
+ }
1452
+ }
1453
+ return this.safeOrder ({
1454
+ 'id': this.safeString2 (order, 'id', 'order_id'),
1455
+ 'clientOrderId': undefined,
1456
+ 'datetime': this.iso8601 (timestamp),
1457
+ 'timestamp': timestamp,
1458
+ 'lastTradeTimestamp': this.safeTimestamp (order, 'update_time'),
1459
+ 'status': status,
1460
+ 'symbol': market['symbol'],
1461
+ 'type': type,
1462
+ 'timeInForce': undefined,
1463
+ 'postOnly': undefined,
1464
+ 'side': side,
1465
+ 'price': priceString,
1466
+ 'stopPrice': this.safeString (order, 'stop_price'),
1467
+ 'cost': costString,
1468
+ 'average': averageString,
1469
+ 'amount': amountString,
1470
+ 'filled': filledString,
1471
+ 'remaining': remainingString,
1472
+ 'trades': undefined,
1473
+ 'fee': {
1474
+ 'currency': feeCurrency,
1475
+ 'cost': this.safeString (order, 'deal_fee'),
1476
+ },
1477
+ 'info': order,
1478
+ }, market);
1479
+ }
1480
+
1481
+ async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
1482
+ await this.loadMarkets ();
1483
+ const market = this.market (symbol);
1484
+ const swap = market['swap'];
1485
+ const stopPrice = this.safeString2 (params, 'stopPrice', 'stop_price');
1486
+ const postOnly = this.safeValue (params, 'postOnly', false);
1487
+ const positionId = this.safeInteger2 (params, 'position_id', 'positionId'); // Required for closing swap positions
1488
+ let timeInForce = this.safeString (params, 'timeInForce'); // Spot: IOC, FOK, PO, GTC, ... NORMAL (default), MAKER_ONLY
1489
+ const reduceOnly = this.safeValue (params, 'reduceOnly');
1490
+ if (reduceOnly !== undefined) {
1491
+ if (market['type'] !== 'swap') {
1492
+ throw new InvalidOrder (this.id + ' createOrder() does not support reduceOnly for ' + market['type'] + ' orders, reduceOnly orders are supported for swap markets only');
1493
+ }
1494
+ }
1495
+ let method = undefined;
1496
+ const request = {
1497
+ 'market': market['id'],
1498
+ };
1499
+ if (swap) {
1500
+ method = 'perpetualPrivatePostOrderPut' + this.capitalize (type);
1501
+ side = (side === 'buy') ? 2 : 1;
1502
+ if (stopPrice !== undefined) {
1503
+ const stopType = this.safeInteger (params, 'stop_type'); // 1: triggered by the latest transaction, 2: mark price, 3: index price
1504
+ if (stopType === undefined) {
1505
+ throw new ArgumentsRequired (this.id + ' createOrder() swap stop orders require a stop_type parameter');
1506
+ }
1507
+ request['stop_price'] = this.priceToPrecision (symbol, stopPrice);
1508
+ request['stop_type'] = this.priceToPrecision (symbol, stopType);
1509
+ request['amount'] = this.amountToPrecision (symbol, amount);
1510
+ request['side'] = side;
1511
+ if (type === 'limit') {
1512
+ method = 'perpetualPrivatePostOrderPutStopLimit';
1513
+ request['price'] = this.priceToPrecision (symbol, price);
1514
+ } else if (type === 'market') {
1515
+ method = 'perpetualPrivatePostOrderPutStopMarket';
1516
+ }
1517
+ request['amount'] = this.amountToPrecision (symbol, amount);
1518
+ }
1519
+ if ((type !== 'market') || (stopPrice !== undefined)) {
1520
+ if ((timeInForce !== undefined) || (postOnly !== undefined)) {
1521
+ let isMakerOrder = false;
1522
+ if ((timeInForce === 'PO') || (postOnly)) {
1523
+ isMakerOrder = true;
1524
+ }
1525
+ if (isMakerOrder) {
1526
+ request['option'] = 1;
1527
+ } else {
1528
+ if (timeInForce === 'IOC') {
1529
+ timeInForce = 2;
1530
+ } else if (timeInForce === 'FOK') {
1531
+ timeInForce = 3;
1532
+ } else {
1533
+ timeInForce = 1;
1534
+ }
1535
+ if (timeInForce !== undefined) {
1536
+ request['effect_type'] = timeInForce; // exchange takes 'IOC' and 'FOK'
1537
+ }
1538
+ }
1539
+ }
1540
+ }
1541
+ if (type === 'limit' && stopPrice === undefined) {
1542
+ if (reduceOnly) {
1543
+ method = 'perpetualPrivatePostOrderCloseLimit';
1544
+ request['position_id'] = positionId;
1545
+ } else {
1546
+ request['side'] = side;
1547
+ }
1548
+ request['price'] = this.priceToPrecision (symbol, price);
1549
+ request['amount'] = this.amountToPrecision (symbol, amount);
1550
+ } else if (type === 'market' && stopPrice === undefined) {
1551
+ if (reduceOnly) {
1552
+ method = 'perpetualPrivatePostOrderCloseMarket';
1553
+ request['position_id'] = positionId;
1554
+ } else {
1555
+ request['side'] = side;
1556
+ request['amount'] = this.amountToPrecision (symbol, amount);
1557
+ }
1558
+ }
1559
+ } else {
1560
+ method = 'privatePostOrder' + this.capitalize (type);
1561
+ request['type'] = side;
1562
+ if ((type === 'market') && (side === 'buy')) {
1563
+ if (this.options['createMarketBuyOrderRequiresPrice']) {
1564
+ if (price === undefined) {
1565
+ throw new InvalidOrder (this.id + " createOrder() requires the price argument with market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = false to supply the cost in the amount argument (the exchange-specific behaviour)");
1566
+ } else {
1567
+ const amountString = this.amountToPrecision (symbol, amount);
1568
+ const priceString = this.priceToPrecision (symbol, price);
1569
+ const costString = Precise.stringMul (amountString, priceString);
1570
+ const costNumber = this.parseNumber (costString);
1571
+ request['amount'] = this.costToPrecision (symbol, costNumber);
1572
+ }
1573
+ } else {
1574
+ request['amount'] = this.costToPrecision (symbol, amount);
1575
+ }
1576
+ } else {
1577
+ request['amount'] = this.amountToPrecision (symbol, amount);
1578
+ }
1579
+ if ((type === 'limit') || (type === 'ioc')) {
1580
+ request['price'] = this.priceToPrecision (symbol, price);
1581
+ }
1582
+ if (stopPrice !== undefined) {
1583
+ request['stop_price'] = this.priceToPrecision (symbol, stopPrice);
1584
+ if (type === 'limit') {
1585
+ method = 'privatePostOrderStopLimit';
1586
+ } else if (type === 'market') {
1587
+ method = 'privatePostOrderStopMarket';
1588
+ }
1589
+ }
1590
+ if ((type !== 'market') || (stopPrice !== undefined)) {
1591
+ // following options cannot be applied to vanilla market orders (but can be applied to stop-market orders)
1592
+ if ((timeInForce !== undefined) || (postOnly !== undefined)) {
1593
+ let isMakerOrder = false;
1594
+ if ((timeInForce === 'PO') || (postOnly)) {
1595
+ isMakerOrder = true;
1596
+ }
1597
+ if ((isMakerOrder || (timeInForce !== 'IOC')) && ((type === 'limit') && (stopPrice !== undefined))) {
1598
+ throw new InvalidOrder (this.id + ' createOrder() only supports the IOC option for stop-limit orders');
1599
+ }
1600
+ if (isMakerOrder) {
1601
+ request['option'] = 'MAKER_ONLY';
1602
+ } else {
1603
+ if (timeInForce !== undefined) {
1604
+ request['option'] = timeInForce; // exchange takes 'IOC' and 'FOK'
1605
+ }
1606
+ }
1607
+ }
1608
+ }
1609
+ }
1610
+ params = this.omit (params, [ 'reduceOnly', 'position_id', 'positionId', 'timeInForce', 'postOnly', 'stopPrice', 'stop_price', 'stop_type' ]);
1611
+ const response = await this[method] (this.extend (request, params));
1612
+ //
1613
+ // Spot
1614
+ //
1615
+ // {
1616
+ // "code": 0,
1617
+ // "data": {
1618
+ // "amount": "0.0005",
1619
+ // "asset_fee": "0",
1620
+ // "avg_price": "0.00",
1621
+ // "client_id": "",
1622
+ // "create_time": 1650951627,
1623
+ // "deal_amount": "0",
1624
+ // "deal_fee": "0",
1625
+ // "deal_money": "0",
1626
+ // "fee_asset": null,
1627
+ // "fee_discount": "1",
1628
+ // "finished_time": null,
1629
+ // "id": 74510932594,
1630
+ // "left": "0.0005",
1631
+ // "maker_fee_rate": "0.002",
1632
+ // "market": "BTCUSDT",
1633
+ // "money_fee": "0",
1634
+ // "order_type": "limit",
1635
+ // "price": "30000",
1636
+ // "status": "not_deal",
1637
+ // "stock_fee": "0",
1638
+ // "taker_fee_rate": "0.002",
1639
+ // "type": "buy"
1640
+ // },
1641
+ // "message": "Success"
1642
+ // }
1643
+ //
1644
+ // Swap
1645
+ //
1646
+ // {
1647
+ // "code": 0,
1648
+ // "data": {
1649
+ // "amount": "0.0005",
1650
+ // "client_id": "",
1651
+ // "create_time": 1651004578.618224,
1652
+ // "deal_asset_fee": "0.00000000000000000000",
1653
+ // "deal_fee": "0.00000000000000000000",
1654
+ // "deal_profit": "0.00000000000000000000",
1655
+ // "deal_stock": "0.00000000000000000000",
1656
+ // "effect_type": 1,
1657
+ // "fee_asset": "",
1658
+ // "fee_discount": "0.00000000000000000000",
1659
+ // "last_deal_amount": "0.00000000000000000000",
1660
+ // "last_deal_id": 0,
1661
+ // "last_deal_price": "0.00000000000000000000",
1662
+ // "last_deal_role": 0,
1663
+ // "last_deal_time": 0,
1664
+ // "last_deal_type": 0,
1665
+ // "left": "0.0005",
1666
+ // "leverage": "3",
1667
+ // "maker_fee": "0.00030",
1668
+ // "market": "BTCUSDT",
1669
+ // "order_id": 18221659097,
1670
+ // "position_id": 0,
1671
+ // "position_type": 1,
1672
+ // "price": "30000.00",
1673
+ // "side": 2,
1674
+ // "source": "api.v1",
1675
+ // "stop_id": 0,
1676
+ // "taker_fee": "0.00050",
1677
+ // "target": 0,
1678
+ // "type": 1,
1679
+ // "update_time": 1651004578.618224,
1680
+ // "user_id": 3620173
1681
+ // },
1682
+ // "message": "OK"
1683
+ // }
1684
+ //
1685
+ // Stop Order
1686
+ //
1687
+ // {"code":0,"data":{"status":"success"},"message":"OK"}
1688
+ //
1689
+ const data = this.safeValue (response, 'data');
1690
+ return this.parseOrder (data, market);
1691
+ }
1692
+
1693
+ async createReduceOnlyOrder (symbol, type, side, amount, price = undefined, params = {}) {
1694
+ const request = {
1695
+ 'reduceOnly': true,
1696
+ };
1697
+ return await this.createOrder (symbol, type, side, amount, price, this.extend (request, params));
1698
+ }
1699
+
1700
+ async cancelOrder (id, symbol = undefined, params = {}) {
1701
+ await this.loadMarkets ();
1702
+ const market = this.market (symbol);
1703
+ const stop = this.safeValue (params, 'stop');
1704
+ const swap = market['swap'];
1705
+ const request = {
1706
+ 'market': market['id'],
1707
+ };
1708
+ const idRequest = swap ? 'order_id' : 'id';
1709
+ request[idRequest] = id;
1710
+ let method = swap ? 'perpetualPrivatePostOrderCancel' : 'privateDeleteOrderPending';
1711
+ if (stop) {
1712
+ if (swap) {
1713
+ method = 'perpetualPrivatePostOrderCancelStop';
1714
+ } else {
1715
+ method = 'privateDeleteOrderStopPendingId';
1716
+ }
1717
+ }
1718
+ const query = this.omit (params, 'stop');
1719
+ const response = await this[method] (this.extend (request, query));
1720
+ //
1721
+ // Spot
1722
+ //
1723
+ // {
1724
+ // "code": 0,
1725
+ // "data": {
1726
+ // "amount": "0.0005",
1727
+ // "asset_fee": "0",
1728
+ // "avg_price": "0.00",
1729
+ // "client_id": "",
1730
+ // "create_time": 1650951627,
1731
+ // "deal_amount": "0",
1732
+ // "deal_fee": "0",
1733
+ // "deal_money": "0",
1734
+ // "fee_asset": null,
1735
+ // "fee_discount": "1",
1736
+ // "finished_time": null,
1737
+ // "id": 74510932594,
1738
+ // "left": "0.0005",
1739
+ // "maker_fee_rate": "0.002",
1740
+ // "market": "BTCUSDT",
1741
+ // "money_fee": "0",
1742
+ // "order_type": "limit",
1743
+ // "price": "30000",
1744
+ // "status": "not_deal",
1745
+ // "stock_fee": "0",
1746
+ // "taker_fee_rate": "0.002",
1747
+ // "type": "buy"
1748
+ // },
1749
+ // "message": "Success"
1750
+ // }
1751
+ //
1752
+ // Swap
1753
+ //
1754
+ // {
1755
+ // "code": 0,
1756
+ // "data": {
1757
+ // "amount": "0.0005",
1758
+ // "client_id": "",
1759
+ // "create_time": 1651004578.618224,
1760
+ // "deal_asset_fee": "0.00000000000000000000",
1761
+ // "deal_fee": "0.00000000000000000000",
1762
+ // "deal_profit": "0.00000000000000000000",
1763
+ // "deal_stock": "0.00000000000000000000",
1764
+ // "effect_type": 1,
1765
+ // "fee_asset": "",
1766
+ // "fee_discount": "0.00000000000000000000",
1767
+ // "last_deal_amount": "0.00000000000000000000",
1768
+ // "last_deal_id": 0,
1769
+ // "last_deal_price": "0.00000000000000000000",
1770
+ // "last_deal_role": 0,
1771
+ // "last_deal_time": 0,
1772
+ // "last_deal_type": 0,
1773
+ // "left": "0.0005",
1774
+ // "leverage": "3",
1775
+ // "maker_fee": "0.00030",
1776
+ // "market": "BTCUSDT",
1777
+ // "order_id": 18221659097,
1778
+ // "position_id": 0,
1779
+ // "position_type": 1,
1780
+ // "price": "30000.00",
1781
+ // "side": 2,
1782
+ // "source": "api.v1",
1783
+ // "stop_id": 0,
1784
+ // "taker_fee": "0.00050",
1785
+ // "target": 0,
1786
+ // "type": 1,
1787
+ // "update_time": 1651004578.618224,
1788
+ // "user_id": 3620173
1789
+ // },
1790
+ // "message": "OK"
1791
+ // }
1792
+ //
1793
+ // Swap Stop
1794
+ //
1795
+ // {
1796
+ // "code": 0,
1797
+ // "data": {
1798
+ // "amount": "0.0005",
1799
+ // "client_id": "",
1800
+ // "create_time": 1651034023.008771,
1801
+ // "effect_type": 1,
1802
+ // "fee_asset": "",
1803
+ // "fee_discount": "0.00000000000000000000",
1804
+ // "maker_fee": "0.00030",
1805
+ // "market": "BTCUSDT",
1806
+ // "order_id": 18256915101,
1807
+ // "price": "31000.00",
1808
+ // "side": 2,
1809
+ // "source": "api.v1",
1810
+ // "state": 1,
1811
+ // "stop_price": "31500.00",
1812
+ // "stop_type": 1,
1813
+ // "taker_fee": "0.00050",
1814
+ // "target": 0,
1815
+ // "type": 1,
1816
+ // "update_time": 1651034397.193624,
1817
+ // "user_id": 3620173
1818
+ // },
1819
+ // "message":"OK"
1820
+ // }
1821
+ //
1822
+ // Spot Stop
1823
+ //
1824
+ // {"code":0,"data":{},"message":"Success"}
1825
+ //
1826
+ const data = this.safeValue (response, 'data');
1827
+ return this.parseOrder (data, market);
1828
+ }
1829
+
1830
+ async cancelAllOrders (symbol = undefined, params = {}) {
1831
+ if (symbol === undefined) {
1832
+ throw new ArgumentsRequired (this.id + ' cancellAllOrders() requires a symbol argument');
1833
+ }
1834
+ await this.loadMarkets ();
1835
+ const market = this.market (symbol);
1836
+ const marketId = market['id'];
1837
+ const accountId = this.safeString (params, 'id', '0');
1838
+ const request = {
1839
+ 'market': marketId,
1840
+ // 'account_id': accountId, // SPOT, main account ID: 0, margin account ID: See < Inquire Margin Account Market Info >, future account ID: See < Inquire Future Account Market Info >
1841
+ // 'side': 0, // SWAP, 0: All, 1: Sell, 2: Buy
1842
+ };
1843
+ const swap = market['swap'];
1844
+ const stop = this.safeValue (params, 'stop');
1845
+ let method = undefined;
1846
+ if (swap) {
1847
+ method = 'perpetualPrivatePostOrderCancelAll';
1848
+ if (stop) {
1849
+ method = 'perpetualPrivatePostOrderCancelStopAll';
1850
+ }
1851
+ } else {
1852
+ method = 'privateDeleteOrderPending';
1853
+ if (stop) {
1854
+ method = 'privateDeleteOrderStopPending';
1855
+ }
1856
+ request['account_id'] = accountId;
1857
+ }
1858
+ params = this.omit (params, 'stop');
1859
+ const response = await this[method] (this.extend (request, params));
1860
+ //
1861
+ // Spot
1862
+ //
1863
+ // {"code": 0, "data": null, "message": "Success"}
1864
+ //
1865
+ // Swap
1866
+ //
1867
+ // {"code": 0, "data": {"status":"success"}, "message": "OK"}
1868
+ //
1869
+ return response;
1870
+ }
1871
+
1872
+ async fetchOrder (id, symbol = undefined, params = {}) {
1873
+ if (symbol === undefined) {
1874
+ throw new ArgumentsRequired (this.id + ' fetchOrder() requires a symbol argument');
1875
+ }
1876
+ await this.loadMarkets ();
1877
+ const market = this.market (symbol);
1878
+ const swap = market['swap'];
1879
+ const stop = this.safeValue (params, 'stop');
1880
+ const request = {
1881
+ 'market': market['id'],
1882
+ // 'id': id, // SPOT
1883
+ // 'order_id': id, // SWAP
1884
+ };
1885
+ const idRequest = swap ? 'order_id' : 'id';
1886
+ request[idRequest] = id;
1887
+ let method = undefined;
1888
+ if (swap) {
1889
+ method = stop ? 'perpetualPrivateGetOrderStopStatus' : 'perpetualPrivateGetOrderStatus';
1890
+ } else {
1891
+ method = 'privateGetOrder';
1892
+ }
1893
+ params = this.omit (params, 'stop');
1894
+ const response = await this[method] (this.extend (request, params));
1895
+ //
1896
+ // Spot
1897
+ //
1898
+ // {
1899
+ // "code": 0,
1900
+ // "data": {
1901
+ // "amount": "0.1",
1902
+ // "asset_fee": "0.22736197736197736197",
1903
+ // "avg_price": "196.85000000000000000000",
1904
+ // "create_time": 1537270135,
1905
+ // "deal_amount": "0.1",
1906
+ // "deal_fee": "0",
1907
+ // "deal_money": "19.685",
1908
+ // "fee_asset": "CET",
1909
+ // "fee_discount": "0.5",
1910
+ // "id": 1788259447,
1911
+ // "left": "0",
1912
+ // "maker_fee_rate": "0",
1913
+ // "market": "ETHUSDT",
1914
+ // "order_type": "limit",
1915
+ // "price": "170.00000000",
1916
+ // "status": "done",
1917
+ // "taker_fee_rate": "0.0005",
1918
+ // "type": "sell",
1919
+ // },
1920
+ // "message": "Ok"
1921
+ // }
1922
+ //
1923
+ // Swap
1924
+ //
1925
+ // {
1926
+ // "code": 0,
1927
+ // "data": {
1928
+ // "amount": "0.0005",
1929
+ // "client_id": "",
1930
+ // "create_time": 1651004578.618224,
1931
+ // "deal_asset_fee": "0.00000000000000000000",
1932
+ // "deal_fee": "0.00000000000000000000",
1933
+ // "deal_profit": "0.00000000000000000000",
1934
+ // "deal_stock": "0.00000000000000000000",
1935
+ // "effect_type": 1,
1936
+ // "fee_asset": "",
1937
+ // "fee_discount": "0.00000000000000000000",
1938
+ // "last_deal_amount": "0.00000000000000000000",
1939
+ // "last_deal_id": 0,
1940
+ // "last_deal_price": "0.00000000000000000000",
1941
+ // "last_deal_role": 0,
1942
+ // "last_deal_time": 0,
1943
+ // "last_deal_type": 0,
1944
+ // "left": "0.0005",
1945
+ // "leverage": "3",
1946
+ // "maker_fee": "0.00030",
1947
+ // "market": "BTCUSDT",
1948
+ // "order_id": 18221659097,
1949
+ // "position_id": 0,
1950
+ // "position_type": 1,
1951
+ // "price": "30000.00",
1952
+ // "side": 2,
1953
+ // "source": "api.v1",
1954
+ // "stop_id": 0,
1955
+ // "taker_fee": "0.00050",
1956
+ // "target": 0,
1957
+ // "type": 1,
1958
+ // "update_time": 1651004578.618224,
1959
+ // "user_id": 3620173
1960
+ // },
1961
+ // "message": "OK"
1962
+ // }
1963
+ //
1964
+ // Swap Stop
1965
+ //
1966
+ // {
1967
+ // "code": 0,
1968
+ // "data": {
1969
+ // "amount": "0.0005",
1970
+ // "client_id": "",
1971
+ // "create_time": 1651034023.008771,
1972
+ // "effect_type": 1,
1973
+ // "fee_asset": "",
1974
+ // "fee_discount": "0.00000000000000000000",
1975
+ // "maker_fee": "0.00030",
1976
+ // "market": "BTCUSDT",
1977
+ // "order_id": 18256915101,
1978
+ // "price": "31000.00",
1979
+ // "side": 2,
1980
+ // "source": "api.v1",
1981
+ // "state": 1,
1982
+ // "stop_price": "31500.00",
1983
+ // "stop_type": 1,
1984
+ // "taker_fee": "0.00050",
1985
+ // "target": 0,
1986
+ // "type": 1,
1987
+ // "update_time": 1651034397.193624,
1988
+ // "user_id": 3620173
1989
+ // },
1990
+ // "message":"OK"
1991
+ // }
1992
+ //
1993
+ const data = this.safeValue (response, 'data');
1994
+ return this.parseOrder (data, market);
1995
+ }
1996
+
1997
+ async fetchOrdersByStatus (status, symbol = undefined, since = undefined, limit = undefined, params = {}) {
1998
+ await this.loadMarkets ();
1999
+ limit = (limit === undefined) ? 100 : limit;
2000
+ const request = {
2001
+ 'limit': limit,
2002
+ // 'page': 1, // SPOT
2003
+ // 'offset': 0, // SWAP
2004
+ // 'side': 0, // SWAP, 0: All, 1: Sell, 2: Buy
2005
+ };
2006
+ const stop = this.safeValue (params, 'stop');
2007
+ const side = this.safeInteger (params, 'side');
2008
+ params = this.omit (params, 'stop');
2009
+ let market = undefined;
2010
+ if (symbol !== undefined) {
2011
+ market = this.market (symbol);
2012
+ request['market'] = market['id'];
2013
+ }
2014
+ const [ marketType, query ] = this.handleMarketTypeAndParams ('fetchOrdersByStatus', market, params);
2015
+ let method = undefined;
2016
+ if (marketType === 'swap') {
2017
+ if (symbol === undefined) {
2018
+ throw new ArgumentsRequired (this.id + ' fetchOrdersByStatus() requires a symbol argument for swap markets');
2019
+ }
2020
+ method = 'perpetualPrivateGetOrder' + this.capitalize (status);
2021
+ if (stop) {
2022
+ method = 'perpetualPrivateGetOrderStopPending';
2023
+ }
2024
+ if (side !== undefined) {
2025
+ request['side'] = side;
2026
+ } else {
2027
+ request['side'] = 0;
2028
+ }
2029
+ request['offset'] = 0;
2030
+ } else {
2031
+ method = 'privateGetOrder' + this.capitalize (status);
2032
+ if (stop) {
2033
+ method = 'privateGetOrderStop' + this.capitalize (status);
2034
+ }
2035
+ request['page'] = 1;
2036
+ }
2037
+ const response = await this[method] (this.extend (request, query));
2038
+ //
2039
+ // Spot
2040
+ //
2041
+ // {
2042
+ // "code": 0,
2043
+ // "data": {
2044
+ // "count": 1,
2045
+ // "curr_page": 1,
2046
+ // "data": [
2047
+ // {
2048
+ // "account_id": 0,
2049
+ // "amount": "0.0005",
2050
+ // "asset_fee": "0",
2051
+ // "avg_price": "0.00",
2052
+ // "client_id": "",
2053
+ // "create_time": 1651089247,
2054
+ // "deal_amount": "0",
2055
+ // "deal_fee": "0",
2056
+ // "deal_money": "0",
2057
+ // "fee_asset": null,
2058
+ // "fee_discount": "1",
2059
+ // "finished_time": 0,
2060
+ // "id": 74660190839,
2061
+ // "left": "0.0005",
2062
+ // "maker_fee_rate": "0.002",
2063
+ // "market": "BTCUSDT",
2064
+ // "money_fee": "0",
2065
+ // "order_type": "limit",
2066
+ // "price": "31000",
2067
+ // "status": "not_deal",
2068
+ // "stock_fee": "0",
2069
+ // "taker_fee_rate": "0.002",
2070
+ // "type": "buy"
2071
+ // }
2072
+ // ],
2073
+ // "has_next": false,
2074
+ // "total": 1
2075
+ // },
2076
+ // "message": "Success"
2077
+ // }
2078
+ //
2079
+ // Swap
2080
+ //
2081
+ // {
2082
+ // "code": 0,
2083
+ // "data": {
2084
+ // "limit": 100,
2085
+ // "offset": 0,
2086
+ // "records": [
2087
+ // {
2088
+ // "amount": "0.0005",
2089
+ // "client_id": "",
2090
+ // "create_time": 1651030414.088431,
2091
+ // "deal_asset_fee": "0",
2092
+ // "deal_fee": "0.00960069",
2093
+ // "deal_profit": "0.009825",
2094
+ // "deal_stock": "19.20138",
2095
+ // "effect_type": 0,
2096
+ // "fee_asset": "",
2097
+ // "fee_discount": "0",
2098
+ // "left": "0",
2099
+ // "leverage": "3",
2100
+ // "maker_fee": "0",
2101
+ // "market": "BTCUSDT",
2102
+ // "order_id": 18253447431,
2103
+ // "position_id": 0,
2104
+ // "position_type": 1,
2105
+ // "price": "0",
2106
+ // "side": 1,
2107
+ // "source": "web",
2108
+ // "stop_id": 0,
2109
+ // "taker_fee": "0.0005",
2110
+ // "target": 0,
2111
+ // "type": 2,
2112
+ // "update_time": 1651030414.08847,
2113
+ // "user_id": 3620173
2114
+ // },
2115
+ // ]
2116
+ // },
2117
+ // "message": "OK"
2118
+ // }
2119
+ //
2120
+ // Spot Stop
2121
+ //
2122
+ // {
2123
+ // "code": 0,
2124
+ // "data": {
2125
+ // "count": 1,
2126
+ // "curr_page": 1,
2127
+ // "data": [
2128
+ // {
2129
+ // "account_id": 0,
2130
+ // "amount": "155",
2131
+ // "client_id": "",
2132
+ // "create_time": 1651089182,
2133
+ // "fee_asset": null,
2134
+ // "fee_discount": "1",
2135
+ // "maker_fee": "0.002",
2136
+ // "market": "BTCUSDT",
2137
+ // "order_id": 74660111965,
2138
+ // "order_type": "market",
2139
+ // "price": "0",
2140
+ // "state": 0,
2141
+ // "stop_price": "31500",
2142
+ // "taker_fee": "0.002",
2143
+ // "type": "buy"
2144
+ // }
2145
+ // ],
2146
+ // "has_next": false,
2147
+ // "total": 0
2148
+ // },
2149
+ // "message": "Success"
2150
+ // }
2151
+ //
2152
+ // Swap Stop
2153
+ //
2154
+ // {
2155
+ // "code": 0,
2156
+ // "data": {
2157
+ // "limit": 100,
2158
+ // "offset": 0,
2159
+ // "records": [
2160
+ // {
2161
+ // "amount": "0.0005",
2162
+ // "client_id": "",
2163
+ // "create_time": 1651089147.321691,
2164
+ // "effect_type": 1,
2165
+ // "fee_asset": "",
2166
+ // "fee_discount": "0.00000000000000000000",
2167
+ // "maker_fee": "0.00030",
2168
+ // "market": "BTCUSDT",
2169
+ // "order_id": 18332143848,
2170
+ // "price": "31000.00",
2171
+ // "side": 2,
2172
+ // "source": "api.v1",
2173
+ // "state": 1,
2174
+ // "stop_price": "31500.00",
2175
+ // "stop_type": 1,
2176
+ // "taker_fee": "0.00050",
2177
+ // "target": 0,
2178
+ // "type": 1,
2179
+ // "update_time": 1651089147.321691,
2180
+ // "user_id": 3620173
2181
+ // }
2182
+ // ],
2183
+ // "total": 1
2184
+ // },
2185
+ // "message": "OK"
2186
+ // }
2187
+ //
2188
+ const tradeRequest = (marketType === 'swap') ? 'records' : 'data';
2189
+ const data = this.safeValue (response, 'data');
2190
+ const orders = this.safeValue (data, tradeRequest, []);
2191
+ return this.parseOrders (orders, market, since, limit);
2192
+ }
2193
+
2194
+ async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
2195
+ return await this.fetchOrdersByStatus ('pending', symbol, since, limit, params);
2196
+ }
2197
+
2198
+ async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
2199
+ return await this.fetchOrdersByStatus ('finished', symbol, since, limit, params);
2200
+ }
2201
+
2202
+ async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
2203
+ if (symbol === undefined) {
2204
+ throw new ArgumentsRequired (this.id + ' fetchMyTrades() requires a symbol argument');
2205
+ }
2206
+ await this.loadMarkets ();
2207
+ const market = this.market (symbol);
2208
+ const swap = market['swap'];
2209
+ if (limit === undefined) {
2210
+ limit = 100;
2211
+ }
2212
+ const request = {
2213
+ 'market': market['id'], // SPOT and SWAP
2214
+ 'limit': limit, // SPOT and SWAP
2215
+ 'offset': 0, // SWAP, means query from a certain record
2216
+ // 'page': 1, // SPOT
2217
+ // 'side': 2, // SWAP, 0 for no limit, 1 for sell, 2 for buy
2218
+ // 'start_time': since, // SWAP
2219
+ // 'end_time': 1524228297, // SWAP
2220
+ };
2221
+ let method = undefined;
2222
+ if (swap) {
2223
+ method = 'perpetualPublicGetMarketUserDeals';
2224
+ const side = this.safeInteger (params, 'side');
2225
+ if (side === undefined) {
2226
+ throw new ArgumentsRequired (this.id + ' fetchMyTrades() requires a side parameter for swap markets');
2227
+ }
2228
+ if (since !== undefined) {
2229
+ request['start_time'] = since;
2230
+ }
2231
+ request['side'] = side;
2232
+ params = this.omit (params, 'side');
2233
+ } else {
2234
+ method = 'privateGetOrderUserDeals';
2235
+ request['page'] = 1;
2236
+ }
2237
+ const response = await this[method] (this.extend (request, params));
2238
+ //
2239
+ // Spot
2240
+ //
2241
+ // {
2242
+ // "code": 0,
2243
+ // "data": {
2244
+ // "data": [
2245
+ // {
2246
+ // "id": 2611520950,
2247
+ // "order_id": 63286573298,
2248
+ // "account_id": 0,
2249
+ // "create_time": 1638990636,
2250
+ // "type": "sell",
2251
+ // "role": "taker",
2252
+ // "price": "192.29",
2253
+ // "amount": "0.098",
2254
+ // "fee": "0.03768884",
2255
+ // "fee_asset": "USDT",
2256
+ // "market": "AAVEUSDT",
2257
+ // "deal_money": "18.84442"
2258
+ // },
2259
+ // ],
2260
+ // "curr_page": 1,
2261
+ // "has_next": false,
2262
+ // "count": 3
2263
+ // },
2264
+ // "message": "Success"
2265
+ // }
2266
+ //
2267
+ // Swap
2268
+ //
2269
+ // {
2270
+ // "code": 0,
2271
+ // "data": {
2272
+ // "limit": 100,
2273
+ // "offset": 0,
2274
+ // "records": [
2275
+ // {
2276
+ // "amount": "0.0012",
2277
+ // "deal_fee": "0.0237528",
2278
+ // "deal_insurance": "0",
2279
+ // "deal_margin": "15.8352",
2280
+ // "deal_order_id": 17797031903,
2281
+ // "deal_profit": "0",
2282
+ // "deal_stock": "47.5056",
2283
+ // "deal_type": 1,
2284
+ // "deal_user_id": 2969195,
2285
+ // "fee_asset": "",
2286
+ // "fee_discount": "0",
2287
+ // "fee_price": "0",
2288
+ // "fee_rate": "0.0005",
2289
+ // "fee_real_rate": "0.0005",
2290
+ // "id": 379044296,
2291
+ // "leverage": "3",
2292
+ // "margin_amount": "15.8352",
2293
+ // "market": "BTCUSDT",
2294
+ // "open_price": "39588",
2295
+ // "order_id": 17797092987,
2296
+ // "position_amount": "0.0012",
2297
+ // "position_id": 62052321,
2298
+ // "position_type": 1,
2299
+ // "price": "39588",
2300
+ // "role": 2,
2301
+ // "side": 2,
2302
+ // "time": 1650675936.016103,
2303
+ // "user_id": 3620173
2304
+ // }
2305
+ // ]
2306
+ // },
2307
+ // "message": "OK"
2308
+ // }
2309
+ //
2310
+ const tradeRequest = swap ? 'records' : 'data';
2311
+ const data = this.safeValue (response, 'data');
2312
+ const trades = this.safeValue (data, tradeRequest, []);
2313
+ return this.parseTrades (trades, market, since, limit);
2314
+ }
2315
+
2316
+ async fetchPositions (symbols = undefined, params = {}) {
2317
+ await this.loadMarkets ();
2318
+ const request = {};
2319
+ let market = undefined;
2320
+ if (symbols !== undefined) {
2321
+ let symbol = undefined;
2322
+ if (Array.isArray (symbols)) {
2323
+ const symbolsLength = symbols.length;
2324
+ if (symbolsLength > 1) {
2325
+ throw new BadRequest (this.id + ' fetchPositions() symbols argument cannot contain more than 1 symbol');
2326
+ }
2327
+ symbol = symbols[0];
2328
+ } else {
2329
+ symbol = symbols;
2330
+ }
2331
+ market = this.market (symbol);
2332
+ request['market'] = market['id'];
2333
+ }
2334
+ const response = await this.perpetualPrivateGetPositionPending (this.extend (request, params));
2335
+ //
2336
+ // {
2337
+ // "code": 0,
2338
+ // "data": [
2339
+ // {
2340
+ // "adl_sort": 3396,
2341
+ // "adl_sort_val": "0.00007786",
2342
+ // "amount": "0.0005",
2343
+ // "amount_max": "0.0005",
2344
+ // "amount_max_margin": "6.42101333333333333333",
2345
+ // "bkr_price": "25684.05333333333333346175",
2346
+ // "bkr_price_imply": "0.00000000000000000000",
2347
+ // "close_left": "0.0005",
2348
+ // "create_time": 1651294226.110899,
2349
+ // "deal_all": "19.26000000000000000000",
2350
+ // "deal_asset_fee": "0.00000000000000000000",
2351
+ // "fee_asset": "",
2352
+ // "finish_type": 1,
2353
+ // "first_price": "38526.08",
2354
+ // "insurance": "0.00000000000000000000",
2355
+ // "latest_price": "38526.08",
2356
+ // "leverage": "3",
2357
+ // "liq_amount": "0.00000000000000000000",
2358
+ // "liq_order_price": "0",
2359
+ // "liq_order_time": 0,
2360
+ // "liq_price": "25876.68373333333333346175",
2361
+ // "liq_price_imply": "0.00000000000000000000",
2362
+ // "liq_profit": "0.00000000000000000000",
2363
+ // "liq_time": 0,
2364
+ // "mainten_margin": "0.005",
2365
+ // "mainten_margin_amount": "0.09631520000000000000",
2366
+ // "maker_fee": "0.00000000000000000000",
2367
+ // "margin_amount": "6.42101333333333333333",
2368
+ // "market": "BTCUSDT",
2369
+ // "open_margin": "0.33333333333333333333",
2370
+ // "open_margin_imply": "0.00000000000000000000",
2371
+ // "open_price": "38526.08000000000000000000",
2372
+ // "open_val": "19.26304000000000000000",
2373
+ // "open_val_max": "19.26304000000000000000",
2374
+ // "position_id": 65847227,
2375
+ // "profit_clearing": "-0.00963152000000000000",
2376
+ // "profit_real": "-0.00963152000000000000",
2377
+ // "profit_unreal": "0.00",
2378
+ // "side": 2,
2379
+ // "stop_loss_price": "0.00000000000000000000",
2380
+ // "stop_loss_type": 0,
2381
+ // "sys": 0,
2382
+ // "take_profit_price": "0.00000000000000000000",
2383
+ // "take_profit_type": 0,
2384
+ // "taker_fee": "0.00000000000000000000",
2385
+ // "total": 4661,
2386
+ // "type": 1,
2387
+ // "update_time": 1651294226.111196,
2388
+ // "user_id": 3620173
2389
+ // },
2390
+ // ],
2391
+ // "message": "OK"
2392
+ // }
2393
+ //
2394
+ const position = this.safeValue (response, 'data', []);
2395
+ const result = [];
2396
+ for (let i = 0; i < position.length; i++) {
2397
+ result.push (this.parsePosition (position[i], market));
2398
+ }
2399
+ return this.filterByArray (result, 'symbol', symbols, false);
2400
+ }
2401
+
2402
+ async fetchPosition (symbol, params = {}) {
2403
+ await this.loadMarkets ();
2404
+ const market = this.market (symbol);
2405
+ const request = {
2406
+ 'market': market['id'],
2407
+ };
2408
+ const response = await this.perpetualPrivateGetPositionPending (this.extend (request, params));
2409
+ //
2410
+ // {
2411
+ // "code": 0,
2412
+ // "data": [
2413
+ // {
2414
+ // "adl_sort": 3396,
2415
+ // "adl_sort_val": "0.00007786",
2416
+ // "amount": "0.0005",
2417
+ // "amount_max": "0.0005",
2418
+ // "amount_max_margin": "6.42101333333333333333",
2419
+ // "bkr_price": "25684.05333333333333346175",
2420
+ // "bkr_price_imply": "0.00000000000000000000",
2421
+ // "close_left": "0.0005",
2422
+ // "create_time": 1651294226.110899,
2423
+ // "deal_all": "19.26000000000000000000",
2424
+ // "deal_asset_fee": "0.00000000000000000000",
2425
+ // "fee_asset": "",
2426
+ // "finish_type": 1,
2427
+ // "first_price": "38526.08",
2428
+ // "insurance": "0.00000000000000000000",
2429
+ // "latest_price": "38526.08",
2430
+ // "leverage": "3",
2431
+ // "liq_amount": "0.00000000000000000000",
2432
+ // "liq_order_price": "0",
2433
+ // "liq_order_time": 0,
2434
+ // "liq_price": "25876.68373333333333346175",
2435
+ // "liq_price_imply": "0.00000000000000000000",
2436
+ // "liq_profit": "0.00000000000000000000",
2437
+ // "liq_time": 0,
2438
+ // "mainten_margin": "0.005",
2439
+ // "mainten_margin_amount": "0.09631520000000000000",
2440
+ // "maker_fee": "0.00000000000000000000",
2441
+ // "margin_amount": "6.42101333333333333333",
2442
+ // "market": "BTCUSDT",
2443
+ // "open_margin": "0.33333333333333333333",
2444
+ // "open_margin_imply": "0.00000000000000000000",
2445
+ // "open_price": "38526.08000000000000000000",
2446
+ // "open_val": "19.26304000000000000000",
2447
+ // "open_val_max": "19.26304000000000000000",
2448
+ // "position_id": 65847227,
2449
+ // "profit_clearing": "-0.00963152000000000000",
2450
+ // "profit_real": "-0.00963152000000000000",
2451
+ // "profit_unreal": "0.00",
2452
+ // "side": 2,
2453
+ // "stop_loss_price": "0.00000000000000000000",
2454
+ // "stop_loss_type": 0,
2455
+ // "sys": 0,
2456
+ // "take_profit_price": "0.00000000000000000000",
2457
+ // "take_profit_type": 0,
2458
+ // "taker_fee": "0.00000000000000000000",
2459
+ // "total": 4661,
2460
+ // "type": 1,
2461
+ // "update_time": 1651294226.111196,
2462
+ // "user_id": 3620173
2463
+ // }
2464
+ // ],
2465
+ // "message": "OK"
2466
+ // }
2467
+ //
2468
+ const data = this.safeValue (response, 'data', []);
2469
+ return this.parsePosition (data[0], market);
2470
+ }
2471
+
2472
+ parsePosition (position, market = undefined) {
2473
+ //
2474
+ // {
2475
+ // "adl_sort": 3396,
2476
+ // "adl_sort_val": "0.00007786",
2477
+ // "amount": "0.0005",
2478
+ // "amount_max": "0.0005",
2479
+ // "amount_max_margin": "6.42101333333333333333",
2480
+ // "bkr_price": "25684.05333333333333346175",
2481
+ // "bkr_price_imply": "0.00000000000000000000",
2482
+ // "close_left": "0.0005",
2483
+ // "create_time": 1651294226.110899,
2484
+ // "deal_all": "19.26000000000000000000",
2485
+ // "deal_asset_fee": "0.00000000000000000000",
2486
+ // "fee_asset": "",
2487
+ // "finish_type": 1,
2488
+ // "first_price": "38526.08",
2489
+ // "insurance": "0.00000000000000000000",
2490
+ // "latest_price": "38526.08",
2491
+ // "leverage": "3",
2492
+ // "liq_amount": "0.00000000000000000000",
2493
+ // "liq_order_price": "0",
2494
+ // "liq_order_time": 0,
2495
+ // "liq_price": "25876.68373333333333346175",
2496
+ // "liq_price_imply": "0.00000000000000000000",
2497
+ // "liq_profit": "0.00000000000000000000",
2498
+ // "liq_time": 0,
2499
+ // "mainten_margin": "0.005",
2500
+ // "mainten_margin_amount": "0.09631520000000000000",
2501
+ // "maker_fee": "0.00000000000000000000",
2502
+ // "margin_amount": "6.42101333333333333333",
2503
+ // "market": "BTCUSDT",
2504
+ // "open_margin": "0.33333333333333333333",
2505
+ // "open_margin_imply": "0.00000000000000000000",
2506
+ // "open_price": "38526.08000000000000000000",
2507
+ // "open_val": "19.26304000000000000000",
2508
+ // "open_val_max": "19.26304000000000000000",
2509
+ // "position_id": 65847227,
2510
+ // "profit_clearing": "-0.00963152000000000000",
2511
+ // "profit_real": "-0.00963152000000000000",
2512
+ // "profit_unreal": "0.00",
2513
+ // "side": 2,
2514
+ // "stop_loss_price": "0.00000000000000000000",
2515
+ // "stop_loss_type": 0,
2516
+ // "sys": 0,
2517
+ // "take_profit_price": "0.00000000000000000000",
2518
+ // "take_profit_type": 0,
2519
+ // "taker_fee": "0.00000000000000000000",
2520
+ // "total": 4661,
2521
+ // "type": 1,
2522
+ // "update_time": 1651294226.111196,
2523
+ // "user_id": 3620173
2524
+ // }
2525
+ //
2526
+ const marketId = this.safeString (position, 'market');
2527
+ market = this.safeMarket (marketId, market);
2528
+ const symbol = market['symbol'];
2529
+ const positionId = this.safeInteger (position, 'position_id');
2530
+ const marginTypeInteger = this.safeInteger (position, 'type');
2531
+ const marginType = (marginTypeInteger === 1) ? 'isolated' : 'cross';
2532
+ const liquidationPrice = this.safeString (position, 'liq_price');
2533
+ const entryPrice = this.safeString (position, 'open_price');
2534
+ const unrealizedPnl = this.safeString (position, 'profit_unreal');
2535
+ const contractSize = this.safeString (position, 'amount');
2536
+ const sideInteger = this.safeInteger (position, 'side');
2537
+ const side = (sideInteger === 1) ? 'short' : 'long';
2538
+ const timestamp = this.safeTimestamp (position, 'update_time');
2539
+ const maintenanceMargin = this.safeString (position, 'mainten_margin_amount');
2540
+ const maintenanceMarginPercentage = this.safeString (position, 'mainten_margin');
2541
+ const collateral = this.safeString (position, 'margin_amount');
2542
+ const leverage = this.safeNumber (position, 'leverage');
2543
+ return {
2544
+ 'info': position,
2545
+ 'id': positionId,
2546
+ 'symbol': symbol,
2547
+ 'notional': undefined,
2548
+ 'marginType': marginType,
2549
+ 'liquidationPrice': liquidationPrice,
2550
+ 'entryPrice': entryPrice,
2551
+ 'unrealizedPnl': unrealizedPnl,
2552
+ 'percentage': undefined,
2553
+ 'contracts': undefined,
2554
+ 'contractSize': contractSize,
2555
+ 'markPrice': undefined,
2556
+ 'side': side,
2557
+ 'hedged': undefined,
2558
+ 'timestamp': timestamp,
2559
+ 'datetime': this.iso8601 (timestamp),
2560
+ 'maintenanceMargin': maintenanceMargin,
2561
+ 'maintenanceMarginPercentage': maintenanceMarginPercentage,
2562
+ 'collateral': collateral,
2563
+ 'initialMargin': undefined,
2564
+ 'initialMarginPercentage': undefined,
2565
+ 'leverage': leverage,
2566
+ 'marginRatio': undefined,
2567
+ };
2568
+ }
2569
+
2570
+ async setMarginMode (marginType, symbol = undefined, params = {}) {
2571
+ if (symbol === undefined) {
2572
+ throw new ArgumentsRequired (this.id + ' setMarginMode() requires a symbol argument');
2573
+ }
2574
+ marginType = marginType.toLowerCase ();
2575
+ if (marginType !== 'isolated' && marginType !== 'cross') {
2576
+ throw new BadRequest (this.id + ' setMarginMode() marginType argument should be isolated or cross');
2577
+ }
2578
+ await this.loadMarkets ();
2579
+ const market = this.market (symbol);
2580
+ if (market['type'] !== 'swap') {
2581
+ throw new BadSymbol (this.id + ' setMarginMode() supports swap contracts only');
2582
+ }
2583
+ const defaultMarginType = this.safeString2 (this.options, 'defaultMarginType', marginType);
2584
+ let defaultPositionType = undefined;
2585
+ if (defaultMarginType === 'isolated') {
2586
+ defaultPositionType = 1;
2587
+ } else if (defaultMarginType === 'cross') {
2588
+ defaultPositionType = 2;
2589
+ }
2590
+ const leverage = this.safeInteger (params, 'leverage');
2591
+ const maxLeverage = this.safeInteger (market['limits']['leverage'], 'max', 100);
2592
+ const positionType = this.safeInteger (params, 'position_type', defaultPositionType);
2593
+ if (leverage === undefined) {
2594
+ throw new ArgumentsRequired (this.id + ' setMarginMode() requires a leverage parameter');
2595
+ }
2596
+ if (positionType === undefined) {
2597
+ throw new ArgumentsRequired (this.id + ' setMarginMode() requires a position_type parameter that will transfer margin to the specified trading pair');
2598
+ }
2599
+ if ((leverage < 3) || (leverage > maxLeverage)) {
2600
+ throw new BadRequest (this.id + ' setMarginMode() leverage should be between 3 and ' + maxLeverage.toString () + ' for ' + symbol);
2601
+ }
2602
+ const request = {
2603
+ 'market': market['id'],
2604
+ 'leverage': leverage.toString (),
2605
+ 'position_type': positionType, // 1: isolated, 2: cross
2606
+ };
2607
+ return await this.perpetualPrivatePostMarketAdjustLeverage (this.extend (request, params));
2608
+ }
2609
+
2610
+ async setLeverage (leverage, symbol = undefined, params = {}) {
2611
+ if (symbol === undefined) {
2612
+ throw new ArgumentsRequired (this.id + ' setLeverage() requires a symbol argument');
2613
+ }
2614
+ await this.loadMarkets ();
2615
+ const defaultMarginType = this.safeString2 (this.options, 'defaultMarginType', 'marginType');
2616
+ let defaultPositionType = undefined;
2617
+ if (defaultMarginType === 'isolated') {
2618
+ defaultPositionType = 1;
2619
+ } else if (defaultMarginType === 'cross') {
2620
+ defaultPositionType = 2;
2621
+ }
2622
+ const positionType = this.safeInteger (params, 'position_type', defaultPositionType);
2623
+ if (positionType === undefined) {
2624
+ throw new ArgumentsRequired (this.id + ' setLeverage() requires a position_type parameter that will transfer margin to the specified trading pair');
2625
+ }
2626
+ const market = this.market (symbol);
2627
+ const maxLeverage = this.safeInteger (market['limits']['leverage'], 'max', 100);
2628
+ if (market['type'] !== 'swap') {
2629
+ throw new BadSymbol (this.id + ' setLeverage() supports swap contracts only');
2630
+ }
2631
+ if ((leverage < 3) || (leverage > maxLeverage)) {
2632
+ throw new BadRequest (this.id + ' setLeverage() leverage should be between 3 and ' + maxLeverage.toString () + ' for ' + symbol);
2633
+ }
2634
+ const request = {
2635
+ 'market': market['id'],
2636
+ 'leverage': leverage.toString (),
2637
+ 'position_type': positionType, // 1: isolated, 2: cross
2638
+ };
2639
+ return await this.perpetualPrivatePostMarketAdjustLeverage (this.extend (request, params));
2640
+ }
2641
+
2642
+ async modifyMarginHelper (symbol, amount, addOrReduce, params = {}) {
2643
+ await this.loadMarkets ();
2644
+ const market = this.market (symbol);
2645
+ const request = {
2646
+ 'market': market['id'],
2647
+ 'amount': this.amountToPrecision (symbol, amount),
2648
+ 'type': addOrReduce,
2649
+ };
2650
+ const response = await this.perpetualPrivatePostPositionAdjustMargin (this.extend (request, params));
2651
+ //
2652
+ // {
2653
+ // "code": 0,
2654
+ // "data": {
2655
+ // "adl_sort": 1,
2656
+ // "adl_sort_val": "0.00004320",
2657
+ // "amount": "0.0005",
2658
+ // "amount_max": "0.0005",
2659
+ // "amount_max_margin": "6.57352000000000000000",
2660
+ // "bkr_price": "16294.08000000000000011090",
2661
+ // "bkr_price_imply": "0.00000000000000000000",
2662
+ // "close_left": "0.0005",
2663
+ // "create_time": 1651202571.320778,
2664
+ // "deal_all": "19.72000000000000000000",
2665
+ // "deal_asset_fee": "0.00000000000000000000",
2666
+ // "fee_asset": "",
2667
+ // "finish_type": 1,
2668
+ // "first_price": "39441.12",
2669
+ // "insurance": "0.00000000000000000000",
2670
+ // "latest_price": "39441.12",
2671
+ // "leverage": "3",
2672
+ // "liq_amount": "0.00000000000000000000",
2673
+ // "liq_order_price": "0",
2674
+ // "liq_order_time": 0,
2675
+ // "liq_price": "16491.28560000000000011090",
2676
+ // "liq_price_imply": "0.00000000000000000000",
2677
+ // "liq_profit": "0.00000000000000000000",
2678
+ // "liq_time": 0,
2679
+ // "mainten_margin": "0.005",
2680
+ // "mainten_margin_amount": "0.09860280000000000000",
2681
+ // "maker_fee": "0.00000000000000000000",
2682
+ // "margin_amount": "11.57352000000000000000",
2683
+ // "market": "BTCUSDT",
2684
+ // "open_margin": "0.58687582908396110455",
2685
+ // "open_margin_imply": "0.00000000000000000000",
2686
+ // "open_price": "39441.12000000000000000000",
2687
+ // "open_val": "19.72056000000000000000",
2688
+ // "open_val_max": "19.72056000000000000000",
2689
+ // "position_id": 65171206,
2690
+ // "profit_clearing": "-0.00986028000000000000",
2691
+ // "profit_real": "-0.00986028000000000000",
2692
+ // "profit_unreal": "0.00",
2693
+ // "side": 2,
2694
+ // "stop_loss_price": "0.00000000000000000000",
2695
+ // "stop_loss_type": 0,
2696
+ // "sys": 0,
2697
+ // "take_profit_price": "0.00000000000000000000",
2698
+ // "take_profit_type": 0,
2699
+ // "taker_fee": "0.00000000000000000000",
2700
+ // "total": 3464,
2701
+ // "type": 1,
2702
+ // "update_time": 1651202638.911212,
2703
+ // "user_id": 3620173
2704
+ // },
2705
+ // "message":"OK"
2706
+ // }
2707
+ //
2708
+ const status = this.safeString (response, 'message');
2709
+ const type = (addOrReduce === 1) ? 'add' : 'reduce';
2710
+ return this.extend (this.parseModifyMargin (response, market), {
2711
+ 'amount': this.parseNumber (amount),
2712
+ 'type': type,
2713
+ 'status': status,
2714
+ });
2715
+ }
2716
+
2717
+ parseModifyMargin (data, market = undefined) {
2718
+ return {
2719
+ 'info': data,
2720
+ 'type': undefined,
2721
+ 'amount': undefined,
2722
+ 'code': market['quote'],
2723
+ 'symbol': this.safeSymbol (undefined, market),
2724
+ 'status': undefined,
2725
+ };
2726
+ }
2727
+
2728
+ async addMargin (symbol, amount, params = {}) {
2729
+ return await this.modifyMarginHelper (symbol, amount, 1, params);
2730
+ }
2731
+
2732
+ async reduceMargin (symbol, amount, params = {}) {
2733
+ return await this.modifyMarginHelper (symbol, amount, 2, params);
2734
+ }
2735
+
2736
+ async fetchFundingHistory (symbol = undefined, since = undefined, limit = undefined, params = {}) {
2737
+ if (symbol === undefined) {
2738
+ throw new ArgumentsRequired (this.id + ' fetchFundingHistory() requires a symbol argument');
2739
+ }
2740
+ limit = (limit === undefined) ? 100 : limit;
2741
+ await this.loadMarkets ();
2742
+ const market = this.market (symbol);
2743
+ const request = {
2744
+ 'market': market['id'],
2745
+ 'limit': limit,
2746
+ // 'offset': 0,
2747
+ // 'end_time': 1638990636000,
2748
+ // 'windowtime': 1638990636000,
2749
+ };
2750
+ if (since !== undefined) {
2751
+ request['start_time'] = since;
2752
+ }
2753
+ const response = await this.perpetualPrivateGetPositionFunding (this.extend (request, params));
2754
+ //
2755
+ // {
2756
+ // "code": 0,
2757
+ // "data": {
2758
+ // "limit": 100,
2759
+ // "offset": 0,
2760
+ // "records": [
2761
+ // {
2762
+ // "amount": "0.0012",
2763
+ // "asset": "USDT",
2764
+ // "funding": "-0.0095688273996",
2765
+ // "funding_rate": "0.00020034",
2766
+ // "market": "BTCUSDT",
2767
+ // "position_id": 62052321,
2768
+ // "price": "39802.45",
2769
+ // "real_funding_rate": "0.00020034",
2770
+ // "side": 2,
2771
+ // "time": 1650729623.933885,
2772
+ // "type": 1,
2773
+ // "user_id": 3620173,
2774
+ // "value": "47.76294"
2775
+ // },
2776
+ // ]
2777
+ // },
2778
+ // "message": "OK"
2779
+ // }
2780
+ //
2781
+ const data = this.safeValue (response, 'data', {});
2782
+ const resultList = this.safeValue (data, 'records', []);
2783
+ const result = [];
2784
+ for (let i = 0; i < resultList.length; i++) {
2785
+ const entry = resultList[i];
2786
+ const timestamp = this.safeTimestamp (entry, 'time');
2787
+ const currencyId = this.safeString (entry, 'asset');
2788
+ const code = this.safeCurrencyCode (currencyId);
2789
+ result.push ({
2790
+ 'info': entry,
2791
+ 'symbol': symbol,
2792
+ 'code': code,
2793
+ 'timestamp': timestamp,
2794
+ 'datetime': this.iso8601 (timestamp),
2795
+ 'id': this.safeNumber (entry, 'position_id'),
2796
+ 'amount': this.safeNumber (entry, 'funding'),
2797
+ });
2798
+ }
2799
+ return result;
2800
+ }
2801
+
2802
+ async fetchFundingRate (symbol, params = {}) {
2803
+ await this.loadMarkets ();
2804
+ const market = this.market (symbol);
2805
+ if (!market['swap']) {
2806
+ throw new BadSymbol (this.id + ' fetchFundingRate() supports swap contracts only');
2807
+ }
2808
+ const request = {
2809
+ 'market': market['id'],
2810
+ };
2811
+ const response = await this.perpetualPublicGetMarketTicker (this.extend (request, params));
2812
+ //
2813
+ // {
2814
+ // "code": 0,
2815
+ // "data":
2816
+ // {
2817
+ // "date": 1650678472474,
2818
+ // "ticker": {
2819
+ // "vol": "6090.9430",
2820
+ // "low": "39180.30",
2821
+ // "open": "40474.97",
2822
+ // "high": "40798.01",
2823
+ // "last": "39659.30",
2824
+ // "buy": "39663.79",
2825
+ // "period": 86400,
2826
+ // "funding_time": 372,
2827
+ // "position_amount": "270.1956",
2828
+ // "funding_rate_last": "0.00022913",
2829
+ // "funding_rate_next": "0.00013158",
2830
+ // "funding_rate_predict": "0.00016552",
2831
+ // "insurance": "16045554.83969682659674035672",
2832
+ // "sign_price": "39652.48",
2833
+ // "index_price": "39648.44250000",
2834
+ // "sell_total": "22.3913",
2835
+ // "buy_total": "19.4498",
2836
+ // "buy_amount": "12.8942",
2837
+ // "sell": "39663.80",
2838
+ // "sell_amount": "0.9388"
2839
+ // }
2840
+ // },
2841
+ // "message": "OK"
2842
+ // }
2843
+ //
2844
+ const data = this.safeValue (response, 'data', {});
2845
+ const ticker = this.safeValue (data, 'ticker', {});
2846
+ return this.parseFundingRate (ticker, market);
2847
+ }
2848
+
2849
+ parseFundingRate (contract, market = undefined) {
2850
+ //
2851
+ // fetchFundingRate
2852
+ //
2853
+ // {
2854
+ // "vol": "6090.9430",
2855
+ // "low": "39180.30",
2856
+ // "open": "40474.97",
2857
+ // "high": "40798.01",
2858
+ // "last": "39659.30",
2859
+ // "buy": "39663.79",
2860
+ // "period": 86400,
2861
+ // "funding_time": 372,
2862
+ // "position_amount": "270.1956",
2863
+ // "funding_rate_last": "0.00022913",
2864
+ // "funding_rate_next": "0.00013158",
2865
+ // "funding_rate_predict": "0.00016552",
2866
+ // "insurance": "16045554.83969682659674035672",
2867
+ // "sign_price": "39652.48",
2868
+ // "index_price": "39648.44250000",
2869
+ // "sell_total": "22.3913",
2870
+ // "buy_total": "19.4498",
2871
+ // "buy_amount": "12.8942",
2872
+ // "sell": "39663.80",
2873
+ // "sell_amount": "0.9388"
2874
+ // }
2875
+ //
2876
+ return {
2877
+ 'info': contract,
2878
+ 'symbol': this.safeSymbol (undefined, market),
2879
+ 'markPrice': this.safeString (contract, 'sign_price'),
2880
+ 'indexPrice': this.safeString (contract, 'index_price'),
2881
+ 'interestRate': undefined,
2882
+ 'estimatedSettlePrice': undefined,
2883
+ 'timestamp': undefined,
2884
+ 'datetime': undefined,
2885
+ 'fundingRate': this.safeString (contract, 'funding_rate_next'),
2886
+ 'fundingTimestamp': undefined,
2887
+ 'fundingDatetime': undefined,
2888
+ 'nextFundingRate': this.safeString (contract, 'funding_rate_predict'),
2889
+ 'nextFundingTimestamp': undefined,
2890
+ 'nextFundingDatetime': undefined,
2891
+ 'previousFundingRate': this.safeString (contract, 'funding_rate_last'),
2892
+ 'previousFundingTimestamp': undefined,
2893
+ 'previousFundingDatetime': undefined,
2894
+ };
2895
+ }
2896
+
2897
+ async withdraw (code, amount, address, tag = undefined, params = {}) {
2898
+ [ tag, params ] = this.handleWithdrawTagAndParams (tag, params);
2899
+ this.checkAddress (address);
2900
+ await this.loadMarkets ();
2901
+ const currency = this.currency (code);
2902
+ if (tag) {
2903
+ address = address + ':' + tag;
2904
+ }
2905
+ const request = {
2906
+ 'coin_type': currency['id'],
2907
+ 'coin_address': address, // must be authorized, inter-user transfer by a registered mobile phone number or an email address is supported
2908
+ 'actual_amount': parseFloat (amount), // the actual amount without fees, https://www.coinex.com/fees
2909
+ 'transfer_method': 'onchain', // onchain, local
2910
+ };
2911
+ const response = await this.privatePostBalanceCoinWithdraw (this.extend (request, params));
2912
+ //
2913
+ // {
2914
+ // "code": 0,
2915
+ // "data": {
2916
+ // "actual_amount": "1.00000000",
2917
+ // "amount": "1.00000000",
2918
+ // "coin_address": "1KAv3pazbTk2JnQ5xTo6fpKK7p1it2RzD4",
2919
+ // "coin_type": "BCH",
2920
+ // "coin_withdraw_id": 206,
2921
+ // "confirmations": 0,
2922
+ // "create_time": 1524228297,
2923
+ // "status": "audit",
2924
+ // "tx_fee": "0",
2925
+ // "tx_id": ""
2926
+ // },
2927
+ // "message": "Ok"
2928
+ // }
2929
+ //
2930
+ const transaction = this.safeValue (response, 'data', {});
2931
+ return this.parseTransaction (transaction, currency);
2932
+ }
2933
+
2934
+ parseTransactionStatus (status) {
2935
+ const statuses = {
2936
+ 'audit': 'pending',
2937
+ 'pass': 'pending',
2938
+ 'processing': 'pending',
2939
+ 'confirming': 'pending',
2940
+ 'not_pass': 'failed',
2941
+ 'cancel': 'canceled',
2942
+ 'finish': 'ok',
2943
+ 'fail': 'failed',
2944
+ };
2945
+ return this.safeString (statuses, status, status);
2946
+ }
2947
+
2948
+ async fetchFundingRateHistory (symbol = undefined, since = undefined, limit = 100, params = {}) {
2949
+ if (symbol === undefined) {
2950
+ throw new ArgumentsRequired (this.id + ' fetchFundingRateHistory() requires a symbol argument');
2951
+ }
2952
+ await this.loadMarkets ();
2953
+ const market = this.market (symbol);
2954
+ const request = {
2955
+ 'market': market['id'],
2956
+ 'limit': limit,
2957
+ 'offset': 0,
2958
+ // 'end_time': 1638990636,
2959
+ };
2960
+ if (since !== undefined) {
2961
+ request['start_time'] = since;
2962
+ }
2963
+ const response = await this.perpetualPublicGetMarketFundingHistory (this.extend (request, params));
2964
+ //
2965
+ // {
2966
+ // "code": 0,
2967
+ // "data": {
2968
+ // "offset": 0,
2969
+ // "limit": 3,
2970
+ // "records": [
2971
+ // {
2972
+ // "time": 1650672021.6230309,
2973
+ // "market": "BTCUSDT",
2974
+ // "asset": "USDT",
2975
+ // "funding_rate": "0.00022913",
2976
+ // "funding_rate_real": "0.00022913"
2977
+ // },
2978
+ // ]
2979
+ // },
2980
+ // "message": "OK"
2981
+ // }
2982
+ //
2983
+ const data = this.safeValue (response, 'data');
2984
+ const result = this.safeValue (data, 'records');
2985
+ const rates = [];
2986
+ for (let i = 0; i < result.length; i++) {
2987
+ const entry = result[i];
2988
+ const marketId = this.safeString (entry, 'market');
2989
+ const symbol = this.safeSymbol (marketId);
2990
+ const timestamp = this.safeTimestamp (entry, 'time');
2991
+ rates.push ({
2992
+ 'info': entry,
2993
+ 'symbol': symbol,
2994
+ 'fundingRate': this.safeString (entry, 'funding_rate'),
2995
+ 'timestamp': timestamp,
2996
+ 'datetime': this.iso8601 (timestamp),
2997
+ });
2998
+ }
2999
+ const sorted = this.sortBy (rates, 'timestamp');
3000
+ return this.filterBySymbolSinceLimit (sorted, market['symbol'], since, limit);
3001
+ }
3002
+
3003
+ parseTransaction (transaction, currency = undefined) {
3004
+ //
3005
+ // fetchDeposits
3006
+ //
3007
+ // {
3008
+ // "actual_amount": "120.00000000",
3009
+ // "actual_amount_display": "120",
3010
+ // "add_explorer": "XXX",
3011
+ // "amount": "120.00000000",
3012
+ // "amount_display": "120",
3013
+ // "coin_address": "XXXXXXXX",
3014
+ // "coin_address_display": "XXXXXXXX",
3015
+ // "coin_deposit_id": 1866,
3016
+ // "coin_type": "USDT",
3017
+ // "confirmations": 0,
3018
+ // "create_time": 1539595701,
3019
+ // "explorer": "",
3020
+ // "remark": "",
3021
+ // "status": "finish",
3022
+ // "status_display": "finish",
3023
+ // "transfer_method": "local",
3024
+ // "tx_id": "",
3025
+ // "tx_id_display": "XXXXXXXXXX"
3026
+ // }
3027
+ //
3028
+ // fetchWithdrawals
3029
+ //
3030
+ // {
3031
+ // "actual_amount": "0.10000000",
3032
+ // "amount": "0.10000000",
3033
+ // "coin_address": "15sr1VdyXQ6sVLqeJUJ1uPzLpmQtgUeBSB",
3034
+ // "coin_type": "BCH",
3035
+ // "coin_withdraw_id": 203,
3036
+ // "confirmations": 11,
3037
+ // "create_time": 1515806440,
3038
+ // "status": "finish",
3039
+ // "tx_fee": "0",
3040
+ // "tx_id": "896371d0e23d64d1cac65a0b7c9e9093d835affb572fec89dd4547277fbdd2f6"
3041
+ // }
3042
+ //
3043
+ const id = this.safeString2 (transaction, 'coin_withdraw_id', 'coin_deposit_id');
3044
+ const address = this.safeString (transaction, 'coin_address');
3045
+ let tag = this.safeString (transaction, 'remark'); // set but unused
3046
+ if (tag !== undefined) {
3047
+ if (tag.length < 1) {
3048
+ tag = undefined;
3049
+ }
3050
+ }
3051
+ let txid = this.safeValue (transaction, 'tx_id');
3052
+ if (txid !== undefined) {
3053
+ if (txid.length < 1) {
3054
+ txid = undefined;
3055
+ }
3056
+ }
3057
+ const currencyId = this.safeString (transaction, 'coin_type');
3058
+ const code = this.safeCurrencyCode (currencyId, currency);
3059
+ const timestamp = this.safeTimestamp (transaction, 'create_time');
3060
+ const type = ('coin_withdraw_id' in transaction) ? 'withdraw' : 'deposit';
3061
+ const status = this.parseTransactionStatus (this.safeString (transaction, 'status'));
3062
+ let amount = this.safeNumber (transaction, 'amount');
3063
+ let feeCost = this.safeNumber (transaction, 'tx_fee');
3064
+ if (type === 'deposit') {
3065
+ feeCost = 0;
3066
+ }
3067
+ const fee = {
3068
+ 'cost': feeCost,
3069
+ 'currency': code,
3070
+ };
3071
+ // https://github.com/ccxt/ccxt/issues/8321
3072
+ if (amount !== undefined) {
3073
+ amount = amount - feeCost;
3074
+ }
3075
+ return {
3076
+ 'info': transaction,
3077
+ 'id': id,
3078
+ 'txid': txid,
3079
+ 'timestamp': timestamp,
3080
+ 'datetime': this.iso8601 (timestamp),
3081
+ 'network': undefined,
3082
+ 'address': address,
3083
+ 'addressTo': undefined,
3084
+ 'addressFrom': undefined,
3085
+ 'tag': tag,
3086
+ 'tagTo': undefined,
3087
+ 'tagFrom': undefined,
3088
+ 'type': type,
3089
+ 'amount': amount,
3090
+ 'currency': code,
3091
+ 'status': status,
3092
+ 'updated': undefined,
3093
+ 'fee': fee,
3094
+ };
3095
+ }
3096
+
3097
+ async transfer (code, amount, fromAccount, toAccount, params = {}) {
3098
+ await this.loadMarkets ();
3099
+ const [ marketType, query ] = this.handleMarketTypeAndParams ('transfer', undefined, params);
3100
+ if (marketType !== 'spot') {
3101
+ throw new BadRequest (this.id + ' transfer() requires defaultType to be spot');
3102
+ }
3103
+ const currency = this.safeCurrencyCode (code);
3104
+ const amountToPrecision = this.currencyToPrecision (code, amount);
3105
+ let transfer = undefined;
3106
+ if ((fromAccount === 'spot') && (toAccount === 'swap')) {
3107
+ transfer = 'in';
3108
+ } else if ((fromAccount === 'swap') && (toAccount === 'spot')) {
3109
+ transfer = 'out';
3110
+ }
3111
+ const request = {
3112
+ 'amount': amountToPrecision,
3113
+ 'coin_type': currency,
3114
+ 'transfer_side': transfer, // 'in': spot to swap, 'out': swap to spot
3115
+ };
3116
+ const response = await this.privatePostContractBalanceTransfer (this.extend (request, query));
3117
+ //
3118
+ // {"code": 0, "data": null, "message": "Success"}
3119
+ //
3120
+ return this.extend (this.parseTransfer (response, currency), {
3121
+ 'amount': this.parseNumber (amountToPrecision),
3122
+ 'fromAccount': fromAccount,
3123
+ 'toAccount': toAccount,
3124
+ });
3125
+ }
3126
+
3127
+ parseTransferStatus (status) {
3128
+ const statuses = {
3129
+ '0': 'ok',
3130
+ };
3131
+ return this.safeString (statuses, status, status);
3132
+ }
3133
+
3134
+ parseTransfer (transfer, currency = undefined) {
3135
+ //
3136
+ // fetchTransfers
3137
+ //
3138
+ // {
3139
+ // "amount": "10",
3140
+ // "asset": "USDT",
3141
+ // "transfer_type": "transfer_out", // from swap to spot
3142
+ // "created_at": 1651633422
3143
+ // },
3144
+ //
3145
+ const timestamp = this.safeTimestamp (transfer, 'created_at');
3146
+ const transferType = this.safeString (transfer, 'transfer_type');
3147
+ let fromAccount = undefined;
3148
+ let toAccount = undefined;
3149
+ if (transferType === 'transfer_out') {
3150
+ fromAccount = 'swap';
3151
+ toAccount = 'spot';
3152
+ } else if (transferType === 'transfer_in') {
3153
+ fromAccount = 'spot';
3154
+ toAccount = 'swap';
3155
+ }
3156
+ const currencyId = this.safeString (transfer, 'asset');
3157
+ const currencyCode = this.safeCurrencyCode (currencyId, currency);
3158
+ return {
3159
+ 'id': undefined,
3160
+ 'timestamp': timestamp,
3161
+ 'datetime': this.iso8601 (timestamp),
3162
+ 'currency': currencyCode,
3163
+ 'amount': this.safeNumber (transfer, 'amount'),
3164
+ 'fromAccount': fromAccount,
3165
+ 'toAccount': toAccount,
3166
+ 'status': this.parseTransferStatus (this.safeString (transfer, 'code')),
3167
+ };
3168
+ }
3169
+
3170
+ async fetchTransfers (code = undefined, since = undefined, limit = undefined, params = {}) {
3171
+ await this.loadMarkets ();
3172
+ let currency = undefined;
3173
+ const request = {
3174
+ 'page': 1,
3175
+ 'limit': limit,
3176
+ // 'asset': 'USDT',
3177
+ // 'start_time': since,
3178
+ // 'end_time': 1515806440,
3179
+ // 'transfer_type': 'transfer_in', // transfer_in: from Spot to Swap Account, transfer_out: from Swap to Spot Account
3180
+ };
3181
+ const page = this.safeInteger (params, 'page');
3182
+ if (page !== undefined) {
3183
+ request['page'] = page;
3184
+ }
3185
+ if (code !== undefined) {
3186
+ currency = this.safeCurrencyCode (code);
3187
+ request['asset'] = currency['id'];
3188
+ }
3189
+ if (since !== undefined) {
3190
+ request['start_time'] = since;
3191
+ }
3192
+ params = this.omit (params, 'page');
3193
+ const response = await this.privateGetContractTransferHistory (this.extend (request, params));
3194
+ //
3195
+ // {
3196
+ // "code": 0,
3197
+ // "data": {
3198
+ // "records": [
3199
+ // {
3200
+ // "amount": "10",
3201
+ // "asset": "USDT",
3202
+ // "transfer_type": "transfer_out",
3203
+ // "created_at": 1651633422
3204
+ // },
3205
+ // ],
3206
+ // "total": 5
3207
+ // },
3208
+ // "message": "Success"
3209
+ // }
3210
+ //
3211
+ const data = this.safeValue (response, 'data', {});
3212
+ const transfers = this.safeValue (data, 'records', []);
3213
+ return this.parseTransfers (transfers, currency, since, limit);
3214
+ }
3215
+
3216
+ async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
3217
+ if (code === undefined) {
3218
+ throw new ArgumentsRequired (this.id + ' fetchWithdrawals() requires a currency code argument');
3219
+ }
3220
+ await this.loadMarkets ();
3221
+ const currency = this.currency (code);
3222
+ const request = {
3223
+ 'coin_type': currency['id'],
3224
+ };
3225
+ if (limit !== undefined) {
3226
+ request['Limit'] = limit;
3227
+ }
3228
+ const response = await this.privateGetBalanceCoinWithdraw (this.extend (request, params));
3229
+ //
3230
+ // {
3231
+ // "code": 0,
3232
+ // "data": {
3233
+ // "has_next": true,
3234
+ // "curr_page": 1,
3235
+ // "count": 10,
3236
+ // "data": [
3237
+ // {
3238
+ // "coin_withdraw_id": 203,
3239
+ // "create_time": 1513933541,
3240
+ // "actual_amount": "0.00100000",
3241
+ // "actual_amount_display": "***",
3242
+ // "amount": "0.00100000",
3243
+ // "amount_display": "******",
3244
+ // "coin_address": "1GVVx5UBddLKrckTprNi4VhHSymeQ8tsLF",
3245
+ // "app_coin_address_display": "**********",
3246
+ // "coin_address_display": "****************",
3247
+ // "add_explorer": "https://explorer.viawallet.com/btc/address/1GVVx5UBddLKrckTprNi4VhHSymeQ8tsLF",
3248
+ // "coin_type": "BTC",
3249
+ // "confirmations": 6,
3250
+ // "explorer": "https://explorer.viawallet.com/btc/tx/1GVVx5UBddLKrckTprNi4VhHSymeQ8tsLF",
3251
+ // "fee": "0",
3252
+ // "remark": "",
3253
+ // "smart_contract_name": "BTC",
3254
+ // "status": "finish",
3255
+ // "status_display": "finish",
3256
+ // "transfer_method": "onchain",
3257
+ // "tx_fee": "0",
3258
+ // "tx_id": "896371d0e23d64d1cac65a0b7c9e9093d835affb572fec89dd4547277fbdd2f6"
3259
+ // }, /* many more data points */
3260
+ // ],
3261
+ // "total": ***,
3262
+ // "total_page":***
3263
+ // },
3264
+ // "message": "Success"
3265
+ // }
3266
+ //
3267
+ let data = this.safeValue (response, 'data');
3268
+ if (!Array.isArray (data)) {
3269
+ data = this.safeValue (data, 'data', []);
3270
+ }
3271
+ return this.parseTransactions (data, currency, since, limit);
3272
+ }
3273
+
3274
+ async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
3275
+ if (code === undefined) {
3276
+ throw new ArgumentsRequired (this.id + ' fetchDeposits() requires a currency code argument');
3277
+ }
3278
+ await this.loadMarkets ();
3279
+ const currency = this.currency (code);
3280
+ const request = {
3281
+ 'coin_type': currency['id'],
3282
+ };
3283
+ if (limit !== undefined) {
3284
+ request['Limit'] = limit;
3285
+ }
3286
+ const response = await this.privateGetBalanceCoinDeposit (this.extend (request, params));
3287
+ // {
3288
+ // "code": 0,
3289
+ // "data": [
3290
+ // {
3291
+ // "actual_amount": "4.65397682",
3292
+ // "actual_amount_display": "4.65397682",
3293
+ // "add_explorer": "https://etherscan.io/address/0x361XXXXXX",
3294
+ // "amount": "4.65397682",
3295
+ // "amount_display": "4.65397682",
3296
+ // "coin_address": "0x36dabcdXXXXXX",
3297
+ // "coin_address_display": "0x361X*****XXXXX",
3298
+ // "coin_deposit_id": 966191,
3299
+ // "coin_type": "ETH",
3300
+ // "confirmations": 30,
3301
+ // "create_time": 1531661445,
3302
+ // "explorer": "https://etherscan.io/tx/0x361XXXXXX",
3303
+ // "remark": "",
3304
+ // "status": "finish",
3305
+ // "status_display": "finish",
3306
+ // "transfer_method": "onchain",
3307
+ // "tx_id": "0x361XXXXXX",
3308
+ // "tx_id_display": "0x361XXXXXX"
3309
+ // }
3310
+ // ],
3311
+ // "message": "Ok"
3312
+ // }
3313
+ //
3314
+ let data = this.safeValue (response, 'data');
3315
+ if (!Array.isArray (data)) {
3316
+ data = this.safeValue (data, 'data', []);
3317
+ }
3318
+ return this.parseTransactions (data, currency, since, limit);
3319
+ }
3320
+
3321
+ nonce () {
3322
+ return this.milliseconds ();
3323
+ }
3324
+
3325
+ sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
3326
+ path = this.implodeParams (path, params);
3327
+ let url = this.urls['api'][api] + '/' + this.version + '/' + path;
3328
+ let query = this.omit (params, this.extractParams (path));
3329
+ this.checkRequiredCredentials ();
3330
+ const nonce = this.nonce ().toString ();
3331
+ if (api === 'perpetualPrivate' || url === 'https://api.coinex.com/perpetual/v1/market/user_deals') {
3332
+ query = this.extend ({
3333
+ 'access_id': this.apiKey,
3334
+ 'timestamp': nonce,
3335
+ }, query);
3336
+ query = this.keysort (query);
3337
+ const urlencoded = this.rawencode (query);
3338
+ const signature = this.hash (this.encode (urlencoded + '&secret_key=' + this.secret), 'sha256');
3339
+ headers = {
3340
+ 'Authorization': signature.toLowerCase (),
3341
+ 'AccessId': this.apiKey,
3342
+ };
3343
+ if ((method === 'GET')) {
3344
+ url += '?' + urlencoded;
3345
+ } else {
3346
+ headers['Content-Type'] = 'application/x-www-form-urlencoded';
3347
+ body = urlencoded;
3348
+ }
3349
+ } else if (api === 'public' || api === 'perpetualPublic') {
3350
+ if (Object.keys (query).length) {
3351
+ url += '?' + this.urlencode (query);
3352
+ }
3353
+ } else {
3354
+ query = this.extend ({
3355
+ 'access_id': this.apiKey,
3356
+ 'tonce': nonce,
3357
+ }, query);
3358
+ query = this.keysort (query);
3359
+ const urlencoded = this.rawencode (query);
3360
+ const signature = this.hash (this.encode (urlencoded + '&secret_key=' + this.secret));
3361
+ headers = {
3362
+ 'Authorization': signature.toUpperCase (),
3363
+ 'Content-Type': 'application/json',
3364
+ };
3365
+ if ((method === 'GET') || (method === 'DELETE')) {
3366
+ url += '?' + urlencoded;
3367
+ } else {
3368
+ body = this.json (query);
3369
+ }
3370
+ }
3371
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
3372
+ }
3373
+
3374
+ handleErrors (httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
3375
+ if (response === undefined) {
3376
+ return;
3377
+ }
3378
+ const code = this.safeString (response, 'code');
3379
+ const data = this.safeValue (response, 'data');
3380
+ const message = this.safeString (response, 'message');
3381
+ if ((code !== '0') || ((message !== 'Success') && (message !== 'Succeeded') && (message !== 'Ok') && !data)) {
3382
+ const responseCodes = {
3383
+ // https://github.com/coinexcom/coinex_exchange_api/wiki/013error_code
3384
+ '23': PermissionDenied, // IP Prohibited
3385
+ '24': AuthenticationError,
3386
+ '25': AuthenticationError,
3387
+ '34': AuthenticationError, // Access id is expires
3388
+ '35': ExchangeNotAvailable, // Service unavailable
3389
+ '36': RequestTimeout, // Service timeout
3390
+ '107': InsufficientFunds,
3391
+ '600': OrderNotFound,
3392
+ '601': InvalidOrder,
3393
+ '602': InvalidOrder,
3394
+ '606': InvalidOrder,
3395
+ };
3396
+ const ErrorClass = this.safeValue (responseCodes, code, ExchangeError);
3397
+ throw new ErrorClass (response['message']);
3398
+ }
3399
+ }
3400
+ };