ccxt 4.4.36 → 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 (38) hide show
  1. package/README.md +7 -7
  2. package/dist/ccxt.browser.min.js +2 -2
  3. package/dist/cjs/ccxt.js +6 -6
  4. package/dist/cjs/src/abstract/bitfinex1.js +9 -0
  5. package/dist/cjs/src/base/Exchange.js +6 -1
  6. package/dist/cjs/src/bitfinex.js +3178 -1161
  7. package/dist/cjs/src/bitfinex1.js +1760 -0
  8. package/dist/cjs/src/coinbase.js +87 -0
  9. package/dist/cjs/src/gate.js +1 -1
  10. package/dist/cjs/src/hyperliquid.js +125 -14
  11. package/dist/cjs/src/paradex.js +4 -2
  12. package/dist/cjs/src/pro/bitfinex.js +760 -271
  13. package/dist/cjs/src/pro/bitfinex1.js +675 -0
  14. package/dist/cjs/src/pro/probit.js +1 -0
  15. package/js/ccxt.d.ts +8 -8
  16. package/js/ccxt.js +6 -6
  17. package/js/src/abstract/bitfinex.d.ts +135 -64
  18. package/js/src/abstract/bitfinex1.d.ts +72 -0
  19. package/js/src/base/Exchange.js +6 -1
  20. package/js/src/bitfinex.d.ts +316 -106
  21. package/js/src/bitfinex.js +3179 -1162
  22. package/js/src/bitfinex1.d.ts +296 -0
  23. package/js/src/bitfinex1.js +1761 -0
  24. package/js/src/coinbase.d.ts +33 -0
  25. package/js/src/coinbase.js +87 -0
  26. package/js/src/gate.js +1 -1
  27. package/js/src/hyperliquid.d.ts +6 -1
  28. package/js/src/hyperliquid.js +125 -14
  29. package/js/src/paradex.d.ts +2 -0
  30. package/js/src/paradex.js +4 -2
  31. package/js/src/pro/bitfinex.d.ts +42 -10
  32. package/js/src/pro/bitfinex.js +761 -272
  33. package/js/src/pro/bitfinex1.d.ts +67 -0
  34. package/js/src/pro/bitfinex1.js +676 -0
  35. package/js/src/pro/probit.js +1 -0
  36. package/package.json +1 -1
  37. package/js/src/abstract/bitfinex2.d.ts +0 -143
  38. /package/js/src/abstract/{bitfinex2.js → bitfinex1.js} +0 -0
