ccxt 4.4.41__py2.py3-none-any.whl → 4.4.42__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 (162) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/binance.py +3 -0
  3. ccxt/abstract/binancecoinm.py +3 -0
  4. ccxt/abstract/binanceus.py +3 -0
  5. ccxt/abstract/binanceusdm.py +3 -0
  6. ccxt/ace.py +1 -1
  7. ccxt/alpaca.py +0 -1
  8. ccxt/ascendex.py +0 -1
  9. ccxt/async_support/__init__.py +1 -1
  10. ccxt/async_support/ace.py +1 -1
  11. ccxt/async_support/alpaca.py +0 -1
  12. ccxt/async_support/ascendex.py +0 -1
  13. ccxt/async_support/base/exchange.py +15 -15
  14. ccxt/async_support/bigone.py +0 -1
  15. ccxt/async_support/binance.py +3 -0
  16. ccxt/async_support/bingx.py +2 -0
  17. ccxt/async_support/bitfinex.py +122 -0
  18. ccxt/async_support/blofin.py +16 -7
  19. ccxt/async_support/cex.py +1 -1
  20. ccxt/async_support/coinbase.py +8 -9
  21. ccxt/async_support/coinbaseexchange.py +5 -6
  22. ccxt/async_support/coinbaseinternational.py +7 -8
  23. ccxt/async_support/coincatch.py +0 -1
  24. ccxt/async_support/coincheck.py +0 -1
  25. ccxt/async_support/coinex.py +91 -6
  26. ccxt/async_support/coinlist.py +3 -4
  27. ccxt/async_support/coinmate.py +1 -3
  28. ccxt/async_support/coinmetro.py +4 -5
  29. ccxt/async_support/coinone.py +0 -1
  30. ccxt/async_support/coinsph.py +7 -8
  31. ccxt/async_support/cryptocom.py +3 -0
  32. ccxt/async_support/currencycom.py +3 -4
  33. ccxt/async_support/defx.py +6 -7
  34. ccxt/async_support/deribit.py +1 -3
  35. ccxt/async_support/digifinex.py +0 -1
  36. ccxt/async_support/ellipx.py +0 -2
  37. ccxt/async_support/exmo.py +1 -2
  38. ccxt/async_support/gate.py +1 -2
  39. ccxt/async_support/gemini.py +4 -5
  40. ccxt/async_support/hashkey.py +79 -67
  41. ccxt/async_support/hitbtc.py +47 -5
  42. ccxt/async_support/hollaex.py +4 -6
  43. ccxt/async_support/htx.py +1 -3
  44. ccxt/async_support/huobijp.py +0 -1
  45. ccxt/async_support/idex.py +8 -8
  46. ccxt/async_support/independentreserve.py +0 -1
  47. ccxt/async_support/indodax.py +0 -1
  48. ccxt/async_support/kraken.py +63 -3
  49. ccxt/async_support/krakenfutures.py +75 -3
  50. ccxt/async_support/kucoin.py +1 -3
  51. ccxt/async_support/kucoinfutures.py +10 -9
  52. ccxt/async_support/kuna.py +1 -3
  53. ccxt/async_support/latoken.py +1 -3
  54. ccxt/async_support/lbank.py +0 -1
  55. ccxt/async_support/luno.py +0 -1
  56. ccxt/async_support/lykke.py +0 -1
  57. ccxt/async_support/mercado.py +0 -1
  58. ccxt/async_support/mexc.py +3 -4
  59. ccxt/async_support/ndax.py +1 -1
  60. ccxt/async_support/novadax.py +4 -6
  61. ccxt/async_support/oceanex.py +0 -1
  62. ccxt/async_support/okcoin.py +1 -3
  63. ccxt/async_support/okx.py +1 -3
  64. ccxt/async_support/onetrading.py +1 -3
  65. ccxt/async_support/p2b.py +1 -1
  66. ccxt/async_support/paradex.py +5 -7
  67. ccxt/async_support/phemex.py +8 -10
  68. ccxt/async_support/poloniex.py +1 -3
  69. ccxt/async_support/poloniexfutures.py +6 -6
  70. ccxt/async_support/probit.py +0 -1
  71. ccxt/async_support/timex.py +0 -1
  72. ccxt/async_support/tokocrypto.py +11 -14
  73. ccxt/async_support/tradeogre.py +1 -1
  74. ccxt/async_support/upbit.py +0 -1
  75. ccxt/async_support/wavesexchange.py +4 -5
  76. ccxt/async_support/whitebit.py +8 -9
  77. ccxt/async_support/woo.py +98 -12
  78. ccxt/async_support/woofipro.py +96 -15
  79. ccxt/async_support/xt.py +3 -2
  80. ccxt/async_support/yobit.py +0 -1
  81. ccxt/async_support/zaif.py +0 -1
  82. ccxt/async_support/zonda.py +1 -2
  83. ccxt/base/exchange.py +21 -17
  84. ccxt/bigone.py +0 -1
  85. ccxt/binance.py +3 -0
  86. ccxt/bingx.py +2 -0
  87. ccxt/bitfinex.py +122 -0
  88. ccxt/blofin.py +16 -7
  89. ccxt/cex.py +1 -1
  90. ccxt/coinbase.py +8 -9
  91. ccxt/coinbaseexchange.py +5 -6
  92. ccxt/coinbaseinternational.py +7 -8
  93. ccxt/coincatch.py +0 -1
  94. ccxt/coincheck.py +0 -1
  95. ccxt/coinex.py +91 -6
  96. ccxt/coinlist.py +3 -4
  97. ccxt/coinmate.py +1 -3
  98. ccxt/coinmetro.py +4 -5
  99. ccxt/coinone.py +0 -1
  100. ccxt/coinsph.py +7 -8
  101. ccxt/cryptocom.py +3 -0
  102. ccxt/currencycom.py +3 -4
  103. ccxt/defx.py +6 -7
  104. ccxt/deribit.py +1 -3
  105. ccxt/digifinex.py +0 -1
  106. ccxt/ellipx.py +0 -2
  107. ccxt/exmo.py +1 -2
  108. ccxt/gate.py +1 -2
  109. ccxt/gemini.py +4 -5
  110. ccxt/hashkey.py +79 -67
  111. ccxt/hitbtc.py +47 -5
  112. ccxt/hollaex.py +4 -6
  113. ccxt/htx.py +1 -3
  114. ccxt/huobijp.py +0 -1
  115. ccxt/idex.py +8 -8
  116. ccxt/independentreserve.py +0 -1
  117. ccxt/indodax.py +0 -1
  118. ccxt/kraken.py +63 -3
  119. ccxt/krakenfutures.py +75 -3
  120. ccxt/kucoin.py +1 -3
  121. ccxt/kucoinfutures.py +10 -9
  122. ccxt/kuna.py +1 -3
  123. ccxt/latoken.py +1 -3
  124. ccxt/lbank.py +0 -1
  125. ccxt/luno.py +0 -1
  126. ccxt/lykke.py +0 -1
  127. ccxt/mercado.py +0 -1
  128. ccxt/mexc.py +3 -4
  129. ccxt/ndax.py +1 -1
  130. ccxt/novadax.py +4 -6
  131. ccxt/oceanex.py +0 -1
  132. ccxt/okcoin.py +1 -3
  133. ccxt/okx.py +1 -3
  134. ccxt/onetrading.py +1 -3
  135. ccxt/p2b.py +1 -1
  136. ccxt/paradex.py +5 -7
  137. ccxt/phemex.py +8 -10
  138. ccxt/poloniex.py +1 -3
  139. ccxt/poloniexfutures.py +6 -6
  140. ccxt/pro/__init__.py +1 -1
  141. ccxt/probit.py +0 -1
  142. ccxt/timex.py +0 -1
  143. ccxt/tokocrypto.py +11 -14
  144. ccxt/tradeogre.py +1 -1
  145. ccxt/upbit.py +0 -1
  146. ccxt/wavesexchange.py +4 -5
  147. ccxt/whitebit.py +8 -9
  148. ccxt/woo.py +98 -12
  149. ccxt/woofipro.py +96 -15
  150. ccxt/xt.py +3 -2
  151. ccxt/yobit.py +0 -1
  152. ccxt/zaif.py +0 -1
  153. ccxt/zonda.py +1 -2
  154. {ccxt-4.4.41.dist-info → ccxt-4.4.42.dist-info}/METADATA +5 -5
  155. {ccxt-4.4.41.dist-info → ccxt-4.4.42.dist-info}/RECORD +158 -162
  156. ccxt/bitbay.py +0 -17
  157. ccxt/bitfinex2.py +0 -3624
  158. ccxt/hitbtc3.py +0 -16
  159. ccxt/pro/bitfinex2.py +0 -1086
  160. {ccxt-4.4.41.dist-info → ccxt-4.4.42.dist-info}/LICENSE.txt +0 -0
  161. {ccxt-4.4.41.dist-info → ccxt-4.4.42.dist-info}/WHEEL +0 -0
  162. {ccxt-4.4.41.dist-info → ccxt-4.4.42.dist-info}/top_level.txt +0 -0
