ccxt 4.3.5__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.
Files changed (48) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/binance.py +1 -0
  3. ccxt/abstract/binancecoinm.py +1 -0
  4. ccxt/abstract/binanceus.py +1 -0
  5. ccxt/abstract/binanceusdm.py +1 -0
  6. ccxt/abstract/bingx.py +1 -0
  7. ccxt/abstract/woo.py +1 -0
  8. ccxt/async_support/__init__.py +1 -1
  9. ccxt/async_support/base/exchange.py +4 -1
  10. ccxt/async_support/binance.py +2 -0
  11. ccxt/async_support/bingx.py +40 -0
  12. ccxt/async_support/bitmex.py +22 -0
  13. ccxt/async_support/bybit.py +81 -1
  14. ccxt/async_support/coinbase.py +4 -4
  15. ccxt/async_support/coinex.py +29 -32
  16. ccxt/async_support/cryptocom.py +30 -1
  17. ccxt/async_support/htx.py +26 -0
  18. ccxt/async_support/hyperliquid.py +37 -0
  19. ccxt/async_support/kraken.py +27 -0
  20. ccxt/async_support/krakenfutures.py +26 -0
  21. ccxt/async_support/kucoinfutures.py +2 -2
  22. ccxt/async_support/okx.py +104 -1
  23. ccxt/async_support/whitebit.py +37 -0
  24. ccxt/async_support/woo.py +27 -0
  25. ccxt/base/exchange.py +4 -1
  26. ccxt/binance.py +2 -0
  27. ccxt/bingx.py +40 -0
  28. ccxt/bitmex.py +22 -0
  29. ccxt/bybit.py +81 -1
  30. ccxt/coinbase.py +4 -4
  31. ccxt/coinex.py +29 -32
  32. ccxt/cryptocom.py +30 -1
  33. ccxt/htx.py +26 -0
  34. ccxt/hyperliquid.py +37 -0
  35. ccxt/kraken.py +27 -0
  36. ccxt/krakenfutures.py +26 -0
  37. ccxt/kucoinfutures.py +2 -2
  38. ccxt/okx.py +104 -1
  39. ccxt/pro/__init__.py +1 -1
  40. ccxt/pro/bitget.py +1 -1
  41. ccxt/test/test_async.py +2 -0
  42. ccxt/test/test_sync.py +2 -0
  43. ccxt/whitebit.py +37 -0
  44. ccxt/woo.py +27 -0
  45. {ccxt-4.3.5.dist-info → ccxt-4.3.6.dist-info}/METADATA +4 -4
  46. {ccxt-4.3.5.dist-info → ccxt-4.3.6.dist-info}/RECORD +48 -48
  47. {ccxt-4.3.5.dist-info → ccxt-4.3.6.dist-info}/WHEEL +0 -0
  48. {ccxt-4.3.5.dist-info → ccxt-4.3.6.dist-info}/top_level.txt +0 -0
@@ -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
@@ -2093,8 +2093,8 @@ class kucoinfutures(kucoin, ImplicitAPI):
2093
2093
  # symbol(str) [optional] Symbol of the contract
2094
2094
  # side(str) [optional] buy or sell
2095
2095
  # type(str) [optional] limit, market, limit_stop or market_stop
2096
- # startAt(long) [optional] Start time(milisecond)
2097
- # endAt(long) [optional] End time(milisecond)
2096
+ # startAt(long) [optional] Start time(millisecond)
2097
+ # endAt(long) [optional] End time(millisecond)
2098
2098
  }
2099
2099
  market = None
2100
2100
  if symbol is not None:
ccxt/async_support/okx.py CHANGED
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.okx import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- from ccxt.base.types import Account, Balances, Conversion, Currencies, Currency, Greeks, Int, Leverage, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
10
+ from ccxt.base.types import Account, Balances, Conversion, Currencies, Currency, Greeks, Int, Leverage, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
11
11
  from typing import List
12
12
  from typing import Any
13
13
  from ccxt.base.errors import ExchangeError
@@ -55,8 +55,10 @@ class okx(Exchange, ImplicitAPI):
55
55
  'option': True,
56
56
  'addMargin': True,
57
57
  'cancelAllOrders': False,
58
+ 'cancelAllOrdersAfter': True,
58
59
  'cancelOrder': True,
