ccxt 4.5.29 → 4.5.30

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 (63) hide show
  1. package/README.md +6 -5
  2. package/dist/ccxt.browser.min.js +7 -7
  3. package/dist/cjs/ccxt.js +6 -1
  4. package/dist/cjs/src/abstract/bydfi.js +11 -0
  5. package/dist/cjs/src/bingx.js +1 -1
  6. package/dist/cjs/src/bullish.js +1 -1
  7. package/dist/cjs/src/bybit.js +2 -0
  8. package/dist/cjs/src/bydfi.js +2907 -0
  9. package/dist/cjs/src/coinbase.js +34 -1
  10. package/dist/cjs/src/dydx.js +3 -3
  11. package/dist/cjs/src/gate.js +3 -2
  12. package/dist/cjs/src/hyperliquid.js +10 -3
  13. package/dist/cjs/src/kucoin.js +112 -4
  14. package/dist/cjs/src/pro/apex.js +5 -3
  15. package/dist/cjs/src/pro/binance.js +10 -6
  16. package/dist/cjs/src/pro/bingx.js +5 -3
  17. package/dist/cjs/src/pro/bitmart.js +5 -3
  18. package/dist/cjs/src/pro/bybit.js +5 -3
  19. package/dist/cjs/src/pro/bydfi.js +1077 -0
  20. package/dist/cjs/src/pro/cryptocom.js +5 -3
  21. package/dist/cjs/src/pro/gate.js +5 -3
  22. package/dist/cjs/src/pro/hashkey.js +5 -3
  23. package/dist/cjs/src/pro/kucoinfutures.js +5 -3
  24. package/dist/cjs/src/pro/modetrade.js +5 -3
  25. package/dist/cjs/src/pro/toobit.js +11 -7
  26. package/dist/cjs/src/pro/woo.js +5 -3
  27. package/dist/cjs/src/pro/woofipro.js +5 -3
  28. package/dist/cjs/src/pro/xt.js +5 -3
  29. package/dist/cjs/src/toobit.js +2 -1
  30. package/js/ccxt.d.ts +8 -2
  31. package/js/ccxt.js +6 -2
  32. package/js/src/abstract/bydfi.d.ts +52 -0
  33. package/js/src/abstract/bydfi.js +11 -0
  34. package/js/src/bingx.js +1 -1
  35. package/js/src/bullish.js +1 -1
  36. package/js/src/bybit.js +2 -0
  37. package/js/src/bydfi.d.ts +472 -0
  38. package/js/src/bydfi.js +2905 -0
  39. package/js/src/coinbase.d.ts +11 -0
  40. package/js/src/coinbase.js +34 -1
  41. package/js/src/dydx.js +3 -3
  42. package/js/src/gate.js +3 -2
  43. package/js/src/hyperliquid.js +10 -3
  44. package/js/src/kucoin.d.ts +14 -0
  45. package/js/src/kucoin.js +112 -4
  46. package/js/src/pro/apex.js +5 -3
  47. package/js/src/pro/binance.js +10 -6
  48. package/js/src/pro/bingx.js +5 -3
  49. package/js/src/pro/bitmart.js +5 -3
  50. package/js/src/pro/bybit.js +5 -3
  51. package/js/src/pro/bydfi.d.ts +206 -0
  52. package/js/src/pro/bydfi.js +1076 -0
  53. package/js/src/pro/cryptocom.js +5 -3
  54. package/js/src/pro/gate.js +5 -3
  55. package/js/src/pro/hashkey.js +5 -3
  56. package/js/src/pro/kucoinfutures.js +5 -3
  57. package/js/src/pro/modetrade.js +5 -3
  58. package/js/src/pro/toobit.js +11 -7
  59. package/js/src/pro/woo.js +5 -3
  60. package/js/src/pro/woofipro.js +5 -3
  61. package/js/src/pro/xt.js +5 -3
  62. package/js/src/toobit.js +2 -1
  63. package/package.json +1 -1
