ccxt 4.4.8__py2.py3-none-any.whl → 4.4.10__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/bigone.py +1 -1
- ccxt/abstract/kucoinfutures.py +5 -0
- ccxt/abstract/oceanex.py +5 -0
- ccxt/ascendex.py +5 -4
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ascendex.py +5 -4
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/bigone.py +35 -86
- ccxt/async_support/binance.py +8 -11
- ccxt/async_support/bingx.py +27 -23
- ccxt/async_support/bitfinex2.py +7 -16
- ccxt/async_support/bitget.py +10 -6
- ccxt/async_support/bitmart.py +4 -3
- ccxt/async_support/bitmex.py +7 -6
- ccxt/async_support/blofin.py +7 -16
- ccxt/async_support/bybit.py +22 -17
- ccxt/async_support/coinex.py +19 -5
- ccxt/async_support/delta.py +6 -5
- ccxt/async_support/deribit.py +4 -3
- ccxt/async_support/digifinex.py +18 -4
- ccxt/async_support/gate.py +61 -13
- ccxt/async_support/hashkey.py +6 -6
- ccxt/async_support/hitbtc.py +6 -5
- ccxt/async_support/htx.py +25 -6
- ccxt/async_support/hyperliquid.py +6 -1
- ccxt/async_support/krakenfutures.py +6 -5
- ccxt/async_support/kucoin.py +1 -0
- ccxt/async_support/kucoinfutures.py +164 -4
- ccxt/async_support/mexc.py +4 -3
- ccxt/async_support/oceanex.py +80 -4
- ccxt/async_support/okx.py +17 -3
- ccxt/async_support/oxfun.py +7 -7
- ccxt/async_support/phemex.py +4 -3
- ccxt/async_support/poloniexfutures.py +13 -2
- ccxt/async_support/vertex.py +6 -5
- ccxt/async_support/whitebit.py +14 -13
- ccxt/async_support/woo.py +42 -21
- ccxt/async_support/woofipro.py +19 -6
- ccxt/async_support/xt.py +5 -3
- ccxt/base/exchange.py +1 -1
- ccxt/base/types.py +1 -0
- ccxt/bigone.py +35 -86
- ccxt/binance.py +8 -11
- ccxt/bingx.py +27 -23
- ccxt/bitfinex2.py +7 -16
- ccxt/bitget.py +10 -6
- ccxt/bitmart.py +4 -3
- ccxt/bitmex.py +7 -6
- ccxt/blofin.py +7 -16
- ccxt/bybit.py +22 -17
- ccxt/coinex.py +19 -5
- ccxt/delta.py +6 -5
- ccxt/deribit.py +4 -3
- ccxt/digifinex.py +18 -4
- ccxt/gate.py +61 -13
- ccxt/hashkey.py +6 -6
- ccxt/hitbtc.py +6 -5
- ccxt/htx.py +25 -6
- ccxt/hyperliquid.py +6 -1
- ccxt/krakenfutures.py +6 -5
- ccxt/kucoin.py +1 -0
- ccxt/kucoinfutures.py +164 -4
- ccxt/mexc.py +4 -3
- ccxt/oceanex.py +80 -4
- ccxt/okx.py +17 -3
- ccxt/oxfun.py +7 -7
- ccxt/phemex.py +4 -3
- ccxt/poloniexfutures.py +13 -2
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +3 -3
- ccxt/pro/deribit.py +39 -2
- ccxt/pro/gate.py +1 -1
- ccxt/pro/hitbtc.py +112 -44
- ccxt/pro/hollaex.py +5 -0
- ccxt/pro/okx.py +12 -1
- ccxt/pro/p2b.py +33 -2
- ccxt/pro/whitebit.py +29 -1
- ccxt/vertex.py +6 -5
- ccxt/whitebit.py +14 -13
- ccxt/woo.py +42 -21
- ccxt/woofipro.py +19 -6
- ccxt/xt.py +5 -3
- ccxt-4.4.10.dist-info/METADATA +636 -0
- {ccxt-4.4.8.dist-info → ccxt-4.4.10.dist-info}/RECORD +88 -88
- ccxt-4.4.8.dist-info/METADATA +0 -636
- {ccxt-4.4.8.dist-info → ccxt-4.4.10.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.8.dist-info → ccxt-4.4.10.dist-info}/WHEEL +0 -0
- {ccxt-4.4.8.dist-info → ccxt-4.4.10.dist-info}/top_level.txt +0 -0
ccxt/phemex.py
CHANGED
@@ -7,7 +7,7 @@ from ccxt.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.phemex import ImplicitAPI
|
8
8
|
import hashlib
|
9
9
|
import numbers
|
10
|
-
from ccxt.base.types import Balances, Currencies, Currency, Int, LeverageTier, LeverageTiers, MarginModification, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
10
|
+
from ccxt.base.types import Balances, Currencies, Currency, Int, LeverageTier, LeverageTiers, MarginModification, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, Trade, Transaction, TransferEntry
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import ExchangeError
|
13
13
|
from ccxt.base.errors import AuthenticationError
|
@@ -3741,7 +3741,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3741
3741
|
value = Precise.string_mul(value, tickPrecision)
|
3742
3742
|
return value
|
3743
3743
|
|
3744
|
-
def fetch_funding_rate(self, symbol: str, params={}):
|
3744
|
+
def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
|
3745
3745
|
"""
|
3746
3746
|
fetch the current funding rate
|
3747
3747
|
:param str symbol: unified market symbol
|
@@ -3786,7 +3786,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3786
3786
|
result = self.safe_value(response, 'result', {})
|
3787
3787
|
return self.parse_funding_rate(result, market)
|
3788
3788
|
|
3789
|
-
def parse_funding_rate(self, contract, market: Market = None):
|
3789
|
+
def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
|
3790
3790
|
#
|
3791
3791
|
# {
|
3792
3792
|
# "askEp": 2332500,
|
@@ -3845,6 +3845,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3845
3845
|
'previousFundingRate': None,
|
3846
3846
|
'previousFundingTimestamp': None,
|
3847
3847
|
'previousFundingDatetime': None,
|
3848
|
+
'interval': None,
|
3848
3849
|
}
|
3849
3850
|
|
3850
3851
|
def set_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
|
ccxt/poloniexfutures.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.poloniexfutures import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade
|
9
|
+
from ccxt.base.types import Balances, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, Trade
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import AuthenticationError
|
12
12
|
from ccxt.base.errors import AccountSuspended
|
@@ -1527,7 +1527,7 @@ class poloniexfutures(Exchange, ImplicitAPI):
|
|
1527
1527
|
'trades': None,
|
1528
1528
|
}, market)
|
1529
1529
|
|
1530
|
-
def fetch_funding_rate(self, symbol: str, params={}):
|
1530
|
+
def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
|
1531
1531
|
"""
|
1532
1532
|
fetch the current funding rate
|
1533
1533
|
:see: https://api-docs.poloniex.com/futures/api/futures-index#get-premium-index
|
@@ -1571,8 +1571,19 @@ class poloniexfutures(Exchange, ImplicitAPI):
|
|
1571
1571
|
'previousFundingRate': self.safe_number(data, 'value'),
|
1572
1572
|
'previousFundingTimestamp': fundingTimestamp,
|
1573
1573
|
'previousFundingDatetime': self.iso8601(fundingTimestamp),
|
1574
|
+
'interval': self.parse_funding_interval(self.safe_string(data, 'interval')),
|
1574
1575
|
}
|
1575
1576
|
|
1577
|
+
def parse_funding_interval(self, interval):
|
1578
|
+
intervals: dict = {
|
1579
|
+
'3600000': '1h',
|
1580
|
+
'14400000': '4h',
|
1581
|
+
'28800000': '8h',
|
1582
|
+
'57600000': '16h',
|
1583
|
+
'86400000': '24h',
|
1584
|
+
}
|
1585
|
+
return self.safe_string(intervals, interval, interval)
|
1586
|
+
|
1576
1587
|
def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
1577
1588
|
"""
|
1578
1589
|
fetch all trades made by the user
|
ccxt/pro/__init__.py
CHANGED
ccxt/pro/binance.py
CHANGED
@@ -2417,13 +2417,13 @@ class binance(ccxt.async_support.binance):
|
|
2417
2417
|
subType, params = self.handle_sub_type_and_params('watchBalance', None, params)
|
2418
2418
|
isPortfolioMargin = None
|
2419
2419
|
isPortfolioMargin, params = self.handle_option_and_params_2(params, 'watchBalance', 'papi', 'portfolioMargin', False)
|
2420
|
-
urlType = type
|
2421
|
-
if isPortfolioMargin:
|
2422
|
-
urlType = 'papi'
|
2423
2420
|
if self.isLinear(type, subType):
|
2424
2421
|
type = 'future'
|
2425
2422
|
elif self.isInverse(type, subType):
|
2426
2423
|
type = 'delivery'
|
2424
|
+
urlType = type
|
2425
|
+
if isPortfolioMargin:
|
2426
|
+
urlType = 'papi'
|
2427
2427
|
url = self.urls['api']['ws'][urlType] + '/' + self.options[type]['listenKey']
|
2428
2428
|
client = self.client(url)
|
2429
2429
|
self.set_balance_cache(client, type, isPortfolioMargin)
|
ccxt/pro/deribit.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
import ccxt.async_support
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Int, Order, OrderBook, Str, Ticker, Trade
|
9
|
+
from ccxt.base.types import Balances, Int, Order, OrderBook, 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 ccxt.base.errors import ExchangeError
|
@@ -22,7 +22,7 @@ class deribit(ccxt.async_support.deribit):
|
|
22
22
|
'ws': True,
|
23
23
|
'watchBalance': True,
|
24
24
|
'watchTicker': True,
|
25
|
-
'watchTickers':
|
25
|
+
'watchTickers': True,
|
26
26
|
'watchTrades': True,
|
27
27
|
'watchTradesForSymbols': True,
|
28
28
|
'watchMyTrades': True,
|
@@ -189,6 +189,43 @@ class deribit(ccxt.async_support.deribit):
|
|
189
189
|
request = self.deep_extend(message, params)
|
190
190
|
return await self.watch(url, channel, request, channel, request)
|
191
191
|
|
192
|
+
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
193
|
+
"""
|
194
|
+
:see: https://docs.deribit.com/#ticker-instrument_name-interval
|
195
|
+
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
196
|
+
:param str[] [symbols]: unified symbol of the market to fetch the ticker for
|
197
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
198
|
+
:param str [params.interval]: specify aggregation and frequency of notifications. Possible values: 100ms, raw
|
199
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
200
|
+
"""
|
201
|
+
await self.load_markets()
|
202
|
+
symbols = self.market_symbols(symbols, None, False)
|
203
|
+
url = self.urls['api']['ws']
|
204
|
+
interval = self.safe_string(params, 'interval', '100ms')
|
205
|
+
params = self.omit(params, 'interval')
|
206
|
+
await self.load_markets()
|
207
|
+
if interval == 'raw':
|
208
|
+
await self.authenticate()
|
209
|
+
channels = []
|
210
|
+
for i in range(0, len(symbols)):
|
211
|
+
market = self.market(symbols[i])
|
212
|
+
channels.append('ticker.' + market['id'] + '.' + interval)
|
213
|
+
message: dict = {
|
214
|
+
'jsonrpc': '2.0',
|
215
|
+
'method': 'public/subscribe',
|
216
|
+
'params': {
|
217
|
+
'channels': channels,
|
218
|
+
},
|
219
|
+
'id': self.request_id(),
|
220
|
+
}
|
221
|
+
request = self.deep_extend(message, params)
|
222
|
+
newTickers = await self.watch_multiple(url, channels, request, channels, request)
|
223
|
+
if self.newUpdates:
|
224
|
+
tickers: dict = {}
|
225
|
+
tickers[newTickers['symbol']] = newTickers
|
226
|
+
return tickers
|
227
|
+
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
228
|
+
|
192
229
|
def handle_ticker(self, client: Client, message):
|
193
230
|
#
|
194
231
|
# {
|
ccxt/pro/gate.py
CHANGED
@@ -332,7 +332,7 @@ class gate(ccxt.async_support.gate):
|
|
332
332
|
symbol = market['symbol']
|
333
333
|
if market['swap'] is not True:
|
334
334
|
raise NotSupported(self.id + ' fetchOrdersByStatusWs is only supported by swap markets. Use rest API for other markets')
|
335
|
-
request, requestParams = self.
|
335
|
+
request, requestParams = self.prepareOrdersByStatusRequest(status, symbol, since, limit, params)
|
336
336
|
newRequest = self.omit(request, ['settle'])
|
337
337
|
messageType = self.get_type_by_market(market)
|
338
338
|
channel = messageType + '.order_list'
|
ccxt/pro/hitbtc.py
CHANGED
@@ -22,6 +22,7 @@ class hitbtc(ccxt.async_support.hitbtc):
|
|
22
22
|
'ws': True,
|
23
23
|
'watchTicker': True,
|
24
24
|
'watchTickers': True,
|
25
|
+
'watchBidsAsks': True,
|
25
26
|
'watchTrades': True,
|
26
27
|
'watchTradesForSymbols': False,
|
27
28
|
'watchOrderBook': True,
|
@@ -56,8 +57,11 @@ class hitbtc(ccxt.async_support.hitbtc):
|
|
56
57
|
'watchTickers': {
|
57
58
|
'method': 'ticker/{speed}', # 'ticker/{speed}','ticker/price/{speed}', 'ticker/{speed}/batch', or 'ticker/{speed}/price/batch''
|
58
59
|
},
|
60
|
+
'watchBidsAsks': {
|
61
|
+
'method': 'orderbook/top/{speed}', # 'orderbook/top/{speed}', 'orderbook/top/{speed}/batch'
|
62
|
+
},
|
59
63
|
'watchOrderBook': {
|
60
|
-
'method': 'orderbook/full', # 'orderbook/full', 'orderbook/{depth}/{speed}', 'orderbook/{depth}/{speed}/batch'
|
64
|
+
'method': 'orderbook/full', # 'orderbook/full', 'orderbook/{depth}/{speed}', 'orderbook/{depth}/{speed}/batch'
|
61
65
|
},
|
62
66
|
},
|
63
67
|
'timeframes': {
|
@@ -130,17 +134,22 @@ class hitbtc(ccxt.async_support.hitbtc):
|
|
130
134
|
:param dict [params]: extra parameters specific to the hitbtc api
|
131
135
|
"""
|
132
136
|
await self.load_markets()
|
137
|
+
symbols = self.market_symbols(symbols)
|
138
|
+
isBatch = name.find('batch') >= 0
|
133
139
|
url = self.urls['api']['ws']['public']
|
134
|
-
|
135
|
-
if symbols is not None:
|
136
|
-
|
140
|
+
messageHashes = []
|
141
|
+
if symbols is not None and not isBatch:
|
142
|
+
for i in range(0, len(symbols)):
|
143
|
+
messageHashes.append(messageHashPrefix + '::' + symbols[i])
|
144
|
+
else:
|
145
|
+
messageHashes.append(messageHashPrefix)
|
137
146
|
subscribe: dict = {
|
138
147
|
'method': 'subscribe',
|
139
148
|
'id': self.nonce(),
|
140
149
|
'ch': name,
|
141
150
|
}
|
142
151
|
request = self.extend(subscribe, params)
|
143
|
-
return await self.
|
152
|
+
return await self.watch_multiple(url, messageHashes, request, messageHashes)
|
144
153
|
|
145
154
|
async def subscribe_private(self, name: str, symbol: Str = None, params={}):
|
146
155
|
"""
|
@@ -192,7 +201,7 @@ class hitbtc(ccxt.async_support.hitbtc):
|
|
192
201
|
:param str symbol: unified symbol of the market to fetch the order book for
|
193
202
|
:param int [limit]: the maximum amount of order book entries to return
|
194
203
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
195
|
-
:param str [params.method]: 'orderbook/full', 'orderbook/{depth}/{speed}', 'orderbook/{depth}/{speed}/batch'
|
204
|
+
:param str [params.method]: 'orderbook/full', 'orderbook/{depth}/{speed}', 'orderbook/{depth}/{speed}/batch'
|
196
205
|
:param int [params.depth]: 5 , 10, or 20(default)
|
197
206
|
:param int [params.speed]: 100(default), 500, or 1000
|
198
207
|
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
@@ -206,10 +215,6 @@ class hitbtc(ccxt.async_support.hitbtc):
|
|
206
215
|
name = 'orderbook/D' + depth + '/' + speed + 'ms'
|
207
216
|
elif name == 'orderbook/{depth}/{speed}/batch':
|
208
217
|
name = 'orderbook/D' + depth + '/' + speed + 'ms/batch'
|
209
|
-
elif name == 'orderbook/top/{speed}':
|
210
|
-
name = 'orderbook/top/' + speed + 'ms'
|
211
|
-
elif name == 'orderbook/top/{speed}/batch':
|
212
|
-
name = 'orderbook/top/' + speed + 'ms/batch'
|
213
218
|
market = self.market(symbol)
|
214
219
|
request: dict = {
|
215
220
|
'params': {
|
@@ -298,33 +303,22 @@ class hitbtc(ccxt.async_support.hitbtc):
|
|
298
303
|
:param str [params.speed]: '1s'(default), or '3s'
|
299
304
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
300
305
|
"""
|
301
|
-
|
302
|
-
|
303
|
-
method = self.safe_string_2(params, 'method', 'defaultMethod', defaultMethod)
|
304
|
-
speed = self.safe_string(params, 'speed', '1s')
|
305
|
-
name = self.implode_params(method, {'speed': speed})
|
306
|
-
params = self.omit(params, ['method', 'speed'])
|
307
|
-
market = self.market(symbol)
|
308
|
-
request: dict = {
|
309
|
-
'params': {
|
310
|
-
'symbols': [market['id']],
|
311
|
-
},
|
312
|
-
}
|
313
|
-
result = await self.subscribe_public(name, 'tickers', [symbol], self.deep_extend(request, params))
|
314
|
-
return self.safe_value(result, symbol)
|
306
|
+
ticker = await self.watch_tickers([symbol], params)
|
307
|
+
return self.safe_value(ticker, symbol)
|
315
308
|
|
316
309
|
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
317
310
|
"""
|
318
311
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
319
312
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
320
313
|
:param dict params: extra parameters specific to the exchange API endpoint
|
321
|
-
:param str params['method']: 'ticker/{speed}'
|
314
|
+
:param str params['method']: 'ticker/{speed}' ,'ticker/price/{speed}', 'ticker/{speed}/batch'(default), or 'ticker/{speed}/price/batch''
|
322
315
|
:param str params['speed']: '1s'(default), or '3s'
|
323
316
|
:returns dict: a `ticker structure <https://docs.ccxt.com/en/latest/manual.html#ticker-structure>`
|
324
317
|
"""
|
325
318
|
await self.load_markets()
|
319
|
+
symbols = self.market_symbols(symbols)
|
326
320
|
options = self.safe_value(self.options, 'watchTicker')
|
327
|
-
defaultMethod = self.safe_string(options, 'method', 'ticker/{speed}')
|
321
|
+
defaultMethod = self.safe_string(options, 'method', 'ticker/{speed}/batch')
|
328
322
|
method = self.safe_string_2(params, 'method', 'defaultMethod', defaultMethod)
|
329
323
|
speed = self.safe_string(params, 'speed', '1s')
|
330
324
|
name = self.implode_params(method, {'speed': speed})
|
@@ -341,10 +335,13 @@ class hitbtc(ccxt.async_support.hitbtc):
|
|
341
335
|
'symbols': marketIds,
|
342
336
|
},
|
343
337
|
}
|
344
|
-
|
338
|
+
newTickers = await self.subscribe_public(name, 'tickers', symbols, self.deep_extend(request, params))
|
345
339
|
if self.newUpdates:
|
346
|
-
|
347
|
-
|
340
|
+
if not isinstance(newTickers, list):
|
341
|
+
tickers: dict = {}
|
342
|
+
tickers[newTickers['symbol']] = newTickers
|
343
|
+
return tickers
|
344
|
+
return self.filter_by_array(newTickers, 'symbol', symbols)
|
348
345
|
|
349
346
|
def handle_ticker(self, client: Client, message):
|
350
347
|
#
|
@@ -387,27 +384,18 @@ class hitbtc(ccxt.async_support.hitbtc):
|
|
387
384
|
#
|
388
385
|
data = self.safe_value(message, 'data', {})
|
389
386
|
marketIds = list(data.keys())
|
390
|
-
|
387
|
+
result = []
|
388
|
+
topic = 'tickers'
|
391
389
|
for i in range(0, len(marketIds)):
|
392
390
|
marketId = marketIds[i]
|
393
391
|
market = self.safe_market(marketId)
|
394
392
|
symbol = market['symbol']
|
395
393
|
ticker = self.parse_ws_ticker(data[marketId], market)
|
396
394
|
self.tickers[symbol] = ticker
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
messageHash = messageHashes[i]
|
402
|
-
parts = messageHash.split('::')
|
403
|
-
symbolsString = parts[1]
|
404
|
-
symbols = symbolsString.split(',')
|
405
|
-
tickers = self.filter_by_array(newTickers, 'symbol', symbols)
|
406
|
-
tickersSymbols = list(tickers.keys())
|
407
|
-
numTickers = len(tickersSymbols)
|
408
|
-
if numTickers > 0:
|
409
|
-
client.resolve(tickers, messageHash)
|
410
|
-
return message
|
395
|
+
result.append(ticker)
|
396
|
+
messageHash = topic + '::' + symbol
|
397
|
+
client.resolve(ticker, messageHash)
|
398
|
+
client.resolve(result, topic)
|
411
399
|
|
412
400
|
def parse_ws_ticker(self, ticker, market=None):
|
413
401
|
#
|
@@ -464,6 +452,81 @@ class hitbtc(ccxt.async_support.hitbtc):
|
|
464
452
|
'info': ticker,
|
465
453
|
}, market)
|
466
454
|
|
455
|
+
async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
|
456
|
+
"""
|
457
|
+
watches best bid & ask for symbols
|
458
|
+
:see: https://api.hitbtc.com/#subscribe-to-top-of-book
|
459
|
+
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
460
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
461
|
+
:param str [params.method]: 'orderbook/top/{speed}' or 'orderbook/top/{speed}/batch(default)'
|
462
|
+
:param str [params.speed]: '100ms'(default) or '500ms' or '1000ms'
|
463
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
464
|
+
"""
|
465
|
+
await self.load_markets()
|
466
|
+
symbols = self.market_symbols(symbols, None, False)
|
467
|
+
options = self.safe_value(self.options, 'watchBidsAsks')
|
468
|
+
defaultMethod = self.safe_string(options, 'method', 'orderbook/top/{speed}/batch')
|
469
|
+
method = self.safe_string_2(params, 'method', 'defaultMethod', defaultMethod)
|
470
|
+
speed = self.safe_string(params, 'speed', '100ms')
|
471
|
+
name = self.implode_params(method, {'speed': speed})
|
472
|
+
params = self.omit(params, ['method', 'speed'])
|
473
|
+
marketIds = self.market_ids(symbols)
|
474
|
+
request: dict = {
|
475
|
+
'params': {
|
476
|
+
'symbols': marketIds,
|
477
|
+
},
|
478
|
+
}
|
479
|
+
newTickers = await self.subscribe_public(name, 'bidask', symbols, self.deep_extend(request, params))
|
480
|
+
if self.newUpdates:
|
481
|
+
if not isinstance(newTickers, list):
|
482
|
+
tickers: dict = {}
|
483
|
+
tickers[newTickers['symbol']] = newTickers
|
484
|
+
return tickers
|
485
|
+
return self.filter_by_array(newTickers, 'symbol', symbols)
|
486
|
+
|
487
|
+
def handle_bid_ask(self, client: Client, message):
|
488
|
+
#
|
489
|
+
# {
|
490
|
+
# "ch": "orderbook/top/100ms", # or 'orderbook/top/100ms/batch'
|
491
|
+
# "data": {
|
492
|
+
# "BTCUSDT": {
|
493
|
+
# "t": 1727276919771,
|
494
|
+
# "a": "63931.45",
|
495
|
+
# "A": "0.02879",
|
496
|
+
# "b": "63926.97",
|
497
|
+
# "B": "0.00100"
|
498
|
+
# }
|
499
|
+
# }
|
500
|
+
# }
|
501
|
+
#
|
502
|
+
data = self.safe_dict(message, 'data', {})
|
503
|
+
marketIds = list(data.keys())
|
504
|
+
result = []
|
505
|
+
topic = 'bidask'
|
506
|
+
for i in range(0, len(marketIds)):
|
507
|
+
marketId = marketIds[i]
|
508
|
+
market = self.safe_market(marketId)
|
509
|
+
symbol = market['symbol']
|
510
|
+
ticker = self.parse_ws_bid_ask(data[marketId], market)
|
511
|
+
self.bidsasks[symbol] = ticker
|
512
|
+
result.append(ticker)
|
513
|
+
messageHash = topic + '::' + symbol
|
514
|
+
client.resolve(ticker, messageHash)
|
515
|
+
client.resolve(result, topic)
|
516
|
+
|
517
|
+
def parse_ws_bid_ask(self, ticker, market=None):
|
518
|
+
timestamp = self.safe_integer(ticker, 't')
|
519
|
+
return self.safe_ticker({
|
520
|
+
'symbol': market['symbol'],
|
521
|
+
'timestamp': timestamp,
|
522
|
+
'datetime': self.iso8601(timestamp),
|
523
|
+
'ask': self.safe_string(ticker, 'a'),
|
524
|
+
'askVolume': self.safe_string(ticker, 'A'),
|
525
|
+
'bid': self.safe_string(ticker, 'b'),
|
526
|
+
'bidVolume': self.safe_string(ticker, 'B'),
|
527
|
+
'info': ticker,
|
528
|
+
}, market)
|
529
|
+
|
467
530
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
468
531
|
"""
|
469
532
|
get the list of most recent trades for a particular symbol
|
@@ -1144,11 +1207,16 @@ class hitbtc(ccxt.async_support.hitbtc):
|
|
1144
1207
|
if channel is not None:
|
1145
1208
|
splitChannel = channel.split('/')
|
1146
1209
|
channel = self.safe_string(splitChannel, 0)
|
1210
|
+
if channel == 'orderbook':
|
1211
|
+
channel2 = self.safe_string(splitChannel, 1)
|
1212
|
+
if channel2 is not None and channel2 == 'top':
|
1213
|
+
channel = 'orderbook/top'
|
1147
1214
|
methods: dict = {
|
1148
1215
|
'candles': self.handle_ohlcv,
|
1149
1216
|
'ticker': self.handle_ticker,
|
1150
1217
|
'trades': self.handle_trades,
|
1151
1218
|
'orderbook': self.handle_order_book,
|
1219
|
+
'orderbook/top': self.handle_bid_ask,
|
1152
1220
|
'spot_order': self.handle_order,
|
1153
1221
|
'spot_orders': self.handle_order,
|
1154
1222
|
'margin_order': self.handle_order,
|
ccxt/pro/hollaex.py
CHANGED
@@ -62,6 +62,7 @@ class hollaex(ccxt.async_support.hollaex):
|
|
62
62
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
63
63
|
"""
|
64
64
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
65
|
+
:see: https://apidocs.hollaex.com/#sending-receiving-messages
|
65
66
|
:param str symbol: unified symbol of the market to fetch the order book for
|
66
67
|
:param int [limit]: the maximum amount of order book entries to return
|
67
68
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -116,6 +117,7 @@ class hollaex(ccxt.async_support.hollaex):
|
|
116
117
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
117
118
|
"""
|
118
119
|
get the list of most recent trades for a particular symbol
|
120
|
+
:see: https://apidocs.hollaex.com/#sending-receiving-messages
|
119
121
|
:param str symbol: unified symbol of the market to fetch trades for
|
120
122
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
121
123
|
:param int [limit]: the maximum amount of trades to fetch
|
@@ -167,6 +169,7 @@ class hollaex(ccxt.async_support.hollaex):
|
|
167
169
|
async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
168
170
|
"""
|
169
171
|
watches information on multiple trades made by the user
|
172
|
+
:see: https://apidocs.hollaex.com/#sending-receiving-messages
|
170
173
|
:param str symbol: unified market symbol of the market trades were made in
|
171
174
|
:param int [since]: the earliest time in ms to fetch trades for
|
172
175
|
:param int [limit]: the maximum number of trade structures to retrieve
|
@@ -239,6 +242,7 @@ class hollaex(ccxt.async_support.hollaex):
|
|
239
242
|
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
240
243
|
"""
|
241
244
|
watches information on multiple orders made by the user
|
245
|
+
:see: https://apidocs.hollaex.com/#sending-receiving-messages
|
242
246
|
:param str symbol: unified market symbol of the market orders were made in
|
243
247
|
:param int [since]: the earliest time in ms to fetch orders for
|
244
248
|
:param int [limit]: the maximum number of order structures to retrieve
|
@@ -350,6 +354,7 @@ class hollaex(ccxt.async_support.hollaex):
|
|
350
354
|
async def watch_balance(self, params={}) -> Balances:
|
351
355
|
"""
|
352
356
|
watch balance and get the amount of funds available for trading or funds locked in orders
|
357
|
+
:see: https://apidocs.hollaex.com/#sending-receiving-messages
|
353
358
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
354
359
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
355
360
|
"""
|
ccxt/pro/okx.py
CHANGED
@@ -2055,10 +2055,21 @@ class okx(ccxt.async_support.okx):
|
|
2055
2055
|
try:
|
2056
2056
|
if errorCode and errorCode != '0':
|
2057
2057
|
feedback = self.id + ' ' + self.json(message)
|
2058
|
-
|
2058
|
+
if errorCode != '1':
|
2059
|
+
self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
|
2059
2060
|
messageString = self.safe_value(message, 'msg')
|
2060
2061
|
if messageString is not None:
|
2061
2062
|
self.throw_broadly_matched_exception(self.exceptions['broad'], messageString, feedback)
|
2063
|
+
else:
|
2064
|
+
data = self.safe_list(message, 'data', [])
|
2065
|
+
for i in range(0, len(data)):
|
2066
|
+
d = data[i]
|
2067
|
+
errorCode = self.safe_string(d, 'sCode')
|
2068
|
+
if errorCode is not None:
|
2069
|
+
self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
|
2070
|
+
messageString = self.safe_value(message, 'sMsg')
|
2071
|
+
if messageString is not None:
|
2072
|
+
self.throw_broadly_matched_exception(self.exceptions['broad'], messageString, feedback)
|
2062
2073
|
raise ExchangeError(feedback)
|
2063
2074
|
except Exception as e:
|
2064
2075
|
# if the message contains an id, it means it is a response to a request
|
ccxt/pro/p2b.py
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
import ccxt.async_support
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheByTimestamp
|
8
|
-
from ccxt.base.types import Int, OrderBook, Ticker, Trade
|
8
|
+
from ccxt.base.types import Int, OrderBook, Strings, Ticker, Tickers, Trade
|
9
9
|
from ccxt.async_support.base.ws.client import Client
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import ExchangeError
|
@@ -34,7 +34,7 @@ class p2b(ccxt.async_support.p2b):
|
|
34
34
|
'watchOrders': False,
|
35
35
|
# 'watchStatus': True,
|
36
36
|
'watchTicker': True,
|
37
|
-
'watchTickers':
|
37
|
+
'watchTickers': True,
|
38
38
|
'watchTrades': True,
|
39
39
|
'watchTradesForSymbols': True,
|
40
40
|
},
|
@@ -133,6 +133,36 @@ class p2b(ccxt.async_support.p2b):
|
|
133
133
|
messageHash = name + '::' + market['symbol']
|
134
134
|
return await self.subscribe(name + '.subscribe', messageHash, request, params)
|
135
135
|
|
136
|
+
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
137
|
+
"""
|
138
|
+
:see: https://github.com/P2B-team/P2B-WSS-Public/blob/main/wss_documentation.md#last-price
|
139
|
+
:see: https://github.com/P2B-team/P2B-WSS-Public/blob/main/wss_documentation.md#market-status
|
140
|
+
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
141
|
+
:param str[] [symbols]: unified symbol of the market to fetch the ticker for
|
142
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
143
|
+
:param dict [params.method]: 'state'(default) or 'price'
|
144
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
145
|
+
"""
|
146
|
+
await self.load_markets()
|
147
|
+
symbols = self.market_symbols(symbols, None, False)
|
148
|
+
watchTickerOptions = self.safe_dict(self.options, 'watchTicker')
|
149
|
+
name = self.safe_string(watchTickerOptions, 'name', 'state') # or price
|
150
|
+
name, params = self.handle_option_and_params(params, 'method', 'name', name)
|
151
|
+
messageHashes = []
|
152
|
+
args = []
|
153
|
+
for i in range(0, len(symbols)):
|
154
|
+
market = self.market(symbols[i])
|
155
|
+
messageHashes.append(name + '::' + market['symbol'])
|
156
|
+
args.append(market['id'])
|
157
|
+
url = self.urls['api']['ws']
|
158
|
+
request: dict = {
|
159
|
+
'method': name + '.subscribe',
|
160
|
+
'params': args,
|
161
|
+
'id': self.milliseconds(),
|
162
|
+
}
|
163
|
+
await self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
|
164
|
+
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
165
|
+
|
136
166
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
137
167
|
"""
|
138
168
|
get the list of most recent trades for a particular symbol
|
@@ -332,6 +362,7 @@ class p2b(ccxt.async_support.p2b):
|
|
332
362
|
else:
|
333
363
|
ticker = self.parse_ticker(tickerData, market)
|
334
364
|
symbol = ticker['symbol']
|
365
|
+
self.tickers[symbol] = ticker
|
335
366
|
messageHash = messageHashStart + '::' + symbol
|
336
367
|
client.resolve(ticker, messageHash)
|
337
368
|
return message
|
ccxt/pro/whitebit.py
CHANGED
@@ -5,7 +5,7 @@
|
|
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 Balances, Int, Order, OrderBook, Str, Ticker, Trade
|
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
11
|
from ccxt.base.errors import AuthenticationError
|
@@ -26,6 +26,7 @@ class whitebit(ccxt.async_support.whitebit):
|
|
26
26
|
'watchOrderBook': True,
|
27
27
|
'watchOrders': True,
|
28
28
|
'watchTicker': True,
|
29
|
+
'watchTickers': True,
|
29
30
|
'watchTrades': True,
|
30
31
|
'watchTradesForSymbols': False,
|
31
32
|
},
|
@@ -249,6 +250,33 @@ class whitebit(ccxt.async_support.whitebit):
|
|
249
250
|
# every time we want to subscribe to another market we have to "re-subscribe" sending it all again
|
250
251
|
return await self.watch_multiple_subscription(messageHash, method, symbol, False, params)
|
251
252
|
|
253
|
+
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
254
|
+
"""
|
255
|
+
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
256
|
+
:see: https://docs.whitebit.com/public/websocket/#market-statistics
|
257
|
+
:param str[] [symbols]: unified symbol of the market to fetch the ticker for
|
258
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
259
|
+
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
260
|
+
"""
|
261
|
+
await self.load_markets()
|
262
|
+
symbols = self.market_symbols(symbols, None, False)
|
263
|
+
method = 'market_subscribe'
|
264
|
+
url = self.urls['api']['ws']
|
265
|
+
id = self.nonce()
|
266
|
+
messageHashes = []
|
267
|
+
args = []
|
268
|
+
for i in range(0, len(symbols)):
|
269
|
+
market = self.market(symbols[i])
|
270
|
+
messageHashes.append('ticker:' + market['symbol'])
|
271
|
+
args.append(market['id'])
|
272
|
+
request: dict = {
|
273
|
+
'id': id,
|
274
|
+
'method': method,
|
275
|
+
'params': args,
|
276
|
+
}
|
277
|
+
await self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
|
278
|
+
return self.filter_by_array(self.tickers, 'symbol', symbols)
|
279
|
+
|
252
280
|
def handle_ticker(self, client: Client, message):
|
253
281
|
#
|
254
282
|
# {
|
ccxt/vertex.py
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
from ccxt.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.vertex import ImplicitAPI
|
8
|
-
from ccxt.base.types import Balances, Currencies, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees
|
8
|
+
from ccxt.base.types import Balances, Currencies, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFees
|
9
9
|
from typing import List
|
10
10
|
from ccxt.base.errors import ExchangeError
|
11
11
|
from ccxt.base.errors import AuthenticationError
|
@@ -1154,7 +1154,7 @@ class vertex(Exchange, ImplicitAPI):
|
|
1154
1154
|
rows = self.safe_list(response, 'candlesticks', [])
|
1155
1155
|
return self.parse_ohlcvs(rows, market, timeframe, since, limit)
|
1156
1156
|
|
1157
|
-
def parse_funding_rate(self, ticker, market: Market = None):
|
1157
|
+
def parse_funding_rate(self, ticker, market: Market = None) -> FundingRate:
|
1158
1158
|
#
|
1159
1159
|
# {
|
1160
1160
|
# "product_id": 4,
|
@@ -1208,9 +1208,10 @@ class vertex(Exchange, ImplicitAPI):
|
|
1208
1208
|
'previousFundingRate': None,
|
1209
1209
|
'previousFundingTimestamp': None,
|
1210
1210
|
'previousFundingDatetime': None,
|
1211
|
+
'interval': None,
|
1211
1212
|
}
|
1212
1213
|
|
1213
|
-
def fetch_funding_rate(self, symbol: str, params={}):
|
1214
|
+
def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
|
1214
1215
|
"""
|
1215
1216
|
fetch the current funding rate
|
1216
1217
|
:see: https://docs.vertexprotocol.com/developer-resources/api/archive-indexer/funding-rate
|
@@ -1235,13 +1236,13 @@ class vertex(Exchange, ImplicitAPI):
|
|
1235
1236
|
#
|
1236
1237
|
return self.parse_funding_rate(response, market)
|
1237
1238
|
|
1238
|
-
def fetch_funding_rates(self, symbols: Strings = None, params={}):
|
1239
|
+
def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
|
1239
1240
|
"""
|
1240
1241
|
fetches funding rates for multiple markets
|
1241
1242
|
:see: https://docs.vertexprotocol.com/developer-resources/api/v2/contracts
|
1242
1243
|
:param str[] symbols: unified symbols of the markets to fetch the funding rates for, all market funding rates are returned if not assigned
|
1243
1244
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1244
|
-
:returns dict: an array of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
1245
|
+
:returns dict[]: an array of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
1245
1246
|
"""
|
1246
1247
|
self.load_markets()
|
1247
1248
|
request = {}
|