ccxt 4.3.72__py2.py3-none-any.whl → 4.3.74__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.
Potentially problematic release.
This version of ccxt might be problematic. Click here for more details.
- ccxt/__init__.py +1 -1
- ccxt/abstract/binance.py +5 -0
- ccxt/abstract/binancecoinm.py +5 -0
- ccxt/abstract/binanceus.py +5 -0
- ccxt/abstract/binanceusdm.py +5 -0
- ccxt/ace.py +1 -1
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ace.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/base/ws/client.py +1 -1
- ccxt/async_support/binance.py +222 -84
- ccxt/async_support/bybit.py +2 -2
- ccxt/async_support/woo.py +1 -1
- ccxt/async_support/yobit.py +49 -26
- ccxt/base/exchange.py +1 -1
- ccxt/binance.py +222 -84
- ccxt/bybit.py +2 -2
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/alpaca.py +5 -0
- ccxt/pro/binance.py +31 -3
- ccxt/pro/bitfinex.py +5 -0
- ccxt/pro/kucoin.py +4 -0
- ccxt/pro/woo.py +111 -12
- ccxt/test/tests_async.py +3 -2
- ccxt/test/tests_helpers.py +3 -0
- ccxt/test/tests_sync.py +3 -2
- ccxt/woo.py +1 -1
- ccxt/yobit.py +48 -26
- {ccxt-4.3.72.dist-info → ccxt-4.3.74.dist-info}/METADATA +6 -6
- {ccxt-4.3.72.dist-info → ccxt-4.3.74.dist-info}/RECORD +33 -33
- {ccxt-4.3.72.dist-info → ccxt-4.3.74.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.3.72.dist-info → ccxt-4.3.74.dist-info}/WHEEL +0 -0
- {ccxt-4.3.72.dist-info → ccxt-4.3.74.dist-info}/top_level.txt +0 -0
ccxt/pro/alpaca.py
CHANGED
@@ -56,6 +56,7 @@ class alpaca(ccxt.async_support.alpaca):
|
|
56
56
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
57
57
|
"""
|
58
58
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
59
|
+
:see: https://docs.alpaca.markets/docs/real-time-crypto-pricing-data#quotes
|
59
60
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
60
61
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
61
62
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
@@ -129,6 +130,7 @@ class alpaca(ccxt.async_support.alpaca):
|
|
129
130
|
async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
130
131
|
"""
|
131
132
|
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
133
|
+
:see: https://docs.alpaca.markets/docs/real-time-crypto-pricing-data#bars
|
132
134
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
133
135
|
:param str timeframe: the length of time each candle represents
|
134
136
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
@@ -181,6 +183,7 @@ class alpaca(ccxt.async_support.alpaca):
|
|
181
183
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
182
184
|
"""
|
183
185
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
186
|
+
:see: https://docs.alpaca.markets/docs/real-time-crypto-pricing-data#orderbooks
|
184
187
|
:param str symbol: unified symbol of the market to fetch the order book for
|
185
188
|
:param int [limit]: the maximum amount of order book entries to return.
|
186
189
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -254,6 +257,7 @@ class alpaca(ccxt.async_support.alpaca):
|
|
254
257
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
255
258
|
"""
|
256
259
|
watches information on multiple trades made in a market
|
260
|
+
:see: https://docs.alpaca.markets/docs/real-time-crypto-pricing-data#trades
|
257
261
|
:param str symbol: unified market symbol of the market trades were made in
|
258
262
|
:param int [since]: the earliest time in ms to fetch orders for
|
259
263
|
:param int [limit]: the maximum number of trade structures to retrieve
|
@@ -302,6 +306,7 @@ class alpaca(ccxt.async_support.alpaca):
|
|
302
306
|
async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
303
307
|
"""
|
304
308
|
watches information on multiple trades made by the user
|
309
|
+
:see: https://docs.alpaca.markets/docs/websocket-streaming#trade-updates
|
305
310
|
:param str symbol: unified market symbol of the market trades were made in
|
306
311
|
:param int [since]: the earliest time in ms to fetch trades for
|
307
312
|
:param int [limit]: the maximum number of trade structures to retrieve
|
ccxt/pro/binance.py
CHANGED
@@ -864,10 +864,15 @@ class binance(ccxt.async_support.binance):
|
|
864
864
|
async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
865
865
|
"""
|
866
866
|
get the list of most recent trades for a list of symbols
|
867
|
+
:see: https://binance-docs.github.io/apidocs/spot/en/#aggregate-trade-streams
|
868
|
+
:see: https://binance-docs.github.io/apidocs/spot/en/#trade-streams
|
869
|
+
:see: https://binance-docs.github.io/apidocs/futures/en/#aggregate-trade-streams
|
870
|
+
:see: https://binance-docs.github.io/apidocs/delivery/en/#aggregate-trade-streams
|
867
871
|
:param str[] symbols: unified symbol of the market to fetch trades for
|
868
872
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
869
873
|
:param int [limit]: the maximum amount of trades to fetch
|
870
874
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
875
|
+
:param str [params.name]: the name of the method to call, 'trade' or 'aggTrade', default is 'trade'
|
871
876
|
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
872
877
|
"""
|
873
878
|
await self.load_markets()
|
@@ -878,8 +883,9 @@ class binance(ccxt.async_support.binance):
|
|
878
883
|
if symbolsLength > 200:
|
879
884
|
raise BadRequest(self.id + ' watchTradesForSymbols() accepts 200 symbols at most. To watch more symbols call watchTradesForSymbols() multiple times')
|
880
885
|
streamHash += '::' + ','.join(symbols)
|
881
|
-
|
882
|
-
name = self.
|
886
|
+
name = None
|
887
|
+
name, params = self.handle_option_and_params(params, 'watchTradesForSymbols', 'name', 'trade')
|
888
|
+
params = self.omit(params, 'callerMethodName')
|
883
889
|
firstMarket = self.market(symbols[0])
|
884
890
|
type = firstMarket['type']
|
885
891
|
if firstMarket['contract']:
|
@@ -914,12 +920,18 @@ class binance(ccxt.async_support.binance):
|
|
914
920
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
915
921
|
"""
|
916
922
|
get the list of most recent trades for a particular symbol
|
923
|
+
:see: https://binance-docs.github.io/apidocs/spot/en/#aggregate-trade-streams
|
924
|
+
:see: https://binance-docs.github.io/apidocs/spot/en/#trade-streams
|
925
|
+
:see: https://binance-docs.github.io/apidocs/futures/en/#aggregate-trade-streams
|
926
|
+
:see: https://binance-docs.github.io/apidocs/delivery/en/#aggregate-trade-streams
|
917
927
|
:param str symbol: unified symbol of the market to fetch trades for
|
918
928
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
919
929
|
:param int [limit]: the maximum amount of trades to fetch
|
920
930
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
931
|
+
:param str [params.name]: the name of the method to call, 'trade' or 'aggTrade', default is 'trade'
|
921
932
|
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
922
933
|
"""
|
934
|
+
params['callerMethodName'] = 'watchTrades'
|
923
935
|
return await self.watch_trades_for_symbols([symbol], since, limit, params)
|
924
936
|
|
925
937
|
def parse_ws_trade(self, trade, market=None) -> Trade:
|
@@ -1098,11 +1110,15 @@ class binance(ccxt.async_support.binance):
|
|
1098
1110
|
async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
1099
1111
|
"""
|
1100
1112
|
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
1113
|
+
:see: https://binance-docs.github.io/apidocs/spot/en/#kline-candlestick-data
|
1114
|
+
:see: https://binance-docs.github.io/apidocs/futures/en/#kline-candlestick-data
|
1115
|
+
:see: https://binance-docs.github.io/apidocs/delivery/en/#kline-candlestick-data
|
1101
1116
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
1102
1117
|
:param str timeframe: the length of time each candle represents
|
1103
1118
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
1104
1119
|
:param int [limit]: the maximum amount of candles to fetch
|
1105
1120
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1121
|
+
:param dict [params.timezone]: if provided, kline intervals are interpreted in that timezone instead of UTC, example '+08:00'
|
1106
1122
|
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
1107
1123
|
"""
|
1108
1124
|
params['callerMethodName'] = 'watchOHLCV'
|
@@ -1112,10 +1128,14 @@ class binance(ccxt.async_support.binance):
|
|
1112
1128
|
async def watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], since: Int = None, limit: Int = None, params={}):
|
1113
1129
|
"""
|
1114
1130
|
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
1131
|
+
:see: https://binance-docs.github.io/apidocs/spot/en/#kline-candlestick-data
|
1132
|
+
:see: https://binance-docs.github.io/apidocs/futures/en/#kline-candlestick-data
|
1133
|
+
:see: https://binance-docs.github.io/apidocs/delivery/en/#kline-candlestick-data
|
1115
1134
|
:param str[][] symbolsAndTimeframes: array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
|
1116
1135
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
1117
1136
|
:param int [limit]: the maximum amount of candles to fetch
|
1118
1137
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1138
|
+
:param dict [params.timezone]: if provided, kline intervals are interpreted in that timezone instead of UTC, example '+08:00'
|
1119
1139
|
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
1120
1140
|
"""
|
1121
1141
|
await self.load_markets()
|
@@ -1127,6 +1147,10 @@ class binance(ccxt.async_support.binance):
|
|
1127
1147
|
type = firstMarket['type']
|
1128
1148
|
if firstMarket['contract']:
|
1129
1149
|
type = 'future' if firstMarket['linear'] else 'delivery'
|
1150
|
+
isSpot = (type == 'spot')
|
1151
|
+
timezone = None
|
1152
|
+
timezone, params = self.handle_param_string(params, 'timezone', None)
|
1153
|
+
isUtc8 = (timezone is not None) and ((timezone == '+08:00') or Precise.string_eq(timezone, '8'))
|
1130
1154
|
rawHashes = []
|
1131
1155
|
messageHashes = []
|
1132
1156
|
for i in range(0, len(symbolsAndTimeframes)):
|
@@ -1139,7 +1163,10 @@ class binance(ccxt.async_support.binance):
|
|
1139
1163
|
if klineType == 'indexPriceKline':
|
1140
1164
|
# weird behavior for index price kline we can't use the perp suffix
|
1141
1165
|
marketId = marketId.replace('_perp', '')
|
1142
|
-
|
1166
|
+
shouldUseUTC8 = (isUtc8 and isSpot)
|
1167
|
+
suffix = '@+08:00'
|
1168
|
+
utcSuffix = suffix if shouldUseUTC8 else ''
|
1169
|
+
rawHashes.append(marketId + '@' + klineType + '_' + interval + utcSuffix)
|
1143
1170
|
messageHashes.append('ohlcv::' + symbolString + '::' + timeframeString)
|
1144
1171
|
url = self.urls['api']['ws'][type] + '/' + self.stream(type, 'multipleOHLCV')
|
1145
1172
|
requestId = self.request_id(url)
|
@@ -1151,6 +1178,7 @@ class binance(ccxt.async_support.binance):
|
|
1151
1178
|
subscribe = {
|
1152
1179
|
'id': requestId,
|
1153
1180
|
}
|
1181
|
+
params = self.omit(params, 'callerMethodName')
|
1154
1182
|
symbol, timeframe, candles = await self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes, subscribe)
|
1155
1183
|
if self.newUpdates:
|
1156
1184
|
limit = candles.getLimit(symbol, limit)
|
ccxt/pro/bitfinex.py
CHANGED
@@ -62,6 +62,7 @@ class bitfinex(ccxt.async_support.bitfinex):
|
|
62
62
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
63
63
|
"""
|
64
64
|
get the list of most recent trades for a particular symbol
|
65
|
+
:see: https://docs.bitfinex.com/v1/reference/ws-public-trades
|
65
66
|
:param str symbol: unified symbol of the market to fetch trades for
|
66
67
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
67
68
|
:param int [limit]: the maximum amount of trades to fetch
|
@@ -78,6 +79,7 @@ class bitfinex(ccxt.async_support.bitfinex):
|
|
78
79
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
79
80
|
"""
|
80
81
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
82
|
+
:see: https://docs.bitfinex.com/v1/reference/ws-public-ticker
|
81
83
|
:param str symbol: 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>`
|
@@ -238,6 +240,7 @@ class bitfinex(ccxt.async_support.bitfinex):
|
|
238
240
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
239
241
|
"""
|
240
242
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
243
|
+
:see: https://docs.bitfinex.com/v1/reference/ws-public-order-books
|
241
244
|
:param str symbol: unified symbol of the market to fetch the order book for
|
242
245
|
:param int [limit]: the maximum amount of order book entries to return
|
243
246
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -430,6 +433,8 @@ class bitfinex(ccxt.async_support.bitfinex):
|
|
430
433
|
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
431
434
|
"""
|
432
435
|
watches information on multiple orders made by the user
|
436
|
+
:see: https://docs.bitfinex.com/v1/reference/ws-auth-order-updates
|
437
|
+
:see: https://docs.bitfinex.com/v1/reference/ws-auth-order-snapshots
|
433
438
|
:param str symbol: unified market symbol of the market orders were made in
|
434
439
|
:param int [since]: the earliest time in ms to fetch orders for
|
435
440
|
:param int [limit]: the maximum number of order structures to retrieve
|
ccxt/pro/kucoin.py
CHANGED
@@ -1024,6 +1024,10 @@ class kucoin(ccxt.async_support.kucoin):
|
|
1024
1024
|
tradeId = self.safe_string(trade, 'tradeId')
|
1025
1025
|
price = self.safe_string(trade, 'matchPrice')
|
1026
1026
|
amount = self.safe_string(trade, 'matchSize')
|
1027
|
+
if price is None:
|
1028
|
+
# /spot/tradeFills
|
1029
|
+
price = self.safe_string(trade, 'price')
|
1030
|
+
amount = self.safe_string(trade, 'size')
|
1027
1031
|
order = self.safe_string(trade, 'orderId')
|
1028
1032
|
timestamp = self.safe_integer_product_2(trade, 'ts', 'time', 0.000001)
|
1029
1033
|
feeCurrency = market['quote']
|
ccxt/pro/woo.py
CHANGED
@@ -90,32 +90,48 @@ class woo(ccxt.async_support.woo):
|
|
90
90
|
|
91
91
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
92
92
|
"""
|
93
|
+
:see: https://docs.woo.org/#orderbookupdate
|
93
94
|
:see: https://docs.woo.org/#orderbook
|
94
95
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
95
96
|
:param str symbol: unified symbol of the market to fetch the order book for
|
96
97
|
:param int [limit]: the maximum amount of order book entries to return.
|
97
98
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
99
|
+
:param str [params.method]: either(default) 'orderbook' or 'orderbookupdate', default is 'orderbook'
|
98
100
|
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
99
101
|
"""
|
100
102
|
await self.load_markets()
|
101
|
-
|
103
|
+
method = None
|
104
|
+
method, params = self.handle_option_and_params(params, 'watchOrderBook', 'method', 'orderbook')
|
102
105
|
market = self.market(symbol)
|
103
|
-
topic = market['id'] + '@' +
|
106
|
+
topic = market['id'] + '@' + method
|
107
|
+
urlUid = '/' + self.uid if (self.uid) else ''
|
108
|
+
url = self.urls['api']['ws']['public'] + urlUid
|
109
|
+
requestId = self.request_id(url)
|
104
110
|
request: dict = {
|
105
111
|
'event': 'subscribe',
|
106
112
|
'topic': topic,
|
113
|
+
'id': requestId,
|
107
114
|
}
|
108
|
-
|
109
|
-
|
115
|
+
subscription: dict = {
|
116
|
+
'id': str(requestId),
|
117
|
+
'name': method,
|
118
|
+
'symbol': symbol,
|
119
|
+
'limit': limit,
|
120
|
+
'params': params,
|
121
|
+
}
|
122
|
+
if method == 'orderbookupdate':
|
123
|
+
subscription['method'] = self.handle_order_book_subscription
|
124
|
+
orderbook = await self.watch(url, topic, self.extend(request, params), topic, subscription)
|
110
125
|
return orderbook.limit()
|
111
126
|
|
112
127
|
def handle_order_book(self, client: Client, message):
|
113
128
|
#
|
114
129
|
# {
|
115
|
-
# "topic": "PERP_BTC_USDT@
|
116
|
-
# "ts":
|
130
|
+
# "topic": "PERP_BTC_USDT@orderbookupdate",
|
131
|
+
# "ts": 1722500373999,
|
117
132
|
# "data": {
|
118
133
|
# "symbol": "PERP_BTC_USDT",
|
134
|
+
# "prevTs": 1722500373799,
|
119
135
|
# "bids": [
|
120
136
|
# [
|
121
137
|
# 0.30891,
|
@@ -136,13 +152,89 @@ class woo(ccxt.async_support.woo):
|
|
136
152
|
market = self.safe_market(marketId)
|
137
153
|
symbol = market['symbol']
|
138
154
|
topic = self.safe_string(message, 'topic')
|
139
|
-
|
140
|
-
|
141
|
-
|
155
|
+
method = self.safe_string(topic.split('@'), 1)
|
156
|
+
if method == 'orderbookupdate':
|
157
|
+
if not (symbol in self.orderbooks):
|
158
|
+
return
|
159
|
+
orderbook = self.orderbooks[symbol]
|
160
|
+
timestamp = self.safe_integer(orderbook, 'timestamp')
|
161
|
+
if timestamp is None:
|
162
|
+
orderbook.cache.append(message)
|
163
|
+
else:
|
164
|
+
try:
|
165
|
+
ts = self.safe_integer(message, 'ts')
|
166
|
+
if ts > timestamp:
|
167
|
+
self.handle_order_book_message(client, message, orderbook)
|
168
|
+
client.resolve(orderbook, topic)
|
169
|
+
except Exception as e:
|
170
|
+
del self.orderbooks[symbol]
|
171
|
+
del client.subscriptions[topic]
|
172
|
+
client.reject(e, topic)
|
173
|
+
else:
|
174
|
+
if not (symbol in self.orderbooks):
|
175
|
+
defaultLimit = self.safe_integer(self.options, 'watchOrderBookLimit', 1000)
|
176
|
+
subscription = client.subscriptions[topic]
|
177
|
+
limit = self.safe_integer(subscription, 'limit', defaultLimit)
|
178
|
+
self.orderbooks[symbol] = self.order_book({}, limit)
|
179
|
+
orderbook = self.orderbooks[symbol]
|
180
|
+
timestamp = self.safe_integer(message, 'ts')
|
181
|
+
snapshot = self.parse_order_book(data, symbol, timestamp, 'bids', 'asks')
|
182
|
+
orderbook.reset(snapshot)
|
183
|
+
client.resolve(orderbook, topic)
|
184
|
+
|
185
|
+
def handle_order_book_subscription(self, client: Client, message, subscription):
|
186
|
+
defaultLimit = self.safe_integer(self.options, 'watchOrderBookLimit', 1000)
|
187
|
+
limit = self.safe_integer(subscription, 'limit', defaultLimit)
|
188
|
+
symbol = self.safe_string(subscription, 'symbol') # watchOrderBook
|
189
|
+
if symbol in self.orderbooks:
|
190
|
+
del self.orderbooks[symbol]
|
191
|
+
self.orderbooks[symbol] = self.order_book({}, limit)
|
192
|
+
self.spawn(self.fetch_order_book_snapshot, client, message, subscription)
|
193
|
+
|
194
|
+
async def fetch_order_book_snapshot(self, client, message, subscription):
|
195
|
+
symbol = self.safe_string(subscription, 'symbol')
|
196
|
+
messageHash = self.safe_string(message, 'topic')
|
197
|
+
try:
|
198
|
+
defaultLimit = self.safe_integer(self.options, 'watchOrderBookLimit', 1000)
|
199
|
+
limit = self.safe_integer(subscription, 'limit', defaultLimit)
|
200
|
+
params = self.safe_value(subscription, 'params')
|
201
|
+
snapshot = await self.fetch_rest_order_book_safe(symbol, limit, params)
|
202
|
+
if self.safe_value(self.orderbooks, symbol) is None:
|
203
|
+
# if the orderbook is dropped before the snapshot is received
|
204
|
+
return
|
205
|
+
orderbook = self.orderbooks[symbol]
|
206
|
+
orderbook.reset(snapshot)
|
207
|
+
messages = orderbook.cache
|
208
|
+
for i in range(0, len(messages)):
|
209
|
+
messageItem = messages[i]
|
210
|
+
ts = self.safe_integer(messageItem, 'ts')
|
211
|
+
if ts < orderbook['timestamp']:
|
212
|
+
continue
|
213
|
+
else:
|
214
|
+
self.handle_order_book_message(client, messageItem, orderbook)
|
215
|
+
self.orderbooks[symbol] = orderbook
|
216
|
+
client.resolve(orderbook, messageHash)
|
217
|
+
except Exception as e:
|
218
|
+
del client.subscriptions[messageHash]
|
219
|
+
client.reject(e, messageHash)
|
220
|
+
|
221
|
+
def handle_order_book_message(self, client: Client, message, orderbook):
|
222
|
+
data = self.safe_dict(message, 'data')
|
223
|
+
self.handle_deltas(orderbook['asks'], self.safe_value(data, 'asks', []))
|
224
|
+
self.handle_deltas(orderbook['bids'], self.safe_value(data, 'bids', []))
|
142
225
|
timestamp = self.safe_integer(message, 'ts')
|
143
|
-
|
144
|
-
orderbook.
|
145
|
-
|
226
|
+
orderbook['timestamp'] = timestamp
|
227
|
+
orderbook['datetime'] = self.iso8601(timestamp)
|
228
|
+
return orderbook
|
229
|
+
|
230
|
+
def handle_delta(self, bookside, delta):
|
231
|
+
price = self.safe_float_2(delta, 'price', 0)
|
232
|
+
amount = self.safe_float_2(delta, 'quantity', 1)
|
233
|
+
bookside.store(price, amount)
|
234
|
+
|
235
|
+
def handle_deltas(self, bookside, deltas):
|
236
|
+
for i in range(0, len(deltas)):
|
237
|
+
self.handle_delta(bookside, deltas[i])
|
146
238
|
|
147
239
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
148
240
|
"""
|
@@ -998,6 +1090,7 @@ class woo(ccxt.async_support.woo):
|
|
998
1090
|
'pong': self.handle_pong,
|
999
1091
|
'subscribe': self.handle_subscribe,
|
1000
1092
|
'orderbook': self.handle_order_book,
|
1093
|
+
'orderbookupdate': self.handle_order_book,
|
1001
1094
|
'ticker': self.handle_ticker,
|
1002
1095
|
'tickers': self.handle_tickers,
|
1003
1096
|
'kline': self.handle_ohlcv,
|
@@ -1056,6 +1149,12 @@ class woo(ccxt.async_support.woo):
|
|
1056
1149
|
# "ts": 1657117712212
|
1057
1150
|
# }
|
1058
1151
|
#
|
1152
|
+
id = self.safe_string(message, 'id')
|
1153
|
+
subscriptionsById = self.index_by(client.subscriptions, 'id')
|
1154
|
+
subscription = self.safe_value(subscriptionsById, id, {})
|
1155
|
+
method = self.safe_value(subscription, 'method')
|
1156
|
+
if method is not None:
|
1157
|
+
method(client, message, subscription)
|
1059
1158
|
return message
|
1060
1159
|
|
1061
1160
|
def handle_auth(self, client: Client, message):
|
ccxt/test/tests_async.py
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
import asyncio
|
4
4
|
|
5
5
|
|
6
|
-
from tests_helpers import AuthenticationError, NotSupported, InvalidProxySettings, ExchangeNotAvailable, OperationFailed, OnMaintenance, get_cli_arg_value, baseMainTestClass, dump, json_parse, json_stringify, convert_ascii, io_file_exists, io_file_read, io_dir_read, call_method, call_method_sync, call_exchange_method_dynamically, call_exchange_method_dynamically_sync, exception_message, exit_script, get_exchange_prop, set_exchange_prop, init_exchange, get_test_files_sync, get_test_files, set_fetch_response, is_null_value, close # noqa: F401
|
6
|
+
from tests_helpers import AuthenticationError, NotSupported, InvalidProxySettings, ExchangeNotAvailable, OperationFailed, OnMaintenance, get_cli_arg_value, baseMainTestClass, dump, json_parse, json_stringify, convert_ascii, io_file_exists, io_file_read, io_dir_read, call_method, call_method_sync, call_exchange_method_dynamically, call_exchange_method_dynamically_sync, get_root_exception, exception_message, exit_script, get_exchange_prop, set_exchange_prop, init_exchange, get_test_files_sync, get_test_files, set_fetch_response, is_null_value, close # noqa: F401
|
7
7
|
|
8
8
|
class testMainClass(baseMainTestClass):
|
9
9
|
def parse_cli_args(self):
|
@@ -261,7 +261,8 @@ class testMainClass(baseMainTestClass):
|
|
261
261
|
try:
|
262
262
|
await self.test_method(method_name, exchange, args, is_public)
|
263
263
|
return True
|
264
|
-
except Exception as
|
264
|
+
except Exception as ex:
|
265
|
+
e = get_root_exception(ex)
|
265
266
|
is_load_markets = (method_name == 'loadMarkets')
|
266
267
|
is_auth_error = (isinstance(e, AuthenticationError))
|
267
268
|
is_not_supported = (isinstance(e, NotSupported))
|
ccxt/test/tests_helpers.py
CHANGED
ccxt/test/tests_sync.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
-
from tests_helpers import AuthenticationError, NotSupported, InvalidProxySettings, ExchangeNotAvailable, OperationFailed, OnMaintenance, get_cli_arg_value, baseMainTestClass, dump, json_parse, json_stringify, convert_ascii, io_file_exists, io_file_read, io_dir_read, call_method, call_method_sync, call_exchange_method_dynamically, call_exchange_method_dynamically_sync, exception_message, exit_script, get_exchange_prop, set_exchange_prop, init_exchange, get_test_files_sync, get_test_files, set_fetch_response, is_null_value, close # noqa: F401
|
3
|
+
from tests_helpers import AuthenticationError, NotSupported, InvalidProxySettings, ExchangeNotAvailable, OperationFailed, OnMaintenance, get_cli_arg_value, baseMainTestClass, dump, json_parse, json_stringify, convert_ascii, io_file_exists, io_file_read, io_dir_read, call_method, call_method_sync, call_exchange_method_dynamically, call_exchange_method_dynamically_sync, get_root_exception, exception_message, exit_script, get_exchange_prop, set_exchange_prop, init_exchange, get_test_files_sync, get_test_files, set_fetch_response, is_null_value, close # noqa: F401
|
4
4
|
|
5
5
|
class testMainClass(baseMainTestClass):
|
6
6
|
def parse_cli_args(self):
|
@@ -258,7 +258,8 @@ class testMainClass(baseMainTestClass):
|
|
258
258
|
try:
|
259
259
|
self.test_method(method_name, exchange, args, is_public)
|
260
260
|
return True
|
261
|
-
except Exception as
|
261
|
+
except Exception as ex:
|
262
|
+
e = get_root_exception(ex)
|
262
263
|
is_load_markets = (method_name == 'loadMarkets')
|
263
264
|
is_auth_error = (isinstance(e, AuthenticationError))
|
264
265
|
is_not_supported = (isinstance(e, NotSupported))
|
ccxt/woo.py
CHANGED
@@ -155,7 +155,7 @@ class woo(Exchange, ImplicitAPI):
|
|
155
155
|
'https://support.woo.org/hc/en-001/articles/4404611795353--Trading-Fees',
|
156
156
|
],
|
157
157
|
'referral': {
|
158
|
-
'url': 'https://x.woo.org/register?ref=
|
158
|
+
'url': 'https://x.woo.org/register?ref=DIJT0CNL',
|
159
159
|
'discount': 0.35,
|
160
160
|
},
|
161
161
|
},
|
ccxt/yobit.py
CHANGED
@@ -541,31 +541,7 @@ class yobit(Exchange, ImplicitAPI):
|
|
541
541
|
'info': ticker,
|
542
542
|
}, market)
|
543
543
|
|
544
|
-
def
|
545
|
-
"""
|
546
|
-
:see: https://yobit.net/en/api
|
547
|
-
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
548
|
-
:param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
549
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
550
|
-
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
551
|
-
"""
|
552
|
-
if symbols is None:
|
553
|
-
raise ArgumentsRequired(self.id + ' fetchTickers() requires "symbols" argument')
|
554
|
-
self.load_markets()
|
555
|
-
symbols = self.market_symbols(symbols)
|
556
|
-
ids = None
|
557
|
-
if symbols is None:
|
558
|
-
ids = self.ids
|
559
|
-
else:
|
560
|
-
ids = self.market_ids(symbols)
|
561
|
-
idsLength: number = len(ids)
|
562
|
-
idsString = '-'.join(ids)
|
563
|
-
maxLength = self.safe_integer(self.options, 'maxUrlLength', 2048)
|
564
|
-
# max URL length is 2048 symbols, including http schema, hostname, tld, etc...
|
565
|
-
lenghtOfBaseUrl = 30 # the url including api-base and endpoint dir is 30 chars
|
566
|
-
actualLength = len(idsString) + lenghtOfBaseUrl
|
567
|
-
if actualLength > maxLength:
|
568
|
-
raise ArgumentsRequired(self.id + ' fetchTickers() is being requested for ' + str(idsLength) + ' markets(which has an URL length of ' + str(actualLength) + ' characters), but it exceedes max URL length(' + str(maxLength) + '), please pass limisted symbols array to fetchTickers to fit in one request')
|
544
|
+
def fetch_tickers_helper(self, idsString: str, params={}) -> Tickers:
|
569
545
|
request: dict = {
|
570
546
|
'pair': idsString,
|
571
547
|
}
|
@@ -578,7 +554,53 @@ class yobit(Exchange, ImplicitAPI):
|
|
578
554
|
market = self.safe_market(id)
|
579
555
|
symbol = market['symbol']
|
580
556
|
result[symbol] = self.parse_ticker(ticker, market)
|
581
|
-
return
|
557
|
+
return result
|
558
|
+
|
559
|
+
def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
560
|
+
"""
|
561
|
+
:see: https://yobit.net/en/api
|
562
|
+
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
563
|
+
:param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
564
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
565
|
+
:param dict [params.all]: you can set to `true` for convenience to fetch all tickers from self exchange by sending multiple requests
|
566
|
+
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
567
|
+
"""
|
568
|
+
allSymbols = None
|
569
|
+
allSymbols, params = self.handle_param_bool(params, 'all', False)
|
570
|
+
if symbols is None and not allSymbols:
|
571
|
+
raise ArgumentsRequired(self.id + ' fetchTickers() requires "symbols" argument or use `params["all"] = True` to send multiple requests for all markets')
|
572
|
+
self.load_markets()
|
573
|
+
promises = []
|
574
|
+
maxLength = self.safe_integer(self.options, 'maxUrlLength', 2048)
|
575
|
+
# max URL length is 2048 symbols, including http schema, hostname, tld, etc...
|
576
|
+
lenghtOfBaseUrl = 40 # safe space for the url including api-base and endpoint dir is 30 chars
|
577
|
+
if allSymbols:
|
578
|
+
symbols = self.symbols
|
579
|
+
ids = ''
|
580
|
+
for i in range(0, len(self.ids)):
|
581
|
+
id = self.ids[i]
|
582
|
+
prefix = '' if (ids == '') else '-'
|
583
|
+
ids += prefix + id
|
584
|
+
if len(ids) > maxLength:
|
585
|
+
promises.append(self.fetch_tickers_helper(ids, params))
|
586
|
+
ids = ''
|
587
|
+
if ids != '':
|
588
|
+
promises.append(self.fetch_tickers_helper(ids, params))
|
589
|
+
else:
|
590
|
+
symbols = self.market_symbols(symbols)
|
591
|
+
ids = self.market_ids(symbols)
|
592
|
+
idsLength: number = len(ids)
|
593
|
+
idsString = '-'.join(ids)
|
594
|
+
actualLength = len(idsString) + lenghtOfBaseUrl
|
595
|
+
if actualLength > maxLength:
|
596
|
+
raise ArgumentsRequired(self.id + ' fetchTickers() is being requested for ' + str(idsLength) + ' markets(which has an URL length of ' + str(actualLength) + ' characters), but it exceedes max URL length(' + str(maxLength) + '), please pass limisted symbols array to fetchTickers to fit in one request')
|
597
|
+
promises.append(self.fetch_tickers_helper(idsString, params))
|
598
|
+
resultAll = promises
|
599
|
+
finalResult = {}
|
600
|
+
for i in range(0, len(resultAll)):
|
601
|
+
result = self.filter_by_array_tickers(resultAll[i], 'symbol', symbols)
|
602
|
+
finalResult = self.extend(finalResult, result)
|
603
|
+
return finalResult
|
582
604
|
|
583
605
|
def fetch_ticker(self, symbol: str, params={}) -> Ticker:
|
584
606
|
"""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ccxt
|
3
|
-
Version: 4.3.
|
3
|
+
Version: 4.3.74
|
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
|
@@ -102,7 +102,7 @@ Current feature list:
|
|
102
102
|
| [](https://futures.kucoin.com/?rcode=E5wkqe) | kucoinfutures | [KuCoin Futures](https://futures.kucoin.com/?rcode=E5wkqe) | [](https://docs.kucoin.com/futures) | cex | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | |
|
103
103
|
| [](https://www.mexc.com/register?inviteCode=mexc-1FQ1GNu1) | mexc | [MEXC Global](https://www.mexc.com/register?inviteCode=mexc-1FQ1GNu1) | [](https://mexcdevelop.github.io/apidocs/) | cex | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | |
|
104
104
|
| [](https://www.okx.com/join/CCXT2023) | okx | [OKX](https://www.okx.com/join/CCXT2023) | [](https://www.okx.com/docs-v5/en/) | cex | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | [](https://www.okx.com/join/CCXT2023) |
|
105
|
-
| [](https://x.woo.org/register?ref=
|
105
|
+
| [](https://x.woo.org/register?ref=DIJT0CNL) | woo | [WOO X](https://x.woo.org/register?ref=DIJT0CNL) | [](https://docs.woo.org/) | cex | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | [](https://x.woo.org/register?ref=DIJT0CNL) |
|
106
106
|
| [](https://dex.woo.org/en/trade?ref=CCXT) | woofipro | [WOOFI PRO](https://dex.woo.org/en/trade?ref=CCXT) | [](https://orderly.network/docs/build-on-evm/building-on-evm) | dex | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) | [](https://dex.woo.org/en/trade?ref=CCXT) |
|
107
107
|
|
108
108
|
## Supported Cryptocurrency Exchanges
|
@@ -207,7 +207,7 @@ The CCXT library currently supports the following 102 cryptocurrency exchange ma
|
|
207
207
|
| [](https://wx.network) | wavesexchange | [Waves.Exchange](https://wx.network) | [](https://docs.wx.network) | dex | | |
|
208
208
|
| [](https://wazirx.com/invite/k7rrnks5) | wazirx | [WazirX](https://wazirx.com/invite/k7rrnks5) | [](https://docs.wazirx.com/#public-rest-api-for-wazirx) | cex | | [](https://ccxt.pro) |
|
209
209
|
| [](https://whitebit.com/referral/d9bdf40e-28f2-4b52-b2f9-cd1415d82963) | whitebit | [WhiteBit](https://whitebit.com/referral/d9bdf40e-28f2-4b52-b2f9-cd1415d82963) | [](https://github.com/whitebit-exchange/api-docs) | cex | | [](https://ccxt.pro) |
|
210
|
-
| [](https://x.woo.org/register?ref=
|
210
|
+
| [](https://x.woo.org/register?ref=DIJT0CNL) | woo | [WOO X](https://x.woo.org/register?ref=DIJT0CNL) | [](https://docs.woo.org/) | cex | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) |
|
211
211
|
| [](https://dex.woo.org/en/trade?ref=CCXT) | woofipro | [WOOFI PRO](https://dex.woo.org/en/trade?ref=CCXT) | [](https://orderly.network/docs/build-on-evm/building-on-evm) | dex | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) |
|
212
212
|
| [](https://www.xt.com/en/accounts/register?ref=9PTM9VW) | xt | [XT](https://www.xt.com/en/accounts/register?ref=9PTM9VW) | [](https://doc.xt.com/) | cex | | [](https://ccxt.pro) |
|
213
213
|
| [](https://www.yobit.net) | yobit | [YoBit](https://www.yobit.net) | [](https://www.yobit.net/en/api/) | cex | | |
|
@@ -270,13 +270,13 @@ console.log(version, Object.keys(exchanges));
|
|
270
270
|
|
271
271
|
All-in-one browser bundle (dependencies included), served from a CDN of your choice:
|
272
272
|
|
273
|
-
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.
|
274
|
-
* unpkg: https://unpkg.com/ccxt@4.3.
|
273
|
+
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.74/dist/ccxt.browser.min.js
|
274
|
+
* unpkg: https://unpkg.com/ccxt@4.3.74/dist/ccxt.browser.min.js
|
275
275
|
|
276
276
|
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.
|
277
277
|
|
278
278
|
```HTML
|
279
|
-
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.
|
279
|
+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.74/dist/ccxt.browser.min.js"></script>
|
280
280
|
```
|
281
281
|
|
282
282
|
Creates a global `ccxt` object:
|