ccxt 4.2.20 → 4.2.22

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 (82) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.js +1405 -274
  3. package/dist/ccxt.browser.min.js +6 -6
  4. package/dist/cjs/ccxt.js +1 -1
  5. package/dist/cjs/src/base/Exchange.js +37 -4
  6. package/dist/cjs/src/base/ws/WsClient.js +3 -1
  7. package/dist/cjs/src/bigone.js +1 -0
  8. package/dist/cjs/src/binance.js +14 -3
  9. package/dist/cjs/src/bitget.js +12 -2
  10. package/dist/cjs/src/bitrue.js +1 -0
  11. package/dist/cjs/src/bitvavo.js +271 -172
  12. package/dist/cjs/src/blockchaincom.js +3 -1
  13. package/dist/cjs/src/bybit.js +57 -9
  14. package/dist/cjs/src/coinbasepro.js +1 -0
  15. package/dist/cjs/src/coinex.js +37 -12
  16. package/dist/cjs/src/deribit.js +164 -0
  17. package/dist/cjs/src/gate.js +32 -1
  18. package/dist/cjs/src/novadax.js +26 -22
  19. package/dist/cjs/src/okcoin.js +3 -0
  20. package/dist/cjs/src/phemex.js +7 -3
  21. package/dist/cjs/src/poloniex.js +1 -0
  22. package/dist/cjs/src/pro/bequant.js +6 -1
  23. package/dist/cjs/src/pro/binance.js +7 -4
  24. package/dist/cjs/src/pro/binancecoinm.js +6 -1
  25. package/dist/cjs/src/pro/binanceus.js +6 -1
  26. package/dist/cjs/src/pro/bitcoincom.js +6 -1
  27. package/dist/cjs/src/pro/bitget.js +1 -1
  28. package/dist/cjs/src/pro/bitopro.js +7 -3
  29. package/dist/cjs/src/pro/bitrue.js +6 -1
  30. package/dist/cjs/src/pro/bitvavo.js +668 -22
  31. package/dist/cjs/src/pro/lbank.js +1 -1
  32. package/dist/cjs/src/pro/okx.js +13 -3
  33. package/dist/cjs/src/woo.js +1 -1
  34. package/js/ccxt.d.ts +1 -1
  35. package/js/ccxt.js +1 -1
  36. package/js/src/abstract/binance.d.ts +3 -0
  37. package/js/src/abstract/binancecoinm.d.ts +3 -0
  38. package/js/src/abstract/binanceus.d.ts +4 -0
  39. package/js/src/abstract/binanceusdm.d.ts +3 -0
  40. package/js/src/abstract/gate.d.ts +1 -0
  41. package/js/src/abstract/gateio.d.ts +1 -0
  42. package/js/src/abstract/novadax.d.ts +5 -1
  43. package/js/src/abstract/phemex.d.ts +1 -0
  44. package/js/src/base/Exchange.d.ts +12 -1
  45. package/js/src/base/Exchange.js +37 -4
  46. package/js/src/base/ws/WsClient.js +3 -2
  47. package/js/src/bigone.js +1 -0
  48. package/js/src/binance.js +14 -3
  49. package/js/src/bitget.js +12 -2
  50. package/js/src/bitrue.js +1 -0
  51. package/js/src/bitvavo.d.ts +14 -2
  52. package/js/src/bitvavo.js +271 -172
  53. package/js/src/blockchaincom.js +3 -1
  54. package/js/src/bybit.d.ts +2 -1
  55. package/js/src/bybit.js +57 -9
  56. package/js/src/coinbasepro.js +1 -0
  57. package/js/src/coinex.d.ts +1 -0
  58. package/js/src/coinex.js +37 -12
  59. package/js/src/deribit.d.ts +6 -1
  60. package/js/src/deribit.js +164 -0
  61. package/js/src/gate.d.ts +1 -0
  62. package/js/src/gate.js +32 -1
  63. package/js/src/novadax.js +26 -22
  64. package/js/src/okcoin.js +3 -0
  65. package/js/src/phemex.js +7 -3
  66. package/js/src/poloniex.js +1 -0
  67. package/js/src/pro/bequant.js +6 -1
  68. package/js/src/pro/binance.js +7 -4
  69. package/js/src/pro/binancecoinm.js +6 -1
  70. package/js/src/pro/binanceus.js +6 -1
  71. package/js/src/pro/bitcoincom.js +6 -1
  72. package/js/src/pro/bitget.js +1 -1
  73. package/js/src/pro/bitopro.js +7 -3
  74. package/js/src/pro/bitrue.js +6 -1
  75. package/js/src/pro/bitvavo.d.ts +35 -2
  76. package/js/src/pro/bitvavo.js +669 -23
  77. package/js/src/pro/lbank.js +1 -1
  78. package/js/src/pro/okx.js +13 -3
  79. package/js/src/woo.js +1 -1
  80. package/jsdoc2md.js +38 -16
  81. package/package.json +4 -1
  82. package/skip-tests.json +4 -0
