ccxt 4.3.98__py2.py3-none-any.whl → 4.4.2__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.
- ccxt/__init__.py +1 -1
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/binance.py +71 -8
- ccxt/async_support/bitget.py +3 -2
- ccxt/async_support/cryptocom.py +1 -1
- ccxt/async_support/currencycom.py +1 -2
- ccxt/async_support/gate.py +1 -0
- ccxt/async_support/htx.py +1 -1
- ccxt/async_support/mexc.py +61 -1
- ccxt/async_support/xt.py +1 -1
- ccxt/base/exchange.py +53 -1
- ccxt/base/types.py +2 -2
- ccxt/binance.py +71 -8
- ccxt/bitget.py +3 -2
- ccxt/cryptocom.py +1 -1
- ccxt/currencycom.py +1 -2
- ccxt/gate.py +1 -0
- ccxt/htx.py +1 -1
- ccxt/mexc.py +61 -1
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +3 -47
- ccxt/pro/bitget.py +1 -7
- ccxt/pro/bitmex.py +11 -1
- ccxt/pro/bybit.py +2 -41
- ccxt/pro/cryptocom.py +2 -31
- ccxt/pro/gate.py +1 -8
- ccxt/pro/hyperliquid.py +217 -11
- ccxt/pro/kucoin.py +2 -43
- ccxt/pro/kucoinfutures.py +122 -0
- ccxt/pro/okx.py +8 -31
- ccxt/xt.py +1 -1
- {ccxt-4.3.98.dist-info → ccxt-4.4.2.dist-info}/METADATA +5 -5
- {ccxt-4.3.98.dist-info → ccxt-4.4.2.dist-info}/RECORD +37 -37
- {ccxt-4.3.98.dist-info → ccxt-4.4.2.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.3.98.dist-info → ccxt-4.4.2.dist-info}/WHEEL +0 -0
- {ccxt-4.3.98.dist-info → ccxt-4.4.2.dist-info}/top_level.txt +0 -0
ccxt/pro/hyperliquid.py
CHANGED
@@ -5,9 +5,10 @@
|
|
5
5
|
|
6
6
|
import ccxt.async_support
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp
|
8
|
-
from ccxt.base.types import
|
8
|
+
from ccxt.base.types import Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade
|
9
9
|
from ccxt.async_support.base.ws.client import Client
|
10
10
|
from typing import List
|
11
|
+
from typing import Any
|
11
12
|
from ccxt.base.errors import ExchangeError
|
12
13
|
|
13
14
|
|
@@ -160,6 +161,32 @@ class hyperliquid(ccxt.async_support.hyperliquid):
|
|
160
161
|
orderbook = await self.watch(url, messageHash, message, messageHash)
|
161
162
|
return orderbook.limit()
|
162
163
|
|
164
|
+
async def un_watch_order_book(self, symbol: str, params={}) -> Any:
|
165
|
+
"""
|
166
|
+
unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
167
|
+
:see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions
|
168
|
+
:param str symbol: unified symbol of the market to fetch the order book for
|
169
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
170
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
171
|
+
"""
|
172
|
+
await self.load_markets()
|
173
|
+
market = self.market(symbol)
|
174
|
+
symbol = market['symbol']
|
175
|
+
subMessageHash = 'orderbook:' + symbol
|
176
|
+
messageHash = 'unsubscribe:' + subMessageHash
|
177
|
+
url = self.urls['api']['ws']['public']
|
178
|
+
id = str(self.nonce())
|
179
|
+
request: dict = {
|
180
|
+
'id': id,
|
181
|
+
'method': 'unsubscribe',
|
182
|
+
'subscription': {
|
183
|
+
'type': 'l2Book',
|
184
|
+
'coin': market['base'] if market['swap'] else market['id'],
|
185
|
+
},
|
186
|
+
}
|
187
|
+
message = self.extend(request, params)
|
188
|
+
return await self.watch(url, messageHash, message, messageHash)
|
189
|
+
|
163
190
|
def handle_order_book(self, client, message):
|
164
191
|
#
|
165
192
|
# {
|
@@ -230,6 +257,28 @@ class hyperliquid(ccxt.async_support.hyperliquid):
|
|
230
257
|
return self.filter_by_array_tickers(tickers, 'symbol', symbols)
|
231
258
|
return self.tickers
|
232
259
|
|
260
|
+
async def un_watch_tickers(self, symbols: Strings = None, params={}) -> Any:
|
261
|
+
"""
|
262
|
+
unWatches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
263
|
+
:see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions
|
264
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
265
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
266
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
267
|
+
"""
|
268
|
+
await self.load_markets()
|
269
|
+
symbols = self.market_symbols(symbols, None, True)
|
270
|
+
subMessageHash = 'tickers'
|
271
|
+
messageHash = 'unsubscribe:' + subMessageHash
|
272
|
+
url = self.urls['api']['ws']['public']
|
273
|
+
request: dict = {
|
274
|
+
'method': 'unsubscribe',
|
275
|
+
'subscription': {
|
276
|
+
'type': 'webData2', # allMids
|
277
|
+
'user': '0x0000000000000000000000000000000000000000',
|
278
|
+
},
|
279
|
+
}
|
280
|
+
return await self.watch(url, messageHash, self.extend(request, params), messageHash)
|
281
|
+
|
233
282
|
async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
234
283
|
"""
|
235
284
|
watches information on multiple trades made by the user
|
@@ -392,15 +441,17 @@ class hyperliquid(ccxt.async_support.hyperliquid):
|
|
392
441
|
client.resolve(trades, messageHash)
|
393
442
|
|
394
443
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
444
|
+
# s
|
445
|
+
# @method
|
446
|
+
# @name hyperliquid#watchTrades
|
447
|
+
# @description watches information on multiple trades made in a market
|
448
|
+
# @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions
|
449
|
+
# @param {string} symbol unified market symbol of the market trades were made in
|
450
|
+
# @param {int} [since] the earliest time in ms to fetch trades for
|
451
|
+
# @param {int} [limit] the maximum number of trade structures to retrieve
|
452
|
+
# @param {object} [params] extra parameters specific to the exchange API endpoint
|
453
|
+
# @returns {object[]} a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
454
|
+
#
|
404
455
|
await self.load_markets()
|
405
456
|
market = self.market(symbol)
|
406
457
|
symbol = market['symbol']
|
@@ -419,6 +470,30 @@ class hyperliquid(ccxt.async_support.hyperliquid):
|
|
419
470
|
limit = trades.getLimit(symbol, limit)
|
420
471
|
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
421
472
|
|
473
|
+
async def un_watch_trades(self, symbol: str, params={}) -> Any:
|
474
|
+
"""
|
475
|
+
unWatches information on multiple trades made in a market
|
476
|
+
:see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions
|
477
|
+
:param str symbol: unified market symbol of the market trades were made in
|
478
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
479
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
480
|
+
"""
|
481
|
+
await self.load_markets()
|
482
|
+
market = self.market(symbol)
|
483
|
+
symbol = market['symbol']
|
484
|
+
subMessageHash = 'trade:' + symbol
|
485
|
+
messageHash = 'unsubscribe:' + subMessageHash
|
486
|
+
url = self.urls['api']['ws']['public']
|
487
|
+
request: dict = {
|
488
|
+
'method': 'unsubscribe',
|
489
|
+
'subscription': {
|
490
|
+
'type': 'trades',
|
491
|
+
'coin': market['base'] if market['swap'] else market['id'],
|
492
|
+
},
|
493
|
+
}
|
494
|
+
message = self.extend(request, params)
|
495
|
+
return await self.watch(url, messageHash, message, messageHash)
|
496
|
+
|
422
497
|
def handle_trades(self, client: Client, message):
|
423
498
|
#
|
424
499
|
# {
|
@@ -546,6 +621,32 @@ class hyperliquid(ccxt.async_support.hyperliquid):
|
|
546
621
|
limit = ohlcv.getLimit(symbol, limit)
|
547
622
|
return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
|
548
623
|
|
624
|
+
async def un_watch_ohlcv(self, symbol: str, timeframe='1m', params={}) -> Any:
|
625
|
+
"""
|
626
|
+
watches historical candlestick data containing the open, high, low, close price, and the volume of a market
|
627
|
+
:see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions
|
628
|
+
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
629
|
+
:param str timeframe: the length of time each candle represents
|
630
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
631
|
+
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
632
|
+
"""
|
633
|
+
await self.load_markets()
|
634
|
+
market = self.market(symbol)
|
635
|
+
symbol = market['symbol']
|
636
|
+
url = self.urls['api']['ws']['public']
|
637
|
+
request: dict = {
|
638
|
+
'method': 'unsubscribe',
|
639
|
+
'subscription': {
|
640
|
+
'type': 'candle',
|
641
|
+
'coin': market['base'] if market['swap'] else market['id'],
|
642
|
+
'interval': timeframe,
|
643
|
+
},
|
644
|
+
}
|
645
|
+
subMessageHash = 'candles:' + timeframe + ':' + symbol
|
646
|
+
messagehash = 'unsubscribe:' + subMessageHash
|
647
|
+
message = self.extend(request, params)
|
648
|
+
return await self.watch(url, messagehash, message, messagehash)
|
649
|
+
|
549
650
|
def handle_ohlcv(self, client: Client, message):
|
550
651
|
#
|
551
652
|
# {
|
@@ -581,7 +682,7 @@ class hyperliquid(ccxt.async_support.hyperliquid):
|
|
581
682
|
messageHash = 'candles:' + timeframe + ':' + symbol
|
582
683
|
client.resolve(ohlcv, messageHash)
|
583
684
|
|
584
|
-
def handle_ws_post(self, client: Client, message:
|
685
|
+
def handle_ws_post(self, client: Client, message: dict):
|
585
686
|
# {
|
586
687
|
# channel: "post",
|
587
688
|
# data: {
|
@@ -689,7 +790,111 @@ class hyperliquid(ccxt.async_support.hyperliquid):
|
|
689
790
|
else:
|
690
791
|
return False
|
691
792
|
|
793
|
+
def handle_order_book_unsubscription(self, client: Client, subscription: dict):
|
794
|
+
#
|
795
|
+
# "subscription":{
|
796
|
+
# "type":"l2Book",
|
797
|
+
# "coin":"BTC",
|
798
|
+
# "nSigFigs":5,
|
799
|
+
# "mantissa":null
|
800
|
+
# }
|
801
|
+
#
|
802
|
+
coin = self.safe_string(subscription, 'coin')
|
803
|
+
marketId = self.coinToMarketId(coin)
|
804
|
+
symbol = self.safe_symbol(marketId)
|
805
|
+
subMessageHash = 'orderbook:' + symbol
|
806
|
+
messageHash = 'unsubscribe:' + subMessageHash
|
807
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
808
|
+
if symbol in self.orderbooks:
|
809
|
+
del self.orderbooks[symbol]
|
810
|
+
|
811
|
+
def handle_trades_unsubscription(self, client: Client, subscription: dict):
|
812
|
+
#
|
813
|
+
coin = self.safe_string(subscription, 'coin')
|
814
|
+
marketId = self.coinToMarketId(coin)
|
815
|
+
symbol = self.safe_symbol(marketId)
|
816
|
+
subMessageHash = 'trade:' + symbol
|
817
|
+
messageHash = 'unsubscribe:' + subMessageHash
|
818
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
819
|
+
if symbol in self.trades:
|
820
|
+
del self.trades[symbol]
|
821
|
+
|
822
|
+
def handle_tickers_unsubscription(self, client: Client, subscription: dict):
|
823
|
+
#
|
824
|
+
subMessageHash = 'tickers'
|
825
|
+
messageHash = 'unsubscribe:' + subMessageHash
|
826
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
827
|
+
symbols = list(self.tickers.keys())
|
828
|
+
for i in range(0, len(symbols)):
|
829
|
+
del self.tickers[symbols[i]]
|
830
|
+
|
831
|
+
def handle_ohlcv_unsubscription(self, client: Client, subscription: dict):
|
832
|
+
coin = self.safe_string(subscription, 'coin')
|
833
|
+
marketId = self.coinToMarketId(coin)
|
834
|
+
symbol = self.safe_symbol(marketId)
|
835
|
+
interval = self.safe_string(subscription, 'interval')
|
836
|
+
timeframe = self.find_timeframe(interval)
|
837
|
+
subMessageHash = 'candles:' + timeframe + ':' + symbol
|
838
|
+
messageHash = 'unsubscribe:' + subMessageHash
|
839
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
840
|
+
if symbol in self.ohlcvs:
|
841
|
+
if timeframe in self.ohlcvs[symbol]:
|
842
|
+
del self.ohlcvs[symbol][timeframe]
|
843
|
+
|
844
|
+
def handle_subscription_response(self, client: Client, message):
|
845
|
+
# {
|
846
|
+
# "channel":"subscriptionResponse",
|
847
|
+
# "data":{
|
848
|
+
# "method":"unsubscribe",
|
849
|
+
# "subscription":{
|
850
|
+
# "type":"l2Book",
|
851
|
+
# "coin":"BTC",
|
852
|
+
# "nSigFigs":5,
|
853
|
+
# "mantissa":null
|
854
|
+
# }
|
855
|
+
# }
|
856
|
+
# }
|
857
|
+
#
|
858
|
+
# {
|
859
|
+
# "channel":"subscriptionResponse",
|
860
|
+
# "data":{
|
861
|
+
# "method":"unsubscribe",
|
862
|
+
# "subscription":{
|
863
|
+
# "type":"trades",
|
864
|
+
# "coin":"PURR/USDC"
|
865
|
+
# }
|
866
|
+
# }
|
867
|
+
# }
|
868
|
+
#
|
869
|
+
data = self.safe_dict(message, 'data', {})
|
870
|
+
method = self.safe_string(data, 'method')
|
871
|
+
if method == 'unsubscribe':
|
872
|
+
subscription = self.safe_dict(data, 'subscription', {})
|
873
|
+
type = self.safe_string(subscription, 'type')
|
874
|
+
if type == 'l2Book':
|
875
|
+
self.handle_order_book_unsubscription(client, subscription)
|
876
|
+
elif type == 'trades':
|
877
|
+
self.handle_trades_unsubscription(client, subscription)
|
878
|
+
elif type == 'webData2':
|
879
|
+
self.handle_tickers_unsubscription(client, subscription)
|
880
|
+
elif type == 'candle':
|
881
|
+
self.handle_ohlcv_unsubscription(client, subscription)
|
882
|
+
|
692
883
|
def handle_message(self, client: Client, message):
|
884
|
+
#
|
885
|
+
# {
|
886
|
+
# "channel":"subscriptionResponse",
|
887
|
+
# "data":{
|
888
|
+
# "method":"unsubscribe",
|
889
|
+
# "subscription":{
|
890
|
+
# "type":"l2Book",
|
891
|
+
# "coin":"BTC",
|
892
|
+
# "nSigFigs":5,
|
893
|
+
# "mantissa":null
|
894
|
+
# }
|
895
|
+
# }
|
896
|
+
# }
|
897
|
+
#
|
693
898
|
if self.handle_error_message(client, message):
|
694
899
|
return
|
695
900
|
topic = self.safe_string(message, 'channel', '')
|
@@ -702,6 +907,7 @@ class hyperliquid(ccxt.async_support.hyperliquid):
|
|
702
907
|
'userFills': self.handle_my_trades,
|
703
908
|
'webData2': self.handle_ws_tickers,
|
704
909
|
'post': self.handle_ws_post,
|
910
|
+
'subscriptionResponse': self.handle_subscription_response,
|
705
911
|
}
|
706
912
|
exacMethod = self.safe_value(methods, topic)
|
707
913
|
if exacMethod is not None:
|
ccxt/pro/kucoin.py
CHANGED
@@ -11,7 +11,6 @@ from typing import List
|
|
11
11
|
from typing import Any
|
12
12
|
from ccxt.base.errors import ExchangeError
|
13
13
|
from ccxt.base.errors import ArgumentsRequired
|
14
|
-
from ccxt.base.errors import UnsubscribeError
|
15
14
|
|
16
15
|
|
17
16
|
class kucoin(ccxt.async_support.kucoin):
|
@@ -502,8 +501,6 @@ class kucoin(ccxt.async_support.kucoin):
|
|
502
501
|
unWatches trades stream
|
503
502
|
:see: https://www.kucoin.com/docs/websocket/spot-trading/public-channels/match-execution-data
|
504
503
|
:param str symbol: unified symbol of the market to fetch trades for
|
505
|
-
:param int [since]: timestamp in ms of the earliest trade to fetch
|
506
|
-
:param int [limit]: the maximum amount of trades to fetch
|
507
504
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
508
505
|
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
509
506
|
"""
|
@@ -851,46 +848,8 @@ class kucoin(ccxt.async_support.kucoin):
|
|
851
848
|
for i in range(0, len(messageHashes)):
|
852
849
|
messageHash = messageHashes[i]
|
853
850
|
subHash = subMessageHashes[i]
|
854
|
-
|
855
|
-
|
856
|
-
if subHash in client.subscriptions:
|
857
|
-
del client.subscriptions[subHash]
|
858
|
-
error = UnsubscribeError(self.id + ' ' + subHash)
|
859
|
-
client.reject(error, subHash)
|
860
|
-
client.resolve(True, messageHash)
|
861
|
-
self.clean_cache(subscription)
|
862
|
-
|
863
|
-
def clean_cache(self, subscription: dict):
|
864
|
-
topic = self.safe_string(subscription, 'topic')
|
865
|
-
symbols = self.safe_list(subscription, 'symbols', [])
|
866
|
-
symbolsLength = len(symbols)
|
867
|
-
if symbolsLength > 0:
|
868
|
-
for i in range(0, len(symbols)):
|
869
|
-
symbol = symbols[i]
|
870
|
-
if topic == 'trades':
|
871
|
-
if symbol in self.trades:
|
872
|
-
del self.trades[symbol]
|
873
|
-
elif topic == 'orderbook':
|
874
|
-
if symbol in self.orderbooks:
|
875
|
-
del self.orderbooks[symbol]
|
876
|
-
elif topic == 'ticker':
|
877
|
-
if symbol in self.tickers:
|
878
|
-
del self.tickers[symbol]
|
879
|
-
else:
|
880
|
-
if topic == 'myTrades':
|
881
|
-
# don't reset self.myTrades directly here
|
882
|
-
# because in c# we need to use a different object
|
883
|
-
keys = list(self.myTrades.keys())
|
884
|
-
for i in range(0, len(keys)):
|
885
|
-
del self.myTrades[keys[i]]
|
886
|
-
elif topic == 'orders':
|
887
|
-
orderSymbols = list(self.orders.keys())
|
888
|
-
for i in range(0, len(orderSymbols)):
|
889
|
-
del self.orders[orderSymbols[i]]
|
890
|
-
elif topic == 'ticker':
|
891
|
-
tickerSymbols = list(self.tickers.keys())
|
892
|
-
for i in range(0, len(tickerSymbols)):
|
893
|
-
del self.tickers[tickerSymbols[i]]
|
851
|
+
self.clean_unsubscription(client, subHash, messageHash)
|
852
|
+
self.clean_cache(subscription)
|
894
853
|
|
895
854
|
def handle_system_status(self, client: Client, message):
|
896
855
|
#
|
ccxt/pro/kucoinfutures.py
CHANGED
@@ -8,6 +8,7 @@ from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById,
|
|
8
8
|
from ccxt.base.types import Balances, Int, Order, OrderBook, Position, Str, Strings, Ticker, Tickers, Trade
|
9
9
|
from ccxt.async_support.base.ws.client import Client
|
10
10
|
from typing import List
|
11
|
+
from typing import Any
|
11
12
|
from ccxt.base.errors import ExchangeError
|
12
13
|
from ccxt.base.errors import ArgumentsRequired
|
13
14
|
|
@@ -175,6 +176,24 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
|
|
175
176
|
}
|
176
177
|
return await self.watch_multiple(url, messageHashes, self.extend(request, params), subscriptionHashes, subscriptionArgs)
|
177
178
|
|
179
|
+
async def un_subscribe_multiple(self, url, messageHashes, topic, subscriptionHashes, params={}, subscription: dict = None):
|
180
|
+
requestId = str(self.request_id())
|
181
|
+
request: dict = {
|
182
|
+
'id': requestId,
|
183
|
+
'type': 'unsubscribe',
|
184
|
+
'topic': topic,
|
185
|
+
'response': True,
|
186
|
+
}
|
187
|
+
message = self.extend(request, params)
|
188
|
+
if subscription is not None:
|
189
|
+
subscription[requestId] = requestId
|
190
|
+
client = self.client(url)
|
191
|
+
for i in range(0, len(subscriptionHashes)):
|
192
|
+
subscriptionHash = subscriptionHashes[i]
|
193
|
+
if not (subscriptionHash in client.subscriptions):
|
194
|
+
client.subscriptions[requestId] = subscriptionHash
|
195
|
+
return await self.watch_multiple(url, messageHashes, message, subscriptionHashes, subscription)
|
196
|
+
|
178
197
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
179
198
|
"""
|
180
199
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
@@ -526,6 +545,44 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
|
|
526
545
|
limit = trades.getLimit(tradeSymbol, limit)
|
527
546
|
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
528
547
|
|
548
|
+
async def un_watch_trades(self, symbol: str, params={}) -> Any:
|
549
|
+
"""
|
550
|
+
unWatches trades stream
|
551
|
+
:see: https://docs.kucoin.com/futures/#execution-data
|
552
|
+
:param str symbol: unified symbol of the market to fetch trades for
|
553
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
554
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
555
|
+
"""
|
556
|
+
return await self.un_watch_trades_for_symbols([symbol], params)
|
557
|
+
|
558
|
+
async def un_watch_trades_for_symbols(self, symbols: List[str], params={}) -> Any:
|
559
|
+
"""
|
560
|
+
get the list of most recent trades for a particular symbol
|
561
|
+
:param str symbol: unified symbol of the market to fetch trades for
|
562
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
563
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
564
|
+
"""
|
565
|
+
await self.load_markets()
|
566
|
+
symbols = self.market_symbols(symbols, None, False)
|
567
|
+
url = await self.negotiate(False)
|
568
|
+
symbols = self.market_symbols(symbols)
|
569
|
+
marketIds = self.market_ids(symbols)
|
570
|
+
topic = '/contractMarket/execution:' + ','.join(marketIds)
|
571
|
+
subscriptionHashes = []
|
572
|
+
messageHashes = []
|
573
|
+
for i in range(0, len(symbols)):
|
574
|
+
symbol = symbols[i]
|
575
|
+
messageHashes.append('unsubscribe:trades:' + symbol)
|
576
|
+
subscriptionHashes.append('trades:' + symbol)
|
577
|
+
subscription = {
|
578
|
+
'messageHashes': messageHashes,
|
579
|
+
'subMessageHashes': subscriptionHashes,
|
580
|
+
'topic': 'trades',
|
581
|
+
'unsubscribe': True,
|
582
|
+
'symbols': symbols,
|
583
|
+
}
|
584
|
+
return await self.un_subscribe_multiple(url, messageHashes, topic, messageHashes, params, subscription)
|
585
|
+
|
529
586
|
def handle_trade(self, client: Client, message):
|
530
587
|
#
|
531
588
|
# {
|
@@ -651,6 +708,7 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
|
|
651
708
|
async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
|
652
709
|
"""
|
653
710
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
711
|
+
:see: https://docs.kucoin.com/futures/#level-2-market-data
|
654
712
|
:param str[] symbols: unified array of symbols
|
655
713
|
:param int [limit]: the maximum amount of order book entries to return
|
656
714
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -680,6 +738,43 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
|
|
680
738
|
orderbook = await self.subscribe_multiple(url, messageHashes, topic, subscriptionHashes, subscriptionArgs, params)
|
681
739
|
return orderbook.limit()
|
682
740
|
|
741
|
+
async def un_watch_order_book(self, symbol: str, params={}) -> Any:
|
742
|
+
"""
|
743
|
+
unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
744
|
+
:see: https://docs.kucoin.com/futures/#level-2-market-data
|
745
|
+
:param str symbol: unified symbol of the market to fetch the order book for
|
746
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
747
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
748
|
+
"""
|
749
|
+
return await self.un_watch_order_book_for_symbols([symbol], params)
|
750
|
+
|
751
|
+
async def un_watch_order_book_for_symbols(self, symbols: List[str], params={}) -> Any:
|
752
|
+
"""
|
753
|
+
unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
754
|
+
:param str[] symbols: unified array of symbols
|
755
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
756
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
757
|
+
"""
|
758
|
+
await self.load_markets()
|
759
|
+
symbols = self.market_symbols(symbols)
|
760
|
+
marketIds = self.market_ids(symbols)
|
761
|
+
url = await self.negotiate(False)
|
762
|
+
topic = '/contractMarket/level2:' + ','.join(marketIds)
|
763
|
+
subscriptionHashes = []
|
764
|
+
messageHashes = []
|
765
|
+
for i in range(0, len(symbols)):
|
766
|
+
symbol = symbols[i]
|
767
|
+
messageHashes.append('unsubscribe:orderbook:' + symbol)
|
768
|
+
subscriptionHashes.append('orderbook:' + symbol)
|
769
|
+
subscription = {
|
770
|
+
'messageHashes': messageHashes,
|
771
|
+
'symbols': symbols,
|
772
|
+
'unsubscribe': True,
|
773
|
+
'topic': 'orderbook',
|
774
|
+
'subMessageHashes': subscriptionHashes,
|
775
|
+
}
|
776
|
+
return await self.un_subscribe_multiple(url, messageHashes, topic, messageHashes, params, subscription)
|
777
|
+
|
683
778
|
def handle_delta(self, orderbook, delta):
|
684
779
|
orderbook['nonce'] = self.safe_integer(delta, 'sequence')
|
685
780
|
timestamp = self.safe_integer(delta, 'timestamp')
|
@@ -1067,6 +1162,32 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
|
|
1067
1162
|
self.options['urls'][type] = None
|
1068
1163
|
self.handle_errors(None, None, client.url, None, None, data, message, None, None)
|
1069
1164
|
|
1165
|
+
def handle_subscription_status(self, client: Client, message):
|
1166
|
+
#
|
1167
|
+
# {
|
1168
|
+
# "id": "1578090438322",
|
1169
|
+
# "type": "ack"
|
1170
|
+
# }
|
1171
|
+
#
|
1172
|
+
id = self.safe_string(message, 'id')
|
1173
|
+
if not (id in client.subscriptions):
|
1174
|
+
return
|
1175
|
+
subscriptionHash = self.safe_string(client.subscriptions, id)
|
1176
|
+
subscription = self.safe_value(client.subscriptions, subscriptionHash)
|
1177
|
+
del client.subscriptions[id]
|
1178
|
+
method = self.safe_value(subscription, 'method')
|
1179
|
+
if method is not None:
|
1180
|
+
method(client, message, subscription)
|
1181
|
+
isUnSub = self.safe_bool(subscription, 'unsubscribe', False)
|
1182
|
+
if isUnSub:
|
1183
|
+
messageHashes = self.safe_list(subscription, 'messageHashes', [])
|
1184
|
+
subMessageHashes = self.safe_list(subscription, 'subMessageHashes', [])
|
1185
|
+
for i in range(0, len(messageHashes)):
|
1186
|
+
messageHash = messageHashes[i]
|
1187
|
+
subHash = subMessageHashes[i]
|
1188
|
+
self.clean_unsubscription(client, subHash, messageHash)
|
1189
|
+
self.clean_cache(subscription)
|
1190
|
+
|
1070
1191
|
def handle_message(self, client: Client, message):
|
1071
1192
|
type = self.safe_string(message, 'type')
|
1072
1193
|
methods: dict = {
|
@@ -1075,6 +1196,7 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
|
|
1075
1196
|
'message': self.handle_subject,
|
1076
1197
|
'pong': self.handle_pong,
|
1077
1198
|
'error': self.handle_error_message,
|
1199
|
+
'ack': self.handle_subscription_status,
|
1078
1200
|
}
|
1079
1201
|
method = self.safe_value(methods, type)
|
1080
1202
|
if method is not None:
|
ccxt/pro/okx.py
CHANGED
@@ -16,7 +16,6 @@ from ccxt.base.errors import ArgumentsRequired
|
|
16
16
|
from ccxt.base.errors import BadRequest
|
17
17
|
from ccxt.base.errors import InvalidNonce
|
18
18
|
from ccxt.base.errors import ChecksumError
|
19
|
-
from ccxt.base.errors import UnsubscribeError
|
20
19
|
|
21
20
|
|
22
21
|
class okx(ccxt.async_support.okx):
|
@@ -2162,54 +2161,32 @@ class okx(ccxt.async_support.okx):
|
|
2162
2161
|
def handle_un_subscription_trades(self, client: Client, symbol: str):
|
2163
2162
|
subMessageHash = 'trades:' + symbol
|
2164
2163
|
messageHash = 'unsubscribe:trades:' + symbol
|
2165
|
-
|
2166
|
-
|
2167
|
-
|
2168
|
-
del client.subscriptions[messageHash]
|
2169
|
-
del self.trades[symbol]
|
2170
|
-
error = UnsubscribeError(self.id + ' ' + subMessageHash)
|
2171
|
-
client.reject(error, subMessageHash)
|
2172
|
-
client.resolve(True, messageHash)
|
2164
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
2165
|
+
if symbol in self.trades:
|
2166
|
+
del self.trades[symbol]
|
2173
2167
|
|
2174
2168
|
def handle_unsubscription_order_book(self, client: Client, symbol: str, channel: str):
|
2175
2169
|
subMessageHash = channel + ':' + symbol
|
2176
2170
|
messageHash = 'unsubscribe:orderbook:' + symbol
|
2177
|
-
|
2178
|
-
|
2179
|
-
|
2180
|
-
del client.subscriptions[messageHash]
|
2181
|
-
del self.orderbooks[symbol]
|
2182
|
-
error = UnsubscribeError(self.id + ' ' + subMessageHash)
|
2183
|
-
client.reject(error, subMessageHash)
|
2184
|
-
client.resolve(True, messageHash)
|
2171
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
2172
|
+
if symbol in self.orderbooks:
|
2173
|
+
del self.orderbooks[symbol]
|
2185
2174
|
|
2186
2175
|
def handle_unsubscription_ohlcv(self, client: Client, symbol: str, channel: str):
|
2187
2176
|
tf = channel.replace('candle', '')
|
2188
2177
|
timeframe = self.find_timeframe(tf)
|
2189
2178
|
subMessageHash = 'multi:' + channel + ':' + symbol
|
2190
2179
|
messageHash = 'unsubscribe:' + subMessageHash
|
2191
|
-
|
2192
|
-
del client.subscriptions[subMessageHash]
|
2193
|
-
if messageHash in client.subscriptions:
|
2194
|
-
del client.subscriptions[messageHash]
|
2180
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
2195
2181
|
if timeframe in self.ohlcvs[symbol]:
|
2196
2182
|
del self.ohlcvs[symbol][timeframe]
|
2197
|
-
error = UnsubscribeError(self.id + ' ' + subMessageHash)
|
2198
|
-
client.reject(error, subMessageHash)
|
2199
|
-
client.resolve(True, messageHash)
|
2200
2183
|
|
2201
2184
|
def handle_unsubscription_ticker(self, client: Client, symbol: str, channel):
|
2202
2185
|
subMessageHash = channel + '::' + symbol
|
2203
2186
|
messageHash = 'unsubscribe:ticker:' + symbol
|
2204
|
-
|
2205
|
-
del client.subscriptions[subMessageHash]
|
2206
|
-
if messageHash in client.subscriptions:
|
2207
|
-
del client.subscriptions[messageHash]
|
2187
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
2208
2188
|
if symbol in self.tickers:
|
2209
2189
|
del self.tickers[symbol]
|
2210
|
-
error = UnsubscribeError(self.id + ' ' + subMessageHash)
|
2211
|
-
client.reject(error, subMessageHash)
|
2212
|
-
client.resolve(True, messageHash)
|
2213
2190
|
|
2214
2191
|
def handle_unsubscription(self, client: Client, message):
|
2215
2192
|
#
|
ccxt/xt.py
CHANGED
@@ -1355,7 +1355,7 @@ class xt(Exchange, ImplicitAPI):
|
|
1355
1355
|
self.safe_number(ohlcv, 'h'),
|
1356
1356
|
self.safe_number(ohlcv, 'l'),
|
1357
1357
|
self.safe_number(ohlcv, 'c'),
|
1358
|
-
self.safe_number_2(ohlcv,
|
1358
|
+
self.safe_number_2(ohlcv, 'q', volumeIndex),
|
1359
1359
|
]
|
1360
1360
|
|
1361
1361
|
def fetch_order_book(self, symbol: str, limit: Int = None, params={}):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ccxt
|
3
|
-
Version: 4.
|
3
|
+
Version: 4.4.2
|
4
4
|
Summary: A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges
|
5
5
|
Home-page: https://ccxt.com
|
6
6
|
Author: Igor Kroitor
|
@@ -95,7 +95,7 @@ Current feature list:
|
|
95
95
|
| [](https://www.coinbase.com/join/58cbe25a355148797479dbd2) | coinbase | [Coinbase Advanced](https://www.coinbase.com/join/58cbe25a355148797479dbd2) | [](https://developers.coinbase.com/api/v2) | cex | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | |
|
96
96
|
| [](https://international.coinbase.com) | coinbaseinternational | [Coinbase International](https://international.coinbase.com) | [](https://docs.cloud.coinbase.com/intx/docs) | cex | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | |
|
97
97
|
| [](https://www.coinex.com/register?refer_code=yw5fz) | coinex | [CoinEx](https://www.coinex.com/register?refer_code=yw5fz) | [](https://docs.coinex.com/api/v2) | cex | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | |
|
98
|
-
| [](https://crypto.com/exch/kdacthrnxt) | cryptocom | [Crypto.com](https://crypto.com/exch/kdacthrnxt) | [](https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html) | cex | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | [](https://crypto.com/exch/kdacthrnxt) | cryptocom | [Crypto.com](https://crypto.com/exch/kdacthrnxt) | [](https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html) | cex | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | [](https://crypto.com/exch/kdacthrnxt) |
|
99
99
|
| [](https://www.gate.io/signup/2436035) | gate | [Gate.io](https://www.gate.io/signup/2436035) | [](https://www.gate.io/docs/developers/apiv4/en/) | cex | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | [](https://www.gate.io/signup/2436035) |
|
100
100
|
| [](https://global.hashkey.com/en-US/register/invite?invite_code=82FQUN) | hashkey | [HashKey Global](https://global.hashkey.com/en-US/register/invite?invite_code=82FQUN) | [](https://hashkeyglobal-apidoc.readme.io/) | cex | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | |
|
101
101
|
| [](https://www.huobi.com/en-us/v/register/double-invite/?inviter_id=11343840&invite_code=6rmm2223) | htx | [HTX](https://www.huobi.com/en-us/v/register/double-invite/?inviter_id=11343840&invite_code=6rmm2223) | [](https://huobiapi.github.io/docs/spot/v1/en/) | cex | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | [](https://www.huobi.com/en-us/v/register/double-invite/?inviter_id=11343840&invite_code=6rmm2223) |
|
@@ -272,13 +272,13 @@ console.log(version, Object.keys(exchanges));
|
|
272
272
|
|
273
273
|
All-in-one browser bundle (dependencies included), served from a CDN of your choice:
|
274
274
|
|
275
|
-
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.
|
276
|
-
* unpkg: https://unpkg.com/ccxt@4.
|
275
|
+
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.4.2/dist/ccxt.browser.min.js
|
276
|
+
* unpkg: https://unpkg.com/ccxt@4.4.2/dist/ccxt.browser.min.js
|
277
277
|
|
278
278
|
CDNs are not updated in real-time and may have delays. Defaulting to the most recent version without specifying the version number is not recommended. Please, keep in mind that we are not responsible for the correct operation of those CDN servers.
|
279
279
|
|
280
280
|
```HTML
|
281
|
-
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.
|
281
|
+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.4.2/dist/ccxt.browser.min.js"></script>
|
282
282
|
```
|
283
283
|
|
284
284
|
Creates a global `ccxt` object:
|