ccxt 4.3.1__py2.py3-none-any.whl → 4.3.2__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 CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  # ----------------------------------------------------------------------------
24
24
 
25
- __version__ = '4.3.1'
25
+ __version__ = '4.3.2'
26
26
 
27
27
  # ----------------------------------------------------------------------------
28
28
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.1'
7
+ __version__ = '4.3.2'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.3.1'
5
+ __version__ = '4.3.2'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -25,7 +25,7 @@ from ccxt.async_support.base.throttler import Throttler
25
25
  # -----------------------------------------------------------------------------
26
26
 
27
27
  from ccxt.base.errors import BaseError, BadSymbol, BadRequest, BadResponse, ExchangeError, ExchangeNotAvailable, RequestTimeout, NotSupported, NullResponse, InvalidAddress, RateLimitExceeded
28
- from ccxt.base.types import OrderType, OrderSide, OrderRequest
28
+ from ccxt.base.types import OrderType, OrderSide, OrderRequest, CancellationRequest
29
29
 
30
30
  # -----------------------------------------------------------------------------
31
31
 
@@ -1210,6 +1210,9 @@ class Exchange(BaseExchange):
1210
1210
  async def cancel_all_orders(self, symbol: Str = None, params={}):
1211
1211
  raise NotSupported(self.id + ' cancelAllOrders() is not supported yet')
1212
1212
 
1213
+ async def cancel_orders_for_symbols(self, orders: List[CancellationRequest], params={}):
1214
+ raise NotSupported(self.id + ' cancelOrdersForSymbols() is not supported yet')
1215
+
1213
1216
  async def cancel_all_orders_ws(self, symbol: Str = None, params={}):
1214
1217
  raise NotSupported(self.id + ' cancelAllOrdersWs() is not supported yet')
1215
1218
 
@@ -21,6 +21,7 @@ from ccxt.base.errors import InsufficientFunds
21
21
  from ccxt.base.errors import OrderNotFound
22
22
  from ccxt.base.errors import NotSupported
23
23
  from ccxt.base.errors import DDoSProtection
24
+ from ccxt.base.errors import ExchangeNotAvailable
24
25
  from ccxt.base.decimal_to_precision import DECIMAL_PLACES
25
26
  from ccxt.base.precise import Precise
26
27
 
@@ -398,7 +399,7 @@ class bingx(Exchange, ImplicitAPI):
398
399
  '100400': BadRequest,
399
400
  '100421': BadSymbol, # {"code":100421,"msg":"This pair is currently restricted from API trading","debugMsg":""}
400
401
  '100440': ExchangeError,
401
- '100500': ExchangeError,
402
+ '100500': ExchangeNotAvailable, # {"code":100500,"msg":"The current system is busy, please try again later","debugMsg":""}
402
403
  '100503': ExchangeError,
403
404
  '80001': BadRequest,
404
405
  '80012': InsufficientFunds, # bingx {"code":80012,"msg":"{\"Code\":101253,\"Msg\":\"margin is not enough\"}}
@@ -3718,7 +3719,7 @@ class bingx(Exchange, ImplicitAPI):
3718
3719
  market = None
3719
3720
  if symbol is not None:
3720
3721
  market = self.market(symbol)
3721
- request['symbol'] = symbol
3722
+ request['symbol'] = market['id']
3722
3723
  if since is not None:
3723
3724
  request['startTime'] = since
3724
3725
  if limit is not None:
@@ -8051,6 +8051,8 @@ class bitget(Exchange, ImplicitAPI):
8051
8051
  #
8052
8052
  # spot
8053
8053
  #
8054
+ # {"code":"00000","msg":"success","requestTime":1713294492511,"data":[...]}"
8055
+ #
8054
8056
  # {"status":"fail","err_code":"01001","err_msg":"系统异常,请稍后重试"}
8055
8057
  # {"status":"error","ts":1595594160149,"err_code":"invalid-parameter","err_msg":"invalid size, valid range: [1,2000]"}
8056
8058
  # {"status":"error","ts":1595684716042,"err_code":"invalid-parameter","err_msg":"illegal sign invalid"}
