ccxt 4.3.85__py2.py3-none-any.whl → 4.3.87__py2.py3-none-any.whl

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 (49) hide show
  1. ccxt/__init__.py +4 -1
  2. ccxt/abstract/hashkey.py +67 -0
  3. ccxt/async_support/__init__.py +4 -1
  4. ccxt/async_support/base/exchange.py +2 -2
  5. ccxt/async_support/binance.py +4 -2
  6. ccxt/async_support/bingx.py +5 -1
  7. ccxt/async_support/bitfinex.py +2 -2
  8. ccxt/async_support/hashkey.py +4061 -0
  9. ccxt/async_support/hyperliquid.py +80 -62
  10. ccxt/async_support/indodax.py +29 -8
  11. ccxt/async_support/kraken.py +32 -5
  12. ccxt/async_support/krakenfutures.py +10 -9
  13. ccxt/async_support/upbit.py +1 -1
  14. ccxt/base/errors.py +7 -1
  15. ccxt/base/exchange.py +2 -2
  16. ccxt/binance.py +4 -2
  17. ccxt/bingx.py +5 -1
  18. ccxt/bitfinex.py +2 -2
  19. ccxt/hashkey.py +4061 -0
  20. ccxt/hyperliquid.py +80 -62
  21. ccxt/indodax.py +29 -8
  22. ccxt/kraken.py +32 -5
  23. ccxt/krakenfutures.py +10 -9
  24. ccxt/pro/__init__.py +3 -1
  25. ccxt/pro/ascendex.py +41 -5
  26. ccxt/pro/bingx.py +13 -12
  27. ccxt/pro/bitget.py +143 -16
  28. ccxt/pro/hashkey.py +783 -0
  29. ccxt/pro/hyperliquid.py +118 -1
  30. ccxt/pro/mexc.py +13 -7
  31. ccxt/pro/p2b.py +30 -7
  32. ccxt/pro/poloniex.py +32 -3
  33. ccxt/pro/poloniexfutures.py +1 -0
  34. ccxt/pro/probit.py +2 -0
  35. ccxt/pro/upbit.py +44 -3
  36. ccxt/pro/vertex.py +1 -0
  37. ccxt/pro/wazirx.py +3 -0
  38. ccxt/pro/whitebit.py +9 -0
  39. ccxt/pro/woo.py +1 -0
  40. ccxt/pro/woofipro.py +1 -0
  41. ccxt/pro/xt.py +1 -0
  42. ccxt/test/tests_async.py +31 -31
  43. ccxt/test/tests_sync.py +31 -31
  44. ccxt/upbit.py +1 -1
  45. {ccxt-4.3.85.dist-info → ccxt-4.3.87.dist-info}/METADATA +9 -6
  46. {ccxt-4.3.85.dist-info → ccxt-4.3.87.dist-info}/RECORD +49 -45
  47. {ccxt-4.3.85.dist-info → ccxt-4.3.87.dist-info}/LICENSE.txt +0 -0
  48. {ccxt-4.3.85.dist-info → ccxt-4.3.87.dist-info}/WHEEL +0 -0
  49. {ccxt-4.3.85.dist-info → ccxt-4.3.87.dist-info}/top_level.txt +0 -0
ccxt/pro/hyperliquid.py CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  import ccxt.async_support
7
7
  from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp
8
- from ccxt.base.types import Int, Market, Order, OrderBook, Str, Strings, Ticker, Tickers, Trade
8
+ from ccxt.base.types import Any, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade
9
9
  from ccxt.async_support.base.ws.client import Client
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
@@ -17,6 +17,9 @@ class hyperliquid(ccxt.async_support.hyperliquid):
17
17
  return self.deep_extend(super(hyperliquid, self).describe(), {
18
18
  'has': {
19
19
  'ws': True,
20
+ 'createOrderWs': True,
21
+ 'createOrdersWs': True,
22
+ 'editOrderWs': True,
20
23
  'watchBalance': False,
21
24
  'watchMyTrades': True,
22
25
  'watchOHLCV': True,
@@ -53,6 +56,84 @@ class hyperliquid(ccxt.async_support.hyperliquid):
53
56
  },
54
57
  })
55
58
 