@@ -0,0 +1,675 @@
1
+ 'use strict';
2
+
3
+ var bitfinex1$1 = require('../bitfinex1.js');
4
+ var errors = require('../base/errors.js');
5
+ var Cache = require('../base/ws/Cache.js');
6
+ var Precise = require('../base/Precise.js');
7
+ var sha512 = require('../static_dependencies/noble-hashes/sha512.js');
8
+
9
+ // ---------------------------------------------------------------------------
10
+ // ---------------------------------------------------------------------------
11
+ class bitfinex1 extends bitfinex1$1 {
12
+ describe() {
13
+ return this.deepExtend(super.describe(), {
14
+ 'has': {
15
+ 'ws': true,
16
+ 'watchTicker': true,
17
+ 'watchTickers': false,
18
+ 'watchOrderBook': true,
19
+ 'watchTrades': true,
20
+ 'watchTradesForSymbols': false,
21
+ 'watchBalance': false,
22
+ 'watchOHLCV': false, // missing on the exchange side in v1
23
+ },
24
+ 'urls': {
25
+ 'api': {
26
+ 'ws': {
27
+ 'public': 'wss://api-pub.bitfinex.com/ws/1',
28
+ 'private': 'wss://api.bitfinex.com/ws/1',
29
+ },
30
+ },
31
+ },
32
+ 'options': {
33
+ 'watchOrderBook': {
34
+ 'prec': 'P0',
35
+ 'freq': 'F0',
36
+ },
37
+ 'ordersLimit': 1000,
38
+ },
39
+ });
40
+ }
41
+ async subscribe(channel, symbol, params = {}) {
42
+ await this.loadMarkets();
43
+ const market = this.market(symbol);
44
+ const marketId = market['id'];
45
+ const url = this.urls['api']['ws']['public'];
46
+ const messageHash = channel + ':' + marketId;
47
+ // const channel = 'trades';
48
+ const request = {
49
+ 'event': 'subscribe',
50
+ 'channel': channel,
51
+ 'symbol': marketId,
52
+ 'messageHash': messageHash,
53
+ };
54
+ return await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
55
+ }
56
+ /**
57
+ * @method
58
+ * @name bitfinex#watchTrades
59
+ * @description get the list of most recent trades for a particular symbol
60
+ * @see https://docs.bitfinex.com/v1/reference/ws-public-trades
61
+ * @param {string} symbol unified symbol of the market to fetch trades for
62
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
63
+ * @param {int} [limit] the maximum amount of trades to fetch
64
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
65
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
66
+ */
67
+ async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
68
+ await this.loadMarkets();
69
+ symbol = this.symbol(symbol);
70
+ const trades = await this.subscribe('trades', symbol, params);
71
+ if (this.newUpdates) {
72
+ limit = trades.getLimit(symbol, limit);
73
+ }
74
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
75
+ }
76
+ /**
77
+ * @method
78
+ * @name bitfinex#watchTicker
79
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
80
+ * @see https://docs.bitfinex.com/v1/reference/ws-public-ticker
81
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
82
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
83
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
84
+ */
85
+ async watchTicker(symbol, params = {}) {
86
+ return await this.subscribe('ticker', symbol, params);
87
+ }
88
+ handleTrades(client, message, subscription) {
89
+ //
90
+ // initial snapshot
91
+ //
92
+ // [
93
+ // 2,
94
+ // [
95
+ // [ null, 1580565020, 9374.9, 0.005 ],
96
+ // [ null, 1580565004, 9374.9, 0.005 ],
97
+ // [ null, 1580565003, 9374.9, 0.005 ],
98
+ // ]
99
+ // ]
100
+ //
101
+ // when a trade does not have an id yet
102
+ //
103
+ // // channel id, update type, seq, time, price, amount
104
+ // [ 2, "te", "28462857-BTCUSD", 1580565041, 9374.9, 0.005 ],
105
+ //
106
+ // when a trade already has an id
107
+ //
108
+ // // channel id, update type, seq, trade id, time, price, amount
109
+ // [ 2, "tu", "28462857-BTCUSD", 413357662, 1580565041, 9374.9, 0.005 ]
110
+ //
111
+ const channel = this.safeValue(subscription, 'channel');
112
+ const marketId = this.safeString(subscription, 'pair');
113
+ const messageHash = channel + ':' + marketId;
114
+ const tradesLimit = this.safeInteger(this.options, 'tradesLimit', 1000);
115
+ const market = this.safeMarket(marketId);
116
+ const symbol = market['symbol'];
117
+ const data = this.safeValue(message, 1);
118
+ let stored = this.safeValue(this.trades, symbol);
119
+ if (stored === undefined) {
120
+ stored = new Cache.ArrayCache(tradesLimit);
121
+ this.trades[symbol] = stored;
122
+ }
123
+ if (Array.isArray(data)) {
124
+ const trades = this.parseTrades(data, market);
125
+ for (let i = 0; i < trades.length; i++) {
126
+ stored.append(trades[i]);
127
+ }
128
+ }
129
+ else {
130
+ const second = this.safeString(message, 1);
131
+ if (second !== 'tu') {
132
+ return;
133
+ }
134
+ const trade = this.parseTrade(message, market);
135
+ stored.append(trade);
136
+ }
137
+ client.resolve(stored, messageHash);
138
+ }
139
+ parseTrade(trade, market = undefined) {
140
+ //
141
+ // snapshot trade
142
+ //
143
+ // // null, time, price, amount
144
+ // [ null, 1580565020, 9374.9, 0.005 ],
145
+ //
146
+ // when a trade does not have an id yet
147
+ //
148
+ // // channel id, update type, seq, time, price, amount
149
+ // [ 2, "te", "28462857-BTCUSD", 1580565041, 9374.9, 0.005 ],
150
+ //
151
+ // when a trade already has an id
152
+ //
153
+ // // channel id, update type, seq, trade id, time, price, amount
154
+ // [ 2, "tu", "28462857-BTCUSD", 413357662, 1580565041, 9374.9, 0.005 ]
155
+ //
156
+ if (!Array.isArray(trade)) {
157
+ return super.parseTrade(trade, market);
158
+ }
159
+ const tradeLength = trade.length;
160
+ const event = this.safeString(trade, 1);
161
+ let id = undefined;
162
+ if (event === 'tu') {
163
+ id = this.safeString(trade, tradeLength - 4);
164
+ }
165
+ const timestamp = this.safeTimestamp(trade, tradeLength - 3);
166
+ const price = this.safeString(trade, tradeLength - 2);
167
+ let amount = this.safeString(trade, tradeLength - 1);
168
+ let side = undefined;
169
+ if (amount !== undefined) {
170
+ side = Precise["default"].stringGt(amount, '0') ? 'buy' : 'sell';
171
+ amount = Precise["default"].stringAbs(amount);
172
+ }
173
+ const seq = this.safeString(trade, 2);
174
+ const parts = seq.split('-');
175
+ let marketId = this.safeString(parts, 1);
176
+ if (marketId !== undefined) {
177
+ marketId = marketId.replace('t', '');
178
+ }
179
+ const symbol = this.safeSymbol(marketId, market);
180
+ const takerOrMaker = undefined;
181
+ const orderId = undefined;
182
+ return this.safeTrade({
183
+ 'info': trade,
184
+ 'timestamp': timestamp,
185
+ 'datetime': this.iso8601(timestamp),
186
+ 'symbol': symbol,
187
+ 'id': id,
188
+ 'order': orderId,
189
+ 'type': undefined,
190
+ 'takerOrMaker': takerOrMaker,
191
+ 'side': side,
192
+ 'price': price,
193
+ 'amount': amount,
194
+ 'cost': undefined,
195
+ 'fee': undefined,
196
+ });
197
+ }
198
+ handleTicker(client, message, subscription) {
199
+ //
200
+ // [
201
+ // 2, // 0 CHANNEL_ID integer Channel ID
202
+ // 236.62, // 1 BID float Price of last highest bid
203
+ // 9.0029, // 2 BID_SIZE float Size of the last highest bid
204
+ // 236.88, // 3 ASK float Price of last lowest ask
205
+ // 7.1138, // 4 ASK_SIZE float Size of the last lowest ask
206
+ // -1.02, // 5 DAILY_CHANGE float Amount that the last price has changed since yesterday
207
+ // 0, // 6 DAILY_CHANGE_PERC float Amount that the price has changed expressed in percentage terms
208
+ // 236.52, // 7 LAST_PRICE float Price of the last trade.
209
+ // 5191.36754297, // 8 VOLUME float Daily volume
210
+ // 250.01, // 9 HIGH float Daily high
211
+ // 220.05, // 10 LOW float Daily low
212
+ // ]
213
+ //
214
+ const marketId = this.safeString(subscription, 'pair');
215
+ const symbol = this.safeSymbol(marketId);
216
+ const channel = 'ticker';
217
+ const messageHash = channel + ':' + marketId;
218
+ const last = this.safeString(message, 7);
219
+ const change = this.safeString(message, 5);
220
+ let open = undefined;
221
+ if ((last !== undefined) && (change !== undefined)) {
222
+ open = Precise["default"].stringSub(last, change);
223
+ }
224
+ const result = this.safeTicker({
225
+ 'symbol': symbol,
226
+ 'timestamp': undefined,
227
+ 'datetime': undefined,
228
+ 'high': this.safeString(message, 9),
229
+ 'low': this.safeString(message, 10),
230
+ 'bid': this.safeString(message, 1),
231
+ 'bidVolume': undefined,
232
+ 'ask': this.safeString(message, 3),
233
+ 'askVolume': undefined,
234
+ 'vwap': undefined,
235
+ 'open': this.parseNumber(open),
236
+ 'close': this.parseNumber(last),
237
+ 'last': this.parseNumber(last),
238
+ 'previousClose': undefined,
239
+ 'change': this.parseNumber(change),
240
+ 'percentage': this.safeString(message, 6),
241
+ 'average': undefined,
242
+ 'baseVolume': this.safeString(message, 8),
243
+ 'quoteVolume': undefined,
244
+ 'info': message,
245
+ });
246
+ this.tickers[symbol] = result;
247
+ client.resolve(result, messageHash);
248
+ }
249
+ /**
250
+ * @method
251
+ * @name bitfinex#watchOrderBook
252
+ * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
253
+ * @see https://docs.bitfinex.com/v1/reference/ws-public-order-books
254
+ * @param {string} symbol unified symbol of the market to fetch the order book for
255
+ * @param {int} [limit] the maximum amount of order book entries to return
256
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
257
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
258
+ */
259
+ async watchOrderBook(symbol, limit = undefined, params = {}) {
260
+ if (limit !== undefined) {
261
+ if ((limit !== 25) && (limit !== 100)) {
262
+ throw new errors.ExchangeError(this.id + ' watchOrderBook limit argument must be undefined, 25 or 100');
263
+ }
264
+ }
265
+ const options = this.safeValue(this.options, 'watchOrderBook', {});
266
+ const prec = this.safeString(options, 'prec', 'P0');
267
+ const freq = this.safeString(options, 'freq', 'F0');
268
+ const request = {
269
+ // "event": "subscribe", // added in subscribe()
270
+ // "channel": channel, // added in subscribe()
271
+ // "symbol": marketId, // added in subscribe()
272
+ 'prec': prec,
273
+ 'freq': freq,
274
+ 'len': limit, // string, number of price points, '25', '100', default = '25'
275
+ };
276
+ const orderbook = await this.subscribe('book', symbol, this.deepExtend(request, params));
277
+ return orderbook.limit();
278
+ }
279
+ handleOrderBook(client, message, subscription) {
280
+ //
281
+ // first message (snapshot)
282
+ //
283
+ // [
284
+ // 18691, // channel id
285
+ // [
286
+ // [ 7364.8, 10, 4.354802 ], // price, count, size > 0 = bid
287
+ // [ 7364.7, 1, 0.00288831 ],
288
+ // [ 7364.3, 12, 0.048 ],
289
+ // [ 7364.9, 3, -0.42028976 ], // price, count, size < 0 = ask
290
+ // [ 7365, 1, -0.25 ],
291
+ // [ 7365.5, 1, -0.00371937 ],
292
+ // ]
293
+ // ]
294
+ //
295
+ // subsequent updates
296
+ //
297
+ // [
298
+ // 30, // channel id
299
+ // 9339.9, // price
300
+ // 0, // count
301
+ // -1, // size > 0 = bid, size < 0 = ask
302
+ // ]
303
+ //
304
+ const marketId = this.safeString(subscription, 'pair');
305
+ const symbol = this.safeSymbol(marketId);
306
+ const channel = 'book';
307
+ const messageHash = channel + ':' + marketId;
308
+ const prec = this.safeString(subscription, 'prec', 'P0');
309
+ const isRaw = (prec === 'R0');
310
+ // if it is an initial snapshot
311
+ if (Array.isArray(message[1])) {
312
+ const limit = this.safeInteger(subscription, 'len');
313
+ if (isRaw) {
314
+ // raw order books
315
+ this.orderbooks[symbol] = this.indexedOrderBook({}, limit);
316
+ }
317
+ else {
318
+ // P0, P1, P2, P3, P4
319
+ this.orderbooks[symbol] = this.countedOrderBook({}, limit);
320
+ }
321
+ const orderbook = this.orderbooks[symbol];
322
+ if (isRaw) {
323
+ const deltas = message[1];
324
+ for (let i = 0; i < deltas.length; i++) {
325
+ const delta = deltas[i];
326
+ const id = this.safeString(delta, 0);
327
+ const price = this.safeFloat(delta, 1);
328
+ const delta2Value = delta[2];
329
+ const size = (delta2Value < 0) ? -delta2Value : delta2Value;
330
+ const side = (delta2Value < 0) ? 'asks' : 'bids';
331
+ const bookside = orderbook[side];
332
+ bookside.storeArray([price, size, id]);
333
+ }
334
+ }
335
+ else {
336
+ const deltas = message[1];
337
+ for (let i = 0; i < deltas.length; i++) {
338
+ const delta = deltas[i];
339
+ const delta2 = delta[2];
340
+ const size = (delta2 < 0) ? -delta2 : delta2;
341
+ const side = (delta2 < 0) ? 'asks' : 'bids';
342
+ const countedBookSide = orderbook[side];
343
+ countedBookSide.storeArray([delta[0], size, delta[1]]);
344
+ }
345
+ }
346
+ client.resolve(orderbook, messageHash);
347
+ }
348
+ else {
349
+ const orderbook = this.orderbooks[symbol];
350
+ if (isRaw) {
351
+ const id = this.safeString(message, 1);
352
+ const price = this.safeString(message, 2);
353
+ const message3 = message[3];
354
+ const size = (message3 < 0) ? -message3 : message3;
355
+ const side = (message3 < 0) ? 'asks' : 'bids';
356
+ const bookside = orderbook[side];
357
+ // price = 0 means that you have to remove the order from your book
358
+ const amount = Precise["default"].stringGt(price, '0') ? size : '0';
359
+ bookside.storeArray([this.parseNumber(price), this.parseNumber(amount), id]);
360
+ }
361
+ else {
362
+ const message3Value = message[3];
363
+ const size = (message3Value < 0) ? -message3Value : message3Value;
364
+ const side = (message3Value < 0) ? 'asks' : 'bids';
365
+ const countedBookSide = orderbook[side];
366
+ countedBookSide.storeArray([message[1], size, message[2]]);
367
+ }
368
+ client.resolve(orderbook, messageHash);
369
+ }
370
+ }
371
+ handleHeartbeat(client, message) {
372
+ //
373
+ // every second (approx) if no other updates are sent
374
+ //
375
+ // { "event": "heartbeat" }
376
+ //
377
+ const event = this.safeString(message, 'event');
378
+ client.resolve(message, event);
379
+ }
380
+ handleSystemStatus(client, message) {
381
+ //
382
+ // todo: answer the question whether handleSystemStatus should be renamed
383
+ // and unified as handleStatus for any usage pattern that
384
+ // involves system status and maintenance updates
385
+ //
386
+ // {
387
+ // "event": "info",
388
+ // "version": 2,
389
+ // "serverId": "e293377e-7bb7-427e-b28c-5db045b2c1d1",
390
+ // "platform": { status: 1 }, // 1 for operative, 0 for maintenance
391
+ // }
392
+ //
393
+ return message;
394
+ }
395
+ handleSubscriptionStatus(client, message) {
396
+ //
397
+ // {
398
+ // "event": "subscribed",
399
+ // "channel": "book",
400
+ // "chanId": 67473,
401
+ // "symbol": "tBTCUSD",
402
+ // "prec": "P0",
403
+ // "freq": "F0",
404
+ // "len": "25",
405
+ // "pair": "BTCUSD"
406
+ // }
407
+ //
408
+ const channelId = this.safeString(message, 'chanId');
409
+ client.subscriptions[channelId] = message;
410
+ return message;
411
+ }
412
+ async authenticate(params = {}) {
413
+ const url = this.urls['api']['ws']['private'];
414
+ const client = this.client(url);
415
+ const future = client.future('authenticated');
416
+ const method = 'auth';
417
+ const authenticated = this.safeValue(client.subscriptions, method);
418
+ if (authenticated === undefined) {
419
+ const nonce = this.milliseconds();
420
+ const payload = 'AUTH' + nonce.toString();
421
+ const signature = this.hmac(this.encode(payload), this.encode(this.secret), sha512.sha384, 'hex');
422
+ const request = {
423
+ 'apiKey': this.apiKey,
424
+ 'authSig': signature,
425
+ 'authNonce': nonce,
426
+ 'authPayload': payload,
427
+ 'event': method,
428
+ 'filter': [
429
+ 'trading',
430
+ 'wallet',
431
+ ],
432
+ };
433
+ this.spawn(this.watch, url, method, request, 1);
434
+ }
435
+ return await future;
436
+ }
437
+ handleAuthenticationMessage(client, message) {
438
+ const status = this.safeString(message, 'status');
439
+ if (status === 'OK') {
440
+ // we resolve the future here permanently so authentication only happens once
441
+ const future = this.safeValue(client.futures, 'authenticated');
442
+ future.resolve(true);
443
+ }
444
+ else {
445
+ const error = new errors.AuthenticationError(this.json(message));
446
+ client.reject(error, 'authenticated');
447
+ // allows further authentication attempts
448
+ const method = this.safeString(message, 'event');
449
+ if (method in client.subscriptions) {
450
+ delete client.subscriptions[method];
451
+ }
452
+ }
453
+ }
454
+ async watchOrder(id, symbol = undefined, params = {}) {
455
+ await this.loadMarkets();
456
+ const url = this.urls['api']['ws']['private'];
457
+ await this.authenticate();
458
+ return await this.watch(url, id, undefined, 1);
459
+ }
460
+ /**
461
+ * @method
462
+ * @name bitfinex#watchOrders
463
+ * @description watches information on multiple orders made by the user
464
+ * @see https://docs.bitfinex.com/v1/reference/ws-auth-order-updates
465
+ * @see https://docs.bitfinex.com/v1/reference/ws-auth-order-snapshots
466
+ * @param {string} symbol unified market symbol of the market orders were made in
467
+ * @param {int} [since] the earliest time in ms to fetch orders for
468
+ * @param {int} [limit] the maximum number of order structures to retrieve
469
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
470
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
471
+ */
472
+ async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
473
+ await this.loadMarkets();
474
+ await this.authenticate();
475
+ if (symbol !== undefined) {
476
+ symbol = this.symbol(symbol);
477
+ }
478
+ const url = this.urls['api']['ws']['private'];
479
+ const orders = await this.watch(url, 'os', undefined, 1);
480
+ if (this.newUpdates) {
481
+ limit = orders.getLimit(symbol, limit);
482
+ }
483
+ return this.filterBySymbolSinceLimit(orders, symbol, since, limit, true);
484
+ }
485
+ handleOrders(client, message, subscription) {
486
+ //
487
+ // order snapshot
488
+ //
489
+ // [
490
+ // 0,
491
+ // "os",
492
+ // [
493
+ // [
494
+ // 45287766631,
495
+ // "ETHUST",
496
+ // -0.07,
497
+ // -0.07,
498
+ // "EXCHANGE LIMIT",
499
+ // "ACTIVE",
500
+ // 210,
501
+ // 0,
502
+ // "2020-05-16T13:17:46Z",
503
+ // 0,
504
+ // 0,
505
+ // 0
506
+ // ]
507
+ // ]
508
+ // ]
509
+ //
510
+ // order cancel
511
+ //
512
+ // [
513
+ // 0,
514
+ // "oc",
515
+ // [
516
+ // 45287766631,
517
+ // "ETHUST",
518
+ // -0.07,
519
+ // -0.07,
520
+ // "EXCHANGE LIMIT",
521
+ // "CANCELED",
522
+ // 210,
523
+ // 0,
524
+ // "2020-05-16T13:17:46Z",
525
+ // 0,
526
+ // 0,
527
+ // 0,
528
+ // ]
529
+ // ]
530
+ //
531
+ const data = this.safeValue(message, 2, []);
532
+ const messageType = this.safeString(message, 1);
533
+ if (messageType === 'os') {
534
+ for (let i = 0; i < data.length; i++) {
535
+ const value = data[i];
536
+ this.handleOrder(client, value);
537
+ }
538
+ }
539
+ else {
540
+ this.handleOrder(client, data);
541
+ }
542
+ if (this.orders !== undefined) {
543
+ client.resolve(this.orders, 'os');
544
+ }
545
+ }
546
+ parseWsOrderStatus(status) {
547
+ const statuses = {
548
+ 'ACTIVE': 'open',
549
+ 'CANCELED': 'canceled',
550
+ };
551
+ return this.safeString(statuses, status, status);
552
+ }
553
+ handleOrder(client, order) {
554
+ // [ 45287766631,
555
+ // "ETHUST",
556
+ // -0.07,
557
+ // -0.07,
558
+ // "EXCHANGE LIMIT",
559
+ // "CANCELED",
560
+ // 210,
561
+ // 0,
562
+ // "2020-05-16T13:17:46Z",
563
+ // 0,
564
+ // 0,
565
+ // 0 ]
566
+ const id = this.safeString(order, 0);
567
+ const marketId = this.safeString(order, 1);
568
+ const symbol = this.safeSymbol(marketId);
569
+ let amount = this.safeString(order, 2);
570
+ let remaining = this.safeString(order, 3);
571
+ let side = 'buy';
572
+ if (Precise["default"].stringLt(amount, '0')) {
573
+ amount = Precise["default"].stringAbs(amount);
574
+ remaining = Precise["default"].stringAbs(remaining);
575
+ side = 'sell';
576
+ }
577
+ let type = this.safeString(order, 4);
578
+ if (type.indexOf('LIMIT') > -1) {
579
+ type = 'limit';
580
+ }
581
+ else if (type.indexOf('MARKET') > -1) {
582
+ type = 'market';
583
+ }
584
+ const status = this.parseWsOrderStatus(this.safeString(order, 5));
585
+ const price = this.safeString(order, 6);
586
+ const rawDatetime = this.safeString(order, 8);
587
+ const timestamp = this.parse8601(rawDatetime);
588
+ const parsed = this.safeOrder({
589
+ 'info': order,
590
+ 'id': id,
591
+ 'clientOrderId': undefined,
592
+ 'timestamp': timestamp,
593
+ 'datetime': this.iso8601(timestamp),
594
+ 'lastTradeTimestamp': undefined,
595
+ 'symbol': symbol,
596
+ 'type': type,
597
+ 'side': side,
598
+ 'price': price,
599
+ 'stopPrice': undefined,
600
+ 'triggerPrice': undefined,
601
+ 'average': undefined,
602
+ 'amount': amount,
603
+ 'remaining': remaining,
604
+ 'filled': undefined,
605
+ 'status': status,
606
+ 'fee': undefined,
607
+ 'cost': undefined,
608
+ 'trades': undefined,
609
+ });
610
+ if (this.orders === undefined) {
611
+ const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
612
+ this.orders = new Cache.ArrayCacheBySymbolById(limit);
613
+ }
614
+ const orders = this.orders;
615
+ orders.append(parsed);
616
+ client.resolve(parsed, id);
617
+ return parsed;
618
+ }
619
+ handleMessage(client, message) {
620
+ if (Array.isArray(message)) {
621
+ const channelId = this.safeString(message, 0);
622
+ //
623
+ // [
624
+ // 1231,
625
+ // "hb",
626
+ // ]
627
+ //
628
+ if (message[1] === 'hb') {
629
+ return; // skip heartbeats within subscription channels for now
630
+ }
631
+ const subscription = this.safeValue(client.subscriptions, channelId, {});
632
+ const channel = this.safeString(subscription, 'channel');
633
+ const name = this.safeString(message, 1);
634
+ const methods = {
635
+ 'book': this.handleOrderBook,
636
+ // 'ohlc': this.handleOHLCV,
637
+ 'ticker': this.handleTicker,
638
+ 'trades': this.handleTrades,
639
+ 'os': this.handleOrders,
640
+ 'on': this.handleOrders,
641
+ 'oc': this.handleOrders,
642
+ };
643
+ const method = this.safeValue2(methods, channel, name);
644
+ if (method !== undefined) {
645
+ method.call(this, client, message, subscription);
646
+ }
647
+ }
648
+ else {
649
+ // todo add bitfinex handleErrorMessage
650
+ //
651
+ // {
652
+ // "event": "info",
653
+ // "version": 2,
654
+ // "serverId": "e293377e-7bb7-427e-b28c-5db045b2c1d1",
655
+ // "platform": { status: 1 }, // 1 for operative, 0 for maintenance
656
+ // }
657
+ //
658
+ const event = this.safeString(message, 'event');
659
+ if (event !== undefined) {
660
+ const methods = {
661
+ 'info': this.handleSystemStatus,
662
+ // 'book': 'handleOrderBook',
663
+ 'subscribed': this.handleSubscriptionStatus,
664
+ 'auth': this.handleAuthenticationMessage,
665
+ };
666
+ const method = this.safeValue(methods, event);
667
+ if (method !== undefined) {
668
+ method.call(this, client, message);
669
+ }
670
+ }
671
+ }
672
+ }
673
+ }
674
+
675
+ module.exports = bitfinex1;
@@ -154,6 +154,7 @@ class probit extends probit$1 {
154
154
  */
155
155
  async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
156
156
  const channel = 'recent_trades';
157
+ symbol = this.safeSymbol(symbol);
157
158
  const trades = await this.subscribePublic('watchTrades', symbol, 'trades', channel, params);
158
159
  if (this.newUpdates) {
159
160
  limit = trades.getLimit(symbol, limit);