ccxt 4.2.29__py2.py3-none-any.whl → 4.2.31__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 (133) hide show
  1. ccxt/__init__.py +3 -3
  2. ccxt/abstract/bybit.py +2 -2
  3. ccxt/abstract/coinbase.py +10 -0
  4. ccxt/abstract/okx.py +12 -1
  5. ccxt/ascendex.py +5 -5
  6. ccxt/async_support/__init__.py +3 -3
  7. ccxt/async_support/ascendex.py +5 -5
  8. ccxt/async_support/base/exchange.py +3 -3
  9. ccxt/async_support/bigone.py +2 -2
  10. ccxt/async_support/binance.py +892 -218
  11. ccxt/async_support/bingx.py +1 -1
  12. ccxt/async_support/bitfinex.py +1 -1
  13. ccxt/async_support/bitfinex2.py +421 -86
  14. ccxt/async_support/bitforex.py +3 -0
  15. ccxt/async_support/bitget.py +8 -4
  16. ccxt/async_support/bitmart.py +3 -3
  17. ccxt/async_support/bitmex.py +4 -4
  18. ccxt/async_support/bitrue.py +1 -1
  19. ccxt/async_support/bitso.py +1 -1
  20. ccxt/async_support/bitteam.py +2 -2
  21. ccxt/async_support/btcalpha.py +1 -1
  22. ccxt/async_support/bybit.py +3 -3
  23. ccxt/async_support/coinbase.py +20 -5
  24. ccxt/async_support/coincheck.py +1 -1
  25. ccxt/async_support/coinex.py +2 -2
  26. ccxt/async_support/coinlist.py +1 -1
  27. ccxt/async_support/coinmate.py +1 -1
  28. ccxt/async_support/coinmetro.py +2 -2
  29. ccxt/async_support/coinsph.py +1 -1
  30. ccxt/async_support/cryptocom.py +3 -3
  31. ccxt/async_support/deribit.py +1 -0
  32. ccxt/async_support/digifinex.py +6 -4
  33. ccxt/async_support/exmo.py +2 -2
  34. ccxt/async_support/gate.py +5 -5
  35. ccxt/async_support/gemini.py +3 -3
  36. ccxt/async_support/hitbtc.py +13 -17
  37. ccxt/async_support/hollaex.py +2 -2
  38. ccxt/async_support/htx.py +6 -6
  39. ccxt/async_support/huobijp.py +1 -1
  40. ccxt/async_support/kraken.py +3 -1
  41. ccxt/async_support/krakenfutures.py +4 -1
  42. ccxt/async_support/kucoin.py +17 -17
  43. ccxt/async_support/kucoinfutures.py +3 -3
  44. ccxt/async_support/lbank.py +4 -3
  45. ccxt/async_support/mexc.py +7 -7
  46. ccxt/async_support/novadax.py +1 -1
  47. ccxt/async_support/okcoin.py +2 -2
  48. ccxt/async_support/okx.py +22 -8
  49. ccxt/async_support/p2b.py +1 -0
  50. ccxt/async_support/phemex.py +3 -3
  51. ccxt/async_support/poloniexfutures.py +6 -3
  52. ccxt/async_support/probit.py +1 -1
  53. ccxt/async_support/timex.py +2 -2
  54. ccxt/async_support/tokocrypto.py +3 -3
  55. ccxt/async_support/wavesexchange.py +2 -2
  56. ccxt/async_support/whitebit.py +3 -3
  57. ccxt/async_support/woo.py +3 -3
  58. ccxt/async_support/yobit.py +1 -1
  59. ccxt/async_support/zaif.py +1 -1
  60. ccxt/async_support/zonda.py +3 -3
  61. ccxt/base/errors.py +13 -12
  62. ccxt/base/exchange.py +36 -26
  63. ccxt/bigone.py +2 -2
  64. ccxt/binance.py +892 -218
  65. ccxt/bingx.py +1 -1
  66. ccxt/bitfinex.py +1 -1
  67. ccxt/bitfinex2.py +421 -86
  68. ccxt/bitforex.py +3 -0
  69. ccxt/bitget.py +8 -4
  70. ccxt/bitmart.py +3 -3
  71. ccxt/bitmex.py +4 -4
  72. ccxt/bitrue.py +1 -1
  73. ccxt/bitso.py +1 -1
  74. ccxt/bitteam.py +2 -2
  75. ccxt/btcalpha.py +1 -1
  76. ccxt/bybit.py +3 -3
  77. ccxt/coinbase.py +20 -5
  78. ccxt/coincheck.py +1 -1
  79. ccxt/coinex.py +2 -2
  80. ccxt/coinlist.py +1 -1
  81. ccxt/coinmate.py +1 -1
  82. ccxt/coinmetro.py +2 -2
  83. ccxt/coinsph.py +1 -1
  84. ccxt/cryptocom.py +3 -3
  85. ccxt/deribit.py +1 -0
  86. ccxt/digifinex.py +6 -4
  87. ccxt/exmo.py +2 -2
  88. ccxt/gate.py +5 -5
  89. ccxt/gemini.py +3 -3
  90. ccxt/hitbtc.py +13 -17
  91. ccxt/hollaex.py +2 -2
  92. ccxt/htx.py +6 -6
  93. ccxt/huobijp.py +1 -1
  94. ccxt/kraken.py +3 -1
  95. ccxt/krakenfutures.py +4 -1
  96. ccxt/kucoin.py +17 -17
  97. ccxt/kucoinfutures.py +3 -3
  98. ccxt/lbank.py +4 -3
  99. ccxt/mexc.py +7 -7
  100. ccxt/novadax.py +1 -1
  101. ccxt/okcoin.py +2 -2
  102. ccxt/okx.py +22 -8
  103. ccxt/p2b.py +1 -0
  104. ccxt/phemex.py +3 -3
  105. ccxt/poloniexfutures.py +6 -3
  106. ccxt/pro/__init__.py +3 -1
  107. ccxt/pro/alpaca.py +1 -1
  108. ccxt/pro/binance.py +4 -4
  109. ccxt/pro/bitget.py +1 -1
  110. ccxt/pro/bitmart.py +1 -1
  111. ccxt/pro/bitmex.py +43 -7
  112. ccxt/pro/bitvavo.py +1 -1
  113. ccxt/pro/bybit.py +2 -2
  114. ccxt/pro/cex.py +2 -2
  115. ccxt/pro/independentreserve.py +1 -1
  116. ccxt/pro/okx.py +1 -1
  117. ccxt/pro/onetrading.py +2 -2
  118. ccxt/pro/p2b.py +407 -0
  119. ccxt/pro/probit.py +5 -5
  120. ccxt/pro/whitebit.py +1 -1
  121. ccxt/probit.py +1 -1
  122. ccxt/timex.py +2 -2
  123. ccxt/tokocrypto.py +3 -3
  124. ccxt/wavesexchange.py +2 -2
  125. ccxt/whitebit.py +3 -3
  126. ccxt/woo.py +3 -3
  127. ccxt/yobit.py +1 -1
  128. ccxt/zaif.py +1 -1
  129. ccxt/zonda.py +3 -3
  130. {ccxt-4.2.29.dist-info → ccxt-4.2.31.dist-info}/METADATA +6 -7
  131. {ccxt-4.2.29.dist-info → ccxt-4.2.31.dist-info}/RECORD +133 -132
  132. {ccxt-4.2.29.dist-info → ccxt-4.2.31.dist-info}/WHEEL +0 -0
  133. {ccxt-4.2.29.dist-info → ccxt-4.2.31.dist-info}/top_level.txt +0 -0
