ccxt 4.4.77 → 4.4.80

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 (154) hide show
  1. package/README.md +8 -10
  2. package/dist/ccxt.browser.min.js +7 -7
  3. package/dist/cjs/ccxt.js +8 -4
  4. package/dist/cjs/src/abstract/ace.js +1 -1
  5. package/dist/cjs/src/abstract/apex.js +9 -0
  6. package/dist/cjs/src/ace.js +1 -1
  7. package/dist/cjs/src/apex.js +1949 -0
  8. package/dist/cjs/src/ascendex.js +25 -4
  9. package/dist/cjs/src/base/Exchange.js +42 -2
  10. package/dist/cjs/src/binance.js +9 -1
  11. package/dist/cjs/src/bingx.js +3 -3
  12. package/dist/cjs/src/bitfinex.js +64 -36
  13. package/dist/cjs/src/bitget.js +191 -138
  14. package/dist/cjs/src/bitmart.js +7 -2
  15. package/dist/cjs/src/bitmex.js +16 -8
  16. package/dist/cjs/src/bitopro.js +5 -1
  17. package/dist/cjs/src/bitrue.js +2 -1
  18. package/dist/cjs/src/bitso.js +1 -1
  19. package/dist/cjs/src/bitteam.js +2 -0
  20. package/dist/cjs/src/bitvavo.js +28 -10
  21. package/dist/cjs/src/btcalpha.js +1 -1
  22. package/dist/cjs/src/btcmarkets.js +1 -1
  23. package/dist/cjs/src/btcturk.js +1 -1
  24. package/dist/cjs/src/bybit.js +32 -16
  25. package/dist/cjs/src/cex.js +1 -1
  26. package/dist/cjs/src/coinbase.js +18 -2
  27. package/dist/cjs/src/coincatch.js +68 -0
  28. package/dist/cjs/src/coinex.js +1 -0
  29. package/dist/cjs/src/coinlist.js +1 -0
  30. package/dist/cjs/src/coinone.js +1 -0
  31. package/dist/cjs/src/delta.js +4 -0
  32. package/dist/cjs/src/deribit.js +1 -0
  33. package/dist/cjs/src/hitbtc.js +3 -0
  34. package/dist/cjs/src/hollaex.js +1 -0
  35. package/dist/cjs/src/htx.js +7 -3
  36. package/dist/cjs/src/huobijp.js +1 -0
  37. package/dist/cjs/src/hyperliquid.js +14 -4
  38. package/dist/cjs/src/kraken.js +2 -0
  39. package/dist/cjs/src/mexc.js +50 -57
  40. package/dist/cjs/src/okx.js +1 -1
  41. package/dist/cjs/src/phemex.js +2 -1
  42. package/dist/cjs/src/poloniex.js +2 -1
  43. package/dist/cjs/src/pro/apex.js +1043 -0
  44. package/dist/cjs/src/pro/binance.js +3 -3
  45. package/dist/cjs/src/pro/coinbase.js +45 -68
  46. package/dist/cjs/src/pro/gate.js +27 -2
  47. package/dist/cjs/src/pro/hollaex.js +2 -2
  48. package/dist/cjs/src/pro/p2b.js +2 -2
  49. package/dist/cjs/src/pro/tradeogre.js +283 -0
  50. package/dist/cjs/src/pro/upbit.js +43 -0
  51. package/dist/cjs/src/probit.js +1 -0
  52. package/dist/cjs/src/static_dependencies/zklink/zklink-sdk-web.js +2639 -0
  53. package/dist/cjs/src/timex.js +2 -2
  54. package/dist/cjs/src/tradeogre.js +2 -1
  55. package/dist/cjs/src/upbit.js +277 -67
  56. package/dist/cjs/src/whitebit.js +66 -12
  57. package/dist/cjs/src/woo.js +3 -1
  58. package/dist/cjs/src/xt.js +9 -0
  59. package/js/ccxt.d.ts +11 -5
  60. package/js/ccxt.js +8 -4
  61. package/js/src/abstract/apex.d.ts +34 -0
  62. package/js/src/abstract/bitmart.d.ts +1 -0
  63. package/js/src/apex.d.ts +333 -0
  64. package/js/src/apex.js +1945 -0
  65. package/js/src/ascendex.d.ts +3 -3
  66. package/js/src/ascendex.js +25 -4
  67. package/js/src/base/Exchange.d.ts +2 -0
  68. package/js/src/base/Exchange.js +42 -1
  69. package/js/src/binance.d.ts +7 -7
  70. package/js/src/binance.js +9 -1
  71. package/js/src/bingx.js +3 -3
  72. package/js/src/bitfinex.d.ts +3 -3
  73. package/js/src/bitfinex.js +64 -36
  74. package/js/src/bitflyer.d.ts +2 -2
  75. package/js/src/bitget.d.ts +2 -0
  76. package/js/src/bitget.js +191 -138
  77. package/js/src/bitmart.d.ts +5 -4
  78. package/js/src/bitmart.js +7 -2
  79. package/js/src/bitmex.d.ts +3 -3
  80. package/js/src/bitmex.js +16 -8
  81. package/js/src/bitopro.js +5 -1
  82. package/js/src/bitrue.js +2 -1
  83. package/js/src/bitso.js +1 -1
  84. package/js/src/bitteam.js +2 -0
  85. package/js/src/bitvavo.js +28 -10
  86. package/js/src/btcalpha.js +1 -1
  87. package/js/src/btcmarkets.js +1 -1
  88. package/js/src/btcturk.js +1 -1
  89. package/js/src/bybit.js +32 -16
  90. package/js/src/cex.js +1 -1
  91. package/js/src/coinbase.d.ts +4 -4
  92. package/js/src/coinbase.js +18 -2
  93. package/js/src/coinbaseexchange.d.ts +1 -1
  94. package/js/src/coincatch.d.ts +11 -0
  95. package/js/src/coincatch.js +68 -0
  96. package/js/src/coinex.js +1 -0
  97. package/js/src/coinlist.js +1 -0
  98. package/js/src/coinone.js +1 -0
  99. package/js/src/cryptocom.d.ts +4 -4
  100. package/js/src/delta.js +4 -0
  101. package/js/src/deribit.d.ts +4 -4
  102. package/js/src/deribit.js +1 -0
  103. package/js/src/derive.d.ts +3 -3
  104. package/js/src/digifinex.d.ts +4 -4
  105. package/js/src/hitbtc.js +3 -0
  106. package/js/src/hollaex.js +1 -0
  107. package/js/src/htx.d.ts +4 -4
  108. package/js/src/htx.js +7 -3
  109. package/js/src/huobijp.js +1 -0
  110. package/js/src/hyperliquid.d.ts +1 -0
  111. package/js/src/hyperliquid.js +14 -4
  112. package/js/src/kraken.d.ts +3 -3
  113. package/js/src/kraken.js +2 -0
  114. package/js/src/krakenfutures.d.ts +2 -2
  115. package/js/src/kucoinfutures.d.ts +5 -5
  116. package/js/src/mexc.d.ts +1 -0
  117. package/js/src/mexc.js +50 -57
  118. package/js/src/okx.js +1 -1
  119. package/js/src/oxfun.d.ts +3 -3
  120. package/js/src/phemex.d.ts +3 -3
  121. package/js/src/phemex.js +2 -1
  122. package/js/src/poloniex.d.ts +3 -3
  123. package/js/src/poloniex.js +2 -1
  124. package/js/src/pro/apex.d.ts +160 -0
  125. package/js/src/pro/apex.js +1038 -0
  126. package/js/src/pro/binance.js +3 -3
  127. package/js/src/pro/coinbase.d.ts +4 -3
  128. package/js/src/pro/coinbase.js +45 -66
  129. package/js/src/pro/gate.js +27 -2
  130. package/js/src/pro/hollaex.js +2 -2
  131. package/js/src/pro/p2b.js +2 -2
  132. package/js/src/pro/tradeogre.d.ts +49 -0
  133. package/js/src/pro/tradeogre.js +278 -0
  134. package/js/src/pro/upbit.d.ts +16 -1
  135. package/js/src/pro/upbit.js +43 -0
  136. package/js/src/probit.js +1 -0
  137. package/js/src/static_dependencies/zklink/zklink-sdk-web.d.ts +1279 -0
  138. package/js/src/static_dependencies/zklink/zklink-sdk-web.js +4276 -0
  139. package/js/src/timex.js +2 -2
  140. package/js/src/tradeogre.js +2 -1
  141. package/js/src/upbit.d.ts +75 -23
  142. package/js/src/upbit.js +277 -67
  143. package/js/src/vertex.d.ts +3 -3
  144. package/js/src/whitebit.js +66 -12
  145. package/js/src/woo.d.ts +4 -4
  146. package/js/src/woo.js +3 -1
  147. package/js/src/woofipro.d.ts +4 -4
  148. package/js/src/xt.d.ts +4 -4
  149. package/js/src/xt.js +9 -0
  150. package/package.json +2 -2
  151. package/js/src/abstract/ace.d.ts +0 -18
  152. package/js/src/ace.d.ts +0 -158
  153. package/js/src/ace.js +0 -1175
  154. /package/js/src/abstract/{ace.js → apex.js} +0 -0
