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/aax.js ADDED
@@ -0,0 +1,2686 @@
1
+ 'use strict';
2
+
3
+ // ----------------------------------------------------------------------------
4
+
5
+ const Exchange = require ('./base/Exchange');
6
+ const { ArgumentsRequired, AuthenticationError, ExchangeError, ExchangeNotAvailable, OrderNotFound, InvalidOrder, CancelPending, RateLimitExceeded, InsufficientFunds, BadRequest, BadSymbol, PermissionDenied } = require ('./base/errors');
7
+ const { TICK_SIZE } = require ('./base/functions/number');
8
+ const Precise = require ('./base/Precise');
9
+
10
+ // ----------------------------------------------------------------------------
11
+
12
+ module.exports = class aax extends Exchange {
13
+ describe () {
14
+ return this.deepExtend (super.describe (), {
15
+ 'id': 'aax',
16
+ 'name': 'AAX',
17
+ 'countries': [ 'MT' ], // Malta
18
+ 'enableRateLimit': true,
19
+ // 6000 / hour => 100 per minute => 1.66 requests per second => rateLimit = 600
20
+ // market endpoints ratelimits arent mentioned in docs so they are also set to "all other authenticated endpoints"
21
+ // 5000 / hour => weight = 1.2 ("all other authenticated endpoints")
22
+ // 600 / hour => weight = 10
23
+ // 200 / hour => weight = 30
24
+ 'rateLimit': 600,
25
+ 'version': 'v2',
26
+ 'hostname': 'aaxpro.com', // aax.com
27
+ 'pro': true,
28
+ 'has': {
29
+ 'CORS': undefined,
30
+ 'spot': true,
31
+ 'margin': false,
32
+ 'swap': true,
33
+ 'future': false,
34
+ 'option': false,
35
+ 'addMargin': undefined,
36
+ 'cancelAllOrders': true,
37
+ 'cancelOrder': true,
38
+ 'cancelOrders': undefined,
39
+ 'createDepositAddress': undefined,
40
+ 'createOrder': true,
41
+ 'createReduceOnlyOrder': false,
42
+ 'createStopLimitOrder': true,
43
+ 'createStopMarketOrder': true,
44
+ 'createStopOrder': true,
45
+ 'editOrder': true,
46
+ 'fetchAccounts': undefined,
47
+ 'fetchBalance': true,
48
+ 'fetchBidsAsks': undefined,
49
+ 'fetchBorrowRate': false,
50
+ 'fetchBorrowRateHistories': false,
51
+ 'fetchBorrowRateHistory': false,
52
+ 'fetchBorrowRates': false,
53
+ 'fetchBorrowRatesPerSymbol': false,
54
+ 'fetchCanceledOrders': true,
55
+ 'fetchClosedOrder': undefined,
56
+ 'fetchClosedOrders': true,
57
+ 'fetchCurrencies': true,
58
+ 'fetchDeposit': undefined,
59
+ 'fetchDepositAddress': true,
60
+ 'fetchDepositAddresses': undefined,
61
+ 'fetchDepositAddressesByNetwork': undefined,
62
+ 'fetchDeposits': true,
63
+ 'fetchFundingFee': undefined,
64
+ 'fetchFundingFees': undefined,
65
+ 'fetchFundingHistory': true,
66
+ 'fetchFundingRate': true,
67
+ 'fetchFundingRateHistory': true,
68
+ 'fetchFundingRates': false,
69
+ 'fetchIndexOHLCV': false,
70
+ 'fetchL3OrderBook': undefined,
71
+ 'fetchLedger': undefined,
72
+ 'fetchLedgerEntry': undefined,
73
+ 'fetchLeverage': undefined,
74
+ 'fetchLeverageTiers': false,
75
+ 'fetchMarketLeverageTiers': false,
76
+ 'fetchMarkets': true,
77
+ 'fetchMarkOHLCV': false,
78
+ 'fetchMyBuys': undefined,
79
+ 'fetchMySells': undefined,
80
+ 'fetchMyTrades': true,
81
+ 'fetchOHLCV': true,
82
+ 'fetchOpenOrder': undefined,
83
+ 'fetchOpenOrders': true,
84
+ 'fetchOrder': true,
85
+ 'fetchOrderBook': true,
86
+ 'fetchOrderBooks': undefined,
87
+ 'fetchOrders': true,
88
+ 'fetchOrderTrades': undefined,
89
+ 'fetchPosition': true,
90
+ 'fetchPositions': true,
91
+ 'fetchPositionsRisk': false,
92
+ 'fetchPremiumIndexOHLCV': false,
93
+ 'fetchStatus': true,
94
+ 'fetchTicker': 'emulated',
95
+ 'fetchTickers': true,
96
+ 'fetchTime': true,
97
+ 'fetchTrades': true,
98
+ 'fetchTradingFee': false,
99
+ 'fetchTradingFees': false,
100
+ 'fetchTradingLimits': undefined,
101
+ 'fetchTransactions': undefined,
102
+ 'fetchTransfer': false,
103
+ 'fetchTransfers': true,
104
+ 'fetchWithdrawal': false,
105
+ 'fetchWithdrawals': true,
106
+ 'fetchWithdrawalWhitelist': undefined,
107
+ 'reduceMargin': undefined,
108
+ 'setLeverage': true,
109
+ 'setMarginMode': false,
110
+ 'setPositionMode': undefined,
111
+ 'signIn': undefined,
112
+ 'transfer': true,
113
+ 'withdraw': false,
114
+ },
115
+ 'timeframes': {
116
+ '1m': '1m',
117
+ '5m': '5m',
118
+ '15m': '15m',
119
+ '30m': '30m',
120
+ '1h': '1h',
121
+ '2h': '2h',
122
+ '4h': '4h',
123
+ '12h': '12h',
124
+ '1d': '1d',
125
+ '3d': '3d',
126
+ '1w': '1w',
127
+ },
128
+ 'urls': {
129
+ 'logo': 'https://user-images.githubusercontent.com/1294454/104140087-a27f2580-53c0-11eb-87c1-5d9e81208fe9.jpg',
130
+ 'test': {
131
+ 'v1': 'https://api.testnet.{hostname}/marketdata/v1',
132
+ 'public': 'https://api.testnet.{hostname}',
133
+ 'private': 'https://api.testnet.{hostname}',
134
+ },
135
+ 'api': {
136
+ 'v1': 'https://api.{hostname}/marketdata/v1',
137
+ 'public': 'https://api.{hostname}',
138
+ 'private': 'https://api.{hostname}',
139
+ },
140
+ 'www': 'https://www.aaxpro.com', // string website URL
141
+ 'doc': 'https://www.aaxpro.com/apidoc/index.html',
142
+ 'fees': 'https://www.aaxpro.com/en-US/fees/',
143
+ 'referral': 'https://www.aaxpro.com/invite/sign-up?inviteCode=JXGm5Fy7R2MB',
144
+ },
145
+ 'api': {
146
+ 'v1': {
147
+ 'get': [
148
+ 'getHistMarketData', // Get OHLC k line of specific market
149
+ ],
150
+ },
151
+ 'public': {
152
+ // these endpoints are not documented
153
+ // 'get': [
154
+ // 'order_book', // Get the order book of specified market
155
+ // 'order_book/{market}',
156
+ // 'trades', // Get recent trades on market, each trade is included only once Trades are sorted in reverse creation order.
157
+ // 'trades/{market}',
158
+ // 'tickers', // Get ticker of all markets
159
+ // 'tickers/{market}', // Get ticker of specific market
160
+ // ],
161
+ 'get': {
162
+ 'currencies': 1.2,
163
+ 'announcement/maintenance': 1.2, // System Maintenance Notice
164
+ 'time': 1.2,
165
+ 'instruments': 1.2, // Retrieve all trading pairs information
166
+ 'market/orderbook': 1.2, // Order Book
167
+ 'futures/position/openInterest': 1.2, // Open Interest
168
+ 'market/tickers': 1.2, // Get the Last 24h Market Summary
169
+ 'market/candles': 1.2, // Get Current Candlestick
170
+ 'market/history/candles': 1.2, // Get Current Candlestick
171
+ 'market/trades': 1.2, // Get the Most Recent Trades
172
+ 'market/markPrice': 1.2, // Get Current Mark Price
173
+ 'futures/funding/predictedFunding/{symbol}': 1.2, // Get Predicted Funding Rate
174
+ 'futures/funding/prevFundingRate/{symbol}': 1.2, // Get Last Funding Rate
175
+ 'futures/funding/fundingRate': 1.2,
176
+ 'market/candles/index': 1.2, // * Deprecated
177
+ 'market/index/candles': 1.2,
178
+ },
179
+ },
180
+ 'private': {
181
+ 'get': {
182
+ 'user/info': 1.2, // Retrieve user information
183
+ 'account/balances': 1.2, // Get Account Balances
184
+ 'account/deposit/address': 1.2, // undocumented
185
+ 'account/deposits': 1.2, // Get account deposits history
186
+ 'account/transfer': 1.2,
187
+ 'account/withdraws': 1.2, // Get account withdrawals history
188
+ 'spot/trades': 1.2, // Retrieve trades details for a spot order
189
+ 'spot/openOrders': 1.2, // Retrieve spot open orders
190
+ 'spot/orders': 1.2, // Retrieve historical spot orders
191
+ 'futures/position': 1.2, // Get positions for all contracts
192
+ 'futures/position/closed': 1.2, // Get closed positions
193
+ 'futures/trades': 1.2, // Retrieve trade details for a futures order
194
+ 'futures/openOrders': 1.2, // Retrieve futures open orders
195
+ 'futures/orders': 1.2, // Retrieve historical futures orders
196
+ 'futures/funding/fundingFee': 1.2,
197
+ 'futures/funding/predictedFundingFee/{symbol}': 1.2, // Get predicted funding fee
198
+ },
199
+ 'post': {
200
+ 'account/transfer': 1.2, // Asset Transfer
201
+ 'spot/orders': 1.2, // Create a new spot order
202
+ 'spot/orders/cancelAllOnTimeout': 10, // Automatically cancel all your spot orders after a specified timeout.
203
+ 'futures/orders': 1.2, // Create a new futures order
204
+ 'futures/orders/cancelAllOnTimeout': 10, // Automatically cancel all your futures orders after a specified timeout.
205
+ 'futures/position/sltp': 1.2, // Set take profit and stop loss orders for an opening position
206
+ 'futures/position/close': 1.2, // Close position
207
+ 'futures/position/leverage': 30, // Update leverage for position
208
+ 'futures/position/margin': 1.2, // Modify Isolated Position Margin
209
+ },
210
+ 'put': {
211
+ 'spot/orders': 1.2, // Amend spot order
212
+ 'futures/orders': 1.2, // Amend the quantity of an open futures order
213
+ },
214
+ 'delete': {
215
+ 'spot/orders/cancel/{orderID}': 1, // Cancel a spot order
216
+ 'spot/orders/cancel/all': 10, // Batch cancel spot orders
217
+ 'futures/orders/cancel/{orderID}': 1, // Cancel a futures order
218
+ 'futures/orders/cancel/all': 10, // Batch cancel futures orders
219
+ },
220
+ },
221
+ },
222
+ 'fees': {
223
+ 'trading': {
224
+ 'tierBased': false,
225
+ 'percentage': true,
226
+ 'maker': this.parseNumber ('0.0006'),
227
+ 'taker': this.parseNumber ('0.001'),
228
+ },
229
+ 'funding': {
230
+ 'tierBased': false,
231
+ 'percentage': true,
232
+ 'withdraw': {}, // There is only 1% fee on withdrawals to your bank account.
233
+ },
234
+ },
235
+ 'commonCurrencies': {
236
+ 'XBT': 'XBT',
237
+ },
238
+ 'exceptions': {
239
+ 'exact': {
240
+ '2002': InsufficientFunds,
241
+ '2003': OrderNotFound,
242
+ '10003': BadRequest, // Parameter validation error
243
+ '10006': AuthenticationError, // Session expired, please relogin
244
+ '10007': AuthenticationError, // Invalid authentication key or token
245
+ '11007': AuthenticationError, // Invalid key format
246
+ '20001': InsufficientFunds, // Insufficient balance. Please deposit to trade.
247
+ '20009': InvalidOrder, // Order amount must be positive
248
+ '30000': OrderNotFound, // {"code":30000,"data":null,"message":"The order does not exist","ts":1610259732263}
249
+ '30001': InvalidOrder, // The order is being submitted, please try again later
250
+ '30004': InvalidOrder, // Minimum quantity is {0}
251
+ '30005': InvalidOrder, // Quantity maximum precision is {0} decimal places
252
+ '30006': InvalidOrder, // Price maximum precision is {0} decimal places
253
+ '30007': InvalidOrder, // Minimum price is {0}
254
+ '30008': InvalidOrder, // Stop price maximum precision is {0} decimal places
255
+ '30009': InvalidOrder, // Stop Price cannot be less than {0}
256
+ '30010': InvalidOrder, // Market price cannot be empty
257
+ '30011': CancelPending, // The order is being cancelled, please wait.
258
+ '30012': BadRequest, // Unknown currency
259
+ '30013': BadSymbol, // Unknown symbol
260
+ '30014': OrderNotFound, // Futures order cannot be found
261
+ '30015': InvalidOrder, // This is not an open order and cannot modified
262
+ '30016': ExchangeError, // No position found
263
+ '30017': InvalidOrder, // The current close position is 0. It is recommended that you cancel the current order closing order.
264
+ '30018': InvalidOrder, // Order price cannot be greater than {0}
265
+ '30019': InvalidOrder, // Order quantity cannot be greater than {0}
266
+ '30020': InvalidOrder, // Order price must be a multiple of {0}
267
+ '30021': InvalidOrder, // Margin adjustement must be greater than 0
268
+ '30022': InvalidOrder, // New quantity must be greater than filled quantity
269
+ '30023': InvalidOrder, // Order failed, please try again
270
+ '30024': InvalidOrder, // TimeInForce error, only GTC or IOC are allowed
271
+ '30025': InvalidOrder, // TimeInForce error, only GTC is allowed
272
+ '30026': InvalidOrder, // Quantity is not a multiple of {0}
273
+ '30027': InvalidOrder, // Close position failed, it is recommended that you cancel the current order and then close the position.
274
+ '30028': BadSymbol, // Symbol cannot be traded at this time
275
+ '30029': InvalidOrder, // Modified quantity or price cannot be empty
276
+ '30030': InvalidOrder, // Price cannot be specified for market orders
277
+ '30031': InvalidOrder, // Liquidation orders cannot be modified
278
+ '30032': InvalidOrder, // Leverage cannot be greater than {0}
279
+ '30033': InvalidOrder, // Leverage cannot be smaller than {0}
280
+ '30034': RateLimitExceeded, // The max number of open orders is {0}. To place a new order, please cancel a previous one
281
+ '30035': RateLimitExceeded, // The max number of {0} open orders is {1}. To place a new order, please cancel a previous one
282
+ '30036': ExchangeNotAvailable, // Liquidation is in progress, please try again later
283
+ '30037': InvalidOrder, // Once stop limit order triggered, stop price cannot be amended
284
+ '30038': ExchangeError, // The total value of your orders has exceeded the current risk limit. Please adjust the risk limit
285
+ '30039': InsufficientFunds, // Your risk limit has now been changed to {0}, your maximum leverage less than 1, please readjust accordingly
286
+ '30040': InvalidOrder, // Order status has changed, please try again later
287
+ '30041': InvalidOrder, // Liquidation orders cannot be cancelled
288
+ '30042': InvalidOrder, // Order cannot be placed as you will be breaching you max limit value of {1} BTC for {0}
289
+ '30043': InvalidOrder, // The risk limit cannot be less than 0
290
+ '30044': BadRequest, // Timeout cannot be greater than 60 minutes
291
+ '30045': InvalidOrder, // Side is not valid, it should be BUY or SELL
292
+ '30046': InvalidOrder, // Order type is not valid, it should be MARKET or LIMIT or STOP-LIMIT or STOP
293
+ '30047': InvalidOrder, // The order is closed. Can't cancel
294
+ '30048': InvalidOrder, // Market orders cannot be modified
295
+ '30049': InvalidOrder, // The order is being modified, please wait
296
+ '30050': InvalidOrder, // Maximum 10 orders
297
+ '40004': BadRequest, // Requested resource doesn't exist
298
+ '40009': RateLimitExceeded, // Too many requests
299
+ '40102': AuthenticationError, // {"code":40102,"message":"Unauthorized(invalid key)"}
300
+ '40103': AuthenticationError, // {"code":40103,"message":"Unauthorized(invalid sign)"}
301
+ '40303': PermissionDenied, // {"code":40303,"message":"Forbidden(invalid scopes)"}
302
+ '41001': BadRequest, // Incorrect HTTP request
303
+ '41002': BadRequest, // Unsupported HTTP request method
304
+ '42001': ExchangeNotAvailable, // Duplicated data entry, please check and try again
305
+ '50001': ExchangeError, // Server side exception, please try again later
306
+ '50002': ExchangeError, // Server is busy, please try again later
307
+ },
308
+ 'broad': {},
309
+ },
310
+ 'precisionMode': TICK_SIZE,
311
+ 'options': {
312
+ 'defaultType': 'spot', // 'spot', 'future'
313
+ 'accountsByType': {
314
+ 'spot': 'SPTP',
315
+ 'future': 'FUTP',
316
+ 'otc': 'F2CP',
317
+ 'saving': 'VLTP',
318
+ },
319
+ 'networks': {
320
+ 'ETH': 'ERC20',
321
+ 'TRX': 'TRC20',
322
+ 'SOL': 'SPL',
323
+ },
324
+ 'transfer': {
325
+ 'fillResponseFromRequest': true,
326
+ },
327
+ },
328
+ });
329
+ }
330
+
331
+ async fetchTime (params = {}) {
332
+ const response = await this.publicGetTime (params);
333
+ //
334
+ // {
335
+ // "code": 1,
336
+ // "data": 1573542445411, // unit: millisecond
337
+ // "message": "success",
338
+ // "ts": 1573542445411
339
+ // }
340
+ //
341
+ return this.safeInteger (response, 'data');
342
+ }
343
+
344
+ async fetchStatus (params = {}) {
345
+ const response = await this.publicGetAnnouncementMaintenance (params);
346
+ //
347
+ // note, when there is no maintenance, then data is `null`
348
+ //
349
+ // {
350
+ // "code": 1,
351
+ // "data": {
352
+ // "startTime":"2020-06-25T02:15:00.000Z",
353
+ // "endTime":"2020-06-25T02:45:00.000Z",
354
+ // "description":"Spot Trading :UTC Jun 25, 2020 02:15 to 02:45 (HKT Jun 25 10:15 to 10:45),Futures Trading: UTC Jun 25, 2020 02:15 to 02:45 (HKT Jun 25 10:15 to 10:45).We apologize for any inconvenience caused. Thank you for your patience and understanding.Should you have any enquiries, please do not hesitate our live chat support or via email at cs@aax.com.",
355
+ // "haltReason":1,
356
+ // "systemStatus":{
357
+ // "spotTrading":"readOnly",
358
+ // "futuresTreading":"closeOnly",
359
+ // "walletOperating":"enable",
360
+ // "otcTrading":"disable"
361
+ // },
362
+ // },
363
+ // "message":"success",
364
+ // "ts":1593043237000
365
+ // }
366
+ //
367
+ const timestamp = this.milliseconds ();
368
+ const updated = this.safeInteger (response, 'ts', timestamp);
369
+ const data = this.safeValue (response, 'data', {});
370
+ let status = undefined;
371
+ let eta = undefined;
372
+ if (data) {
373
+ const startTime = this.parse8601 (this.safeString (data, 'startTime'));
374
+ const endTime = this.parse8601 (this.safeString (data, 'endTime'));
375
+ if (endTime !== undefined) {
376
+ const startTimeIsOk = (startTime === undefined) ? true : (updated < startTime);
377
+ const isOk = (updated > endTime) || startTimeIsOk;
378
+ eta = endTime;
379
+ status = isOk ? 'ok' : 'maintenance';
380
+ } else {
381
+ status = data;
382
+ }
383
+ } else {
384
+ eta = undefined;
385
+ status = 'ok';
386
+ }
387
+ return {
388
+ 'status': status,
389
+ 'updated': updated,
390
+ 'eta': eta,
391
+ 'url': undefined,
392
+ 'info': response,
393
+ };
394
+ }
395
+
396
+ async fetchMarkets (params = {}) {
397
+ const response = await this.publicGetInstruments (params);
398
+ //
399
+ // {
400
+ // "code":1,
401
+ // "message":"success",
402
+ // "ts":1610159448962,
403
+ // "data":[
404
+ // {
405
+ // "tickSize":"0.01",
406
+ // "lotSize":"1",
407
+ // "base":"BTC",
408
+ // "quote":"USDT",
409
+ // "minQuantity":"1.0000000000",
410
+ // "maxQuantity":"30000",
411
+ // "minPrice":"0.0100000000",
412
+ // "maxPrice":"999999.0000000000",
413
+ // "status":"readOnly",
414
+ // "symbol":"BTCUSDTFP",
415
+ // "code":"FP",
416
+ // "takerFee":"0.00040",
417
+ // "makerFee":"0.00020",
418
+ // "multiplier":"0.001000000000",
419
+ // "mmRate":"0.00500",
420
+ // "imRate":"0.01000",
421
+ // "type":"futures",
422
+ // "settleType":"Vanilla",
423
+ // "settleCurrency":"USDT"
424
+ // },
425
+ // {
426
+ // "tickSize":"0.5",
427
+ // "lotSize":"10",
428
+ // "base":"BTC",
429
+ // "quote":"USD",
430
+ // "minQuantity":"10.0000000000",
431
+ // "maxQuantity":"300000",
432
+ // "minPrice":"0.5000000000",
433
+ // "maxPrice":"999999.0000000000",
434
+ // "status":"readOnly",
435
+ // "symbol":"BTCUSDFP",
436
+ // "code":"FP",
437
+ // "takerFee":"0.00040",
438
+ // "makerFee":"0.00020",
439
+ // "multiplier":"1.000000000000",
440
+ // "mmRate":"0.00500",
441
+ // "imRate":"0.01000",
442
+ // "type":"futures",
443
+ // "settleType":"Inverse",
444
+ // "settleCurrency":"BTC"
445
+ // },
446
+ // {
447
+ // "tickSize":"0.0001",
448
+ // "lotSize":"0.01",
449
+ // "base":"AAB",
450
+ // "quote":"USDT",
451
+ // "minQuantity":"5.0000000000",
452
+ // "maxQuantity":"50000.0000000000",
453
+ // "minPrice":"0.0001000000",
454
+ // "maxPrice":"999999.0000000000",
455
+ // "status":"readOnly",
456
+ // "symbol":"AABUSDT",
457
+ // "code":null,
458
+ // "takerFee":"0.00100",
459
+ // "makerFee":"0.00100",
460
+ // "multiplier":"1.000000000000",
461
+ // "mmRate":"0.02500",
462
+ // "imRate":"0.05000",
463
+ // "type":"spot",
464
+ // "settleType":null,
465
+ // "settleCurrency":null
466
+ // },
467
+ // ]
468
+ // }
469
+ //
470
+ const data = this.safeValue (response, 'data');
471
+ const result = [];
472
+ for (let i = 0; i < data.length; i++) {
473
+ const market = data[i];
474
+ const id = this.safeString (market, 'symbol');
475
+ const baseId = this.safeString (market, 'base');
476
+ const quoteId = this.safeString (market, 'quote');
477
+ const settleId = this.safeString (market, 'settleCurrency');
478
+ const base = this.safeCurrencyCode (baseId);
479
+ const quote = this.safeCurrencyCode (quoteId);
480
+ const settle = this.safeCurrencyCode (settleId);
481
+ const status = this.safeString (market, 'status');
482
+ const marketType = this.safeString (market, 'type');
483
+ let inverse = undefined;
484
+ let linear = undefined;
485
+ let quanto = undefined;
486
+ const spot = (marketType === 'spot');
487
+ const swap = (marketType === 'futures');
488
+ const settleType = this.safeStringLower (market, 'settleType');
489
+ if (settleType !== undefined) {
490
+ inverse = (settleType === 'inverse');
491
+ linear = (settleType === 'vanilla');
492
+ quanto = (settleType === 'quanto');
493
+ }
494
+ let symbol = base + '/' + quote;
495
+ let type = 'spot';
496
+ let contractSize = undefined;
497
+ if (swap) {
498
+ symbol = symbol + ':' + settle;
499
+ type = 'swap';
500
+ contractSize = this.safeNumber (market, 'multiplier');
501
+ }
502
+ result.push ({
503
+ 'id': id,
504
+ 'symbol': symbol,
505
+ 'base': base,
506
+ 'quote': quote,
507
+ 'settle': settle,
508
+ 'baseId': baseId,
509
+ 'quoteId': quoteId,
510
+ 'settleId': settleId,
511
+ 'type': type,
512
+ 'spot': spot,
513
+ 'margin': false,
514
+ 'swap': swap,
515
+ 'future': false,
516
+ 'option': false,
517
+ 'active': (status === 'enable'),
518
+ 'contract': swap,
519
+ 'linear': linear,
520
+ 'inverse': inverse,
521
+ 'taker': this.safeNumber (market, 'takerFee'),
522
+ 'maker': this.safeNumber (market, 'makerFee'),
523
+ 'contractSize': contractSize,
524
+ 'expiry': undefined,
525
+ 'expiryDatetime': undefined,
526
+ 'strike': undefined,
527
+ 'optionType': undefined,
528
+ 'quanto': quanto,
529
+ 'precision': {
530
+ 'amount': this.safeNumber (market, 'lotSize'),
531
+ 'price': this.safeNumber (market, 'tickSize'),
532
+ },
533
+ 'limits': {
534
+ 'leverage': {
535
+ 'min': undefined,
536
+ 'max': undefined,
537
+ },
538
+ 'amount': {
539
+ 'min': this.safeString (market, 'minQuantity'),
540
+ 'max': this.safeString (market, 'maxQuantity'),
541
+ },
542
+ 'price': {
543
+ 'min': this.safeString (market, 'minPrice'),
544
+ 'max': this.safeString (market, 'maxPrice'),
545
+ },
546
+ 'cost': {
547
+ 'min': undefined,
548
+ 'max': undefined,
549
+ },
550
+ },
551
+ 'info': market,
552
+ });
553
+ }
554
+ return result;
555
+ }
556
+
557
+ async fetchCurrencies (params = {}) {
558
+ const response = await this.publicGetCurrencies (params);
559
+ //
560
+ // {
561
+ // "code":1,
562
+ // "data":[
563
+ // {
564
+ // "chain":"BTC",
565
+ // "displayName":"Bitcoin",
566
+ // "withdrawFee":"0.0004",
567
+ // "withdrawMin":"0.001",
568
+ // "otcFee":"0",
569
+ // "enableOTC":true,
570
+ // "visible":true,
571
+ // "enableTransfer":true,
572
+ // "transferMin":"0.00001",
573
+ // "depositMin":"0.0005",
574
+ // "enableWithdraw":true,
575
+ // "enableDeposit":true,
576
+ // "addrWithMemo":false,
577
+ // "withdrawPrecision":"0.00000001",
578
+ // "currency":"BTC",
579
+ // "network":"BTC", // ETH, ERC20, TRX, TRC20, OMNI, LTC, XRP, XLM, ...
580
+ // "minConfirm":"2"
581
+ // },
582
+ // ],
583
+ // "message":"success",
584
+ // "ts":1624330530697
585
+ // }
586
+ //
587
+ const result = {};
588
+ const data = this.safeValue (response, 'data', []);
589
+ for (let i = 0; i < data.length; i++) {
590
+ const currency = data[i];
591
+ const id = this.safeString (currency, 'chain');
592
+ const name = this.safeString (currency, 'displayName');
593
+ const code = this.safeCurrencyCode (id);
594
+ const precision = this.safeNumber (currency, 'withdrawPrecision');
595
+ const enableWithdraw = this.safeValue (currency, 'enableWithdraw');
596
+ const enableDeposit = this.safeValue (currency, 'enableDeposit');
597
+ const fee = this.safeNumber (currency, 'withdrawFee');
598
+ const visible = this.safeValue (currency, 'visible');
599
+ const active = (enableWithdraw && enableDeposit && visible);
600
+ const deposit = (enableDeposit && visible);
601
+ const withdraw = (enableWithdraw && visible);
602
+ const network = this.safeString (currency, 'network');
603
+ result[code] = {
604
+ 'id': id,
605
+ 'name': name,
606
+ 'code': code,
607
+ 'precision': precision,
608
+ 'info': currency,
609
+ 'active': active,
610
+ 'deposit': deposit,
611
+ 'withdraw': withdraw,
612
+ 'fee': fee,
613
+ 'network': network,
614
+ 'limits': {
615
+ 'deposit': {
616
+ 'min': this.safeNumber (currency, 'depositMin'),
617
+ 'max': undefined,
618
+ },
619
+ 'withdraw': {
620
+ 'min': this.safeNumber (currency, 'withdrawMin'),
621
+ 'max': undefined,
622
+ },
623
+ },
624
+ };
625
+ }
626
+ return result;
627
+ }
628
+
629
+ parseTicker (ticker, market = undefined) {
630
+ //
631
+ // {
632
+ // "t":1610162685342, // timestamp
633
+ // "a":"0.00000000", // trading volume in USD in the last 24 hours, futures only
634
+ // "c":"435.20000000", // close
635
+ // "d":"4.22953489", // change
636
+ // "h":"455.04000000", // high
637
+ // "l":"412.78000000", // low
638
+ // "o":"417.54000000", // open
639
+ // "s":"BCHUSDTFP", // market id
640
+ // "v":"2031068.00000000", // trading volume in quote currency of last 24 hours
641
+ // }
642
+ //
643
+ const timestamp = this.safeInteger (ticker, 't');
644
+ const marketId = this.safeString (ticker, 's');
645
+ const symbol = this.safeSymbol (marketId, market);
646
+ const last = this.safeString (ticker, 'c');
647
+ const open = this.safeString (ticker, 'o');
648
+ const quoteVolume = this.safeString (ticker, 'v');
649
+ return this.safeTicker ({
650
+ 'symbol': symbol,
651
+ 'timestamp': timestamp,
652
+ 'datetime': undefined,
653
+ 'high': this.safeString (ticker, 'h'),
654
+ 'low': this.safeString (ticker, 'l'),
655
+ 'bid': undefined,
656
+ 'bidVolume': undefined,
657
+ 'ask': undefined,
658
+ 'askVolume': undefined,
659
+ 'vwap': undefined,
660
+ 'open': open,
661
+ 'close': last,
662
+ 'last': last,
663
+ 'previousClose': undefined,
664
+ 'change': undefined,
665
+ 'percentage': undefined,
666
+ 'average': undefined,
667
+ 'baseVolume': undefined,
668
+ 'quoteVolume': quoteVolume,
669
+ 'info': ticker,
670
+ }, market, false);
671
+ }
672
+
673
+ async fetchTickers (symbols = undefined, params = {}) {
674
+ await this.loadMarkets ();
675
+ const response = await this.publicGetMarketTickers (params);
676
+ //
677
+ // {
678
+ // "e":"tickers",
679
+ // "t":1610162685342,
680
+ // "tickers":[
681
+ // {
682
+ // "a":"0.00000000",
683
+ // "c":"435.20000000",
684
+ // "d":"4.22953489",
685
+ // "h":"455.04000000",
686
+ // "l":"412.78000000",
687
+ // "o":"417.54000000",
688
+ // "s":"BCHUSDTFP",
689
+ // "v":"2031068.00000000",
690
+ // },
691
+ // ],
692
+ // }
693
+ //
694
+ const tickers = this.safeValue (response, 'tickers', []);
695
+ const result = [];
696
+ const timestamp = this.safeInteger (response, 't');
697
+ for (let i = 0; i < tickers.length; i++) {
698
+ const ticker = this.parseTicker (this.extend (tickers[i], { 't': timestamp }));
699
+ result.push (ticker);
700
+ }
701
+ return this.filterByArray (result, 'symbol', symbols);
702
+ }
703
+
704
+ async fetchOrderBook (symbol, limit = undefined, params = {}) {
705
+ await this.loadMarkets ();
706
+ const market = this.market (symbol);
707
+ if (limit === undefined) {
708
+ limit = 20;
709
+ } else {
710
+ if ((limit !== 20) && (limit !== 50)) {
711
+ throw new BadRequest (this.id + ' fetchOrderBook() limit argument must be undefined, 20 or 50');
712
+ }
713
+ }
714
+ const request = {
715
+ 'symbol': market['id'],
716
+ 'level': limit, // required
717
+ };
718
+ //
719
+ const response = await this.publicGetMarketOrderbook (this.extend (request, params));
720
+ //
721
+ // {
722
+ // "asks":[
723
+ // ["10823.00000000","0.004000"],
724
+ // ["10823.10000000","0.100000"],
725
+ // ["10823.20000000","0.010000"]
726
+ // ],
727
+ // "bids":[
728
+ // ["10821.20000000","0.002000"],
729
+ // ["10821.10000000","0.005000"],
730
+ // ["10820.40000000","0.013000"]
731
+ // ],
732
+ // "e":"BTCUSDT@book_50",
733
+ // "t":1561543614756
734
+ // }
735
+ //
736
+ const timestamp = this.safeInteger (response, 't'); // need unix type
737
+ return this.parseOrderBook (response, symbol, timestamp);
738
+ }
739
+
740
+ parseTrade (trade, market = undefined) {
741
+ //
742
+ // public fetchTrades
743
+ //
744
+ // {
745
+ // "i":"T1qzQeZG9g",
746
+ // "p":"-61348.81000000",
747
+ // "q":"0.045400",
748
+ // "s":"sell",
749
+ // "t":1635731102731
750
+ // }
751
+ //
752
+ // private fetchMyTrades
753
+ //
754
+ // {
755
+ // "avgPrice":"1199.8",
756
+ // "base":"ETH",
757
+ // "clOrdID":null,
758
+ // "commission":"0.00002",
759
+ // "createTime":"2021-01-11T02:47:51.512Z",
760
+ // "cumQty":"0.02",
761
+ // "filledOrderID":"1eUD4F5rwK",
762
+ // "filledPrice":"1199.8",
763
+ // "filledQty":"0.02",
764
+ // "leavesQty":"0",
765
+ // "oCreateTime":"2021-01-11T02:47:51.377Z",
766
+ // "orderID":"1eUD4EHfdU",
767
+ // "orderQty":"0.02",
768
+ // "orderStatus":3,
769
+ // "orderType":1,
770
+ // "price":"1198.25",
771
+ // "quote":"USDT",
772
+ // "rejectCode":null,
773
+ // "rejectReason":null,
774
+ // "side":1,
775
+ // "stopPrice":"0",
776
+ // "symbol":"ETHUSDT",
777
+ // "taker":true,
778
+ // "tradeID":"E04WTIgfmULU",
779
+ // "transactTime":"2021-01-11T02:47:51.389Z",
780
+ // "updateTime":null,
781
+ // "userID":"1362494"
782
+ // }
783
+ //
784
+ let timestamp = this.safeInteger (trade, 't');
785
+ if (timestamp === undefined) {
786
+ timestamp = this.parse8601 (this.safeString (trade, 'createTime'));
787
+ }
788
+ let id = this.safeString2 (trade, 'tid', 'tradeID');
789
+ id = this.safeString (trade, 'i', id);
790
+ const marketId = this.safeString (trade, 'symbol');
791
+ market = this.safeMarket (marketId, market);
792
+ let priceString = this.safeString2 (trade, 'p', 'filledPrice');
793
+ const amountString = this.safeString2 (trade, 'q', 'filledQty');
794
+ const orderId = this.safeString (trade, 'orderID');
795
+ const isTaker = this.safeValue (trade, 'taker');
796
+ let takerOrMaker = undefined;
797
+ if (isTaker !== undefined) {
798
+ takerOrMaker = isTaker ? 'taker' : 'maker';
799
+ }
800
+ let side = this.safeString (trade, 'side');
801
+ if (side === '1') {
802
+ side = 'buy';
803
+ } else if (side === '2') {
804
+ side = 'sell';
805
+ }
806
+ if (side === undefined) {
807
+ side = (priceString[0] === '-') ? 'sell' : 'buy';
808
+ }
809
+ priceString = Precise.stringAbs (priceString);
810
+ const orderType = this.parseOrderType (this.safeString (trade, 'orderType'));
811
+ let fee = undefined;
812
+ const feeCost = this.safeString (trade, 'commission');
813
+ if (feeCost !== undefined) {
814
+ let feeCurrency = undefined;
815
+ if (side === 'buy') {
816
+ feeCurrency = market['base'];
817
+ } else if (side === 'sell') {
818
+ feeCurrency = market['quote'];
819
+ }
820
+ fee = {
821
+ 'currency': feeCurrency,
822
+ 'cost': feeCost,
823
+ };
824
+ }
825
+ return this.safeTrade ({
826
+ 'info': trade,
827
+ 'id': id,
828
+ 'timestamp': timestamp,
829
+ 'datetime': this.iso8601 (timestamp),
830
+ 'symbol': market['symbol'],
831
+ 'type': orderType,
832
+ 'side': side,
833
+ 'order': orderId,
834
+ 'takerOrMaker': takerOrMaker,
835
+ 'price': priceString,
836
+ 'amount': amountString,
837
+ 'cost': undefined,
838
+ 'fee': fee,
839
+ }, market);
840
+ }
841
+
842
+ async fetchTransfers (code = undefined, since = undefined, limit = undefined, params = {}) {
843
+ await this.loadMarkets ();
844
+ let currency = undefined;
845
+ const request = {};
846
+ if (code !== undefined) {
847
+ currency = this.currency (code);
848
+ request['currency'] = currency['id'];
849
+ }
850
+ if (since !== undefined) {
851
+ request['startTime'] = since;
852
+ }
853
+ const response = await this.privateGetAccountTransfer (this.extend (request, params));
854
+ //
855
+ // {
856
+ // code: '1',
857
+ // data: [{
858
+ // quantity: '0.000010000000',
859
+ // transferID: '480975741034369024',
860
+ // transferTime: '2022-03-24T13:53:07.042Z',
861
+ // fromPurse: 'VLTP',
862
+ // toPurse: 'SPTP',
863
+ // currency: 'ETH'
864
+ // },
865
+ // ],
866
+ // message: 'success',
867
+ // ts: '1648338516932'
868
+ // }
869
+ //
870
+ const transfers = this.safeValue (response, 'data', []);
871
+ return this.parseTransfers (transfers, currency, since, limit);
872
+ }
873
+
874
+ async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
875
+ await this.loadMarkets ();
876
+ const market = this.market (symbol);
877
+ limit = (limit === undefined) ? 2000 : limit;
878
+ limit = Math.min (limit, 2000);
879
+ const request = {
880
+ 'symbol': market['id'],
881
+ 'limit': limit,
882
+ };
883
+ const response = await this.publicGetMarketTrades (request);
884
+ //
885
+ // {
886
+ // "e":"BTCUSDT@trades",
887
+ // "trades":[
888
+ // {"i":"T1qzQeZG9g","p":"-61348.81000000","q":"0.045400","s":"sell","t":1635731102731},
889
+ // {"i":"T1qzQeU6UK","p":"61343.10000000","q":"0.179300","s":"buy","t":1635731102133},
890
+ // {"i":"T1qzQe5BQm","p":"-61346.02000000","q":"0.021100","s":"sell","t":1635731099231},
891
+ // ]
892
+ // }
893
+ //
894
+ const trades = this.safeValue (response, 'trades', []);
895
+ return this.parseTrades (trades, market, since, limit);
896
+ }
897
+
898
+ parseOHLCV (ohlcv, market = undefined) {
899
+ //
900
+ // [
901
+ // 0.042398, // 0 open
902
+ // 0.042684, // 1 high
903
+ // 0.042366, // 2 low
904
+ // 0.042386, // 3 close
905
+ // 0.93734243, // 4 volume
906
+ // 1611514800, // 5 timestamp
907
+ // ]
908
+ //
909
+ return [
910
+ this.safeTimestamp (ohlcv, 5),
911
+ this.safeNumber (ohlcv, 0),
912
+ this.safeNumber (ohlcv, 1),
913
+ this.safeNumber (ohlcv, 2),
914
+ this.safeNumber (ohlcv, 3),
915
+ this.safeNumber (ohlcv, 4),
916
+ ];
917
+ }
918
+
919
+ async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
920
+ await this.loadMarkets ();
921
+ const market = this.market (symbol);
922
+ const request = {
923
+ // 'limit': limit, // if set counts from now into the past
924
+ 'symbol': market['id'],
925
+ 'timeFrame': this.timeframes[timeframe],
926
+ };
927
+ limit = (limit === undefined) ? 500 : limit;
928
+ const duration = this.parseTimeframe (timeframe);
929
+ if (since === undefined) {
930
+ const end = this.seconds ();
931
+ request['start'] = end - duration * limit;
932
+ request['end'] = end;
933
+ } else {
934
+ const start = parseInt (since / 1000);
935
+ request['start'] = start;
936
+ request['end'] = this.sum (start, duration * limit);
937
+ }
938
+ const response = await this.publicGetMarketHistoryCandles (this.extend (request, params));
939
+ //
940
+ // {
941
+ // "data":[
942
+ // [0.042398,0.042684,0.042366,0.042386,0.93734243,1611514800],
943
+ // [0.042386,0.042602,0.042234,0.042373,1.01925239,1611518400],
944
+ // [0.042373,0.042558,0.042362,0.042389,0.93801705,1611522000],
945
+ // ],
946
+ // "success":true,
947
+ // "t":1611875157
948
+ // }
949
+ //
950
+ const data = this.safeValue (response, 'data', []);
951
+ return this.parseOHLCVs (data, market, timeframe, since, limit);
952
+ }
953
+
954
+ async fetchBalance (params = {}) {
955
+ await this.loadMarkets ();
956
+ const defaultType = this.safeString2 (this.options, 'fetchBalance', 'defaultType', 'spot');
957
+ const type = this.safeString (params, 'type', defaultType);
958
+ const types = this.safeValue (this.options, 'accountsByType', {});
959
+ const purseType = this.safeString (types, type, type);
960
+ const request = {
961
+ 'purseType': purseType,
962
+ };
963
+ params = this.omit (params, 'type');
964
+ const response = await this.privateGetAccountBalances (this.extend (request, params));
965
+ //
966
+ // {
967
+ // "code":1,
968
+ // "data":[
969
+ // {
970
+ // "purseType":"FUTP",
971
+ // "currency":"BTC",
972
+ // "available":"0.41000000",
973
+ // "unavailable":"0.00000000"
974
+ // },
975
+ // {
976
+ // "purseType":"FUTP",
977
+ // "currency":"USDT",
978
+ // "available":"0.21000000",
979
+ // "unvaliable":"0.00000000"
980
+ // }
981
+ // ]
982
+ // "message":"success",
983
+ // "ts":1573530401020
984
+ // }
985
+ //
986
+ const data = this.safeValue (response, 'data');
987
+ const timestamp = this.safeInteger (response, 'ts');
988
+ const result = {
989
+ 'info': response,
990
+ 'timestamp': timestamp,
991
+ 'datetime': this.iso8601 (timestamp),
992
+ };
993
+ for (let i = 0; i < data.length; i++) {
994
+ const balance = data[i];
995
+ const balanceType = this.safeString (balance, 'purseType');
996
+ if (balanceType === purseType) {
997
+ const currencyId = this.safeString (balance, 'currency');
998
+ const code = this.safeCurrencyCode (currencyId);
999
+ const account = this.account ();
1000
+ account['free'] = this.safeString (balance, 'available');
1001
+ account['used'] = this.safeString (balance, 'unavailable');
1002
+ result[code] = account;
1003
+ }
1004
+ }
1005
+ return this.safeBalance (result);
1006
+ }
1007
+
1008
+ async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
1009
+ let orderType = type.toUpperCase ();
1010
+ const orderSide = side.toUpperCase ();
1011
+ await this.loadMarkets ();
1012
+ const market = this.market (symbol);
1013
+ const request = {
1014
+ // 'orderType': orderType, // MARKET, LIMIT, STOP, STOP-LIMIT
1015
+ 'symbol': market['id'],
1016
+ 'orderQty': this.amountToPrecision (symbol, amount),
1017
+ 'side': orderSide,
1018
+ // 'stopPrice': this.priceToPrecision (symbol, stopPrice),
1019
+ // 'clOrdID': clientOrderId, // up to 20 chars, lowercase and uppercase letters only
1020
+ // 'timeInForce': 'GTC', // GTC, IOC, FOK, default is GTC
1021
+ // 'execInst': 'Post-Only', // the only value supported by the exchange, futures and spot
1022
+ };
1023
+ const clientOrderId = this.safeString2 (params, 'clOrdID', 'clientOrderId');
1024
+ if (clientOrderId !== undefined) {
1025
+ request['clOrdID'] = clientOrderId;
1026
+ }
1027
+ const postOnly = this.safeValue (params, 'postOnly', false);
1028
+ if (postOnly !== undefined) {
1029
+ request['execInst'] = 'Post-Only';
1030
+ }
1031
+ params = this.omit (params, [ 'clOrdID', 'clientOrderId', 'postOnly' ]);
1032
+ const stopPrice = this.safeNumber (params, 'stopPrice');
1033
+ if (stopPrice === undefined) {
1034
+ if ((orderType === 'STOP-LIMIT') || (orderType === 'STOP')) {
1035
+ throw new ArgumentsRequired (this.id + ' createOrder() requires a stopPrice parameter for ' + orderType + ' orders');
1036
+ }
1037
+ } else {
1038
+ if (orderType === 'LIMIT') {
1039
+ orderType = 'STOP-LIMIT';
1040
+ } else if (orderType === 'MARKET') {
1041
+ orderType = 'STOP';
1042
+ }
1043
+ request['stopPrice'] = this.priceToPrecision (symbol, stopPrice);
1044
+ params = this.omit (params, 'stopPrice');
1045
+ }
1046
+ if (orderType === 'LIMIT' || orderType === 'STOP-LIMIT') {
1047
+ request['price'] = this.priceToPrecision (symbol, price);
1048
+ }
1049
+ request['orderType'] = orderType;
1050
+ let method = undefined;
1051
+ if (market['spot']) {
1052
+ method = 'privatePostSpotOrders';
1053
+ } else if (market['contract']) {
1054
+ method = 'privatePostFuturesOrders';
1055
+ }
1056
+ const response = await this[method] (this.extend (request, params));
1057
+ //
1058
+ // spot
1059
+ //
1060
+ // {
1061
+ // "code":1,
1062
+ // "data":{
1063
+ // "symbol":"ETHUSDT",
1064
+ // "orderType":2,
1065
+ // "avgPrice":"0",
1066
+ // "execInst":null,
1067
+ // "orderStatus":0,
1068
+ // "userID":"1362494",
1069
+ // "quote":"USDT",
1070
+ // "rejectReason":null,
1071
+ // "rejectCode":null,
1072
+ // "price":"1500",
1073
+ // "orderQty":"1",
1074
+ // "commission":"0",
1075
+ // "id":"268323430253735936",
1076
+ // "timeInForce":1,
1077
+ // "isTriggered":false,
1078
+ // "side":2,
1079
+ // "orderID":"1eO51MDSpQ",
1080
+ // "leavesQty":"0",
1081
+ // "cumQty":"0",
1082
+ // "updateTime":null,
1083
+ // "lastQty":"0",
1084
+ // "clOrdID":null,
1085
+ // "stopPrice":null,
1086
+ // "createTime":null,
1087
+ // "transactTime":null,
1088
+ // "base":"ETH",
1089
+ // "lastPrice":"0"
1090
+ // },
1091
+ // "message":"success",
1092
+ // "ts":1610245290980
1093
+ // }
1094
+ //
1095
+ // futures
1096
+ //
1097
+ // {
1098
+ // "code":1,
1099
+ // "data":{
1100
+ // "liqType":0,
1101
+ // "symbol":"ETHUSDTFP",
1102
+ // "orderType":2,
1103
+ // "leverage":"1",
1104
+ // "marketPrice":"1318.3150000000",
1105
+ // "code":"FP",
1106
+ // "avgPrice":"0",
1107
+ // "execInst":null,
1108
+ // "orderStatus":0,
1109
+ // "userID":"1362494",
1110
+ // "quote":"USDT",
1111
+ // "rejectReason":null,
1112
+ // "rejectCode":null,
1113
+ // "price":"500",
1114
+ // "orderQty":"1",
1115
+ // "commission":"0",
1116
+ // "id":"268346885133053953",
1117
+ // "timeInForce":1,
1118
+ // "isTriggered":false,
1119
+ // "side":1,
1120
+ // "orderID":"1eOuPUAAkq",
1121
+ // "leavesQty":"1",
1122
+ // "cumQty":"0",
1123
+ // "updateTime":null,
1124
+ // "lastQty":null,
1125
+ // "clOrdID":null,
1126
+ // "stopPrice":null,
1127
+ // "createTime":null,
1128
+ // "transactTime":null,
1129
+ // "settleType":"VANILLA",
1130
+ // "base":"ETH",
1131
+ // "lastPrice":"0"
1132
+ // },
1133
+ // "message":"success",
1134
+ // "ts":1610250883059
1135
+ // }
1136
+ //
1137
+ const data = this.safeValue (response, 'data', {});
1138
+ return this.parseOrder (data, market);
1139
+ }
1140
+
1141
+ async editOrder (id, symbol, type, side, amount, price = undefined, params = {}) {
1142
+ await this.loadMarkets ();
1143
+ const market = this.market (symbol);
1144
+ const request = {
1145
+ 'orderID': id,
1146
+ // 'orderQty': this.amountToPrecision (symbol, amount),
1147
+ // 'price': this.priceToPrecision (symbol, price),
1148
+ // 'stopPrice': this.priceToPrecision (symbol, stopPrice),
1149
+ };
1150
+ const stopPrice = this.safeNumber (params, 'stopPrice');
1151
+ if (stopPrice !== undefined) {
1152
+ request['stopPrice'] = this.priceToPrecision (symbol, stopPrice);
1153
+ params = this.omit (params, 'stopPrice');
1154
+ }
1155
+ if (price !== undefined) {
1156
+ request['price'] = this.priceToPrecision (symbol, price);
1157
+ }
1158
+ if (amount !== undefined) {
1159
+ request['orderQty'] = this.amountToPrecision (symbol, amount);
1160
+ }
1161
+ let method = undefined;
1162
+ if (market['spot']) {
1163
+ method = 'privatePutSpotOrders';
1164
+ } else if (market['contract']) {
1165
+ method = 'privatePutFuturesOrders';
1166
+ }
1167
+ const response = await this[method] (this.extend (request, params));
1168
+ //
1169
+ // spot
1170
+ //
1171
+ // {
1172
+ // "code":1,
1173
+ // "data":{
1174
+ // "symbol":"ETHUSDT",
1175
+ // "orderType":2,
1176
+ // "avgPrice":"0",
1177
+ // "execInst":null,
1178
+ // "orderStatus":0,
1179
+ // "userID":"1362494",
1180
+ // "quote":"USDT",
1181
+ // "rejectReason":null,
1182
+ // "rejectCode":null,
1183
+ // "price":"1500",
1184
+ // "orderQty":"1",
1185
+ // "commission":"0",
1186
+ // "id":"268323430253735936",
1187
+ // "timeInForce":1,
1188
+ // "isTriggered":false,
1189
+ // "side":2,
1190
+ // "orderID":"1eO51MDSpQ",
1191
+ // "leavesQty":"0",
1192
+ // "cumQty":"0",
1193
+ // "updateTime":null,
1194
+ // "lastQty":"0",
1195
+ // "clOrdID":null,
1196
+ // "stopPrice":null,
1197
+ // "createTime":null,
1198
+ // "transactTime":null,
1199
+ // "base":"ETH",
1200
+ // "lastPrice":"0"
1201
+ // },
1202
+ // "message":"success",
1203
+ // "ts":1610245290980
1204
+ // }
1205
+ //
1206
+ // futures
1207
+ //
1208
+ // {
1209
+ // "code":1,
1210
+ // "data":{
1211
+ // "liqType":0,
1212
+ // "symbol":"ETHUSDTFP",
1213
+ // "orderType":2,
1214
+ // "leverage":"1",
1215
+ // "marketPrice":"1318.3150000000",
1216
+ // "code":"FP",
1217
+ // "avgPrice":"0",
1218
+ // "execInst":null,
1219
+ // "orderStatus":0,
1220
+ // "userID":"1362494",
1221
+ // "quote":"USDT",
1222
+ // "rejectReason":null,
1223
+ // "rejectCode":null,
1224
+ // "price":"500",
1225
+ // "orderQty":"1",
1226
+ // "commission":"0",
1227
+ // "id":"268346885133053953",
1228
+ // "timeInForce":1,
1229
+ // "isTriggered":false,
1230
+ // "side":1,
1231
+ // "orderID":"1eOuPUAAkq",
1232
+ // "leavesQty":"1",
1233
+ // "cumQty":"0",
1234
+ // "updateTime":null,
1235
+ // "lastQty":null,
1236
+ // "clOrdID":null,
1237
+ // "stopPrice":null,
1238
+ // "createTime":null,
1239
+ // "transactTime":null,
1240
+ // "settleType":"VANILLA",
1241
+ // "base":"ETH",
1242
+ // "lastPrice":"0"
1243
+ // },
1244
+ // "message":"success",
1245
+ // "ts":1610250883059
1246
+ // }
1247
+ //
1248
+ const data = this.safeValue (response, 'data', {});
1249
+ return this.parseOrder (data, market);
1250
+ }
1251
+
1252
+ async cancelOrder (id, symbol = undefined, params = {}) {
1253
+ await this.loadMarkets ();
1254
+ const request = {
1255
+ 'orderID': id,
1256
+ };
1257
+ let market = undefined;
1258
+ if (symbol !== undefined) {
1259
+ market = this.market (symbol);
1260
+ }
1261
+ const [ marketType, query ] = this.handleMarketTypeAndParams ('cancelOrder', market, params);
1262
+ const method = this.getSupportedMapping (marketType, {
1263
+ 'spot': 'privateDeleteSpotOrdersCancelOrderID',
1264
+ 'swap': 'privateDeleteFuturesOrdersCancelOrderID',
1265
+ 'future': 'privateDeleteFuturesOrdersCancelOrderID',
1266
+ });
1267
+ const response = await this[method] (this.extend (request, query));
1268
+ //
1269
+ // spot
1270
+ //
1271
+ // {
1272
+ // "code":1,
1273
+ // "data":{
1274
+ // "avgPrice":"0",
1275
+ // "base":"BTC",
1276
+ // "clOrdID":"aax",
1277
+ // "commission":"0",
1278
+ // "createTime":"2019-11-12T03:46:41Z",
1279
+ // "cumQty":"0",
1280
+ // "id":"114330021504606208",
1281
+ // "isTriggered":false,
1282
+ // "lastPrice":"0",
1283
+ // "lastQty":"0",
1284
+ // "leavesQty":"0",
1285
+ // "orderID":"wJ4L366KB",
1286
+ // "orderQty":"0.05",
1287
+ // "orderStatus":1,
1288
+ // "orderType":2,
1289
+ // "price":"8000",
1290
+ // "quote":"USDT",
1291
+ // "rejectCode":0,
1292
+ // "rejectReason":null,
1293
+ // "side":1,
1294
+ // "stopPrice":"0",
1295
+ // "symbol":"BTCUSDT",
1296
+ // "transactTime":null,
1297
+ // "updateTime":"2019-11-12T03:46:41Z",
1298
+ // "timeInForce":1,
1299
+ // "userID":"216214"
1300
+ // },
1301
+ // "message":"success",
1302
+ // "ts":1573530402029
1303
+ // }
1304
+ //
1305
+ // futures
1306
+ //
1307
+ // {
1308
+ // "code":1,
1309
+ // "data":{
1310
+ // "avgPrice":"0",
1311
+ // "base":"BTC",
1312
+ // "clOrdID":"aax_futures",
1313
+ // "code":"FP",
1314
+ // "commission":"0",
1315
+ // "createTime":"2019-11-12T06:48:58Z",
1316
+ // "cumQty":"0",
1317
+ // "id":"114375893764395008",
1318
+ // "isTriggered":false,
1319
+ // "lastPrice":"0",
1320
+ // "lastQty":null,
1321
+ // "leavesQty":"300",
1322
+ // "leverage":"1",
1323
+ // "liqType":0,
1324
+ // "marketPrice":"8760.75",
1325
+ // "orderID":"wJTewQc81",
1326
+ // "orderQty":"300",
1327
+ // "orderStatus":1,
1328
+ // "orderType":2,
1329
+ // "price":"8000",
1330
+ // "quote":"USD",
1331
+ // "rejectCode":0,
1332
+ // "rejectReason":null,
1333
+ // "settleType":"INVERSE",
1334
+ // "side":1,
1335
+ // "stopPrice":"0",
1336
+ // "symbol":"BTCUSDFP",
1337
+ // "transactTime":"2019-11-12T06:48:58Z",
1338
+ // "updateTime":"2019-11-12T06:48:58Z",
1339
+ // "timeInForce":1,
1340
+ // "execInst": "",
1341
+ // "userID":"216214"
1342
+ // },
1343
+ // "message":"success",
1344
+ // "ts":1573541642970
1345
+ // }
1346
+ //
1347
+ const data = this.safeValue (response, 'data', {});
1348
+ return this.parseOrder (data, market);
1349
+ }
1350
+
1351
+ async cancelAllOrders (symbol = undefined, params = {}) {
1352
+ if (symbol === undefined) {
1353
+ throw new ArgumentsRequired (this.id + ' cancelAllOrders() requires a symbol argument');
1354
+ }
1355
+ await this.loadMarkets ();
1356
+ const market = this.market (symbol);
1357
+ const request = {
1358
+ 'symbol': market['id'],
1359
+ };
1360
+ let method = undefined;
1361
+ if (market['spot']) {
1362
+ method = 'privateDeleteSpotOrdersCancelAll';
1363
+ } else if (market['contract']) {
1364
+ method = 'privateDeleteFuturesOrdersCancelAll';
1365
+ }
1366
+ const response = await this[method] (this.extend (request, params));
1367
+ //
1368
+ // {
1369
+ // "code":1,
1370
+ // "data":[
1371
+ // "vBC9rXsEE",
1372
+ // "vBCc46OI0"
1373
+ // ],
1374
+ // "message":"success",
1375
+ // "ts":1572597435470
1376
+ // }
1377
+ //
1378
+ return response;
1379
+ }
1380
+
1381
+ async fetchOrder (id, symbol = undefined, params = {}) {
1382
+ await this.loadMarkets ();
1383
+ const defaultType = this.safeString2 (this.options, 'fetchOrder', 'defaultType', 'spot');
1384
+ params['type'] = this.safeString (params, 'type', defaultType);
1385
+ const request = {};
1386
+ const clientOrderId = this.safeString2 (params, 'clOrdID', 'clientOrderId');
1387
+ if (clientOrderId === undefined) {
1388
+ request['orderID'] = id;
1389
+ } else {
1390
+ request['clOrdID'] = clientOrderId;
1391
+ params = this.omit (params, [ 'clOrdID', 'clientOrderId' ]);
1392
+ }
1393
+ const orders = await this.fetchOrders (symbol, undefined, undefined, this.extend (request, params));
1394
+ const order = this.safeValue (orders, 0);
1395
+ if (order === undefined) {
1396
+ if (clientOrderId === undefined) {
1397
+ throw new OrderNotFound (this.id + ' fetchOrder() could not find order id ' + id);
1398
+ } else {
1399
+ throw new OrderNotFound (this.id + ' fetchOrder() could not find order clientOrderID ' + clientOrderId);
1400
+ }
1401
+ }
1402
+ return order;
1403
+ }
1404
+
1405
+ async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1406
+ await this.loadMarkets ();
1407
+ const request = {
1408
+ // 'pageNum': '1',
1409
+ // 'pageSize': '10',
1410
+ // 'symbol': market['id'],
1411
+ // 'orderID': id,
1412
+ // 'side': 'undefined', // BUY, SELL
1413
+ // 'clOrdID': clientOrderId,
1414
+ };
1415
+ let market = undefined;
1416
+ if (symbol !== undefined) {
1417
+ market = this.market (symbol);
1418
+ request['symbol'] = market['id'];
1419
+ }
1420
+ const [ marketType, query ] = this.handleMarketTypeAndParams ('fetchOpenOrders', market, params);
1421
+ const method = this.getSupportedMapping (marketType, {
1422
+ 'spot': 'privateGetSpotOpenOrders',
1423
+ 'swap': 'privateGetFuturesOpenOrders',
1424
+ 'future': 'privateGetFuturesOpenOrders',
1425
+ });
1426
+ const clientOrderId = this.safeString2 (params, 'clOrdID', 'clientOrderId');
1427
+ if (clientOrderId !== undefined) {
1428
+ request['clOrdID'] = clientOrderId;
1429
+ params = this.omit (params, [ 'clOrdID', 'clientOrderId' ]);
1430
+ }
1431
+ if (limit !== undefined) {
1432
+ request['pageSize'] = limit; // default 10
1433
+ }
1434
+ const response = await this[method] (this.extend (request, query));
1435
+ //
1436
+ // spot
1437
+ //
1438
+ // {
1439
+ // "code":1,
1440
+ // "data":{
1441
+ // "total":19,
1442
+ // "pageSize":10,
1443
+ // "list":[
1444
+ // {
1445
+ // "orderType":2,
1446
+ // "symbol":"BTCUSDT",
1447
+ // "avgPrice":"0",
1448
+ // "orderStatus":0,
1449
+ // "userID":"7225",
1450
+ // "quote":"USDT",
1451
+ // "rejectReason":null,
1452
+ // "rejectCode":null,
1453
+ // "price":"0",
1454
+ // "orderQty":"0.002",
1455
+ // "commission":"0",
1456
+ // "id":"110419975166304256",
1457
+ // "isTriggered":null,
1458
+ // "side":1,
1459
+ // "orderID":"vBGlDcLwk",
1460
+ // "cumQty":"0",
1461
+ // "leavesQty":"0",
1462
+ // "updateTime":null,
1463
+ // "clOrdID":"0001",
1464
+ // "lastQty":"0",
1465
+ // "stopPrice":"0",
1466
+ // "createTime":"2019-11-01T08:49:33Z",
1467
+ // "transactTime":null,
1468
+ // "timeInForce":1,
1469
+ // "base":"BTC",
1470
+ // "lastPrice":"0"
1471
+ // }
1472
+ // ],
1473
+ // "pageNum":1
1474
+ // },
1475
+ // "message":"success",
1476
+ // "ts":1572598173682
1477
+ // }
1478
+ //
1479
+ // futures
1480
+ //
1481
+ // {
1482
+ // "code":1,
1483
+ // "data":{
1484
+ // "list":[
1485
+ // {
1486
+ // "avgPrice":"8768.99999999484997",
1487
+ // "base":"BTC",
1488
+ // "clOrdID":null,
1489
+ // "code":"FP",
1490
+ // "commission":"0.00000913",
1491
+ // "createTime":"2019-11-12T07:05:52.000Z,
1492
+ // "cumQty":"100",
1493
+ // "id":"114380149603028993",
1494
+ // "isTriggered":false,
1495
+ // "lastPrice":"8769",
1496
+ // "lastQty":"100",
1497
+ // "leavesQty":"0",
1498
+ // "leverage":"1",
1499
+ // "liqType":1,
1500
+ // "marketPrice":"8769.75",
1501
+ // "orderID":"wJXURIFBT",
1502
+ // "orderQty":"100",
1503
+ // "orderStatus":3,
1504
+ // "orderType":1,
1505
+ // "price":"8769.75",
1506
+ // "quote":"USD",
1507
+ // "rejectCode":0,
1508
+ // "rejectReason":null,
1509
+ // "settleType":"INVERSE",
1510
+ // "side":2,
1511
+ // "stopPrice":"0",
1512
+ // "symbol":"BTCUSDFP",
1513
+ // "transactTime":"2019-11-12T07:05:52.000Z,
1514
+ // "updateTime":"2019-11-12T07:05:52.000Z,
1515
+ // "timeInForce":1,
1516
+ // "execInst": "",
1517
+ // "userID":"216214"
1518
+ // },
1519
+ // ],
1520
+ // "pageNum":1,
1521
+ // "pageSize":10,
1522
+ // "total":21
1523
+ // },
1524
+ // "message":"success",
1525
+ // "ts":1573546960172
1526
+ // }
1527
+ //
1528
+ const data = this.safeValue (response, 'data', {});
1529
+ const orders = this.safeValue (data, 'list', []);
1530
+ return this.parseOrders (orders, market, since, limit);
1531
+ }
1532
+
1533
+ async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1534
+ const request = {
1535
+ 'orderStatus': '2', // 1 new, 2 filled, 3 canceled
1536
+ };
1537
+ return await this.fetchOrders (symbol, since, limit, this.extend (request, params));
1538
+ }
1539
+
1540
+ async fetchCanceledOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1541
+ const request = {
1542
+ 'orderStatus': '3', // 1 new, 2 filled, 3 canceled
1543
+ };
1544
+ return await this.fetchOrders (symbol, since, limit, this.extend (request, params));
1545
+ }
1546
+
1547
+ async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1548
+ await this.loadMarkets ();
1549
+ const request = {
1550
+ // 'pageNum': '1',
1551
+ // 'pageSize': '10',
1552
+ // 'symbol': market['id'],
1553
+ // 'orderID': id,
1554
+ // 'base': market['baseId'],
1555
+ // 'quote': market['quoteId'],
1556
+ // 'orderStatus': undefined, // 1 new, 2 filled, 3 canceled
1557
+ // 'startDate': this.yyyymmdd (since),
1558
+ // 'endDate': this.yyyymmdd (this.milliseconds()),
1559
+ // 'orderType': undefined, // MARKET, LIMIT, STOP, STOP-LIMIT
1560
+ // 'side': 'undefined', // BUY, SELL
1561
+ // 'clOrdID': clientOrderId,
1562
+ };
1563
+ let market = undefined;
1564
+ if (symbol !== undefined) {
1565
+ market = this.market (symbol);
1566
+ request['symbol'] = market['id'];
1567
+ }
1568
+ const [ marketType, query ] = this.handleMarketTypeAndParams ('fetchOrders', market, params);
1569
+ const method = this.getSupportedMapping (marketType, {
1570
+ 'spot': 'privateGetSpotOrders',
1571
+ 'swap': 'privateGetFuturesOrders',
1572
+ 'future': 'privateGetFuturesOrders',
1573
+ });
1574
+ const clientOrderId = this.safeString2 (params, 'clOrdID', 'clientOrderId');
1575
+ if (clientOrderId !== undefined) {
1576
+ request['clOrdID'] = clientOrderId;
1577
+ params = this.omit (params, [ 'clOrdID', 'clientOrderId' ]);
1578
+ }
1579
+ if (limit !== undefined) {
1580
+ request['pageSize'] = limit; // default 10
1581
+ }
1582
+ if (since !== undefined) {
1583
+ request['startDate'] = this.yyyymmdd (since);
1584
+ }
1585
+ const response = await this[method] (this.extend (request, query));
1586
+ //
1587
+ // spot
1588
+ //
1589
+ // {
1590
+ // "code":1,
1591
+ // "data":{
1592
+ // "total":19,
1593
+ // "pageSize":10,
1594
+ // "list":[
1595
+ // {
1596
+ // "orderType":2,
1597
+ // "symbol":"BTCUSDT",
1598
+ // "avgPrice":"0",
1599
+ // "orderStatus":0,
1600
+ // "userID":"7225",
1601
+ // "quote":"USDT",
1602
+ // "rejectReason":null,
1603
+ // "rejectCode":null,
1604
+ // "price":"0",
1605
+ // "orderQty":"0.002",
1606
+ // "commission":"0",
1607
+ // "id":"110419975166304256",
1608
+ // "isTriggered":null,
1609
+ // "side":1,
1610
+ // "orderID":"vBGlDcLwk",
1611
+ // "cumQty":"0",
1612
+ // "leavesQty":"0",
1613
+ // "updateTime":null,
1614
+ // "clOrdID":"0001",
1615
+ // "lastQty":"0",
1616
+ // "stopPrice":"0",
1617
+ // "createTime":"2019-11-01T08:49:33Z",
1618
+ // "transactTime":null,
1619
+ // "timeInForce":1,
1620
+ // "base":"BTC",
1621
+ // "lastPrice":"0"
1622
+ // }
1623
+ // ],
1624
+ // "pageNum":1
1625
+ // },
1626
+ // "message":"success",
1627
+ // "ts":1572598173682
1628
+ // }
1629
+ //
1630
+ // futures
1631
+ //
1632
+ // {
1633
+ // "code":1,
1634
+ // "data":{
1635
+ // "list":[
1636
+ // {
1637
+ // "avgPrice":"8768.99999999484997",
1638
+ // "base":"BTC",
1639
+ // "clOrdID":null,
1640
+ // "code":"FP",
1641
+ // "commission":"0.00000913",
1642
+ // "createTime":"2019-11-12T07:05:52.000Z,
1643
+ // "cumQty":"100",
1644
+ // "id":"114380149603028993",
1645
+ // "isTriggered":false,
1646
+ // "lastPrice":"8769",
1647
+ // "lastQty":"100",
1648
+ // "leavesQty":"0",
1649
+ // "leverage":"1",
1650
+ // "liqType":1,
1651
+ // "marketPrice":"8769.75",
1652
+ // "orderID":"wJXURIFBT",
1653
+ // "orderQty":"100",
1654
+ // "orderStatus":3,
1655
+ // "orderType":1,
1656
+ // "price":"8769.75",
1657
+ // "quote":"USD",
1658
+ // "rejectCode":0,
1659
+ // "rejectReason":null,
1660
+ // "settleType":"INVERSE",
1661
+ // "side":2,
1662
+ // "stopPrice":"0",
1663
+ // "symbol":"BTCUSDFP",
1664
+ // "transactTime":"2019-11-12T07:05:52.000Z,
1665
+ // "updateTime":"2019-11-12T07:05:52.000Z,
1666
+ // "timeInForce":1,
1667
+ // "execInst": "",
1668
+ // "userID":"216214"
1669
+ // },
1670
+ // ],
1671
+ // "pageNum":1,
1672
+ // "pageSize":10,
1673
+ // "total":21
1674
+ // },
1675
+ // "message":"success",
1676
+ // "ts":1573546960172
1677
+ // }
1678
+ //
1679
+ const data = this.safeValue (response, 'data', {});
1680
+ const orders = this.safeValue (data, 'list', []);
1681
+ return this.parseOrders (orders, market, since, limit);
1682
+ }
1683
+
1684
+ parseOrderStatus (status) {
1685
+ const statuses = {
1686
+ '0': 'open', // pending new
1687
+ '1': 'open', // new
1688
+ '2': 'open', // partially-filled
1689
+ '3': 'closed', // filled
1690
+ '4': 'canceled', // cancel-reject
1691
+ '5': 'canceled', // canceled
1692
+ '6': 'rejected', // rejected
1693
+ '10': 'expired', // expired
1694
+ '11': 'rejected', // business-reject
1695
+ };
1696
+ return this.safeString (statuses, status, status);
1697
+ }
1698
+
1699
+ parseOrderType (status) {
1700
+ const statuses = {
1701
+ '1': 'market',
1702
+ '2': 'limit',
1703
+ '3': 'stop',
1704
+ '4': 'stop-limit',
1705
+ '7': 'stop-loss',
1706
+ '8': 'take-profit',
1707
+ };
1708
+ return this.safeString (statuses, status, status);
1709
+ }
1710
+
1711
+ parseTimeInForce (timeInForce) {
1712
+ const timeInForces = {
1713
+ '1': 'GTC',
1714
+ '3': 'IOC',
1715
+ '4': 'FOK',
1716
+ };
1717
+ return this.safeString (timeInForces, timeInForce, timeInForce);
1718
+ }
1719
+
1720
+ parseOrder (order, market = undefined) {
1721
+ //
1722
+ // {
1723
+ // "avgPrice":"8768.99999999484997",
1724
+ // "base":"BTC",
1725
+ // "clOrdID":null,
1726
+ // "code":"FP", // futures only
1727
+ // "commission":"0.00000913",
1728
+ // "createTime":"2019-11-12T07:05:52.000Z,
1729
+ // "cumQty":"100",
1730
+ // "id":"114380149603028993", // futures only
1731
+ // "isTriggered":false,
1732
+ // "lastPrice":"8769",
1733
+ // "lastQty":"100",
1734
+ // "leavesQty":"0",
1735
+ // "leverage":"1", // futures only
1736
+ // "liqType":1, // futures only
1737
+ // "marketPrice":"8769.75", // futures only
1738
+ // "orderID":"wJXURIFBT",
1739
+ // "orderQty":"100",
1740
+ // "orderStatus":3,
1741
+ // "orderType":1,
1742
+ // "price":"8769.75",
1743
+ // "quote":"USD",
1744
+ // "rejectCode":0,
1745
+ // "rejectReason":null,
1746
+ // "settleType":"INVERSE", // futures only
1747
+ // "side":2,
1748
+ // "stopPrice":"0",
1749
+ // "symbol":"BTCUSDFP",
1750
+ // "transactTime":"2019-11-12T07:05:52.000Z,
1751
+ // "updateTime":"2019-11-12T07:05:52.000Z,
1752
+ // "timeInForce":1,
1753
+ // "execInst": "",
1754
+ // "userID":"216214"
1755
+ // }
1756
+ //
1757
+ // sometimes the timestamp is returned in milliseconds
1758
+ let timestamp = this.safeValue (order, 'createTime');
1759
+ if (typeof timestamp === 'string') {
1760
+ timestamp = this.parse8601 (timestamp);
1761
+ }
1762
+ const status = this.parseOrderStatus (this.safeString (order, 'orderStatus'));
1763
+ const type = this.parseOrderType (this.safeString (order, 'orderType'));
1764
+ let side = this.safeString (order, 'side');
1765
+ if (side === '1') {
1766
+ side = 'buy';
1767
+ } else if (side === '2') {
1768
+ side = 'sell';
1769
+ }
1770
+ const id = this.safeString (order, 'orderID');
1771
+ const clientOrderId = this.safeString (order, 'clOrdID');
1772
+ const marketId = this.safeString (order, 'symbol');
1773
+ market = this.safeMarket (marketId, market);
1774
+ const price = this.safeString (order, 'price');
1775
+ const stopPrice = this.safeNumber (order, 'stopPrice');
1776
+ const timeInForce = this.parseTimeInForce (this.safeString (order, 'timeInForce'));
1777
+ const execInst = this.safeString (order, 'execInst');
1778
+ const postOnly = (execInst === 'Post-Only');
1779
+ const average = this.safeString (order, 'avgPrice');
1780
+ const amount = this.safeString (order, 'orderQty');
1781
+ const filled = this.safeString (order, 'cumQty');
1782
+ let remaining = this.safeString (order, 'leavesQty');
1783
+ if ((Precise.stringEquals (filled, '0')) && (Precise.stringEquals (remaining, '0'))) {
1784
+ remaining = undefined;
1785
+ }
1786
+ let lastTradeTimestamp = this.safeValue (order, 'transactTime');
1787
+ if (typeof lastTradeTimestamp === 'string') {
1788
+ lastTradeTimestamp = this.parse8601 (lastTradeTimestamp);
1789
+ }
1790
+ let fee = undefined;
1791
+ const feeCost = this.safeNumber (order, 'commission');
1792
+ if (feeCost !== undefined) {
1793
+ let feeCurrency = undefined;
1794
+ if (side === 'buy') {
1795
+ feeCurrency = market['base'];
1796
+ } else if (side === 'sell') {
1797
+ feeCurrency = market['quote'];
1798
+ }
1799
+ fee = {
1800
+ 'currency': feeCurrency,
1801
+ 'cost': feeCost,
1802
+ };
1803
+ }
1804
+ return this.safeOrder ({
1805
+ 'id': id,
1806
+ 'info': order,
1807
+ 'clientOrderId': clientOrderId,
1808
+ 'timestamp': timestamp,
1809
+ 'datetime': this.iso8601 (timestamp),
1810
+ 'lastTradeTimestamp': lastTradeTimestamp,
1811
+ 'status': status,
1812
+ 'symbol': market['symbol'],
1813
+ 'type': type,
1814
+ 'timeInForce': timeInForce,
1815
+ 'postOnly': postOnly,
1816
+ 'side': side,
1817
+ 'price': price,
1818
+ 'stopPrice': stopPrice,
1819
+ 'average': average,
1820
+ 'amount': amount,
1821
+ 'filled': filled,
1822
+ 'remaining': remaining,
1823
+ 'cost': undefined,
1824
+ 'trades': undefined,
1825
+ 'fee': fee,
1826
+ }, market);
1827
+ }
1828
+
1829
+ async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1830
+ await this.loadMarkets ();
1831
+ const request = {
1832
+ // 'pageNum': '1',
1833
+ // 'pageSize': '10',
1834
+ // 'symbol': market['id'],
1835
+ // 'orderID': id,
1836
+ // 'base': market['baseId'],
1837
+ // 'quote': market['quoteId'],
1838
+ // 'startDate': this.yyyymmdd (since),
1839
+ // 'endDate': this.yyyymmdd (this.milliseconds()),
1840
+ // 'orderType': undefined, // MARKET, LIMIT, STOP, STOP-LIMIT
1841
+ // 'side': 'undefined', // BUY, SELL
1842
+ };
1843
+ let market = undefined;
1844
+ if (symbol !== undefined) {
1845
+ market = this.market (symbol);
1846
+ request['symbol'] = market['id'];
1847
+ }
1848
+ const [ marketType, query ] = this.handleMarketTypeAndParams ('fetchMyTrades', market, params);
1849
+ const method = this.getSupportedMapping (marketType, {
1850
+ 'spot': 'privateGetSpotTrades',
1851
+ 'swap': 'privateGetFuturesTrades',
1852
+ 'future': 'privateGetFuturesTrades',
1853
+ });
1854
+ if (limit !== undefined) {
1855
+ request['pageSize'] = limit; // default 10
1856
+ }
1857
+ if (since !== undefined) {
1858
+ request['startDate'] = this.yyyymmdd (since);
1859
+ }
1860
+ const response = await this[method] (this.extend (request, query));
1861
+ //
1862
+ // {
1863
+ // "code":1,
1864
+ // "data":{
1865
+ // "list":[
1866
+ // {
1867
+ // "avgPrice":"1199.8",
1868
+ // "base":"ETH",
1869
+ // "clOrdID":null,
1870
+ // "commission":"0.00002",
1871
+ // "createTime":"2021-01-11T02:47:51.512Z",
1872
+ // "cumQty":"0.02",
1873
+ // "filledOrderID":"1eUD4F5rwK",
1874
+ // "filledPrice":"1199.8",
1875
+ // "filledQty":"0.02",
1876
+ // "leavesQty":"0",
1877
+ // "oCreateTime":"2021-01-11T02:47:51.377Z",
1878
+ // "orderID":"1eUD4EHfdU",
1879
+ // "orderQty":"0.02",
1880
+ // "orderStatus":3,
1881
+ // "orderType":1,
1882
+ // "price":"1198.25",
1883
+ // "quote":"USDT",
1884
+ // "rejectCode":null,
1885
+ // "rejectReason":null,
1886
+ // "side":1,
1887
+ // "stopPrice":"0",
1888
+ // "symbol":"ETHUSDT",
1889
+ // "taker":true,
1890
+ // "tradeID":"E04WTIgfmULU",
1891
+ // "transactTime":"2021-01-11T02:47:51.389Z",
1892
+ // "updateTime":null,
1893
+ // "userID":"1362494"
1894
+ // }
1895
+ // ],
1896
+ // "pageNum":1,
1897
+ // "pageSize":10,
1898
+ // "total":1
1899
+ // },
1900
+ // "message":"success",
1901
+ // "ts":1610333278042
1902
+ // }
1903
+ //
1904
+ const data = this.safeValue (response, 'data', {});
1905
+ const trades = this.safeValue (data, 'list', []);
1906
+ return this.parseTrades (trades, market, since, limit);
1907
+ }
1908
+
1909
+ async fetchDepositAddress (code, params = {}) {
1910
+ await this.loadMarkets ();
1911
+ const currency = this.currency (code);
1912
+ const request = {
1913
+ 'currency': currency['id'],
1914
+ // 'network': undefined, // 'ERC20
1915
+ };
1916
+ if ('network' in params) {
1917
+ const networks = this.safeValue (this.options, 'networks', {});
1918
+ const network = this.safeStringUpper (params, 'network');
1919
+ params = this.omit (params, 'network');
1920
+ request['network'] = this.safeStringUpper (networks, network, network);
1921
+ }
1922
+ const response = await this.privateGetAccountDepositAddress (this.extend (request, params));
1923
+ //
1924
+ // {
1925
+ // "code":1,
1926
+ // "data":{
1927
+ // "address":"0x080c5c667381404cca9be0be9a04b2e47691ff86",
1928
+ // "tag":null,
1929
+ // "currency":"USDT",
1930
+ // "network":"ERC20"
1931
+ // },
1932
+ // "message":"success",
1933
+ // "ts":1610270465132
1934
+ // }
1935
+ //
1936
+ const data = this.safeValue (response, 'data', {});
1937
+ return this.parseDepositAddress (data, currency);
1938
+ }
1939
+
1940
+ async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
1941
+ await this.loadMarkets ();
1942
+ const request = {
1943
+ // status Not required - Deposit status, "1: pending,2: confirmed, 3:failed"
1944
+ // currency: Not required - String Currency
1945
+ // startTime Not required Integer Default: 90 days from current timestamp.
1946
+ // endTime Not required Integer Default: present timestamp.
1947
+ };
1948
+ let currency = undefined;
1949
+ if (code !== undefined) {
1950
+ currency = this.currency (code);
1951
+ request['currency'] = currency['id'];
1952
+ }
1953
+ if (since !== undefined) {
1954
+ const startTime = parseInt (since / 1000);
1955
+ request['startTime'] = startTime;
1956
+ request['endTime'] = this.sum (startTime, 90 * 24 * 60 * 60); // Only allows a 90 day window between start and end
1957
+ }
1958
+ const response = await this.privateGetAccountDeposits (this.extend (request, params));
1959
+ // { "code": 1,
1960
+ // "data": [{
1961
+ // "currency": "USDT",
1962
+ // "network": "USDT",
1963
+ // "quantity": "19.000000000000",
1964
+ // "txHash": "75eb2e5f037b025c535664c49a0f7cc8f601dae218a5f4fe82290ff652c43f3d",
1965
+ // "address": "1GkB7Taf7uttcguKEb2DmmyRTnihskJ9Le",
1966
+ // "status": "2",
1967
+ // "createdTime": "2021-01-08T19:45:01.354Z",
1968
+ // "updatedTime": "2021-01-08T20:03:05.000Z",
1969
+ // }]
1970
+ // "message": "success",
1971
+ // "ts": 1573561743499
1972
+ // }
1973
+ const data = this.safeValue (response, 'data', []);
1974
+ return this.parseTransactions (data, code, since, limit);
1975
+ }
1976
+
1977
+ async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
1978
+ await this.loadMarkets ();
1979
+ const request = {
1980
+ // status Not required : "0: Under Review, 1: Manual Review, 2: On Chain, 3: Review Failed, 4: On Chain, 5: Completed, 6: Failed"
1981
+ // currency: Not required - String Currency
1982
+ // startTime Not required Integer Default: 30 days from current timestamp.
1983
+ // endTime Not required Integer Default: present timestamp.
1984
+ // Note difference between endTime and startTime must be 90 days or less
1985
+ };
1986
+ let currency = undefined;
1987
+ if (code !== undefined) {
1988
+ currency = this.currency (code);
1989
+ request['currency'] = currency['id'];
1990
+ }
1991
+ if (since !== undefined) {
1992
+ const startTime = parseInt (since / 1000);
1993
+ request['startTime'] = startTime;
1994
+ request['endTime'] = this.sum (startTime, 90 * 24 * 60 * 60); // Only allows a 90 day window between start and end
1995
+ }
1996
+ const response = await this.privateGetAccountWithdraws (this.extend (request, params));
1997
+ // {
1998
+ // "code":1,
1999
+ // "data": [
2000
+ // {
2001
+ // "currency":"USDT",
2002
+ // "network":"USDT",
2003
+ // "quantity":"19.000000000000",
2004
+ // "fee":"0.10000"
2005
+ // "txHash":"75eb2e5f037b025c535664c49a0f7cc8f601dae218a5f4fe82290ff652c43f3d",
2006
+ // "address":"1GkB7Taf7uttcguKEb2DmmyRTnihskJ9Le",
2007
+ // "addressTag": "",
2008
+ // "status":"2",
2009
+ // "createdTime":"2021-01-08T19:45:01.354Z",
2010
+ // "updatedTime":"2021-01-08T20:03:05.000Z",
2011
+ // }
2012
+ // ]
2013
+ // "message":"success",
2014
+ // "ts":1573561743499
2015
+ // }
2016
+ const data = this.safeValue (response, 'data', []);
2017
+ return this.parseTransactions (data, code, since, limit);
2018
+ }
2019
+
2020
+ parseTransactionStatusByType (status, type = undefined) {
2021
+ const statuses = {
2022
+ 'deposit': {
2023
+ '1': 'pending',
2024
+ '2': 'ok',
2025
+ '3': 'failed',
2026
+ },
2027
+ 'withdrawal': {
2028
+ '0': 'pending', // under review
2029
+ '1': 'pending', // manual review
2030
+ '2': 'pending', // on chain
2031
+ '3': 'failed', // failed
2032
+ '4': 'pending', // on chain
2033
+ '5': 'ok', // completed
2034
+ '6': 'failed', // failed
2035
+ },
2036
+ };
2037
+ return this.safeString (this.safeValue (statuses, type, {}), status, status);
2038
+ }
2039
+
2040
+ parseAddressByType (address, tag, type = undefined) {
2041
+ let addressFrom = undefined;
2042
+ let addressTo = undefined;
2043
+ let tagFrom = undefined;
2044
+ let tagTo = undefined;
2045
+ if (type === 'deposit') {
2046
+ addressFrom = address;
2047
+ tagFrom = tag;
2048
+ } else if (type === 'withdrawal') {
2049
+ addressTo = address;
2050
+ tagTo = tag;
2051
+ }
2052
+ return [ addressFrom, tagFrom, addressTo, tagTo ];
2053
+ }
2054
+
2055
+ parseTransaction (transaction, currency = undefined) {
2056
+ //
2057
+ // fetchDeposits
2058
+ //
2059
+ // {
2060
+ // "currency": "USDT",
2061
+ // "network": "USDT",
2062
+ // "quantity": "19.000000000000",
2063
+ // "txHash": "75eb2e5f037b025c535664c49a0f7cc8f601dae218a5f4fe82290ff652c43f3d",
2064
+ // "address": "1GkB7Taf7uttcguKEb2DmmyRTnihskJ9Le",
2065
+ // "status": "2",
2066
+ // "createdTime": "2021-01-08T19:45:01.354Z",
2067
+ // "updatedTime": "2021-01-08T20:03:05.000Z",
2068
+ // }
2069
+ //
2070
+ // fetchWithdrawals
2071
+ //
2072
+ // {
2073
+ // "currency":"USDT",
2074
+ // "network":"USDT",
2075
+ // "quantity":"19.000000000000",
2076
+ // "fee":"0.10000"
2077
+ // "txHash":"75eb2e5f037b025c535664c49a0f7cc8f601dae218a5f4fe82290ff652c43f3d",
2078
+ // "address":"1GkB7Taf7uttcguKEb2DmmyRTnihskJ9Le",
2079
+ // "addressTag": "",
2080
+ // "status":"2",
2081
+ // "createdTime":"2021-01-08T19:45:01.354Z",
2082
+ // "updatedTime":"2021-01-08T20:03:05.000Z",
2083
+ // }
2084
+ //
2085
+ const fee = this.safeString (transaction, 'fee');
2086
+ let type = 'withdrawal';
2087
+ if (fee === undefined) {
2088
+ type = 'deposit';
2089
+ }
2090
+ const code = this.safeCurrencyCode (this.safeString (transaction, 'currency'));
2091
+ const txid = this.safeString (transaction, 'txHash');
2092
+ const address = this.safeString (transaction, 'address');
2093
+ const tag = this.safeString (transaction, 'addressTag'); // withdrawals only
2094
+ const [ addressFrom, tagFrom, addressTo, tagTo ] = this.parseAddressByType (address, tag, type);
2095
+ const amountString = this.safeString (transaction, 'quantity');
2096
+ const timestamp = this.parse8601 (this.safeString (transaction, 'createdTime'));
2097
+ const updated = this.parse8601 (this.safeString (transaction, 'updatedTime'));
2098
+ const status = this.parseTransactionStatusByType (this.safeString (transaction, 'status'), type);
2099
+ const network = this.safeString (transaction, 'network');
2100
+ return {
2101
+ 'id': undefined,
2102
+ 'info': transaction,
2103
+ 'txid': txid,
2104
+ 'timestamp': timestamp,
2105
+ 'datetime': this.iso8601 (timestamp),
2106
+ 'network': network,
2107
+ 'addressFrom': addressFrom,
2108
+ 'address': address,
2109
+ 'addressTo': addressTo,
2110
+ 'amount': this.parseNumber (amountString),
2111
+ 'type': type,
2112
+ 'currency': code,
2113
+ 'status': status,
2114
+ 'updated': updated,
2115
+ 'tagFrom': tagFrom,
2116
+ 'tag': tag,
2117
+ 'tagTo': tagTo,
2118
+ 'comment': undefined,
2119
+ 'fee': fee,
2120
+ };
2121
+ }
2122
+
2123
+ async fetchFundingRate (symbol, params = {}) {
2124
+ await this.loadMarkets ();
2125
+ const market = this.market (symbol);
2126
+ if (!market['swap']) {
2127
+ throw new BadRequest ('Funding rates only exist for swap contracts');
2128
+ }
2129
+ const request = {
2130
+ 'symbol': market['id'],
2131
+ };
2132
+ const response = await this.publicGetFuturesFundingPrevFundingRateSymbol (this.extend (request, params));
2133
+ //
2134
+ // {
2135
+ // "code": 1,
2136
+ // "data": {
2137
+ // "symbol": "BTCUSDFP",
2138
+ // "markPrice": "11192.5",
2139
+ // "fundingRate": "0.001",
2140
+ // "fundingTime": "2020-08-12T08:00:00Z",
2141
+ // "nextFundingTime": "2020-08-12T16:00:00Z"
2142
+ // },
2143
+ // "message": "success",
2144
+ // "ts": 1573542445411
2145
+ // }
2146
+ //
2147
+ const data = this.safeValue (response, 'data');
2148
+ return this.parseFundingRate (data);
2149
+ }
2150
+
2151
+ parseFundingRate (contract, market = undefined) {
2152
+ //
2153
+ // {
2154
+ // "symbol": "BTCUSDFP",
2155
+ // "markPrice": "11192.5",
2156
+ // "fundingRate": "0.001",
2157
+ // "fundingTime": "2020-08-12T08:00:00Z",
2158
+ // "nextFundingTime": "2020-08-12T16:00:00Z"
2159
+ // }
2160
+ //
2161
+ const marketId = this.safeString (contract, 'symbol');
2162
+ const symbol = this.safeSymbol (marketId, market);
2163
+ const markPrice = this.safeNumber (contract, 'markPrice');
2164
+ const fundingRate = this.safeNumber (contract, 'fundingRate');
2165
+ const fundingDatetime = this.safeString (contract, 'fundingTime');
2166
+ const nextFundingDatetime = this.safeString (contract, 'nextFundingTime');
2167
+ return {
2168
+ 'info': contract,
2169
+ 'symbol': symbol,
2170
+ 'markPrice': markPrice,
2171
+ 'indexPrice': undefined,
2172
+ 'interestRate': undefined,
2173
+ 'estimatedSettlePrice': undefined,
2174
+ 'timestamp': undefined,
2175
+ 'datetime': undefined,
2176
+ 'fundingRate': fundingRate,
2177
+ 'fundingTimestamp': this.parse8601 (fundingDatetime),
2178
+ 'fundingDatetime': fundingDatetime,
2179
+ 'nextFundingRate': undefined,
2180
+ 'nextFundingTimestamp': this.parse8601 (nextFundingDatetime),
2181
+ 'nextFundingDatetime': nextFundingDatetime,
2182
+ 'previousFundingRate': undefined,
2183
+ 'previousFundingTimestamp': undefined,
2184
+ 'previousFundingDatetime': undefined,
2185
+ };
2186
+ }
2187
+
2188
+ parseDepositAddress (depositAddress, currency = undefined) {
2189
+ //
2190
+ // {
2191
+ // "address":"0x080c5c667381404cca9be0be9a04b2e47691ff86",
2192
+ // "tag":null,
2193
+ // "currency":"USDT",
2194
+ // "network":"ERC20"
2195
+ // }
2196
+ //
2197
+ const address = this.safeString (depositAddress, 'address');
2198
+ const tag = this.safeString (depositAddress, 'tag');
2199
+ let currencyId = this.safeString (depositAddress, 'currency');
2200
+ const network = this.safeString (depositAddress, 'network');
2201
+ if (network !== undefined) {
2202
+ currencyId = currencyId.replace (network, '');
2203
+ }
2204
+ const code = this.safeCurrencyCode (currencyId);
2205
+ return {
2206
+ 'info': depositAddress,
2207
+ 'currency': code,
2208
+ 'address': address,
2209
+ 'tag': tag,
2210
+ 'network': network,
2211
+ };
2212
+ }
2213
+
2214
+ async fetchFundingRateHistory (symbol = undefined, since = undefined, limit = undefined, params = {}) {
2215
+ if (symbol === undefined) {
2216
+ throw new ArgumentsRequired (this.id + ' fetchFundingRateHistory() requires a symbol argument');
2217
+ }
2218
+ await this.loadMarkets ();
2219
+ const market = this.market (symbol);
2220
+ const request = {
2221
+ 'symbol': market['id'],
2222
+ };
2223
+ if (since !== undefined) {
2224
+ request['startTime'] = parseInt (since / 1000);
2225
+ }
2226
+ const till = this.safeInteger (params, 'till'); // unified in milliseconds
2227
+ const endTime = this.safeString (params, 'endTime'); // exchange-specific in seconds
2228
+ params = this.omit (params, [ 'endTime', 'till' ]);
2229
+ if (till !== undefined) {
2230
+ request['endTime'] = parseInt (till / 1000);
2231
+ } else if (endTime !== undefined) {
2232
+ request['endTime'] = endTime;
2233
+ }
2234
+ if (limit !== undefined) {
2235
+ request['limit'] = limit;
2236
+ }
2237
+ const response = await this.publicGetFuturesFundingFundingRate (this.extend (request, params));
2238
+ //
2239
+ // {
2240
+ // "code": 1,
2241
+ // "data": [
2242
+ // {
2243
+ // "fundingRate": "0.00033992",
2244
+ // "fundingTime": "2021-12-31T00:00:00.000Z",
2245
+ // "symbol": "ETHUSDTFP"
2246
+ // },
2247
+ // ]
2248
+ // }
2249
+ //
2250
+ const data = this.safeValue (response, 'data');
2251
+ const rates = [];
2252
+ for (let i = 0; i < data.length; i++) {
2253
+ const entry = data[i];
2254
+ const marketId = this.safeString (entry, 'symbol');
2255
+ const symbol = this.safeSymbol (marketId);
2256
+ const datetime = this.safeString (entry, 'fundingTime');
2257
+ rates.push ({
2258
+ 'info': entry,
2259
+ 'symbol': symbol,
2260
+ 'fundingRate': this.safeNumber (entry, 'fundingRate'),
2261
+ 'timestamp': this.parse8601 (datetime),
2262
+ 'datetime': datetime,
2263
+ });
2264
+ }
2265
+ const sorted = this.sortBy (rates, 'timestamp');
2266
+ return this.filterBySymbolSinceLimit (sorted, market['symbol'], since, limit);
2267
+ }
2268
+
2269
+ async fetchFundingHistory (symbol = undefined, since = undefined, limit = undefined, params = {}) {
2270
+ await this.loadMarkets ();
2271
+ if (symbol === undefined) {
2272
+ throw new ArgumentsRequired (this.id + ' fetchFundingHistory() requires a symbol argument');
2273
+ }
2274
+ if (limit === undefined) {
2275
+ limit = 100; // Default
2276
+ } else if (limit > 1000) {
2277
+ throw new BadRequest (this.id + ' fetchFundingHistory() limit argument cannot exceed 1000');
2278
+ }
2279
+ const market = this.market (symbol);
2280
+ const request = {
2281
+ 'symbol': market['id'],
2282
+ 'limit': limit,
2283
+ };
2284
+ if (since !== undefined) {
2285
+ request['startTime'] = since;
2286
+ }
2287
+ const response = await this.privateGetFuturesFundingFundingFee (this.extend (request, params));
2288
+ //
2289
+ // {
2290
+ // "code": 1,
2291
+ // "data": [
2292
+ // {
2293
+ // "symbol": "BTCUSDTFP",
2294
+ // "fundingRate":"0.001",
2295
+ // "fundingFee":"100",
2296
+ // "currency":"USDT",
2297
+ // "fundingTime": "2020-08-12T08:00:00Z",
2298
+ // "markPrice": "11192.5",
2299
+ // }
2300
+ // ],
2301
+ // "message": "success",
2302
+ // "ts": 1573542445411
2303
+ // }
2304
+ //
2305
+ const data = this.safeValue (response, 'data', []);
2306
+ const result = [];
2307
+ for (let i = 0; i < data.length; i++) {
2308
+ const entry = data[i];
2309
+ const datetime = this.safeString (entry, 'fundingTime');
2310
+ result.push ({
2311
+ 'info': entry,
2312
+ 'symbol': symbol,
2313
+ 'code': this.safeCurrencyCode (this.safeString (entry, 'currency')),
2314
+ 'timestamp': this.parse8601 (datetime),
2315
+ 'datetime': datetime,
2316
+ 'id': undefined,
2317
+ 'amount': this.safeNumber (entry, 'fundingFee'),
2318
+ });
2319
+ }
2320
+ return result;
2321
+ }
2322
+
2323
+ async setLeverage (leverage, symbol = undefined, params = {}) {
2324
+ await this.loadMarkets ();
2325
+ if (symbol === undefined) {
2326
+ throw new ArgumentsRequired (this.id + ' setLeverage() requires a symbol argument');
2327
+ }
2328
+ if ((leverage < 1) || (leverage > 100)) {
2329
+ throw new BadRequest (this.id + ' leverage should be between 1 and 100');
2330
+ }
2331
+ const market = this.market (symbol);
2332
+ if (market['type'] !== 'swap') {
2333
+ throw new BadSymbol (this.id + ' setLeverage() supports swap contracts only');
2334
+ }
2335
+ const request = {
2336
+ 'symbol': market['id'],
2337
+ 'leverage': leverage,
2338
+ };
2339
+ return await this.privatePostFuturesPositionLeverage (this.extend (request, params));
2340
+ }
2341
+
2342
+ parseTransfer (transfer, currency = undefined) {
2343
+ // {
2344
+ // quantity: '0.000010000000',
2345
+ // transferID: '480975741034369024',
2346
+ // transferTime: '2022-03-24T13:53:07.042Z',
2347
+ // fromPurse: 'VLTP',
2348
+ // toPurse: 'SPTP',
2349
+ // currency: 'ETH'
2350
+ // },
2351
+ const id = this.safeString (transfer, 'transferID');
2352
+ const amount = this.safeNumber (transfer, 'quantity');
2353
+ const timestamp = this.parse8601 (this.safeString (transfer, 'transferTime'));
2354
+ const accounts = this.safeValue (this.options, 'accounts', {});
2355
+ const fromId = this.safeString (transfer, 'fromPurse');
2356
+ const toId = this.safeString (transfer, 'toPurse');
2357
+ const fromAccount = this.safeString (accounts, fromId);
2358
+ const toAccount = this.safeString (accounts, toId);
2359
+ const currencyId = this.safeString (transfer, 'currency');
2360
+ const currencyCode = this.safeCurrencyCode (currencyId, currency);
2361
+ return {
2362
+ 'info': transfer,
2363
+ 'id': id,
2364
+ 'timestamp': timestamp,
2365
+ 'datetime': this.iso8601 (timestamp),
2366
+ 'currency': currencyCode,
2367
+ 'amount': amount,
2368
+ 'fromAccount': fromAccount,
2369
+ 'toAccount': toAccount,
2370
+ 'status': undefined,
2371
+ };
2372
+ }
2373
+
2374
+ parseTransferStatus (status) {
2375
+ const statuses = {
2376
+ '1': 'ok',
2377
+ };
2378
+ return this.safeString (statuses, status, 'canceled');
2379
+ }
2380
+
2381
+ async transfer (code, amount, fromAccount, toAccount, params = {}) {
2382
+ await this.loadMarkets ();
2383
+ const currency = this.currency (code);
2384
+ const accountTypes = this.safeValue (this.options, 'accountsByType', {});
2385
+ const fromId = this.safeString (accountTypes, fromAccount, fromAccount);
2386
+ const toId = this.safeString (accountTypes, toAccount, toAccount);
2387
+ const request = {
2388
+ 'currency': currency['id'],
2389
+ 'fromPurse': fromId,
2390
+ 'toPurse': toId,
2391
+ 'quantity': amount,
2392
+ };
2393
+ const response = await this.privatePostAccountTransfer (this.extend (request, params));
2394
+ //
2395
+ // {
2396
+ // "code": 1,
2397
+ // "data": {
2398
+ // "transferID": 888561,
2399
+ // "transferTime": "2022-03-22T15:29:05.197Z"
2400
+ // },
2401
+ // "message": "success",
2402
+ // "ts": 1647962945151
2403
+ // }
2404
+ //
2405
+ const data = this.safeValue (response, 'data', {});
2406
+ const transfer = this.parseTransfer (data, currency);
2407
+ const transferOptions = this.safeValue (this.options, 'transfer', {});
2408
+ const fillResponseFromRequest = this.safeValue (transferOptions, 'fillResponseFromRequest', true);
2409
+ if (fillResponseFromRequest) {
2410
+ if (transfer['fromAccount'] === undefined) {
2411
+ transfer['fromAccount'] = fromAccount;
2412
+ }
2413
+ if (transfer['toAccount'] === undefined) {
2414
+ transfer['toAccount'] = toAccount;
2415
+ }
2416
+ if (transfer['amount'] === undefined) {
2417
+ transfer['amount'] = amount;
2418
+ }
2419
+ }
2420
+ transfer['status'] = this.parseTransferStatus (this.safeString (response, 'code'));
2421
+ return transfer;
2422
+ }
2423
+
2424
+ parsePosition (position, market = undefined) {
2425
+ //
2426
+ // {
2427
+ // "autoMarginCall": false,
2428
+ // "avgEntryPrice": "3706.03",
2429
+ // "bankruptPrice": "2963.3415880000",
2430
+ // "base": "ETH",
2431
+ // "code": "FP",
2432
+ // "commission": "0.02964824",
2433
+ // "currentQty": "2",
2434
+ // "funding": "-0.04827355",
2435
+ // "fundingStatus": null,
2436
+ // "id": "385839395735639395",
2437
+ // "leverage": "5",
2438
+ // "liquidationPrice": "2983.07",
2439
+ // "marketPrice": "3731.84",
2440
+ // "openTime": "2021-12-31T18:57:25.930Z",
2441
+ // "posLeverage": "5.00",
2442
+ // "posMargin": "14.85376824",
2443
+ // "quote": "USDT",
2444
+ // "realisedPnl": "-0.07792179",
2445
+ // "riskLimit": "10000000",
2446
+ // "riskyPrice": "3272.25",
2447
+ // "settleType": "VANILLA",
2448
+ // "stopLossPrice": "0",
2449
+ // "stopLossSource": 1,
2450
+ // "symbol": "ETHUSDTFP",
2451
+ // "takeProfitPrice": "0",
2452
+ // "takeProfitSource": 1,
2453
+ // "unrealisedPnl": "0.51620000",
2454
+ // "userID": "3829384",
2455
+ // "ts": 1641027194500
2456
+ // }
2457
+ //
2458
+ const contract = this.safeString (position, 'symbol');
2459
+ market = this.safeMarket (contract, market);
2460
+ const size = this.safeString (position, 'currentQty');
2461
+ let side = undefined;
2462
+ if (Precise.stringGt (size, '0')) {
2463
+ side = 'long';
2464
+ } else if (Precise.stringLt (size, '0')) {
2465
+ side = 'short';
2466
+ }
2467
+ const leverage = this.safeString (position, 'leverage');
2468
+ const unrealisedPnl = this.safeString (position, 'unrealisedPnl');
2469
+ const currentQty = this.safeString (position, 'currentQty');
2470
+ const contractSize = this.safeString (market, 'contractSize');
2471
+ const initialQuote = Precise.stringMul (currentQty, contractSize);
2472
+ const marketPrice = this.safeString (position, 'marketPrice');
2473
+ const notional = Precise.stringMul (initialQuote, marketPrice);
2474
+ const timestamp = this.safeInteger (position, 'ts');
2475
+ const liquidationPrice = this.safeString (position, 'liquidationPrice');
2476
+ return {
2477
+ 'info': position,
2478
+ 'symbol': this.safeString (market, 'symbol'),
2479
+ 'timestamp': timestamp,
2480
+ 'datetime': this.iso8601 (timestamp),
2481
+ 'initialMargin': undefined,
2482
+ 'initialMarginPercentage': undefined,
2483
+ 'maintenanceMargin': undefined,
2484
+ 'maintenanceMarginPercentage': undefined,
2485
+ 'entryPrice': this.safeNumber (position, 'avgEntryPrice'),
2486
+ 'notional': this.parseNumber (notional),
2487
+ 'leverage': this.parseNumber (leverage),
2488
+ 'unrealizedPnl': this.parseNumber (unrealisedPnl),
2489
+ 'contracts': this.parseNumber (size),
2490
+ 'contractSize': this.parseNumber (contractSize),
2491
+ 'marginRatio': undefined,
2492
+ 'liquidationPrice': liquidationPrice,
2493
+ 'markPrice': this.safeNumber (position, 'marketPrice'),
2494
+ 'collateral': this.safeNumber (position, 'posMargin'),
2495
+ 'marginType': this.safeString (position, 'settleType'),
2496
+ 'side': side,
2497
+ 'percentage': undefined,
2498
+ };
2499
+ }
2500
+
2501
+ async fetchPosition (symbol = undefined, params = {}) {
2502
+ await this.loadMarkets ();
2503
+ const market = this.market (symbol);
2504
+ const request = {
2505
+ 'symbol': market['id'],
2506
+ };
2507
+ const response = await this.privateGetFuturesPosition (this.extend (request, params));
2508
+ //
2509
+ // {
2510
+ // "code": 1,
2511
+ // "data": [
2512
+ // {
2513
+ // "autoMarginCall": false,
2514
+ // "avgEntryPrice": "3706.03",
2515
+ // "bankruptPrice": "2963.3415880000",
2516
+ // "base": "ETH",
2517
+ // "code": "FP",
2518
+ // "commission": "0.02964824",
2519
+ // "currentQty": "2",
2520
+ // "funding": "-0.04827355",
2521
+ // "fundingStatus": null,
2522
+ // "id": "385839395735639395",
2523
+ // "leverage": "5",
2524
+ // "liquidationPrice": "2983.07",
2525
+ // "marketPrice": "3731.84",
2526
+ // "openTime": "2021-12-31T18:57:25.930Z",
2527
+ // "posLeverage": "5.00",
2528
+ // "posMargin": "14.85376824",
2529
+ // "quote": "USDT",
2530
+ // "realisedPnl": "-0.07792179",
2531
+ // "riskLimit": "10000000",
2532
+ // "riskyPrice": "3272.25",
2533
+ // "settleType": "VANILLA",
2534
+ // "stopLossPrice": "0",
2535
+ // "stopLossSource": 1,
2536
+ // "symbol": "ETHUSDTFP",
2537
+ // "takeProfitPrice": "0",
2538
+ // "takeProfitSource": 1,
2539
+ // "unrealisedPnl": "0.51620000",
2540
+ // "userID": "3829384"
2541
+ // }
2542
+ // ...
2543
+ // ],
2544
+ // "message": "success",
2545
+ // "ts": 1641026778068
2546
+ // }
2547
+ //
2548
+ const positions = this.safeValue (response, 'data', []);
2549
+ const timestamp = this.safeInteger (response, 'ts');
2550
+ const first = this.safeValue (positions, 0);
2551
+ const position = this.parsePosition (first);
2552
+ return this.extend (position, {
2553
+ 'timestamp': timestamp,
2554
+ 'datetime': this.iso8601 (timestamp),
2555
+ });
2556
+ }
2557
+
2558
+ async fetchPositions (symbols = undefined, params = {}) {
2559
+ await this.loadMarkets ();
2560
+ const request = {};
2561
+ if (symbols !== undefined) {
2562
+ let symbol = undefined;
2563
+ if (Array.isArray (symbols)) {
2564
+ const symbolsLength = symbols.length;
2565
+ if (symbolsLength > 1) {
2566
+ throw new BadRequest (this.id + ' fetchPositions() symbols argument cannot contain more than 1 symbol');
2567
+ }
2568
+ symbol = symbols[0];
2569
+ } else {
2570
+ symbol = symbols;
2571
+ }
2572
+ const market = this.market (symbol);
2573
+ request['symbol'] = market['id'];
2574
+ }
2575
+ const response = await this.privateGetFuturesPosition (this.extend (request, params));
2576
+ //
2577
+ // {
2578
+ // "code": 1,
2579
+ // "data": [
2580
+ // {
2581
+ // "autoMarginCall": false,
2582
+ // "avgEntryPrice": "3706.03",
2583
+ // "bankruptPrice": "2963.3415880000",
2584
+ // "base": "ETH",
2585
+ // "code": "FP",
2586
+ // "commission": "0.02964824",
2587
+ // "currentQty": "2",
2588
+ // "funding": "-0.04827355",
2589
+ // "fundingStatus": null,
2590
+ // "id": "385839395735639395",
2591
+ // "leverage": "5",
2592
+ // "liquidationPrice": "2983.07",
2593
+ // "marketPrice": "3731.84",
2594
+ // "openTime": "2021-12-31T18:57:25.930Z",
2595
+ // "posLeverage": "5.00",
2596
+ // "posMargin": "14.85376824",
2597
+ // "quote": "USDT",
2598
+ // "realisedPnl": "-0.07792179",
2599
+ // "riskLimit": "10000000",
2600
+ // "riskyPrice": "3272.25",
2601
+ // "settleType": "VANILLA",
2602
+ // "stopLossPrice": "0",
2603
+ // "stopLossSource": 1,
2604
+ // "symbol": "ETHUSDTFP",
2605
+ // "takeProfitPrice": "0",
2606
+ // "takeProfitSource": 1,
2607
+ // "unrealisedPnl": "0.51620000",
2608
+ // "userID": "3829384"
2609
+ // }
2610
+ // ...
2611
+ // ],
2612
+ // "message": "success",
2613
+ // "ts": 1641026778068
2614
+ // }
2615
+ //
2616
+ const result = [];
2617
+ const positions = this.safeValue (response, 'data', []);
2618
+ const timestamp = this.safeInteger (response, 'ts');
2619
+ for (let i = 0; i < positions.length; i++) {
2620
+ const position = this.parsePosition (positions[i]);
2621
+ result.push (this.extend (position, {
2622
+ 'timestamp': timestamp,
2623
+ 'datetime': this.iso8601 (timestamp),
2624
+ }));
2625
+ }
2626
+ return this.filterByArray (result, 'symbol', symbols, false);
2627
+ }
2628
+
2629
+ nonce () {
2630
+ return this.milliseconds ();
2631
+ }
2632
+
2633
+ sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
2634
+ let url = '/' + this.implodeParams (path, params);
2635
+ const query = this.omit (params, this.extractParams (path));
2636
+ if (api === 'v1') {
2637
+ if (Object.keys (query).length) {
2638
+ url += '?' + this.urlencode (query);
2639
+ }
2640
+ } else {
2641
+ url = '/' + this.version + url;
2642
+ if (api === 'public') {
2643
+ if (Object.keys (query).length) {
2644
+ url += '?' + this.urlencode (query);
2645
+ }
2646
+ } else if (api === 'private') {
2647
+ this.checkRequiredCredentials ();
2648
+ const nonce = this.nonce ().toString ();
2649
+ headers = {
2650
+ 'X-ACCESS-KEY': this.apiKey,
2651
+ 'X-ACCESS-NONCE': nonce,
2652
+ };
2653
+ let auth = nonce + ':' + method;
2654
+ if (method === 'GET') {
2655
+ if (Object.keys (query).length) {
2656
+ url += '?' + this.urlencode (query);
2657
+ }
2658
+ auth += url;
2659
+ } else {
2660
+ headers['Content-Type'] = 'application/json';
2661
+ body = this.json (query);
2662
+ auth += url + body;
2663
+ }
2664
+ const signature = this.hmac (this.encode (auth), this.encode (this.secret));
2665
+ headers['X-ACCESS-SIGN'] = signature;
2666
+ }
2667
+ }
2668
+ url = this.implodeHostname (this.urls['api'][api]) + url;
2669
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
2670
+ }
2671
+
2672
+ handleErrors (code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
2673
+ if (response === undefined) {
2674
+ return; // fallback to default error handler
2675
+ }
2676
+ //
2677
+ // {"code":40102,"message":"Unauthorized(invalid key)"}
2678
+ //
2679
+ const errorCode = this.safeString (response, 'code');
2680
+ if ((errorCode !== undefined) && (errorCode !== '1')) {
2681
+ const feedback = this.id + ' ' + this.json (response);
2682
+ this.throwExactlyMatchedException (this.exceptions['exact'], errorCode, feedback);
2683
+ this.throwBroadlyMatchedException (this.exceptions['broad'], body, feedback);
2684
+ }
2685
+ }
2686
+ };