ccxt/pro/bitmex.py CHANGED
@@ -6,7 +6,7 @@
6
6
  import ccxt.async_support
7
7
  from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Int, Order, OrderBook, Position, Str, Strings, Ticker, Trade
9
+ from ccxt.base.types import Balances, Int, Order, OrderBook, Position, Str, Strings, Ticker, Tickers, Trade
10
10
  from ccxt.async_support.base.ws.client import Client
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
@@ -28,7 +28,7 @@ class bitmex(ccxt.async_support.bitmex):
28
28
  'watchOrders': True,
29
29
  'watchPostions': True,
30
30
  'watchTicker': True,
31
- 'watchTickers': False,
31
+ 'watchTickers': True,
32
32
  'watchTrades': True,
33
33
  'watchTradesForSymbols': True,
34
34
  },
@@ -79,6 +79,39 @@ class bitmex(ccxt.async_support.bitmex):
79
79
  }
80
80
  return await self.watch(url, messageHash, self.extend(request, params), messageHash)
81
81
 
82
+ async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
83
+ """
84
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
85
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
86
+ :param dict [params]: extra parameters specific to the exchange API endpoint
87
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
88
+ """
89
+ await self.load_markets()
90
+ symbols = self.market_symbols(symbols, None, True)
91
+ name = 'instrument'
92
+ url = self.urls['api']['ws']
93
+ messageHashes = []
94
+ if symbols is not None:
95
+ for i in range(0, len(symbols)):
96
+ symbol = symbols[i]
97
+ market = self.market(symbol)
98
+ hash = name + ':' + market['id']
99
+ messageHashes.append(hash)
100
+ else:
101
+ messageHashes.append(name)
102
+ request = {
103
+ 'op': 'subscribe',
104
+ 'args': messageHashes,
105
+ }
106
+ ticker = await self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
107
+ if self.newUpdates:
108
+ if symbols is None:
109
+ return ticker
110
+ result = {}
111
+ result[ticker['symbol']] = ticker
112
+ return result
113
+ return self.filter_by_array(self.tickers, 'symbol', symbols)
114
+
82
115
  def handle_ticker(self, client: Client, message):