@@ -0,0 +1,1949 @@
1
+ 'use strict';
2
+
3
+ var Precise = require('./base/Precise.js');
4
+ var apex$1 = require('./abstract/apex.js');
5
+ var number = require('./base/functions/number.js');
6
+ var sha256 = require('./static_dependencies/noble-hashes/sha256.js');
7
+ var errors = require('./base/errors.js');
8
+
9
+ // ---------------------------------------------------------------------------
10
+ // ---------------------------------------------------------------------------
11
+ /**
12
+ * @class apex
13
+ * @augments Exchange
14
+ */
15
+ class apex extends apex$1 {
16
+ describe() {
17
+ return this.deepExtend(super.describe(), {
18
+ 'id': 'apex',
19
+ 'name': 'Apex',
20
+ 'countries': [],
21
+ 'version': 'v3',
22
+ 'rateLimit': 20,
23
+ 'certified': false,
24
+ 'pro': true,
25
+ 'dex': true,
26
+ 'has': {
27
+ 'CORS': undefined,
28
+ 'spot': false,
29
+ 'margin': false,
30
+ 'swap': true,
31
+ 'future': false,
32
+ 'option': false,
33
+ 'addMargin': false,
34
+ 'borrowCrossMargin': false,
35
+ 'borrowIsolatedMargin': false,
36
+ 'cancelAllOrders': true,
37
+ 'cancelAllOrdersAfter': false,
38
+ 'cancelOrder': true,
39
+ 'cancelOrders': false,
40
+ 'cancelOrdersForSymbols': false,
41
+ 'closeAllPositions': false,
42
+ 'closePosition': false,
43
+ 'createMarketBuyOrderWithCost': false,
44
+ 'createMarketOrderWithCost': false,
45
+ 'createMarketSellOrderWithCost': false,
46
+ 'createOrder': true,
47
+ 'createOrders': false,
48
+ 'createPostOnlyOrder': true,
49
+ 'createReduceOnlyOrder': true,
50
+ 'createStopOrder': true,
51
+ 'createTriggerOrder': true,
52
+ 'editOrder': false,
53
+ 'fetchAccounts': true,
54
+ 'fetchBalance': true,
55
+ 'fetchBorrowInterest': false,
56
+ 'fetchBorrowRateHistories': false,
57
+ 'fetchBorrowRateHistory': false,
58
+ 'fetchCanceledAndClosedOrders': false,
59
+ 'fetchCanceledOrders': false,
60
+ 'fetchClosedOrders': false,
61
+ 'fetchCrossBorrowRate': false,
62
+ 'fetchCrossBorrowRates': false,
63
+ 'fetchCurrencies': true,
64
+ 'fetchDepositAddress': false,
65
+ 'fetchDepositAddresses': false,
66
+ 'fetchDeposits': false,
67
+ 'fetchDepositWithdrawFee': false,
68
+ 'fetchDepositWithdrawFees': false,
69
+ 'fetchFundingHistory': true,
70
+ 'fetchFundingRate': false,
71
+ 'fetchFundingRateHistory': true,
72
+ 'fetchFundingRates': false,
73
+ 'fetchIndexOHLCV': false,
74
+ 'fetchIsolatedBorrowRate': false,
75
+ 'fetchIsolatedBorrowRates': false,
76
+ 'fetchLedger': false,
77
+ 'fetchLeverage': false,
78
+ 'fetchLeverageTiers': false,
79
+ 'fetchLiquidations': false,
80
+ 'fetchMarginMode': false,
81
+ 'fetchMarketLeverageTiers': false,
82
+ 'fetchMarkets': true,
83
+ 'fetchMarkOHLCV': false,
84
+ 'fetchMyLiquidations': false,
85
+ 'fetchMyTrades': true,
86
+ 'fetchOHLCV': true,
87
+ 'fetchOpenInterest': true,
88
+ 'fetchOpenInterestHistory': false,
89
+ 'fetchOpenInterests': false,
90
+ 'fetchOpenOrders': true,
91
+ 'fetchOrder': true,
92
+ 'fetchOrderBook': true,
93
+ 'fetchOrders': true,
94
+ 'fetchOrderTrades': true,
95
+ 'fetchPosition': false,
96
+ 'fetchPositionMode': false,
97
+ 'fetchPositions': true,
98
+ 'fetchPositionsRisk': false,
99
+ 'fetchPremiumIndexOHLCV': false,
100
+ 'fetchTicker': true,
101
+ 'fetchTickers': true,
102
+ 'fetchTime': true,
103
+ 'fetchTrades': true,
104
+ 'fetchTradingFee': false,
105
+ 'fetchTradingFees': false,
106
+ 'fetchTransfer': true,
107
+ 'fetchTransfers': true,
108
+ 'fetchWithdrawal': false,
109
+ 'fetchWithdrawals': false,
110
+ 'reduceMargin': false,
111
+ 'repayCrossMargin': false,
112
+ 'repayIsolatedMargin': false,
113
+ 'sandbox': true,
114
+ 'setLeverage': true,
115
+ 'setMarginMode': false,
116
+ 'setPositionMode': false,
117
+ 'transfer': false,
118
+ 'withdraw': false,
119
+ },
120
+ 'timeframes': {
121
+ '1m': '1',
122
+ '5m': '5',
123
+ '15m': '15',
124
+ '30m': '30',
125
+ '1h': '60',
126
+ '2h': '120',
127
+ '4h': '240',
128
+ '6h': '360',
129
+ '12h': '720',
130
+ '1d': 'D',
131
+ '1w': 'W',
132
+ '1M': 'M',
133
+ },
134
+ 'hostname': 'omni.apex.exchange',
135
+ 'urls': {
136
+ 'logo': 'https://github.com/user-attachments/assets/fef8f2f7-4265-46aa-965e-33a91881cb00',
137
+ 'api': {
138
+ 'public': 'https://{hostname}/api',
139
+ 'private': 'https://{hostname}/api',
140
+ },
141
+ 'test': {
142
+ 'public': 'https://testnet.omni.apex.exchange/api',
143
+ 'private': 'https://testnet.omni.apex.exchange/api',
144
+ },
145
+ 'www': 'https://apex.exchange/',
146
+ 'doc': 'https://api-docs.pro.apex.exchange',
147
+ 'fees': 'https://apex-pro.gitbook.io/apex-pro/apex-omni-live-now/trading-perpetual-contracts/trading-fees',
148
+ 'referral': 'https://omni.apex.exchange/trade',
149
+ },
150
+ 'api': {
151
+ 'public': {
152
+ 'get': {
153
+ 'v3/symbols': 1,
154
+ 'v3/history-funding': 1,
155
+ 'v3/ticker': 1,
156
+ 'v3/klines': 1,
157
+ 'v3/trades': 1,
158
+ 'v3/depth': 1,
159
+ 'v3/time': 1,
160
+ 'v3/data/all-ticker-info': 1,
161
+ },
162
+ },
163
+ 'private': {
164
+ 'get': {
165
+ 'v3/account': 1,
166
+ 'v3/account-balance': 1,
167
+ 'v3/fills': 1,
168
+ 'v3/order-fills': 1,
169
+ 'v3/order': 1,
170
+ 'v3/history-orders': 1,
171
+ 'v3/order-by-client-order-id': 1,
172
+ 'v3/funding': 1,
173
+ 'v3/historical-pnl': 1,
174
+ 'v3/open-orders': 1,
175
+ 'v3/transfers': 1,
176
+ 'v3/transfer': 1,
177
+ },
178
+ 'post': {
179
+ 'v3/delete-open-orders': 1,
180
+ 'v3/delete-client-order-id': 1,
181
+ 'v3/delete-order': 1,
182
+ 'v3/order': 1,
183
+ 'v3/set-initial-margin-rate': 1,
184
+ 'v3/transfer-out': 1,
185
+ 'v3/contract-transfer-out': 1,
186
+ },
187
+ },
188
+ },
189
+ 'httpExceptions': {
190
+ '403': errors.RateLimitExceeded, // Forbidden -- You request too many times
191
+ },
192
+ 'exceptions': {
193
+ // Uncodumented explanation of error strings:
194
+ // - oc_diff: order cost needed to place this order
195
+ // - new_oc: total order cost of open orders including the order you are trying to open
196
+ // - ob: order balance - the total cost of current open orders
197
+ // - ab: available balance
198
+ 'exact': {
199
+ '20006': 'apikey sign error',
200
+ '20016': 'request para error',
201
+ '10001': errors.BadRequest,
202
+ },
203
+ 'broad': {
204
+ 'ORDER_PRICE_MUST_GREETER_ZERO': errors.InvalidOrder,
205
+ 'ORDER_POSSIBLE_LEAD_TO_ACCOUNT_LIQUIDATED': errors.InvalidOrder,
206
+ 'ORDER_WITH_THIS_PRICE_CANNOT_REDUCE_POSITION_ONLY': errors.InvalidOrder,
207
+ },
208
+ },
209
+ 'fees': {
210
+ 'swap': {
211
+ 'taker': this.parseNumber('0.0005'),
212
+ 'maker': this.parseNumber('0.0002'),
213
+ },
214
+ },
215
+ 'requiredCredentials': {
216
+ 'apiKey': true,
217
+ 'secret': true,
218
+ 'walletAddress': false,
219
+ 'privateKey': false,
220
+ 'password': true,
221
+ },
222
+ 'precisionMode': number.TICK_SIZE,
223
+ 'commonCurrencies': {},
224
+ 'options': {
225
+ 'defaultType': 'swap',
226
+ 'defaultSlippage': 0.05,
227
+ 'brokerId': '6956',
228
+ },
229
+ 'features': {
230
+ 'default': {
231
+ 'sandbox': true,
232
+ 'createOrder': {
233
+ 'marginMode': false,
234
+ 'triggerPrice': true,
235
+ 'triggerPriceType': undefined,
236
+ 'triggerDirection': false,
237
+ 'stopLossPrice': false,
238
+ 'takeProfitPrice': false,
239
+ 'attachedStopLossTakeProfit': undefined,
240
+ 'timeInForce': {
241
+ 'IOC': true,
242
+ 'FOK': true,
243
+ 'PO': true,
244
+ 'GTD': true,
245
+ },
246
+ 'hedged': false,
247
+ 'selfTradePrevention': false,
248
+ 'trailing': true,
249
+ 'leverage': false,
250
+ 'marketBuyByCost': false,
251
+ 'marketBuyRequiresPrice': false,
252
+ 'iceberg': false,
253
+ },
254
+ 'createOrders': undefined,
255
+ 'fetchMyTrades': {
256
+ 'marginMode': false,
257
+ 'limit': 500,
258
+ 'daysBack': 100000,
259
+ 'untilDays': 100000,
260
+ 'symbolRequired': false,
261
+ },
262
+ 'fetchOrder': {
263
+ 'marginMode': false,
264
+ 'trigger': false,
265
+ 'trailing': false,
266
+ 'symbolRequired': false,
267
+ },
268
+ 'fetchOpenOrders': {
269
+ 'marginMode': false,
270
+ 'limit': undefined,
271
+ 'trigger': false,
272
+ 'trailing': false,
273
+ 'symbolRequired': false,
274
+ },
275
+ 'fetchOrders': {
276
+ 'marginMode': false,
277
+ 'limit': 100,
278
+ 'daysBack': 100000,
279
+ 'untilDays': 100000,
280
+ 'trigger': false,
281
+ 'trailing': false,
282
+ 'symbolRequired': false,
283
+ },
284
+ 'fetchClosedOrders': undefined,
285
+ 'fetchOHLCV': {
286
+ 'limit': 200,
287
+ },
288
+ },
289
+ 'swap': {
290
+ 'linear': {
291
+ 'extends': 'default',
292
+ },
293
+ 'inverse': undefined,
294
+ },
295
+ },
296
+ });
297
+ }
298
+ /**
299
+ * @method
300
+ * @name apex#fetchTime
301
+ * @description fetches the current integer timestamp in milliseconds from the exchange server
302
+ * @see https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-system-time-v3
303
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
304
+ * @returns {int} the current integer timestamp in milliseconds from the exchange server
305
+ */
306
+ async fetchTime(params = {}) {
307
+ const response = await this.publicGetV3Time(params);
308
+ const data = this.safeDict(response, 'data', {});
309
+ //
310
+ // {
311
+ // "data": {
312
+ // "time": 1738837534454
313
+ // }
314
+ // }
315
+ return this.safeInteger(data, 'time');
316
+ }
317
+ parseBalance(response) {
318
+ //
319
+ // {
320
+ // "totalEquityValue": "100.000000",
321
+ // "availableBalance": "100.000000",
322
+ // "initialMargin": "100.000000",
323
+ // "maintenanceMargin": "100.000000",
324
+ // "symbolToOraclePrice": {
325
+ // "BTC-USDC": {
326
+ // "oraclePrice": "20000",
327
+ // "createdTime": 124566
328
+ // }
329
+ // }
330
+ // }
331
+ //
332
+ const timestamp = this.milliseconds();
333
+ const result = {
334
+ 'info': response,
335
+ 'timestamp': timestamp,
336
+ 'datetime': this.iso8601(timestamp),
337
+ };
338
+ const code = 'USDT';
339
+ const account = this.account();
340
+ account['free'] = this.safeString(response, 'availableBalance');
341
+ account['total'] = this.safeString(response, 'totalEquityValue');
342
+ result[code] = account;
343
+ return this.safeBalance(result);
344
+ }
345
+ /**
346
+ * @method
347
+ * @name apex#fetchBalance
348
+ * @description query for account info
349
+ * @see https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-retrieve-user-account-balance
350
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
351
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
352
+ */
353
+ async fetchBalance(params = {}) {
354
+ await this.loadMarkets();
355
+ const response = await this.privateGetV3AccountBalance(params);
356
+ const data = this.safeDict(response, 'data', {});
357
+ return this.parseBalance(data);
358
+ }
359
+ parseAccount(account) {
360
+ const accountId = this.safeString(account, 'id', '0');
361
+ return {
362
+ 'id': accountId,
363
+ 'type': undefined,
364
+ 'code': undefined,
365
+ 'info': account,
366
+ };
367
+ }
368
+ /**
369
+ * @method
370
+ * @name apex#fetchAccount
371
+ * @description query for balance and get the amount of funds available for trading or funds locked in orders
372
+ * @see https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-retrieve-user-account-data
373
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
374
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
375
+ */
376
+ async fetchAccount(params = {}) {
377
+ await this.loadMarkets();
378
+ const response = await this.privateGetV3Account(params);
379
+ const data = this.safeDict(response, 'data', {});
380
+ return this.parseAccount(data);
381
+ }
382
+ /**
383
+ * @method
384
+ * @name apex#fetchCurrencies
385
+ * @description fetches all available currencies on an exchange
386
+ * @see https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-all-config-data-v3
387
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
388
+ * @returns {object} an associative dictionary of currencies
389
+ */
390
+ async fetchCurrencies(params = {}) {
391
+ const response = await this.publicGetV3Symbols(params);
392
+ const data = this.safeDict(response, 'data', {});
393
+ const spotConfig = this.safeDict(data, 'spotConfig', {});
394
+ const multiChain = this.safeDict(spotConfig, 'multiChain', {});
395
+ // "spotConfig": {
396
+ // "assets": [
397
+ // {
398
+ // "tokenId": "141",
399
+ // "token": "USDT",
400
+ // "displayName": "Tether USD Coin",
401
+ // "decimals": 18,
402
+ // "showStep": "0.01",
403
+ // "iconUrl": "https://static-pro.apex.exchange/chains/chain_tokens/Ethereum/Ethereum_USDT.svg",
404
+ // "l2WithdrawFee": "0",
405
+ // "enableCollateral": true,
406
+ // "enableCrossCollateral": false,
407
+ // "crossCollateralDiscountRate": null,
408
+ // "isGray": false
409
+ // }
410
+ // ],
411
+ // "multiChain": {
412
+ // "chains": [
413
+ // {
414
+ // "chain": "Arbitrum One",
415
+ // "chainId": "9",
416
+ // "chainType": "0",
417
+ // "l1ChainId": "42161",
418
+ // "chainIconUrl": "https://static-pro.apex.exchange/chains/chain_logos/Arbitrum.svg",
419
+ // "contractAddress": "0x3169844a120c0f517b4eb4a750c08d8518c8466a",
420
+ // "swapContractAddress": "0x9e07b6Aef1bbD9E513fc2Eb8873e311E80B4f855",
421
+ // "stopDeposit": false,
422
+ // "feeLess": false,
423
+ // "gasLess": false,
424
+ // "gasToken": "ETH",
425
+ // "dynamicFee": true,
426
+ // "gasTokenDecimals": 18,
427
+ // "feeGasLimit": 300000,
428
+ // "blockTimeSeconds": 2,
429
+ // "rpcUrl": "https://arb.pro.apex.exchange",
430
+ // "minSwapUsdtAmount": "",
431
+ // "maxSwapUsdtAmount": "",
432
+ // "webRpcUrl": "https://arb.pro.apex.exchange",
433
+ // "webTxUrl": "https://arbiscan.io/tx/",
434
+ // "backupRpcUrl": "https://arb-mainnet.g.alchemy.com/v2/rGlYUbRHtUav5mfeThCPtsV9GLPt2Xq5",
435
+ // "txConfirm": 20,
436
+ // "withdrawGasFeeLess": false,
437
+ // "tokens": [
438
+ // {
439
+ // "decimals": 6,
440
+ // "iconUrl": "https://static-pro.apex.exchange/chains/chain_tokens/Arbitrum/Arbitrum_USDT.svg",
441
+ // "token": "USDT",
442
+ // "tokenAddress": "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
443
+ // "pullOff": false,
444
+ // "withdrawEnable": true,
445
+ // "slippage": "",
446
+ // "isDefaultToken": false,
447
+ // "displayToken": "USDT",
448
+ // "needResetApproval": true,
449
+ // "minFee": "2",
450
+ // "maxFee": "40",
451
+ // "feeRate": "0.0001",
452
+ // "maxWithdraw": "",
453
+ // "minDeposit": "",
454
+ // "minWithdraw": "",
455
+ // "maxFastWithdrawAmount": "40000",
456
+ // "minFastWithdrawAmount": "1",
457
+ // "isGray": false
458
+ // },
459
+ // {
460
+ // "decimals": 6,
461
+ // "iconUrl": "https://static-pro.apex.exchange/chains/chain_tokens/Arbitrum/Arbitrum_USDC.svg",
462
+ // "token": "USDC",
463
+ // "tokenAddress": "0xaf88d065e77c8cc2239327c5edb3a432268e5831",
464
+ // "pullOff": false,
465
+ // "withdrawEnable": true,
466
+ // "slippage": "",
467
+ // "isDefaultToken": false,
468
+ // "displayToken": "USDC",
469
+ // "needResetApproval": true,
470
+ // "minFee": "2",
471
+ // "maxFee": "20",
472
+ // "feeRate": "0.0001",
473
+ // "maxWithdraw": "",
474
+ // "minDeposit": "",
475
+ // "minWithdraw": "",
476
+ // "maxFastWithdrawAmount": "1",
477
+ // "minFastWithdrawAmount": "1",
478
+ // "isGray": false
479
+ // }
480
+ // ]
481
+ // }
482
+ // ]
483
+ // }
484
+ const rows = this.safeList(spotConfig, 'assets', []);
485
+ const chains = this.safeList(multiChain, 'chains', []);
486
+ const result = {};
487
+ for (let i = 0; i < rows.length; i++) {
488
+ const currency = rows[i];
489
+ const currencyId = this.safeString(currency, 'token');
490
+ const code = this.safeCurrencyCode(currencyId);
491
+ const name = this.safeString(currency, 'displayName');
492
+ const networks = {};
493
+ let minPrecision = undefined;
494
+ let minWithdrawFeeString = undefined;
495
+ let minWithdrawString = undefined;
496
+ let deposit = false;
497
+ let withdraw = false;
498
+ for (let j = 0; j < chains.length; j++) {
499
+ const chain = chains[j];
500
+ const tokens = this.safeList(chain, 'tokens', []);
501
+ for (let f = 0; f < tokens.length; f++) {
502
+ const token = tokens[f];
503
+ const tokenName = this.safeString(token, 'token');
504
+ if (tokenName === currencyId) {
505
+ const networkId = this.safeString(chain, 'chainId');
506
+ const networkCode = this.networkIdToCode(networkId);
507
+ const precision = this.parseNumber(this.parsePrecision(this.safeString(currency, 'decimals')));
508
+ minPrecision = (minPrecision === undefined) ? precision : Math.min(minPrecision, precision);
509
+ const depositAllowed = !this.safeBool(chain, 'stopDeposit');
510
+ deposit = (depositAllowed) ? depositAllowed : deposit;
511
+ const withdrawAllowed = this.safeBool(token, 'withdrawEnable');
512
+ withdraw = (withdrawAllowed) ? withdrawAllowed : withdraw;
513
+ minWithdrawFeeString = this.safeString(token, 'minFee');
514
+ minWithdrawString = this.safeString(token, 'minWithdraw');
515
+ const minNetworkDepositString = this.safeString(chain, 'depositMin');
516
+ networks[networkCode] = {
517
+ 'info': chain,
518
+ 'id': networkId,
519
+ 'network': networkCode,
520
+ 'active': depositAllowed && withdrawAllowed,
521
+ 'deposit': depositAllowed,
522
+ 'withdraw': withdrawAllowed,
523
+ 'fee': this.parseNumber(minWithdrawFeeString),
524
+ 'precision': precision,
525
+ 'limits': {
526
+ 'withdraw': {
527
+ 'min': this.parseNumber(minWithdrawString),
528
+ 'max': undefined,
529
+ },
530
+ 'deposit': {
531
+ 'min': this.parseNumber(minNetworkDepositString),
532
+ 'max': undefined,
533
+ },
534
+ },
535
+ };
536
+ }
537
+ }
538
+ }
539
+ result[code] = {
540
+ 'info': currency,
541
+ 'code': code,
542
+ 'id': currencyId,
543
+ 'type': 'crypto',
544
+ 'name': name,
545
+ 'active': deposit && withdraw,
546
+ 'deposit': deposit,
547
+ 'withdraw': withdraw,
548
+ 'fee': this.parseNumber(minWithdrawFeeString),
549
+ 'precision': minPrecision,
550
+ 'limits': {
551
+ 'amount': {
552
+ 'min': undefined,
553
+ 'max': undefined,
554
+ },
555
+ 'withdraw': {
556
+ 'min': this.parseNumber(minWithdrawString),
557
+ 'max': undefined,
558
+ },
559
+ 'deposit': {
560
+ 'min': undefined,
561
+ 'max': undefined,
562
+ },
563
+ },
564
+ 'networks': networks,
565
+ };
566
+ }
567
+ return result;
568
+ }
569
+ /**
570
+ * @method
571
+ * @name apex#fetchMarkets
572
+ * @description retrieves data on all markets for apex
573
+ * @see https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-all-config-data-v3
574
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
575
+ * @returns {object[]} an array of objects representing market data
576
+ */
577
+ async fetchMarkets(params = {}) {
578
+ const response = await this.publicGetV3Symbols(params);
579
+ const data = this.safeDict(response, 'data', {});
580
+ const contractConfig = this.safeDict(data, 'contractConfig', {});
581
+ const perpetualContract = this.safeList(contractConfig, 'perpetualContract', []);
582
+ // {
583
+ // "perpetualContract":[
584
+ // {
585
+ // "baselinePositionValue": "50000.0000",
586
+ // "crossId": 30002,
587
+ // "crossSymbolId": 10,
588
+ // "crossSymbolName": "BTCUSDT",
589
+ // "digitMerge": "0.1,0.2,0.4,1,2",
590
+ // "displayMaxLeverage": "100",
591
+ // "displayMinLeverage": "1",
592
+ // "enableDisplay": true,
593
+ // "enableOpenPosition": true,
594
+ // "enableTrade": true,
595
+ // "fundingImpactMarginNotional": "6",
596
+ // "fundingInterestRate": "0.0003",
597
+ // "incrementalInitialMarginRate": "0.00250",
598
+ // "incrementalMaintenanceMarginRate": "0.00100",
599
+ // "incrementalPositionValue": "50000.0000",
600
+ // "initialMarginRate": "0.01",
601
+ // "maintenanceMarginRate": "0.005",
602
+ // "maxOrderSize": "50",
603
+ // "maxPositionSize": "100",
604
+ // "minOrderSize": "0.0010",
605
+ // "maxMarketPriceRange": "0.025",
606
+ // "settleAssetId": "USDT",
607
+ // "baseTokenId": "BTC",
608
+ // "stepSize": "0.001",
609
+ // "symbol": "BTC-USDT",
610
+ // "symbolDisplayName": "BTCUSDT",
611
+ // "tickSize": "0.1",
612
+ // "maxMaintenanceMarginRate": "0.5000",
613
+ // "maxPositionValue": "5000000.0000",
614
+ // "tagIconUrl": "https://static-pro.apex.exchange/icon/LABLE_HOT.svg",
615
+ // "tag": "HOT",
616
+ // "riskTip": false,
617
+ // "defaultInitialMarginRate": "0.05",
618
+ // "klineStartTime": 0,
619
+ // "maxMarketSizeBuffer": "0.98",
620
+ // "enableFundingSettlement": true,
621
+ // "indexPriceDecimals": 2,
622
+ // "indexPriceVarRate": "0.001",
623
+ // "openPositionOiLimitRate": "0.05",
624
+ // "fundingMaxRate": "0.000234",
625
+ // "fundingMinRate": "-0.000234",
626
+ // "fundingMaxValue": "",
627
+ // "enableFundingMxValue": true,
628
+ // "l2PairId": "50001",
629
+ // "settleTimeStamp": 0,
630
+ // "isPrelaunch": false,
631
+ // "riskLimitConfig": {},
632
+ // "category": "L1"
633
+ // }
634
+ // ]
635
+ // }
636
+ return this.parseMarkets(perpetualContract);
637
+ }
638
+ parseMarket(market) {
639
+ const id = this.safeString(market, 'symbol');
640
+ const id2 = this.safeString(market, 'crossSymbolName');
641
+ const quoteId = this.safeString(market, 'l2PairId');
642
+ const baseId = this.safeString(market, 'baseTokenId');
643
+ const quote = this.safeString(market, 'settleAssetId');
644
+ const base = this.safeCurrencyCode(baseId);
645
+ const settleId = this.safeString(market, 'settleAssetId');
646
+ const settle = this.safeCurrencyCode(settleId);
647
+ const symbol = baseId + '/' + quote + ':' + settle;
648
+ const takerFee = this.parseNumber('0.0002');
649
+ const makerFee = this.parseNumber('0.0005');
650
+ return this.safeMarketStructure({
651
+ 'id': id,
652
+ 'id2': id2,
653
+ 'symbol': symbol,
654
+ 'base': base,
655
+ 'quote': quote,
656
+ 'settle': settle,
657
+ 'baseId': baseId,
658
+ 'quoteId': quoteId,
659
+ 'settleId': settleId,
660
+ 'type': 'swap',
661
+ 'spot': false,
662
+ 'margin': undefined,
663
+ 'swap': true,
664
+ 'future': false,
665
+ 'option': false,
666
+ 'active': this.safeBool(market, 'enableTrade'),
667
+ 'contract': true,
668
+ 'linear': true,
669
+ 'inverse': false,
670
+ 'taker': takerFee,
671
+ 'maker': makerFee,
672
+ 'contractSize': this.safeNumber(market, 'minOrderSize'),
673
+ 'expiry': undefined ,
674
+ 'expiryDatetime': undefined ,
675
+ 'strike': undefined,
676
+ 'optionType': undefined,
677
+ 'precision': {
678
+ 'amount': this.safeNumber(market, 'stepSize'),
679
+ 'price': this.safeNumber(market, 'tickSize'),
680
+ },
681
+ 'limits': {
682
+ 'leverage': {
683
+ 'min': this.safeNumber(market, 'displayMinLeverage'),
684
+ 'max': this.safeNumber(market, 'displayMaxLeverage'),
685
+ },
686
+ 'amount': {
687
+ 'min': this.safeNumber(market, 'minOrderSize'),
688
+ 'max': this.safeNumber(market, 'maxOrderSize'),
689
+ },
690
+ 'price': {
691
+ 'min': undefined,
692
+ 'max': undefined,
693
+ },
694
+ 'cost': {
695
+ 'min': undefined,
696
+ 'max': undefined,
697
+ },
698
+ },
699
+ 'created': undefined,
700
+ 'info': market,
701
+ });
702
+ }
703
+ parseTicker(ticker, market = undefined) {
704
+ //
705
+ // {
706
+ // "symbol": "BTCUSDT",
707
+ // "price24hPcnt": "0.450141",
708
+ // "lastPrice": "43511.50",
709
+ // "highPrice24h": "43513.50",
710
+ // "lowPrice24h": "29996.00",
711
+ // "markPrice": "43513.50",
712
+ // "indexPrice": "40828.94",
713
+ // "openInterest": "2036854775808",
714
+ // "turnover24h": "5626085.23749999",
715
+ // "volume24h": "169.317",
716
+ // "fundingRate": "0",
717
+ // "predictedFundingRate": "0",
718
+ // "nextFundingTime": "10:00:00",
719
+ // "tradeCount": 100
720
+ // }
721
+ //
722
+ const timestamp = this.milliseconds();
723
+ const marketId = this.safeString(ticker, 'symbol');
724
+ market = this.safeMarket(marketId, market);
725
+ const symbol = this.safeSymbol(marketId, market);
726
+ const last = this.safeString(ticker, 'lastPrice');
727
+ const percentage = this.safeString(ticker, 'price24hPcnt');
728
+ const quoteVolume = this.safeString(ticker, 'turnover24h');
729
+ const baseVolume = this.safeString(ticker, 'volume24h');
730
+ const high = this.safeString(ticker, 'highPrice24h');
731
+ const low = this.safeString(ticker, 'lowPrice24h');
732
+ return this.safeTicker({
733
+ 'symbol': symbol,
734
+ 'timestamp': timestamp,
735
+ 'datetime': this.iso8601(timestamp),
736
+ 'high': high,
737
+ 'low': low,
738
+ 'bid': undefined,
739
+ 'bidVolume': undefined,
740
+ 'ask': undefined,
741
+ 'askVolume': undefined,
742
+ 'vwap': undefined,
743
+ 'open': undefined,
744
+ 'close': last,
745
+ 'last': last,
746
+ 'previousClose': undefined,
747
+ 'change': undefined,
748
+ 'percentage': percentage,
749
+ 'average': undefined,
750
+ 'baseVolume': baseVolume,
751
+ 'quoteVolume': quoteVolume,
752
+ 'markPrice': this.safeString(ticker, 'markPrice'),
753
+ 'indexPrice': this.safeString(ticker, 'indexPrice'),
754
+ 'info': ticker,
755
+ }, market);
756
+ }
757
+ /**
758
+ * @method
759
+ * @name apex#fetchTicker
760
+ * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
761
+ * @see https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-ticker-data-v3
762
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
763
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
764
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
765
+ */
766
+ async fetchTicker(symbol, params = {}) {
767
+ await this.loadMarkets();
768
+ const market = this.market(symbol);
769
+ const request = {
770
+ 'symbol': market['id2'],
771
+ };
772
+ const response = await this.publicGetV3Ticker(this.extend(request, params));
773
+ const tickers = this.safeList(response, 'data', []);
774
+ const rawTicker = this.safeDict(tickers, 0, {});
775
+ return this.parseTicker(rawTicker, market);
776
+ }
777
+ /**
778
+ * @method
779
+ * @name apex#fetchTickers
780
+ * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
781
+ * @see https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-ticker-data-v3
782
+ * @param {string} symbols unified symbol of the market to fetch the ticker for
783
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
784
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
785
+ */
786
+ async fetchTickers(symbols = undefined, params = {}) {
787
+ await this.loadMarkets();
788
+ const response = await this.publicGetV3DataAllTickerInfo(params);
789
+ const tickers = this.safeList(response, 'data', []);
790
+ return this.parseTickers(tickers, symbols);
791
+ }
792
+ /**
793
+ * @method
794
+ * @name apex#fetchOHLCV
795
+ * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
796
+ * @see https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-candlestick-chart-data-v3
797
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
798
+ * @param {string} timeframe the length of time each candle represents
799
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
800
+ * @param {int} [limit] the maximum amount of candles to fetch
801
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
802
+ * @param {int} [params.until] timestamp in ms of the latest candle to fetch
803
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
804
+ */
805
+ async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
806
+ await this.loadMarkets();
807
+ const market = this.market(symbol);
808
+ let request = {
809
+ 'interval': this.safeString(this.timeframes, timeframe, timeframe),
810
+ 'symbol': market['id2'],
811
+ };
812
+ if (limit === undefined) {
813
+ limit = 200; // default is 200 when requested with `since`
814
+ }
815
+ request['limit'] = limit; // max 200, default 200
816
+ [request, params] = this.handleUntilOption('end', request, params);
817
+ if (since !== undefined) {
818
+ request['start'] = since;
819
+ }
820
+ const response = await this.publicGetV3Klines(this.extend(request, params));
821
+ const data = this.safeDict(response, 'data', {});
822
+ const OHLCVs = this.safeList(data, market['id2'], []);
823
+ return this.parseOHLCVs(OHLCVs, market, timeframe, since, limit);
824
+ }
825
+ parseOHLCV(ohlcv, market = undefined) {
826
+ //
827
+ // {
828
+ // "start": 1647511440000,
829
+ // "symbol": "BTC-USD",
830
+ // "interval": "1",
831
+ // "low": "40000",
832
+ // "high": "45000",
833
+ // "open": "45000",
834
+ // "close": "40000",
835
+ // "volume": "1.002",
836
+ // "turnover": "3"
837
+ // } {"s":"BTCUSDT","i":"1","t":1741265880000,"c":"90235","h":"90235","l":"90156","o":"90156","v":"0.052","tr":"4690.4466"}
838
+ //
839
+ return [
840
+ this.safeIntegerN(ohlcv, ['start', 't']),
841
+ this.safeNumberN(ohlcv, ['open', 'o']),
842
+ this.safeNumberN(ohlcv, ['high', 'h']),
843
+ this.safeNumberN(ohlcv, ['low', 'l']),
844
+ this.safeNumberN(ohlcv, ['close', 'c']),
845
+ this.safeNumberN(ohlcv, ['volume', 'v']),
846
+ ];
847
+ }
848
+ /**
849
+ * @method
850
+ * @name apex#fetchOrderBook
851
+ * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
852
+ * @see https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-market-depth-v3
853
+ * @param {string} symbol unified symbol of the market to fetch the order book for
854
+ * @param {int} [limit] the maximum amount of order book entries to return
855
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
856
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
857
+ */
858
+ async fetchOrderBook(symbol, limit = undefined, params = {}) {
859
+ await this.loadMarkets();
860
+ const market = this.market(symbol);
861
+ const request = {
862
+ 'symbol': market['id2'],
863
+ };
864
+ if (limit === undefined) {
865
+ limit = 100; // default is 200 when requested with `since`
866
+ }
867
+ request['limit'] = limit; // max 100, default 100
868
+ const response = await this.publicGetV3Depth(this.extend(request, params));
869
+ //
870
+ // {
871
+ // "a": [
872
+ // [
873
+ // "96576.3",
874
+ // "0.399"
875
+ // ],
876
+ // [
877
+ // "96577.6",
878
+ // "0.106"
879
+ // ]
880
+ // ],
881
+ // "b": [
882
+ // [
883
+ // "96565.2",
884
+ // "0.131"
885
+ // ],
886
+ // [
887
+ // "96565.1",
888
+ // "0.038"
889
+ // ]
890
+ // ],
891
+ // "s": "BTCUSDT",
892
+ // "u": 18665465
893
+ // }
894
+ //
895
+ const data = this.safeDict(response, 'data', {});
896
+ const timestamp = this.milliseconds();
897
+ const orderbook = this.parseOrderBook(data, market['symbol'], timestamp, 'b', 'a');
898
+ orderbook['nonce'] = this.safeInteger(data, 'u');
899
+ return orderbook;
900
+ }
901
+ /**
902
+ * @method
903
+ * @name apex#fetchTrades
904
+ * @description get the list of most recent trades for a particular symbol
905
+ * @see https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-newest-trading-data-v3
906
+ * @param {string} symbol unified symbol of the market to fetch trades for
907
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
908
+ * @param {int} [limit] the maximum amount of trades to fetch
909
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
910
+ * @param {int} [params.until] the latest time in ms to fetch trades for
911
+ * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times
912
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
913
+ */
914
+ async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
915
+ await this.loadMarkets();
916
+ const market = this.market(symbol);
917
+ const request = {
918
+ 'symbol': market['id2'],
919
+ };
920
+ if (limit === undefined) {
921
+ limit = 500; // default is 50
922
+ }
923
+ request['limit'] = limit;
924
+ const response = await this.publicGetV3Trades(this.extend(request, params));
925
+ //
926
+ // [
927
+ // {
928
+ // "i": "993f7f85-9215-5723-9078-2186ae140847",
929
+ // "p": "96534.3",
930
+ // "S": "Sell",
931
+ // "v": "0.261",
932
+ // "s": "BTCUSDT",
933
+ // "T": 1739118072710
934
+ // },
935
+ // {
936
+ // "i": "c947c9cf-8c18-5784-89c3-91bdf86ddde8",
937
+ // "p": "96513.5",
938
+ // "S": "Sell",
939
+ // "v": "0.042",
940
+ // "s": "BTCUSDT",
941
+ // "T": 1739118075944
942
+ // }
943
+ // ]
944
+ //
945
+ const trades = this.safeList(response, 'data', []);
946
+ return this.parseTrades(trades, market, since, limit);
947
+ }
948
+ parseTrade(trade, market = undefined) {
949
+ //
950
+ // [
951
+ // {
952
+ // "i": "993f7f85-9215-5723-9078-2186ae140847",
953
+ // "p": "96534.3",
954
+ // "S": "Sell",
955
+ // "v": "0.261",
956
+ // "s": "BTCUSDT",
957
+ // "T": 1739118072710
958
+ // }
959
+ // ]
960
+ //
961
+ const marketId = this.safeStringN(trade, ['s', 'symbol']);
962
+ market = this.safeMarket(marketId, market);
963
+ const id = this.safeStringN(trade, ['i', 'id']);
964
+ const timestamp = this.safeIntegerN(trade, ['t', 'T', 'createdAt']);
965
+ const priceString = this.safeStringN(trade, ['p', 'price']);
966
+ const amountString = this.safeStringN(trade, ['v', 'size']);
967
+ const side = this.safeStringLowerN(trade, ['S', 'side']);
968
+ const type = this.safeStringN(trade, ['type']);
969
+ const fee = this.safeStringN(trade, ['fee']);
970
+ return this.safeTrade({
971
+ 'info': trade,
972
+ 'id': id,
973
+ 'order': undefined,
974
+ 'timestamp': timestamp,
975
+ 'datetime': this.iso8601(timestamp),
976
+ 'symbol': market['symbol'],
977
+ 'type': type,
978
+ 'takerOrMaker': undefined,
979
+ 'side': side,
980
+ 'price': priceString,
981
+ 'amount': amountString,
982
+ 'cost': undefined,
983
+ 'fee': fee,
984
+ }, market);
985
+ }
986
+ /**
987
+ * @method
988
+ * @name apex#fetchOpenInterest
989
+ * @description retrieves the open interest of a contract trading pair
990
+ * @see https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-ticker-data-v3
991
+ * @param {string} symbol unified CCXT market symbol
992
+ * @param {object} [params] exchange specific parameters
993
+ * @returns {object} an open interest structure{@link https://docs.ccxt.com/#/?id=open-interest-structure}
994
+ */
995
+ async fetchOpenInterest(symbol, params = {}) {
996
+ await this.loadMarkets();
997
+ const market = this.market(symbol);
998
+ const request = {
999
+ 'symbol': market['id2'],
1000
+ };
1001
+ const response = await this.publicGetV3Ticker(this.extend(request, params));
1002
+ const tickers = this.safeList(response, 'data', []);
1003
+ const rawTicker = this.safeDict(tickers, 0, {});
1004
+ return this.parseOpenInterest(rawTicker, market);
1005
+ }
1006
+ parseOpenInterest(interest, market = undefined) {
1007
+ //
1008
+ // {
1009
+ // "symbol": "BTCUSDT",
1010
+ // "price24hPcnt": "0.450141",
1011
+ // "lastPrice": "43511.50",
1012
+ // "highPrice24h": "43513.50",
1013
+ // "lowPrice24h": "29996.00",
1014
+ // "markPrice": "43513.50",
1015
+ // "indexPrice": "40828.94",
1016
+ // "openInterest": "2036854775808",
1017
+ // "turnover24h": "5626085.23749999",
1018
+ // "volume24h": "169.317",
1019
+ // "fundingRate": "0",
1020
+ // "predictedFundingRate": "0",
1021
+ // "nextFundingTime": "10:00:00",
1022
+ // "tradeCount": 100
1023
+ // }
1024
+ //
1025
+ const timestamp = this.milliseconds();
1026
+ const marketId = this.safeString(interest, 'symbol');
1027
+ market = this.safeMarket(marketId, market);
1028
+ const symbol = this.safeSymbol(marketId, market);
1029
+ return this.safeOpenInterest({
1030
+ 'symbol': symbol,
1031
+ 'openInterestAmount': this.safeString(interest, 'openInterest'),
1032
+ 'openInterestValue': undefined,
1033
+ 'timestamp': timestamp,
1034
+ 'datetime': this.iso8601(timestamp),
1035
+ 'info': interest,
1036
+ }, market);
1037
+ }
1038
+ /**
1039
+ * @method
1040
+ * @name apex#fetchFundingRateHistory
1041
+ * @description fetches historical funding rate prices
1042
+ * @see https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-funding-rate-history-v3
1043
+ * @param {string} symbol unified symbol of the market to fetch the funding rate history for
1044
+ * @param {int} [since] timestamp in ms of the earliest funding rate to fetch
1045
+ * @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch
1046
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1047
+ * @param {int} [params.until] timestamp in ms of the latest funding rate
1048
+ * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
1049
+ * @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure}
1050
+ */
1051
+ async fetchFundingRateHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1052
+ if (symbol === undefined) {
1053
+ throw new errors.ArgumentsRequired(this.id + ' fetchFundingRateHistory() requires a symbol argument');
1054
+ }
1055
+ await this.loadMarkets();
1056
+ const request = {};
1057
+ const market = this.market(symbol);
1058
+ request['symbol'] = market['id'];
1059
+ if (since !== undefined) {
1060
+ request['beginTimeInclusive'] = since;
1061
+ }
1062
+ if (limit !== undefined) {
1063
+ request['limit'] = limit;
1064
+ }
1065
+ const page = this.safeInteger(params, 'page');
1066
+ if (page !== undefined) {
1067
+ request['page'] = page;
1068
+ }
1069
+ const endTimeExclusive = this.safeIntegerN(params, ['endTime', 'endTimeExclusive', 'until']);
1070
+ if (endTimeExclusive !== undefined) {
1071
+ request['endTimeExclusive'] = endTimeExclusive;
1072
+ }
1073
+ const response = await this.publicGetV3HistoryFunding(this.extend(request, params));
1074
+ //
1075
+ // {
1076
+ // "historyFunds": [
1077
+ // {
1078
+ // "symbol": "BTC-USD",
1079
+ // "rate": "0.0000125000",
1080
+ // "price": "31297.5000008009374142",
1081
+ // "fundingTime": 12315555,
1082
+ // "fundingTimestamp": 12315555
1083
+ // }
1084
+ // ],
1085
+ // "totalSize": 11
1086
+ // }
1087
+ //
1088
+ const rates = [];
1089
+ const data = this.safeDict(response, 'data', {});
1090
+ const resultList = this.safeList(data, 'historyFunds', []);
1091
+ for (let i = 0; i < resultList.length; i++) {
1092
+ const entry = resultList[i];
1093
+ const timestamp = this.safeInteger(entry, 'fundingTimestamp');
1094
+ rates.push({
1095
+ 'info': entry,
1096
+ 'symbol': this.safeString(entry, 'symbol'),
1097
+ 'fundingRate': this.safeNumber(entry, 'rate'),
1098
+ 'timestamp': timestamp,
1099
+ 'datetime': this.iso8601(timestamp),
1100
+ });
1101
+ }
1102
+ const sorted = this.sortBy(rates, 'timestamp');
1103
+ return this.filterBySymbolSinceLimit(sorted, symbol, since, limit);
1104
+ }
1105
+ parseOrder(order, market = undefined) {
1106
+ //
1107
+ // {
1108
+ // "id": "1234",
1109
+ // "clientId": "1234",
1110
+ // "accountId": "12345",
1111
+ // "symbol": "BTC-USD",
1112
+ // "side": "SELL",
1113
+ // "price": "18000",
1114
+ // "limitFee": "100",
1115
+ // "fee": "100",
1116
+ // "triggerPrice": "1.2",
1117
+ // "trailingPercent": "0.12",
1118
+ // "size": "100",
1119
+ // "remainingSize": "100",
1120
+ // "type": "LIMIT",
1121
+ // "createdAt": 1647502440973,
1122
+ // "updatedTime": 1647502440973,
1123
+ // "expiresAt": 1647502440973,
1124
+ // "status": "PENDING",
1125
+ // "timeInForce": "GOOD_TIL_CANCEL",
1126
+ // "postOnly": false,
1127
+ // "reduceOnly": false,
1128
+ // "stopPnl": false,
1129
+ // "latestMatchFillPrice": "reason",
1130
+ // "cumMatchFillSize": "0.1",
1131
+ // "cumMatchFillValue": "1000",
1132
+ // "cumMatchFillFee": "1",
1133
+ // "cumSuccessFillSize": "0.1",
1134
+ // "cumSuccessFillValue": "1000",
1135
+ // "cumSuccessFillFee": "1",
1136
+ // "triggerPriceType": "INDEX",
1137
+ // "isOpenTpslOrder": true,
1138
+ // "isSetOpenTp": true,
1139
+ // "isSetOpenSl": false,
1140
+ // "openTpParam": {
1141
+ // "side": "SELL",
1142
+ // "price": "18000",
1143
+ // "limitFee": "100",
1144
+ // "clientOrderId": "111100",
1145
+ // "triggerPrice": "1.2",
1146
+ // "trailingPercent": "0.12",
1147
+ // "size": "100"
1148
+ // },
1149
+ // "openSlParam": {
1150
+ // "side": "SELL",
1151
+ // "price": "18000",
1152
+ // "limitFee": "100",
1153
+ // "clientOrderId": "111100",
1154
+ // "triggerPrice": "1.2",
1155
+ // "trailingPercent": "0.12",
1156
+ // "size": "100"
1157
+ // }
1158
+ // }
1159
+ //
1160
+ const timestamp = this.safeInteger(order, 'createdAt');
1161
+ const orderId = this.safeString(order, 'id');
1162
+ const clientOrderId = this.safeString(order, 'clientId');
1163
+ const marketId = this.safeString(order, 'symbol');
1164
+ market = this.safeMarket(marketId, market);
1165
+ const symbol = market['symbol'];
1166
+ const price = this.safeString(order, 'price');
1167
+ const amount = this.safeString(order, 'size');
1168
+ const orderType = this.safeString(order, 'type');
1169
+ const status = this.safeString(order, 'status');
1170
+ const side = this.safeStringLower(order, 'side');
1171
+ // const average = this.omitZero (this.safeString (order, 'avg_fill_price'));
1172
+ const remaining = this.omitZero(this.safeString(order, 'remainingSize'));
1173
+ const lastUpdateTimestamp = this.safeInteger(order, 'updatedTime');
1174
+ return this.safeOrder({
1175
+ 'id': orderId,
1176
+ 'clientOrderId': clientOrderId,
1177
+ 'timestamp': timestamp,
1178
+ 'datetime': this.iso8601(timestamp),
1179
+ 'lastTradeTimestamp': undefined,
1180
+ 'lastUpdateTimestamp': lastUpdateTimestamp,
1181
+ 'status': this.parseOrderStatus(status),
1182
+ 'symbol': symbol,
1183
+ 'type': this.parseOrderType(orderType),
1184
+ 'timeInForce': this.parseTimeInForce(this.safeString(order, 'timeInForce')),
1185
+ 'postOnly': this.safeBool(order, 'postOnly'),
1186
+ 'reduceOnly': this.safeBool(order, 'reduceOnly'),
1187
+ 'side': side,
1188
+ 'price': price,
1189
+ 'triggerPrice': this.safeString(order, 'triggerPrice'),
1190
+ 'takeProfitPrice': undefined,
1191
+ 'stopLossPrice': undefined,
1192
+ 'average': undefined,
1193
+ 'amount': amount,
1194
+ 'filled': undefined,
1195
+ 'remaining': remaining,
1196
+ 'cost': undefined,
1197
+ 'trades': undefined,
1198
+ 'fee': {
1199
+ 'cost': this.safeString(order, 'fee'),
1200
+ 'currency': market['settleId'],
1201
+ },
1202
+ 'info': order,
1203
+ }, market);
1204
+ }
1205
+ parseTimeInForce(timeInForce) {
1206
+ const timeInForces = {
1207
+ 'GOOD_TIL_CANCEL': 'GOOD_TIL_CANCEL',
1208
+ 'FILL_OR_KILL': 'FILL_OR_KILL',
1209
+ 'IMMEDIATE_OR_CANCEL': 'IMMEDIATE_OR_CANCEL',
1210
+ 'POST_ONLY': 'POST_ONLY',
1211
+ };
1212
+ return this.safeString(timeInForces, timeInForce, undefined);
1213
+ }
1214
+ parseOrderStatus(status) {
1215
+ if (status !== undefined) {
1216
+ const statuses = {
1217
+ 'PENDING': 'open',
1218
+ 'OPEN': 'open',
1219
+ 'FILLED': 'filled',
1220
+ 'CANCELING': 'canceled',
1221
+ 'CANCELED': 'canceled',
1222
+ 'UNTRIGGERED': 'open',
1223
+ };
1224
+ return this.safeString(statuses, status, status);
1225
+ }
1226
+ return status;
1227
+ }
1228
+ parseOrderType(type) {
1229
+ const types = {
1230
+ 'LIMIT': 'LIMIT',
1231
+ 'MARKET': 'MARKET',
1232
+ 'STOP_LIMIT': 'STOP_LIMIT',
1233
+ 'STOP_MARKET': 'STOP_MARKET',
1234
+ 'TAKE_PROFIT_LIMIT': 'TAKE_PROFIT_LIMIT',
1235
+ 'TAKE_PROFIT_MARKET': 'TAKE_PROFIT_MARKET',
1236
+ };
1237
+ return this.safeStringUpper(types, type, type);
1238
+ }
1239
+ safeMarket(marketId = undefined, market = undefined, delimiter = undefined, marketType = undefined) {
1240
+ if (market === undefined && marketId !== undefined) {
1241
+ if (marketId in this.markets) {
1242
+ market = this.markets[marketId];
1243
+ }
1244
+ else if (marketId in this.markets_by_id) {
1245
+ market = this.markets_by_id[marketId];
1246
+ }
1247
+ else {
1248
+ const newMarketId = this.addHyphenBeforeUsdt(marketId);
1249
+ if (newMarketId in this.markets_by_id) {
1250
+ const markets = this.markets_by_id[newMarketId];
1251
+ const numMarkets = markets.length;
1252
+ if (numMarkets > 0) {
1253
+ if (this.markets_by_id[newMarketId][0]['id2'] === marketId) {
1254
+ market = this.markets_by_id[newMarketId][0];
1255
+ }
1256
+ }
1257
+ }
1258
+ }
1259
+ }
1260
+ return super.safeMarket(marketId, market, delimiter, marketType);
1261
+ }
1262
+ generateRandomClientIdOmni(_accountId) {
1263
+ const accountId = _accountId || this.randNumber(12).toString();
1264
+ return 'apexomni-' + accountId + '-' + this.milliseconds().toString() + '-' + this.randNumber(6).toString();
1265
+ }
1266
+ addHyphenBeforeUsdt(symbol) {
1267
+ const uppercaseSymbol = symbol.toUpperCase();
1268
+ const index = uppercaseSymbol.indexOf('USDT');
1269
+ const symbolChar = this.safeString(symbol, index - 1);
1270
+ if (index > 0 && symbolChar !== '-') {
1271
+ return symbol.slice(0, index) + '-' + symbol.slice(index);
1272
+ }
1273
+ return symbol;
1274
+ }
1275
+ getSeeds() {
1276
+ const seeds = this.safeString(this.options, 'seeds');
1277
+ if (seeds === undefined) {
1278
+ throw new errors.ArgumentsRequired(this.id + ' the "seeds" key is required in the options to access private endpoints. You can find it in API Management > Omni Key, and then set it as exchange.options["seeds"] = XXXX');
1279
+ }
1280
+ return seeds;
1281
+ }
1282
+ async getAccountId() {
1283
+ const accountId = this.safeString(this.options, 'accountId', '0');
1284
+ if (accountId === '0') {
1285
+ const accountData = await this.fetchAccount();
1286
+ this.options['accountId'] = this.safeString(accountData, 'id', '0');
1287
+ }
1288
+ return this.options['accountId'];
1289
+ }
1290
+ /**
1291
+ * @method
1292
+ * @name apex#createOrder
1293
+ * @description create a trade order
1294
+ * @see https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-post-creating-orders
1295
+ * @param {string} symbol unified symbol of the market to create an order in
1296
+ * @param {string} type 'market' or 'limit'
1297
+ * @param {string} side 'buy' or 'sell'
1298
+ * @param {float} amount how much of currency you want to trade in units of base currency
1299
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1300
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1301
+ * @param {float} [params.triggerPrice] The price a trigger order is triggered at
1302
+ * @param {string} [params.timeInForce] "GTC", "IOC", or "POST_ONLY"
1303
+ * @param {bool} [params.postOnly] true or false
1304
+ * @param {bool} [params.reduceOnly] Ensures that the executed order does not flip the opened position.
1305
+ * @param {string} [params.clientOrderId] a unique id for the order
1306
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1307
+ */
1308
+ async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1309
+ await this.loadMarkets();
1310
+ const market = this.market(symbol);
1311
+ const orderType = type.toUpperCase();
1312
+ const orderSide = side.toUpperCase();
1313
+ const orderSize = this.amountToPrecision(symbol, amount);
1314
+ let orderPrice = '0';
1315
+ if (price !== undefined) {
1316
+ orderPrice = this.priceToPrecision(symbol, price);
1317
+ }
1318
+ const fees = this.safeDict(this.fees, 'swap', {});
1319
+ const taker = this.safeNumber(fees, 'taker', 0.0005);
1320
+ const maker = this.safeNumber(fees, 'maker', 0.0002);
1321
+ const limitFee = this.decimalToPrecision(Precise["default"].stringAdd(Precise["default"].stringMul(Precise["default"].stringMul(orderPrice, orderSize), taker.toString()), market['precision']['price'].toString()), number.TRUNCATE, market['precision']['price'], this.precisionMode, this.paddingMode);
1322
+ const timeNow = this.milliseconds();
1323
+ // const triggerPrice = this.safeString2 (params, 'triggerPrice', 'stopPrice');
1324
+ const isMarket = orderType === 'MARKET';
1325
+ if (isMarket && (price === undefined)) {
1326
+ throw new errors.ArgumentsRequired(this.id + ' createOrder() requires a price argument for market orders');
1327
+ }
1328
+ let timeInForce = this.safeStringUpper(params, 'timeInForce');
1329
+ const postOnly = this.isPostOnly(isMarket, undefined, params);
1330
+ if (timeInForce === undefined) {
1331
+ timeInForce = 'GOOD_TIL_CANCEL';
1332
+ }
1333
+ if (!isMarket) {
1334
+ if (postOnly) {
1335
+ timeInForce = 'POST_ONLY';
1336
+ }
1337
+ else if (timeInForce === 'ioc') {
1338
+ timeInForce = 'IMMEDIATE_OR_CANCEL';
1339
+ }
1340
+ }
1341
+ params = this.omit(params, 'timeInForce');
1342
+ params = this.omit(params, 'postOnly');
1343
+ let clientOrderId = this.safeStringN(params, ['clientId', 'clientOrderId', 'client_order_id']);
1344
+ const accountId = await this.getAccountId();
1345
+ if (clientOrderId === undefined) {
1346
+ clientOrderId = this.generateRandomClientIdOmni(accountId);
1347
+ }
1348
+ params = this.omit(params, ['clientId', 'clientOrderId', 'client_order_id']);
1349
+ const orderToSign = {
1350
+ 'accountId': accountId,
1351
+ 'slotId': clientOrderId,
1352
+ 'nonce': clientOrderId,
1353
+ 'pairId': market['quoteId'],
1354
+ 'size': orderSize,
1355
+ 'price': orderPrice,
1356
+ 'direction': orderSide,
1357
+ 'makerFeeRate': maker.toString(),
1358
+ 'takerFeeRate': taker.toString(),
1359
+ };
1360
+ const signature = await this.getZKContractSignatureObj(this.remove0xPrefix(this.getSeeds()), orderToSign);
1361
+ const request = {
1362
+ 'symbol': market['id'],
1363
+ 'side': orderSide,
1364
+ 'type': orderType,
1365
+ 'size': orderSize,
1366
+ 'price': orderPrice,
1367
+ 'limitFee': limitFee,
1368
+ 'expiration': Math.floor(timeNow / 1000 + 30 * 24 * 60 * 60),
1369
+ 'timeInForce': timeInForce,
1370
+ 'clientId': clientOrderId,
1371
+ 'brokerId': this.safeString(this.options, 'brokerId', '6956'),
1372
+ };
1373
+ request['signature'] = signature;
1374
+ const response = await this.privatePostV3Order(this.extend(request, params));
1375
+ const data = this.safeDict(response, 'data', {});
1376
+ return this.parseOrder(data, market);
1377
+ }
1378
+ /**
1379
+ * @method
1380
+ * @name apex#transfer
1381
+ * @description transfer currency internally between wallets on the same account
1382
+ * @param {string} code unified currency code
1383
+ * @param {float} amount amount to transfer
1384
+ * @param {string} fromAccount account to transfer from
1385
+ * @param {string} toAccount account to transfer to
1386
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1387
+ * @param {string} [params.transferId] UUID, which is unique across the platform
1388
+ * @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
1389
+ */
1390
+ async transfer(code, amount, fromAccount, toAccount, params = {}) {
1391
+ await this.loadMarkets();
1392
+ const configResponse = await this.publicGetV3Symbols(params);
1393
+ const configData = this.safeDict(configResponse, 'data', {});
1394
+ const contractConfig = this.safeDict(configData, 'contractConfig', {});
1395
+ const contractAssets = this.safeList(contractConfig, 'assets', []);
1396
+ const spotConfig = this.safeDict(configData, 'spotConfig', {});
1397
+ const spotAssets = this.safeList(spotConfig, 'assets', []);
1398
+ const globalConfig = this.safeDict(spotConfig, 'global', {});
1399
+ const receiverAddress = this.safeString(globalConfig, 'contractAssetPoolEthAddress', '');
1400
+ const receiverZkAccountId = this.safeString(globalConfig, 'contractAssetPoolZkAccountId', '');
1401
+ const receiverSubAccountId = this.safeString(globalConfig, 'contractAssetPoolSubAccount', '');
1402
+ const receiverAccountId = this.safeString(globalConfig, 'contractAssetPoolAccountId', '');
1403
+ const accountResponse = await this.privateGetV3Account(params);
1404
+ const accountData = this.safeDict(accountResponse, 'data', {});
1405
+ const spotAccount = this.safeDict(accountData, 'spotAccount', {});
1406
+ const zkAccountId = this.safeString(spotAccount, 'zkAccountId', '');
1407
+ const subAccountId = this.safeString(spotAccount, 'defaultSubAccountId', '0');
1408
+ const subAccounts = this.safeList(spotAccount, 'subAccounts', []);
1409
+ let nonce = '0';
1410
+ if (subAccounts.length > 0) {
1411
+ nonce = this.safeString(subAccounts[0], 'nonce', '0');
1412
+ }
1413
+ const ethAddress = this.safeString(accountData, 'ethereumAddress', '');
1414
+ const accountId = this.safeString(accountData, 'id', '');
1415
+ let currency = {};
1416
+ let assets = [];
1417
+ if (fromAccount !== undefined && fromAccount.toLowerCase() === 'contract') {
1418
+ assets = contractAssets;
1419
+ }
1420
+ else {
1421
+ assets = spotAssets;
1422
+ }
1423
+ for (let i = 0; i < assets.length; i++) {
1424
+ if (this.safeString(assets[i], 'token', '') === code) {
1425
+ currency = assets[i];
1426
+ }
1427
+ }
1428
+ const tokenId = this.safeString(currency, 'tokenId', '');
1429
+ const amountNumber = this.parseToInt(amount * (Math.pow(10, this.safeNumber(currency, 'decimals', 0))));
1430
+ const timestampSeconds = this.parseToInt(this.milliseconds() / 1000);
1431
+ let clientOrderId = this.safeStringN(params, ['clientId', 'clientOrderId', 'client_order_id']);
1432
+ if (clientOrderId === undefined) {
1433
+ clientOrderId = this.generateRandomClientIdOmni(this.safeString(this.options, 'accountId'));
1434
+ }
1435
+ params = this.omit(params, ['clientId', 'clientOrderId', 'client_order_id']);
1436
+ if (fromAccount !== undefined && fromAccount.toLowerCase() === 'contract') {
1437
+ const formattedUint32 = '4294967295';
1438
+ const zkSignAccountId = Precise["default"].stringMod(accountId, formattedUint32);
1439
+ const expireTime = timestampSeconds + 3600 * 24 * 28;
1440
+ const orderToSign = {
1441
+ 'zkAccountId': zkSignAccountId,
1442
+ 'receiverAddress': ethAddress,
1443
+ 'subAccountId': subAccountId,
1444
+ 'receiverSubAccountId': subAccountId,
1445
+ 'tokenId': tokenId,
1446
+ 'amount': amountNumber.toString(),
1447
+ 'fee': '0',
1448
+ 'nonce': clientOrderId,
1449
+ 'timestampSeconds': expireTime,
1450
+ 'isContract': true,
1451
+ };
1452
+ const signature = await this.getZKTransferSignatureObj(this.remove0xPrefix(this.getSeeds()), orderToSign);
1453
+ const request = {
1454
+ 'amount': amount,
1455
+ 'expireTime': expireTime,
1456
+ 'clientWithdrawId': clientOrderId,
1457
+ 'signature': signature,
1458
+ 'token': code,
1459
+ 'ethAddress': ethAddress,
1460
+ };
1461
+ const response = await this.privatePostV3ContractTransferOut(this.extend(request, params));
1462
+ const data = this.safeDict(response, 'data', {});
1463
+ const currentTime = this.milliseconds();
1464
+ return this.extend(this.parseTransfer(data, this.currency(code)), {
1465
+ 'timestamp': currentTime,
1466
+ 'datetime': this.iso8601(currentTime),
1467
+ 'amount': this.parseNumber(amount),
1468
+ 'fromAccount': 'contract',
1469
+ 'toAccount': 'spot',
1470
+ });
1471
+ }
1472
+ else {
1473
+ const orderToSign = {
1474
+ 'zkAccountId': zkAccountId,
1475
+ 'receiverAddress': receiverAddress,
1476
+ 'subAccountId': subAccountId,
1477
+ 'receiverSubAccountId': receiverSubAccountId,
1478
+ 'tokenId': tokenId,
1479
+ 'amount': amountNumber.toString(),
1480
+ 'fee': '0',
1481
+ 'nonce': nonce,
1482
+ 'timestampSeconds': timestampSeconds,
1483
+ };
1484
+ const signature = await this.getZKTransferSignatureObj(this.remove0xPrefix(this.getSeeds()), orderToSign);
1485
+ const request = {
1486
+ 'amount': amount.toString(),
1487
+ 'timestamp': timestampSeconds,
1488
+ 'clientTransferId': clientOrderId,
1489
+ 'signature': signature,
1490
+ 'zkAccountId': zkAccountId,
1491
+ 'subAccountId': subAccountId,
1492
+ 'fee': '0',
1493
+ 'token': code,
1494
+ 'tokenId': tokenId,
1495
+ 'receiverAccountId': receiverAccountId,
1496
+ 'receiverZkAccountId': receiverZkAccountId,
1497
+ 'receiverSubAccountId': receiverSubAccountId,
1498
+ 'receiverAddress': receiverAddress,
1499
+ 'nonce': nonce,
1500
+ };
1501
+ const response = await this.privatePostV3TransferOut(this.extend(request, params));
1502
+ const data = this.safeDict(response, 'data', {});
1503
+ const currentTime = this.milliseconds();
1504
+ return this.extend(this.parseTransfer(data, this.currency(code)), {
1505
+ 'timestamp': currentTime,
1506
+ 'datetime': this.iso8601(currentTime),
1507
+ 'amount': this.parseNumber(amount),
1508
+ 'fromAccount': 'spot',
1509
+ 'toAccount': 'contract',
1510
+ });
1511
+ }
1512
+ }
1513
+ parseTransfer(transfer, currency = undefined) {
1514
+ const currencyId = this.safeString(transfer, 'coin');
1515
+ const timestamp = this.safeInteger(transfer, 'timestamp');
1516
+ const fromAccount = this.safeString(transfer, 'fromAccount');
1517
+ const toAccount = this.safeString(transfer, 'toAccount');
1518
+ return {
1519
+ 'info': transfer,
1520
+ 'id': this.safeStringN(transfer, ['transferId', 'id']),
1521
+ 'timestamp': timestamp,
1522
+ 'datetime': this.iso8601(timestamp),
1523
+ 'currency': this.safeCurrencyCode(currencyId, currency),
1524
+ 'amount': this.safeNumber(transfer, 'amount'),
1525
+ 'fromAccount': fromAccount,
1526
+ 'toAccount': toAccount,
1527
+ 'status': this.safeString(transfer, 'status'),
1528
+ };
1529
+ }
1530
+ /**
1531
+ * @method
1532
+ * @name apex#cancelAllOrders
1533
+ * @description cancel all open orders in a market
1534
+ * @see https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-post-cancel-all-open-orders
1535
+ * @param {string} symbol unified market symbol of the market to cancel orders in
1536
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1537
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1538
+ */
1539
+ async cancelAllOrders(symbol = undefined, params = {}) {
1540
+ await this.loadMarkets();
1541
+ let market = undefined;
1542
+ const request = {};
1543
+ if (symbol !== undefined) {
1544
+ market = this.market(symbol);
1545
+ request['symbol'] = market['id'];
1546
+ }
1547
+ const response = await this.privatePostV3DeleteOpenOrders(this.extend(request, params));
1548
+ const data = this.safeDict(response, 'data', {});
1549
+ return data;
1550
+ }
1551
+ /**
1552
+ * @method
1553
+ * @name apex#cancelOrder
1554
+ * @description cancels an open order
1555
+ * @see https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-post-cancel-order
1556
+ * @param {string} id order id
1557
+ * @param symbol
1558
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1559
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1560
+ */
1561
+ async cancelOrder(id, symbol = undefined, params = {}) {
1562
+ const request = {};
1563
+ const clientOrderId = this.safeStringN(params, ['clientId', 'clientOrderId', 'client_order_id']);
1564
+ let response = undefined;
1565
+ if (clientOrderId !== undefined) {
1566
+ request['id'] = clientOrderId;
1567
+ params = this.omit(params, ['clientId', 'clientOrderId', 'client_order_id']);
1568
+ response = await this.privatePostV3DeleteClientOrderId(this.extend(request, params));
1569
+ }
1570
+ else {
1571
+ request['id'] = id;
1572
+ response = await this.privatePostV3DeleteOrder(this.extend(request, params));
1573
+ }
1574
+ const data = this.safeDict(response, 'data', {});
1575
+ return data;
1576
+ }
1577
+ /**
1578
+ * @method
1579
+ * @name apex#fetchOrder
1580
+ * @description fetches information on an order made by the user
1581
+ * @see https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-order-id
1582
+ * @see https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-order-by-clientorderid
1583
+ * @param {string} id the order id
1584
+ * @param {string} symbol unified symbol of the market the order was made in
1585
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1586
+ * @param {string} [params.clientOrderId] a unique id for the order
1587
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1588
+ */
1589
+ async fetchOrder(id, symbol = undefined, params = {}) {
1590
+ await this.loadMarkets();
1591
+ const request = {};
1592
+ const clientOrderId = this.safeStringN(params, ['clientId', 'clientOrderId', 'client_order_id']);
1593
+ let response = undefined;
1594
+ if (clientOrderId !== undefined) {
1595
+ request['id'] = clientOrderId;
1596
+ params = this.omit(params, ['clientId', 'clientOrderId', 'client_order_id']);
1597
+ response = await this.privateGetV3OrderByClientOrderId(this.extend(request, params));
1598
+ }
1599
+ else {
1600
+ request['id'] = id;
1601
+ response = await this.privateGetV3Order(this.extend(request, params));
1602
+ }
1603
+ const data = this.safeDict(response, 'data', {});
1604
+ return this.parseOrder(data);
1605
+ }
1606
+ /**
1607
+ * @method
1608
+ * @name apex#fetchOpenOrders
1609
+ * @description fetches information on multiple orders made by the user
1610
+ * @see https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-open-orders
1611
+ * @param {string} symbol unified market symbol of the market orders were made in
1612
+ * @param {int} [since] the earliest time in ms to fetch orders for
1613
+ * @param {int} [limit] the maximum number of order structures to retrieve
1614
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1615
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1616
+ */
1617
+ async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1618
+ await this.loadMarkets();
1619
+ const response = await this.privateGetV3OpenOrders(params);
1620
+ const orders = this.safeList(response, 'data', []);
1621
+ return this.parseOrders(orders, undefined, since, limit);
1622
+ }
1623
+ /**
1624
+ * @method
1625
+ * @name apex#fetchOrders
1626
+ * @description fetches information on multiple orders made by the user *classic accounts only*
1627
+ * @see https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-all-order-history
1628
+ * @param {string} symbol unified market symbol of the market orders were made in
1629
+ * @param {int} [since] the earliest time in ms to fetch orders for
1630
+ * @param {int} [limit] the maximum number of order structures to retrieve, default 100
1631
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1632
+ * @param {object} [params.until] end time, ms
1633
+ * @param {boolean} [params.status] "PENDING", "OPEN", "FILLED", "CANCELED", "EXPIRED", "UNTRIGGERED"
1634
+ * @param {boolean} [params.side] BUY or SELL
1635
+ * @param {string} [params.type] "LIMIT", "MARKET","STOP_LIMIT", "STOP_MARKET", "TAKE_PROFIT_LIMIT","TAKE_PROFIT_MARKET"
1636
+ * @param {string} [params.orderType] "ACTIVE","CONDITION","HISTORY"
1637
+ * @param {boolean} [params.page] Page numbers start from 0
1638
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1639
+ */
1640
+ async fetchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1641
+ await this.loadMarkets();
1642
+ const request = {};
1643
+ let market = undefined;
1644
+ if (symbol !== undefined) {
1645
+ market = this.market(symbol);
1646
+ request['symbol'] = market['id'];
1647
+ }
1648
+ if (since !== undefined) {
1649
+ request['beginTimeInclusive'] = since;
1650
+ }
1651
+ if (limit !== undefined) {
1652
+ request['limit'] = limit;
1653
+ }
1654
+ const endTimeExclusive = this.safeIntegerN(params, ['endTime', 'endTimeExclusive', 'until']);
1655
+ if (endTimeExclusive !== undefined) {
1656
+ request['endTimeExclusive'] = endTimeExclusive;
1657
+ params = this.omit(params, ['endTime', 'endTimeExclusive', 'until']);
1658
+ }
1659
+ const response = await this.privateGetV3HistoryOrders(this.extend(request, params));
1660
+ const data = this.safeDict(response, 'data', {});
1661
+ const orders = this.safeList(data, 'orders', []);
1662
+ return this.parseOrders(orders, market, since, limit);
1663
+ }
1664
+ /**
1665
+ * @method
1666
+ * @name apex#fetchOrderTrades
1667
+ * @description fetch all the trades made from a single order
1668
+ * @see https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-trade-history
1669
+ * @param {string} id order id
1670
+ * @param {string} symbol unified market symbol
1671
+ * @param {int} [since] the earliest time in ms to fetch trades for
1672
+ * @param {int} [limit] the maximum number of trades to retrieve
1673
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1674
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
1675
+ */
1676
+ async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
1677
+ await this.loadMarkets();
1678
+ const request = {};
1679
+ const clientOrderId = this.safeString2(params, 'clientOrderId', 'clientId');
1680
+ if (clientOrderId !== undefined) {
1681
+ request['clientOrderId'] = clientOrderId;
1682
+ }
1683
+ else {
1684
+ request['orderId'] = id;
1685
+ }
1686
+ params = this.omit(params, ['clientOrderId', 'clientId']);
1687
+ const response = await this.privateGetV3OrderFills(this.extend(request, params));
1688
+ const data = this.safeDict(response, 'data', {});
1689
+ const orders = this.safeList(data, 'orders', []);
1690
+ return this.parseTrades(orders, undefined, since, limit);
1691
+ }
1692
+ /**
1693
+ * @method
1694
+ * @name apex#fetchMyTrades
1695
+ * @description fetches information on multiple orders made by the user *classic accounts only*
1696
+ * @see https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-trade-history
1697
+ * @param {string} symbol unified market symbol of the market orders were made in
1698
+ * @param {int} [since] the earliest time in ms to fetch orders for
1699
+ * @param {int} [limit] the maximum number of order structures to retrieve, default 100
1700
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1701
+ * @param {object} [params.until] end time
1702
+ * @param {boolean} [params.side] BUY or SELL
1703
+ * @param {string} [params.orderType] "LIMIT", "MARKET","STOP_LIMIT", "STOP_MARKET", "TAKE_PROFIT_LIMIT","TAKE_PROFIT_MARKET"
1704
+ * @param {boolean} [params.page] Page numbers start from 0
1705
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
1706
+ */
1707
+ async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1708
+ await this.loadMarkets();
1709
+ const request = {};
1710
+ let market = undefined;
1711
+ if (symbol !== undefined) {
1712
+ market = this.market(symbol);
1713
+ request['symbol'] = market['id'];
1714
+ }
1715
+ if (since !== undefined) {
1716
+ request['beginTimeInclusive'] = since;
1717
+ }
1718
+ if (limit !== undefined) {
1719
+ request['limit'] = limit;
1720
+ }
1721
+ const endTimeExclusive = this.safeIntegerN(params, ['endTime', 'endTimeExclusive', 'until']);
1722
+ if (endTimeExclusive !== undefined) {
1723
+ request['endTimeExclusive'] = endTimeExclusive;
1724
+ params = this.omit(params, ['endTime', 'endTimeExclusive', 'until']);
1725
+ }
1726
+ const response = await this.privateGetV3Fills(this.extend(request, params));
1727
+ const data = this.safeDict(response, 'data', {});
1728
+ const orders = this.safeList(data, 'orders', []);
1729
+ return this.parseTrades(orders, market, since, limit);
1730
+ }
1731
+ /**
1732
+ * @method
1733
+ * @name apex#fetchFundingHistory
1734
+ * @description fetches information on multiple orders made by the user *classic accounts only*
1735
+ * @see https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-funding-rate
1736
+ * @param {string} symbol unified market symbol of the market orders were made in
1737
+ * @param {int} [since] the earliest time in ms to fetch orders for
1738
+ * @param {int} [limit] the maximum number of order structures to retrieve, default 100
1739
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1740
+ * @param {object} [params.until] end time, ms
1741
+ * @param {boolean} [params.side] BUY or SELL
1742
+ * @param {boolean} [params.page] Page numbers start from 0
1743
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=funding-history-structure}
1744
+ */
1745
+ async fetchFundingHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1746
+ await this.loadMarkets();
1747
+ const request = {};
1748
+ let market = undefined;
1749
+ if (symbol !== undefined) {
1750
+ market = this.market(symbol);
1751
+ request['symbol'] = market['id'];
1752
+ }
1753
+ if (since !== undefined) {
1754
+ request['beginTimeInclusive'] = since;
1755
+ }
1756
+ if (limit !== undefined) {
1757
+ request['limit'] = limit;
1758
+ }
1759
+ const endTimeExclusive = this.safeIntegerN(params, ['endTime', 'endTimeExclusive', 'until']);
1760
+ if (endTimeExclusive !== undefined) {
1761
+ params = this.omit(params, ['endTime', 'endTimeExclusive', 'until']);
1762
+ request['endTimeExclusive'] = endTimeExclusive;
1763
+ }
1764
+ const response = await this.privateGetV3Funding(this.extend(request, params));
1765
+ const data = this.safeDict(response, 'data', {});
1766
+ const fundingValues = this.safeList(data, 'fundingValues', []);
1767
+ return this.parseIncomes(fundingValues, market, since, limit);
1768
+ }
1769
+ parseIncome(income, market = undefined) {
1770
+ //
1771
+ // {
1772
+ // "id": "1234",
1773
+ // "symbol": "BTC-USDT",
1774
+ // "fundingValue": "10000",
1775
+ // "rate": "0.0000125000",
1776
+ // "positionSize": "500",
1777
+ // "price": "90",
1778
+ // "side": "LONG",
1779
+ // "status": "SUCCESS",
1780
+ // "fundingTime": 1647502440973,
1781
+ // "transactionId": "1234556"
1782
+ // }
1783
+ //
1784
+ const marketId = this.safeString(income, 'symbol');
1785
+ market = this.safeMarket(marketId, market, undefined, 'contract');
1786
+ const code = 'USDT';
1787
+ const timestamp = this.safeInteger(income, 'fundingTime');
1788
+ return {
1789
+ 'info': income,
1790
+ 'symbol': this.safeSymbol(marketId, market),
1791
+ 'code': code,
1792
+ 'timestamp': timestamp,
1793
+ 'datetime': this.iso8601(timestamp),
1794
+ 'id': this.safeString(income, 'id'),
1795
+ 'amount': this.safeNumber(income, 'fundingValue'),
1796
+ 'rate': this.safeNumber(income, 'rate'),
1797
+ };
1798
+ }
1799
+ /**
1800
+ * @method
1801
+ * @name apex#setLeverage
1802
+ * @description set the level of leverage for a market
1803
+ * @see https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-post-sets-the-initial-margin-rate-of-a-contract
1804
+ * @param {float} leverage the rate of leverage
1805
+ * @param {string} symbol unified market symbol
1806
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1807
+ * @returns {object} response from the exchange
1808
+ */
1809
+ async setLeverage(leverage, symbol = undefined, params = {}) {
1810
+ if (symbol === undefined) {
1811
+ throw new errors.ArgumentsRequired(this.id + ' setLeverage() requires a symbol argument');
1812
+ }
1813
+ await this.loadMarkets();
1814
+ const market = this.market(symbol);
1815
+ const leverageString = this.numberToString(leverage);
1816
+ const initialMarginRate = Precise["default"].stringDiv('1', leverageString, 4);
1817
+ const request = {
1818
+ 'symbol': market['id'],
1819
+ 'initialMarginRate': initialMarginRate,
1820
+ };
1821
+ const response = await this.privatePostV3SetInitialMarginRate(this.extend(request, params));
1822
+ const data = this.safeDict(response, 'data', {});
1823
+ return data;
1824
+ }
1825
+ /**
1826
+ * @method
1827
+ * @name apex#fetchPositions
1828
+ * @description fetch all open positions
1829
+ * @see https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-retrieve-user-account-data
1830
+ * @param {string[]} [symbols] list of unified market symbols
1831
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1832
+ * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
1833
+ */
1834
+ async fetchPositions(symbols = undefined, params = {}) {
1835
+ await this.loadMarkets();
1836
+ const response = await this.privateGetV3Account(params);
1837
+ const data = this.safeDict(response, 'data', {});
1838
+ const positions = this.safeList(data, 'positions', []);
1839
+ return this.parsePositions(positions, symbols);
1840
+ }
1841
+ parsePosition(position, market = undefined) {
1842
+ //
1843
+ // {
1844
+ // "symbol": "BTC-USDT",
1845
+ // "status": "",
1846
+ // "side": "LONG",
1847
+ // "size": "0.000",
1848
+ // "entryPrice": "0.00",
1849
+ // "exitPrice": "",
1850
+ // "createdAt": 1690366452416,
1851
+ // "updatedTime": 1690366452416,
1852
+ // "fee": "0.000000",
1853
+ // "fundingFee": "0.000000",
1854
+ // "lightNumbers": "",
1855
+ // "customInitialMarginRate": "0"
1856
+ // }
1857
+ const marketId = this.safeString(position, 'symbol');
1858
+ market = this.safeMarket(marketId, market);
1859
+ const symbol = market['symbol'];
1860
+ const side = this.safeStringLower(position, 'side');
1861
+ const quantity = this.safeString(position, 'size');
1862
+ const timestamp = this.safeInteger(position, 'updatedTime');
1863
+ let leverage = 20;
1864
+ const customInitialMarginRate = this.safeStringN(position, ['customInitialMarginRate', 'customImr'], '0');
1865
+ if (this.precisionFromString(customInitialMarginRate) !== 0) {
1866
+ leverage = this.parseToInt(Precise["default"].stringDiv('1', customInitialMarginRate, 4));
1867
+ }
1868
+ return this.safePosition({
1869
+ 'info': position,
1870
+ 'id': this.safeString(position, 'id'),
1871
+ 'symbol': symbol,
1872
+ 'entryPrice': this.safeString(position, 'entryPrice'),
1873
+ 'markPrice': undefined,
1874
+ 'notional': undefined,
1875
+ 'collateral': undefined,
1876
+ 'unrealizedPnl': undefined,
1877
+ 'side': side,
1878
+ 'contracts': this.parseNumber(quantity),
1879
+ 'contractSize': undefined,
1880
+ 'timestamp': timestamp,
1881
+ 'datetime': this.iso8601(timestamp),
1882
+ 'hedged': undefined,
1883
+ 'maintenanceMargin': undefined,
1884
+ 'maintenanceMarginPercentage': undefined,
1885
+ 'initialMargin': undefined,
1886
+ 'initialMarginPercentage': undefined,
1887
+ 'leverage': leverage,
1888
+ 'liquidationPrice': undefined,
1889
+ 'marginRatio': undefined,
1890
+ 'marginMode': undefined,
1891
+ 'percentage': undefined,
1892
+ });
1893
+ }
1894
+ sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
1895
+ let url = this.implodeHostname(this.urls['api'][api]) + '/' + path;
1896
+ headers = {
1897
+ 'User-Agent': 'apex-CCXT',
1898
+ 'Accept': 'application/json',
1899
+ 'Content-Type': 'application/x-www-form-urlencoded',
1900
+ };
1901
+ let signPath = '/api/' + path;
1902
+ let signBody = body;
1903
+ if (method.toUpperCase() !== 'POST') {
1904
+ if (Object.keys(params).length) {
1905
+ signPath += '?' + this.rawencode(params);
1906
+ url += '?' + this.rawencode(params);
1907
+ }
1908
+ }
1909
+ else {
1910
+ const sortedQuery = this.keysort(params);
1911
+ signBody = this.rawencode(sortedQuery);
1912
+ }
1913
+ if (api === 'private') {
1914
+ this.checkRequiredCredentials();
1915
+ const timestamp = this.milliseconds().toString();
1916
+ let messageString = timestamp + method.toUpperCase() + signPath;
1917
+ if (signBody !== undefined) {
1918
+ messageString = messageString + signBody;
1919
+ }
1920
+ const signature = this.hmac(this.encode(messageString), this.encode(this.stringToBase64(this.secret)), sha256.sha256, 'base64');
1921
+ headers['APEX-SIGNATURE'] = signature;
1922
+ headers['APEX-API-KEY'] = this.apiKey;
1923
+ headers['APEX-TIMESTAMP'] = timestamp;
1924
+ headers['APEX-PASSPHRASE'] = this.password;
1925
+ }
1926
+ return { 'url': url, 'method': method, 'body': signBody, 'headers': headers };
1927
+ }
1928
+ handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
1929
+ //
1930
+ // {"code":3,"msg":"Order price must be greater than 0. Order price is 0.","key":"ORDER_PRICE_MUST_GREETER_ZERO","detail":{"price":"0"}}
1931
+ // {"code":400,"msg":"strconv.ParseInt: parsing \"dsfdfsd\": invalid syntax","timeCost":5320995}
1932
+ //
1933
+ if (response === undefined) {
1934
+ return undefined;
1935
+ }
1936
+ const errorCode = this.safeInteger(response, 'code');
1937
+ if (errorCode !== undefined && errorCode !== 0) {
1938
+ const feedback = this.id + ' ' + body;
1939
+ const message = this.safeString2(response, 'key', 'msg');
1940
+ this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
1941
+ const status = code.toString();
1942
+ this.throwExactlyMatchedException(this.exceptions['exact'], status, feedback);
1943
+ throw new errors.ExchangeError(feedback);
1944
+ }
1945
+ return undefined;
1946
+ }
1947
+ }
1948
+
1949
+ module.exports = apex;