59
+ async def create_orders_ws(self, orders: List[OrderRequest], params={}):
60
+ """
61
+ create a list of trade orders using WebSocket post request
62
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-an-order
63
+ :param Array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
64
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
65
+ """
66
+ await self.load_markets()
67
+ url = self.urls['api']['ws']['public']
68
+ ordersRequest = self.createOrdersRequest(orders, params)
69
+ wrapped = self.wrap_as_post_action(ordersRequest)
70
+ request = self.safe_dict(wrapped, 'request', {})
71
+ requestId = self.safe_string(wrapped, 'requestId')
72
+ response = await self.watch(url, requestId, request, requestId)
73
+ responseOjb = self.safe_dict(response, 'response', {})
74
+ data = self.safe_dict(responseOjb, 'data', {})
75
+ statuses = self.safe_list(data, 'statuses', [])
76
+ return self.parse_orders(statuses, None)
77
+
78
+ async def create_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
79
+ """
80
+ create a trade order using WebSocket post request
81
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-an-order
82
+ :param str symbol: unified symbol of the market to create an order in
83
+ :param str type: 'market' or 'limit'
84
+ :param str side: 'buy' or 'sell'
85
+ :param float amount: how much of currency you want to trade in units of base currency
86
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
87
+ :param dict [params]: extra parameters specific to the exchange API endpoint
88
+ :param str [params.timeInForce]: 'Gtc', 'Ioc', 'Alo'
89
+ :param bool [params.postOnly]: True or False whether the order is post-only
90
+ :param bool [params.reduceOnly]: True or False whether the order is reduce-only
91
+ :param float [params.triggerPrice]: The price at which a trigger order is triggered at
92
+ :param str [params.clientOrderId]: client order id,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
93
+ :param str [params.slippage]: the slippage for market order
94
+ :param str [params.vaultAddress]: the vault address for order
95
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
96
+ """
97
+ await self.load_markets()
98
+ order, globalParams = self.parseCreateOrderArgs(symbol, type, side, amount, price, params)
99
+ orders = await self.create_orders_ws([order], globalParams)
100
+ return orders[0]
101
+
102
+ async def edit_order_ws(self, id: str, symbol: str, type: str, side: str, amount: Num = None, price: Num = None, params={}):
103
+ """
104
+ edit a trade order
105
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-an-order
106
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-multiple-orders
107
+ :param str id: cancel order id
108
+ :param str symbol: unified symbol of the market to create an order in
109
+ :param str type: 'market' or 'limit'
110
+ :param str side: 'buy' or 'sell'
111
+ :param float amount: how much of currency you want to trade in units of base currency
112
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
113
+ :param dict [params]: extra parameters specific to the exchange API endpoint
114
+ :param str [params.timeInForce]: 'Gtc', 'Ioc', 'Alo'
115
+ :param bool [params.postOnly]: True or False whether the order is post-only
116
+ :param bool [params.reduceOnly]: True or False whether the order is reduce-only
117
+ :param float [params.triggerPrice]: The price at which a trigger order is triggered at
118
+ :param str [params.clientOrderId]: client order id,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
119
+ :param str [params.vaultAddress]: the vault address for order
120
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
121
+ """
122
+ await self.load_markets()
123
+ market = self.market(symbol)
124
+ url = self.urls['api']['ws']['public']
125
+ postRequest = self.edit_order_request(id, symbol, type, side, amount, price, params)
126
+ wrapped = self.wrap_as_post_action(postRequest)
127
+ request = self.safe_dict(wrapped, 'request', {})
128
+ requestId = self.safe_string(wrapped, 'requestId')
129
+ response = await self.watch(url, requestId, request, requestId)
130
+ # response is the same self.edit_order
131
+ responseObject = self.safe_dict(response, 'response', {})
132
+ dataObject = self.safe_dict(responseObject, 'data', {})
133
+ statuses = self.safe_list(dataObject, 'statuses', [])
134
+ first = self.safe_dict(statuses, 0, {})
135
+ return self.parse_order(first, market)
136
+
56
137
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
57
138
  """
58
139
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
@@ -494,6 +575,22 @@ class hyperliquid(ccxt.async_support.hyperliquid):
494
575
  messageHash = 'candles:' + timeframe + ':' + symbol
495
576
  client.resolve(ohlcv, messageHash)
496
577
 
578
+ def handle_ws_post(self, client: Client, message: Any):
579
+ # {
580
+ # channel: "post",
581
+ # data: {
582
+ # id: <number>,
583
+ # response: {
584
+ # type: "info" | "action" | "error",
585
+ # payload: {...}
586
+ # }
587
+ # }
588
+ data = self.safe_dict(message, 'data')
589
+ id = self.safe_string(data, 'id')
590
+ response = self.safe_dict(data, 'response')
591
+ payload = self.safe_dict(response, 'payload')
592
+ client.resolve(payload, id)
593
+
497
594
  async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
498
595
  """
