ccxt 4.4.90 → 4.4.91
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -6
- package/dist/ccxt.browser.min.js +2 -2
- package/dist/cjs/ccxt.js +1 -4
- package/dist/cjs/src/base/Exchange.js +9 -11
- package/dist/cjs/src/base/ws/Client.js +4 -34
- package/dist/cjs/src/binance.js +1 -1
- package/dist/cjs/src/bitmex.js +2 -1
- package/dist/cjs/src/cex.js +61 -0
- package/dist/cjs/src/cryptocom.js +21 -2
- package/dist/cjs/src/cryptomus.js +1 -1
- package/dist/cjs/src/exmo.js +14 -7
- package/dist/cjs/src/fmfwio.js +1 -1
- package/dist/cjs/src/gate.js +2 -2
- package/dist/cjs/src/hyperliquid.js +115 -59
- package/dist/cjs/src/kraken.js +29 -1
- package/dist/cjs/src/mexc.js +1 -0
- package/dist/cjs/src/modetrade.js +2 -2
- package/dist/cjs/src/paradex.js +1 -1
- package/dist/cjs/src/pro/bitstamp.js +1 -1
- package/dist/cjs/src/pro/bybit.js +6 -143
- package/dist/cjs/src/pro/kraken.js +251 -264
- package/dist/cjs/src/pro/mexc.js +0 -1
- package/js/ccxt.d.ts +2 -5
- package/js/ccxt.js +2 -4
- package/js/src/base/Exchange.d.ts +2 -1
- package/js/src/base/Exchange.js +10 -12
- package/js/src/base/ws/Client.d.ts +0 -2
- package/js/src/base/ws/Client.js +4 -34
- package/js/src/binance.js +1 -1
- package/js/src/bitmex.js +2 -1
- package/js/src/cex.js +61 -0
- package/js/src/cryptocom.js +21 -2
- package/js/src/cryptomus.js +1 -1
- package/js/src/exmo.js +14 -7
- package/js/src/fmfwio.js +2 -2
- package/js/src/gate.js +2 -2
- package/js/src/hyperliquid.d.ts +1 -0
- package/js/src/hyperliquid.js +115 -59
- package/js/src/kraken.js +29 -1
- package/js/src/mexc.js +1 -0
- package/js/src/modetrade.js +2 -2
- package/js/src/p2b.d.ts +1 -2
- package/js/src/paradex.js +1 -1
- package/js/src/pro/bitstamp.js +1 -1
- package/js/src/pro/bybit.d.ts +0 -1
- package/js/src/pro/bybit.js +6 -143
- package/js/src/pro/kraken.d.ts +17 -17
- package/js/src/pro/kraken.js +251 -264
- package/js/src/pro/mexc.js +0 -1
- package/js/src/tradeogre.d.ts +1 -2
- package/package.json +1 -1
- package/js/src/abstract/coinlist.d.ts +0 -60
- package/js/src/abstract/coinlist.js +0 -11
- package/js/src/coinlist.d.ts +0 -384
- package/js/src/coinlist.js +0 -2610
package/js/src/pro/kraken.js
CHANGED
|
@@ -40,6 +40,7 @@ export default class kraken extends krakenRest {
|
|
|
40
40
|
'public': 'wss://ws.kraken.com',
|
|
41
41
|
'private': 'wss://ws-auth.kraken.com',
|
|
42
42
|
'privateV2': 'wss://ws-auth.kraken.com/v2',
|
|
43
|
+
'publicV2': 'wss://ws.kraken.com/v2',
|
|
43
44
|
'beta': 'wss://beta-ws.kraken.com',
|
|
44
45
|
'beta-private': 'wss://beta-ws-auth.kraken.com',
|
|
45
46
|
},
|
|
@@ -54,9 +55,13 @@ export default class kraken extends krakenRest {
|
|
|
54
55
|
'ordersLimit': 1000,
|
|
55
56
|
'symbolsByOrderId': {},
|
|
56
57
|
'watchOrderBook': {
|
|
57
|
-
'checksum':
|
|
58
|
+
'checksum': false,
|
|
58
59
|
},
|
|
59
60
|
},
|
|
61
|
+
'streaming': {
|
|
62
|
+
'ping': this.ping,
|
|
63
|
+
'keepAlive': 6000,
|
|
64
|
+
},
|
|
60
65
|
'exceptions': {
|
|
61
66
|
'ws': {
|
|
62
67
|
'exact': {
|
|
@@ -107,6 +112,7 @@ export default class kraken extends krakenRest {
|
|
|
107
112
|
'EService:Market in post_only mode': NotSupported,
|
|
108
113
|
'EService:Unavailable': ExchangeNotAvailable,
|
|
109
114
|
'ETrade:Invalid request': BadRequest,
|
|
115
|
+
'ESession:Invalid session': AuthenticationError,
|
|
110
116
|
},
|
|
111
117
|
},
|
|
112
118
|
},
|
|
@@ -374,8 +380,8 @@ export default class kraken extends krakenRest {
|
|
|
374
380
|
/**
|
|
375
381
|
* @method
|
|
376
382
|
* @name kraken#cancelOrdersWs
|
|
377
|
-
* @see https://docs.kraken.com/api/docs/websocket-v1/cancelorder
|
|
378
383
|
* @description cancel multiple orders
|
|
384
|
+
* @see https://docs.kraken.com/api/docs/websocket-v2/cancel_order
|
|
379
385
|
* @param {string[]} ids order ids
|
|
380
386
|
* @param {string} [symbol] unified market symbol, default is undefined
|
|
381
387
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
@@ -403,8 +409,8 @@ export default class kraken extends krakenRest {
|
|
|
403
409
|
/**
|
|
404
410
|
* @method
|
|
405
411
|
* @name kraken#cancelOrderWs
|
|
406
|
-
* @see https://docs.kraken.com/api/docs/websocket-v1/cancelorder
|
|
407
412
|
* @description cancels an open order
|
|
413
|
+
* @see https://docs.kraken.com/api/docs/websocket-v2/cancel_order
|
|
408
414
|
* @param {string} id order id
|
|
409
415
|
* @param {string} [symbol] unified symbol of the market the order was made in
|
|
410
416
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
@@ -448,8 +454,8 @@ export default class kraken extends krakenRest {
|
|
|
448
454
|
/**
|
|
449
455
|
* @method
|
|
450
456
|
* @name kraken#cancelAllOrdersWs
|
|
451
|
-
* @see https://docs.kraken.com/api/docs/websocket-v1/cancelall
|
|
452
457
|
* @description cancel all open orders
|
|
458
|
+
* @see https://docs.kraken.com/api/docs/websocket-v2/cancel_all
|
|
453
459
|
* @param {string} [symbol] unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
|
|
454
460
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
455
461
|
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
@@ -488,54 +494,57 @@ export default class kraken extends krakenRest {
|
|
|
488
494
|
const reqId = this.safeValue(message, 'req_id');
|
|
489
495
|
client.resolve(message, reqId);
|
|
490
496
|
}
|
|
491
|
-
handleTicker(client, message
|
|
497
|
+
handleTicker(client, message) {
|
|
492
498
|
//
|
|
493
|
-
//
|
|
494
|
-
//
|
|
495
|
-
//
|
|
496
|
-
//
|
|
497
|
-
//
|
|
498
|
-
//
|
|
499
|
-
//
|
|
500
|
-
//
|
|
501
|
-
//
|
|
502
|
-
//
|
|
503
|
-
//
|
|
504
|
-
//
|
|
505
|
-
//
|
|
506
|
-
//
|
|
507
|
-
//
|
|
508
|
-
//
|
|
499
|
+
// {
|
|
500
|
+
// "channel": "ticker",
|
|
501
|
+
// "type": "snapshot",
|
|
502
|
+
// "data": [
|
|
503
|
+
// {
|
|
504
|
+
// "symbol": "BTC/USD",
|
|
505
|
+
// "bid": 108359.8,
|
|
506
|
+
// "bid_qty": 0.01362603,
|
|
507
|
+
// "ask": 108359.9,
|
|
508
|
+
// "ask_qty": 17.17988863,
|
|
509
|
+
// "last": 108359.8,
|
|
510
|
+
// "volume": 2158.32346723,
|
|
511
|
+
// "vwap": 108894.5,
|
|
512
|
+
// "low": 106824,
|
|
513
|
+
// "high": 111300,
|
|
514
|
+
// "change": -2679.9,
|
|
515
|
+
// "change_pct": -2.41
|
|
516
|
+
// }
|
|
517
|
+
// ]
|
|
518
|
+
// }
|
|
509
519
|
//
|
|
510
|
-
const
|
|
511
|
-
const
|
|
512
|
-
const symbol =
|
|
520
|
+
const data = this.safeList(message, 'data', []);
|
|
521
|
+
const ticker = data[0];
|
|
522
|
+
const symbol = this.safeString(ticker, 'symbol');
|
|
513
523
|
const messageHash = this.getMessageHash('ticker', undefined, symbol);
|
|
514
|
-
const
|
|
515
|
-
const vwap = this.safeString(ticker['p'], 0);
|
|
524
|
+
const vwap = this.safeString(ticker, 'vwap');
|
|
516
525
|
let quoteVolume = undefined;
|
|
517
|
-
const baseVolume = this.safeString(ticker
|
|
526
|
+
const baseVolume = this.safeString(ticker, 'volume');
|
|
518
527
|
if (baseVolume !== undefined && vwap !== undefined) {
|
|
519
528
|
quoteVolume = Precise.stringMul(baseVolume, vwap);
|
|
520
529
|
}
|
|
521
|
-
const last = this.safeString(ticker
|
|
530
|
+
const last = this.safeString(ticker, 'last');
|
|
522
531
|
const result = this.safeTicker({
|
|
523
532
|
'symbol': symbol,
|
|
524
533
|
'timestamp': undefined,
|
|
525
534
|
'datetime': undefined,
|
|
526
|
-
'high': this.safeString(ticker
|
|
527
|
-
'low': this.safeString(ticker
|
|
528
|
-
'bid': this.safeString(ticker
|
|
529
|
-
'bidVolume': this.safeString(ticker
|
|
530
|
-
'ask': this.safeString(ticker
|
|
531
|
-
'askVolume': this.safeString(ticker
|
|
535
|
+
'high': this.safeString(ticker, 'high'),
|
|
536
|
+
'low': this.safeString(ticker, 'low'),
|
|
537
|
+
'bid': this.safeString(ticker, 'bid'),
|
|
538
|
+
'bidVolume': this.safeString(ticker, 'bid_qty'),
|
|
539
|
+
'ask': this.safeString(ticker, 'ask'),
|
|
540
|
+
'askVolume': this.safeString(ticker, 'ask_qty'),
|
|
532
541
|
'vwap': vwap,
|
|
533
|
-
'open':
|
|
542
|
+
'open': undefined,
|
|
534
543
|
'close': last,
|
|
535
544
|
'last': last,
|
|
536
545
|
'previousClose': undefined,
|
|
537
|
-
'change':
|
|
538
|
-
'percentage':
|
|
546
|
+
'change': this.safeString(ticker, 'change'),
|
|
547
|
+
'percentage': this.safeString(ticker, 'change_pct'),
|
|
539
548
|
'average': undefined,
|
|
540
549
|
'baseVolume': baseVolume,
|
|
541
550
|
'quoteVolume': quoteVolume,
|
|
@@ -544,31 +553,36 @@ export default class kraken extends krakenRest {
|
|
|
544
553
|
this.tickers[symbol] = result;
|
|
545
554
|
client.resolve(result, messageHash);
|
|
546
555
|
}
|
|
547
|
-
handleTrades(client, message
|
|
556
|
+
handleTrades(client, message) {
|
|
548
557
|
//
|
|
549
|
-
//
|
|
550
|
-
//
|
|
551
|
-
//
|
|
552
|
-
//
|
|
553
|
-
//
|
|
554
|
-
//
|
|
555
|
-
//
|
|
556
|
-
//
|
|
557
|
-
//
|
|
558
|
+
// {
|
|
559
|
+
// "channel": "trade",
|
|
560
|
+
// "type": "update",
|
|
561
|
+
// "data": [
|
|
562
|
+
// {
|
|
563
|
+
// "symbol": "MATIC/USD",
|
|
564
|
+
// "side": "sell",
|
|
565
|
+
// "price": 0.5117,
|
|
566
|
+
// "qty": 40.0,
|
|
567
|
+
// "ord_type": "market",
|
|
568
|
+
// "trade_id": 4665906,
|
|
569
|
+
// "timestamp": "2023-09-25T07:49:37.708706Z"
|
|
570
|
+
// }
|
|
571
|
+
// ]
|
|
572
|
+
// }
|
|
558
573
|
//
|
|
559
|
-
const
|
|
560
|
-
const
|
|
561
|
-
const
|
|
562
|
-
const
|
|
563
|
-
const messageHash = this.getMessageHash(name, undefined, symbol);
|
|
574
|
+
const data = this.safeList(message, 'data', []);
|
|
575
|
+
const trade = data[0];
|
|
576
|
+
const symbol = this.safeString(trade, 'symbol');
|
|
577
|
+
const messageHash = this.getMessageHash('trade', undefined, symbol);
|
|
564
578
|
let stored = this.safeValue(this.trades, symbol);
|
|
565
579
|
if (stored === undefined) {
|
|
566
580
|
const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
|
|
567
581
|
stored = new ArrayCache(limit);
|
|
568
582
|
this.trades[symbol] = stored;
|
|
569
583
|
}
|
|
570
|
-
const
|
|
571
|
-
const parsed = this.parseTrades(
|
|
584
|
+
const market = this.market(symbol);
|
|
585
|
+
const parsed = this.parseTrades(data, market);
|
|
572
586
|
for (let i = 0; i < parsed.length; i++) {
|
|
573
587
|
stored.append(parsed[i]);
|
|
574
588
|
}
|
|
@@ -656,7 +670,7 @@ export default class kraken extends krakenRest {
|
|
|
656
670
|
* @method
|
|
657
671
|
* @name kraken#watchTicker
|
|
658
672
|
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
659
|
-
* @see https://docs.kraken.com/api/docs/websocket-
|
|
673
|
+
* @see https://docs.kraken.com/api/docs/websocket-v2/ticker
|
|
660
674
|
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
661
675
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
662
676
|
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
@@ -671,7 +685,7 @@ export default class kraken extends krakenRest {
|
|
|
671
685
|
* @method
|
|
672
686
|
* @name kraken#watchTickers
|
|
673
687
|
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
674
|
-
* @see https://docs.kraken.com/api/docs/websocket-
|
|
688
|
+
* @see https://docs.kraken.com/api/docs/websocket-v2/ticker
|
|
675
689
|
* @param {string[]} symbols
|
|
676
690
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
677
691
|
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
@@ -690,8 +704,8 @@ export default class kraken extends krakenRest {
|
|
|
690
704
|
/**
|
|
691
705
|
* @method
|
|
692
706
|
* @name kraken#watchBidsAsks
|
|
693
|
-
* @see https://docs.kraken.com/api/docs/websocket-v1/spread
|
|
694
707
|
* @description watches best bid & ask for symbols
|
|
708
|
+
* @see https://docs.kraken.com/api/docs/websocket-v2/ticker
|
|
695
709
|
* @param {string[]} symbols unified symbol of the market to fetch the ticker for
|
|
696
710
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
697
711
|
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
@@ -699,7 +713,8 @@ export default class kraken extends krakenRest {
|
|
|
699
713
|
async watchBidsAsks(symbols = undefined, params = {}) {
|
|
700
714
|
await this.loadMarkets();
|
|
701
715
|
symbols = this.marketSymbols(symbols, undefined, false);
|
|
702
|
-
|
|
716
|
+
params['event_trigger'] = 'bbo';
|
|
717
|
+
const ticker = await this.watchMultiHelper('bidask', 'ticker', symbols, undefined, params);
|
|
703
718
|
if (this.newUpdates) {
|
|
704
719
|
const result = {};
|
|
705
720
|
result[ticker['symbol']] = ticker;
|
|
@@ -707,49 +722,11 @@ export default class kraken extends krakenRest {
|
|
|
707
722
|
}
|
|
708
723
|
return this.filterByArray(this.bidsasks, 'symbol', symbols);
|
|
709
724
|
}
|
|
710
|
-
handleBidAsk(client, message, subscription) {
|
|
711
|
-
//
|
|
712
|
-
// [
|
|
713
|
-
// 7208974, // channelID
|
|
714
|
-
// [
|
|
715
|
-
// "63758.60000", // bid
|
|
716
|
-
// "63759.10000", // ask
|
|
717
|
-
// "1726814731.089778", // timestamp
|
|
718
|
-
// "0.00057917", // bid_volume
|
|
719
|
-
// "0.15681688" // ask_volume
|
|
720
|
-
// ],
|
|
721
|
-
// "spread",
|
|
722
|
-
// "XBT/USDT"
|
|
723
|
-
// ]
|
|
724
|
-
//
|
|
725
|
-
const parsedTicker = this.parseWsBidAsk(message);
|
|
726
|
-
const symbol = parsedTicker['symbol'];
|
|
727
|
-
this.bidsasks[symbol] = parsedTicker;
|
|
728
|
-
const messageHash = this.getMessageHash('bidask', undefined, symbol);
|
|
729
|
-
client.resolve(parsedTicker, messageHash);
|
|
730
|
-
}
|
|
731
|
-
parseWsBidAsk(ticker, market = undefined) {
|
|
732
|
-
const data = this.safeList(ticker, 1, []);
|
|
733
|
-
const marketId = this.safeString(ticker, 3);
|
|
734
|
-
market = this.safeValue(this.options['marketsByWsName'], marketId);
|
|
735
|
-
const symbol = this.safeString(market, 'symbol');
|
|
736
|
-
const timestamp = this.parseToInt(this.safeInteger(data, 2)) * 1000;
|
|
737
|
-
return this.safeTicker({
|
|
738
|
-
'symbol': symbol,
|
|
739
|
-
'timestamp': timestamp,
|
|
740
|
-
'datetime': this.iso8601(timestamp),
|
|
741
|
-
'ask': this.safeString(data, 1),
|
|
742
|
-
'askVolume': this.safeString(data, 4),
|
|
743
|
-
'bid': this.safeString(data, 0),
|
|
744
|
-
'bidVolume': this.safeString(data, 3),
|
|
745
|
-
'info': ticker,
|
|
746
|
-
}, market);
|
|
747
|
-
}
|
|
748
725
|
/**
|
|
749
726
|
* @method
|
|
750
727
|
* @name kraken#watchTrades
|
|
751
728
|
* @description get the list of most recent trades for a particular symbol
|
|
752
|
-
* @see https://docs.kraken.com/api/docs/websocket-
|
|
729
|
+
* @see https://docs.kraken.com/api/docs/websocket-v2/trade
|
|
753
730
|
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
754
731
|
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
755
732
|
* @param {int} [limit] the maximum amount of trades to fetch
|
|
@@ -762,8 +739,8 @@ export default class kraken extends krakenRest {
|
|
|
762
739
|
/**
|
|
763
740
|
* @method
|
|
764
741
|
* @name kraken#watchTradesForSymbols
|
|
765
|
-
* @see https://docs.kraken.com/api/docs/websocket-v1/trade
|
|
766
742
|
* @description get the list of most recent trades for a list of symbols
|
|
743
|
+
* @see https://docs.kraken.com/api/docs/websocket-v2/trade
|
|
767
744
|
* @param {string[]} symbols unified symbol of the market to fetch trades for
|
|
768
745
|
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
769
746
|
* @param {int} [limit] the maximum amount of trades to fetch
|
|
@@ -783,7 +760,7 @@ export default class kraken extends krakenRest {
|
|
|
783
760
|
* @method
|
|
784
761
|
* @name kraken#watchOrderBook
|
|
785
762
|
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
786
|
-
* @see https://docs.kraken.com/api/docs/websocket-
|
|
763
|
+
* @see https://docs.kraken.com/api/docs/websocket-v2/book
|
|
787
764
|
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
788
765
|
* @param {int} [limit] the maximum amount of order book entries to return
|
|
789
766
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
@@ -796,7 +773,7 @@ export default class kraken extends krakenRest {
|
|
|
796
773
|
* @method
|
|
797
774
|
* @name kraken#watchOrderBookForSymbols
|
|
798
775
|
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
799
|
-
* @see https://docs.kraken.com/api/docs/websocket-
|
|
776
|
+
* @see https://docs.kraken.com/api/docs/websocket-v2/book
|
|
800
777
|
* @param {string[]} symbols unified array of symbols
|
|
801
778
|
* @param {int} [limit] the maximum amount of order book entries to return
|
|
802
779
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
@@ -806,7 +783,7 @@ export default class kraken extends krakenRest {
|
|
|
806
783
|
const request = {};
|
|
807
784
|
if (limit !== undefined) {
|
|
808
785
|
if (this.inArray(limit, [10, 25, 100, 500, 1000])) {
|
|
809
|
-
request['
|
|
786
|
+
request['params'] = {
|
|
810
787
|
'depth': limit, // default 10, valid options 10, 25, 100, 500, 1000
|
|
811
788
|
};
|
|
812
789
|
}
|
|
@@ -872,6 +849,21 @@ export default class kraken extends krakenRest {
|
|
|
872
849
|
}
|
|
873
850
|
return markets;
|
|
874
851
|
}
|
|
852
|
+
ping(client) {
|
|
853
|
+
const url = client.url;
|
|
854
|
+
const request = {};
|
|
855
|
+
if (url.indexOf('v2') >= 0) {
|
|
856
|
+
request['method'] = 'ping';
|
|
857
|
+
}
|
|
858
|
+
else {
|
|
859
|
+
request['event'] = 'ping';
|
|
860
|
+
}
|
|
861
|
+
return request;
|
|
862
|
+
}
|
|
863
|
+
handlePong(client, message) {
|
|
864
|
+
client.lastPong = this.milliseconds();
|
|
865
|
+
return message;
|
|
866
|
+
}
|
|
875
867
|
async watchHeartbeat(params = {}) {
|
|
876
868
|
await this.loadMarkets();
|
|
877
869
|
const event = 'heartbeat';
|
|
@@ -887,175 +879,165 @@ export default class kraken extends krakenRest {
|
|
|
887
879
|
const event = this.safeString(message, 'event');
|
|
888
880
|
client.resolve(message, event);
|
|
889
881
|
}
|
|
890
|
-
handleOrderBook(client, message
|
|
882
|
+
handleOrderBook(client, message) {
|
|
891
883
|
//
|
|
892
884
|
// first message (snapshot)
|
|
893
885
|
//
|
|
894
|
-
//
|
|
895
|
-
//
|
|
896
|
-
//
|
|
897
|
-
//
|
|
898
|
-
//
|
|
899
|
-
//
|
|
900
|
-
//
|
|
901
|
-
//
|
|
902
|
-
//
|
|
903
|
-
//
|
|
904
|
-
//
|
|
905
|
-
//
|
|
906
|
-
//
|
|
907
|
-
//
|
|
908
|
-
//
|
|
909
|
-
//
|
|
910
|
-
//
|
|
886
|
+
// {
|
|
887
|
+
// "channel": "book",
|
|
888
|
+
// "type": "snapshot",
|
|
889
|
+
// "data": [
|
|
890
|
+
// {
|
|
891
|
+
// "symbol": "MATIC/USD",
|
|
892
|
+
// "bids": [
|
|
893
|
+
// {
|
|
894
|
+
// "price": 0.5666,
|
|
895
|
+
// "qty": 4831.75496356
|
|
896
|
+
// },
|
|
897
|
+
// {
|
|
898
|
+
// "price": 0.5665,
|
|
899
|
+
// "qty": 6658.22734739
|
|
900
|
+
// }
|
|
901
|
+
// ],
|
|
902
|
+
// "asks": [
|
|
903
|
+
// {
|
|
904
|
+
// "price": 0.5668,
|
|
905
|
+
// "qty": 4410.79769741
|
|
906
|
+
// },
|
|
907
|
+
// {
|
|
908
|
+
// "price": 0.5669,
|
|
909
|
+
// "qty": 4655.40412487
|
|
910
|
+
// }
|
|
911
|
+
// ],
|
|
912
|
+
// "checksum": 2439117997
|
|
913
|
+
// }
|
|
914
|
+
// ]
|
|
915
|
+
// }
|
|
911
916
|
//
|
|
912
917
|
// subsequent updates
|
|
913
918
|
//
|
|
914
|
-
//
|
|
915
|
-
//
|
|
916
|
-
//
|
|
917
|
-
//
|
|
918
|
-
//
|
|
919
|
-
//
|
|
920
|
-
//
|
|
921
|
-
//
|
|
922
|
-
//
|
|
923
|
-
//
|
|
924
|
-
//
|
|
925
|
-
//
|
|
926
|
-
//
|
|
927
|
-
//
|
|
928
|
-
//
|
|
929
|
-
//
|
|
919
|
+
// {
|
|
920
|
+
// "channel": "book",
|
|
921
|
+
// "type": "update",
|
|
922
|
+
// "data": [
|
|
923
|
+
// {
|
|
924
|
+
// "symbol": "MATIC/USD",
|
|
925
|
+
// "bids": [
|
|
926
|
+
// {
|
|
927
|
+
// "price": 0.5657,
|
|
928
|
+
// "qty": 1098.3947558
|
|
929
|
+
// }
|
|
930
|
+
// ],
|
|
931
|
+
// "asks": [],
|
|
932
|
+
// "checksum": 2114181697,
|
|
933
|
+
// "timestamp": "2023-10-06T17:35:55.440295Z"
|
|
934
|
+
// }
|
|
935
|
+
// ]
|
|
936
|
+
// }
|
|
930
937
|
//
|
|
931
|
-
const
|
|
932
|
-
const
|
|
933
|
-
const
|
|
934
|
-
const
|
|
935
|
-
const
|
|
936
|
-
const
|
|
937
|
-
const
|
|
938
|
-
let timestamp = undefined;
|
|
938
|
+
const type = this.safeString(message, 'type');
|
|
939
|
+
const data = this.safeList(message, 'data', []);
|
|
940
|
+
const first = this.safeDict(data, 0, {});
|
|
941
|
+
const symbol = this.safeString(first, 'symbol');
|
|
942
|
+
const a = this.safeValue(first, 'asks', []);
|
|
943
|
+
const b = this.safeValue(first, 'bids', []);
|
|
944
|
+
const c = this.safeInteger(first, 'checksum');
|
|
939
945
|
const messageHash = this.getMessageHash('orderbook', undefined, symbol);
|
|
940
|
-
|
|
941
|
-
if ('
|
|
942
|
-
|
|
946
|
+
let orderbook = undefined;
|
|
947
|
+
if (type === 'update') {
|
|
948
|
+
orderbook = this.orderbooks[symbol];
|
|
949
|
+
const storedAsks = orderbook['asks'];
|
|
950
|
+
const storedBids = orderbook['bids'];
|
|
951
|
+
if (a !== undefined) {
|
|
952
|
+
this.customHandleDeltas(storedAsks, a);
|
|
953
|
+
}
|
|
954
|
+
if (b !== undefined) {
|
|
955
|
+
this.customHandleDeltas(storedBids, b);
|
|
956
|
+
}
|
|
957
|
+
const datetime = this.safeString(first, 'timestamp');
|
|
958
|
+
orderbook['symbol'] = symbol;
|
|
959
|
+
orderbook['timestamp'] = this.parse8601(datetime);
|
|
960
|
+
orderbook['datetime'] = datetime;
|
|
961
|
+
}
|
|
962
|
+
else {
|
|
963
|
+
// snapshot
|
|
964
|
+
const depth = a.length;
|
|
943
965
|
this.orderbooks[symbol] = this.orderBook({}, depth);
|
|
944
|
-
|
|
945
|
-
const
|
|
946
|
-
'as': 'asks',
|
|
947
|
-
'bs': 'bids',
|
|
948
|
-
};
|
|
949
|
-
const keys = Object.keys(sides);
|
|
966
|
+
orderbook = this.orderbooks[symbol];
|
|
967
|
+
const keys = ['asks', 'bids'];
|
|
950
968
|
for (let i = 0; i < keys.length; i++) {
|
|
951
969
|
const key = keys[i];
|
|
952
|
-
const
|
|
953
|
-
const
|
|
954
|
-
|
|
955
|
-
|
|
970
|
+
const bookside = orderbook[key];
|
|
971
|
+
const deltas = this.safeValue(first, key, []);
|
|
972
|
+
if (deltas.length > 0) {
|
|
973
|
+
this.customHandleDeltas(bookside, deltas);
|
|
974
|
+
}
|
|
956
975
|
}
|
|
957
976
|
orderbook['symbol'] = symbol;
|
|
958
|
-
orderbook['timestamp'] = timestamp;
|
|
959
|
-
orderbook['datetime'] = this.iso8601(timestamp);
|
|
960
|
-
client.resolve(orderbook, messageHash);
|
|
961
977
|
}
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
if ('a' in message[1]) {
|
|
977
|
-
a = this.safeValue(message[1], 'a', []);
|
|
978
|
+
orderbook.limit();
|
|
979
|
+
// checksum temporarily disabled because the exchange checksum was not reliable
|
|
980
|
+
const checksum = this.handleOption('watchOrderBook', 'checksum', false);
|
|
981
|
+
if (checksum) {
|
|
982
|
+
const payloadArray = [];
|
|
983
|
+
if (c !== undefined) {
|
|
984
|
+
const checkAsks = orderbook['asks'];
|
|
985
|
+
const checkBids = orderbook['bids'];
|
|
986
|
+
// const checkAsks = asks.map ((elem) => [ elem['price'], elem['qty'] ]);
|
|
987
|
+
// const checkBids = bids.map ((elem) => [ elem['price'], elem['qty'] ]);
|
|
988
|
+
for (let i = 0; i < 10; i++) {
|
|
989
|
+
const currentAsk = this.safeValue(checkAsks, i, {});
|
|
990
|
+
const formattedAsk = this.formatNumber(currentAsk[0]) + this.formatNumber(currentAsk[1]);
|
|
991
|
+
payloadArray.push(formattedAsk);
|
|
978
992
|
}
|
|
979
|
-
|
|
980
|
-
|
|
993
|
+
for (let i = 0; i < 10; i++) {
|
|
994
|
+
const currentBid = this.safeValue(checkBids, i, {});
|
|
995
|
+
const formattedBid = this.formatNumber(currentBid[0]) + this.formatNumber(currentBid[1]);
|
|
996
|
+
payloadArray.push(formattedBid);
|
|
981
997
|
}
|
|
982
998
|
}
|
|
983
|
-
const
|
|
984
|
-
const
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
timestamp = this.customHandleDeltas(storedBids, b, timestamp);
|
|
992
|
-
example = this.safeValue(b, 0);
|
|
993
|
-
}
|
|
994
|
-
// don't remove this line or I will poop on your face
|
|
995
|
-
orderbook.limit();
|
|
996
|
-
const checksum = this.handleOption('watchOrderBook', 'checksum', true);
|
|
997
|
-
if (checksum) {
|
|
998
|
-
const priceString = this.safeString(example, 0);
|
|
999
|
-
const amountString = this.safeString(example, 1);
|
|
1000
|
-
const priceParts = priceString.split('.');
|
|
1001
|
-
const amountParts = amountString.split('.');
|
|
1002
|
-
const priceLength = priceParts[1].length - 0;
|
|
1003
|
-
const amountLength = amountParts[1].length - 0;
|
|
1004
|
-
const payloadArray = [];
|
|
1005
|
-
if (c !== undefined) {
|
|
1006
|
-
for (let i = 0; i < 10; i++) {
|
|
1007
|
-
const formatted = this.formatNumber(storedAsks[i][0], priceLength) + this.formatNumber(storedAsks[i][1], amountLength);
|
|
1008
|
-
payloadArray.push(formatted);
|
|
1009
|
-
}
|
|
1010
|
-
for (let i = 0; i < 10; i++) {
|
|
1011
|
-
const formatted = this.formatNumber(storedBids[i][0], priceLength) + this.formatNumber(storedBids[i][1], amountLength);
|
|
1012
|
-
payloadArray.push(formatted);
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
const payload = payloadArray.join('');
|
|
1016
|
-
const localChecksum = this.crc32(payload, false);
|
|
1017
|
-
if (localChecksum !== c) {
|
|
1018
|
-
const error = new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
1019
|
-
delete client.subscriptions[messageHash];
|
|
1020
|
-
delete this.orderbooks[symbol];
|
|
1021
|
-
client.reject(error, messageHash);
|
|
1022
|
-
return;
|
|
1023
|
-
}
|
|
999
|
+
const payload = payloadArray.join('');
|
|
1000
|
+
const localChecksum = this.crc32(payload, false);
|
|
1001
|
+
if (localChecksum !== c) {
|
|
1002
|
+
const error = new ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
|
|
1003
|
+
delete client.subscriptions[messageHash];
|
|
1004
|
+
delete this.orderbooks[symbol];
|
|
1005
|
+
client.reject(error, messageHash);
|
|
1006
|
+
return;
|
|
1024
1007
|
}
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1008
|
+
}
|
|
1009
|
+
client.resolve(orderbook, messageHash);
|
|
1010
|
+
}
|
|
1011
|
+
customHandleDeltas(bookside, deltas) {
|
|
1012
|
+
// const sortOrder = (key === 'bids') ? true : false;
|
|
1013
|
+
for (let j = 0; j < deltas.length; j++) {
|
|
1014
|
+
const delta = deltas[j];
|
|
1015
|
+
const price = this.safeNumber(delta, 'price');
|
|
1016
|
+
const amount = this.safeNumber(delta, 'qty');
|
|
1017
|
+
bookside.store(price, amount);
|
|
1018
|
+
// if (amount === 0) {
|
|
1019
|
+
// const index = bookside.findIndex ((x: Int) => x[0] === price);
|
|
1020
|
+
// bookside.splice (index, 1);
|
|
1021
|
+
// } else {
|
|
1022
|
+
// bookside.store (price, amount);
|
|
1023
|
+
// }
|
|
1024
|
+
// bookside = this.sortBy (bookside, 0, sortOrder);
|
|
1025
|
+
// bookside.slice (0, 9);
|
|
1029
1026
|
}
|
|
1030
1027
|
}
|
|
1031
|
-
formatNumber(
|
|
1032
|
-
const
|
|
1033
|
-
const parts = stringNumber.split('.');
|
|
1028
|
+
formatNumber(data) {
|
|
1029
|
+
const parts = data.split('.');
|
|
1034
1030
|
const integer = this.safeString(parts, 0);
|
|
1035
1031
|
const decimals = this.safeString(parts, 1, '');
|
|
1036
|
-
|
|
1037
|
-
const joined = integer + paddedDecimals;
|
|
1032
|
+
let joinedResult = integer + decimals;
|
|
1038
1033
|
let i = 0;
|
|
1039
|
-
while (
|
|
1034
|
+
while (joinedResult[i] === '0') {
|
|
1040
1035
|
i += 1;
|
|
1041
1036
|
}
|
|
1042
1037
|
if (i > 0) {
|
|
1043
|
-
|
|
1038
|
+
joinedResult = joinedResult.slice(i);
|
|
1044
1039
|
}
|
|
1045
|
-
|
|
1046
|
-
return joined;
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
|
-
customHandleDeltas(bookside, deltas, timestamp = undefined) {
|
|
1050
|
-
for (let j = 0; j < deltas.length; j++) {
|
|
1051
|
-
const delta = deltas[j];
|
|
1052
|
-
const price = this.parseNumber(delta[0]);
|
|
1053
|
-
const amount = this.parseNumber(delta[1]);
|
|
1054
|
-
const oldTimestamp = timestamp ? timestamp : 0;
|
|
1055
|
-
timestamp = Math.max(oldTimestamp, this.parseToInt(parseFloat(delta[2]) * 1000));
|
|
1056
|
-
bookside.store(price, amount);
|
|
1057
|
-
}
|
|
1058
|
-
return timestamp;
|
|
1040
|
+
return joinedResult;
|
|
1059
1041
|
}
|
|
1060
1042
|
handleSystemStatus(client, message) {
|
|
1061
1043
|
//
|
|
@@ -1091,7 +1073,11 @@ export default class kraken extends krakenRest {
|
|
|
1091
1073
|
const client = this.client(url);
|
|
1092
1074
|
const authenticated = 'authenticated';
|
|
1093
1075
|
let subscription = this.safeValue(client.subscriptions, authenticated);
|
|
1094
|
-
|
|
1076
|
+
const now = this.seconds();
|
|
1077
|
+
const start = this.safeInteger(subscription, 'start');
|
|
1078
|
+
const expires = this.safeInteger(subscription, 'expires');
|
|
1079
|
+
if ((subscription === undefined) || ((subscription !== undefined) && (start + expires) <= now)) {
|
|
1080
|
+
// https://docs.kraken.com/api/docs/rest-api/get-websockets-token
|
|
1095
1081
|
const response = await this.privatePostGetWebSocketsToken(params);
|
|
1096
1082
|
//
|
|
1097
1083
|
// {
|
|
@@ -1102,7 +1088,8 @@ export default class kraken extends krakenRest {
|
|
|
1102
1088
|
// }
|
|
1103
1089
|
// }
|
|
1104
1090
|
//
|
|
1105
|
-
subscription = this.
|
|
1091
|
+
subscription = this.safeDict(response, 'result');
|
|
1092
|
+
subscription['start'] = now;
|
|
1106
1093
|
client.subscriptions[authenticated] = subscription;
|
|
1107
1094
|
}
|
|
1108
1095
|
return this.safeString(subscription, 'token');
|
|
@@ -1568,25 +1555,25 @@ export default class kraken extends krakenRest {
|
|
|
1568
1555
|
symbols = this.marketSymbols(symbols, undefined, false, true, false);
|
|
1569
1556
|
const messageHashes = [];
|
|
1570
1557
|
for (let i = 0; i < symbols.length; i++) {
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
wsMarketIds.push(wsMarketId);
|
|
1558
|
+
const eventTrigger = this.safeString(params, 'event_trigger');
|
|
1559
|
+
if (eventTrigger !== undefined) {
|
|
1560
|
+
messageHashes.push(this.getMessageHash(channelName, undefined, this.symbol(symbols[i])));
|
|
1561
|
+
}
|
|
1562
|
+
else {
|
|
1563
|
+
messageHashes.push(this.getMessageHash(unifiedName, undefined, this.symbol(symbols[i])));
|
|
1564
|
+
}
|
|
1579
1565
|
}
|
|
1580
1566
|
const request = {
|
|
1581
|
-
'
|
|
1582
|
-
'
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
'name': channelName,
|
|
1567
|
+
'method': 'subscribe',
|
|
1568
|
+
'params': {
|
|
1569
|
+
'channel': channelName,
|
|
1570
|
+
'symbol': symbols,
|
|
1586
1571
|
},
|
|
1572
|
+
'req_id': this.requestId(),
|
|
1587
1573
|
};
|
|
1588
|
-
|
|
1589
|
-
|
|
1574
|
+
request['params'] = this.deepExtend(request['params'], params);
|
|
1575
|
+
const url = this.urls['api']['ws']['publicV2'];
|
|
1576
|
+
return await this.watchMultiple(url, messageHashes, request, messageHashes, subscriptionArgs);
|
|
1590
1577
|
}
|
|
1591
1578
|
/**
|
|
1592
1579
|
* @method
|
|
@@ -1751,11 +1738,7 @@ export default class kraken extends krakenRest {
|
|
|
1751
1738
|
const name = this.safeString(info, 'name');
|
|
1752
1739
|
const methods = {
|
|
1753
1740
|
// public
|
|
1754
|
-
'book': this.handleOrderBook,
|
|
1755
1741
|
'ohlc': this.handleOHLCV,
|
|
1756
|
-
'ticker': this.handleTicker,
|
|
1757
|
-
'spread': this.handleBidAsk,
|
|
1758
|
-
'trade': this.handleTrades,
|
|
1759
1742
|
// private
|
|
1760
1743
|
'openOrders': this.handleOrders,
|
|
1761
1744
|
'ownTrades': this.handleMyTrades,
|
|
@@ -1770,6 +1753,9 @@ export default class kraken extends krakenRest {
|
|
|
1770
1753
|
if (channel !== undefined) {
|
|
1771
1754
|
const methods = {
|
|
1772
1755
|
'balances': this.handleBalance,
|
|
1756
|
+
'book': this.handleOrderBook,
|
|
1757
|
+
'ticker': this.handleTicker,
|
|
1758
|
+
'trade': this.handleTrades,
|
|
1773
1759
|
};
|
|
1774
1760
|
const method = this.safeValue(methods, channel);
|
|
1775
1761
|
if (method !== undefined) {
|
|
@@ -1786,6 +1772,7 @@ export default class kraken extends krakenRest {
|
|
|
1786
1772
|
'amend_order': this.handleCreateEditOrder,
|
|
1787
1773
|
'cancel_order': this.handleCancelOrder,
|
|
1788
1774
|
'cancel_all': this.handleCancelAllOrders,
|
|
1775
|
+
'pong': this.handlePong,
|
|
1789
1776
|
};
|
|
1790
1777
|
const method = this.safeValue(methods, event);
|
|
1791
1778
|
if (method !== undefined) {
|