ccxt 4.4.1__py2.py3-none-any.whl → 4.4.3__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/abstract/bitmart.py +1 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/binance.py +81 -18
- ccxt/async_support/bitmart.py +3 -1
- ccxt/async_support/bitstamp.py +24 -36
- ccxt/async_support/bybit.py +2 -0
- ccxt/async_support/cryptocom.py +3 -2
- ccxt/async_support/currencycom.py +1 -2
- ccxt/async_support/htx.py +1 -1
- ccxt/async_support/mexc.py +76 -1
- ccxt/async_support/xt.py +6 -2
- ccxt/base/exchange.py +53 -1
- ccxt/base/types.py +2 -2
- ccxt/binance.py +81 -18
- ccxt/bitmart.py +3 -1
- ccxt/bitstamp.py +24 -36
- ccxt/bybit.py +2 -0
- ccxt/cryptocom.py +3 -2
- ccxt/currencycom.py +1 -2
- ccxt/htx.py +1 -1
- ccxt/mexc.py +76 -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 +183 -53
- ccxt/pro/gate.py +1 -8
- ccxt/pro/hyperliquid.py +4 -29
- ccxt/pro/kucoin.py +2 -43
- ccxt/pro/kucoinfutures.py +122 -0
- ccxt/pro/mexc.py +76 -4
- ccxt/pro/okx.py +13 -34
- ccxt/pro/oxfun.py +70 -0
- ccxt/pro/phemex.py +41 -2
- ccxt/pro/woofipro.py +64 -0
- ccxt/xt.py +6 -2
- {ccxt-4.4.1.dist-info → ccxt-4.4.3.dist-info}/METADATA +5 -5
- {ccxt-4.4.1.dist-info → ccxt-4.4.3.dist-info}/RECORD +44 -44
- {ccxt-4.4.1.dist-info → ccxt-4.4.3.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.1.dist-info → ccxt-4.4.3.dist-info}/WHEEL +0 -0
- {ccxt-4.4.1.dist-info → ccxt-4.4.3.dist-info}/top_level.txt +0 -0
ccxt/pro/__init__.py
CHANGED
ccxt/pro/binance.py
CHANGED
@@ -14,7 +14,6 @@ from ccxt.base.errors import ArgumentsRequired
|
|
14
14
|
from ccxt.base.errors import BadRequest
|
15
15
|
from ccxt.base.errors import NotSupported
|
16
16
|
from ccxt.base.errors import ChecksumError
|
17
|
-
from ccxt.base.errors import UnsubscribeError
|
18
17
|
from ccxt.base.precise import Precise
|
19
18
|
|
20
19
|
|
@@ -952,52 +951,9 @@ class binance(ccxt.async_support.binance):
|
|
952
951
|
for j in range(0, len(messageHashes)):
|
953
952
|
unsubHash = messageHashes[j]
|
954
953
|
subHash = subMessageHashes[j]
|
955
|
-
|
956
|
-
del client.subscriptions[unsubHash]
|
957
|
-
if subHash in client.subscriptions:
|
958
|
-
del client.subscriptions[subHash]
|
959
|
-
error = UnsubscribeError(self.id + ' ' + subHash)
|
960
|
-
client.reject(error, subHash)
|
961
|
-
client.resolve(True, unsubHash)
|
954
|
+
self.clean_unsubscription(client, subHash, unsubHash)
|
962
955
|
self.clean_cache(subscription)
|
963
956
|
|
964
|
-
def clean_cache(self, subscription: dict):
|
965
|
-
topic = self.safe_string(subscription, 'topic')
|
966
|
-
symbols = self.safe_list(subscription, 'symbols', [])
|
967
|
-
symbolsLength = len(symbols)
|
968
|
-
if topic == 'ohlcv':
|
969
|
-
symbolsAndTimeFrames = self.safe_list(subscription, 'symbolsAndTimeframes', [])
|
970
|
-
for i in range(0, len(symbolsAndTimeFrames)):
|
971
|
-
symbolAndTimeFrame = symbolsAndTimeFrames[i]
|
972
|
-
symbol = self.safe_string(symbolAndTimeFrame, 0)
|
973
|
-
timeframe = self.safe_string(symbolAndTimeFrame, 1)
|
974
|
-
if timeframe in self.ohlcvs[symbol]:
|
975
|
-
del self.ohlcvs[symbol][timeframe]
|
976
|
-
elif symbolsLength > 0:
|
977
|
-
for i in range(0, len(symbols)):
|
978
|
-
symbol = symbols[i]
|
979
|
-
if topic == 'trade':
|
980
|
-
del self.trades[symbol]
|
981
|
-
elif topic == 'orderbook':
|
982
|
-
del self.orderbooks[symbol]
|
983
|
-
elif topic == 'ticker':
|
984
|
-
del self.tickers[symbol]
|
985
|
-
else:
|
986
|
-
if topic == 'myTrades':
|
987
|
-
# don't reset self.myTrades directly here
|
988
|
-
# because in c# we need to use a different object
|
989
|
-
keys = list(self.myTrades.keys())
|
990
|
-
for i in range(0, len(keys)):
|
991
|
-
del self.myTrades[keys[i]]
|
992
|
-
elif topic == 'orders':
|
993
|
-
orderSymbols = list(self.orders.keys())
|
994
|
-
for i in range(0, len(orderSymbols)):
|
995
|
-
del self.orders[orderSymbols[i]]
|
996
|
-
elif topic == 'ticker':
|
997
|
-
tickerSymbols = list(self.tickers.keys())
|
998
|
-
for i in range(0, len(tickerSymbols)):
|
999
|
-
del self.tickers[tickerSymbols[i]]
|
1000
|
-
|
1001
957
|
async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
1002
958
|
"""
|
1003
959
|
get the list of most recent trades for a list of symbols
|
@@ -1106,7 +1062,7 @@ class binance(ccxt.async_support.binance):
|
|
1106
1062
|
'subMessageHashes': subMessageHashes,
|
1107
1063
|
'messageHashes': messageHashes,
|
1108
1064
|
'symbols': symbols,
|
1109
|
-
'topic': '
|
1065
|
+
'topic': 'trades',
|
1110
1066
|
}
|
1111
1067
|
return await self.watch_multiple(url, messageHashes, self.extend(request, query), messageHashes, subscription)
|
1112
1068
|
|
@@ -1810,7 +1766,7 @@ class binance(ccxt.async_support.binance):
|
|
1810
1766
|
result = await self.watch_multi_ticker_helper('watchBidsAsks', 'bookTicker', symbols, params)
|
1811
1767
|
if self.newUpdates:
|
1812
1768
|
return result
|
1813
|
-
return self.filter_by_array(self.
|
1769
|
+
return self.filter_by_array(self.bidsasks, 'symbol', symbols)
|
1814
1770
|
|
1815
1771
|
async def watch_multi_ticker_helper(self, methodName, channelName: str, symbols: Strings = None, params={}):
|
1816
1772
|
await self.load_markets()
|
ccxt/pro/bitget.py
CHANGED
@@ -1876,13 +1876,7 @@ class bitget(ccxt.async_support.bitget):
|
|
1876
1876
|
if symbol in self.ohlcvs:
|
1877
1877
|
if timeframe in self.ohlcvs[symbol]:
|
1878
1878
|
del self.ohlcvs[symbol][timeframe]
|
1879
|
-
|
1880
|
-
del client.subscriptions[subMessageHash]
|
1881
|
-
if messageHash in client.subscriptions:
|
1882
|
-
del client.subscriptions[messageHash]
|
1883
|
-
error = UnsubscribeError(self.id + ' ohlcv ' + timeframe + ' ' + symbol)
|
1884
|
-
client.reject(error, subMessageHash)
|
1885
|
-
client.resolve(True, messageHash)
|
1879
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
1886
1880
|
|
1887
1881
|
def handle_un_subscription_status(self, client: Client, message):
|
1888
1882
|
#
|
ccxt/pro/bitmex.py
CHANGED
@@ -66,6 +66,7 @@ class bitmex(ccxt.async_support.bitmex):
|
|
66
66
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
67
67
|
"""
|
68
68
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
69
|
+
:see: https://www.bitmex.com/app/wsAPI#Subscriptions
|
69
70
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
70
71
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
71
72
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
@@ -78,6 +79,7 @@ class bitmex(ccxt.async_support.bitmex):
|
|
78
79
|
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
79
80
|
"""
|
80
81
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
82
|
+
:see: https://www.bitmex.com/app/wsAPI#Subscriptions
|
81
83
|
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
82
84
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
83
85
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
@@ -449,6 +451,7 @@ class bitmex(ccxt.async_support.bitmex):
|
|
449
451
|
async def watch_balance(self, params={}) -> Balances:
|
450
452
|
"""
|
451
453
|
watch balance and get the amount of funds available for trading or funds locked in orders
|
454
|
+
:see: https://www.bitmex.com/app/wsAPI#Subscriptions
|
452
455
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
453
456
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
454
457
|
"""
|
@@ -651,6 +654,7 @@ class bitmex(ccxt.async_support.bitmex):
|
|
651
654
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
652
655
|
"""
|
653
656
|
get the list of most recent trades for a particular symbol
|
657
|
+
:see: https://www.bitmex.com/app/wsAPI#Subscriptions
|
654
658
|
:param str symbol: unified symbol of the market to fetch trades for
|
655
659
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
656
660
|
:param int [limit]: the maximum amount of trades to fetch
|
@@ -697,8 +701,8 @@ class bitmex(ccxt.async_support.bitmex):
|
|
697
701
|
|
698
702
|
async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
|
699
703
|
"""
|
700
|
-
:see: https://www.bitmex.com/app/wsAPI
|
701
704
|
watch all open positions
|
705
|
+
:see: https://www.bitmex.com/app/wsAPI#Subscriptions
|
702
706
|
:param str[]|None symbols: list of unified market symbols
|
703
707
|
:param dict params: extra parameters specific to the exchange API endpoint
|
704
708
|
:returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
|
@@ -894,6 +898,7 @@ class bitmex(ccxt.async_support.bitmex):
|
|
894
898
|
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
895
899
|
"""
|
896
900
|
watches information on multiple orders made by the user
|
901
|
+
:see: https://www.bitmex.com/app/wsAPI#Subscriptions
|
897
902
|
:param str symbol: unified market symbol of the market orders were made in
|
898
903
|
:param int [since]: the earliest time in ms to fetch orders for
|
899
904
|
:param int [limit]: the maximum number of order structures to retrieve
|
@@ -1100,6 +1105,7 @@ class bitmex(ccxt.async_support.bitmex):
|
|
1100
1105
|
async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
1101
1106
|
"""
|
1102
1107
|
watches information on multiple trades made by the user
|
1108
|
+
:see: https://www.bitmex.com/app/wsAPI#Subscriptions
|
1103
1109
|
:param str symbol: unified market symbol of the market trades were made in
|
1104
1110
|
:param int [since]: the earliest time in ms to fetch trades for
|
1105
1111
|
:param int [limit]: the maximum number of trade structures to retrieve
|
@@ -1209,6 +1215,7 @@ class bitmex(ccxt.async_support.bitmex):
|
|
1209
1215
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
1210
1216
|
"""
|
1211
1217
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
1218
|
+
:see: https://www.bitmex.com/app/wsAPI#OrderBookL2
|
1212
1219
|
:param str symbol: unified symbol of the market to fetch the order book for
|
1213
1220
|
:param int [limit]: the maximum amount of order book entries to return
|
1214
1221
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1219,6 +1226,7 @@ class bitmex(ccxt.async_support.bitmex):
|
|
1219
1226
|
async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
|
1220
1227
|
"""
|
1221
1228
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
1229
|
+
:see: https://www.bitmex.com/app/wsAPI#OrderBookL2
|
1222
1230
|
:param str[] symbols: unified array of symbols
|
1223
1231
|
:param int [limit]: the maximum amount of order book entries to return
|
1224
1232
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1255,6 +1263,7 @@ class bitmex(ccxt.async_support.bitmex):
|
|
1255
1263
|
async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
1256
1264
|
"""
|
1257
1265
|
get the list of most recent trades for a list of symbols
|
1266
|
+
:see: https://www.bitmex.com/app/wsAPI#Subscriptions
|
1258
1267
|
:param str[] symbols: unified symbol of the market to fetch trades for
|
1259
1268
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
1260
1269
|
:param int [limit]: the maximum amount of trades to fetch
|
@@ -1288,6 +1297,7 @@ class bitmex(ccxt.async_support.bitmex):
|
|
1288
1297
|
async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
1289
1298
|
"""
|
1290
1299
|
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
1300
|
+
:see: https://www.bitmex.com/app/wsAPI#Subscriptions
|
1291
1301
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
1292
1302
|
:param str timeframe: the length of time each candle represents
|
1293
1303
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
ccxt/pro/bybit.py
CHANGED
@@ -15,7 +15,6 @@ from ccxt.base.errors import ExchangeError
|
|
15
15
|
from ccxt.base.errors import AuthenticationError
|
16
16
|
from ccxt.base.errors import ArgumentsRequired
|
17
17
|
from ccxt.base.errors import BadRequest
|
18
|
-
from ccxt.base.errors import UnsubscribeError
|
19
18
|
|
20
19
|
|
21
20
|
class bybit(ccxt.async_support.bybit):
|
@@ -953,7 +952,7 @@ class bybit(ccxt.async_support.bybit):
|
|
953
952
|
messageHash = 'unsubscribe:trade:' + symbol
|
954
953
|
messageHashes.append(messageHash)
|
955
954
|
subMessageHashes.append('trade:' + symbol)
|
956
|
-
return await self.un_watch_topics(url, '
|
955
|
+
return await self.un_watch_topics(url, 'trades', symbols, messageHashes, subMessageHashes, topics, params)
|
957
956
|
|
958
957
|
async def un_watch_trades(self, symbol: str, params={}) -> Any:
|
959
958
|
"""
|
@@ -2310,44 +2309,6 @@ class bybit(ccxt.async_support.bybit):
|
|
2310
2309
|
for j in range(0, len(messageHashes)):
|
2311
2310
|
unsubHash = messageHashes[j]
|
2312
2311
|
subHash = subMessageHashes[j]
|
2313
|
-
|
2314
|
-
del client.subscriptions[unsubHash]
|
2315
|
-
if subHash in client.subscriptions:
|
2316
|
-
del client.subscriptions[subHash]
|
2317
|
-
error = UnsubscribeError(self.id + ' ' + messageHash)
|
2318
|
-
client.reject(error, subHash)
|
2319
|
-
client.resolve(True, unsubHash)
|
2312
|
+
self.clean_unsubscription(client, subHash, unsubHash)
|
2320
2313
|
self.clean_cache(subscription)
|
2321
2314
|
return message
|
2322
|
-
|
2323
|
-
def clean_cache(self, subscription: dict):
|
2324
|
-
topic = self.safe_string(subscription, 'topic')
|
2325
|
-
symbols = self.safe_list(subscription, 'symbols', [])
|
2326
|
-
symbolsLength = len(symbols)
|
2327
|
-
if topic == 'ohlcv':
|
2328
|
-
symbolsAndTimeFrames = self.safe_list(subscription, 'symbolsAndTimeframes', [])
|
2329
|
-
for i in range(0, len(symbolsAndTimeFrames)):
|
2330
|
-
symbolAndTimeFrame = symbolsAndTimeFrames[i]
|
2331
|
-
symbol = self.safe_string(symbolAndTimeFrame, 0)
|
2332
|
-
timeframe = self.safe_string(symbolAndTimeFrame, 1)
|
2333
|
-
del self.ohlcvs[symbol][timeframe]
|
2334
|
-
elif symbolsLength > 0:
|
2335
|
-
for i in range(0, len(symbols)):
|
2336
|
-
symbol = symbols[i]
|
2337
|
-
if topic == 'trade':
|
2338
|
-
del self.trades[symbol]
|
2339
|
-
elif topic == 'orderbook':
|
2340
|
-
del self.orderbooks[symbol]
|
2341
|
-
elif topic == 'ticker':
|
2342
|
-
del self.tickers[symbol]
|
2343
|
-
else:
|
2344
|
-
if topic == 'myTrades':
|
2345
|
-
# don't reset self.myTrades directly here
|
2346
|
-
# because in c# we need to use a different object
|
2347
|
-
keys = list(self.myTrades.keys())
|
2348
|
-
for i in range(0, len(keys)):
|
2349
|
-
del self.myTrades[keys[i]]
|
2350
|
-
elif topic == 'orders':
|
2351
|
-
orderSymbols = list(self.orders.keys())
|
2352
|
-
for i in range(0, len(orderSymbols)):
|
2353
|
-
del self.orders[orderSymbols[i]]
|
ccxt/pro/cryptocom.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
import ccxt.async_support
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Int, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Trade
|
9
|
+
from ccxt.base.types import Balances, Int, Market, Num, Order, OrderBook, 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
12
|
from typing import Any
|
@@ -14,7 +14,6 @@ from ccxt.base.errors import ExchangeError
|
|
14
14
|
from ccxt.base.errors import AuthenticationError
|
15
15
|
from ccxt.base.errors import NetworkError
|
16
16
|
from ccxt.base.errors import ChecksumError
|
17
|
-
from ccxt.base.errors import UnsubscribeError
|
18
17
|
|
19
18
|
|
20
19
|
class cryptocom(ccxt.async_support.cryptocom):
|
@@ -25,7 +24,8 @@ class cryptocom(ccxt.async_support.cryptocom):
|
|
25
24
|
'ws': True,
|
26
25
|
'watchBalance': True,
|
27
26
|
'watchTicker': True,
|
28
|
-
'watchTickers':
|
27
|
+
'watchTickers': True,
|
28
|
+
'watchBidsAsks': True,
|
29
29
|
'watchMyTrades': True,
|
30
30
|
'watchTrades': True,
|
31
31
|
'watchTradesForSymbols': True,
|
@@ -349,7 +349,7 @@ class cryptocom(ccxt.async_support.cryptocom):
|
|
349
349
|
currentTopic = 'trade' + '.' + market['id']
|
350
350
|
messageHashes.append('unsubscribe:trades:' + market['symbol'])
|
351
351
|
topics.append(currentTopic)
|
352
|
-
return await self.un_watch_public_multiple('
|
352
|
+
return await self.un_watch_public_multiple('trades', symbols, messageHashes, topics, topics, params)
|
353
353
|
|
354
354
|
def handle_trades(self, client: Client, message):
|
355
355
|
#
|
@@ -444,40 +444,198 @@ class cryptocom(ccxt.async_support.cryptocom):
|
|
444
444
|
messageHash = 'unsubscribe:ticker:' + market['symbol']
|
445
445
|
return await self.un_watch_public_multiple('ticker', [market['symbol']], [messageHash], [subMessageHash], [subMessageHash], params)
|
446
446
|
|
447
|
+
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
448
|
+
"""
|
449
|
+
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
450
|
+
:see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#ticker-instrument_name
|
451
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
452
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
453
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
454
|
+
"""
|
455
|
+
await self.load_markets()
|
456
|
+
symbols = self.market_symbols(symbols, None, False)
|
457
|
+
messageHashes = []
|
458
|
+
marketIds = self.market_ids(symbols)
|
459
|
+
for i in range(0, len(marketIds)):
|
460
|
+
marketId = marketIds[i]
|
461
|
+
messageHashes.append('ticker.' + marketId)
|
462
|
+
url = self.urls['api']['ws']['public']
|
463
|
+
id = self.nonce()
|
464
|
+
request: dict = {
|
465
|
+
'method': 'subscribe',
|
466
|
+
'params': {
|
467
|
+
'channels': messageHashes,
|
468
|
+
},
|
469
|
+
'nonce': id,
|
470
|
+
}
|
471
|
+
ticker = await self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
|
472
|
+
if self.newUpdates:
|
473
|
+
result: dict = {}
|
474
|
+
result[ticker['symbol']] = ticker
|
475
|
+
return result
|
476
|
+
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
477
|
+
|
478
|
+
async def un_watch_tickers(self, symbols: Strings = None, params={}) -> Any:
|
479
|
+
"""
|
480
|
+
unWatches a price ticker
|
481
|
+
:see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#ticker-instrument_name
|
482
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
483
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
484
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
485
|
+
"""
|
486
|
+
await self.load_markets()
|
487
|
+
symbols = self.market_symbols(symbols, None, False)
|
488
|
+
messageHashes = []
|
489
|
+
subMessageHashes = []
|
490
|
+
marketIds = self.market_ids(symbols)
|
491
|
+
for i in range(0, len(marketIds)):
|
492
|
+
marketId = marketIds[i]
|
493
|
+
symbol = symbols[i]
|
494
|
+
subMessageHashes.append('ticker.' + marketId)
|
495
|
+
messageHashes.append('unsubscribe:ticker:' + symbol)
|
496
|
+
return await self.un_watch_public_multiple('ticker', symbols, messageHashes, subMessageHashes, subMessageHashes, params)
|
497
|
+
|
447
498
|
def handle_ticker(self, client: Client, message):
|
448
499
|
#
|
449
|
-
#
|
450
|
-
#
|
451
|
-
#
|
452
|
-
#
|
453
|
-
#
|
454
|
-
#
|
455
|
-
#
|
456
|
-
#
|
457
|
-
#
|
458
|
-
#
|
459
|
-
#
|
460
|
-
#
|
461
|
-
#
|
462
|
-
#
|
463
|
-
#
|
464
|
-
#
|
465
|
-
#
|
466
|
-
#
|
500
|
+
# {
|
501
|
+
# "instrument_name": "ETHUSD-PERP",
|
502
|
+
# "subscription": "ticker.ETHUSD-PERP",
|
503
|
+
# "channel": "ticker",
|
504
|
+
# "data": [
|
505
|
+
# {
|
506
|
+
# "h": "2400.20",
|
507
|
+
# "l": "2277.10",
|
508
|
+
# "a": "2335.25",
|
509
|
+
# "c": "-0.0022",
|
510
|
+
# "b": "2335.10",
|
511
|
+
# "bs": "5.4000",
|
512
|
+
# "k": "2335.16",
|
513
|
+
# "ks": "1.9970",
|
514
|
+
# "i": "ETHUSD-PERP",
|
515
|
+
# "v": "1305697.6462",
|
516
|
+
# "vv": "3058704939.17",
|
517
|
+
# "oi": "161646.3614",
|
518
|
+
# "t": 1726069647560
|
519
|
+
# }
|
520
|
+
# ]
|
467
521
|
# }
|
468
|
-
# }
|
469
522
|
#
|
523
|
+
self.handle_bid_ask(client, message)
|
470
524
|
messageHash = self.safe_string(message, 'subscription')
|
471
525
|
marketId = self.safe_string(message, 'instrument_name')
|
472
526
|
market = self.safe_market(marketId)
|
473
527
|
data = self.safe_value(message, 'data', [])
|
474
528
|
for i in range(0, len(data)):
|
475
529
|
ticker = data[i]
|
476
|
-
parsed = self.
|
530
|
+
parsed = self.parse_ws_ticker(ticker, market)
|
477
531
|
symbol = parsed['symbol']
|
478
532
|
self.tickers[symbol] = parsed
|
479
533
|
client.resolve(parsed, messageHash)
|
480
534
|
|
535
|
+
def parse_ws_ticker(self, ticker: dict, market: Market = None) -> Ticker:
|
536
|
+
#
|
537
|
+
# {
|
538
|
+
# "h": "2400.20",
|
539
|
+
# "l": "2277.10",
|
540
|
+
# "a": "2335.25",
|
541
|
+
# "c": "-0.0022",
|
542
|
+
# "b": "2335.10",
|
543
|
+
# "bs": "5.4000",
|
544
|
+
# "k": "2335.16",
|
545
|
+
# "ks": "1.9970",
|
546
|
+
# "i": "ETHUSD-PERP",
|
547
|
+
# "v": "1305697.6462",
|
548
|
+
# "vv": "3058704939.17",
|
549
|
+
# "oi": "161646.3614",
|
550
|
+
# "t": 1726069647560
|
551
|
+
# }
|
552
|
+
#
|
553
|
+
timestamp = self.safe_integer(ticker, 't')
|
554
|
+
marketId = self.safe_string(ticker, 'i')
|
555
|
+
market = self.safe_market(marketId, market, '_')
|
556
|
+
quote = self.safe_string(market, 'quote')
|
557
|
+
last = self.safe_string(ticker, 'a')
|
558
|
+
return self.safe_ticker({
|
559
|
+
'symbol': market['symbol'],
|
560
|
+
'timestamp': timestamp,
|
561
|
+
'datetime': self.iso8601(timestamp),
|
562
|
+
'high': self.safe_number(ticker, 'h'),
|
563
|
+
'low': self.safe_number(ticker, 'l'),
|
564
|
+
'bid': self.safe_number(ticker, 'b'),
|
565
|
+
'bidVolume': self.safe_number(ticker, 'bs'),
|
566
|
+
'ask': self.safe_number(ticker, 'k'),
|
567
|
+
'askVolume': self.safe_number(ticker, 'ks'),
|
568
|
+
'vwap': None,
|
569
|
+
'open': None,
|
570
|
+
'close': last,
|
571
|
+
'last': last,
|
572
|
+
'previousClose': None,
|
573
|
+
'change': None,
|
574
|
+
'percentage': self.safe_string(ticker, 'c'),
|
575
|
+
'average': None,
|
576
|
+
'baseVolume': self.safe_string(ticker, 'v'),
|
577
|
+
'quoteVolume': self.safe_string(ticker, 'vv') if (quote == 'USD') else None,
|
578
|
+
'info': ticker,
|
579
|
+
}, market)
|
580
|
+
|
581
|
+
async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
|
582
|
+
"""
|
583
|
+
:see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#ticker-instrument_name
|
584
|
+
watches best bid & ask for symbols
|
585
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
586
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
587
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
588
|
+
"""
|
589
|
+
await self.load_markets()
|
590
|
+
symbols = self.market_symbols(symbols, None, False)
|
591
|
+
messageHashes = []
|
592
|
+
topics = []
|
593
|
+
marketIds = self.market_ids(symbols)
|
594
|
+
for i in range(0, len(marketIds)):
|
595
|
+
marketId = marketIds[i]
|
596
|
+
messageHashes.append('bidask.' + symbols[i])
|
597
|
+
topics.append('ticker.' + marketId)
|
598
|
+
url = self.urls['api']['ws']['public']
|
599
|
+
id = self.nonce()
|
600
|
+
request: dict = {
|
601
|
+
'method': 'subscribe',
|
602
|
+
'params': {
|
603
|
+
'channels': topics,
|
604
|
+
},
|
605
|
+
'nonce': id,
|
606
|
+
}
|
607
|
+
newTickers = await self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
|
608
|
+
if self.newUpdates:
|
609
|
+
tickers: dict = {}
|
610
|
+
tickers[newTickers['symbol']] = newTickers
|
611
|
+
return tickers
|
612
|
+
return self.filter_by_array(self.bidsasks, 'symbol', symbols)
|
613
|
+
|
614
|
+
def handle_bid_ask(self, client: Client, message):
|
615
|
+
data = self.safe_list(message, 'data', [])
|
616
|
+
ticker = self.safe_dict(data, 0, {})
|
617
|
+
parsedTicker = self.parse_ws_bid_ask(ticker)
|
618
|
+
symbol = parsedTicker['symbol']
|
619
|
+
self.bidsasks[symbol] = parsedTicker
|
620
|
+
messageHash = 'bidask.' + symbol
|
621
|
+
client.resolve(parsedTicker, messageHash)
|
622
|
+
|
623
|
+
def parse_ws_bid_ask(self, ticker, market=None):
|
624
|
+
marketId = self.safe_string(ticker, 'i')
|
625
|
+
market = self.safe_market(marketId, market)
|
626
|
+
symbol = self.safe_string(market, 'symbol')
|
627
|
+
timestamp = self.safe_integer(ticker, 't')
|
628
|
+
return self.safe_ticker({
|
629
|
+
'symbol': symbol,
|
630
|
+
'timestamp': timestamp,
|
631
|
+
'datetime': self.iso8601(timestamp),
|
632
|
+
'ask': self.safe_string(ticker, 'k'),
|
633
|
+
'askVolume': self.safe_string(ticker, 'ks'),
|
634
|
+
'bid': self.safe_string(ticker, 'b'),
|
635
|
+
'bidVolume': self.safe_string(ticker, 'bs'),
|
636
|
+
'info': ticker,
|
637
|
+
}, market)
|
638
|
+
|
481
639
|
async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
482
640
|
"""
|
483
641
|
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
@@ -1118,33 +1276,5 @@ class cryptocom(ccxt.async_support.cryptocom):
|
|
1118
1276
|
for j in range(0, len(messageHashes)):
|
1119
1277
|
unsubHash = messageHashes[j]
|
1120
1278
|
subHash = subMessageHashes[j]
|
1121
|
-
|
1122
|
-
del client.subscriptions[unsubHash]
|
1123
|
-
if subHash in client.subscriptions:
|
1124
|
-
del client.subscriptions[subHash]
|
1125
|
-
error = UnsubscribeError(self.id + ' ' + subHash)
|
1126
|
-
client.reject(error, subHash)
|
1127
|
-
client.resolve(True, unsubHash)
|
1279
|
+
self.clean_unsubscription(client, subHash, unsubHash)
|
1128
1280
|
self.clean_cache(subscription)
|
1129
|
-
|
1130
|
-
def clean_cache(self, subscription: dict):
|
1131
|
-
topic = self.safe_string(subscription, 'topic')
|
1132
|
-
symbols = self.safe_list(subscription, 'symbols', [])
|
1133
|
-
symbolsLength = len(symbols)
|
1134
|
-
if topic == 'ohlcv':
|
1135
|
-
symbolsAndTimeFrames = self.safe_list(subscription, 'symbolsAndTimeframes', [])
|
1136
|
-
for i in range(0, len(symbolsAndTimeFrames)):
|
1137
|
-
symbolAndTimeFrame = symbolsAndTimeFrames[i]
|
1138
|
-
symbol = self.safe_string(symbolAndTimeFrame, 0)
|
1139
|
-
timeframe = self.safe_string(symbolAndTimeFrame, 1)
|
1140
|
-
if timeframe in self.ohlcvs[symbol]:
|
1141
|
-
del self.ohlcvs[symbol][timeframe]
|
1142
|
-
elif symbolsLength > 0:
|
1143
|
-
for i in range(0, len(symbols)):
|
1144
|
-
symbol = symbols[i]
|
1145
|
-
if topic == 'trade':
|
1146
|
-
del self.trades[symbol]
|
1147
|
-
elif topic == 'orderbook':
|
1148
|
-
del self.orderbooks[symbol]
|
1149
|
-
elif topic == 'ticker':
|
1150
|
-
del self.tickers[symbol]
|
ccxt/pro/gate.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 NotSupported
|
18
18
|
from ccxt.base.errors import ChecksumError
|
19
|
-
from ccxt.base.errors import UnsubscribeError
|
20
19
|
from ccxt.base.precise import Precise
|
21
20
|
|
22
21
|
|
@@ -1539,13 +1538,7 @@ class gate(ccxt.async_support.gate):
|
|
1539
1538
|
for j in range(0, len(messageHashes)):
|
1540
1539
|
unsubHash = messageHashes[j]
|
1541
1540
|
subHash = subMessageHashes[j]
|
1542
|
-
|
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)
|
1541
|
+
self.clean_unsubscription(client, subHash, unsubHash)
|
1549
1542
|
self.clean_cache(subscription)
|
1550
1543
|
|
1551
1544
|
def clean_cache(self, subscription: dict):
|
ccxt/pro/hyperliquid.py
CHANGED
@@ -10,7 +10,6 @@ from ccxt.async_support.base.ws.client import Client
|
|
10
10
|
from typing import List
|
11
11
|
from typing import Any
|
12
12
|
from ccxt.base.errors import ExchangeError
|
13
|
-
from ccxt.base.errors import UnsubscribeError
|
14
13
|
|
15
14
|
|
16
15
|
class hyperliquid(ccxt.async_support.hyperliquid):
|
@@ -805,13 +804,7 @@ class hyperliquid(ccxt.async_support.hyperliquid):
|
|
805
804
|
symbol = self.safe_symbol(marketId)
|
806
805
|
subMessageHash = 'orderbook:' + symbol
|
807
806
|
messageHash = 'unsubscribe:' + subMessageHash
|
808
|
-
|
809
|
-
del client.subscriptions[messageHash]
|
810
|
-
if subMessageHash in client.subscriptions:
|
811
|
-
del client.subscriptions[subMessageHash]
|
812
|
-
error = UnsubscribeError(self.id + ' ' + subMessageHash)
|
813
|
-
client.reject(error, subMessageHash)
|
814
|
-
client.resolve(True, messageHash)
|
807
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
815
808
|
if symbol in self.orderbooks:
|
816
809
|
del self.orderbooks[symbol]
|
817
810
|
|
@@ -822,13 +815,7 @@ class hyperliquid(ccxt.async_support.hyperliquid):
|
|
822
815
|
symbol = self.safe_symbol(marketId)
|
823
816
|
subMessageHash = 'trade:' + symbol
|
824
817
|
messageHash = 'unsubscribe:' + subMessageHash
|
825
|
-
|
826
|
-
del client.subscriptions[messageHash]
|
827
|
-
if subMessageHash in client.subscriptions:
|
828
|
-
del client.subscriptions[subMessageHash]
|
829
|
-
error = UnsubscribeError(self.id + ' ' + subMessageHash)
|
830
|
-
client.reject(error, subMessageHash)
|
831
|
-
client.resolve(True, messageHash)
|
818
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
832
819
|
if symbol in self.trades:
|
833
820
|
del self.trades[symbol]
|
834
821
|
|
@@ -836,13 +823,7 @@ class hyperliquid(ccxt.async_support.hyperliquid):
|
|
836
823
|
#
|
837
824
|
subMessageHash = 'tickers'
|
838
825
|
messageHash = 'unsubscribe:' + subMessageHash
|
839
|
-
|
840
|
-
del client.subscriptions[messageHash]
|
841
|
-
if subMessageHash in client.subscriptions:
|
842
|
-
del client.subscriptions[subMessageHash]
|
843
|
-
error = UnsubscribeError(self.id + ' ' + subMessageHash)
|
844
|
-
client.reject(error, subMessageHash)
|
845
|
-
client.resolve(True, messageHash)
|
826
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
846
827
|
symbols = list(self.tickers.keys())
|
847
828
|
for i in range(0, len(symbols)):
|
848
829
|
del self.tickers[symbols[i]]
|
@@ -855,13 +836,7 @@ class hyperliquid(ccxt.async_support.hyperliquid):
|
|
855
836
|
timeframe = self.find_timeframe(interval)
|
856
837
|
subMessageHash = 'candles:' + timeframe + ':' + symbol
|
857
838
|
messageHash = 'unsubscribe:' + subMessageHash
|
858
|
-
|
859
|
-
del client.subscriptions[messageHash]
|
860
|
-
if subMessageHash in client.subscriptions:
|
861
|
-
del client.subscriptions[subMessageHash]
|
862
|
-
error = UnsubscribeError(self.id + ' ' + subMessageHash)
|
863
|
-
client.reject(error, subMessageHash)
|
864
|
-
client.resolve(True, messageHash)
|
839
|
+
self.clean_unsubscription(client, subMessageHash, messageHash)
|
865
840
|
if symbol in self.ohlcvs:
|
866
841
|
if timeframe in self.ohlcvs[symbol]:
|
867
842
|
del self.ohlcvs[symbol][timeframe]
|