59
60
  'cancelOrders': True,
61
+ 'cancelOrdersForSymbols': True,
60
62
  'closeAllPositions': False,
61
63
  'closePosition': True,
62
64
  'createConvertTrade': True,
@@ -3084,6 +3086,107 @@ class okx(Exchange, ImplicitAPI):
3084
3086
  ordersData = self.safe_list(response, 'data', [])
3085
3087
  return self.parse_orders(ordersData, market, None, None, params)
3086
3088
 
3089
+ async def cancel_orders_for_symbols(self, orders: List[CancellationRequest], params={}):
3090
+ """
3091
+ cancel multiple orders for multiple symbols
3092
+ :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-multiple-orders
3093
+ :see: https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-cancel-algo-order
3094
+ :param CancellationRequest[] orders: each order should contain the parameters required by cancelOrder namely id and symbol
3095
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3096
+ :param boolean [params.trigger]: whether the order is a stop/trigger order
3097
+ :param boolean [params.trailing]: set to True if you want to cancel trailing orders
3098
+ :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
3099
+ """
3100
+ await self.load_markets()
3101
+ request = []
3102
+ options = self.safe_dict(self.options, 'cancelOrders', {})
3103
+ defaultMethod = self.safe_string(options, 'method', 'privatePostTradeCancelBatchOrders')
3104
+ method = self.safe_string(params, 'method', defaultMethod)
3105
+ stop = self.safe_bool_2(params, 'stop', 'trigger')
3106
+ trailing = self.safe_bool(params, 'trailing', False)
3107
+ isStopOrTrailing = stop or trailing
3108
+ if isStopOrTrailing:
3109
+ method = 'privatePostTradeCancelAlgos'
3110
+ for i in range(0, len(orders)):
3111
+ order = orders[i]
3112
+ id = self.safe_string(order, 'id')
3113
+ clientOrderId = self.safe_string_2(order, 'clOrdId', 'clientOrderId')
3114
+ symbol = self.safe_string(order, 'symbol')
3115
+ market = self.market(symbol)
3116
+ idKey = 'ordId'
3117
+ if isStopOrTrailing:
3118
+ idKey = 'algoId'
3119
+ elif clientOrderId is not None:
3120
+ idKey = 'clOrdId'
3121
+ requestItem = {
3122
+ 'instId': market['id'],
3123
+ }
3124
+ requestItem[idKey] = clientOrderId if (clientOrderId is not None) else id
3125
+ request.append(requestItem)
3126
+ response = None
3127
+ if method == 'privatePostTradeCancelAlgos':
3128
+ response = await self.privatePostTradeCancelAlgos(request) # * dont self.extend with params, otherwise ARRAY will be turned into OBJECT
3129
+ else:
3130
+ response = await self.privatePostTradeCancelBatchOrders(request) # * dont self.extend with params, otherwise ARRAY will be turned into OBJECT
3131
+ #
3132
+ # {
3133
+ # "code": "0",
3134
+ # "data": [
3135
+ # {
3136
+ # "clOrdId": "e123456789ec4dBC1123456ba123b45e",
3137
+ # "ordId": "405071912345641543",
3138
+ # "sCode": "0",
3139
+ # "sMsg": ""
3140
+ # },
3141
+ # ...
3142
+ # ],
3143
+ # "msg": ""
3144
+ # }
3145
+ #
3146
+ # Algo order
3147
+ #
3148
+ # {
3149
+ # "code": "0",
3150
+ # "data": [
3151
+ # {
3152
+ # "algoId": "431375349042380800",
3153
+ # "sCode": "0",
3154
+ # "sMsg": ""
3155
+ # }
3156
+ # ],
3157
+ # "msg": ""
3158
+ # }
3159
+ #
3160
+ ordersData = self.safe_list(response, 'data', [])
3161
+ return self.parse_orders(ordersData, None, None, None, params)
3162
+
3163
+ async def cancel_all_orders_after(self, timeout: Int, params={}):
3164
+ """
3165
+ dead man's switch, cancel all orders after the given timeout
3166
+ :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-all-after
3167
+ :param number timeout: time in milliseconds, 0 represents cancel the timer
3168
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3169
+ :returns dict: the api result
3170
+ """
3171
+ await self.load_markets()
3172
+ request: dict = {
3173
+ 'timeOut': self.parse_to_int(timeout / 1000) if (timeout > 0) else 0,
3174
+ }
3175
+ response = await self.privatePostTradeCancelAllAfter(self.extend(request, params))
3176
+ #
3177
+ # {
3178
+ # "code":"0",
3179
+ # "msg":"",
3180
+ # "data":[
3181
+ # {
3182
+ # "triggerTime":"1587971460",
3183
+ # "ts":"1587971400"
3184
+ # }
3185
+ # ]
3186
+ # }
3187
+ #
3188
+ return response
3189
+
3087
3190
  def parse_order_status(self, status):
