ccxt 4.4.88__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 (101) hide show
  1. ccxt/__init__.py +1 -3
  2. ccxt/abstract/bitget.py +58 -0
  3. ccxt/abstract/bitrue.py +65 -65
  4. ccxt/abstract/cryptocom.py +2 -0
  5. ccxt/abstract/luno.py +1 -0
  6. ccxt/async_support/__init__.py +1 -3
  7. ccxt/async_support/base/exchange.py +6 -3
  8. ccxt/async_support/base/ws/client.py +173 -64
  9. ccxt/async_support/base/ws/future.py +23 -50
  10. ccxt/async_support/binance.py +2 -2
  11. ccxt/async_support/bingx.py +55 -29
  12. ccxt/async_support/bitget.py +469 -147
  13. ccxt/async_support/bitmex.py +2 -1
  14. ccxt/async_support/bitrue.py +72 -66
  15. ccxt/async_support/bitvavo.py +34 -0
  16. ccxt/async_support/btcalpha.py +35 -0
  17. ccxt/async_support/btcbox.py +35 -0
  18. ccxt/async_support/btcmarkets.py +35 -0
  19. ccxt/async_support/btcturk.py +35 -0
  20. ccxt/async_support/bybit.py +9 -3
  21. ccxt/async_support/cex.py +61 -0
  22. ccxt/async_support/coinbase.py +1 -3
  23. ccxt/async_support/cryptocom.py +66 -2
  24. ccxt/async_support/cryptomus.py +1 -1
  25. ccxt/async_support/delta.py +2 -2
  26. ccxt/async_support/digifinex.py +39 -99
  27. ccxt/async_support/exmo.py +14 -7
  28. ccxt/async_support/gate.py +14 -7
  29. ccxt/async_support/hashkey.py +15 -28
  30. ccxt/async_support/hollaex.py +27 -22
  31. ccxt/async_support/hyperliquid.py +104 -53
  32. ccxt/async_support/kraken.py +54 -50
  33. ccxt/async_support/luno.py +87 -1
  34. ccxt/async_support/mexc.py +1 -0
  35. ccxt/async_support/modetrade.py +2 -2
  36. ccxt/async_support/okx.py +2 -1
  37. ccxt/async_support/paradex.py +1 -1
  38. ccxt/async_support/phemex.py +16 -8
  39. ccxt/async_support/tradeogre.py +3 -3
  40. ccxt/async_support/xt.py +1 -1
  41. ccxt/base/exchange.py +20 -8
  42. ccxt/binance.py +2 -2
  43. ccxt/bingx.py +55 -29
  44. ccxt/bitget.py +469 -147
  45. ccxt/bitmex.py +2 -1
  46. ccxt/bitrue.py +72 -66
  47. ccxt/bitvavo.py +34 -0
  48. ccxt/btcalpha.py +35 -0
  49. ccxt/btcbox.py +35 -0
  50. ccxt/btcmarkets.py +35 -0
  51. ccxt/btcturk.py +35 -0
  52. ccxt/bybit.py +9 -3
  53. ccxt/cex.py +61 -0
  54. ccxt/coinbase.py +1 -3
  55. ccxt/cryptocom.py +66 -2
  56. ccxt/cryptomus.py +1 -1
  57. ccxt/delta.py +2 -2
  58. ccxt/digifinex.py +39 -99
  59. ccxt/exmo.py +13 -7
  60. ccxt/gate.py +14 -7
  61. ccxt/hashkey.py +15 -28
  62. ccxt/hollaex.py +27 -22
  63. ccxt/hyperliquid.py +104 -53
  64. ccxt/kraken.py +53 -50
  65. ccxt/luno.py +87 -1
  66. ccxt/mexc.py +1 -0
  67. ccxt/modetrade.py +2 -2
  68. ccxt/okx.py +2 -1
  69. ccxt/paradex.py +1 -1
  70. ccxt/phemex.py +16 -8
  71. ccxt/pro/__init__.py +1 -127
  72. ccxt/pro/bitstamp.py +1 -1
  73. ccxt/pro/bybit.py +6 -136
  74. ccxt/pro/coinbase.py +2 -0
  75. ccxt/pro/cryptocom.py +27 -0
  76. ccxt/pro/kraken.py +249 -267
  77. ccxt/pro/mexc.py +0 -1
  78. ccxt/tradeogre.py +3 -3
  79. ccxt/xt.py +1 -1
  80. {ccxt-4.4.88.dist-info → ccxt-4.4.91.dist-info}/METADATA +64 -23
  81. {ccxt-4.4.88.dist-info → ccxt-4.4.91.dist-info}/RECORD +84 -101
  82. ccxt/abstract/coinlist.py +0 -57
  83. ccxt/async_support/base/ws/aiohttp_client.py +0 -147
  84. ccxt/async_support/bitcoincom.py +0 -18
  85. ccxt/async_support/bitfinex1.py +0 -1711
  86. ccxt/async_support/bitpanda.py +0 -17
  87. ccxt/async_support/coinlist.py +0 -2542
  88. ccxt/async_support/poloniexfutures.py +0 -1875
  89. ccxt/bitcoincom.py +0 -18
  90. ccxt/bitfinex1.py +0 -1710
  91. ccxt/bitpanda.py +0 -17
  92. ccxt/coinlist.py +0 -2542
  93. ccxt/poloniexfutures.py +0 -1875
  94. ccxt/pro/bitcoincom.py +0 -35
  95. ccxt/pro/bitfinex1.py +0 -635
  96. ccxt/pro/bitpanda.py +0 -16
  97. ccxt/pro/poloniexfutures.py +0 -1004
  98. ccxt/pro/wazirx.py +0 -766
  99. {ccxt-4.4.88.dist-info → ccxt-4.4.91.dist-info}/LICENSE.txt +0 -0
  100. {ccxt-4.4.88.dist-info → ccxt-4.4.91.dist-info}/WHEEL +0 -0
  101. {ccxt-4.4.88.dist-info → ccxt-4.4.91.dist-info}/top_level.txt +0 -0
