ccxt 4.3.83__py2.py3-none-any.whl → 4.3.85__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 +2 -1
- ccxt/abstract/cryptocom.py +2 -0
- ccxt/abstract/kucoinfutures.py +2 -0
- ccxt/async_support/__init__.py +2 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/binance.py +1 -1
- ccxt/async_support/bitfinex2.py +2 -2
- ccxt/async_support/bitmex.py +2 -0
- ccxt/async_support/bybit.py +16 -14
- ccxt/async_support/cryptocom.py +113 -3
- ccxt/async_support/kraken.py +32 -7
- ccxt/async_support/kucoinfutures.py +5 -0
- ccxt/async_support/mexc.py +2 -2
- ccxt/base/errors.py +6 -0
- ccxt/base/exchange.py +1 -1
- ccxt/binance.py +1 -1
- ccxt/bitfinex2.py +2 -2
- ccxt/bitmex.py +2 -0
- ccxt/bybit.py +16 -14
- ccxt/cryptocom.py +113 -3
- ccxt/kraken.py +32 -7
- ccxt/kucoinfutures.py +5 -0
- ccxt/mexc.py +2 -2
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +7 -2
- ccxt/pro/bitget.py +104 -4
- ccxt/pro/bitrue.py +1 -7
- ccxt/pro/gate.py +4 -4
- ccxt/pro/okx.py +21 -3
- {ccxt-4.3.83.dist-info → ccxt-4.3.85.dist-info}/METADATA +4 -4
- {ccxt-4.3.83.dist-info → ccxt-4.3.85.dist-info}/RECORD +34 -34
- {ccxt-4.3.83.dist-info → ccxt-4.3.85.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.3.83.dist-info → ccxt-4.3.85.dist-info}/WHEEL +0 -0
- {ccxt-4.3.83.dist-info → ccxt-4.3.85.dist-info}/top_level.txt +0 -0
ccxt/cryptocom.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.cryptocom import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
|
9
|
+
from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import ExchangeError
|
12
12
|
from ccxt.base.errors import AuthenticationError
|
@@ -109,8 +109,8 @@ class cryptocom(Exchange, ImplicitAPI):
|
|
109
109
|
'fetchTickers': True,
|
110
110
|
'fetchTime': False,
|
111
111
|
'fetchTrades': True,
|
112
|
-
'fetchTradingFee':
|
113
|
-
'fetchTradingFees':
|
112
|
+
'fetchTradingFee': True,
|
113
|
+
'fetchTradingFees': True,
|
114
114
|
'fetchTransactionFees': False,
|
115
115
|
'fetchTransactions': False,
|
116
116
|
'fetchTransfers': False,
|
@@ -211,6 +211,8 @@ class cryptocom(Exchange, ImplicitAPI):
|
|
211
211
|
'private/get-accounts': 10 / 3,
|
212
212
|
'private/get-withdrawal-history': 10 / 3,
|
213
213
|
'private/get-deposit-history': 10 / 3,
|
214
|
+
'private/get-fee-rate': 2,
|
215
|
+
'private/get-instrument-fee-rate': 2,
|
214
216
|
'private/staking/stake': 2,
|
215
217
|
'private/staking/unstake': 2,
|
216
218
|
'private/staking/get-staking-position': 2,
|
@@ -2806,6 +2808,114 @@ class cryptocom(Exchange, ImplicitAPI):
|
|
2806
2808
|
result = self.safe_dict(response, 'result')
|
2807
2809
|
return self.parse_order(result, market)
|
2808
2810
|
|
2811
|
+
def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
|
2812
|
+
"""
|
2813
|
+
fetch the trading fees for a market
|
2814
|
+
:see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-get-instrument-fee-rate
|
2815
|
+
:param str symbol: unified market symbol
|
2816
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2817
|
+
:returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
|
2818
|
+
"""
|
2819
|
+
self.load_markets()
|
2820
|
+
market = self.market(symbol)
|
2821
|
+
request: dict = {
|
2822
|
+
'instrument_name': market['id'],
|
2823
|
+
}
|
2824
|
+
response = self.v1PrivatePostPrivateGetInstrumentFeeRate(self.extend(request, params))
|
2825
|
+
#
|
2826
|
+
# {
|
2827
|
+
# "id": 1,
|
2828
|
+
# "code": 0,
|
2829
|
+
# "method": "private/staking/unstake",
|
2830
|
+
# "result": {
|
2831
|
+
# "staking_id": "1",
|
2832
|
+
# "instrument_name": "SOL.staked",
|
2833
|
+
# "status": "NEW",
|
2834
|
+
# "quantity": "1",
|
2835
|
+
# "underlying_inst_name": "SOL",
|
2836
|
+
# "reason": "NO_ERROR"
|
2837
|
+
# }
|
2838
|
+
# }
|
2839
|
+
#
|
2840
|
+
data = self.safe_dict(response, 'result', {})
|
2841
|
+
return self.parse_trading_fee(data, market)
|
2842
|
+
|
2843
|
+
def fetch_trading_fees(self, params={}) -> TradingFees:
|
2844
|
+
"""
|
2845
|
+
:see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-get-fee-rate
|
2846
|
+
fetch the trading fees for multiple markets
|
2847
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2848
|
+
:returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
|
2849
|
+
"""
|
2850
|
+
self.load_markets()
|
2851
|
+
response = self.v1PrivatePostPrivateGetFeeRate(params)
|
2852
|
+
#
|
2853
|
+
# {
|
2854
|
+
# "id": 1,
|
2855
|
+
# "method": "/private/get-fee-rate",
|
2856
|
+
# "code": 0,
|
2857
|
+
# "result": {
|
2858
|
+
# "spot_tier": "3",
|
2859
|
+
# "deriv_tier": "3",
|
2860
|
+
# "effective_spot_maker_rate_bps": "6.5",
|
2861
|
+
# "effective_spot_taker_rate_bps": "6.9",
|
2862
|
+
# "effective_deriv_maker_rate_bps": "1.1",
|
2863
|
+
# "effective_deriv_taker_rate_bps": "3"
|
2864
|
+
# }
|
2865
|
+
# }
|
2866
|
+
#
|
2867
|
+
result = self.safe_dict(response, 'result', {})
|
2868
|
+
return self.parse_trading_fees(result)
|
2869
|
+
|
2870
|
+
def parse_trading_fees(self, response):
|
2871
|
+
#
|
2872
|
+
# {
|
2873
|
+
# "spot_tier": "3",
|
2874
|
+
# "deriv_tier": "3",
|
2875
|
+
# "effective_spot_maker_rate_bps": "6.5",
|
2876
|
+
# "effective_spot_taker_rate_bps": "6.9",
|
2877
|
+
# "effective_deriv_maker_rate_bps": "1.1",
|
2878
|
+
# "effective_deriv_taker_rate_bps": "3"
|
2879
|
+
# }
|
2880
|
+
#
|
2881
|
+
result: dict = {}
|
2882
|
+
result['info'] = response
|
2883
|
+
for i in range(0, len(self.symbols)):
|
2884
|
+
symbol = self.symbols[i]
|
2885
|
+
market = self.market(symbol)
|
2886
|
+
isSwap = market['swap']
|
2887
|
+
takerFeeKey = 'effective_deriv_taker_rate_bps' if isSwap else 'effective_spot_taker_rate_bps'
|
2888
|
+
makerFeeKey = 'effective_deriv_maker_rate_bps' if isSwap else 'effective_spot_maker_rate_bps'
|
2889
|
+
tradingFee = {
|
2890
|
+
'info': response,
|
2891
|
+
'symbol': symbol,
|
2892
|
+
'maker': self.parse_number(Precise.string_div(self.safe_string(response, makerFeeKey), '10000')),
|
2893
|
+
'taker': self.parse_number(Precise.string_div(self.safe_string(response, takerFeeKey), '10000')),
|
2894
|
+
'percentage': None,
|
2895
|
+
'tierBased': None,
|
2896
|
+
}
|
2897
|
+
result[symbol] = tradingFee
|
2898
|
+
return result
|
2899
|
+
|
2900
|
+
def parse_trading_fee(self, fee: dict, market: Market = None) -> TradingFeeInterface:
|
2901
|
+
#
|
2902
|
+
# {
|
2903
|
+
# "instrument_name": "BTC_USD",
|
2904
|
+
# "effective_maker_rate_bps": "6.5",
|
2905
|
+
# "effective_taker_rate_bps": "6.9"
|
2906
|
+
# }
|
2907
|
+
#
|
2908
|
+
marketId = self.safe_string(fee, 'instrument_name')
|
2909
|
+
symbol = self.safe_symbol(marketId, market)
|
2910
|
+
return {
|
2911
|
+
'info': fee,
|
2912
|
+
'symbol': symbol,
|
2913
|
+
'maker': self.parse_number(Precise.string_div(self.safe_string(fee, 'effective_maker_rate_bps'), '10000')),
|
2914
|
+
'taker': self.parse_number(Precise.string_div(self.safe_string(fee, 'effective_taker_rate_bps'), '10000')),
|
2915
|
+
'percentage': None,
|
2916
|
+
'tierBased': None,
|
2917
|
+
}
|
2918
|
+
|
2809
2919
|
def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
|
2810
2920
|
type = self.safe_string(api, 0)
|
2811
2921
|
access = self.safe_string(api, 1)
|
ccxt/kraken.py
CHANGED
@@ -1181,6 +1181,26 @@ class kraken(Exchange, ImplicitAPI):
|
|
1181
1181
|
# "misc": ''
|
1182
1182
|
# }
|
1183
1183
|
#
|
1184
|
+
# fetchMyTrades
|
1185
|
+
#
|
1186
|
+
# {
|
1187
|
+
# "ordertxid": "OSJVN7-A2AE-63WZV",
|
1188
|
+
# "postxid": "TBP7O6-PNXI-CONU",
|
1189
|
+
# "pair": "XXBTZUSD",
|
1190
|
+
# "time": 1710429248.3052235,
|
1191
|
+
# "type": "sell",
|
1192
|
+
# "ordertype": "liquidation market",
|
1193
|
+
# "price": "72026.50000",
|
1194
|
+
# "cost": "7.20265",
|
1195
|
+
# "fee": "0.01873",
|
1196
|
+
# "vol": "0.00010000",
|
1197
|
+
# "margin": "1.44053",
|
1198
|
+
# "leverage": "5",
|
1199
|
+
# "misc": "closing",
|
1200
|
+
# "trade_id": 68230622,
|
1201
|
+
# "maker": False
|
1202
|
+
# }
|
1203
|
+
#
|
1184
1204
|
timestamp = None
|
1185
1205
|
side = None
|
1186
1206
|
type = None
|
@@ -1227,6 +1247,10 @@ class kraken(Exchange, ImplicitAPI):
|
|
1227
1247
|
if market is not None:
|
1228
1248
|
symbol = market['symbol']
|
1229
1249
|
cost = self.safe_string(trade, 'cost')
|
1250
|
+
maker = self.safe_bool(trade, 'maker')
|
1251
|
+
takerOrMaker = None
|
1252
|
+
if maker is not None:
|
1253
|
+
takerOrMaker = 'maker' if maker else 'taker'
|
1230
1254
|
return self.safe_trade({
|
1231
1255
|
'id': id,
|
1232
1256
|
'order': orderId,
|
@@ -1236,7 +1260,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
1236
1260
|
'symbol': symbol,
|
1237
1261
|
'type': type,
|
1238
1262
|
'side': side,
|
1239
|
-
'takerOrMaker':
|
1263
|
+
'takerOrMaker': takerOrMaker,
|
1240
1264
|
'price': price,
|
1241
1265
|
'amount': amount,
|
1242
1266
|
'cost': cost,
|
@@ -2001,7 +2025,10 @@ class kraken(Exchange, ImplicitAPI):
|
|
2001
2025
|
# "fee": "0.000026",
|
2002
2026
|
# "vol": "16.00000000",
|
2003
2027
|
# "margin": "0.000000",
|
2028
|
+
# "leverage": "5",
|
2004
2029
|
# "misc": ""
|
2030
|
+
# "trade_id": 68230622,
|
2031
|
+
# "maker": False
|
2005
2032
|
# },
|
2006
2033
|
# ...
|
2007
2034
|
# },
|
@@ -2367,13 +2394,11 @@ class kraken(Exchange, ImplicitAPI):
|
|
2367
2394
|
:returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
|
2368
2395
|
"""
|
2369
2396
|
# https://www.kraken.com/en-us/help/api#deposit-status
|
2370
|
-
if code is None:
|
2371
|
-
raise ArgumentsRequired(self.id + ' fetchDeposits() requires a currency code argument')
|
2372
2397
|
self.load_markets()
|
2373
|
-
|
2374
|
-
|
2375
|
-
|
2376
|
-
|
2398
|
+
request: dict = {}
|
2399
|
+
if code is not None:
|
2400
|
+
currency = self.currency(code)
|
2401
|
+
request['asset'] = currency['id']
|
2377
2402
|
if since is not None:
|
2378
2403
|
request['start'] = since
|
2379
2404
|
response = self.privatePostDepositStatus(self.extend(request, params))
|
ccxt/kucoinfutures.py
CHANGED
@@ -137,6 +137,7 @@ class kucoinfutures(kucoin, ImplicitAPI):
|
|
137
137
|
'contracts/{symbol}': 1,
|
138
138
|
'contracts/risk-limit/{symbol}': 1,
|
139
139
|
'ticker': 1,
|
140
|
+
'allTickers': 1,
|
140
141
|
'level2/snapshot': 1.33,
|
141
142
|
'level2/depth{limit}': 1,
|
142
143
|
'level2/message/query': 1,
|
@@ -180,6 +181,7 @@ class kucoinfutures(kucoin, ImplicitAPI):
|
|
180
181
|
'trade-statistics': 1,
|
181
182
|
'trade-fees': 1,
|
182
183
|
'history-positions': 1,
|
184
|
+
'getMaxOpenSize': 1,
|
183
185
|
},
|
184
186
|
'post': {
|
185
187
|
'withdrawals': 1,
|
@@ -325,6 +327,9 @@ class kucoinfutures(kucoin, ImplicitAPI):
|
|
325
327
|
# endpoint versions
|
326
328
|
'versions': {
|
327
329
|
'futuresPrivate': {
|
330
|
+
'GET': {
|
331
|
+
'getMaxOpenSize': 'v2',
|
332
|
+
},
|
328
333
|
'POST': {
|
329
334
|
'transfer-out': 'v2',
|
330
335
|
},
|
ccxt/mexc.py
CHANGED
@@ -1158,7 +1158,7 @@ class mexc(Exchange, ImplicitAPI):
|
|
1158
1158
|
# "symbols": [
|
1159
1159
|
# {
|
1160
1160
|
# "symbol": "OGNUSDT",
|
1161
|
-
# "status": "
|
1161
|
+
# "status": "1",
|
1162
1162
|
# "baseAsset": "OGN",
|
1163
1163
|
# "baseAssetPrecision": "2",
|
1164
1164
|
# "quoteAsset": "USDT",
|
@@ -1203,7 +1203,7 @@ class mexc(Exchange, ImplicitAPI):
|
|
1203
1203
|
status = self.safe_string(market, 'status')
|
1204
1204
|
isSpotTradingAllowed = self.safe_value(market, 'isSpotTradingAllowed')
|
1205
1205
|
active = False
|
1206
|
-
if (status == '
|
1206
|
+
if (status == '1') and (isSpotTradingAllowed):
|
1207
1207
|
active = True
|
1208
1208
|
isMarginTradingAllowed = self.safe_value(market, 'isMarginTradingAllowed')
|
1209
1209
|
makerCommission = self.safe_number(market, 'makerCommission')
|
ccxt/pro/__init__.py
CHANGED
ccxt/pro/binance.py
CHANGED
@@ -228,7 +228,7 @@ class binance(ccxt.async_support.binance):
|
|
228
228
|
else:
|
229
229
|
for i in range(0, len(symbols)):
|
230
230
|
market = self.market(symbols[i])
|
231
|
-
subscriptionHashes.append(market['
|
231
|
+
subscriptionHashes.append(market['lowercaseId'] + '@forceOrder')
|
232
232
|
messageHashes.append('liquidations::' + symbols[i])
|
233
233
|
streamHash += '::' + ','.join(symbols)
|
234
234
|
firstMarket = self.get_market_from_symbols(symbols)
|
@@ -1133,6 +1133,9 @@ class binance(ccxt.async_support.binance):
|
|
1133
1133
|
:param dict [params.timezone]: if provided, kline intervals are interpreted in that timezone instead of UTC, example '+08:00'
|
1134
1134
|
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
1135
1135
|
"""
|
1136
|
+
await self.load_markets()
|
1137
|
+
market = self.market(symbol)
|
1138
|
+
symbol = market['symbol']
|
1136
1139
|
params['callerMethodName'] = 'watchOHLCV'
|
1137
1140
|
result = await self.watch_ohlcv_for_symbols([[symbol, timeframe]], since, limit, params)
|
1138
1141
|
return result[symbol][timeframe]
|
@@ -1179,7 +1182,7 @@ class binance(ccxt.async_support.binance):
|
|
1179
1182
|
suffix = '@+08:00'
|
1180
1183
|
utcSuffix = suffix if shouldUseUTC8 else ''
|
1181
1184
|
rawHashes.append(marketId + '@' + klineType + '_' + interval + utcSuffix)
|
1182
|
-
messageHashes.append('ohlcv::' +
|
1185
|
+
messageHashes.append('ohlcv::' + market['symbol'] + '::' + timeframeString)
|
1183
1186
|
url = self.urls['api']['ws'][type] + '/' + self.stream(type, 'multipleOHLCV')
|
1184
1187
|
requestId = self.request_id(url)
|
1185
1188
|
request = {
|
@@ -1434,6 +1437,8 @@ class binance(ccxt.async_support.binance):
|
|
1434
1437
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1435
1438
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
1436
1439
|
"""
|
1440
|
+
await self.load_markets()
|
1441
|
+
symbols = self.market_symbols(symbols, None, True, False, True)
|
1437
1442
|
result = await self.watch_multi_ticker_helper('watchBidsAsks', 'bookTicker', symbols, params)
|
1438
1443
|
if self.newUpdates:
|
1439
1444
|
return result
|
ccxt/pro/bitget.py
CHANGED
@@ -9,6 +9,7 @@ import hashlib
|
|
9
9
|
from ccxt.base.types import Balances, Int, Order, OrderBook, 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
|
@@ -429,6 +430,32 @@ class bitget(ccxt.async_support.bitget):
|
|
429
430
|
"""
|
430
431
|
return await self.watch_order_book_for_symbols([symbol], limit, params)
|
431
432
|
|
433
|
+
async def un_watch_order_book(self, symbol: str, params={}) -> Any:
|
434
|
+
"""
|
435
|
+
unsubscribe from the orderbook channel
|
436
|
+
:see: https://www.bitget.com/api-doc/spot/websocket/public/Depth-Channel
|
437
|
+
:see: https://www.bitget.com/api-doc/contract/websocket/public/Order-Book-Channel
|
438
|
+
:param str symbol: unified symbol of the market to fetch the order book for
|
439
|
+
:param int [params.limit]: orderbook limit, default is None
|
440
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
441
|
+
"""
|
442
|
+
await self.load_markets()
|
443
|
+
market = self.market(symbol)
|
444
|
+
messageHash = 'unsubscribe:orderbook:' + market['symbol']
|
445
|
+
channel = 'books'
|
446
|
+
limit = self.safe_integer(params, 'limit')
|
447
|
+
if (limit == 1) or (limit == 5) or (limit == 15):
|
448
|
+
params = self.omit(params, 'limit')
|
449
|
+
channel += str(limit)
|
450
|
+
instType = None
|
451
|
+
instType, params = self.get_inst_type(market, params)
|
452
|
+
args: dict = {
|
453
|
+
'instType': instType,
|
454
|
+
'channel': channel,
|
455
|
+
'instId': market['id'],
|
456
|
+
}
|
457
|
+
return await self.un_watch_public(messageHash, args, params)
|
458
|
+
|
432
459
|
async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
|
433
460
|
"""
|
434
461
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
@@ -542,10 +569,11 @@ class bitget(ccxt.async_support.bitget):
|
|
542
569
|
calculatedChecksum = self.crc32(payload, True)
|
543
570
|
responseChecksum = self.safe_integer(rawOrderBook, 'checksum')
|
544
571
|
if calculatedChecksum != responseChecksum:
|
545
|
-
|
546
|
-
del
|
547
|
-
|
548
|
-
|
572
|
+
# if messageHash in client.subscriptions:
|
573
|
+
# # del client.subscriptions[messageHash]
|
574
|
+
# # del self.orderbooks[symbol]
|
575
|
+
# }
|
576
|
+
self.spawn(self.handle_check_sum_error, client, symbol, messageHash)
|
549
577
|
return
|
550
578
|
else:
|
551
579
|
orderbook = self.order_book({})
|
@@ -554,6 +582,11 @@ class bitget(ccxt.async_support.bitget):
|
|
554
582
|
self.orderbooks[symbol] = orderbook
|
555
583
|
client.resolve(self.orderbooks[symbol], messageHash)
|
556
584
|
|
585
|
+
async def handle_check_sum_error(self, client: Client, symbol: str, messageHash: str):
|
586
|
+
await self.un_watch_order_book(symbol)
|
587
|
+
error = ChecksumError(self.id + ' ' + self.orderbook_checksum_message(symbol))
|
588
|
+
client.reject(error, messageHash)
|
589
|
+
|
557
590
|
def handle_delta(self, bookside, delta):
|
558
591
|
bidAsk = self.parse_bid_ask(delta, 0, 1)
|
559
592
|
# we store the string representations in the orderbook for checksum calculation
|
@@ -1524,6 +1557,15 @@ class bitget(ccxt.async_support.bitget):
|
|
1524
1557
|
message = self.extend(request, params)
|
1525
1558
|
return await self.watch(url, messageHash, message, messageHash)
|
1526
1559
|
|
1560
|
+
async def un_watch_public(self, messageHash, args, params={}):
|
1561
|
+
url = self.urls['api']['ws']['public']
|
1562
|
+
request: dict = {
|
1563
|
+
'op': 'unsubscribe',
|
1564
|
+
'args': [args],
|
1565
|
+
}
|
1566
|
+
message = self.extend(request, params)
|
1567
|
+
return await self.watch(url, messageHash, message, messageHash)
|
1568
|
+
|
1527
1569
|
async def watch_public_multiple(self, messageHashes, argsArray, params={}):
|
1528
1570
|
url = self.urls['api']['ws']['public']
|
1529
1571
|
request: dict = {
|
@@ -1637,6 +1679,17 @@ class bitget(ccxt.async_support.bitget):
|
|
1637
1679
|
# "event": "subscribe",
|
1638
1680
|
# "arg": {instType: 'SPOT', channel: "account", instId: "default"}
|
1639
1681
|
# }
|
1682
|
+
# unsubscribe
|
1683
|
+
# {
|
1684
|
+
# "op":"unsubscribe",
|
1685
|
+
# "args":[
|
1686
|
+
# {
|
1687
|
+
# "instType":"USDT-FUTURES",
|
1688
|
+
# "channel":"ticker",
|
1689
|
+
# "instId":"BTCUSDT"
|
1690
|
+
# }
|
1691
|
+
# ]
|
1692
|
+
# }
|
1640
1693
|
#
|
1641
1694
|
if self.handle_error_message(client, message):
|
1642
1695
|
return
|
@@ -1654,6 +1707,9 @@ class bitget(ccxt.async_support.bitget):
|
|
1654
1707
|
if event == 'subscribe':
|
1655
1708
|
self.handle_subscription_status(client, message)
|
1656
1709
|
return
|
1710
|
+
if event == 'unsubscribe':
|
1711
|
+
self.handle_un_subscription_status(client, message)
|
1712
|
+
return
|
1657
1713
|
methods: dict = {
|
1658
1714
|
'ticker': self.handle_ticker,
|
1659
1715
|
'trade': self.handle_trades,
|
@@ -1693,3 +1749,47 @@ class bitget(ccxt.async_support.bitget):
|
|
1693
1749
|
# }
|
1694
1750
|
#
|
1695
1751
|
return message
|
1752
|
+
|
1753
|
+
def handle_un_subscription_status(self, client: Client, message):
|
1754
|
+
#
|
1755
|
+
# {
|
1756
|
+
# "op":"unsubscribe",
|
1757
|
+
# "args":[
|
1758
|
+
# {
|
1759
|
+
# "instType":"USDT-FUTURES",
|
1760
|
+
# "channel":"ticker",
|
1761
|
+
# "instId":"BTCUSDT"
|
1762
|
+
# },
|
1763
|
+
# {
|
1764
|
+
# "instType":"USDT-FUTURES",
|
1765
|
+
# "channel":"candle1m",
|
1766
|
+
# "instId":"BTCUSDT"
|
1767
|
+
# }
|
1768
|
+
# ]
|
1769
|
+
# }
|
1770
|
+
# or
|
1771
|
+
# {"event":"unsubscribe","arg":{"instType":"SPOT","channel":"books","instId":"BTCUSDT"}}
|
1772
|
+
#
|
1773
|
+
argsList = self.safe_list(message, 'args')
|
1774
|
+
if argsList is None:
|
1775
|
+
argsList = [self.safe_dict(message, 'arg', {})]
|
1776
|
+
for i in range(0, len(argsList)):
|
1777
|
+
arg = argsList[i]
|
1778
|
+
channel = self.safe_string(arg, 'channel')
|
1779
|
+
if channel == 'books':
|
1780
|
+
# for now only unWatchOrderBook is supporteod
|
1781
|
+
instType = self.safe_string_lower(arg, 'instType')
|
1782
|
+
type = 'spot' if (instType == 'spot') else 'contract'
|
1783
|
+
instId = self.safe_string(arg, 'instId')
|
1784
|
+
market = self.safe_market(instId, None, None, type)
|
1785
|
+
symbol = market['symbol']
|
1786
|
+
messageHash = 'unsubscribe:orderbook:' + market['symbol']
|
1787
|
+
subMessageHash = 'orderbook:' + symbol
|
1788
|
+
if symbol in self.orderbooks:
|
1789
|
+
del self.orderbooks[symbol]
|
1790
|
+
if subMessageHash in client.subscriptions:
|
1791
|
+
del client.subscriptions[subMessageHash]
|
1792
|
+
if messageHash in client.subscriptions:
|
1793
|
+
del client.subscriptions[messageHash]
|
1794
|
+
client.resolve(True, messageHash)
|
1795
|
+
return message
|
ccxt/pro/bitrue.py
CHANGED
@@ -401,13 +401,7 @@ class bitrue(ccxt.async_support.bitrue):
|
|
401
401
|
async def authenticate(self, params={}):
|
402
402
|
listenKey = self.safe_value(self.options, 'listenKey')
|
403
403
|
if listenKey is None:
|
404
|
-
response =
|
405
|
-
try:
|
406
|
-
response = await self.openPrivatePostPoseidonApiV1ListenKey(params)
|
407
|
-
except Exception as error:
|
408
|
-
self.options['listenKey'] = None
|
409
|
-
self.options['listenKeyUrl'] = None
|
410
|
-
return None
|
404
|
+
response = await self.openPrivatePostPoseidonApiV1ListenKey(params)
|
411
405
|
#
|
412
406
|
# {
|
413
407
|
# "msg": "succ",
|
ccxt/pro/gate.py
CHANGED
@@ -1408,7 +1408,7 @@ class gate(ccxt.async_support.gate):
|
|
1408
1408
|
errs = self.safe_dict(data, 'errs')
|
1409
1409
|
error = self.safe_dict(message, 'error', errs)
|
1410
1410
|
code = self.safe_string_2(error, 'code', 'label')
|
1411
|
-
id = self.
|
1411
|
+
id = self.safe_string_n(message, ['id', 'requestId', 'request_id'])
|
1412
1412
|
if error is not None:
|
1413
1413
|
messageHash = self.safe_string(client.subscriptions, id)
|
1414
1414
|
try:
|
@@ -1421,7 +1421,7 @@ class gate(ccxt.async_support.gate):
|
|
1421
1421
|
client.reject(e, messageHash)
|
1422
1422
|
if (messageHash is not None) and (messageHash in client.subscriptions):
|
1423
1423
|
del client.subscriptions[messageHash]
|
1424
|
-
if id is not None:
|
1424
|
+
if (id is not None) and (id in client.subscriptions):
|
1425
1425
|
del client.subscriptions[id]
|
1426
1426
|
return True
|
1427
1427
|
return False
|
@@ -1686,7 +1686,7 @@ class gate(ccxt.async_support.gate):
|
|
1686
1686
|
'event': event,
|
1687
1687
|
'payload': payload,
|
1688
1688
|
}
|
1689
|
-
return await self.watch(url, messageHash, request, messageHash)
|
1689
|
+
return await self.watch(url, messageHash, request, messageHash, requestId)
|
1690
1690
|
|
1691
1691
|
async def subscribe_private(self, url, messageHash, payload, channel, params, requiresUid=False):
|
1692
1692
|
self.check_required_credentials()
|
@@ -1724,4 +1724,4 @@ class gate(ccxt.async_support.gate):
|
|
1724
1724
|
# in case of authenticationError we will throw
|
1725
1725
|
client.subscriptions[tempSubscriptionHash] = messageHash
|
1726
1726
|
message = self.extend(request, params)
|
1727
|
-
return await self.watch(url, messageHash, message, messageHash)
|
1727
|
+
return await self.watch(url, messageHash, message, messageHash, messageHash)
|
ccxt/pro/okx.py
CHANGED
@@ -419,8 +419,13 @@ class okx(ccxt.async_support.okx):
|
|
419
419
|
await self.load_markets()
|
420
420
|
symbols = self.market_symbols(symbols, None, True, True)
|
421
421
|
messageHash = 'liquidations'
|
422
|
+
messageHashes = []
|
422
423
|
if symbols is not None:
|
423
|
-
|
424
|
+
for i in range(0, len(symbols)):
|
425
|
+
symbol = symbols[i]
|
426
|
+
messageHashes.append(messageHash + '::' + symbol)
|
427
|
+
else:
|
428
|
+
messageHashes.append(messageHash)
|
424
429
|
market = self.get_market_from_symbols(symbols)
|
425
430
|
type = None
|
426
431
|
type, params = self.handle_market_type_and_params('watchliquidationsForSymbols', market, params)
|
@@ -431,9 +436,16 @@ class okx(ccxt.async_support.okx):
|
|
431
436
|
type = 'futures'
|
432
437
|
uppercaseType = type.upper()
|
433
438
|
request = {
|
434
|
-
'
|
439
|
+
'op': 'subscribe',
|
440
|
+
'args': [
|
441
|
+
{
|
442
|
+
'channel': channel,
|
443
|
+
'instType': uppercaseType,
|
444
|
+
},
|
445
|
+
],
|
435
446
|
}
|
436
|
-
|
447
|
+
url = self.get_url(channel, 'public')
|
448
|
+
newLiquidations = await self.watch_multiple(url, messageHashes, request, messageHashes)
|
437
449
|
if self.newUpdates:
|
438
450
|
return newLiquidations
|
439
451
|
return self.filter_by_symbols_since_limit(self.liquidations, symbols, since, limit, True)
|
@@ -1305,6 +1317,12 @@ class okx(ccxt.async_support.okx):
|
|
1305
1317
|
for i in range(0, len(data)):
|
1306
1318
|
rawPosition = data[i]
|
1307
1319
|
position = self.parse_position(rawPosition)
|
1320
|
+
if position['contracts'] == 0:
|
1321
|
+
position['side'] = 'long'
|
1322
|
+
shortPosition = self.clone(position)
|
1323
|
+
shortPosition['side'] = 'short'
|
1324
|
+
cache.append(shortPosition)
|
1325
|
+
newPositions.append(shortPosition)
|
1308
1326
|
newPositions.append(position)
|
1309
1327
|
cache.append(position)
|
1310
1328
|
messageHashes = self.find_message_hashes(client, channel + '::')
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ccxt
|
3
|
-
Version: 4.3.
|
3
|
+
Version: 4.3.85
|
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
|
@@ -269,13 +269,13 @@ console.log(version, Object.keys(exchanges));
|
|
269
269
|
|
270
270
|
All-in-one browser bundle (dependencies included), served from a CDN of your choice:
|
271
271
|
|
272
|
-
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.
|
273
|
-
* unpkg: https://unpkg.com/ccxt@4.3.
|
272
|
+
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.85/dist/ccxt.browser.min.js
|
273
|
+
* unpkg: https://unpkg.com/ccxt@4.3.85/dist/ccxt.browser.min.js
|
274
274
|
|
275
275
|
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.
|
276
276
|
|
277
277
|
```HTML
|
278
|
-
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.
|
278
|
+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.85/dist/ccxt.browser.min.js"></script>
|
279
279
|
```
|
280
280
|
|
281
281
|
Creates a global `ccxt` object:
|