ccxt 4.5.26 → 4.5.28

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 (60) hide show
  1. package/README.md +6 -5
  2. package/dist/ccxt.browser.min.js +3 -3
  3. package/dist/cjs/ccxt.js +4 -1
  4. package/dist/cjs/src/abstract/zebpay.js +11 -0
  5. package/dist/cjs/src/base/Exchange.js +2 -2
  6. package/dist/cjs/src/binance.js +18 -7
  7. package/dist/cjs/src/bingx.js +5 -5
  8. package/dist/cjs/src/bitget.js +18 -17
  9. package/dist/cjs/src/bitmex.js +5 -1
  10. package/dist/cjs/src/blofin.js +5 -5
  11. package/dist/cjs/src/bybit.js +58 -29
  12. package/dist/cjs/src/coincatch.js +9 -9
  13. package/dist/cjs/src/coinex.js +93 -0
  14. package/dist/cjs/src/coinmate.js +20 -0
  15. package/dist/cjs/src/coinsph.js +23 -0
  16. package/dist/cjs/src/cryptocom.js +7 -0
  17. package/dist/cjs/src/gate.js +2 -0
  18. package/dist/cjs/src/hyperliquid.js +12 -15
  19. package/dist/cjs/src/pro/binance.js +1 -1
  20. package/dist/cjs/src/pro/bybit.js +1 -1
  21. package/dist/cjs/src/whitebit.js +4 -2
  22. package/dist/cjs/src/zebpay.js +1908 -0
  23. package/js/ccxt.d.ts +5 -2
  24. package/js/ccxt.js +4 -2
  25. package/js/src/abstract/binance.d.ts +3 -1
  26. package/js/src/abstract/binancecoinm.d.ts +3 -1
  27. package/js/src/abstract/binanceus.d.ts +3 -1
  28. package/js/src/abstract/binanceusdm.d.ts +3 -1
  29. package/js/src/abstract/coinex.d.ts +16 -0
  30. package/js/src/abstract/coinmate.d.ts +3 -0
  31. package/js/src/abstract/coinsph.d.ts +21 -0
  32. package/js/src/abstract/cryptocom.d.ts +7 -0
  33. package/js/src/abstract/gate.d.ts +2 -0
  34. package/js/src/abstract/gateio.d.ts +2 -0
  35. package/js/src/abstract/zebpay.d.ts +49 -0
  36. package/js/src/abstract/zebpay.js +11 -0
  37. package/js/src/base/Exchange.js +2 -2
  38. package/js/src/binance.d.ts +1 -0
  39. package/js/src/binance.js +18 -7
  40. package/js/src/bingx.js +5 -5
  41. package/js/src/bitget.js +19 -18
  42. package/js/src/bitmex.js +5 -1
  43. package/js/src/blofin.js +5 -5
  44. package/js/src/bybit.d.ts +3 -0
  45. package/js/src/bybit.js +58 -29
  46. package/js/src/coincatch.js +9 -9
  47. package/js/src/coinex.d.ts +11 -0
  48. package/js/src/coinex.js +93 -0
  49. package/js/src/coinmate.d.ts +9 -0
  50. package/js/src/coinmate.js +20 -0
  51. package/js/src/coinsph.js +23 -0
  52. package/js/src/cryptocom.js +7 -0
  53. package/js/src/gate.js +2 -0
  54. package/js/src/hyperliquid.js +12 -15
  55. package/js/src/pro/binance.js +1 -1
  56. package/js/src/pro/bybit.js +1 -1
  57. package/js/src/whitebit.js +4 -2
  58. package/js/src/zebpay.d.ts +361 -0
  59. package/js/src/zebpay.js +1907 -0
  60. package/package.json +1 -1
