ccxt 4.4.35 → 4.4.37

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 (73) hide show
  1. package/README.md +10 -9
  2. package/dist/ccxt.browser.min.js +2 -2
  3. package/dist/cjs/ccxt.js +11 -6
  4. package/dist/cjs/src/abstract/bitfinex1.js +9 -0
  5. package/dist/cjs/src/abstract/defx.js +9 -0
  6. package/dist/cjs/src/base/Exchange.js +6 -1
  7. package/dist/cjs/src/bitfinex.js +3178 -1161
  8. package/dist/cjs/src/bitfinex1.js +1760 -0
  9. package/dist/cjs/src/bitfinex2.js +20 -12
  10. package/dist/cjs/src/bitmex.js +103 -1
  11. package/dist/cjs/src/bitopro.js +22 -4
  12. package/dist/cjs/src/bitso.js +2 -1
  13. package/dist/cjs/src/bybit.js +20 -0
  14. package/dist/cjs/src/coinbase.js +87 -0
  15. package/dist/cjs/src/defx.js +2048 -0
  16. package/dist/cjs/src/deribit.js +34 -14
  17. package/dist/cjs/src/gate.js +16 -2
  18. package/dist/cjs/src/hashkey.js +1 -1
  19. package/dist/cjs/src/htx.js +14 -2
  20. package/dist/cjs/src/hyperliquid.js +125 -14
  21. package/dist/cjs/src/kraken.js +39 -48
  22. package/dist/cjs/src/paradex.js +4 -2
  23. package/dist/cjs/src/pro/bitfinex.js +760 -271
  24. package/dist/cjs/src/pro/bitfinex1.js +675 -0
  25. package/dist/cjs/src/pro/defx.js +864 -0
  26. package/dist/cjs/src/pro/probit.js +1 -0
  27. package/js/ccxt.d.ts +14 -8
  28. package/js/ccxt.js +10 -6
  29. package/js/src/abstract/bitfinex.d.ts +135 -64
  30. package/js/src/abstract/bitfinex1.d.ts +72 -0
  31. package/js/src/abstract/bitopro.d.ts +1 -0
  32. package/js/src/abstract/bybit.d.ts +15 -0
  33. package/js/src/abstract/defx.d.ts +72 -0
  34. package/js/src/abstract/defx.js +11 -0
  35. package/js/src/abstract/deribit.d.ts +1 -0
  36. package/js/src/abstract/gate.d.ts +14 -0
  37. package/js/src/abstract/gateio.d.ts +14 -0
  38. package/js/src/base/Exchange.js +6 -1
  39. package/js/src/bitfinex.d.ts +316 -106
  40. package/js/src/bitfinex.js +3179 -1162
  41. package/js/src/bitfinex1.d.ts +296 -0
  42. package/js/src/bitfinex1.js +1761 -0
  43. package/js/src/bitfinex2.js +21 -13
  44. package/js/src/bitmex.js +103 -1
  45. package/js/src/bitopro.d.ts +11 -0
  46. package/js/src/bitopro.js +22 -4
  47. package/js/src/bitso.js +2 -1
  48. package/js/src/bybit.js +20 -0
  49. package/js/src/coinbase.d.ts +33 -0
  50. package/js/src/coinbase.js +87 -0
  51. package/js/src/defx.d.ts +349 -0
  52. package/js/src/defx.js +2049 -0
  53. package/js/src/deribit.d.ts +2 -0
  54. package/js/src/deribit.js +34 -14
  55. package/js/src/gate.js +16 -2
  56. package/js/src/hashkey.js +1 -1
  57. package/js/src/htx.d.ts +3 -0
  58. package/js/src/htx.js +14 -2
  59. package/js/src/hyperliquid.d.ts +6 -1
  60. package/js/src/hyperliquid.js +125 -14
  61. package/js/src/kraken.js +39 -48
  62. package/js/src/paradex.d.ts +2 -0
  63. package/js/src/paradex.js +4 -2
  64. package/js/src/pro/bitfinex.d.ts +42 -10
  65. package/js/src/pro/bitfinex.js +761 -272
  66. package/js/src/pro/bitfinex1.d.ts +67 -0
  67. package/js/src/pro/bitfinex1.js +676 -0
  68. package/js/src/pro/defx.d.ts +236 -0
  69. package/js/src/pro/defx.js +865 -0
  70. package/js/src/pro/probit.js +1 -0
  71. package/package.json +1 -1
  72. package/js/src/abstract/bitfinex2.d.ts +0 -143
  73. /package/js/src/abstract/{bitfinex2.js → bitfinex1.js} +0 -0
