ccxt 4.5.1 → 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 (43) hide show
  1. package/README.md +110 -112
  2. package/dist/ccxt.browser.min.js +3 -3
  3. package/dist/cjs/ccxt.js +1 -9
  4. package/dist/cjs/src/ascendex.js +1 -1
  5. package/dist/cjs/src/binance.js +20 -14
  6. package/dist/cjs/src/bitget.js +1 -1
  7. package/dist/cjs/src/indodax.js +11 -12
  8. package/dist/cjs/src/okx.js +2 -2
  9. package/dist/cjs/src/poloniex.js +1 -1
  10. package/dist/cjs/src/pro/bitget.js +161 -26
  11. package/dist/cjs/src/pro/bitmart.js +1 -1
  12. package/dist/cjs/src/pro/gemini.js +7 -2
  13. package/dist/cjs/src/pro/hyperliquid.js +5 -0
  14. package/dist/cjs/src/pro/kraken.js +4 -6
  15. package/dist/cjs/src/zonda.js +12 -0
  16. package/js/ccxt.d.ts +2 -11
  17. package/js/ccxt.js +2 -8
  18. package/js/src/ascendex.js +1 -1
  19. package/js/src/binance.d.ts +1 -1
  20. package/js/src/binance.js +20 -14
  21. package/js/src/bitget.js +1 -1
  22. package/js/src/indodax.js +11 -12
  23. package/js/src/okx.js +2 -2
  24. package/js/src/poloniex.js +1 -1
  25. package/js/src/pro/bitget.d.ts +4 -0
  26. package/js/src/pro/bitget.js +167 -26
  27. package/js/src/pro/bitmart.js +1 -1
  28. package/js/src/pro/gemini.d.ts +1 -1
  29. package/js/src/pro/gemini.js +7 -2
  30. package/js/src/pro/hyperliquid.js +5 -0
  31. package/js/src/pro/kraken.js +4 -6
  32. package/js/src/zonda.js +12 -0
  33. package/package.json +2 -1
  34. package/js/src/abstract/ellipx.d.ts +0 -28
  35. package/js/src/abstract/ellipx.js +0 -11
  36. package/js/src/abstract/vertex.d.ts +0 -22
  37. package/js/src/abstract/vertex.js +0 -11
  38. package/js/src/ellipx.d.ts +0 -237
  39. package/js/src/ellipx.js +0 -2071
  40. package/js/src/pro/vertex.d.ts +0 -104
  41. package/js/src/pro/vertex.js +0 -999
  42. package/js/src/vertex.d.ts +0 -346
  43. package/js/src/vertex.js +0 -3146