@@ -0,0 +1,1907 @@
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/zebpay.js';
9
+ import { TICK_SIZE } from './base/functions/number.js';
10
+ import { BadRequest, AuthenticationError, NotSupported, RateLimitExceeded, ExchangeNotAvailable, ExchangeError, ArgumentsRequired, InvalidOrder, OrderNotFound, InsufficientFunds } from './base/errors.js';
11
+ import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
12
+ import { Precise } from './base/Precise.js';
13
+ // ---------------------------------------------------------------------------
14
+ /**
15
+ * @class
16
+ * @augments Exchange
17
+ */
18
+ export default class zebpay extends Exchange {
19
+ describe() {
20
+ return this.deepExtend(super.describe(), {
21
+ 'id': 'zebpay',
22
+ 'name': 'Zebpay',
23
+ 'countries': ['IN'],
24
+ 'rateLimit': 50,
25
+ 'version': 'v1',
26
+ 'certified': false,
27
+ 'pro': false,
28
+ 'has': {
29
+ 'CORS': undefined,
30
+ 'spot': true,
31
+ 'margin': false,
32
+ 'swap': true,
33
+ 'future': false,
34
+ 'option': undefined,
35
+ 'addMargin': true,
36
+ 'cancelAllOrders': true,
37
+ 'cancelOrder': true,
38
+ 'cancelOrders': false,
39
+ 'closePosition': true,
40
+ 'createOrder': true,
41
+ 'fetchBalance': true,
42
+ 'fetchCurrencies': true,
43
+ 'fetchLeverage': true,
44
+ 'fetchLeverages': true,
45
+ 'fetchMarkets': true,
46
+ 'fetchMyTrades': true,
47
+ 'fetchOHLCV': true,
48
+ 'fetchOpenOrders': true,
49
+ 'fetchOrder': true,
50
+ 'fetchOrderBook': true,
51
+ 'fetchOrderTrades': true,
52
+ 'fetchPositions': true,
53
+ 'fetchTicker': true,
54
+ 'fetchTickers': true,
55
+ 'fetchTrades': true,
56
+ 'fetchTradingFee': true,
57
+ 'reduceMargin': true,
58
+ 'setLeverage': true,
59
+ },
60
+ 'timeframes': {
61
+ '1m': 1,
62
+ '5m': 5,
63
+ '15m': 15,
64
+ '30m': 30,
65
+ '1h': 60,
66
+ '2h': 120,
67
+ '4h': 480,
68
+ '12h': 720,
69
+ '1d': 1440,
70
+ '1w': 10080,
71
+ },
72
+ 'urls': {
73
+ 'logo': 'https://github.com/user-attachments/assets/8094e7be-55a7-46f4-a087-0ca31b48ecad',
74
+ 'api': {
75
+ 'spot': 'https://sapi.zebpay.com',
76
+ 'swap': 'https://futuresbe.zebpay.com',
77
+ },
78
+ 'test': {
79
+ 'spot': 'https://www.zebstage.com',
80
+ 'swap': 'https://dev-futuresbe.zebstage.com',
81
+ },
82
+ 'www': 'https://www.zebpay.com',
83
+ 'doc': 'https://github.com/zebpay/zebpay-api-references',
84
+ 'fees': 'https://zebpay.com/in/features/pricing',
85
+ },
86
+ 'api': {
87
+ 'public': {
88
+ 'spot': {
89
+ 'get': {
90
+ 'v2/system/time': 10,
91
+ 'v2/system/status': 10,
92
+ 'v2/market/orderbook': 10,
93
+ 'v2/market/trades': 10,
94
+ 'v2/market/ticker': 10,
95
+ 'v2/market/allTickers': 10,
96
+ 'v2/ex/exchangeInfo': 10,
97
+ 'v2/ex/currencies': 10,
98
+ 'v2/market/klines': 10,
99
+ 'v2/ex/tradefees': 10,
100
+ },
101
+ },
102
+ 'swap': {
103
+ 'get': {
104
+ 'v1/system/time': 10,
105
+ 'v1/system/status': 10,
106
+ 'v1/exchange/tradefee': 10,
107
+ 'v1/exchange/tradefees': 10,
108
+ 'v1/market/orderBook': 10,
109
+ 'v1/market/ticker24Hr': 10,
110
+ 'v1/market/markets': 10,
111
+ 'v1/market/aggTrade': 10,
112
+ },
113
+ 'post': {
114
+ 'v1/market/klines': 10,
115
+ },
116
+ },
117
+ },
118
+ 'private': {
119
+ 'spot': {
120
+ 'post': {
121
+ 'v2/ex/orders': 10,
122
+ },
123
+ 'get': {
124
+ 'v2/ex/orders': 10,
125
+ 'v2/account/balance': 10,
126
+ 'v2/ex/tradefee': 10,
127
+ 'v2/ex/order': 10,
128
+ 'v2/ex/order/fills': 10,
129
+ },
130
+ 'delete': {
131
+ 'v2/ex/order': 10,
132
+ 'v2/ex/orders': 10,
133
+ 'v2/ex/orders/cancelAll': 10,
134
+ },
135
+ },
136
+ 'swap': {
137
+ 'get': {
138
+ 'v1/wallet/balance': 10,
139
+ 'v1/trade/order': 10,
140
+ 'v1/trade/order/open-orders': 10,
141
+ 'v1/trade/userLeverages': 10,
142
+ 'v1/trade/userLeverage': 10,
143
+ 'v1/trade/positions': 10,
144
+ 'v1/trade/history': 10,
145
+ },
146
+ 'post': {
147
+ 'v1/trade/order': 10,
148
+ 'v1/trade/order/addTPSL': 10,
149
+ 'v1/trade/addMargin': 10,
150
+ 'v1/trade/reduceMargin': 10,
151
+ 'v1/trade/position/close': 10,
152
+ 'v1/trade/update/userLeverage': 10,
153
+ },
154
+ 'delete': {
155
+ 'v1/trade/order': 10,
156
+ },
157
+ },
158
+ },
159
+ },
160
+ 'precisionMode': TICK_SIZE,
161
+ 'fees': {},
162
+ 'commonCurrencies': {},
163
+ 'requiredCredentials': {
164
+ 'apiKey': true,
165
+ 'secret': true,
166
+ },
167
+ 'options': {
168
+ 'fetchMarkets': {
169
+ 'types': ['spot', 'swap'],
170
+ },
171
+ 'defaultType': 'spot', // 'spot', 'swap'
172
+ },
173
+ 'features': {
174
+ 'default': {
175
+ 'fetchOHLCV': {
176
+ 'limit': 100,
177
+ },
178
+ },
179
+ },
180
+ 'exceptions': {
181
+ 'exact': {
182
+ '77': InvalidOrder,
183
+ '400': BadRequest,
184
+ '401': AuthenticationError,
185
+ '403': NotSupported,
186
+ '404': NotSupported,
187
+ '429': RateLimitExceeded,
188
+ '500': ExchangeNotAvailable,
189
+ '503': ExchangeNotAvailable,
190
+ '3013': OrderNotFound,
191
+ 'Order quantity is out of range': InvalidOrder,
192
+ 'Invalid trade order type': InvalidOrder,
193
+ 'Insufficient margin': InsufficientFunds,
194
+ 'insufficient balance': InsufficientFunds,
195
+ 'leverage must be in [1,8]': BadRequest,
196
+ 'the request you sent is invalid': BadRequest,
197
+ },
198
+ 'broad': {
199
+ 'InvalidOrder': InvalidOrder, // Rate should be in the range of
200
+ },
201
+ },
202
+ });
203
+ }
204
+ /**
205
+ * @method
206
+ * @name zebpay#fetchStatus
207
+ * @description the latest known information on the availability of the exchange API
208
+ * @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#system-status
209
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/system.md#get-system-status
210
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
211
+ * @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure}
212
+ */
213
+ async fetchStatus(params = {}) {
214
+ let type = undefined;
215
+ [type, params] = this.handleMarketTypeAndParams('fetchStatus', undefined, params);
216
+ const isSpot = (type === 'spot');
217
+ let response = undefined;
218
+ let data = {};
219
+ if (isSpot) {
220
+ response = await this.publicSpotGetV2SystemStatus(params);
221
+ data = response;
222
+ }
223
+ else {
224
+ response = await this.publicSwapGetV1SystemStatus(params);
225
+ data = this.safeDict(response, 'data', {});
226
+ }
227
+ //
228
+ // {
229
+ // "statusDescription": "OK",
230
+ // "data":
231
+ // {
232
+ // "systemStatus": "ok"
233
+ // }
234
+ // "statusCode": 200,
235
+ // "customMessage": ["OK"]
236
+ // }
237
+ //
238
+ const status = this.safeString2(data, 'systemStatus', 'status');
239
+ return {
240
+ 'status': status,
241
+ 'updated': undefined,
242
+ 'eta': undefined,
243
+ 'url': undefined,
244
+ 'info': response,
245
+ };
246
+ }
247
+ /**
248
+ * @method
249
+ * @name zebpayfutures#fetchTime
250
+ * @description fetches the current integer timestamp in milliseconds from the poloniexfutures server
251
+ * @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#get-server-time
252
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/system.md#get-system-time
253
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
254
+ * @returns {int} the current integer timestamp in milliseconds from the poloniexfutures server
255
+ */
256
+ async fetchTime(params = {}) {
257
+ let type = undefined;
258
+ [type, params] = this.handleMarketTypeAndParams('fetchTime', undefined, params);
259
+ const isSpot = (type === 'spot');
260
+ let response = undefined;
261
+ let data = {};
262
+ if (isSpot) {
263
+ response = await this.publicSpotGetV2SystemTime(params);
264
+ data = response;
265
+ }
266
+ else {
267
+ response = await this.publicSwapGetV1SystemTime(params);
268
+ data = this.safeDict(response, 'data', {});
269
+ }
270
+ //
271
+ // {
272
+ // "statusDescription": "OK",
273
+ // "data":
274
+ // {
275
+ // "timestamp": 1546837113087
276
+ // }
277
+ // "statusCode": 200,
278
+ // "customMessage": ["OK"]
279
+ // }
280
+ //
281
+ const time = this.safeInteger(data, 'timestamp');
282
+ return time;
283
+ }
284
+ /**
285
+ * @method
286
+ * @name zebpay#fetchMarkets
287
+ * @description retrieves data on all markets for zebpay
288
+ * @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#get-trading-pairs
289
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/market.md#fetch-markets
290
+ * @param {object} [params] extra parameters specific to the exchange api endpoint
291
+ * @returns {object[]} an array of objects representing market data
292
+ */
293
+ async fetchMarkets(params = {}) {
294
+ const promisesUnresolved = [];
295
+ const fetchMarketsOptions = this.safeDict(this.options, 'fetchMarkets');
296
+ const defaultMarkets = ['spot', 'swap'];
297
+ const types = this.safeList(fetchMarketsOptions, 'types', defaultMarkets);
298
+ for (let i = 0; i < types.length; i++) {
299
+ const type = types[i];
300
+ if (type === 'spot') {
301
+ promisesUnresolved.push(this.fetchSpotMarkets(params));
302
+ }
303
+ else if (type === 'swap') {
304
+ promisesUnresolved.push(this.fetchSwapMarkets(params));
305
+ }
306
+ else {
307
+ throw new ExchangeError(this.id + ' fetchMarkets() this.options fetchMarkets "' + type + '" is not a supported market type');
308
+ }
309
+ }
310
+ const promises = await Promise.all(promisesUnresolved);
311
+ const spotMarkets = this.safeList(promises, 0, []);
312
+ const futureMarkets = this.safeList(promises, 1, []);
313
+ return this.arrayConcat(spotMarkets, futureMarkets);
314
+ }
315
+ /**
316
+ * @method
317
+ * @name zebpay#fetchCurrencies
318
+ * @description fetches all available currencies on an exchange
319
+ * @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#get-coin-settings
320
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
321
+ * @returns {object} an associative dictionary of currencies
322
+ */
323
+ async fetchCurrencies(params = {}) {
324
+ const response = await this.publicSpotGetV2ExCurrencies(params);
325
+ //
326
+ // {
327
+ // "data": [
328
+ // {
329
+ // "currency": "BTC",
330
+ // "name": "BTC",
331
+ // "fullName": "150",
332
+ // "precision": "0.2",
333
+ // "type": "fiat",
334
+ // "isDebitEnabled": false,
335
+ // "chains": [
336
+ // {
337
+ // "chainName": "Bitcoin",
338
+ // "withdrawalMinSize": "0.000482",
339
+ // "depositMinSize": "0.00000001",
340
+ // "withdrawalFee": "0.00040000",
341
+ // "isWithdrawEnabled": "true",
342
+ // "isDepositEnabled": "true",
343
+ // "contractAddress": "0x095418A82BC2439703b69fbE1210824F2247D77c",
344
+ // "withdrawPrecision": "8",
345
+ // "maxWithdraw": "2.43090487000000",
346
+ // "maxDeposit": "100.00000000",
347
+ // "needTag": "false",
348
+ // "chainId": "bitcoin",
349
+ // "AddressRegex": "^tb1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{39,59}|m[a-zA-Z0-9]{25,34}|n[a-zA-Z0-9]{25,34}|^2[a-zA-Z0-9]{25,34}$"
350
+ // }
351
+ // ]
352
+ // }
353
+ // ]
354
+ // }
355
+ //
356
+ const rows = this.safeList(response, 'data', []);
357
+ const result = {};
358
+ for (let i = 0; i < rows.length; i++) {
359
+ const currency = rows[i];
360
+ const currencyId = this.safeString(currency, 'currency');
361
+ const code = this.safeCurrencyCode(currencyId);
362
+ const name = this.safeString(currency, 'name');
363
+ const precision = this.parseNumber(this.parsePrecision(this.safeString(currency, 'precision')));
364
+ const chains = this.safeList(currency, 'chains', []);
365
+ const networks = {};
366
+ let minWithdrawFeeString = undefined;
367
+ let minWithdrawString = undefined;
368
+ let minDepositString = undefined;
369
+ let deposit = false;
370
+ let withdraw = false;
371
+ for (let j = 0; j < chains.length; j++) {
372
+ const chain = chains[j];
373
+ const networkId = this.safeString(chain, 'chainId');
374
+ const networkCode = this.networkIdToCode(networkId);
375
+ const depositAllowed = this.safeBool(chain, 'isDepositEnabled') === true;
376
+ deposit = (depositAllowed) ? depositAllowed : deposit;
377
+ const withdrawAllowed = this.safeBool(chain, 'isWithdrawEnabled') === true;
378
+ withdraw = (withdrawAllowed) ? withdrawAllowed : withdraw;
379
+ const withdrawFeeString = this.safeString(chain, 'withdrawalFee');
380
+ if (withdrawFeeString !== undefined) {
381
+ minWithdrawFeeString = (minWithdrawFeeString === undefined) ? withdrawFeeString : Precise.stringMin(withdrawFeeString, minWithdrawFeeString);
382
+ }
383
+ const minNetworkWithdrawString = this.safeString(chain, 'withdrawalMinSize');
384
+ if (minNetworkWithdrawString !== undefined) {
385
+ minWithdrawString = (minWithdrawString === undefined) ? minNetworkWithdrawString : Precise.stringMin(minNetworkWithdrawString, minWithdrawString);
386
+ }
387
+ const minNetworkDepositString = this.safeString(chain, 'depositMinSize');
388
+ if (minNetworkDepositString !== undefined) {
389
+ minDepositString = (minDepositString === undefined) ? minNetworkDepositString : Precise.stringMin(minNetworkDepositString, minDepositString);
390
+ }
391
+ networks[networkCode] = {
392
+ 'info': chain,
393
+ 'id': networkId,
394
+ 'network': networkCode,
395
+ 'active': depositAllowed && withdrawAllowed,
396
+ 'deposit': depositAllowed,
397
+ 'withdraw': withdrawAllowed,
398
+ 'fee': this.parseNumber(withdrawFeeString),
399
+ 'precision': precision,
400
+ 'limits': {
401
+ 'withdraw': {
402
+ 'min': this.parseNumber(minNetworkWithdrawString),
403
+ 'max': undefined,
404
+ },
405
+ 'deposit': {
406
+ 'min': this.parseNumber(minNetworkDepositString),
407
+ 'max': undefined,
408
+ },
409
+ },
410
+ };
411
+ }
412
+ result[code] = this.safeCurrencyStructure({
413
+ 'info': currency,
414
+ 'code': code,
415
+ 'id': currencyId,
416
+ 'name': name,
417
+ 'active': deposit && withdraw,
418
+ 'deposit': deposit,
419
+ 'withdraw': withdraw,
420
+ 'fee': this.parseNumber(minWithdrawFeeString),
421
+ 'precision': precision,
422
+ 'limits': {
423
+ 'amount': {
424
+ 'min': undefined,
425
+ 'max': undefined,
426
+ },
427
+ 'withdraw': {
428
+ 'min': this.parseNumber(minWithdrawString),
429
+ 'max': undefined,
430
+ },
431
+ 'deposit': {
432
+ 'min': this.parseNumber(minDepositString),
433
+ 'max': undefined,
434
+ },
435
+ },
436
+ 'networks': networks,
437
+ });
438
+ }
439
+ return result;
440
+ }
441
+ /**
442
+ * @method
443
+ * @name zebpay#fetchTradingFee
444
+ * @description fetch the trading fees for a market
445
+ * @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/private-endpoints.md#get-exchange-fee
446
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/exchange.md#get-trade-fee-single-symbol
447
+ * @param {string} symbol unified symbol of the market to fetch the order book for
448
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
449
+ * @param {object} [params.side] side to fetch trading fee
450
+ * @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure}
451
+ */
452
+ async fetchTradingFee(symbol, params = {}) {
453
+ await this.loadMarkets();
454
+ const market = this.market(symbol);
455
+ let response = undefined;
456
+ let data;
457
+ const request = {
458
+ 'symbol': market['id'],
459
+ };
460
+ if (market['spot']) {
461
+ response = await this.privateSpotGetV2ExTradefee(this.extend(request, params));
462
+ //
463
+ // {
464
+ // "statusDescription": "Success",
465
+ // "data":
466
+ // {
467
+ // "symbol": "BTCINR",
468
+ // "takerFeeRate": "0.01",
469
+ // "makerFeeRate": "0.05",
470
+ // "percentage": true
471
+ // } ,
472
+ // "statusCode": 200,
473
+ // }
474
+ data = this.safeDict(response, 'data', {});
475
+ }
476
+ else {
477
+ response = await this.publicSwapGetV1ExchangeTradefee(this.extend(request, params));
478
+ //
479
+ // {
480
+ // "statusDescription": "OK",
481
+ // "data":
482
+ // [
483
+ // {
484
+ // "symbol": "BTCINR",
485
+ // "takerFee": "0.01",
486
+ // "makerFee": "0.05"
487
+ // }
488
+ // ] ,
489
+ // "statusCode": 200,
490
+ // "customMessage": ["OK"]
491
+ // }
492
+ //
493
+ const responseData = this.safeList(response, 'data', []);
494
+ data = this.safeDict(responseData, 0);
495
+ }
496
+ return this.parseTradingFee(data, market);
497
+ }
498
+ /**
499
+ * @method
500
+ * @name zebpay(futures)#fetchTradingFees
501
+ * @description fetch the trading fees for multiple markets
502
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/exchange.md#get-trade-fees-all-symbols
503
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
504
+ * @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure}
505
+ */
506
+ async fetchTradingFees(params = {}) {
507
+ let type = undefined;
508
+ [type, params] = this.handleMarketTypeAndParams('fetchTradingFees', undefined, params);
509
+ let response = undefined;
510
+ if (type === 'spot') {
511
+ response = await this.publicSpotGetV2ExTradefees(params);
512
+ }
513
+ else {
514
+ response = await this.publicSwapGetV1ExchangeTradefees(params);
515
+ }
516
+ //
517
+ // {
518
+ // "statusDescription": "OK",
519
+ // "data": [
520
+ // {
521
+ // "symbol": "BTCINR",
522
+ // "takerFee": "0.01",
523
+ // "makerFee": "0.05"
524
+ // }
525
+ // ],
526
+ // "statusCode": 200,
527
+ // "customMessage": ["OK"]
528
+ // }
529
+ //
530
+ const fees = this.safeList(response, 'data', []);
531
+ const result = {};
532
+ for (let i = 0; i < fees.length; i++) {
533
+ const fee = this.parseTradingFee(fees[i]);
534
+ const symbol = fee['symbol'];
535
+ result[symbol] = fee;
536
+ }
537
+ return result;
538
+ }
539
+ /**
540
+ * @method
541
+ * @name zebpay#fetchOrderBook
542
+ * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
543
+ * @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#get-order-book
544
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/market.md#get-order-book
545
+ * @param {string} symbol unified symbol of the market to fetch the order book for
546
+ * @param {int} [limit] the maximum amount of order book entries to return
547
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
548
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
549
+ */
550
+ async fetchOrderBook(symbol, limit = undefined, params = {}) {
551
+ await this.loadMarkets();
552
+ const market = this.market(symbol);
553
+ const request = {
554
+ 'symbol': market['id'],
555
+ };
556
+ let response = undefined;
557
+ if (market['spot']) {
558
+ if (limit !== undefined) {
559
+ request['limit'] = limit;
560
+ }
561
+ //
562
+ // {
563
+ // "asks": [
564
+ // [5000, 1000], //Price, quantity
565
+ // [6000, 1983] //Price, quantity
566
+ // ],
567
+ // "bids": [
568
+ // [3200, 800], //Price, quantity
569
+ // [3100, 100] //Price, quantity
570
+ // ],
571
+ // }
572
+ // }
573
+ response = await this.publicSpotGetV2MarketOrderbook(this.extend(request, params));
574
+ }
575
+ else {
576
+ response = await this.publicSwapGetV1MarketOrderBook(this.extend(request, params));
577
+ }
578
+ const bookData = this.safeDict(response, 'data', {});
579
+ const orderbook = this.parseOrderBook(bookData, market['symbol'], undefined, 'bids', 'asks', 0, 1);
580
+ orderbook['nonce'] = this.safeInteger(bookData, 'nonce');
581
+ return orderbook;
582
+ }
583
+ /**
584
+ * @method
585
+ * @name zebpay#fetchTicker
586
+ * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
587
+ * @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#get-ticker
588
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/market.md#get-24hr-ticker
589
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
590
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
591
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
592
+ */
593
+ async fetchTicker(symbol, params = {}) {
594
+ await this.loadMarkets();
595
+ const market = this.market(symbol);
596
+ const request = {
597
+ 'symbol': market['id'],
598
+ };
599
+ let response = undefined;
600
+ if (market['spot']) {
601
+ response = await this.publicSpotGetV2MarketTicker(this.extend(request, params));
602
+ //
603
+ // [
604
+ // {
605
+ // "symbol": "BTC-INR",
606
+ // "bestBid": "4900000",
607
+ // "bestBidQty": "0.00014938",
608
+ // "bestAsk": "",
609
+ // "bestAskQty": "0",
610
+ // "priceChange": "-98134.56",
611
+ // "priceChangePercent": "-1.84",
612
+ // "high": "5433400",
613
+ // "low": "5333400",
614
+ // "vol": "0.0002",
615
+ // "volValue": "1066.68",
616
+ // "last": "5333400"
617
+ // }
618
+ // ]
619
+ //
620
+ }
621
+ else {
622
+ response = await this.publicSwapGetV1MarketTicker24Hr(this.extend(request, params));
623
+ }
624
+ const data = this.safeDict(response, 'data', {});
625
+ return this.parseTicker(data, market);
626
+ }
627
+ /**
628
+ * @method
629
+ * @name zebpay#fetchTickers
630
+ * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
631
+ * @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#get-all-tickers
632
+ * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
633
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
634
+ * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
635
+ */
636
+ async fetchTickers(symbols = undefined, params = {}) {
637
+ let type = undefined;
638
+ [type, params] = this.handleMarketTypeAndParams('fetchTickers', undefined, params);
639
+ if (type !== 'spot') {
640
+ throw new NotSupported(this.id + ' fetchTickers() does not support ' + type + ' markets');
641
+ }
642
+ await this.loadMarkets();
643
+ symbols = this.marketSymbols(symbols);
644
+ const response = await this.publicSpotGetV2MarketAllTickers(params);
645
+ //
646
+ // [
647
+ // {
648
+ // "symbol": "BTC-INR",
649
+ // "bestBid": "4900000",
650
+ // "bestBidQty": "0.00014938",
651
+ // "bestAsk": "",
652
+ // "bestAskQty": "0",
653
+ // "priceChange": "-98134.56",
654
+ // "priceChangePercent": "-1.84",
655
+ // "high": "5433400",
656
+ // "low": "5333400",
657
+ // "vol": "0.0002",
658
+ // "volValue": "1066.68",
659
+ // "last": "5333400"
660
+ // }
661
+ // ]
662
+ //
663
+ const tickerList = this.safeList(response, 'data', []);
664
+ return this.parseTickers(tickerList, symbols);
665
+ }
666
+ /**
667
+ * @method
668
+ * @name zebpay#fetchOHLCV
669
+ * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
670
+ * @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#get-klinescandlesticks
671
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/market.md#-get-k-lines-ohlcv-data
672
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
673
+ * @param {string} timeframe the length of time each candle represents
674
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
675
+ * @param {int} [limit] the maximum amount of candles to fetch
676
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
677
+ * @param {int} [params.endtime] the latest time in ms to fetch orders for
678
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
679
+ */
680
+ async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
681
+ await this.loadMarkets();
682
+ const market = this.market(symbol);
683
+ if (limit === undefined) {
684
+ limit = 100; // default is 200
685
+ }
686
+ const request = {
687
+ 'symbol': market['id'],
688
+ };
689
+ if (market['spot']) {
690
+ request['interval'] = this.safeString(this.timeframes, timeframe, timeframe);
691
+ }
692
+ else {
693
+ request['interval'] = timeframe;
694
+ }
695
+ if (market['contract'] && (limit !== undefined)) {
696
+ request['limit'] = limit;
697
+ }
698
+ if (since !== undefined) {
699
+ if (market['spot']) {
700
+ request['startTime'] = since;
701
+ }
702
+ else {
703
+ request['since'] = since;
704
+ }
705
+ }
706
+ const until = this.safeInteger2(params, 'until', 'endtime');
707
+ if (until !== undefined) {
708
+ request['endTime'] = until;
709
+ params = this.omit(params, ['endtime', 'until']);
710
+ }
711
+ let response = undefined;
712
+ if (market['spot']) {
713
+ if (until === undefined || since === undefined) {
714
+ throw new ArgumentsRequired(this.id + ' fetchOHLCV() requires a both a since and until/endtime parameter for spot markets');
715
+ }
716
+ response = await this.publicSpotGetV2MarketKlines(this.extend(request, params));
717
+ }
718
+ else {
719
+ response = await this.publicSwapPostV1MarketKlines(this.extend(request, params));
720
+ }
721
+ //
722
+ // [
723
+ // [
724
+ // "1670608800000",
725
+ // "17071",
726
+ // "17073",
727
+ // "17027",
728
+ // "17055.5",
729
+ // "268611",
730
+ // "15.74462667"
731
+ // ],
732
+ // [
733
+ // "1670605200000",
734
+ // "17071.5",
735
+ // "17071.5",
736
+ // "17061",
737
+ // "17071",
738
+ // "4177",
739
+ // "0.24469757"
740
+ // ],
741
+ // [
742
+ // "1670601600000",
743
+ // "17086.5",
744
+ // "17088",
745
+ // "16978",
746
+ // "17071.5",
747
+ // "6356",
748
+ // "0.37288112"
749
+ // ]
750
+ // ]
751
+ //
752
+ const data = this.safeList(response, 'data', []);
753
+ return this.parseOHLCVs(data, market, timeframe, since, limit);
754
+ }
755
+ /**
756
+ * @method
757
+ * @name zebpay#fetchTrades
758
+ * @description get the list of most recent trades for a particular symbol
759
+ * @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/public-endpoints.md#get-recent-trades
760
+ * @see https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/public-endpoints/market.md#get-aggregate-trades
761
+ * @param {string} symbol unified symbol of the market to fetch trades for
762
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
763
+ * @param {int} [limit] the maximum amount of trades to fetch
764
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
765
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
766
+ */
767
+ async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
768
+ await this.loadMarkets();
769
+ const market = this.market(symbol);
770
+ const request = {
771
+ 'symbol': market['id'],
772
+ };
773
+ if (market['spot'] && limit !== undefined) {
774
+ request['limit'] = limit;
775
+ }
776
+ let response = undefined;
777
+ if (market['spot']) {
778
+ response = await this.publicSpotGetV2MarketTrades(this.extend(request, params));
779
+ }
780
+ else {
781
+ response = await this.publicSwapGetV1MarketAggTrade(this.extend(request, params));
782
+ }
783
+ //
784
+ // [
785
+ // {
786
+ // "id" : "60014521",
787
+ // "price" : "23162.94",
788
+ // "qty" : "0.00009",
789
+ // "side" : "SELL",
790
+ // "time" : 1659684602042,
791
+ // "isBuyerMaker" : 1659684602036
792
+ // }
793
+ // ]
794
+ //
795
+ const data = this.safeList(response, 'data', []);
796
+ return this.parseTrades(data, market, since, limit);
797
+ }
798
+ /**
799
+ * @method
800
+ * @name zebpay#fetchMyTrades
801
+ * @description get the list of most recent trades for a particular symbol
802
+ * @see https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/private-endpoints/trade.md#-get-trade-history
803
+ * @param {string} symbol unified symbol of the market to fetch trades for
804
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
805
+ * @param {int} [limit] the maximum amount of trades to fetch
806
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
807
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
808
+ */
809
+ async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
810
+ await this.loadMarkets();
811
+ let market = undefined;
812
+ if (symbol !== undefined) {
813
+ market = this.market(symbol);
814
+ }
815
+ let type = undefined;
816
+ [type, params] = this.handleMarketTypeAndParams('fetchMyTrades', market, params);
817
+ let response = undefined;
818
+ if (type === 'spot') {
819
+ throw new NotSupported(this.id + ' fetchMyTrades() does not support spot markets');
820
+ }
821
+ else {
822
+ response = await this.privateSwapGetV1TradeHistory(params);
823
+ }
824
+ const data = this.safeDict(response, 'data', {});
825
+ const items = this.safeList(data, 'items', []);
826
+ return this.parseTrades(items, market, since, limit);
827
+ }
828
+ /**
829
+ * @method
830
+ * @name zebpatspot#fetchOrderTrades
831
+ * @description fetch all the trades made from a single order
832
+ * @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/private-endpoints.md#get-order-fills
833
+ * @param {string} id order id
834
+ * @param {string} symbol unified market symbol
835
+ * @param {int} [since] the earliest time in ms to fetch trades for
836
+ * @param {int} [limit] the maximum number of trades to retrieve
837
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
838
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
839
+ */
840
+ async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
841
+ let type = undefined;
842
+ [type, params] = this.handleMarketTypeAndParams('fetchOrderTrades', undefined, params);
843
+ if (type !== 'spot') {
844
+ throw new NotSupported(this.id + ' fetchOrderTrades() does not support ' + type + ' markets');
845
+ }
846
+ await this.loadMarkets();
847
+ const request = {
848
+ 'orderId': id,
849
+ };
850
+ const response = await this.privateSpotGetV2ExOrderFills(this.extend(request, params));
851
+ //
852
+ // {
853
+ // "orderId": "456789",
854
+ // "symbol": "LINK_USDT",
855
+ // "origQty": "1.5",
856
+ // "orderId": "30249408733945856",
857
+ // "side": "BUY",
858
+ // "type": "LIMIT",
859
+ // "matchRole": "MAKER",
860
+ // "createTime": 1648200366864,
861
+ // "price": "3.1",
862
+ // "avgExecutedPrice": "2.3456"
863
+ // "openQty": "1",
864
+ // "filledQty": "0",
865
+ // "fees": "0.00145",
866
+ // }
867
+ //
868
+ const data = this.safeDict(response, 'data', {});
869
+ const trades = [data];
870
+ return this.parseTrades(trades);
871
+ }
872
+ parseTrade(trade, market = undefined) {
873
+ //
874
+ // fetchMyTrades
875
+ //
876
+ // {
877
+ // "id": "32164924331503616",
878
+ // "symbol": "LINK_USDT",
879
+ // "accountType": "SPOT",
880
+ // "orderId": "32164923987566592",
881
+ // "side": "SELL",
882
+ // "type": "MARKET",
883
+ // "matchRole": "TAKER",
884
+ // "createTime": 1648635115525,
885
+ // "price": "11",
886
+ // "quantity": "0.5",
887
+ // "amount": "5.5",
888
+ // "feeCurrency": "USDT",
889
+ // "feeAmount": "0.007975",
890
+ // "pageId": "32164924331503616",
891
+ // "clientOrderId": "myOwnId-321"
892
+ // }
893
+ // {
894
+ // aggregateTradeId: '2659115835',
895
+ // symbol: 'ETHINR',
896
+ // price: '292848',
897
+ // quantity: '0.147',
898
+ // firstTradeId: '7018766077',
899
+ // lastTradeId: '7018766081',
900
+ // tradeTime: '1765381971447',
901
+ // isBuyerMarketMaker: true
902
+ // }
903
+ //
904
+ //
905
+ const id = this.safeString2(trade, 'id', 'aggregateTradeId');
906
+ const orderId = this.safeString2(trade, 'id', 'order');
907
+ const timestamp = this.safeInteger2(trade, 'timestamp', 'tradeTime');
908
+ const marketId = this.safeString(trade, 'symbol');
909
+ market = this.safeMarket(marketId, market, '_');
910
+ const symbol = market['symbol'];
911
+ const side = this.safeStringLower(trade, 'side');
912
+ const priceString = this.safeString(trade, 'price');
913
+ const amountString = this.safeString2(trade, 'amount', 'quantity');
914
+ return this.safeTrade({
915
+ 'id': id,
916
+ 'info': trade,
917
+ 'timestamp': timestamp,
918
+ 'datetime': this.iso8601(timestamp),
919
+ 'symbol': symbol,
920
+ 'order': orderId,
921
+ 'type': this.safeStringLower(trade, 'type'),
922
+ 'side': side,
923
+ 'takerOrMaker': undefined,
924
+ 'price': priceString,
925
+ 'amount': amountString,
926
+ 'cost': this.safeString(trade, 'cost'),
927
+ 'fee': this.safeDict(trade, 'fee'),
928
+ }, market);
929
+ }
930
+ /**
931
+ * @method
932
+ * @name zebpay#fetchBalance
933
+ * @description query for balance and get the amount of funds available for trading or funds locked in orders
934
+ * @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/private-endpoints.md#get-account-balance
935
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/private-endpoints/wallet.md#get-wallet-balance
936
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
937
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
938
+ */
939
+ async fetchBalance(params = {}) {
940
+ await this.loadMarkets();
941
+ let type = undefined;
942
+ [type, params] = this.handleMarketTypeAndParams('fetchBalance', undefined, params);
943
+ const isSpot = (type === 'spot');
944
+ let response = undefined;
945
+ if (isSpot) {
946
+ response = await this.privateSpotGetV2AccountBalance(params);
947
+ }
948
+ else {
949
+ response = await this.privateSwapGetV1WalletBalance(params);
950
+ }
951
+ //
952
+ // {
953
+ // "data": [
954
+ // {
955
+ // "free": 200,
956
+ // "used": 100,
957
+ // "total": 300,
958
+ // "currency": "INR"
959
+ // },
960
+ // {
961
+ // "free": 0,
962
+ // "used": 0,
963
+ // "total": 0,
964
+ // "currency": "USDT"
965
+ // }
966
+ // ]
967
+ // }
968
+ //
969
+ return this.parseBalance(response);
970
+ }
971
+ /**
972
+ * @method
973
+ * @name zebpay#createOrder
974
+ * @description Create an order on the exchange
975
+ * @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/private-endpoints.md#place-new-order
976
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/private-endpoints/trade.md#--create-order
977
+ * @param {string} symbol Unified CCXT market symbol
978
+ * @param {string} type 'limit' or 'market'
979
+ * @param {string} side 'buy' or 'sell'
980
+ * @param {float} amount the amount of currency to trade
981
+ * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
982
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
983
+ * @param {string} [params.formType] The price at which a trigger order is triggered at
984
+ * @param {string} [params.marginAsset] The asset the order creates, default is INR.
985
+ * @param {boolean} [params.takeProfit] Takeprofit flag for the order.
986
+ * @param {boolean} [params.stopLoss] Stop loss flag for the order.
987
+ * @param {string} [params.positionId] PositionId of the order.
988
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
989
+ */
990
+ async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
991
+ await this.loadMarkets();
992
+ const market = this.market(symbol);
993
+ const upperCaseType = type.toUpperCase();
994
+ const takeProfitPrice = this.safeString(params, 'takeProfitPrice');
995
+ const stopLossPrice = this.safeString(params, 'stopLossPrice');
996
+ params = this.omit(params, ['marginAsset', 'takeProfitPrice', 'takeProfitPrice']);
997
+ let request = {
998
+ 'symbol': market['id'],
999
+ 'side': side.toUpperCase(),
1000
+ };
1001
+ let response = undefined;
1002
+ if (market['spot']) {
1003
+ [request, params] = this.orderRequest(symbol, type, amount, request, price, params);
1004
+ response = await this.privateSpotPostV2ExOrders(this.extend(request, params));
1005
+ }
1006
+ else {
1007
+ const marginAsset = this.safeString(params, 'marginAsset', 'INR');
1008
+ const formType = this.safeStringUpper(params, 'formType', 'ORDER_FORM');
1009
+ request['formType'] = formType;
1010
+ request['amount'] = this.parseToNumeric(this.amountToPrecision(market['id'], amount));
1011
+ request['marginAsset'] = marginAsset;
1012
+ const hasTP = takeProfitPrice !== undefined;
1013
+ const hasSL = stopLossPrice !== undefined;
1014
+ if (hasTP || hasSL) {
1015
+ if (hasTP) {
1016
+ request['takeProfitPrice'] = this.parseToNumeric(this.priceToPrecision(symbol, takeProfitPrice));
1017
+ }
1018
+ if (hasSL) {
1019
+ request['stopLossPrice'] = this.parseToNumeric(this.priceToPrecision(symbol, stopLossPrice));
1020
+ }
1021
+ response = await this.privateSwapPostV1TradeOrderAddTPSL(this.extend(request, params));
1022
+ }
1023
+ else {
1024
+ request['type'] = upperCaseType;
1025
+ if (type === 'limit') {
1026
+ if (price === undefined) {
1027
+ throw new ArgumentsRequired(this.id + ' createOrder() requires a price argument for limit orders');
1028
+ }
1029
+ request['price'] = this.parseToNumeric(this.priceToPrecision(symbol, price));
1030
+ }
1031
+ response = await this.privateSwapPostV1TradeOrder(this.extend(request, params));
1032
+ }
1033
+ }
1034
+ //
1035
+ // {
1036
+ // "data": {
1037
+ // "clientOrderId": "619717484f1d010001510cde",
1038
+ // },
1039
+ // }
1040
+ //
1041
+ const data = this.safeDict(response, 'data', {});
1042
+ return this.parseOrder(data, market);
1043
+ }
1044
+ orderRequest(symbol, type, amount, request, price = undefined, params = {}) {
1045
+ const upperCaseType = type.toUpperCase();
1046
+ const triggerPrice = this.safeString(params, 'stopLossPrice', undefined);
1047
+ const quoteOrderQty = this.safeString2(params, 'quoteOrderQty', 'cost', undefined);
1048
+ const timeInForce = this.safeString(params, 'timeInForce', 'GTC');
1049
+ const clientOrderId = this.safeString(params, 'clientOrderId', this.uuid());
1050
+ params = this.omit(params, ['stopLossPrice', 'cost', 'timeInForce', 'clientOrderId']);
1051
+ request['type'] = upperCaseType;
1052
+ request['clientOrderId'] = clientOrderId;
1053
+ request['timeInForce'] = timeInForce;
1054
+ if (upperCaseType === 'MARKET') {
1055
+ if (quoteOrderQty === undefined) {
1056
+ throw new ExchangeError(this.id + ' spot market orders require cost in params');
1057
+ }
1058
+ request['quoteOrderAmount'] = this.costToPrecision(symbol, quoteOrderQty);
1059
+ }
1060
+ else {
1061
+ if (triggerPrice !== undefined) {
1062
+ request['stopLossPrice'] = this.priceToPrecision(symbol, triggerPrice);
1063
+ }
1064
+ request['amount'] = this.amountToPrecision(symbol, amount);
1065
+ request['price'] = this.priceToPrecision(symbol, price);
1066
+ }
1067
+ return [request, params];
1068
+ }
1069
+ /**
1070
+ * @method
1071
+ * @name zebpay#cancelOrder
1072
+ * @description cancels an open order
1073
+ * @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/private-endpoints.md#cancel-order
1074
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/private-endpoints/trade.md#-cancel-order
1075
+ * @param {string} id order id
1076
+ * @param {string} symbol unified symbol of the market the order was made in
1077
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1078
+ * @param {object} [params.timestamp] extra parameters specific to the exchange API endpoint
1079
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1080
+ */
1081
+ async cancelOrder(id, symbol = undefined, params = {}) {
1082
+ await this.loadMarkets();
1083
+ const market = this.market(symbol);
1084
+ let response = undefined;
1085
+ const request = {};
1086
+ if (market['spot']) {
1087
+ request['orderId'] = id;
1088
+ response = await this.privateSpotDeleteV2ExOrder(this.extend(request, params));
1089
+ }
1090
+ else {
1091
+ const clientOrderId = this.safeString(params, 'clientOrderId');
1092
+ if (clientOrderId === undefined) {
1093
+ throw new ArgumentsRequired(this.id + ' cancelOrder() requires a clientOrderId parameter for swap orders');
1094
+ }
1095
+ request['clientOrderId'] = clientOrderId;
1096
+ request['symbol'] = market['id'];
1097
+ response = await this.privateSwapDeleteV1TradeOrder(this.extend(request, params));
1098
+ }
1099
+ //
1100
+ // {
1101
+ // "data": {
1102
+ // "clientOrderId": "619714b8b6353000014c505a",
1103
+ // "status": "canceled"
1104
+ // },
1105
+ // }
1106
+ //
1107
+ return this.parseOrder(this.safeDict(response, 'data'));
1108
+ }
1109
+ /**
1110
+ * @method
1111
+ * @name zebpay#cancelOrders
1112
+ * @description cancels all open orders
1113
+ * @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/private-endpoints.md#cancel-all-orders
1114
+ * @param {string} symbol unified symbol of the market the order was made in
1115
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1116
+ * @param {object} [params.timestamp] extra parameters specific to the exchange API endpoint
1117
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1118
+ */
1119
+ async cancelAllOrders(symbol = undefined, params = {}) {
1120
+ let type = undefined;
1121
+ [type, params] = this.handleMarketTypeAndParams('cancelAllOrders', undefined, params);
1122
+ if (type !== 'spot') {
1123
+ throw new NotSupported(this.id + ' cancelAllOrders() does not support ' + type + ' markets');
1124
+ }
1125
+ await this.loadMarkets();
1126
+ const response = await this.privateSpotDeleteV2ExOrdersCancelAll(params);
1127
+ //
1128
+ // {
1129
+ // "data": {
1130
+ // "orderId": "12345",
1131
+ // "symbol": 'BTC-INR
1132
+ // },
1133
+ // }
1134
+ //
1135
+ const data = this.safeDict(response, 'data', {});
1136
+ const parsedOrder = this.parseOrder(data);
1137
+ return [parsedOrder];
1138
+ }
1139
+ /**
1140
+ * @method
1141
+ * @name zebpay#fetchOpenOrders
1142
+ * @description fetches information on multiple open orders made by the user
1143
+ * @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/private-endpoints.md#get-orders
1144
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/private-endpoints/trade.md#-get-open-orders
1145
+ * @param {string} symbol unified market symbol of the market orders were made in
1146
+ * @param {int} [since] the earliest time in ms to fetch orders for
1147
+ * @param {int} [limit] the maximum number of order structures to retrieve
1148
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1149
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1150
+ */
1151
+ async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1152
+ await this.loadMarkets();
1153
+ const market = this.market(symbol);
1154
+ const request = {
1155
+ 'symbol': market['id'],
1156
+ };
1157
+ let response = undefined;
1158
+ let orders = [];
1159
+ if (market['spot']) {
1160
+ request['currentPage'] = 1;
1161
+ if (limit !== undefined) {
1162
+ request['pageSize'] = limit;
1163
+ }
1164
+ response = await this.privateSpotGetV2ExOrders(this.extend(request, params));
1165
+ const responseData = this.safeDict(response, 'data', {});
1166
+ orders = this.safeList(responseData, 'items', []);
1167
+ }
1168
+ else {
1169
+ if (since !== undefined) {
1170
+ request['since'] = since;
1171
+ }
1172
+ if (limit !== undefined) {
1173
+ request['limit'] = limit;
1174
+ }
1175
+ response = await this.privateSwapGetV1TradeOrderOpenOrders(this.extend(request, params));
1176
+ const responseData = this.safeDict(response, 'data', {});
1177
+ orders = this.safeList(responseData, 'data', []);
1178
+ }
1179
+ //
1180
+ // {
1181
+ // "data": {
1182
+ // "nextTimeStamp": null,
1183
+ // "totalCount": 100,
1184
+ // "data": [
1185
+ // {
1186
+ // "clientOrderId": "64507d02921f1c0001ff6892-123-zeb",
1187
+ // "datetime": "2025-03-14T14:34:34.4567",
1188
+ // "timestamp": 1741962557553,
1189
+ // "status": "open",
1190
+ // "symbol": "BTCINR",
1191
+ // "type": "market",
1192
+ // "timeInForce": "GTC",
1193
+ // "side": "buy",
1194
+ // "price": 700000,
1195
+ // "amount": 0.002,
1196
+ // "filled": null,
1197
+ // "remaining": 0.002,
1198
+ // "trades": []
1199
+ // }
1200
+ // ]
1201
+ // }
1202
+ // }
1203
+ //
1204
+ return this.parseOrders(orders, market, undefined, limit);
1205
+ }
1206
+ /**
1207
+ * @method
1208
+ * @name zebpay#fetchOrder
1209
+ * @description fetches information on an order made by the user
1210
+ * @see [Spot] https://github.com/zebpay/zebpay-api-references/blob/main/spot/api-reference/private-endpoints.md#get-order-details
1211
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/private-endpoints/trade.md#-get-order-details
1212
+ * @param {string} id order id
1213
+ * @param {string} symbol unified symbol of the market the order was made in
1214
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1215
+ * @param {string} [params.clientOrderId] cancel order by client order id
1216
+ * @param {string} [params.timestamp] cancel order by client order id
1217
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1218
+ */
1219
+ async fetchOrder(id, symbol = undefined, params = {}) {
1220
+ await this.loadMarkets();
1221
+ const market = this.market(symbol);
1222
+ const request = {};
1223
+ let response = undefined;
1224
+ if (market['spot']) {
1225
+ request['orderId'] = id;
1226
+ response = await this.privateSpotGetV2ExOrder(this.extend(request, params));
1227
+ }
1228
+ else {
1229
+ request['id'] = id;
1230
+ response = await this.privateSwapGetV1TradeOrder(this.extend(request, params));
1231
+ }
1232
+ //
1233
+ // {
1234
+ // "data": {
1235
+ // "nextTimeStamp": null,
1236
+ // "totalCount": 100,
1237
+ // "data": [
1238
+ // {
1239
+ // "clientOrderId": "64507d02921f1c0001ff6892-123-zeb",
1240
+ // "datetime": "2025-03-14T14:34:34.4567",
1241
+ // "timestamp": 1741962557553,
1242
+ // "status": "open",
1243
+ // "symbol": "BTCINR",
1244
+ // "type": "market",
1245
+ // "timeInForce": "GTC",
1246
+ // "side": "buy",
1247
+ // "price": 700000,
1248
+ // "amount": 0.002,
1249
+ // "filled": null,
1250
+ // "remaining": 0.002,
1251
+ // "trades": []
1252
+ // }
1253
+ // ]
1254
+ // }
1255
+ // }
1256
+ //
1257
+ const responseData = this.safeDict(response, 'data');
1258
+ return this.parseOrder(responseData, market);
1259
+ }
1260
+ parseOrder(order, market = undefined) {
1261
+ //
1262
+ // {
1263
+ // "clientOrderId": "64507d02921f1c0001ff6892-123-zeb",
1264
+ // "datetime": "2025-03-14T14:34:34.4567",
1265
+ // "timestamp": 1741962557553,
1266
+ // "status": "open",
1267
+ // "symbol": "BTCINR",
1268
+ // "type": "market",
1269
+ // "timeInForce": "GTC",
1270
+ // "side": "buy",
1271
+ // "price": 700000,
1272
+ // "amount": 0.002,
1273
+ // "filled": null,
1274
+ // "remaining": 0.002,
1275
+ // "trades": []
1276
+ // }
1277
+ //
1278
+ const marketId = this.safeString(order, 'symbol');
1279
+ market = this.safeMarket(marketId, market);
1280
+ const symbol = market['symbol'];
1281
+ const type = this.safeString(order, 'type');
1282
+ const timestamp = this.safeNumber(order, 'timestamp');
1283
+ const datetime = this.iso8601(timestamp);
1284
+ const price = this.safeString(order, 'price');
1285
+ const side = this.safeString(order, 'side');
1286
+ const amount = this.safeString(order, 'amount');
1287
+ const clientOrderId = this.safeString(order, 'clientOrderId');
1288
+ const timeInForce = this.safeString(order, 'timeInForce');
1289
+ const status = this.safeStringLower(order, 'status');
1290
+ const orderId = this.safeString(order, 'orderId', undefined);
1291
+ const parsedOrder = this.safeOrder({
1292
+ 'id': orderId,
1293
+ 'clientOrderId': clientOrderId,
1294
+ 'symbol': symbol,
1295
+ 'type': type,
1296
+ 'timeInForce': timeInForce,
1297
+ 'postOnly': undefined,
1298
+ 'reduceOnly': undefined,
1299
+ 'side': side,
1300
+ 'amount': amount,
1301
+ 'price': price,
1302
+ 'triggerPrice': undefined,
1303
+ 'cost': undefined,
1304
+ 'filled': undefined,
1305
+ 'remaining': undefined,
1306
+ 'timestamp': timestamp,
1307
+ 'datetime': datetime,
1308
+ 'fee': undefined,
1309
+ 'status': status,
1310
+ 'info': order,
1311
+ 'lastTradeTimestamp': undefined,
1312
+ 'lastUpdateTimestamp': undefined,
1313
+ 'average': undefined,
1314
+ 'trades': undefined,
1315
+ }, market);
1316
+ return parsedOrder;
1317
+ }
1318
+ /**
1319
+ * @method
1320
+ * @name zebpay#closePosition
1321
+ * @description closes open positions for a market
1322
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/private-endpoints/trade.md#-close-position
1323
+ * @param {string} symbol Unified CCXT market symbol
1324
+ * @param {string} side not used by kucoinfutures closePositions
1325
+ * @param {object} [params] extra parameters specific to the okx api endpoint
1326
+ * @param {string} [params.positionId] client order id of the order
1327
+ * @returns {object[]} [A list of position structures]{@link https://docs.ccxt.com/#/?id=position-structure}
1328
+ */
1329
+ async closePosition(symbol, side = undefined, params = {}) {
1330
+ await this.loadMarkets();
1331
+ const market = this.market(symbol);
1332
+ const request = {
1333
+ 'symbol': market['id'],
1334
+ };
1335
+ const response = await this.privateSwapPostV1TradePositionClose(this.extend(request, params));
1336
+ const data = this.safeDict(response, 'data', {});
1337
+ return this.parseOrder(data, market);
1338
+ }
1339
+ /**
1340
+ * @method
1341
+ * @name zebpay#fetchLeverages
1342
+ * @description fetch the set leverage for all contract and margin markets
1343
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/private-endpoints/trade.md#-get-all-user-leverages
1344
+ * @param {string[]} [symbols] a list of unified market symbols
1345
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1346
+ * @returns {object} a list of [leverage structures]{@link https://docs.ccxt.com/#/?id=leverage-structure}
1347
+ */
1348
+ async fetchLeverages(symbols = undefined, params = {}) {
1349
+ await this.loadMarkets();
1350
+ const response = await this.privateSwapGetV1TradeUserLeverages(params);
1351
+ //
1352
+ // {
1353
+ // "leveragePreferences": [
1354
+ // {
1355
+ // "symbol": "ETHINR",
1356
+ // "shortLeverage": 1,
1357
+ // "longLeverage": 10,
1358
+ // "marginMode": "isolated"
1359
+ // },
1360
+ // ]
1361
+ // }
1362
+ //
1363
+ const leveragePreferences = this.safeList(response, 'data', []);
1364
+ return this.parseLeverages(leveragePreferences, symbols, 'symbol');
1365
+ }
1366
+ /**
1367
+ * @method
1368
+ * @name zebpay#fetchLeverage
1369
+ * @description fetch the set leverage for a market
1370
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/private-endpoints/trade.md#get-user-leverage-single-symbol
1371
+ * @param {string} symbol unified market symbol
1372
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1373
+ * @returns {object} a [leverage structure]{@link https://docs.ccxt.com/#/?id=leverage-structure}
1374
+ */
1375
+ async fetchLeverage(symbol, params = {}) {
1376
+ await this.loadMarkets();
1377
+ const market = this.market(symbol);
1378
+ const request = {
1379
+ 'symbol': market['id'].toUpperCase(),
1380
+ };
1381
+ const response = await this.privateSwapGetV1TradeUserLeverage(this.extend(request, params));
1382
+ //
1383
+ // {
1384
+ // "data": { symbol: "ETHINR", longLeverage: 1, shortLeverage: 1, marginMode: "isolated" }
1385
+ // }
1386
+ //
1387
+ const data = this.safeDict(response, 'data', {});
1388
+ return this.parseLeverage(data, market);
1389
+ }
1390
+ /**
1391
+ * @method
1392
+ * @name zebpay#setLeverage
1393
+ * @description set the level of leverage for a market
1394
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/private-endpoints/trade.md#-update-user-leverage
1395
+ * @param {float} leverage the rate of leverage
1396
+ * @param {string} symbol unified market symbol
1397
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1398
+ * @returns {object} response from the exchange
1399
+ */
1400
+ async setLeverage(leverage, symbol = undefined, params = {}) {
1401
+ if (symbol === undefined) {
1402
+ throw new ArgumentsRequired(this.id + ' setLeverage() requires a symbol argument');
1403
+ }
1404
+ await this.loadMarkets();
1405
+ const market = this.market(symbol);
1406
+ const request = {
1407
+ 'leverage': leverage,
1408
+ 'symbol': market['id'],
1409
+ };
1410
+ //
1411
+ // { data: { "symbol", "longLeverage": 10, "shortLeverage": 1, "marginMode": "isolated" }
1412
+ //
1413
+ const response = await this.privateSwapPostV1TradeUpdateUserLeverage(this.extend(request, params));
1414
+ return response;
1415
+ }
1416
+ /**
1417
+ * @method
1418
+ * @name zebpay#fetchPositions
1419
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/private-endpoints/trade.md#--get-positions
1420
+ * @description Fetches current contract trading positions
1421
+ * @param {string[]} symbols List of unified symbols
1422
+ * @param {object} [params] Not used by krakenfutures
1423
+ * @returns Parsed exchange response for positions
1424
+ */
1425
+ async fetchPositions(symbols = undefined, params = {}) {
1426
+ await this.loadMarkets();
1427
+ const request = {};
1428
+ if (symbols !== undefined) {
1429
+ request['symbols'] = this.marketIds(symbols);
1430
+ }
1431
+ const response = await this.privateSwapGetV1TradePositions(this.extend(request, params));
1432
+ //
1433
+ // {
1434
+ // "data": [
1435
+ // {
1436
+ // "id": "31998678-6056-413f-9d0d-fc3678641650",
1437
+ // "symbol": "ETHINR",
1438
+ // "entryPrice": "0.7533",
1439
+ // "datetime": "2022-03-03T22:51:16.566Z",
1440
+ // "contractSize": "230"
1441
+ // }
1442
+ // ],
1443
+ // }
1444
+ //
1445
+ const positions = this.safeList(response, 'data', []);
1446
+ const result = this.parsePositions(positions);
1447
+ return this.filterByArrayPositions(result, 'symbol', symbols, false);
1448
+ }
1449
+ /**
1450
+ * @method
1451
+ * @name zebpayfutures#addMargin
1452
+ * @description add margin
1453
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/private-endpoints/trade.md#-add-margin-to-position
1454
+ * @param {string} symbol unified market symbol
1455
+ * @param {float} amount amount of margin to add
1456
+ * @param {object} [params] extra parameters specific to the exchange API endpoint.
1457
+ * @param {string} [params.positionId] PositionId of the order to add margin.
1458
+ * @param {string} [params.timestamp] Tiemstamp.
1459
+ * @returns {object} a [margin structure]{@link https://docs.ccxt.com/#/?id=add-margin-structure}
1460
+ */
1461
+ async addMargin(symbol, amount, params = {}) {
1462
+ await this.loadMarkets();
1463
+ const market = this.market(symbol);
1464
+ const request = {
1465
+ 'symbol': market['id'],
1466
+ 'amount': amount,
1467
+ };
1468
+ const response = await this.privateSwapPostV1TradeAddMargin(this.extend(request, params));
1469
+ //
1470
+ // {
1471
+ // "code": "200000",
1472
+ // "data": {
1473
+ // "symbol": "BTCINR",
1474
+ // "type": "add",
1475
+ // "amount": 1000,
1476
+ // "code": "INR",
1477
+ // "status": "ok"
1478
+ // }
1479
+ // }
1480
+ //
1481
+ //
1482
+ // {
1483
+ // "code":"200000",
1484
+ // "msg":"Position does not exist"
1485
+ // }
1486
+ //
1487
+ const data = this.safeDict(response, 'data', {});
1488
+ return this.extend(this.parseMarginModification(data, market), {
1489
+ 'amount': amount,
1490
+ 'direction': 'in',
1491
+ });
1492
+ }
1493
+ /**
1494
+ * @method
1495
+ * @name zebpayfutures#reduceMargin
1496
+ * @description add margin
1497
+ * @see [Swap] https://github.com/zebpay/zebpay-api-references/blob/main/futures/api-reference/private-endpoints/trade.md#-reduce-margin-from-position
1498
+ * @param {string} symbol unified market symbol.
1499
+ * @param {float} amount amount of margin to add.
1500
+ * @param {object} [params] extra parameters specific to the exchange API endpoint.
1501
+ * @param {string} [params.positionId] PositionId of the order to add margin.
1502
+ * @param {string} [params.timestamp] Tiemstamp.
1503
+ * @returns {object} a [margin structure]{@link https://docs.ccxt.com/#/?id=add-margin-structure}
1504
+ */
1505
+ async reduceMargin(symbol, amount, params = {}) {
1506
+ await this.loadMarkets();
1507
+ const market = this.market(symbol);
1508
+ const request = {
1509
+ 'symbol': market['id'],
1510
+ 'amount': amount,
1511
+ };
1512
+ const response = await this.privateSwapPostV1TradeReduceMargin(this.extend(request, params));
1513
+ //
1514
+ // {
1515
+ // "code": "200000",
1516
+ // "data": {
1517
+ // "symbol": "BTCINR",
1518
+ // "type": "reduce",
1519
+ // "amount": 1000,
1520
+ // "code": "INR",
1521
+ // "status": "ok"
1522
+ // }
1523
+ // }
1524
+ //
1525
+ const data = this.safeDict(response, 'data', {});
1526
+ return this.extend(this.parseMarginModification(data, market), {
1527
+ 'amount': amount,
1528
+ 'direction': 'out',
1529
+ });
1530
+ }
1531
+ async fetchSpotMarkets(params = {}) {
1532
+ const response = await this.publicSpotGetV2ExExchangeInfo(params);
1533
+ //
1534
+ // {
1535
+ // "data": {
1536
+ // "symbol": "ETH-INR",
1537
+ // "name": "ETH-INR",
1538
+ // "baseCurrency": "ETH",
1539
+ // "quoteCurrency": "INR",
1540
+ // "feeCurrency": "INR",
1541
+ // "baseMinSize": "",
1542
+ // "quoteMinSize": "100",
1543
+ // "baseMaxSize": "",
1544
+ // "quoteMaxSize": "2000",
1545
+ // "baseIncrement": "0.00001"
1546
+ // "quoteIncrement": "0.00001",
1547
+ // "enableTrading": true
1548
+ // }
1549
+ // }
1550
+ //
1551
+ const result = [];
1552
+ const data = this.safeDict(response, 'data', {});
1553
+ const markets = this.safeList(data, 'symbols', []);
1554
+ for (let i = 0; i < markets.length; i++) {
1555
+ const market = markets[i];
1556
+ const id = this.safeString(market, 'symbol');
1557
+ const baseId = this.safeString(market, 'baseAsset');
1558
+ const quoteId = this.safeString(market, 'quoteAsset');
1559
+ const base = this.safeCurrencyCode(baseId);
1560
+ const quote = this.safeCurrencyCode(quoteId);
1561
+ const symbol = base + '/' + quote;
1562
+ result.push({
1563
+ 'id': id,
1564
+ 'symbol': symbol,
1565
+ 'base': base,
1566
+ 'quote': quote,
1567
+ 'baseId': baseId,
1568
+ 'quoteId': quoteId,
1569
+ 'type': 'spot',
1570
+ 'spot': true,
1571
+ 'swap': false,
1572
+ 'margin': false,
1573
+ 'future': false,
1574
+ 'option': false,
1575
+ 'active': undefined,
1576
+ 'contract': undefined,
1577
+ 'taker': this.safeNumber(market, 'takerFee'),
1578
+ 'maker': this.safeNumber(market, 'makerFee'),
1579
+ 'strike': undefined,
1580
+ 'optionType': undefined,
1581
+ 'precision': {
1582
+ 'amount': this.safeNumber(market, 'lotSz'),
1583
+ 'price': this.safeNumber(market, 'tickSz'),
1584
+ },
1585
+ 'limits': {
1586
+ 'amount': {
1587
+ 'min': undefined,
1588
+ 'max': undefined,
1589
+ },
1590
+ 'price': {
1591
+ 'min': undefined,
1592
+ 'max': undefined,
1593
+ },
1594
+ 'cost': {
1595
+ 'min': undefined,
1596
+ 'max': undefined,
1597
+ },
1598
+ },
1599
+ 'info': market,
1600
+ });
1601
+ }
1602
+ return result;
1603
+ }
1604
+ async fetchSwapMarkets(params = {}) {
1605
+ const response = await this.publicSwapGetV1MarketMarkets(params);
1606
+ //
1607
+ // {
1608
+ // "data": {
1609
+ // "symbol": "ETHUSDT",
1610
+ // "status": "TRADING",
1611
+ // "mainMarginPercent": "10",
1612
+ // "baseAsset": "ETH",
1613
+ // "quoteAsset": "USDT",
1614
+ // "pricePrecision": 1,
1615
+ // "quantityPrecision": 0.05,
1616
+ // "baseAssetPrecision": 0,
1617
+ // "quotePrecision": 0,
1618
+ // "orderType": ["LIMIT", "MARKET" ]
1619
+ // "timeInForce": ["GTC"],
1620
+ // "makerFee": "0.01",
1621
+ // "takerFee": "0.01",
1622
+ // "minLeverage": "1",
1623
+ // "maxLeverage": "20"
1624
+ // "tickSz": "0.1",
1625
+ // "lotSz": "0.1"
1626
+ // }
1627
+ // }
1628
+ //
1629
+ const result = [];
1630
+ const data = this.safeDict(response, 'data', {});
1631
+ const markets = this.safeList(data, 'symbols', []);
1632
+ for (let i = 0; i < markets.length; i++) {
1633
+ const market = markets[i];
1634
+ const id = this.safeString(market, 'symbol');
1635
+ const baseId = this.safeString(market, 'baseAsset');
1636
+ const quoteId = this.safeString(market, 'quoteAsset');
1637
+ const base = this.safeCurrencyCode(baseId);
1638
+ const quote = this.safeCurrencyCode(quoteId);
1639
+ const settle = this.safeCurrencyCode(quoteId);
1640
+ const status = this.safeString(market, 'status');
1641
+ const symbol = base + '/' + quote;
1642
+ result.push(this.safeMarketStructure({
1643
+ 'id': id,
1644
+ 'symbol': symbol + ':' + settle,
1645
+ 'base': base,
1646
+ 'quote': quote,
1647
+ 'baseId': baseId,
1648
+ 'quoteId': quoteId,
1649
+ 'spot': false,
1650
+ 'margin': false,
1651
+ 'swap': true,
1652
+ 'future': false,
1653
+ 'type': 'swap',
1654
+ 'option': false,
1655
+ 'active': (status === 'Open'),
1656
+ 'contract': true,
1657
+ 'taker': this.safeNumber(market, 'takerFee'),
1658
+ 'maker': this.safeNumber(market, 'makerFee'),
1659
+ 'strike': undefined,
1660
+ 'optionType': undefined,
1661
+ 'precision': {
1662
+ 'amount': this.safeNumber(market, 'lotSz'),
1663
+ 'price': this.safeNumber(market, 'tickSz'),
1664
+ },
1665
+ 'limits': {
1666
+ 'leverage': {
1667
+ 'min': this.safeNumber(market, 'minLeverage'),
1668
+ 'max': this.safeNumber(market, 'maxLeverage'),
1669
+ },
1670
+ },
1671
+ 'info': market,
1672
+ }));
1673
+ }
1674
+ return result;
1675
+ }
1676
+ parseBalance(response) {
1677
+ const result = {
1678
+ 'info': response,
1679
+ 'timestamp': undefined,
1680
+ 'datetime': undefined,
1681
+ };
1682
+ const currencyList = this.safeList(response, 'data', []);
1683
+ for (let i = 0; i < currencyList.length; i++) {
1684
+ const entry = currencyList[i];
1685
+ const account = this.account();
1686
+ account['total'] = this.safeString(entry, 'total');
1687
+ account['free'] = this.safeString(entry, 'free');
1688
+ account['used'] = this.safeString(entry, 'used');
1689
+ const currencyId = this.safeString(entry, 'currency');
1690
+ const code = this.safeCurrencyCode(currencyId);
1691
+ result[code] = account;
1692
+ }
1693
+ return this.safeBalance(result);
1694
+ }
1695
+ parsePosition(position, market = undefined) {
1696
+ //
1697
+ // isolated
1698
+ // {
1699
+ // "id":"long",
1700
+ // "symbol":"pf_ftmusd",
1701
+ // "entryPrice":"0.4921",
1702
+ // "datetime":"2023-02-22T11:37:16.685Z",
1703
+ // "contractSize":"1",
1704
+ // "leverage":"1.0"
1705
+ // }
1706
+ //
1707
+ const leverage = this.safeNumber(position, 'leverage');
1708
+ const datetime = this.safeString(position, 'datetime');
1709
+ const marketId = this.safeString(position, 'symbol');
1710
+ market = this.safeMarket(marketId, market);
1711
+ return {
1712
+ 'info': position,
1713
+ 'symbol': marketId,
1714
+ 'timestamp': this.parse8601(datetime),
1715
+ 'datetime': datetime,
1716
+ 'initialMargin': this.safeNumber(position, 'initialMargin'),
1717
+ 'initialMarginPercentage': undefined,
1718
+ 'maintenanceMargin': undefined,
1719
+ 'maintenanceMarginPercentage': undefined,
1720
+ 'entryPrice': this.safeNumber(position, 'entryPrice'),
1721
+ 'notional': this.safeNumber(position, 'notional'),
1722
+ 'leverage': leverage,
1723
+ 'unrealizedPnl': undefined,
1724
+ 'contracts': this.safeNumber(position, 'contracts'),
1725
+ 'contractSize': this.safeNumber(market, 'contractSize'),
1726
+ 'marginRatio': undefined,
1727
+ 'liquidationPrice': this.safeNumber(position, 'liquidationPrice'),
1728
+ 'markPrice': undefined,
1729
+ 'collateral': undefined,
1730
+ 'marginType': 'isolated',
1731
+ 'side': this.safeString(position, 'side'),
1732
+ 'percentage': undefined,
1733
+ };
1734
+ }
1735
+ parseLeverage(leverage, market = undefined) {
1736
+ const marketId = this.safeString(leverage, 'symbol');
1737
+ const info = this.safeDict(leverage, 'info');
1738
+ const leverageValue = this.safeInteger(leverage, 'longLeverage');
1739
+ const leverageValueShort = this.safeInteger(leverage, 'shortLeverage');
1740
+ const marginMode = this.safeString(leverage, 'marginMode');
1741
+ return {
1742
+ 'info': info,
1743
+ 'symbol': marketId,
1744
+ 'marginMode': marginMode,
1745
+ 'longLeverage': leverageValue,
1746
+ 'shortLeverage': leverageValueShort,
1747
+ };
1748
+ }
1749
+ parseTradingFee(fee, market = undefined) {
1750
+ const marketId = this.safeString(fee, 'symbol');
1751
+ const symbol = this.safeSymbol(marketId, market);
1752
+ return {
1753
+ 'info': fee,
1754
+ 'symbol': symbol,
1755
+ 'maker': this.safeNumber2(fee, 'makerFeeRate', 'makerFee'),
1756
+ 'taker': this.safeNumber2(fee, 'takerFeeRate', 'takerFee'),
1757
+ 'percentage': undefined,
1758
+ 'tierBased': undefined,
1759
+ };
1760
+ }
1761
+ parseTicker(ticker, market = undefined) {
1762
+ //
1763
+ // [
1764
+ // {
1765
+ // "symbol": "BTC-INR",
1766
+ // "bestBid": "4900000",
1767
+ // "bestBidQty": "0.00014938",
1768
+ // "bestAsk": "",
1769
+ // "bestAskQty": "0",
1770
+ // "priceChange": "-98134.56",
1771
+ // "priceChangePercent": "-1.84",
1772
+ // "high": "5433400",
1773
+ // "low": "5333400",
1774
+ // "vol": "0.0002",
1775
+ // "volValue": "1066.68",
1776
+ // "last": "5333400"
1777
+ // }
1778
+ // ]
1779
+ //
1780
+ const timestamp = this.safeInteger2(ticker, 'timestamp', 'ts', undefined);
1781
+ const marketId = this.safeString(ticker, 'symbol');
1782
+ market = this.safeMarket(marketId);
1783
+ const close = this.safeString(ticker, 'close', undefined);
1784
+ const last = this.safeString(ticker, 'last', undefined);
1785
+ const percentage = this.safeString(ticker, 'percentage');
1786
+ const bidVolume = this.safeString(ticker, 'bidVolume');
1787
+ const askVolume = this.safeString(ticker, 'askVolume');
1788
+ return this.safeTicker({
1789
+ 'id': marketId,
1790
+ 'symbol': market['symbol'],
1791
+ 'timestamp': timestamp,
1792
+ 'datetime': this.iso8601(timestamp),
1793
+ 'high': this.safeString(ticker, 'high'),
1794
+ 'low': this.safeString(ticker, 'low'),
1795
+ 'bid': this.safeString(ticker, 'bid'),
1796
+ 'bidVolume': bidVolume,
1797
+ 'ask': this.safeString(ticker, 'ask'),
1798
+ 'askVolume': askVolume,
1799
+ 'vwap': undefined,
1800
+ 'open': undefined,
1801
+ 'close': close,
1802
+ 'last': last,
1803
+ 'previousClose': this.safeString(ticker, 'previousClose'),
1804
+ 'change': this.safeString(ticker, 'change'),
1805
+ 'percentage': percentage,
1806
+ 'average': this.safeString(ticker, 'average'),
1807
+ 'baseVolume': this.safeString(ticker, 'baseVolume'),
1808
+ 'quoteVolume': this.safeString(ticker, 'quoteVolume'),
1809
+ 'markPrice': undefined,
1810
+ 'info': ticker,
1811
+ }, market);
1812
+ }
1813
+ parseMarginModification(info, market = undefined) {
1814
+ //
1815
+ // {
1816
+ // "symbol": "BTCINR",
1817
+ // "type": "reduce",
1818
+ // "amount": 1000,
1819
+ // "code": "INR",
1820
+ // "status": "ok"
1821
+ // }
1822
+ //
1823
+ const timestamp = this.milliseconds();
1824
+ return {
1825
+ 'info': info,
1826
+ 'symbol': market['id'],
1827
+ 'type': undefined,
1828
+ 'marginMode': undefined,
1829
+ 'amount': this.safeNumber(info, 'amount'),
1830
+ 'total': undefined,
1831
+ 'code': this.safeString(info, 'code'),
1832
+ 'status': this.safeString(info, 'status'),
1833
+ 'timestamp': timestamp,
1834
+ 'datetime': this.iso8601(timestamp),
1835
+ };
1836
+ }
1837
+ sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
1838
+ params = this.omit(params, 'defaultType');
1839
+ const isV1 = path.indexOf('v1/') > -1;
1840
+ const marketType = isV1 ? 'swap' : 'spot';
1841
+ let url = this.urls['api'][marketType];
1842
+ const tail = '/api/' + this.implodeParams(path, params);
1843
+ url += tail;
1844
+ const timestamp = this.milliseconds().toString();
1845
+ let signature = '';
1846
+ const query = this.omit(params, this.extractParams(path));
1847
+ const queryLength = Object.keys(query).length;
1848
+ const access = this.safeString(api, 0, 'public');
1849
+ if (access === 'public') {
1850
+ if (method === 'GET' || method === 'DELETE') {
1851
+ if (queryLength) {
1852
+ url += '?' + this.urlencode(query);
1853
+ }
1854
+ }
1855
+ else {
1856
+ body = JSON.stringify(params);
1857
+ headers = {
1858
+ 'Referrer': 'ccxt',
1859
+ 'Content-Type': 'application/json',
1860
+ };
1861
+ }
1862
+ }
1863
+ else {
1864
+ this.checkRequiredCredentials();
1865
+ const isSpot = marketType === 'spot';
1866
+ params['timestamp'] = timestamp;
1867
+ if (method === 'GET' || (method === 'DELETE' && isSpot)) {
1868
+ // For GET/DELETE: Append params to URL and sign the query string
1869
+ const queryString = this.urlencode(params);
1870
+ signature = this.hmac(this.encode(queryString), this.encode(this.secret), sha256, 'hex');
1871
+ url += '?' + queryString;
1872
+ }
1873
+ else {
1874
+ // For POST/PUT: Convert body to JSON and sign the stringified payload
1875
+ body = this.json(params);
1876
+ signature = this.hmac(this.encode(body), this.encode(this.secret), sha256, 'hex');
1877
+ }
1878
+ headers = {
1879
+ 'Referrer': 'ccxt',
1880
+ 'X-AUTH-APIKEY': this.apiKey,
1881
+ 'X-AUTH-SIGNATURE': signature,
1882
+ };
1883
+ headers['Content-Type'] = 'application/json';
1884
+ }
1885
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
1886
+ }
1887
+ handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
1888
+ if (!response) {
1889
+ this.throwBroadlyMatchedException(this.exceptions['broad'], body, body);
1890
+ return undefined;
1891
+ }
1892
+ //
1893
+ // bad
1894
+ // { "code": "400100", "msg": "validation.createOrder.clientOidIsRequired" }
1895
+ // good
1896
+ // { code: "200000", data: { ... }}
1897
+ // {"statusDescription":"Order quantity is out of range","data":{},"statusCode":400,"customMessage":["Order quantity is out of range"]}
1898
+ //
1899
+ const errorCode = this.safeString2(response, 'code', 'statusCode');
1900
+ const message = this.safeString2(response, 'msg', 'statusDescription');
1901
+ const feedback = this.id + ' ' + message;
1902
+ this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
1903
+ this.throwExactlyMatchedException(this.exceptions['exact'], message, feedback);
1904
+ this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
1905
+ return undefined;
1906
+ }
1907
+ }