499
596
  watches information on multiple orders made by the user
@@ -597,6 +694,7 @@ class hyperliquid(ccxt.async_support.hyperliquid):
597
694
  'orderUpdates': self.handle_order,
598
695
  'userFills': self.handle_my_trades,
599
696
  'webData2': self.handle_ws_tickers,
697
+ 'post': self.handle_ws_post,
600
698
  }
601
699
  exacMethod = self.safe_value(methods, topic)
602
700
  if exacMethod is not None:
@@ -623,3 +721,22 @@ class hyperliquid(ccxt.async_support.hyperliquid):
623
721
  #
624
722
  client.lastPong = self.safe_integer(message, 'pong')
625
723
  return message
724
+
725
+ def request_id(self) -> float:
726
+ requestId = self.sum(self.safe_integer(self.options, 'requestId', 0), 1)
727
+ self.options['requestId'] = requestId
728
+ return requestId
729
+
730
+ def wrap_as_post_action(self, request: dict) -> dict:
731
+ requestId = self.request_id()
732
+ return {
733
+ 'requestId': requestId,
734
+ 'request': {
735
+ 'method': 'post',
736
+ 'id': requestId,
737
+ 'request': {
738
+ 'type': 'action',
739
+ 'payload': request,
740
+ },
741
+ },
742
+ }
ccxt/pro/mexc.py CHANGED
@@ -35,6 +35,7 @@ class mexc(ccxt.async_support.mexc):
35
35
  'watchTicker': True,
36
36
  'watchTickers': False,
37
37
  'watchTrades': True,
38
+ 'watchTradesForSymbols': False,
38
39
  },
