ccxt 4.3.47__py2.py3-none-any.whl → 4.3.48__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/krakenfutures.py +4 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/binance.py +5 -3
- ccxt/async_support/gate.py +92 -48
- ccxt/async_support/krakenfutures.py +4 -0
- ccxt/async_support/woo.py +4 -0
- ccxt/base/exchange.py +1 -1
- ccxt/binance.py +5 -3
- ccxt/gate.py +92 -48
- ccxt/krakenfutures.py +4 -0
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bingx.py +5 -5
- ccxt/pro/gate.py +342 -34
- ccxt/test/base/test_order_book.py +1 -1
- ccxt/woo.py +4 -0
- {ccxt-4.3.47.dist-info → ccxt-4.3.48.dist-info}/METADATA +4 -4
- {ccxt-4.3.47.dist-info → ccxt-4.3.48.dist-info}/RECORD +21 -21
- {ccxt-4.3.47.dist-info → ccxt-4.3.48.dist-info}/WHEEL +0 -0
- {ccxt-4.3.47.dist-info → ccxt-4.3.48.dist-info}/top_level.txt +0 -0
ccxt/pro/__init__.py
CHANGED
ccxt/pro/bingx.py
CHANGED
@@ -693,14 +693,14 @@ class bingx(ccxt.async_support.bingx):
|
|
693
693
|
# ]
|
694
694
|
# }
|
695
695
|
#
|
696
|
-
|
696
|
+
isSwap = client.url.find('swap') >= 0
|
697
697
|
candles = None
|
698
|
-
if
|
699
|
-
candles = data
|
698
|
+
if isSwap:
|
699
|
+
candles = self.safe_list(message, 'data', [])
|
700
700
|
else:
|
701
|
-
|
701
|
+
data = self.safe_dict(message, 'data', {})
|
702
|
+
candles = [self.safe_dict(data, 'K', {})]
|
702
703
|
dataType = self.safe_string(message, 'dataType')
|
703
|
-
isSwap = client.url.find('swap') >= 0
|
704
704
|
parts = dataType.split('@')
|
705
705
|
firstPart = parts[0]
|
706
706
|
isAllEndpoint = (firstPart == 'all')
|
ccxt/pro/gate.py
CHANGED
@@ -6,12 +6,14 @@
|
|
6
6
|
import ccxt.async_support
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Int, Liquidation, Order, OrderBook, Position, Str, Strings, Ticker, Tickers, Trade
|
9
|
+
from ccxt.base.types import Balances, Int, Liquidation, Market, MarketType, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade
|
10
10
|
from ccxt.async_support.base.ws.client import Client
|
11
11
|
from typing import List
|
12
|
+
from ccxt.base.errors import ExchangeError
|
12
13
|
from ccxt.base.errors import AuthenticationError
|
13
14
|
from ccxt.base.errors import ArgumentsRequired
|
14
15
|
from ccxt.base.errors import BadRequest
|
16
|
+
from ccxt.base.errors import NotSupported
|
15
17
|
from ccxt.base.errors import InvalidNonce
|
16
18
|
from ccxt.base.precise import Precise
|
17
19
|
|
@@ -22,6 +24,27 @@ class gate(ccxt.async_support.gate):
|
|
22
24
|
return self.deep_extend(super(gate, self).describe(), {
|
23
25
|
'has': {
|
24
26
|
'ws': True,
|
27
|
+
'cancelAllOrdersWs': True,
|
28
|
+
'cancelOrderWs': True,
|
29
|
+
'createMarketBuyOrderWithCostWs': True,
|
30
|
+
'createMarketOrderWs': True,
|
31
|
+
'createMarketOrderWithCostWs': False,
|
32
|
+
'createMarketSellOrderWithCostWs': False,
|
33
|
+
'createOrderWs': True,
|
34
|
+
'createOrdersWs': True,
|
35
|
+
'createPostOnlyOrderWs': True,
|
36
|
+
'createReduceOnlyOrderWs': True,
|
37
|
+
'createStopLimitOrderWs': True,
|
38
|
+
'createStopLossOrderWs': True,
|
39
|
+
'createStopMarketOrderWs': False,
|
40
|
+
'createStopOrderWs': True,
|
41
|
+
'createTakeProfitOrderWs': True,
|
42
|
+
'createTriggerOrderWs': True,
|
43
|
+
'editOrderWs': True,
|
44
|
+
'fetchOrderWs': True,
|
45
|
+
'fetchOrdersWs': False,
|
46
|
+
'fetchOpenOrdersWs': True,
|
47
|
+
'fetchClosedOrdersWs': True,
|
25
48
|
'watchOrderBook': True,
|
26
49
|
'watchTicker': True,
|
27
50
|
'watchTickers': True,
|
@@ -95,15 +118,228 @@ class gate(ccxt.async_support.gate):
|
|
95
118
|
'exceptions': {
|
96
119
|
'ws': {
|
97
120
|
'exact': {
|
121
|
+
'1': BadRequest,
|
98
122
|
'2': BadRequest,
|
99
123
|
'4': AuthenticationError,
|
100
124
|
'6': AuthenticationError,
|
101
125
|
'11': AuthenticationError,
|
102
126
|
},
|
127
|
+
'broad': {},
|
103
128
|
},
|
104
129
|
},
|
105
130
|
})
|
106
131
|
|
132
|
+
async def create_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
133
|
+
"""
|
134
|
+
:see: https://www.gate.io/docs/developers/apiv4/ws/en/#order-place
|
135
|
+
:see: https://www.gate.io/docs/developers/futures/ws/en/#order-place
|
136
|
+
Create an order on the exchange
|
137
|
+
:param str symbol: Unified CCXT market symbol
|
138
|
+
:param str type: 'limit' or 'market' *"market" is contract only*
|
139
|
+
:param str side: 'buy' or 'sell'
|
140
|
+
:param float amount: the amount of currency to trade
|
141
|
+
:param float [price]: *ignored in "market" orders* the price at which the order is to be fullfilled at in units of the quote currency
|
142
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
143
|
+
:param float [params.stopPrice]: The price at which a trigger order is triggered at
|
144
|
+
:param str [params.timeInForce]: "GTC", "IOC", or "PO"
|
145
|
+
:param float [params.stopLossPrice]: The price at which a stop loss order is triggered at
|
146
|
+
:param float [params.takeProfitPrice]: The price at which a take profit order is triggered at
|
147
|
+
:param str [params.marginMode]: 'cross' or 'isolated' - marginMode for margin trading if not provided self.options['defaultMarginMode'] is used
|
148
|
+
:param int [params.iceberg]: Amount to display for the iceberg order, Null or 0 for normal orders, Set to -1 to hide the order completely
|
149
|
+
:param str [params.text]: User defined information
|
150
|
+
:param str [params.account]: *spot and margin only* "spot", "margin" or "cross_margin"
|
151
|
+
:param bool [params.auto_borrow]: *margin only* Used in margin or cross margin trading to allow automatic loan of insufficient amount if balance is not enough
|
152
|
+
:param str [params.settle]: *contract only* Unified Currency Code for settle currency
|
153
|
+
:param bool [params.reduceOnly]: *contract only* Indicates if self order is to reduce the size of a position
|
154
|
+
:param bool [params.close]: *contract only* Set to close the position, with size set to 0
|
155
|
+
:param bool [params.auto_size]: *contract only* Set side to close dual-mode position, close_long closes the long side, while close_short the short one, size also needs to be set to 0
|
156
|
+
:param int [params.price_type]: *contract only* 0 latest deal price, 1 mark price, 2 index price
|
157
|
+
:param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
|
158
|
+
:returns dict|None: `An order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
159
|
+
"""
|
160
|
+
await self.load_markets()
|
161
|
+
market = self.market(symbol)
|
162
|
+
symbol = market['symbol']
|
163
|
+
messageType = self.get_type_by_market(market)
|
164
|
+
channel = messageType + '.order_place'
|
165
|
+
url = self.get_url_by_market(market)
|
166
|
+
params['textIsRequired'] = True
|
167
|
+
request = self.create_order_request(symbol, type, side, amount, price, params)
|
168
|
+
await self.authenticate(url, messageType)
|
169
|
+
rawOrder = await self.request_private(url, request, channel)
|
170
|
+
order = self.parse_order(rawOrder, market)
|
171
|
+
return order
|
172
|
+
|
173
|
+
async def create_orders_ws(self, orders: List[OrderRequest], params={}):
|
174
|
+
"""
|
175
|
+
create a list of trade orders
|
176
|
+
:see: https://www.gate.io/docs/developers/futures/ws/en/#order-batch-place
|
177
|
+
:param Array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
|
178
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
179
|
+
"""
|
180
|
+
await self.load_markets()
|
181
|
+
request = self.createOrdersRequest(orders, params)
|
182
|
+
firstOrder = orders[0]
|
183
|
+
market = self.market(firstOrder['symbol'])
|
184
|
+
if market['swap'] is not True:
|
185
|
+
raise NotSupported(self.id + ' createOrdersWs is not supported for swap markets')
|
186
|
+
messageType = self.get_type_by_market(market)
|
187
|
+
channel = messageType + '.order_batch_place'
|
188
|
+
url = self.get_url_by_market(market)
|
189
|
+
await self.authenticate(url, messageType)
|
190
|
+
rawOrders = await self.request_private(url, request, channel)
|
191
|
+
return self.parse_orders(rawOrders, market)
|
192
|
+
|
193
|
+
async def cancel_all_orders_ws(self, symbol: Str = None, params={}):
|
194
|
+
"""
|
195
|
+
cancel all open orders
|
196
|
+
:see: https://www.gate.io/docs/developers/futures/ws/en/#cancel-all-open-orders-matched
|
197
|
+
:see: https://www.gate.io/docs/developers/apiv4/ws/en/#order-cancel-all-with-specified-currency-pair
|
198
|
+
:param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
|
199
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
200
|
+
:param str [params.channel]: the channel to use, defaults to spot.order_cancel_cp or futures.order_cancel_cp
|
201
|
+
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
202
|
+
"""
|
203
|
+
await self.load_markets()
|
204
|
+
market = None if (symbol is None) else self.market(symbol)
|
205
|
+
stop = self.safe_bool_2(params, 'stop', 'trigger')
|
206
|
+
messageType = self.get_type_by_market(market)
|
207
|
+
channel = messageType + '.order_cancel_cp'
|
208
|
+
channel, params = self.handle_option_and_params(params, 'cancelAllOrdersWs', 'channel', channel)
|
209
|
+
url = self.get_url_by_market(market)
|
210
|
+
params = self.omit(params, ['stop', 'trigger'])
|
211
|
+
type, query = self.handle_market_type_and_params('cancelAllOrders', market, params)
|
212
|
+
request, requestParams = self.multiOrderSpotPrepareRequest(market, stop, query) if (type == 'spot') else self.prepareRequest(market, type, query)
|
213
|
+
await self.authenticate(url, messageType)
|
214
|
+
rawOrders = await self.request_private(url, self.extend(request, requestParams), channel)
|
215
|
+
return self.parse_orders(rawOrders, market)
|
216
|
+
|
217
|
+
async def cancel_order_ws(self, id: str, symbol: Str = None, params={}):
|
218
|
+
"""
|
219
|
+
Cancels an open order
|
220
|
+
:see: https://www.gate.io/docs/developers/apiv4/ws/en/#order-cancel
|
221
|
+
:see: https://www.gate.io/docs/developers/futures/ws/en/#order-cancel
|
222
|
+
:param str id: Order id
|
223
|
+
:param str symbol: Unified market symbol
|
224
|
+
:param dict [params]: Parameters specified by the exchange api
|
225
|
+
:param bool [params.stop]: True if the order to be cancelled is a trigger order
|
226
|
+
:returns: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
227
|
+
"""
|
228
|
+
await self.load_markets()
|
229
|
+
market = None if (symbol is None) else self.market(symbol)
|
230
|
+
stop = self.safe_value_2(params, 'is_stop_order', 'stop', False)
|
231
|
+
params = self.omit(params, ['is_stop_order', 'stop'])
|
232
|
+
type, query = self.handle_market_type_and_params('cancelOrder', market, params)
|
233
|
+
request, requestParams = self.spotOrderPrepareRequest(market, stop, query) if (type == 'spot' or type == 'margin') else self.prepareRequest(market, type, query)
|
234
|
+
messageType = self.get_type_by_market(market)
|
235
|
+
channel = messageType + '.order_cancel'
|
236
|
+
url = self.get_url_by_market(market)
|
237
|
+
await self.authenticate(url, messageType)
|
238
|
+
request['order_id'] = str(id)
|
239
|
+
res = await self.request_private(url, self.extend(request, requestParams), channel)
|
240
|
+
return self.parse_order(res, market)
|
241
|
+
|
242
|
+
async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
|
243
|
+
"""
|
244
|
+
edit a trade order, gate currently only supports the modification of the price or amount fields
|
245
|
+
:see: https://www.gate.io/docs/developers/apiv4/ws/en/#order-amend
|
246
|
+
:see: https://www.gate.io/docs/developers/futures/ws/en/#order-amend
|
247
|
+
:param str id: order id
|
248
|
+
:param str symbol: unified symbol of the market to create an order in
|
249
|
+
:param str type: 'market' or 'limit'
|
250
|
+
:param str side: 'buy' or 'sell'
|
251
|
+
:param float amount: how much of the currency you want to trade in units of the base currency
|
252
|
+
:param float [price]: the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
|
253
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
254
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
255
|
+
"""
|
256
|
+
await self.load_markets()
|
257
|
+
market = self.market(symbol)
|
258
|
+
extendedRequest = self.edit_order_request(id, symbol, type, side, amount, price, params)
|
259
|
+
messageType = self.get_type_by_market(market)
|
260
|
+
channel = messageType + '.order_amend'
|
261
|
+
url = self.get_url_by_market(market)
|
262
|
+
await self.authenticate(url, messageType)
|
263
|
+
rawOrder = await self.request_private(url, extendedRequest, channel)
|
264
|
+
return self.parse_order(rawOrder, market)
|
265
|
+
|
266
|
+
async def fetch_order_ws(self, id: str, symbol: Str = None, params={}):
|
267
|
+
"""
|
268
|
+
Retrieves information on an order
|
269
|
+
:see: https://www.gate.io/docs/developers/apiv4/ws/en/#order-status
|
270
|
+
:see: https://www.gate.io/docs/developers/futures/ws/en/#order-status
|
271
|
+
:param str id: Order id
|
272
|
+
:param str symbol: Unified market symbol, *required for spot and margin*
|
273
|
+
:param dict [params]: Parameters specified by the exchange api
|
274
|
+
:param bool [params.stop]: True if the order being fetched is a trigger order
|
275
|
+
:param str [params.marginMode]: 'cross' or 'isolated' - marginMode for margin trading if not provided self.options['defaultMarginMode'] is used
|
276
|
+
:param str [params.type]: 'spot', 'swap', or 'future', if not provided self.options['defaultMarginMode'] is used
|
277
|
+
:param str [params.settle]: 'btc' or 'usdt' - settle currency for perpetual swap and future - market settle currency is used if symbol is not None, default="usdt" for swap and "btc" for future
|
278
|
+
:returns: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
279
|
+
"""
|
280
|
+
await self.load_markets()
|
281
|
+
market = None if (symbol is None) else self.market(symbol)
|
282
|
+
request, requestParams = self.fetchOrderRequest(id, symbol, params)
|
283
|
+
messageType = self.get_type_by_market(market)
|
284
|
+
channel = messageType + '.order_status'
|
285
|
+
url = self.get_url_by_market(market)
|
286
|
+
await self.authenticate(url, messageType)
|
287
|
+
rawOrder = await self.request_private(url, self.extend(request, requestParams), channel)
|
288
|
+
return self.parse_order(rawOrder, market)
|
289
|
+
|
290
|
+
async def fetch_open_orders_ws(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
291
|
+
"""
|
292
|
+
fetch all unfilled currently open orders
|
293
|
+
:see: https://www.gate.io/docs/developers/futures/ws/en/#order-list
|
294
|
+
:param str symbol: unified market symbol
|
295
|
+
:param int [since]: the earliest time in ms to fetch open orders for
|
296
|
+
:param int [limit]: the maximum number of open orders structures to retrieve
|
297
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
298
|
+
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
299
|
+
"""
|
300
|
+
return await self.fetch_orders_by_status_ws('open', symbol, since, limit, params)
|
301
|
+
|
302
|
+
async def fetch_closed_orders_ws(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
303
|
+
"""
|
304
|
+
fetches information on multiple closed orders made by the user
|
305
|
+
:see: https://www.gate.io/docs/developers/futures/ws/en/#order-list
|
306
|
+
:param str symbol: unified market symbol of the market orders were made in
|
307
|
+
:param int [since]: the earliest time in ms to fetch orders for
|
308
|
+
:param int [limit]: the maximum number of order structures to retrieve
|
309
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
310
|
+
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
311
|
+
"""
|
312
|
+
return await self.fetch_orders_by_status_ws('finished', symbol, since, limit, params)
|
313
|
+
|
314
|
+
async def fetch_orders_by_status_ws(self, status: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
315
|
+
"""
|
316
|
+
:see: https://www.gate.io/docs/developers/futures/ws/en/#order-list
|
317
|
+
fetches information on multiple orders made by the user by status
|
318
|
+
:param str symbol: unified market symbol of the market orders were made in
|
319
|
+
:param int|None [since]: the earliest time in ms to fetch orders for
|
320
|
+
:param int|None [limit]: the maximum number of order structures to retrieve
|
321
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
322
|
+
:param int [params.orderId]: order id to begin at
|
323
|
+
:param int [params.limit]: the maximum number of order structures to retrieve
|
324
|
+
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
325
|
+
"""
|
326
|
+
await self.load_markets()
|
327
|
+
market = None
|
328
|
+
if symbol is not None:
|
329
|
+
market = self.market(symbol)
|
330
|
+
symbol = market['symbol']
|
331
|
+
if market['swap'] is not True:
|
332
|
+
raise NotSupported(self.id + ' fetchOrdersByStatusWs is only supported by swap markets. Use rest API for other markets')
|
333
|
+
request, requestParams = self.fetchOrdersByStatusRequest(status, symbol, since, limit, params)
|
334
|
+
newRequest = self.omit(request, ['settle'])
|
335
|
+
messageType = self.get_type_by_market(market)
|
336
|
+
channel = messageType + '.order_list'
|
337
|
+
url = self.get_url_by_market(market)
|
338
|
+
await self.authenticate(url, messageType)
|
339
|
+
rawOrders = await self.request_private(url, self.extend(newRequest, requestParams), channel)
|
340
|
+
orders = self.parse_orders(rawOrders, market)
|
341
|
+
return self.filter_by_symbol_since_limit(orders, symbol, since, limit)
|
342
|
+
|
107
343
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
108
344
|
"""
|
109
345
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
@@ -1135,37 +1371,55 @@ class gate(ccxt.async_support.gate):
|
|
1135
1371
|
})
|
1136
1372
|
|
1137
1373
|
def handle_error_message(self, client: Client, message):
|
1138
|
-
#
|
1139
|
-
#
|
1140
|
-
#
|
1141
|
-
#
|
1142
|
-
#
|
1143
|
-
# }
|
1144
|
-
#
|
1145
|
-
#
|
1146
|
-
#
|
1147
|
-
#
|
1148
|
-
#
|
1149
|
-
#
|
1150
|
-
#
|
1151
|
-
#
|
1152
|
-
#
|
1153
|
-
#
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1374
|
+
#
|
1375
|
+
# {
|
1376
|
+
# "time": 1647274664,
|
1377
|
+
# "channel": "futures.orders",
|
1378
|
+
# "event": "subscribe",
|
1379
|
+
# "error": {code: 2, message: "unknown contract BTC_USDT_20220318"},
|
1380
|
+
# }
|
1381
|
+
# {
|
1382
|
+
# "time": 1647276473,
|
1383
|
+
# "channel": "futures.orders",
|
1384
|
+
# "event": "subscribe",
|
1385
|
+
# "error": {
|
1386
|
+
# "code": 4,
|
1387
|
+
# "message": "{"label":"INVALID_KEY","message":"Invalid key provided"}\n"
|
1388
|
+
# },
|
1389
|
+
# "result": null
|
1390
|
+
# }
|
1391
|
+
# {
|
1392
|
+
# header: {
|
1393
|
+
# response_time: '1718551891329',
|
1394
|
+
# status: '400',
|
1395
|
+
# channel: 'spot.order_place',
|
1396
|
+
# event: 'api',
|
1397
|
+
# client_id: '81.34.68.6-0xc16375e2c0',
|
1398
|
+
# conn_id: '9539116e0e09678f'
|
1399
|
+
# },
|
1400
|
+
# data: {errs: {label: 'AUTHENTICATION_FAILED', message: 'Not login'}},
|
1401
|
+
# request_id: '10406147'
|
1402
|
+
# }
|
1403
|
+
#
|
1404
|
+
data = self.safe_dict(message, 'data')
|
1405
|
+
errs = self.safe_dict(data, 'errs')
|
1406
|
+
error = self.safe_dict(message, 'error', errs)
|
1407
|
+
code = self.safe_string_2(error, 'code', 'label')
|
1408
|
+
id = self.safe_string_2(message, 'id', 'requestId')
|
1409
|
+
if error is not None:
|
1160
1410
|
messageHash = self.safe_string(client.subscriptions, id)
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1411
|
+
try:
|
1412
|
+
self.throw_exactly_matched_exception(self.exceptions['ws']['exact'], code, self.json(message))
|
1413
|
+
self.throw_exactly_matched_exception(self.exceptions['exact'], code, self.json(errs))
|
1414
|
+
errorMessage = self.safe_string(error, 'message', self.safe_string(errs, 'message'))
|
1415
|
+
self.throw_broadly_matched_exception(self.exceptions['ws']['broad'], errorMessage, self.json(message))
|
1416
|
+
raise ExchangeError(self.json(message))
|
1417
|
+
except Exception as e:
|
1418
|
+
client.reject(e, messageHash)
|
1419
|
+
if (messageHash is not None) and (messageHash in client.subscriptions):
|
1420
|
+
del client.subscriptions[messageHash]
|
1421
|
+
if id is not None:
|
1422
|
+
del client.subscriptions[id]
|
1169
1423
|
return True
|
1170
1424
|
return False
|
1171
1425
|
|
@@ -1302,6 +1556,17 @@ class gate(ccxt.async_support.gate):
|
|
1302
1556
|
method = self.safe_value(v4Methods, channelType)
|
1303
1557
|
if method is not None:
|
1304
1558
|
method(client, message)
|
1559
|
+
requestId = self.safe_string(message, 'request_id')
|
1560
|
+
if requestId == 'authenticated':
|
1561
|
+
self.handle_authentication_message(client, message)
|
1562
|
+
return
|
1563
|
+
if requestId is not None:
|
1564
|
+
data = self.safe_dict(message, 'data')
|
1565
|
+
# use safeValue may be Array or an Object
|
1566
|
+
result = self.safe_value(data, 'result')
|
1567
|
+
ack = self.safe_bool(message, 'ack')
|
1568
|
+
if ack is not True:
|
1569
|
+
client.resolve(result, requestId)
|
1305
1570
|
|
1306
1571
|
def get_url_by_market(self, market):
|
1307
1572
|
baseUrl = self.urls['api'][market['type']]
|
@@ -1310,7 +1575,7 @@ class gate(ccxt.async_support.gate):
|
|
1310
1575
|
else:
|
1311
1576
|
return baseUrl
|
1312
1577
|
|
1313
|
-
def get_type_by_market(self, market):
|
1578
|
+
def get_type_by_market(self, market: Market):
|
1314
1579
|
if market['spot']:
|
1315
1580
|
return 'spot'
|
1316
1581
|
elif market['option']:
|
@@ -1318,7 +1583,7 @@ class gate(ccxt.async_support.gate):
|
|
1318
1583
|
else:
|
1319
1584
|
return 'futures'
|
1320
1585
|
|
1321
|
-
def get_url_by_market_type(self, type, isInverse=False):
|
1586
|
+
def get_url_by_market_type(self, type: MarketType, isInverse=False):
|
1322
1587
|
api = self.urls['api']
|
1323
1588
|
url = api[type]
|
1324
1589
|
if (type == 'swap') or (type == 'future'):
|
@@ -1377,6 +1642,49 @@ class gate(ccxt.async_support.gate):
|
|
1377
1642
|
message = self.extend(request, params)
|
1378
1643
|
return await self.watch_multiple(url, messageHashes, message, messageHashes)
|
1379
1644
|
|
1645
|
+
async def authenticate(self, url, messageType):
|
1646
|
+
channel = messageType + '.login'
|
1647
|
+
client = self.client(url)
|
1648
|
+
messageHash = 'authenticated'
|
1649
|
+
future = client.future(messageHash)
|
1650
|
+
authenticated = self.safe_value(client.subscriptions, messageHash)
|
1651
|
+
if authenticated is None:
|
1652
|
+
return await self.request_private(url, {}, channel, messageHash)
|
1653
|
+
return future
|
1654
|
+
|
1655
|
+
def handle_authentication_message(self, client: Client, message):
|
1656
|
+
messageHash = 'authenticated'
|
1657
|
+
future = self.safe_value(client.futures, messageHash)
|
1658
|
+
future.resolve(True)
|
1659
|
+
|
1660
|
+
async def request_private(self, url, reqParams, channel, requestId: Str = None):
|
1661
|
+
self.check_required_credentials()
|
1662
|
+
# uid is required for some subscriptions only so it's not a part of required credentials
|
1663
|
+
event = 'api'
|
1664
|
+
if requestId is None:
|
1665
|
+
reqId = self.request_id()
|
1666
|
+
requestId = str(reqId)
|
1667
|
+
messageHash = requestId
|
1668
|
+
time = self.seconds()
|
1669
|
+
# unfortunately, PHP demands double quotes for the escaped newline symbol
|
1670
|
+
signatureString = "\n".join([event, channel, self.json(reqParams), str(time)]) # eslint-disable-line quotes
|
1671
|
+
signature = self.hmac(self.encode(signatureString), self.encode(self.secret), hashlib.sha512, 'hex')
|
1672
|
+
payload: dict = {
|
1673
|
+
'req_id': requestId,
|
1674
|
+
'timestamp': str(time),
|
1675
|
+
'api_key': self.apiKey,
|
1676
|
+
'signature': signature,
|
1677
|
+
'req_param': reqParams,
|
1678
|
+
}
|
1679
|
+
request: dict = {
|
1680
|
+
'id': requestId,
|
1681
|
+
'time': time,
|
1682
|
+
'channel': channel,
|
1683
|
+
'event': event,
|
1684
|
+
'payload': payload,
|
1685
|
+
}
|
1686
|
+
return await self.watch(url, messageHash, request, messageHash)
|
1687
|
+
|
1380
1688
|
async def subscribe_private(self, url, messageHash, payload, channel, params, requiresUid=False):
|
1381
1689
|
self.check_required_credentials()
|
1382
1690
|
# uid is required for some subscriptions only so it's not a part of required credentials
|
@@ -1402,7 +1710,7 @@ class gate(ccxt.async_support.gate):
|
|
1402
1710
|
'id': requestId,
|
1403
1711
|
'time': time,
|
1404
1712
|
'channel': channel,
|
1405
|
-
'event':
|
1713
|
+
'event': event,
|
1406
1714
|
'auth': auth,
|
1407
1715
|
}
|
1408
1716
|
if payload is not None:
|
@@ -66,4 +66,4 @@ def test_order_book(exchange, skipped_properties, method, orderbook, symbol):
|
|
66
66
|
first_bid = exchange.safe_string(bids[0], 0)
|
67
67
|
first_ask = exchange.safe_string(asks[0], 0)
|
68
68
|
# check bid-ask spread
|
69
|
-
assert Precise.string_lt(first_bid, first_ask), 'bids[0][0] (' +
|
69
|
+
assert Precise.string_lt(first_bid, first_ask), 'bids[0][0] (' + first_bid + ') should be < than asks[0][0] (' + first_ask + ')' + log_text
|
ccxt/woo.py
CHANGED
@@ -2361,6 +2361,10 @@ class woo(Exchange, ImplicitAPI):
|
|
2361
2361
|
url += access + '/' + pathWithParams
|
2362
2362
|
if params:
|
2363
2363
|
url += '?' + self.urlencode(params)
|
2364
|
+
elif access == 'pub':
|
2365
|
+
url += pathWithParams
|
2366
|
+
if params:
|
2367
|
+
url += '?' + self.urlencode(params)
|
2364
2368
|
else:
|
2365
2369
|
self.check_required_credentials()
|
2366
2370
|
if method == 'POST' and (path == 'algo/order' or path == 'order'):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ccxt
|
3
|
-
Version: 4.3.
|
3
|
+
Version: 4.3.48
|
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
|
@@ -268,13 +268,13 @@ console.log(version, Object.keys(exchanges));
|
|
268
268
|
|
269
269
|
All-in-one browser bundle (dependencies included), served from a CDN of your choice:
|
270
270
|
|
271
|
-
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.
|
272
|
-
* unpkg: https://unpkg.com/ccxt@4.3.
|
271
|
+
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.48/dist/ccxt.browser.min.js
|
272
|
+
* unpkg: https://unpkg.com/ccxt@4.3.48/dist/ccxt.browser.min.js
|
273
273
|
|
274
274
|
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.
|
275
275
|
|
276
276
|
```HTML
|
277
|
-
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.
|
277
|
+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.48/dist/ccxt.browser.min.js"></script>
|
278
278
|
```
|
279
279
|
|
280
280
|
Creates a global `ccxt` object:
|