ccxt/pro/bitcoincom.py DELETED
@@ -1,35 +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
- from ccxt.pro.hitbtc import hitbtc
7
- from ccxt.base.types import Any
8
-
9
- import ccxt.async_support.hitbtc as hitbtcRest
10
-
11
- import ccxt.async_support.bitcoincom as bitcoincomRest
12
-
13
-
14
- class bitcoincom(hitbtc):
15
-
16
- def describe(self) -> Any:
17
- # eslint-disable-next-line new-cap
18
- describeExtended = self.get_describe_for_extended_ws_exchange(bitcoincomRest(), hitbtcRest(), super(bitcoincom, self).describe())
19
- return self.deep_extend(describeExtended, {
20
- 'id': 'bitcoincom',
21
- 'name': 'bitcoin.com',
22
- 'countries': ['KN'],
23
- 'urls': {
24
- 'logo': 'https://user-images.githubusercontent.com/1294454/97296144-514fa300-1861-11eb-952b-3d55d492200b.jpg',
25
- 'api': {
26
- 'ws': 'wss://api.fmfw.io/api/2/ws',
27
- },
28
- },
29
- 'fees': {
30
- 'trading': {
31
- 'maker': self.parse_number('0.0015'),
32
- 'taker': self.parse_number('0.002'),
33
- },
34
- },
35
- })
ccxt/pro/bitfinex1.py DELETED
@@ -1,635 +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
8
- import hashlib
9
- from ccxt.base.types import Any, 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.precise import Precise
15
-
16
-
17
- class bitfinex1(ccxt.async_support.bitfinex1):
18
-
19
- def describe(self) -> Any:
20
- return self.deep_extend(super(bitfinex1, self).describe(), {
21
- 'has': {
22
- 'ws': True,
23
- 'watchTicker': True,
24
- 'watchTickers': False,
25
- 'watchOrderBook': True,
26
- 'watchTrades': True,
27
- 'watchTradesForSymbols': False,
28
- 'watchBalance': False, # for now
29
- 'watchOHLCV': False, # missing on the exchange side in v1
30
- },
31
- 'urls': {
32
- 'api': {
33
- 'ws': {
34
- 'public': 'wss://api-pub.bitfinex.com/ws/1',
35
- 'private': 'wss://api.bitfinex.com/ws/1',
36
- },
37
- },
38
- },
39
- 'options': {
40
- 'watchOrderBook': {
41
- 'prec': 'P0',
42
- 'freq': 'F0',
43
- },
44
- 'ordersLimit': 1000,
45
- },
46
- })
47
-
48
- async def subscribe(self, channel, symbol, params={}):
49
- await self.load_markets()
50
- market = self.market(symbol)
51
- marketId = market['id']
52
- url = self.urls['api']['ws']['public']
53
- messageHash = channel + ':' + marketId
54
- # channel = 'trades'
55
- request: dict = {
56
- 'event': 'subscribe',
57
- 'channel': channel,
58
- 'symbol': marketId,
59
- 'messageHash': messageHash,
60
- }
61
- return await self.watch(url, messageHash, self.deep_extend(request, params), messageHash)
62
-
63
- async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
64
- """
65
- get the list of most recent trades for a particular symbol
66
-
67
- https://docs.bitfinex.com/v1/reference/ws-public-trades
68
-
69
- :param str symbol: unified symbol of the market to fetch trades for
70
- :param int [since]: timestamp in ms of the earliest trade to fetch
71
- :param int [limit]: the maximum amount of trades to fetch
72
- :param dict [params]: extra parameters specific to the exchange API endpoint
73
- :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
74
- """
75
- await self.load_markets()
76
- symbol = self.symbol(symbol)
77
- trades = await self.subscribe('trades', symbol, params)
78
- if self.newUpdates:
79
- limit = trades.getLimit(symbol, limit)
80
- return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
81
-
82
- async def watch_ticker(self, symbol: str, params={}) -> Ticker:
83
- """
84
- watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
85
-
86
- https://docs.bitfinex.com/v1/reference/ws-public-ticker
87
-
88
- :param str symbol: unified symbol of the market to fetch the ticker for
89
- :param dict [params]: extra parameters specific to the exchange API endpoint
90
- :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
91
- """
92
- return await self.subscribe('ticker', symbol, params)
93
-
94
- def handle_trades(self, client: Client, message, subscription):
95
- #
96
- # initial snapshot
97
- #
98
- # [
99
- # 2,
100
- # [
101
- # [null, 1580565020, 9374.9, 0.005],
102
- # [null, 1580565004, 9374.9, 0.005],
103
- # [null, 1580565003, 9374.9, 0.005],
104
- # ]
105
- # ]
106
- #
107
- # when a trade does not have an id yet
108
- #
109
- # # channel id, update type, seq, time, price, amount
110
- # [2, "te", "28462857-BTCUSD", 1580565041, 9374.9, 0.005],
111
- #
112
- # when a trade already has an id
113
- #
114
- # # channel id, update type, seq, trade id, time, price, amount
115
- # [2, "tu", "28462857-BTCUSD", 413357662, 1580565041, 9374.9, 0.005]
116
- #
117
- channel = self.safe_value(subscription, 'channel')
118
- marketId = self.safe_string(subscription, 'pair')
119
- messageHash = channel + ':' + marketId
120
- tradesLimit = self.safe_integer(self.options, 'tradesLimit', 1000)
121
- market = self.safe_market(marketId)
122
- symbol = market['symbol']
123
- data = self.safe_value(message, 1)
124
- stored = self.safe_value(self.trades, symbol)
125
- if stored is None:
126
- stored = ArrayCache(tradesLimit)
127
- self.trades[symbol] = stored
128
- if isinstance(data, list):
129
- trades = self.parse_trades(data, market)
130
- for i in range(0, len(trades)):
131
- stored.append(trades[i])
132
- else:
133
- second = self.safe_string(message, 1)
134
- if second != 'tu':
135
- return
136
- trade = self.parse_trade(message, market)
137
- stored.append(trade)
138
- client.resolve(stored, messageHash)
139
-
140
- def parse_trade(self, trade, market=None) -> Trade:
141
- #
142
- # snapshot trade
143
- #
144
- # # null, time, price, amount
145
- # [null, 1580565020, 9374.9, 0.005],
146
- #
147
- # when a trade does not have an id yet
148
- #
149
- # # channel id, update type, seq, time, price, amount
150
- # [2, "te", "28462857-BTCUSD", 1580565041, 9374.9, 0.005],
151
- #
152
- # when a trade already has an id
153
- #
154
- # # channel id, update type, seq, trade id, time, price, amount
155
- # [2, "tu", "28462857-BTCUSD", 413357662, 1580565041, 9374.9, 0.005]
156
- #
157
- if not isinstance(trade, list):
158
- return super(bitfinex1, self).parse_trade(trade, market)
159
- tradeLength = len(trade)
160
- event = self.safe_string(trade, 1)
161
- id = None
162
- if event == 'tu':
163
- id = self.safe_string(trade, tradeLength - 4)
164
- timestamp = self.safe_timestamp(trade, tradeLength - 3)
165
- price = self.safe_string(trade, tradeLength - 2)
166
- amount = self.safe_string(trade, tradeLength - 1)
167
- side = None
168
- if amount is not None:
169
- side = 'buy' if Precise.string_gt(amount, '0') else 'sell'
170
- amount = Precise.string_abs(amount)
171
- seq = self.safe_string(trade, 2)
172
- parts = seq.split('-')
173
- marketId = self.safe_string(parts, 1)
174
- if marketId is not None:
175
- marketId = marketId.replace('t', '')
176
- symbol = self.safe_symbol(marketId, market)
177
- takerOrMaker = None
178
- orderId = None
179
- return self.safe_trade({
180
- 'info': trade,
181
- 'timestamp': timestamp,
182
- 'datetime': self.iso8601(timestamp),
183
- 'symbol': symbol,
184
- 'id': id,
185
- 'order': orderId,
186
- 'type': None,
187
- 'takerOrMaker': takerOrMaker,
188
- 'side': side,
189
- 'price': price,
190
- 'amount': amount,
191
- 'cost': None,
192
- 'fee': None,
193
- })
194
-
195
- def handle_ticker(self, client: Client, message, subscription):
196
- #
197
- # [
198
- # 2, # 0 CHANNEL_ID integer Channel ID
199
- # 236.62, # 1 BID float Price of last highest bid
200
- # 9.0029, # 2 BID_SIZE float Size of the last highest bid
201
- # 236.88, # 3 ASK float Price of last lowest ask
202
- # 7.1138, # 4 ASK_SIZE float Size of the last lowest ask
203
- # -1.02, # 5 DAILY_CHANGE float Amount that the last price has changed since yesterday
204
- # 0, # 6 DAILY_CHANGE_PERC float Amount that the price has changed expressed in percentage terms
205
- # 236.52, # 7 LAST_PRICE float Price of the last trade.
206
- # 5191.36754297, # 8 VOLUME float Daily volume
207
- # 250.01, # 9 HIGH float Daily high
208
- # 220.05, # 10 LOW float Daily low
209
- # ]
210
- #
211
- marketId = self.safe_string(subscription, 'pair')
212
- symbol = self.safe_symbol(marketId)
213
- channel = 'ticker'
214
- messageHash = channel + ':' + marketId
215
- last = self.safe_string(message, 7)
216
- change = self.safe_string(message, 5)
217
- open = None
218
- if (last is not None) and (change is not None):
219
- open = Precise.string_sub(last, change)
220
- result = self.safe_ticker({
221
- 'symbol': symbol,
222
- 'timestamp': None,
223
- 'datetime': None,
224
- 'high': self.safe_string(message, 9),
225
- 'low': self.safe_string(message, 10),
226
- 'bid': self.safe_string(message, 1),
227
- 'bidVolume': None,
228
- 'ask': self.safe_string(message, 3),
229
- 'askVolume': None,
230
- 'vwap': None,
231
- 'open': self.parse_number(open),
232
- 'close': self.parse_number(last),
233
- 'last': self.parse_number(last),
234
- 'previousClose': None,
235
- 'change': self.parse_number(change),
236
- 'percentage': self.safe_string(message, 6),
237
- 'average': None,
238
- 'baseVolume': self.safe_string(message, 8),
239
- 'quoteVolume': None,
240
- 'info': message,
241
- })
242
- self.tickers[symbol] = result
243
- client.resolve(result, messageHash)
244
-
245
- async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
246
- """
247
- watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
248
-
249
- https://docs.bitfinex.com/v1/reference/ws-public-order-books
250
-
251
- :param str symbol: unified symbol of the market to fetch the order book for
252
- :param int [limit]: the maximum amount of order book entries to return
253
- :param dict [params]: extra parameters specific to the exchange API endpoint
254
- :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
255
- """
256
- if limit is not None:
257
- if (limit != 25) and (limit != 100):
258
- raise ExchangeError(self.id + ' watchOrderBook limit argument must be None, 25 or 100')
259
- options = self.safe_value(self.options, 'watchOrderBook', {})
260
- prec = self.safe_string(options, 'prec', 'P0')
261
- freq = self.safe_string(options, 'freq', 'F0')
262
- request: dict = {
263
- # "event": "subscribe", # added in subscribe()
264
- # "channel": channel, # added in subscribe()
265
- # "symbol": marketId, # added in subscribe()
266
- 'prec': prec, # string, level of price aggregation, 'P0', 'P1', 'P2', 'P3', 'P4', default P0
267
- 'freq': freq, # string, frequency of updates 'F0' = realtime, 'F1' = 2 seconds, default is 'F0'
268
- 'len': limit, # string, number of price points, '25', '100', default = '25'
269
- }
270
- orderbook = await self.subscribe('book', symbol, self.deep_extend(request, params))
271
- return orderbook.limit()
272
-
273
- def handle_order_book(self, client: Client, message, subscription):
274
- #
275
- # first message(snapshot)
276
- #
277
- # [
278
- # 18691, # channel id
279
- # [
280
- # [7364.8, 10, 4.354802], # price, count, size > 0 = bid
281
- # [7364.7, 1, 0.00288831],
282
- # [7364.3, 12, 0.048],
283
- # [7364.9, 3, -0.42028976], # price, count, size < 0 = ask
284
- # [7365, 1, -0.25],
285
- # [7365.5, 1, -0.00371937],
286
- # ]
287
- # ]
288
- #
289
- # subsequent updates
290
- #
291
- # [
292
- # 30, # channel id
293
- # 9339.9, # price
294
- # 0, # count
295
- # -1, # size > 0 = bid, size < 0 = ask
296
- # ]
297
- #
298
- marketId = self.safe_string(subscription, 'pair')
299
- symbol = self.safe_symbol(marketId)
300
- channel = 'book'
301
- messageHash = channel + ':' + marketId
302
- prec = self.safe_string(subscription, 'prec', 'P0')
303
- isRaw = (prec == 'R0')
304
- # if it is an initial snapshot
305
- if isinstance(message[1], list):
306
- limit = self.safe_integer(subscription, 'len')
307
- if isRaw:
308
- # raw order books
309
- self.orderbooks[symbol] = self.indexed_order_book({}, limit)
310
- else:
311
- # P0, P1, P2, P3, P4
312
- self.orderbooks[symbol] = self.counted_order_book({}, limit)
313
- orderbook = self.orderbooks[symbol]
314
- if isRaw:
315
- deltas = message[1]
316
- for i in range(0, len(deltas)):
317
- delta = deltas[i]
318
- id = self.safe_string(delta, 0)
319
- price = self.safe_float(delta, 1)
320
- delta2Value = delta[2]
321
- size = -delta2Value if (delta2Value < 0) else delta2Value
322
- side = 'asks' if (delta2Value < 0) else 'bids'
323
- bookside = orderbook[side]
324
- bookside.storeArray([price, size, id])
325
- else:
326
- deltas = message[1]
327
- for i in range(0, len(deltas)):
328
- delta = deltas[i]
329
- delta2 = delta[2]
330
- size = -delta2 if (delta2 < 0) else delta2
331
- side = 'asks' if (delta2 < 0) else 'bids'
332
- countedBookSide = orderbook[side]
333
- countedBookSide.storeArray([delta[0], size, delta[1]])
334
- client.resolve(orderbook, messageHash)
335
- else:
336
- orderbook = self.orderbooks[symbol]
337
- if isRaw:
338
- id = self.safe_string(message, 1)
339
- price = self.safe_string(message, 2)
340
- message3 = message[3]
341
- size = -message3 if (message3 < 0) else message3
342
- side = 'asks' if (message3 < 0) else 'bids'
343
- bookside = orderbook[side]
344
- # price = 0 means that you have to remove the order from your book
345
- amount = size if Precise.string_gt(price, '0') else '0'
346
- bookside.storeArray([self.parse_number(price), self.parse_number(amount), id])
347
- else:
348
- message3Value = message[3]
349
- size = -message3Value if (message3Value < 0) else message3Value
350
- side = 'asks' if (message3Value < 0) else 'bids'
351
- countedBookSide = orderbook[side]
352
- countedBookSide.storeArray([message[1], size, message[2]])
353
- client.resolve(orderbook, messageHash)
354
-
355
- def handle_heartbeat(self, client: Client, message):
356
- #
357
- # every second(approx) if no other updates are sent
358
- #
359
- # {"event": "heartbeat"}
360
- #
361
- event = self.safe_string(message, 'event')
362
- client.resolve(message, event)
363
-
364
- def handle_system_status(self, client: Client, message):
365
- #
366
- # todo: answer the question whether handleSystemStatus should be renamed
367
- # and unified for any usage pattern that
368
- # involves system status and maintenance updates
369
- #
370
- # {
371
- # "event": "info",
372
- # "version": 2,
373
- # "serverId": "e293377e-7bb7-427e-b28c-5db045b2c1d1",
374
- # "platform": {status: 1}, # 1 for operative, 0 for maintenance
375
- # }
376
- #
377
- return message
378
-
379
- def handle_subscription_status(self, client: Client, message):
380
- #
381
- # {
382
- # "event": "subscribed",
383
- # "channel": "book",
384
- # "chanId": 67473,
385
- # "symbol": "tBTCUSD",
386
- # "prec": "P0",
387
- # "freq": "F0",
388
- # "len": "25",
389
- # "pair": "BTCUSD"
390
- # }
391
- #
392
- channelId = self.safe_string(message, 'chanId')
393
- client.subscriptions[channelId] = message
394
- return message
395
-
396
- async def authenticate(self, params={}):
397
- url = self.urls['api']['ws']['private']
398
- client = self.client(url)
399
- future = client.future('authenticated')
400
- method = 'auth'
401
- authenticated = self.safe_value(client.subscriptions, method)
402
- if authenticated is None:
403
- nonce = self.milliseconds()
404
- payload = 'AUTH' + str(nonce)
405
- signature = self.hmac(self.encode(payload), self.encode(self.secret), hashlib.sha384, 'hex')
406
- request: dict = {
407
- 'apiKey': self.apiKey,
408
- 'authSig': signature,
409
- 'authNonce': nonce,
410
- 'authPayload': payload,
411
- 'event': method,
412
- 'filter': [
413
- 'trading',
414
- 'wallet',
415
- ],
416
- }
417
- self.spawn(self.watch, url, method, request, 1)
418
- return await future
419
-
420
- def handle_authentication_message(self, client: Client, message):
421
- status = self.safe_string(message, 'status')
422
- if status == 'OK':
423
- # we resolve the future here permanently so authentication only happens once
424
- future = self.safe_value(client.futures, 'authenticated')
425
- future.resolve(True)
426
- else:
427
- error = AuthenticationError(self.json(message))
428
- client.reject(error, 'authenticated')
429
- # allows further authentication attempts
430
- method = self.safe_string(message, 'event')
431
- if method in client.subscriptions:
432
- del client.subscriptions[method]
433
-
434
- async def watch_order(self, id, symbol: Str = None, params={}):
435
- await self.load_markets()
436
- url = self.urls['api']['ws']['private']
437
- await self.authenticate()
438
- return await self.watch(url, id, None, 1)
439
-
440
- async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
441
- """
442
- watches information on multiple orders made by the user
443
-
444
- https://docs.bitfinex.com/v1/reference/ws-auth-order-updates
445
- https://docs.bitfinex.com/v1/reference/ws-auth-order-snapshots
446
-
447
- :param str symbol: unified market symbol of the market orders were made in
448
- :param int [since]: the earliest time in ms to fetch orders for
449
- :param int [limit]: the maximum number of order structures to retrieve
450
- :param dict [params]: extra parameters specific to the exchange API endpoint
451
- :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
452
- """
453
- await self.load_markets()
454
- await self.authenticate()
455
- if symbol is not None:
456
- symbol = self.symbol(symbol)
457
- url = self.urls['api']['ws']['private']
458
- orders = await self.watch(url, 'os', None, 1)
459
- if self.newUpdates:
460
- limit = orders.getLimit(symbol, limit)
461
- return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
462
-
463
- def handle_orders(self, client: Client, message, subscription):
464
- #
465
- # order snapshot
466
- #
467
- # [
468
- # 0,
469
- # "os",
470
- # [
471
- # [
472
- # 45287766631,
473
- # "ETHUST",
474
- # -0.07,
475
- # -0.07,
476
- # "EXCHANGE LIMIT",
477
- # "ACTIVE",
478
- # 210,
479
- # 0,
480
- # "2020-05-16T13:17:46Z",
481
- # 0,
482
- # 0,
483
- # 0
484
- # ]
485
- # ]
486
- # ]
487
- #
488
- # order cancel
489
- #
490
- # [
491
- # 0,
492
- # "oc",
493
- # [
494
- # 45287766631,
495
- # "ETHUST",
496
- # -0.07,
497
- # -0.07,
498
- # "EXCHANGE LIMIT",
499
- # "CANCELED",
500
- # 210,
501
- # 0,
502
- # "2020-05-16T13:17:46Z",
503
- # 0,
504
- # 0,
505
- # 0,
506
- # ]
507
- # ]
508
- #
509
- data = self.safe_value(message, 2, [])
510
- messageType = self.safe_string(message, 1)
511
- if messageType == 'os':
512
- for i in range(0, len(data)):
513
- value = data[i]
514
- self.handle_order(client, value)
515
- else:
516
- self.handle_order(client, data)
517
- if self.orders is not None:
518
- client.resolve(self.orders, 'os')
519
-
520
- def parse_ws_order_status(self, status):
521
- statuses: dict = {
522
- 'ACTIVE': 'open',
523
- 'CANCELED': 'canceled',
524
- }
525
- return self.safe_string(statuses, status, status)
526
-
527
- def handle_order(self, client: Client, order):
528
- # [45287766631,
529
- # "ETHUST",
530
- # -0.07,
531
- # -0.07,
532
- # "EXCHANGE LIMIT",
533
- # "CANCELED",
534
- # 210,
535
- # 0,
536
- # "2020-05-16T13:17:46Z",
537
- # 0,
538
- # 0,
539
- # 0]
540
- id = self.safe_string(order, 0)
541
- marketId = self.safe_string(order, 1)
542
- symbol = self.safe_symbol(marketId)
543
- amount = self.safe_string(order, 2)
544
- remaining = self.safe_string(order, 3)
545
- side = 'buy'
546
- if Precise.string_lt(amount, '0'):
547
- amount = Precise.string_abs(amount)
548
- remaining = Precise.string_abs(remaining)
549
- side = 'sell'
550
- type = self.safe_string(order, 4)
551
- if type.find('LIMIT') > -1:
552
- type = 'limit'
553
- elif type.find('MARKET') > -1:
554
- type = 'market'
555
- status = self.parse_ws_order_status(self.safe_string(order, 5))
556
- price = self.safe_string(order, 6)
557
- rawDatetime = self.safe_string(order, 8)
558
- timestamp = self.parse8601(rawDatetime)
559
- parsed = self.safe_order({
560
- 'info': order,
561
- 'id': id,
562
- 'clientOrderId': None,
563
- 'timestamp': timestamp,
564
- 'datetime': self.iso8601(timestamp),
565
- 'lastTradeTimestamp': None,
566
- 'symbol': symbol,
567
- 'type': type,
568
- 'side': side,
569
- 'price': price,
570
- 'stopPrice': None,
571
- 'triggerPrice': None,
572
- 'average': None,
573
- 'amount': amount,
574
- 'remaining': remaining,
575
- 'filled': None,
576
- 'status': status,
577
- 'fee': None,
578
- 'cost': None,
579
- 'trades': None,
580
- })
581
- if self.orders is None:
582
- limit = self.safe_integer(self.options, 'ordersLimit', 1000)
583
- self.orders = ArrayCacheBySymbolById(limit)
584
- orders = self.orders
585
- orders.append(parsed)
586
- client.resolve(parsed, id)
587
- return parsed
588
-
589
- def handle_message(self, client: Client, message):
590
- if isinstance(message, list):
591
- channelId = self.safe_string(message, 0)
592
- #
593
- # [
594
- # 1231,
595
- # "hb",
596
- # ]
597
- #
598
- if message[1] == 'hb':
599
- return # skip heartbeats within subscription channels for now
600
- subscription = self.safe_value(client.subscriptions, channelId, {})
601
- channel = self.safe_string(subscription, 'channel')
602
- name = self.safe_string(message, 1)
603
- methods: dict = {
604
- 'book': self.handle_order_book,
605
- # 'ohlc': self.handleOHLCV,
606
- 'ticker': self.handle_ticker,
607
- 'trades': self.handle_trades,
608
- 'os': self.handle_orders,
609
- 'on': self.handle_orders,
610
- 'oc': self.handle_orders,
611
- }
612
- method = self.safe_value_2(methods, channel, name)
613
- if method is not None:
614
- method(client, message, subscription)
615
- else:
616
- # todo add bitfinex handleErrorMessage
617
- #
618
- # {
619
- # "event": "info",
620
- # "version": 2,
621
- # "serverId": "e293377e-7bb7-427e-b28c-5db045b2c1d1",
622
- # "platform": {status: 1}, # 1 for operative, 0 for maintenance
623
- # }
624
- #
625
- event = self.safe_string(message, 'event')
626
- if event is not None:
627
- methods: dict = {
628
- 'info': self.handle_system_status,
629
- # 'book': 'handleOrderBook',
630
- 'subscribed': self.handle_subscription_status,
631
- 'auth': self.handle_authentication_message,
632
- }
633
- method = self.safe_value(methods, event)
634
- if method is not None:
635
- method(client, message)
ccxt/pro/bitpanda.py DELETED
@@ -1,16 +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
- from ccxt.pro.onetrading import onetrading
7
- from ccxt.base.types import Any
8
-
9
-
10
- class bitpanda(onetrading):
11
-
12
- def describe(self) -> Any:
13
- return self.deep_extend(super(bitpanda, self).describe(), {
14
- 'alias': True,
15
- 'id': 'bitpanda',
16
- })