@@ -8072,13 +8074,13 @@ class bitget(Exchange, ImplicitAPI):
8072
8074
  # {"code":"40108","msg":"","requestTime":1595885064600,"data":null}
8073
8075
  # {"order_id":"513468410013679613","client_oid":null,"symbol":"ethusd","result":false,"err_code":"order_no_exist_error","err_msg":"订单不存在!"}
8074
8076
  #
8075
- message = self.safe_string(response, 'err_msg')
8076
- errorCode = self.safe_string_2(response, 'code', 'err_code')
8077
+ message = self.safe_string_2(response, 'err_msg', 'msg')
8077
8078
  feedback = self.id + ' ' + body
8078
- nonEmptyMessage = ((message is not None) and (message != ''))
8079
+ nonEmptyMessage = ((message is not None) and (message != '') and (message != 'success'))
8079
8080
  if nonEmptyMessage:
8080
8081
  self.throw_exactly_matched_exception(self.exceptions['exact'], message, feedback)
8081
8082
  self.throw_broadly_matched_exception(self.exceptions['broad'], message, feedback)
8083
+ errorCode = self.safe_string_2(response, 'code', 'err_code')
8082
8084
  nonZeroErrorCode = (errorCode is not None) and (errorCode != '00000')
8083
8085
  if nonZeroErrorCode:
8084
8086
  self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
@@ -28,9 +28,10 @@ class coinbase(Exchange, ImplicitAPI):
28
28
  def describe(self):
