ccxt 4.5.0 → 4.5.2

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 (82) hide show
  1. package/README.md +110 -112
  2. package/dist/ccxt.browser.min.js +5 -5
  3. package/dist/cjs/ccxt.js +1 -9
  4. package/dist/cjs/src/ascendex.js +1 -1
  5. package/dist/cjs/src/base/Exchange.js +13 -0
  6. package/dist/cjs/src/binance.js +20 -14
  7. package/dist/cjs/src/bitget.js +1 -1
  8. package/dist/cjs/src/coinbase.js +46 -34
  9. package/dist/cjs/src/gate.js +39 -18
  10. package/dist/cjs/src/gemini.js +1 -1
  11. package/dist/cjs/src/hibachi.js +1 -1
  12. package/dist/cjs/src/hyperliquid.js +16 -2
  13. package/dist/cjs/src/indodax.js +11 -12
  14. package/dist/cjs/src/kraken.js +1 -12
  15. package/dist/cjs/src/krakenfutures.js +25 -25
  16. package/dist/cjs/src/mexc.js +2 -1
  17. package/dist/cjs/src/okx.js +2 -2
  18. package/dist/cjs/src/poloniex.js +1 -1
  19. package/dist/cjs/src/pro/bitget.js +352 -75
  20. package/dist/cjs/src/pro/bitmart.js +1 -1
  21. package/dist/cjs/src/pro/bybit.js +8 -15
  22. package/dist/cjs/src/pro/gate.js +6 -1
  23. package/dist/cjs/src/pro/gemini.js +7 -2
  24. package/dist/cjs/src/pro/hyperliquid.js +9 -1
  25. package/dist/cjs/src/pro/kraken.js +5 -6
  26. package/dist/cjs/src/pro/lbank.js +55 -1
  27. package/dist/cjs/src/pro/mexc.js +1 -1
  28. package/dist/cjs/src/timex.js +35 -0
  29. package/dist/cjs/src/tradeogre.js +32 -0
  30. package/dist/cjs/src/wavesexchange.js +33 -0
  31. package/dist/cjs/src/zonda.js +12 -0
  32. package/js/ccxt.d.ts +2 -11
  33. package/js/ccxt.js +2 -8
  34. package/js/src/ascendex.js +1 -1
  35. package/js/src/base/Exchange.d.ts +1 -0
  36. package/js/src/base/Exchange.js +14 -1
  37. package/js/src/binance.d.ts +1 -1
  38. package/js/src/binance.js +20 -14
  39. package/js/src/bitget.js +1 -1
  40. package/js/src/coinbase.js +46 -34
  41. package/js/src/gate.d.ts +2 -1
  42. package/js/src/gate.js +39 -18
  43. package/js/src/gemini.js +1 -1
  44. package/js/src/hibachi.js +1 -1
  45. package/js/src/hyperliquid.d.ts +1 -0
  46. package/js/src/hyperliquid.js +16 -2
  47. package/js/src/indodax.js +11 -12
  48. package/js/src/kraken.d.ts +0 -1
  49. package/js/src/kraken.js +1 -12
  50. package/js/src/krakenfutures.d.ts +24 -24
  51. package/js/src/krakenfutures.js +25 -25
  52. package/js/src/mexc.js +2 -1
  53. package/js/src/okx.js +2 -2
  54. package/js/src/poloniex.js +1 -1
  55. package/js/src/pro/bitget.d.ts +12 -2
  56. package/js/src/pro/bitget.js +358 -75
  57. package/js/src/pro/bitmart.js +1 -1
  58. package/js/src/pro/bybit.js +8 -15
  59. package/js/src/pro/gate.d.ts +5 -0
  60. package/js/src/pro/gate.js +6 -1
  61. package/js/src/pro/gemini.d.ts +1 -1
  62. package/js/src/pro/gemini.js +7 -2
  63. package/js/src/pro/hyperliquid.js +9 -1
  64. package/js/src/pro/kraken.js +5 -6
  65. package/js/src/pro/lbank.d.ts +11 -1
  66. package/js/src/pro/lbank.js +55 -1
  67. package/js/src/pro/mexc.js +1 -1
  68. package/js/src/timex.js +35 -0
  69. package/js/src/tradeogre.js +32 -0
  70. package/js/src/wavesexchange.js +33 -0
  71. package/js/src/zonda.js +12 -0
  72. package/package.json +2 -1
  73. package/js/src/abstract/ellipx.d.ts +0 -28
  74. package/js/src/abstract/ellipx.js +0 -11
  75. package/js/src/abstract/vertex.d.ts +0 -22
  76. package/js/src/abstract/vertex.js +0 -11
  77. package/js/src/ellipx.d.ts +0 -237
  78. package/js/src/ellipx.js +0 -2071
  79. package/js/src/pro/vertex.d.ts +0 -104
  80. package/js/src/pro/vertex.js +0 -999
  81. package/js/src/vertex.d.ts +0 -346
  82. package/js/src/vertex.js +0 -3146