@@ -0,0 +1,1077 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var bydfi$1 = require('../bydfi.js');
6
+ var Precise = require('../base/Precise.js');
7
+ var errors = require('../base/errors.js');
8
+ var Cache = require('../base/ws/Cache.js');
9
+ var sha256 = require('../static_dependencies/noble-hashes/sha256.js');
10
+
11
+ // ----------------------------------------------------------------------------
12
+ // ---------------------------------------------------------------------------
13
+ class bydfi extends bydfi$1["default"] {
14
+ describe() {
15
+ return this.deepExtend(super.describe(), {
16
+ 'has': {
17
+ 'ws': true,
18
+ 'watchBalance': true,
19
+ 'watchBidsAsks': false,
20
+ 'watchMyTrades': false,
21
+ 'watchOHLCV': true,
22
+ 'watchOHLCVForSymbols': true,
23
+ 'watchOrderBook': true,
24
+ 'watchOrderBookForSymbols': true,
25
+ 'watchOrders': true,
26
+ 'watchOrdersForSymbols': true,
27
+ 'watchPositions': true,
28
+ 'watchTicker': true,
29
+ 'watchTickers': true,
30
+ 'watchTrades': false,
31
+ 'watchTradesForSymbols': false,
32
+ 'unwatchBidsAsks': false,
33
+ 'unwatchOHLCV': true,
34
+ 'unwatchOHLCVForSymbols': true,
35
+ 'unwatchOrderBook': true,
36
+ 'unwatchOrderBookForSymbols': true,
37
+ 'unwatchTicker': true,
38
+ 'unwatchTickers': true,
39
+ 'unWatchTrades': false,
40
+ 'unWatchTradesForSymbols': false,
41
+ 'unWatchOrders': false,
42
+ 'unWatchOrdersForSymbols': false,
43
+ 'unWatchPositions': false,
44
+ },
45
+ 'urls': {
46
+ 'api': {
47
+ 'ws': 'wss://stream.bydfi.com/v1/public/swap',
48
+ },
49
+ },
50
+ 'options': {
51
+ 'watchOrderBookForSymbols': {
52
+ 'depth': '100',
53
+ 'frequency': '1000ms', // 100ms, 1000ms
54
+ },
55
+ 'watchBalance': {
56
+ 'fetchBalanceSnapshot': false,
57
+ 'awaitBalanceSnapshot': true, // whether to wait for the balance snapshot before providing updates
58
+ },
59
+ 'timeframes': {
60
+ '1m': '1m',
61
+ '3m': '3m',
62
+ '5m': '5m',
63
+ '15m': '15m',
64
+ '30m': '30m',
65
+ '1h': '1h',
66
+ '2h': '2h',
67
+ '4h': '4h',
68
+ '6h': '6h',
69
+ '8h': '8h',
70
+ '12h': '12h',
71
+ '1d': '1d',
72
+ '1w': '1w',
73
+ '1M': '1M',
74
+ },
75
+ },
76
+ 'streaming': {
77
+ 'ping': this.ping,
78
+ 'keepAlive': 119000, // 2 minutes
79
+ },
80
+ });
81
+ }
82
+ ping(client) {
83
+ return {
84
+ 'id': this.requestId(),
85
+ 'method': 'ping',
86
+ };
87
+ }
88
+ requestId() {
89
+ this.lockId();
90
+ const reqid = this.sum(this.safeInteger(this.options, 'reqid', 0), 1);
91
+ this.options['reqid'] = reqid;
92
+ this.unlockId();
93
+ return reqid;
94
+ }
95
+ async watchPublic(messageHashes, channels, params = {}, subscription = {}) {
96
+ const url = this.urls['api']['ws'];
97
+ const id = this.requestId();
98
+ const subscriptionParams = {
99
+ 'id': id,
100
+ };
101
+ const unsubscribe = this.safeBool(params, 'unsubscribe', false);
102
+ let method = 'SUBSCRIBE';
103
+ if (unsubscribe) {
104
+ method = 'UNSUBSCRIBE';
105
+ params = this.omit(params, 'unsubscribe');
106
+ subscriptionParams['unsubscribe'] = true;
107
+ subscriptionParams['messageHashes'] = messageHashes;
108
+ }
109
+ const message = {
110
+ 'id': id,
111
+ 'method': method,
112
+ 'params': channels,
113
+ };
114
+ return await this.watchMultiple(url, messageHashes, this.deepExtend(message, params), messageHashes, this.extend(subscriptionParams, subscription));
115
+ }
116
+ async watchPrivate(messageHashes, params = {}) {
117
+ this.checkRequiredCredentials();
118
+ const url = this.urls['api']['ws'];
119
+ const subHash = 'private';
120
+ const client = this.client(url);
121
+ const privateSubscription = this.safeValue(client.subscriptions, subHash);
122
+ const subscription = {};
123
+ if (privateSubscription === undefined) {
124
+ const id = this.requestId();
125
+ const timestamp = this.milliseconds().toString();
126
+ const payload = this.apiKey + timestamp;
127
+ const signature = this.hmac(this.encode(payload), this.encode(this.secret), sha256.sha256, 'hex');
128
+ const request = {
129
+ 'id': id,
130
+ 'method': 'LOGIN',
131
+ 'params': {
132
+ 'apiKey': this.apiKey,
133
+ 'timestamp': timestamp,
134
+ 'sign': signature,
135
+ },
136
+ };
137
+ params = this.deepExtend(request, params);
138
+ subscription['id'] = id;
139
+ }
140
+ return await this.watchMultiple(url, messageHashes, params, ['private'], subscription);
141
+ }
142
+ /**
143
+ * @method
144
+ * @name bydfi#watchTicker
145
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
146
+ * @see https://developers.bydfi.com/en/swap/websocket-market#ticker-by-symbol
147
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
148
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
149
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/?id=ticker-structure}
150
+ */
151
+ async watchTicker(symbol, params = {}) {
152
+ await this.loadMarkets();
153
+ const market = this.market(symbol);
154
+ const marketId = market['id'];
155
+ const messageHash = 'ticker::' + symbol;
156
+ const channel = marketId + '@ticker';
157
+ return await this.watchPublic([messageHash], [channel], params);
158
+ }
159
+ /**
160
+ * @method
161
+ * @name bydfi#unWatchTicker
162
+ * @description unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
163
+ * @see https://developers.bydfi.com/en/swap/websocket-market#ticker-by-symbol
164
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
165
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
166
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/?id=ticker-structure}
167
+ */
168
+ async unWatchTicker(symbol, params = {}) {
169
+ return await this.unWatchTickers([symbol], params);
170
+ }
171
+ /**
172
+ * @method
173
+ * @name bydfi#watchTickers
174
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
175
+ * @see https://developers.bydfi.com/en/swap/websocket-market#ticker-by-symbol
176
+ * @see https://developers.bydfi.com/en/swap/websocket-market#market-wide-ticker
177
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
178
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
179
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/?id=ticker-structure}
180
+ */
181
+ async watchTickers(symbols = undefined, params = {}) {
182
+ await this.loadMarkets();
183
+ symbols = this.marketSymbols(symbols, undefined, true);
184
+ const messageHashes = [];
185
+ const messageHash = 'ticker::';
186
+ const channels = [];
187
+ const channel = '@ticker';
188
+ if (symbols === undefined) {
189
+ messageHashes.push(messageHash + 'all');
190
+ channels.push('!ticker@arr');
191
+ }
192
+ else {
193
+ for (let i = 0; i < symbols.length; i++) {
194
+ const symbol = symbols[i];
195
+ const marketId = this.marketId(symbol);
196
+ messageHashes.push(messageHash + symbol);
197
+ channels.push(marketId + channel);
198
+ }
199
+ }
200
+ await this.watchPublic(messageHashes, channels, params);
201
+ return this.filterByArray(this.tickers, 'symbol', symbols);
202
+ }
203
+ /**
204
+ * @method
205
+ * @name bydfi#unWatchTickers
206
+ * @description unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
207
+ * @see https://developers.bydfi.com/en/swap/websocket-market#ticker-by-symbol
208
+ * @see https://developers.bydfi.com/en/swap/websocket-market#market-wide-ticker
209
+ * @param {string[]} symbols unified symbol of the market to fetch the ticker for
210
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
211
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/?id=ticker-structure}
212
+ */
213
+ async unWatchTickers(symbols = undefined, params = {}) {
214
+ symbols = this.marketSymbols(symbols, undefined, true);
215
+ const messageHashes = [];
216
+ const messageHash = 'unsubscribe::ticker::';
217
+ const channels = [];
218
+ const channel = '@ticker';
219
+ const subscription = {
220
+ 'topic': 'ticker',
221
+ };
222
+ if (symbols === undefined) {
223
+ // all tickers and tickers for specific symbols are different channels
224
+ // we need to unsubscribe from all ticker channels
225
+ const subHashes = this.getMessageHashesForTickersUnsubscription();
226
+ subscription['subHashIsPrefix'] = true;
227
+ for (let i = 0; i < subHashes.length; i++) {
228
+ const subHash = this.safeString(subHashes, i);
229
+ if (subHash !== undefined) {
230
+ const parts = subHash.split('::');
231
+ const symbol = this.safeString(parts, 1);
232
+ if (symbol === 'all') {
233
+ continue;
234
+ }
235
+ const marketId = this.marketId(symbol);
236
+ channels.push(marketId + channel);
237
+ }
238
+ }
239
+ messageHashes.push(messageHash);
240
+ channels.push('!ticker@arr');
241
+ }
242
+ else {
243
+ for (let i = 0; i < symbols.length; i++) {
244
+ const symbol = symbols[i];
245
+ const marketId = this.marketId(symbol);
246
+ messageHashes.push(messageHash + symbol);
247
+ channels.push(marketId + channel);
248
+ }
249
+ subscription['symbols'] = symbols;
250
+ }
251
+ params = this.extend(params, { 'unsubscribe': true });
252
+ return await this.watchPublic(messageHashes, channels, params, subscription);
253
+ }
254
+ getMessageHashesForTickersUnsubscription() {
255
+ const url = this.urls['api']['ws']['public'];
256
+ const client = this.client(url);
257
+ const subscriptions = client.subscriptions;
258
+ const messageHashes = [];
259
+ const keys = Object.keys(subscriptions);
260
+ for (let i = 0; i < keys.length; i++) {
261
+ const key = keys[i];
262
+ if (key.indexOf('ticker::') === 0) {
263
+ messageHashes.push(key);
264
+ }
265
+ }
266
+ return messageHashes;
267
+ }
268
+ handleTicker(client, message) {
269
+ //
270
+ // {
271
+ // "s": "KAS-USDT",
272
+ // "c": 0.04543,
273
+ // "e": "24hrTicker",
274
+ // "E": 1766528295905,
275
+ // "v": 98278925,
276
+ // "h": 0.04685,
277
+ // "l": 0.04404,
278
+ // "o": 0.04657
279
+ // }
280
+ //
281
+ const ticker = this.parseTicker(message);
282
+ const symbol = ticker['symbol'];
283
+ const messageHash = 'ticker::' + symbol;
284
+ this.tickers[symbol] = ticker;
285
+ client.resolve(this.tickers[symbol], messageHash);
286
+ client.resolve(this.tickers, 'ticker::all');
287
+ }
288
+ /**
289
+ * @method
290
+ * @name bydfi#watchOHLCV
291
+ * @description watches historical candlestick data containing the open, high, low, close price, and the volume of a market
292
+ * @see https://developers.bydfi.com/en/swap/websocket-market#candlestick-data
293
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
294
+ * @param {string} timeframe the length of time each candle represents
295
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
296
+ * @param {int} [limit] the maximum amount of candles to fetch
297
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
298
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
299
+ */
300
+ async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
301
+ const result = await this.watchOHLCVForSymbols([[symbol, timeframe]], since, limit, params);
302
+ return result[symbol][timeframe];
303
+ }
304
+ /**
305
+ * @method
306
+ * @name bydfi#unWatchOHLCV
307
+ * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
308
+ * @see https://developers.bydfi.com/en/swap/websocket-market#candlestick-data
309
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
310
+ * @param {string} timeframe the length of time each candle represents
311
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
312
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
313
+ */
314
+ async unWatchOHLCV(symbol, timeframe = '1m', params = {}) {
315
+ return await this.unWatchOHLCVForSymbols([[symbol, timeframe]], params);
316
+ }
317
+ /**
318
+ * @method
319
+ * @name bydfi#watchOHLCVForSymbols
320
+ * @description watches historical candlestick data containing the open, high, low, close price, and the volume of a market
321
+ * @see https://developers.bydfi.com/en/swap/websocket-market#candlestick-data
322
+ * @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
323
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
324
+ * @param {int} [limit] the maximum amount of candles to fetch
325
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
326
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
327
+ */
328
+ async watchOHLCVForSymbols(symbolsAndTimeframes, since = undefined, limit = undefined, params = {}) {
329
+ const symbolsLength = symbolsAndTimeframes.length;
330
+ if (symbolsLength === 0 || !Array.isArray(symbolsAndTimeframes[0])) {
331
+ throw new errors.ArgumentsRequired(this.id + " watchOHLCVForSymbols() requires a an array of symbols and timeframes, like ['ETH/USDC', '1m']");
332
+ }
333
+ await this.loadMarkets();
334
+ const channels = [];
335
+ const messageHashes = [];
336
+ for (let i = 0; i < symbolsAndTimeframes.length; i++) {
337
+ const symbolAndTimeframe = symbolsAndTimeframes[i];
338
+ const marketId = this.safeString(symbolAndTimeframe, 0);
339
+ const market = this.market(marketId);
340
+ const tf = this.safeString(symbolAndTimeframe, 1);
341
+ const timeframes = this.safeDict(this.options, 'timeframes', {});
342
+ const interval = this.safeString(timeframes, tf, tf);
343
+ channels.push(market['id'] + '@kline_' + interval);
344
+ messageHashes.push('ohlcv::' + market['symbol'] + '::' + interval);
345
+ }
346
+ const [symbol, timeframe, candles] = await this.watchPublic(messageHashes, channels, params);
347
+ if (this.newUpdates) {
348
+ limit = candles.getLimit(symbol, limit);
349
+ }
350
+ const filtered = this.filterBySinceLimit(candles, since, limit, 0, true);
351
+ return this.createOHLCVObject(symbol, timeframe, filtered);
352
+ }
353
+ /**
354
+ * @method
355
+ * @name bydfi#unWatchOHLCVForSymbols
356
+ * @description unWatches historical candlestick data containing the open, high, low, and close price, and the volume of a market
357
+ * @see https://developers.bydfi.com/en/swap/websocket-market#candlestick-data
358
+ * @param {string[][]} symbolsAndTimeframes array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
359
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
360
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
361
+ */
362
+ async unWatchOHLCVForSymbols(symbolsAndTimeframes, params = {}) {
363
+ const symbolsLength = symbolsAndTimeframes.length;
364
+ if (symbolsLength === 0 || !Array.isArray(symbolsAndTimeframes[0])) {
365
+ throw new errors.ArgumentsRequired(this.id + " unWatchOHLCVForSymbols() requires a an array of symbols and timeframes, like ['ETH/USDC', '1m']");
366
+ }
367
+ await this.loadMarkets();
368
+ const channels = [];
369
+ const messageHashes = [];
370
+ for (let i = 0; i < symbolsAndTimeframes.length; i++) {
371
+ const symbolAndTimeframe = symbolsAndTimeframes[i];
372
+ const marketId = this.safeString(symbolAndTimeframe, 0);
373
+ const market = this.market(marketId);
374
+ const tf = this.safeString(symbolAndTimeframe, 1);
375
+ const interval = this.safeString(this.timeframes, tf, tf);
376
+ channels.push(market['id'] + '@kline_' + interval);
377
+ messageHashes.push('unsubscribe::ohlcv::' + market['symbol'] + '::' + interval);
378
+ }
379
+ params = this.extend(params, { 'unsubscribe': true });
380
+ const subscription = {
381
+ 'topic': 'ohlcv',
382
+ 'symbolsAndTimeframes': symbolsAndTimeframes,
383
+ };
384
+ return await this.watchPublic(messageHashes, channels, params, subscription);
385
+ }
386
+ handleOHLCV(client, message) {
387
+ //
388
+ // {
389
+ // "s": "ETH-USDC",
390
+ // "c": 2956.13,
391
+ // "t": 1766506860000,
392
+ // "T": 1766506920000,
393
+ // "e": "kline",
394
+ // "v": 3955,
395
+ // "h": 2956.41,
396
+ // "i": "1m",
397
+ // "l": 2956.05,
398
+ // "o": 2956.05
399
+ // }
400
+ //
401
+ const marketId = this.safeString(message, 's');
402
+ const market = this.safeMarket(marketId);
403
+ const symbol = market['symbol'];
404
+ const interval = this.safeString(message, 'i');
405
+ const timeframes = this.safeDict(this.options, 'timeframes', {});
406
+ const timeframe = this.findTimeframe(interval, timeframes);
407
+ if (!(symbol in this.ohlcvs)) {
408
+ this.ohlcvs[symbol] = {};
409
+ }
410
+ if (!(timeframe in this.ohlcvs[symbol])) {
411
+ const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
412
+ const stored = new Cache.ArrayCacheByTimestamp(limit);
413
+ this.ohlcvs[symbol][timeframe] = stored;
414
+ }
415
+ const ohlcv = this.ohlcvs[symbol][timeframe];
416
+ const parsed = this.parseWsOHLCV(message);
417
+ ohlcv.append(parsed);
418
+ const messageHash = 'ohlcv::' + symbol + '::' + timeframe;
419
+ client.resolve([symbol, timeframe, ohlcv], messageHash);
420
+ }
421
+ /**
422
+ * @method
423
+ * @name bydfi#watchOrderBook
424
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
425
+ * @see https://developers.bydfi.com/en/swap/websocket-market#limited-depth-information
426
+ * @param {string} symbol unified symbol of the market to fetch the order book for
427
+ * @param {int} [limit] the maximum amount of order book entries to return (default and maxi is 100)
428
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
429
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/?id=order-book-structure} indexed by market symbols
430
+ */
431
+ async watchOrderBook(symbol, limit = undefined, params = {}) {
432
+ return await this.watchOrderBookForSymbols([symbol], limit, params);
433
+ }
434
+ /**
435
+ * @method
436
+ * @name bydfi#unWatchOrderBook
437
+ * @description unWatches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
438
+ * @see https://developers.bydfi.com/en/swap/websocket-market#limited-depth-information
439
+ * @param {string} symbol unified array of symbols
440
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
441
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/?id=order-book-structure} indexed by market symbols
442
+ */
443
+ async unWatchOrderBook(symbol, params = {}) {
444
+ return await this.unWatchOrderBookForSymbols([symbol], params);
445
+ }
446
+ /**
447
+ * @method
448
+ * @name bydfi#watchOrderBookForSymbols
449
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
450
+ * @see https://developers.bydfi.com/en/swap/websocket-market#limited-depth-information
451
+ * @param {string[]} symbols unified array of symbols
452
+ * @param {int} [limit] the maximum amount of order book entries to return (default and max is 100)
453
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
454
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/?id=order-book-structure} indexed by market symbols
455
+ */
456
+ async watchOrderBookForSymbols(symbols, limit = undefined, params = {}) {
457
+ await this.loadMarkets();
458
+ symbols = this.marketSymbols(symbols, undefined, false);
459
+ let depth = '100';
460
+ [depth, params] = this.handleOptionAndParams(params, 'watchOrderBookForSymbols', 'depth', depth);
461
+ let frequency = '100ms';
462
+ [frequency, params] = this.handleOptionAndParams(params, 'watchOrderBookForSymbols', 'frequency', frequency);
463
+ let channelSuffix = '';
464
+ if (frequency === '100ms') {
465
+ channelSuffix = '@100ms';
466
+ }
467
+ const channels = [];
468
+ const messageHashes = [];
469
+ for (let i = 0; i < symbols.length; i++) {
470
+ const symbol = symbols[i];
471
+ const market = this.market(symbol);
472
+ channels.push(market['id'] + '@depth' + depth + channelSuffix);
473
+ messageHashes.push('orderbook::' + symbol);
474
+ }
475
+ const orderbook = await this.watchPublic(messageHashes, channels, params);
476
+ return orderbook.limit();
477
+ }
478
+ /**
479
+ * @method
480
+ * @name bydfi#unWatchOrderBookForSymbols
481
+ * @description unWatches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
482
+ * @see https://developers.bydfi.com/en/swap/websocket-market#limited-depth-information
483
+ * @param {string[]} symbols unified array of symbols
484
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
485
+ * @param {string} [params.method] either '/market/level2' or '/spotMarket/level2Depth5' or '/spotMarket/level2Depth50' default is '/market/level2'
486
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/?id=order-book-structure} indexed by market symbols
487
+ */
488
+ async unWatchOrderBookForSymbols(symbols, params = {}) {
489
+ await this.loadMarkets();
490
+ symbols = this.marketSymbols(symbols, undefined, false);
491
+ let depth = '100';
492
+ [depth, params] = this.handleOptionAndParams(params, 'watchOrderBookForSymbols', 'depth', depth);
493
+ let frequency = '100ms';
494
+ [frequency, params] = this.handleOptionAndParams(params, 'watchOrderBookForSymbols', 'frequency', frequency);
495
+ let channelSuffix = '';
496
+ if (frequency === '100ms') {
497
+ channelSuffix = '@100ms';
498
+ }
499
+ const channels = [];
500
+ const messageHashes = [];
501
+ for (let i = 0; i < symbols.length; i++) {
502
+ const symbol = symbols[i];
503
+ const market = this.market(symbol);
504
+ channels.push(market['id'] + '@depth' + depth + channelSuffix);
505
+ messageHashes.push('unsubscribe::orderbook::' + symbol);
506
+ }
507
+ const subscription = {
508
+ 'topic': 'orderbook',
509
+ 'symbols': symbols,
510
+ };
511
+ params = this.extend(params, { 'unsubscribe': true });
512
+ return await this.watchPublic(messageHashes, channels, params, subscription);
513
+ }
514
+ handleOrderBook(client, message) {
515
+ //
516
+ // {
517
+ // "a": [ [ 150000, 15 ], ... ],
518
+ // "b": [ [ 90450.7, 3615 ], ... ],
519
+ // "s": "BTC-USDT",
520
+ // "e": "depthUpdate",
521
+ // "E": 1766577624512
522
+ // }
523
+ //
524
+ const marketId = this.safeString(message, 's');
525
+ const symbol = this.safeSymbol(marketId);
526
+ const timestamp = this.safeInteger(message, 'E');
527
+ if (!(symbol in this.orderbooks)) {
528
+ this.orderbooks[symbol] = this.orderBook();
529
+ }
530
+ const orderbook = this.orderbooks[symbol];
531
+ const parsed = this.parseOrderBook(message, symbol, timestamp, 'b', 'a');
532
+ orderbook.reset(parsed);
533
+ const messageHash = 'orderbook::' + symbol;
534
+ this.orderbooks[symbol] = orderbook;
535
+ client.resolve(orderbook, messageHash);
536
+ }
537
+ /**
538
+ * @method
539
+ * @name bydfi#watchOrders
540
+ * @description watches information on multiple orders made by the user
541
+ * @see https://developers.bydfi.com/en/swap/websocket-account#order-trade-update-push
542
+ * @param {string} symbol unified market symbol of the market orders were made in
543
+ * @param {int} [since] the earliest time in ms to fetch orders for
544
+ * @param {int} [limit] the maximum number of order structures to retrieve
545
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
546
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/?id=order-structure}
547
+ */
548
+ async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
549
+ let symbols = undefined;
550
+ if (symbol !== undefined) {
551
+ symbols = [symbol];
552
+ }
553
+ return await this.watchOrdersForSymbols(symbols, since, limit, params);
554
+ }
555
+ /**
556
+ * @method
557
+ * @name bydfi#watchOrdersForSymbols
558
+ * @description watches information on multiple orders made by the user
559
+ * @see https://developers.bydfi.com/en/swap/websocket-account#order-trade-update-push
560
+ * @param {string[]} symbols unified symbol of the market to fetch orders for
561
+ * @param {int} [since] the earliest time in ms to fetch orders for
562
+ * @param {int} [limit] the maximum number of trade structures to retrieve
563
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
564
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/?id=order-structure}
565
+ */
566
+ async watchOrdersForSymbols(symbols, since = undefined, limit = undefined, params = {}) {
567
+ await this.loadMarkets();
568
+ symbols = this.marketSymbols(symbols, undefined, true);
569
+ const messageHashes = [];
570
+ if (symbols === undefined) {
571
+ messageHashes.push('orders');
572
+ }
573
+ else {
574
+ for (let i = 0; i < symbols.length; i++) {
575
+ const symbol = symbols[i];
576
+ messageHashes.push('orders::' + symbol);
577
+ }
578
+ }
579
+ const orders = await this.watchPrivate(messageHashes, params);
580
+ if (this.newUpdates) {
581
+ const first = this.safeValue(orders, 0);
582
+ const tradeSymbol = this.safeString(first, 'symbol');
583
+ limit = orders.getLimit(tradeSymbol, limit);
584
+ }
585
+ return this.filterBySinceLimit(orders, since, limit, 'timestamp', true);
586
+ }
587
+ handleOrder(client, message) {
588
+ //
589
+ // {
590
+ // "T": 1766588450558,
591
+ // "E": 1766588450685,
592
+ // "e": "ORDER_TRADE_UPDATE",
593
+ // "o": {
594
+ // "S": "BUY",
595
+ // "ap": "0",
596
+ // "cpt": false,
597
+ // "ct": "future",
598
+ // "ev": "0",
599
+ // "fee": "0",
600
+ // "lv": 2,
601
+ // "mt": "isolated",
602
+ // "o": "7409609004526010368",
603
+ // "p": "1000",
604
+ // "ps": "BOTH",
605
+ // "pt": "ONE_WAY",
606
+ // "ro": false,
607
+ // "s": "ETH-USDC",
608
+ // "st": "NEW",
609
+ // "t": "LIMIT",
610
+ // "tp": "0",
611
+ // "u": "0.001",
612
+ // "v": "2"
613
+ // }
614
+ // }
615
+ //
616
+ const rawOrder = this.safeDict(message, 'o', {});
617
+ const marketId = this.safeString(rawOrder, 's');
618
+ const market = this.safeMarket(marketId);
619
+ const symbol = market['symbol'];
620
+ let match = false;
621
+ const messageHash = 'orders';
622
+ const symbolMessageHash = messageHash + '::' + symbol;
623
+ const messageHashes = this.findMessageHashes(client, messageHash);
624
+ for (let i = 0; i < messageHashes.length; i++) {
625
+ const hash = messageHashes[i];
626
+ if (hash === symbolMessageHash || hash === messageHash) {
627
+ match = true;
628
+ break;
629
+ }
630
+ }
631
+ if (match) {
632
+ if (this.orders === undefined) {
633
+ const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
634
+ this.orders = new Cache.ArrayCacheBySymbolById(limit);
635
+ }
636
+ const orders = this.orders;
637
+ const order = this.parseWsOrder(rawOrder, market);
638
+ const lastUpdateTimestamp = this.safeInteger(message, 'T');
639
+ order['lastUpdateTimestamp'] = lastUpdateTimestamp;
640
+ orders.append(order);
641
+ client.resolve(orders, messageHash);
642
+ client.resolve(orders, symbolMessageHash);
643
+ }
644
+ }
645
+ parseWsOrder(order, market = undefined) {
646
+ //
647
+ // {
648
+ // "S": "BUY",
649
+ // "ap": "0",
650
+ // "cpt": false,
651
+ // "ct": "future",
652
+ // "ev": "0",
653
+ // "fee": "0",
654
+ // "lv": 2,
655
+ // "mt": "isolated",
656
+ // "o": "7409609004526010368",
657
+ // "p": "1000",
658
+ // "ps": "BOTH",
659
+ // "pt": "ONE_WAY",
660
+ // "ro": false,
661
+ // "s": "ETH-USDC",
662
+ // "st": "NEW",
663
+ // "t": "LIMIT",
664
+ // "tp": "0",
665
+ // "u": "0.001",
666
+ // "v": "2"
667
+ // }
668
+ //
669
+ const marketId = this.safeString(order, 's');
670
+ market = this.safeMarket(marketId, market);
671
+ const rawStatus = this.safeString(order, 'st');
672
+ const rawType = this.safeString(order, 't');
673
+ let fee = undefined;
674
+ const feeCost = this.safeString(order, 'fee');
675
+ if (feeCost !== undefined) {
676
+ fee = {
677
+ 'cost': Precise["default"].stringAbs(feeCost),
678
+ 'currency': market['quote'],
679
+ };
680
+ }
681
+ return this.safeOrder({
682
+ 'info': order,
683
+ 'id': this.safeString(order, 'o'),
684
+ 'clientOrderId': this.safeString(order, 'cid'),
685
+ 'timestamp': undefined,
686
+ 'datetime': undefined,
687
+ 'lastTradeTimestamp': undefined,
688
+ 'lastUpdateTimestamp': undefined,
689
+ 'status': this.parseOrderStatus(rawStatus),
690
+ 'symbol': market['symbol'],
691
+ 'type': this.parseOrderType(rawType),
692
+ 'timeInForce': undefined,
693
+ 'postOnly': undefined,
694
+ 'reduceOnly': this.safeBool(order, 'ro'),
695
+ 'side': this.safeStringLower(order, 'S'),
696
+ 'price': this.safeString(order, 'p'),
697
+ 'triggerPrice': undefined,
698
+ 'stopLossPrice': undefined,
699
+ 'takeProfitPrice': undefined,
700
+ 'amount': this.safeString(order, 'v'),
701
+ 'filled': this.safeString(order, 'ev'),
702
+ 'remaining': this.safeString(order, 'qty'),
703
+ 'cost': undefined,
704
+ 'trades': undefined,
705
+ 'fee': fee,
706
+ 'average': this.omitZero(this.safeString(order, 'ap')),
707
+ }, market);
708
+ }
709
+ /**
710
+ * @method
711
+ * @name bydfi#watchPositions
712
+ * @description watch all open positions
713
+ * @see https://developers.bydfi.com/en/swap/websocket-account#balance-and-position-update-push
714
+ * @param {string[]} [symbols] list of unified market symbols
715
+ * @param {int} [since] the earliest time in ms to fetch positions for
716
+ * @param {int} [limit] the maximum number of positions to retrieve
717
+ * @param {object} params extra parameters specific to the exchange API endpoint
718
+ * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/en/latest/manual.html#position-structure}
719
+ */
720
+ async watchPositions(symbols = undefined, since = undefined, limit = undefined, params = {}) {
721
+ await this.loadMarkets();
722
+ symbols = this.marketSymbols(symbols, undefined, true);
723
+ const messageHashes = [];
724
+ const messageHash = 'positions';
725
+ if (symbols === undefined) {
726
+ messageHashes.push(messageHash);
727
+ }
728
+ else {
729
+ for (let i = 0; i < symbols.length; i++) {
730
+ const symbol = symbols[i];
731
+ messageHashes.push(messageHash + '::' + symbol);
732
+ }
733
+ }
734
+ const positions = await this.watchPrivate(messageHashes, params);
735
+ if (this.newUpdates) {
736
+ return positions;
737
+ }
738
+ return this.filterBySymbolsSinceLimit(this.positions, symbols, since, limit, true);
739
+ }
740
+ handlePositions(client, message) {
741
+ //
742
+ // {
743
+ // "a": {
744
+ // "B": [
745
+ // {
746
+ // "a": "USDC",
747
+ // "ba": "0",
748
+ // "im": "1.46282986",
749
+ // "om": "0",
750
+ // "tfm": "1.46282986",
751
+ // "wb": "109.86879703"
752
+ // }
753
+ // ],
754
+ // "m": "ORDER",
755
+ // "p": [
756
+ // {
757
+ // "S": "1",
758
+ // "ap": "2925.81666667",
759
+ // "c": "USDC",
760
+ // "ct": "FUTURE",
761
+ // "l": 2,
762
+ // "lq": "1471.1840621072728637",
763
+ // "lv": "0",
764
+ // "ma": "0",
765
+ // "mt": "ISOLATED",
766
+ // "pm": "1.4628298566666665",
767
+ // "pt": "ONEWAY",
768
+ // "rp": "-0.00036721",
769
+ // "s": "ETH-USDC",
770
+ // "t": "0",
771
+ // "uq": "0.001",
772
+ // "v": "1"
773
+ // }
774
+ // ]
775
+ // },
776
+ // "T": 1766592694451,
777
+ // "E": 1766592694554,
778
+ // "e": "ACCOUNT_UPDATE"
779
+ // }
780
+ //
781
+ const data = this.safeDict(message, 'a', {});
782
+ const positionsData = this.safeList(data, 'p', []);
783
+ const rawPosition = this.safeDict(positionsData, 0, {});
784
+ const marketId = this.safeString(rawPosition, 's');
785
+ const market = this.safeMarket(marketId);
786
+ const symbol = market['symbol'];
787
+ const messageHash = 'positions';
788
+ const symbolMessageHash = messageHash + '::' + symbol;
789
+ const messageHashes = this.findMessageHashes(client, messageHash);
790
+ let match = false;
791
+ for (let i = 0; i < messageHashes.length; i++) {
792
+ const hash = messageHashes[i];
793
+ if (hash === symbolMessageHash || hash === messageHash) {
794
+ match = true;
795
+ break;
796
+ }
797
+ }
798
+ if (match) {
799
+ if (this.positions === undefined) {
800
+ this.positions = new Cache.ArrayCacheBySymbolBySide();
801
+ }
802
+ const cache = this.positions;
803
+ const parsedPosition = this.parseWsPosition(rawPosition, market);
804
+ const timestamp = this.safeInteger(message, 'T');
805
+ parsedPosition['timestamp'] = timestamp;
806
+ parsedPosition['datetime'] = this.iso8601(timestamp);
807
+ cache.append(parsedPosition);
808
+ const symbolSpecificMessageHash = messageHash + ':' + parsedPosition['symbol'];
809
+ client.resolve([parsedPosition], messageHash);
810
+ client.resolve([parsedPosition], symbolSpecificMessageHash);
811
+ }
812
+ }
813
+ parseWsPosition(position, market = undefined) {
814
+ //
815
+ // {
816
+ // "S": "1",
817
+ // "ap": "2925.81666667",
818
+ // "c": "USDC",
819
+ // "ct": "FUTURE",
820
+ // "l": 2,
821
+ // "lq": "1471.1840621072728637",
822
+ // "lv": "0",
823
+ // "ma": "0",
824
+ // "mt": "ISOLATED",
825
+ // "pm": "1.4628298566666665",
826
+ // "pt": "ONEWAY",
827
+ // "rp": "-0.00036721",
828
+ // "s": "ETH-USDC",
829
+ // "t": "0",
830
+ // "uq": "0.001",
831
+ // "v": "1"
832
+ // }
833
+ //
834
+ const marketId = this.safeString(position, 's');
835
+ market = this.safeMarket(marketId, market);
836
+ const rawPositionSide = this.safeString(position, 'S');
837
+ const positionMode = this.safeString(position, 'pt');
838
+ return this.safePosition({
839
+ 'info': position,
840
+ 'id': this.safeString(position, 'id'),
841
+ 'symbol': market['symbol'],
842
+ 'entryPrice': this.parseNumber(this.safeString(position, 'ap')),
843
+ 'markPrice': undefined,
844
+ 'lastPrice': undefined,
845
+ 'notional': undefined,
846
+ 'collateral': undefined,
847
+ 'unrealizedPnl': undefined,
848
+ 'realizedPnl': this.parseNumber(this.safeString(position, 'rp')),
849
+ 'side': this.parseWsPositionSide(rawPositionSide),
850
+ 'contracts': this.parseNumber(this.safeString(position, 'v')),
851
+ 'contractSize': this.parseNumber(this.safeString(position, 'uq')),
852
+ 'timestamp': undefined,
853
+ 'datetime': undefined,
854
+ 'lastUpdateTimestamp': undefined,
855
+ 'hedged': (positionMode !== 'ONEWAY'),
856
+ 'maintenanceMargin': undefined,
857
+ 'maintenanceMarginPercentage': undefined,
858
+ 'initialMargin': this.parseNumber(this.safeString(position, 'pm')),
859
+ 'initialMarginPercentage': undefined,
860
+ 'leverage': this.safeInteger(position, 'l'),
861
+ 'liquidationPrice': this.parseNumber(this.safeString(position, 'lq')),
862
+ 'marginRatio': undefined,
863
+ 'marginMode': this.safeStringLower(position, 'mt'),
864
+ 'percentage': undefined,
865
+ });
866
+ }
867
+ parseWsPositionSide(rawPositionSide) {
868
+ const sides = {
869
+ '1': 'long',
870
+ '2': 'short',
871
+ };
872
+ return this.safeString(sides, rawPositionSide, rawPositionSide);
873
+ }
874
+ /**
875
+ * @method
876
+ * @name bydfi#watchBalance
877
+ * @description watch balance and get the amount of funds available for trading or funds locked in orders
878
+ * @see https://developers.bydfi.com/en/swap/websocket-account#balance-and-position-update-push
879
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
880
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/?id=balance-structure}
881
+ */
882
+ async watchBalance(params = {}) {
883
+ await this.loadMarkets();
884
+ const url = this.urls['api']['ws'];
885
+ const client = this.client(url);
886
+ this.fetchBalanceSnapshot(client);
887
+ const options = this.safeDict(this.options, 'watchBalance');
888
+ const fetchBalanceSnapshot = this.safeBool(options, 'fetchBalanceSnapshot', false);
889
+ const awaitBalanceSnapshot = this.safeBool(options, 'awaitBalanceSnapshot', true);
890
+ if (fetchBalanceSnapshot && awaitBalanceSnapshot) {
891
+ await client.future('fetchBalanceSnapshot');
892
+ }
893
+ const messageHash = 'balance';
894
+ return await this.watchPrivate([messageHash], params);
895
+ }
896
+ fetchBalanceSnapshot(client) {
897
+ const options = this.safeValue(this.options, 'watchBalance');
898
+ const fetchBalanceSnapshot = this.safeBool(options, 'fetchBalanceSnapshot', false);
899
+ if (fetchBalanceSnapshot) {
900
+ const messageHash = 'fetchBalanceSnapshot';
901
+ if (!(messageHash in client.futures)) {
902
+ client.future(messageHash);
903
+ this.spawn(this.loadBalanceSnapshot, client, messageHash);
904
+ }
905
+ }
906
+ }
907
+ async loadBalanceSnapshot(client, messageHash) {
908
+ const params = {
909
+ 'type': 'swap',
910
+ };
911
+ const response = await this.fetchBalance(params);
912
+ this.balance = this.extend(response, this.balance);
913
+ // don't remove the future from the .futures cache
914
+ const future = client.futures[messageHash];
915
+ future.resolve();
916
+ client.resolve(this.balance, 'balance');
917
+ }
918
+ handleBalance(client, message) {
919
+ //
920
+ // {
921
+ // "a": {
922
+ // "B": [
923
+ // {
924
+ // "a": "USDC",
925
+ // "ba": "0",
926
+ // "im": "1.46282986",
927
+ // "om": "0",
928
+ // "tfm": "1.46282986",
929
+ // "wb": "109.86879703"
930
+ // }
931
+ // ],
932
+ // "m": "ORDER",
933
+ // "p": [
934
+ // {
935
+ // "S": "1",
936
+ // "ap": "2925.81666667",
937
+ // "c": "USDC",
938
+ // "ct": "FUTURE",
939
+ // "l": 2,
940
+ // "lq": "1471.1840621072728637",
941
+ // "lv": "0",
942
+ // "ma": "0",
943
+ // "mt": "ISOLATED",
944
+ // "pm": "1.4628298566666665",
945
+ // "pt": "ONEWAY",
946
+ // "rp": "-0.00036721",
947
+ // "s": "ETH-USDC",
948
+ // "t": "0",
949
+ // "uq": "0.001",
950
+ // "v": "1"
951
+ // }
952
+ // ]
953
+ // },
954
+ // "T": 1766592694451,
955
+ // "E": 1766592694554,
956
+ // "e": "ACCOUNT_UPDATE"
957
+ // }
958
+ //
959
+ const messageHash = 'balance';
960
+ if (messageHash in client.futures) {
961
+ const data = this.safeDict(message, 'a', {});
962
+ const balances = this.safeList(data, 'B', []);
963
+ const timestamp = this.safeInteger(message, 'T');
964
+ const result = {
965
+ 'info': message,
966
+ 'timestamp': timestamp,
967
+ 'datetime': this.iso8601(timestamp),
968
+ };
969
+ for (let i = 0; i < balances.length; i++) {
970
+ const balance = balances[i];
971
+ const currencyId = this.safeString(balance, 'a');
972
+ const code = this.safeCurrencyCode(currencyId);
973
+ const account = this.account();
974
+ account['total'] = this.safeString(balance, 'wb');
975
+ account['used'] = this.safeString(balance, 'tfm');
976
+ result[code] = account;
977
+ }
978
+ const parsedBalance = this.safeBalance(result);
979
+ this.balance = this.extend(this.balance, parsedBalance);
980
+ client.resolve(this.balance, messageHash);
981
+ }
982
+ }
983
+ handleSubscriptionStatus(client, message) {
984
+ //
985
+ // {
986
+ // "result": true,
987
+ // "id": 1
988
+ // }
989
+ //
990
+ const id = this.safeString(message, 'id');
991
+ const subscriptionsById = this.indexBy(client.subscriptions, 'id');
992
+ const subscription = this.safeDict(subscriptionsById, id, {});
993
+ const isUnSubMessage = this.safeBool(subscription, 'unsubscribe', false);
994
+ if (isUnSubMessage) {
995
+ this.handleUnSubscription(client, subscription);
996
+ }
997
+ return message;
998
+ }
999
+ handleUnSubscription(client, subscription) {
1000
+ const messageHashes = this.safeList(subscription, 'messageHashes', []);
1001
+ const subHashIsPrefix = this.safeBool(subscription, 'subHashIsPrefix', false);
1002
+ for (let i = 0; i < messageHashes.length; i++) {
1003
+ const unsubHash = messageHashes[i];
1004
+ const subHash = unsubHash.replace('unsubscribe::', '');
1005
+ this.cleanUnsubscription(client, subHash, unsubHash, subHashIsPrefix);
1006
+ }
1007
+ this.cleanCache(subscription);
1008
+ }
1009
+ handlePong(client, message) {
1010
+ //
1011
+ // {
1012
+ // "id": 1,
1013
+ // "result": "pong"
1014
+ // }
1015
+ //
1016
+ client.lastPong = this.milliseconds();
1017
+ return message;
1018
+ }
1019
+ handleErrorMessage(client, message) {
1020
+ //
1021
+ // {
1022
+ // "msg": "Service error",
1023
+ // "code": "-1"
1024
+ // }
1025
+ //
1026
+ const code = this.safeString(message, 'code');
1027
+ const msg = this.safeString(message, 'msg');
1028
+ const feedback = this.id + ' ' + this.json(message);
1029
+ this.throwExactlyMatchedException(this.exceptions['exact'], msg, feedback);
1030
+ this.throwBroadlyMatchedException(this.exceptions['broad'], msg, feedback);
1031
+ this.throwExactlyMatchedException(this.exceptions['exact'], code, feedback);
1032
+ throw new errors.ExchangeError(feedback);
1033
+ }
1034
+ handleMessage(client, message) {
1035
+ const code = this.safeString(message, 'code');
1036
+ if (code !== undefined && (code !== '0')) {
1037
+ this.handleErrorMessage(client, message);
1038
+ }
1039
+ const result = this.safeString(message, 'result');
1040
+ if (result === 'pong') {
1041
+ this.handlePong(client, message);
1042
+ }
1043
+ else if (result !== undefined) {
1044
+ this.handleSubscriptionStatus(client, message);
1045
+ }
1046
+ else {
1047
+ const event = this.safeString(message, 'e');
1048
+ if (event === '24hrTicker') {
1049
+ this.handleTicker(client, message);
1050
+ }
1051
+ else if (event === 'kline') {
1052
+ this.handleOHLCV(client, message);
1053
+ }
1054
+ else if (event === 'depthUpdate') {
1055
+ this.handleOrderBook(client, message);
1056
+ }
1057
+ else if (event === 'ORDER_TRADE_UPDATE') {
1058
+ this.handleOrder(client, message);
1059
+ }
1060
+ else if (event === 'ACCOUNT_UPDATE') {
1061
+ const account = this.safeDict(message, 'a', {});
1062
+ const balances = this.safeList(account, 'B', []);
1063
+ const balancesLength = balances.length;
1064
+ if (balancesLength > 0) {
1065
+ this.handleBalance(client, message);
1066
+ }
1067
+ const positions = this.safeList(account, 'p', []);
1068
+ const positionsLength = positions.length;
1069
+ if (positionsLength > 0) {
1070
+ this.handlePositions(client, message);
1071
+ }
1072
+ }
1073
+ }
1074
+ }
1075
+ }
1076
+
1077
+ exports["default"] = bydfi;