package/js/src/vertex.js DELETED
@@ -1,3146 +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/vertex.js';
9
- import { ExchangeError, RateLimitExceeded, PermissionDenied, InsufficientFunds, AuthenticationError, ArgumentsRequired, NotSupported, InvalidOrder, BadRequest } from './base/errors.js';
10
- import { Precise } from './base/Precise.js';
11
- import { TICK_SIZE } from './base/functions/number.js';
12
- import { keccak_256 as keccak } from './static_dependencies/noble-hashes/sha3.js';
13
- import { secp256k1 } from './static_dependencies/noble-curves/secp256k1.js';
14
- import { ecdsa } from './base/functions/crypto.js';
15
- // ---------------------------------------------------------------------------
16
- /**
17
- * @class vertex
18
- * @augments Exchange
19
- */
20
- export default class vertex extends Exchange {
21
- describe() {
22
- return this.deepExtend(super.describe(), {
23
- 'id': 'vertex',
24
- 'name': 'Vertex',
25
- 'countries': [],
26
- 'version': 'v1',
27
- 'rateLimit': 50,
28
- 'certified': false,
29
- 'pro': true,
30
- 'dex': true,
31
- 'has': {
32
- 'CORS': undefined,
33
- 'spot': true,
34
- 'margin': false,
35
- 'swap': true,
36
- 'future': true,
37
- 'option': false,
38
- 'addMargin': false,
39
- 'borrowCrossMargin': false,
40
- 'borrowIsolatedMargin': false,
41
- 'cancelAllOrders': true,
42
- 'cancelAllOrdersAfter': false,
43
- 'cancelOrder': true,
44
- 'cancelOrders': true,
45
- 'cancelOrdersForSymbols': false,
46
- 'closeAllPositions': false,
47
- 'closePosition': false,
48
- 'createMarketBuyOrderWithCost': false,
49
- 'createMarketOrderWithCost': false,
50
- 'createMarketSellOrderWithCost': false,
51
- 'createOrder': true,
52
- 'createOrders': true,
53
- 'createReduceOnlyOrder': true,
54
- 'createStopOrder': true,
55
- 'createTriggerOrder': true,
56
- 'editOrder': false,
57
- 'fetchAccounts': false,
58
- 'fetchBalance': true,
59
- 'fetchBorrowInterest': false,
60
- 'fetchBorrowRateHistories': false,
61
- 'fetchBorrowRateHistory': false,
62
- 'fetchCanceledOrders': false,
63
- 'fetchClosedOrders': false,
64
- 'fetchCrossBorrowRate': false,
65
- 'fetchCrossBorrowRates': false,
66
- 'fetchCurrencies': true,
67
- 'fetchDepositAddress': false,
68
- 'fetchDepositAddresses': false,
69
- 'fetchDeposits': false,
70
- 'fetchDepositWithdrawFee': false,
71
- 'fetchDepositWithdrawFees': false,
72
- 'fetchFundingHistory': false,
73
- 'fetchFundingRate': true,
74
- 'fetchFundingRateHistory': false,
75
- 'fetchFundingRates': true,
76
- 'fetchIndexOHLCV': false,
77
- 'fetchIsolatedBorrowRate': false,
78
- 'fetchIsolatedBorrowRates': false,
79
- 'fetchLedger': false,
80
- 'fetchLeverage': false,
81
- 'fetchLeverageTiers': false,
82
- 'fetchLiquidations': false,
83
- 'fetchMarginMode': undefined,
84
- 'fetchMarketLeverageTiers': false,
85
- 'fetchMarkets': true,
86
- 'fetchMarkOHLCV': false,
87
- 'fetchMyLiquidations': false,
88
- 'fetchMyTrades': true,
89
- 'fetchOHLCV': true,
90
- 'fetchOpenInterest': true,
91
- 'fetchOpenInterestHistory': false,
92
- 'fetchOpenInterests': true,
93
- 'fetchOpenOrders': true,
94
- 'fetchOrder': true,
95
- 'fetchOrderBook': true,
96
- 'fetchOrders': true,
97
- 'fetchOrderTrades': false,
98
- 'fetchPosition': false,
99
- 'fetchPositionMode': false,
100
- 'fetchPositions': true,
101
- 'fetchPositionsRisk': false,
102
- 'fetchPremiumIndexOHLCV': false,
103
- 'fetchStatus': true,
104
- 'fetchTicker': false,
105
- 'fetchTickers': true,
106
- 'fetchTime': true,
107
- 'fetchTrades': true,
108
- 'fetchTradingFee': false,
109
- 'fetchTradingFees': true,
110
- 'fetchTransfer': false,
111
- 'fetchTransfers': false,
112
- 'fetchWithdrawal': false,
113
- 'fetchWithdrawals': false,
114
- 'reduceMargin': false,
115
- 'repayCrossMargin': false,
116
- 'repayIsolatedMargin': false,
117
- 'sandbox': true,
118
- 'setLeverage': false,
119
- 'setMarginMode': false,
120
- 'setPositionMode': false,
121
- 'transfer': false,
122
- 'withdraw': true,
123
- },
124
- 'timeframes': {
125
- '1m': 60,
126
- '5m': 300,
127
- '15m': 900,
128
- '1h': 3600,
129
- '2h': 7200,
130
- '4h': 14400,
131
- '1d': 86400,
132
- '1w': 604800,
133
- '1M': 604800,
134
- },
135
- 'hostname': 'vertexprotocol.com',
136
- 'urls': {
137
- 'logo': 'https://github.com/ccxt/ccxt/assets/43336371/bd04a0fa-3b48-47b6-9d8b-124954d520a8',
138
- 'api': {
139
- 'v1': {
140
- 'archive': 'https://archive.prod.{hostname}/v1',
141
- 'gateway': 'https://gateway.prod.{hostname}/v1',
142
- 'trigger': 'https://trigger.prod.{hostname}/v1',
143
- },
144
- 'v2': {
145
- 'archive': 'https://archive.prod.{hostname}/v2',
146
- 'gateway': 'https://gateway.prod.{hostname}/v2',
147
- },
148
- },
149
- 'test': {
150
- 'v1': {
151
- 'archive': 'https://archive.sepolia-test.{hostname}/v1',
152
- 'gateway': 'https://gateway.sepolia-test.{hostname}/v1',
153
- 'trigger': 'https://trigger.sepolia-test.{hostname}/v1',
154
- },
155
- 'v2': {
156
- 'archive': 'https://archive.sepolia-test.{hostname}/v2',
157
- 'gateway': 'https://gateway.sepolia-test.{hostname}/v2',
158
- },
159
- },
160
- 'www': 'https://vertexprotocol.com/',
161
- 'doc': 'https://docs.vertexprotocol.com/',
162
- 'fees': 'https://docs.vertexprotocol.com/basics/fees',
163
- 'referral': 'https://app.vertexprotocol.com?referrer=0xCfC9BaB96a2eA3d3c3F031c005e82E1D9F295aC1',
164
- },
165
- 'api': {
166
- 'v1': {
167
- 'archive': {
168
- 'post': {
169
- '': 1,
170
- },
171
- },
172
- 'gateway': {
173
- 'get': {
174
- 'query': 1,
175
- 'symbols': 1,
176
- 'time': 1,
177
- },
178
- 'post': {
179
- 'query': 1,
180
- 'execute': 1,
181
- },
182
- },
183
- 'trigger': {
184
- 'post': {
185
- 'execute': 1,
186
- 'query': 1,
187
- },
188
- },
189
- },
190
- 'v2': {
191
- 'archive': {
192
- 'get': {
193
- 'tickers': 1,
194
- 'contracts': 1,
195
- 'trades': 1,
196
- 'vrtx': 1,
197
- },
198
- },
199
- 'gateway': {
200
- 'get': {
201
- 'assets': 0.6667,
202
- 'pairs': 1,
203
- 'orderbook': 1,
204
- },
205
- },
206
- },
207
- },
208
- 'fees': {
209
- 'swap': {
210
- 'taker': this.parseNumber('0.0002'),
211
- 'maker': this.parseNumber('0.0002'),
212
- },
213
- 'spot': {
214
- 'taker': this.parseNumber('0.0002'),
215
- 'maker': this.parseNumber('0.0002'),
216
- },
217
- },
218
- 'requiredCredentials': {
219
- 'apiKey': false,
220
- 'secret': false,
221
- 'walletAddress': true,
222
- 'privateKey': true,
223
- },
224
- 'exceptions': {
225
- 'exact': {
226
- '1000': RateLimitExceeded,
227
- '1015': RateLimitExceeded,
228
- '1001': PermissionDenied,
229
- '1002': PermissionDenied,
230
- '1003': PermissionDenied,
231
- '2000': InvalidOrder,
232
- '2001': InvalidOrder,
233
- '2002': InvalidOrder,
234
- '2003': InvalidOrder,
235
- '2004': InvalidOrder,
236
- '2005': InvalidOrder,
237
- '2006': InvalidOrder,
238
- '2007': InvalidOrder,
239
- '2008': InvalidOrder,
240
- '2009': InvalidOrder,
241
- '2010': InvalidOrder,
242
- '2011': BadRequest,
243
- '2012': BadRequest,
244
- '2013': InvalidOrder,
245
- '2014': PermissionDenied,
246
- '2015': InvalidOrder,
247
- '2016': InvalidOrder,
248
- '2017': InvalidOrder,
249
- '2019': InvalidOrder,
250
- '2020': InvalidOrder,
251
- '2021': InvalidOrder,
252
- '2022': InvalidOrder,
253
- '2023': InvalidOrder,
254
- '2024': InsufficientFunds,
255
- '2025': InsufficientFunds,
256
- '2026': BadRequest,
257
- '2027': AuthenticationError,
258
- '2028': AuthenticationError,
259
- '2029': AuthenticationError,
260
- '2030': BadRequest,
261
- '2031': InvalidOrder,
262
- '2033': InvalidOrder,
263
- '2034': InvalidOrder,
264
- '2035': InvalidOrder,
265
- '2036': InvalidOrder,
266
- '2037': InvalidOrder,
267
- '2038': InvalidOrder,
268
- '2039': InvalidOrder,
269
- '2040': InvalidOrder,
270
- '2041': InvalidOrder,
271
- '2042': InvalidOrder,
272
- '2043': InvalidOrder,
273
- '2044': InvalidOrder,
274
- '2045': InvalidOrder,
275
- '2046': InvalidOrder,
276
- '2047': InvalidOrder,
277
- '2048': InvalidOrder,
278
- '2049': ExchangeError,
279
- '2050': PermissionDenied,
280
- '2051': InvalidOrder,
281
- '2052': InvalidOrder,
282
- '2053': InvalidOrder,
283
- '2054': InvalidOrder,
284
- '2055': InvalidOrder,
285
- '2056': InvalidOrder,
286
- '2057': InvalidOrder,
287
- '2058': InvalidOrder,
288
- '2059': InvalidOrder,
289
- '2060': InvalidOrder,
290
- '2061': InvalidOrder,
291
- '2062': InvalidOrder,
292
- '2063': InvalidOrder,
293
- '2064': InvalidOrder,
294
- '2065': InvalidOrder,
295
- '2066': InvalidOrder,
296
- '2067': InvalidOrder,
297
- '2068': InvalidOrder,
298
- '2069': InvalidOrder,
299
- '2070': InvalidOrder,
300
- '2071': InvalidOrder,
301
- '2072': InvalidOrder,
302
- '2073': InvalidOrder,
303
- '2074': InvalidOrder,
304
- '2075': InvalidOrder,
305
- '2076': InvalidOrder,
306
- '3000': BadRequest,
307
- '3001': BadRequest,
308
- '3002': BadRequest,
309
- '3003': BadRequest,
310
- '4000': BadRequest,
311
- '4001': ExchangeError,
312
- '4002': ExchangeError,
313
- '4003': ExchangeError,
314
- '4004': InvalidOrder,
315
- '5000': ExchangeError,
316
- },
317
- 'broad': {},
318
- },
319
- 'precisionMode': TICK_SIZE,
320
- 'commonCurrencies': {},
321
- 'options': {
322
- 'defaultType': 'swap',
323
- 'sandboxMode': false,
324
- 'timeDifference': 0,
325
- 'brokerId': 5930043274845996,
326
- },
327
- 'features': {
328
- 'default': {
329
- 'sandbox': true,
330
- 'createOrder': {
331
- 'marginMode': false,
332
- 'triggerPrice': true,
333
- 'triggerDirection': false,
334
- 'triggerPriceType': undefined,
335
- 'stopLossPrice': true,
336
- 'takeProfitPrice': true,
337
- 'attachedStopLossTakeProfit': undefined,
338
- 'timeInForce': {
339
- 'IOC': false,
340
- 'FOK': false,
341
- 'PO': true,
342
- 'GTD': true,
343
- },
344
- 'hedged': false,
345
- 'trailing': false,
346
- 'leverage': false,
347
- 'marketBuyByCost': true,
348
- 'marketBuyRequiresPrice': true,
349
- 'selfTradePrevention': false,
350
- 'iceberg': false,
351
- },
352
- 'createOrders': undefined,
353
- 'fetchMyTrades': {
354
- 'marginMode': false,
355
- 'limit': 500,
356
- 'daysBack': 100000,
357
- 'untilDays': undefined,
358
- 'symbolRequired': false,
359
- },
360
- 'fetchOrder': {
361
- 'marginMode': false,
362
- 'trigger': false,
363
- 'trailing': false,
364
- 'symbolRequired': true,
365
- },
366
- 'fetchOpenOrders': {
367
- 'marginMode': false,
368
- 'limit': 500,
369
- 'trigger': true,
370
- 'trailing': false,
371
- 'symbolRequired': false,
372
- },
373
- 'fetchOrders': undefined,
374
- 'fetchClosedOrders': undefined,
375
- 'fetchOHLCV': {
376
- 'limit': 1000,
377
- },
378
- },
379
- 'spot': {
380
- 'extends': 'default',
381
- },
382
- 'swap': {
383
- 'linear': {
384
- 'extends': 'default',
385
- },
386
- 'inverse': undefined,
387
- },
388
- 'future': {
389
- 'linear': undefined,
390
- 'inverse': undefined,
391
- },
392
- },
393
- });
394
- }
395
- setSandboxMode(enabled) {
396
- super.setSandboxMode(enabled);
397
- this.options['sandboxMode'] = enabled;
398
- }
399
- convertToX18(num) {
400
- if (typeof num === 'string') {
401
- return Precise.stringMul(num, '1000000000000000000');
402
- }
403
- const numStr = this.numberToString(num);
404
- return Precise.stringMul(numStr, '1000000000000000000');
405
- }
406
- convertFromX18(num) {
407
- if (typeof num === 'string') {
408
- return Precise.stringDiv(num, '1000000000000000000');
409
- }
410
- const numStr = this.numberToString(num);
411
- return Precise.stringDiv(numStr, '1000000000000000000');
412
- }
413
- /**
414
- * @method
415
- * @name vertex#fetchCurrencies
416
- * @description fetches all available currencies on an exchange
417
- * @see https://docs.vertexprotocol.com/developer-resources/api/v2/assets
418
- * @param {object} [params] extra parameters specific to the exchange API endpoint
419
- * @returns {object} an associative dictionary of currencies
420
- */
421
- async fetchCurrencies(params = {}) {
422
- const request = {};
423
- const response = await this.v2GatewayGetAssets(this.extend(request, params));
424
- //
425
- // [
426
- // {
427
- // "product_id": 2,
428
- // "ticker_id": "BTC-PERP_USDC",
429
- // "market_type": "perp",
430
- // "name": "Bitcoin Perp",
431
- // "symbol": "BTC-PERP",
432
- // "maker_fee": 0.0002,
433
- // "taker_fee": 0,
434
- // "can_withdraw": false,
435
- // "can_deposit": false
436
- // },
437
- // {
438
- // "product_id": 1,
439
- // "ticker_id": "BTC_USDC",
440
- // "market_type": "spot",
441
- // "name": "Bitcoin",
442
- // "symbol": "BTC",
443
- // "taker_fee": 0.0003,
444
- // "maker_fee": 0,
445
- // "can_withdraw": true,
446
- // "can_deposit": true
447
- // }
448
- // ]
449
- //
450
- const result = {};
451
- for (let i = 0; i < response.length; i++) {
452
- const data = this.safeDict(response, i, {});
453
- const tickerId = this.safeString(data, 'ticker_id');
454
- if ((tickerId !== undefined) && (tickerId.indexOf('PERP') > 0)) {
455
- continue;
456
- }
457
- const name = this.safeString(data, 'symbol');
458
- const code = this.safeCurrencyCode(name);
459
- result[code] = this.safeCurrencyStructure({
460
- 'id': this.safeString(data, 'product_id'),
461
- 'name': name,
462
- 'code': code,
463
- 'precision': undefined,
464
- 'info': data,
465
- 'active': undefined,
466
- 'deposit': this.safeBool(data, 'can_deposit'),
467
- 'withdraw': this.safeBool(data, 'can_withdraw'),
468
- 'networks': undefined,
469
- 'fee': undefined,
470
- 'limits': {
471
- 'amount': {
472
- 'min': undefined,
473
- 'max': undefined,
474
- },
475
- 'withdraw': {
476
- 'min': undefined,
477
- 'max': undefined,
478
- },
479
- },
480
- });
481
- }
482
- return result;
483
- }
484
- parseMarket(market) {
485
- //
486
- // {
487
- // "type": "spot",
488
- // "product_id": 3,
489
- // "symbol": "WETH",
490
- // "price_increment_x18": "100000000000000000",
491
- // "size_increment": "10000000000000000",
492
- // "min_size": "100000000000000000",
493
- // "min_depth_x18": "5000000000000000000000",
494
- // "max_spread_rate_x18": "2000000000000000",
495
- // "maker_fee_rate_x18": "0",
496
- // "taker_fee_rate_x18": "300000000000000",
497
- // "long_weight_initial_x18": "900000000000000000",
498
- // "long_weight_maintenance_x18": "950000000000000000"
499
- // }
500
- //
501
- const marketType = this.safeString(market, 'type');
502
- const quoteId = 'USDC';
503
- const quote = this.safeCurrencyCode(quoteId);
504
- const baseId = this.safeString(market, 'symbol');
505
- const base = this.safeCurrencyCode(baseId);
506
- const settleId = quoteId;
507
- const settle = this.safeCurrencyCode(settleId);
508
- let symbol = base + '/' + quote;
509
- const spot = marketType === 'spot';
510
- const contract = !spot;
511
- const swap = !spot;
512
- if (swap) {
513
- const splitSymbol = base.split('-');
514
- symbol = splitSymbol[0] + '/' + quote + ':' + settle;
515
- }
516
- const priceIncrementX18 = this.safeString(market, 'price_increment_x18');
517
- const sizeIncrementX18 = this.safeString(market, 'size_increment');
518
- const minSizeX18 = this.safeString(market, 'min_size');
519
- const takerX18 = this.safeNumber(market, 'taker_fee_rate_x18');
520
- const makerX18 = this.safeNumber(market, 'maker_fee_rate_x18');
521
- const isInverse = (spot) ? undefined : false;
522
- const isLinear = (spot) ? undefined : true;
523
- const contractSize = (spot) ? undefined : this.parseNumber('1');
524
- return {
525
- 'id': this.safeString(market, 'product_id'),
526
- 'symbol': symbol,
527
- 'base': base,
528
- 'quote': quote,
529
- 'settle': (spot) ? undefined : settle,
530
- 'baseId': baseId,
531
- 'quoteId': quoteId,
532
- 'settleId': (spot) ? undefined : settleId,
533
- 'type': (spot) ? 'spot' : 'swap',
534
- 'spot': spot,
535
- 'margin': undefined,
536
- 'swap': swap,
537
- 'future': false,
538
- 'option': false,
539
- 'active': true,
540
- 'contract': contract,
541
- 'linear': isLinear,
542
- 'inverse': isInverse,
543
- 'taker': this.parseNumber(this.convertFromX18(takerX18)),
544
- 'maker': this.parseNumber(this.convertFromX18(makerX18)),
545
- 'contractSize': contractSize,
546
- 'expiry': undefined,
547
- 'expiryDatetime': undefined,
548
- 'strike': undefined,
549
- 'optionType': undefined,
550
- 'precision': {
551
- 'amount': this.parseNumber(this.convertFromX18(sizeIncrementX18)),
552
- 'price': this.parseNumber(this.convertFromX18(priceIncrementX18)),
553
- },
554
- 'limits': {
555
- 'leverage': {
556
- 'min': undefined,
557
- 'max': undefined,
558
- },
559
- 'amount': {
560
- 'min': this.parseNumber(this.convertFromX18(minSizeX18)),
561
- 'max': undefined,
562
- },
563
- 'price': {
564
- 'min': undefined,
565
- 'max': undefined,
566
- },
567
- 'cost': {
568
- 'min': undefined,
569
- 'max': undefined,
570
- },
571
- },
572
- 'created': undefined,
573
- 'info': market,
574
- };
575
- }
576
- /**
577
- * @method
578
- * @name vertex#fetchMarkets
579
- * @description retrieves data on all markets for vertex
580
- * @see https://docs.vertexprotocol.com/developer-resources/api/gateway/queries/symbols
581
- * @param {object} [params] extra parameters specific to the exchange API endpoint
582
- * @returns {object[]} an array of objects representing market data
583
- */
584
- async fetchMarkets(params = {}) {
585
- const request = {
586
- 'type': 'symbols',
587
- };
588
- const response = await this.v1GatewayGetQuery(this.extend(request, params));
589
- //
590
- // {
591
- // "status": "success",
592
- // "data": {
593
- // "symbols": {
594
- // "WETH": {
595
- // "type": "spot",
596
- // "product_id": 3,
597
- // "symbol": "WETH",
598
- // "price_increment_x18": "100000000000000000",
599
- // "size_increment": "10000000000000000",
600
- // "min_size": "100000000000000000",
601
- // "min_depth_x18": "5000000000000000000000",
602
- // "max_spread_rate_x18": "2000000000000000",
603
- // "maker_fee_rate_x18": "0",
604
- // "taker_fee_rate_x18": "300000000000000",
605
- // "long_weight_initial_x18": "900000000000000000",
606
- // "long_weight_maintenance_x18": "950000000000000000"
607
- // }
608
- // }
609
- // },
610
- // "request_type": "query_symbols"
611
- // }
612
- //
613
- const data = this.safeDict(response, 'data', {});
614
- const markets = this.safeDict(data, 'symbols', {});
615
- const symbols = Object.keys(markets);
616
- const result = [];
617
- for (let i = 0; i < symbols.length; i++) {
618
- const symbol = symbols[i];
619
- const rawMarket = this.safeDict(markets, symbol, {});
620
- result.push(this.parseMarket(rawMarket));
621
- }
622
- return result;
623
- }
624
- /**
625
- * @method
626
- * @name vertex#fetchTime
627
- * @description fetches the current integer timestamp in milliseconds from the exchange server
628
- * @param {object} [params] extra parameters specific to the exchange API endpoint
629
- * @returns {int} the current integer timestamp in milliseconds from the exchange server
630
- */
631
- async fetchTime(params = {}) {
632
- const response = await this.v1GatewayGetTime(params);
633
- // 1717481623452
634
- return this.parseToInt(response);
635
- }
636
- /**
637
- * @method
638
- * @name vertex#fetchStatus
639
- * @description the latest known information on the availability of the exchange API
640
- * @see https://docs.vertexprotocol.com/developer-resources/api/gateway/queries/status
641
- * @param {object} [params] extra parameters specific to the exchange API endpoint
642
- * @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure}
643
- */
644
- async fetchStatus(params = {}) {
645
- const request = {
646
- 'type': 'status',
647
- };
648
- const response = await this.v1GatewayGetQuery(this.extend(request, params));
649
- //
650
- // {
651
- // "status": "success",
652
- // "data": "active",
653
- // "request_type": "query_status",
654
- // }
655
- //
656
- let status = this.safeString(response, 'data');
657
- if (status === 'active') {
658
- status = 'ok';
659
- }
660
- else {
661
- status = 'error';
662
- }
663
- return {
664
- 'status': status,
665
- 'updated': undefined,
666
- 'eta': undefined,
667
- 'url': undefined,
668
- 'info': response,
669
- };
670
- }
671
- parseTrade(trade, market = undefined) {
672
- //
673
- // {
674
- // "ticker_id": "ARB_USDC",
675
- // "trade_id": 999994,
676
- // "price": 1.1366122408151016,
677
- // "base_filled": 175,
678
- // "quote_filled": -198.90714214264278,
679
- // "timestamp": 1691068943,
680
- // "trade_type": "buy"
681
- // }
682
- // fetchMytrades
683
- // {
684
- // "digest": "0x80ce789702b670b7d33f2aa67e12c85f124395c3f9acdb422dde3b4973ccd50c",
685
- // "order": {
686
- // "sender": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000",
687
- // "priceX18": "27544000000000000000000",
688
- // "amount": "2000000000000000000",
689
- // "expiration": "4611686020107119633",
690
- // "nonce": "1761322608857448448"
691
- // },
692
- // "base_filled": "736000000000000000",
693
- // "quote_filled": "-20276464287857571514302",
694
- // "fee": "4055287857571514302",
695
- // "sequencer_fee": "0"
696
- // "cumulative_fee": "4055287857571514302",
697
- // "cumulative_base_filled": "736000000000000000",
698
- // "cumulative_quote_filled": "-20276464287857571514302",
699
- // "submission_idx": "563012",
700
- // "pre_balance": {
701
- // "base": {
702
- // "perp": {
703
- // "product_id": 2,
704
- // "lp_balance": {
705
- // "amount": "0",
706
- // "last_cumulative_funding_x18": "1823351297710837"
707
- // },
708
- // "balance": {
709
- // "amount": "2686684000000000000000",
710
- // "v_quote_balance": "-76348662407149297671587247",
711
- // "last_cumulative_funding_x18": "134999841911604906604576"
712
- // }
713
- // }
714
- // },
715
- // "quote": null
716
- // },
717
- // "post_balance": {
718
- // "base": {
719
- // "perp": {
720
- // "product_id": 2,
721
- // "lp_balance": {
722
- // "amount": "0",
723
- // "last_cumulative_funding_x18": "1823351297710837"
724
- // },
725
- // "balance": {
726
- // "amount": "2686013000000000000000",
727
- // "v_quote_balance": "-76328351274188497671587247",
728
- // "last_cumulative_funding_x18": "134999841911604906604576"
729
- // }
730
- // }
731
- // },
732
- // "quote": null
733
- // }
734
- // }
735
- let price = undefined;
736
- let amount = undefined;
737
- let side = undefined;
738
- let fee = undefined;
739
- const feeCost = this.convertFromX18(this.safeString(trade, 'fee'));
740
- if (feeCost !== undefined) {
741
- fee = {
742
- 'cost': feeCost,
743
- 'currency': undefined,
744
- };
745
- }
746
- const id = this.safeString2(trade, 'trade_id', 'submission_idx');
747
- const order = this.safeString(trade, 'digest');
748
- const timestamp = this.safeTimestamp(trade, 'timestamp');
749
- if (timestamp === undefined) {
750
- // fetchMyTrades
751
- const baseBalance = this.safeDict(this.safeDict(trade, 'pre_balance', {}), 'base', {});
752
- let marketId = undefined;
753
- if ('perp' in baseBalance) {
754
- marketId = this.safeString(this.safeDict(baseBalance, 'perp', {}), 'product_id');
755
- }
756
- else {
757
- marketId = this.safeString(this.safeDict(baseBalance, 'spot', {}), 'product_id');
758
- }
759
- market = this.safeMarket(marketId);
760
- const subOrder = this.safeDict(trade, 'order', {});
761
- price = this.convertFromX18(this.safeString(subOrder, 'priceX18'));
762
- amount = this.convertFromX18(this.safeString(trade, 'base_filled'));
763
- if (Precise.stringLt(amount, '0')) {
764
- side = 'sell';
765
- }
766
- else {
767
- side = 'buy';
768
- }
769
- }
770
- else {
771
- const tickerId = this.safeString(trade, 'ticker_id');
772
- const splitTickerId = tickerId.split('_');
773
- const splitSymbol = splitTickerId[0].split('-');
774
- const marketId = splitSymbol[0] + splitTickerId[1];
775
- market = this.safeMarket(marketId, market);
776
- price = this.safeString(trade, 'price');
777
- amount = this.safeString(trade, 'base_filled');
778
- side = this.safeStringLower(trade, 'trade_type');
779
- }
780
- amount = Precise.stringAbs(amount);
781
- const symbol = market['symbol'];
782
- return this.safeTrade({
783
- 'id': id,
784
- 'timestamp': timestamp,
785
- 'datetime': this.iso8601(timestamp),
786
- 'symbol': symbol,
787
- 'side': side,
788
- 'price': price,
789
- 'amount': amount,
790
- 'cost': undefined,
791
- 'order': order,
792
- 'takerOrMaker': undefined,
793
- 'type': undefined,
794
- 'fee': fee,
795
- 'info': trade,
796
- }, market);
797
- }
798
- /**
799
- * @method
800
- * @name vertex#fetchTrades
801
- * @description get the list of most recent trades for a particular symbol
802
- * @see https://docs.vertexprotocol.com/developer-resources/api/v2/trades
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 fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
810
- await this.loadMarkets();
811
- const market = this.market(symbol);
812
- const marketId = market['baseId'] + '_USDC';
813
- const request = {
814
- 'ticker_id': marketId,
815
- };
816
- if (limit !== undefined) {
817
- request['limit'] = limit;
818
- }
819
- const response = await this.v2ArchiveGetTrades(this.extend(request, params));
820
- //
821
- // [
822
- // {
823
- // "ticker_id": "ARB_USDC",
824
- // "trade_id": 999994,
825
- // "price": 1.1366122408151016,
826
- // "base_filled": 175,
827
- // "quote_filled": -198.90714214264278,
828
- // "timestamp": 1691068943,
829
- // "trade_type": "buy"
830
- // },
831
- // {
832
- // "ticker_id": "ARB_USDC",
833
- // "trade_id": 999978,
834
- // "price": 1.136512210806099,
835
- // "base_filled": 175,
836
- // "quote_filled": -198.8896368910673,
837
- // "timestamp": 1691068882,
838
- // "trade_type": "buy"
839
- // }
840
- // ]
841
- //
842
- return this.parseTrades(response, market, since, limit);
843
- }
844
- /**
845
- * @method
846
- * @name vertex#fetchMyTrades
847
- * @description fetch all trades made by the user
848
- * @see https://docs.vertexprotocol.com/developer-resources/api/archive-indexer/matches
849
- * @param {string} symbol unified market symbol
850
- * @param {int} [since] the earliest time in ms to fetch trades for
851
- * @param {int} [limit] the maximum number of trades structures to retrieve
852
- * @param {object} [params] extra parameters specific to the exchange API endpoint
853
- * @param {string} [params.user] user address, will default to this.walletAddress if not provided
854
- * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
855
- */
856
- async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
857
- await this.loadMarkets();
858
- let userAddress = undefined;
859
- [userAddress, params] = this.handlePublicAddress('fetchMyTrades', params);
860
- let market = undefined;
861
- const matchesRequest = {
862
- 'subaccount': this.convertAddressToSender(userAddress),
863
- };
864
- if (symbol !== undefined) {
865
- market = this.market(symbol);
866
- matchesRequest['product_ids'] = [this.parseToNumeric(market['id'])];
867
- }
868
- const until = this.safeInteger(params, 'until');
869
- if (until !== undefined) {
870
- params = this.omit(params, 'until');
871
- matchesRequest['max_time'] = until;
872
- }
873
- if (limit !== undefined) {
874
- matchesRequest['limit'] = limit;
875
- }
876
- const request = {
877
- 'matches': matchesRequest,
878
- };
879
- const response = await this.v1ArchivePost(this.extend(request, params));
880
- //
881
- // {
882
- // "matches": [
883
- // {
884
- // "digest": "0x80ce789702b670b7d33f2aa67e12c85f124395c3f9acdb422dde3b4973ccd50c",
885
- // "order": {
886
- // "sender": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000",
887
- // "priceX18": "27544000000000000000000",
888
- // "amount": "2000000000000000000",
889
- // "expiration": "4611686020107119633",
890
- // "nonce": "1761322608857448448"
891
- // },
892
- // "base_filled": "736000000000000000",
893
- // "quote_filled": "-20276464287857571514302",
894
- // "fee": "4055287857571514302",
895
- // "sequencer_fee": "0"
896
- // "cumulative_fee": "4055287857571514302",
897
- // "cumulative_base_filled": "736000000000000000",
898
- // "cumulative_quote_filled": "-20276464287857571514302",
899
- // "submission_idx": "563012",
900
- // "pre_balance": {
901
- // "base": {
902
- // "perp": {
903
- // "product_id": 2,
904
- // "lp_balance": {
905
- // "amount": "0",
906
- // "last_cumulative_funding_x18": "1823351297710837"
907
- // },
908
- // "balance": {
909
- // "amount": "2686684000000000000000",
910
- // "v_quote_balance": "-76348662407149297671587247",
911
- // "last_cumulative_funding_x18": "134999841911604906604576"
912
- // }
913
- // }
914
- // },
915
- // "quote": null
916
- // },
917
- // "post_balance": {
918
- // "base": {
919
- // "perp": {
920
- // "product_id": 2,
921
- // "lp_balance": {
922
- // "amount": "0",
923
- // "last_cumulative_funding_x18": "1823351297710837"
924
- // },
925
- // "balance": {
926
- // "amount": "2686013000000000000000",
927
- // "v_quote_balance": "-76328351274188497671587247",
928
- // "last_cumulative_funding_x18": "134999841911604906604576"
929
- // }
930
- // }
931
- // },
932
- // "quote": null
933
- // }
934
- // },
935
- // {
936
- // "digest": "0x0f6e5a0434e36d8e6d4fed950d3624b0d8c91a8a84efd156bb25c1382561c0c2",
937
- // "order": {
938
- // "sender": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000",
939
- // "priceX18": "27540000000000000000000",
940
- // "amount": "2000000000000000000",
941
- // "expiration": "4611686020107119623",
942
- // "nonce": "1761322602510417920"
943
- // },
944
- // "base_filled": "723999999999999999",
945
- // "quote_filled": "-19944943483044913474043",
946
- // "fee": "5983483044913474042",
947
- // "cumulative_fee": "11958484645393618085",
948
- // "cumulative_base_filled": "1446999999999999998",
949
- // "cumulative_quote_filled": "-39861640484645393618087",
950
- // "submission_idx": "563011",
951
- // "pre_balance": {
952
- // "base": {
953
- // "perp": {
954
- // "product_id": 2,
955
- // "lp_balance": {
956
- // "amount": "0",
957
- // "last_cumulative_funding_x18": "1823351297710837"
958
- // },
959
- // "balance": {
960
- // "amount": "2686684000000000000000",
961
- // "v_quote_balance": "-76348662407149297671587247",
962
- // "last_cumulative_funding_x18": "134999841911604906604576"
963
- // }
964
- // }
965
- // },
966
- // "quote": null
967
- // },
968
- // "post_balance": {
969
- // "base": {
970
- // "perp": {
971
- // "product_id": 2,
972
- // "lp_balance": {
973
- // "amount": "0",
974
- // "last_cumulative_funding_x18": "1823351297710837"
975
- // },
976
- // "balance": {
977
- // "amount": "2686013000000000000000",
978
- // "v_quote_balance": "-76328351274188497671587247",
979
- // "last_cumulative_funding_x18": "134999841911604906604576"
980
- // }
981
- // }
982
- // },
983
- // "quote": null
984
- // }
985
- // }
986
- // ],
987
- // "txs": [
988
- // {
989
- // "tx": {
990
- // "match_orders": {
991
- // "product_id": 2,
992
- // "amm": true,
993
- // "taker": {
994
- // "order": {
995
- // "sender": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000",
996
- // "price_x18": "27544000000000000000000",
997
- // "amount": "2000000000000000000",
998
- // "expiration": 4611686020107120000,
999
- // "nonce": 1761322608857448400
1000
- // },
1001
- // "signature": "0xe8fa7151bde348afa3b46dc52798046b7c8318f1b0a7f689710debbc094658cc1bf5a7e478ccc8278b625da0b9402c86b580d2e31e13831337dfd6153f4b37811b"
1002
- // },
1003
- // "maker": {
1004
- // "order": {
1005
- // "sender": "0xebdbbcdbd2646c5f23a1e0806027eee5f71b074664656661756c740000000000",
1006
- // "price_x18": "27544000000000000000000",
1007
- // "amount": "-736000000000000000",
1008
- // "expiration": 1679731669,
1009
- // "nonce": 1761322585591644200
1010
- // },
1011
- // "signature": "0x47f9d47f0777f3ca0b13f07b7682dbeea098c0e377b87dcb025754fe34c900e336b8c7744e021fb9c46a4f8c6a1478bafa28bf0d023ae496aa3efa4d8e81df181c"
1012
- // }
1013
- // }
1014
- // },
1015
- // "submission_idx": "563012",
1016
- // "timestamp": "1679728133"
1017
- // },
1018
- // {
1019
- // "tx": {
1020
- // "match_orders": {
1021
- // "product_id": 1,
1022
- // "amm": true,
1023
- // "taker": {
1024
- // "order": {
1025
- // "sender": "0x12a0b4888021576eb10a67616dd3dd3d9ce206b664656661756c740000000000",
1026
- // "price_x18": "27540000000000000000000",
1027
- // "amount": "2000000000000000000",
1028
- // "expiration": 4611686020107120000,
1029
- // "nonce": 1761322602510418000
1030
- // },
1031
- // "signature": "0x826c68f1a3f76d9ffbe8041f8d45e969d31f1ab6f2ae2f6379d1493e479e56436091d6cf4c72e212dd2f1d2fa17c627c4c21bd6d281c77172b8af030488478b71c"
1032
- // },
1033
- // "maker": {
1034
- // "order": {
1035
- // "sender": "0xf8d240d9514c9a4715d66268d7af3b53d619642564656661756c740000000000",
1036
- // "price_x18": "27540000000000000000000",
1037
- // "amount": "-724000000000000000",
1038
- // "expiration": 1679731656,
1039
- // "nonce": 1761322565506171000
1040
- // },
1041
- // "signature": "0xd8b6505b8d9b8c3cbfe793080976388035682c02a27893fb26b48a5b2bfe943f4162dea3a42e24e0dff5e2f74fbf77e33d83619140a2a581117c55e6cc236bdb1c"
1042
- // }
1043
- // }
1044
- // },
1045
- // "submission_idx": "563011",
1046
- // "timestamp": "1679728127"
1047
- // }
1048
- // ]
1049
- // }
1050
- //
1051
- const trades = this.safeList(response, 'matches', []);
1052
- return this.parseTrades(trades, market, since, limit, params);
1053
- }
1054
- /**
1055
- * @method
1056
- * @name vertex#fetchOrderBook
1057
- * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
1058
- * @see https://docs.vertexprotocol.com/developer-resources/api/v2/orderbook
1059
- * @param {string} symbol unified symbol of the market to fetch the order book for
1060
- * @param {int} [limit] the maximum amount of order book entries to return
1061
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1062
- * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
1063
- */
1064
- async fetchOrderBook(symbol, limit = undefined, params = {}) {
1065
- await this.loadMarkets();
1066
- const market = this.market(symbol);
1067
- const marketId = market['baseId'] + '_USDC';
1068
- if (limit === undefined) {
1069
- limit = 100;
1070
- }
1071
- const request = {
1072
- 'ticker_id': marketId,
1073
- 'depth': limit,
1074
- };
1075
- const response = await this.v2GatewayGetOrderbook(this.extend(request, params));
1076
- //
1077
- // {
1078
- // "ticker_id": "ETH-PERP_USDC",
1079
- // "bids": [
1080
- // [
1081
- // 1612.3,
1082
- // 0.31
1083
- // ],
1084
- // [
1085
- // 1612.0,
1086
- // 0.93
1087
- // ],
1088
- // [
1089
- // 1611.5,
1090
- // 1.55
1091
- // ],
1092
- // [
1093
- // 1610.8,
1094
- // 2.17
1095
- // ]
1096
- // ],
1097
- // "asks": [
1098
- // [
1099
- // 1612.9,
1100
- // 0.93
1101
- // ],
1102
- // [
1103
- // 1613.4,
1104
- // 1.55
1105
- // ],
1106
- // [
1107
- // 1614.1,
1108
- // 2.17
1109
- // ]
1110
- // ],
1111
- // "timestamp": 1694375362016
1112
- // }
1113
- //
1114
- const timestamp = this.safeInteger(response, 'timestamp');
1115
- return this.parseOrderBook(response, symbol, timestamp, 'bids', 'asks');
1116
- }
1117
- /**
1118
- * @method
1119
- * @name vertex#fetchTradingFees
1120
- * @description fetch the trading fees for multiple markets
1121
- * @see https://docs.vertexprotocol.com/developer-resources/api/gateway/queries/fee-rates
1122
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1123
- * @param {string} [params.user] user address, will default to this.walletAddress if not provided
1124
- * @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols
1125
- */
1126
- async fetchTradingFees(params = {}) {
1127
- await this.loadMarkets();
1128
- let userAddress = undefined;
1129
- [userAddress, params] = this.handlePublicAddress('fetchTradingFees', params);
1130
- const request = {
1131
- 'type': 'fee_rates',
1132
- 'sender': this.convertAddressToSender(userAddress),
1133
- };
1134
- const response = await this.v1GatewayGetQuery(this.extend(request, params));
1135
- //
1136
- // {
1137
- // "status": "success",
1138
- // "data": {
1139
- // "taker_fee_rates_x18": [
1140
- // "0",
1141
- // "300000000000000",
1142
- // "200000000000000",
1143
- // "300000000000000",
1144
- // "200000000000000"
1145
- // ],
1146
- // "maker_fee_rates_x18": [
1147
- // "0",
1148
- // "0",
1149
- // "0",
1150
- // "0",
1151
- // "0"
1152
- // ],
1153
- // "liquidation_sequencer_fee": "250000000000000000",
1154
- // "health_check_sequencer_fee": "100000000000000000",
1155
- // "taker_sequencer_fee": "25000000000000000",
1156
- // "withdraw_sequencer_fees": [
1157
- // "10000000000000000",
1158
- // "40000000000000",
1159
- // "0",
1160
- // "600000000000000",
1161
- // "0"
1162
- // ]
1163
- // },
1164
- // "request_type": "query_fee_rates",
1165
- // }
1166
- //
1167
- const data = this.safeDict(response, 'data', {});
1168
- const maker = this.safeList(data, 'maker_fee_rates_x18', []);
1169
- const taker = this.safeList(data, 'taker_fee_rates_x18', []);
1170
- const result = {};
1171
- for (let i = 0; i < taker.length; i++) {
1172
- const market = this.safeMarket(this.numberToString(i));
1173
- if (market['id'] === undefined) {
1174
- continue;
1175
- }
1176
- const symbol = market['symbol'];
1177
- result[symbol] = {
1178
- 'info': response,
1179
- 'symbol': symbol,
1180
- 'maker': this.parseNumber(this.convertFromX18(maker[i])),
1181
- 'taker': this.parseNumber(this.convertFromX18(taker[i])),
1182
- 'percentage': true,
1183
- 'tierBased': false,
1184
- };
1185
- }
1186
- return result;
1187
- }
1188
- parseOHLCV(ohlcv, market = undefined) {
1189
- // example response in fetchOHLCV
1190
- return [
1191
- this.safeTimestamp(ohlcv, 'timestamp'),
1192
- this.parseNumber(this.convertFromX18(this.safeString(ohlcv, 'open_x18'))),
1193
- this.parseNumber(this.convertFromX18(this.safeString(ohlcv, 'high_x18'))),
1194
- this.parseNumber(this.convertFromX18(this.safeString(ohlcv, 'low_x18'))),
1195
- this.parseNumber(this.convertFromX18(this.safeString(ohlcv, 'close_x18'))),
1196
- this.parseNumber(this.convertFromX18(this.safeString(ohlcv, 'volume'))),
1197
- ];
1198
- }
1199
- /**
1200
- * @method
1201
- * @name vertex#fetchOHLCV
1202
- * @see https://docs.vertexprotocol.com/developer-resources/api/archive-indexer/candlesticks
1203
- * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1204
- * @param {string} symbol unified symbol of the market to fetch OHLCV data for
1205
- * @param {string} timeframe the length of time each candle represents
1206
- * @param {int} [since] timestamp in ms of the earliest candle to fetch
1207
- * @param {int} [limit] max=1000, max=100 when since is defined and is less than (now - (999 * (timeframe in ms)))
1208
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1209
- * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1210
- */
1211
- async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
1212
- await this.loadMarkets();
1213
- const market = this.market(symbol);
1214
- const ohlcvRequest = {
1215
- 'product_id': this.parseToInt(market['id']),
1216
- 'granularity': this.safeInteger(this.timeframes, timeframe),
1217
- };
1218
- const until = this.safeInteger(params, 'until');
1219
- if (until !== undefined) {
1220
- params = this.omit(params, 'until');
1221
- ohlcvRequest['max_time'] = until;
1222
- }
1223
- if (limit !== undefined) {
1224
- ohlcvRequest['limit'] = Math.min(limit, 1000);
1225
- }
1226
- const request = {
1227
- 'candlesticks': ohlcvRequest,
1228
- };
1229
- const response = await this.v1ArchivePost(this.extend(request, params));
1230
- //
1231
- // {
1232
- // "candlesticks": [
1233
- // {
1234
- // "product_id": 1,
1235
- // "granularity": 60,
1236
- // "submission_idx": "627709",
1237
- // "timestamp": "1680118140",
1238
- // "open_x18": "27235000000000000000000",
1239
- // "high_x18": "27298000000000000000000",
1240
- // "low_x18": "27235000000000000000000",
1241
- // "close_x18": "27298000000000000000000",
1242
- // "volume": "1999999999999999998"
1243
- // },
1244
- // {
1245
- // "product_id": 1,
1246
- // "granularity": 60,
1247
- // "submission_idx": "627699",
1248
- // "timestamp": "1680118080",
1249
- // "open_x18": "27218000000000000000000",
1250
- // "high_x18": "27245000000000000000000",
1251
- // "low_x18": "27218000000000000000000",
1252
- // "close_x18": "27245000000000000000000",
1253
- // "volume": "11852999999999999995"
1254
- // }
1255
- // ]
1256
- // }
1257
- //
1258
- const rows = this.safeList(response, 'candlesticks', []);
1259
- return this.parseOHLCVs(rows, market, timeframe, since, limit);
1260
- }
1261
- parseFundingRate(ticker, market = undefined) {
1262
- //
1263
- // {
1264
- // "product_id": 4,
1265
- // "funding_rate_x18": "2447900598160952",
1266
- // "update_time": "1680116326"
1267
- // }
1268
- //
1269
- // {
1270
- // "ETH-PERP_USDC": {
1271
- // "ticker_id": "ETH-PERP_USDC",
1272
- // "base_currency": "ETH-PERP",
1273
- // "quote_currency": "USDC",
1274
- // "last_price": 1620.3,
1275
- // "base_volume": 1309.2,
1276
- // "quote_volume": 2117828.093867611,
1277
- // "product_type": "perpetual",
1278
- // "contract_price": 1620.372642114429,
1279
- // "contract_price_currency": "USD",
1280
- // "open_interest": 1635.2,
1281
- // "open_interest_usd": 2649633.3443855145,
1282
- // "index_price": 1623.293496279935,
1283
- // "mark_price": 1623.398589416731,
1284
- // "funding_rate": 0.000068613217104332,
1285
- // "next_funding_rate_timestamp": 1694379600,
1286
- // "price_change_percent_24h": -0.6348599635253989
1287
- // }
1288
- // }
1289
- //
1290
- let fundingRate = this.safeNumber(ticker, 'funding_rate');
1291
- if (fundingRate === undefined) {
1292
- const fundingRateX18 = this.safeString(ticker, 'funding_rate_x18');
1293
- fundingRate = this.parseNumber(this.convertFromX18(fundingRateX18));
1294
- }
1295
- const fundingTimestamp = this.safeTimestamp2(ticker, 'update_time', 'next_funding_rate_timestamp');
1296
- const markPrice = this.safeNumber(ticker, 'mark_price');
1297
- const indexPrice = this.safeNumber(ticker, 'index_price');
1298
- return {
1299
- 'info': ticker,
1300
- 'symbol': market['symbol'],
1301
- 'markPrice': markPrice,
1302
- 'indexPrice': indexPrice,
1303
- 'interestRate': undefined,
1304
- 'estimatedSettlePrice': undefined,
1305
- 'timestamp': undefined,
1306
- 'datetime': undefined,
1307
- 'fundingRate': fundingRate,
1308
- 'fundingTimestamp': fundingTimestamp,
1309
- 'fundingDatetime': this.iso8601(fundingTimestamp),
1310
- 'nextFundingRate': undefined,
1311
- 'nextFundingTimestamp': undefined,
1312
- 'nextFundingDatetime': undefined,
1313
- 'previousFundingRate': undefined,
1314
- 'previousFundingTimestamp': undefined,
1315
- 'previousFundingDatetime': undefined,
1316
- 'interval': undefined,
1317
- };
1318
- }
1319
- /**
1320
- * @method
1321
- * @name vertex#fetchFundingRate
1322
- * @description fetch the current funding rate
1323
- * @see https://docs.vertexprotocol.com/developer-resources/api/archive-indexer/funding-rate
1324
- * @param {string} symbol unified market symbol
1325
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1326
- * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
1327
- */
1328
- async fetchFundingRate(symbol, params = {}) {
1329
- await this.loadMarkets();
1330
- const market = this.market(symbol);
1331
- const request = {
1332
- 'funding_rate': {
1333
- 'product_id': this.parseToInt(market['id']),
1334
- },
1335
- };
1336
- const response = await this.v1ArchivePost(this.extend(request, params));
1337
- //
1338
- // {
1339
- // "product_id": 4,
1340
- // "funding_rate_x18": "2447900598160952",
1341
- // "update_time": "1680116326"
1342
- // }
1343
- //
1344
- return this.parseFundingRate(response, market);
1345
- }
1346
- /**
1347
- * @method
1348
- * @name vertex#fetchFundingRates
1349
- * @description fetches funding rates for multiple markets
1350
- * @see https://docs.vertexprotocol.com/developer-resources/api/v2/contracts
1351
- * @param {string[]} symbols unified symbols of the markets to fetch the funding rates for, all market funding rates are returned if not assigned
1352
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1353
- * @returns {object[]} an array of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
1354
- */
1355
- async fetchFundingRates(symbols = undefined, params = {}) {
1356
- await this.loadMarkets();
1357
- const request = {};
1358
- if (symbols !== undefined) {
1359
- symbols = this.marketSymbols(symbols);
1360
- }
1361
- const response = await this.v2ArchiveGetContracts(this.extend(request, params));
1362
- //
1363
- // {
1364
- // "ETH-PERP_USDC": {
1365
- // "ticker_id": "ETH-PERP_USDC",
1366
- // "base_currency": "ETH-PERP",
1367
- // "quote_currency": "USDC",
1368
- // "last_price": 1620.3,
1369
- // "base_volume": 1309.2,
1370
- // "quote_volume": 2117828.093867611,
1371
- // "product_type": "perpetual",
1372
- // "contract_price": 1620.372642114429,
1373
- // "contract_price_currency": "USD",
1374
- // "open_interest": 1635.2,
1375
- // "open_interest_usd": 2649633.3443855145,
1376
- // "index_price": 1623.293496279935,
1377
- // "mark_price": 1623.398589416731,
1378
- // "funding_rate": 0.000068613217104332,
1379
- // "next_funding_rate_timestamp": 1694379600,
1380
- // "price_change_percent_24h": -0.6348599635253989
1381
- // }
1382
- // }
1383
- //
1384
- const keys = Object.keys(response);
1385
- const fundingRates = {};
1386
- for (let i = 0; i < keys.length; i++) {
1387
- const tickerId = keys[i];
1388
- const parsedTickerId = tickerId.split('-');
1389
- const data = response[tickerId];
1390
- const marketId = parsedTickerId[0] + '/USDC:USDC';
1391
- const market = this.market(marketId);
1392
- const ticker = this.parseFundingRate(data, market);
1393
- const symbol = ticker['symbol'];
1394
- fundingRates[symbol] = ticker;
1395
- }
1396
- return this.filterByArray(fundingRates, 'symbol', symbols);
1397
- }
1398
- parseOpenInterest(interest, market = undefined) {
1399
- //
1400
- // {
1401
- // "ETH-PERP_USDC": {
1402
- // "ticker_id": "ETH-PERP_USDC",
1403
- // "base_currency": "ETH-PERP",
1404
- // "quote_currency": "USDC",
1405
- // "last_price": 1620.3,
1406
- // "base_volume": 1309.2,
1407
- // "quote_volume": 2117828.093867611,
1408
- // "product_type": "perpetual",
1409
- // "contract_price": 1620.372642114429,
1410
- // "contract_price_currency": "USD",
1411
- // "open_interest": 1635.2,
1412
- // "open_interest_usd": 2649633.3443855145,
1413
- // "index_price": 1623.293496279935,
1414
- // "mark_price": 1623.398589416731,
1415
- // "funding_rate": 0.000068613217104332,
1416
- // "next_funding_rate_timestamp": 1694379600,
1417
- // "price_change_percent_24h": -0.6348599635253989
1418
- // }
1419
- // }
1420
- //
1421
- const marketId = this.safeString(interest, 'ticker_id');
1422
- return this.safeOpenInterest({
1423
- 'symbol': this.safeSymbol(marketId, market),
1424
- 'openInterestAmount': this.safeNumber(interest, 'open_interest'),
1425
- 'openInterestValue': this.safeNumber(interest, 'open_interest_usd'),
1426
- 'timestamp': undefined,
1427
- 'datetime': undefined,
1428
- 'info': interest,
1429
- }, market);
1430
- }
1431
- /**
1432
- * @method
1433
- * @name vertex#fetchOpenInterests
1434
- * @description Retrieves the open interest for a list of symbols
1435
- * @see https://docs.vertexprotocol.com/developer-resources/api/v2/contracts
1436
- * @param {string[]} [symbols] a list of unified CCXT market symbols
1437
- * @param {object} [params] exchange specific parameters
1438
- * @returns {object[]} a list of [open interest structures]{@link https://docs.ccxt.com/#/?id=open-interest-structure}
1439
- */
1440
- async fetchOpenInterests(symbols = undefined, params = {}) {
1441
- await this.loadMarkets();
1442
- symbols = this.marketSymbols(symbols);
1443
- const response = await this.v2ArchiveGetContracts(params);
1444
- //
1445
- // {
1446
- // "ADA-PERP_USDC": {
1447
- // "ticker_id": "ADA-PERP_USDC",
1448
- // "base_currency": "ADA-PERP",
1449
- // "quote_currency": "USDC",
1450
- // "last_price": 0.85506,
1451
- // "base_volume": 1241320.0,
1452
- // "quote_volume": 1122670.9080057142,
1453
- // "product_type": "perpetual",
1454
- // "contract_price": 0.8558601432685385,
1455
- // "contract_price_currency": "USD",
1456
- // "open_interest": 104040.0,
1457
- // "open_interest_usd": 89043.68930565874,
1458
- // "index_price": 0.8561952606869176,
1459
- // "mark_price": 0.856293781088936,
1460
- // "funding_rate": 0.000116153806226841,
1461
- // "next_funding_rate_timestamp": 1734685200,
1462
- // "price_change_percent_24h": -12.274325340321374
1463
- // },
1464
- // }
1465
- //
1466
- const parsedSymbols = [];
1467
- const results = [];
1468
- const markets = Object.keys(response);
1469
- if (symbols === undefined) {
1470
- symbols = [];
1471
- for (let y = 0; y < markets.length; y++) {
1472
- const tickerId = markets[y];
1473
- const parsedTickerId = tickerId.split('-');
1474
- const currentSymbol = parsedTickerId[0] + '/USDC:USDC';
1475
- if (!this.inArray(currentSymbol, symbols)) {
1476
- symbols.push(currentSymbol);
1477
- }
1478
- }
1479
- }
1480
- for (let i = 0; i < markets.length; i++) {
1481
- const marketId = markets[i];
1482
- const marketInner = this.safeMarket(marketId);
1483
- const openInterest = this.safeDict(response, marketId, {});
1484
- for (let j = 0; j < symbols.length; j++) {
1485
- const market = this.market(symbols[j]);
1486
- const tickerId = market['base'] + '_USDC';
1487
- if (marketInner['marketId'] === tickerId) {
1488
- parsedSymbols.push(market['symbol']);
1489
- results.push(this.parseOpenInterest(openInterest, market));
1490
- }
1491
- }
1492
- }
1493
- return this.filterByArray(results, 'symbol', parsedSymbols);
1494
- }
1495
- /**
1496
- * @method
1497
- * @name vertex#fetchOpenInterest
1498
- * @description Retrieves the open interest of a derivative trading pair
1499
- * @see https://docs.vertexprotocol.com/developer-resources/api/v2/contracts
1500
- * @param {string} symbol Unified CCXT market symbol
1501
- * @param {object} [params] exchange specific parameters
1502
- * @returns {object} an open interest structure{@link https://docs.ccxt.com/#/?id=open-interest-structure}
1503
- */
1504
- async fetchOpenInterest(symbol, params = {}) {
1505
- await this.loadMarkets();
1506
- const market = this.market(symbol);
1507
- if (!market['contract']) {
1508
- throw new BadRequest(this.id + ' fetchOpenInterest() supports contract markets only');
1509
- }
1510
- const request = {};
1511
- const response = await this.v2ArchiveGetContracts(this.extend(request, params));
1512
- //
1513
- // {
1514
- // "ETH-PERP_USDC": {
1515
- // "ticker_id": "ETH-PERP_USDC",
1516
- // "base_currency": "ETH-PERP",
1517
- // "quote_currency": "USDC",
1518
- // "last_price": 1620.3,
1519
- // "base_volume": 1309.2,
1520
- // "quote_volume": 2117828.093867611,
1521
- // "product_type": "perpetual",
1522
- // "contract_price": 1620.372642114429,
1523
- // "contract_price_currency": "USD",
1524
- // "open_interest": 1635.2,
1525
- // "open_interest_usd": 2649633.3443855145,
1526
- // "index_price": 1623.293496279935,
1527
- // "mark_price": 1623.398589416731,
1528
- // "funding_rate": 0.000068613217104332,
1529
- // "next_funding_rate_timestamp": 1694379600,
1530
- // "price_change_percent_24h": -0.6348599635253989
1531
- // }
1532
- // }
1533
- //
1534
- const tickerId = market['base'] + '_USDC';
1535
- const openInterest = this.safeDict(response, tickerId, {});
1536
- return this.parseOpenInterest(openInterest, market);
1537
- }
1538
- parseTicker(ticker, market = undefined) {
1539
- //
1540
- // {
1541
- // "ticker_id": "BTC_USDC",
1542
- // "base_currency": "BTC",
1543
- // "quote_currency": "USDC",
1544
- // "last_price": 25728.0,
1545
- // "base_volume": 552.048,
1546
- // "quote_volume": 14238632.207250029,
1547
- // "price_change_percent_24h": -0.6348599635253989
1548
- // }
1549
- //
1550
- const base = this.safeString(ticker, 'base_currency');
1551
- const quote = this.safeString(ticker, 'quote_currency');
1552
- let marketId = base + '/' + quote;
1553
- if (base.indexOf('PERP') > 0) {
1554
- marketId = marketId.replace('-PERP', '') + ':USDC';
1555
- }
1556
- market = this.safeMarket(marketId, market);
1557
- const last = this.safeString(ticker, 'last_price');
1558
- return this.safeTicker({
1559
- 'symbol': market['symbol'],
1560
- 'timestamp': undefined,
1561
- 'datetime': undefined,
1562
- 'high': undefined,
1563
- 'low': undefined,
1564
- 'bid': undefined,
1565
- 'bidVolume': undefined,
1566
- 'ask': undefined,
1567
- 'askVolume': undefined,
1568
- 'vwap': undefined,
1569
- 'open': undefined,
1570
- 'close': last,
1571
- 'last': last,
1572
- 'previousClose': undefined,
1573
- 'change': undefined,
1574
- 'percentage': this.safeString(ticker, 'price_change_percent_24h'),
1575
- 'average': undefined,
1576
- 'baseVolume': this.safeString(ticker, 'base_volume'),
1577
- 'quoteVolume': this.safeString(ticker, 'quote_volume'),
1578
- 'info': ticker,
1579
- }, market);
1580
- }
1581
- /**
1582
- * @method
1583
- * @name vertex#fetchTickers
1584
- * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1585
- * @see https://docs.vertexprotocol.com/developer-resources/api/v2/tickers
1586
- * @param {string[]} [symbols] unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1587
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1588
- * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1589
- */
1590
- async fetchTickers(symbols = undefined, params = {}) {
1591
- await this.loadMarkets();
1592
- symbols = this.marketSymbols(symbols, undefined, true, true, true);
1593
- const request = {};
1594
- const response = await this.v2ArchiveGetTickers(this.extend(request, params));
1595
- //
1596
- // {
1597
- // "ETH_USDC": {
1598
- // "ticker_id": "ETH_USDC",
1599
- // "base_currency": "ETH",
1600
- // "quote_currency": "USDC",
1601
- // "last_price": 1619.1,
1602
- // "base_volume": 1428.32,
1603
- // "quote_volume": 2310648.316391866,
1604
- // "price_change_percent_24h": -1.0509394462969588
1605
- // },
1606
- // "BTC_USDC": {
1607
- // "ticker_id": "BTC_USDC",
1608
- // "base_currency": "BTC",
1609
- // "quote_currency": "USDC",
1610
- // "last_price": 25728.0,
1611
- // "base_volume": 552.048,
1612
- // "quote_volume": 14238632.207250029,
1613
- // "price_change_percent_24h": -0.6348599635253989
1614
- // }
1615
- // }
1616
- //
1617
- const tickers = Object.values(response);
1618
- return this.parseTickers(tickers, symbols);
1619
- }
1620
- async queryContracts(params = {}) {
1621
- // query contract addresses for sending order
1622
- const cachedContracts = this.safeDict(this.options, 'v1contracts');
1623
- if (cachedContracts !== undefined) {
1624
- return cachedContracts;
1625
- }
1626
- const request = {
1627
- 'type': 'contracts',
1628
- };
1629
- const response = await this.v1GatewayGetQuery(this.extend(request, params));
1630
- const data = this.safeDict(response, 'data', {});
1631
- this.options['v1contracts'] = data;
1632
- return data;
1633
- }
1634
- nonce() {
1635
- return this.milliseconds() - this.options['timeDifference'];
1636
- }
1637
- hashMessage(message) {
1638
- return '0x' + this.hash(message, keccak, 'hex');
1639
- }
1640
- signHash(hash, privateKey) {
1641
- const signature = ecdsa(hash.slice(-64), privateKey.slice(-64), secp256k1, undefined);
1642
- const r = signature['r'];
1643
- const s = signature['s'];
1644
- const v = this.intToBase16(this.sum(27, signature['v']));
1645
- return '0x' + r.padStart(64, '0') + s.padStart(64, '0') + v;
1646
- }
1647
- signMessage(message, privateKey) {
1648
- return this.signHash(this.hashMessage(message), privateKey.slice(-64));
1649
- }
1650
- buildSig(chainId, messageTypes, message, verifyingContractAddress = '') {
1651
- const domain = {
1652
- 'chainId': chainId,
1653
- 'name': 'Vertex',
1654
- 'verifyingContract': verifyingContractAddress,
1655
- 'version': '0.0.1',
1656
- };
1657
- const msg = this.ethEncodeStructuredData(domain, messageTypes, message);
1658
- const signature = this.signMessage(msg, this.privateKey);
1659
- return signature;
1660
- }
1661
- buildCreateOrderSig(message, chainId, verifyingContractAddress) {
1662
- const messageTypes = {
1663
- 'Order': [
1664
- { 'name': 'sender', 'type': 'bytes32' },
1665
- { 'name': 'priceX18', 'type': 'int128' },
1666
- { 'name': 'amount', 'type': 'int128' },
1667
- { 'name': 'expiration', 'type': 'uint64' },
1668
- { 'name': 'nonce', 'type': 'uint64' },
1669
- ],
1670
- };
1671
- return this.buildSig(chainId, messageTypes, message, verifyingContractAddress);
1672
- }
1673
- buildListTriggerTxSig(message, chainId, verifyingContractAddress) {
1674
- const messageTypes = {
1675
- 'ListTriggerOrders': [
1676
- { 'name': 'sender', 'type': 'bytes32' },
1677
- { 'name': 'recvTime', 'type': 'uint64' },
1678
- ],
1679
- };
1680
- return this.buildSig(chainId, messageTypes, message, verifyingContractAddress);
1681
- }
1682
- buildCancelAllOrdersSig(message, chainId, verifyingContractAddress) {
1683
- const messageTypes = {
1684
- 'CancellationProducts': [
1685
- { 'name': 'sender', 'type': 'bytes32' },
1686
- { 'name': 'productIds', 'type': 'uint32[]' },
1687
- { 'name': 'nonce', 'type': 'uint64' },
1688
- ],
1689
- };
1690
- return this.buildSig(chainId, messageTypes, message, verifyingContractAddress);
1691
- }
1692
- buildCancelOrdersSig(message, chainId, verifyingContractAddress) {
1693
- const messageTypes = {
1694
- 'Cancellation': [
1695
- { 'name': 'sender', 'type': 'bytes32' },
1696
- { 'name': 'productIds', 'type': 'uint32[]' },
1697
- { 'name': 'digests', 'type': 'bytes32[]' },
1698
- { 'name': 'nonce', 'type': 'uint64' },
1699
- ],
1700
- };
1701
- return this.buildSig(chainId, messageTypes, message, verifyingContractAddress);
1702
- }
1703
- buildWithdrawSig(message, chainId, verifyingContractAddress) {
1704
- const messageTypes = {
1705
- 'WithdrawCollateral': [
1706
- { 'name': 'sender', 'type': 'bytes32' },
1707
- { 'name': 'productId', 'type': 'uint32' },
1708
- { 'name': 'amount', 'type': 'uint128' },
1709
- { 'name': 'nonce', 'type': 'uint64' },
1710
- ],
1711
- };
1712
- return this.buildSig(chainId, messageTypes, message, verifyingContractAddress);
1713
- }
1714
- convertAddressToSender(address) {
1715
- const sender = address + '64656661756c74';
1716
- return sender.padEnd(66, '0');
1717
- }
1718
- getNonce(now, expiration) {
1719
- if (now === undefined) {
1720
- now = this.nonce();
1721
- }
1722
- // nonce = ((now + expiration) << 20) + 1000
1723
- // 1 << 20 = 1048576
1724
- return Precise.stringAdd(Precise.stringMul(Precise.stringAdd(this.numberToString(now), this.numberToString(expiration)), '1048576'), '1000');
1725
- }
1726
- getExpiration(now, timeInForce, postOnly, reduceOnly) {
1727
- let expiration = Precise.stringAdd(this.numberToString(now), '86400');
1728
- if (timeInForce === 'ioc') {
1729
- // 1 << 62 = 4611686018427387904
1730
- expiration = Precise.stringOr(expiration, '4611686018427387904');
1731
- }
1732
- else if (timeInForce === 'fok') {
1733
- // 2 << 62 = 9223372036854775808
1734
- expiration = Precise.stringOr(expiration, '9223372036854775808');
1735
- }
1736
- else if (postOnly) {
1737
- // 3 << 62 = 13835058055282163712
1738
- expiration = Precise.stringOr(expiration, '13835058055282163712');
1739
- }
1740
- if (reduceOnly) {
1741
- // 1 << 61 = 2305843009213693952
1742
- expiration = Precise.stringOr(expiration, '2305843009213693952');
1743
- }
1744
- return expiration;
1745
- }
1746
- getAmount(amount, side) {
1747
- let amountString = this.numberToString(amount);
1748
- if (side === 'sell') {
1749
- if (amount > 0) {
1750
- // amount *= -1;
1751
- amountString = Precise.stringMul(amountString, '-1');
1752
- }
1753
- }
1754
- else {
1755
- if (amount < 0) {
1756
- // amount *= -1;
1757
- amountString = Precise.stringMul(amountString, '-1');
1758
- }
1759
- }
1760
- return amountString;
1761
- }
1762
- /**
1763
- * @method
1764
- * @name vertex#createOrder
1765
- * @description create a trade order
1766
- * @see https://docs.vertexprotocol.com/developer-resources/api/gateway/executes/place-order
1767
- * @see https://docs.vertexprotocol.com/developer-resources/api/trigger/executes/place-order
1768
- * @param {string} symbol unified symbol of the market to create an order in
1769
- * @param {string} type 'market' or 'limit'
1770
- * @param {string} side 'buy' or 'sell'
1771
- * @param {float} amount how much of currency you want to trade in units of base currency
1772
- * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1773
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1774
- * @param {string} [params.timeInForce] ioc, fok
1775
- * @param {bool} [params.postOnly] true or false whether the order is post-only
1776
- * @param {bool} [params.reduceOnly] true or false whether the order is reduce-only, only works for ioc and fok order
1777
- * @param {float} [params.triggerPrice] The price at which a trigger order is triggered at
1778
- * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1779
- */
1780
- async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1781
- this.checkRequiredCredentials();
1782
- const marketType = type.toLowerCase();
1783
- const isMarketOrder = marketType === 'market';
1784
- if (isMarketOrder && price === undefined) {
1785
- throw new ArgumentsRequired(this.id + ' createOrder() requires a price argument for market order');
1786
- }
1787
- await this.loadMarkets();
1788
- const market = this.market(symbol);
1789
- const marketId = this.parseToInt(market['id']);
1790
- const contracts = await this.queryContracts();
1791
- const chainId = this.safeString(contracts, 'chain_id');
1792
- const bookAddresses = this.safeList(contracts, 'book_addrs', []);
1793
- const verifyingContractAddress = this.safeString(bookAddresses, marketId);
1794
- const defaultTimeInForce = (isMarketOrder) ? 'fok' : undefined;
1795
- const timeInForce = this.safeStringLower(params, 'timeInForce', defaultTimeInForce);
1796
- const postOnly = this.safeBool(params, 'postOnly', false);
1797
- const reduceOnly = this.safeBool(params, 'reduceOnly', false);
1798
- const triggerPrice = this.safeString2(params, 'triggerPrice', 'stopPrice');
1799
- const stopLossPrice = this.safeString(params, 'stopLossPrice', triggerPrice);
1800
- const takeProfitPrice = this.safeString(params, 'takeProfitPrice');
1801
- const isTrigger = (stopLossPrice || takeProfitPrice);
1802
- const now = this.nonce();
1803
- let nonce = this.getNonce(now, 90000);
1804
- if (postOnly && reduceOnly) {
1805
- throw new NotSupported(this.id + ' reduceOnly not supported when postOnly is enabled');
1806
- }
1807
- const expiration = this.getExpiration(now, timeInForce, postOnly, reduceOnly);
1808
- if (isTrigger) {
1809
- // 1 << 63 = 9223372036854775808
1810
- nonce = Precise.stringOr(nonce, '9223372036854775808');
1811
- }
1812
- const amountString = this.getAmount(amount, side);
1813
- const order = {
1814
- 'sender': this.convertAddressToSender(this.walletAddress),
1815
- 'priceX18': this.convertToX18(this.priceToPrecision(symbol, price)),
1816
- 'amount': this.convertToX18(this.amountToPrecision(symbol, amountString)),
1817
- 'expiration': expiration,
1818
- 'nonce': nonce,
1819
- };
1820
- const request = {
1821
- 'place_order': {
1822
- 'product_id': marketId,
1823
- 'order': {
1824
- 'sender': order['sender'],
1825
- 'priceX18': order['priceX18'],
1826
- 'amount': order['amount'],
1827
- 'expiration': this.numberToString(order['expiration']),
1828
- 'nonce': order['nonce'],
1829
- },
1830
- 'signature': this.buildCreateOrderSig(order, chainId, verifyingContractAddress),
1831
- 'id': this.safeInteger(this.options, 'brokerId', 5930043274845996),
1832
- },
1833
- };
1834
- params = this.omit(params, ['timeInForce', 'reduceOnly', 'postOnly', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice']);
1835
- let response = undefined;
1836
- if (isTrigger) {
1837
- const trigger = {};
1838
- if (stopLossPrice !== undefined) {
1839
- trigger['last_price_below'] = this.convertToX18(stopLossPrice);
1840
- }
1841
- else if (takeProfitPrice !== undefined) {
1842
- trigger['last_price_above'] = this.convertToX18(takeProfitPrice);
1843
- }
1844
- request['place_order']['trigger'] = trigger;
1845
- response = await this.v1TriggerPostExecute(this.extend(request, params));
1846
- }
1847
- else {
1848
- response = await this.v1GatewayPostExecute(this.extend(request, params));
1849
- }
1850
- //
1851
- // {
1852
- // "status": "success",
1853
- // "signature": {signature},
1854
- // "data": {
1855
- // "digest": {order digest}
1856
- // },
1857
- // "request_type": "execute_place_order"
1858
- // "id": 100
1859
- // }
1860
- //
1861
- const data = this.safeDict(response, 'data', {});
1862
- return this.safeOrder({
1863
- 'id': this.safeString(data, 'digest'),
1864
- });
1865
- }
1866
- /**
1867
- * @method
1868
- * @name vertex#editOrder
1869
- * @description edit a trade order
1870
- * @see https://docs.vertexprotocol.com/developer-resources/api/gateway/executes/cancel-and-place
1871
- * @param {string} id cancel order id
1872
- * @param {string} symbol unified symbol of the market to create an order in
1873
- * @param {string} type 'market' or 'limit'
1874
- * @param {string} side 'buy' or 'sell'
1875
- * @param {float} amount how much of currency you want to trade in units of base currency
1876
- * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1877
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1878
- * @param {string} [params.timeInForce] ioc, fok
1879
- * @param {bool} [params.postOnly] true or false whether the order is post-only
1880
- * @param {bool} [params.reduceOnly] true or false whether the order is reduce-only, only works for ioc and fok order
1881
- * @param {float} [params.triggerPrice] The price at which a trigger order is triggered at
1882
- * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1883
- */
1884
- async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
1885
- this.checkRequiredCredentials();
1886
- const marketType = type.toLowerCase();
1887
- const isMarketOrder = marketType === 'market';
1888
- if (isMarketOrder && price === undefined) {
1889
- throw new ArgumentsRequired(this.id + ' editOrder() requires a price argument for market order');
1890
- }
1891
- await this.loadMarkets();
1892
- const market = this.market(symbol);
1893
- const marketId = this.parseToInt(market['id']);
1894
- const defaultTimeInForce = (isMarketOrder) ? 'fok' : undefined;
1895
- const timeInForce = this.safeStringLower(params, 'timeInForce', defaultTimeInForce);
1896
- const postOnly = this.safeBool(params, 'postOnly', false);
1897
- const reduceOnly = this.safeBool(params, 'reduceOnly', false);
1898
- const triggerPrice = this.safeString2(params, 'triggerPrice', 'stopPrice');
1899
- const stopLossPrice = this.safeString(params, 'stopLossPrice', triggerPrice);
1900
- const takeProfitPrice = this.safeString(params, 'takeProfitPrice');
1901
- const isTrigger = (stopLossPrice || takeProfitPrice);
1902
- const contracts = await this.queryContracts();
1903
- const chainId = this.safeString(contracts, 'chain_id');
1904
- const bookAddresses = this.safeList(contracts, 'book_addrs', []);
1905
- const verifyingContractAddressOrder = this.safeString(bookAddresses, marketId);
1906
- const verifyingContractAddressCancel = this.safeString(contracts, 'endpoint_addr');
1907
- const now = this.nonce();
1908
- const nonce = this.getNonce(now, 90000);
1909
- const sender = this.convertAddressToSender(this.walletAddress);
1910
- if (postOnly && reduceOnly) {
1911
- throw new NotSupported(this.id + ' reduceOnly not supported when postOnly is enabled');
1912
- }
1913
- if (isTrigger) {
1914
- throw new NotSupported(this.id + ' editOrder() not supported for trigger order');
1915
- }
1916
- const expiration = this.getExpiration(now, timeInForce, postOnly, reduceOnly);
1917
- const amountString = this.getAmount(amount, side);
1918
- const order = {
1919
- 'sender': sender,
1920
- 'priceX18': this.convertToX18(this.priceToPrecision(symbol, price)),
1921
- 'amount': this.convertToX18(this.amountToPrecision(symbol, amountString)),
1922
- 'expiration': expiration,
1923
- 'nonce': nonce,
1924
- };
1925
- const cancels = {
1926
- 'sender': sender,
1927
- 'productIds': [marketId],
1928
- 'digests': [id],
1929
- 'nonce': nonce,
1930
- };
1931
- const request = {
1932
- 'cancel_and_place': {
1933
- 'cancel_tx': {
1934
- 'sender': cancels['sender'],
1935
- 'productIds': cancels['productIds'],
1936
- 'digests': cancels['digests'],
1937
- 'nonce': this.numberToString(cancels['nonce']),
1938
- },
1939
- 'cancel_signature': this.buildCancelOrdersSig(cancels, chainId, verifyingContractAddressCancel),
1940
- 'place_order': {
1941
- 'product_id': marketId,
1942
- 'order': {
1943
- 'sender': order['sender'],
1944
- 'priceX18': order['priceX18'],
1945
- 'amount': order['amount'],
1946
- 'expiration': this.numberToString(order['expiration']),
1947
- 'nonce': order['nonce'],
1948
- },
1949
- 'signature': this.buildCreateOrderSig(order, chainId, verifyingContractAddressOrder),
1950
- 'id': this.safeInteger(this.options, 'brokerId', 5930043274845996),
1951
- },
1952
- },
1953
- };
1954
- params = this.omit(params, ['timeInForce', 'reduceOnly', 'postOnly', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice']);
1955
- const response = await this.v1GatewayPostExecute(this.extend(request, params));
1956
- //
1957
- // {
1958
- // "status": "success",
1959
- // "signature": {signature},
1960
- // "data": {
1961
- // "digest": {order digest}
1962
- // },
1963
- // "request_type": "execute_cancel_and_place"
1964
- // }
1965
- //
1966
- const data = this.safeDict(response, 'data', {});
1967
- return this.safeOrder({
1968
- 'id': this.safeString(data, 'digest'),
1969
- });
1970
- }
1971
- parseOrderStatus(status) {
1972
- if (status !== undefined) {
1973
- const statuses = {
1974
- 'pending': 'open',
1975
- };
1976
- if (typeof status === 'string') {
1977
- return this.safeString(statuses, status, status);
1978
- }
1979
- const statusCancelled = this.safeDict(status, 'cancelled');
1980
- if (statusCancelled !== undefined) {
1981
- return 'canceled';
1982
- }
1983
- const statusTriggered = this.safeDict(status, 'triggered', {});
1984
- const triggeredStatus = this.safeString(statusTriggered, 'status', 'failure');
1985
- if (triggeredStatus === 'success') {
1986
- return 'closed';
1987
- }
1988
- return 'canceled';
1989
- }
1990
- return status;
1991
- }
1992
- parseOrder(order, market = undefined) {
1993
- //
1994
- // {
1995
- // "product_id": 1,
1996
- // "sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
1997
- // "price_x18": "1000000000000000000",
1998
- // "amount": "1000000000000000000",
1999
- // "expiration": "2000000000",
2000
- // "nonce": "1",
2001
- // "unfilled_amount": "1000000000000000000",
2002
- // "digest": "0x0000000000000000000000000000000000000000000000000000000000000000",
2003
- // "placed_at": 1681951347,
2004
- // "order_type": "ioc"
2005
- // }
2006
- // stop order
2007
- // {
2008
- // "order": {
2009
- // "order": {
2010
- // "sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
2011
- // "priceX18": "1000000000000000000",
2012
- // "amount": "1000000000000000000",
2013
- // "expiration": "2000000000",
2014
- // "nonce": "1",
2015
- // },
2016
- // "signature": "0x...",
2017
- // "product_id": 1,
2018
- // "spot_leverage": true,
2019
- // "trigger": {
2020
- // "price_above": "1000000000000000000"
2021
- // },
2022
- // "digest": "0x..."
2023
- // },
2024
- // "status": "pending",
2025
- // "updated_at": 1688768157050
2026
- // }
2027
- //
2028
- let marketId = this.safeString(order, 'product_id');
2029
- let timestamp = this.safeTimestamp(order, 'placed_at');
2030
- let amount = this.safeString(order, 'amount');
2031
- let price = this.safeString(order, 'price_x18');
2032
- const remaining = this.safeString(order, 'unfilled_amount');
2033
- let triggerPriceNum = undefined;
2034
- const status = this.safeValue(order, 'status');
2035
- if (status !== undefined) {
2036
- // trigger order
2037
- const outerOrder = this.safeDict(order, 'order', {});
2038
- const innerOrder = this.safeDict(outerOrder, 'order', {});
2039
- marketId = this.safeString(outerOrder, 'product_id');
2040
- amount = this.safeString(innerOrder, 'amount');
2041
- price = this.safeString(innerOrder, 'priceX18');
2042
- timestamp = this.safeTimestamp(order, 'updated_at');
2043
- const trigger = this.safeDict(outerOrder, 'trigger', {});
2044
- const triggerPrice = this.safeStringN(trigger, ['price_above', 'price_below', 'last_price_above', 'last_price_below']);
2045
- if (triggerPrice !== undefined) {
2046
- triggerPriceNum = this.parseToNumeric(this.convertFromX18(triggerPrice));
2047
- }
2048
- }
2049
- market = this.safeMarket(marketId, market);
2050
- const symbol = market['symbol'];
2051
- let priceNum = undefined;
2052
- if (price !== undefined) {
2053
- priceNum = this.parseToNumeric(this.convertFromX18(price));
2054
- }
2055
- let amountNum = undefined;
2056
- if (amount !== undefined) {
2057
- amountNum = this.parseToNumeric(this.convertFromX18(amount));
2058
- }
2059
- let remainingNum = undefined;
2060
- if (remaining !== undefined) {
2061
- remainingNum = this.parseToNumeric(this.convertFromX18(remaining));
2062
- }
2063
- let side = undefined;
2064
- if (amountNum !== undefined && remainingNum !== undefined) {
2065
- side = (amountNum < 0 || remainingNum < 0) ? 'sell' : 'buy';
2066
- }
2067
- const tif = this.parseTimeInForce(this.safeString(order, 'order_type'));
2068
- const isPostOnly = (tif === 'PO');
2069
- return this.safeOrder({
2070
- 'info': order,
2071
- 'id': this.safeString(order, 'digest'),
2072
- 'clientOrderId': undefined,
2073
- 'timestamp': timestamp,
2074
- 'datetime': this.iso8601(timestamp),
2075
- 'lastTradeTimestamp': undefined,
2076
- 'lastUpdateTimestamp': undefined,
2077
- 'symbol': symbol,
2078
- 'type': undefined,
2079
- 'timeInForce': tif,
2080
- 'postOnly': isPostOnly,
2081
- 'reduceOnly': undefined,
2082
- 'side': side,
2083
- 'price': priceNum,
2084
- 'triggerPrice': triggerPriceNum,
2085
- 'amount': amountNum,
2086
- 'cost': undefined,
2087
- 'average': undefined,
2088
- 'filled': undefined,
2089
- 'remaining': remainingNum,
2090
- 'status': this.parseOrderStatus(status),
2091
- 'fee': undefined,
2092
- 'trades': undefined,
2093
- }, market);
2094
- }
2095
- parseTimeInForce(timeInForce) {
2096
- const timeInForces = {
2097
- 'POST_ONLY': 'PO',
2098
- };
2099
- return this.safeStringUpper(timeInForces, timeInForce, timeInForce);
2100
- }
2101
- /**
2102
- * @method
2103
- * @name vertex#fetchOrder
2104
- * @description fetches information on an order made by the user
2105
- * @see https://docs.vertexprotocol.com/developer-resources/api/gateway/queries/order
2106
- * @param {string} id the order id
2107
- * @param {string} symbol unified symbol of the market the order was made in
2108
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2109
- * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2110
- */
2111
- async fetchOrder(id, symbol = undefined, params = {}) {
2112
- await this.loadMarkets();
2113
- const market = this.market(symbol);
2114
- const request = {
2115
- 'type': 'order',
2116
- 'product_id': this.parseToInt(market['id']),
2117
- 'digest': id,
2118
- };
2119
- const response = await this.v1GatewayGetQuery(this.extend(request, params));
2120
- //
2121
- // {
2122
- // "status": "success",
2123
- // "data": {
2124
- // "product_id": 1,
2125
- // "sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
2126
- // "price_x18": "1000000000000000000",
2127
- // "amount": "1000000000000000000",
2128
- // "expiration": "2000000000",
2129
- // "nonce": "1",
2130
- // "unfilled_amount": "1000000000000000000",
2131
- // "digest": "0x0000000000000000000000000000000000000000000000000000000000000000",
2132
- // "placed_at": 1681951347,
2133
- // "order_type": "ioc"
2134
- // },
2135
- // "request_type": "query_order",
2136
- // }
2137
- //
2138
- const data = this.safeDict(response, 'data');
2139
- return this.parseOrder(data, market);
2140
- }
2141
- /**
2142
- * @method
2143
- * @name vertex#fetchOpenOrders
2144
- * @description fetch all unfilled currently open orders
2145
- * @see https://docs.vertexprotocol.com/developer-resources/api/gateway/queries/orders
2146
- * @see https://docs.vertexprotocol.com/developer-resources/api/trigger/queries/list-trigger-orders
2147
- * @param {string} symbol unified market symbol
2148
- * @param {int} [since] the earliest time in ms to fetch open orders for
2149
- * @param {int} [limit] the maximum number of open orders structures to retrieve
2150
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2151
- * @param {boolean} [params.trigger] whether the order is a trigger/algo order
2152
- * @param {string} [params.user] user address, will default to this.walletAddress if not provided
2153
- * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2154
- */
2155
- async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2156
- this.checkRequiredCredentials();
2157
- await this.loadMarkets();
2158
- let userAddress = undefined;
2159
- [userAddress, params] = this.handlePublicAddress('fetchOpenOrders', params);
2160
- const request = {};
2161
- let market = undefined;
2162
- const trigger = this.safeBool2(params, 'stop', 'trigger');
2163
- params = this.omit(params, ['stop', 'trigger']);
2164
- if (symbol !== undefined) {
2165
- market = this.market(symbol);
2166
- request['product_id'] = this.parseToNumeric(market['id']);
2167
- }
2168
- let response = undefined;
2169
- if (trigger) {
2170
- const contracts = await this.queryContracts();
2171
- const chainId = this.safeString(contracts, 'chain_id');
2172
- const verifyingContractAddress = this.safeString(contracts, 'endpoint_addr');
2173
- const tx = {
2174
- 'sender': this.convertAddressToSender(userAddress),
2175
- 'recvTime': this.nonce() + 90000,
2176
- };
2177
- request['signature'] = this.buildListTriggerTxSig(tx, chainId, verifyingContractAddress);
2178
- request['tx'] = {
2179
- 'sender': tx['sender'],
2180
- 'recvTime': this.numberToString(tx['recvTime']),
2181
- };
2182
- request['type'] = 'list_trigger_orders';
2183
- request['pending'] = true;
2184
- const until = this.safeInteger(params, 'until');
2185
- params = this.omit(params, 'until');
2186
- if (until !== undefined) {
2187
- request['max_update_time'] = until;
2188
- }
2189
- if (limit !== undefined) {
2190
- request['limit'] = limit;
2191
- }
2192
- response = await this.v1TriggerPostQuery(this.extend(request, params));
2193
- //
2194
- // {
2195
- // "status": "success",
2196
- // "data": {
2197
- // "orders": [
2198
- // {
2199
- // "order": {
2200
- // "order": {
2201
- // "sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
2202
- // "priceX18": "1000000000000000000",
2203
- // "amount": "1000000000000000000",
2204
- // "expiration": "2000000000",
2205
- // "nonce": "1",
2206
- // },
2207
- // "signature": "0x...",
2208
- // "product_id": 1,
2209
- // "spot_leverage": true,
2210
- // "trigger": {
2211
- // "price_above": "1000000000000000000"
2212
- // },
2213
- // "digest": "0x..."
2214
- // },
2215
- // "status": "pending",
2216
- // "updated_at": 1688768157050
2217
- // }
2218
- // ]
2219
- // },
2220
- // "request_type": "query_list_trigger_orders"
2221
- // }
2222
- //
2223
- }
2224
- else {
2225
- this.checkRequiredArgument('fetchOpenOrders', symbol, 'symbol');
2226
- request['type'] = 'subaccount_orders';
2227
- request['sender'] = this.convertAddressToSender(userAddress);
2228
- response = await this.v1GatewayPostQuery(this.extend(request, params));
2229
- //
2230
- // {
2231
- // "status": "success",
2232
- // "data": {
2233
- // "sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
2234
- // "product_id": 1,
2235
- // "orders": [
2236
- // {
2237
- // "product_id": 2,
2238
- // "sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
2239
- // "price_x18": "1000000000000000000",
2240
- // "amount": "1000000000000000000",
2241
- // "expiration": "2000000000",
2242
- // "nonce": "1",
2243
- // "order_type": "default",
2244
- // "unfilled_amount": "1000000000000000000",
2245
- // "digest": "0x0000000000000000000000000000000000000000000000000000000000000000",
2246
- // "placed_at": 1682437737,
2247
- // "order_type": "ioc"
2248
- // }
2249
- // ]
2250
- // },
2251
- // "request_type": "query_subaccount_orders"
2252
- // }
2253
- //
2254
- }
2255
- const data = this.safeDict(response, 'data', {});
2256
- const orders = this.safeList(data, 'orders');
2257
- return this.parseOrders(orders, market, since, limit);
2258
- }
2259
- /**
2260
- * @method
2261
- * @name vertex#fetchOrders
2262
- * @description fetches information on multiple orders made by the user
2263
- * @see https://docs.vertexprotocol.com/developer-resources/api/trigger/queries/list-trigger-orders
2264
- * @param {string} symbol unified market symbol
2265
- * @param {int} [since] the earliest time in ms to fetch open orders for
2266
- * @param {int} [limit] the maximum number of open orders structures to retrieve
2267
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2268
- * @param {boolean} [params.trigger] whether the order is a trigger/algo order
2269
- * @param {string} [params.user] user address, will default to this.walletAddress if not provided
2270
- * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2271
- */
2272
- async fetchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2273
- this.checkRequiredCredentials();
2274
- const trigger = this.safeBool2(params, 'stop', 'trigger');
2275
- params = this.omit(params, ['stop', 'trigger']);
2276
- if (!trigger) {
2277
- throw new NotSupported(this.id + ' fetchOrders only support trigger orders');
2278
- }
2279
- let userAddress = undefined;
2280
- [userAddress, params] = this.handlePublicAddress('fetchOrders', params);
2281
- await this.loadMarkets();
2282
- let market = undefined;
2283
- const request = {
2284
- 'type': 'list_trigger_orders',
2285
- 'pending': false,
2286
- };
2287
- if (symbol !== undefined) {
2288
- market = this.market(symbol);
2289
- request['product_id'] = this.parseToNumeric(market['id']);
2290
- }
2291
- const contracts = await this.queryContracts();
2292
- const chainId = this.safeString(contracts, 'chain_id');
2293
- const verifyingContractAddress = this.safeString(contracts, 'endpoint_addr');
2294
- const tx = {
2295
- 'sender': this.convertAddressToSender(userAddress),
2296
- 'recvTime': this.nonce() + 90000,
2297
- };
2298
- request['signature'] = this.buildListTriggerTxSig(tx, chainId, verifyingContractAddress);
2299
- request['tx'] = {
2300
- 'sender': tx['sender'],
2301
- 'recvTime': this.numberToString(tx['recvTime']),
2302
- };
2303
- const until = this.safeInteger(params, 'until');
2304
- params = this.omit(params, 'until');
2305
- if (until !== undefined) {
2306
- request['max_update_time'] = until;
2307
- }
2308
- if (limit !== undefined) {
2309
- request['limit'] = limit;
2310
- }
2311
- const response = await this.v1TriggerPostQuery(this.extend(request, params));
2312
- //
2313
- // {
2314
- // "status": "success",
2315
- // "data": {
2316
- // "orders": [
2317
- // {
2318
- // "order": {
2319
- // "order": {
2320
- // "sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43000000000000000000000000",
2321
- // "priceX18": "1000000000000000000",
2322
- // "amount": "1000000000000000000",
2323
- // "expiration": "2000000000",
2324
- // "nonce": "1",
2325
- // },
2326
- // "signature": "0x...",
2327
- // "product_id": 1,
2328
- // "spot_leverage": true,
2329
- // "trigger": {
2330
- // "price_above": "1000000000000000000"
2331
- // },
2332
- // "digest": "0x..."
2333
- // },
2334
- // "status": "pending",
2335
- // "updated_at": 1688768157050
2336
- // }
2337
- // ]
2338
- // },
2339
- // "request_type": "query_list_trigger_orders"
2340
- // }
2341
- //
2342
- const data = this.safeDict(response, 'data', {});
2343
- const orders = this.safeList(data, 'orders');
2344
- return this.parseOrders(orders, market, since, limit);
2345
- }
2346
- /**
2347
- * @method
2348
- * @name vertex#cancelAllOrders
2349
- * @see https://docs.vertexprotocol.com/developer-resources/api/gateway/executes/cancel-product-orders
2350
- * @see https://docs.vertexprotocol.com/developer-resources/api/trigger/executes/cancel-product-orders
2351
- * @description cancel all open orders in a market
2352
- * @param {string} symbol unified market symbol
2353
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2354
- * @param {boolean} [params.trigger] whether the order is a trigger/algo order
2355
- * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2356
- */
2357
- async cancelAllOrders(symbol = undefined, params = {}) {
2358
- this.checkRequiredCredentials();
2359
- await this.loadMarkets();
2360
- if (symbol === undefined) {
2361
- throw new ArgumentsRequired(this.id + ' cancelAllOrders() requires a symbol argument');
2362
- }
2363
- const market = this.market(symbol);
2364
- const marketId = market['id'];
2365
- const contracts = await this.queryContracts();
2366
- const chainId = this.safeString(contracts, 'chain_id');
2367
- const verifyingContractAddress = this.safeString(contracts, 'endpoint_addr');
2368
- const now = this.nonce();
2369
- const nonce = this.getNonce(now, 90000);
2370
- const cancels = {
2371
- 'sender': this.convertAddressToSender(this.walletAddress),
2372
- 'productIds': [
2373
- this.parseToNumeric(marketId),
2374
- ],
2375
- 'nonce': nonce,
2376
- };
2377
- const request = {
2378
- 'cancel_product_orders': {
2379
- 'tx': {
2380
- 'sender': cancels['sender'],
2381
- 'productIds': cancels['productIds'],
2382
- 'nonce': this.numberToString(cancels['nonce']),
2383
- },
2384
- 'signature': this.buildCancelAllOrdersSig(cancels, chainId, verifyingContractAddress),
2385
- },
2386
- };
2387
- const trigger = this.safeBool2(params, 'stop', 'trigger');
2388
- params = this.omit(params, ['stop', 'trigger']);
2389
- let response = undefined;
2390
- if (trigger) {
2391
- response = await this.v1TriggerPostExecute(this.extend(request, params));
2392
- //
2393
- // {
2394
- // "status": "success",
2395
- // "signature": {signature},
2396
- // "request_type": "execute_cancel_product_orders"
2397
- // }
2398
- //
2399
- }
2400
- else {
2401
- response = await this.v1GatewayPostExecute(this.extend(request, params));
2402
- //
2403
- // {
2404
- // "status": "success",
2405
- // "signature": {signature},
2406
- // "data": {
2407
- // "cancelled_orders": [
2408
- // {
2409
- // "product_id": 2,
2410
- // "sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
2411
- // "price_x18": "20000000000000000000000",
2412
- // "amount": "-100000000000000000",
2413
- // "expiration": "1686332748",
2414
- // "order_type": "post_only",
2415
- // "nonce": "1768248100142339392",
2416
- // "unfilled_amount": "-100000000000000000",
2417
- // "digest": "0x3195a7929feb8307edecf9c045j5ced68925108f0aa305f0ee5773854159377c",
2418
- // "placed_at": 1686332708
2419
- // },
2420
- // ...
2421
- // ]
2422
- // },
2423
- // "request_type": "execute_cancel_product_orders"
2424
- // }
2425
- //
2426
- }
2427
- return [this.safeOrder({ 'info': response })];
2428
- }
2429
- /**
2430
- * @method
2431
- * @name vertex#cancelOrder
2432
- * @description cancels an open order
2433
- * @see https://docs.vertexprotocol.com/developer-resources/api/gateway/executes/cancel-orders
2434
- * @see https://docs.vertexprotocol.com/developer-resources/api/trigger/executes/cancel-orders
2435
- * @param {string} id order id
2436
- * @param {string} symbol unified symbol of the market the order was made in
2437
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2438
- * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2439
- */
2440
- async cancelOrder(id, symbol = undefined, params = {}) {
2441
- const order = await this.cancelOrders([id], symbol, params);
2442
- return this.safeOrder({ 'info': order });
2443
- }
2444
- /**
2445
- * @method
2446
- * @name vertex#cancelOrders
2447
- * @description cancel multiple orders
2448
- * @see https://docs.vertexprotocol.com/developer-resources/api/gateway/executes/cancel-orders
2449
- * @see https://docs.vertexprotocol.com/developer-resources/api/trigger/executes/cancel-orders
2450
- * @param {string[]} ids order ids
2451
- * @param {string} [symbol] unified market symbol
2452
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2453
- * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2454
- */
2455
- async cancelOrders(ids, symbol = undefined, params = {}) {
2456
- this.checkRequiredCredentials();
2457
- if (symbol === undefined) {
2458
- throw new ArgumentsRequired(this.id + ' cancelOrders() requires a symbol argument');
2459
- }
2460
- await this.loadMarkets();
2461
- const market = this.market(symbol);
2462
- const marketId = market['id'];
2463
- const contracts = await this.queryContracts();
2464
- const chainId = this.safeString(contracts, 'chain_id');
2465
- const verifyingContractAddress = this.safeString(contracts, 'endpoint_addr');
2466
- const now = this.nonce();
2467
- const nonce = this.getNonce(now, 90000);
2468
- const cancels = {
2469
- 'sender': this.convertAddressToSender(this.walletAddress),
2470
- 'productIds': [],
2471
- 'digests': ids,
2472
- 'nonce': nonce,
2473
- };
2474
- const productIds = cancels['productIds'];
2475
- const marketIdNum = this.parseToNumeric(marketId);
2476
- for (let i = 0; i < ids.length; i++) {
2477
- productIds.push(marketIdNum);
2478
- }
2479
- const request = {
2480
- 'cancel_orders': {
2481
- 'tx': {
2482
- 'sender': cancels['sender'],
2483
- 'productIds': productIds,
2484
- 'digests': cancels['digests'],
2485
- 'nonce': this.numberToString(cancels['nonce']),
2486
- },
2487
- 'signature': this.buildCancelOrdersSig(cancels, chainId, verifyingContractAddress),
2488
- },
2489
- };
2490
- const trigger = this.safeBool2(params, 'stop', 'trigger');
2491
- params = this.omit(params, ['stop', 'trigger']);
2492
- let response = undefined;
2493
- if (trigger) {
2494
- response = await this.v1TriggerPostExecute(this.extend(request, params));
2495
- //
2496
- // {
2497
- // "status": "success",
2498
- // "signature": {signature},
2499
- // "request_type": "execute_cancel_orders"
2500
- // }
2501
- //
2502
- }
2503
- else {
2504
- response = await this.v1GatewayPostExecute(this.extend(request, params));
2505
- //
2506
- // {
2507
- // "status": "success",
2508
- // "signature": {signature},
2509
- // "data": {
2510
- // "cancelled_orders": [
2511
- // {
2512
- // "product_id": 2,
2513
- // "sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
2514
- // "price_x18": "20000000000000000000000",
2515
- // "amount": "-100000000000000000",
2516
- // "expiration": "1686332748",
2517
- // "order_type": "post_only",
2518
- // "nonce": "1768248100142339392",
2519
- // "unfilled_amount": "-100000000000000000",
2520
- // "digest": "0x3195a7929feb8307edecf9c045j5ced68925108f0aa305f0ee5773854159377c",
2521
- // "placed_at": 1686332708
2522
- // },
2523
- // ...
2524
- // ]
2525
- // },
2526
- // "request_type": "execute_cancel_orders"
2527
- // }
2528
- //
2529
- }
2530
- return response;
2531
- }
2532
- /**
2533
- * @method
2534
- * @name vertex#fetchBalance
2535
- * @description query for balance and get the amount of funds available for trading or funds locked in orders
2536
- * @see https://docs.vertexprotocol.com/developer-resources/api/gateway/queries/subaccount-info
2537
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2538
- * @param {string} [params.user] user address, will default to this.walletAddress if not provided
2539
- * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
2540
- */
2541
- async fetchBalance(params = {}) {
2542
- let userAddress = undefined;
2543
- [userAddress, params] = this.handlePublicAddress('fetchBalance', params);
2544
- const request = {
2545
- 'type': 'subaccount_info',
2546
- 'subaccount': this.convertAddressToSender(userAddress),
2547
- };
2548
- const response = await this.v1GatewayGetQuery(this.extend(request, params));
2549
- //
2550
- // {
2551
- // "status": "success",
2552
- // "data": {
2553
- // "subaccount": "0x265167ddfac55365d6ff07fc5943276319aa6b9f64656661756c740000000000",
2554
- // "exists": true,
2555
- // "healths": [
2556
- // {
2557
- // "assets": "75323297691833342306",
2558
- // "liabilities": "46329556869051092241",
2559
- // "health": "28993740822782250065"
2560
- // },
2561
- // {
2562
- // "assets": "75323297691833342306",
2563
- // "liabilities": "35968911700887320741",
2564
- // "health": "39354385990946021565"
2565
- // },
2566
- // {
2567
- // "assets": "80796966663601107565",
2568
- // "liabilities": "0",
2569
- // "health": "80796966663601107565"
2570
- // }
2571
- // ],
2572
- // "health_contributions": [
2573
- // [
2574
- // "75323297691833340000",
2575
- // "75323297691833340000",
2576
- // "75323297691833340000"
2577
- // ],
2578
- // [
2579
- // "0",
2580
- // "0",
2581
- // "0"
2582
- // ],
2583
- // [
2584
- // "0",
2585
- // "0",
2586
- // "0"
2587
- // ],
2588
- // [
2589
- // "0",
2590
- // "0",
2591
- // "0"
2592
- // ],
2593
- // [
2594
- // "-46329556869051090000",
2595
- // "-35968911700887323000",
2596
- // "5473668971767765000"
2597
- // ]
2598
- // ],
2599
- // "spot_count": 3,
2600
- // "perp_count": 2,
2601
- // "spot_balances": [
2602
- // {
2603
- // "product_id": 1,
2604
- // "lp_balance": {
2605
- // "amount": "0"
2606
- // },
2607
- // "balance": {
2608
- // "amount": "0",
2609
- // "last_cumulative_multiplier_x18": "1003419811982007193"
2610
- // }
2611
- // },
2612
- // {
2613
- // "product_id": 3,
2614
- // "lp_balance": {
2615
- // "amount": "0"
2616
- // },
2617
- // "balance": {
2618
- // "amount": "0",
2619
- // "last_cumulative_multiplier_x18": "1007584195035969404"
2620
- // }
2621
- // },
2622
- // {
2623
- // "product_id": 0,
2624
- // "lp_balance": {
2625
- // "amount": "0"
2626
- // },
2627
- // "balance": {
2628
- // "amount": "75323297691833342306",
2629
- // "last_cumulative_multiplier_x18": "1000000002391497578"
2630
- // }
2631
- // }
2632
- // ],
2633
- // "perp_balances": [
2634
- // {
2635
- // "product_id": 2,
2636
- // "lp_balance": {
2637
- // "amount": "0",
2638
- // "last_cumulative_funding_x18": "-284321955122859921"
2639
- // },
2640
- // "balance": {
2641
- // "amount": "0",
2642
- // "v_quote_balance": "0",
2643
- // "last_cumulative_funding_x18": "6363466629611946777168"
2644
- // }
2645
- // },
2646
- // {
2647
- // "product_id": 4,
2648
- // "lp_balance": {
2649
- // "amount": "0",
2650
- // "last_cumulative_funding_x18": "-90979748449893411"
2651
- // },
2652
- // "balance": {
2653
- // "amount": "-200000000000000000",
2654
- // "v_quote_balance": "419899475698318625259",
2655
- // "last_cumulative_funding_x18": "141182516563970577208"
2656
- // }
2657
- // }
2658
- // ],
2659
- // "spot_products": [
2660
- // {
2661
- // "product_id": 1,
2662
- // "oracle_price_x18": "30217830336443750750000",
2663
- // "risk": {
2664
- // "long_weight_initial_x18": "750000000000000000",
2665
- // "short_weight_initial_x18": "1250000000000000000",
2666
- // "long_weight_maintenance_x18": "800000000000000000",
2667
- // "short_weight_maintenance_x18": "1200000000000000000",
2668
- // "large_position_penalty_x18": "0"
2669
- // },
2670
- // "config": {
2671
- // "token": "0x5cc7c91690b2cbaee19a513473d73403e13fb431",
2672
- // "interest_inflection_util_x18": "800000000000000000",
2673
- // "interest_floor_x18": "10000000000000000",
2674
- // "interest_small_cap_x18": "40000000000000000",
2675
- // "interest_large_cap_x18": "1000000000000000000"
2676
- // },
2677
- // "state": {
2678
- // "cumulative_deposits_multiplier_x18": "1001304691727847318",
2679
- // "cumulative_borrows_multiplier_x18": "1003419811982007193",
2680
- // "total_deposits_normalized": "213107447159798397806318",
2681
- // "total_borrows_normalized": "4907820740150097483532"
2682
- // },
2683
- // "lp_state": {
2684
- // "supply": "1304981417419495030893348",
2685
- // "quote": {
2686
- // "amount": "2048495687410669565222259",
2687
- // "last_cumulative_multiplier_x18": "1000000002391497578"
2688
- // },
2689
- // "base": {
2690
- // "amount": "67623029247538886515",
2691
- // "last_cumulative_multiplier_x18": "1001304691727847318"
2692
- // }
2693
- // },
2694
- // "book_info": {
2695
- // "size_increment": "1000000000000000",
2696
- // "price_increment_x18": "1000000000000000000",
2697
- // "min_size": "10000000000000000",
2698
- // "collected_fees": "8865582805773573662738183",
2699
- // "lp_spread_x18": "3000000000000000"
2700
- // }
2701
- // },
2702
- // {
2703
- // "product_id": 3,
2704
- // "oracle_price_x18": "2075217009708333333333",
2705
- // "risk": {
2706
- // "long_weight_initial_x18": "750000000000000000",
2707
- // "short_weight_initial_x18": "1250000000000000000",
2708
- // "long_weight_maintenance_x18": "800000000000000000",
2709
- // "short_weight_maintenance_x18": "1200000000000000000",
2710
- // "large_position_penalty_x18": "0"
2711
- // },
2712
- // "config": {
2713
- // "token": "0xcc59686e3a32fb104c8ff84dd895676265efb8a6",
2714
- // "interest_inflection_util_x18": "800000000000000000",
2715
- // "interest_floor_x18": "10000000000000000",
2716
- // "interest_small_cap_x18": "40000000000000000",
2717
- // "interest_large_cap_x18": "1000000000000000000"
2718
- // },
2719
- // "state": {
2720
- // "cumulative_deposits_multiplier_x18": "1003722507760089346",
2721
- // "cumulative_borrows_multiplier_x18": "1007584195035969404",
2722
- // "total_deposits_normalized": "232750303205807326418622",
2723
- // "total_borrows_normalized": "110730726549469855171025"
2724
- // },
2725
- // "lp_state": {
2726
- // "supply": "902924999999999999774268",
2727
- // "quote": {
2728
- // "amount": "1165328092090344104989049",
2729
- // "last_cumulative_multiplier_x18": "1000000002391497578"
2730
- // },
2731
- // "base": {
2732
- // "amount": "563265647183403990588",
2733
- // "last_cumulative_multiplier_x18": "1003722507760089346"
2734
- // }
2735
- // },
2736
- // "book_info": {
2737
- // "size_increment": "10000000000000000",
2738
- // "price_increment_x18": "100000000000000000",
2739
- // "min_size": "100000000000000000",
2740
- // "collected_fees": "1801521329724633001446457",
2741
- // "lp_spread_x18": "3000000000000000"
2742
- // }
2743
- // },
2744
- // {
2745
- // "product_id": 0,
2746
- // "oracle_price_x18": "1000000000000000000",
2747
- // "risk": {
2748
- // "long_weight_initial_x18": "1000000000000000000",
2749
- // "short_weight_initial_x18": "1000000000000000000",
2750
- // "long_weight_maintenance_x18": "1000000000000000000",
2751
- // "short_weight_maintenance_x18": "1000000000000000000",
2752
- // "large_position_penalty_x18": "0"
2753
- // },
2754
- // "config": {
2755
- // "token": "0x179522635726710dd7d2035a81d856de4aa7836c",
2756
- // "interest_inflection_util_x18": "800000000000000000",
2757
- // "interest_floor_x18": "10000000000000000",
2758
- // "interest_small_cap_x18": "40000000000000000",
2759
- // "interest_large_cap_x18": "1000000000000000000"
2760
- // },
2761
- // "state": {
2762
- // "cumulative_deposits_multiplier_x18": "1000000002391497578",
2763
- // "cumulative_borrows_multiplier_x18": "1001593395547514024",
2764
- // "total_deposits_normalized": "60000256267437588885818752247843",
2765
- // "total_borrows_normalized": "391445043137305055810336885"
2766
- // },
2767
- // "lp_state": {
2768
- // "supply": "0",
2769
- // "quote": {
2770
- // "amount": "0",
2771
- // "last_cumulative_multiplier_x18": "0"
2772
- // },
2773
- // "base": {
2774
- // "amount": "0",
2775
- // "last_cumulative_multiplier_x18": "0"
2776
- // }
2777
- // },
2778
- // "book_info": {
2779
- // "size_increment": "0",
2780
- // "price_increment_x18": "0",
2781
- // "min_size": "0",
2782
- // "collected_fees": "0",
2783
- // "lp_spread_x18": "0"
2784
- // }
2785
- // }
2786
- // ],
2787
- // "perp_products": [
2788
- // {
2789
- // "product_id": 2,
2790
- // "oracle_price_x18": "30219079716463070000000",
2791
- // "risk": {
2792
- // "long_weight_initial_x18": "875000000000000000",
2793
- // "short_weight_initial_x18": "1125000000000000000",
2794
- // "long_weight_maintenance_x18": "900000000000000000",
2795
- // "short_weight_maintenance_x18": "1100000000000000000",
2796
- // "large_position_penalty_x18": "0"
2797
- // },
2798
- // "state": {
2799
- // "cumulative_funding_long_x18": "6363466629611946777168",
2800
- // "cumulative_funding_short_x18": "6363466629611946777168",
2801
- // "available_settle": "100612314098927536086702448",
2802
- // "open_interest": "57975708279961875623240"
2803
- // },
2804
- // "lp_state": {
2805
- // "supply": "783207415944433511804197",
2806
- // "last_cumulative_funding_x18": "6363466629611946777168",
2807
- // "cumulative_funding_per_lp_x18": "-284321955122859921",
2808
- // "base": "37321000000000000000",
2809
- // "quote": "1150991638943862165224593"
2810
- // },
2811
- // "book_info": {
2812
- // "size_increment": "1000000000000000",
2813
- // "price_increment_x18": "1000000000000000000",
2814
- // "min_size": "10000000000000000",
2815
- // "collected_fees": "7738341933653651206856235",
2816
- // "lp_spread_x18": "3000000000000000"
2817
- // }
2818
- // },
2819
- // {
2820
- // "product_id": 4,
2821
- // "oracle_price_x18": "2072129033632754300000",
2822
- // "risk": {
2823
- // "long_weight_initial_x18": "875000000000000000",
2824
- // "short_weight_initial_x18": "1125000000000000000",
2825
- // "long_weight_maintenance_x18": "900000000000000000",
2826
- // "short_weight_maintenance_x18": "1100000000000000000",
2827
- // "large_position_penalty_x18": "0"
2828
- // },
2829
- // "state": {
2830
- // "cumulative_funding_long_x18": "141182516563970577208",
2831
- // "cumulative_funding_short_x18": "141182516563970577208",
2832
- // "available_settle": "33807443862986950288685582",
2833
- // "open_interest": "316343836992291503987611"
2834
- // },
2835
- // "lp_state": {
2836
- // "supply": "541756546038144467864559",
2837
- // "last_cumulative_funding_x18": "141182516563970577208",
2838
- // "cumulative_funding_per_lp_x18": "-90979748449893411",
2839
- // "base": "362320000000000000000",
2840
- // "quote": "750080187685127907834038"
2841
- // },
2842
- // "book_info": {
2843
- // "size_increment": "10000000000000000",
2844
- // "price_increment_x18": "100000000000000000",
2845
- // "min_size": "100000000000000000",
2846
- // "collected_fees": "1893278317732551619694831",
2847
- // "lp_spread_x18": "3000000000000000"
2848
- // }
2849
- // }
2850
- // ]
2851
- // },
2852
- // "request_type": "query_subaccount_info"
2853
- // }
2854
- //
2855
- const data = this.safeDict(response, 'data', {});
2856
- const balances = this.safeList(data, 'spot_balances', []);
2857
- const result = { 'info': response };
2858
- for (let i = 0; i < balances.length; i++) {
2859
- const balance = balances[i];
2860
- const marketId = this.safeString(balance, 'product_id');
2861
- const market = this.safeMarket(marketId);
2862
- const isUsdcMarketId = marketId === '0';
2863
- if (market['id'] === undefined && !isUsdcMarketId) {
2864
- continue;
2865
- }
2866
- const baseId = (isUsdcMarketId) ? 'USDC' : this.safeString(market, 'baseId');
2867
- const code = this.safeCurrencyCode(baseId);
2868
- const account = this.account();
2869
- const tokenBalance = this.safeDict(balance, 'balance', {});
2870
- const total = this.convertFromX18(this.safeString(tokenBalance, 'amount'));
2871
- account['total'] = total;
2872
- result[code] = account;
2873
- }
2874
- return this.safeBalance(result);
2875
- }
2876
- parsePosition(position, market = undefined) {
2877
- //
2878
- // {
2879
- // "product_id": 2,
2880
- // "lp_balance": {
2881
- // "amount": "0",
2882
- // "last_cumulative_funding_x18": "-284321955122859921"
2883
- // },
2884
- // "balance": {
2885
- // "amount": "0",
2886
- // "v_quote_balance": "0",
2887
- // "last_cumulative_funding_x18": "6363466629611946777168"
2888
- // }
2889
- // },
2890
- // {
2891
- // "product_id": 4,
2892
- // "lp_balance": {
2893
- // "amount": "0",
2894
- // "last_cumulative_funding_x18": "-90979748449893411"
2895
- // },
2896
- // "balance": {
2897
- // "amount": "-200000000000000000",
2898
- // "v_quote_balance": "419899475698318625259",
2899
- // "last_cumulative_funding_x18": "141182516563970577208"
2900
- // }
2901
- // }
2902
- //
2903
- const marketId = this.safeString(position, 'product_id');
2904
- market = this.safeMarket(marketId);
2905
- const balance = this.safeDict(position, 'balance', {});
2906
- const contractSize = this.convertFromX18(this.safeString(balance, 'amount'));
2907
- let side = 'buy';
2908
- if (Precise.stringLt(contractSize, '1')) {
2909
- side = 'sell';
2910
- }
2911
- return this.safePosition({
2912
- 'info': position,
2913
- 'id': undefined,
2914
- 'symbol': this.safeString(market, 'symbol'),
2915
- 'timestamp': undefined,
2916
- 'datetime': undefined,
2917
- 'lastUpdateTimestamp': undefined,
2918
- 'initialMargin': undefined,
2919
- 'initialMarginPercentage': undefined,
2920
- 'maintenanceMargin': undefined,
2921
- 'maintenanceMarginPercentage': undefined,
2922
- 'entryPrice': undefined,
2923
- 'notional': undefined,
2924
- 'leverage': undefined,
2925
- 'unrealizedPnl': undefined,
2926
- 'contracts': undefined,
2927
- 'contractSize': this.parseToNumeric(contractSize),
2928
- 'marginRatio': undefined,
2929
- 'liquidationPrice': undefined,
2930
- 'markPrice': undefined,
2931
- 'lastPrice': undefined,
2932
- 'collateral': undefined,
2933
- 'marginMode': 'cross',
2934
- 'marginType': undefined,
2935
- 'side': side,
2936
- 'percentage': undefined,
2937
- 'hedged': undefined,
2938
- 'stopLossPrice': undefined,
2939
- 'takeProfitPrice': undefined,
2940
- });
2941
- }
2942
- /**
2943
- * @method
2944
- * @name vertex#fetchPositions
2945
- * @description fetch all open positions
2946
- * @see https://docs.vertexprotocol.com/developer-resources/api/gateway/queries/subaccount-info
2947
- * @param {string[]} [symbols] list of unified market symbols
2948
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2949
- * @param {string} [params.user] user address, will default to this.walletAddress if not provided
2950
- * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
2951
- */
2952
- async fetchPositions(symbols = undefined, params = {}) {
2953
- let userAddress = undefined;
2954
- [userAddress, params] = this.handlePublicAddress('fetchPositions', params);
2955
- const request = {
2956
- 'type': 'subaccount_info',
2957
- 'subaccount': this.convertAddressToSender(userAddress),
2958
- };
2959
- const response = await this.v1GatewayGetQuery(this.extend(request, params));
2960
- // the response is the same as fetchBalance
2961
- const data = this.safeDict(response, 'data', {});
2962
- const positions = this.safeList(data, 'perp_balances', []);
2963
- symbols = this.marketSymbols(symbols);
2964
- const result = [];
2965
- for (let i = 0; i < positions.length; i++) {
2966
- const position = this.extend(this.parsePosition(positions[i], undefined), params);
2967
- if (position['contractSize'] === 0) {
2968
- continue;
2969
- }
2970
- result.push(position);
2971
- }
2972
- return this.filterByArrayPositions(result, 'symbol', symbols, false);
2973
- }
2974
- async queryNonces() {
2975
- const request = {
2976
- 'type': 'nonces',
2977
- 'address': this.walletAddress,
2978
- };
2979
- const response = await this.v1GatewayGetQuery(request);
2980
- //
2981
- // {
2982
- // "status":"success",
2983
- // "data":{
2984
- // "tx_nonce": 0,
2985
- // "order_nonce": 1753048133299863552
2986
- // },
2987
- // "request_type": "query_nonces",
2988
- // }
2989
- //
2990
- return this.safeDict(response, 'data', {});
2991
- }
2992
- /**
2993
- * @method
2994
- * @name vertex#withdraw
2995
- * @description make a withdrawal
2996
- * @see https://docs.vertexprotocol.com/developer-resources/api/withdrawing-on-chain
2997
- * @param {string} code unified currency code
2998
- * @param {float} amount the amount to withdraw
2999
- * @param {string} address the address to withdraw to
3000
- * @param {string} tag
3001
- * @param {object} [params] extra parameters specific to the exchange API endpoint
3002
- * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
3003
- */
3004
- async withdraw(code, amount, address, tag = undefined, params = {}) {
3005
- this.checkRequiredCredentials();
3006
- await this.loadMarkets();
3007
- const currency = this.currency(code);
3008
- const contracts = await this.queryContracts();
3009
- const chainId = this.safeString(contracts, 'chain_id');
3010
- const verifyingContractAddress = this.safeString(contracts, 'endpoint_addr');
3011
- const nonces = await this.queryNonces();
3012
- const nonce = this.safeNumber(nonces, 'tx_nonce');
3013
- const withdraw = {
3014
- 'sender': this.convertAddressToSender(this.walletAddress),
3015
- 'productId': this.parseToNumeric(currency['id']),
3016
- 'amount': amount.toString(),
3017
- 'nonce': nonce,
3018
- };
3019
- const request = {
3020
- 'withdraw_collateral': {
3021
- 'tx': {
3022
- 'sender': withdraw['sender'],
3023
- 'productId': withdraw['productId'],
3024
- 'amount': withdraw['amount'],
3025
- 'nonce': this.numberToString(withdraw['nonce']),
3026
- },
3027
- 'signature': this.buildWithdrawSig(withdraw, chainId, verifyingContractAddress),
3028
- },
3029
- };
3030
- const response = await this.v1GatewayPostExecute(this.extend(request, params));
3031
- //
3032
- // {
3033
- // "status": "success",
3034
- // "signature": {signature},
3035
- // "request_type": "execute_withdraw_collateral"
3036
- // }
3037
- //
3038
- const transaction = this.parseTransaction(response, currency);
3039
- return this.extend(transaction, {
3040
- 'amount': amount,
3041
- 'address': address,
3042
- });
3043
- }
3044
- parseTransaction(transaction, currency = undefined) {
3045
- //
3046
- // {
3047
- // "status": "success",
3048
- // "signature": {signature},
3049
- // "request_type": "execute_withdraw_collateral"
3050
- // }
3051
- //
3052
- let code = undefined;
3053
- if (currency !== undefined) {
3054
- code = currency['code'];
3055
- }
3056
- return {
3057
- 'info': transaction,
3058
- 'id': undefined,
3059
- 'txid': undefined,
3060
- 'timestamp': undefined,
3061
- 'datetime': undefined,
3062
- 'addressFrom': undefined,
3063
- 'address': undefined,
3064
- 'addressTo': undefined,
3065
- 'tagFrom': undefined,
3066
- 'tag': undefined,
3067
- 'tagTo': undefined,
3068
- 'type': 'withdrawal',
3069
- 'amount': undefined,
3070
- 'currency': code,
3071
- 'status': this.parseTransactionStatus(this.safeString(transaction, 'status')),
3072
- 'updated': undefined,
3073
- 'network': undefined,
3074
- 'comment': undefined,
3075
- 'internal': undefined,
3076
- 'fee': undefined,
3077
- };
3078
- }
3079
- parseTransactionStatus(status) {
3080
- const statuses = {
3081
- 'success': 'ok',
3082
- };
3083
- return this.safeString(statuses, status, status);
3084
- }
3085
- handlePublicAddress(methodName, params) {
3086
- let userAux = undefined;
3087
- [userAux, params] = this.handleOptionAndParams(params, methodName, 'user');
3088
- let user = userAux;
3089
- [user, params] = this.handleOptionAndParams(params, methodName, 'address', userAux);
3090
- if ((user !== undefined) && (user !== '')) {
3091
- return [user, params];
3092
- }
3093
- if ((this.walletAddress !== undefined) && (this.walletAddress !== '')) {
3094
- return [this.walletAddress, params];
3095
- }
3096
- throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires a user parameter inside \'params\' or the wallet address set');
3097
- }
3098
- handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
3099
- if (!response) {
3100
- return undefined; // fallback to default error handler
3101
- }
3102
- //
3103
- //
3104
- const status = this.safeString(response, 'status', '');
3105
- if (status === 'failure') {
3106
- const message = this.safeString(response, 'error');
3107
- const feedback = this.id + ' ' + body;
3108
- const errorCode = this.safeString(response, 'error_code');
3109
- this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
3110
- this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
3111
- throw new ExchangeError(feedback);
3112
- }
3113
- return undefined;
3114
- }
3115
- sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
3116
- const version = this.safeString(api, 0);
3117
- const type = this.safeString(api, 1);
3118
- let url = this.implodeHostname(this.urls['api'][version][type]);
3119
- if (version !== 'v1' || type !== 'archive') {
3120
- url = url + '/' + path;
3121
- }
3122
- if (method === 'POST') {
3123
- headers = {
3124
- 'Content-Type': 'application/json',
3125
- };
3126
- body = this.json(params);
3127
- }
3128
- else {
3129
- if (Object.keys(params).length) {
3130
- url += '?' + this.urlencode(params);
3131
- }
3132
- }
3133
- if (path !== 'execute') {
3134
- // required encoding for public methods
3135
- if (headers !== undefined) {
3136
- headers['Accept-Encoding'] = 'gzip';
3137
- }
3138
- else {
3139
- headers = {
3140
- 'Accept-Encoding': 'gzip',
3141
- };
3142
- }
3143
- }
3144
- return { 'url': url, 'method': method, 'body': body, 'headers': headers };
3145
- }
3146
- }