83
116
  #
84
117
  # {
@@ -307,18 +340,21 @@ class bitmex(ccxt.async_support.bitmex):
307
340
  # }
308
341
  #
309
342
  table = self.safe_string(message, 'table')
310
- data = self.safe_value(message, 'data', [])
343
+ data = self.safe_list(message, 'data', [])
344
+ tickers = {}
311
345
  for i in range(0, len(data)):
312
346
  update = data[i]
313
- marketId = self.safe_value(update, 'symbol')
347
+ marketId = self.safe_string(update, 'symbol')
314
348
  market = self.safe_market(marketId)
315
349
  symbol = market['symbol']
316
350
  messageHash = table + ':' + marketId
317
- ticker = self.safe_value(self.tickers, symbol, {})
318
- info = self.safe_value(ticker, 'info', {})
351
+ ticker = self.safe_dict(self.tickers, symbol, {})
352
+ info = self.safe_dict(ticker, 'info', {})
319
353
  ticker = self.parse_ticker(self.extend(info, update), market)
354
+ tickers[symbol] = ticker
320
355
  self.tickers[symbol] = ticker
321
356
  client.resolve(ticker, messageHash)
357
+ client.resolve(tickers, 'instrument')
322
358
  return message
323
359
 
324
360
  async def watch_balance(self, params={}) -> Balances:
@@ -573,7 +609,7 @@ class bitmex(ccxt.async_support.bitmex):
573
609
  return future
574
610
 
575
611
  def handle_authentication_message(self, client: Client, message):
576
- authenticated = self.safe_value(message, 'success', False)
612
+ authenticated = self.safe_bool(message, 'success', False)
577
613
  messageHash = 'authenticated'
578
614
  if authenticated:
579
615
  # we resolve the future here permanently so authentication only happens once
ccxt/pro/bitvavo.py CHANGED
@@ -1152,7 +1152,7 @@ class bitvavo(ccxt.async_support.bitvavo):
1152
1152
  # }
1153
1153
  #
1154
1154
  messageHash = 'authenticated'
1155
- authenticated = self.safe_value(message, 'authenticated', False)
1155
+ authenticated = self.safe_bool(message, 'authenticated', False)
1156
1156
  if authenticated:
1157
1157
  # we resolve the future here permanently so authentication only happens once
1158
1158
  client.resolve(message, messageHash)
ccxt/pro/bybit.py CHANGED
@@ -1259,8 +1259,8 @@ class bybit(ccxt.async_support.bybit):
1259
1259
  subType = None
1260
1260
  subType, params = self.handle_sub_type_and_params('watchBalance', None, params)
1261
1261
  unified = await self.isUnifiedEnabled()
1262
- isUnifiedMargin = self.safe_value(unified, 0, False)
1263
- isUnifiedAccount = self.safe_value(unified, 1, False)
1262
+ isUnifiedMargin = self.safe_bool(unified, 0, False)
1263
+ isUnifiedAccount = self.safe_bool(unified, 1, False)
1264
1264
  url = self.get_url_by_market_type(None, True, method, params)
1265
1265
  await self.authenticate(url)
