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.
Files changed (55) 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/whitebit.py +22 -1
  8. ccxt/abstract/woo.py +1 -0
  9. ccxt/async_support/__init__.py +1 -1
  10. ccxt/async_support/base/exchange.py +227 -36
  11. ccxt/async_support/binance.py +21 -14
  12. ccxt/async_support/bingx.py +40 -0
  13. ccxt/async_support/bitmex.py +22 -0
  14. ccxt/async_support/bybit.py +81 -1
  15. ccxt/async_support/coinbase.py +4 -4
  16. ccxt/async_support/coinex.py +29 -32
  17. ccxt/async_support/cryptocom.py +30 -1
  18. ccxt/async_support/htx.py +26 -0
  19. ccxt/async_support/hyperliquid.py +37 -0
  20. ccxt/async_support/kraken.py +27 -0
  21. ccxt/async_support/krakenfutures.py +26 -0
  22. ccxt/async_support/kucoin.py +52 -4
  23. ccxt/async_support/kucoinfutures.py +2 -2
  24. ccxt/async_support/okx.py +104 -1
  25. ccxt/async_support/whitebit.py +149 -2
  26. ccxt/async_support/woo.py +27 -0
  27. ccxt/base/exchange.py +233 -4
  28. ccxt/binance.py +21 -14
  29. ccxt/bingx.py +40 -0
  30. ccxt/bitmex.py +22 -0
  31. ccxt/bybit.py +81 -1
  32. ccxt/coinbase.py +4 -4
  33. ccxt/coinex.py +29 -32
  34. ccxt/cryptocom.py +30 -1
  35. ccxt/htx.py +26 -0
  36. ccxt/hyperliquid.py +37 -0
  37. ccxt/kraken.py +27 -0
  38. ccxt/krakenfutures.py +26 -0
  39. ccxt/kucoin.py +52 -4
  40. ccxt/kucoinfutures.py +2 -2
  41. ccxt/okx.py +104 -1
  42. ccxt/pro/__init__.py +1 -1
  43. ccxt/pro/binance.py +410 -73
  44. ccxt/pro/bitget.py +1 -1
  45. ccxt/pro/cex.py +1 -1
  46. ccxt/pro/lbank.py +1 -1
  47. ccxt/pro/woo.py +0 -1
  48. ccxt/test/test_async.py +17 -17
  49. ccxt/test/test_sync.py +17 -17
  50. ccxt/whitebit.py +149 -2
  51. ccxt/woo.py +27 -0
  52. {ccxt-4.3.4.dist-info → ccxt-4.3.6.dist-info}/METADATA +4 -4
  53. {ccxt-4.3.4.dist-info → ccxt-4.3.6.dist-info}/RECORD +55 -55
  54. {ccxt-4.3.4.dist-info → ccxt-4.3.6.dist-info}/WHEEL +0 -0
  55. {ccxt-4.3.4.dist-info → ccxt-4.3.6.dist-info}/top_level.txt +0 -0
ccxt/pro/bitget.py CHANGED
@@ -947,7 +947,7 @@ class bitget(ccxt.async_support.bitget):
947
947
  limit = orders.getLimit(symbol, limit)
948
948
  return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
949
949
 
950
- def handle_order(self, client: Client, message, subscription=None):
950
+ def handle_order(self, client: Client, message):
951
951
  #
952
952
  # spot
953
953
  #
ccxt/pro/cex.py CHANGED
@@ -297,7 +297,7 @@ class cex(ccxt.async_support.cex):
297
297
  return result
298
298
  return self.filter_by_array(self.tickers, 'symbol', symbols)
299
299
 
300
- async def fetch_ticker_ws(self, symbol: str, params={}):
300
+ async def fetch_ticker_ws(self, symbol: str, params={}) -> Ticker:
301
301
  """
302
302
  :see: https://docs.cex.io/#ws-api-ticker-deprecated
303
303
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
ccxt/pro/lbank.py CHANGED
@@ -227,7 +227,7 @@ class lbank(ccxt.async_support.lbank):
227
227
  messageHash = 'ohlcv:' + symbol + ':' + timeframeId
228
228
  client.resolve(stored, messageHash)
229
229
 
230
- async def fetch_ticker_ws(self, symbol, params={}) -> Ticker:
230
+ async def fetch_ticker_ws(self, symbol: str, params={}) -> Ticker:
231
231
  """
232
232
  :see: https://www.lbank.com/en-US/docs/index.html#request-amp-subscription-instruction
233
233
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
ccxt/pro/woo.py CHANGED
@@ -79,7 +79,6 @@ class woo(ccxt.async_support.woo):
79
79
  return newValue
