ccxt 4.4.35 → 4.4.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +10 -9
  2. package/dist/ccxt.browser.min.js +2 -2
  3. package/dist/cjs/ccxt.js +11 -6
  4. package/dist/cjs/src/abstract/bitfinex1.js +9 -0
  5. package/dist/cjs/src/abstract/defx.js +9 -0
  6. package/dist/cjs/src/base/Exchange.js +6 -1
  7. package/dist/cjs/src/bitfinex.js +3178 -1161
  8. package/dist/cjs/src/bitfinex1.js +1760 -0
  9. package/dist/cjs/src/bitfinex2.js +20 -12
  10. package/dist/cjs/src/bitmex.js +103 -1
  11. package/dist/cjs/src/bitopro.js +22 -4
  12. package/dist/cjs/src/bitso.js +2 -1
  13. package/dist/cjs/src/bybit.js +20 -0
  14. package/dist/cjs/src/coinbase.js +87 -0
  15. package/dist/cjs/src/defx.js +2048 -0
  16. package/dist/cjs/src/deribit.js +34 -14
  17. package/dist/cjs/src/gate.js +16 -2
  18. package/dist/cjs/src/hashkey.js +1 -1
  19. package/dist/cjs/src/htx.js +14 -2
  20. package/dist/cjs/src/hyperliquid.js +125 -14
  21. package/dist/cjs/src/kraken.js +39 -48
  22. package/dist/cjs/src/paradex.js +4 -2
  23. package/dist/cjs/src/pro/bitfinex.js +760 -271
  24. package/dist/cjs/src/pro/bitfinex1.js +675 -0
  25. package/dist/cjs/src/pro/defx.js +864 -0
  26. package/dist/cjs/src/pro/probit.js +1 -0
  27. package/js/ccxt.d.ts +14 -8
  28. package/js/ccxt.js +10 -6
  29. package/js/src/abstract/bitfinex.d.ts +135 -64
  30. package/js/src/abstract/bitfinex1.d.ts +72 -0
  31. package/js/src/abstract/bitopro.d.ts +1 -0
  32. package/js/src/abstract/bybit.d.ts +15 -0
  33. package/js/src/abstract/defx.d.ts +72 -0
  34. package/js/src/abstract/defx.js +11 -0
  35. package/js/src/abstract/deribit.d.ts +1 -0
  36. package/js/src/abstract/gate.d.ts +14 -0
  37. package/js/src/abstract/gateio.d.ts +14 -0
  38. package/js/src/base/Exchange.js +6 -1
  39. package/js/src/bitfinex.d.ts +316 -106
  40. package/js/src/bitfinex.js +3179 -1162
  41. package/js/src/bitfinex1.d.ts +296 -0
  42. package/js/src/bitfinex1.js +1761 -0
  43. package/js/src/bitfinex2.js +21 -13
  44. package/js/src/bitmex.js +103 -1
  45. package/js/src/bitopro.d.ts +11 -0
  46. package/js/src/bitopro.js +22 -4
  47. package/js/src/bitso.js +2 -1
  48. package/js/src/bybit.js +20 -0
  49. package/js/src/coinbase.d.ts +33 -0
  50. package/js/src/coinbase.js +87 -0
  51. package/js/src/defx.d.ts +349 -0
  52. package/js/src/defx.js +2049 -0
  53. package/js/src/deribit.d.ts +2 -0
  54. package/js/src/deribit.js +34 -14
  55. package/js/src/gate.js +16 -2
  56. package/js/src/hashkey.js +1 -1
  57. package/js/src/htx.d.ts +3 -0
  58. package/js/src/htx.js +14 -2
  59. package/js/src/hyperliquid.d.ts +6 -1
  60. package/js/src/hyperliquid.js +125 -14
  61. package/js/src/kraken.js +39 -48
  62. package/js/src/paradex.d.ts +2 -0
  63. package/js/src/paradex.js +4 -2
  64. package/js/src/pro/bitfinex.d.ts +42 -10
  65. package/js/src/pro/bitfinex.js +761 -272
  66. package/js/src/pro/bitfinex1.d.ts +67 -0
  67. package/js/src/pro/bitfinex1.js +676 -0
  68. package/js/src/pro/defx.d.ts +236 -0
  69. package/js/src/pro/defx.js +865 -0
  70. package/js/src/pro/probit.js +1 -0
  71. package/package.json +1 -1
  72. package/js/src/abstract/bitfinex2.d.ts +0 -143
  73. /package/js/src/abstract/{bitfinex2.js → bitfinex1.js} +0 -0