1266
1266
  topicByMarket = {
ccxt/pro/cex.py CHANGED
@@ -686,7 +686,7 @@ class cex(ccxt.async_support.cex):
686
686
  if order is None:
687
687
  order = self.parse_ws_order_update(data, market)
688
688
  order['remaining'] = remains
689
- canceled = self.safe_value(data, 'cancel', False)
689
+ canceled = self.safe_bool(data, 'cancel', False)
690
690
  if canceled:
691
691
  order['status'] = 'canceled'
692
692
  if isTransaction:
@@ -767,7 +767,7 @@ class cex(ccxt.async_support.cex):
767
767
  timestamp = time
768
768
  if isTransaction:
769
769
  timestamp = self.parse8601(time)
770
- canceled = self.safe_value(order, 'cancel', False)
770
+ canceled = self.safe_bool(order, 'cancel', False)
771
771
  status = 'open'
772
772
  if canceled:
773
773
  status = 'canceled'
@@ -179,7 +179,7 @@ class independentreserve(ccxt.async_support.independentreserve):
179
179
  orderBook = self.safe_value(message, 'Data', {})
180
180
  messageHash = 'orderbook:' + symbol + ':' + depth
181
181
  subscription = self.safe_value(client.subscriptions, messageHash, {})
182
- receivedSnapshot = self.safe_value(subscription, 'receivedSnapshot', False)
182
+ receivedSnapshot = self.safe_bool(subscription, 'receivedSnapshot', False)
183
183
  timestamp = self.safe_integer(message, 'Time')
184
184
  storedOrderBook = self.safe_value(self.orderbooks, symbol)
185
185
  if storedOrderBook is None:
ccxt/pro/okx.py CHANGED
@@ -815,7 +815,7 @@ class okx(ccxt.async_support.okx):
815
815
  # By default, receive order updates from any instrument type
816
816
  type = None
817
817
  type, params = self.handle_option_and_params(params, 'watchMyTrades', 'type', 'ANY')
818
- isStop = self.safe_value(params, 'stop', False)
818
+ isStop = self.safe_bool(params, 'stop', False)
819
819
  params = self.omit(params, ['stop'])
820
820
  await self.load_markets()
821
821
  await self.authenticate({'access': 'business' if isStop else 'private'})
ccxt/pro/onetrading.py CHANGED
@@ -1020,7 +1020,7 @@ class onetrading(ccxt.async_support.onetrading):
1020
1020
  subscription = self.safe_value(client.subscriptions, subscriptionHash)
1021
1021
  if subscription is not None:
1022
1022
  ohlcvMarket = self.safe_value(subscription, marketId, {})
1023
- marketSubscribed = self.safe_value(ohlcvMarket, timeframe, False)
1023
+ marketSubscribed = self.safe_bool(ohlcvMarket, timeframe, False)
1024
1024
  if not marketSubscribed:
1025
1025
  type = 'UPDATE_SUBSCRIPTION'
1026
1026
  client.subscriptions[subscriptionHash] = None
@@ -1245,7 +1245,7 @@ class onetrading(ccxt.async_support.onetrading):
1245
1245
  if subscription is not None:
1246
1246
  for i in range(0, len(marketIds)):
1247
1247
  marketId = marketIds[i]
1248
- marketSubscribed = self.safe_value(subscription, marketId, False)
1248
+ marketSubscribed = self.safe_bool(subscription, marketId, False)
1249
1249
  if not marketSubscribed:
1250
1250
  type = 'UPDATE_SUBSCRIPTION'
1251
1251
  client.subscriptions[subscriptionHash] = None
ccxt/pro/p2b.py ADDED
@@ -0,0 +1,407 @@
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, ArrayCacheByTimestamp
8
+ from ccxt.base.types import Int, OrderBook, Ticker, 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 BadRequest
13
+
14
+
15
+ class p2b(ccxt.async_support.p2b):
16
+
17
+ def describe(self):
18
+ return self.deep_extend(super(p2b, self).describe(), {
19
+ 'has': {
20
+ 'ws': True,
21
+ 'cancelAllOrdersWs': False,
22
+ 'cancelOrdersWs': False,
23
+ 'cancelOrderWs': False,
24
+ 'createOrderWs': False,
25
+ 'editOrderWs': False,
26
+ 'fetchBalanceWs': False,
27
+ 'fetchOpenOrdersWs': False,
28
+ 'fetchOrderWs': False,
29
+ 'fetchTradesWs': False,
30
+ 'watchBalance': False,
31
+ 'watchMyTrades': False,
32
+ 'watchOHLCV': True,
33
+ 'watchOrderBook': True,
34
+ 'watchOrders': False,
35
+ # 'watchStatus': True,
36
+ 'watchTicker': True,
37
+ 'watchTickers': False, # in the docs but does not return anything when subscribed to
38
+ 'watchTrades': True,
39
+ },
40
+ 'urls': {
41
+ 'api': {
42
+ 'ws': 'wss://apiws.p2pb2b.com/',
43
+ },
44
+ },
45
+ 'options': {
46
+ 'OHLCVLimit': 1000,
47
+ 'tradesLimit': 1000,
48
+ 'timeframes': {
49
+ '15m': 900,
50
+ '30m': 1800,
51
+ '1h': 3600,
52
+ '1d': 86400,
53
+ },
54
+ 'watchTicker': {
55
+ 'name': 'state', # or 'price'
56
+ },
57
+ 'watchTickers': {
58
+ 'name': 'state', # or 'price'
59
+ },
60
+ },
61
+ 'streaming': {
62
+ 'ping': self.ping,
63
+ },
64
+ })
65
+
66
+ async def subscribe(self, name: str, messageHash: str, request, params={}):
67
+ """
68
+ * @ignore
69
+ Connects to a websocket channel
70
+ :param str name: name of the channel
71
+ :param str messageHash: string to look up in handler
72
+ :param str[]|float[] request: endpoint parameters
73
+ :param dict [params]: extra parameters specific to the p2b api
74
+ :returns dict: data from the websocket stream
75
+ """
76
+ url = self.urls['api']['ws']
77
+ subscribe = {
78
+ 'method': name,
79
+ 'params': request,
80
+ 'id': self.milliseconds(),
81
+ }
82
+ query = self.extend(subscribe, params)
83
+ return await self.watch(url, messageHash, query, messageHash)
84
+
85
+ async def watch_ohlcv(self, symbol: str, timeframe='15m', since: Int = None, limit: Int = None, params={}) -> List[list]:
86
+ """
87
+ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market. Can only subscribe to one timeframe at a time for each symbol
88
+ :see: https://github.com/P2B-team/P2B-WSS-Public/blob/main/wss_documentation.md#kline-candlestick
89
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
90
+ :param str timeframe: 15m, 30m, 1h or 1d
91
+ :param int [since]: timestamp in ms of the earliest candle to fetch
92
+ :param int [limit]: the maximum amount of candles to fetch
93
+ :param dict [params]: extra parameters specific to the exchange API endpoint
94
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
95
+ """
96
+ await self.load_markets()
97
+ timeframes = self.safe_value(self.options, 'timeframes', {})
98
+ channel = self.safe_integer(timeframes, timeframe)
99
+ if channel is None:
100
+ raise BadRequest(self.id + ' watchOHLCV cannot take a timeframe of ' + timeframe)
101
+ market = self.market(symbol)
102
+ request = [
103
+ market['id'],
104
+ channel,
105
+ ]
106
+ messageHash = 'kline::' + market['symbol']
107
+ ohlcv = await self.subscribe('kline.subscribe', messageHash, request, params)
108
+ if self.newUpdates:
109
+ limit = ohlcv.getLimit(symbol, limit)
110
+ return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
111
+
112
+ async def watch_ticker(self, symbol: str, params={}) -> Ticker:
113
+ """
114
+ watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
115
+ :see: https://github.com/P2B-team/P2B-WSS-Public/blob/main/wss_documentation.md#last-price
116
+ :see: https://github.com/P2B-team/P2B-WSS-Public/blob/main/wss_documentation.md#market-status
117
+ :param str symbol: unified symbol of the market to fetch the ticker for
118
+ :param dict [params]: extra parameters specific to the exchange API endpoint
119
+ :param dict [params.method]: 'state'(default) or 'price'
120
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
121
+ """
122
+ await self.load_markets()
123
+ watchTickerOptions = self.safe_value(self.options, 'watchTicker')
124
+ name = self.safe_string(watchTickerOptions, 'name', 'state') # or price
125
+ name, params = self.handle_option_and_params(params, 'method', 'name', name)
126
+ market = self.market(symbol)
127
+ request = [
128
+ market['id'],
129
+ ]
130
+ messageHash = name + '::' + market['symbol']
131
+ return await self.subscribe(name + '.subscribe', messageHash, request, params)
132
+
133
+ async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
134
+ """
135
+ get the list of most recent trades for a particular symbol
136
+ :see: https://github.com/P2B-team/P2B-WSS-Public/blob/main/wss_documentation.md#deals
137
+ :param str symbol: unified symbol of the market to fetch trades for
138
+ :param int [since]: timestamp in ms of the earliest trade to fetch
139
+ :param int [limit]: the maximum amount of trades to fetch
140
+ :param dict [params]: extra parameters specific to the exchange API endpoint
141
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
142
+ """
143
+ await self.load_markets()
144
+ market = self.market(symbol)
145
+ request = [
146
+ market['id'],
147
+ ]
148
+ messageHash = 'deals::' + market['symbol']
149
+ trades = await self.subscribe('deals.subscribe', messageHash, request, params)
150
+ if self.newUpdates:
151
+ limit = trades.getLimit(symbol, limit)
152
+ return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
153
+
154
+ async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
155
+ """
156
+ watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
157
+ :see: https://github.com/P2B-team/P2B-WSS-Public/blob/main/wss_documentation.md#depth-of-market
158
+ :param str symbol: unified symbol of the market to fetch the order book for
159
+ :param int [limit]: 1-100, default=100
160
+ :param dict [params]: extra parameters specific to the exchange API endpoint
161
+ :param float [params.interval]: 0, 0.00000001, 0.0000001, 0.000001, 0.00001, 0.0001, 0.001, 0.01, 0.1, interval of precision for order, default=0.001
162
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
163
+ """
164
+ await self.load_markets()
165
+ market = self.market(symbol)
166
+ name = 'depth.subscribe'
167
+ messageHash = 'orderbook::' + market['symbol']
168
+ interval = self.safe_string(params, 'interval', '0.001')
169
+ if limit is None:
170
+ limit = 100
171
+ request = [
172
+ market['id'],
173
+ limit,
174
+ interval,
175
+ ]
176
+ orderbook = await self.subscribe(name, messageHash, request, params)
177
+ return orderbook.limit()
178
+
179
+ def handle_ohlcv(self, client: Client, message):
180
+ #
181
+ # {
182
+ # "method": "kline.update",
183
+ # "params": [
184
+ # [
185
+ # 1657648800, # Kline start time
186
+ # "0.054146", # Kline open price
187
+ # "0.053938", # Kline close price(current price)
188
+ # "0.054146", # Kline high price
189
+ # "0.053911", # Kline low price
190
+ # "596.4674", # Volume for stock currency
191
+ # "32.2298758767", # Volume for money currency
192
+ # "ETH_BTC" # Market
193
+ # ]
194
+ # ],
195
+ # "id": null
196
+ # }
197
+ #
198
+ data = self.safe_list(message, 'params')
199
+ data = self.safe_list(data, 0)
200
+ method = self.safe_string(message, 'method')
201
+ splitMethod = method.split('.')
202
+ channel = self.safe_string(splitMethod, 0)
203
+ marketId = self.safe_string(data, 7)
204
+ market = self.safe_market(marketId)
205
+ timeframes = self.safe_dict(self.options, 'timeframes', {})
206
+ timeframe = self.find_timeframe(channel, timeframes)
207
+ symbol = self.safe_string(market, 'symbol')
208
+ messageHash = channel + '::' + symbol
209
+ parsed = self.parse_ohlcv(data, market)
210
+ self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
211
+ stored = self.safe_value(self.ohlcvs[symbol], timeframe)
212
+ if symbol is not None:
213
+ if stored is None:
214
+ limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
215
+ stored = ArrayCacheByTimestamp(limit)
216
+ self.ohlcvs[symbol][timeframe] = stored
217
+ stored.append(parsed)
218
+ client.resolve(stored, messageHash)
219
+ return message
220
+
221
+ def handle_trade(self, client: Client, message):
222
+ #
223
+ # {
224
+ # "method": "deals.update",
225
+ # "params": [
226
+ # "ETH_BTC",
227
+ # [
228
+ # {
229
+ # "id": 4503032979, # Order_id
230
+ # "amount": "0.103",
231
+ # "type": "sell", # Side
232
+ # "time": 1657661950.8487639, # Creation time
233
+ # "price": "0.05361"
234
+ # },
235
+ # ...
236
+ # ]
237
+ # ],
238
+ # "id": null
239
+ # }
240
+ #
241
+ data = self.safe_list(message, 'params', [])
242
+ trades = self.safe_list(data, 1)
243
+ marketId = self.safe_string(data, 0)
244
+ market = self.safe_market(marketId)
245
+ symbol = self.safe_string(market, 'symbol')
246
+ tradesArray = self.safe_value(self.trades, symbol)
247
+ if tradesArray is None:
248
+ tradesLimit = self.safe_integer(self.options, 'tradesLimit', 1000)
249
+ tradesArray = ArrayCache(tradesLimit)
250
+ self.trades[symbol] = tradesArray
251
+ for i in range(0, len(trades)):
252
+ item = trades[i]
253
+ trade = self.parse_trade(item, market)
254
+ tradesArray.append(trade)
255
+ messageHash = 'deals::' + symbol
256
+ client.resolve(tradesArray, messageHash)
257
+ return message
258
+
259
+ def handle_ticker(self, client: Client, message):
260
+ #
261
+ # state
262
+ #
263
+ # {
264
+ # "method": "state.update",
265
+ # "params": [
266
+ # "ETH_BTC",
267
+ # {
268
+ # "high": "0.055774", # High price for the last 24h
269
+ # "close": "0.053679", # Close price for the last 24h
270
+ # "low": "0.053462", # Low price for the last 24h
271
+ # "period": 86400, # Period 24h
272
+ # "last": "0.053679", # Last price for the last 24h
273
+ # "volume": "38463.6132", # Stock volume for the last 24h
274
+ # "open": "0.055682", # Open price for the last 24h
275
+ # "deal": "2091.0038055314" # Money volume for the last 24h
276
+ # }
277
+ # ],
278
+ # "id": null
279
+ # }
280
+ #
281
+ # price
282
+ #
283
+ # {
284
+ # "method": "price.update",
285
+ # "params": [
286
+ # "ETH_BTC", # market
287
+ # "0.053836" # last price
288
+ # ],
289
+ # "id": null
290
+ # }
291
+ #
292
+ data = self.safe_list(message, 'params', [])
293
+ marketId = self.safe_string(data, 0)
294
+ market = self.safe_market(marketId)
295
+ method = self.safe_string(message, 'method')
296
+ splitMethod = method.split('.')
297
+ messageHashStart = self.safe_string(splitMethod, 0)
298
+ tickerData = self.safe_dict(data, 1)
299
+ ticker = None
300
+ if method == 'price.update':
301
+ lastPrice = self.safe_string(data, 1)
302
+ ticker = self.safe_ticker({
303
+ 'last': lastPrice,
304
+ 'close': lastPrice,
305
+ 'symbol': market['symbol'],
306
+ })
307
+ else:
308
+ ticker = self.parse_ticker(tickerData, market)
309
+ symbol = ticker['symbol']
310
+ messageHash = messageHashStart + '::' + symbol
311
+ client.resolve(ticker, messageHash)
312
+ return message
313
+
314
+ def handle_order_book(self, client: Client, message):
315
+ #
316
+ # {
317
+ # "method": "depth.update",
318
+ # "params": [
319
+ # False, # True - all records, False - new records
320
+ # {
321
+ # "asks": [ # side
322
+ # [
323
+ # "19509.81", # price
324
+ # "0.277" # amount
325
+ # ]
326
+ # ]
327
+ # },
328
+ # "BTC_USDT"
329
+ # ],
330
+ # "id": null
331
+ # }
332
+ #
333
+ params = self.safe_list(message, 'params', [])
334
+ data = self.safe_dict(params, 1)
335
+ asks = self.safe_list(data, 'asks')
336
+ bids = self.safe_list(data, 'bids')
337
+ marketId = self.safe_string(params, 2)
338
+ market = self.safe_market(marketId)
339
+ symbol = market['symbol']
340
+ messageHash = 'orderbook::' + market['symbol']
341
+ subscription = self.safe_value(client.subscriptions, messageHash, {})
342
+ limit = self.safe_integer(subscription, 'limit')
343
+ orderbook = self.safe_value(self.orderbooks, symbol)
344
+ if orderbook is None:
345
+ self.orderbooks[symbol] = self.order_book({}, limit)
346
+ orderbook = self.orderbooks[symbol]
347
+ if bids is not None:
348
+ for i in range(0, len(bids)):
349
+ bid = self.safe_value(bids, i)
350
+ price = self.safe_number(bid, 0)
351
+ amount = self.safe_number(bid, 1)
352
+ orderbook['bids'].store(price, amount)
353
+ if asks is not None:
354
+ for i in range(0, len(asks)):
355
+ ask = self.safe_value(asks, i)
356
+ price = self.safe_number(ask, 0)
357
+ amount = self.safe_number(ask, 1)
358
+ orderbook['asks'].store(price, amount)
359
+ orderbook['symbol'] = symbol
360
+ client.resolve(orderbook, messageHash)
361
+
362
+ def handle_message(self, client: Client, message):
363
+ if self.handle_error_message(client, message):
364
+ return
365
+ result = self.safe_string(message, 'result')
366
+ if result == 'pong':
367
+ self.handle_pong(client, message)
368
+ return
369
+ method = self.safe_string(message, 'method')
370
+ methods = {
371
+ 'depth.update': self.handle_order_book,
372
+ 'price.update': self.handle_ticker,
373
+ 'kline.update': self.handle_ohlcv,
374
+ 'state.update': self.handle_ticker,
375
+ 'deals.update': self.handle_trade,
376
+ }
377
+ endpoint = self.safe_value(methods, method)
378
+ if endpoint is not None:
379
+ return endpoint(client, message)
380
+
381
+ def handle_error_message(self, client: Client, message):
382
+ error = self.safe_string(message, 'error')
383
+ if error is not None:
384
+ raise ExchangeError(self.id + ' error: ' + self.json(error))
385
+ return False
386
+
387
+ def ping(self, client):
388
+ """
389
+ :see: https://github.com/P2B-team/P2B-WSS-Public/blob/main/wss_documentation.md#ping
390
+ * @param client
391
+ """
392
+ return {
393
+ 'method': 'server.ping',
394
+ 'params': [],
395
+ 'id': self.milliseconds(),
396
+ }
397
+
398
+ def handle_pong(self, client: Client, message):
399
+ #
400
+ # {
401
+ # error: null,
402
+ # result: 'pong',
403
+ # id: 1706539608030
404
+ # }
405
+ #
406
+ client.lastPong = self.safe_integer(message, 'id')
407
+ return message
ccxt/pro/probit.py CHANGED
@@ -103,7 +103,7 @@ class probit(ccxt.async_support.probit):
103
103
  # }
104
104
  # }
105
105
  #
106
- reset = self.safe_value(message, 'reset', False)
106
+ reset = self.safe_bool(message, 'reset', False)
107
107
  data = self.safe_value(message, 'data', {})
108
108
  currencyIds = list(data.keys())
109
109
  if reset:
@@ -202,7 +202,7 @@ class probit(ccxt.async_support.probit):
202
202
  symbol = self.safe_symbol(marketId)
203
203
  market = self.safe_market(marketId)
204
204
  trades = self.safe_value(message, 'recent_trades', [])
205
- reset = self.safe_value(message, 'reset', False)
205
+ reset = self.safe_bool(message, 'reset', False)
206
206
  messageHash = 'trades:' + symbol
207
207
  stored = self.safe_value(self.trades, symbol)
208
208
  if stored is None or reset:
@@ -268,7 +268,7 @@ class probit(ccxt.async_support.probit):
268
268
  length = len(rawTrades)
269
269
  if length == 0:
270
270
  return
271
- reset = self.safe_value(message, 'reset', False)
271
+ reset = self.safe_bool(message, 'reset', False)
272
272
  messageHash = 'myTrades'
273
273
  stored = self.myTrades
274
274
  if (stored is None) or reset:
@@ -348,7 +348,7 @@ class probit(ccxt.async_support.probit):
348
348
  if length == 0:
349
349
  return
350
350
  messageHash = 'orders'
351
- reset = self.safe_value(message, 'reset', False)
351
+ reset = self.safe_bool(message, 'reset', False)
352
352
  stored = self.orders
353
353
  if stored is None or reset:
354
354
  limit = self.safe_integer(self.options, 'ordersLimit', 1000)
@@ -432,7 +432,7 @@ class probit(ccxt.async_support.probit):
432
432
  if storedOrderBook is None:
433
433
  storedOrderBook = self.order_book({})
434
434
  self.orderbooks[symbol] = storedOrderBook
435
- reset = self.safe_value(message, 'reset', False)
435
+ reset = self.safe_bool(message, 'reset', False)
436
436
  if reset:
437
437
  snapshot = self.parse_order_book(dataBySide, symbol, None, 'buy', 'sell', 'price', 'quantity')
438
438
  storedOrderBook.reset(snapshot)
ccxt/pro/whitebit.py CHANGED
@@ -698,7 +698,7 @@ class whitebit(ccxt.async_support.whitebit):
698
698
  hasSymbolSubscription = True
699
699
  market = self.market(symbol)
700
700
  marketId = market['id']
701
- isSubscribed = self.safe_value(subscription, marketId, False)
701
+ isSubscribed = self.safe_bool(subscription, marketId, False)
702
702
  if not isSubscribed:
703
703
  subscription[marketId] = True
704
704
  hasSymbolSubscription = False
ccxt/probit.py CHANGED
@@ -297,7 +297,7 @@ class probit(Exchange, ImplicitAPI):
297
297
  quoteId = self.safe_string(market, 'quote_currency_id')
298
298
  base = self.safe_currency_code(baseId)
299
299
  quote = self.safe_currency_code(quoteId)
300
- closed = self.safe_value(market, 'closed', False)
300
+ closed = self.safe_bool(market, 'closed', False)
301
301
  takerFeeRate = self.safe_string(market, 'taker_fee_rate')
302
302
  taker = Precise.string_div(takerFeeRate, '100')
303
303
  makerFeeRate = self.safe_string(market, 'maker_fee_rate')
ccxt/timex.py CHANGED
@@ -109,7 +109,7 @@ class timex(Exchange, ImplicitAPI):
109
109
  'rest': 'https://plasma-relay-backend.timex.io',
110
110
  },
111
111
  'www': 'https://timex.io',
112
- 'doc': 'https://docs.timex.io',
112
+ 'doc': 'https://plasma-relay-backend.timex.io/swagger-ui/index.html',
113
113
  'referral': 'https://timex.io/?refcode=1x27vNkTbP1uwkCck',
114
114
  },
115
115
  'api': {
@@ -701,7 +701,7 @@ class timex(Exchange, ImplicitAPI):
701
701
  market = self.market(symbol)
702
702
  uppercaseSide = side.upper()
703
703
  uppercaseType = type.upper()
704
- postOnly = self.safe_value(params, 'postOnly', False)
704
+ postOnly = self.safe_bool(params, 'postOnly', False)
705
705
  if postOnly:
706
706
  uppercaseType = 'POST_ONLY'
707
707
  params = self.omit(params, ['postOnly'])