ccxt 4.4.75 → 4.4.78

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