@@ -6,7 +6,7 @@
6
6
 
7
7
  // ---------------------------------------------------------------------------
8
8
  import bitvavoRest from '../bitvavo.js';
9
- import { ArgumentsRequired, AuthenticationError } from '../base/errors.js';
9
+ import { AuthenticationError, ArgumentsRequired, ExchangeError } from '../base/errors.js';
10
10
  import { ArrayCache, ArrayCacheByTimestamp, ArrayCacheBySymbolById } from '../base/ws/Cache.js';
11
11
  import { sha256 } from '../static_dependencies/noble-hashes/sha256.js';
12
12
  // ---------------------------------------------------------------------------
@@ -15,21 +15,38 @@ export default class bitvavo extends bitvavoRest {
15
15
  return this.deepExtend(super.describe(), {
16
16
  'has': {
17
17
  'ws': true,
18
- 'createOrderWs': false,
19
- 'editOrderWs': false,
20
- 'fetchOpenOrdersWs': false,
21
- 'fetchOrderWs': false,
22
- 'cancelOrderWs': false,
23
18
  'cancelOrdersWs': false,
24
- 'cancelAllOrdersWs': false,
25
19
  'fetchTradesWs': false,
26
- 'fetchBalanceWs': false,
27
20
  'watchOrderBook': true,
28
21
  'watchTrades': true,
29
22
  'watchTicker': true,
30
23
  'watchOHLCV': true,
31
24
  'watchOrders': true,
32
25
  'watchMyTrades': true,
26
+ 'cancelAllOrdersWs': true,
27
+ 'cancelOrderWs': true,
28
+ 'createOrderWs': true,
29
+ 'createStopLimitOrderWs': true,
30
+ 'createStopMarketOrderWs': true,
31
+ 'createStopOrderWs': true,
32
+ 'editOrderWs': true,
33
+ 'fetchBalanceWs': true,
34
+ 'fetchCurrenciesWS': true,
35
+ 'fetchDepositAddressWs': true,
36
+ 'fetchDepositsWs': true,
37
+ 'fetchDepositWithdrawFeesWs': true,
38
+ 'fetchMyTradesWs': true,
39
+ 'fetchOHLCVWs': true,
40
+ 'fetchOpenOrdersWs': true,
41
+ 'fetchOrderWs': true,
42
+ 'fetchOrderBookWs': true,
43
+ 'fetchOrdersWs': true,
44
+ 'fetchTickerWs': true,
45
+ 'fetchTickersWs': true,
46
+ 'fetchTimeWs': true,
47
+ 'fetchTradingFeesWs': true,
48
+ 'fetchWithdrawalsWs': true,
49
+ 'withdrawWs': true,
33
50
  },
34
51
  'urls': {
35
52
  'api': {
@@ -37,6 +54,7 @@ export default class bitvavo extends bitvavoRest {
37
54
  },
38
55
  },
39
56
  'options': {
57
+ 'supressMultipleWsRequestsError': false,
40
58
  'tradesLimit': 1000,
41
59
  'ordersLimit': 1000,
42
60
  'OHLCVLimit': 1000,
@@ -192,6 +210,22 @@ export default class bitvavo extends bitvavoRest {
192
210
  }
193
211
  return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
194
212
  }
213
+ handleFetchOHLCV(client, message) {
214
+ //
215
+ // {
216
+ // action: 'getCandles',
217
+ // response: [
218
+ // [1690325820000, '26453', '26453', '26436', '26447', '0.01626246'],
219
+ // [1690325760000, '26454', '26454', '26453', '26453', '0.00037707']
220
+ // ]
221
+ // }
222
+ //
223
+ const action = this.safeString(message, 'action');
224
+ const response = this.safeValue(message, 'response');
225
+ const ohlcv = this.parseOHLCVs(response, undefined, undefined, undefined);
226
+ const messageHash = this.buildMessageHash(action);
227
+ client.resolve(ohlcv, messageHash);
228
+ }
195
229
  handleOHLCV(client, message) {
196
230
  //
197
231
  // {
@@ -497,6 +531,584 @@ export default class bitvavo extends bitvavoRest {
497
531
  }
498
532
  return this.filterBySymbolSinceLimit(trades, symbol, since, limit, true);
499
533
  }
534
+ async createOrderWs(symbol, type, side, amount, price = undefined, params = {}) {
535
+ /**
536
+ * @method
537
+ * @name bitvavo#createOrderWs
538
+ * @description create a trade order
539
+ * @see https://docs.bitvavo.com/#tag/Orders/paths/~1order/post
540
+ * @param {string} symbol unified symbol of the market to create an order in
541
+ * @param {string} type 'market' or 'limit'
542
+ * @param {string} side 'buy' or 'sell'
543
+ * @param {float} amount how much of currency you want to trade in units of base currency
544
+ * @param {float} price the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
545
+ * @param {object} [params] extra parameters specific to the bitvavo api endpoint
546
+ * @param {string} [params.timeInForce] "GTC", "IOC", or "PO"
547
+ * @param {float} [params.stopPrice] The price at which a trigger order is triggered at
548
+ * @param {float} [params.triggerPrice] The price at which a trigger order is triggered at
549
+ * @param {bool} [params.postOnly] If true, the order will only be posted to the order book and not executed immediately
550
+ * @param {float} [params.stopLossPrice] The price at which a stop loss order is triggered at
551
+ * @param {float} [params.takeProfitPrice] The price at which a take profit order is triggered at
552
+ * @param {string} [params.triggerType] "price"
553
+ * @param {string} [params.triggerReference] "lastTrade", "bestBid", "bestAsk", "midPrice" Only for stop orders: Use this to determine which parameter will trigger the order
554
+ * @param {string} [params.selfTradePrevention] "decrementAndCancel", "cancelOldest", "cancelNewest", "cancelBoth"
555
+ * @param {bool} [params.disableMarketProtection] don't cancel if the next fill price is 10% worse than the best fill price
556
+ * @param {bool} [params.responseRequired] Set this to 'false' when only an acknowledgement of success or failure is required, this is faster.
557
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
558
+ */
559
+ await this.loadMarkets();
560
+ await this.authenticate();
561
+ const request = this.createOrderRequest(symbol, type, side, amount, price, params);
562
+ return await this.watchRequest('privateCreateOrder', request);
563
+ }
564
+ async editOrderWs(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
565
+ /**
566
+ * @method
567
+ * @name bitvavo#editOrderWs
568
+ * @description edit a trade order
569
+ * @see https://docs.bitvavo.com/#tag/Orders/paths/~1order/put
570
+ * @param {string} id cancel order id
571
+ * @param {string} symbol unified symbol of the market to create an order in
572
+ * @param {string} type 'market' or 'limit'
573
+ * @param {string} side 'buy' or 'sell'
574
+ * @param {float} [amount] how much of currency you want to trade in units of base currency
575
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
576
+ * @param {object} [params] extra parameters specific to the bitvavo api endpoint
577
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
578
+ */
579
+ await this.loadMarkets();
580
+ await this.authenticate();
581
+ const request = this.editOrderRequest(id, symbol, type, side, amount, price, params);
582
+ return await this.watchRequest('privateUpdateOrder', request);
583
+ }
584
+ async cancelOrderWs(id, symbol = undefined, params = {}) {
585
+ /**
586
+ * @method
587
+ * @name bitvavo#cancelOrderWs
588
+ * @see https://docs.bitvavo.com/#tag/Orders/paths/~1order/delete
589
+ * @description cancels an open order
590
+ * @param {string} id order id
591
+ * @param {string} symbol unified symbol of the market the order was made in
592
+ * @param {object} [params] extra parameters specific to the bitvavo api endpoint
593
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
594
+ */
595
+ await this.loadMarkets();
596
+ await this.authenticate();
597
+ const request = this.cancelOrderRequest(id, symbol, params);
598
+ return await this.watchRequest('privateCancelOrder', request);
599
+ }
600
+ async cancelAllOrdersWs(symbol = undefined, params = {}) {
601
+ /**
602
+ * @method
603
+ * @name bitvavo#cancelAllOrdersWs
604
+ * @see https://docs.bitvavo.com/#tag/Orders/paths/~1orders/delete
605
+ * @description cancel all open orders
606
+ * @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
607
+ * @param {object} [params] extra parameters specific to the bitvavo api endpoint
608
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
609
+ */
610
+ await this.loadMarkets();
611
+ await this.authenticate();
612
+ const request = {};
613
+ let market = undefined;
614
+ if (symbol !== undefined) {
615
+ market = this.market(symbol);
616
+ request['market'] = market['id'];
617
+ }
618
+ return await this.watchRequest('privateCancelOrders', this.extend(request, params));
619
+ }
620
+ handleMultipleOrders(client, message) {
621
+ //
622
+ // {
623
+ // action: 'privateCancelOrders',
624
+ // response: [{
625
+ // orderId: 'd71df826-1130-478a-8741-d219128675b0'
626
+ // }]
627
+ // }
628
+ //
629
+ const action = this.safeString(message, 'action');
630
+ const response = this.safeValue(message, 'response');
631
+ const firstRawOrder = this.safeValue(response, 0, {});
632
+ const marketId = this.safeString(firstRawOrder, 'market');
633
+ const orders = this.parseOrders(response);
634
+ let messageHash = this.buildMessageHash(action, { 'market': marketId });
635
+ client.resolve(orders, messageHash);
636
+ messageHash = this.buildMessageHash(action, message);
637
+ client.resolve(orders, messageHash);
638
+ }
639
+ async fetchOrderWs(id, symbol = undefined, params = {}) {
640
+ /**
641
+ * @method
642
+ * @name bitvavo#fetchOrderWs
643
+ * @see https://docs.bitvavo.com/#tag/General/paths/~1assets/get
644
+ * @description fetches information on an order made by the user
645
+ * @param {string} symbol unified symbol of the market the order was made in
646
+ * @param {object} [params] extra parameters specific to the bitvavo api endpoint
647
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
648
+ */
649
+ if (symbol === undefined) {
650
+ throw new ArgumentsRequired(this.id + ' fetchOrder() requires a symbol argument');
651
+ }
652
+ await this.loadMarkets();
653
+ await this.authenticate();
654
+ const market = this.market(symbol);
655
+ const request = {
656
+ 'orderId': id,
657
+ 'market': market['id'],
658
+ };
659
+ return await this.watchRequest('privateGetOrder', this.extend(request, params));
660
+ }
661
+ async fetchOrdersWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
662
+ /**
663
+ * @method
664
+ * @name bitvavo#fetchOrdersWs
665
+ * @see https://docs.bitvavo.com/#tag/Orders/paths/~1orders/get
666
+ * @description fetches information on multiple orders made by the user
667
+ * @param {string} symbol unified market symbol of the market orders were made in
668
+ * @param {int} [since] the earliest time in ms to fetch orders for
669
+ * @param {int} [limit] the maximum number of orde structures to retrieve
670
+ * @param {object} [params] extra parameters specific to the bitvavo api endpoint
671
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
672
+ */
673
+ if (symbol === undefined) {
674
+ throw new ArgumentsRequired(this.id + ' fetchOrdersWs() requires a symbol argument');
675
+ }
676
+ await this.loadMarkets();
677
+ await this.authenticate();
678
+ const request = this.fetchOrdersRequest(symbol, since, limit, params);
679
+ const orders = await this.watchRequest('privateGetOrders', request);
680
+ return this.filterBySymbolSinceLimit(orders, symbol, since, limit);
681
+ }
682
+ async watchRequest(action, request) {
683
+ request['action'] = action;
684
+ const messageHash = this.buildMessageHash(action, request);
685
+ this.checkMessageHashDoesNotExist(messageHash);
686
+ const url = this.urls['api']['ws'];
687
+ return await this.watch(url, messageHash, request, messageHash);
688
+ }
689
+ async fetchOpenOrdersWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
690
+ /**
691
+ * @method
692
+ * @name bitvavo#fetchOpenOrdersWs
693
+ * @description fetch all unfilled currently open orders
694
+ * @param {string} symbol unified market symbol
695
+ * @param {int} [since] the earliest time in ms to fetch open orders for
696
+ * @param {int} [limit] the maximum number of open orders structures to retrieve
697
+ * @param {object} [params] extra parameters specific to the bitvavo api endpoint
698
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
699
+ */
700
+ await this.loadMarkets();
701
+ await this.authenticate();
702
+ const request = {
703
+ // 'market': market['id'], // rate limit 25 without a market, 1 with market specified
704
+ };
705
+ let market = undefined;
706
+ if (symbol !== undefined) {
707
+ market = this.market(symbol);
708
+ request['market'] = market['id'];
709
+ }
710
+ const orders = await this.watchRequest('privateGetOrdersOpen', this.extend(request, params));
711
+ return this.filterBySymbolSinceLimit(orders, symbol, since, limit);
712
+ }
713
+ async fetchMyTradesWs(symbol = undefined, since = undefined, limit = undefined, params = {}) {
714
+ /**
715
+ * @method
716
+ * @name bitvavo#fetchMyTradesWs
717
+ * @see https://docs.bitvavo.com/#tag/Trades
718
+ * @description fetch all trades made by the user
719
+ * @param {string} symbol unified market symbol
720
+ * @param {int} [since] the earliest time in ms to fetch trades for
721
+ * @param {int} [limit] the maximum number of trades structures to retrieve
722
+ * @param {object} [params] extra parameters specific to the bitvavo api endpoint
723
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
724
+ */
725
+ if (symbol === undefined) {
726
+ throw new ArgumentsRequired(this.id + ' fetchMyTradesWs() requires a symbol argument');
727
+ }
728
+ await this.loadMarkets();
729
+ await this.authenticate();
730
+ const request = this.fetchMyTradesRequest(symbol, since, limit, params);
731
+ const myTrades = await this.watchRequest('privateGetTrades', request);
732
+ return this.filterBySymbolSinceLimit(myTrades, symbol, since, limit);
733
+ }
734
+ handleMyTrades(client, message) {
735
+ //
736
+ // {
737
+ // action: 'privateGetTrades',
738
+ // response: [
739
+ // {
740
+ // "id": "108c3633-0276-4480-a902-17a01829deae",
741
+ // "orderId": "1d671998-3d44-4df4-965f-0d48bd129a1b",
742
+ // "timestamp": 1542967486256,
743
+ // "market": "BTC-EUR",
744
+ // "side": "buy",
745
+ // "amount": "0.005",
746
+ // "price": "5000.1",
747
+ // "taker": true,
748
+ // "fee": "0.03",
749
+ // "feeCurrency": "EUR",
750
+ // "settled": true
751
+ // }
752
+ // ]
753
+ // }
754
+ //
755
+ //
756
+ const action = this.safeString(message, 'action');
757
+ const response = this.safeValue(message, 'response');
758
+ const firstRawTrade = this.safeValue(response, 0, {});
759
+ const marketId = this.safeString(firstRawTrade, 'market');
760
+ const trades = this.parseTrades(response, undefined, undefined, undefined);
761
+ const messageHash = this.buildMessageHash(action, { 'market': marketId });
762
+ client.resolve(trades, messageHash);
763
+ }
764
+ async withdrawWs(code, amount, address, tag = undefined, params = {}) {
765
+ /**
766
+ * @method
767
+ * @name bitvavo#withdrawWs
768
+ * @description make a withdrawal
769
+ * @param {string} code unified currency code
770
+ * @param {float} amount the amount to withdraw
771
+ * @param {string} address the address to withdraw to
772
+ * @param {string} tag
773
+ * @param {object} [params] extra parameters specific to the bitvavo api endpoint
774
+ * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
775
+ */
776
+ [tag, params] = this.handleWithdrawTagAndParams(tag, params);
777
+ this.checkAddress(address);
778
+ await this.loadMarkets();
779
+ await this.authenticate();
780
+ const request = this.withdrawRequest(code, amount, address, tag, params);
781
+ return await this.watchRequest('privateWithdrawAssets', request);
782
+ }
783
+ handleWithdraw(client, message) {
784
+ //
785
+ // {
786
+ // action: 'privateWithdrawAssets',
787
+ // response: {
788
+ // "success": true,
789
+ // "symbol": "BTC",
790
+ // "amount": "1.5"
791
+ // }
792
+ // }
793
+ //
794
+ const action = this.safeString(message, 'action');
795
+ const messageHash = this.buildMessageHash(action, message);
796
+ const response = this.safeValue(message, 'response');
797
+ const withdraw = this.parseTransaction(response);
798
+ client.resolve(withdraw, messageHash);
799
+ }
800
+ async fetchWithdrawalsWs(code = undefined, since = undefined, limit = undefined, params = {}) {
801
+ /**
802
+ * @method
803
+ * @name bitvavo#fetchWithdrawalsWs
804
+ * @see https://docs.bitvavo.com/#tag/Account/paths/~1withdrawalHistory/get
805
+ * @description fetch all withdrawals made from an account
806
+ * @param {string} code unified currency code
807
+ * @param {int} [since] the earliest time in ms to fetch withdrawals for
808
+ * @param {int} [limit] the maximum number of withdrawals structures to retrieve
809
+ * @param {object} [params] extra parameters specific to the bitvavo api endpoint
810
+ * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
811
+ */
812
+ await this.loadMarkets();
813
+ await this.authenticate();
814
+ const request = this.fetchWithdrawalsRequest(code, since, limit, params);
815
+ const withdraws = await this.watchRequest('privateGetWithdrawalHistory', request);
816
+ return this.filterByCurrencySinceLimit(withdraws, code, since, limit);
817
+ }
818
+ handleWithdraws(client, message) {
819
+ //
820
+ // {
821
+ // action: 'privateGetWithdrawalHistory',
822
+ // response: [{
823
+ // timestamp: 1689792085000,
824
+ // symbol: 'BTC',
825
+ // amount: '0.0009',
826
+ // fee: '0',
827
+ // status: 'completed',
828
+ // txId: '7dbadc658d7d59c129de1332c55ee8e08d0ab74432faae03b417b9809c819d1f'
829
+ // },
830
+ // ...
831
+ // ]
832
+ // }
833
+ //
834
+ const action = this.safeString(message, 'action');
835
+ const messageHash = this.buildMessageHash(action, message);
836
+ const response = this.safeValue(message, 'response');
837
+ const withdrawals = this.parseTransactions(response, undefined, undefined, undefined, { 'type': 'withdrawal' });
838
+ client.resolve(withdrawals, messageHash);
839
+ }
840
+ async fetchOHLCVWs(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
841
+ /**
842
+ * @method
843
+ * @name bitvavo#fetchOHLCVWs
844
+ * @see https://docs.bitvavo.com/#tag/Market-Data/paths/~1{market}~1candles/get
845
+ * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
846
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
847
+ * @param {string} timeframe the length of time each candle represents
848
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
849
+ * @param {int} [limit] the maximum amount of candles to fetch
850
+ * @param {object} [params] extra parameters specific to the bitvavo api endpoint
851
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
852
+ */
853
+ await this.loadMarkets();
854
+ const request = this.fetchOHLCVRequest(symbol, timeframe, since, limit, params);
855
+ const action = 'getCandles';
856
+ const ohlcv = await this.watchRequest(action, request);
857
+ return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
858
+ }
859
+ async fetchDepositsWs(code = undefined, since = undefined, limit = undefined, params = {}) {
860
+ /**
861
+ * @method
862
+ * @name bitvavo#fetchDepositsWs
863
+ * @see https://docs.bitvavo.com/#tag/Account/paths/~1depositHistory/get
864
+ * @description fetch all deposits made to an account
865
+ * @param {string} code unified currency code
866
+ * @param {int} [since] the earliest time in ms to fetch deposits for
867
+ * @param {int} [limit] the maximum number of deposits structures to retrieve
868
+ * @param {object} [params] extra parameters specific to the bitvavo api endpoint
869
+ * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
870
+ */
871
+ await this.loadMarkets();
872
+ await this.authenticate();
873
+ const request = this.fetchDepositsRequest(code, since, limit, params);
874
+ const deposits = await this.watchRequest('privateGetDepositHistory', request);
875
+ return this.filterByCurrencySinceLimit(deposits, code, since, limit);
876
+ }
877
+ handleDeposits(client, message) {
878
+ //
879
+ // {
880
+ // action: 'privateGetDepositHistory',
881
+ // response: [{
882
+ // timestamp: 1689792085000,
883
+ // symbol: 'BTC',
884
+ // amount: '0.0009',
885
+ // fee: '0',
886
+ // status: 'completed',
887
+ // txId: '7dbadc658d7d59c129de1332c55ee8e08d0ab74432faae03b417b9809c819d1f'
888
+ // },
889
+ // ...
890
+ // ]
891
+ // }
892
+ //
893
+ const action = this.safeString(message, 'action');
894
+ const messageHash = this.buildMessageHash(action, message);
895
+ const response = this.safeValue(message, 'response');
896
+ const deposits = this.parseTransactions(response, undefined, undefined, undefined, { 'type': 'deposit' });
897
+ client.resolve(deposits, messageHash);
898
+ }
899
+ async fetchTradingFeesWs(params = {}) {
900
+ /**
901
+ * @method
902
+ * @name bitvavo#fetchTradingFeesWs
903
+ * @see https://docs.bitvavo.com/#tag/Account/paths/~1account/get
904
+ * @description fetch the trading fees for multiple markets
905
+ * @param {object} [params] extra parameters specific to the bitvavo api endpoint
906
+ * @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols
907
+ */
908
+ await this.loadMarkets();
909
+ await this.authenticate();
910
+ return await this.watchRequest('privateGetAccount', params);
911
+ }
912
+ async fetchMarketsWs(params = {}) {
913
+ /**
914
+ * @method
915
+ * @name bitvavo#fetchMarketsWs
916
+ * @see https://docs.bitvavo.com/#tag/General/paths/~1markets/get
917
+ * @description retrieves data on all markets for bitvavo
918
+ * @param {object} [params] extra parameters specific to the exchange api endpoint
919
+ * @returns {object[]} an array of objects representing market data
920
+ */
921
+ return await this.watchRequest('getMarkets', params);
922
+ }
923
+ async fetchCurrenciesWs(params = {}) {
924
+ /**
925
+ * @method
926
+ * @name bitvavo#fetchCurrenciesWs
927
+ * @see https://docs.bitvavo.com/#tag/General/paths/~1assets/get
928
+ * @description fetches all available currencies on an exchange
929
+ * @param {object} [params] extra parameters specific to the bitvavo api endpoint
930
+ * @returns {object} an associative dictionary of currencies
931
+ */
932
+ await this.loadMarkets();
933
+ return await this.watchRequest('getAssets', params);
934
+ }
935
+ handleFetchCurrencies(client, message) {
936
+ //
937
+ // {
938
+ // action: 'getAssets',
939
+ // response: [{
940
+ // symbol: '1INCH',
941
+ // name: '1inch',
942
+ // decimals: 8,
943
+ // depositFee: '0',
944
+ // depositConfirmations: 64,
945
+ // depositStatus: 'OK',
946
+ // withdrawalFee: '13',
947
+ // withdrawalMinAmount: '13',
948
+ // withdrawalStatus: 'OK',
949
+ // networks: [Array],
950
+ // message: ''
951
+ // },
952
+ // ...
953
+ // ]
954
+ // }
955
+ //
956
+ const action = this.safeString(message, 'action');
957
+ const messageHash = this.buildMessageHash(action, message);
958
+ const response = this.safeValue(message, 'response');
959
+ const currencies = this.parseCurrencies(response);
960
+ client.resolve(currencies, messageHash);
961
+ }
962
+ handleTradingFees(client, message) {
963
+ //
964
+ // {
965
+ // action: 'privateGetAccount',
966
+ // response: {
967
+ // fees: {
968
+ // taker: '0.0025',
969
+ // maker: '0.0015',
970
+ // volume: '1693.74'
971
+ // }
972
+ // }
973
+ // }
974
+ //
975
+ const action = this.safeString(message, 'action');
976
+ const messageHash = this.buildMessageHash(action, message);
977
+ const response = this.safeValue(message, 'response');
978
+ const fees = this.parseTradingFees(response);
979
+ client.resolve(fees, messageHash);
980
+ }
981
+ async fetchBalanceWs(params = {}) {
982
+ /**
983
+ * @method
984
+ * @name bitvavo#fetchBalanceWs
985
+ * @see https://docs.bitvavo.com/#tag/Account/paths/~1balance/get
986
+ * @description query for balance and get the amount of funds available for trading or funds locked in orders
987
+ * @param {object} [params] extra parameters specific to the bitvavo api endpoint
988
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/en/latest/manual.html?#balance-structure}
989
+ */
990
+ await this.loadMarkets();
991
+ await this.authenticate();
992
+ return await this.watchRequest('privateGetBalance', params);
993
+ }
994
+ handleFetchBalance(client, message) {
995
+ //
996
+ // {
997
+ // action: 'privateGetBalance',
998
+ // response: [{
999
+ // symbol: 'ADA',
1000
+ // available: '0',
1001
+ // inOrder: '0'
1002
+ // },
1003
+ // ...
1004
+ // ]
1005
+ // }
1006
+ //
1007
+ const action = this.safeString(message, 'action', 'privateGetBalance');
1008
+ const messageHash = this.buildMessageHash(action, message);
1009
+ const response = this.safeValue(message, 'response', []);
1010
+ const balance = this.parseBalance(response);
1011
+ client.resolve(balance, messageHash);
1012
+ }
1013
+ handleSingleOrder(client, message) {
1014
+ //
1015
+ // {
1016
+ // action: 'privateCreateOrder',
1017
+ // response: {
1018
+ // orderId: 'd71df826-1130-478a-8741-d219128675b0',
1019
+ // market: 'BTC-EUR',
1020
+ // created: 1689792749748,
1021
+ // updated: 1689792749748,
1022
+ // status: 'new',
1023
+ // side: 'sell',
1024
+ // orderType: 'limit',
1025
+ // amount: '0.0002',
1026
+ // amountRemaining: '0.0002',
1027
+ // price: '37000',
1028
+ // onHold: '0.0002',
1029
+ // onHoldCurrency: 'BTC',
1030
+ // filledAmount: '0',
1031
+ // filledAmountQuote: '0',
1032
+ // feePaid: '0',
1033
+ // feeCurrency: 'EUR',
1034
+ // fills: [],
1035
+ // selfTradePrevention: 'decrementAndCancel',
1036
+ // visible: true,
1037
+ // timeInForce: 'GTC',
1038
+ // postOnly: false
1039
+ // }
1040
+ // }
1041
+ //
1042
+ const action = this.safeString(message, 'action');
1043
+ const response = this.safeValue(message, 'response', {});
1044
+ const order = this.parseOrder(response);
1045
+ const messageHash = this.buildMessageHash(action, response);
1046
+ client.resolve(order, messageHash);
1047
+ }
1048
+ handleMarkets(client, message) {
1049
+ //
1050
+ // {
1051
+ // action: 'getMarkets',
1052
+ // response: [{
1053
+ // market: '1INCH-EUR',
1054
+ // status: 'trading',
1055
+ // base: '1INCH',
1056
+ // quote: 'EUR',
1057
+ // pricePrecision: 5,
1058
+ // minOrderInBaseAsset: '2',
1059
+ // minOrderInQuoteAsset: '5',
1060
+ // maxOrderInBaseAsset: '1000000000',
1061
+ // maxOrderInQuoteAsset: '1000000000',
1062
+ // orderTypes: [Array]
1063
+ // },
1064
+ // ...
1065
+ // ]
1066
+ // }
1067
+ //
1068
+ const action = this.safeString(message, 'action');
1069
+ const response = this.safeValue(message, 'response', {});
1070
+ const markets = this.parseMarkets(response);
1071
+ const messageHash = this.buildMessageHash(action, response);
1072
+ client.resolve(markets, messageHash);
1073
+ }
1074
+ buildMessageHash(action, params = {}) {
1075
+ const methods = {
1076
+ 'privateCreateOrder': this.actionAndMarketMessageHash,
1077
+ 'privateUpdateOrder': this.actionAndOrderIdMessageHash,
1078
+ 'privateCancelOrder': this.actionAndOrderIdMessageHash,
1079
+ 'privateGetOrder': this.actionAndOrderIdMessageHash,
1080
+ 'privateGetTrades': this.actionAndMarketMessageHash,
1081
+ };
1082
+ const method = this.safeValue(methods, action);
1083
+ let messageHash = action;
1084
+ if (method !== undefined) {
1085
+ messageHash = method.call(this, action, params);
1086
+ }
1087
+ return messageHash;
1088
+ }
1089
+ checkMessageHashDoesNotExist(messageHash) {
1090
+ const supressMultipleWsRequestsError = this.safeValue(this.options, 'supressMultipleWsRequestsError', false);
1091
+ if (!supressMultipleWsRequestsError) {
1092
+ const client = this.safeValue(this.clients, this.urls['api']['ws']);
1093
+ if (client !== undefined) {
1094
+ const future = this.safeValue(client.futures, messageHash);
1095
+ if (future !== undefined) {
1096
+ throw new ExchangeError(this.id + ' a similar request with messageHash ' + messageHash + ' is already pending, you must wait for a response, or turn off this error by setting supressMultipleWsRequestsError in the options to true');
1097
+ }
1098
+ }
1099
+ }
1100
+ }
1101
+ actionAndMarketMessageHash(action, params = {}) {
1102
+ const symbol = this.safeString(params, 'market', '');
1103
+ return action + symbol;
1104
+ }
1105
+ actionAndOrderIdMessageHash(action, params = {}) {
1106
+ const orderId = this.safeString(params, 'orderId');
1107
+ if (orderId === undefined) {
1108
+ throw new ExchangeError(this.id + ' privateUpdateOrderMessageHash requires a orderId parameter');
1109
+ }
1110
+ return action + orderId;
1111
+ }
500
1112
  handleOrder(client, message) {
501
1113
  //
502
1114
  // {
@@ -630,6 +1242,31 @@ export default class bitvavo extends bitvavoRest {
630
1242
  }
631
1243
  }
632
1244
  }
1245
+ handleErrorMessage(client, message) {
1246
+ //
1247
+ // {
1248
+ // action: 'privateCreateOrder',
1249
+ // market: 'BTC-EUR',
1250
+ // errorCode: 217,
1251
+ // error: 'Minimum order size in quote currency is 5 EUR or 0.001 BTC.'
1252
+ // }
1253
+ //
1254
+ const error = this.safeString(message, 'error');
1255
+ const code = this.safeInteger(error, 'errorCode');
1256
+ const action = this.safeString(message, 'action');
1257
+ const messageHash = this.buildMessageHash(action, message);
1258
+ let rejected = false;
1259
+ try {
1260
+ this.handleErrors(code, error, client.url, undefined, undefined, error, message, undefined, undefined);
1261
+ }
1262
+ catch (e) {
1263
+ rejected = true;
1264
+ client.reject(e, messageHash);
1265
+ }
1266
+ if (!rejected) {
1267
+ client.reject(message, messageHash);
1268
+ }
1269
+ }
633
1270
  handleMessage(client, message) {
634
1271
  //
635
1272
  // {
@@ -639,7 +1276,6 @@ export default class bitvavo extends bitvavoRest {
639
1276
  // }
640
1277
  // }
641
1278
  //
642
- //
643
1279
  // {
644
1280
  // "event": "book",
645
1281
  // "market": "BTC-EUR",
@@ -675,6 +1311,10 @@ export default class bitvavo extends bitvavoRest {
675
1311
  // "authenticated": true
676
1312
  // }
677
1313
  //
1314
+ const error = this.safeString(message, 'error');
1315
+ if (error !== undefined) {
1316
+ this.handleErrorMessage(client, message);
1317
+ }
678
1318
  const methods = {
679
1319
  'subscribed': this.handleSubscriptionStatus,
680
1320
  'book': this.handleOrderBook,
@@ -685,21 +1325,27 @@ export default class bitvavo extends bitvavoRest {
685
1325
  'authenticate': this.handleAuthenticationMessage,
686
1326
  'order': this.handleOrder,
687
1327
  'fill': this.handleMyTrade,
1328
+ 'privateCreateOrder': this.handleSingleOrder,
1329
+ 'privateUpdateOrder': this.handleSingleOrder,
1330
+ 'privateGetBalance': this.handleFetchBalance,
1331
+ 'privateCancelOrders': this.handleMultipleOrders,
1332
+ 'privateGetOrders': this.handleMultipleOrders,
1333
+ 'privateGetOrder': this.handleSingleOrder,
1334
+ 'privateCancelOrder': this.handleSingleOrder,
1335
+ 'privateGetOrdersOpen': this.handleMultipleOrders,
1336
+ 'privateGetAccount': this.handleTradingFees,
1337
+ 'privateGetDepositHistory': this.handleDeposits,
1338
+ 'privateGetWithdrawalHistory': this.handleWithdraws,
1339
+ 'privateWithdrawAssets': this.handleWithdraw,
1340
+ 'privateGetTrades': this.handleMyTrades,
1341
+ 'getAssets': this.handleFetchCurrencies,
1342
+ 'getCandles': this.handleFetchOHLCV,
1343
+ 'getMarkets': this.handleMarkets,
688
1344
  };
689
- const event = this.safeString(message, 'event');
690
- let method = this.safeValue(methods, event);
691
- if (method === undefined) {
692
- const action = this.safeString(message, 'action');
693
- method = this.safeValue(methods, action);
694
- if (method === undefined) {
695
- return message;
696
- }
697
- else {
698
- return method.call(this, client, message);
699
- }
700
- }
701
- else {
702
- return method.call(this, client, message);
1345
+ const event = this.safeString2(message, 'event', 'action');
1346
+ const method = this.safeValue(methods, event);
1347
+ if (method !== undefined) {
1348
+ method.call(this, client, message);
703
1349
  }
704
1350
  }
705
1351
  }