ccxt 4.3.4__py2.py3-none-any.whl → 4.3.6__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ccxt/__init__.py +1 -1
- ccxt/abstract/binance.py +1 -0
- ccxt/abstract/binancecoinm.py +1 -0
- ccxt/abstract/binanceus.py +1 -0
- ccxt/abstract/binanceusdm.py +1 -0
- ccxt/abstract/bingx.py +1 -0
- ccxt/abstract/whitebit.py +22 -1
- ccxt/abstract/woo.py +1 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +227 -36
- ccxt/async_support/binance.py +21 -14
- ccxt/async_support/bingx.py +40 -0
- ccxt/async_support/bitmex.py +22 -0
- ccxt/async_support/bybit.py +81 -1
- ccxt/async_support/coinbase.py +4 -4
- ccxt/async_support/coinex.py +29 -32
- ccxt/async_support/cryptocom.py +30 -1
- ccxt/async_support/htx.py +26 -0
- ccxt/async_support/hyperliquid.py +37 -0
- ccxt/async_support/kraken.py +27 -0
- ccxt/async_support/krakenfutures.py +26 -0
- ccxt/async_support/kucoin.py +52 -4
- ccxt/async_support/kucoinfutures.py +2 -2
- ccxt/async_support/okx.py +104 -1
- ccxt/async_support/whitebit.py +149 -2
- ccxt/async_support/woo.py +27 -0
- ccxt/base/exchange.py +233 -4
- ccxt/binance.py +21 -14
- ccxt/bingx.py +40 -0
- ccxt/bitmex.py +22 -0
- ccxt/bybit.py +81 -1
- ccxt/coinbase.py +4 -4
- ccxt/coinex.py +29 -32
- ccxt/cryptocom.py +30 -1
- ccxt/htx.py +26 -0
- ccxt/hyperliquid.py +37 -0
- ccxt/kraken.py +27 -0
- ccxt/krakenfutures.py +26 -0
- ccxt/kucoin.py +52 -4
- ccxt/kucoinfutures.py +2 -2
- ccxt/okx.py +104 -1
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +410 -73
- ccxt/pro/bitget.py +1 -1
- ccxt/pro/cex.py +1 -1
- ccxt/pro/lbank.py +1 -1
- ccxt/pro/woo.py +0 -1
- ccxt/test/test_async.py +17 -17
- ccxt/test/test_sync.py +17 -17
- ccxt/whitebit.py +149 -2
- ccxt/woo.py +27 -0
- {ccxt-4.3.4.dist-info → ccxt-4.3.6.dist-info}/METADATA +4 -4
- {ccxt-4.3.4.dist-info → ccxt-4.3.6.dist-info}/RECORD +55 -55
- {ccxt-4.3.4.dist-info → ccxt-4.3.6.dist-info}/WHEEL +0 -0
- {ccxt-4.3.4.dist-info → ccxt-4.3.6.dist-info}/top_level.txt +0 -0
ccxt/async_support/bingx.py
CHANGED
@@ -47,6 +47,7 @@ class bingx(Exchange, ImplicitAPI):
|
|
47
47
|
'option': False,
|
48
48
|
'addMargin': True,
|
49
49
|
'cancelAllOrders': True,
|
50
|
+
'cancelAllOrdersAfter': True,
|
50
51
|
'cancelOrder': True,
|
51
52
|
'cancelOrders': True,
|
52
53
|
'closeAllPositions': True,
|
@@ -243,6 +244,7 @@ class bingx(Exchange, ImplicitAPI):
|
|
243
244
|
'trade/order': 3,
|
244
245
|
'trade/batchOrders': 3,
|
245
246
|
'trade/closeAllPositions': 3,
|
247
|
+
'trade/cancelAllAfter': 3,
|
246
248
|
'trade/marginType': 3,
|
247
249
|
'trade/leverage': 3,
|
248
250
|
'trade/positionMargin': 3,
|
@@ -2582,6 +2584,44 @@ class bingx(Exchange, ImplicitAPI):
|
|
2582
2584
|
#
|
2583
2585
|
return response
|
2584
2586
|
|
2587
|
+
async def cancel_all_orders_after(self, timeout: Int, params={}):
|
2588
|
+
"""
|
2589
|
+
dead man's switch, cancel all orders after the given timeout
|
2590
|
+
:see: https://bingx-api.github.io/docs/#/en-us/spot/trade-api.html#Cancel%20all%20orders%20in%20countdown
|
2591
|
+
:see: https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Cancel%20all%20orders%20in%20countdown
|
2592
|
+
:param number timeout: time in milliseconds, 0 represents cancel the timer
|
2593
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2594
|
+
:param str [params.type]: spot or swap market
|
2595
|
+
:returns dict: the api result
|
2596
|
+
"""
|
2597
|
+
await self.load_markets()
|
2598
|
+
isActive = (timeout > 0)
|
2599
|
+
request: dict = {
|
2600
|
+
'type': 'ACTIVATE' if (isActive) else 'CLOSE',
|
2601
|
+
'timeOut': (self.parse_to_int(timeout / 1000)) if (isActive) else 0,
|
2602
|
+
}
|
2603
|
+
response = None
|
2604
|
+
type = None
|
2605
|
+
type, params = self.handle_market_type_and_params('cancelAllOrdersAfter', None, params)
|
2606
|
+
if type == 'spot':
|
2607
|
+
response = await self.spotV1PrivatePostTradeCancelAllAfter(self.extend(request, params))
|
2608
|
+
elif type == 'swap':
|
2609
|
+
response = await self.swapV2PrivatePostTradeCancelAllAfter(self.extend(request, params))
|
2610
|
+
else:
|
2611
|
+
raise NotSupported(self.id + ' cancelAllOrdersAfter() is not supported for ' + type + ' markets')
|
2612
|
+
#
|
2613
|
+
# {
|
2614
|
+
# code: '0',
|
2615
|
+
# msg: '',
|
2616
|
+
# data: {
|
2617
|
+
# triggerTime: '1712645434',
|
2618
|
+
# status: 'ACTIVATED',
|
2619
|
+
# note: 'All your perpetual pending orders will be closed automatically at 2024-04-09 06:50:34 UTC(+0),before that you can cancel the timer, or self.extend triggerTime time by self request'
|
2620
|
+
# }
|
2621
|
+
# }
|
2622
|
+
#
|
2623
|
+
return response
|
2624
|
+
|
2585
2625
|
async def fetch_order(self, id: str, symbol: Str = None, params={}):
|
2586
2626
|
"""
|
2587
2627
|
fetches information on an order made by the user
|
ccxt/async_support/bitmex.py
CHANGED
@@ -48,6 +48,7 @@ class bitmex(Exchange, ImplicitAPI):
|
|
48
48
|
'option': False,
|
49
49
|
'addMargin': None,
|
50
50
|
'cancelAllOrders': True,
|
51
|
+
'cancelAllOrdersAfter': True,
|
51
52
|
'cancelOrder': True,
|
52
53
|
'cancelOrders': True,
|
53
54
|
'closeAllPositions': False,
|
@@ -1979,6 +1980,27 @@ class bitmex(Exchange, ImplicitAPI):
|
|
1979
1980
|
#
|
1980
1981
|
return self.parse_orders(response, market)
|
1981
1982
|
|
1983
|
+
async def cancel_all_orders_after(self, timeout: Int, params={}):
|
1984
|
+
"""
|
1985
|
+
dead man's switch, cancel all orders after the given timeout
|
1986
|
+
:see: https://www.bitmex.com/api/explorer/#not /Order/Order_cancelAllAfter
|
1987
|
+
:param number timeout: time in milliseconds, 0 represents cancel the timer
|
1988
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1989
|
+
:returns dict: the api result
|
1990
|
+
"""
|
1991
|
+
await self.load_markets()
|
1992
|
+
request: dict = {
|
1993
|
+
'timeout': self.parse_to_int(timeout / 1000) if (timeout > 0) else 0,
|
1994
|
+
}
|
1995
|
+
response = await self.privatePostOrderCancelAllAfter(self.extend(request, params))
|
1996
|
+
#
|
1997
|
+
# {
|
1998
|
+
# now: '2024-04-09T09:01:56.560Z',
|
1999
|
+
# cancelTime: '2024-04-09T09:01:56.660Z'
|
2000
|
+
# }
|
2001
|
+
#
|
2002
|
+
return response
|
2003
|
+
|
1982
2004
|
async def fetch_leverages(self, symbols: List[str] = None, params={}) -> Leverages:
|
1983
2005
|
"""
|
1984
2006
|
fetch the set leverage for all contract markets
|
ccxt/async_support/bybit.py
CHANGED
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.bybit import ImplicitAPI
|
8
8
|
import asyncio
|
9
9
|
import hashlib
|
10
|
-
from ccxt.base.types import Balances, Currencies, Currency, Greeks, Int, Leverage, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
|
10
|
+
from ccxt.base.types import Balances, Currencies, Currency, Greeks, Int, Leverage, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import ExchangeError
|
13
13
|
from ccxt.base.errors import AuthenticationError
|
@@ -50,6 +50,8 @@ class bybit(Exchange, ImplicitAPI):
|
|
50
50
|
'borrowCrossMargin': True,
|
51
51
|
'cancelAllOrders': True,
|
52
52
|
'cancelOrder': True,
|
53
|
+
'cancelOrders': True,
|
54
|
+
'cancelOrdersForSymbols': True,
|
53
55
|
'closeAllPositions': False,
|
54
56
|
'closePosition': False,
|
55
57
|
'createMarketBuyOrderWithCost': True,
|
@@ -4089,6 +4091,84 @@ class bybit(Exchange, ImplicitAPI):
|
|
4089
4091
|
row = self.safe_list(result, 'list', [])
|
4090
4092
|
return self.parse_orders(row, market)
|
4091
4093
|
|
4094
|
+
async def cancel_orders_for_symbols(self, orders: List[CancellationRequest], params={}):
|
4095
|
+
"""
|
4096
|
+
cancel multiple orders for multiple symbols
|
4097
|
+
:see: https://bybit-exchange.github.io/docs/v5/order/batch-cancel
|
4098
|
+
:param str[] ids: order ids
|
4099
|
+
:param str symbol: unified symbol of the market the order was made in
|
4100
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4101
|
+
:param str[] [params.clientOrderIds]: client order ids
|
4102
|
+
:returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
4103
|
+
"""
|
4104
|
+
await self.load_markets()
|
4105
|
+
ordersRequests = []
|
4106
|
+
category = None
|
4107
|
+
for i in range(0, len(orders)):
|
4108
|
+
order = orders[i]
|
4109
|
+
symbol = self.safe_string(order, 'symbol')
|
4110
|
+
market = self.market(symbol)
|
4111
|
+
currentCategory = None
|
4112
|
+
currentCategory, params = self.get_bybit_type('cancelOrders', market, params)
|
4113
|
+
if currentCategory == 'inverse':
|
4114
|
+
raise NotSupported(self.id + ' cancelOrdersForSymbols does not allow inverse orders')
|
4115
|
+
if (category is not None) and (category != currentCategory):
|
4116
|
+
raise ExchangeError(self.id + ' cancelOrdersForSymbols requires all orders to be of the same category(linear, spot or option))')
|
4117
|
+
category = currentCategory
|
4118
|
+
id = self.safe_string(order, 'id')
|
4119
|
+
clientOrderId = self.safe_string(order, 'clientOrderId')
|
4120
|
+
idKey = 'orderId'
|
4121
|
+
if clientOrderId is not None:
|
4122
|
+
idKey = 'orderLinkId'
|
4123
|
+
orderItem = {
|
4124
|
+
'symbol': market['id'],
|
4125
|
+
}
|
4126
|
+
orderItem[idKey] = id if (idKey == 'orderId') else clientOrderId
|
4127
|
+
ordersRequests.append(orderItem)
|
4128
|
+
request = {
|
4129
|
+
'category': category,
|
4130
|
+
'request': ordersRequests,
|
4131
|
+
}
|
4132
|
+
response = await self.privatePostV5OrderCancelBatch(self.extend(request, params))
|
4133
|
+
#
|
4134
|
+
# {
|
4135
|
+
# "retCode": "0",
|
4136
|
+
# "retMsg": "OK",
|
4137
|
+
# "result": {
|
4138
|
+
# "list": [
|
4139
|
+
# {
|
4140
|
+
# "category": "spot",
|
4141
|
+
# "symbol": "BTCUSDT",
|
4142
|
+
# "orderId": "1636282505818800896",
|
4143
|
+
# "orderLinkId": "1636282505818800897"
|
4144
|
+
# },
|
4145
|
+
# {
|
4146
|
+
# "category": "spot",
|
4147
|
+
# "symbol": "BTCUSDT",
|
4148
|
+
# "orderId": "1636282505818800898",
|
4149
|
+
# "orderLinkId": "1636282505818800899"
|
4150
|
+
# }
|
4151
|
+
# ]
|
4152
|
+
# },
|
4153
|
+
# "retExtInfo": {
|
4154
|
+
# "list": [
|
4155
|
+
# {
|
4156
|
+
# "code": "0",
|
4157
|
+
# "msg": "OK"
|
4158
|
+
# },
|
4159
|
+
# {
|
4160
|
+
# "code": "0",
|
4161
|
+
# "msg": "OK"
|
4162
|
+
# }
|
4163
|
+
# ]
|
4164
|
+
# },
|
4165
|
+
# "time": "1709796158501"
|
4166
|
+
# }
|
4167
|
+
#
|
4168
|
+
result = self.safe_dict(response, 'result', {})
|
4169
|
+
row = self.safe_list(result, 'list', [])
|
4170
|
+
return self.parse_orders(row, None)
|
4171
|
+
|
4092
4172
|
async def cancel_all_usdc_orders(self, symbol: Str = None, params={}):
|
4093
4173
|
if symbol is None:
|
4094
4174
|
raise ArgumentsRequired(self.id + ' cancelAllUsdcOrders() requires a symbol argument')
|
ccxt/async_support/coinbase.py
CHANGED
@@ -3245,11 +3245,11 @@ class coinbase(Exchange, ImplicitAPI):
|
|
3245
3245
|
now = str(self.seconds())
|
3246
3246
|
sinceString = Precise.string_sub(now, str(requestedDuration))
|
3247
3247
|
request['start'] = sinceString
|
3248
|
-
|
3249
|
-
|
3248
|
+
if until is not None:
|
3249
|
+
request['end'] = self.number_to_string(self.parse_to_int(until / 1000))
|
3250
|
+
else:
|
3250
3251
|
# 300 candles max
|
3251
|
-
|
3252
|
-
request['end'] = endString
|
3252
|
+
request['end'] = Precise.string_add(sinceString, str(requestedDuration))
|
3253
3253
|
response = await self.v3PrivateGetBrokerageProductsProductIdCandles(self.extend(request, params))
|
3254
3254
|
#
|
3255
3255
|
# {
|
ccxt/async_support/coinex.py
CHANGED
@@ -1116,14 +1116,13 @@ class coinex(Exchange, ImplicitAPI):
|
|
1116
1116
|
#
|
1117
1117
|
# Spot and Swap fetchTrades(public)
|
1118
1118
|
#
|
1119
|
-
#
|
1120
|
-
#
|
1121
|
-
#
|
1122
|
-
#
|
1123
|
-
#
|
1124
|
-
#
|
1125
|
-
#
|
1126
|
-
# },
|
1119
|
+
# {
|
1120
|
+
# "amount": "0.00049432",
|
1121
|
+
# "created_at": 1713849825667,
|
1122
|
+
# "deal_id": 4137517302,
|
1123
|
+
# "price": "66251",
|
1124
|
+
# "side": "buy"
|
1125
|
+
# }
|
1127
1126
|
#
|
1128
1127
|
# Spot and Margin fetchMyTrades(private)
|
1129
1128
|
#
|
@@ -1177,8 +1176,8 @@ class coinex(Exchange, ImplicitAPI):
|
|
1177
1176
|
#
|
1178
1177
|
timestamp = self.safe_timestamp_2(trade, 'create_time', 'time')
|
1179
1178
|
if timestamp is None:
|
1180
|
-
timestamp = self.safe_integer(trade, '
|
1181
|
-
tradeId = self.
|
1179
|
+
timestamp = self.safe_integer(trade, 'created_at')
|
1180
|
+
tradeId = self.safe_string_2(trade, 'id', 'deal_id')
|
1182
1181
|
orderId = self.safe_string(trade, 'order_id')
|
1183
1182
|
priceString = self.safe_string(trade, 'price')
|
1184
1183
|
amountString = self.safe_string(trade, 'amount')
|
@@ -1210,9 +1209,9 @@ class coinex(Exchange, ImplicitAPI):
|
|
1210
1209
|
elif rawSide == 2:
|
1211
1210
|
side = 'buy'
|
1212
1211
|
if side is None:
|
1213
|
-
side = self.
|
1212
|
+
side = self.safe_string_2(trade, 'type', 'side')
|
1214
1213
|
else:
|
1215
|
-
side = self.
|
1214
|
+
side = self.safe_string_2(trade, 'type', 'side')
|
1216
1215
|
return self.safe_trade({
|
1217
1216
|
'info': trade,
|
1218
1217
|
'timestamp': timestamp,
|
@@ -1231,9 +1230,9 @@ class coinex(Exchange, ImplicitAPI):
|
|
1231
1230
|
|
1232
1231
|
async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
1233
1232
|
"""
|
1234
|
-
get the list of most recent trades for a particular symbol
|
1235
|
-
:see: https://
|
1236
|
-
:see: https://
|
1233
|
+
get the list of the most recent trades for a particular symbol
|
1234
|
+
:see: https://docs.coinex.com/api/v2/spot/market/http/list-market-deals
|
1235
|
+
:see: https://docs.coinex.com/api/v2/futures/market/http/list-market-deals
|
1237
1236
|
:param str symbol: unified symbol of the market to fetch trades for
|
1238
1237
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
1239
1238
|
:param int [limit]: the maximum amount of trades to fetch
|
@@ -1250,26 +1249,25 @@ class coinex(Exchange, ImplicitAPI):
|
|
1250
1249
|
request['limit'] = limit
|
1251
1250
|
response = None
|
1252
1251
|
if market['swap']:
|
1253
|
-
response = await self.
|
1252
|
+
response = await self.v2PublicGetFuturesDeals(self.extend(request, params))
|
1254
1253
|
else:
|
1255
|
-
response = await self.
|
1254
|
+
response = await self.v2PublicGetSpotDeals(self.extend(request, params))
|
1256
1255
|
#
|
1257
1256
|
# Spot and Swap
|
1258
1257
|
#
|
1259
|
-
#
|
1260
|
-
#
|
1261
|
-
#
|
1262
|
-
#
|
1263
|
-
#
|
1264
|
-
#
|
1265
|
-
#
|
1266
|
-
#
|
1267
|
-
#
|
1268
|
-
#
|
1269
|
-
#
|
1270
|
-
#
|
1271
|
-
#
|
1272
|
-
# }
|
1258
|
+
# {
|
1259
|
+
# "code": 0,
|
1260
|
+
# "data": [
|
1261
|
+
# {
|
1262
|
+
# "amount": "0.00049432",
|
1263
|
+
# "created_at": 1713849825667,
|
1264
|
+
# "deal_id": 4137517302,
|
1265
|
+
# "price": "66251",
|
1266
|
+
# "side": "buy"
|
1267
|
+
# },
|
1268
|
+
# ],
|
1269
|
+
# "message": "OK"
|
1270
|
+
# }
|
1273
1271
|
#
|
1274
1272
|
return self.parse_trades(response['data'], market, since, limit)
|
1275
1273
|
|
@@ -4205,7 +4203,6 @@ class coinex(Exchange, ImplicitAPI):
|
|
4205
4203
|
|
4206
4204
|
async def fetch_funding_rates(self, symbols: Strings = None, params={}):
|
4207
4205
|
"""
|
4208
|
-
* @method
|
4209
4206
|
fetch the current funding rates
|
4210
4207
|
:see: https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http009_market_ticker_all
|
4211
4208
|
:param str[] symbols: unified market symbols
|
ccxt/async_support/cryptocom.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.async_support.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.cryptocom import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
|
9
|
+
from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import ExchangeError
|
12
12
|
from ccxt.base.errors import AuthenticationError
|
@@ -47,6 +47,7 @@ class cryptocom(Exchange, ImplicitAPI):
|
|
47
47
|
'cancelAllOrders': True,
|
48
48
|
'cancelOrder': True,
|
49
49
|
'cancelOrders': True,
|
50
|
+
'cancelOrdersForSymbols': True,
|
50
51
|
'closeAllPositions': False,
|
51
52
|
'closePosition': True,
|
52
53
|
'createMarketBuyOrderWithCost': False,
|
@@ -1353,6 +1354,34 @@ class cryptocom(Exchange, ImplicitAPI):
|
|
1353
1354
|
result = self.safe_list(response, 'result', [])
|
1354
1355
|
return self.parse_orders(result, market, None, None, params)
|
1355
1356
|
|
1357
|
+
async def cancel_orders_for_symbols(self, orders: List[CancellationRequest], params={}):
|
1358
|
+
"""
|
1359
|
+
cancel multiple orders for multiple symbols
|
1360
|
+
:see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-cancel-order-list-list
|
1361
|
+
:param CancellationRequest[] orders: each order should contain the parameters required by cancelOrder namely id and symbol
|
1362
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1363
|
+
:returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
1364
|
+
"""
|
1365
|
+
await self.load_markets()
|
1366
|
+
orderRequests = []
|
1367
|
+
for i in range(0, len(orders)):
|
1368
|
+
order = orders[i]
|
1369
|
+
id = self.safe_string(order, 'id')
|
1370
|
+
symbol = self.safe_string(order, 'symbol')
|
1371
|
+
market = self.market(symbol)
|
1372
|
+
orderItem = {
|
1373
|
+
'instrument_name': market['id'],
|
1374
|
+
'order_id': str(id),
|
1375
|
+
}
|
1376
|
+
orderRequests.append(orderItem)
|
1377
|
+
request = {
|
1378
|
+
'contingency_type': 'LIST',
|
1379
|
+
'order_list': orderRequests,
|
1380
|
+
}
|
1381
|
+
response = await self.v1PrivatePostPrivateCancelOrderList(self.extend(request, params))
|
1382
|
+
result = self.safe_list(response, 'result', [])
|
1383
|
+
return self.parse_orders(result, None, None, None, params)
|
1384
|
+
|
1356
1385
|
async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
1357
1386
|
"""
|
1358
1387
|
fetch all unfilled currently open orders
|
ccxt/async_support/htx.py
CHANGED
@@ -54,6 +54,7 @@ class htx(Exchange, ImplicitAPI):
|
|
54
54
|
'borrowCrossMargin': True,
|
55
55
|
'borrowIsolatedMargin': True,
|
56
56
|
'cancelAllOrders': True,
|
57
|
+
'cancelAllOrdersAfter': True,
|
57
58
|
'cancelOrder': True,
|
58
59
|
'cancelOrders': True,
|
59
60
|
'createDepositAddress': None,
|
@@ -5629,6 +5630,31 @@ class htx(Exchange, ImplicitAPI):
|
|
5629
5630
|
#
|
5630
5631
|
return response
|
5631
5632
|
|
5633
|
+
async def cancel_all_orders_after(self, timeout: Int, params={}):
|
5634
|
+
"""
|
5635
|
+
dead man's switch, cancel all orders after the given timeout
|
5636
|
+
:see: https://huobiapi.github.io/docs/spot/v1/en/#dead-man-s-switch
|
5637
|
+
:param number timeout: time in milliseconds, 0 represents cancel the timer
|
5638
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
5639
|
+
:returns dict: the api result
|
5640
|
+
"""
|
5641
|
+
await self.load_markets()
|
5642
|
+
request: dict = {
|
5643
|
+
'timeout': self.parse_to_int(timeout / 1000) if (timeout > 0) else 0,
|
5644
|
+
}
|
5645
|
+
response = await self.v2PrivatePostAlgoOrdersCancelAllAfter(self.extend(request, params))
|
5646
|
+
#
|
5647
|
+
# {
|
5648
|
+
# "code": 200,
|
5649
|
+
# "message": "success",
|
5650
|
+
# "data": {
|
5651
|
+
# "currentTime": 1630491627230,
|
5652
|
+
# "triggerTime": 1630491637230
|
5653
|
+
# }
|
5654
|
+
# }
|
5655
|
+
#
|
5656
|
+
return response
|
5657
|
+
|
5632
5658
|
def parse_deposit_address(self, depositAddress, currency: Currency = None):
|
5633
5659
|
#
|
5634
5660
|
# {
|
@@ -43,6 +43,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
43
43
|
'borrowCrossMargin': False,
|
44
44
|
'borrowIsolatedMargin': False,
|
45
45
|
'cancelAllOrders': False,
|
46
|
+
'cancelAllOrdersAfter': True,
|
46
47
|
'cancelOrder': True,
|
47
48
|
'cancelOrders': True,
|
48
49
|
'cancelOrdersForSymbols': True,
|
@@ -1303,6 +1304,42 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1303
1304
|
#
|
1304
1305
|
return response
|
1305
1306
|
|
1307
|
+
async def cancel_all_orders_after(self, timeout: Int, params={}):
|
1308
|
+
"""
|
1309
|
+
dead man's switch, cancel all orders after the given timeout
|
1310
|
+
:param number timeout: time in milliseconds, 0 represents cancel the timer
|
1311
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1312
|
+
:param str [params.vaultAddress]: the vault address
|
1313
|
+
:returns dict: the api result
|
1314
|
+
"""
|
1315
|
+
self.check_required_credentials()
|
1316
|
+
await self.load_markets()
|
1317
|
+
params = self.omit(params, ['clientOrderId', 'client_id'])
|
1318
|
+
nonce = self.milliseconds()
|
1319
|
+
request = {
|
1320
|
+
'nonce': nonce,
|
1321
|
+
# 'vaultAddress': vaultAddress,
|
1322
|
+
}
|
1323
|
+
cancelAction = {
|
1324
|
+
'type': 'scheduleCancel',
|
1325
|
+
'time': nonce + timeout,
|
1326
|
+
}
|
1327
|
+
vaultAddress = self.format_vault_address(self.safe_string(params, 'vaultAddress'))
|
1328
|
+
signature = self.sign_l1_action(cancelAction, nonce, vaultAddress)
|
1329
|
+
request['action'] = cancelAction
|
1330
|
+
request['signature'] = signature
|
1331
|
+
if vaultAddress is not None:
|
1332
|
+
params = self.omit(params, 'vaultAddress')
|
1333
|
+
request['vaultAddress'] = vaultAddress
|
1334
|
+
response = await self.privatePostExchange(self.extend(request, params))
|
1335
|
+
#
|
1336
|
+
# {
|
1337
|
+
# "status":"err",
|
1338
|
+
# "response":"Cannot set scheduled cancel time until enough volume traded. Required: $1000000. Traded: $373.47205."
|
1339
|
+
# }
|
1340
|
+
#
|
1341
|
+
return response
|
1342
|
+
|
1306
1343
|
async def edit_order(self, id: str, symbol: str, type: str, side: str, amount: Num = None, price: Num = None, params={}):
|
1307
1344
|
"""
|
1308
1345
|
edit a trade order
|
ccxt/async_support/kraken.py
CHANGED
@@ -54,6 +54,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
54
54
|
'option': False,
|
55
55
|
'addMargin': False,
|
56
56
|
'cancelAllOrders': True,
|
57
|
+
'cancelAllOrdersAfter': True,
|
57
58
|
'cancelOrder': True,
|
58
59
|
'cancelOrders': True,
|
59
60
|
'createDepositAddress': True,
|
@@ -2006,6 +2007,32 @@ class kraken(Exchange, ImplicitAPI):
|
|
2006
2007
|
await self.load_markets()
|
2007
2008
|
return await self.privatePostCancelAll(params)
|
2008
2009
|
|
2010
|
+
async def cancel_all_orders_after(self, timeout: Int, params={}):
|
2011
|
+
"""
|
2012
|
+
dead man's switch, cancel all orders after the given timeout
|
2013
|
+
:see: https://docs.kraken.com/rest/#tag/Spot-Trading/operation/cancelAllOrdersAfter
|
2014
|
+
:param number timeout: time in milliseconds, 0 represents cancel the timer
|
2015
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2016
|
+
:returns dict: the api result
|
2017
|
+
"""
|
2018
|
+
if timeout > 86400000:
|
2019
|
+
raise BadRequest(self.id + 'cancelAllOrdersAfter timeout should be less than 86400000 milliseconds')
|
2020
|
+
await self.load_markets()
|
2021
|
+
request: dict = {
|
2022
|
+
'timeout': (self.parse_to_int(timeout / 1000)) if (timeout > 0) else 0,
|
2023
|
+
}
|
2024
|
+
response = await self.privatePostCancelAllOrdersAfter(self.extend(request, params))
|
2025
|
+
#
|
2026
|
+
# {
|
2027
|
+
# "error": [],
|
2028
|
+
# "result": {
|
2029
|
+
# "currentTime": "2023-03-24T17:41:56Z",
|
2030
|
+
# "triggerTime": "2023-03-24T17:42:56Z"
|
2031
|
+
# }
|
2032
|
+
# }
|
2033
|
+
#
|
2034
|
+
return response
|
2035
|
+
|
2009
2036
|
async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
2010
2037
|
"""
|
2011
2038
|
fetch all unfilled currently open orders
|
@@ -46,6 +46,7 @@ class krakenfutures(Exchange, ImplicitAPI):
|
|
46
46
|
'future': True,
|
47
47
|
'option': False,
|
48
48
|
'cancelAllOrders': True,
|
49
|
+
'cancelAllOrdersAfter': True,
|
49
50
|
'cancelOrder': True,
|
50
51
|
'cancelOrders': True,
|
51
52
|
'createMarketOrder': False,
|
@@ -1207,6 +1208,31 @@ class krakenfutures(Exchange, ImplicitAPI):
|
|
1207
1208
|
response = await self.privatePostCancelallorders(self.extend(request, params))
|
1208
1209
|
return response
|
1209
1210
|
|
1211
|
+
async def cancel_all_orders_after(self, timeout: Int, params={}):
|
1212
|
+
"""
|
1213
|
+
dead man's switch, cancel all orders after the given timeout
|
1214
|
+
:see: https://docs.futures.kraken.com/#http-api-trading-v3-api-order-management-dead-man-39-s-switch
|
1215
|
+
:param number timeout: time in milliseconds, 0 represents cancel the timer
|
1216
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1217
|
+
:returns dict: the api result
|
1218
|
+
"""
|
1219
|
+
await self.load_markets()
|
1220
|
+
request: dict = {
|
1221
|
+
'timeout': (self.parse_to_int(timeout / 1000)) if (timeout > 0) else 0,
|
1222
|
+
}
|
1223
|
+
response = await self.privatePostCancelallordersafter(self.extend(request, params))
|
1224
|
+
#
|
1225
|
+
# {
|
1226
|
+
# "result": "success",
|
1227
|
+
# "serverTime": "2018-06-19T16:51:23.839Z",
|
1228
|
+
# "status": {
|
1229
|
+
# "currentTime": "2018-06-19T16:51:23.839Z",
|
1230
|
+
# "triggerTime": "0"
|
1231
|
+
# }
|
1232
|
+
# }
|
1233
|
+
#
|
1234
|
+
return response
|
1235
|
+
|
1210
1236
|
async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
1211
1237
|
"""
|
1212
1238
|
:see: https://docs.futures.kraken.com/#http-api-trading-v3-api-order-management-get-open-orders
|
ccxt/async_support/kucoin.py
CHANGED
@@ -534,7 +534,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
534
534
|
'400006': AuthenticationError,
|
535
535
|
'400007': AuthenticationError,
|
536
536
|
'400008': NotSupported,
|
537
|
-
'400100': InsufficientFunds, # {"msg":"account.available.amount","code":"400100"}
|
537
|
+
'400100': InsufficientFunds, # {"msg":"account.available.amount","code":"400100"} or {"msg":"Withdrawal amount is below the minimum requirement.","code":"400100"}
|
538
538
|
'400200': InvalidOrder, # {"code":"400200","msg":"Forbidden to place an order"}
|
539
539
|
'400350': InvalidOrder, # {"code":"400350","msg":"Upper limit for holding: 10,000USDT, you can still buy 10,000USDT worth of coin."}
|
540
540
|
'400370': InvalidOrder, # {"code":"400370","msg":"Max. price: 0.02500000000000000000"}
|
@@ -1159,8 +1159,10 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1159
1159
|
# "chains":[
|
1160
1160
|
# {
|
1161
1161
|
# "chainName":"ERC20",
|
1162
|
-
# "
|
1162
|
+
# "chainId": "eth"
|
1163
1163
|
# "withdrawalMinSize":"2999",
|
1164
|
+
# "depositMinSize":null,
|
1165
|
+
# "withdrawFeeRate":"0",
|
1164
1166
|
# "withdrawalMinFee":"2999",
|
1165
1167
|
# "isWithdrawEnabled":false,
|
1166
1168
|
# "isDepositEnabled":false,
|
@@ -1263,7 +1265,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1263
1265
|
'max': None,
|
1264
1266
|
},
|
1265
1267
|
'deposit': {
|
1266
|
-
'min': self.safe_number(
|
1268
|
+
'min': self.safe_number(chain, 'depositMinSize'),
|
1267
1269
|
'max': None,
|
1268
1270
|
},
|
1269
1271
|
},
|
@@ -3020,7 +3022,6 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3020
3022
|
request = {
|
3021
3023
|
'currency': currency['id'],
|
3022
3024
|
'address': address,
|
3023
|
-
'amount': amount,
|
3024
3025
|
# 'memo': tag,
|
3025
3026
|
# 'isInner': False, # internal transfer or external withdrawal
|
3026
3027
|
# 'remark': 'optional',
|
@@ -3032,6 +3033,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3032
3033
|
networkCode, params = self.handle_network_code_and_params(params)
|
3033
3034
|
if networkCode is not None:
|
3034
3035
|
request['chain'] = self.network_code_to_id(networkCode).lower()
|
3036
|
+
await self.load_currency_precision(currency, networkCode)
|
3037
|
+
request['amount'] = self.currency_to_precision(code, amount, networkCode)
|
3035
3038
|
includeFee = None
|
3036
3039
|
includeFee, params = self.handle_option_and_params(params, 'withdraw', 'includeFee', False)
|
3037
3040
|
if includeFee:
|
@@ -3050,6 +3053,51 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3050
3053
|
data = self.safe_dict(response, 'data', {})
|
3051
3054
|
return self.parse_transaction(data, currency)
|
3052
3055
|
|
3056
|
+
async def load_currency_precision(self, currency, networkCode: Str = None):
|
3057
|
+
# might not have network specific precisions defined in fetchCurrencies(because of webapi failure)
|
3058
|
+
# we should check and refetch precision once-per-instance for that specific currency & network
|
3059
|
+
# so avoids thorwing exceptions and burden to users
|
3060
|
+
# Note: self needs to be executed only if networkCode was provided
|
3061
|
+
if networkCode is not None:
|
3062
|
+
networks = currency['networks']
|
3063
|
+
network = self.safe_dict(networks, networkCode)
|
3064
|
+
if self.safe_number(network, 'precision') is not None:
|
3065
|
+
# if precision exists, no need to refetch
|
3066
|
+
return
|
3067
|
+
# otherwise try to fetch and store in instance
|
3068
|
+
request = {
|
3069
|
+
'currency': currency['id'],
|
3070
|
+
'chain': self.network_code_to_id(networkCode).lower(),
|
3071
|
+
}
|
3072
|
+
response = await self.privateGetWithdrawalsQuotas(request)
|
3073
|
+
#
|
3074
|
+
# {
|
3075
|
+
# "code": "200000",
|
3076
|
+
# "data": {
|
3077
|
+
# "currency": "USDT",
|
3078
|
+
# "limitBTCAmount": "14.24094850",
|
3079
|
+
# "usedBTCAmount": "0.00000000",
|
3080
|
+
# "quotaCurrency": "USDT",
|
3081
|
+
# "limitQuotaCurrencyAmount": "999999.00000000",
|
3082
|
+
# "usedQuotaCurrencyAmount": "0",
|
3083
|
+
# "remainAmount": "999999.0000",
|
3084
|
+
# "availableAmount": "10.77545071",
|
3085
|
+
# "withdrawMinFee": "1",
|
3086
|
+
# "innerWithdrawMinFee": "0",
|
3087
|
+
# "withdrawMinSize": "10",
|
3088
|
+
# "isWithdrawEnabled": True,
|
3089
|
+
# "precision": 4,
|
3090
|
+
# "chain": "EOS",
|
3091
|
+
# "reason": null,
|
3092
|
+
# "lockedAmount": "0"
|
3093
|
+
# }
|
3094
|
+
# }
|
3095
|
+
#
|
3096
|
+
data = self.safe_dict(response, 'data', {})
|
3097
|
+
precision = self.parse_number(self.parse_precision(self.safe_string(data, 'precision')))
|
3098
|
+
code = currency['code']
|
3099
|
+
self.currencies[code]['networks'][networkCode]['precision'] = precision
|
3100
|
+
|
3053
3101
|
def parse_transaction_status(self, status):
|
3054
3102
|
statuses = {
|
3055
3103
|
'SUCCESS': 'ok',
|