ccxt 4.3.95__py2.py3-none-any.whl → 4.3.97__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 -5
- ccxt/async_support/__init__.py +1 -5
- ccxt/async_support/base/exchange.py +1 -4
- ccxt/async_support/binance.py +2 -0
- ccxt/async_support/bingx.py +1 -0
- ccxt/async_support/blofin.py +0 -1
- ccxt/async_support/bybit.py +7 -2
- ccxt/async_support/coinex.py +15 -3
- ccxt/async_support/hyperliquid.py +243 -29
- ccxt/async_support/kucoin.py +12 -12
- ccxt/async_support/mexc.py +6 -0
- ccxt/async_support/okx.py +0 -1
- ccxt/async_support/p2b.py +0 -1
- ccxt/async_support/tradeogre.py +0 -1
- ccxt/base/exchange.py +1 -5
- ccxt/binance.py +2 -0
- ccxt/bingx.py +1 -0
- ccxt/blofin.py +0 -1
- ccxt/bybit.py +7 -2
- ccxt/coinex.py +15 -3
- ccxt/hyperliquid.py +243 -29
- ccxt/kucoin.py +2 -2
- ccxt/mexc.py +6 -0
- ccxt/okx.py +0 -1
- ccxt/p2b.py +0 -1
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +90 -2
- ccxt/pro/bybit.py +58 -4
- ccxt/pro/cryptocom.py +195 -0
- ccxt/pro/gate.py +155 -0
- ccxt/pro/kucoin.py +107 -0
- ccxt/pro/okx.py +238 -31
- ccxt/tradeogre.py +0 -1
- {ccxt-4.3.95.dist-info → ccxt-4.3.97.dist-info}/METADATA +5 -5
- {ccxt-4.3.95.dist-info → ccxt-4.3.97.dist-info}/RECORD +38 -40
- ccxt/abstract/bitbay.py +0 -53
- ccxt/abstract/hitbtc3.py +0 -115
- {ccxt-4.3.95.dist-info → ccxt-4.3.97.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.3.95.dist-info → ccxt-4.3.97.dist-info}/WHEEL +0 -0
- {ccxt-4.3.95.dist-info → ccxt-4.3.97.dist-info}/top_level.txt +0 -0
ccxt/pro/gate.py
CHANGED
@@ -9,12 +9,14 @@ import hashlib
|
|
9
9
|
from ccxt.base.types import Balances, Int, Liquidation, Market, MarketType, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade
|
10
10
|
from ccxt.async_support.base.ws.client import Client
|
11
11
|
from typing import List
|
12
|
+
from typing import Any
|
12
13
|
from ccxt.base.errors import ExchangeError
|
13
14
|
from ccxt.base.errors import AuthenticationError
|
14
15
|
from ccxt.base.errors import ArgumentsRequired
|
15
16
|
from ccxt.base.errors import BadRequest
|
16
17
|
from ccxt.base.errors import NotSupported
|
17
18
|
from ccxt.base.errors import ChecksumError
|
19
|
+
from ccxt.base.errors import UnsubscribeError
|
18
20
|
from ccxt.base.precise import Precise
|
19
21
|
|
20
22
|
|
@@ -371,6 +373,31 @@ class gate(ccxt.async_support.gate):
|
|
371
373
|
orderbook = await self.subscribe_public(url, messageHash, payload, channel, query, subscription)
|
372
374
|
return orderbook.limit()
|
373
375
|
|
376
|
+
async def un_watch_order_book(self, symbol: str, params={}) -> Any:
|
377
|
+
"""
|
378
|
+
unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
379
|
+
:param str symbol: unified symbol of the market to fetch the order book for
|
380
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
381
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
382
|
+
"""
|
383
|
+
await self.load_markets()
|
384
|
+
market = self.market(symbol)
|
385
|
+
symbol = market['symbol']
|
386
|
+
marketId = market['id']
|
387
|
+
interval = '100ms'
|
388
|
+
interval, params = self.handle_option_and_params(params, 'watchOrderBook', 'interval', interval)
|
389
|
+
messageType = self.get_type_by_market(market)
|
390
|
+
channel = messageType + '.order_book_update'
|
391
|
+
subMessageHash = 'orderbook' + ':' + symbol
|
392
|
+
messageHash = 'unsubscribe:orderbook' + ':' + symbol
|
393
|
+
url = self.get_url_by_market(market)
|
394
|
+
payload = [marketId, interval]
|
395
|
+
limit = self.safe_integer(params, 'limit', 100)
|
396
|
+
if market['contract']:
|
397
|
+
stringLimit = str(limit)
|
398
|
+
payload.append(stringLimit)
|
399
|
+
return await self.un_subscribe_public_multiple(url, 'orderbook', [symbol], [messageHash], [subMessageHash], payload, channel, params)
|
400
|
+
|
374
401
|
def handle_order_book_subscription(self, client: Client, message, subscription):
|
375
402
|
symbol = self.safe_string(subscription, 'symbol')
|
376
403
|
limit = self.safe_integer(subscription, 'limit')
|
@@ -671,6 +698,37 @@ class gate(ccxt.async_support.gate):
|
|
671
698
|
limit = trades.getLimit(tradeSymbol, limit)
|
672
699
|
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
673
700
|
|
701
|
+
async def un_watch_trades_for_symbols(self, symbols: List[str], params={}) -> Any:
|
702
|
+
"""
|
703
|
+
get the list of most recent trades for a particular symbol
|
704
|
+
:param str symbol: unified symbol of the market to fetch trades for
|
705
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
706
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
707
|
+
"""
|
708
|
+
await self.load_markets()
|
709
|
+
symbols = self.market_symbols(symbols)
|
710
|
+
marketIds = self.market_ids(symbols)
|
711
|
+
market = self.market(symbols[0])
|
712
|
+
messageType = self.get_type_by_market(market)
|
713
|
+
channel = messageType + '.trades'
|
714
|
+
subMessageHashes = []
|
715
|
+
messageHashes = []
|
716
|
+
for i in range(0, len(symbols)):
|
717
|
+
symbol = symbols[i]
|
718
|
+
subMessageHashes.append('trades:' + symbol)
|
719
|
+
messageHashes.append('unsubscribe:trades:' + symbol)
|
720
|
+
url = self.get_url_by_market(market)
|
721
|
+
return await self.un_subscribe_public_multiple(url, 'trades', symbols, messageHashes, subMessageHashes, marketIds, channel, params)
|
722
|
+
|
723
|
+
async def un_watch_trades(self, symbol: str, params={}) -> Any:
|
724
|
+
"""
|
725
|
+
get the list of most recent trades for a particular symbol
|
726
|
+
:param str symbol: unified symbol of the market to fetch trades for
|
727
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
728
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
729
|
+
"""
|
730
|
+
return await self.un_watch_trades_for_symbols([symbol], params)
|
731
|
+
|
674
732
|
def handle_trades(self, client: Client, message):
|
675
733
|
#
|
676
734
|
# {
|
@@ -1445,6 +1503,79 @@ class gate(ccxt.async_support.gate):
|
|
1445
1503
|
if id in client.subscriptions:
|
1446
1504
|
del client.subscriptions[id]
|
1447
1505
|
|
1506
|
+
def handle_un_subscribe(self, client: Client, message):
|
1507
|
+
#
|
1508
|
+
# {
|
1509
|
+
# "time":1725534679,
|
1510
|
+
# "time_ms":1725534679786,
|
1511
|
+
# "id":2,
|
1512
|
+
# "conn_id":"fac539b443fd7002",
|
1513
|
+
# "trace_id":"efe1d282b630b4aa266b84bee177791a",
|
1514
|
+
# "channel":"spot.trades",
|
1515
|
+
# "event":"unsubscribe",
|
1516
|
+
# "payload":[
|
1517
|
+
# "LTC_USDT"
|
1518
|
+
# ],
|
1519
|
+
# "result":{
|
1520
|
+
# "status":"success"
|
1521
|
+
# },
|
1522
|
+
# "requestId":"efe1d282b630b4aa266b84bee177791a"
|
1523
|
+
# }
|
1524
|
+
#
|
1525
|
+
id = self.safe_string(message, 'id')
|
1526
|
+
keys = list(client.subscriptions.keys())
|
1527
|
+
for i in range(0, len(keys)):
|
1528
|
+
messageHash = keys[i]
|
1529
|
+
if not (messageHash in client.subscriptions):
|
1530
|
+
continue
|
1531
|
+
# the previous iteration can have deleted the messageHash from the subscriptions
|
1532
|
+
if messageHash.startswith('unsubscribe'):
|
1533
|
+
subscription = client.subscriptions[messageHash]
|
1534
|
+
subId = self.safe_string(subscription, 'id')
|
1535
|
+
if id != subId:
|
1536
|
+
continue
|
1537
|
+
messageHashes = self.safe_list(subscription, 'messageHashes', [])
|
1538
|
+
subMessageHashes = self.safe_list(subscription, 'subMessageHashes', [])
|
1539
|
+
for j in range(0, len(messageHashes)):
|
1540
|
+
unsubHash = messageHashes[j]
|
1541
|
+
subHash = subMessageHashes[j]
|
1542
|
+
if unsubHash in client.subscriptions:
|
1543
|
+
del client.subscriptions[unsubHash]
|
1544
|
+
if subHash in client.subscriptions:
|
1545
|
+
del client.subscriptions[subHash]
|
1546
|
+
error = UnsubscribeError(self.id + ' ' + messageHash)
|
1547
|
+
client.reject(error, subHash)
|
1548
|
+
client.resolve(True, unsubHash)
|
1549
|
+
self.clean_cache(subscription)
|
1550
|
+
|
1551
|
+
def clean_cache(self, subscription: dict):
|
1552
|
+
topic = self.safe_string(subscription, 'topic', '')
|
1553
|
+
symbols = self.safe_list(subscription, 'symbols', [])
|
1554
|
+
symbolsLength = len(symbols)
|
1555
|
+
if topic == 'ohlcv':
|
1556
|
+
symbolsAndTimeFrames = self.safe_list(subscription, 'symbolsAndTimeframes', [])
|
1557
|
+
for i in range(0, len(symbolsAndTimeFrames)):
|
1558
|
+
symbolAndTimeFrame = symbolsAndTimeFrames[i]
|
1559
|
+
symbol = self.safe_string(symbolAndTimeFrame, 0)
|
1560
|
+
timeframe = self.safe_string(symbolAndTimeFrame, 1)
|
1561
|
+
del self.ohlcvs[symbol][timeframe]
|
1562
|
+
elif symbolsLength > 0:
|
1563
|
+
for i in range(0, len(symbols)):
|
1564
|
+
symbol = symbols[i]
|
1565
|
+
if topic.endswith('trades'):
|
1566
|
+
del self.trades[symbol]
|
1567
|
+
elif topic == 'orderbook':
|
1568
|
+
del self.orderbooks[symbol]
|
1569
|
+
elif topic == 'ticker':
|
1570
|
+
del self.tickers[symbol]
|
1571
|
+
else:
|
1572
|
+
if topic.endswith('trades'):
|
1573
|
+
# don't reset self.myTrades directly here
|
1574
|
+
# because in c# we need to use a different object
|
1575
|
+
keys = list(self.trades.keys())
|
1576
|
+
for i in range(0, len(keys)):
|
1577
|
+
del self.trades[keys[i]]
|
1578
|
+
|
1448
1579
|
def handle_message(self, client: Client, message):
|
1449
1580
|
#
|
1450
1581
|
# subscribe
|
@@ -1541,6 +1672,9 @@ class gate(ccxt.async_support.gate):
|
|
1541
1672
|
if event == 'subscribe':
|
1542
1673
|
self.handle_subscription_status(client, message)
|
1543
1674
|
return
|
1675
|
+
if event == 'unsubscribe':
|
1676
|
+
self.handle_un_subscribe(client, message)
|
1677
|
+
return
|
1544
1678
|
channel = self.safe_string(message, 'channel', '')
|
1545
1679
|
channelParts = channel.split('.')
|
1546
1680
|
channelType = self.safe_value(channelParts, 1)
|
@@ -1645,6 +1779,27 @@ class gate(ccxt.async_support.gate):
|
|
1645
1779
|
message = self.extend(request, params)
|
1646
1780
|
return await self.watch_multiple(url, messageHashes, message, messageHashes)
|
1647
1781
|
|
1782
|
+
async def un_subscribe_public_multiple(self, url, topic, symbols, messageHashes, subMessageHashes, payload, channel, params={}):
|
1783
|
+
requestId = self.request_id()
|
1784
|
+
time = self.seconds()
|
1785
|
+
request: dict = {
|
1786
|
+
'id': requestId,
|
1787
|
+
'time': time,
|
1788
|
+
'channel': channel,
|
1789
|
+
'event': 'unsubscribe',
|
1790
|
+
'payload': payload,
|
1791
|
+
}
|
1792
|
+
sub = {
|
1793
|
+
'id': str(requestId),
|
1794
|
+
'topic': topic,
|
1795
|
+
'unsubscribe': True,
|
1796
|
+
'messageHashes': messageHashes,
|
1797
|
+
'subMessageHashes': subMessageHashes,
|
1798
|
+
'symbols': symbols,
|
1799
|
+
}
|
1800
|
+
message = self.extend(request, params)
|
1801
|
+
return await self.watch_multiple(url, messageHashes, message, messageHashes, sub)
|
1802
|
+
|
1648
1803
|
async def authenticate(self, url, messageType):
|
1649
1804
|
channel = messageType + '.login'
|
1650
1805
|
client = self.client(url)
|
ccxt/pro/kucoin.py
CHANGED
@@ -8,8 +8,10 @@ from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById,
|
|
8
8
|
from ccxt.base.types import Balances, Int, Order, OrderBook, 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
|
14
|
+
from ccxt.base.errors import UnsubscribeError
|
13
15
|
|
14
16
|
|
15
17
|
class kucoin(ccxt.async_support.kucoin):
|
@@ -153,6 +155,24 @@ class kucoin(ccxt.async_support.kucoin):
|
|
153
155
|
client.subscriptions[requestId] = subscriptionHash
|
154
156
|
return await self.watch_multiple(url, messageHashes, message, subscriptionHashes, subscription)
|
155
157
|
|
158
|
+
async def un_subscribe_multiple(self, url, messageHashes, topic, subscriptionHashes, params={}, subscription: dict = None):
|
159
|
+
requestId = str(self.request_id())
|
160
|
+
request: dict = {
|
161
|
+
'id': requestId,
|
162
|
+
'type': 'unsubscribe',
|
163
|
+
'topic': topic,
|
164
|
+
'response': True,
|
165
|
+
}
|
166
|
+
message = self.extend(request, params)
|
167
|
+
if subscription is not None:
|
168
|
+
subscription[requestId] = requestId
|
169
|
+
client = self.client(url)
|
170
|
+
for i in range(0, len(subscriptionHashes)):
|
171
|
+
subscriptionHash = subscriptionHashes[i]
|
172
|
+
if not (subscriptionHash in client.subscriptions):
|
173
|
+
client.subscriptions[requestId] = subscriptionHash
|
174
|
+
return await self.watch_multiple(url, messageHashes, message, subscriptionHashes, subscription)
|
175
|
+
|
156
176
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
157
177
|
"""
|
158
178
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
@@ -477,6 +497,46 @@ class kucoin(ccxt.async_support.kucoin):
|
|
477
497
|
limit = trades.getLimit(tradeSymbol, limit)
|
478
498
|
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
479
499
|
|
500
|
+
async def un_watch_trades_for_symbols(self, symbols: List[str], params={}) -> Any:
|
501
|
+
"""
|
502
|
+
unWatches trades stream
|
503
|
+
:see: https://www.kucoin.com/docs/websocket/spot-trading/public-channels/match-execution-data
|
504
|
+
: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
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
508
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
509
|
+
"""
|
510
|
+
await self.load_markets()
|
511
|
+
symbols = self.market_symbols(symbols, None, False)
|
512
|
+
marketIds = self.market_ids(symbols)
|
513
|
+
url = await self.negotiate(False)
|
514
|
+
messageHashes = []
|
515
|
+
subscriptionHashes = []
|
516
|
+
topic = '/market/match:' + ','.join(marketIds)
|
517
|
+
for i in range(0, len(symbols)):
|
518
|
+
symbol = symbols[i]
|
519
|
+
messageHashes.append('unsubscribe:trades:' + symbol)
|
520
|
+
subscriptionHashes.append('trades:' + symbol)
|
521
|
+
subscription = {
|
522
|
+
'messageHashes': messageHashes,
|
523
|
+
'subMessageHashes': subscriptionHashes,
|
524
|
+
'topic': 'trades',
|
525
|
+
'unsubscribe': True,
|
526
|
+
'symbols': symbols,
|
527
|
+
}
|
528
|
+
return await self.un_subscribe_multiple(url, messageHashes, topic, messageHashes, params, subscription)
|
529
|
+
|
530
|
+
async def un_watch_trades(self, symbol: str, params={}) -> Any:
|
531
|
+
"""
|
532
|
+
unWatches trades stream
|
533
|
+
:see: https://www.kucoin.com/docs/websocket/spot-trading/public-channels/match-execution-data
|
534
|
+
:param str symbol: unified symbol of the market to fetch trades for
|
535
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
536
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
537
|
+
"""
|
538
|
+
return await self.un_watch_trades_for_symbols([symbol], params)
|
539
|
+
|
480
540
|
def handle_trade(self, client: Client, message):
|
481
541
|
#
|
482
542
|
# {
|
@@ -731,6 +791,53 @@ class kucoin(ccxt.async_support.kucoin):
|
|
731
791
|
method = self.safe_value(subscription, 'method')
|
732
792
|
if method is not None:
|
733
793
|
method(client, message, subscription)
|
794
|
+
isUnSub = self.safe_bool(subscription, 'unsubscribe', False)
|
795
|
+
if isUnSub:
|
796
|
+
messageHashes = self.safe_list(subscription, 'messageHashes', [])
|
797
|
+
subMessageHashes = self.safe_list(subscription, 'subMessageHashes', [])
|
798
|
+
for i in range(0, len(messageHashes)):
|
799
|
+
messageHash = messageHashes[i]
|
800
|
+
subHash = subMessageHashes[i]
|
801
|
+
if messageHash in client.subscriptions:
|
802
|
+
del client.subscriptions[messageHash]
|
803
|
+
if subHash in client.subscriptions:
|
804
|
+
del client.subscriptions[subHash]
|
805
|
+
error = UnsubscribeError(self.id + ' ' + subHash)
|
806
|
+
client.reject(error, subHash)
|
807
|
+
client.resolve(True, messageHash)
|
808
|
+
self.clean_cache(subscription)
|
809
|
+
|
810
|
+
def clean_cache(self, subscription: dict):
|
811
|
+
topic = self.safe_string(subscription, 'topic')
|
812
|
+
symbols = self.safe_list(subscription, 'symbols', [])
|
813
|
+
symbolsLength = len(symbols)
|
814
|
+
if symbolsLength > 0:
|
815
|
+
for i in range(0, len(symbols)):
|
816
|
+
symbol = symbols[i]
|
817
|
+
if topic == 'trades':
|
818
|
+
if symbol in self.trades:
|
819
|
+
del self.trades[symbol]
|
820
|
+
elif topic == 'orderbook':
|
821
|
+
if symbol in self.orderbooks:
|
822
|
+
del self.orderbooks[symbol]
|
823
|
+
elif topic == 'ticker':
|
824
|
+
if symbol in self.tickers:
|
825
|
+
del self.tickers[symbol]
|
826
|
+
else:
|
827
|
+
if topic == 'myTrades':
|
828
|
+
# don't reset self.myTrades directly here
|
829
|
+
# because in c# we need to use a different object
|
830
|
+
keys = list(self.myTrades.keys())
|
831
|
+
for i in range(0, len(keys)):
|
832
|
+
del self.myTrades[keys[i]]
|
833
|
+
elif topic == 'orders':
|
834
|
+
orderSymbols = list(self.orders.keys())
|
835
|
+
for i in range(0, len(orderSymbols)):
|
836
|
+
del self.orders[orderSymbols[i]]
|
837
|
+
elif topic == 'ticker':
|
838
|
+
tickerSymbols = list(self.tickers.keys())
|
839
|
+
for i in range(0, len(tickerSymbols)):
|
840
|
+
del self.tickers[tickerSymbols[i]]
|
734
841
|
|
735
842
|
def handle_system_status(self, client: Client, message):
|
736
843
|
#
|