ccxt 4.4.90__py2.py3-none-any.whl → 4.4.91__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 (57) hide show
  1. ccxt/__init__.py +1 -3
  2. ccxt/async_support/__init__.py +1 -3
  3. ccxt/async_support/base/exchange.py +6 -3
  4. ccxt/async_support/base/ws/client.py +173 -64
  5. ccxt/async_support/base/ws/future.py +23 -50
  6. ccxt/async_support/binance.py +1 -1
  7. ccxt/async_support/bitmex.py +2 -1
  8. ccxt/async_support/cex.py +61 -0
  9. ccxt/async_support/cryptocom.py +17 -2
  10. ccxt/async_support/cryptomus.py +1 -1
  11. ccxt/async_support/exmo.py +14 -7
  12. ccxt/async_support/gate.py +2 -2
  13. ccxt/async_support/hyperliquid.py +104 -53
  14. ccxt/async_support/kraken.py +26 -1
  15. ccxt/async_support/mexc.py +1 -0
  16. ccxt/async_support/modetrade.py +2 -2
  17. ccxt/async_support/paradex.py +1 -1
  18. ccxt/base/exchange.py +8 -5
  19. ccxt/binance.py +1 -1
  20. ccxt/bitmex.py +2 -1
  21. ccxt/cex.py +61 -0
  22. ccxt/cryptocom.py +17 -2
  23. ccxt/cryptomus.py +1 -1
  24. ccxt/exmo.py +13 -7
  25. ccxt/gate.py +2 -2
  26. ccxt/hyperliquid.py +104 -53
  27. ccxt/kraken.py +26 -1
  28. ccxt/mexc.py +1 -0
  29. ccxt/modetrade.py +2 -2
  30. ccxt/paradex.py +1 -1
  31. ccxt/pro/__init__.py +1 -1
  32. ccxt/pro/bitstamp.py +1 -1
  33. ccxt/pro/bybit.py +6 -136
  34. ccxt/pro/kraken.py +246 -258
  35. ccxt/pro/mexc.py +0 -1
  36. {ccxt-4.4.90.dist-info → ccxt-4.4.91.dist-info}/METADATA +6 -7
  37. {ccxt-4.4.90.dist-info → ccxt-4.4.91.dist-info}/RECORD +40 -57
  38. ccxt/abstract/coinlist.py +0 -57
  39. ccxt/async_support/base/ws/aiohttp_client.py +0 -147
  40. ccxt/async_support/bitcoincom.py +0 -18
  41. ccxt/async_support/bitfinex1.py +0 -1711
  42. ccxt/async_support/bitpanda.py +0 -17
  43. ccxt/async_support/coinlist.py +0 -2542
  44. ccxt/async_support/poloniexfutures.py +0 -1875
  45. ccxt/bitcoincom.py +0 -18
  46. ccxt/bitfinex1.py +0 -1710
  47. ccxt/bitpanda.py +0 -17
  48. ccxt/coinlist.py +0 -2542
  49. ccxt/poloniexfutures.py +0 -1875
  50. ccxt/pro/bitcoincom.py +0 -35
  51. ccxt/pro/bitfinex1.py +0 -635
  52. ccxt/pro/bitpanda.py +0 -16
  53. ccxt/pro/poloniexfutures.py +0 -1004
  54. ccxt/pro/wazirx.py +0 -766
  55. {ccxt-4.4.90.dist-info → ccxt-4.4.91.dist-info}/LICENSE.txt +0 -0
  56. {ccxt-4.4.90.dist-info → ccxt-4.4.91.dist-info}/WHEEL +0 -0
  57. {ccxt-4.4.90.dist-info → ccxt-4.4.91.dist-info}/top_level.txt +0 -0