29
29
  return self.deep_extend(super(coinbase, self).describe(), {
30
30
  'id': 'coinbase',
31
- 'name': 'Coinbase',
31
+ 'name': 'Coinbase Advanced',
32
32
  'countries': ['US'],
33
33
  'pro': True,
34
+ 'certified': True,
34
35
  # rate-limits:
35
36
  # ADVANCED API: https://docs.cloud.coinbase.com/advanced-trade-api/docs/rest-api-rate-limits
36
37
  # - max 30 req/second for private data, 10 req/s for public data
@@ -27,7 +27,7 @@ class coinbasepro(Exchange, ImplicitAPI):
27
27
  def describe(self):
28
28
  return self.deep_extend(super(coinbasepro, self).describe(), {
29
29
  'id': 'coinbasepro',
30
- 'name': 'Coinbase Pro',
30
+ 'name': 'Coinbase Pro(Deprecated)',
31
31
  'countries': ['US'],
32
32
  'rateLimit': 100,
33
33
  'userAgent': self.userAgents['chrome'],
@@ -815,65 +815,59 @@ class coinex(Exchange, ImplicitAPI):
815
815
  # Spot fetchTicker, fetchTickers
816
816
  #
817
817
  # {
818
- # "vol": "293.19415130",
819
- # "low": "38200.00",
820
- # "open": "39514.99",
821
- # "high": "39530.00",
822
- # "last": "38649.57",
823
- # "buy": "38640.20",
824
- # "buy_amount": "0.22800000",
825
- # "sell": "38640.21",
826
- # "sell_amount": "0.02828439"
818
+ # "close": "62393.47",
819
+ # "high": "64106.41",
820
+ # "last": "62393.47",
821
+ # "low": "59650.01",
822
+ # "market": "BTCUSDT",
823
+ # "open": "61616.15",
824
+ # "period": 86400,
825
+ # "value": "28711273.4065667262",
826
+ # "volume": "461.76557205",
827
+ # "volume_buy": "11.41506354",
828
+ # "volume_sell": "7.3240169"
827
829
  # }
828
830
  #
829
831
  # Swap fetchTicker, fetchTickers
830
832
  #
831
833
  # {
832
- # "vol": "7714.2175",
833
- # "low": "38200.00",
834
- # "open": "39569.23",
835
- # "high": "39569.23",
836
- # "last": "38681.37",
837
- # "buy": "38681.36",
834
+ # "close": "62480.08",
835
+ # "high": "64100",
836
+ # "index_price": "62443.05",
837
+ # "last": "62480.08",
838
+ # "low": "59600",
839
+ # "mark_price": "62443.05",
840
+ # "market": "BTCUSDT",
841
+ # "open": "61679.98",
838
842
  # "period": 86400,
839
- # "funding_time": 462,
840
- # "position_amount": "296.7552",
841
- # "funding_rate_last": "0.00009395",
842
- # "funding_rate_next": "0.00000649",
843
- # "funding_rate_predict": "-0.00007176",
844
- # "insurance": "16464465.09431942163278132918",
845
- # "sign_price": "38681.93",
846
- # "index_price": "38681.69500000",
847
- # "sell_total": "16.6039",
848
- # "buy_total": "19.8481",
849
- # "buy_amount": "4.6315",
850
- # "sell": "38681.37",
851
- # "sell_amount": "11.4044"
843
+ # "value": "180226025.69791713065326633165",
844
+ # "volume": "2900.2218",
845
+ # "volume_buy": "7.3847",
846
+ # "volume_sell": "6.1249"
852
847
  # }
853
848
  #
854
- timestamp = self.safe_integer(ticker, 'date')
855
- symbol = self.safe_symbol(None, market)
856
- ticker = self.safe_value(ticker, 'ticker', {})
857
- last = self.safe_string(ticker, 'last')
849
+ marketType = 'swap' if ('mark_price' in ticker) else 'spot'
850
+ marketId = self.safe_string(ticker, 'market')
851
+ symbol = self.safe_symbol(marketId, market, None, marketType)
858
852
  return self.safe_ticker({
859
853
  'symbol': symbol,
860
- 'timestamp': timestamp,
861
- 'datetime': self.iso8601(timestamp),
854
+ 'timestamp': None,
855
+ 'datetime': None,
862
856
  'high': self.safe_string(ticker, 'high'),
863
857
  'low': self.safe_string(ticker, 'low'),
864
- 'bid': self.safe_string(ticker, 'buy'),
865
- 'bidVolume': self.safe_string(ticker, 'buy_amount'),
866
- 'ask': self.safe_string(ticker, 'sell'),
867
- 'askVolume': self.safe_string(ticker, 'sell_amount'),
858
+ 'bid': None,
859
+ 'bidVolume': self.safe_string(ticker, 'volume_buy'),
860
+ 'ask': None,
861
+ 'askVolume': self.safe_string(ticker, 'volume_sell'),
868
862
  'vwap': None,
869
863
  'open': self.safe_string(ticker, 'open'),
870
- 'close': last,
871
- 'last': last,
864
+ 'close': self.safe_string(ticker, 'close'),
865
+ 'last': self.safe_string(ticker, 'last'),
872
866
  'previousClose': None,
873
867
  'change': None,
874
868
  'percentage': None,
875
869
  'average': None,
876
- 'baseVolume': self.safe_string_2(ticker, 'vol', 'volume'),
870
+ 'baseVolume': self.safe_string(ticker, 'volume'),
877
871
  'quoteVolume': None,
878
872
  'info': ticker,
879
873
  }, market)
@@ -881,8 +875,8 @@ class coinex(Exchange, ImplicitAPI):
881
875
  async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
882
876
  """
883
877
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
884
- :see: https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot001_market007_single_market_ticker
885
- :see: https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http008_market_ticker
878
+ :see: https://docs.coinex.com/api/v2/spot/market/http/list-market-ticker
879
+ :see: https://docs.coinex.com/api/v2/futures/market/http/list-market-ticker
886
880
  :param str symbol: unified symbol of the market to fetch the ticker for
887
881
  :param dict [params]: extra parameters specific to the exchange API endpoint
888
882
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -894,28 +888,29 @@ class coinex(Exchange, ImplicitAPI):
894
888
  }
895
889
  response = None
896
890
  if market['swap']:
897
- response = await self.v1PerpetualPublicGetMarketTicker(self.extend(request, params))
891
+ response = await self.v2PublicGetFuturesTicker(self.extend(request, params))
898
892
  else:
899
- response = await self.v1PublicGetMarketTicker(self.extend(request, params))
893
+ response = await self.v2PublicGetSpotTicker(self.extend(request, params))
900
894
  #
901
895
  # Spot
902
896
  #
903
897
  # {
904
898
  # "code": 0,
905
- # "data": {
906
- # "date": 1651306913414,
907
- # "ticker": {
908
- # "vol": "293.19415130",
909
- # "low": "38200.00",
910
- # "open": "39514.99",
911
- # "high": "39530.00",
912
- # "last": "38649.57",
913
- # "buy": "38640.20",
914
- # "buy_amount": "0.22800000",
915
- # "sell": "38640.21",
916
- # "sell_amount": "0.02828439"
899
+ # "data": [
900
+ # {
901
+ # "close": "62393.47",
902
+ # "high": "64106.41",
903
+ # "last": "62393.47",
904
+ # "low": "59650.01",
905
+ # "market": "BTCUSDT",
906
+ # "open": "61616.15",
907
+ # "period": 86400,
908
+ # "value": "28711273.4065667262",
909
+ # "volume": "461.76557205",
910
+ # "volume_buy": "11.41506354",
911
+ # "volume_sell": "7.3240169"
917
912
  # }
918
- # },
913
+ # ],
919
914
  # "message": "OK"
920
915
  # }
921
916
  #
@@ -923,41 +918,35 @@ class coinex(Exchange, ImplicitAPI):
923
918
  #
924
919
  # {
925
920
  # "code": 0,
926
- # "data": {
927
- # "date": 1651306641500,
928
- # "ticker": {
929
- # "vol": "7714.2175",
930
- # "low": "38200.00",
931
- # "open": "39569.23",
932
- # "high": "39569.23",
933
- # "last": "38681.37",
934
- # "buy": "38681.36",
921
+ # "data": [
922
+ # {
923
+ # "close": "62480.08",
924
+ # "high": "64100",
925
+ # "index_price": "62443.05",
926
+ # "last": "62480.08",
927
+ # "low": "59600",
928
+ # "mark_price": "62443.05",
929
+ # "market": "BTCUSDT",
930
+ # "open": "61679.98",
935
931
  # "period": 86400,
936
- # "funding_time": 462,
937
- # "position_amount": "296.7552",
938
- # "funding_rate_last": "0.00009395",
939
- # "funding_rate_next": "0.00000649",
940
- # "funding_rate_predict": "-0.00007176",
941
- # "insurance": "16464465.09431942163278132918",
942
- # "sign_price": "38681.93",
943
- # "index_price": "38681.69500000",
944
- # "sell_total": "16.6039",
945
- # "buy_total": "19.8481",
946
- # "buy_amount": "4.6315",
947
- # "sell": "38681.37",
948
- # "sell_amount": "11.4044"
932
+ # "value": "180226025.69791713065326633165",
933
+ # "volume": "2900.2218",
934
+ # "volume_buy": "7.3847",
935
+ # "volume_sell": "6.1249"
949
936
  # }
950
- # },
937
+ # ],
951
938
  # "message": "OK"
952
939
  # }
953
940
  #
954
- return self.parse_ticker(response['data'], market)
941
+ data = self.safe_list(response, 'data', [])
942
+ result = self.safe_dict(data, 0, {})
943
+ return self.parse_ticker(result, market)
955
944
 
956
945
  async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
957
946
  """
958
947
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
959
- :see: https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot001_market008_all_market_ticker
960
- :see: https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http009_market_ticker_all
948
+ :see: https://docs.coinex.com/api/v2/spot/market/http/list-market-ticker
949
+ :see: https://docs.coinex.com/api/v2/futures/market/http/list-market-ticker
961
950
  :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
962
951
  :param dict [params]: extra parameters specific to the exchange API endpoint
963
952
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -971,83 +960,58 @@ class coinex(Exchange, ImplicitAPI):
971
960
  marketType, query = self.handle_market_type_and_params('fetchTickers', market, params)
972
961
  response = None
973
962
  if marketType == 'swap':
974
- response = await self.v1PerpetualPublicGetMarketTickerAll(query)
963
+ response = await self.v2PublicGetFuturesTicker(query)
975
964
  else:
976
- response = await self.v1PublicGetMarketTickerAll()
965
+ response = await self.v2PublicGetSpotTicker(query)
977
966
  #
978
967
  # Spot
979
968
  #
980
969
  # {
981
970
  # "code": 0,
982
- # "data": {
983
- # "date": 1651519857284,
984
- # "ticker": {
985
- # "PSPUSDT": {
986
- # "vol": "127131.55227034",
987
- # "low": "0.0669",
988
- # "open": "0.0688",
989
- # "high": "0.0747",
990
- # "last": "0.0685",
991
- # "buy": "0.0676",
992
- # "buy_amount": "702.70117866",
993
- # "sell": "0.0690",
994
- # "sell_amount": "686.76861562"
995
- # },
971
+ # "data": [
972
+ # {
973
+ # "close": "62393.47",
974
+ # "high": "64106.41",
975
+ # "last": "62393.47",
976
+ # "low": "59650.01",
977
+ # "market": "BTCUSDT",
978
+ # "open": "61616.15",
979
+ # "period": 86400,
980
+ # "value": "28711273.4065667262",
981
+ # "volume": "461.76557205",
982
+ # "volume_buy": "11.41506354",
983
+ # "volume_sell": "7.3240169"
996
984
  # }
997
- # },
998
- # "message": "Ok"
985
+ # ],
986
+ # "message": "OK"
999
987
  # }
1000
988
  #
1001
989
  # Swap
1002
990
  #
1003
991
  # {
1004
992
  # "code": 0,
1005
- # "data": {
1006
- # "date": 1651520268644,
1007
- # "ticker": {
1008
- # "KAVAUSDT": {
1009
- # "vol": "834924",
1010
- # "low": "3.9418",
1011
- # "open": "4.1834",
1012
- # "high": "4.4328",
1013
- # "last": "4.0516",
1014
- # "buy": "4.0443",
1015
- # "period": 86400,
1016
- # "funding_time": 262,
1017
- # "position_amount": "16111",
1018
- # "funding_rate_last": "-0.00069514",
1019
- # "funding_rate_next": "-0.00061009",
1020
- # "funding_rate_predict": "-0.00055812",
1021
- # "insurance": "16532425.53026084124483989548",
1022
- # "sign_price": "4.0516",
1023
- # "index_price": "4.0530",
1024
- # "sell_total": "59446",
1025
- # "buy_total": "62423",
1026
- # "buy_amount": "959",
1027
- # "sell": "4.0466",
1028
- # "sell_amount": "141"
1029
- # },
993
+ # "data": [
994
+ # {
995
+ # "close": "62480.08",
996
+ # "high": "64100",
997
+ # "index_price": "62443.05",
998
+ # "last": "62480.08",
999
+ # "low": "59600",
1000
+ # "mark_price": "62443.05",
1001
+ # "market": "BTCUSDT",
1002
+ # "open": "61679.98",
1003
+ # "period": 86400,
1004
+ # "value": "180226025.69791713065326633165",
1005
+ # "volume": "2900.2218",
1006
+ # "volume_buy": "7.3847",
1007
+ # "volume_sell": "6.1249"
1030
1008
  # }
1031
- # },
1032
- # "message": "Ok"
1009
+ # ],
1010
+ # "message": "OK"
1033
1011
  # }
1034
1012
  #
1035
- data = self.safe_value(response, 'data')
1036
- timestamp = self.safe_integer(data, 'date')
1037
- tickers = self.safe_value(data, 'ticker', {})
1038
- marketIds = list(tickers.keys())
1039
- result = {}
1040
- for i in range(0, len(marketIds)):
1041
- marketId = marketIds[i]
1042
- marketInner = self.safe_market(marketId, None, None, marketType)
1043
- symbol = marketInner['symbol']
1044
- ticker = self.parse_ticker({
1045
- 'date': timestamp,
1046
- 'ticker': tickers[marketId],
1047
- }, marketInner)
1048
- ticker['symbol'] = symbol
1049
- result[symbol] = ticker
1050
- return self.filter_by_array_tickers(result, 'symbol', symbols)
1013
+ data = self.safe_list(response, 'data', [])
1014
+ return self.parse_tickers(data, symbols)
1051
1015
 
1052
1016
  async def fetch_time(self, params={}):
1053
1017
  """
@@ -1500,7 +1500,7 @@ class cryptocom(Exchange, ImplicitAPI):
1500
1500
  """
1501
1501
  tag, params = self.handle_withdraw_tag_and_params(tag, params)
1502
1502
  await self.load_markets()
1503
- currency = self.currency(code)
1503
+ currency = self.safe_currency(code) # for instance, USDC is not inferred from markets but it's still available
1504
1504
  request = {
1505
1505
  'currency': currency['id'],
1506
1506
  'amount': amount,
@@ -1542,7 +1542,7 @@ class cryptocom(Exchange, ImplicitAPI):
1542
1542
  :returns dict: a dictionary of `address structures <https://docs.ccxt.com/#/?id=address-structure>` indexed by the network
1543
1543
  """
1544
1544
  await self.load_markets()
1545
- currency = self.currency(code)
1545
+ currency = self.safe_currency(code)
1546
1546
  request = {
1547
1547
  'currency': currency['id'],
1548
1548
  }
@@ -1633,7 +1633,7 @@ class cryptocom(Exchange, ImplicitAPI):
1633
1633
  currency = None
1634
1634
  request = {}
1635
1635
  if code is not None:
1636
- currency = self.currency(code)
1636
+ currency = self.safe_currency(code)
1637
1637
  request['currency'] = currency['id']
1638
1638
  if since is not None:
1639
1639
  # 90 days date range
@@ -1686,7 +1686,7 @@ class cryptocom(Exchange, ImplicitAPI):
1686
1686
  currency = None
1687
1687
  request = {}
1688
1688
  if code is not None:
1689
- currency = self.currency(code)
1689
+ currency = self.safe_currency(code)
1690
1690
  request['currency'] = currency['id']
1691
1691
  if since is not None:
1692
1692
  # 90 days date range
@@ -2179,7 +2179,7 @@ class cryptocom(Exchange, ImplicitAPI):
2179
2179
  request = {}
2180
2180
  currency = None
2181
2181
  if code is not None:
2182
- currency = self.currency(code)
2182
+ currency = self.safe_currency(code)
2183
2183
  if since is not None:
2184
2184
  request['start_time'] = since
2185
2185
  if limit is not None:
@@ -6,10 +6,11 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.hyperliquid import ImplicitAPI
8
8
  import asyncio
9
- from ccxt.base.types import Balances, Currencies, Int, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Trade, TransferEntry
9
+ from ccxt.base.types import Balances, Currencies, Int, MarginModification, Market, Num, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Str, Strings, Trade, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import ArgumentsRequired
13
+ from ccxt.base.errors import BadRequest
13
14
  from ccxt.base.errors import InvalidOrder
14
15
  from ccxt.base.errors import OrderNotFound
15
16
  from ccxt.base.errors import NotSupported
@@ -44,6 +45,7 @@ class hyperliquid(Exchange, ImplicitAPI):
44
45
  'cancelAllOrders': False,
45
46
  'cancelOrder': True,
46
47
  'cancelOrders': True,
48
+ 'cancelOrdersForSymbols': True,
47
49
  'closeAllPositions': False,
48
50
  'closePosition': False,
49
51
  'createMarketBuyOrderWithCost': False,
@@ -1168,6 +1170,72 @@ class hyperliquid(Exchange, ImplicitAPI):
1168
1170
  #
1169
1171
  return response
1170
1172
 
1173
+ async def cancel_orders_for_symbols(self, orders: List[CancellationRequest], params={}):
1174
+ """
1175
+ cancel multiple orders for multiple symbols
1176
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s
1177
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s-by-cloid
1178
+ :param CancellationRequest[] orders: each order should contain the parameters required by cancelOrder namely id and symbol
1179
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1180
+ :param str [params.vaultAddress]: the vault address
1181
+ :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1182
+ """
1183
+ self.check_required_credentials()
1184
+ await self.load_markets()
1185
+ nonce = self.milliseconds()
1186
+ request = {
1187
+ 'nonce': nonce,
1188
+ # 'vaultAddress': vaultAddress,
1189
+ }
1190
+ cancelReq = []
1191
+ cancelAction = {
1192
+ 'type': '',
1193
+ 'cancels': [],
1194
+ }
1195
+ cancelByCloid = False
1196
+ for i in range(0, len(orders)):
1197
+ order = orders[i]
1198
+ clientOrderId = self.safe_string(order, 'clientOrderId')
1199
+ if clientOrderId is not None:
1200
+ cancelByCloid = True
1201
+ id = self.safe_string(order, 'id')
1202
+ symbol = self.safe_string(order, 'symbol')
1203
+ if symbol is None:
1204
+ raise ArgumentsRequired(self.id + ' cancelOrdersForSymbols() requires a symbol argument in each order')
1205
+ if id is not None and cancelByCloid:
1206
+ raise BadRequest(self.id + ' cancelOrdersForSymbols() all orders must have either id or clientOrderId')
1207
+ assetKey = 'asset' if cancelByCloid else 'a'
1208
+ idKey = 'cloid' if cancelByCloid else 'o'
1209
+ market = self.market(symbol)
1210
+ cancelObj = {}
1211
+ cancelObj[assetKey] = self.parse_to_numeric(market['baseId'])
1212
+ cancelObj[idKey] = clientOrderId if cancelByCloid else self.parse_to_numeric(id)
1213
+ cancelReq.append(cancelObj)
1214
+ cancelAction['type'] = 'cancelByCloid' if cancelByCloid else 'cancel'
1215
+ cancelAction['cancels'] = cancelReq
1216
+ vaultAddress = self.format_vault_address(self.safe_string(params, 'vaultAddress'))
1217
+ signature = self.sign_l1_action(cancelAction, nonce, vaultAddress)
1218
+ request['action'] = cancelAction
1219
+ request['signature'] = signature
1220
+ if vaultAddress is not None:
1221
+ params = self.omit(params, 'vaultAddress')
1222
+ request['vaultAddress'] = vaultAddress
1223
+ response = await self.privatePostExchange(self.extend(request, params))
1224
+ #
1225
+ # {
1226
+ # "status":"ok",
1227
+ # "response":{
1228
+ # "type":"cancel",
1229
+ # "data":{
1230
+ # "statuses":[
1231
+ # "success"
1232
+ # ]
1233
+ # }
1234
+ # }
1235
+ # }
1236
+ #
1237
+ return response
1238
+
1171
1239
  async def edit_order(self, id: str, symbol: str, type: str, side: str, amount: Num = None, price: Num = None, params={}):
1172
1240
  """
1173
1241
  edit a trade order
@@ -1333,7 +1333,7 @@ class kraken(Exchange, ImplicitAPI):
1333
1333
  'ordertype': type,
1334
1334
  'volume': self.amount_to_precision(symbol, amount),
1335
1335
  }
1336
- orderRequest = self.order_request('createOrder()', symbol, type, request, price, params)
1336
+ orderRequest = self.order_request('createOrder', symbol, type, request, price, params)
1337
1337
  response = await self.privatePostAddOrder(self.extend(orderRequest[0], orderRequest[1]))
1338
1338
  #
1339
1339
  # {
@@ -1659,7 +1659,10 @@ class kraken(Exchange, ImplicitAPI):
1659
1659
  request['price'] = trailingAmountString
1660
1660
  request['ordertype'] = 'trailing-stop'
1661
1661
  if reduceOnly:
1662
- request['reduce_only'] = 'true' # not using hasattr(self, boolean) case, because the urlencodedNested transforms it into 'True' string
1662
+ if method == 'createOrderWs':
1663
+ request['reduce_only'] = True # ws request can't have stringified bool
1664
+ else:
1665
+ request['reduce_only'] = 'true' # not using hasattr(self, boolean) case, because the urlencodedNested transforms it into 'True' string
1663
1666
  close = self.safe_value(params, 'close')
1664
1667
  if close is not None:
1665
1668
  close = self.extend({}, close)
@@ -1710,7 +1713,7 @@ class kraken(Exchange, ImplicitAPI):
1710
1713
  }
1711
1714
  if amount is not None:
1712
1715
  request['volume'] = self.amount_to_precision(symbol, amount)
1713
- orderRequest = self.order_request('editOrder()', symbol, type, request, price, params)
1716
+ orderRequest = self.order_request('editOrder', symbol, type, request, price, params)
1714
1717
  response = await self.privatePostEditOrder(self.extend(orderRequest[0], orderRequest[1]))
1715
1718
  #
1716
1719
  # {