80
80
 
81
81
  async def watch_public(self, messageHash, message):
82
- self.check_required_uid()
83
82
  url = self.urls['api']['ws']['public'] + '/' + self.uid
84
83
  requestId = self.request_id(url)
85
84
  subscribe = {
ccxt/test/test_async.py CHANGED
@@ -278,7 +278,7 @@ class testMainClass(baseMainTestClass):
278
278
  self.load_keys = get_cli_arg_value('--loadKeys')
279
279
  self.ws_tests = get_cli_arg_value('--ws')
280
280
 
281
- async def init(self, exchange_id, symbol_argv):
281
+ async def init(self, exchange_id, symbol_argv, method_argv):
282
282
  self.parse_cli_args()
283
283
  if self.request_tests and self.response_tests:
284
284
  await self.run_static_request_tests(exchange_id, symbol_argv)
@@ -293,13 +293,12 @@ class testMainClass(baseMainTestClass):
293
293
  if self.id_tests:
294
294
  await self.run_broker_id_tests()
295
295
  return
296
- symbol_str = symbol_argv if symbol_argv is not None else 'all'
297
- exchange_object = {
296
+ dump(self.new_line + '' + self.new_line + '' + '[INFO] TESTING ', self.ext, {
298
297
  'exchange': exchange_id,
299
- 'symbol': symbol_str,
298
+ 'symbol': symbol_argv,
299
+ 'method': method_argv,
300
300
  'isWs': self.ws_tests,
301
- }
302
- dump(self.new_line + '' + self.new_line + '' + '[INFO] TESTING ', self.ext, json_stringify(exchange_object), self.new_line)
301
+ }, self.new_line)
303
302
  exchange_args = {
304
303
  'verbose': self.verbose,
305
304
  'debug': self.debug,
@@ -312,25 +311,22 @@ class testMainClass(baseMainTestClass):
312
311
  await self.import_files(exchange)
313
312
  assert len(list(self.test_files.keys())) > 0, 'Test files were not loaded' # ensure test files are found & filled
314
313
  self.expand_settings(exchange)
315
- symbol = self.check_if_specific_test_is_chosen(symbol_argv)
316
- await self.start_test(exchange, symbol)
314
+ self.check_if_specific_test_is_chosen(method_argv)
315
+ await self.start_test(exchange, symbol_argv)
317
316
  exit_script(0) # needed to be explicitly finished for WS tests
318
317
 
319
- def check_if_specific_test_is_chosen(self, symbol_argv):
320
- if symbol_argv is not None:
318
+ def check_if_specific_test_is_chosen(self, method_argv):
319
+ if method_argv is not None:
321
320
  test_file_names = list(self.test_files.keys())
322
- possible_method_names = symbol_argv.split(',') # i.e. `test.ts binance fetchBalance,fetchDeposits`
321
+ possible_method_names = method_argv.split(',') # i.e. `test.ts binance fetchBalance,fetchDeposits`
323
322
  if len(possible_method_names) >= 1:
324
323
  for i in range(0, len(test_file_names)):
325
324
  test_file_name = test_file_names[i]
326
325
  for j in range(0, len(possible_method_names)):
327
326
  method_name = possible_method_names[j]
327
+ method_name = method_name.replace('()', '')
328
328
  if test_file_name == method_name:
329
329
  self.only_specific_tests.append(test_file_name)
330
- # if method names were found, then remove them from symbolArgv
331
- if len(self.only_specific_tests) > 0:
332
- return None
333
- return symbol_argv
334
330
 
335
331
  async def import_files(self, exchange):
336
332
  properties = list(exchange.has.keys())
@@ -500,6 +496,8 @@ class testMainClass(baseMainTestClass):
500
496
  final_skips['datetime'] = final_skips['timestamp']
501
497
  if ('bid' in final_skips) and not ('ask' in final_skips):
502
498
  final_skips['ask'] = final_skips['bid']
499
+ if ('baseVolume' in final_skips) and not ('quoteVolume' in final_skips):
500
+ final_skips['quoteVolume'] = final_skips['baseVolume']
503
501
  return final_skips
504
502
 
505
503
  async def test_safe(self, method_name, exchange, args=[], is_public=False):
@@ -1579,5 +1577,7 @@ class testMainClass(baseMainTestClass):
1579
1577
 
1580
1578
 
1581
1579
  if __name__ == '__main__':
1582
- symbol = argv.symbol if argv.symbol else None
1583
- asyncio.run(testMainClass().init(argv.exchange, symbol))
1580
+ argvSymbol = argv.symbol if argv.symbol and '/' in argv.symbol else None
1581
+ # in python, we check it through "symbol" arg (as opposed to JS/PHP) because argvs were already built above
1582
+ argvMethod = argv.symbol if argv.symbol and '()' in argv.symbol else None
1583
+ asyncio.run(testMainClass().init(argv.exchange, argvSymbol, argvMethod))
ccxt/test/test_sync.py CHANGED
@@ -277,7 +277,7 @@ class testMainClass(baseMainTestClass):
277
277
  self.load_keys = get_cli_arg_value('--loadKeys')
278
278
  self.ws_tests = get_cli_arg_value('--ws')
279
279
 
280
- def init(self, exchange_id, symbol_argv):
280
+ def init(self, exchange_id, symbol_argv, method_argv):
281
281
  self.parse_cli_args()
282
282
  if self.request_tests and self.response_tests:
283
283
  self.run_static_request_tests(exchange_id, symbol_argv)
@@ -292,13 +292,12 @@ class testMainClass(baseMainTestClass):
292
292
  if self.id_tests:
293
293
  self.run_broker_id_tests()
294
294
  return
295
- symbol_str = symbol_argv if symbol_argv is not None else 'all'
296
- exchange_object = {
295
+ dump(self.new_line + '' + self.new_line + '' + '[INFO] TESTING ', self.ext, {
297
296
  'exchange': exchange_id,
298
- 'symbol': symbol_str,
297
+ 'symbol': symbol_argv,
298
+ 'method': method_argv,
299
299
  'isWs': self.ws_tests,
300
- }
301
- dump(self.new_line + '' + self.new_line + '' + '[INFO] TESTING ', self.ext, json_stringify(exchange_object), self.new_line)
300
+ }, self.new_line)
302
301
  exchange_args = {
303
302
  'verbose': self.verbose,
304
303
  'debug': self.debug,
@@ -311,25 +310,22 @@ class testMainClass(baseMainTestClass):
311
310
  self.import_files(exchange)
312
311
  assert len(list(self.test_files.keys())) > 0, 'Test files were not loaded' # ensure test files are found & filled
313
312
  self.expand_settings(exchange)
314
- symbol = self.check_if_specific_test_is_chosen(symbol_argv)
315
- self.start_test(exchange, symbol)
313
+ self.check_if_specific_test_is_chosen(method_argv)
314
+ self.start_test(exchange, symbol_argv)
316
315
  exit_script(0) # needed to be explicitly finished for WS tests
317
316
 
318
- def check_if_specific_test_is_chosen(self, symbol_argv):
319
- if symbol_argv is not None:
317
+ def check_if_specific_test_is_chosen(self, method_argv):
318
+ if method_argv is not None:
320
319
  test_file_names = list(self.test_files.keys())
321
- possible_method_names = symbol_argv.split(',') # i.e. `test.ts binance fetchBalance,fetchDeposits`
320
+ possible_method_names = method_argv.split(',') # i.e. `test.ts binance fetchBalance,fetchDeposits`
322
321
  if len(possible_method_names) >= 1:
323
322
  for i in range(0, len(test_file_names)):
324
323
  test_file_name = test_file_names[i]
325
324
  for j in range(0, len(possible_method_names)):
326
325
  method_name = possible_method_names[j]
326
+ method_name = method_name.replace('()', '')
327
327
  if test_file_name == method_name:
328
328
  self.only_specific_tests.append(test_file_name)
329
- # if method names were found, then remove them from symbolArgv
330
- if len(self.only_specific_tests) > 0:
331
- return None
332
- return symbol_argv
333
329
 
334
330
  def import_files(self, exchange):
335
331
  properties = list(exchange.has.keys())
@@ -499,6 +495,8 @@ class testMainClass(baseMainTestClass):
499
495
  final_skips['datetime'] = final_skips['timestamp']
500
496
  if ('bid' in final_skips) and not ('ask' in final_skips):
501
497
  final_skips['ask'] = final_skips['bid']
498
+ if ('baseVolume' in final_skips) and not ('quoteVolume' in final_skips):
499
+ final_skips['quoteVolume'] = final_skips['baseVolume']
502
500
  return final_skips
503
501
 
504
502
  def test_safe(self, method_name, exchange, args=[], is_public=False):
@@ -1578,5 +1576,7 @@ class testMainClass(baseMainTestClass):
1578
1576
 
1579
1577
 
1580
1578
  if __name__ == '__main__':
1581
- symbol = argv.symbol if argv.symbol else None
1582
- (testMainClass().init(argv.exchange, symbol))
1579
+ argvSymbol = argv.symbol if argv.symbol and '/' in argv.symbol else None
1580
+ # in python, we check it through "symbol" arg (as opposed to JS/PHP) because argvs were already built above
1581
+ argvMethod = argv.symbol if argv.symbol and '()' in argv.symbol else None
1582
+ (testMainClass().init(argv.exchange, argvSymbol, argvMethod))
ccxt/whitebit.py CHANGED
@@ -41,7 +41,8 @@ class whitebit(Exchange, ImplicitAPI):
41
41
  'swap': False,
42
42
  'future': False,
43
43
  'option': False,
44
- 'cancelAllOrders': False,
44
+ 'cancelAllOrders': True,
45
+ 'cancelAllOrdersAfter': True,
45
46
  'cancelOrder': True,
46
47
  'cancelOrders': False,
47
48
  'createOrder': True,
@@ -186,11 +187,13 @@ class whitebit(Exchange, ImplicitAPI):
186
187
  'ping',
187
188
  'markets',
188
189
  'futures',
190
+ 'platform/status',
189
191
  ],
190
192
  },
191
193
  'private': {
192
194
  'post': [
193
195
  'collateral-account/balance',
196
+ 'collateral-account/balance-summary',
194
197
  'collateral-account/positions/history',
195
198
  'collateral-account/leverage',
196
199
  'collateral-account/positions/open',
@@ -207,21 +210,40 @@ class whitebit(Exchange, ImplicitAPI):
207
210
  'main-account/withdraw',
208
211
  'main-account/withdraw-pay',
209
212
  'main-account/transfer',
213
+ 'main-account/smart/plans',
214
+ 'main-account/smart/investment',
215
+ 'main-account/smart/investment/close',
216
+ 'main-account/smart/investments',
217
+ 'main-account/fee',
218
+ 'main-account/smart/interest-payment-history',
210
219
  'trade-account/balance',
211
220
  'trade-account/executed-history',
212
221
  'trade-account/order',
213
222
  'trade-account/order/history',
214
223
  'order/collateral/limit',
215
224
  'order/collateral/market',
216
- 'order/collateral/trigger_market',
225
+ 'order/collateral/stop-limit',
226
+ 'order/collateral/trigger-market',
217
227
  'order/new',
218
228
  'order/market',
219
229
  'order/stock_market',
220
230
  'order/stop_limit',
221
231
  'order/stop_market',
222
232
  'order/cancel',
233
+ 'order/cancel/all',
234
+ 'order/kill-switch',
235
+ 'order/kill-switch/status',
236
+ 'order/bulk',
237
+ 'order/modify',
223
238
  'orders',
239
+ 'oco-orders',
240
+ 'order/collateral/oco',
241
+ 'order/oco-cancel',
242
+ 'order/oto-cancel',
224
243
  'profile/websocket_token',
244
+ 'convert/estimate',
245
+ 'convert/confirm',
246
+ 'convert/history',
225
247
  ],
226
248
  },
227
249
  },