package/js/src/ellipx.js DELETED
@@ -1,2071 +0,0 @@
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/ellipx.js';
9
- import { AuthenticationError, BadRequest, DDoSProtection, ExchangeError, PermissionDenied, NotSupported, ArgumentsRequired } from './base/errors.js';
10
- import { ed25519 } from './static_dependencies/noble-curves/ed25519.js';
11
- import { eddsa } from './base/functions/crypto.js';
12
- import { Precise } from './base/Precise.js';
13
- import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
14
- import { TICK_SIZE } from './base/functions/number.js';
15
- // ---------------------------------------------------------------------------
16
- /**
17
- * @class ellipx
18
- * @augments Exchange
19
- */
20
- export default class ellipx extends Exchange {
21
- describe() {
22
- return this.deepExtend(super.describe(), {
23
- 'id': 'ellipx',
24
- 'name': 'Ellipx',
25
- 'countries': ['PL'],
26
- 'rateLimit': 200,
27
- 'version': 'v1',
28
- 'certified': false,
29
- 'pro': false,
30
- 'has': {
31
- 'CORS': undefined,
32
- 'spot': true,
33
- 'margin': false,
34
- 'swap': false,
35
- 'future': false,
36
- 'option': false,
37
- 'addMargin': false,
38
- 'borrowCrossMargin': false,
39
- 'borrowIsolatedMargin': false,
40
- 'borrowMargin': false,
41
- 'cancelAllOrders': false,
42
- 'cancelAllOrdersAfter': false,
43
- 'cancelOrder': true,
44
- 'cancelOrders': false,
45
- 'cancelWithdraw': false,
46
- 'closeAllPositions': false,
47
- 'closePosition': false,
48
- 'createConvertTrade': false,
49
- 'createDepositAddress': false,
50
- 'createMarketBuyOrderWithCost': false,
51
- 'createMarketOrder': false,
52
- 'createMarketOrderWithCost': false,
53
- 'createMarketSellOrderWithCost': false,
54
- 'createOrder': true,
55
- 'createOrderWithTakeProfitAndStopLoss': false,
56
- 'createOrderWithTakeProfitAndStopLossWs': false,
57
- 'createPostOnlyOrder': false,
58
- 'createReduceOnlyOrder': false,
59
- 'createStopLimitOrder': false,
60
- 'createStopLossOrder': false,
61
- 'createStopMarketOrder': false,
62
- 'createStopOrder': false,
63
- 'createTakeProfitOrder': false,
64
- 'createTrailingAmountOrder': false,
65
- 'createTrailingPercentOrder': false,
66
- 'createTriggerOrder': false,
67
- 'fetchAccounts': false,
68
- 'fetchBalance': true,
69
- 'fetchBorrowInterest': false,
70
- 'fetchBorrowRate': false,
71
- 'fetchBorrowRateHistories': false,
72
- 'fetchBorrowRateHistory': false,
73
- 'fetchBorrowRates': false,
74
- 'fetchBorrowRatesPerSymbol': false,
75
- 'fetchCanceledAndClosedOrders': false,
76
- 'fetchCanceledOrders': false,
77
- 'fetchClosedOrder': false,
78
- 'fetchClosedOrders': false,
79
- 'fetchConvertCurrencies': false,
80
- 'fetchConvertQuote': false,
81
- 'fetchConvertTrade': false,
82
- 'fetchConvertTradeHistory': false,
83
- 'fetchCrossBorrowRate': false,
84
- 'fetchCrossBorrowRates': false,
85
- 'fetchCurrencies': true,
86
- 'fetchDepositAddress': true,
87
- 'fetchDeposits': false,
88
- 'fetchDepositsWithdrawals': false,
89
- 'fetchFundingHistory': false,
90
- 'fetchFundingInterval': false,
91
- 'fetchFundingIntervals': false,
92
- 'fetchFundingRate': false,
93
- 'fetchFundingRateHistory': false,
94
- 'fetchFundingRates': false,
95
- 'fetchGreeks': false,
96
- 'fetchIndexOHLCV': false,
97
- 'fetchIsolatedBorrowRate': false,
98
- 'fetchIsolatedBorrowRates': false,
99
- 'fetchIsolatedPositions': false,
100
- 'fetchLedger': false,
101
- 'fetchLeverage': false,
102
- 'fetchLeverages': false,
103
- 'fetchLeverageTiers': false,
104
- 'fetchLiquidations': false,
105
- 'fetchLongShortRatio': false,
106
- 'fetchLongShortRatioHistory': false,
107
- 'fetchMarginAdjustmentHistory': false,
108
- 'fetchMarginMode': false,
109
- 'fetchMarginModes': false,
110
- 'fetchMarketLeverageTiers': false,
111
- 'fetchMarkets': true,
112
- 'fetchMarkOHLCV': false,
113
- 'fetchMarkPrices': false,
114
- 'fetchMyLiquidations': false,
115
- 'fetchMySettlementHistory': false,
116
- 'fetchMyTrades': false,
117
- 'fetchOHLCV': true,
118
- 'fetchOpenInterest': false,
119
- 'fetchOpenInterestHistory': false,
120
- 'fetchOpenInterests': false,
121
- 'fetchOpenOrder': false,
122
- 'fetchOpenOrders': true,
123
- 'fetchOption': false,
124
- 'fetchOptionChain': false,
125
- 'fetchOrder': true,
126
- 'fetchOrderBook': true,
127
- 'fetchOrders': true,
128
- 'fetchOrderTrades': true,
129
- 'fetchPosition': false,
130
- 'fetchPositionHistory': false,
131
- 'fetchPositionMode': false,
132
- 'fetchPositions': false,
133
- 'fetchPositionsForSymbol': false,
134
- 'fetchPositionsHistory': false,
135
- 'fetchPositionsRisk': false,
136
- 'fetchPremiumIndexOHLCV': false,
137
- 'fetchSettlementHistory': false,
138
- 'fetchStatus': false,
139
- 'fetchTicker': true,
140
- 'fetchTickers': false,
141
- 'fetchTime': false,
142
- 'fetchTrades': true,
143
- 'fetchTradingFee': true,
144
- 'fetchTradingFees': false,
145
- 'fetchTransactions': false,
146
- 'fetchTransfers': false,
147
- 'fetchVolatilityHistory': false,
148
- 'fetchWithdrawals': false,
149
- 'reduceMargin': false,
150
- 'repayCrossMargin': false,
151
- 'repayIsolatedMargin': false,
152
- 'repayMargin': false,
153
- 'sandbox': false,
154
- 'setLeverage': false,
155
- 'setMargin': false,
156
- 'setMarginMode': false,
157
- 'setPositionMode': false,
158
- 'transfer': false,
159
- 'withdraw': true,
160
- },
161
- 'timeframes': {
162
- '1m': '1m',
163
- '5m': '5m',
164
- '10m': '10m',
165
- '1h': '1h',
166
- '6h': '6h',
167
- '12h': '12h',
168
- '1d': '1d',
169
- },
170
- 'urls': {
171
- 'logo': 'https://github.com/user-attachments/assets/e07c3f40-281c-4cdf-bacf-fa1c58218a2c',
172
- 'api': {
173
- 'public': 'https://data.ellipx.com',
174
- 'private': 'https://app.ellipx.com/_rest',
175
- '_rest': 'https://app.ellipx.com/_rest',
176
- },
177
- 'www': 'https://www.ellipx.com',
178
- 'doc': 'https://docs.google.com/document/d/1ZXzTQYffKE_EglTaKptxGQERRnunuLHEMmar7VC9syM',
179
- 'fees': 'https://www.ellipx.com/pages/pricing',
180
- 'referral': '', // todo
181
- },
182
- 'api': {
183
- '_rest': {
184
- 'get': {
185
- 'Market': 1,
186
- 'Market/{currencyPair}': 1,
187
- 'Crypto/Token/Info': 1,
188
- },
189
- },
190
- 'public': {
191
- 'get': {
192
- 'Market/{currencyPair}:getDepth': 1,
193
- 'Market/{currencyPair}:ticker': 1,
194
- 'Market/{currencyPair}:getTrades': 1,
195
- 'Market/{currencyPair}:getGraph': 1,
196
- 'CMC:summary': 1,
197
- 'CMC/{currencyPair}:ticker': 1,
198
- },
199
- },
200
- 'private': {
201
- 'get': {
202
- 'User/Wallet': 1,
203
- 'Market/{currencyPair}/Order': 1,
204
- 'Market/Order/{orderUuid}': 1,
205
- 'Market/{currencyPair}/Trade': 1,
206
- 'Market/TradeFee:query': 1,
207
- 'Unit/{currency}': 1,
208
- 'Crypto/Token/{currency}': 1,
209
- 'Crypto/Token/{currency}:chains': 1,
210
- },
211
- 'post': {
212
- 'Market/{currencyPair}/Order': 1,
213
- 'Crypto/Address:fetch': 1,
214
- 'Crypto/Disbursement:withdraw': 1,
215
- },
216
- 'delete': {
217
- 'Market/Order/{orderUuid}': 1,
218
- },
219
- },
220
- },
221
- 'fees': {
222
- 'trading': {
223
- 'tierBased': true,
224
- 'feeSide': 'get',
225
- 'percentage': true,
226
- 'maker': this.parseNumber('0.0025'),
227
- 'taker': this.parseNumber('0.0030'),
228
- 'tiers': {
229
- // volume in USDT
230
- 'maker': [
231
- [this.parseNumber('0'), this.parseNumber('0.0025')],
232
- [this.parseNumber('10000'), this.parseNumber('0.0020')],
233
- [this.parseNumber('50000'), this.parseNumber('0.0015')],
234
- [this.parseNumber('100000'), this.parseNumber('0.0010')],
235
- [this.parseNumber('1000000'), this.parseNumber('0.0008')],
236
- [this.parseNumber('5000000'), this.parseNumber('0.0003')],
237
- [this.parseNumber('15000000'), this.parseNumber('0.0000')],
238
- [this.parseNumber('75000000'), this.parseNumber('0.0000')],
239
- [this.parseNumber('100000000'), this.parseNumber('0.0000')], // 100M+: 0bps
240
- ],
241
- 'taker': [
242
- [this.parseNumber('0'), this.parseNumber('0.0030')],
243
- [this.parseNumber('10000'), this.parseNumber('0.0025')],
244
- [this.parseNumber('50000'), this.parseNumber('0.0020')],
245
- [this.parseNumber('100000'), this.parseNumber('0.0015')],
246
- [this.parseNumber('1000000'), this.parseNumber('0.0012')],
247
- [this.parseNumber('5000000'), this.parseNumber('0.0010')],
248
- [this.parseNumber('15000000'), this.parseNumber('0.0008')],
249
- [this.parseNumber('75000000'), this.parseNumber('0.0005')],
250
- [this.parseNumber('100000000'), this.parseNumber('0.0003')], // 100M+: 3bps
251
- ],
252
- },
253
- },
254
- 'stablecoin': {
255
- 'tierBased': false,
256
- 'percentage': true,
257
- 'maker': this.parseNumber('0.0000'),
258
- 'taker': this.parseNumber('0.000015'), // 0.0015%
259
- },
260
- },
261
- 'options': {
262
- 'defaultType': 'spot',
263
- 'recvWindow': 5 * 1000,
264
- 'broker': 'CCXT',
265
- 'networks': {
266
- 'Bitcoin': 'Bitcoin',
267
- 'Ethereum': 'ERC20',
268
- },
269
- 'defaultNetwork': 'defaultNetwork',
270
- 'defaultNetworkCodeReplacements': {
271
- 'BTC': 'Bitcoin',
272
- 'ETH': 'Ethereum',
273
- },
274
- },
275
- 'features': {
276
- 'spot': {
277
- 'sandbox': false,
278
- 'createOrder': {
279
- 'marginMode': false,
280
- 'triggerPrice': false,
281
- 'triggerPriceType': undefined,
282
- 'triggerDirection': false,
283
- 'stopLossPrice': false,
284
- 'takeProfitPrice': false,
285
- 'attachedStopLossTakeProfit': undefined,
286
- 'timeInForce': {
287
- 'IOC': false,
288
- 'FOK': false,
289
- 'PO': false,
290
- 'GTD': false,
291
- },
292
- 'hedged': false,
293
- 'selfTradePrevention': false,
294
- 'trailing': false,
295
- 'leverage': false,
296
- 'marketBuyByCost': true,
297
- 'marketBuyRequiresPrice': false,
298
- 'iceberg': false,
299
- },
300
- 'createOrders': undefined,
301
- 'fetchMyTrades': undefined,
302
- 'fetchOrder': {
303
- 'marginMode': false,
304
- 'trigger': false,
305
- 'trailing': false,
306
- 'symbolRequired': false,
307
- },
308
- 'fetchOpenOrders': {
309
- 'marginMode': false,
310
- 'limit': undefined,
311
- 'trigger': false,
312
- 'trailing': false,
313
- 'symbolRequired': true,
314
- },
315
- 'fetchOrders': {
316
- 'marginMode': false,
317
- 'limit': undefined,
318
- 'daysBack': undefined,
319
- 'untilDays': undefined,
320
- 'trigger': false,
321
- 'trailing': false,
322
- 'symbolRequired': true,
323
- },
324
- 'fetchClosedOrders': undefined,
325
- 'fetchOHLCV': {
326
- 'limit': 100,
327
- },
328
- },
329
- 'swap': {
330
- 'linear': undefined,
331
- 'inverse': undefined,
332
- },
333
- 'future': {
334
- 'linear': undefined,
335
- 'inverse': undefined,
336
- },
337
- },
338
- 'commonCurrencies': {},
339
- 'exceptions': {
340
- 'exact': {
341
- // todo
342
- '400': BadRequest,
343
- '401': AuthenticationError,
344
- '403': PermissionDenied,
345
- '404': BadRequest,
346
- '429': DDoSProtection,
347
- '418': PermissionDenied,
348
- '500': ExchangeError,
349
- '504': ExchangeError,
350
- },
351
- 'broad': {},
352
- },
353
- 'precisionMode': TICK_SIZE,
354
- });
355
- }
356
- sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
357
- path = this.implodeParams(path, params);
358
- let url = this.urls['api'][api] + '/' + path;
359
- if (api === 'private') {
360
- this.checkRequiredCredentials();
361
- const nonce = this.uuid();
362
- const timestamp = this.seconds().toString();
363
- if (method === 'GET') {
364
- body = '';
365
- }
366
- else {
367
- body = this.json(params);
368
- }
369
- params = this.extend({
370
- '_key': this.apiKey,
371
- '_time': timestamp,
372
- '_nonce': nonce,
373
- }, params);
374
- const query = this.urlencode(params);
375
- const bodyHash = this.hash(this.encode(body), sha256);
376
- // Create sign string components
377
- const bodyHashBytes = this.base16ToBinary(bodyHash);
378
- const nulByte = this.numberToBE(0, 1);
379
- const components = [
380
- this.encode(method),
381
- nulByte,
382
- this.encode(path),
383
- nulByte,
384
- this.encode(query),
385
- nulByte,
386
- bodyHashBytes,
387
- ];
388
- // Join with null byte separator using encode
389
- const signString = this.binaryConcatArray(components);
390
- const sec = this.secret;
391
- const remainder = this.calculateMod(sec.length, 4);
392
- const paddingLength = remainder ? 4 - remainder : 0;
393
- let secretWithPadding = this.secret.replaceAll('-', '+');
394
- secretWithPadding = secretWithPadding.replaceAll('_', '/');
395
- secretWithPadding = secretWithPadding.padEnd(this.secret.length + paddingLength, '=');
396
- const secretBytes = this.base64ToBinary(secretWithPadding);
397
- const seed = this.arraySlice(secretBytes, 0, 32); // Extract first 32 bytes as seed
398
- const signature = eddsa(signString, seed, ed25519);
399
- params['_sign'] = signature;
400
- }
401
- if (Object.keys(params).length) {
402
- url += '?' + this.urlencode(params);
403
- }
404
- if (method === 'GET') {
405
- body = undefined;
406
- }
407
- else {
408
- headers = {
409
- 'Content-Type': 'application/json',
410
- };
411
- }
412
- return { 'url': url, 'method': method, 'body': body, 'headers': headers };
413
- }
414
- calculateMod(a, b) {
415
- // trick to fix php transpiling error
416
- return a % b;
417
- }
418
- /**
419
- * @method
420
- * @name ellipx#fetchMarkets
421
- * @description Fetches market information from the exchange.
422
- * @see https://docs.ccxt.com/en/latest/manual.html#markets
423
- * @see https://docs.google.com/document/d/1ZXzTQYffKE_EglTaKptxGQERRnunuLHEMmar7VC9syM/edit?tab=t.0#heading=h.1a1t05wpgfof
424
- * @param {object} [params] - Extra parameters specific to the exchange API endpoint
425
- * @returns {Promise<Market[]>} An array of market structures.
426
- */
427
- async fetchMarkets(params = {}) {
428
- const response = await this._restGetMarket(params);
429
- // {
430
- // Market__: "mkt-lrnp2e-eaor-eobj-ua73-75j6sjxe",
431
- // Primary_Unit__: "unit-aebkye-u35b-e5zm-zt22-2qvwhsqa",
432
- // Secondary_Unit__: "unit-jcevlk-soxf-fepb-yjwm-b32q5bom",
433
- // Primary_Step: null,
434
- // Secondary_Step: null,
435
- // Status: "active",
436
- // Default_Scale: "5",
437
- // Priority: "100",
438
- // Created: {
439
- // unix: "1728113809",
440
- // us: "0",
441
- // iso: "2024-10-05 07:36:49.000000",
442
- // tz: "UTC",
443
- // full: "1728113809000000",
444
- // unixms: "1728113809000",
445
- // },
446
- // Start: {
447
- // unix: "1728295200",
448
- // us: "0",
449
- // iso: "2024-10-07 10:00:00.000000",
450
- // tz: "UTC",
451
- // full: "1728295200000000",
452
- // unixms: "1728295200000",
453
- // },
454
- // Key: "BTC_USDC",
455
- // Primary: {
456
- // Unit__: "unit-aebkye-u35b-e5zm-zt22-2qvwhsqa",
457
- // Currency__: "BTC",
458
- // Crypto_Token__: "crtok-c5v3mh-grfn-hl5d-lmel-fvggbf4i",
459
- // Key: "BTC",
460
- // Symbol: "BTC",
461
- // Symbol_Position: "after",
462
- // Name: "Bitcoin",
463
- // Decimals: "8",
464
- // Display_Decimals: "8",
465
- // Legacy_Decimals: null,
466
- // Type: "crypto_token",
467
- // Visible: "Y",
468
- // Created: {
469
- // unix: "1495247415",
470
- // us: "0",
471
- // iso: "2017-05-20 02:30:15.000000",
472
- // tz: "UTC",
473
- // full: "1495247415000000",
474
- // unixms: "1495247415000",
475
- // },
476
- // },
477
- // Secondary: {
478
- // Unit__: "unit-jcevlk-soxf-fepb-yjwm-b32q5bom",
479
- // Currency__: null,
480
- // Crypto_Token__: "crtok-ptabkh-ra4r-anbd-cqra-bqfbtnba",
481
- // Key: "USDC",
482
- // Symbol: null,
483
- // Symbol_Position: "before",
484
- // Name: "Circle USD",
485
- // Decimals: "6",
486
- // Display_Decimals: "6",
487
- // Legacy_Decimals: null,
488
- // Type: "crypto_token",
489
- // Visible: "Y",
490
- // Created: {
491
- // unix: "1694859829",
492
- // us: "0",
493
- // iso: "2023-09-16 10:23:49.000000",
494
- // tz: "UTC",
495
- // full: "1694859829000000",
496
- // unixms: "1694859829000",
497
- // },
498
- // },
499
- // }
500
- const markets = this.safeValue(response, 'data', []);
501
- return this.parseMarkets(markets);
502
- }
503
- parseMarket(market) {
504
- const id = this.safeString(market, 'Key');
505
- const base = this.safeString(market['Primary'], 'Key');
506
- const quote = this.safeString(market['Secondary'], 'Key');
507
- const baseId = this.safeString(market['Primary'], 'Crypto_Token__');
508
- const quoteId = this.safeString(market['Secondary'], 'Crypto_Token__');
509
- const status = this.safeString(market, 'Status') === 'active';
510
- const created = this.safeTimestamp(market['Created'], 'unix');
511
- const amountPrecision = this.parseNumber(this.parsePrecision(this.safeString(market['Primary'], 'Decimals')));
512
- const pricePrecision = this.parseNumber(this.parsePrecision(this.safeString(market['Secondary'], 'Decimals')));
513
- const fees = this.fees; // should use fetchTradingFees
514
- return this.safeMarketStructure({
515
- 'id': id,
516
- 'symbol': base + '/' + quote,
517
- 'base': base,
518
- 'quote': quote,
519
- 'settle': undefined,
520
- 'baseId': baseId,
521
- 'quoteId': quoteId,
522
- 'settleId': undefined,
523
- 'type': 'spot',
524
- 'spot': true,
525
- 'margin': false,
526
- 'swap': false,
527
- 'future': false,
528
- 'option': false,
529
- 'active': status,
530
- 'contract': false,
531
- 'linear': undefined,
532
- 'inverse': undefined,
533
- 'taker': fees['trading']['taker'],
534
- 'maker': fees['trading']['maker'],
535
- 'contractSize': undefined,
536
- 'expiry': undefined,
537
- 'expiryDatetime': undefined,
538
- 'strike': undefined,
539
- 'optionType': undefined,
540
- 'precision': {
541
- 'amount': amountPrecision,
542
- 'price': pricePrecision,
543
- },
544
- 'limits': {
545
- 'amount': {
546
- 'min': undefined,
547
- 'max': undefined,
548
- },
549
- 'price': {
550
- 'min': undefined,
551
- 'max': undefined,
552
- },
553
- 'cost': {
554
- 'min': undefined,
555
- 'max': undefined,
556
- },
557
- },
558
- 'info': market,
559
- 'created': created,
560
- });
561
- }
562
- /**
563
- * @method
564
- * @name ellipx#fetchTicker
565
- * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
566
- * @see https://docs.google.com/document/d/1ZXzTQYffKE_EglTaKptxGQERRnunuLHEMmar7VC9syM/edit?tab=t.0#heading=h.d2jylz4u6pmu
567
- * @param {string} symbol unified symbol of the market to fetch the ticker for
568
- * @param {object} [params] extra parameters specific to the exchange API endpoint
569
- * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
570
- */
571
- async fetchTicker(symbol, params = {}) {
572
- await this.loadMarkets();
573
- const market = this.market(symbol);
574
- const marketId = market['id'];
575
- const request = {
576
- 'currencyPair': marketId,
577
- };
578
- const response = await this.publicGetMarketCurrencyPairTicker(this.extend(request, params));
579
- //
580
- // {
581
- // "data": {
582
- // "market": "BTC_USDC",
583
- // "ticker": {
584
- // "time": 1730814600,
585
- // "count": 2135,
586
- // "high": {
587
- // "v": "74766990000",
588
- // "e": 6,
589
- // "f": 74766.99
590
- // },
591
- // "low": {
592
- // "v": "68734020000",
593
- // "e": 6,
594
- // "f": 68734.02
595
- // },
596
- // "avg": {
597
- // "v": "72347941430",
598
- // "e": 6,
599
- // "f": 72347.94143
600
- // },
601
- // "vwap": {
602
- // "v": "73050064447",
603
- // "e": 6,
604
- // "f": 73050.064447
605
- // },
606
- // "vol": {
607
- // "v": "4885361",
608
- // "e": 8,
609
- // "f": 0.04885361
610
- // },
611
- // "secvol": {
612
- // "v": "3568759346",
613
- // "e": 6,
614
- // "f": 3568.759346
615
- // },
616
- // "open": {
617
- // "v": "68784020000",
618
- // "e": 6,
619
- // "f": 68784.02
620
- // },
621
- // "close": {
622
- // "v": "73955570000",
623
- // "e": 6,
624
- // "f": 73955.57
625
- // }
626
- // }
627
- // },
628
- // "request_id": "cbf183e0-7a62-4674-838c-6693031fa240",
629
- // "result": "success",
630
- // "time": 0.015463566
631
- // }
632
- //
633
- const ticker = this.safeValue(response['data'], 'ticker', {});
634
- return this.parseTicker(ticker, market);
635
- }
636
- parseTicker(ticker, market = undefined) {
637
- const timestamp = this.safeIntegerProduct(ticker, 'time', 1000);
638
- const open = this.parseAmount(this.safeValue(ticker, 'open'));
639
- const high = this.parseAmount(this.safeValue(ticker, 'high'));
640
- const low = this.parseAmount(this.safeValue(ticker, 'low'));
641
- const close = this.parseAmount(this.safeValue(ticker, 'close'));
642
- const avg = this.parseAmount(this.safeValue(ticker, 'avg'));
643
- const vwap = this.parseAmount(this.safeValue(ticker, 'vwap'));
644
- const baseVolume = this.parseAmount(this.safeValue(ticker, 'vol'));
645
- const quoteVolume = this.parseAmount(this.safeValue(ticker, 'secvol'));
646
- // const count = this.safeInteger(ticker, 'count'); not used
647
- return this.safeTicker({
648
- 'symbol': this.safeSymbol(undefined, market),
649
- 'timestamp': timestamp,
650
- 'datetime': this.iso8601(timestamp),
651
- 'high': high,
652
- 'low': low,
653
- 'bid': undefined,
654
- 'bidVolume': undefined,
655
- 'ask': undefined,
656
- 'askVolume': undefined,
657
- 'vwap': vwap,
658
- 'open': open,
659
- 'close': close,
660
- 'last': close,
661
- 'previousClose': undefined,
662
- 'change': undefined,
663
- 'percentage': undefined,
664
- 'average': avg,
665
- 'baseVolume': baseVolume,
666
- 'quoteVolume': quoteVolume,
667
- 'info': ticker,
668
- }, market);
669
- }
670
- /**
671
- * @method
672
- * @name ellipx#fetchOrderBook
673
- * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
674
- * @see https://docs.google.com/document/d/1ZXzTQYffKE_EglTaKptxGQERRnunuLHEMmar7VC9syM/edit?tab=t.0#heading=h.bqmucewhkpdz
675
- * @param {string} symbol unified symbol of the market to fetch the order book for
676
- * @param {int} [limit] the maximum amount of order book entries to return the exchange not supported yet.
677
- * @param {object} [params] extra parameters specific to the exchange API endpoint
678
- * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
679
- */
680
- async fetchOrderBook(symbol, limit = undefined, params = {}) {
681
- await this.loadMarkets();
682
- const market = this.market(symbol);
683
- const marketId = market['id'];
684
- const request = {
685
- 'currencyPair': marketId,
686
- };
687
- const response = await this.publicGetMarketCurrencyPairGetDepth(this.extend(request, params));
688
- // {
689
- // "data": {
690
- // "asks": [
691
- // {
692
- // "price": {
693
- // "v": "74941875231",
694
- // "e": 6,
695
- // "f": 74941.875231
696
- // },
697
- // "amount": {
698
- // "v": "149",
699
- // "e": 8,
700
- // "f": 0.00000149
701
- // }
702
- // },
703
- // {
704
- // "price": {
705
- // "v": "75063426037",
706
- // "e": 6,
707
- // "f": 75063.426037
708
- // },
709
- // "amount": {
710
- // "v": "335",
711
- // "e": 8,
712
- // "f": 0.00000335
713
- // }
714
- // }
715
- // ],
716
- // "bids": [
717
- // {
718
- // "price": {
719
- // "v": "64518711040",
720
- // "e": 6,
721
- // "f": 64518.71104
722
- // },
723
- // "amount": {
724
- // "v": "132",
725
- // "e": 8,
726
- // "f": 0.00000132
727
- // }
728
- // },
729
- // {
730
- // "price": {
731
- // "v": "64263569273",
732
- // "e": 6,
733
- // "f": 64263.569273
734
- // },
735
- // "amount": {
736
- // "v": "210",
737
- // "e": 8,
738
- // "f": 0.0000021
739
- // }
740
- // }
741
- // ],
742
- // "market": "BTC_USDC"
743
- // },
744
- // "request_id": "71b7dffc-3120-4e46-a0bb-49ece5aea7e1",
745
- // "result": "success",
746
- // "time": 0.000074661
747
- // }
748
- const data = this.safeValue(response, 'data', {}); // exchange specific v e f params
749
- const timestamp = this.milliseconds(); // the exchange does not provide timestamp for this.
750
- const dataBidsLength = data['bids'].length;
751
- const dataAsksLength = data['asks'].length;
752
- for (let i = 0; i < dataBidsLength; i++) {
753
- data['bids'][i]['price'] = this.parseAmount(data['bids'][i]['price']);
754
- data['bids'][i]['amount'] = this.parseAmount(data['bids'][i]['amount']);
755
- }
756
- for (let i = 0; i < dataAsksLength; i++) {
757
- data['asks'][i]['price'] = this.parseAmount(data['asks'][i]['price']);
758
- data['asks'][i]['amount'] = this.parseAmount(data['asks'][i]['amount']);
759
- }
760
- return this.parseOrderBook(data, symbol, timestamp, 'bids', 'asks', 'price', 'amount');
761
- }
762
- /**
763
- * @method
764
- * @name ellipx#fetchOHLCV
765
- * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market, default will return the last 24h period.
766
- * @see https://docs.google.com/document/d/1ZXzTQYffKE_EglTaKptxGQERRnunuLHEMmar7VC9syM/edit?tab=t.0#heading=h.w65baeuhxwt8
767
- * @param {string} symbol unified symbol of the market to fetch OHLCV data for
768
- * @param {string} timeframe the length of time each candle represents
769
- * @param {int} [since] timestamp in ms of the earliest candle to fetch
770
- * @param {int} [limit] the maximum amount of candles to fetch
771
- * @param {object} [params] extra parameters specific to the API endpoint
772
- * @param {int} [params.until] timestamp in ms of the earliest candle to fetch
773
- * @returns {OHLCV[]} A list of candles ordered as timestamp, open, high, low, close, volume
774
- */
775
- async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
776
- await this.loadMarkets();
777
- const methodName = 'fetchOHLCV';
778
- let paginate = false;
779
- [paginate, params] = this.handleOptionAndParams(params, methodName, 'paginate');
780
- if (paginate) {
781
- return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 1000);
782
- }
783
- const market = this.market(symbol);
784
- const marketId = market['id'];
785
- const time_frame = this.safeString(this.timeframes, timeframe, undefined);
786
- const request = {
787
- 'currencyPair': marketId,
788
- 'interval': time_frame,
789
- };
790
- if (since !== undefined) {
791
- request['start'] = Math.floor(since / 1000);
792
- }
793
- let until = undefined;
794
- [until, params] = this.handleOptionAndParams(params, methodName, 'until');
795
- if (until !== undefined) {
796
- request['end'] = until;
797
- }
798
- // {
799
- // "data": {
800
- // "market": "BTC_USDC",
801
- // "real_end": 1730970780,
802
- // "requested_end": 1730970784,
803
- // "start": 1730884200,
804
- // "stats": [
805
- // {
806
- // "time": 1730884200,
807
- // "count": 48,
808
- // "high": {"v": "73898950000", "e": 6, "f": 73898.95},
809
- // "low": {"v": "73642930000", "e": 6, "f": 73642.93},
810
- // "open": {"v": "73830990000", "e": 6, "f": 73830.99},
811
- // "close": {"v": "73682510000", "e": 6, "f": 73682.51},
812
- // "vol": {"v": "88159", "e": 8, "f": 0.00088159}
813
- // }
814
- // ]
815
- // }
816
- // }
817
- // No limit parameter supported by the API
818
- const response = await this.publicGetMarketCurrencyPairGetGraph(this.extend(request, params));
819
- const data = this.safeDict(response, 'data', {});
820
- const ohlcv = this.safeList(data, 'stats', []);
821
- return this.parseOHLCVs(ohlcv, market, timeframe, since, limit);
822
- }
823
- parseOHLCV(ohlcv, market = undefined) {
824
- return [
825
- this.safeInteger(ohlcv, 'time') * 1000,
826
- this.parseNumber(this.parseAmount(this.safeDict(ohlcv, 'open'))),
827
- this.parseNumber(this.parseAmount(this.safeDict(ohlcv, 'high'))),
828
- this.parseNumber(this.parseAmount(this.safeDict(ohlcv, 'low'))),
829
- this.parseNumber(this.parseAmount(this.safeDict(ohlcv, 'close'))),
830
- this.parseNumber(this.parseAmount(this.safeDict(ohlcv, 'vol'))), // volume
831
- ];
832
- }
833
- /**
834
- * @method
835
- * @name ellipx#fetchCurrencies
836
- * @description fetches information on all currencies from the exchange, including deposit/withdrawal details and available chains
837
- * @see https://docs.google.com/document/d/1ZXzTQYffKE_EglTaKptxGQERRnunuLHEMmar7VC9syM/edit?tab=t.0#heading=h.x65f9s9j74jf
838
- * @param {object} [params] extra parameters specific to the ellipx API endpoint
839
- * @param {string} [params.Can_Deposit] filter currencies by deposit availability, Y for available
840
- * @param {number} [params.results_per_page] number of results per page, default 100
841
- * @param {string} [params._expand] additional fields to expand in response, default '/Crypto_Token,/Crypto_Chain'
842
- * @returns {Promise<Currencies>} An object of currency structures indexed by currency codes
843
- */
844
- async fetchCurrencies(params = {}) {
845
- const response = await this._restGetCryptoTokenInfo(this.extend({
846
- 'Can_Deposit': 'Y',
847
- 'results_per_page': 100,
848
- '_expand': '/Crypto_Token,/Crypto_Chain',
849
- }, params));
850
- const result = {};
851
- const data = this.safeList(response, 'data', []);
852
- for (let i = 0; i < data.length; i++) {
853
- const networkEntry = data[i];
854
- //
855
- // {
856
- // "Crypto_Token_Info__": "crtev-5nsn35-f4ir-g5hp-iaft-i4ztx6zu",
857
- // "Crypto_Token__": "crtok-c5v3mh-grfn-hl5d-lmel-fvggbf4i",
858
- // "Crypto_Chain__": "chain-xjbini-7wlz-dmzf-gm7z-zf7ei6fq",
859
- // "Type": "native",
860
- // "Symbol": null,
861
- // "Name": null,
862
- // "Contract_Address": null,
863
- // "Minimum_Deposit": {
864
- // "v": "6",
865
- // "e": "6",
866
- // "f": "6.0e-6"
867
- // },
868
- // "Minimum_Withdraw": {
869
- // "v": "15",
870
- // "e": "5",
871
- // "f": "0.00015"
872
- // },
873
- // "Withdraw_Fee": {
874
- // "v": "1",
875
- // "e": "4",
876
- // "f": "0.0001"
877
- // },
878
- // "Minimum_Collect": null,
879
- // "Status": "valid",
880
- // "Can_Deposit": "Y",
881
- // "Decimals": null,
882
- // "Priority": "100",
883
- // "Created": {
884
- // "unix": "1727552199",
885
- // "us": "0",
886
- // "iso": "2024-09-28 19:36:39.000000",
887
- // "tz": "UTC",
888
- // "full": "1727552199000000",
889
- // "unixms": "1727552199000"
890
- // },
891
- // "Crypto_Token": {
892
- // "Crypto_Token__": "crtok-c5v3mh-grfn-hl5d-lmel-fvggbf4i",
893
- // "Name": "Bitcoin",
894
- // "Symbol": "BTC",
895
- // "Decimals": "8",
896
- // "CMC_Id": "1",
897
- // "Priority": "100",
898
- // "Can_Deposit": "Y",
899
- // "Category": "token",
900
- // "Testnet": "N",
901
- // "Created": {
902
- // "unix": "1727552113",
903
- // "us": "0",
904
- // "iso": "2024-09-28 19:35:13.000000",
905
- // "tz": "UTC",
906
- // "full": "1727552113000000",
907
- // "unixms": "1727552113000"
908
- // },
909
- // "Logo": [
910
- // {
911
- // "Crypto_Token_Logo__": "ctklg-aoozyr-rzm5-fphf-dhm7-5wbtetha",
912
- // "Crypto_Token__": "crtok-c5v3mh-grfn-hl5d-lmel-fvggbf4i",
913
- // "Blob__": "blob-d6hvgx-37s5-dh5h-ogj5-qxqvnaoy",
914
- // "Default": "Y",
915
- // "Format": "png",
916
- // "Priority": "0",
917
- // "Created": {
918
- // "unix": "1730196627",
919
- // "us": "929660",
920
- // "iso": "2024-10-29 10:10:27.929660",
921
- // "tz": "UTC",
922
- // "full": "1730196627929660",
923
- // "unixms": "1730196627929"
924
- // },
925
- // "Source": {
926
- // "Media_Image__": "blob-d6hvgx-37s5-dh5h-ogj5-qxqvnaoy",
927
- // "Url": "https://static.atonline.net/image/m_X7_tnmIYFCwn6EUVQuMKqrCuPB3CMl4ONTegeYpC0wIg68YZM0CuBpbjspnYwz/1a942eab068a2173e66d08c736283cfe22e1c1ed"
928
- // }
929
- // }
930
- // ]
931
- // },
932
- // "Crypto_Chain": {
933
- // "Crypto_Chain__": "chain-xjbini-7wlz-dmzf-gm7z-zf7ei6fq",
934
- // "EVM_Chain__": null,
935
- // "Crypto_Token__": "crtok-c5v3mh-grfn-hl5d-lmel-fvggbf4i",
936
- // "Name": "Bitcoin",
937
- // "Key": "bitcoin",
938
- // "Type": "Bitcoin",
939
- // "Curve": "secp256k1",
940
- // "Backend_Url": null,
941
- // "Wallet_Verification_Methods": {
942
- // "signature": true
943
- // },
944
- // "Block_Margin": "3",
945
- // "Created": {
946
- // "unix": "1725340084",
947
- // "us": "0",
948
- // "iso": "2024-09-03 05:08:04.000000",
949
- // "tz": "UTC",
950
- // "full": "1725340084000000",
951
- // "unixms": "1725340084000"
952
- // }
953
- // }
954
- // }
955
- //
956
- const id = this.safeString(networkEntry, 'Crypto_Token__');
957
- const token = this.safeDict(networkEntry, 'Crypto_Token', {});
958
- const code = this.safeCurrencyCode(this.safeString(token, 'Symbol'));
959
- if (!(code in result)) {
960
- result[code] = {
961
- 'id': id,
962
- 'code': code,
963
- 'info': [],
964
- 'type': undefined,
965
- 'name': this.safeString(token, 'Name'),
966
- 'active': undefined,
967
- 'deposit': undefined,
968
- 'withdraw': undefined,
969
- 'fee': undefined,
970
- 'precision': undefined,
971
- 'limits': {
972
- 'amount': {
973
- 'min': undefined,
974
- 'max': undefined,
975
- },
976
- 'withdraw': {
977
- 'min': undefined,
978
- 'max': undefined,
979
- },
980
- 'deposit': {
981
- 'min': undefined,
982
- 'max': undefined,
983
- },
984
- },
985
- 'networks': {},
986
- };
987
- }
988
- const networkId = this.safeString(networkEntry, 'Crypto_Chain__');
989
- const cryptoChainDict = this.safeString(networkEntry, 'Crypto_Chain');
990
- const networkName = this.safeString(cryptoChainDict, 'Type', 'default');
991
- const networkCode = this.networkIdToCode(networkName);
992
- result[code]['networks'][networkCode] = {
993
- 'id': networkId,
994
- 'network': networkCode,
995
- 'active': this.safeString(networkEntry, 'Status') === 'valid',
996
- 'deposit': this.safeString(networkEntry, 'Can_Deposit') === 'Y',
997
- 'withdraw': undefined,
998
- 'fee': this.parseNumber(this.parseAmount(networkEntry['Withdraw_Fee'])),
999
- 'precision': this.parseNumber(this.parsePrecision(this.safeString(token, 'Decimals'))),
1000
- 'limits': {
1001
- 'amount': {
1002
- 'min': undefined,
1003
- 'max': undefined,
1004
- },
1005
- 'withdraw': {
1006
- 'min': this.parseAmount(networkEntry['Minimum_Withdraw']),
1007
- 'max': undefined,
1008
- },
1009
- 'deposit': {
1010
- 'min': this.parseAmount(networkEntry['Minimum_Deposit']),
1011
- 'max': undefined,
1012
- },
1013
- },
1014
- };
1015
- const infos = this.safeList(result[code], 'info', []);
1016
- infos.push(networkEntry);
1017
- result[code]['info'] = infos;
1018
- }
1019
- // only after all entries are formed in currencies, restructure each entry
1020
- const allKeys = Object.keys(result);
1021
- for (let i = 0; i < allKeys.length; i++) {
1022
- const code = allKeys[i];
1023
- result[code] = this.safeCurrencyStructure(result[code]); // this is needed after adding network entry
1024
- }
1025
- return result;
1026
- }
1027
- /**
1028
- * @method
1029
- * @name ellipx#fetchTrades
1030
- * @description fetches all completed trades for a particular market/symbol
1031
- * @param {string} symbol unified market symbol (e.g. 'BTC/USDT')
1032
- * @param {int} [since] timestamp in ms of the earliest trade to fetch
1033
- * @param {int} [limit] the maximum amount of trades to fetch
1034
- * @param {object} [params] extra parameters specific to the EllipX API endpoint
1035
- * @param {string} [params.before] get trades before the given trade ID
1036
- * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
1037
- */
1038
- async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
1039
- await this.loadMarkets();
1040
- const market = this.market(symbol);
1041
- const marketId = market['id'];
1042
- const request = {
1043
- 'currencyPair': marketId,
1044
- };
1045
- // endpoint support before trade id.
1046
- // The actual endpoint URL will be: https://data.ellipx.com/Market/{currencyPair}:getTrades
1047
- // {
1048
- // "id": "BTC_USDC:1731053859:914141972:0",
1049
- // "pair": [
1050
- // "BTC",
1051
- // "USDC"
1052
- // ],
1053
- // "bid": {
1054
- // "id": "mktor-swishf-uv6n-hrzj-63ye-bdqnk33q",
1055
- // "iss": "ellipx:beta",
1056
- // "uniq": "order:1731053859:914141972:0"
1057
- // },
1058
- // "ask": {
1059
- // "id": "mktor-p3ozvt-qurz-gmzo-bf5n-g4rcuy6u",
1060
- // "iss": "ellipx:beta",
1061
- // "uniq": "order:1731053859:874659786:0"
1062
- // },
1063
- // "type": "bid",
1064
- // "amount": {
1065
- // "v": "412",
1066
- // "e": 8,
1067
- // "f": 0.00000412
1068
- // },
1069
- // "price": {
1070
- // "v": "75878090000",
1071
- // "e": 6,
1072
- // "f": 75878.09
1073
- // },
1074
- // "date": "2024-11-08T08:17:39.914141972Z"
1075
- // }
1076
- const response = await this.publicGetMarketCurrencyPairGetTrades(this.extend(request, params));
1077
- const data = this.safeDict(response, 'data', {});
1078
- const trades = this.safeList(data, 'trades', []);
1079
- return this.parseTrades(trades, market, since, limit);
1080
- }
1081
- parseTrade(trade, market = undefined) {
1082
- // Format of trade ID: "BTC_USDC:1731053859:914141972:0"
1083
- const id = this.safeString(trade, 'id');
1084
- // fetchTrades and fetchMyTrades return different trade structures
1085
- const date = this.safeDict(trade, 'date');
1086
- let timestamp = undefined;
1087
- if (date === undefined) {
1088
- timestamp = this.parse8601(this.safeString(trade, 'date'));
1089
- }
1090
- else {
1091
- timestamp = this.safeInteger(date, 'unixms');
1092
- }
1093
- const type = this.safeString(trade, 'type');
1094
- const side = (type === 'bid') ? 'buy' : 'sell';
1095
- const amount = this.safeDict(trade, 'amount');
1096
- const price = this.safeDict(trade, 'price');
1097
- const amountFloat = this.parseAmount(amount);
1098
- const priceFloat = this.parseAmount(price);
1099
- // fetchTrades and fetchMyTrades return different trade structures
1100
- const pair = this.safeList(trade, 'pair');
1101
- let marketSymbol = undefined;
1102
- if (pair === undefined) {
1103
- const symbol = this.safeString(trade, 'pair');
1104
- const [base, quote] = symbol.split('_');
1105
- marketSymbol = base + '/' + quote;
1106
- }
1107
- else {
1108
- marketSymbol = this.safeString(pair, 0) + '/' + this.safeString(pair, 1);
1109
- }
1110
- const bidOrder = this.safeDict(trade, 'bid');
1111
- const askOrder = this.safeDict(trade, 'ask');
1112
- const isBuy = (side === 'buy');
1113
- const orderId = isBuy ? this.safeString(bidOrder, 'id') : this.safeString(askOrder, 'id');
1114
- return this.safeTrade({
1115
- 'id': id,
1116
- 'info': trade,
1117
- 'timestamp': timestamp,
1118
- 'datetime': this.iso8601(timestamp),
1119
- 'symbol': marketSymbol,
1120
- 'type': undefined,
1121
- 'side': side,
1122
- 'order': orderId,
1123
- 'takerOrMaker': undefined,
1124
- 'price': priceFloat,
1125
- 'amount': amountFloat,
1126
- 'cost': undefined,
1127
- 'fee': undefined,
1128
- });
1129
- }
1130
- /**
1131
- * @method
1132
- * @name ellipx#fetchBalance
1133
- * @description query for balance and get the amount of funds available for trading or funds locked in orders
1134
- * @see https://docs.google.com/document/d/1ZXzTQYffKE_EglTaKptxGQERRnunuLHEMmar7VC9syM/edit?tab=t.0#heading=h.ihrjov144txg
1135
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1136
- * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
1137
- */
1138
- async fetchBalance(params = {}) {
1139
- await this.loadMarkets();
1140
- const response = await this.privateGetUserWallet(params);
1141
- // {
1142
- // "User_Wallet__": "usw-vv7hzo-qel5-gupk-neqi-7f3wz5pq",
1143
- // "User__": "usr-...",
1144
- // "Realm__": "usrr-cb3c7n-qvxv-fdrb-uc2q-gpja2foi",
1145
- // "Unit__": "unit-aebkye-u35b-e5zm-zt22-2qvwhsqa",
1146
- // "Balance": {
1147
- // "value": "0.00006394",
1148
- // "value_int": "6394",
1149
- // "value_disp": "0.00006394",
1150
- // "value_xint": {
1151
- // "v": "6394",
1152
- // "e": 8,
1153
- // "f": 0.00006394
1154
- // },
1155
- // "display": "0.00006394BTC",
1156
- // "display_short": "0.00006394BTC",
1157
- // "currency": "BTC",
1158
- // "unit": "BTC",
1159
- // "has_vat": false,
1160
- // "tax_profile": null
1161
- // },
1162
- // "Balance_Date": {
1163
- // "unix": 1731128270,
1164
- // "us": 426208,
1165
- // "iso": "2024-11-09 04:57:50.426208",
1166
- // "tz": "UTC",
1167
- // "full": "1731128270426208",
1168
- // "unixms": "1731128270426"
1169
- // },
1170
- // "Liabilities": {
1171
- // "value": "0.00000000",
1172
- // "value_int": "0",
1173
- // "value_disp": "0.00000000",
1174
- // "value_xint": {
1175
- // "v": "0",
1176
- // "e": 8,
1177
- // "f": 0
1178
- // },
1179
- // "display": "0.00000000BTC",
1180
- // "display_short": "0.00000000BTC",
1181
- // "currency": "BTC",
1182
- // "unit": "BTC",
1183
- // "has_vat": false,
1184
- // "tax_profile": null
1185
- // },
1186
- // "Index": "5",
1187
- // "Backend": "virtual",
1188
- // "Disable_Limits": "N",
1189
- // "Unencumbered_Balance": {
1190
- // "value": "0.00006394",
1191
- // "value_int": "6394",
1192
- // "value_disp": "0.00006394",
1193
- // "value_xint": {
1194
- // "v": "6394",
1195
- // "e": 8,
1196
- // "f": 0.00006394
1197
- // },
1198
- // "display": "0.00006394BTC",
1199
- // "display_short": "0.00006394BTC",
1200
- // "currency": "BTC",
1201
- // "unit": "BTC",
1202
- // "has_vat": false,
1203
- // "tax_profile": null
1204
- // }
1205
- // }
1206
- const result = {
1207
- 'info': response,
1208
- 'timestamp': undefined,
1209
- 'datetime': undefined,
1210
- };
1211
- const dataArray = this.safeList(response, 'data', []);
1212
- // Use first item's timestamp if available
1213
- const dataArrayLength = dataArray.length;
1214
- if (dataArrayLength > 0) {
1215
- const firstItem = dataArray[0];
1216
- const balanceDate = this.safeDict(firstItem, 'Balance_Date', {});
1217
- result['timestamp'] = this.safeInteger(balanceDate, 'unixms');
1218
- result['datetime'] = this.iso8601(result['timestamp']);
1219
- }
1220
- // Process each balance entry
1221
- for (let i = 0; i < dataArray.length; i++) {
1222
- const entry = dataArray[i];
1223
- const balance = this.safeDict(entry, 'Balance', {});
1224
- const code = this.safeString(balance, 'currency');
1225
- if (code !== undefined) {
1226
- const account = {
1227
- 'free': this.parseAmount(entry['Unencumbered_Balance']['value_xint']),
1228
- 'used': this.parseAmount(entry['Liabilities']['value_xint']),
1229
- 'total': this.parseAmount(balance['value_xint']),
1230
- };
1231
- result[code] = account;
1232
- }
1233
- }
1234
- return this.safeBalance(result);
1235
- }
1236
- /**
1237
- * @method
1238
- * @name ellipx#createOrder
1239
- * @description create a new order in a market
1240
- * @see https://docs.google.com/document/d/1ZXzTQYffKE_EglTaKptxGQERRnunuLHEMmar7VC9syM/edit?tab=t.0#heading=h.yzfak2n2bwpo
1241
- * @param {string} symbol unified market symbol (e.g. 'BTC/USDT')
1242
- * @param {string} type order type - the exchange automatically sets type to 'limit' if price defined, 'market' if undefined
1243
- * @param {string} side 'buy' or 'sell'
1244
- * @param {float} [amount] amount of base currency to trade (can be undefined if using Spend_Limit)
1245
- * @param {float} [price] price per unit of base currency for limit orders
1246
- * @param {object} [params] extra parameters specific to the EllipX API endpoint
1247
- * @param {float} [params.cost] maximum amount to spend in quote currency (required for market orders if amount undefined)
1248
- * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1249
- */
1250
- async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1251
- await this.loadMarkets();
1252
- const market = this.market(symbol);
1253
- // the exchange automatically sets the type to 'limit' if the price is defined and to 'market' if it is not
1254
- const marketId = market['id'];
1255
- let orderType = 'bid';
1256
- if (side === 'buy') {
1257
- orderType = 'bid';
1258
- }
1259
- else {
1260
- orderType = 'ask';
1261
- }
1262
- const request = {
1263
- 'currencyPair': marketId,
1264
- 'Type': orderType,
1265
- };
1266
- if (amount !== undefined) {
1267
- request['Amount'] = this.amountToPrecision(symbol, amount);
1268
- }
1269
- if (price !== undefined) {
1270
- request['Price'] = this.priceToPrecision(symbol, price);
1271
- }
1272
- const cost = this.safeString(params, 'cost');
1273
- if (cost !== undefined) {
1274
- params = this.omit(params, 'cost');
1275
- request['Spend_Limit'] = this.priceToPrecision(symbol, cost);
1276
- }
1277
- const response = await this.privatePostMarketCurrencyPairOrder(this.extend(request, params));
1278
- // {
1279
- // "result": "success",
1280
- // "data": {
1281
- // "Market_Order__": "mktor-x2grmu-zwo5-fyxc-4gue-vd4ouvsa",
1282
- // "Market__": "mkt-lrnp2e-eaor-eobj-ua73-75j6sjxe",
1283
- // "User__": "usr-...",
1284
- // "Uniq": "order:1728719021:583795548:0",
1285
- // "Type": "bid",
1286
- // "Status": "pending",
1287
- // "Flags": {},
1288
- // "Amount": {
1289
- // "v": "100000000",
1290
- // "e": 8,
1291
- // "f": 1
1292
- // },
1293
- // "Price": null,
1294
- // "Spend_Limit": {
1295
- // "v": "1000000",
1296
- // "e": 6,
1297
- // "f": 1
1298
- // },
1299
- // "Executed": {
1300
- // "v": "0",
1301
- // "e": 0,
1302
- // "f": 0
1303
- // },
1304
- // "Secured": {
1305
- // "v": "1000000",
1306
- // "e": 6,
1307
- // "f": 1
1308
- // },
1309
- // "Version": "0",
1310
- // "Created": {
1311
- // "unix": 1728719020,
1312
- // "us": 315195,
1313
- // "iso": "2024-10-12 07:43:40.315195",
1314
- // "tz": "UTC",
1315
- // "full": "1728719020315195",
1316
- // "unixms": "1728719020315"
1317
- // },
1318
- // "Updated": {
1319
- // "unix": 1728719020,
1320
- // "us": 315195,
1321
- // "iso": "2024-10-12 07:43:40.315195",
1322
- // "tz": "UTC",
1323
- // "full": "1728719020315195",
1324
- // "unixms": "1728719020315"
1325
- // }
1326
- // }
1327
- // }
1328
- const order = this.safeDict(response, 'data', {});
1329
- return this.parseOrder(order, market);
1330
- }
1331
- /**
1332
- * @method
1333
- * @name ellipx#fetchOrder
1334
- * @description fetches information on an order made by the user
1335
- * @param {string} id the order ID as returned by createOrder or fetchOrders
1336
- * @param {string|undefined} symbol not used by ellipx.fetchOrder
1337
- * @param {object} [params] extra parameters specific to the EllipX API endpoint
1338
- * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1339
- */
1340
- async fetchOrder(id, symbol = undefined, params = {}) {
1341
- await this.loadMarkets();
1342
- const request = {
1343
- 'orderUuid': id,
1344
- };
1345
- const response = await this.privateGetMarketOrderOrderUuid(this.extend(request, params));
1346
- const data = this.safeDict(response, 'data', {});
1347
- return this.parseOrder(data, undefined);
1348
- }
1349
- /**
1350
- * @method
1351
- * @name ellipx#fetchOrdersByStatus
1352
- * @description fetches a list of orders placed on the exchange
1353
- * @see https://docs.google.com/document/d/1ZXzTQYffKE_EglTaKptxGQERRnunuLHEMmar7VC9syM/edit?tab=t.0#heading=h.5z2nh2b5s81n
1354
- * @param {string} status 'open' or 'closed', omit for all orders
1355
- * @param {string} symbol unified market symbol
1356
- * @param {int} [since] timestamp in ms of the earliest order
1357
- * @param {int} [limit] the maximum amount of orders to fetch
1358
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1359
- * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1360
- */
1361
- async fetchOrdersByStatus(status, symbol = undefined, since = undefined, limit = undefined, params = {}) {
1362
- await this.loadMarkets();
1363
- let market = undefined;
1364
- const request = {};
1365
- if (symbol !== undefined) {
1366
- market = this.market(symbol);
1367
- const marketId = market['id'];
1368
- request['currencyPair'] = marketId;
1369
- }
1370
- if (status !== undefined) {
1371
- request['Status'] = status;
1372
- }
1373
- const response = await this.privateGetMarketCurrencyPairOrder(this.extend(request, params));
1374
- // {
1375
- // "result": "success",
1376
- // "data": [
1377
- // {
1378
- // "Market_Order__": "mktor-aglvd2-iy5v-enbj-nwrb-scqsnosa",
1379
- // "Market__": "mkt-lrnp2e-eaor-eobj-ua73-75j6sjxe",
1380
- // "User__": "usr-...",
1381
- // "Uniq": "order:1728712511:964332600:0",
1382
- // "Type": "ask",
1383
- // "Status": "open",
1384
- // "Flags": {},
1385
- // "Amount": {
1386
- // "v": "1",
1387
- // "e": 8,
1388
- // "f": 1.0e-8
1389
- // },
1390
- // "Price": {
1391
- // "v": "63041306872",
1392
- // "e": 6,
1393
- // "f": 63041.306872
1394
- // },
1395
- // "Spend_Limit": null,
1396
- // "Executed": {
1397
- // "v": "892",
1398
- // "e": 8,
1399
- // "f": 8.92e-6
1400
- // },
1401
- // "Secured": null,
1402
- // "Version": "3",
1403
- // "Created": {
1404
- // "unix": 1728712510,
1405
- // "us": 669096,
1406
- // "iso": "2024-10-12 05:55:10.669096",
1407
- // "tz": "UTC",
1408
- // "full": "1728712510669096",
1409
- // "unixms": "1728712510669"
1410
- // },
1411
- // "Updated": {
1412
- // "unix": 1728712510,
1413
- // "us": 669096,
1414
- // "iso": "2024-10-12 05:55:10.669096",
1415
- // "tz": "UTC",
1416
- // "full": "1728712510669096",
1417
- // "unixms": "1728712510669"
1418
- // }
1419
- // }
1420
- // ],
1421
- // "paging": {
1422
- // "page_no": 1,
1423
- // "count": "1",
1424
- // "page_max": 1,
1425
- // "results_per_page": 20
1426
- // }
1427
- // }
1428
- const data = this.safeValue(response, 'data', []);
1429
- return this.parseOrders(data, market, since, limit);
1430
- }
1431
- /**
1432
- * @method
1433
- * @name ellipx#fetchOrders
1434
- * @description fetches information on multiple orders made by the user
1435
- * @see https://docs.google.com/document/d/1ZXzTQYffKE_EglTaKptxGQERRnunuLHEMmar7VC9syM/edit?tab=t.0#heading=h.5z2nh2b5s81n
1436
- * @param {string} symbol unified market symbol of the market orders were made in
1437
- * @param {int|undefined} since timestamp in ms of the earliest order
1438
- * @param {int|undefined} limit the maximum amount of orders to fetch
1439
- * @param {object} params extra parameters specific to the exchange API endpoint
1440
- * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1441
- */
1442
- async fetchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1443
- if (symbol === undefined) {
1444
- throw new ArgumentsRequired(this.id + ' fetchOrders requires a symbol parameter');
1445
- }
1446
- return await this.fetchOrdersByStatus(undefined, symbol, since, limit, params);
1447
- }
1448
- /**
1449
- * @method
1450
- * @name ellipx#fetchOpenOrders
1451
- * @description fetches information on open orders made by the user
1452
- * @see https://docs.google.com/document/d/1ZXzTQYffKE_EglTaKptxGQERRnunuLHEMmar7VC9syM/edit?tab=t.0#heading=h.5z2nh2b5s81n
1453
- * @param {string} symbol unified market symbol of the market orders were made in
1454
- * @param {int|undefined} since timestamp in ms of the earliest order
1455
- * @param {int|undefined} limit the maximum amount of orders to fetch
1456
- * @param {object} params extra parameters specific to the exchange API endpoint
1457
- * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1458
- */
1459
- async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1460
- if (symbol === undefined) {
1461
- throw new ArgumentsRequired(this.id + ' fetchOpenOrders requires a symbol parameter');
1462
- }
1463
- return await this.fetchOrdersByStatus('open', symbol, since, limit, params);
1464
- }
1465
- parseOrder(order, market = undefined) {
1466
- const id = this.safeString(order, 'Market_Order__');
1467
- const timestamp = this.safeInteger(this.safeDict(order, 'Created'), 'unixms');
1468
- const orderType = this.safeString(order, 'Type');
1469
- let side = 'sell';
1470
- if (orderType === 'bid') {
1471
- side = 'buy';
1472
- }
1473
- const status = this.parseOrderStatus(this.safeString(order, 'Status'));
1474
- const amount = this.parseNumber(this.parseAmount(this.safeDict(order, 'Amount')));
1475
- const price = this.parseNumber(this.parseAmount(this.safeDict(order, 'Price')));
1476
- const type = (price === undefined) ? 'market' : 'limit';
1477
- const executed = this.parseNumber(this.parseAmount(this.safeDict(order, 'Executed')));
1478
- const filled = executed;
1479
- const remaining = this.parseNumber(this.parseAmount(this.safeDict(order, 'Secured')));
1480
- const cost = this.parseNumber(this.parseAmount(this.safeDict(order, 'Total_Spent')));
1481
- const symbol = market ? market['symbol'] : undefined;
1482
- const clientOrderId = undefined;
1483
- const timeInForce = 'GTC'; // default to Good Till Cancelled
1484
- const postOnly = false;
1485
- const updated = this.safeDict(order, 'Updated', {});
1486
- const lastTradeTimestamp = this.safeInteger(updated, 'unixms', undefined);
1487
- return this.safeOrder({
1488
- 'id': id,
1489
- 'clientOrderId': clientOrderId,
1490
- 'info': order,
1491
- 'timestamp': timestamp,
1492
- 'datetime': this.iso8601(timestamp),
1493
- 'lastTradeTimestamp': lastTradeTimestamp,
1494
- 'status': this.parseOrderStatus(status),
1495
- 'symbol': symbol,
1496
- 'type': type,
1497
- 'timeInForce': timeInForce,
1498
- 'postOnly': postOnly,
1499
- 'side': side,
1500
- 'price': price,
1501
- 'triggerPrice': undefined,
1502
- 'average': undefined,
1503
- 'cost': cost,
1504
- 'amount': amount,
1505
- 'filled': filled,
1506
- 'remaining': remaining,
1507
- 'fee': undefined,
1508
- 'trades': undefined,
1509
- }, market);
1510
- }
1511
- /**
1512
- * @method
1513
- * @name ellipx#cancelOrder
1514
- * @description Cancels an open order on the exchange
1515
- * @see https://docs.google.com/document/d/1ZXzTQYffKE_EglTaKptxGQERRnunuLHEMmar7VC9syM/edit?tab=t.0#heading=h.f1qu1pb1rebn
1516
- * @param {string} id - The order ID to cancel (format: mktor-xxxxx-xxxx-xxxx-xxxx-xxxxxxxx)
1517
- * @param {string} [symbol] - ellipx.cancelOrder does not use the symbol parameter
1518
- * @param {object} [params] - Extra parameters specific to the exchange API
1519
- * @returns {Promise<object>} A Promise that resolves to the canceled order info
1520
- */
1521
- async cancelOrder(id, symbol = undefined, params = {}) {
1522
- await this.loadMarkets();
1523
- const request = {
1524
- 'orderUuid': id,
1525
- };
1526
- const response = await this.privateDeleteMarketOrderOrderUuid(this.extend(request, params));
1527
- // {
1528
- // result: "success",
1529
- // request_id: "887dba33-d11b-43f0-8034-dd7890882cc5",
1530
- // time: "0.8975801467895508",
1531
- // data: true,
1532
- // access: {
1533
- // "mktor-rf5k5b-5fhf-dmde-wxqj-3y23jeii": {
1534
- // required: "A",
1535
- // available: "O",
1536
- // },
1537
- // },
1538
- // }
1539
- // this endpoint always returns true and a warning message if the order cancelled before.
1540
- const warningResponse = this.safeValue(response, 'warning', undefined);
1541
- const statusResponse = this.safeBool(response, 'data');
1542
- let status = 'canceled';
1543
- if (statusResponse !== true || warningResponse !== undefined) {
1544
- status = 'closed';
1545
- }
1546
- return this.safeOrder({
1547
- 'id': id,
1548
- 'clientOrderId': undefined,
1549
- 'info': this.json(response),
1550
- 'timestamp': undefined,
1551
- 'datetime': undefined,
1552
- 'lastTradeTimestamp': undefined,
1553
- 'status': status,
1554
- 'symbol': undefined,
1555
- 'type': undefined,
1556
- 'timeInForce': undefined,
1557
- 'postOnly': undefined,
1558
- 'side': undefined,
1559
- 'price': undefined,
1560
- 'triggerPrice': undefined,
1561
- 'average': undefined,
1562
- 'cost': undefined,
1563
- 'amount': undefined,
1564
- 'filled': undefined,
1565
- 'remaining': undefined,
1566
- 'fee': undefined,
1567
- 'trades': undefined,
1568
- }, undefined);
1569
- }
1570
- /**
1571
- * @method
1572
- * @name ellipx#fetchOrderTrades
1573
- * @description fetch all the trades made from a single order
1574
- * @param {string} id order id
1575
- * @param {string} symbol unified market symbol
1576
- * @param {int} [since] the earliest time in ms to fetch trades for
1577
- * @param {int} [limit] the maximum number of trades to retrieve
1578
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1579
- * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
1580
- */
1581
- async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
1582
- if (symbol === undefined) {
1583
- throw new ArgumentsRequired('fetchMyTrades requires a symbol parameter');
1584
- }
1585
- await this.loadMarkets();
1586
- const market = this.market(symbol);
1587
- const currencyPair = market['id'];
1588
- const request = {
1589
- 'Market_Order__': id,
1590
- 'currencyPair': currencyPair,
1591
- };
1592
- const response = await this.privateGetMarketCurrencyPairTrade(this.extend(request, params));
1593
- // {
1594
- // "result": "success",
1595
- // "request_id": "fc5be99d-d085-46f8-9228-e46d0996f112",
1596
- // "time": 0.030913114547729492,
1597
- // "data": [
1598
- // {
1599
- // "id": "DOGE_USDC:1731505789:911642994:0",
1600
- // "pair": "DOGE_USDC",
1601
- // "bid": {
1602
- // "id": "mktor-xb3ne5-emm5-fx7e-xggk-fyfoiye4"
1603
- // },
1604
- // "ask": {
1605
- // "id": "mktor-oxmac4-mtkf-gi3o-mamg-u2cboqe4"
1606
- // },
1607
- // "type": "bid",
1608
- // "amount": {
1609
- // "v": "334609419",
1610
- // "e": 8,
1611
- // "f": 3.34609419
1612
- // },
1613
- // "price": {
1614
- // "v": "410673",
1615
- // "e": 6,
1616
- // "f": 0.410673
1617
- // },
1618
- // "date": {
1619
- // "unix": 1731505789,
1620
- // "us": 911642,
1621
- // "iso": "2024-11-13 13:49:49.911642",
1622
- // "tz": "UTC",
1623
- // "full": "1731505789911642",
1624
- // "unixms": "1731505789911"
1625
- // }
1626
- // },
1627
- // {
1628
- // "id": "DOGE_USDC:1731505789:911642994:4",
1629
- // "pair": "DOGE_USDC",
1630
- // "bid": {
1631
- // "id": "mktor-xb3ne5-emm5-fx7e-xggk-fyfoiye4"
1632
- // },
1633
- // "ask": {
1634
- // "id": "mktor-cmtztk-3z3n-gupp-uqdg-74g4wjfq"
1635
- // },
1636
- // "type": "bid",
1637
- // "amount": {
1638
- // "v": "145453950",
1639
- // "e": 8,
1640
- // "f": 1.4545395
1641
- // },
1642
- // "price": {
1643
- // "v": "412589",
1644
- // "e": 6,
1645
- // "f": 0.412589
1646
- // },
1647
- // "date": {
1648
- // "unix": 1731505789,
1649
- // "us": 911642,
1650
- // "iso": "2024-11-13 13:49:49.911642",
1651
- // "tz": "UTC",
1652
- // "full": "1731505789911642",
1653
- // "unixms": "1731505789911"
1654
- // }
1655
- // },
1656
- // {
1657
- // "id": "DOGE_USDC:1731505789:911642994:2",
1658
- // "pair": "DOGE_USDC",
1659
- // "bid": {
1660
- // "id": "mktor-xb3ne5-emm5-fx7e-xggk-fyfoiye4"
1661
- // },
1662
- // "ask": {
1663
- // "id": "mktor-6tyslh-b33b-flnm-2ata-acjkco4y"
1664
- // },
1665
- // "type": "bid",
1666
- // "amount": {
1667
- // "v": "587627076",
1668
- // "e": 8,
1669
- // "f": 5.87627076
1670
- // },
1671
- // "price": {
1672
- // "v": "411005",
1673
- // "e": 6,
1674
- // "f": 0.411005
1675
- // },
1676
- // "date": {
1677
- // "unix": 1731505789,
1678
- // "us": 911642,
1679
- // "iso": "2024-11-13 13:49:49.911642",
1680
- // "tz": "UTC",
1681
- // "full": "1731505789911642",
1682
- // "unixms": "1731505789911"
1683
- // }
1684
- // },
1685
- // {
1686
- // "id": "DOGE_USDC:1731505789:911642994:1",
1687
- // "pair": "DOGE_USDC",
1688
- // "bid": {
1689
- // "id": "mktor-xb3ne5-emm5-fx7e-xggk-fyfoiye4"
1690
- // },
1691
- // "ask": {
1692
- // "id": "mktor-ihpjlj-5ufj-dm5l-fmud-oftkqcgu"
1693
- // },
1694
- // "type": "bid",
1695
- // "amount": {
1696
- // "v": "475845734",
1697
- // "e": 8,
1698
- // "f": 4.75845734
1699
- // },
1700
- // "price": {
1701
- // "v": "410830",
1702
- // "e": 6,
1703
- // "f": 0.41083
1704
- // },
1705
- // "date": {
1706
- // "unix": 1731505789,
1707
- // "us": 911642,
1708
- // "iso": "2024-11-13 13:49:49.911642",
1709
- // "tz": "UTC",
1710
- // "full": "1731505789911642",
1711
- // "unixms": "1731505789911"
1712
- // }
1713
- // },
1714
- // {
1715
- // "id": "DOGE_USDC:1731505789:911642994:3",
1716
- // "pair": "DOGE_USDC",
1717
- // "bid": {
1718
- // "id": "mktor-xb3ne5-emm5-fx7e-xggk-fyfoiye4"
1719
- // },
1720
- // "ask": {
1721
- // "id": "mktor-d2uyb3-nzsj-aevn-dikr-tq3sxhre"
1722
- // },
1723
- // "type": "bid",
1724
- // "amount": {
1725
- // "v": "641013461",
1726
- // "e": 8,
1727
- // "f": 6.41013461
1728
- // },
1729
- // "price": {
1730
- // "v": "411846",
1731
- // "e": 6,
1732
- // "f": 0.411846
1733
- // },
1734
- // "date": {
1735
- // "unix": 1731505789,
1736
- // "us": 911642,
1737
- // "iso": "2024-11-13 13:49:49.911642",
1738
- // "tz": "UTC",
1739
- // "full": "1731505789911642",
1740
- // "unixms": "1731505789911"
1741
- // }
1742
- // }
1743
- // ],
1744
- // "access": {
1745
- // "mkt-xrkg5l-akjz-cxxl-3a2e-mul5gfo4": {
1746
- // "required": "r",
1747
- // "available": "?"
1748
- // },
1749
- // "mktor-xb3ne5-emm5-fx7e-xggk-fyfoiye4": {
1750
- // "required": "R",
1751
- // "available": "O"
1752
- // }
1753
- // },
1754
- // "paging": {
1755
- // "page_no": 1,
1756
- // "count": "5",
1757
- // "page_max": 1,
1758
- // "results_per_page": 20
1759
- // }
1760
- // }
1761
- const data = this.safeList(response, 'data');
1762
- return this.parseTrades(data, market, since, limit);
1763
- }
1764
- /**
1765
- * @method
1766
- * @name ellipx#fetchDepositAddress
1767
- * @description fetches a crypto deposit address for a specific currency
1768
- * @see https://docs.google.com/document/d/1ZXzTQYffKE_EglTaKptxGQERRnunuLHEMmar7VC9syM/edit?tab=t.0#heading=h.k7qe5aricayh
1769
- * @param {string} code unified currency code (e.g. "BTC", "ETH", "USDT")
1770
- * @param {object} [params] extra parameters specific to the EllipX API endpoint
1771
- * @returns {object} an address structure {
1772
- * 'currency': string, // unified currency code
1773
- * 'address': string, // the address for deposits
1774
- * 'tag': string|undefined, // tag/memo for deposits if needed
1775
- * 'network': object, // network object from currency info
1776
- * 'info': object // raw response from exchange
1777
- * }
1778
- * @throws {ExchangeError} if currency does not support deposits
1779
- */
1780
- async fetchDepositAddress(code, params = {}) {
1781
- await this.loadMarkets();
1782
- const currency = this.currency(code);
1783
- const network = this.safeValue(currency['info'], 'Crypto_Chain', undefined);
1784
- const request = {
1785
- 'Crypto_Token__': this.safeString(network, 'Crypto_Token__'),
1786
- 'Crypto_Chain__': this.safeString(network, 'Crypto_Chain__'),
1787
- };
1788
- const response = await this.privatePostCryptoAddressFetch(this.extend(request, params));
1789
- const data = this.safeValue(response, 'data', {});
1790
- const address = this.safeString(data, 'Address');
1791
- const tag = this.safeString(data, 'memo');
1792
- this.checkAddress(address);
1793
- return {
1794
- 'currency': code,
1795
- 'address': address,
1796
- 'tag': tag,
1797
- 'network': network,
1798
- 'info': response,
1799
- };
1800
- }
1801
- /**
1802
- * @method
1803
- * @name ellipx#fetchTradingFee
1804
- * @description Fetches the current trading fees (maker and taker) applicable to the user.
1805
- * @see https://docs.google.com/document/d/1ZXzTQYffKE_EglTaKptxGQERRnunuLHEMmar7VC9syM/edit?tab=t.0#heading=h.kki5jay2c8it
1806
- * @param {string} [symbol] Not used by EllipX as fees are not symbol-specific.
1807
- * @param {object} [params] Extra parameters specific to the EllipX API endpoint.
1808
- * @returns {Promise<object>} A promise resolving to a unified trading fee structure:
1809
- * {
1810
- * 'info': object, // the raw response from the exchange
1811
- * 'symbol': undefined, // symbol is not used for this exchange
1812
- * 'maker': number, // maker fee rate in decimal form
1813
- * 'taker': number, // taker fee rate in decimal form
1814
- * 'percentage': true, // indicates fees are in percentage
1815
- * 'tierBased': false, // indicates fees do not vary by volume tiers
1816
- * }
1817
- */
1818
- async fetchTradingFee(symbol, params = {}) {
1819
- await this.loadMarkets();
1820
- const response = await this.privateGetMarketTradeFeeQuery(params);
1821
- //
1822
- // Example response:
1823
- // {
1824
- // "result": "success",
1825
- // "data": {
1826
- // "maker": 15.0, // in basis points
1827
- // "taker": 25.0, // in basis points
1828
- // "volume": 123456.78,
1829
- // "promo": {
1830
- // // promotional discounts if any
1831
- // }
1832
- // }
1833
- // }
1834
- //
1835
- const data = this.safeValue(response, 'data', {});
1836
- const maker = this.safeNumber(data, 'maker'); // in basis points
1837
- const taker = this.safeNumber(data, 'taker'); // in basis points
1838
- const makerFee = (maker !== undefined) ? maker / 10000 : undefined;
1839
- const takerFee = (taker !== undefined) ? taker / 10000 : undefined;
1840
- return {
1841
- 'info': response,
1842
- 'symbol': undefined,
1843
- 'maker': makerFee,
1844
- 'taker': takerFee,
1845
- 'percentage': true,
1846
- 'tierBased': true, // fees can vary based on volume tiers
1847
- };
1848
- }
1849
- /**
1850
- * @method
1851
- * @name ellipx#withdraw
1852
- * @description Make a withdrawal request
1853
- * @see https://docs.google.com/document/d/1ZXzTQYffKE_EglTaKptxGQERRnunuLHEMmar7VC9syM/edit?tab=t.0#heading=h.zegupoa8g4t9
1854
- * @param {string} code unified currency code
1855
- * @param {number} amount Amount to withdraw
1856
- * @param {string} address Destination wallet address
1857
- * @param {string} [tag] Additional tag/memo for currencies that require it
1858
- * @param {object} params Extra parameters specific to the EllipX API endpoint (Crypto_Chain__, Unit__)
1859
- * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
1860
- */
1861
- async withdraw(code, amount, address, tag = undefined, params = {}) {
1862
- this.checkAddress(address);
1863
- await this.loadMarkets();
1864
- const currency = this.currency(code);
1865
- const networks = this.safeValue(currency, 'networks');
1866
- if (networks === undefined) {
1867
- throw new NotSupported(this.id + ' withdraw() for ' + code + ' is not supported');
1868
- }
1869
- const chainsResponse = await this.privateGetUnitCurrency({ 'currency': currency['code'] }); // fetch Unit__ params for currency
1870
- const chainsData = this.safeValue(chainsResponse, 'data', []);
1871
- const unit = this.safeString(chainsData, 'Unit__');
1872
- // check params again and omit params
1873
- this.omit(params, 'Unit__');
1874
- this.omit(params, 'Crypto_Chain__');
1875
- const amountString = amount.toString();
1876
- const request = {
1877
- 'Unit__': unit,
1878
- 'amount': amountString,
1879
- 'address': address,
1880
- 'Crypto_Chain__': networks['id'],
1881
- };
1882
- if (tag !== undefined) {
1883
- request['memo'] = tag;
1884
- }
1885
- const response = await this.privatePostCryptoDisbursementWithdraw(this.extend(request, params));
1886
- // {
1887
- // Crypto_Disbursement__: "crdsb-4pw3kg-ipn5-amvb-da4n-6xncy4r4",
1888
- // Crypto_Token__: "crtok-dnehz4-wbgv-bunf-iyd3-m7gtsz2q",
1889
- // Crypto_Chain__: "chain-kjfvwn-l2xn-eclc-ul5d-mb6fu5hm",
1890
- // User__: "usr-5oint6-ozpr-alfp-2wxi-zgbm4osy",
1891
- // Value: {
1892
- // v: "1000000000",
1893
- // e: "8",
1894
- // f: "10",
1895
- // },
1896
- // Value_USD: "4.08723",
1897
- // Address: "D6z62LUwyNBi3QbPkzW8C4m7VDAgu9wb2Z",
1898
- // Status: "pending",
1899
- // Transaction: null,
1900
- // Requested: {
1901
- // unix: "1731570982",
1902
- // us: "203569",
1903
- // iso: "2024-11-14 07:56:22.203569",
1904
- // tz: "UTC",
1905
- // full: "1731570982203569",
1906
- // unixms: "1731570982203",
1907
- // },
1908
- // Scheduled: null,
1909
- // Processed: null,
1910
- // Amount: {
1911
- // value: "10.00000000",
1912
- // value_int: "1000000000",
1913
- // value_disp: "10.00000000",
1914
- // value_xint: {
1915
- // v: "1000000000",
1916
- // e: "8",
1917
- // f: "10",
1918
- // },
1919
- // display: "10.00000000DOGE",
1920
- // display_short: "10.00000000DOGE",
1921
- // currency: "DOGE",
1922
- // unit: "DOGE",
1923
- // has_vat: false,
1924
- // tax_profile: null,
1925
- // raw: {
1926
- // value: "10.00000000",
1927
- // value_int: "1000000000",
1928
- // value_disp: "10.00000000",
1929
- // value_xint: {
1930
- // v: "1000000000",
1931
- // e: "8",
1932
- // f: "10",
1933
- // },
1934
- // display: "10.00000000DOGE",
1935
- // display_short: "10.00000000DOGE",
1936
- // currency: "DOGE",
1937
- // unit: "DOGE",
1938
- // has_vat: false,
1939
- // tax_profile: null,
1940
- // },
1941
- // tax: {
1942
- // value: "10.00000000",
1943
- // value_int: "1000000000",
1944
- // value_disp: "10.00000000",
1945
- // value_xint: {
1946
- // v: "1000000000",
1947
- // e: "8",
1948
- // f: "10",
1949
- // },
1950
- // display: "10.00000000DOGE",
1951
- // display_short: "10.00000000DOGE",
1952
- // currency: "DOGE",
1953
- // unit: "DOGE",
1954
- // has_vat: true,
1955
- // tax_profile: null,
1956
- // },
1957
- // tax_only: {
1958
- // value: "0.000",
1959
- // value_int: "0",
1960
- // value_disp: "0",
1961
- // value_xint: {
1962
- // v: "0",
1963
- // e: "3",
1964
- // f: "0",
1965
- // },
1966
- // display: "¥0",
1967
- // display_short: "¥0",
1968
- // currency: "JPY",
1969
- // unit: "JPY",
1970
- // has_vat: false,
1971
- // tax_profile: null,
1972
- // },
1973
- // tax_rate: "0",
1974
- // },
1975
- // }
1976
- const data = this.safeDict(response, 'data');
1977
- const amountResponse = this.safeDict(data, 'Amount');
1978
- const requested = this.safeDict(data, 'Requested');
1979
- const processed = this.safeDict(data, 'Processed');
1980
- const withdrawId = this.safeString(data, 'Crypto_Disbursement__');
1981
- const timestamp = this.safeInteger(requested, 'unixms');
1982
- return {
1983
- 'info': response,
1984
- 'id': withdrawId,
1985
- 'txid': undefined,
1986
- 'timestamp': timestamp,
1987
- 'datetime': this.iso8601(timestamp),
1988
- 'network': this.safeString(data, 'Crypto_Chain__'),
1989
- 'address': this.safeString(data, 'Address'),
1990
- 'addressTo': this.safeString(data, 'Address'),
1991
- 'addressFrom': undefined,
1992
- 'tag': tag,
1993
- 'tagTo': tag,
1994
- 'tagFrom': undefined,
1995
- 'type': 'withdrawal',
1996
- 'amount': this.safeNumber(amountResponse, 'value'),
1997
- 'currency': code,
1998
- 'status': this.parseTransactionStatus(this.safeString(data, 'Status')),
1999
- 'updated': this.safeTimestamp(processed, 'unix'),
2000
- 'internal': false,
2001
- 'comment': undefined,
2002
- 'fee': {
2003
- 'currency': code,
2004
- 'cost': undefined,
2005
- 'rate': undefined,
2006
- },
2007
- };
2008
- }
2009
- parseTransactionStatus(status) {
2010
- const statuses = {
2011
- 'pending': 'pending',
2012
- 'completed': 'ok',
2013
- 'failed': 'failed',
2014
- 'cancelled': 'canceled',
2015
- };
2016
- return this.safeString(statuses, status, status);
2017
- }
2018
- parseOrderStatus(status) {
2019
- const statuses = {
2020
- 'pending': 'open',
2021
- 'running': 'open',
2022
- 'post-pending': 'open',
2023
- 'open': 'open',
2024
- 'stop': 'open',
2025
- 'invalid': 'rejected',
2026
- 'done': 'closed',
2027
- 'cancel': 'canceled',
2028
- 'canceled': 'canceled', // alternative spelling
2029
- };
2030
- return this.safeString(statuses, status, status);
2031
- }
2032
- parseAmount(amount) {
2033
- const v = this.safeString(amount, 'v', undefined);
2034
- const e = this.safeInteger(amount, 'e', undefined);
2035
- if (v === undefined || e === undefined) {
2036
- return undefined;
2037
- }
2038
- const precise = new Precise(v);
2039
- precise.decimals = e;
2040
- precise.reduce();
2041
- const amountString = precise.toString();
2042
- return amountString;
2043
- }
2044
- toAmount(amount, precision) {
2045
- const v = amount.toString();
2046
- const e = precision;
2047
- return {
2048
- 'v': v,
2049
- 'e': e,
2050
- };
2051
- }
2052
- handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
2053
- // {
2054
- // "code": 404,
2055
- // "error": "Not Found: Crypto\\Token(US)",
2056
- // "exception": "Exception\\NotFound",
2057
- // "message": "[I18N:error_not_found]",
2058
- // "request": "cc83738a-2438-4f53-ae44-f15306c07f32",
2059
- // "result": "error",
2060
- // "time": 0.0089569091796875,
2061
- // "token": "error_not_found"
2062
- // }
2063
- const errorCode = this.safeString(response, 'code');
2064
- const message = this.safeString(response, 'message');
2065
- if (errorCode !== undefined) {
2066
- this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, message);
2067
- throw new ExchangeError(this.id + ' ' + message);
2068
- }
2069
- return undefined;
2070
- }
2071
- }