39
40
  'urls': {
40
41
  'api': {
@@ -76,6 +77,8 @@ class mexc(ccxt.async_support.mexc):
76
77
  async def watch_ticker(self, symbol: str, params={}) -> Ticker:
77
78
  """
78
79
  watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
80
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#individual-symbol-book-ticker-streams
81
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#public-channels
79
82
  :param str symbol: unified symbol of the market to fetch the ticker for
80
83
  :param dict [params]: extra parameters specific to the exchange API endpoint
81
84
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -202,7 +205,7 @@ class mexc(ccxt.async_support.mexc):
202
205
 
203
206
  async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
204
207
  """
205
- :see: https://mxcdevelop.github.io/apidocs/spot_v3_en/#kline-streams
208
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#kline-streams
206
209
  watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
207
210
  :param str symbol: unified symbol of the market to fetch OHLCV data for
208
211
  :param str timeframe: the length of time each candle represents
@@ -342,7 +345,8 @@ class mexc(ccxt.async_support.mexc):
342
345
 
343
346
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
344
347
  """
345
- :see: https://mxcdevelop.github.io/apidocs/spot_v3_en/#diff-depth-stream
348
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#diff-depth-stream
349
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#public-channels
346
350
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
347
351
  :param str symbol: unified symbol of the market to fetch the order book for
348
352
  :param int [limit]: the maximum amount of order book entries to return
@@ -496,7 +500,8 @@ class mexc(ccxt.async_support.mexc):
496
500
 
497
501
  async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
498
502
  """
499
- :see: https://mxcdevelop.github.io/apidocs/spot_v3_en/#trade-streams
503
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#trade-streams
504
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#public-channels
500
505
  get the list of most recent trades for a particular symbol
501
506
  :param str symbol: unified symbol of the market to fetch trades for
502
507
  :param int [since]: timestamp in ms of the earliest trade to fetch
@@ -576,7 +581,8 @@ class mexc(ccxt.async_support.mexc):
576
581
 
577
582
  async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
578
583
  """
579
- :see: https://mxcdevelop.github.io/apidocs/spot_v3_en/#spot-account-deals
584
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#spot-account-deals
585
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#private-channels
580
586
  watches information on multiple trades made by the user
581
587
  :param str symbol: unified market symbol of the market trades were made in
582
588
  :param int [since]: the earliest time in ms to fetch trades for
@@ -713,8 +719,8 @@ class mexc(ccxt.async_support.mexc):
713
719
 
714
720
  async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
715
721
  """
716
- :see: https://mxcdevelop.github.io/apidocs/spot_v3_en/#spot-account-orders
717
- :see: https://mxcdevelop.github.io/apidocs/spot_v3_en/#margin-account-orders
722
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#spot-account-orders
723
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#margin-account-orders
718
724
  watches information on multiple orders made by the user
719
725
  :param str symbol: unified market symbol of the market orders were made in
720
726
  :param int [since]: the earliest time in ms to fetch orders for
@@ -955,7 +961,7 @@ class mexc(ccxt.async_support.mexc):
955
961
 
956
962
  async def watch_balance(self, params={}) -> Balances:
957
963
  """
958
- :see: https://mxcdevelop.github.io/apidocs/spot_v3_en/#spot-account-upadte
964
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#spot-account-upadte
959
965
  watch balance and get the amount of funds available for trading or funds locked in orders
960
966
  :param dict [params]: extra parameters specific to the exchange API endpoint
961
967
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
ccxt/pro/p2b.py CHANGED
@@ -36,6 +36,7 @@ class p2b(ccxt.async_support.p2b):
36
36
  'watchTicker': True,
37
37
  'watchTickers': False, # in the docs but does not return anything when subscribed to
38
38
  'watchTrades': True,
39
+ 'watchTradesForSymbols': True,
39
40
  },
40
41
  'urls': {
41
42
  'api': {
@@ -142,15 +143,37 @@ class p2b(ccxt.async_support.p2b):
142
143
  :param dict [params]: extra parameters specific to the exchange API endpoint
143
144
  :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
144
145
  """
146
+ return await self.watch_trades_for_symbols([symbol], since, limit, params)
147
+
148
+ async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
149
+ """
150
+ get the list of most recent trades for a list of symbols
151
+ :see: https://github.com/P2B-team/P2B-WSS-Public/blob/main/wss_documentation.md#deals
152
+ :param str[] symbols: unified symbol of the market to fetch trades for
153
+ :param int [since]: timestamp in ms of the earliest trade to fetch
154
+ :param int [limit]: the maximum amount of trades to fetch
155
+ :param dict [params]: extra parameters specific to the exchange API endpoint
156
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
157
+ """
145
158
  await self.load_markets()
146
- market = self.market(symbol)
147
- request = [
148
- market['id'],
149
- ]
150
- messageHash = 'deals::' + market['symbol']
151
- trades = await self.subscribe('deals.subscribe', messageHash, request, params)
159
+ symbols = self.market_symbols(symbols, None, False, True, True)
160
+ messageHashes = []
161
+ if symbols is not None:
162
+ for i in range(0, len(symbols)):
163
+ messageHashes.append('deals::' + symbols[i])
164
+ marketIds = self.market_ids(symbols)
165
+ url = self.urls['api']['ws']
166
+ subscribe: dict = {
167
+ 'method': 'deals.subscribe',
168
+ 'params': marketIds,
169
+ 'id': self.milliseconds(),
170
+ }
171
+ query = self.extend(subscribe, params)
172
+ trades = await self.watch_multiple(url, messageHashes, query, messageHashes)
152
173
  if self.newUpdates:
153
- limit = trades.getLimit(symbol, limit)
174
+ first = self.safe_value(trades, 0)
175
+ tradeSymbol = self.safe_string(first, 'symbol')
176
+ limit = trades.getLimit(tradeSymbol, limit)
154
177
  return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
155
178
 
156
179
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
ccxt/pro/poloniex.py CHANGED
@@ -27,6 +27,7 @@ class poloniex(ccxt.async_support.poloniex):
27
27
  'watchTicker': True,
28
28
  'watchTickers': True,
29
29
  'watchTrades': True,
30
+ 'watchTradesForSymbols': True,
30
31
  'watchBalance': True,
31
32
  'watchStatus': False,
32
33
  'watchOrders': True,
@@ -367,12 +368,40 @@ class poloniex(ccxt.async_support.poloniex):
367
368
  :param dict [params]: extra parameters specific to the exchange API endpoint
368
369
  :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
369
370
  """
371
+ return await self.watch_trades_for_symbols([symbol], since, limit, params)
372
+
373
+ async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
374
+ """
375
+ get the list of most recent trades for a list of symbols
376
+ :see: https://api-docs.poloniex.com/spot/websocket/market-data#trades
377
+ :param str[] symbols: unified symbol of the market to fetch trades for
378
+ :param int [since]: timestamp in ms of the earliest trade to fetch
379
+ :param int [limit]: the maximum amount of trades to fetch
380
+ :param dict [params]: extra parameters specific to the exchange API endpoint
381
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
382
+ """
370
383
  await self.load_markets()
371
- symbol = self.symbol(symbol)
384
+ symbols = self.market_symbols(symbols, None, False, True, True)
372
385
  name = 'trades'
373
- trades = await self.subscribe(name, name, False, [symbol], params)
386
+ url = self.urls['api']['ws']['public']
387
+ marketIds = self.market_ids(symbols)
388
+ subscribe: dict = {
389
+ 'event': 'subscribe',
390
+ 'channel': [
391
+ name,
392
+ ],
393
+ 'symbols': marketIds,
394
+ }
395
+ request = self.extend(subscribe, params)
396
+ messageHashes = []
397
+ if symbols is not None:
398
+ for i in range(0, len(symbols)):
399
+ messageHashes.append(name + '::' + symbols[i])
400
+ trades = await self.watch_multiple(url, messageHashes, request, messageHashes)
374
401
  if self.newUpdates:
375
- limit = trades.getLimit(symbol, limit)
402
+ first = self.safe_value(trades, 0)
403
+ tradeSymbol = self.safe_string(first, 'symbol')
404
+ limit = trades.getLimit(tradeSymbol, limit)
376
405
  return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
377
406
 
378
407
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
@@ -33,6 +33,7 @@ class poloniexfutures(ccxt.async_support.poloniexfutures):
33
33
  'watchTicker': True,
34
34
  'watchTickers': False,
35
35
  'watchTrades': True,
36
+ 'watchTradesForSymbols': False,
36
37
  'watchBalance': True,
37
38
  'watchOrders': True,
38
39
  'watchMyTrades': False,
ccxt/pro/probit.py CHANGED
@@ -22,6 +22,7 @@ class probit(ccxt.async_support.probit):
22
22
  'watchTicker': True,
23
23
  'watchTickers': False,
24
24
  'watchTrades': True,
25
+ 'watchTradesForSymbols': False,
25
26
  'watchMyTrades': True,
26
27
  'watchOrders': True,
27
28
  'watchOrderBook': True,
@@ -217,6 +218,7 @@ class probit(ccxt.async_support.probit):
217
218
  async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
218
219
  """
219
220
  get the list of trades associated with the user
221
+ :see: https://docs-en.probit.com/reference/trade_history
220
222
  :param str symbol: unified symbol of the market to fetch trades for
221
223
  :param int [since]: timestamp in ms of the earliest trade to fetch
222
224
  :param int [limit]: the maximum amount of trades to fetch
ccxt/pro/upbit.py CHANGED
@@ -19,6 +19,7 @@ class upbit(ccxt.async_support.upbit):
19
19
  'watchOrderBook': True,
20
20
  'watchTicker': True,
21
21
  'watchTrades': True,
22
+ 'watchTradesForSymbols': True,
22
23
  'watchOrders': True,
23
24
  'watchMyTrades': True,
24
25
  'watchBalance': True,
@@ -79,11 +80,51 @@ class upbit(ccxt.async_support.upbit):
79
80
  :param dict [params]: extra parameters specific to the exchange API endpoint
80
81
  :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
81
82
  """
83
+ return await self.watch_trades_for_symbols([symbol], since, limit, params)
84
+
85
+ async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
86
+ """
87
+ get the list of most recent trades for a list of symbols
88
+ :see: https://global-docs.upbit.com/reference/websocket-trade
89
+ :param str[] symbols: unified symbol of the market to fetch trades for
90
+ :param int [since]: timestamp in ms of the earliest trade to fetch
91
+ :param int [limit]: the maximum amount of trades to fetch
92
+ :param dict [params]: extra parameters specific to the exchange API endpoint
93
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
94
+ """
82
95
  await self.load_markets()
83
- symbol = self.symbol(symbol)
84
- trades = await self.watch_public(symbol, 'trade')
96
+ symbols = self.market_symbols(symbols, None, False, True, True)
97
+ channel = 'trade'
98
+ messageHashes = []
99
+ url = self.implode_params(self.urls['api']['ws'], {
100
+ 'hostname': self.hostname,
101
+ })
102
+ if symbols is not None:
103
+ for i in range(0, len(symbols)):
104
+ market = self.market(symbols[i])
105
+ marketId = market['id']
106
+ symbol = market['symbol']
107
+ self.options[channel] = self.safe_value(self.options, channel, {})
108
+ self.options[channel][symbol] = True
109
+ messageHashes.append(channel + ':' + marketId)
110
+ optionSymbols = list(self.options[channel].keys())
111
+ marketIds = self.market_ids(optionSymbols)
112
+ request = [
113
+ {
114
+ 'ticket': self.uuid(),
115
+ },
116
+ {
117
+ 'type': channel,
118
+ 'codes': marketIds,
119
+ # 'isOnlySnapshot': False,
120
+ # 'isOnlyRealtime': False,
121
+ },
122
+ ]
123
+ trades = await self.watch_multiple(url, messageHashes, request, messageHashes)
85
124
  if self.newUpdates:
86
- limit = trades.getLimit(symbol, limit)
125
+ first = self.safe_value(trades, 0)
126
+ tradeSymbol = self.safe_string(first, 'symbol')
127
+ limit = trades.getLimit(tradeSymbol, limit)
87
128
  return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
88
129
 
89
130
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
ccxt/pro/vertex.py CHANGED
@@ -28,6 +28,7 @@ class vertex(ccxt.async_support.vertex):
28
28
  'watchTicker': True,
29
29
  'watchTickers': False,
30
30
  'watchTrades': True,
31
+ 'watchTradesForSymbols': False,
31
32
  'watchPositions': True,
32
33
  },
33
34
  'urls': {
ccxt/pro/wazirx.py CHANGED
@@ -22,6 +22,7 @@ class wazirx(ccxt.async_support.wazirx):
22
22
  'watchTicker': True,
23
23
  'watchTickers': True,
24
24
  'watchTrades': True,
25
+ 'watchTradesForSymbols': False,
25
26
  'watchMyTrades': True,
26
27
  'watchOrders': True,
27
28
  'watchOrderBook': True,
@@ -283,6 +284,7 @@ class wazirx(ccxt.async_support.wazirx):
283
284
  async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
284
285
  """
285
286
  get the list of most recent trades for a particular symbol
287
+ :see: https://docs.wazirx.com/#trade-streams
286
288
  :param str symbol: unified symbol of the market to fetch trades for
287
289
  :param int [since]: timestamp in ms of the earliest trade to fetch
288
290
  :param int [limit]: the maximum amount of trades to fetch
@@ -371,6 +373,7 @@ class wazirx(ccxt.async_support.wazirx):
371
373
  async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
372
374
  """
373
375
  watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
376
+ :see: https://docs.wazirx.com/#kline-candlestick-stream
374
377
  :param str symbol: unified symbol of the market to fetch OHLCV data for
375
378
  :param str timeframe: the length of time each candle represents
376
379
  :param int [since]: timestamp in ms of the earliest candle to fetch
ccxt/pro/whitebit.py CHANGED
@@ -27,6 +27,7 @@ class whitebit(ccxt.async_support.whitebit):
27
27
  'watchOrders': True,
28
28
  'watchTicker': True,
29
29
  'watchTrades': True,
30
+ 'watchTradesForSymbols': False,
30
31
  },
31
32
  'urls': {
32
33
  'api': {
@@ -67,6 +68,7 @@ class whitebit(ccxt.async_support.whitebit):
67
68
  async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
68
69
  """
69
70
  watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
71
+ :see: https://docs.whitebit.com/public/websocket/#kline
70
72
  :param str symbol: unified symbol of the market to fetch OHLCV data for
71
73
  :param str timeframe: the length of time each candle represents
72
74
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -135,6 +137,7 @@ class whitebit(ccxt.async_support.whitebit):
135
137
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
136
138
  """
137
139
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
140
+ :see: https://docs.whitebit.com/public/websocket/#market-depth
138
141
  :param str symbol: unified symbol of the market to fetch the order book for
139
142
  :param int [limit]: the maximum amount of order book entries to return
140
143
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -233,6 +236,7 @@ class whitebit(ccxt.async_support.whitebit):
233
236
  async def watch_ticker(self, symbol: str, params={}) -> Ticker:
234
237
  """
235
238
  watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
239
+ :see: https://docs.whitebit.com/public/websocket/#market-statistics
236
240
  :param str symbol: unified symbol of the market to fetch the ticker for
237
241
  :param dict [params]: extra parameters specific to the exchange API endpoint
238
242
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -295,6 +299,7 @@ class whitebit(ccxt.async_support.whitebit):
295
299
  async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
296
300
  """
297
301
  get the list of most recent trades for a particular symbol
302
+ :see: https://docs.whitebit.com/public/websocket/#market-trades
298
303
  :param str symbol: unified symbol of the market to fetch trades for
299
304
  :param int [since]: timestamp in ms of the earliest trade to fetch
300
305
  :param int [limit]: the maximum amount of trades to fetch
@@ -356,6 +361,7 @@ class whitebit(ccxt.async_support.whitebit):
356
361
  async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
357
362
  """
358
363
  watches trades made by the user
364
+ :see: https://docs.whitebit.com/private/websocket/#deals
359
365
  :param str symbol: unified market symbol
360
366
  :param int [since]: the earliest time in ms to fetch trades for
361
367
  :param int [limit]: the maximum number of trades structures to retrieve
@@ -449,6 +455,7 @@ class whitebit(ccxt.async_support.whitebit):
449
455
  async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
450
456
  """
451
457
  watches information on multiple orders made by the user
458
+ :see: https://docs.whitebit.com/private/websocket/#orders-pending
452
459
  :param str symbol: unified market symbol of the market orders were made in
453
460
  :param int [since]: the earliest time in ms to fetch orders for
454
461
  :param int [limit]: the maximum number of order structures to retrieve
@@ -612,6 +619,8 @@ class whitebit(ccxt.async_support.whitebit):
612
619
  async def watch_balance(self, params={}) -> Balances:
613
620
  """
614
621
  watch balance and get the amount of funds available for trading or funds locked in orders
622
+ :see: https://docs.whitebit.com/private/websocket/#balance-spot
623
+ :see: https://docs.whitebit.com/private/websocket/#balance-margin
615
624
  :param dict [params]: extra parameters specific to the exchange API endpoint
616
625
  :param str [params.type]: spot or contract if not provided self.options['defaultType'] is used
617
626
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
ccxt/pro/woo.py CHANGED
@@ -28,6 +28,7 @@ class woo(ccxt.async_support.woo):
28
28
  'watchTicker': True,
29
29
  'watchTickers': True,
30
30
  'watchTrades': True,
31
+ 'watchTradesForSymbols': False,
31
32
  'watchPositions': True,
32
33
  },
33
34
  'urls': {
ccxt/pro/woofipro.py CHANGED
@@ -27,6 +27,7 @@ class woofipro(ccxt.async_support.woofipro):
27
27
  'watchTicker': True,
28
28
  'watchTickers': True,
29
29
  'watchTrades': True,
30
+ 'watchTradesForSymbols': False,
30
31
  'watchPositions': True,
31
32
  },
32
33
  'urls': {
ccxt/pro/xt.py CHANGED
@@ -21,6 +21,7 @@ class xt(ccxt.async_support.xt):
21
21
  'watchTicker': True,
22
22
  'watchTickers': True,
23
23
  'watchTrades': True,
24
+ 'watchTradesForSymbols': False,
24
25
  'watchBalance': True,
25
26
  'watchOrders': True,
26
27
  'watchMyTrades': True,