3088
3191
  statuses = {
3089
3192
  'canceled': 'canceled',
@@ -42,6 +42,7 @@ class whitebit(Exchange, ImplicitAPI):
42
42
  'future': False,
43
43
  'option': False,
44
44
  'cancelAllOrders': True,
45
+ 'cancelAllOrdersAfter': True,
45
46
  'cancelOrder': True,
46
47
  'cancelOrders': False,
47
48
  'createOrder': True,
@@ -1332,6 +1333,42 @@ class whitebit(Exchange, ImplicitAPI):
1332
1333
  #
1333
1334
  return response
1334
1335
 
1336
+ async def cancel_all_orders_after(self, timeout: Int, params={}):
1337
+ """
1338
+ dead man's switch, cancel all orders after the given timeout
1339
+ :see: https://docs.whitebit.com/private/http-trade-v4/#sync-kill-switch-timer
1340
+ :param number timeout: time in milliseconds, 0 represents cancel the timer
1341
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1342
+ :param str [params.types]: Order types value. Example: "spot", "margin", "futures" or None
1343
+ :param str [params.symbol]: symbol unified symbol of the market the order was made in
1344
+ :returns dict: the api result
1345
+ """
1346
+ await self.load_markets()
1347
+ symbol = self.safe_string(params, 'symbol')
1348
+ if symbol is None:
1349
+ raise ArgumentsRequired(self.id + ' cancelAllOrdersAfter() requires a symbol argument in params')
1350
+ market = self.market(symbol)
1351
+ params = self.omit(params, 'symbol')
1352
+ isBiggerThanZero = (timeout > 0)
1353
+ request: dict = {
1354
+ 'market': market['id'],
1355
+ # 'timeout': self.number_to_string(timeout / 1000) if (timeout > 0) else null,
1356
+ }
1357
+ if isBiggerThanZero:
1358
+ request['timeout'] = self.number_to_string(timeout / 1000)
1359
+ else:
1360
+ request['timeout'] = 'null'
1361
+ response = await self.v4PrivatePostOrderKillSwitch(self.extend(request, params))
1362
+ #
1363
+ # {
1364
+ # "market": "BTC_USDT", # currency market,
1365
+ # "startTime": 1662478154, # now timestamp,
1366
+ # "cancellationTime": 1662478154, # now + timer_value,
1367
+ # "types": ["spot", "margin"]
1368
+ # }
1369
+ #
1370
+ return response
1371
+
1335
1372
  def parse_balance(self, response) -> Balances:
1336
1373
  balanceKeys = list(response.keys())
1337
1374
  result = {}
ccxt/async_support/woo.py CHANGED
@@ -41,6 +41,7 @@ class woo(Exchange, ImplicitAPI):
41
41
  'option': False,
42
42
  'addMargin': False,
43
43
  'cancelAllOrders': True,
44
+ 'cancelAllOrdersAfter': True,
44
45
  'cancelOrder': True,
45
46
  'cancelWithdraw': False, # exchange have that endpoint disabled atm, but was once implemented in ccxt per old docs: https://kronosresearch.github.io/wootrade-documents/#cancel-withdraw-request
46
47
  'closeAllPositions': False,
@@ -208,6 +209,7 @@ class woo(Exchange, ImplicitAPI):
208
209
  },