@@ -1203,6 +1225,58 @@ class whitebit(Exchange, ImplicitAPI):
1203
1225
  response = self.v4PrivatePostOrderStockMarket(self.extend(request, params))
1204
1226
  return self.parse_order(response)
1205
1227
 
1228
+ def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
1229
+ """
1230
+ edit a trade order
1231
+ :see: https://docs.whitebit.com/private/http-trade-v4/#modify-order
1232
+ :param str id: cancel order id
1233
+ :param str symbol: unified symbol of the market to create an order in
1234
+ :param str type: 'market' or 'limit'
1235
+ :param str side: 'buy' or 'sell'
1236
+ :param float amount: how much of currency you want to trade in units of base currency
1237
+ :param float price: the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
1238
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1239
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1240
+ """
1241
+ if id is None:
1242
+ raise ArgumentsRequired(self.id + ' editOrder() requires a id argument')
1243
+ if symbol is None:
1244
+ raise ArgumentsRequired(self.id + ' editOrder() requires a symbol argument')
1245
+ self.load_markets()
1246
+ market = self.market(symbol)
1247
+ request = {
1248
+ 'orderId': id,
1249
+ 'market': market['id'],
1250
+ }
1251
+ clientOrderId = self.safe_string_2(params, 'clOrdId', 'clientOrderId')
1252
+ if clientOrderId is not None:
1253
+ # Update clientOrderId of the order
1254
+ request['clientOrderId'] = clientOrderId
1255
+ isLimitOrder = type == 'limit'
1256
+ stopPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'activation_price'])
1257
+ isStopOrder = (stopPrice is not None)
1258
+ params = self.omit(params, ['clOrdId', 'clientOrderId', 'triggerPrice', 'stopPrice'])
1259
+ if isStopOrder:
1260
+ request['activation_price'] = self.price_to_precision(symbol, stopPrice)
1261
+ if isLimitOrder:
1262
+ # stop limit order
1263
+ request['amount'] = self.amount_to_precision(symbol, amount)
1264
+ request['price'] = self.price_to_precision(symbol, price)
1265
+ else:
1266
+ # stop market order
1267
+ if side == 'buy':
1268
+ # Use total parameter instead of amount for modify buy stop market order
1269
+ request['total'] = self.amount_to_precision(symbol, amount)
1270
+ else:
1271
+ request['amount'] = self.amount_to_precision(symbol, amount)
1272
+ else:
1273
+ request['amount'] = self.amount_to_precision(symbol, amount)
1274
+ if isLimitOrder:
1275
+ # limit order
1276
+ request['price'] = self.price_to_precision(symbol, price)
1277
+ response = self.v4PrivatePostOrderModify(self.extend(request, params))
1278
+ return self.parse_order(response)
1279
+
1206
1280
  def cancel_order(self, id: str, symbol: Str = None, params={}):
