ccxt 4.3.33__py2.py3-none-any.whl → 4.3.35__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 +1 -0
- ccxt/abstract/binancecoinm.py +1 -0
- ccxt/abstract/binanceus.py +1 -0
- ccxt/abstract/binanceusdm.py +1 -0
- ccxt/ace.py +2 -2
- ccxt/alpaca.py +2 -2
- ccxt/ascendex.py +2 -2
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ace.py +2 -2
- ccxt/async_support/alpaca.py +2 -2
- ccxt/async_support/ascendex.py +2 -2
- ccxt/async_support/base/exchange.py +56 -40
- ccxt/async_support/bigone.py +2 -2
- ccxt/async_support/binance.py +6 -5
- ccxt/async_support/bingx.py +4 -3
- ccxt/async_support/bit2c.py +1 -1
- ccxt/async_support/bitbank.py +1 -1
- ccxt/async_support/bitbns.py +1 -1
- ccxt/async_support/bitfinex.py +2 -2
- ccxt/async_support/bitfinex2.py +1 -1
- ccxt/async_support/bitflyer.py +1 -1
- ccxt/async_support/bitget.py +4 -4
- ccxt/async_support/bithumb.py +1 -1
- ccxt/async_support/bitmart.py +4 -9
- ccxt/async_support/bitmex.py +3 -3
- ccxt/async_support/bitopro.py +3 -3
- ccxt/async_support/bitrue.py +2 -2
- ccxt/async_support/bitso.py +2 -2
- ccxt/async_support/bitstamp.py +2 -2
- ccxt/async_support/bitteam.py +3 -3
- ccxt/async_support/bitvavo.py +2 -2
- ccxt/async_support/blockchaincom.py +1 -1
- ccxt/async_support/blofin.py +3 -3
- ccxt/async_support/btcalpha.py +3 -3
- ccxt/async_support/btcbox.py +1 -1
- ccxt/async_support/btcmarkets.py +6 -4
- ccxt/async_support/btcturk.py +1 -1
- ccxt/async_support/bybit.py +3 -3
- ccxt/async_support/cex.py +1 -1
- ccxt/async_support/coinbase.py +156 -58
- ccxt/async_support/coinbaseexchange.py +1 -1
- ccxt/async_support/coinbaseinternational.py +3 -3
- ccxt/async_support/coincheck.py +2 -2
- ccxt/async_support/coinex.py +28 -21
- ccxt/async_support/coinlist.py +2 -2
- ccxt/async_support/coinmate.py +2 -2
- ccxt/async_support/coinmetro.py +2 -2
- ccxt/async_support/coinone.py +1 -1
- ccxt/async_support/coinsph.py +2 -2
- ccxt/async_support/cryptocom.py +1 -1
- ccxt/async_support/currencycom.py +2 -2
- ccxt/async_support/delta.py +1 -1
- ccxt/async_support/deribit.py +2 -2
- ccxt/async_support/digifinex.py +2 -2
- ccxt/async_support/exmo.py +2 -2
- ccxt/async_support/gate.py +2 -2
- ccxt/async_support/gemini.py +3 -3
- ccxt/async_support/hitbtc.py +2 -2
- ccxt/async_support/hollaex.py +1 -1
- ccxt/async_support/htx.py +2 -2
- ccxt/async_support/huobijp.py +2 -2
- ccxt/async_support/hyperliquid.py +2 -2
- ccxt/async_support/idex.py +2 -2
- ccxt/async_support/indodax.py +2 -2
- ccxt/async_support/kraken.py +5 -3
- ccxt/async_support/krakenfutures.py +1 -1
- ccxt/async_support/kucoin.py +2 -2
- ccxt/async_support/kuna.py +2 -2
- ccxt/async_support/latoken.py +2 -2
- ccxt/async_support/lbank.py +1 -1
- ccxt/async_support/luno.py +1 -1
- ccxt/async_support/lykke.py +1 -1
- ccxt/async_support/mercado.py +1 -1
- ccxt/async_support/mexc.py +1 -1
- ccxt/async_support/ndax.py +2 -2
- ccxt/async_support/novadax.py +3 -3
- ccxt/async_support/oceanex.py +2 -2
- ccxt/async_support/okcoin.py +3 -3
- ccxt/async_support/okx.py +3 -3
- ccxt/async_support/onetrading.py +2 -2
- ccxt/async_support/p2b.py +2 -2
- ccxt/async_support/paymium.py +1 -1
- ccxt/async_support/phemex.py +4 -4
- ccxt/async_support/poloniex.py +3 -3
- ccxt/async_support/poloniexfutures.py +2 -2
- ccxt/async_support/probit.py +3 -3
- ccxt/async_support/timex.py +2 -2
- ccxt/async_support/tokocrypto.py +1 -1
- ccxt/async_support/tradeogre.py +1 -1
- ccxt/async_support/upbit.py +3 -3
- ccxt/async_support/wavesexchange.py +1 -1
- ccxt/async_support/wazirx.py +3 -3
- ccxt/async_support/whitebit.py +3 -3
- ccxt/async_support/woo.py +3 -3
- ccxt/async_support/woofipro.py +3 -3
- ccxt/async_support/yobit.py +1 -1
- ccxt/async_support/zaif.py +2 -2
- ccxt/async_support/zonda.py +1 -1
- ccxt/base/exchange.py +107 -76
- ccxt/base/types.py +0 -1
- ccxt/bigone.py +2 -2
- ccxt/binance.py +6 -5
- ccxt/bingx.py +4 -3
- ccxt/bit2c.py +1 -1
- ccxt/bitbank.py +1 -1
- ccxt/bitbns.py +1 -1
- ccxt/bitfinex.py +2 -2
- ccxt/bitfinex2.py +1 -1
- ccxt/bitflyer.py +1 -1
- ccxt/bitget.py +4 -4
- ccxt/bithumb.py +1 -1
- ccxt/bitmart.py +4 -9
- ccxt/bitmex.py +3 -3
- ccxt/bitopro.py +3 -3
- ccxt/bitrue.py +2 -2
- ccxt/bitso.py +2 -2
- ccxt/bitstamp.py +2 -2
- ccxt/bitteam.py +3 -3
- ccxt/bitvavo.py +2 -2
- ccxt/blockchaincom.py +1 -1
- ccxt/blofin.py +3 -3
- ccxt/btcalpha.py +3 -3
- ccxt/btcbox.py +1 -1
- ccxt/btcmarkets.py +6 -4
- ccxt/btcturk.py +1 -1
- ccxt/bybit.py +3 -3
- ccxt/cex.py +1 -1
- ccxt/coinbase.py +156 -58
- ccxt/coinbaseexchange.py +1 -1
- ccxt/coinbaseinternational.py +3 -3
- ccxt/coincheck.py +2 -2
- ccxt/coinex.py +28 -21
- ccxt/coinlist.py +2 -2
- ccxt/coinmate.py +2 -2
- ccxt/coinmetro.py +2 -2
- ccxt/coinone.py +1 -1
- ccxt/coinsph.py +2 -2
- ccxt/cryptocom.py +1 -1
- ccxt/currencycom.py +2 -2
- ccxt/delta.py +1 -1
- ccxt/deribit.py +2 -2
- ccxt/digifinex.py +2 -2
- ccxt/exmo.py +2 -2
- ccxt/gate.py +2 -2
- ccxt/gemini.py +3 -3
- ccxt/hitbtc.py +2 -2
- ccxt/hollaex.py +1 -1
- ccxt/htx.py +2 -2
- ccxt/huobijp.py +2 -2
- ccxt/hyperliquid.py +2 -2
- ccxt/idex.py +2 -2
- ccxt/indodax.py +2 -2
- ccxt/kraken.py +5 -3
- ccxt/krakenfutures.py +1 -1
- ccxt/kucoin.py +2 -2
- ccxt/kuna.py +2 -2
- ccxt/latoken.py +2 -2
- ccxt/lbank.py +1 -1
- ccxt/luno.py +1 -1
- ccxt/lykke.py +1 -1
- ccxt/mercado.py +1 -1
- ccxt/mexc.py +1 -1
- ccxt/ndax.py +2 -2
- ccxt/novadax.py +3 -3
- ccxt/oceanex.py +2 -2
- ccxt/okcoin.py +3 -3
- ccxt/okx.py +3 -3
- ccxt/onetrading.py +2 -2
- ccxt/p2b.py +2 -2
- ccxt/paymium.py +1 -1
- ccxt/phemex.py +4 -4
- ccxt/poloniex.py +3 -3
- ccxt/poloniexfutures.py +2 -2
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +331 -2
- ccxt/pro/bitget.py +24 -1
- ccxt/pro/bitmart.py +1 -1
- ccxt/pro/bitmex.py +98 -1
- ccxt/pro/bybit.py +82 -1
- ccxt/pro/gate.py +173 -1
- ccxt/pro/kraken.py +1 -1
- ccxt/pro/kucoinfutures.py +4 -0
- ccxt/pro/okx.py +244 -1
- ccxt/probit.py +3 -3
- ccxt/test/base/__init__.py +1 -0
- ccxt/test/base/test_crypto.py +1 -1
- ccxt/test/base/test_liquidation.py +50 -0
- ccxt/timex.py +2 -2
- ccxt/tokocrypto.py +1 -1
- ccxt/tradeogre.py +1 -1
- ccxt/upbit.py +3 -3
- ccxt/wavesexchange.py +1 -1
- ccxt/wazirx.py +3 -3
- ccxt/whitebit.py +3 -3
- ccxt/woo.py +3 -3
- ccxt/woofipro.py +3 -3
- ccxt/yobit.py +1 -1
- ccxt/zaif.py +2 -2
- ccxt/zonda.py +1 -1
- {ccxt-4.3.33.dist-info → ccxt-4.3.35.dist-info}/METADATA +4 -4
- {ccxt-4.3.33.dist-info → ccxt-4.3.35.dist-info}/RECORD +204 -203
- {ccxt-4.3.33.dist-info → ccxt-4.3.35.dist-info}/WHEEL +0 -0
- {ccxt-4.3.33.dist-info → ccxt-4.3.35.dist-info}/top_level.txt +0 -0
ccxt/pro/binance.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
import ccxt.async_support
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Int, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade
|
9
|
+
from ccxt.base.types import Balances, Int, Liquidation, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade
|
10
10
|
from ccxt.async_support.base.ws.client import Client
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import ArgumentsRequired
|
@@ -23,6 +23,10 @@ class binance(ccxt.async_support.binance):
|
|
23
23
|
'has': {
|
24
24
|
'ws': True,
|
25
25
|
'watchBalance': True,
|
26
|
+
'watchLiquidations': True,
|
27
|
+
'watchLiquidationsForSymbols': True,
|
28
|
+
'watchMyLiquidations': True,
|
29
|
+
'watchMyLiquidationsForSymbols': True,
|
26
30
|
'watchBidsAsks': True,
|
27
31
|
'watchMyTrades': True,
|
28
32
|
'watchOHLCV': True,
|
@@ -107,6 +111,8 @@ class binance(ccxt.async_support.binance):
|
|
107
111
|
# get updates every 1000ms or 100ms
|
108
112
|
# or every 0ms in real-time for futures
|
109
113
|
'watchOrderBookRate': 100,
|
114
|
+
'liquidationsLimit': 1000,
|
115
|
+
'myLiquidationsLimit': 1000,
|
110
116
|
'tradesLimit': 1000,
|
111
117
|
'ordersLimit': 1000,
|
112
118
|
'OHLCVLimit': 1000,
|
@@ -131,6 +137,9 @@ class binance(ccxt.async_support.binance):
|
|
131
137
|
'fetchBalanceSnapshot': False, # or True
|
132
138
|
'awaitBalanceSnapshot': True, # whether to wait for the balance snapshot before providing updates
|
133
139
|
},
|
140
|
+
'watchLiquidationsForSymbols': {
|
141
|
+
'defaultType': 'swap',
|
142
|
+
},
|
134
143
|
'watchPositions': {
|
135
144
|
'fetchPositionsSnapshot': True, # or False
|
136
145
|
'awaitPositionsSnapshot': True, # whether to wait for the positions snapshot before providing updates
|
@@ -159,7 +168,7 @@ class binance(ccxt.async_support.binance):
|
|
159
168
|
self.options['requestId'][url] = newValue
|
160
169
|
return newValue
|
161
170
|
|
162
|
-
def stream(self, type, subscriptionHash, numSubscriptions=1):
|
171
|
+
def stream(self, type: Str, subscriptionHash: Str, numSubscriptions=1):
|
163
172
|
streamBySubscriptionsHash = self.safe_dict(self.options, 'streamBySubscriptionsHash', self.create_safe_dictionary())
|
164
173
|
stream = self.safe_string(streamBySubscriptionsHash, subscriptionHash)
|
165
174
|
if stream is None:
|
@@ -182,6 +191,324 @@ class binance(ccxt.async_support.binance):
|
|
182
191
|
self.options['numSubscriptionsByStream'][stream] = subscriptionsByStream + numSubscriptions
|
183
192
|
return stream
|
184
193
|
|
194
|
+
async def watch_liquidations(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
195
|
+
"""
|
196
|
+
watch the public liquidations of a trading pair
|
197
|
+
:see: https://binance-docs.github.io/apidocs/futures/en/#liquidation-order-streams
|
198
|
+
:see: https://binance-docs.github.io/apidocs/delivery/en/#liquidation-order-streams
|
199
|
+
:param str symbol: unified CCXT market symbol
|
200
|
+
:param int [since]: the earliest time in ms to fetch liquidations for
|
201
|
+
:param int [limit]: the maximum number of liquidation structures to retrieve
|
202
|
+
:param dict [params]: exchange specific parameters for the bitmex api endpoint
|
203
|
+
:returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
|
204
|
+
"""
|
205
|
+
return self.watch_liquidations_for_symbols([symbol], since, limit, params)
|
206
|
+
|
207
|
+
async def watch_liquidations_for_symbols(self, symbols: List[str] = None, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
208
|
+
"""
|
209
|
+
watch the public liquidations of a trading pair
|
210
|
+
:see: https://binance-docs.github.io/apidocs/futures/en/#all-market-liquidation-order-streams
|
211
|
+
:see: https://binance-docs.github.io/apidocs/delivery/en/#all-market-liquidation-order-streams
|
212
|
+
:param str symbol: unified CCXT market symbol
|
213
|
+
:param int [since]: the earliest time in ms to fetch liquidations for
|
214
|
+
:param int [limit]: the maximum number of liquidation structures to retrieve
|
215
|
+
:param dict [params]: exchange specific parameters for the bitmex api endpoint
|
216
|
+
:returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
|
217
|
+
"""
|
218
|
+
await self.load_markets()
|
219
|
+
subscriptionHashes = []
|
220
|
+
messageHashes = []
|
221
|
+
streamHash = 'liquidations'
|
222
|
+
symbols = self.market_symbols(symbols, None, True, True)
|
223
|
+
if self.is_empty(symbols):
|
224
|
+
subscriptionHashes.append('!' + 'forceOrder@arr')
|
225
|
+
messageHashes.append('liquidations')
|
226
|
+
else:
|
227
|
+
for i in range(0, len(symbols)):
|
228
|
+
market = self.market(symbols[i])
|
229
|
+
subscriptionHashes.append(market['id'] + '@forceOrder')
|
230
|
+
messageHashes.append('liquidations::' + symbols[i])
|
231
|
+
streamHash += '::' + ','.join(symbols)
|
232
|
+
firstMarket = self.get_market_from_symbols(symbols)
|
233
|
+
type = None
|
234
|
+
type, params = self.handle_market_type_and_params('watchLiquidationsForSymbols', firstMarket, params)
|
235
|
+
if type == 'spot':
|
236
|
+
raise BadRequest(self.id + 'watchLiquidationsForSymbols is not supported for swap symbols')
|
237
|
+
subType = None
|
238
|
+
subType, params = self.handle_sub_type_and_params('watchLiquidationsForSymbols', firstMarket, params)
|
239
|
+
if self.isLinear(type, subType):
|
240
|
+
type = 'future'
|
241
|
+
elif self.isInverse(type, subType):
|
242
|
+
type = 'delivery'
|
243
|
+
numSubscriptions = len(subscriptionHashes)
|
244
|
+
url = self.urls['api']['ws'][type] + '/' + self.stream(type, streamHash, numSubscriptions)
|
245
|
+
requestId = self.request_id(url)
|
246
|
+
request = {
|
247
|
+
'method': 'SUBSCRIBE',
|
248
|
+
'params': subscriptionHashes,
|
249
|
+
'id': requestId,
|
250
|
+
}
|
251
|
+
subscribe = {
|
252
|
+
'id': requestId,
|
253
|
+
}
|
254
|
+
newLiquidations = await self.watch_multiple(url, messageHashes, self.extend(request, params), subscriptionHashes, subscribe)
|
255
|
+
if self.newUpdates:
|
256
|
+
return newLiquidations
|
257
|
+
return self.filter_by_symbols_since_limit(self.liquidations, symbols, since, limit, True)
|
258
|
+
|
259
|
+
def handle_liquidation(self, client: Client, message):
|
260
|
+
#
|
261
|
+
# future
|
262
|
+
# {
|
263
|
+
# "e":"forceOrder",
|
264
|
+
# "E":1698871323061,
|
265
|
+
# "o":{
|
266
|
+
# "s":"BTCUSDT",
|
267
|
+
# "S":"BUY",
|
268
|
+
# "o":"LIMIT",
|
269
|
+
# "f":"IOC",
|
270
|
+
# "q":"1.437",
|
271
|
+
# "p":"35100.81",
|
272
|
+
# "ap":"34959.70",
|
273
|
+
# "X":"FILLED",
|
274
|
+
# "l":"1.437",
|
275
|
+
# "z":"1.437",
|
276
|
+
# "T":1698871323059
|
277
|
+
# }
|
278
|
+
# }
|
279
|
+
# delivery
|
280
|
+
# {
|
281
|
+
# "e":"forceOrder", # Event Type
|
282
|
+
# "E": 1591154240950, # Event Time
|
283
|
+
# "o":{
|
284
|
+
# "s":"BTCUSD_200925", # Symbol
|
285
|
+
# "ps": "BTCUSD", # Pair
|
286
|
+
# "S":"SELL", # Side
|
287
|
+
# "o":"LIMIT", # Order Type
|
288
|
+
# "f":"IOC", # Time in Force
|
289
|
+
# "q":"1", # Original Quantity
|
290
|
+
# "p":"9425.5", # Price
|
291
|
+
# "ap":"9496.5", # Average Price
|
292
|
+
# "X":"FILLED", # Order Status
|
293
|
+
# "l":"1", # Order Last Filled Quantity
|
294
|
+
# "z":"1", # Order Filled Accumulated Quantity
|
295
|
+
# "T": 1591154240949, # Order Trade Time
|
296
|
+
# }
|
297
|
+
# }
|
298
|
+
#
|
299
|
+
rawLiquidation = self.safe_value(message, 'o', {})
|
300
|
+
marketId = self.safe_string(rawLiquidation, 's')
|
301
|
+
market = self.safe_market(marketId, None, '', 'contract')
|
302
|
+
symbol = market['symbol']
|
303
|
+
liquidation = self.parse_ws_liquidation(rawLiquidation, market)
|
304
|
+
liquidations = self.safe_value(self.liquidations, symbol)
|
305
|
+
if liquidations is None:
|
306
|
+
limit = self.safe_integer(self.options, 'liquidationsLimit', 1000)
|
307
|
+
liquidations = ArrayCache(limit)
|
308
|
+
liquidations.append(liquidation)
|
309
|
+
self.liquidations[symbol] = liquidations
|
310
|
+
client.resolve([liquidation], 'liquidations')
|
311
|
+
client.resolve([liquidation], 'liquidations::' + symbol)
|
312
|
+
|
313
|
+
def parse_ws_liquidation(self, liquidation, market=None):
|
314
|
+
#
|
315
|
+
# future
|
316
|
+
# {
|
317
|
+
# "s":"BTCUSDT",
|
318
|
+
# "S":"BUY",
|
319
|
+
# "o":"LIMIT",
|
320
|
+
# "f":"IOC",
|
321
|
+
# "q":"1.437",
|
322
|
+
# "p":"35100.81",
|
323
|
+
# "ap":"34959.70",
|
324
|
+
# "X":"FILLED",
|
325
|
+
# "l":"1.437",
|
326
|
+
# "z":"1.437",
|
327
|
+
# "T":1698871323059
|
328
|
+
# }
|
329
|
+
# delivery
|
330
|
+
# {
|
331
|
+
# "s":"BTCUSD_200925", # Symbol
|
332
|
+
# "ps": "BTCUSD", # Pair
|
333
|
+
# "S":"SELL", # Side
|
334
|
+
# "o":"LIMIT", # Order Type
|
335
|
+
# "f":"IOC", # Time in Force
|
336
|
+
# "q":"1", # Original Quantity
|
337
|
+
# "p":"9425.5", # Price
|
338
|
+
# "ap":"9496.5", # Average Price
|
339
|
+
# "X":"FILLED", # Order Status
|
340
|
+
# "l":"1", # Order Last Filled Quantity
|
341
|
+
# "z":"1", # Order Filled Accumulated Quantity
|
342
|
+
# "T": 1591154240949, # Order Trade Time
|
343
|
+
# }
|
344
|
+
# myLiquidation
|
345
|
+
# {
|
346
|
+
# "s":"BTCUSDT", # Symbol
|
347
|
+
# "c":"TEST", # Client Order Id
|
348
|
+
# # special client order id:
|
349
|
+
# # starts with "autoclose-": liquidation order
|
350
|
+
# # "adl_autoclose": ADL auto close order
|
351
|
+
# # "settlement_autoclose-": settlement order for delisting or delivery
|
352
|
+
# "S":"SELL", # Side
|
353
|
+
# "o":"TRAILING_STOP_MARKET", # Order Type
|
354
|
+
# "f":"GTC", # Time in Force
|
355
|
+
# "q":"0.001", # Original Quantity
|
356
|
+
# "p":"0", # Original Price
|
357
|
+
# "ap":"0", # Average Price
|
358
|
+
# "sp":"7103.04", # Stop Price. Please ignore with TRAILING_STOP_MARKET order
|
359
|
+
# "x":"NEW", # Execution Type
|
360
|
+
# "X":"NEW", # Order Status
|
361
|
+
# "i":8886774, # Order Id
|
362
|
+
# "l":"0", # Order Last Filled Quantity
|
363
|
+
# "z":"0", # Order Filled Accumulated Quantity
|
364
|
+
# "L":"0", # Last Filled Price
|
365
|
+
# "N":"USDT", # Commission Asset, will not push if no commission
|
366
|
+
# "n":"0", # Commission, will not push if no commission
|
367
|
+
# "T":1568879465650, # Order Trade Time
|
368
|
+
# "t":0, # Trade Id
|
369
|
+
# "b":"0", # Bids Notional
|
370
|
+
# "a":"9.91", # Ask Notional
|
371
|
+
# "m":false, # Is self trade the maker side?
|
372
|
+
# "R":false, # Is self reduce only
|
373
|
+
# "wt":"CONTRACT_PRICE", # Stop Price Working Type
|
374
|
+
# "ot":"TRAILING_STOP_MARKET",// Original Order Type
|
375
|
+
# "ps":"LONG", # Position Side
|
376
|
+
# "cp":false, # If Close-All, pushed with conditional order
|
377
|
+
# "AP":"7476.89", # Activation Price, only puhed with TRAILING_STOP_MARKET order
|
378
|
+
# "cr":"5.0", # Callback Rate, only puhed with TRAILING_STOP_MARKET order
|
379
|
+
# "pP": False, # If price protection is turned on
|
380
|
+
# "si": 0, # ignore
|
381
|
+
# "ss": 0, # ignore
|
382
|
+
# "rp":"0", # Realized Profit of the trade
|
383
|
+
# "V":"EXPIRE_TAKER", # STP mode
|
384
|
+
# "pm":"OPPONENT", # Price match mode
|
385
|
+
# "gtd":0 # TIF GTD order auto cancel time
|
386
|
+
# }
|
387
|
+
#
|
388
|
+
marketId = self.safe_string(liquidation, 's')
|
389
|
+
market = self.safe_market(marketId, market)
|
390
|
+
timestamp = self.safe_integer(liquidation, 'T')
|
391
|
+
return self.safe_liquidation({
|
392
|
+
'info': liquidation,
|
393
|
+
'symbol': self.safe_symbol(marketId, market),
|
394
|
+
'contracts': self.safe_number(liquidation, 'l'),
|
395
|
+
'contractSize': self.safe_number(market, 'contractSize'),
|
396
|
+
'price': self.safe_number(liquidation, 'ap'),
|
397
|
+
'baseValue': None,
|
398
|
+
'quoteValue': None,
|
399
|
+
'timestamp': timestamp,
|
400
|
+
'datetime': self.iso8601(timestamp),
|
401
|
+
})
|
402
|
+
|
403
|
+
async def watch_my_liquidations(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
404
|
+
"""
|
405
|
+
watch the private liquidations of a trading pair
|
406
|
+
:see: https://binance-docs.github.io/apidocs/futures/en/#event-order-update
|
407
|
+
:see: https://binance-docs.github.io/apidocs/delivery/en/#event-order-update
|
408
|
+
:param str symbol: unified CCXT market symbol
|
409
|
+
:param int [since]: the earliest time in ms to fetch liquidations for
|
410
|
+
:param int [limit]: the maximum number of liquidation structures to retrieve
|
411
|
+
:param dict [params]: exchange specific parameters for the bitmex api endpoint
|
412
|
+
:returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
|
413
|
+
"""
|
414
|
+
return self.watch_my_liquidations_for_symbols([symbol], since, limit, params)
|
415
|
+
|
416
|
+
async def watch_my_liquidations_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
417
|
+
"""
|
418
|
+
watch the private liquidations of a trading pair
|
419
|
+
:see: https://binance-docs.github.io/apidocs/futures/en/#event-order-update
|
420
|
+
:see: https://binance-docs.github.io/apidocs/delivery/en/#event-order-update
|
421
|
+
:param str symbol: unified CCXT market symbol
|
422
|
+
:param int [since]: the earliest time in ms to fetch liquidations for
|
423
|
+
:param int [limit]: the maximum number of liquidation structures to retrieve
|
424
|
+
:param dict [params]: exchange specific parameters for the bitmex api endpoint
|
425
|
+
:returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
|
426
|
+
"""
|
427
|
+
await self.load_markets()
|
428
|
+
symbols = self.market_symbols(symbols, None, True, True, True)
|
429
|
+
market = self.get_market_from_symbols(symbols)
|
430
|
+
messageHashes = ['myLiquidations']
|
431
|
+
if not self.is_empty(symbols):
|
432
|
+
for i in range(0, len(symbols)):
|
433
|
+
symbol = symbols[i]
|
434
|
+
messageHashes.append('myLiquidations::' + symbol)
|
435
|
+
type = None
|
436
|
+
type, params = self.handle_market_type_and_params('watchMyLiquidationsForSymbols', market, params)
|
437
|
+
subType = None
|
438
|
+
subType, params = self.handle_sub_type_and_params('watchMyLiquidationsForSymbols', market, params)
|
439
|
+
if self.isLinear(type, subType):
|
440
|
+
type = 'future'
|
441
|
+
elif self.isInverse(type, subType):
|
442
|
+
type = 'delivery'
|
443
|
+
await self.authenticate(params)
|
444
|
+
url = self.urls['api']['ws'][type] + '/' + self.options[type]['listenKey']
|
445
|
+
message = None
|
446
|
+
newLiquidations = await self.watch_multiple(url, messageHashes, message, [type])
|
447
|
+
if self.newUpdates:
|
448
|
+
return newLiquidations
|
449
|
+
return self.filter_by_symbols_since_limit(self.liquidations, symbols, since, limit)
|
450
|
+
|
451
|
+
def handle_my_liquidation(self, client: Client, message):
|
452
|
+
#
|
453
|
+
# {
|
454
|
+
# "s":"BTCUSDT", # Symbol
|
455
|
+
# "c":"TEST", # Client Order Id
|
456
|
+
# # special client order id:
|
457
|
+
# # starts with "autoclose-": liquidation order
|
458
|
+
# # "adl_autoclose": ADL auto close order
|
459
|
+
# # "settlement_autoclose-": settlement order for delisting or delivery
|
460
|
+
# "S":"SELL", # Side
|
461
|
+
# "o":"TRAILING_STOP_MARKET", # Order Type
|
462
|
+
# "f":"GTC", # Time in Force
|
463
|
+
# "q":"0.001", # Original Quantity
|
464
|
+
# "p":"0", # Original Price
|
465
|
+
# "ap":"0", # Average Price
|
466
|
+
# "sp":"7103.04", # Stop Price. Please ignore with TRAILING_STOP_MARKET order
|
467
|
+
# "x":"NEW", # Execution Type
|
468
|
+
# "X":"NEW", # Order Status
|
469
|
+
# "i":8886774, # Order Id
|
470
|
+
# "l":"0", # Order Last Filled Quantity
|
471
|
+
# "z":"0", # Order Filled Accumulated Quantity
|
472
|
+
# "L":"0", # Last Filled Price
|
473
|
+
# "N":"USDT", # Commission Asset, will not push if no commission
|
474
|
+
# "n":"0", # Commission, will not push if no commission
|
475
|
+
# "T":1568879465650, # Order Trade Time
|
476
|
+
# "t":0, # Trade Id
|
477
|
+
# "b":"0", # Bids Notional
|
478
|
+
# "a":"9.91", # Ask Notional
|
479
|
+
# "m":false, # Is self trade the maker side?
|
480
|
+
# "R":false, # Is self reduce only
|
481
|
+
# "wt":"CONTRACT_PRICE", # Stop Price Working Type
|
482
|
+
# "ot":"TRAILING_STOP_MARKET",// Original Order Type
|
483
|
+
# "ps":"LONG", # Position Side
|
484
|
+
# "cp":false, # If Close-All, pushed with conditional order
|
485
|
+
# "AP":"7476.89", # Activation Price, only puhed with TRAILING_STOP_MARKET order
|
486
|
+
# "cr":"5.0", # Callback Rate, only puhed with TRAILING_STOP_MARKET order
|
487
|
+
# "pP": False, # If price protection is turned on
|
488
|
+
# "si": 0, # ignore
|
489
|
+
# "ss": 0, # ignore
|
490
|
+
# "rp":"0", # Realized Profit of the trade
|
491
|
+
# "V":"EXPIRE_TAKER", # STP mode
|
492
|
+
# "pm":"OPPONENT", # Price match mode
|
493
|
+
# "gtd":0 # TIF GTD order auto cancel time
|
494
|
+
# }
|
495
|
+
#
|
496
|
+
orderType = self.safe_string(message, 'o')
|
497
|
+
if orderType != 'LIQUIDATION':
|
498
|
+
return
|
499
|
+
marketId = self.safe_string(message, 's')
|
500
|
+
market = self.safe_market(marketId)
|
501
|
+
symbol = self.safe_symbol(marketId)
|
502
|
+
liquidation = self.parse_ws_liquidation(message, market)
|
503
|
+
myLiquidations = self.safe_value(self.myLiquidations, symbol)
|
504
|
+
if myLiquidations is None:
|
505
|
+
limit = self.safe_integer(self.options, 'myLiquidationsLimit', 1000)
|
506
|
+
myLiquidations = ArrayCache(limit)
|
507
|
+
myLiquidations.append(liquidation)
|
508
|
+
self.myLiquidations[symbol] = myLiquidations
|
509
|
+
client.resolve([liquidation], 'myLiquidations')
|
510
|
+
client.resolve([liquidation], 'myLiquidations::' + symbol)
|
511
|
+
|
185
512
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
186
513
|
"""
|
187
514
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
@@ -2590,6 +2917,7 @@ class binance(ccxt.async_support.binance):
|
|
2590
2917
|
message = self.safe_dict(message, 'o', message)
|
2591
2918
|
self.handle_my_trade(client, message)
|
2592
2919
|
self.handle_order(client, message)
|
2920
|
+
self.handle_my_liquidation(client, message)
|
2593
2921
|
|
2594
2922
|
async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
|
2595
2923
|
"""
|
@@ -3131,6 +3459,7 @@ class binance(ccxt.async_support.binance):
|
|
3131
3459
|
'ACCOUNT_UPDATE': self.handle_acount_update,
|
3132
3460
|
'executionReport': self.handle_order_update,
|
3133
3461
|
'ORDER_TRADE_UPDATE': self.handle_order_update,
|
3462
|
+
'forceOrder': self.handle_liquidation,
|
3134
3463
|
}
|
3135
3464
|
event = self.safe_string(message, 'e')
|
3136
3465
|
if isinstance(message, list):
|
ccxt/pro/bitget.py
CHANGED
@@ -917,7 +917,9 @@ class bitget(ccxt.async_support.bitget):
|
|
917
917
|
:param int [limit]: the maximum number of order structures to retrieve
|
918
918
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
919
919
|
:param boolean [params.stop]: *contract only* set to True for watching trigger orders
|
920
|
-
:param str [params.marginMode]: 'isolated' or 'cross' for watching spot margin orders
|
920
|
+
:param str [params.marginMode]: 'isolated' or 'cross' for watching spot margin orders]
|
921
|
+
:param str [params.type]: 'spot', 'swap'
|
922
|
+
:param str [params.subType]: 'linear', 'inverse'
|
921
923
|
:returns dict[]: a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure
|
922
924
|
"""
|
923
925
|
await self.load_markets()
|
@@ -932,10 +934,21 @@ class bitget(ccxt.async_support.bitget):
|
|
932
934
|
symbol = market['symbol']
|
933
935
|
marketId = market['id']
|
934
936
|
messageHash = messageHash + ':' + symbol
|
937
|
+
productType = self.safe_string(params, 'productType')
|
935
938
|
type = None
|
936
939
|
type, params = self.handle_market_type_and_params('watchOrders', market, params)
|
940
|
+
subType = None
|
941
|
+
subType, params = self.handle_sub_type_and_params('watchOrders', market, params, 'linear')
|
937
942
|
if (type == 'spot') and (symbol is None):
|
938
943
|
raise ArgumentsRequired(self.id + ' watchOrders requires a symbol argument for ' + type + ' markets.')
|
944
|
+
if (productType is None) and (type != 'spot') and (symbol is None):
|
945
|
+
messageHash = messageHash + ':' + subType
|
946
|
+
elif productType == 'USDT-FUTURES':
|
947
|
+
messageHash = messageHash + ':linear'
|
948
|
+
elif productType == 'COIN-FUTURES':
|
949
|
+
messageHash = messageHash + ':inverse'
|
950
|
+
elif productType == 'USDC-FUTURES':
|
951
|
+
messageHash = messageHash + ':usdcfutures' # non unified channel
|
939
952
|
instType = None
|
940
953
|
instType, params = self.get_inst_type(market, params)
|
941
954
|
if type == 'spot':
|
@@ -952,6 +965,7 @@ class bitget(ccxt.async_support.bitget):
|
|
952
965
|
channel = 'orders-isolated'
|
953
966
|
else:
|
954
967
|
channel = 'orders-crossed'
|
968
|
+
subscriptionHash = subscriptionHash + ':' + instType
|
955
969
|
args: dict = {
|
956
970
|
'instType': instType,
|
957
971
|
'channel': channel,
|
@@ -1007,6 +1021,9 @@ class bitget(ccxt.async_support.bitget):
|
|
1007
1021
|
marketType = 'spot'
|
1008
1022
|
else:
|
1009
1023
|
marketType = 'contract'
|
1024
|
+
isLinearSwap = (instType == 'USDT-FUTURES')
|
1025
|
+
isInverseSwap = (instType == 'COIN-FUTURES')
|
1026
|
+
isUSDCFutures = (instType == 'USDC-FUTURES')
|
1010
1027
|
data = self.safe_value(message, 'data', [])
|
1011
1028
|
if self.orders is None:
|
1012
1029
|
limit = self.safe_integer(self.options, 'ordersLimit', 1000)
|
@@ -1030,6 +1047,12 @@ class bitget(ccxt.async_support.bitget):
|
|
1030
1047
|
innerMessageHash = messageHash + ':' + symbol
|
1031
1048
|
client.resolve(stored, innerMessageHash)
|
1032
1049
|
client.resolve(stored, messageHash)
|
1050
|
+
if isLinearSwap:
|
1051
|
+
client.resolve(stored, 'order:linear')
|
1052
|
+
if isInverseSwap:
|
1053
|
+
client.resolve(stored, 'order:inverse')
|
1054
|
+
if isUSDCFutures:
|
1055
|
+
client.resolve(stored, 'order:usdcfutures')
|
1033
1056
|
|
1034
1057
|
def parse_ws_order(self, order, market=None):
|
1035
1058
|
#
|
ccxt/pro/bitmart.py
CHANGED
@@ -506,7 +506,7 @@ class bitmart(ccxt.async_support.bitmart):
|
|
506
506
|
amount = self.safe_string(order, 'size')
|
507
507
|
type = self.safe_string(order, 'type')
|
508
508
|
rawState = self.safe_string(order, 'state')
|
509
|
-
status = self.
|
509
|
+
status = self.parse_order_status_by_type(market['type'], rawState)
|
510
510
|
timestamp = self.safe_integer(order, 'ms_t')
|
511
511
|
symbol = market['symbol']
|
512
512
|
side = self.safe_string_lower(order, 'side')
|
ccxt/pro/bitmex.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
import ccxt.async_support
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Int, Order, OrderBook, Position, Str, Strings, Ticker, Tickers, Trade
|
9
|
+
from ccxt.base.types import Balances, Int, Liquidation, Order, OrderBook, Position, Str, Strings, Ticker, Tickers, Trade
|
10
10
|
from ccxt.async_support.base.ws.client import Client
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import ExchangeError
|
@@ -21,6 +21,10 @@ class bitmex(ccxt.async_support.bitmex):
|
|
21
21
|
'has': {
|
22
22
|
'ws': True,
|
23
23
|
'watchBalance': True,
|
24
|
+
'watchLiquidations': True,
|
25
|
+
'watchLiquidationsForSymbols': True,
|
26
|
+
'watchMyLiquidations': None,
|
27
|
+
'watchMyLiquidationsForSymbols': None,
|
24
28
|
'watchMyTrades': True,
|
25
29
|
'watchOHLCV': True,
|
26
30
|
'watchOrderBook': True,
|
@@ -350,6 +354,98 @@ class bitmex(ccxt.async_support.bitmex):
|
|
350
354
|
client.resolve(fullParsedTicker, 'alltickers')
|
351
355
|
return message
|
352
356
|
|
357
|
+
async def watch_liquidations(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
358
|
+
"""
|
359
|
+
watch the public liquidations of a trading pair
|
360
|
+
:see: https://www.bitmex.com/app/wsAPI#Liquidation
|
361
|
+
:param str symbol: unified CCXT market symbol
|
362
|
+
:param int [since]: the earliest time in ms to fetch liquidations for
|
363
|
+
:param int [limit]: the maximum number of liquidation structures to retrieve
|
364
|
+
:param dict [params]: exchange specific parameters for the bitmex api endpoint
|
365
|
+
:returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
|
366
|
+
"""
|
367
|
+
return self.watch_liquidations_for_symbols([symbol], since, limit, params)
|
368
|
+
|
369
|
+
async def watch_liquidations_for_symbols(self, symbols: List[str] = None, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
370
|
+
"""
|
371
|
+
watch the public liquidations of a trading pair
|
372
|
+
:see: https://www.bitmex.com/app/wsAPI#Liquidation
|
373
|
+
:param str symbol: unified CCXT market symbol
|
374
|
+
:param int [since]: the earliest time in ms to fetch liquidations for
|
375
|
+
:param int [limit]: the maximum number of liquidation structures to retrieve
|
376
|
+
:param dict [params]: exchange specific parameters for the bitmex api endpoint
|
377
|
+
:returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
|
378
|
+
"""
|
379
|
+
await self.load_markets()
|
380
|
+
symbols = self.market_symbols(symbols, None, True, True)
|
381
|
+
messageHashes = []
|
382
|
+
subscriptionHashes = []
|
383
|
+
if self.is_empty(symbols):
|
384
|
+
subscriptionHashes.append('liquidation')
|
385
|
+
messageHashes.append('liquidations')
|
386
|
+
else:
|
387
|
+
for i in range(0, len(symbols)):
|
388
|
+
symbol = symbols[i]
|
389
|
+
market = self.market(symbol)
|
390
|
+
subscriptionHashes.append('liquidation:' + market['id'])
|
391
|
+
messageHashes.append('liquidations::' + symbol)
|
392
|
+
url = self.urls['api']['ws']
|
393
|
+
request = {
|
394
|
+
'op': 'subscribe',
|
395
|
+
'args': subscriptionHashes,
|
396
|
+
}
|
397
|
+
newLiquidations = await self.watch_multiple(url, messageHashes, self.deep_extend(request, params), subscriptionHashes)
|
398
|
+
if self.newUpdates:
|
399
|
+
return newLiquidations
|
400
|
+
return self.filter_by_symbols_since_limit(self.liquidations, symbols, since, limit, True)
|
401
|
+
|
402
|
+
def handle_liquidation(self, client: Client, message):
|
403
|
+
#
|
404
|
+
# {
|
405
|
+
# "table":"liquidation",
|
406
|
+
# "action":"partial",
|
407
|
+
# "keys":[
|
408
|
+
# "orderID"
|
409
|
+
# ],
|
410
|
+
# "types":{
|
411
|
+
# "orderID":"guid",
|
412
|
+
# "symbol":"symbol",
|
413
|
+
# "side":"symbol",
|
414
|
+
# "price":"float",
|
415
|
+
# "leavesQty":"long"
|
416
|
+
# },
|
417
|
+
# "filter":{},
|
418
|
+
# "data":[
|
419
|
+
# {
|
420
|
+
# "orderID":"e0a568ee-7830-4428-92c3-73e82b9576ce",
|
421
|
+
# "symbol":"XPLAUSDT",
|
422
|
+
# "side":"Sell",
|
423
|
+
# "price":0.206,
|
424
|
+
# "leavesQty":340
|
425
|
+
# }
|
426
|
+
# ]
|
427
|
+
# }
|
428
|
+
#
|
429
|
+
rawLiquidations = self.safe_value(message, 'data', [])
|
430
|
+
newLiquidations = []
|
431
|
+
for i in range(0, len(rawLiquidations)):
|
432
|
+
rawLiquidation = rawLiquidations[i]
|
433
|
+
liquidation = self.parse_liquidation(rawLiquidation)
|
434
|
+
symbol = liquidation['symbol']
|
435
|
+
liquidations = self.safe_value(self.liquidations, symbol)
|
436
|
+
if liquidations is None:
|
437
|
+
limit = self.safe_integer(self.options, 'liquidationsLimit', 1000)
|
438
|
+
liquidations = ArrayCache(limit)
|
439
|
+
liquidations.append(liquidation)
|
440
|
+
self.liquidations[symbol] = liquidations
|
441
|
+
newLiquidations.append(liquidation)
|
442
|
+
client.resolve(newLiquidations, 'liquidations')
|
443
|
+
liquidationsBySymbol = self.index_by(newLiquidations, 'symbol')
|
444
|
+
symbols = list(liquidationsBySymbol.keys())
|
445
|
+
for i in range(0, len(symbols)):
|
446
|
+
symbol = symbols[i]
|
447
|
+
client.resolve(liquidationsBySymbol[symbol], 'liquidations::' + symbol)
|
448
|
+
|
353
449
|
async def watch_balance(self, params={}) -> Balances:
|
354
450
|
"""
|
355
451
|
watch balance and get the amount of funds available for trading or funds locked in orders
|
@@ -1541,6 +1637,7 @@ class bitmex(ccxt.async_support.bitmex):
|
|
1541
1637
|
'order': self.handle_orders,
|
1542
1638
|
'execution': self.handle_my_trades,
|
1543
1639
|
'margin': self.handle_balance,
|
1640
|
+
'liquidation': self.handle_liquidation,
|
1544
1641
|
'position': self.handle_positions,
|
1545
1642
|
}
|
1546
1643
|
method = self.safe_value(methods, table)
|