209
210
  'post': {
210
211
  'order': 5, # 2 requests per 1 second per symbol
212
+ 'order/cancel_all_after': 1,
211
213
  'asset/main_sub_transfer': 30, # 20 requests per 60 seconds
212
214
  'asset/ltv': 30,
213
215
  'asset/withdraw': 30, # implemented in ccxt, disabled on the exchange side https://kronosresearch.github.io/wootrade-documents/#token-withdraw
@@ -1203,6 +1205,31 @@ class woo(Exchange, ImplicitAPI):
1203
1205
  #
1204
1206
  return response
1205
1207
 
1208
+ async def cancel_all_orders_after(self, timeout: Int, params={}):
1209
+ """
1210
+ dead man's switch, cancel all orders after the given timeout
1211
+ :see: https://docs.woo.org/#cancel-all-after
1212
+ :param number timeout: time in milliseconds, 0 represents cancel the timer
1213
+ :param boolean activated: countdown
1214
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1215
+ :returns dict: the api result
1216
+ """
1217
+ await self.load_markets()
1218
+ request: dict = {
1219
+ 'trigger_after': timeout if (timeout > 0) else 0,
1220
+ }
1221
+ response = await self.v1PrivatePostOrderCancelAllAfter(self.extend(request, params))
1222
+ #
1223
+ # {
1224
+ # "success": True,
1225
+ # "data": {
1226
+ # "expected_trigger_time": 1711534302938
1227
+ # },
1228
+ # "timestamp": 1711534302943
1229
+ # }
1230
+ #
1231
+ return response
1232
+
1206
1233
  async def fetch_order(self, id: str, symbol: Str = None, params={}):
1207
1234
  """
1208
1235
  :see: https://docs.woo.org/#get-algo-order
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.5'
7
+ __version__ = '4.3.6'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -4494,6 +4494,9 @@ class Exchange(object):
4494
4494
  def cancel_all_orders(self, symbol: Str = None, params={}):
4495
4495
  raise NotSupported(self.id + ' cancelAllOrders() is not supported yet')
4496
4496
 
4497
+ def cancel_all_orders_after(self, timeout: Int, params={}):
4498
+ raise NotSupported(self.id + ' cancelAllOrdersAfter() is not supported yet')
4499
+
4497
4500
  def cancel_orders_for_symbols(self, orders: List[CancellationRequest], params={}):
4498
4501
  raise NotSupported(self.id + ' cancelOrdersForSymbols() is not supported yet')
4499
4502
 
ccxt/binance.py CHANGED
@@ -343,6 +343,7 @@ class binance(Exchange, ImplicitAPI):
343
343
  'capital/deposit/subAddress': 0.1,
344
344
  'capital/deposit/subHisrec': 0.1,
345
345
  'capital/withdraw/history': 1800, # Weight(IP): 18000 => cost = 0.1 * 18000 = 1800
346
+ 'capital/withdraw/address/list': 10,
346
347
  'capital/contract/convertible-coins': 4.0002, # Weight(UID): 600 => cost = 0.006667 * 600 = 4.0002
347
348
  'convert/tradeFlow': 20.001, # Weight(UID): 3000 => cost = 0.006667 * 3000 = 20.001
348
349
  'convert/exchangeInfo': 50,
@@ -3987,6 +3988,7 @@ class binance(Exchange, ImplicitAPI):
3987
3988
  :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
3988
3989
  :param dict [params]: extra parameters specific to the exchange API endpoint
3989
3990
  :param str [params.subType]: "linear" or "inverse"
3991
+ :param str [params.type]: 'spot', 'option', use params["subType"] for swap and future markets
3990
3992
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
3991
3993
  """
3992
3994
  self.load_markets()
ccxt/bingx.py CHANGED
@@ -46,6 +46,7 @@ class bingx(Exchange, ImplicitAPI):
46
46
  'option': False,
47
47
  'addMargin': True,
48
48
  'cancelAllOrders': True,
49
+ 'cancelAllOrdersAfter': True,
49
50
  'cancelOrder': True,
50
51
  'cancelOrders': True,
51
52
  'closeAllPositions': True,
@@ -242,6 +243,7 @@ class bingx(Exchange, ImplicitAPI):
242
243
  'trade/order': 3,
243
244
  'trade/batchOrders': 3,
244
245
  'trade/closeAllPositions': 3,
246
+ 'trade/cancelAllAfter': 3,
245
247
  'trade/marginType': 3,
246
248
  'trade/leverage': 3,
247
249
  'trade/positionMargin': 3,
@@ -2581,6 +2583,44 @@ class bingx(Exchange, ImplicitAPI):
2581
2583
  #
2582
2584
  return response
2583
2585
 
2586
+ def cancel_all_orders_after(self, timeout: Int, params={}):
2587
+ """
2588
+ dead man's switch, cancel all orders after the given timeout
2589
+ :see: https://bingx-api.github.io/docs/#/en-us/spot/trade-api.html#Cancel%20all%20orders%20in%20countdown
2590
+ :see: https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Cancel%20all%20orders%20in%20countdown
2591
+ :param number timeout: time in milliseconds, 0 represents cancel the timer
2592
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2593
+ :param str [params.type]: spot or swap market
2594
+ :returns dict: the api result
2595
+ """
2596
+ self.load_markets()
2597
+ isActive = (timeout > 0)
2598
+ request: dict = {
2599
+ 'type': 'ACTIVATE' if (isActive) else 'CLOSE',
2600
+ 'timeOut': (self.parse_to_int(timeout / 1000)) if (isActive) else 0,
2601
+ }
2602
+ response = None
2603
+ type = None
2604
+ type, params = self.handle_market_type_and_params('cancelAllOrdersAfter', None, params)
2605
+ if type == 'spot':
2606
+ response = self.spotV1PrivatePostTradeCancelAllAfter(self.extend(request, params))
2607
+ elif type == 'swap':
2608
+ response = self.swapV2PrivatePostTradeCancelAllAfter(self.extend(request, params))
2609
+ else:
2610
+ raise NotSupported(self.id + ' cancelAllOrdersAfter() is not supported for ' + type + ' markets')
2611
+ #
2612
+ # {
2613
+ # code: '0',
2614
+ # msg: '',
2615
+ # data: {
2616
+ # triggerTime: '1712645434',
2617
+ # status: 'ACTIVATED',
2618
+ # 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'
2619
+ # }
2620
+ # }
2621
+ #
2622
+ return response
2623
+
2584
2624
  def fetch_order(self, id: str, symbol: Str = None, params={}):
2585
2625
  """
2586
2626
  fetches information on an order made by the user
ccxt/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
+ 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
+ self.load_markets()
1992
+ request: dict = {
1993
+ 'timeout': self.parse_to_int(timeout / 1000) if (timeout > 0) else 0,
1994
+ }
1995
+ response = 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
  def fetch_leverages(self, symbols: List[str] = None, params={}) -> Leverages:
1983
2005
  """
1984
2006
  fetch the set leverage for all contract markets
ccxt/bybit.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.bybit import ImplicitAPI
8
8
  import hashlib
9
- 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
9
+ 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
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -49,6 +49,8 @@ class bybit(Exchange, ImplicitAPI):
49
49
  'borrowCrossMargin': True,
50
50
  'cancelAllOrders': True,
51
51
  'cancelOrder': True,
52
+ 'cancelOrders': True,
53
+ 'cancelOrdersForSymbols': True,
52
54
  'closeAllPositions': False,
53
55
  'closePosition': False,
54
56
  'createMarketBuyOrderWithCost': True,
@@ -4088,6 +4090,84 @@ class bybit(Exchange, ImplicitAPI):
4088
4090
  row = self.safe_list(result, 'list', [])
4089
4091
  return self.parse_orders(row, market)
4090
4092
 
4093
+ def cancel_orders_for_symbols(self, orders: List[CancellationRequest], params={}):
4094
+ """
4095
+ cancel multiple orders for multiple symbols
4096
+ :see: https://bybit-exchange.github.io/docs/v5/order/batch-cancel
4097
+ :param str[] ids: order ids
4098
+ :param str symbol: unified symbol of the market the order was made in
4099
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4100
+ :param str[] [params.clientOrderIds]: client order ids
4101
+ :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4102
+ """
4103
+ self.load_markets()
4104
+ ordersRequests = []
4105
+ category = None
4106
+ for i in range(0, len(orders)):
4107
+ order = orders[i]
4108
+ symbol = self.safe_string(order, 'symbol')
4109
+ market = self.market(symbol)
4110
+ currentCategory = None
4111
+ currentCategory, params = self.get_bybit_type('cancelOrders', market, params)
4112
+ if currentCategory == 'inverse':
4113
+ raise NotSupported(self.id + ' cancelOrdersForSymbols does not allow inverse orders')
4114
+ if (category is not None) and (category != currentCategory):
4115
+ raise ExchangeError(self.id + ' cancelOrdersForSymbols requires all orders to be of the same category(linear, spot or option))')
4116
+ category = currentCategory
4117
+ id = self.safe_string(order, 'id')
4118
+ clientOrderId = self.safe_string(order, 'clientOrderId')
4119
+ idKey = 'orderId'
4120
+ if clientOrderId is not None:
4121
+ idKey = 'orderLinkId'
4122
+ orderItem = {
4123
+ 'symbol': market['id'],
4124
+ }
4125
+ orderItem[idKey] = id if (idKey == 'orderId') else clientOrderId
4126
+ ordersRequests.append(orderItem)
4127
+ request = {
4128
+ 'category': category,
4129
+ 'request': ordersRequests,
4130
+ }
4131
+ response = self.privatePostV5OrderCancelBatch(self.extend(request, params))
4132
+ #
4133
+ # {
4134
+ # "retCode": "0",
4135
+ # "retMsg": "OK",
4136
+ # "result": {
4137
+ # "list": [
4138
+ # {
4139
+ # "category": "spot",
4140
+ # "symbol": "BTCUSDT",
4141
+ # "orderId": "1636282505818800896",
4142
+ # "orderLinkId": "1636282505818800897"
4143
+ # },
4144
+ # {
4145
+ # "category": "spot",
4146
+ # "symbol": "BTCUSDT",
4147
+ # "orderId": "1636282505818800898",
4148
+ # "orderLinkId": "1636282505818800899"
4149
+ # }
4150
+ # ]
4151
+ # },
4152
+ # "retExtInfo": {
4153
+ # "list": [
4154
+ # {
4155
+ # "code": "0",
4156
+ # "msg": "OK"
4157
+ # },
4158
+ # {
4159
+ # "code": "0",
4160
+ # "msg": "OK"
4161
+ # }
4162
+ # ]
4163
+ # },
4164
+ # "time": "1709796158501"
4165
+ # }
4166
+ #
4167
+ result = self.safe_dict(response, 'result', {})
4168
+ row = self.safe_list(result, 'list', [])
4169
+ return self.parse_orders(row, None)
4170
+
4091
4171
  def cancel_all_usdc_orders(self, symbol: Str = None, params={}):
4092
4172
  if symbol is None:
4093
4173
  raise ArgumentsRequired(self.id + ' cancelAllUsdcOrders() requires a symbol argument')
ccxt/coinbase.py CHANGED
@@ -3244,11 +3244,11 @@ class coinbase(Exchange, ImplicitAPI):
3244
3244
  now = str(self.seconds())
3245
3245
  sinceString = Precise.string_sub(now, str(requestedDuration))
3246
3246
  request['start'] = sinceString
3247
- endString = self.number_to_string(until)
3248
- if until is None:
3247
+ if until is not None:
3248
+ request['end'] = self.number_to_string(self.parse_to_int(until / 1000))
3249
+ else:
3249
3250
  # 300 candles max
3250
- endString = Precise.string_add(sinceString, str(requestedDuration))
3251
- request['end'] = endString
3251
+ request['end'] = Precise.string_add(sinceString, str(requestedDuration))
3252
3252
  response = self.v3PrivateGetBrokerageProductsProductIdCandles(self.extend(request, params))
3253
3253
  #
3254
3254
  # {
ccxt/coinex.py CHANGED
@@ -1115,14 +1115,13 @@ class coinex(Exchange, ImplicitAPI):
1115
1115
  #
1116
1116
  # Spot and Swap fetchTrades(public)
1117
1117
  #
1118
- # {
1119
- # "id": 2611511379,
1120
- # "type": "buy",
1121
- # "price": "192.63",
1122
- # "amount": "0.02266931",
1123
- # "date": 1638990110,
1124
- # "date_ms": 1638990110518
1125
- # },
1118
+ # {
1119
+ # "amount": "0.00049432",
1120
+ # "created_at": 1713849825667,
1121
+ # "deal_id": 4137517302,
1122
+ # "price": "66251",
1123
+ # "side": "buy"
1124
+ # }
1126
1125
  #
1127
1126
  # Spot and Margin fetchMyTrades(private)
1128
1127
  #
@@ -1176,8 +1175,8 @@ class coinex(Exchange, ImplicitAPI):
1176
1175
  #
1177
1176
  timestamp = self.safe_timestamp_2(trade, 'create_time', 'time')
1178
1177
  if timestamp is None:
1179
- timestamp = self.safe_integer(trade, 'date_ms')
1180
- tradeId = self.safe_string(trade, 'id')
1178
+ timestamp = self.safe_integer(trade, 'created_at')
1179
+ tradeId = self.safe_string_2(trade, 'id', 'deal_id')
1181
1180
  orderId = self.safe_string(trade, 'order_id')
1182
1181
  priceString = self.safe_string(trade, 'price')
1183
1182
  amountString = self.safe_string(trade, 'amount')
@@ -1209,9 +1208,9 @@ class coinex(Exchange, ImplicitAPI):
1209
1208
  elif rawSide == 2:
1210
1209
  side = 'buy'
1211
1210
  if side is None:
1212
- side = self.safe_string(trade, 'type')
1211
+ side = self.safe_string_2(trade, 'type', 'side')
1213
1212
  else:
1214
- side = self.safe_string(trade, 'type')
1213
+ side = self.safe_string_2(trade, 'type', 'side')
1215
1214
  return self.safe_trade({
1216
1215
  'info': trade,
1217
1216
  'timestamp': timestamp,
@@ -1230,9 +1229,9 @@ class coinex(Exchange, ImplicitAPI):
1230
1229
 
1231
1230
  def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
1232
1231
  """
1233
- get the list of most recent trades for a particular symbol
1234
- :see: https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot001_market005_market_deals
1235
- :see: https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http011_market_deals
1232
+ get the list of the most recent trades for a particular symbol
1233
+ :see: https://docs.coinex.com/api/v2/spot/market/http/list-market-deals
1234
+ :see: https://docs.coinex.com/api/v2/futures/market/http/list-market-deals
1236
1235
  :param str symbol: unified symbol of the market to fetch trades for
1237
1236
  :param int [since]: timestamp in ms of the earliest trade to fetch
1238
1237
  :param int [limit]: the maximum amount of trades to fetch
@@ -1249,26 +1248,25 @@ class coinex(Exchange, ImplicitAPI):
1249
1248
  request['limit'] = limit
1250
1249
  response = None
1251
1250
  if market['swap']:
1252
- response = self.v1PerpetualPublicGetMarketDeals(self.extend(request, params))
1251
+ response = self.v2PublicGetFuturesDeals(self.extend(request, params))
1253
1252
  else:
1254
- response = self.v1PublicGetMarketDeals(self.extend(request, params))
1253
+ response = self.v2PublicGetSpotDeals(self.extend(request, params))
1255
1254
  #
1256
1255
  # Spot and Swap
1257
1256
  #
1258
- # {
1259
- # "code": 0,
1260
- # "data": [
1261
- # {
1262
- # "id": 2611511379,
1263
- # "type": "buy",
1264
- # "price": "192.63",
1265
- # "amount": "0.02266931",
1266
- # "date": 1638990110,
1267
- # "date_ms": 1638990110518
1268
- # },
1269
- # ],
1270
- # "message": "OK"
1271
- # }
1257
+ # {
1258
+ # "code": 0,
1259
+ # "data": [
1260
+ # {
1261
+ # "amount": "0.00049432",
1262
+ # "created_at": 1713849825667,
1263
+ # "deal_id": 4137517302,
1264
+ # "price": "66251",
1265
+ # "side": "buy"
1266
+ # },
1267
+ # ],
1268
+ # "message": "OK"
1269
+ # }
1272
1270
  #
1273
1271
  return self.parse_trades(response['data'], market, since, limit)
1274
1272
 
@@ -4204,7 +4202,6 @@ class coinex(Exchange, ImplicitAPI):
4204
4202
 
4205
4203
  def fetch_funding_rates(self, symbols: Strings = None, params={}):
4206
4204
  """
4207
- * @method
4208
4205
  fetch the current funding rates
4209
4206
  :see: https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http009_market_ticker_all
4210
4207
  :param str[] symbols: unified market symbols