ccxt/pro/wazirx.py DELETED
@@ -1,766 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
- # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
-
6
- import ccxt.async_support
7
- from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp
8
- from ccxt.base.types import Any, Balances, Int, Order, OrderBook, Str, Strings, Ticker, Tickers, Trade
9
- from ccxt.async_support.base.ws.client import Client
10
- from typing import List
11
- from ccxt.base.errors import ExchangeError
12
- from ccxt.base.errors import NotSupported
13
-
14
-
15
- class wazirx(ccxt.async_support.wazirx):
16
-
17
- def describe(self) -> Any:
18
- return self.deep_extend(super(wazirx, self).describe(), {
19
- 'has': {
20
- 'ws': True,
21
- 'watchBalance': True,
22
- 'watchTicker': True,
23
- 'watchTickers': True,
24
- 'watchTrades': True,
25
- 'watchTradesForSymbols': False,
26
- 'watchMyTrades': True,
27
- 'watchOrders': True,
28
- 'watchOrderBook': True,
29
- 'watchOHLCV': True,
30
- },
31
- 'urls': {
32
- 'api': {
33
- 'ws': 'wss://stream.wazirx.com/stream',
34
- },
35
- },
36
- 'options': {
37
- },
38
- 'streaming': {
39
- },
40
- 'exceptions': {
41
- },
42
- 'api': {
43
- 'private': {
44
- 'post': {
45
- 'create_auth_token': 1,
46
- },
47
- },
48
- },
49
- })
50
-
51
- async def watch_balance(self, params={}) -> Balances:
52
- """
53
- watch balance and get the amount of funds available for trading or funds locked in orders
54
-
55
- https://docs.wazirx.com/#account-update
56
-
57
- :param dict [params]: extra parameters specific to the exchange API endpoint
58
- :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
59
- """
60
- await self.load_markets()
61
- token = await self.authenticate(params)
62
- messageHash = 'balance'
63
- url = self.urls['api']['ws']
64
- subscribe: dict = {
65
- 'event': 'subscribe',
66
- 'streams': ['outboundAccountPosition'],
67
- 'auth_key': token,
68
- }
69
- request = self.deep_extend(subscribe, params)
70
- return await self.watch(url, messageHash, request, messageHash)
71
-
72
- def handle_balance(self, client: Client, message):
73
- #
74
- # {
75
- # "data":
76
- # {
77
- # "B": [
78
- # {
79
- # "a":"wrx",
80
- # "b":"2043856.426455209",
81
- # "l":"3001318.98"
82
- # }
83
- # ],
84
- # "E":1631683058909
85
- # },
86
- # "stream":"outboundAccountPosition"
87
- # }
88
- #
89
- data = self.safe_value(message, 'data', {})
90
- balances = self.safe_value(data, 'B', [])
91
- timestamp = self.safe_integer(data, 'E')
92
- self.balance['info'] = balances
93
- self.balance['timestamp'] = timestamp
94
- self.balance['datetime'] = self.iso8601(timestamp)
95
- for i in range(0, len(balances)):
96
- balance = balances[i]
97
- currencyId = self.safe_string(balance, 'a')
98
- code = self.safe_currency_code(currencyId)
99
- available = self.safe_string(balance, 'b')
100
- locked = self.safe_string(balance, 'l')
101
- account = self.account()
102
- account['free'] = available
103
- account['used'] = locked
104
- self.balance[code] = account
105
- self.balance = self.safe_balance(self.balance)
106
- messageHash = 'balance'
107
- client.resolve(self.balance, messageHash)
108
-
109
- def parse_ws_trade(self, trade, market=None):
110
- #
111
- # trade
112
- # {
113
- # "E": 1631681323000, Event time
114
- # "S": "buy", Side
115
- # "a": 26946138, Buyer order ID
116
- # "b": 26946169, Seller order ID
117
- # "m": True, Is buyer maker?
118
- # "p": "7.0", Price
119
- # "q": "15.0", Quantity
120
- # "s": "btcinr", Symbol
121
- # "t": 17376030 Trade ID
122
- # }
123
- # ownTrade
124
- # {
125
- # "E": 1631683058000,
126
- # "S": "ask",
127
- # "U": "inr",
128
- # "a": 114144050,
129
- # "b": 114144121,
130
- # "f": "0.2",
131
- # "m": True,
132
- # "o": 26946170,
133
- # "p": "5.0",
134
- # "q": "20.0",
135
- # "s": "btcinr",
136
- # "t": 17376032,
137
- # "w": "100.0"
138
- # }
139
- #
140
- timestamp = self.safe_integer(trade, 'E')
141
- marketId = self.safe_string(trade, 's')
142
- market = self.safe_market(marketId, market)
143
- feeCost = self.safe_string(trade, 'f')
144
- feeCurrencyId = self.safe_string(trade, 'U')
145
- isMaker = self.safe_value(trade, 'm') is True
146
- fee = None
147
- if feeCost is not None:
148
- fee = {
149
- 'cost': feeCost,
150
- 'currency': self.safe_currency_code(feeCurrencyId),
151
- 'rate': None,
152
- }
153
- return self.safe_trade({
154
- 'id': self.safe_string(trade, 't'),
155
- 'info': trade,
156
- 'timestamp': timestamp,
157
- 'datetime': self.iso8601(timestamp),
158
- 'symbol': market['symbol'],
159
- 'order': self.safe_string_n(trade, ['o']),
160
- 'type': None,
161
- 'side': self.safe_string(trade, 'S'),
162
- 'takerOrMaker': 'maker' if isMaker else 'taker',
163
- 'price': self.safe_string(trade, 'p'),
164
- 'amount': self.safe_string(trade, 'q'),
165
- 'cost': None,
166
- 'fee': fee,
167
- }, market)
168
-
169
- async def watch_ticker(self, symbol: str, params={}) -> Ticker:
170
- """
171
- watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
172
-
173
- https://docs.wazirx.com/#all-market-tickers-stream
174
-
175
- :param str symbol: unified symbol of the market to fetch the ticker for
176
- :param dict [params]: extra parameters specific to the exchange API endpoint
177
- :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
178
- """
179
- await self.load_markets()
180
- market = self.market(symbol)
181
- url = self.urls['api']['ws']
182
- messageHash = 'ticker:' + market['symbol']
183
- subscribeHash = 'tickers'
184
- stream = '!' + 'ticker@arr'
185
- subscribe: dict = {
186
- 'event': 'subscribe',
187
- 'streams': [stream],
188
- }
189
- request = self.deep_extend(subscribe, params)
190
- return await self.watch(url, messageHash, request, subscribeHash)
191
-
192
- async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
193
- """
194
- watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
195
-
196
- https://docs.wazirx.com/#all-market-tickers-stream
197
-
198
- :param str[] symbols: unified symbol of the market to fetch the ticker for
199
- :param dict [params]: extra parameters specific to the exchange API endpoint
200
- :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
201
- """
202
- await self.load_markets()
203
- symbols = self.market_symbols(symbols)
204
- url = self.urls['api']['ws']
205
- messageHash = 'tickers'
206
- stream = '!' + 'ticker@arr'
207
- subscribe: dict = {
208
- 'event': 'subscribe',
209
- 'streams': [stream],
210
- }
211
- request = self.deep_extend(subscribe, params)
212
- tickers = await self.watch(url, messageHash, request, messageHash)
213
- return self.filter_by_array(tickers, 'symbol', symbols, False)
214
-
215
- def handle_ticker(self, client: Client, message):
216
- #
217
- # {
218
- # "data":
219
- # [
220
- # {
221
- # "E":1631625534000, # Event time
222
- # "T":"SPOT", # Type
223
- # "U":"wrx", # Quote unit
224
- # "a":"0.0", # Best sell price
225
- # "b":"0.0", # Best buy price
226
- # "c":"5.0", # Last price
227
- # "h":"5.0", # High price
228
- # "l":"5.0", # Low price
229
- # "o":"5.0", # Open price
230
- # "q":"0.0", # Quantity
231
- # "s":"btcwrx", # Symbol
232
- # "u":"btc" # Base unit
233
- # }
234
- # ],
235
- # "stream":"not ticker@arr"
236
- # }
237
- #
238
- data = self.safe_value(message, 'data', [])
239
- for i in range(0, len(data)):
240
- ticker = data[i]
241
- parsedTicker = self.parse_ws_ticker(ticker)
242
- symbol = parsedTicker['symbol']
243
- self.tickers[symbol] = parsedTicker
244
- messageHash = 'ticker:' + symbol
245
- client.resolve(parsedTicker, messageHash)
246
- client.resolve(self.tickers, 'tickers')
247
-
248
- def parse_ws_ticker(self, ticker, market=None):
249
- #
250
- # {
251
- # "E":1631625534000, # Event time
252
- # "T":"SPOT", # Type
253
- # "U":"wrx", # Quote unit
254
- # "a":"0.0", # Best sell price
255
- # "b":"0.0", # Best buy price
256
- # "c":"5.0", # Last price
257
- # "h":"5.0", # High price
258
- # "l":"5.0", # Low price
259
- # "o":"5.0", # Open price
260
- # "q":"0.0", # Quantity
261
- # "s":"btcwrx", # Symbol
262
- # "u":"btc" # Base unit
263
- # }
264
- #
265
- marketId = self.safe_string(ticker, 's')
266
- timestamp = self.safe_integer(ticker, 'E')
267
- return self.safe_ticker({
268
- 'symbol': self.safe_symbol(marketId, market),
269
- 'timestamp': timestamp,
270
- 'datetime': self.iso8601(timestamp),
271
- 'high': self.safe_string(ticker, 'h'),
272
- 'low': self.safe_string(ticker, 'l'),
273
- 'bid': self.safe_number(ticker, 'b'),
274
- 'bidVolume': None,
275
- 'ask': self.safe_number(ticker, 'a'),
276
- 'askVolume': None,
277
- 'vwap': None,
278
- 'open': self.safe_string(ticker, 'o'),
279
- 'close': None,
280
- 'last': self.safe_string(ticker, 'l'),
281
- 'previousClose': None,
282
- 'change': None,
283
- 'percentage': None,
284
- 'average': None,
285
- 'baseVolume': None,
286
- 'quoteVolume': self.safe_string(ticker, 'q'),
287
- 'info': ticker,
288
- }, market)
289
-
290
- async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
291
- """
292
- get the list of most recent trades for a particular symbol
293
-
294
- https://docs.wazirx.com/#trade-streams
295
-
296
- :param str symbol: unified symbol of the market to fetch trades for
297
- :param int [since]: timestamp in ms of the earliest trade to fetch
298
- :param int [limit]: the maximum amount of trades to fetch
299
- :param dict [params]: extra parameters specific to the exchange API endpoint
300
- :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
301
- """
302
- await self.load_markets()
303
- market = self.market(symbol)
304
- symbol = market['symbol']
305
- messageHash = market['id'] + '@trades'
306
- url = self.urls['api']['ws']
307
- message: dict = {
308
- 'event': 'subscribe',
309
- 'streams': [messageHash],
310
- }
311
- request = self.extend(message, params)
312
- trades = await self.watch(url, messageHash, request, messageHash)
313
- if self.newUpdates:
314
- limit = trades.getLimit(symbol, limit)
315
- return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
316
-
317
- def handle_trades(self, client: Client, message):
318
- #
319
- # {
320
- # "data": {
321
- # "trades": [{
322
- # "E": 1631681323000, Event time
323
- # "S": "buy", Side
324
- # "a": 26946138, Buyer order ID
325
- # "b": 26946169, Seller order ID
326
- # "m": True, Is buyer maker?
327
- # "p": "7.0", Price
328
- # "q": "15.0", Quantity
329
- # "s": "btcinr", Symbol
330
- # "t": 17376030 Trade ID
331
- # }]
332
- # },
333
- # "stream": "btcinr@trades"
334
- # }
335
- #
336
- data = self.safe_value(message, 'data', {})
337
- rawTrades = self.safe_value(data, 'trades', [])
338
- messageHash = self.safe_string(message, 'stream')
339
- split = messageHash.split('@')
340
- marketId = self.safe_string(split, 0)
341
- market = self.safe_market(marketId)
342
- symbol = self.safe_symbol(marketId, market)
343
- trades = self.safe_value(self.trades, symbol)
344
- if trades is None:
345
- limit = self.safe_integer(self.options, 'tradesLimit', 1000)
346
- trades = ArrayCache(limit)
347
- self.trades[symbol] = trades
348
- for i in range(0, len(rawTrades)):
349
- parsedTrade = self.parse_ws_trade(rawTrades[i], market)
350
- trades.append(parsedTrade)
351
- client.resolve(trades, messageHash)
352
-
353
- async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
354
- """
355
- watch trades by user
356
-
357
- https://docs.wazirx.com/#trade-update
358
-
359
- :param str symbol: unified symbol of the market to fetch trades for
360
- :param int [since]: timestamp in ms of the earliest trade to fetch
361
- :param int [limit]: the maximum amount of trades to fetch
362
- :param dict [params]: extra parameters specific to the exchange API endpoint
363
- :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
364
- """
365
- await self.load_markets()
366
- token = await self.authenticate(params)
367
- if symbol is not None:
368
- market = self.market(symbol)
369
- symbol = market['symbol']
370
- url = self.urls['api']['ws']
371
- messageHash = 'myTrades'
372
- message: dict = {
373
- 'event': 'subscribe',
374
- 'streams': ['ownTrade'],
375
- 'auth_key': token,
376
- }
377
- request = self.deep_extend(message, params)
378
- trades = await self.watch(url, messageHash, request, messageHash)
379
- if self.newUpdates:
380
- limit = trades.getLimit(symbol, limit)
381
- return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
382
-
383
- async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
384
- """
385
- watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
386
-
387
- https://docs.wazirx.com/#kline-candlestick-stream
388
-
389
- :param str symbol: unified symbol of the market to fetch OHLCV data for
390
- :param str timeframe: the length of time each candle represents
391
- :param int [since]: timestamp in ms of the earliest candle to fetch
392
- :param int [limit]: the maximum amount of candles to fetch
393
- :param dict [params]: extra parameters specific to the exchange API endpoint
394
- :returns int[][]: A list of candles ordered, open, high, low, close, volume
395
- """
396
- await self.load_markets()
397
- market = self.market(symbol)
398
- symbol = market['symbol']
399
- url = self.urls['api']['ws']
400
- messageHash = 'ohlcv:' + symbol + ':' + timeframe
401
- stream = market['id'] + '@kline_' + timeframe
402
- message: dict = {
403
- 'event': 'subscribe',
404
- 'streams': [stream],
405
- }
406
- request = self.deep_extend(message, params)
407
- ohlcv = await self.watch(url, messageHash, request, messageHash)
408
- if self.newUpdates:
409
- limit = ohlcv.getLimit(symbol, limit)
410
- return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
411
-
412
- def handle_ohlcv(self, client: Client, message):
413
- #
414
- # {
415
- # "data": {
416
- # "E":1631683058904, Event time
417
- # "s": "btcinr", Symbol
418
- # "t": 1638747660000, Kline start time
419
- # "T": 1638747719999, Kline close time
420
- # "i": "1m", Interval
421
- # "o": "0.0010", Open price
422
- # "c": "0.0020", Close price
423
- # "h": "0.0025", High price
424
- # "l": "0.0015", Low price
425
- # "v": "1000", Base asset volume
426
- # },
427
- # "stream": "btcinr@kline_1m"
428
- # }
429
- #
430
- data = self.safe_value(message, 'data', {})
431
- marketId = self.safe_string(data, 's')
432
- market = self.safe_market(marketId)
433
- symbol = self.safe_symbol(marketId, market)
434
- timeframe = self.safe_string(data, 'i')
435
- self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
436
- stored = self.safe_value(self.ohlcvs[symbol], timeframe)
437
- if stored is None:
438
- limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
439
- stored = ArrayCacheByTimestamp(limit)
440
- self.ohlcvs[symbol][timeframe] = stored
441
- parsed = self.parse_ws_ohlcv(data, market)
442
- stored.append(parsed)
443
- messageHash = 'ohlcv:' + symbol + ':' + timeframe
444
- client.resolve(stored, messageHash)
445
-
446
- def parse_ws_ohlcv(self, ohlcv, market=None) -> list:
447
- #
448
- # {
449
- # "E":1631683058904, Event time
450
- # "s": "btcinr", Symbol
451
- # "t": 1638747660000, Kline start time
452
- # "T": 1638747719999, Kline close time
453
- # "i": "1m", Interval
454
- # "o": "0.0010", Open price
455
- # "c": "0.0020", Close price
456
- # "h": "0.0025", High price
457
- # "l": "0.0015", Low price
458
- # "v": "1000", Base asset volume
459
- # }
460
- #
461
- return [
462
- self.safe_integer(ohlcv, 't'),
463
- self.safe_number(ohlcv, 'o'),
464
- self.safe_number(ohlcv, 'c'),
465
- self.safe_number(ohlcv, 'h'),
466
- self.safe_number(ohlcv, 'l'),
467
- self.safe_number(ohlcv, 'v'),
468
- ]
469
-
470
- async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
471
- """
472
- watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
473
-
474
- https://docs.wazirx.com/#depth-stream
475
-
476
- :param str symbol: unified symbol of the market to fetch the order book for
477
- :param int [limit]: the maximum amount of order book entries to return
478
- :param dict [params]: extra parameters specific to the exchange API endpoint
479
- :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
480
- """
481
- await self.load_markets()
482
- market = self.market(symbol)
483
- symbol = market['symbol']
484
- url = self.urls['api']['ws']
485
- messageHash = 'orderbook:' + symbol
486
- stream = market['id'] + '@depth'
487
- subscribe: dict = {
488
- 'event': 'subscribe',
489
- 'streams': [stream],
490
- }
491
- request = self.deep_extend(subscribe, params)
492
- orderbook = await self.watch(url, messageHash, request, messageHash)
493
- return orderbook.limit()
494
-
495
- def handle_delta(self, bookside, delta):
496
- bidAsk = self.parse_bid_ask(delta, 0, 1)
497
- bookside.storeArray(bidAsk)
498
-
499
- def handle_deltas(self, bookside, deltas):
500
- for i in range(0, len(deltas)):
501
- self.handle_delta(bookside, deltas[i])
502
-
503
- def handle_order_book(self, client: Client, message):
504
- #
505
- # {
506
- # "data": {
507
- # "E": 1659475095000,
508
- # "a": [
509
- # ["23051.0", "1.30141"],
510
- # ],
511
- # "b": [
512
- # ["22910.0", "1.30944"],
513
- # ],
514
- # "s": "btcusdt"
515
- # },
516
- # "stream": "btcusdt@depth"
517
- # }
518
- #
519
- data = self.safe_value(message, 'data', {})
520
- timestamp = self.safe_integer(data, 'E')
521
- marketId = self.safe_string(data, 's')
522
- market = self.safe_market(marketId)
523
- symbol = market['symbol']
524
- messageHash = 'orderbook:' + symbol
525
- # currentOrderBook = self.safe_value(self.orderbooks, symbol)
526
- if not (symbol in self.orderbooks):
527
- snapshot = self.parse_order_book(data, symbol, timestamp, 'b', 'a')
528
- self.orderbooks[symbol] = self.order_book(snapshot)
529
- else:
530
- orderbook = self.orderbooks[symbol]
531
- asks = self.safe_list(data, 'a', [])
532
- bids = self.safe_list(data, 'b', [])
533
- self.handle_deltas(orderbook['asks'], asks)
534
- self.handle_deltas(orderbook['bids'], bids)
535
- orderbook['nonce'] = timestamp
536
- orderbook['timestamp'] = timestamp
537
- orderbook['datetime'] = self.iso8601(timestamp)
538
- self.orderbooks[symbol] = orderbook
539
- client.resolve(self.orderbooks[symbol], messageHash)
540
-
541
- async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
542
- await self.load_markets()
543
- if symbol is not None:
544
- market = self.market(symbol)
545
- symbol = market['symbol']
546
- token = await self.authenticate(params)
547
- messageHash = 'orders'
548
- message: dict = {
549
- 'event': 'subscribe',
550
- 'streams': ['orderUpdate'],
551
- 'auth_key': token,
552
- }
553
- url = self.urls['api']['ws']
554
- request = self.deep_extend(message, params)
555
- orders = await self.watch(url, messageHash, request, messageHash, request)
556
- if self.newUpdates:
557
- limit = orders.getLimit(symbol, limit)
558
- return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
559
-
560
- def handle_order(self, client: Client, message):
561
- #
562
- # {
563
- # "data": {
564
- # "E": 1631683058904,
565
- # "O": 1631683058000,
566
- # "S": "ask",
567
- # "V": "70.0",
568
- # "X": "wait",
569
- # "i": 26946170,
570
- # "m": True,
571
- # "o": "sell",
572
- # "p": "5.0",
573
- # "q": "70.0",
574
- # "s": "wrxinr",
575
- # "v": "0.0"
576
- # },
577
- # "stream": "orderUpdate"
578
- # }
579
- #
580
- order = self.safe_value(message, 'data', {})
581
- parsedOrder = self.parse_ws_order(order)
582
- if self.orders is None:
583
- limit = self.safe_integer(self.options, 'ordersLimit', 1000)
584
- self.orders = ArrayCacheBySymbolById(limit)
585
- orders = self.orders
586
- orders.append(parsedOrder)
587
- messageHash = 'orders'
588
- client.resolve(self.orders, messageHash)
589
- messageHash += ':' + parsedOrder['symbol']
590
- client.resolve(self.orders, messageHash)
591
-
592
- def parse_ws_order(self, order, market=None):
593
- #
594
- # {
595
- # "E": 1631683058904,
596
- # "O": 1631683058000,
597
- # "S": "ask",
598
- # "V": "70.0",
599
- # "X": "wait",
600
- # "i": 26946170,
601
- # "m": True,
602
- # "o": "sell",
603
- # "p": "5.0",
604
- # "q": "70.0",
605
- # "s": "wrxinr",
606
- # "v": "0.0"
607
- # }
608
- #
609
- timestamp = self.safe_integer(order, 'O')
610
- marketId = self.safe_string(order, 's')
611
- status = self.safe_string(order, 'X')
612
- market = self.safe_market(marketId)
613
- return self.safe_order({
614
- 'info': order,
615
- 'id': self.safe_string(order, 'i'),
616
- 'clientOrderId': self.safe_string(order, 'c'),
617
- 'datetime': self.iso8601(timestamp),
618
- 'timestamp': timestamp,
619
- 'lastTradeTimestamp': None,
620
- 'symbol': market['symbol'],
621
- 'type': 'limit' if self.safe_value(order, 'm') else 'market',
622
- 'timeInForce': None,
623
- 'postOnly': None,
624
- 'side': self.safe_string(order, 'o'),
625
- 'price': self.safe_string(order, 'p'),
626
- 'stopPrice': None,
627
- 'triggerPrice': None,
628
- 'amount': self.safe_string(order, 'V'),
629
- 'filled': None,
630
- 'remaining': self.safe_string(order, 'q'),
631
- 'cost': None,
632
- 'average': self.safe_string(order, 'v'),
633
- 'status': self.parse_order_status(status),
634
- 'fee': None,
635
- 'trades': None,
636
- }, market)
637
-
638
- def handle_my_trades(self, client: Client, message):
639
- #
640
- # {
641
- # "data": {
642
- # "E": 1631683058000,
643
- # "S": "ask",
644
- # "U": "usdt",
645
- # "a": 114144050,
646
- # "b": 114144121,
647
- # "f": "0.2",
648
- # "ga": "0.0",
649
- # "gc": "usdt",
650
- # "m": True,
651
- # "o": 26946170,
652
- # "p": "5.0",
653
- # "q": "20.0",
654
- # "s": "btcusdt",
655
- # "t": 17376032,
656
- # "w": "100.0"
657
- # },
658
- # "stream": "ownTrade"
659
- # }
660
- #
661
- trade = self.safe_value(message, 'data', {})
662
- messageHash = 'myTrades'
663
- myTrades = None
664
- if self.myTrades is None:
665
- limit = self.safe_integer(self.options, 'tradesLimit', 1000)
666
- myTrades = ArrayCacheBySymbolById(limit)
667
- self.myTrades = myTrades
668
- else:
669
- myTrades = self.myTrades
670
- parsedTrade = self.parse_ws_trade(trade)
671
- myTrades.append(parsedTrade)
672
- client.resolve(myTrades, messageHash)
673
-
674
- def handle_connected(self, client: Client, message):
675
- #
676
- # {
677
- # "data": {
678
- # "timeout_duration": 1800
679
- # },
680
- # "event": "connected"
681
- # }
682
- #
683
- return message
684
-
685
- def handle_subscribed(self, client: Client, message):
686
- #
687
- # {
688
- # "data": {
689
- # "streams": ["not ticker@arr"]
690
- # },
691
- # "event": "subscribed",
692
- # "id": 0
693
- # }
694
- #
695
- return message
696
-
697
- def handle_error(self, client: Client, message):
698
- #
699
- # {
700
- # "data": {
701
- # "code": 400,
702
- # "message": "Invalid request: streams must be an array"
703
- # },
704
- # "event": "error",
705
- # "id": 0
706
- # }
707
- #
708
- # {
709
- # "message": "HeartBeat message not received, closing the connection",
710
- # "status": "error"
711
- # }
712
- #
713
- raise ExchangeError(self.id + ' ' + self.json(message))
714
-
715
- def handle_message(self, client: Client, message):
716
- status = self.safe_string(message, 'status')
717
- if status == 'error':
718
- self.handle_error(client, message)
719
- return
720
- event = self.safe_string(message, 'event')
721
- eventHandlers: dict = {
722
- 'error': self.handle_error,
723
- 'connected': self.handle_connected,
724
- 'subscribed': self.handle_subscribed,
725
- }
726
- eventHandler = self.safe_value(eventHandlers, event)
727
- if eventHandler is not None:
728
- eventHandler(client, message)
729
- return
730
- stream = self.safe_string(message, 'stream', '')
731
- streamHandlers: dict = {
732
- 'ticker@arr': self.handle_ticker,
733
- '@depth': self.handle_order_book,
734
- '@kline': self.handle_ohlcv,
735
- '@trades': self.handle_trades,
736
- 'outboundAccountPosition': self.handle_balance,
737
- 'orderUpdate': self.handle_order,
738
- 'ownTrade': self.handle_my_trades,
739
- }
740
- streams = list(streamHandlers.keys())
741
- for i in range(0, len(streams)):
742
- streamContains = stream.find(streams[i]) > -1
743
- if streamContains:
744
- handler = streamHandlers[streams[i]]
745
- handler(client, message)
746
- return
747
- raise NotSupported(self.id + ' self message type is not supported yet. Message: ' + self.json(message))
748
-
749
- async def authenticate(self, params={}):
750
- url = self.urls['api']['ws']
751
- client = self.client(url)
752
- messageHash = 'authenticated'
753
- now = self.milliseconds()
754
- subscription = self.safe_value(client.subscriptions, messageHash)
755
- expires = self.safe_integer(subscription, 'expires')
756
- if subscription is None or now > expires:
757
- subscription = await self.privatePostCreateAuthToken()
758
- subscription['expires'] = now + self.safe_integer(subscription, 'timeout_duration') * 1000
759
- #
760
- # {
761
- # "auth_key": "Xx***dM",
762
- # "timeout_duration": 900
763
- # }
764
- #
765
- client.subscriptions[messageHash] = subscription
766
- return self.safe_string(subscription, 'auth_key')