ccxt/pro/bitfinex2.py DELETED
@@ -1,1086 +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
- import hashlib
9
- from ccxt.base.types import Balances, Int, Order, OrderBook, Str, Ticker, Trade
10
- from ccxt.async_support.base.ws.client import Client
11
- from typing import List
12
- from ccxt.base.errors import ExchangeError
13
- from ccxt.base.errors import AuthenticationError
14
- from ccxt.base.errors import ChecksumError
15
- from ccxt.base.precise import Precise
16
-
17
-
18
- class bitfinex2(ccxt.async_support.bitfinex2):
19
-
20
- def describe(self):
21
- return self.deep_extend(super(bitfinex2, self).describe(), {
22
- 'has': {
23
- 'ws': True,
24
- 'watchTicker': True,
25
- 'watchTickers': False,
26
- 'watchOrderBook': True,
27
- 'watchTrades': True,
28
- 'watchTradesForSymbols': False,
29
- 'watchMyTrades': True,
30
- 'watchBalance': True,
31
- 'watchOHLCV': True,
32
- 'watchOrders': True,
33
- },
34
- 'urls': {
35
- 'api': {
36
- 'ws': {
37
- 'public': 'wss://api-pub.bitfinex.com/ws/2',
38
- 'private': 'wss://api.bitfinex.com/ws/2',
39
- },
40
- },
41
- },
42
- 'options': {
43
- 'watchOrderBook': {
44
- 'prec': 'P0',
45
- 'freq': 'F0',
46
- 'checksum': True,
47
- },
48
- 'ordersLimit': 1000,
49
- },
50
- })
51
-
52
- async def subscribe(self, channel, symbol, params={}):
53
- await self.load_markets()
54
- market = self.market(symbol)
55
- marketId = market['id']
56
- url = self.urls['api']['ws']['public']
57
- client = self.client(url)
58
- messageHash = channel + ':' + marketId
59
- request: dict = {
60
- 'event': 'subscribe',
61
- 'channel': channel,
62
- 'symbol': marketId,
63
- }
64
- result = await self.watch(url, messageHash, self.deep_extend(request, params), messageHash, {'checksum': False})
65
- checksum = self.safe_bool(self.options, 'checksum', True)
66
- if checksum and not client.subscriptions[messageHash]['checksum'] and (channel == 'book'):
67
- client.subscriptions[messageHash]['checksum'] = True
68
- await client.send({
69
- 'event': 'conf',
70
- 'flags': 131072,
71
- })
72
- return result
73
-
74
- async def subscribe_private(self, messageHash):
75
- await self.load_markets()
76
- await self.authenticate()
77
- url = self.urls['api']['ws']['private']
78
- return await self.watch(url, messageHash, None, 1)
79
-
80
- async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
81
- """
82
- watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
83
- :param str symbol: unified symbol of the market to fetch OHLCV data for
84
- :param str timeframe: the length of time each candle represents
85
- :param int [since]: timestamp in ms of the earliest candle to fetch
86
- :param int [limit]: the maximum amount of candles to fetch
87
- :param dict [params]: extra parameters specific to the exchange API endpoint
88
- :returns int[][]: A list of candles ordered, open, high, low, close, volume
89
- """
90
- await self.load_markets()
91
- market = self.market(symbol)
92
- symbol = market['symbol']
93
- interval = self.safe_string(self.timeframes, timeframe, timeframe)
94
- channel = 'candles'
95
- key = 'trade:' + interval + ':' + market['id']
96
- messageHash = channel + ':' + interval + ':' + market['id']
97
- request: dict = {
98
- 'event': 'subscribe',
99
- 'channel': channel,
100
- 'key': key,
101
- }
102
- url = self.urls['api']['ws']['public']
103
- # not using subscribe here because self message has a different format
104
- ohlcv = await self.watch(url, messageHash, self.deep_extend(request, params), messageHash)
105
- if self.newUpdates:
106
- limit = ohlcv.getLimit(symbol, limit)
107
- return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
108
-
109
- def handle_ohlcv(self, client: Client, message, subscription):
110
- #
111
- # initial snapshot
112
- # [
113
- # 341527, # channel id
114
- # [
115
- # [
116
- # 1654705860000, # timestamp
117
- # 1802.6, # open
118
- # 1800.3, # close
119
- # 1802.8, # high
120
- # 1800.3, # low
121
- # 86.49588236 # volume
122
- # ],
123
- # [
124
- # 1654705800000,
125
- # 1803.6,
126
- # 1802.6,
127
- # 1804.9,
128
- # 1802.3,
129
- # 74.6348086
130
- # ],
131
- # [
132
- # 1654705740000,
133
- # 1802.5,
134
- # 1803.2,
135
- # 1804.4,
136
- # 1802.4,
137
- # 23.61801085
138
- # ]
139
- # ]
140
- # ]
141
- #
142
- # update
143
- # [
144
- # 211171,
145
- # [
146
- # 1654705680000,
147
- # 1801,
148
- # 1802.4,
149
- # 1802.9,
150
- # 1800.4,
151
- # 23.91911091
152
- # ]
153
- # ]
154
- #
155
- data = self.safe_value(message, 1, [])
156
- ohlcvs = None
157
- first = self.safe_value(data, 0)
158
- if isinstance(first, list):
159
- # snapshot
160
- ohlcvs = data
161
- else:
162
- # update
163
- ohlcvs = [data]
164
- channel = self.safe_value(subscription, 'channel')
165
- key = self.safe_string(subscription, 'key')
166
- keyParts = key.split(':')
167
- interval = self.safe_string(keyParts, 1)
168
- marketId = key
169
- marketId = marketId.replace('trade:', '')
170
- marketId = marketId.replace(interval + ':', '')
171
- market = self.safe_market(marketId)
172
- timeframe = self.find_timeframe(interval)
173
- symbol = market['symbol']
174
- messageHash = channel + ':' + interval + ':' + marketId
175
- self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
176
- stored = self.safe_value(self.ohlcvs[symbol], timeframe)
177
- if stored is None:
178
- limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
179
- stored = ArrayCacheByTimestamp(limit)
180
- self.ohlcvs[symbol][timeframe] = stored
181
- ohlcvsLength = len(ohlcvs)
182
- for i in range(0, ohlcvsLength):
183
- ohlcv = ohlcvs[ohlcvsLength - i - 1]
184
- parsed = self.parse_ohlcv(ohlcv, market)
185
- stored.append(parsed)
186
- client.resolve(stored, messageHash)
187
-
188
- async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
189
- """
190
- get the list of most recent trades for a particular symbol
191
- :param str symbol: unified symbol of the market to fetch trades for
192
- :param int [since]: timestamp in ms of the earliest trade to fetch
193
- :param int [limit]: the maximum amount of trades to fetch
194
- :param dict [params]: extra parameters specific to the exchange API endpoint
195
- :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
196
- """
197
- trades = await self.subscribe('trades', symbol, params)
198
- if self.newUpdates:
199
- limit = trades.getLimit(symbol, limit)
200
- return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
201
-
202
- async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
203
- """
204
- watches information on multiple trades made by the user
205
- :param str symbol: unified market symbol of the market trades were made in
206
- :param int [since]: the earliest time in ms to fetch trades for
207
- :param int [limit]: the maximum number of trade structures to retrieve
208
- :param dict [params]: extra parameters specific to the exchange API endpoint
209
- :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
210
- """
211
- await self.load_markets()
212
- messageHash = 'myTrade'
213
- if symbol is not None:
214
- market = self.market(symbol)
215
- messageHash += ':' + market['id']
216
- trades = await self.subscribe_private(messageHash)
217
- if self.newUpdates:
218
- limit = trades.getLimit(symbol, limit)
219
- return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
220
-
221
- async def watch_ticker(self, symbol: str, params={}) -> Ticker:
222
- """
223
- watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
224
- :param str symbol: unified symbol of the market to fetch the ticker for
225
- :param dict [params]: extra parameters specific to the exchange API endpoint
226
- :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
227
- """
228
- return await self.subscribe('ticker', symbol, params)
229
-
230
- def handle_my_trade(self, client: Client, message, subscription={}):
231
- #
232
- # trade execution
233
- # [
234
- # 0,
235
- # "te", # or tu
236
- # [
237
- # 1133411090,
238
- # "tLTCUST",
239
- # 1655110144598,
240
- # 97084883506,
241
- # 0.1,
242
- # 42.821,
243
- # "EXCHANGE MARKET",
244
- # 42.799,
245
- # -1,
246
- # null,
247
- # null,
248
- # 1655110144596
249
- # ]
250
- # ]
251
- #
252
- name = 'myTrade'
253
- data = self.safe_value(message, 2)
254
- trade = self.parse_ws_trade(data)
255
- symbol = trade['symbol']
256
- market = self.market(symbol)
257
- messageHash = name + ':' + market['id']
258
- if self.myTrades is None:
259
- limit = self.safe_integer(self.options, 'tradesLimit', 1000)
260
- self.myTrades = ArrayCacheBySymbolById(limit)
261
- tradesArray = self.myTrades
262
- tradesArray.append(trade)
263
- self.myTrades = tradesArray
264
- # generic subscription
265
- client.resolve(tradesArray, name)
266
- # specific subscription
267
- client.resolve(tradesArray, messageHash)
268
-
269
- def handle_trades(self, client: Client, message, subscription):
270
- #
271
- # initial snapshot
272
- #
273
- # [
274
- # 188687, # channel id
275
- # [
276
- # [1128060675, 1654701572690, 0.00217533, 1815.3], # id, mts, amount, price
277
- # [1128060665, 1654701551231, -0.00280472, 1814.1],
278
- # [1128060664, 1654701550996, -0.00364444, 1814.1],
279
- # [1128060656, 1654701527730, -0.00265203, 1814.2],
280
- # [1128060647, 1654701505193, 0.00262395, 1815.2],
281
- # [1128060642, 1654701484656, -0.13411443, 1816],
282
- # [1128060641, 1654701484656, -0.00088557, 1816],
283
- # [1128060639, 1654701478326, -0.002, 1816],
284
- # ]
285
- # ]
286
- # update
287
- #
288
- # [
289
- # 360141,
290
- # "te",
291
- # [
292
- # 1128060969, # id
293
- # 1654702500098, # mts
294
- # 0.00325131, # amount positive buy, negative sell
295
- # 1818.5, # price
296
- # ],
297
- # ]
298
- #
299
- #
300
- channel = self.safe_value(subscription, 'channel')
301
- marketId = self.safe_string(subscription, 'symbol')
302
- market = self.safe_market(marketId)
303
- messageHash = channel + ':' + marketId
304
- tradesLimit = self.safe_integer(self.options, 'tradesLimit', 1000)
305
- symbol = market['symbol']
306
- stored = self.safe_value(self.trades, symbol)
307
- if stored is None:
308
- stored = ArrayCache(tradesLimit)
309
- self.trades[symbol] = stored
310
- messageLength = len(message)
311
- if messageLength == 2:
312
- # initial snapshot
313
- trades = self.safe_list(message, 1, [])
314
- # needs to be reversed to make chronological order
315
- length = len(trades)
316
- for i in range(0, length):
317
- index = length - i - 1
318
- parsed = self.parse_ws_trade(trades[index], market)
319
- stored.append(parsed)
320
- else:
321
- # update
322
- type = self.safe_string(message, 1)
323
- if type == 'tu':
324
- # don't resolve for a duplicate update
325
- # since te and tu updates are duplicated on the public stream
326
- return
327
- trade = self.safe_value(message, 2, [])
328
- parsed = self.parse_ws_trade(trade, market)
329
- stored.append(parsed)
330
- client.resolve(stored, messageHash)
331
-
332
- def parse_ws_trade(self, trade, market=None):
333
- #
334
- # [
335
- # 1128060969, # id
336
- # 1654702500098, # mts
337
- # 0.00325131, # amount positive buy, negative sell
338
- # 1818.5, # price
339
- # ]
340
- #
341
- # trade execution
342
- #
343
- # [
344
- # 1133411090, # id
345
- # "tLTCUST", # symbol
346
- # 1655110144598, # create ms
347
- # 97084883506, # order id
348
- # 0.1, # amount
349
- # 42.821, # price
350
- # "EXCHANGE MARKET", # order type
351
- # 42.799, # order price
352
- # -1, # maker
353
- # null, # fee
354
- # null, # fee currency
355
- # 1655110144596 # cid
356
- # ]
357
- #
358
- # trade update
359
- #
360
- # [
361
- # 1133411090,
362
- # "tLTCUST",
363
- # 1655110144598,
364
- # 97084883506,
365
- # 0.1,
366
- # 42.821,
367
- # "EXCHANGE MARKET",
368
- # 42.799,
369
- # -1,
370
- # -0.0002,
371
- # "LTC",
372
- # 1655110144596
373
- # ]
374
- #
375
- numFields = len(trade)
376
- isPublic = numFields <= 8
377
- marketId = self.safe_string(trade, 1) if (not isPublic) else None
378
- market = self.safe_market(marketId, market)
379
- createdKey = 1 if isPublic else 2
380
- priceKey = 3 if isPublic else 5
381
- amountKey = 2 if isPublic else 4
382
- marketId = market['id']
383
- type = self.safe_string(trade, 6)
384
- if type is not None:
385
- if type.find('LIMIT') > -1:
386
- type = 'limit'
387
- elif type.find('MARKET') > -1:
388
- type = 'market'
389
- orderId = self.safe_string(trade, 3) if (not isPublic) else None
390
- id = self.safe_string(trade, 0)
391
- timestamp = self.safe_integer(trade, createdKey)
392
- price = self.safe_string(trade, priceKey)
393
- amountString = self.safe_string(trade, amountKey)
394
- amount = self.parse_number(Precise.string_abs(amountString))
395
- side = None
396
- if amount is not None:
397
- side = 'buy' if Precise.string_gt(amountString, '0') else 'sell'
398
- symbol = self.safe_symbol(marketId, market)
399
- feeValue = self.safe_string(trade, 9)
400
- fee = None
401
- if feeValue is not None:
402
- currencyId = self.safe_string(trade, 10)
403
- code = self.safe_currency_code(currencyId)
404
- fee = {
405
- 'cost': feeValue,
406
- 'currency': code,
407
- }
408
- maker = self.safe_integer(trade, 8)
409
- takerOrMaker = None
410
- if maker is not None:
411
- takerOrMaker = 'taker' if (maker == -1) else 'maker'
412
- return self.safe_trade({
413
- 'info': trade,
414
- 'timestamp': timestamp,
415
- 'datetime': self.iso8601(timestamp),
416
- 'symbol': symbol,
417
- 'id': id,
418
- 'order': orderId,
419
- 'type': type,
420
- 'takerOrMaker': takerOrMaker,
421
- 'side': side,
422
- 'price': price,
423
- 'amount': amount,
424
- 'cost': None,
425
- 'fee': fee,
426
- }, market)
427
-
428
- def handle_ticker(self, client: Client, message, subscription):
429
- #
430
- # [
431
- # 340432, # channel ID
432
- # [
433
- # 236.62, # 1 BID float Price of last highest bid
434
- # 9.0029, # 2 BID_SIZE float Size of the last highest bid
435
- # 236.88, # 3 ASK float Price of last lowest ask
436
- # 7.1138, # 4 ASK_SIZE float Size of the last lowest ask
437
- # -1.02, # 5 DAILY_CHANGE float Amount that the last price has changed since yesterday
438
- # 0, # 6 DAILY_CHANGE_PERC float Amount that the price has changed expressed in percentage terms
439
- # 236.52, # 7 LAST_PRICE float Price of the last trade.
440
- # 5191.36754297, # 8 VOLUME float Daily volume
441
- # 250.01, # 9 HIGH float Daily high
442
- # 220.05, # 10 LOW float Daily low
443
- # ]
444
- # ]
445
- #
446
- ticker = self.safe_value(message, 1)
447
- marketId = self.safe_string(subscription, 'symbol')
448
- market = self.safe_market(marketId)
449
- symbol = self.safe_symbol(marketId)
450
- parsed = self.parse_ws_ticker(ticker, market)
451
- channel = 'ticker'
452
- messageHash = channel + ':' + marketId
453
- self.tickers[symbol] = parsed
454
- client.resolve(parsed, messageHash)
455
-
456
- def parse_ws_ticker(self, ticker, market=None):
457
- #
458
- # [
459
- # 236.62, # 1 BID float Price of last highest bid
460
- # 9.0029, # 2 BID_SIZE float Size of the last highest bid
461
- # 236.88, # 3 ASK float Price of last lowest ask
462
- # 7.1138, # 4 ASK_SIZE float Size of the last lowest ask
463
- # -1.02, # 5 DAILY_CHANGE float Amount that the last price has changed since yesterday
464
- # 0, # 6 DAILY_CHANGE_PERC float Amount that the price has changed expressed in percentage terms
465
- # 236.52, # 7 LAST_PRICE float Price of the last trade.
466
- # 5191.36754297, # 8 VOLUME float Daily volume
467
- # 250.01, # 9 HIGH float Daily high
468
- # 220.05, # 10 LOW float Daily low
469
- # ]
470
- #
471
- market = self.safe_market(None, market)
472
- symbol = market['symbol']
473
- last = self.safe_string(ticker, 6)
474
- change = self.safe_string(ticker, 4)
475
- return self.safe_ticker({
476
- 'symbol': symbol,
477
- 'timestamp': None,
478
- 'datetime': None,
479
- 'high': self.safe_string(ticker, 8),
480
- 'low': self.safe_string(ticker, 9),
481
- 'bid': self.safe_string(ticker, 0),
482
- 'bidVolume': self.safe_string(ticker, 1),
483
- 'ask': self.safe_string(ticker, 2),
484
- 'askVolume': self.safe_string(ticker, 3),
485
- 'vwap': None,
486
- 'open': None,
487
- 'close': last,
488
- 'last': last,
489
- 'previousClose': None,
490
- 'change': change,
491
- 'percentage': self.safe_string(ticker, 5),
492
- 'average': None,
493
- 'baseVolume': self.safe_string(ticker, 7),
494
- 'quoteVolume': None,
495
- 'info': ticker,
496
- }, market)
497
-
498
- async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
499
- """
500
- watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
501
- :param str symbol: unified symbol of the market to fetch the order book for
502
- :param int [limit]: the maximum amount of order book entries to return
503
- :param dict [params]: extra parameters specific to the exchange API endpoint
504
- :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
505
- """
506
- if limit is not None:
507
- if (limit != 25) and (limit != 100):
508
- raise ExchangeError(self.id + ' watchOrderBook limit argument must be None, 25 or 100')
509
- options = self.safe_value(self.options, 'watchOrderBook', {})
510
- prec = self.safe_string(options, 'prec', 'P0')
511
- freq = self.safe_string(options, 'freq', 'F0')
512
- request: dict = {
513
- 'prec': prec, # string, level of price aggregation, 'P0', 'P1', 'P2', 'P3', 'P4', default P0
514
- 'freq': freq, # string, frequency of updates 'F0' = realtime, 'F1' = 2 seconds, default is 'F0'
515
- }
516
- if limit is not None:
517
- request['len'] = limit # string, number of price points, '25', '100', default = '25'
518
- orderbook = await self.subscribe('book', symbol, self.deep_extend(request, params))
519
- return orderbook.limit()
520
-
521
- def handle_order_book(self, client: Client, message, subscription):
522
- #
523
- # first message(snapshot)
524
- #
525
- # [
526
- # 18691, # channel id
527
- # [
528
- # [7364.8, 10, 4.354802], # price, count, size > 0 = bid
529
- # [7364.7, 1, 0.00288831],
530
- # [7364.3, 12, 0.048],
531
- # [7364.9, 3, -0.42028976], # price, count, size < 0 = ask
532
- # [7365, 1, -0.25],
533
- # [7365.5, 1, -0.00371937],
534
- # ]
535
- # ]
536
- #
537
- # subsequent updates
538
- #
539
- # [
540
- # 358169, # channel id
541
- # [
542
- # 1807.1, # price
543
- # 0, # cound
544
- # 1 # size
545
- # ]
546
- # ]
547
- #
548
- marketId = self.safe_string(subscription, 'symbol')
549
- symbol = self.safe_symbol(marketId)
550
- channel = 'book'
551
- messageHash = channel + ':' + marketId
552
- prec = self.safe_string(subscription, 'prec', 'P0')
553
- isRaw = (prec == 'R0')
554
- # if it is an initial snapshot
555
- if not (symbol in self.orderbooks):
556
- limit = self.safe_integer(subscription, 'len')
557
- if isRaw:
558
- # raw order books
559
- self.orderbooks[symbol] = self.indexed_order_book({}, limit)
560
- else:
561
- # P0, P1, P2, P3, P4
562
- self.orderbooks[symbol] = self.counted_order_book({}, limit)
563
- orderbook = self.orderbooks[symbol]
564
- if isRaw:
565
- deltas = message[1]
566
- for i in range(0, len(deltas)):
567
- delta = deltas[i]
568
- delta2 = delta[2]
569
- size = -delta2 if (delta2 < 0) else delta2
570
- side = 'asks' if (delta2 < 0) else 'bids'
571
- bookside = orderbook[side]
572
- idString = self.safe_string(delta, 0)
573
- price = self.safe_float(delta, 1)
574
- bookside.storeArray([price, size, idString])
575
- else:
576
- deltas = message[1]
577
- for i in range(0, len(deltas)):
578
- delta = deltas[i]
579
- amount = self.safe_number(delta, 2)
580
- counter = self.safe_number(delta, 1)
581
- price = self.safe_number(delta, 0)
582
- size = -amount if (amount < 0) else amount
583
- side = 'asks' if (amount < 0) else 'bids'
584
- bookside = orderbook[side]
585
- bookside.storeArray([price, size, counter])
586
- orderbook['symbol'] = symbol
587
- client.resolve(orderbook, messageHash)
588
- else:
589
- orderbook = self.orderbooks[symbol]
590
- deltas = message[1]
591
- orderbookItem = self.orderbooks[symbol]
592
- if isRaw:
593
- price = self.safe_string(deltas, 1)
594
- deltas2 = deltas[2]
595
- size = -deltas2 if (deltas2 < 0) else deltas2
596
- side = 'asks' if (deltas2 < 0) else 'bids'
597
- bookside = orderbookItem[side]
598
- # price = 0 means that you have to remove the order from your book
599
- amount = size if Precise.string_gt(price, '0') else '0'
600
- idString = self.safe_string(deltas, 0)
601
- bookside.storeArray([self.parse_number(price), self.parse_number(amount), idString])
602
- else:
603
- amount = self.safe_string(deltas, 2)
604
- counter = self.safe_string(deltas, 1)
605
- price = self.safe_string(deltas, 0)
606
- size = Precise.string_neg(amount) if Precise.string_lt(amount, '0') else amount
607
- side = 'asks' if Precise.string_lt(amount, '0') else 'bids'
608
- bookside = orderbookItem[side]
609
- bookside.storeArray([self.parse_number(price), self.parse_number(size), self.parse_number(counter)])
610
- client.resolve(orderbook, messageHash)
611
-
612
- def handle_checksum(self, client: Client, message, subscription):
613
- #
614
- # [173904, "cs", -890884919]
615
- #
616
- marketId = self.safe_string(subscription, 'symbol')
617
- symbol = self.safe_symbol(marketId)
618
- channel = 'book'
619
- messageHash = channel + ':' + marketId
620
- book = self.safe_value(self.orderbooks, symbol)
621
- if book is None:
622
- return
623
- depth = 25 # covers the first 25 bids and asks
624
- stringArray = []
625
- bids = book['bids']
626
- asks = book['asks']
627
- prec = self.safe_string(subscription, 'prec', 'P0')
628
- isRaw = (prec == 'R0')
629
- idToCheck = 2 if isRaw else 0
630
- # pepperoni pizza from bitfinex
631
- for i in range(0, depth):
632
- bid = self.safe_value(bids, i)
633
- ask = self.safe_value(asks, i)
634
- if bid is not None:
635
- stringArray.append(self.number_to_string(bids[i][idToCheck]))
636
- stringArray.append(self.number_to_string(bids[i][1]))
637
- if ask is not None:
638
- stringArray.append(self.number_to_string(asks[i][idToCheck]))
639
- aski1 = asks[i][1]
640
- stringArray.append(self.number_to_string(-aski1))
641
- payload = ':'.join(stringArray)
642
- localChecksum = self.crc32(payload, True)
643
- responseChecksum = self.safe_integer(message, 2)
644
- if responseChecksum != localChecksum:
645
- del client.subscriptions[messageHash]
646
- del self.orderbooks[symbol]
647
- checksum = self.handle_option('watchOrderBook', 'checksum', True)
648
- if checksum:
649
- error = ChecksumError(self.id + ' ' + self.orderbook_checksum_message(symbol))
650
- client.reject(error, messageHash)
651
-
652
- async def watch_balance(self, params={}) -> Balances:
653
- """
654
- watch balance and get the amount of funds available for trading or funds locked in orders
655
- :param dict [params]: extra parameters specific to the exchange API endpoint
656
- :param str [params.type]: spot or contract if not provided self.options['defaultType'] is used
657
- :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
658
- """
659
- await self.load_markets()
660
- balanceType = self.safe_string(params, 'wallet', 'exchange') # exchange, margin
661
- params = self.omit(params, 'wallet')
662
- messageHash = 'balance:' + balanceType
663
- return await self.subscribe_private(messageHash)
664
-
665
- def handle_balance(self, client: Client, message, subscription):
666
- #
667
- # snapshot(exchange + margin together)
668
- # [
669
- # 0,
670
- # "ws",
671
- # [
672
- # [
673
- # "exchange",
674
- # "LTC",
675
- # 0.05479727,
676
- # 0,
677
- # null,
678
- # "Trading fees for 0.05 LTC(LTCUST) @ 51.872 on BFX(0.2%)",
679
- # null,
680
- # ]
681
- # [
682
- # "margin",
683
- # "USTF0",
684
- # 11.960650700086292,
685
- # 0,
686
- # null,
687
- # "Trading fees for 0.1 LTCF0(LTCF0:USTF0) @ 51.844 on BFX(0.065%)",
688
- # null,
689
- # ],
690
- # ],
691
- # ]
692
- #
693
- # spot
694
- # [
695
- # 0,
696
- # "wu",
697
- # [
698
- # "exchange",
699
- # "LTC", # currency
700
- # 0.06729727, # wallet balance
701
- # 0, # unsettled balance
702
- # 0.06729727, # available balance might be null
703
- # "Exchange 0.4 LTC for UST @ 65.075",
704
- # {
705
- # "reason": "TRADE",
706
- # "order_id": 96596397973,
707
- # "order_id_oppo": 96596632735,
708
- # "trade_price": "65.075",
709
- # "trade_amount": "-0.4",
710
- # "order_cid": 1654636218766,
711
- # "order_gid": null
712
- # }
713
- # ]
714
- # ]
715
- #
716
- # margin
717
- #
718
- # [
719
- # "margin",
720
- # "USTF0",
721
- # 11.960650700086292, # total
722
- # 0,
723
- # 6.776250700086292, # available
724
- # "Trading fees for 0.1 LTCF0(LTCF0:USTF0) @ 51.844 on BFX(0.065%)",
725
- # null
726
- # ]
727
- #
728
- updateType = self.safe_value(message, 1)
729
- data = None
730
- if updateType == 'ws':
731
- data = self.safe_value(message, 2)
732
- else:
733
- data = [self.safe_value(message, 2)]
734
- updatedTypes: dict = {}
735
- for i in range(0, len(data)):
736
- rawBalance = data[i]
737
- currencyId = self.safe_string(rawBalance, 1)
738
- code = self.safe_currency_code(currencyId)
739
- balance = self.parse_ws_balance(rawBalance)
740
- balanceType = self.safe_string(rawBalance, 0)
741
- oldBalance = self.safe_value(self.balance, balanceType, {})
742
- oldBalance[code] = balance
743
- oldBalance['info'] = message
744
- self.balance[balanceType] = self.safe_balance(oldBalance)
745
- updatedTypes[balanceType] = True
746
- updatesKeys = list(updatedTypes.keys())
747
- for i in range(0, len(updatesKeys)):
748
- type = updatesKeys[i]
749
- messageHash = 'balance:' + type
750
- client.resolve(self.balance[type], messageHash)
751
-
752
- def parse_ws_balance(self, balance):
753
- #
754
- # [
755
- # "exchange",
756
- # "LTC",
757
- # 0.05479727, # balance
758
- # 0,
759
- # null, # available null if not calculated yet
760
- # "Trading fees for 0.05 LTC(LTCUST) @ 51.872 on BFX(0.2%)",
761
- # null,
762
- # ]
763
- #
764
- totalBalance = self.safe_string(balance, 2)
765
- availableBalance = self.safe_string(balance, 4)
766
- account = self.account()
767
- if availableBalance is not None:
768
- account['free'] = availableBalance
769
- account['total'] = totalBalance
770
- return account
771
-
772
- def handle_system_status(self, client: Client, message):
773
- #
774
- # {
775
- # "event": "info",
776
- # "version": 2,
777
- # "serverId": "e293377e-7bb7-427e-b28c-5db045b2c1d1",
778
- # "platform": {status: 1}, # 1 for operative, 0 for maintenance
779
- # }
780
- #
781
- return message
782
-
783
- def handle_subscription_status(self, client: Client, message):
784
- #
785
- # {
786
- # "event": "subscribed",
787
- # "channel": "book",
788
- # "chanId": 67473,
789
- # "symbol": "tBTCUSD",
790
- # "prec": "P0",
791
- # "freq": "F0",
792
- # "len": "25",
793
- # "pair": "BTCUSD"
794
- # }
795
- #
796
- channelId = self.safe_string(message, 'chanId')
797
- client.subscriptions[channelId] = message
798
- return message
799
-
800
- async def authenticate(self, params={}):
801
- url = self.urls['api']['ws']['private']
802
- client = self.client(url)
803
- messageHash = 'authenticated'
804
- future = client.future(messageHash)
805
- authenticated = self.safe_value(client.subscriptions, messageHash)
806
- if authenticated is None:
807
- nonce = self.milliseconds()
808
- payload = 'AUTH' + str(nonce)
809
- signature = self.hmac(self.encode(payload), self.encode(self.secret), hashlib.sha384, 'hex')
810
- event = 'auth'
811
- request: dict = {
812
- 'apiKey': self.apiKey,
813
- 'authSig': signature,
814
- 'authNonce': nonce,
815
- 'authPayload': payload,
816
- 'event': event,
817
- }
818
- message = self.extend(request, params)
819
- self.watch(url, messageHash, message, messageHash)
820
- return await future
821
-
822
- def handle_authentication_message(self, client: Client, message):
823
- messageHash = 'authenticated'
824
- status = self.safe_string(message, 'status')
825
- if status == 'OK':
826
- # we resolve the future here permanently so authentication only happens once
827
- future = self.safe_value(client.futures, messageHash)
828
- future.resolve(True)
829
- else:
830
- error = AuthenticationError(self.json(message))
831
- client.reject(error, messageHash)
832
- # allows further authentication attempts
833
- if messageHash in client.subscriptions:
834
- del client.subscriptions[messageHash]
835
-
836
- async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
837
- """
838
- watches information on multiple orders made by the user
839
- :param str symbol: unified market symbol of the market orders were made in
840
- :param int [since]: the earliest time in ms to fetch orders for
841
- :param int [limit]: the maximum number of order structures to retrieve
842
- :param dict [params]: extra parameters specific to the exchange API endpoint
843
- :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
844
- """
845
- await self.load_markets()
846
- messageHash = 'orders'
847
- if symbol is not None:
848
- market = self.market(symbol)
849
- messageHash += ':' + market['id']
850
- orders = await self.subscribe_private(messageHash)
851
- if self.newUpdates:
852
- limit = orders.getLimit(symbol, limit)
853
- return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
854
-
855
- def handle_orders(self, client: Client, message, subscription):
856
- #
857
- # limit order
858
- # [
859
- # 0,
860
- # "on", # ou or oc
861
- # [
862
- # 96923856256, # order id
863
- # null, # gid
864
- # 1655029337026, # cid
865
- # "tLTCUST", # symbol
866
- # 1655029337027, # created timestamp
867
- # 1655029337029, # updated timestamp
868
- # 0.1, # amount
869
- # 0.1, # amount_orig
870
- # "EXCHANGE LIMIT", # order type
871
- # null, # type_prev
872
- # null, # mts_tif
873
- # null, # placeholder
874
- # 0, # flags
875
- # "ACTIVE", # status
876
- # null,
877
- # null,
878
- # 30, # price
879
- # 0, # price average
880
- # 0, # price_trailling
881
- # 0, # price_aux_limit
882
- # null,
883
- # null,
884
- # null,
885
- # 0, # notify
886
- # 0,
887
- # null,
888
- # null,
889
- # null,
890
- # "BFX",
891
- # null,
892
- # null,
893
- # ]
894
- # ]
895
- #
896
- data = self.safe_value(message, 2, [])
897
- messageType = self.safe_string(message, 1)
898
- if self.orders is None:
899
- limit = self.safe_integer(self.options, 'ordersLimit', 1000)
900
- self.orders = ArrayCacheBySymbolById(limit)
901
- orders = self.orders
902
- symbolIds: dict = {}
903
- if messageType == 'os':
904
- snapshotLength = len(data)
905
- if snapshotLength == 0:
906
- return
907
- for i in range(0, len(data)):
908
- value = data[i]
909
- parsed = self.parse_ws_order(value)
910
- symbol = parsed['symbol']
911
- symbolIds[symbol] = True
912
- orders.append(parsed)
913
- else:
914
- parsed = self.parse_ws_order(data)
915
- orders.append(parsed)
916
- symbol = parsed['symbol']
917
- symbolIds[symbol] = True
918
- name = 'orders'
919
- client.resolve(self.orders, name)
920
- keys = list(symbolIds.keys())
921
- for i in range(0, len(keys)):
922
- symbol = keys[i]
923
- market = self.market(symbol)
924
- messageHash = name + ':' + market['id']
925
- client.resolve(self.orders, messageHash)
926
-
927
- def parse_ws_order_status(self, status):
928
- statuses: dict = {
929
- 'ACTIVE': 'open',
930
- 'CANCELED': 'canceled',
931
- 'EXECUTED': 'closed',
932
- 'PARTIALLY': 'open',
933
- }
934
- return self.safe_string(statuses, status, status)
935
-
936
- def parse_ws_order(self, order, market=None):
937
- #
938
- # [
939
- # 97084883506, # order id
940
- # null,
941
- # 1655110144596, # clientOrderId
942
- # "tLTCUST", # symbol
943
- # 1655110144596, # created timestamp
944
- # 1655110144598, # updated timestamp
945
- # 0, # amount
946
- # 0.1, # amount_orig negative if sell order
947
- # "EXCHANGE MARKET", # type
948
- # null,
949
- # null,
950
- # null,
951
- # 0,
952
- # "EXECUTED @ 42.821(0.1)", # status
953
- # null,
954
- # null,
955
- # 42.799, # price
956
- # 42.821, # price average
957
- # 0, # price trailling
958
- # 0, # price_aux_limit
959
- # null,
960
- # null,
961
- # null,
962
- # 0,
963
- # 0,
964
- # null,
965
- # null,
966
- # null,
967
- # "BFX",
968
- # null,
969
- # null,
970
- # {}
971
- # ]
972
- #
973
- id = self.safe_string(order, 0)
974
- clientOrderId = self.safe_string(order, 1)
975
- marketId = self.safe_string(order, 3)
976
- symbol = self.safe_symbol(marketId)
977
- market = self.safe_market(symbol)
978
- amount = self.safe_string(order, 7)
979
- side = 'buy'
980
- if Precise.string_lt(amount, '0'):
981
- amount = Precise.string_abs(amount)
982
- side = 'sell'
983
- remaining = Precise.string_abs(self.safe_string(order, 6))
984
- type = self.safe_string(order, 8)
985
- if type.find('LIMIT') > -1:
986
- type = 'limit'
987
- elif type.find('MARKET') > -1:
988
- type = 'market'
989
- rawState = self.safe_string(order, 13)
990
- stateParts = rawState.split(' ')
991
- trimmedStatus = self.safe_string(stateParts, 0)
992
- status = self.parse_ws_order_status(trimmedStatus)
993
- price = self.safe_string(order, 16)
994
- timestamp = self.safe_integer_2(order, 5, 4)
995
- average = self.safe_string(order, 17)
996
- stopPrice = self.omit_zero(self.safe_string(order, 18))
997
- return self.safe_order({
998
- 'info': order,
999
- 'id': id,
1000
- 'clientOrderId': clientOrderId,
1001
- 'timestamp': timestamp,
1002
- 'datetime': self.iso8601(timestamp),
1003
- 'lastTradeTimestamp': None,
1004
- 'symbol': symbol,
1005
- 'type': type,
1006
- 'side': side,
1007
- 'price': price,
1008
- 'stopPrice': stopPrice,
1009
- 'triggerPrice': stopPrice,
1010
- 'average': average,
1011
- 'amount': amount,
1012
- 'remaining': remaining,
1013
- 'filled': None,
1014
- 'status': status,
1015
- 'fee': None,
1016
- 'cost': None,
1017
- 'trades': None,
1018
- }, market)
1019
-
1020
- def handle_message(self, client: Client, message):
1021
- channelId = self.safe_string(message, 0)
1022
- #
1023
- # [
1024
- # 1231,
1025
- # "hb",
1026
- # ]
1027
- #
1028
- # auth message
1029
- # {
1030
- # "event": "auth",
1031
- # "status": "OK",
1032
- # "chanId": 0,
1033
- # "userId": 3159883,
1034
- # "auth_id": "ac7108e7-2f26-424d-9982-c24700dc02ca",
1035
- # "caps": {
1036
- # "orders": {read: 1, write: 1},
1037
- # "account": {read: 1, write: 1},
1038
- # "funding": {read: 1, write: 1},
1039
- # "history": {read: 1, write: 0},
1040
- # "wallets": {read: 1, write: 1},
1041
- # "withdraw": {read: 0, write: 1},
1042
- # "positions": {read: 1, write: 1},
1043
- # "ui_withdraw": {read: 0, write: 0}
1044
- # }
1045
- # }
1046
- #
1047
- if isinstance(message, list):
1048
- if message[1] == 'hb':
1049
- return # skip heartbeats within subscription channels for now
1050
- subscription = self.safe_value(client.subscriptions, channelId, {})
1051
- channel = self.safe_string(subscription, 'channel')
1052
- name = self.safe_string(message, 1)
1053
- publicMethods: dict = {
1054
- 'book': self.handle_order_book,
1055
- 'cs': self.handle_checksum,
1056
- 'candles': self.handle_ohlcv,
1057
- 'ticker': self.handle_ticker,
1058
- 'trades': self.handle_trades,
1059
- }
1060
- privateMethods: dict = {
1061
- 'os': self.handle_orders,
1062
- 'ou': self.handle_orders,
1063
- 'on': self.handle_orders,
1064
- 'oc': self.handle_orders,
1065
- 'wu': self.handle_balance,
1066
- 'ws': self.handle_balance,
1067
- 'tu': self.handle_my_trade,
1068
- }
1069
- method = None
1070
- if channelId == '0':
1071
- method = self.safe_value(privateMethods, name)
1072
- else:
1073
- method = self.safe_value_2(publicMethods, name, channel)
1074
- if method is not None:
1075
- method(client, message, subscription)
1076
- else:
1077
- event = self.safe_string(message, 'event')
1078
- if event is not None:
1079
- methods: dict = {
1080
- 'info': self.handle_system_status,
1081
- 'subscribed': self.handle_subscription_status,
1082
- 'auth': self.handle_authentication_message,
1083
- }
1084
- method = self.safe_value(methods, event)
1085
- if method is not None:
1086
- method(client, message)