package/js/src/defx.js ADDED
@@ -0,0 +1,2049 @@
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 Exchange from './abstract/defx.js';
9
+ import { Precise } from './base/Precise.js';
10
+ import { TICK_SIZE } from './base/functions/number.js';
11
+ import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
12
+ import { NotSupported, ArgumentsRequired, BadRequest, AuthenticationError, InvalidOrder, ExchangeError } from './base/errors.js';
13
+ // ---------------------------------------------------------------------------
14
+ /**
15
+ * @class defx
16
+ * @augments Exchange
17
+ */
18
+ export default class defx extends Exchange {
19
+ describe() {
20
+ return this.deepExtend(super.describe(), {
21
+ 'id': 'defx',
22
+ 'name': 'Defx X',
23
+ // 'countries': [ '' ],
24
+ 'rateLimit': 100,
25
+ 'version': 'v1',
26
+ 'certified': false,
27
+ 'pro': false,
28
+ 'hostname': 'defx.com',
29
+ 'dex': true,
30
+ 'has': {
31
+ 'CORS': undefined,
32
+ 'spot': false,
33
+ 'margin': false,
34
+ 'swap': true,
35
+ 'future': false,
36
+ 'option': false,
37
+ 'addMargin': true,
38
+ 'cancelAllOrders': true,
39
+ 'cancelAllOrdersAfter': false,
40
+ 'cancelOrder': true,
41
+ 'cancelWithdraw': false,
42
+ 'closeAllPositions': true,
43
+ 'closePosition': true,
44
+ 'createConvertTrade': false,
45
+ 'createDepositAddress': false,
46
+ 'createMarketBuyOrderWithCost': false,
47
+ 'createMarketOrder': false,
48
+ 'createMarketOrderWithCost': false,
49
+ 'createMarketSellOrderWithCost': false,
50
+ 'createOrder': true,
51
+ 'createOrderWithTakeProfitAndStopLoss': true,
52
+ 'createReduceOnlyOrder': true,
53
+ 'createStopLimitOrder': false,
54
+ 'createStopLossOrder': false,
55
+ 'createStopMarketOrder': false,
56
+ 'createStopOrder': false,
57
+ 'createTakeProfitOrder': true,
58
+ 'createTrailingAmountOrder': false,
59
+ 'createTrailingPercentOrder': false,
60
+ 'createTriggerOrder': true,
61
+ 'fetchAccounts': false,
62
+ 'fetchBalance': true,
63
+ 'fetchCanceledOrders': true,
64
+ 'fetchClosedOrder': false,
65
+ 'fetchClosedOrders': true,
66
+ 'fetchConvertCurrencies': false,
67
+ 'fetchConvertQuote': false,
68
+ 'fetchConvertTrade': false,
69
+ 'fetchConvertTradeHistory': false,
70
+ 'fetchCurrencies': false,
71
+ 'fetchDepositAddress': false,
72
+ 'fetchDepositAddresses': false,
73
+ 'fetchDepositAddressesByNetwork': false,
74
+ 'fetchDeposits': false,
75
+ 'fetchDepositsWithdrawals': false,
76
+ 'fetchFundingHistory': false,
77
+ 'fetchFundingInterval': false,
78
+ 'fetchFundingIntervals': false,
79
+ 'fetchFundingRate': true,
80
+ 'fetchFundingRateHistory': false,
81
+ 'fetchFundingRates': false,
82
+ 'fetchIndexOHLCV': false,
83
+ 'fetchLedger': true,
84
+ 'fetchLeverage': false,
85
+ 'fetchMarginAdjustmentHistory': false,
86
+ 'fetchMarginMode': false,
87
+ 'fetchMarkets': true,
88
+ 'fetchMarkOHLCV': false,
89
+ 'fetchMarkPrice': false,
90
+ 'fetchMarkPrices': false,
91
+ 'fetchMyTrades': true,
92
+ 'fetchOHLCV': true,
93
+ 'fetchOpenInterestHistory': false,
94
+ 'fetchOpenOrder': false,
95
+ 'fetchOpenOrders': true,
96
+ 'fetchOrder': true,
97
+ 'fetchOrderBook': true,
98
+ 'fetchOrders': true,
99
+ 'fetchOrderTrades': false,
100
+ 'fetchPosition': true,
101
+ 'fetchPositionHistory': false,
102
+ 'fetchPositionMode': false,
103
+ 'fetchPositions': true,
104
+ 'fetchPositionsHistory': false,
105
+ 'fetchPremiumIndexOHLCV': false,
106
+ 'fetchStatus': true,
107
+ 'fetchTicker': true,
108
+ 'fetchTickers': true,
109
+ 'fetchTime': true,
110
+ 'fetchTrades': true,
111
+ 'fetchTradingFee': false,
112
+ 'fetchTradingFees': false,
113
+ 'fetchTransactions': false,
114
+ 'fetchTransfers': false,
115
+ 'fetchWithdrawals': false,
116
+ 'reduceMargin': false,
117
+ 'sandbox': true,
118
+ 'setLeverage': true,
119
+ 'setMargin': false,
120
+ 'setPositionMode': false,
121
+ 'transfer': false,
122
+ 'withdraw': true,
123
+ },
124
+ 'timeframes': {
125
+ '1m': '1m',
126
+ '3m': '3m',
127
+ '5m': '5m',
128
+ '15m': '15m',
129
+ '30m': '30m',
130
+ '1h': '1h',
131
+ '2h': '2h',
132
+ '4h': '4h',
133
+ '12h': '12h',
134
+ '1d': '1d',
135
+ '1w': '1w',
136
+ '1M': '1M',
137
+ },
138
+ 'urls': {
139
+ 'logo': 'https://github.com/user-attachments/assets/4e92bace-d7a9-45ea-92be-122168dc87e4',
140
+ 'api': {
141
+ 'public': 'https://api.{hostname}',
142
+ 'private': 'https://api.{hostname}',
143
+ },
144
+ 'test': {
145
+ 'public': 'https://api.testnet.{hostname}',
146
+ 'private': 'https://api.testnet.{hostname}',
147
+ },
148
+ 'www': 'https://defx.com/home',
149
+ 'doc': [
150
+ 'https://docs.defx.com/docs',
151
+ 'https://api-docs.defx.com/',
152
+ ],
153
+ 'fees': [
154
+ '',
155
+ ],
156
+ 'referral': {
157
+ 'url': 'https://app.defx.com/join/6I2CZ7',
158
+ },
159
+ },
160
+ 'api': {
161
+ 'v1': {
162
+ 'public': {
163
+ 'get': {
164
+ 'healthcheck/ping': 1,
165
+ 'symbols/{symbol}/ohlc': 1,
166
+ 'symbols/{symbol}/trades': 1,
167
+ 'symbols/{symbol}/prices': 1,
168
+ 'symbols/{symbol}/ticker/24hr': 1,
169
+ 'symbols/{symbol}/depth/{level}/{slab}': 1,
170
+ 'ticker/24HrAgg': 1,
171
+ 'c/markets': 1,
172
+ 'c/markets/metadata': 1,
173
+ 'analytics/market/stats/newUsers': 1,
174
+ 'analytics/market/stats/tvl': 1,
175
+ 'analytics/market/stats/volumeByInstrument': 1,
176
+ 'analytics/market/stats/liquidation': 1,
177
+ 'analytics/market/stats/totalVolume': 1,
178
+ 'analytics/market/stats/openInterest': 1,
179
+ 'analytics/market/stats/totalTrades': 1,
180
+ 'analytics/market/stats/basis': 1,
181
+ 'analytics/market/stats/insuranceFund': 1,
182
+ 'analytics/market/stats/longAndShortRatio': 1,
183
+ 'analytics/market/stats/fundingRate': 1,
184
+ 'analytics/market/overview': 1,
185
+ 'explorer/search': 1,
186
+ 'explorer/transactions': 1,
187
+ 'explorer/blocks': 1,
188
+ },
189
+ },
190
+ 'private': {
191
+ 'get': {
192
+ 'api/order/{orderId}': 1,
193
+ 'api/orders': 1,
194
+ 'api/orders/oco/{parentOrderId}': 1,
195
+ 'api/trades': 1,
196
+ 'api/position/active': 1,
197
+ 'api/users/metadata/leverage': 1,
198
+ 'api/users/metadata/feeMultiplier': 1,
199
+ 'api/users/metadata/slippage': 1,
200
+ 'api/users/referral': 1,
201
+ 'api/users/apikeys': 1,
202
+ 'connection-signature-message/evm': 1,
203
+ 'api/users/profile/wallets': 1,
204
+ 'api/notifications': 1,
205
+ 'api/wallet/balance': 1,
206
+ 'api/wallet/transactions': 1,
207
+ 'api/analytics/user/overview': 1,
208
+ 'api/analytics/user/pnl': 1,
209
+ 'api/analytics/points/overview': 1,
210
+ 'api/analytics/points/history': 1,
211
+ },
212
+ 'post': {
213
+ 'api/order': 1,
214
+ 'api/position/oco': 1,
215
+ 'api/users/socket/listenKeys': 1,
216
+ 'api/users/metadata/leverage': 1,
217
+ 'api/users/metadata/feeMultiplier': 1,
218
+ 'api/users/metadata/slippage': 1,
219
+ 'api/users/referral/recordReferralSignup': 1,
220
+ 'api/users/apikeys': 1,
221
+ 'api/users/profile/wallets': 1,
222
+ 'api/transfers/withdrawal': 1,
223
+ 'api/transfers/bridge/withdrawal': 1,
224
+ },
225
+ 'put': {
226
+ 'api/position/updatePositionMargin': 1,
227
+ 'api/users/socket/listenKeys/{listenKey}': 1,
228
+ 'api/users/apikeys/{accessKey}/status': 1,
229
+ 'api/users/referral': 1,
230
+ },
231
+ 'patch': {
232
+ 'api/users/apikeys/{accessKey}': 1,
233
+ },
234
+ 'delete': {
235
+ 'api/orders/allOpen': 1,
236
+ 'api/order/{orderId}': 1,
237
+ 'api/position/{positionId}': 1,
238
+ 'api/position/all': 1,
239
+ 'api/users/socket/listenKeys/{listenKey}': 1,
240
+ 'api/users/apikeys/{accessKey}': 1,
241
+ },
242
+ },
243
+ },
244
+ },
245
+ 'fees': {
246
+ 'trading': {
247
+ 'tierBased': true,
248
+ 'percentage': true,
249
+ 'maker': this.parseNumber('0.0002'),
250
+ 'taker': this.parseNumber('0.0005'),
251
+ },
252
+ },
253
+ 'options': {
254
+ 'sandboxMode': false,
255
+ },
256
+ 'commonCurrencies': {},
257
+ 'exceptions': {
258
+ 'exact': {
259
+ '404': BadRequest,
260
+ 'missing_auth_signature': AuthenticationError,
261
+ 'order_rejected': InvalidOrder,
262
+ 'invalid_order_id': InvalidOrder,
263
+ 'filter_lotsize_maxqty': InvalidOrder,
264
+ 'filter_notional_min': InvalidOrder,
265
+ 'failed_index_price_up_multiplier_filter': InvalidOrder,
266
+ 'no_open_orders': InvalidOrder,
267
+ 'active_position_not_found': InvalidOrder,
268
+ 'position_inactive': InvalidOrder,
269
+ 'invalid_position_id': InvalidOrder,
270
+ 'Internal server error': ExchangeError, // {"msg":"Internal server error","code":"internal_server_error"}
271
+ },
272
+ 'broad': {
273
+ 'Bad Request': BadRequest, // {"errorMessage":"Bad Request","data":[{"param":"symbol","message":"\"symbol\" must be one of [ETH_USDC, BTC_USDC, BNB_USDC, SOL_USDC, DOGE_USDC, TON_USDC, AVAX_USDC, WIF_USDC, KPEPE_USDC, KSHIB_USDC, KBONK_USDC, MOODENG_USDC, POPCAT_USDC, MOTHER_USDC]"}]}
274
+ },
275
+ },
276
+ 'precisionMode': TICK_SIZE,
277
+ });
278
+ }
279
+ /**
280
+ * @method
281
+ * @name defx#fetchStatus
282
+ * @description the latest known information on the availability of the exchange API
283
+ * @see https://api-docs.defx.com/#4b03bb3b-a0fa-4dfb-b96c-237bde0ce9e6
284
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
285
+ * @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure}
286
+ */
287
+ async fetchStatus(params = {}) {
288
+ const response = await this.v1PublicGetHealthcheckPing(params);
289
+ //
290
+ // {
291
+ // "success": true,
292
+ // "t": 1709705048323,
293
+ // "v": "0.0.7",
294
+ // "msg": "A programmer’s wife tells him, “While you’re at the grocery store, buy some eggs.” He never comes back."
295
+ // }
296
+ //
297
+ let status = undefined;
298
+ const success = this.safeBool(response, 'success');
299
+ if (success) {
300
+ status = 'ok';
301
+ }
302
+ else {
303
+ status = 'error';
304
+ }
305
+ return {
306
+ 'status': status,
307
+ 'updated': undefined,
308
+ 'eta': undefined,
309
+ 'url': undefined,
310
+ 'info': response,
311
+ };
312
+ }
313
+ /**
314
+ * @method
315
+ * @name defx#fetchTime
316
+ * @description fetches the current integer timestamp in milliseconds from the exchange server
317
+ * @see https://api-docs.defx.com/#4b03bb3b-a0fa-4dfb-b96c-237bde0ce9e6
318
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
319
+ * @returns {int} the current integer timestamp in milliseconds from the exchange server
320
+ */
321
+ async fetchTime(params = {}) {
322
+ const response = await this.v1PublicGetHealthcheckPing(params);
323
+ //
324
+ // {
325
+ // "success": true,
326
+ // "t": 1709705048323,
327
+ // "v": "0.0.7",
328
+ // "msg": "A programmer’s wife tells him, “While you’re at the grocery store, buy some eggs.” He never comes back."
329
+ // }
330
+ //
331
+ return this.safeInteger(response, 't');
332
+ }
333
+ /**
334
+ * @method
335
+ * @name defx#fetchMarkets
336
+ * @description retrieves data on all markets for defx
337
+ * @see https://api-docs.defx.com/#73cce0c8-f842-4891-9145-01bb6d61324d
338
+ * @see https://api-docs.defx.com/#24fd4e5b-840e-451e-99e0-7fea47c7f371
339
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
340
+ * @returns {object[]} an array of objects representing market data
341
+ */
342
+ async fetchMarkets(params = {}) {
343
+ const request = {
344
+ 'type': 'perps',
345
+ };
346
+ const promises = [
347
+ this.v1PublicGetCMarkets(this.extend(request, params)),
348
+ this.v1PublicGetCMarketsMetadata(this.extend(request, params)),
349
+ ];
350
+ const responses = await Promise.all(promises);
351
+ //
352
+ // {
353
+ // "data": [
354
+ // {
355
+ // "market": "DOGE_USDC",
356
+ // "candleWindows": [
357
+ // "1m",
358
+ // "3m",
359
+ // "5m",
360
+ // "15m",
361
+ // "30m",
362
+ // "1h",
363
+ // "2h",
364
+ // "4h",
365
+ // "12h",
366
+ // "1d",
367
+ // "1w",
368
+ // "1M"
369
+ // ],
370
+ // "depthSlabs": [
371
+ // "0.00001",
372
+ // "0.00005",
373
+ // "0.0001",
374
+ // "0.001",
375
+ // "0.01"
376
+ // ],
377
+ // "filters": [
378
+ // {
379
+ // "filterType": "LOT_SIZE",
380
+ // "minQty": "1.00000",
381
+ // "maxQty": "1500000.00000",
382
+ // "stepSize": "1.00000"
383
+ // },
384
+ // {
385
+ // "filterType": "MARKET_LOT_SIZE",
386
+ // "minQty": "1.00000",
387
+ // "maxQty": "750000.00000",
388
+ // "stepSize": "1.00000"
389
+ // },
390
+ // {
391
+ // "filterType": "PRICE_FILTER",
392
+ // "minPrice": "0.00244000",
393
+ // "maxPrice": "30.00000000",
394
+ // "tickSize": "0.00001"
395
+ // },
396
+ // {
397
+ // "filterType": "NOTIONAL",
398
+ // "minNotional": "100.00000000"
399
+ // },
400
+ // {
401
+ // "filterType": "PERCENT_PRICE_BY_SIDE",
402
+ // "bidMultiplierUp": "1.5",
403
+ // "bidMultiplierDown": "0.5",
404
+ // "askMultiplierUp": "1.5",
405
+ // "askMultiplierDown": "0.5"
406
+ // },
407
+ // {
408
+ // "filterType": "INDEX_PRICE_FILTER",
409
+ // "multiplierUp": "1.3",
410
+ // "multiplierDown": "0.7"
411
+ // }
412
+ // ],
413
+ // "cappedLeverage": "25",
414
+ // "maintenanceMarginTiers": [
415
+ // {
416
+ // "tier": "1",
417
+ // "minMaintenanceMargin": "0",
418
+ // "maxMaintenanceMargin": "2500",
419
+ // "leverage": "25"
420
+ // },
421
+ // {
422
+ // "tier": "2",
423
+ // "minMaintenanceMargin": "2500",
424
+ // "maxMaintenanceMargin": "12500",
425
+ // "leverage": "20"
426
+ // },
427
+ // {
428
+ // "tier": "3",
429
+ // "minMaintenanceMargin": "12500",
430
+ // "maxMaintenanceMargin": "25000",
431
+ // "leverage": "15"
432
+ // },
433
+ // {
434
+ // "tier": "4",
435
+ // "minMaintenanceMargin": "25000",
436
+ // "maxMaintenanceMargin": "50000",
437
+ // "leverage": "10"
438
+ // },
439
+ // {
440
+ // "tier": "5",
441
+ // "minMaintenanceMargin": "50000",
442
+ // "maxMaintenanceMargin": "75000",
443
+ // "leverage": "8"
444
+ // },
445
+ // {
446
+ // "tier": "6",
447
+ // "minMaintenanceMargin": "75000",
448
+ // "maxMaintenanceMargin": "125000",
449
+ // "leverage": "7"
450
+ // },
451
+ // {
452
+ // "tier": "7",
453
+ // "minMaintenanceMargin": "125000",
454
+ // "maxMaintenanceMargin": "187500",
455
+ // "leverage": "5"
456
+ // },
457
+ // {
458
+ // "tier": "8",
459
+ // "minMaintenanceMargin": "187500",
460
+ // "maxMaintenanceMargin": "250000",
461
+ // "leverage": "3"
462
+ // },
463
+ // {
464
+ // "tier": "9",
465
+ // "minMaintenanceMargin": "250000",
466
+ // "maxMaintenanceMargin": "375000",
467
+ // "leverage": "2"
468
+ // },
469
+ // {
470
+ // "tier": "10",
471
+ // "minMaintenanceMargin": "375000",
472
+ // "maxMaintenanceMargin": "500000",
473
+ // "leverage": "1"
474
+ // }
475
+ // ],
476
+ // "fees": {
477
+ // "maker": "0.08",
478
+ // "taker": "0.1"
479
+ // }
480
+ // },
481
+ // ]
482
+ // }
483
+ //
484
+ const activeMarkets = this.safeList(responses[0], 'data');
485
+ const activeMarketsByType = this.indexBy(activeMarkets, 'market');
486
+ const marketMetadatas = this.safeList(responses[1], 'data');
487
+ for (let i = 0; i < marketMetadatas.length; i++) {
488
+ const marketId = marketMetadatas[i]['market'];
489
+ let status = undefined;
490
+ if (marketId in activeMarketsByType) {
491
+ status = activeMarketsByType[marketId]['status'];
492
+ }
493
+ marketMetadatas[i]['status'] = status;
494
+ }
495
+ return this.parseMarkets(marketMetadatas);
496
+ }
497
+ parseMarket(market) {
498
+ const marketId = this.safeString(market, 'market');
499
+ const parts = marketId.split('_');
500
+ const baseId = this.safeString(parts, 0);
501
+ const quoteId = this.safeString(parts, 1);
502
+ const base = this.safeCurrencyCode(baseId);
503
+ const quote = this.safeCurrencyCode(quoteId);
504
+ const symbol = base + '/' + quote + ':' + quote;
505
+ const filters = this.safeList(market, 'filters', []);
506
+ const fees = this.safeDict(market, 'fees', {});
507
+ const filtersByType = this.indexBy(filters, 'filterType');
508
+ const priceFilter = this.safeDict(filtersByType, 'PRICE_FILTER', {});
509
+ const lotFilter = this.safeDict(filtersByType, 'LOT_SIZE', {});
510
+ const marketLotFilter = this.safeDict(filtersByType, 'MARKET_LOT_SIZE', {});
511
+ const notionalFilter = this.safeDict(filtersByType, 'NOTIONAL', {});
512
+ return {
513
+ 'id': marketId,
514
+ 'symbol': symbol,
515
+ 'base': base,
516
+ 'quote': quote,
517
+ 'settle': quote,
518
+ 'baseId': baseId,
519
+ 'quoteId': quoteId,
520
+ 'settleId': quoteId,
521
+ 'type': 'swap',
522
+ 'spot': false,
523
+ 'margin': false,
524
+ 'swap': true,
525
+ 'future': false,
526
+ 'option': false,
527
+ 'active': this.safeString(market, 'status', '') === 'active',
528
+ 'contract': true,
529
+ 'linear': true,
530
+ 'inverse': undefined,
531
+ 'taker': this.safeNumber(fees, 'taker'),
532
+ 'maker': this.safeNumber(fees, 'maker'),
533
+ 'contractSize': this.parseNumber('1'),
534
+ 'expiry': undefined,
535
+ 'expiryDatetime': undefined,
536
+ 'strike': undefined,
537
+ 'optionType': undefined,
538
+ 'precision': {
539
+ 'amount': this.safeNumber(lotFilter, 'stepSize'),
540
+ 'price': this.safeNumber(priceFilter, 'tickSize'),
541
+ },
542
+ 'limits': {
543
+ 'leverage': {
544
+ 'min': undefined,
545
+ 'max': this.safeNumber(market, 'cappedLeverage'),
546
+ },
547
+ 'amount': {
548
+ 'min': this.safeNumber(lotFilter, 'minQty'),
549
+ 'max': this.safeNumber(lotFilter, 'maxQty'),
550
+ },
551
+ 'price': {
552
+ 'min': this.safeNumber(priceFilter, 'minPrice'),
553
+ 'max': this.safeNumber(priceFilter, 'maxPrice'),
554
+ },
555
+ 'cost': {
556
+ 'min': this.safeNumber(notionalFilter, 'minNotional'),
557
+ 'max': undefined,
558
+ },
559
+ 'market': {
560
+ 'min': this.safeNumber(marketLotFilter, 'minQty'),
561
+ 'max': this.safeNumber(marketLotFilter, 'maxQty'),
562
+ },
563
+ },
564
+ 'created': undefined,
565
+ 'info': market,
566
+ };
567
+ }
568
+ /**
569
+ * @method
570
+ * @name defx#fetchTicker
571
+ * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
572
+ * @see https://api-docs.defx.com/#fe6f81d0-2f3a-4eee-976f-c8fc8f4c5d56
573
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
574
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
575
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
576
+ */
577
+ async fetchTicker(symbol, params = {}) {
578
+ await this.loadMarkets();
579
+ const market = this.market(symbol);
580
+ const request = {
581
+ 'symbol': market['id'],
582
+ };
583
+ const response = await this.v1PublicGetSymbolsSymbolTicker24hr(this.extend(request, params));
584
+ //
585
+ // {
586
+ // "symbol": "BTC_USDC",
587
+ // "priceChange": "0",
588
+ // "priceChangePercent": "0",
589
+ // "weightedAvgPrice": "0",
590
+ // "lastPrice": "2.00",
591
+ // "lastQty": "10.000",
592
+ // "bestBidPrice": "1646.00",
593
+ // "bestBidQty": "10.000",
594
+ // "bestAskPrice": "1646.00",
595
+ // "bestAskQty": "10.000",
596
+ // "openPrice": "0.00",
597
+ // "highPrice": "0.00",
598
+ // "lowPrice": "0.00",
599
+ // "volume": "0.000",
600
+ // "quoteVolume": "0.00",
601
+ // "openTime": 1700142658697,
602
+ // "closeTime": 1700142658697,
603
+ // "openInterestBase": "1.000",
604
+ // "openInterestQuote": "0.43112300"
605
+ // }
606
+ //
607
+ return this.parseTicker(response, market);
608
+ }
609
+ /**
610
+ * @method
611
+ * @name defx#fetchTickers
612
+ * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
613
+ * @see https://api-docs.defx.com/#8c61cfbd-40d9-410e-b014-f5b36eba51d1
614
+ * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
615
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
616
+ * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
617
+ */
618
+ async fetchTickers(symbols = undefined, params = {}) {
619
+ await this.loadMarkets();
620
+ let market = undefined;
621
+ if (symbols !== undefined) {
622
+ symbols = this.marketSymbols(symbols);
623
+ const firstSymbol = this.safeString(symbols, 0);
624
+ if (firstSymbol !== undefined) {
625
+ market = this.market(firstSymbol);
626
+ }
627
+ }
628
+ let type = undefined;
629
+ [type, params] = this.handleMarketTypeAndParams('fetchTickers', market, params);
630
+ if (type === 'spot') {
631
+ throw new NotSupported(this.id + ' fetchTickers() is not supported for ' + type + ' markets');
632
+ }
633
+ const response = await this.v1PublicGetTicker24HrAgg(params);
634
+ //
635
+ // {
636
+ // "ETH_USDC": {
637
+ // "priceChange": "0",
638
+ // "priceChangePercent": "0",
639
+ // "openPrice": "1646.15",
640
+ // "highPrice": "1646.15",
641
+ // "lowPrice": "1646.15",
642
+ // "lastPrice": "1646.15",
643
+ // "quoteVolume": "13.17",
644
+ // "volume": "0.008",
645
+ // "markPrice": "1645.15"
646
+ // }
647
+ // }
648
+ //
649
+ return this.parseTickers(response, symbols);
650
+ }
651
+ parseTicker(ticker, market = undefined) {
652
+ //
653
+ // fetchTicker
654
+ //
655
+ // {
656
+ // "symbol": "BTC_USDC",
657
+ // "priceChange": "0",
658
+ // "priceChangePercent": "0",
659
+ // "weightedAvgPrice": "0",
660
+ // "lastPrice": "2.00",
661
+ // "lastQty": "10.000",
662
+ // "bestBidPrice": "1646.00",
663
+ // "bestBidQty": "10.000",
664
+ // "bestAskPrice": "1646.00",
665
+ // "bestAskQty": "10.000",
666
+ // "openPrice": "0.00",
667
+ // "highPrice": "0.00",
668
+ // "lowPrice": "0.00",
669
+ // "volume": "0.000",
670
+ // "quoteVolume": "0.00",
671
+ // "openTime": 1700142658697,
672
+ // "closeTime": 1700142658697,
673
+ // "openInterestBase": "1.000",
674
+ // "openInterestQuote": "0.43112300"
675
+ // }
676
+ //
677
+ // fetchTickers
678
+ //
679
+ // "ETH_USDC": {
680
+ // "priceChange": "0",
681
+ // "priceChangePercent": "0",
682
+ // "openPrice": "1646.15",
683
+ // "highPrice": "1646.15",
684
+ // "lowPrice": "1646.15",
685
+ // "lastPrice": "1646.15",
686
+ // "quoteVolume": "13.17",
687
+ // "volume": "0.008",
688
+ // "markPrice": "1645.15"
689
+ // }
690
+ //
691
+ // fetchMarkPrice
692
+ //
693
+ // {
694
+ // "markPrice": "100.00",
695
+ // "indexPrice": "100.00",
696
+ // "ltp": "101.34",
697
+ // "movingFundingRate": "0.08",
698
+ // "payoutFundingRate": "-0.03",
699
+ // "nextFundingPayout": 1711555532146
700
+ // }
701
+ //
702
+ const marketId = this.safeString(ticker, 'symbol');
703
+ if (marketId !== undefined) {
704
+ market = this.market(marketId);
705
+ }
706
+ const symbol = market['symbol'];
707
+ const open = this.safeString(ticker, 'openPrice');
708
+ const high = this.safeString(ticker, 'highPrice');
709
+ const low = this.safeString(ticker, 'lowPrice');
710
+ const close = this.safeString(ticker, 'lastPrice');
711
+ const quoteVolume = this.safeString(ticker, 'quoteVolume');
712
+ const baseVolume = this.safeString(ticker, 'volume');
713
+ const percentage = this.safeString(ticker, 'priceChangePercent');
714
+ const change = this.safeString(ticker, 'priceChange');
715
+ let ts = this.safeInteger(ticker, 'closeTime');
716
+ if (ts === 0) {
717
+ ts = undefined;
718
+ }
719
+ const datetime = this.iso8601(ts);
720
+ const bid = this.safeString(ticker, 'bestBidPrice');
721
+ const bidVolume = this.safeString(ticker, 'bestBidQty');
722
+ const ask = this.safeString(ticker, 'bestAskPrice');
723
+ const askVolume = this.safeString(ticker, 'bestAskQty');
724
+ return this.safeTicker({
725
+ 'symbol': symbol,
726
+ 'timestamp': ts,
727
+ 'datetime': datetime,
728
+ 'high': high,
729
+ 'low': low,
730
+ 'bid': bid,
731
+ 'bidVolume': bidVolume,
732
+ 'ask': ask,
733
+ 'askVolume': askVolume,
734
+ 'vwap': undefined,
735
+ 'open': open,
736
+ 'close': close,
737
+ 'last': undefined,
738
+ 'previousClose': undefined,
739
+ 'change': change,
740
+ 'percentage': percentage,
741
+ 'average': undefined,
742
+ 'baseVolume': baseVolume,
743
+ 'quoteVolume': quoteVolume,
744
+ 'markPrice': this.safeString(ticker, 'markPrice'),
745
+ 'indexPrice': this.safeString(ticker, 'indexPrice'),
746
+ 'info': ticker,
747
+ }, market);
748
+ }
749
+ /**
750
+ * @method
751
+ * @name defx#fetchOHLCV
752
+ * @see https://api-docs.defx.com/#54b71951-1472-4670-b5af-4c2dc41e73d0
753
+ * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
754
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
755
+ * @param {string} timeframe the length of time each candle represents
756
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
757
+ * @param {int} [limit] max=1000, max=100 when since is defined and is less than (now - (999 * (timeframe in ms)))
758
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
759
+ * @param {int} [params.until] the latest time in ms to fetch orders for
760
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
761
+ */
762
+ async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
763
+ await this.loadMarkets();
764
+ const market = this.market(symbol);
765
+ const maxLimit = 1000;
766
+ if (limit === undefined) {
767
+ limit = maxLimit;
768
+ }
769
+ limit = Math.min(maxLimit, limit);
770
+ const request = {
771
+ 'symbol': market['id'],
772
+ 'interval': this.safeString(this.timeframes, timeframe, timeframe),
773
+ 'limit': limit,
774
+ };
775
+ const until = this.safeInteger2(params, 'until', 'till');
776
+ params = this.omit(params, ['until', 'till']);
777
+ request['endTime'] = (until === undefined) ? this.milliseconds() : until;
778
+ if (since === undefined) {
779
+ request['startTime'] = 0;
780
+ }
781
+ else {
782
+ request['startTime'] = since;
783
+ if (until === undefined) {
784
+ const timeframeInSeconds = this.parseTimeframe(timeframe);
785
+ const timeframeInMilliseconds = timeframeInSeconds * 1000;
786
+ const totalTimeframeInMilliseconds = limit * timeframeInMilliseconds;
787
+ request['endTime'] = this.sum(since, totalTimeframeInMilliseconds);
788
+ }
789
+ }
790
+ const response = await this.v1PublicGetSymbolsSymbolOhlc(this.extend(request, params));
791
+ //
792
+ // [
793
+ // {
794
+ // "symbol": "BTC_USDC",
795
+ // "open": "0.00",
796
+ // "high": "0.00",
797
+ // "low": "0.00",
798
+ // "close": "0.00",
799
+ // "volume": "0.000",
800
+ // "quoteAssetVolume": "0.00",
801
+ // "takerBuyAssetVolume": "0.000",
802
+ // "takerBuyQuoteAssetVolume": "0.00",
803
+ // "numberOfTrades": 0,
804
+ // "start": 1702453663894,
805
+ // "end": 1702453663894,
806
+ // "isClosed": true
807
+ // }
808
+ // ]
809
+ //
810
+ return this.parseOHLCVs(response, market, timeframe, since, limit);
811
+ }
812
+ parseOHLCV(ohlcv, market = undefined) {
813
+ // example response in fetchOHLCV
814
+ return [
815
+ this.safeInteger(ohlcv, 'start'),
816
+ this.safeNumber(ohlcv, 'open'),
817
+ this.safeNumber(ohlcv, 'high'),
818
+ this.safeNumber(ohlcv, 'low'),
819
+ this.safeNumber(ohlcv, 'close'),
820
+ this.safeNumber(ohlcv, 'volume'),
821
+ ];
822
+ }
823
+ /**
824
+ * @method
825
+ * @name defx#fetchTrades
826
+ * @description get the list of most recent trades for a particular symbol
827
+ * @see https://api-docs.defx.com/#5865452f-ea32-4f13-bfbc-03af5f5574fd
828
+ * @param {string} symbol unified symbol of the market to fetch trades for
829
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
830
+ * @param {int} [limit] the maximum amount of trades to fetch
831
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
832
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
833
+ */
834
+ async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
835
+ await this.loadMarkets();
836
+ const market = this.market(symbol);
837
+ const maxLimit = 50;
838
+ if (limit === undefined) {
839
+ limit = maxLimit;
840
+ }
841
+ limit = Math.min(maxLimit, limit);
842
+ const request = {
843
+ 'symbol': market['id'],
844
+ 'limit': limit,
845
+ };
846
+ const response = await this.v1PublicGetSymbolsSymbolTrades(this.extend(request, params));
847
+ //
848
+ // [
849
+ // {
850
+ // "buyerMaker": "false",
851
+ // "price": "2.0000",
852
+ // "qty": "10.0000",
853
+ // "symbol": "BTC_USDC",
854
+ // "timestamp": "1702453663894"
855
+ // }
856
+ // ]
857
+ //
858
+ return this.parseTrades(response, market, since, limit);
859
+ }
860
+ /**
861
+ * @method
862
+ * @name defx#fetchTrades
863
+ * @description fetch all trades made by the user
864
+ * @see https://api-docs.defx.com/#06b5b33c-2fc6-48de-896c-fc316f5871a7
865
+ * @param {string} symbol unified symbol of the market to fetch trades for
866
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
867
+ * @param {int} [limit] the maximum amount of trades to fetch
868
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
869
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
870
+ */
871
+ async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
872
+ await this.loadMarkets();
873
+ const request = {};
874
+ if (symbol !== undefined) {
875
+ const market = this.market(symbol);
876
+ request['symbols'] = market['id'];
877
+ }
878
+ if (limit !== undefined) {
879
+ const maxLimit = 100;
880
+ limit = Math.min(maxLimit, limit);
881
+ request['pageSize'] = limit;
882
+ }
883
+ const response = await this.v1PrivateGetApiTrades(this.extend(request, params));
884
+ //
885
+ // {
886
+ // "data": [
887
+ // {
888
+ // "id": "0192f665-c05b-7ba0-a080-8b6c99083489",
889
+ // "orderId": "757730811259651728",
890
+ // "time": "2024-11-04T08:58:36.474Z",
891
+ // "symbol": "SOL_USDC",
892
+ // "side": "SELL",
893
+ // "price": "160.43600000",
894
+ // "qty": "1.00",
895
+ // "fee": "0.08823980",
896
+ // "role": "TAKER",
897
+ // "pnl": "0.00000000"
898
+ // }
899
+ // ]
900
+ // }
901
+ //
902
+ const data = this.safeList(response, 'data', []);
903
+ return this.parseTrades(data, undefined, since, limit);
904
+ }
905
+ parseTrade(trade, market = undefined) {
906
+ //
907
+ // fetchTrades
908
+ // {
909
+ // "buyerMaker": "false",
910
+ // "price": "2.0000",
911
+ // "qty": "10.0000",
912
+ // "symbol": "BTC_USDC",
913
+ // "timestamp": "1702453663894"
914
+ // }
915
+ //
916
+ // fetchMyTrades
917
+ // {
918
+ // "id": "0192f665-c05b-7ba0-a080-8b6c99083489",
919
+ // "orderId": "757730811259651728",
920
+ // "time": "2024-11-04T08:58:36.474Z",
921
+ // "symbol": "SOL_USDC",
922
+ // "side": "SELL",
923
+ // "price": "160.43600000",
924
+ // "qty": "1.00",
925
+ // "fee": "0.08823980",
926
+ // "role": "TAKER",
927
+ // "pnl": "0.00000000"
928
+ // }
929
+ //
930
+ const time = this.safeString(trade, 'time');
931
+ const timestamp = this.safeInteger(trade, 'timestamp', this.parse8601(time));
932
+ const marketId = this.safeString(trade, 'symbol');
933
+ market = this.safeMarket(marketId, market);
934
+ const symbol = market['symbol'];
935
+ const price = this.safeString(trade, 'price');
936
+ const amount = this.safeString(trade, 'qty');
937
+ const id = this.safeString(trade, 'id');
938
+ const oid = this.safeString(trade, 'orderId');
939
+ const takerOrMaker = this.safeStringLower(trade, 'role');
940
+ const buyerMaker = this.safeString(trade, 'buyerMaker');
941
+ let side = this.safeStringLower(trade, 'side');
942
+ if (buyerMaker !== undefined) {
943
+ if (buyerMaker === 'true') {
944
+ side = 'sell';
945
+ }
946
+ else {
947
+ side = 'buy';
948
+ }
949
+ }
950
+ return this.safeTrade({
951
+ 'id': id,
952
+ 'timestamp': timestamp,
953
+ 'datetime': this.iso8601(timestamp),
954
+ 'symbol': symbol,
955
+ 'side': side,
956
+ 'price': price,
957
+ 'amount': amount,
958
+ 'cost': undefined,
959
+ 'order': oid,
960
+ 'takerOrMaker': takerOrMaker,
961
+ 'type': undefined,
962
+ 'fee': {
963
+ 'cost': this.safeString(trade, 'fee'),
964
+ 'currency': 'USDC',
965
+ },
966
+ 'info': trade,
967
+ }, market);
968
+ }
969
+ /**
970
+ * @method
971
+ * @name defx#fetchOrderBook
972
+ * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
973
+ * @see https://api-docs.defx.com/#6c1a2971-8325-4e7d-9962-e0bfcaacf9c4
974
+ * @param {string} symbol unified symbol of the market to fetch the order book for
975
+ * @param {int} [limit] the maximum amount of order book entries to return
976
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
977
+ * @param {string} [params.slab] slab from market.info.depthSlabs
978
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
979
+ */
980
+ async fetchOrderBook(symbol, limit = undefined, params = {}) {
981
+ await this.loadMarkets();
982
+ const market = this.market(symbol);
983
+ if (limit === undefined) {
984
+ limit = 10; // limit must be one of [5, 10, 20]
985
+ }
986
+ const marketInfo = this.safeDict(market, 'info', {});
987
+ const slab = this.safeList(marketInfo, 'depthSlabs', []);
988
+ const request = {
989
+ 'symbol': market['id'],
990
+ 'level': limit,
991
+ 'slab': this.safeString(slab, 0),
992
+ };
993
+ const response = await this.v1PublicGetSymbolsSymbolDepthLevelSlab(this.extend(request, params));
994
+ //
995
+ // {
996
+ // "symbol": "ETH_USDC",
997
+ // "level": "5",
998
+ // "slab": "1",
999
+ // "lastTradeTimestamp": "1708313446812",
1000
+ // "timestamp": "1708313446812",
1001
+ // "bids": [
1002
+ // {
1003
+ // "price": "1646.16",
1004
+ // "qty": "0.001"
1005
+ // }
1006
+ // ],
1007
+ // "asks": [
1008
+ // {
1009
+ // "price": "1646.16",
1010
+ // "qty": "0.001"
1011
+ // }
1012
+ // ]
1013
+ // }
1014
+ //
1015
+ const timestamp = this.safeInteger(response, 'timestamp');
1016
+ return this.parseOrderBook(response, symbol, timestamp, 'bids', 'asks', 'price', 'qty');
1017
+ }
1018
+ /**
1019
+ * @method
1020
+ * @name defx#fetchMarkPrice
1021
+ * @description fetches mark price for the market
1022
+ * @see https://api-docs.defx.com/#12168192-4e7b-4458-a001-e8b80961f0b7
1023
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
1024
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1025
+ * @param {string} [params.subType] "linear" or "inverse"
1026
+ * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1027
+ */
1028
+ async fetchMarkPrice(symbol, params = {}) {
1029
+ await this.loadMarkets();
1030
+ const market = this.market(symbol);
1031
+ const request = {
1032
+ 'symbol': market['id'],
1033
+ };
1034
+ const response = await this.v1PublicGetSymbolsSymbolPrices(this.extend(request, params));
1035
+ //
1036
+ // {
1037
+ // "markPrice": "100.00",
1038
+ // "indexPrice": "100.00",
1039
+ // "ltp": "101.34",
1040
+ // "movingFundingRate": "0.08",
1041
+ // "payoutFundingRate": "-0.03",
1042
+ // "nextFundingPayout": 1711555532146
1043
+ // }
1044
+ //
1045
+ return this.parseTicker(response, market);
1046
+ }
1047
+ /**
1048
+ * @method
1049
+ * @name defx#fetchFundingRate
1050
+ * @description fetch the current funding rate
1051
+ * @see https://api-docs.defx.com/#12168192-4e7b-4458-a001-e8b80961f0b7
1052
+ * @param {string} symbol unified market symbol
1053
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1054
+ * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
1055
+ */
1056
+ async fetchFundingRate(symbol, params = {}) {
1057
+ await this.loadMarkets();
1058
+ const market = this.market(symbol);
1059
+ const request = {
1060
+ 'symbol': market['id'],
1061
+ };
1062
+ const response = await this.v1PublicGetSymbolsSymbolPrices(this.extend(request, params));
1063
+ //
1064
+ // {
1065
+ // "markPrice": "100.00",
1066
+ // "indexPrice": "100.00",
1067
+ // "ltp": "101.34",
1068
+ // "movingFundingRate": "0.08",
1069
+ // "payoutFundingRate": "-0.03",
1070
+ // "nextFundingPayout": 1711555532146
1071
+ // }
1072
+ //
1073
+ return this.parseFundingRate(response, market);
1074
+ }
1075
+ parseFundingRate(contract, market = undefined) {
1076
+ //
1077
+ // {
1078
+ // "markPrice": "100.00",
1079
+ // "indexPrice": "100.00",
1080
+ // "ltp": "101.34",
1081
+ // "movingFundingRate": "0.08",
1082
+ // "payoutFundingRate": "-0.03",
1083
+ // "nextFundingPayout": 1711555532146
1084
+ // }
1085
+ //
1086
+ const markPrice = this.safeNumber(contract, 'markPrice');
1087
+ const indexPrice = this.safeNumber(contract, 'indexPrice');
1088
+ const fundingRate = this.safeNumber(contract, 'payoutFundingRate');
1089
+ const fundingTime = this.safeInteger(contract, 'nextFundingPayout');
1090
+ return {
1091
+ 'info': contract,
1092
+ 'symbol': market['symbol'],
1093
+ 'markPrice': markPrice,
1094
+ 'indexPrice': indexPrice,
1095
+ 'interestRate': undefined,
1096
+ 'estimatedSettlePrice': undefined,
1097
+ 'timestamp': undefined,
1098
+ 'datetime': undefined,
1099
+ 'fundingRate': fundingRate,
1100
+ 'fundingTimestamp': fundingTime,
1101
+ 'fundingDatetime': this.iso8601(fundingTime),
1102
+ 'nextFundingRate': undefined,
1103
+ 'nextFundingTimestamp': undefined,
1104
+ 'nextFundingDatetime': undefined,
1105
+ 'previousFundingRate': undefined,
1106
+ 'previousFundingTimestamp': undefined,
1107
+ 'previousFundingDatetime': undefined,
1108
+ 'interval': undefined,
1109
+ };
1110
+ }
1111
+ /**
1112
+ * @method
1113
+ * @name defx#fetchBalance
1114
+ * @description query for balance and get the amount of funds available for trading or funds locked in orders
1115
+ * @see https://api-docs.defx.com/#26414338-14f7-40a1-b246-f8ea8571493f
1116
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1117
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
1118
+ */
1119
+ async fetchBalance(params = {}) {
1120
+ await this.loadMarkets();
1121
+ const response = await this.v1PrivateGetApiWalletBalance(params);
1122
+ //
1123
+ // {
1124
+ // "assets": [
1125
+ // {
1126
+ // "asset": "USDC",
1127
+ // "balance": "0.000"
1128
+ // }
1129
+ // ]
1130
+ // }
1131
+ //
1132
+ const data = this.safeList(response, 'assets');
1133
+ return this.parseBalance(data);
1134
+ }
1135
+ parseBalance(balances) {
1136
+ const result = {
1137
+ 'info': balances,
1138
+ };
1139
+ for (let i = 0; i < balances.length; i++) {
1140
+ const balance = balances[i];
1141
+ const code = this.safeCurrencyCode(this.safeString(balance, 'asset'));
1142
+ const account = this.account();
1143
+ account['total'] = this.safeString(balance, 'balance');
1144
+ result[code] = account;
1145
+ }
1146
+ return this.safeBalance(result);
1147
+ }
1148
+ /**
1149
+ * @method
1150
+ * @name defx#createOrder
1151
+ * @description create a trade order
1152
+ * @see https://api-docs.defx.com/#ba222d88-8856-4d3c-87a9-7cec07bb2622
1153
+ * @param {string} symbol unified symbol of the market to create an order in
1154
+ * @param {string} type 'market' or 'limit'
1155
+ * @param {string} side 'buy' or 'sell'
1156
+ * @param {float} amount how much of currency you want to trade in units of base currency
1157
+ * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1158
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1159
+ * @param {float} [params.triggerPrice] The price a trigger order is triggered at
1160
+ * @param {string} [params.reduceOnly] for swap and future reduceOnly is a string 'true' or 'false' that cant be sent with close position set to true or in hedge mode. For spot margin and option reduceOnly is a boolean.
1161
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1162
+ */
1163
+ async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1164
+ await this.loadMarkets();
1165
+ const market = this.market(symbol);
1166
+ const reduceOnly = this.safeBool2(params, 'reduceOnly', 'reduce_only');
1167
+ params = this.omit(params, ['reduceOnly', 'reduce_only']);
1168
+ const orderType = type.toUpperCase();
1169
+ const orderSide = side.toUpperCase();
1170
+ const request = {
1171
+ 'symbol': market['id'],
1172
+ 'side': orderSide,
1173
+ 'type': orderType,
1174
+ };
1175
+ const takeProfitPrice = this.safeString(params, 'takeProfitPrice');
1176
+ const stopPrice = this.safeString2(params, 'stopPrice', 'triggerPrice');
1177
+ const isMarket = orderType === 'MARKET';
1178
+ const isLimit = orderType === 'LIMIT';
1179
+ const timeInForce = this.safeStringUpper(params, 'timeInForce');
1180
+ if (timeInForce !== undefined) {
1181
+ // GTC, IOC, FOK, AON
1182
+ request['timeInForce'] = timeInForce;
1183
+ }
1184
+ else {
1185
+ if (isLimit) {
1186
+ request['timeInForce'] = 'GTC';
1187
+ }
1188
+ }
1189
+ if (reduceOnly) {
1190
+ request['reduceOnly'] = reduceOnly;
1191
+ }
1192
+ const clientOrderId = this.safeString(params, 'clientOrderId');
1193
+ if (clientOrderId !== undefined) {
1194
+ request['newClientOrderId'] = clientOrderId;
1195
+ }
1196
+ if (stopPrice !== undefined || takeProfitPrice !== undefined) {
1197
+ request['workingType'] = 'MARK_PRICE';
1198
+ if (takeProfitPrice !== undefined) {
1199
+ request['stopPrice'] = this.priceToPrecision(symbol, takeProfitPrice);
1200
+ if (isMarket) {
1201
+ request['type'] = 'TAKE_PROFIT_MARKET';
1202
+ }
1203
+ else {
1204
+ request['type'] = 'TAKE_PROFIT_LIMIT';
1205
+ }
1206
+ }
1207
+ else {
1208
+ request['stopPrice'] = this.priceToPrecision(symbol, stopPrice);
1209
+ if (isMarket) {
1210
+ request['type'] = 'STOP_MARKET';
1211
+ }
1212
+ else {
1213
+ request['type'] = 'STOP_LIMIT';
1214
+ }
1215
+ }
1216
+ }
1217
+ if (isLimit && price !== undefined) {
1218
+ request['price'] = this.priceToPrecision(symbol, price);
1219
+ }
1220
+ request['quantity'] = this.amountToPrecision(symbol, amount);
1221
+ params = this.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id', 'postOnly', 'timeInForce', 'stopPrice', 'triggerPrice', 'takeProfitPrice']);
1222
+ const response = await this.v1PrivatePostApiOrder(this.extend(request, params));
1223
+ //
1224
+ // {
1225
+ // "success": true,
1226
+ // "data": {
1227
+ // "orderId": "",
1228
+ // "clientOrderId": "",
1229
+ // "cumulativeQty": "",
1230
+ // "cumulativeQuote": "",
1231
+ // "executedQty": "",
1232
+ // "avgPrice": "",
1233
+ // "origQty": "",
1234
+ // "price": "",
1235
+ // "reduceOnly": true,
1236
+ // "side": "",
1237
+ // "status": "",
1238
+ // "symbol": "",
1239
+ // "timeInForce": "",
1240
+ // "type": "",
1241
+ // "workingType": ""
1242
+ // }
1243
+ // }
1244
+ //
1245
+ const data = this.safeDict(response, 'data');
1246
+ return this.parseOrder(data, market);
1247
+ }
1248
+ parseOrderStatus(status) {
1249
+ if (status !== undefined) {
1250
+ const statuses = {
1251
+ 'NEW': 'open',
1252
+ 'OPEN': 'open',
1253
+ 'CANCELLED': 'canceled',
1254
+ 'REJECTED': 'rejected',
1255
+ 'FILLED': 'closed',
1256
+ };
1257
+ return this.safeString(statuses, status, status);
1258
+ }
1259
+ return status;
1260
+ }
1261
+ parseOrder(order, market = undefined) {
1262
+ //
1263
+ // {
1264
+ // "orderId": "746472647227344528",
1265
+ // "createdAt": "2024-10-25T16:49:31.077Z",
1266
+ // "updatedAt": "2024-10-25T16:49:31.378Z",
1267
+ // "clientOrderId": "0192c495-49c3-71ee-b3d3-7442a2090807",
1268
+ // "reduceOnly": false,
1269
+ // "side": "SELL",
1270
+ // "status": "FILLED",
1271
+ // "symbol": "SOL_USDC",
1272
+ // "timeInForce": "GTC",
1273
+ // "type": "MARKET",
1274
+ // "origQty": "0.80",
1275
+ // "executedQty": "0.80",
1276
+ // "cumulativeQuote": "137.87440000",
1277
+ // "avgPrice": "172.34300000",
1278
+ // "totalPnL": "0.00000000",
1279
+ // "totalFee": "0.07583092",
1280
+ // "workingType": null,
1281
+ // "postOnly": false,
1282
+ // "linkedOrderParentType": null,
1283
+ // "isTriggered": false,
1284
+ // "slippagePercentage": "5"
1285
+ // }
1286
+ //
1287
+ const orderId = this.safeString(order, 'orderId');
1288
+ const clientOrderId = this.safeString(order, 'clientOrderId');
1289
+ const marketId = this.safeString(order, 'symbol');
1290
+ market = this.safeMarket(marketId, market);
1291
+ const symbol = market['symbol'];
1292
+ const price = this.safeString(order, 'price');
1293
+ const amount = this.safeString(order, 'origQty');
1294
+ const orderType = this.safeStringLower(order, 'type');
1295
+ const status = this.safeString(order, 'status');
1296
+ const side = this.safeStringLower(order, 'side');
1297
+ const filled = this.omitZero(this.safeString(order, 'executedQty'));
1298
+ const average = this.omitZero(this.safeString(order, 'avgPrice'));
1299
+ const timeInForce = this.safeStringLower(order, 'timeInForce');
1300
+ let takeProfitPrice = undefined;
1301
+ let stopPrice = undefined;
1302
+ if (orderType !== undefined) {
1303
+ if (orderType.indexOf('take_profit') >= 0) {
1304
+ takeProfitPrice = this.safeString(order, 'stopPrice');
1305
+ }
1306
+ else {
1307
+ stopPrice = this.safeString(order, 'stopPrice');
1308
+ }
1309
+ }
1310
+ const timestamp = this.parse8601(this.safeString(order, 'createdAt'));
1311
+ const lastTradeTimestamp = this.parse8601(this.safeString(order, 'updatedAt'));
1312
+ return this.safeOrder({
1313
+ 'id': orderId,
1314
+ 'clientOrderId': clientOrderId,
1315
+ 'timestamp': timestamp,
1316
+ 'datetime': this.iso8601(timestamp),
1317
+ 'lastTradeTimestamp': lastTradeTimestamp,
1318
+ 'lastUpdateTimestamp': lastTradeTimestamp,
1319
+ 'status': this.parseOrderStatus(status),
1320
+ 'symbol': symbol,
1321
+ 'type': orderType,
1322
+ 'timeInForce': timeInForce,
1323
+ 'postOnly': this.safeBool(order, 'postOnly'),
1324
+ 'reduceOnly': this.safeBool(order, 'reduceOnly'),
1325
+ 'side': side,
1326
+ 'price': price,
1327
+ 'stopPrice': stopPrice,
1328
+ 'triggerPrice': stopPrice,
1329
+ 'takeProfitPrice': takeProfitPrice,
1330
+ 'stopLossPrice': undefined,
1331
+ 'average': average,
1332
+ 'amount': amount,
1333
+ 'filled': filled,
1334
+ 'remaining': undefined,
1335
+ 'cost': undefined,
1336
+ 'trades': undefined,
1337
+ 'fee': {
1338
+ 'cost': this.safeString(order, 'totalFee'),
1339
+ 'currency': 'USDC',
1340
+ },
1341
+ 'info': order,
1342
+ }, market);
1343
+ }
1344
+ /**
1345
+ * @method
1346
+ * @name defx#cancelOrder
1347
+ * @see https://api-docs.defx.com/#09186f23-f8d1-4993-acf4-9974d8a6ddb0
1348
+ * @description cancels an open order
1349
+ * @param {string} id order id
1350
+ * @param {string} symbol unified symbol of the market the order was made in
1351
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1352
+ * @param {boolean} [params.stop] whether the order is a stop/algo order
1353
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1354
+ */
1355
+ async cancelOrder(id, symbol = undefined, params = {}) {
1356
+ await this.loadMarkets();
1357
+ const request = {
1358
+ 'orderId': id,
1359
+ 'idType': 'orderId',
1360
+ };
1361
+ const clientOrderId = this.safeStringN(params, ['clOrdID', 'clientOrderId', 'client_order_id']);
1362
+ const isByClientOrder = clientOrderId !== undefined;
1363
+ if (isByClientOrder) {
1364
+ if (symbol === undefined) {
1365
+ throw new ArgumentsRequired(this.id + ' cancelOrder() requires a symbol argument');
1366
+ }
1367
+ const market = this.market(symbol);
1368
+ request['orderId'] = clientOrderId;
1369
+ request['idType'] = 'clientOrderId';
1370
+ request['symbol'] = market['id'];
1371
+ }
1372
+ params = this.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id']);
1373
+ const response = await this.v1PrivateDeleteApiOrderOrderId(this.extend(request, params));
1374
+ //
1375
+ // {
1376
+ // "success": true
1377
+ // }
1378
+ //
1379
+ const extendParams = { 'symbol': symbol };
1380
+ if (isByClientOrder) {
1381
+ extendParams['clientOrderId'] = clientOrderId;
1382
+ }
1383
+ else {
1384
+ extendParams['id'] = id;
1385
+ }
1386
+ return this.extend(this.parseOrder(response), extendParams);
1387
+ }
1388
+ /**
1389
+ * @method
1390
+ * @name defx#cancelAllOrders
1391
+ * @description cancel all open orders
1392
+ * @see https://api-docs.defx.com/#db5531da-3692-4a53-841f-6ad6495f823a
1393
+ * @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
1394
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1395
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1396
+ */
1397
+ async cancelAllOrders(symbol = undefined, params = {}) {
1398
+ await this.loadMarkets();
1399
+ const market = this.market(symbol);
1400
+ const request = {
1401
+ 'symbols': [market['id']],
1402
+ };
1403
+ const response = await this.v1PrivateDeleteApiOrdersAllOpen(this.extend(request, params));
1404
+ //
1405
+ // {
1406
+ // "data": {
1407
+ // "msg": "The operation of cancel all open order is done."
1408
+ // }
1409
+ // }
1410
+ //
1411
+ return response;
1412
+ }
1413
+ /**
1414
+ * @method
1415
+ * @name defx#fetchPosition
1416
+ * @description fetch data on a single open contract trade position
1417
+ * @see https://api-docs.defx.com/#d89dbb86-9aba-4f59-ac5d-a97ff25ea80e
1418
+ * @param {string} symbol unified market symbol of the market the position is held in, default is undefined
1419
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1420
+ * @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
1421
+ */
1422
+ async fetchPosition(symbol, params = {}) {
1423
+ if (symbol === undefined) {
1424
+ throw new ArgumentsRequired(this.id + ' fetchPosition() requires a symbol argument');
1425
+ }
1426
+ await this.loadMarkets();
1427
+ const market = this.market(symbol);
1428
+ const request = {
1429
+ 'symbol': market['id'],
1430
+ };
1431
+ const response = await this.v1PrivateGetApiPositionActive(this.extend(request, params));
1432
+ //
1433
+ // {
1434
+ // "data": [
1435
+ // {
1436
+ // "positionId": "0192c495-4a68-70ee-9081-9d368bd16dfc",
1437
+ // "symbol": "SOL_USDC",
1438
+ // "positionSide": "SHORT",
1439
+ // "entryPrice": "172.34300000",
1440
+ // "quantity": "0.80",
1441
+ // "marginAmount": "20.11561173",
1442
+ // "marginAsset": "USDC",
1443
+ // "pnl": "0.00000000"
1444
+ // }
1445
+ // ]
1446
+ // }
1447
+ //
1448
+ const data = this.safeList(response, 'data', []);
1449
+ const first = this.safeDict(data, 0, {});
1450
+ return this.parsePosition(first, market);
1451
+ }
1452
+ /**
1453
+ * @method
1454
+ * @name defx#fetchPositions
1455
+ * @description fetch all open positions
1456
+ * @see https://api-docs.defx.com/#d89dbb86-9aba-4f59-ac5d-a97ff25ea80e
1457
+ * @param {string[]} [symbols] list of unified market symbols
1458
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1459
+ * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
1460
+ */
1461
+ async fetchPositions(symbols = undefined, params = {}) {
1462
+ await this.loadMarkets();
1463
+ const response = await this.v1PrivateGetApiPositionActive(params);
1464
+ //
1465
+ // {
1466
+ // "data": [
1467
+ // {
1468
+ // "positionId": "0192c495-4a68-70ee-9081-9d368bd16dfc",
1469
+ // "symbol": "SOL_USDC",
1470
+ // "positionSide": "SHORT",
1471
+ // "entryPrice": "172.34300000",
1472
+ // "quantity": "0.80",
1473
+ // "marginAmount": "20.11561173",
1474
+ // "marginAsset": "USDC",
1475
+ // "pnl": "0.00000000"
1476
+ // }
1477
+ // ]
1478
+ // }
1479
+ //
1480
+ const positions = this.safeList(response, 'data', []);
1481
+ return this.parsePositions(positions, symbols);
1482
+ }
1483
+ parsePosition(position, market = undefined) {
1484
+ //
1485
+ // {
1486
+ // "positionId": "0192c495-4a68-70ee-9081-9d368bd16dfc",
1487
+ // "symbol": "SOL_USDC",
1488
+ // "positionSide": "SHORT",
1489
+ // "entryPrice": "172.34300000",
1490
+ // "quantity": "0.80",
1491
+ // "marginAmount": "20.11561173",
1492
+ // "marginAsset": "USDC",
1493
+ // "pnl": "0.00000000"
1494
+ // }
1495
+ //
1496
+ const marketId = this.safeString(position, 'symbol');
1497
+ market = this.safeMarket(marketId, market);
1498
+ const size = Precise.stringAbs(this.safeString(position, 'quantity'));
1499
+ const side = this.safeStringLower(position, 'positionSide');
1500
+ const unrealisedPnl = this.omitZero(this.safeString(position, 'pnl'));
1501
+ const entryPrice = this.omitZero(this.safeString(position, 'entryPrice'));
1502
+ const initialMargin = this.safeString(position, 'marginAmount');
1503
+ return this.safePosition({
1504
+ 'info': position,
1505
+ 'id': this.safeString(position, 'positionId'),
1506
+ 'symbol': market['symbol'],
1507
+ 'timestamp': undefined,
1508
+ 'datetime': undefined,
1509
+ 'lastUpdateTimestamp': undefined,
1510
+ 'initialMargin': this.parseNumber(initialMargin),
1511
+ 'initialMarginPercentage': undefined,
1512
+ 'maintenanceMargin': undefined,
1513
+ 'maintenanceMarginPercentage': undefined,
1514
+ 'entryPrice': this.parseNumber(entryPrice),
1515
+ 'notional': undefined,
1516
+ 'leverage': undefined,
1517
+ 'unrealizedPnl': this.parseNumber(unrealisedPnl),
1518
+ 'realizedPnl': undefined,
1519
+ 'contracts': this.parseNumber(size),
1520
+ 'contractSize': this.safeNumber(market, 'contractSize'),
1521
+ 'marginRatio': undefined,
1522
+ 'liquidationPrice': undefined,
1523
+ 'markPrice': undefined,
1524
+ 'lastPrice': undefined,
1525
+ 'collateral': undefined,
1526
+ 'marginMode': undefined,
1527
+ 'side': side,
1528
+ 'percentage': undefined,
1529
+ 'stopLossPrice': undefined,
1530
+ 'takeProfitPrice': undefined,
1531
+ 'hedged': undefined,
1532
+ });
1533
+ }
1534
+ /**
1535
+ * @method
1536
+ * @name defx#fetchOrder
1537
+ * @description fetches information on an order made by the user
1538
+ * @see https://api-docs.defx.com/#44f82dd5-26b3-4e1f-b4aa-88ceddd65237
1539
+ * @param {string} id the order id
1540
+ * @param {string} symbol unified symbol of the market the order was made in
1541
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1542
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1543
+ */
1544
+ async fetchOrder(id, symbol = undefined, params = {}) {
1545
+ await this.loadMarkets();
1546
+ const request = {
1547
+ 'orderId': id,
1548
+ 'idType': 'orderId',
1549
+ };
1550
+ const clientOrderId = this.safeStringN(params, ['clOrdID', 'clientOrderId', 'client_order_id']);
1551
+ params = this.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id']);
1552
+ if (clientOrderId !== undefined) {
1553
+ if (symbol === undefined) {
1554
+ throw new ArgumentsRequired(this.id + ' fetchOrder() requires a symbol argument');
1555
+ }
1556
+ const market = this.market(symbol);
1557
+ request['orderId'] = clientOrderId;
1558
+ request['idType'] = 'clientOrderId';
1559
+ request['symbol'] = market['id'];
1560
+ }
1561
+ const response = await this.v1PrivateGetApiOrderOrderId(this.extend(request, params));
1562
+ //
1563
+ // {
1564
+ // "success": true,
1565
+ // "data": {
1566
+ // "orderId": "555068654076559792",
1567
+ // "createdAt": "2024-05-08T05:45:42.148Z",
1568
+ // "updatedAt": "2024-05-08T05:45:42.166Z",
1569
+ // "clientOrderId": "dummyClientOrderId",
1570
+ // "reduceOnly": false,
1571
+ // "side": "SELL",
1572
+ // "status": "REJECTED",
1573
+ // "symbol": "BTC_USDC",
1574
+ // "timeInForce": "GTC",
1575
+ // "type": "TAKE_PROFIT_MARKET",
1576
+ // "origQty": "1.000",
1577
+ // "executedQty": "0.000",
1578
+ // "cumulativeQuote": "0.00",
1579
+ // "avgPrice": "0.00",
1580
+ // "stopPrice": "65000.00",
1581
+ // "totalPnL": "0.00",
1582
+ // "workingType": "MARK_PRICE",
1583
+ // "postOnly": false
1584
+ // }
1585
+ // }
1586
+ //
1587
+ const data = this.safeDict(response, 'data');
1588
+ return this.parseOrder(data);
1589
+ }
1590
+ /**
1591
+ * @method
1592
+ * @name defx#fetchOrders
1593
+ * @description fetches information on multiple orders made by the user
1594
+ * @see https://api-docs.defx.com/#ab200038-8acb-4170-b05e-4fcb4cc13751
1595
+ * @param {string} symbol unified market symbol
1596
+ * @param {int} [since] the earliest time in ms to fetch open orders for
1597
+ * @param {int} [limit] the maximum number of open order structures to retrieve
1598
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1599
+ * @param {int} [params.until] the latest time in ms to fetch orders for
1600
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1601
+ */
1602
+ async fetchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1603
+ await this.loadMarkets();
1604
+ const request = {};
1605
+ if (symbol !== undefined) {
1606
+ const market = this.market(symbol);
1607
+ request['symbols'] = market['id'];
1608
+ }
1609
+ const until = this.safeInteger(params, 'until');
1610
+ if (until !== undefined) {
1611
+ params = this.omit(params, 'until');
1612
+ request['end'] = this.iso8601(until);
1613
+ }
1614
+ if (since !== undefined) {
1615
+ request['start'] = this.iso8601(since);
1616
+ }
1617
+ if (limit !== undefined) {
1618
+ const maxLimit = 100;
1619
+ limit = Math.min(maxLimit, limit);
1620
+ request['pageSize'] = limit;
1621
+ }
1622
+ const response = await this.v1PrivateGetApiOrders(this.extend(request, params));
1623
+ //
1624
+ // {
1625
+ // "data": [
1626
+ // {
1627
+ // "orderId": "746472647227344528",
1628
+ // "createdAt": "2024-10-25T16:49:31.077Z",
1629
+ // "updatedAt": "2024-10-25T16:49:31.378Z",
1630
+ // "clientOrderId": "0192c495-49c3-71ee-b3d3-7442a2090807",
1631
+ // "reduceOnly": false,
1632
+ // "side": "SELL",
1633
+ // "status": "FILLED",
1634
+ // "symbol": "SOL_USDC",
1635
+ // "timeInForce": "GTC",
1636
+ // "type": "MARKET",
1637
+ // "origQty": "0.80",
1638
+ // "executedQty": "0.80",
1639
+ // "cumulativeQuote": "137.87440000",
1640
+ // "avgPrice": "172.34300000",
1641
+ // "totalPnL": "0.00000000",
1642
+ // "totalFee": "0.07583092",
1643
+ // "workingType": null,
1644
+ // "postOnly": false,
1645
+ // "linkedOrderParentType": null,
1646
+ // "isTriggered": false,
1647
+ // "slippagePercentage": 5
1648
+ // }
1649
+ // ]
1650
+ // }
1651
+ //
1652
+ const data = this.safeList(response, 'data', []);
1653
+ return this.parseOrders(data, undefined, since, limit);
1654
+ }
1655
+ /**
1656
+ * @method
1657
+ * @name defx#fetchOpenOrders
1658
+ * @description fetch all unfilled currently open orders
1659
+ * @see https://api-docs.defx.com/#ab200038-8acb-4170-b05e-4fcb4cc13751
1660
+ * @param {string} symbol unified market symbol
1661
+ * @param {int} [since] the earliest time in ms to fetch open orders for
1662
+ * @param {int} [limit] the maximum number of open order structures to retrieve
1663
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1664
+ * @param {int} [params.until] the latest time in ms to fetch orders for
1665
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1666
+ */
1667
+ async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1668
+ params['statuses'] = 'OPEN';
1669
+ return await this.fetchOrders(symbol, since, limit, params);
1670
+ }
1671
+ /**
1672
+ * @method
1673
+ * @name defx#fetchClosedOrders
1674
+ * @description fetches information on multiple closed orders made by the user
1675
+ * @see https://api-docs.defx.com/#ab200038-8acb-4170-b05e-4fcb4cc13751
1676
+ * @param {string} symbol unified market symbol
1677
+ * @param {int} [since] the earliest time in ms to fetch open orders for
1678
+ * @param {int} [limit] the maximum number of open order structures to retrieve
1679
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1680
+ * @param {int} [params.until] the latest time in ms to fetch orders for
1681
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1682
+ */
1683
+ async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1684
+ params['statuses'] = 'FILLED';
1685
+ return await this.fetchOrders(symbol, since, limit, params);
1686
+ }
1687
+ /**
1688
+ * @method
1689
+ * @name defx#fetchCanceledOrders
1690
+ * @description fetches information on multiple canceled orders made by the user
1691
+ * @see https://api-docs.defx.com/#ab200038-8acb-4170-b05e-4fcb4cc13751
1692
+ * @param {string} symbol unified market symbol
1693
+ * @param {int} [since] the earliest time in ms to fetch open orders for
1694
+ * @param {int} [limit] the maximum number of open order structures to retrieve
1695
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1696
+ * @param {int} [params.until] the latest time in ms to fetch orders for
1697
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1698
+ */
1699
+ async fetchCanceledOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1700
+ params['statuses'] = 'CANCELED';
1701
+ return await this.fetchOrders(symbol, since, limit, params);
1702
+ }
1703
+ /**
1704
+ * @method
1705
+ * @name defx#closePosition
1706
+ * @description closes an open position for a market
1707
+ * @see https://api-docs.defx.com/#b2c08074-c4d9-4e50-b637-0d6c498fa29e
1708
+ * @param {string} symbol unified CCXT market symbol
1709
+ * @param {string} [side] one-way mode: 'buy' or 'sell', hedge-mode: 'long' or 'short'
1710
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1711
+ * @param {string} [params.positionId] the position id you want to close
1712
+ * @param {string} [params.type] 'MARKET' or 'LIMIT'
1713
+ * @param {string} [params.quantity] how much of currency you want to trade in units of base currency
1714
+ * @param {string} [params.price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1715
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1716
+ */
1717
+ async closePosition(symbol, side = undefined, params = {}) {
1718
+ await this.loadMarkets();
1719
+ const positionId = this.safeString(params, 'positionId');
1720
+ if (positionId === undefined) {
1721
+ throw new ArgumentsRequired(this.id + ' closePosition() requires a positionId');
1722
+ }
1723
+ const type = this.safeStringUpper(params, 'type');
1724
+ if (type === undefined) {
1725
+ throw new ArgumentsRequired(this.id + ' closePosition() requires a type');
1726
+ }
1727
+ const quantity = this.safeString(params, 'quantity');
1728
+ if (quantity === undefined) {
1729
+ throw new ArgumentsRequired(this.id + ' closePosition() requires a quantity');
1730
+ }
1731
+ const request = {
1732
+ 'positionId': positionId,
1733
+ 'type': type,
1734
+ 'quantity': quantity,
1735
+ };
1736
+ if (type !== 'MARKET') {
1737
+ const price = this.safeString(params, 'price');
1738
+ if (price === undefined) {
1739
+ throw new ArgumentsRequired(this.id + ' closePosition() requires a price');
1740
+ }
1741
+ request['price'] = price;
1742
+ }
1743
+ params = this.omit(params, ['positionId', 'type', 'quantity', 'price']);
1744
+ const response = await this.v1PrivateDeleteApiPositionPositionId(this.extend(request, params));
1745
+ //
1746
+ // {}
1747
+ //
1748
+ return response;
1749
+ }
1750
+ /**
1751
+ * @method
1752
+ * @name defx#closeAllPositions
1753
+ * @description closes all open positions for a market type
1754
+ * @see https://api-docs.defx.com/#d6f63b43-100e-47a9-998c-8b6c0c72d204
1755
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1756
+ * @returns {object[]} A list of [position structures]{@link https://docs.ccxt.com/#/?id=position-structure}
1757
+ */
1758
+ async closeAllPositions(params = {}) {
1759
+ await this.loadMarkets();
1760
+ const response = await this.v1PrivateDeleteApiPositionAll(params);
1761
+ //
1762
+ // {
1763
+ // "data": [
1764
+ // {
1765
+ // "positionId": "d6ca1a27-28ad-47ae-b244-0bda5ac37b2b",
1766
+ // "success": true
1767
+ // }
1768
+ // ]
1769
+ // }
1770
+ //
1771
+ const data = this.safeList(response, 'data', []);
1772
+ return this.parsePositions(data, undefined, params);
1773
+ }
1774
+ /**
1775
+ * @method
1776
+ * @name defx#fetchLedger
1777
+ * @description fetch the history of changes, actions done by the user or operations that altered the balance of the user
1778
+ * @see https://api-docs.defx.com/#38cc8974-794f-48c0-b959-db045a0ee565
1779
+ * @param {string} [code] unified currency code
1780
+ * @param {int} [since] timestamp in ms of the earliest ledger entry
1781
+ * @param {int} [limit] max number of ledger entries to return
1782
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1783
+ * @param {int} [params.until] timestamp in ms of the latest ledger entry
1784
+ * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
1785
+ * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger-structure}
1786
+ */
1787
+ async fetchLedger(code = undefined, since = undefined, limit = undefined, params = {}) {
1788
+ await this.loadMarkets();
1789
+ let paginate = false;
1790
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchLedger', 'paginate');
1791
+ if (paginate) {
1792
+ return await this.fetchPaginatedCallDynamic('fetchLedger', code, since, limit, params);
1793
+ }
1794
+ const request = {};
1795
+ if (since !== undefined) {
1796
+ request['start'] = since;
1797
+ }
1798
+ else {
1799
+ request['start'] = 0;
1800
+ }
1801
+ const until = this.safeInteger(params, 'until');
1802
+ if (until !== undefined) {
1803
+ params = this.omit(params, 'until');
1804
+ request['end'] = until;
1805
+ }
1806
+ else {
1807
+ request['end'] = this.milliseconds();
1808
+ }
1809
+ const response = await this.v1PrivateGetApiWalletTransactions(this.extend(request, params));
1810
+ const data = this.safeList(response, 'transactions', []);
1811
+ return this.parseLedger(data, undefined, since, limit);
1812
+ }
1813
+ parseLedgerEntry(item, currency = undefined) {
1814
+ //
1815
+ // {
1816
+ // "id": "01JCSZS6H5VQND3GF5P98SJ29C",
1817
+ // "timestamp": 1731744012054,
1818
+ // "type": "FundingFee",
1819
+ // "amount": "0.02189287",
1820
+ // "asset": "USDC",
1821
+ // "operation": "CREDIT"
1822
+ // }
1823
+ //
1824
+ const amount = this.safeString(item, 'amount');
1825
+ const currencyId = this.safeString(item, 'asset');
1826
+ const code = this.safeCurrencyCode(currencyId, currency);
1827
+ currency = this.safeCurrency(currencyId, currency);
1828
+ const timestamp = this.safeInteger(item, 'timestamp');
1829
+ const type = this.safeString(item, 'type');
1830
+ return this.safeLedgerEntry({
1831
+ 'info': item,
1832
+ 'id': this.safeString(item, 'id'),
1833
+ 'direction': undefined,
1834
+ 'account': undefined,
1835
+ 'referenceAccount': undefined,
1836
+ 'referenceId': undefined,
1837
+ 'type': this.parseLedgerEntryType(type),
1838
+ 'currency': code,
1839
+ 'amount': this.parseNumber(amount),
1840
+ 'timestamp': timestamp,
1841
+ 'datetime': this.iso8601(timestamp),
1842
+ 'before': undefined,
1843
+ 'after': undefined,
1844
+ 'status': undefined,
1845
+ 'fee': undefined,
1846
+ }, currency);
1847
+ }
1848
+ parseLedgerEntryType(type) {
1849
+ const ledgerType = {
1850
+ 'FundingFee': 'fee',
1851
+ 'FeeRebate': 'fee',
1852
+ 'FeeKickback': 'fee',
1853
+ 'RealizedPnl': 'trade',
1854
+ 'LiquidationClearance': 'trade',
1855
+ 'Transfer': 'transfer',
1856
+ 'ReferralPayout': 'referral',
1857
+ 'Commission': 'commission',
1858
+ };
1859
+ return this.safeString(ledgerType, type, type);
1860
+ }
1861
+ /**
1862
+ * @method
1863
+ * @name defx#withdraw
1864
+ * @description make a withdrawal
1865
+ * @see https://api-docs.defx.com/#2600f503-63ed-4672-b8f6-69ea5f03203b
1866
+ * @param {string} code unified currency code
1867
+ * @param {float} amount the amount to withdraw
1868
+ * @param {string} address the address to withdraw to
1869
+ * @param {string} tag
1870
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1871
+ * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
1872
+ */
1873
+ async withdraw(code, amount, address, tag = undefined, params = {}) {
1874
+ await this.loadMarkets();
1875
+ const currency = this.currency(code);
1876
+ const request = {
1877
+ 'amount': this.currencyToPrecision(code, amount),
1878
+ 'asset': currency['id'],
1879
+ // 'network': 'ARB_SEPOLIA',
1880
+ // 'chainId': '421614',
1881
+ };
1882
+ const response = await this.v1PrivatePostApiTransfersBridgeWithdrawal(this.extend(request, params));
1883
+ //
1884
+ // {
1885
+ // "transactionId": "0x301e5851e5aefa733abfbc8b30817ca3b61601e0ddf1df8c59656fb888b0bc9c"
1886
+ // }
1887
+ //
1888
+ return this.parseTransaction(response, currency);
1889
+ }
1890
+ parseTransaction(transaction, currency = undefined) {
1891
+ //
1892
+ // withdraw
1893
+ //
1894
+ // {
1895
+ // "transactionId": "0x301e5851e5aefa733abfbc8b30817ca3b61601e0ddf1df8c59656fb888b0bc9c"
1896
+ // }
1897
+ //
1898
+ const txid = this.safeString(transaction, 'transactionId');
1899
+ return {
1900
+ 'info': transaction,
1901
+ 'id': undefined,
1902
+ 'txid': txid,
1903
+ 'timestamp': undefined,
1904
+ 'datetime': undefined,
1905
+ 'network': undefined,
1906
+ 'address': undefined,
1907
+ 'addressTo': undefined,
1908
+ 'addressFrom': undefined,
1909
+ 'tag': undefined,
1910
+ 'tagTo': undefined,
1911
+ 'tagFrom': undefined,
1912
+ 'type': undefined,
1913
+ 'amount': undefined,
1914
+ 'currency': this.safeCurrencyCode(undefined, currency),
1915
+ 'status': undefined,
1916
+ 'updated': undefined,
1917
+ 'internal': undefined,
1918
+ 'comment': undefined,
1919
+ 'fee': undefined,
1920
+ };
1921
+ }
1922
+ /**
1923
+ * @method
1924
+ * @name defx#setLeverage
1925
+ * @description set the level of leverage for a market
1926
+ * @see https://api-docs.defx.com/#4cb4ecc4-6c61-4194-8353-be67faaf7ca7
1927
+ * @param {float} leverage the rate of leverage
1928
+ * @param {string} symbol unified market symbol
1929
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1930
+ * @returns {object} response from the exchange
1931
+ */
1932
+ async setLeverage(leverage, symbol = undefined, params = {}) {
1933
+ if (symbol === undefined) {
1934
+ throw new ArgumentsRequired(this.id + ' setLeverage() requires a symbol argument');
1935
+ }
1936
+ await this.loadMarkets();
1937
+ const request = {
1938
+ 'leverage': this.numberToString(leverage),
1939
+ };
1940
+ const market = this.market(symbol);
1941
+ request['symbol'] = market['id'];
1942
+ const response = await this.v1PrivatePostApiUsersMetadataLeverage(this.extend(request, params));
1943
+ //
1944
+ // {
1945
+ // "success": true,
1946
+ // "data": {
1947
+ // "leverage": "11",
1948
+ // "symbol": "BTC_USDC"
1949
+ // }
1950
+ // }
1951
+ //
1952
+ const data = this.safeDict(response, 'data', {});
1953
+ return this.parseLeverage(data, market);
1954
+ }
1955
+ parseLeverage(leverage, market = undefined) {
1956
+ //
1957
+ // "data": {
1958
+ // "leverage": "11",
1959
+ // "symbol": "BTC_USDC"
1960
+ // }
1961
+ //
1962
+ const marketId = this.safeString(leverage, 'symbol');
1963
+ const leverageValue = this.safeInteger(leverage, 'leverage');
1964
+ return {
1965
+ 'info': leverage,
1966
+ 'symbol': this.safeSymbol(marketId, market),
1967
+ 'marginMode': undefined,
1968
+ 'longLeverage': leverageValue,
1969
+ 'shortLeverage': leverageValue,
1970
+ };
1971
+ }
1972
+ nonce() {
1973
+ return this.milliseconds();
1974
+ }
1975
+ sign(path, section = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
1976
+ const version = section[0];
1977
+ const access = section[1];
1978
+ const pathWithParams = this.implodeParams(path, params);
1979
+ let url = this.implodeHostname(this.urls['api'][access]);
1980
+ url += '/' + version + '/';
1981
+ params = this.omit(params, this.extractParams(path));
1982
+ params = this.keysort(params);
1983
+ if (access === 'public') {
1984
+ url += 'open/' + pathWithParams;
1985
+ if (Object.keys(params).length) {
1986
+ url += '?' + this.rawencode(params);
1987
+ }
1988
+ }
1989
+ else {
1990
+ this.checkRequiredCredentials();
1991
+ headers = { 'X-DEFX-SOURCE': 'ccxt' };
1992
+ url += 'auth/' + pathWithParams;
1993
+ const nonce = this.milliseconds().toString();
1994
+ let payload = nonce;
1995
+ if (method === 'GET' || path === 'api/order/{orderId}') {
1996
+ payload += this.rawencode(params);
1997
+ if (Object.keys(params).length) {
1998
+ url += '?' + this.rawencode(params);
1999
+ }
2000
+ }
2001
+ else {
2002
+ if (params !== undefined) {
2003
+ body = this.json(params);
2004
+ payload += body;
2005
+ }
2006
+ headers['Content-Type'] = 'application/json';
2007
+ }
2008
+ const signature = this.hmac(this.encode(payload), this.encode(this.secret), sha256);
2009
+ headers['X-DEFX-APIKEY'] = this.apiKey;
2010
+ headers['X-DEFX-TIMESTAMP'] = nonce;
2011
+ headers['X-DEFX-SIGNATURE'] = signature;
2012
+ }
2013
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
2014
+ }
2015
+ handleErrors(httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
2016
+ if (!response) {
2017
+ return undefined; // fallback to default error handler
2018
+ }
2019
+ // {"errorCode":404,"errorMessage":"Not Found"}
2020
+ // {"msg":"Missing auth signature","code":"missing_auth_signature"}
2021
+ // {"success":false,"err":{"msg":"Invalid order id","code":"invalid_order_id"}}
2022
+ const success = this.safeBool(response, 'success');
2023
+ const err = this.safeDict(response, 'err', response);
2024
+ const errorCode = this.safeString2(err, 'errorCode', 'code');
2025
+ if (!success) {
2026
+ const feedback = this.id + ' ' + this.json(response);
2027
+ this.throwBroadlyMatchedException(this.exceptions['broad'], body, feedback);
2028
+ this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
2029
+ }
2030
+ return undefined;
2031
+ }
2032
+ defaultNetworkCodeForCurrency(code) {
2033
+ const currencyItem = this.currency(code);
2034
+ const networks = currencyItem['networks'];
2035
+ const networkKeys = Object.keys(networks);
2036
+ for (let i = 0; i < networkKeys.length; i++) {
2037
+ const network = networkKeys[i];
2038
+ if (network === 'ETH') {
2039
+ return network;
2040
+ }
2041
+ }
2042
+ // if it was not returned according to above options, then return the first network of currency
2043
+ return this.safeValue(networkKeys, 0);
2044
+ }
2045
+ setSandboxMode(enable) {
2046
+ super.setSandboxMode(enable);
2047
+ this.options['sandboxMode'] = enable;
2048
+ }
2049
+ }