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.
- package/README.md +110 -112
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/ccxt.js +1 -9
- package/dist/cjs/src/ascendex.js +1 -1
- package/dist/cjs/src/binance.js +20 -14
- package/dist/cjs/src/bitget.js +1 -1
- package/dist/cjs/src/indodax.js +11 -12
- package/dist/cjs/src/okx.js +2 -2
- package/dist/cjs/src/poloniex.js +1 -1
- package/dist/cjs/src/pro/bitget.js +161 -26
- package/dist/cjs/src/pro/bitmart.js +1 -1
- package/dist/cjs/src/pro/gemini.js +7 -2
- package/dist/cjs/src/pro/hyperliquid.js +5 -0
- package/dist/cjs/src/pro/kraken.js +4 -6
- package/dist/cjs/src/zonda.js +12 -0
- package/js/ccxt.d.ts +2 -11
- package/js/ccxt.js +2 -8
- package/js/src/ascendex.js +1 -1
- package/js/src/binance.d.ts +1 -1
- package/js/src/binance.js +20 -14
- package/js/src/bitget.js +1 -1
- package/js/src/indodax.js +11 -12
- package/js/src/okx.js +2 -2
- package/js/src/poloniex.js +1 -1
- package/js/src/pro/bitget.d.ts +4 -0
- package/js/src/pro/bitget.js +167 -26
- package/js/src/pro/bitmart.js +1 -1
- package/js/src/pro/gemini.d.ts +1 -1
- package/js/src/pro/gemini.js +7 -2
- package/js/src/pro/hyperliquid.js +5 -0
- package/js/src/pro/kraken.js +4 -6
- package/js/src/zonda.js +12 -0
- package/package.json +2 -1
- package/js/src/abstract/ellipx.d.ts +0 -28
- package/js/src/abstract/ellipx.js +0 -11
- package/js/src/abstract/vertex.d.ts +0 -22
- package/js/src/abstract/vertex.js +0 -11
- package/js/src/ellipx.d.ts +0 -237
- package/js/src/ellipx.js +0 -2071
- package/js/src/pro/vertex.d.ts +0 -104
- package/js/src/pro/vertex.js +0 -999
- package/js/src/vertex.d.ts +0 -346
- 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
|
-
}
|