@@ -0,0 +1,865 @@
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 defxRest from '../defx.js';
9
+ import { ArgumentsRequired, ExchangeError } from '../base/errors.js';
10
+ import { ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp } from '../base/ws/Cache.js';
11
+ // ---------------------------------------------------------------------------
12
+ export default class defx extends defxRest {
13
+ describe() {
14
+ return this.deepExtend(super.describe(), {
15
+ 'has': {
16
+ 'ws': true,
17
+ 'watchBalance': true,
18
+ 'watchTicker': true,
19
+ 'watchTickers': true,
20
+ 'watchBidsAsks': true,
21
+ 'watchTrades': true,
22
+ 'watchTradesForSymbols': true,
23
+ 'watchMyTrades': false,
24
+ 'watchOrders': true,
25
+ 'watchOrderBook': true,
26
+ 'watchOrderBookForSymbols': true,
27
+ 'watchOHLCV': true,
28
+ 'watchOHLCVForSymbols': true,
29
+ },
30
+ 'urls': {
31
+ 'test': {
32
+ 'ws': {
33
+ 'public': 'wss://stream.testnet.defx.com/pricefeed',
34
+ 'private': 'wss://ws.testnet.defx.com/user',
35
+ },
36
+ },
37
+ 'api': {
38
+ 'ws': {
39
+ 'public': 'wss://marketfeed.api.defx.com/pricefeed',
40
+ 'private': 'wss://userfeed.api.defx.com/user',
41
+ },
42
+ },
43
+ },
44
+ 'options': {
45
+ 'listenKeyRefreshRate': 3540000,
46
+ 'ws': {
47
+ 'timeframes': {
48
+ '1m': '1m',
49
+ '3m': '3m',
50
+ '5m': '5m',
51
+ '15m': '15m',
52
+ '30m': '30m',
53
+ '1h': '1h',
54
+ '2h': '2h',
55
+ '4h': '4h',
56
+ '12h': '12h',
57
+ '1d': '1d',
58
+ '1w': '1w',
59
+ '1M': '1M',
60
+ },
61
+ },
62
+ },
63
+ 'streaming': {},
64
+ 'exceptions': {},
65
+ });
66
+ }
67
+ async watchPublic(topics, messageHashes, params = {}) {
68
+ await this.loadMarkets();
69
+ const url = this.urls['api']['ws']['public'];
70
+ const request = {
71
+ 'method': 'SUBSCRIBE',
72
+ 'topics': topics,
73
+ };
74
+ const message = this.extend(request, params);
75
+ return await this.watchMultiple(url, messageHashes, message, messageHashes);
76
+ }
77
+ async unWatchPublic(topics, messageHashes, params = {}) {
78
+ await this.loadMarkets();
79
+ const url = this.urls['api']['ws']['public'];
80
+ const request = {
81
+ 'method': 'UNSUBSCRIBE',
82
+ 'topics': topics,
83
+ };
84
+ const message = this.extend(request, params);
85
+ return await this.watchMultiple(url, messageHashes, message, messageHashes);
86
+ }
87
+ /**
88
+ * @method
89
+ * @name defx#watchOHLCV
90
+ * @description watches historical candlestick data containing the open, high, low, close price, and the volume of a market
91
+ * @see https://www.postman.com/defxcode/defx-public-apis/collection/667939a1b5d8069c13d614e9
92
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
93
+ * @param {string} timeframe the length of time each candle represents
94
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
95
+ * @param {int} [limit] the maximum amount of candles to fetch
96
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
97
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
98
+ */
99
+ async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
100
+ const result = await this.watchOHLCVForSymbols([[symbol, timeframe]], since, limit, params);
101
+ return result[symbol][timeframe];
102
+ }
103
+ /**
104
+ * @method
105
+ * @name defx#unWatchOHLCV
106
+ * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
107
+ * @see https://www.postman.com/defxcode/defx-public-apis/collection/667939a1b5d8069c13d614e9
108
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
109
+ * @param {string} timeframe the length of time each candle represents
110
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
111
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
112
+ */
113
+ async unWatchOHLCV(symbol, timeframe = '1m', params = {}) {
114
+ return await this.unWatchOHLCVForSymbols([[symbol, timeframe]], params);
115
+ }
116
+ /**
117
+ * @method
118
+ * @name defx#watchOHLCVForSymbols
119
+ * @description watches historical candlestick data containing the open, high, low, close price, and the volume of a market
120
+ * @see https://www.postman.com/defxcode/defx-public-apis/collection/667939a1b5d8069c13d614e9
121
+ * @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
122
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
123
+ * @param {int} [limit] the maximum amount of candles to fetch
124
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
125
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
126
+ */
127
+ async watchOHLCVForSymbols(symbolsAndTimeframes, since = undefined, limit = undefined, params = {}) {
128
+ const symbolsLength = symbolsAndTimeframes.length;
129
+ if (symbolsLength === 0 || !Array.isArray(symbolsAndTimeframes[0])) {
130
+ throw new ArgumentsRequired(this.id + " watchOHLCVForSymbols() requires a an array of symbols and timeframes, like [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]");
131
+ }
132
+ await this.loadMarkets();
133
+ const topics = [];
134
+ const messageHashes = [];
135
+ for (let i = 0; i < symbolsAndTimeframes.length; i++) {
136
+ const symbolAndTimeframe = symbolsAndTimeframes[i];
137
+ const marketId = this.safeString(symbolAndTimeframe, 0);
138
+ const market = this.market(marketId);
139
+ const tf = this.safeString(symbolAndTimeframe, 1);
140
+ const interval = this.safeString(this.timeframes, tf, tf);
141
+ topics.push('symbol:' + market['id'] + ':ohlc:' + interval);
142
+ messageHashes.push('candles:' + interval + ':' + market['symbol']);
143
+ }
144
+ const [symbol, timeframe, candles] = await this.watchPublic(topics, messageHashes, params);
145
+ if (this.newUpdates) {
146
+ limit = candles.getLimit(symbol, limit);
147
+ }
148
+ const filtered = this.filterBySinceLimit(candles, since, limit, 0, true);
149
+ return this.createOHLCVObject(symbol, timeframe, filtered);
150
+ }
151
+ /**
152
+ * @method
153
+ * @name defx#unWatchOHLCVForSymbols
154
+ * @description unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
155
+ * @see https://www.postman.com/defxcode/defx-public-apis/collection/667939a1b5d8069c13d614e9
156
+ * @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
157
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
158
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
159
+ */
160
+ async unWatchOHLCVForSymbols(symbolsAndTimeframes, params = {}) {
161
+ const symbolsLength = symbolsAndTimeframes.length;
162
+ if (symbolsLength === 0 || !Array.isArray(symbolsAndTimeframes[0])) {
163
+ throw new ArgumentsRequired(this.id + " unWatchOHLCVForSymbols() requires a an array of symbols and timeframes, like [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]");
164
+ }
165
+ await this.loadMarkets();
166
+ const topics = [];
167
+ const messageHashes = [];
168
+ for (let i = 0; i < symbolsAndTimeframes.length; i++) {
169
+ const symbolAndTimeframe = symbolsAndTimeframes[i];
170
+ const marketId = this.safeString(symbolAndTimeframe, 0);
171
+ const market = this.market(marketId);
172
+ const tf = this.safeString(symbolAndTimeframe, 1);
173
+ const interval = this.safeString(this.timeframes, tf, tf);
174
+ topics.push('symbol:' + market['id'] + ':ohlc:' + interval);
175
+ messageHashes.push('candles:' + interval + ':' + market['symbol']);
176
+ }
177
+ return await this.unWatchPublic(topics, messageHashes, params);
178
+ }
179
+ handleOHLCV(client, message) {
180
+ //
181
+ // {
182
+ // "topic": "symbol:BTC_USDC:ohlc:3m",
183
+ // "event": "ohlc",
184
+ // "timestamp": 1730794277104,
185
+ // "data": {
186
+ // "symbol": "BTC_USDC",
187
+ // "window": "3m",
188
+ // "open": "57486.90000000",
189
+ // "high": "57486.90000000",
190
+ // "low": "57486.90000000",
191
+ // "close": "57486.90000000",
192
+ // "volume": "0.000",
193
+ // "quoteAssetVolume": "0.00000000",
194
+ // "takerBuyAssetVolume": "0.000",
195
+ // "takerBuyQuoteAssetVolume": "0.00000000",
196
+ // "numberOfTrades": 0,
197
+ // "start": 1730794140000,
198
+ // "end": 1730794320000,
199
+ // "isClosed": false
200
+ // }
201
+ // }
202
+ //
203
+ const data = this.safeDict(message, 'data', {});
204
+ const marketId = this.safeString(data, 'symbol');
205
+ const market = this.market(marketId);
206
+ const symbol = market['symbol'];
207
+ const timeframe = this.safeString(data, 'window');
208
+ if (!(symbol in this.ohlcvs)) {
209
+ this.ohlcvs[symbol] = {};
210
+ }
211
+ if (!(timeframe in this.ohlcvs[symbol])) {
212
+ const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
213
+ const stored = new ArrayCacheByTimestamp(limit);
214
+ this.ohlcvs[symbol][timeframe] = stored;
215
+ }
216
+ const ohlcv = this.ohlcvs[symbol][timeframe];
217
+ const parsed = this.parseOHLCV(data);
218
+ ohlcv.append(parsed);
219
+ const messageHash = 'candles:' + timeframe + ':' + symbol;
220
+ client.resolve([symbol, timeframe, ohlcv], messageHash);
221
+ }
222
+ /**
223
+ * @method
224
+ * @name defx#watchTicker
225
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
226
+ * @see https://www.postman.com/defxcode/defx-public-apis/collection/667939a1b5d8069c13d614e9
227
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
228
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
229
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
230
+ */
231
+ async watchTicker(symbol, params = {}) {
232
+ await this.loadMarkets();
233
+ const market = this.market(symbol);
234
+ symbol = market['symbol'];
235
+ const topic = 'symbol:' + market['id'] + ':24hrTicker';
236
+ const messageHash = 'ticker:' + symbol;
237
+ return await this.watchPublic([topic], [messageHash], params);
238
+ }
239
+ /**
240
+ * @method
241
+ * @name defx#unWatchTicker
242
+ * @description unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
243
+ * @see https://www.postman.com/defxcode/defx-public-apis/collection/667939a1b5d8069c13d614e9
244
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
245
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
246
+ * @param {string} [params.channel] the channel to subscribe to, tickers by default. Can be tickers, sprd-tickers, index-tickers, block-tickers
247
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
248
+ */
249
+ async unWatchTicker(symbol, params = {}) {
250
+ return await this.unWatchTickers([symbol], params);
251
+ }
252
+ /**
253
+ * @method
254
+ * @name defx#watchTickers
255
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
256
+ * @see https://www.postman.com/defxcode/defx-public-apis/collection/667939a1b5d8069c13d614e9
257
+ * @param {string[]} [symbols] unified symbol of the market to fetch the ticker for
258
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
259
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
260
+ */
261
+ async watchTickers(symbols = undefined, params = {}) {
262
+ await this.loadMarkets();
263
+ symbols = this.marketSymbols(symbols, undefined, false);
264
+ const topics = [];
265
+ const messageHashes = [];
266
+ for (let i = 0; i < symbols.length; i++) {
267
+ const symbol = symbols[i];
268
+ const marketId = this.marketId(symbol);
269
+ topics.push('symbol:' + marketId + ':24hrTicker');
270
+ messageHashes.push('ticker:' + symbol);
271
+ }
272
+ await this.watchPublic(topics, messageHashes, params);
273
+ return this.filterByArray(this.tickers, 'symbol', symbols);
274
+ }
275
+ /**
276
+ * @method
277
+ * @name defx#unWatchTickers
278
+ * @description unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
279
+ * @see https://www.postman.com/defxcode/defx-public-apis/collection/667939a1b5d8069c13d614e9
280
+ * @param {string[]} [symbols] unified symbol of the market to fetch the ticker for
281
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
282
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
283
+ */
284
+ async unWatchTickers(symbols = undefined, params = {}) {
285
+ await this.loadMarkets();
286
+ symbols = this.marketSymbols(symbols, undefined, false);
287
+ const topics = [];
288
+ const messageHashes = [];
289
+ for (let i = 0; i < symbols.length; i++) {
290
+ const symbol = symbols[i];
291
+ const marketId = this.marketId(symbol);
292
+ topics.push('symbol:' + marketId + ':24hrTicker');
293
+ messageHashes.push('ticker:' + symbol);
294
+ }
295
+ return await this.unWatchPublic(topics, messageHashes, params);
296
+ }
297
+ handleTicker(client, message) {
298
+ //
299
+ // {
300
+ // "topic": "symbol:BTC_USDC:24hrTicker",
301
+ // "event": "24hrTicker",
302
+ // "timestamp": 1730862543095,
303
+ // "data": {
304
+ // "symbol": "BTC_USDC",
305
+ // "priceChange": "17114.70000000",
306
+ // "priceChangePercent": "29.77",
307
+ // "weightedAvgPrice": "6853147668",
308
+ // "lastPrice": "74378.90000000",
309
+ // "lastQty": "0.107",
310
+ // "bestBidPrice": "61987.60000000",
311
+ // "bestBidQty": "0.005",
312
+ // "bestAskPrice": "84221.60000000",
313
+ // "bestAskQty": "0.015",
314
+ // "openPrice": "57486.90000000",
315
+ // "highPrice": "88942.60000000",
316
+ // "lowPrice": "47364.20000000",
317
+ // "volume": "28.980",
318
+ // "quoteVolume": "1986042.19424035",
319
+ // "openTime": 1730776080000,
320
+ // "closeTime": 1730862540000,
321
+ // "openInterestBase": "67.130",
322
+ // "openInterestQuote": "5008005.40800000"
323
+ // }
324
+ // }
325
+ //
326
+ this.handleBidAsk(client, message);
327
+ const data = this.safeDict(message, 'data', {});
328
+ const parsedTicker = this.parseTicker(data);
329
+ const symbol = parsedTicker['symbol'];
330
+ const timestamp = this.safeInteger(message, 'timestamp');
331
+ parsedTicker['timestamp'] = timestamp;
332
+ parsedTicker['datetime'] = this.iso8601(timestamp);
333
+ this.tickers[symbol] = parsedTicker;
334
+ const messageHash = 'ticker:' + symbol;
335
+ client.resolve(parsedTicker, messageHash);
336
+ }
337
+ /**
338
+ * @method
339
+ * @name defx#watchBidsAsks
340
+ * @description watches best bid & ask for symbols
341
+ * @see https://www.postman.com/defxcode/defx-public-apis/collection/667939a1b5d8069c13d614e9
342
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
343
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
344
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
345
+ */
346
+ async watchBidsAsks(symbols = undefined, params = {}) {
347
+ await this.loadMarkets();
348
+ symbols = this.marketSymbols(symbols, undefined, false);
349
+ const topics = [];
350
+ const messageHashes = [];
351
+ for (let i = 0; i < symbols.length; i++) {
352
+ const symbol = symbols[i];
353
+ const marketId = this.marketId(symbol);
354
+ topics.push('symbol:' + marketId + ':24hrTicker');
355
+ messageHashes.push('bidask:' + symbol);
356
+ }
357
+ await this.watchPublic(topics, messageHashes, params);
358
+ return this.filterByArray(this.bidsasks, 'symbol', symbols);
359
+ }
360
+ handleBidAsk(client, message) {
361
+ const data = this.safeDict(message, 'data', {});
362
+ const parsedTicker = this.parseWsBidAsk(data);
363
+ const symbol = parsedTicker['symbol'];
364
+ const timestamp = this.safeInteger(message, 'timestamp');
365
+ parsedTicker['timestamp'] = timestamp;
366
+ parsedTicker['datetime'] = this.iso8601(timestamp);
367
+ this.bidsasks[symbol] = parsedTicker;
368
+ const messageHash = 'bidask:' + symbol;
369
+ client.resolve(parsedTicker, messageHash);
370
+ }
371
+ parseWsBidAsk(ticker, market = undefined) {
372
+ const marketId = this.safeString(ticker, 'symbol');
373
+ market = this.safeMarket(marketId, market);
374
+ const symbol = this.safeString(market, 'symbol');
375
+ return this.safeTicker({
376
+ 'symbol': symbol,
377
+ 'timestamp': undefined,
378
+ 'datetime': undefined,
379
+ 'ask': this.safeString(ticker, 'bestAskPrice'),
380
+ 'askVolume': this.safeString(ticker, 'bestAskQty'),
381
+ 'bid': this.safeString(ticker, 'bestBidPrice'),
382
+ 'bidVolume': this.safeString(ticker, 'bestBidQty'),
383
+ 'info': ticker,
384
+ }, market);
385
+ }
386
+ /**
387
+ * @method
388
+ * @name defx#watchTrades
389
+ * @description watches information on multiple trades made in a market
390
+ * @see https://www.postman.com/defxcode/defx-public-apis/collection/667939a1b5d8069c13d614e9
391
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
392
+ * @param {int} [since] the earliest time in ms to fetch trades for
393
+ * @param {int} [limit] the maximum number of trade structures to retrieve
394
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
395
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
396
+ */
397
+ async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
398
+ return await this.watchTradesForSymbols([symbol], since, limit, params);
399
+ }
400
+ /**
401
+ * @method
402
+ * @name defx#unWatchTradesForSymbols
403
+ * @description unWatches from the stream channel
404
+ * @see https://www.postman.com/defxcode/defx-public-apis/collection/667939a1b5d8069c13d614e9
405
+ * @param {string} symbol unified symbol of the market to fetch trades for
406
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
407
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
408
+ */
409
+ async unWatchTrades(symbol, params = {}) {
410
+ return await this.unWatchTradesForSymbols([symbol], params);
411
+ }
412
+ /**
413
+ * @method
414
+ * @name defx#watchTradesForSymbols
415
+ * @description watches information on multiple trades made in a market
416
+ * @see https://www.postman.com/defxcode/defx-public-apis/collection/667939a1b5d8069c13d614e9
417
+ * @param {string[]} symbols unified symbol of the market to fetch trades for
418
+ * @param {int} [since] the earliest time in ms to fetch trades for
419
+ * @param {int} [limit] the maximum number of trade structures to retrieve
420
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
421
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
422
+ */
423
+ async watchTradesForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
424
+ await this.loadMarkets();
425
+ symbols = this.marketSymbols(symbols);
426
+ const symbolsLength = symbols.length;
427
+ if (symbolsLength === 0) {
428
+ throw new ArgumentsRequired(this.id + ' watchTradesForSymbols() requires a non-empty array of symbols');
429
+ }
430
+ const topics = [];
431
+ const messageHashes = [];
432
+ for (let i = 0; i < symbols.length; i++) {
433
+ const symbol = symbols[i];
434
+ const marketId = this.marketId(symbol);
435
+ topics.push('symbol:' + marketId + ':trades');
436
+ messageHashes.push('trade:' + symbol);
437
+ }
438
+ const trades = await this.watchPublic(topics, messageHashes, params);
439
+ if (this.newUpdates) {
440
+ const first = this.safeValue(trades, 0);
441
+ const tradeSymbol = this.safeString(first, 'symbol');
442
+ limit = trades.getLimit(tradeSymbol, limit);
443
+ }
444
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
445
+ }
446
+ /**
447
+ * @method
448
+ * @name defx#unWatchTradesForSymbols
449
+ * @description unWatches from the stream channel
450
+ * @see https://www.postman.com/defxcode/defx-public-apis/collection/667939a1b5d8069c13d614e9
451
+ * @param {string[]} symbols unified symbol of the market to fetch trades for
452
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
453
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
454
+ */
455
+ async unWatchTradesForSymbols(symbols, params = {}) {
456
+ await this.loadMarkets();
457
+ symbols = this.marketSymbols(symbols);
458
+ const symbolsLength = symbols.length;
459
+ if (symbolsLength === 0) {
460
+ throw new ArgumentsRequired(this.id + ' unWatchTradesForSymbols() requires a non-empty array of symbols');
461
+ }
462
+ const topics = [];
463
+ const messageHashes = [];
464
+ for (let i = 0; i < symbols.length; i++) {
465
+ const symbol = symbols[i];
466
+ const marketId = this.marketId(symbol);
467
+ topics.push('symbol:' + marketId + ':trades');
468
+ messageHashes.push('trade:' + symbol);
469
+ }
470
+ return await this.unWatchPublic(topics, messageHashes, params);
471
+ }
472
+ handleTrades(client, message) {
473
+ //
474
+ // {
475
+ // "topic": "symbol:SOL_USDC:trades",
476
+ // "event": "trades",
477
+ // "timestamp": 1730967426331,
478
+ // "data": {
479
+ // "buyerMaker": true,
480
+ // "price": "188.38700000",
481
+ // "qty": "1.00",
482
+ // "symbol": "SOL_USDC",
483
+ // "timestamp": 1730967426328
484
+ // }
485
+ // }
486
+ //
487
+ const data = this.safeDict(message, 'data', {});
488
+ const parsedTrade = this.parseTrade(data);
489
+ const symbol = parsedTrade['symbol'];
490
+ if (!(symbol in this.trades)) {
491
+ const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
492
+ const stored = new ArrayCache(limit);
493
+ this.trades[symbol] = stored;
494
+ }
495
+ const trades = this.trades[symbol];
496
+ trades.append(parsedTrade);
497
+ const messageHash = 'trade:' + symbol;
498
+ client.resolve(trades, messageHash);
499
+ }
500
+ /**
501
+ * @method
502
+ * @name defx#watchOrderBook
503
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
504
+ * @see https://www.postman.com/defxcode/defx-public-apis/collection/667939a1b5d8069c13d614e9
505
+ * @param {string} symbol unified symbol of the market to fetch the order book for
506
+ * @param {int} [limit] the maximum amount of order book entries to return
507
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
508
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
509
+ */
510
+ async watchOrderBook(symbol, limit = undefined, params = {}) {
511
+ return await this.watchOrderBookForSymbols([symbol], limit, params);
512
+ }
513
+ /**
514
+ * @method
515
+ * @name defx#unWatchOrderBook
516
+ * @description unWatches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
517
+ * @see https://www.postman.com/defxcode/defx-public-apis/collection/667939a1b5d8069c13d614e9
518
+ * @param {string} symbol unified array of symbols
519
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
520
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
521
+ */
522
+ async unWatchOrderBook(symbol, params = {}) {
523
+ return await this.unWatchOrderBookForSymbols([symbol], params);
524
+ }
525
+ /**
526
+ * @method
527
+ * @name defx#watchOrderBookForSymbols
528
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
529
+ * @see https://www.postman.com/defxcode/defx-public-apis/collection/667939a1b5d8069c13d614e9
530
+ * @param {string[]} symbols unified array of symbols
531
+ * @param {int} [limit] the maximum amount of order book entries to return
532
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
533
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
534
+ */
535
+ async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
536
+ await this.loadMarkets();
537
+ const symbolsLength = symbols.length;
538
+ if (symbolsLength === 0) {
539
+ throw new ArgumentsRequired(this.id + ' watchOrderBookForSymbols() requires a non-empty array of symbols');
540
+ }
541
+ symbols = this.marketSymbols(symbols);
542
+ const topics = [];
543
+ const messageHashes = [];
544
+ for (let i = 0; i < symbols.length; i++) {
545
+ const symbol = symbols[i];
546
+ const marketId = this.marketId(symbol);
547
+ topics.push('symbol:' + marketId + ':depth:20:0.001');
548
+ messageHashes.push('orderbook:' + symbol);
549
+ }
550
+ const orderbook = await this.watchPublic(topics, messageHashes, params);
551
+ return orderbook.limit();
552
+ }
553
+ /**
554
+ * @method
555
+ * @name defx#unWatchOrderBookForSymbols
556
+ * @description unWatches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
557
+ * @see https://www.postman.com/defxcode/defx-public-apis/collection/667939a1b5d8069c13d614e9
558
+ * @param {string[]} symbols unified array of symbols
559
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
560
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
561
+ */
562
+ async unWatchOrderBookForSymbols(symbols, params = {}) {
563
+ await this.loadMarkets();
564
+ const symbolsLength = symbols.length;
565
+ if (symbolsLength === 0) {
566
+ throw new ArgumentsRequired(this.id + ' unWatchOrderBookForSymbols() requires a non-empty array of symbols');
567
+ }
568
+ symbols = this.marketSymbols(symbols);
569
+ const topics = [];
570
+ const messageHashes = [];
571
+ for (let i = 0; i < symbols.length; i++) {
572
+ const symbol = symbols[i];
573
+ const marketId = this.marketId(symbol);
574
+ topics.push('symbol:' + marketId + ':depth:20:0.001');
575
+ messageHashes.push('orderbook:' + symbol);
576
+ }
577
+ return await this.unWatchPublic(topics, messageHashes, params);
578
+ }
579
+ handleOrderBook(client, message) {
580
+ //
581
+ // {
582
+ // "topic": "symbol:SOL_USDC:depth:20:0.01",
583
+ // "event": "depth",
584
+ // "timestamp": 1731030695319,
585
+ // "data": {
586
+ // "symbol": "SOL_USDC",
587
+ // "timestamp": 1731030695319,
588
+ // "lastTradeTimestamp": 1731030275258,
589
+ // "level": "20",
590
+ // "slab": "0.01",
591
+ // "bids": [
592
+ // {
593
+ // "price": "198.27000000",
594
+ // "qty": "1.52"
595
+ // }
596
+ // ],
597
+ // "asks": [
598
+ // {
599
+ // "price": "198.44000000",
600
+ // "qty": "6.61"
601
+ // }
602
+ // ]
603
+ // }
604
+ // }
605
+ //
606
+ const data = this.safeDict(message, 'data', {});
607
+ const marketId = this.safeString(data, 'symbol');
608
+ const market = this.market(marketId);
609
+ const symbol = market['symbol'];
610
+ const timestamp = this.safeInteger(data, 'timestamp');
611
+ const snapshot = this.parseOrderBook(data, symbol, timestamp, 'bids', 'asks', 'price', 'qty');
612
+ if (!(symbol in this.orderbooks)) {
613
+ const ob = this.orderBook(snapshot);
614
+ this.orderbooks[symbol] = ob;
615
+ }
616
+ const orderbook = this.orderbooks[symbol];
617
+ orderbook.reset(snapshot);
618
+ const messageHash = 'orderbook:' + symbol;
619
+ client.resolve(orderbook, messageHash);
620
+ }
621
+ async keepAliveListenKey(params = {}) {
622
+ const listenKey = this.safeString(this.options, 'listenKey');
623
+ if (listenKey === undefined) {
624
+ // A network error happened: we can't renew a listen key that does not exist.
625
+ return;
626
+ }
627
+ try {
628
+ await this.v1PrivatePutApiUsersSocketListenKeysListenKey({ 'listenKey': listenKey }); // extend the expiry
629
+ }
630
+ catch (error) {
631
+ const url = this.urls['api']['ws']['private'] + '?listenKey=' + listenKey;
632
+ const client = this.client(url);
633
+ const messageHashes = Object.keys(client.futures);
634
+ for (let j = 0; j < messageHashes.length; j++) {
635
+ const messageHash = messageHashes[j];
636
+ client.reject(error, messageHash);
637
+ }
638
+ this.options['listenKey'] = undefined;
639
+ this.options['lastAuthenticatedTime'] = 0;
640
+ return;
641
+ }
642
+ // whether or not to schedule another listenKey keepAlive request
643
+ const listenKeyRefreshRate = this.safeInteger(this.options, 'listenKeyRefreshRate', 3540000);
644
+ this.delay(listenKeyRefreshRate, this.keepAliveListenKey, params);
645
+ }
646
+ async authenticate(params = {}) {
647
+ const time = this.milliseconds();
648
+ const lastAuthenticatedTime = this.safeInteger(this.options, 'lastAuthenticatedTime', 0);
649
+ const listenKeyRefreshRate = this.safeInteger(this.options, 'listenKeyRefreshRate', 3540000); // 1 hour
650
+ if (time - lastAuthenticatedTime > listenKeyRefreshRate) {
651
+ const response = await this.v1PrivatePostApiUsersSocketListenKeys();
652
+ this.options['listenKey'] = this.safeString(response, 'listenKey');
653
+ this.options['lastAuthenticatedTime'] = time;
654
+ this.delay(listenKeyRefreshRate, this.keepAliveListenKey, params);
655
+ }
656
+ }
657
+ /**
658
+ * @method
659
+ * @name defx#watchBalance
660
+ * @description query for balance and get the amount of funds available for trading or funds locked in orders
661
+ * @see https://www.postman.com/defxcode/defx-public-apis/ws-raw-request/667939b2f00f79161bb47809
662
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
663
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
664
+ */
665
+ async watchBalance(params = {}) {
666
+ await this.loadMarkets();
667
+ await this.authenticate();
668
+ const baseUrl = this.urls['api']['ws']['private'];
669
+ const messageHash = 'WALLET_BALANCE_UPDATE';
670
+ const url = baseUrl + '?listenKey=' + this.options['listenKey'];
671
+ return await this.watch(url, messageHash, undefined, messageHash);
672
+ }
673
+ handleBalance(client, message) {
674
+ //
675
+ // {
676
+ // "event": "WALLET_BALANCE_UPDATE",
677
+ // "timestamp": 1711015961397,
678
+ // "data": {
679
+ // "asset": "USDC", "balance": "27.64712963"
680
+ // }
681
+ // }
682
+ //
683
+ const messageHash = this.safeString(message, 'event');
684
+ const data = this.safeDict(message, 'data', []);
685
+ const timestamp = this.safeInteger(message, 'timestamp');
686
+ if (this.balance === undefined) {
687
+ this.balance = {};
688
+ }
689
+ this.balance['info'] = data;
690
+ this.balance['timestamp'] = timestamp;
691
+ this.balance['datetime'] = this.iso8601(timestamp);
692
+ const currencyId = this.safeString(data, 'asset');
693
+ const code = this.safeCurrencyCode(currencyId);
694
+ const account = (code in this.balance) ? this.balance[code] : this.account();
695
+ account['free'] = this.safeString(data, 'balance');
696
+ this.balance[code] = account;
697
+ this.balance = this.safeBalance(this.balance);
698
+ client.resolve(this.balance, messageHash);
699
+ }
700
+ /**
701
+ * @method
702
+ * @name defx#watchOrders
703
+ * @description watches information on multiple orders made by the user
704
+ * @see https://www.postman.com/defxcode/defx-public-apis/ws-raw-request/667939b2f00f79161bb47809
705
+ * @param {string} [symbol] unified market symbol of the market the orders were made in
706
+ * @param {int} [since] the earliest time in ms to fetch orders for
707
+ * @param {int} [limit] the maximum number of order structures to retrieve
708
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
709
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
710
+ */
711
+ async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
712
+ await this.loadMarkets();
713
+ await this.authenticate();
714
+ const baseUrl = this.urls['api']['ws']['private'];
715
+ let messageHash = 'orders';
716
+ if (symbol !== undefined) {
717
+ const market = this.market(symbol);
718
+ messageHash += ':' + market['symbol'];
719
+ }
720
+ const url = baseUrl + '?listenKey=' + this.options['listenKey'];
721
+ const orders = await this.watch(url, messageHash, undefined, messageHash);
722
+ if (this.newUpdates) {
723
+ limit = orders.getLimit(symbol, limit);
724
+ }
725
+ return this.filterBySymbolSinceLimit(orders, symbol, since, limit, true);
726
+ }
727
+ handleOrder(client, message) {
728
+ //
729
+ // {
730
+ // "event": "ORDER_UPDATE",
731
+ // "timestamp": 1731417961446,
732
+ // "data": {
733
+ // "orderId": "766738557656630928",
734
+ // "symbol": "SOL_USDC",
735
+ // "side": "SELL",
736
+ // "type": "MARKET",
737
+ // "status": "FILLED",
738
+ // "clientOrderId": "0193208d-717b-7811-a80e-c036e220ad9b",
739
+ // "reduceOnly": false,
740
+ // "postOnly": false,
741
+ // "timeInForce": "GTC",
742
+ // "isTriggered": false,
743
+ // "createdAt": "2024-11-12T13:26:00.829Z",
744
+ // "updatedAt": "2024-11-12T13:26:01.436Z",
745
+ // "avgPrice": "209.60000000",
746
+ // "cumulativeQuote": "104.80000000",
747
+ // "totalFee": "0.05764000",
748
+ // "executedQty": "0.50",
749
+ // "origQty": "0.50",
750
+ // "role": "TAKER",
751
+ // "pnl": "0.00000000",
752
+ // "lastFillPnL": "0.00000000",
753
+ // "lastFillPrice": "209.60000000",
754
+ // "lastFillQty": "0.50",
755
+ // "linkedOrderParentType": null,
756
+ // "workingType": null
757
+ // }
758
+ // }
759
+ //
760
+ const channel = 'orders';
761
+ const data = this.safeDict(message, 'data', {});
762
+ if (this.orders === undefined) {
763
+ const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
764
+ this.orders = new ArrayCacheBySymbolById(limit);
765
+ }
766
+ const orders = this.orders;
767
+ const parsedOrder = this.parseOrder(data);
768
+ orders.append(parsedOrder);
769
+ const messageHash = channel + ':' + parsedOrder['symbol'];
770
+ client.resolve(orders, channel);
771
+ client.resolve(orders, messageHash);
772
+ }
773
+ /**
774
+ * @method
775
+ * @name defx#watchPositions
776
+ * @description watch all open positions
777
+ * @see https://www.postman.com/defxcode/defx-public-apis/ws-raw-request/667939b2f00f79161bb47809
778
+ * @param {string[]|undefined} symbols list of unified market symbols
779
+ * @param {number} [since] since timestamp
780
+ * @param {number} [limit] limit
781
+ * @param {object} params extra parameters specific to the exchange API endpoint
782
+ * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
783
+ */
784
+ async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
785
+ await this.loadMarkets();
786
+ await this.authenticate();
787
+ symbols = this.marketSymbols(symbols);
788
+ const baseUrl = this.urls['api']['ws']['private'];
789
+ const channel = 'positions';
790
+ const url = baseUrl + '?listenKey=' + this.options['listenKey'];
791
+ let newPosition = undefined;
792
+ if (symbols !== undefined) {
793
+ const messageHashes = [];
794
+ for (let i = 0; i < symbols.length; i++) {
795
+ const symbol = symbols[i];
796
+ messageHashes.push(channel + ':' + symbol);
797
+ }
798
+ newPosition = await this.watchMultiple(url, messageHashes, undefined, messageHashes);
799
+ }
800
+ else {
801
+ newPosition = await this.watch(url, channel, undefined, channel);
802
+ }
803
+ if (this.newUpdates) {
804
+ return newPosition;
805
+ }
806
+ return this.filterBySymbolsSinceLimit(this.positions, symbols, since, limit, true);
807
+ }
808
+ handlePositions(client, message) {
809
+ //
810
+ // {
811
+ // "event": "POSITION_UPDATE",
812
+ // "timestamp": 1731417961456,
813
+ // "data": {
814
+ // "positionId": "0193208d-735d-7fe9-90bd-8bc6d6bc1eda",
815
+ // "createdAt": 1289847904328,
816
+ // "symbol": "SOL_USDC",
817
+ // "positionSide": "SHORT",
818
+ // "entryPrice": "209.60000000",
819
+ // "quantity": "0.50",
820
+ // "status": "ACTIVE",
821
+ // "marginAsset": "USDC",
822
+ // "marginAmount": "15.17475649",
823
+ // "realizedPnL": "0.00000000"
824
+ // }
825
+ // }
826
+ //
827
+ const channel = 'positions';
828
+ const data = this.safeDict(message, 'data', {});
829
+ if (this.positions === undefined) {
830
+ this.positions = new ArrayCacheBySymbolById();
831
+ }
832
+ const cache = this.positions;
833
+ const parsedPosition = this.parsePosition(data);
834
+ const timestamp = this.safeInteger(message, 'timestamp');
835
+ parsedPosition['timestamp'] = timestamp;
836
+ parsedPosition['datetime'] = this.iso8601(timestamp);
837
+ cache.append(parsedPosition);
838
+ const messageHash = channel + ':' + parsedPosition['symbol'];
839
+ client.resolve([parsedPosition], channel);
840
+ client.resolve([parsedPosition], messageHash);
841
+ }
842
+ handleMessage(client, message) {
843
+ const error = this.safeString(message, 'code');
844
+ if (error !== undefined) {
845
+ const errorMsg = this.safeString(message, 'msg');
846
+ throw new ExchangeError(this.id + ' ' + errorMsg);
847
+ }
848
+ const event = this.safeString(message, 'event');
849
+ if (event !== undefined) {
850
+ const methods = {
851
+ 'ohlc': this.handleOHLCV,
852
+ '24hrTicker': this.handleTicker,
853
+ 'trades': this.handleTrades,
854
+ 'depth': this.handleOrderBook,
855
+ 'WALLET_BALANCE_UPDATE': this.handleBalance,
856
+ 'ORDER_UPDATE': this.handleOrder,
857
+ 'POSITION_UPDATE': this.handlePositions,
858
+ };
859
+ const exacMethod = this.safeValue(methods, event);
860
+ if (exacMethod !== undefined) {
861
+ exacMethod.call(this, client, message);
862
+ }
863
+ }
864
+ }
865
+ }