1207
1281
  """
1208
1282
  cancels an open order
@@ -1222,6 +1296,79 @@ class whitebit(Exchange, ImplicitAPI):
1222
1296
  }
1223
1297
  return self.v4PrivatePostOrderCancel(self.extend(request, params))
1224
1298
 
1299
+ def cancel_all_orders(self, symbol: Str = None, params={}):
1300
+ """
1301
+ cancel all open orders
1302
+ :see: https://docs.whitebit.com/private/http-trade-v4/#cancel-all-orders
1303
+ :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
1304
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1305
+ :param str [params.type]: market type, ['swap', 'spot']
1306
+ :param boolean [params.isMargin]: cancel all margin orders
1307
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1308
+ """
1309
+ self.load_markets()
1310
+ market = None
1311
+ request = {}
1312
+ if symbol is not None:
1313
+ market = self.market(symbol)
1314
+ request['market'] = market['id']
1315
+ type = None
1316
+ type, params = self.handle_market_type_and_params('cancelAllOrders', market, params)
1317
+ requestType = []
1318
+ if type == 'spot':
1319
+ isMargin = None
1320
+ isMargin, params = self.handle_option_and_params(params, 'cancelAllOrders', 'isMargin', False)
1321
+ if isMargin:
1322
+ requestType.append('margin')
1323
+ else:
1324
+ requestType.append('spot')
1325
+ elif type == 'swap':
1326
+ requestType.append('futures')
1327
+ else:
1328
+ raise NotSupported(self.id + ' cancelAllOrders() does not support ' + type + ' type')
1329
+ request['type'] = requestType
1330
+ response = self.v4PrivatePostOrderCancelAll(self.extend(request, params))
1331
+ #
1332
+ # []
1333
+ #
1334
+ return response
1335
+
1336
+ 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
+ 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 = 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
+
1225
1372
  def parse_balance(self, response) -> Balances:
1226
1373
  balanceKeys = list(response.keys())
1227
1374
  result = {}
ccxt/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
+ 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
+ self.load_markets()
1218
+ request: dict = {
1219
+ 'trigger_after': timeout if (timeout > 0) else 0,
1220
+ }
1221
+ response = 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
  def fetch_order(self, id: str, symbol: Str = None, params={}):
1207
1234
  """
1208
1235
  :see: https://docs.woo.org/#get-algo-order
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ccxt
3
- Version: 4.3.4
3
+ Version: 4.3.6
4
4
  Summary: A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges
5
5
  Home-page: https://ccxt.com
6
6
  Author: Igor Kroitor
@@ -262,13 +262,13 @@ console.log(version, Object.keys(exchanges));
262
262
 
263
263
  All-in-one browser bundle (dependencies included), served from a CDN of your choice:
264
264
 
265
- * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.4/dist/ccxt.browser.js
266
- * unpkg: https://unpkg.com/ccxt@4.3.4/dist/ccxt.browser.js
265
+ * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.6/dist/ccxt.browser.js
266
+ * unpkg: https://unpkg.com/ccxt@4.3.6/dist/ccxt.browser.js
267
267
 
268
268
  CDNs are not updated in real-time and may have delays. Defaulting to the most recent version without specifying the version number is not recommended. Please, keep in mind that we are not responsible for the correct operation of those CDN servers.
269
269
 
270
270
  ```HTML
271
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.4/dist/ccxt.browser.js"></script>
271
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.6/dist/ccxt.browser.js"></script>
272
272
  ```
273
273
 
274
274
  Creates a global `ccxt` object: