ccxt 4.3.1__py2.py3-none-any.whl → 4.3.3__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/coinex.py CHANGED
@@ -814,65 +814,59 @@ class coinex(Exchange, ImplicitAPI):
814
814
  # Spot fetchTicker, fetchTickers
815
815
  #
816
816
  # {
817
- # "vol": "293.19415130",
818
- # "low": "38200.00",
819
- # "open": "39514.99",
820
- # "high": "39530.00",
821
- # "last": "38649.57",
822
- # "buy": "38640.20",
823
- # "buy_amount": "0.22800000",
824
- # "sell": "38640.21",
825
- # "sell_amount": "0.02828439"
817
+ # "close": "62393.47",
818
+ # "high": "64106.41",
819
+ # "last": "62393.47",
820
+ # "low": "59650.01",
821
+ # "market": "BTCUSDT",
822
+ # "open": "61616.15",
823
+ # "period": 86400,
824
+ # "value": "28711273.4065667262",
825
+ # "volume": "461.76557205",
826
+ # "volume_buy": "11.41506354",
827
+ # "volume_sell": "7.3240169"
826
828
  # }
827
829
  #
828
830
  # Swap fetchTicker, fetchTickers
829
831
  #
830
832
  # {
831
- # "vol": "7714.2175",
832
- # "low": "38200.00",
833
- # "open": "39569.23",
834
- # "high": "39569.23",
835
- # "last": "38681.37",
836
- # "buy": "38681.36",
833
+ # "close": "62480.08",
834
+ # "high": "64100",
835
+ # "index_price": "62443.05",
836
+ # "last": "62480.08",
837
+ # "low": "59600",
838
+ # "mark_price": "62443.05",
839
+ # "market": "BTCUSDT",
840
+ # "open": "61679.98",
837
841
  # "period": 86400,
838
- # "funding_time": 462,
839
- # "position_amount": "296.7552",
840
- # "funding_rate_last": "0.00009395",
841
- # "funding_rate_next": "0.00000649",
842
- # "funding_rate_predict": "-0.00007176",
843
- # "insurance": "16464465.09431942163278132918",
844
- # "sign_price": "38681.93",
845
- # "index_price": "38681.69500000",
846
- # "sell_total": "16.6039",
847
- # "buy_total": "19.8481",
848
- # "buy_amount": "4.6315",
849
- # "sell": "38681.37",
850
- # "sell_amount": "11.4044"
842
+ # "value": "180226025.69791713065326633165",
843
+ # "volume": "2900.2218",
844
+ # "volume_buy": "7.3847",
845
+ # "volume_sell": "6.1249"
851
846
  # }
852
847
  #
853
- timestamp = self.safe_integer(ticker, 'date')
854
- symbol = self.safe_symbol(None, market)
855
- ticker = self.safe_value(ticker, 'ticker', {})
856
- last = self.safe_string(ticker, 'last')
848
+ marketType = 'swap' if ('mark_price' in ticker) else 'spot'
849
+ marketId = self.safe_string(ticker, 'market')
850
+ symbol = self.safe_symbol(marketId, market, None, marketType)
857
851
  return self.safe_ticker({
858
852
  'symbol': symbol,
859
- 'timestamp': timestamp,
860
- 'datetime': self.iso8601(timestamp),
853
+ 'timestamp': None,
854
+ 'datetime': None,
861
855
  'high': self.safe_string(ticker, 'high'),
862
856
  'low': self.safe_string(ticker, 'low'),
863
- 'bid': self.safe_string(ticker, 'buy'),
864
- 'bidVolume': self.safe_string(ticker, 'buy_amount'),
865
- 'ask': self.safe_string(ticker, 'sell'),
866
- 'askVolume': self.safe_string(ticker, 'sell_amount'),
857
+ 'bid': None,
858
+ 'bidVolume': self.safe_string(ticker, 'volume_buy'),
859
+ 'ask': None,
860
+ 'askVolume': self.safe_string(ticker, 'volume_sell'),
867
861
  'vwap': None,
868
862
  'open': self.safe_string(ticker, 'open'),
869
- 'close': last,
870
- 'last': last,
863
+ 'close': self.safe_string(ticker, 'close'),
864
+ 'last': self.safe_string(ticker, 'last'),
871
865
  'previousClose': None,
872
866
  'change': None,
873
867
  'percentage': None,
874
868
  'average': None,
875
- 'baseVolume': self.safe_string_2(ticker, 'vol', 'volume'),
869
+ 'baseVolume': self.safe_string(ticker, 'volume'),
876
870
  'quoteVolume': None,
877
871
  'info': ticker,
878
872
  }, market)
@@ -880,8 +874,8 @@ class coinex(Exchange, ImplicitAPI):
880
874
  def fetch_ticker(self, symbol: str, params={}) -> Ticker:
881
875
  """
882
876
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
883
- :see: https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot001_market007_single_market_ticker
884
- :see: https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http008_market_ticker
877
+ :see: https://docs.coinex.com/api/v2/spot/market/http/list-market-ticker
878
+ :see: https://docs.coinex.com/api/v2/futures/market/http/list-market-ticker
885
879
  :param str symbol: unified symbol of the market to fetch the ticker for
886
880
  :param dict [params]: extra parameters specific to the exchange API endpoint
887
881
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -893,28 +887,29 @@ class coinex(Exchange, ImplicitAPI):
893
887
  }
894
888
  response = None
895
889
  if market['swap']:
896
- response = self.v1PerpetualPublicGetMarketTicker(self.extend(request, params))
890
+ response = self.v2PublicGetFuturesTicker(self.extend(request, params))
897
891
  else:
898
- response = self.v1PublicGetMarketTicker(self.extend(request, params))
892
+ response = self.v2PublicGetSpotTicker(self.extend(request, params))
899
893
  #
900
894
  # Spot
901
895
  #
902
896
  # {
903
897
  # "code": 0,
904
- # "data": {
905
- # "date": 1651306913414,
906
- # "ticker": {
907
- # "vol": "293.19415130",
908
- # "low": "38200.00",
909
- # "open": "39514.99",
910
- # "high": "39530.00",
911
- # "last": "38649.57",
912
- # "buy": "38640.20",
913
- # "buy_amount": "0.22800000",
914
- # "sell": "38640.21",
915
- # "sell_amount": "0.02828439"
898
+ # "data": [
899
+ # {
900
+ # "close": "62393.47",
901
+ # "high": "64106.41",
902
+ # "last": "62393.47",
903
+ # "low": "59650.01",
904
+ # "market": "BTCUSDT",
905
+ # "open": "61616.15",
906
+ # "period": 86400,
907
+ # "value": "28711273.4065667262",
908
+ # "volume": "461.76557205",
909
+ # "volume_buy": "11.41506354",
910
+ # "volume_sell": "7.3240169"
916
911
  # }
917
- # },
912
+ # ],
918
913
  # "message": "OK"
919
914
  # }
920
915
  #
@@ -922,41 +917,35 @@ class coinex(Exchange, ImplicitAPI):
922
917
  #
923
918
  # {
924
919
  # "code": 0,
925
- # "data": {
926
- # "date": 1651306641500,
927
- # "ticker": {
928
- # "vol": "7714.2175",
929
- # "low": "38200.00",
930
- # "open": "39569.23",
931
- # "high": "39569.23",
932
- # "last": "38681.37",
933
- # "buy": "38681.36",
920
+ # "data": [
921
+ # {
922
+ # "close": "62480.08",
923
+ # "high": "64100",
924
+ # "index_price": "62443.05",
925
+ # "last": "62480.08",
926
+ # "low": "59600",
927
+ # "mark_price": "62443.05",
928
+ # "market": "BTCUSDT",
929
+ # "open": "61679.98",
934
930
  # "period": 86400,
935
- # "funding_time": 462,
936
- # "position_amount": "296.7552",
937
- # "funding_rate_last": "0.00009395",
938
- # "funding_rate_next": "0.00000649",
939
- # "funding_rate_predict": "-0.00007176",
940
- # "insurance": "16464465.09431942163278132918",
941
- # "sign_price": "38681.93",
942
- # "index_price": "38681.69500000",
943
- # "sell_total": "16.6039",
944
- # "buy_total": "19.8481",
945
- # "buy_amount": "4.6315",
946
- # "sell": "38681.37",
947
- # "sell_amount": "11.4044"
931
+ # "value": "180226025.69791713065326633165",
932
+ # "volume": "2900.2218",
933
+ # "volume_buy": "7.3847",
934
+ # "volume_sell": "6.1249"
948
935
  # }
949
- # },
936
+ # ],
950
937
  # "message": "OK"
951
938
  # }
952
939
  #
953
- return self.parse_ticker(response['data'], market)
940
+ data = self.safe_list(response, 'data', [])
941
+ result = self.safe_dict(data, 0, {})
942
+ return self.parse_ticker(result, market)
954
943
 
955
944
  def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
956
945
  """
957
946
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
958
- :see: https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot001_market008_all_market_ticker
959
- :see: https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http009_market_ticker_all
947
+ :see: https://docs.coinex.com/api/v2/spot/market/http/list-market-ticker
948
+ :see: https://docs.coinex.com/api/v2/futures/market/http/list-market-ticker
960
949
  :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
961
950
  :param dict [params]: extra parameters specific to the exchange API endpoint
962
951
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -970,83 +959,58 @@ class coinex(Exchange, ImplicitAPI):
970
959
  marketType, query = self.handle_market_type_and_params('fetchTickers', market, params)
971
960
  response = None
972
961
  if marketType == 'swap':
973
- response = self.v1PerpetualPublicGetMarketTickerAll(query)
962
+ response = self.v2PublicGetFuturesTicker(query)
974
963
  else:
975
- response = self.v1PublicGetMarketTickerAll()
964
+ response = self.v2PublicGetSpotTicker(query)
976
965
  #
977
966
  # Spot
978
967
  #
979
968
  # {
980
969
  # "code": 0,
981
- # "data": {
982
- # "date": 1651519857284,
983
- # "ticker": {
984
- # "PSPUSDT": {
985
- # "vol": "127131.55227034",
986
- # "low": "0.0669",
987
- # "open": "0.0688",
988
- # "high": "0.0747",
989
- # "last": "0.0685",
990
- # "buy": "0.0676",
991
- # "buy_amount": "702.70117866",
992
- # "sell": "0.0690",
993
- # "sell_amount": "686.76861562"
994
- # },
970
+ # "data": [
971
+ # {
972
+ # "close": "62393.47",
973
+ # "high": "64106.41",
974
+ # "last": "62393.47",
975
+ # "low": "59650.01",
976
+ # "market": "BTCUSDT",
977
+ # "open": "61616.15",
978
+ # "period": 86400,
979
+ # "value": "28711273.4065667262",
980
+ # "volume": "461.76557205",
981
+ # "volume_buy": "11.41506354",
982
+ # "volume_sell": "7.3240169"
995
983
  # }
996
- # },
997
- # "message": "Ok"
984
+ # ],
985
+ # "message": "OK"
998
986
  # }
999
987
  #
1000
988
  # Swap
1001
989
  #
1002
990
  # {
1003
991
  # "code": 0,
1004
- # "data": {
1005
- # "date": 1651520268644,
1006
- # "ticker": {
1007
- # "KAVAUSDT": {
1008
- # "vol": "834924",
1009
- # "low": "3.9418",
1010
- # "open": "4.1834",
1011
- # "high": "4.4328",
1012
- # "last": "4.0516",
1013
- # "buy": "4.0443",
1014
- # "period": 86400,
1015
- # "funding_time": 262,
1016
- # "position_amount": "16111",
1017
- # "funding_rate_last": "-0.00069514",
1018
- # "funding_rate_next": "-0.00061009",
1019
- # "funding_rate_predict": "-0.00055812",
1020
- # "insurance": "16532425.53026084124483989548",
1021
- # "sign_price": "4.0516",
1022
- # "index_price": "4.0530",
1023
- # "sell_total": "59446",
1024
- # "buy_total": "62423",
1025
- # "buy_amount": "959",
1026
- # "sell": "4.0466",
1027
- # "sell_amount": "141"
1028
- # },
992
+ # "data": [
993
+ # {
994
+ # "close": "62480.08",
995
+ # "high": "64100",
996
+ # "index_price": "62443.05",
997
+ # "last": "62480.08",
998
+ # "low": "59600",
999
+ # "mark_price": "62443.05",
1000
+ # "market": "BTCUSDT",
1001
+ # "open": "61679.98",
1002
+ # "period": 86400,
1003
+ # "value": "180226025.69791713065326633165",
1004
+ # "volume": "2900.2218",
1005
+ # "volume_buy": "7.3847",
1006
+ # "volume_sell": "6.1249"
1029
1007
  # }
1030
- # },
1031
- # "message": "Ok"
1008
+ # ],
1009
+ # "message": "OK"
1032
1010
  # }
1033
1011
  #
1034
- data = self.safe_value(response, 'data')
1035
- timestamp = self.safe_integer(data, 'date')
1036
- tickers = self.safe_value(data, 'ticker', {})
1037
- marketIds = list(tickers.keys())
1038
- result = {}
1039
- for i in range(0, len(marketIds)):
1040
- marketId = marketIds[i]
1041
- marketInner = self.safe_market(marketId, None, None, marketType)
1042
- symbol = marketInner['symbol']
1043
- ticker = self.parse_ticker({
1044
- 'date': timestamp,
1045
- 'ticker': tickers[marketId],
1046
- }, marketInner)
1047
- ticker['symbol'] = symbol
1048
- result[symbol] = ticker
1049
- return self.filter_by_array_tickers(result, 'symbol', symbols)
1012
+ data = self.safe_list(response, 'data', [])
1013
+ return self.parse_tickers(data, symbols)
1050
1014
 
1051
1015
  def fetch_time(self, params={}):
1052
1016
  """
ccxt/cryptocom.py CHANGED
@@ -1500,7 +1500,7 @@ class cryptocom(Exchange, ImplicitAPI):
1500
1500
  """
1501
1501
  tag, params = self.handle_withdraw_tag_and_params(tag, params)
1502
1502
  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
  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:
ccxt/hyperliquid.py CHANGED
@@ -5,10 +5,11 @@
5
5
 
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.hyperliquid import ImplicitAPI
8
- from ccxt.base.types import Balances, Currencies, Int, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Trade, TransferEntry
8
+ from ccxt.base.types import Balances, Currencies, Int, MarginModification, Market, Num, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Str, Strings, Trade, TransferEntry
9
9
  from typing import List
10
10
  from ccxt.base.errors import ExchangeError
11
11
  from ccxt.base.errors import ArgumentsRequired
12
+ from ccxt.base.errors import BadRequest
12
13
  from ccxt.base.errors import InvalidOrder
13
14
  from ccxt.base.errors import OrderNotFound
14
15
  from ccxt.base.errors import NotSupported
@@ -43,6 +44,7 @@ class hyperliquid(Exchange, ImplicitAPI):
43
44
  'cancelAllOrders': False,
44
45
  'cancelOrder': True,
45
46
  'cancelOrders': True,
47
+ 'cancelOrdersForSymbols': True,
46
48
  'closeAllPositions': False,
47
49
  'closePosition': False,
48
50
  'createMarketBuyOrderWithCost': False,
@@ -312,6 +314,7 @@ class hyperliquid(Exchange, ImplicitAPI):
312
314
  # ]
313
315
  # ]
314
316
  #
317
+ #
315
318
  meta = self.safe_dict(response, 0, {})
316
319
  meta = self.safe_list(meta, 'universe', [])
317
320
  assetCtxs = self.safe_dict(response, 1, {})
@@ -370,10 +373,70 @@ class hyperliquid(Exchange, ImplicitAPI):
370
373
  # },
371
374
  # ],
372
375
  # ]
376
+ # mainnet
377
+ # [
378
+ # {
379
+ # "canonical_tokens2":[
380
+ # 0,
381
+ # 1
382
+ # ],
383
+ # "spot_infos":[
384
+ # {
385
+ # "name":"PURR/USDC",
386
+ # "tokens":[
387
+ # 1,
388
+ # 0
389
+ # ]
390
+ # }
391
+ # ],
392
+ # "token_id_to_token":[
393
+ # [
394
+ # "0x6d1e7cde53ba9467b783cb7c530ce054",
395
+ # 0
396
+ # ],
397
+ # [
398
+ # "0xc1fb593aeffbeb02f85e0308e9956a90",
399
+ # 1
400
+ # ]
401
+ # ],
402
+ # "token_infos":[
403
+ # {
404
+ # "deployer":null,
405
+ # "spec":{
406
+ # "name":"USDC",
407
+ # "szDecimals":"8",
408
+ # "weiDecimals":"8"
409
+ # },
410
+ # "spots":[
411
+ # ]
412
+ # },
413
+ # {
414
+ # "deployer":null,
415
+ # "spec":{
416
+ # "name":"PURR",
417
+ # "szDecimals":"0",
418
+ # "weiDecimals":"5"
419
+ # },
420
+ # "spots":[
421
+ # 0
422
+ # ]
423
+ # }
424
+ # ]
425
+ # },
426
+ # [
427
+ # {
428
+ # "dayNtlVlm":"35001170.16631",
429
+ # "markPx":"0.15743",
430
+ # "midPx":"0.157555",
431
+ # "prevDayPx":"0.158"
432
+ # }
433
+ # ]
434
+ # ]
373
435
  #
436
+ # response differs depending on the environment(mainnet vs sandbox)
374
437
  first = self.safe_dict(response, 0, {})
375
- meta = self.safe_list(first, 'universe', [])
376
- tokens = self.safe_list(first, 'tokens', [])
438
+ meta = self.safe_list_2(first, 'universe', 'spot_infos', [])
439
+ tokens = self.safe_list_2(first, 'tokens', 'token_infos', [])
377
440
  markets = []
378
441
  for i in range(0, len(meta)):
379
442
  market = self.safe_dict(meta, i, {})
@@ -389,14 +452,16 @@ class hyperliquid(Exchange, ImplicitAPI):
389
452
  maker = self.safe_number(fees, 'maker')
390
453
  tokensPos = self.safe_list(market, 'tokens', [])
391
454
  baseTokenPos = self.safe_integer(tokensPos, 0)
392
- quoteTokenPos = self.safe_integer(tokensPos, 1)
455
+ # quoteTokenPos = self.safe_integer(tokensPos, 1)
393
456
  baseTokenInfo = self.safe_dict(tokens, baseTokenPos, {})
394
- quoteTokenInfo = self.safe_dict(tokens, quoteTokenPos, {})
395
- baseDecimals = self.safe_string(baseTokenInfo, 'szDecimals')
396
- quoteDecimals = self.safe_integer(quoteTokenInfo, 'szDecimals')
457
+ # quoteTokenInfo = self.safe_dict(tokens, quoteTokenPos, {})
458
+ innerBaseTokenInfo = self.safe_dict(baseTokenInfo, 'spec', baseTokenInfo)
459
+ # innerQuoteTokenInfo = self.safe_dict(quoteTokenInfo, 'spec', quoteTokenInfo)
460
+ amountPrecision = self.parse_number(self.parse_precision(self.safe_string(innerBaseTokenInfo, 'szDecimals')))
461
+ # quotePrecision = self.parse_number(self.parse_precision(self.safe_string(innerQuoteTokenInfo, 'szDecimals')))
397
462
  baseId = self.number_to_string(i + 10000)
398
463
  markets.append(self.safe_market_structure({
399
- 'id': baseId,
464
+ 'id': marketName,
400
465
  'symbol': symbol,
401
466
  'base': base,
402
467
  'quote': quote,
@@ -406,14 +471,15 @@ class hyperliquid(Exchange, ImplicitAPI):
406
471
  'settleId': None,
407
472
  'type': 'spot',
408
473
  'spot': True,
474
+ 'subType': None,
409
475
  'margin': None,
410
476
  'swap': False,
411
477
  'future': False,
412
478
  'option': False,
413
479
  'active': True,
414
480
  'contract': False,
415
- 'linear': True,
416
- 'inverse': False,
481
+ 'linear': None,
482
+ 'inverse': None,
417
483
  'taker': taker,
418
484
  'maker': maker,
419
485
  'contractSize': None,
@@ -422,8 +488,8 @@ class hyperliquid(Exchange, ImplicitAPI):
422
488
  'strike': None,
423
489
  'optionType': None,
424
490
  'precision': {
425
- 'amount': self.parse_number(self.parse_precision(baseDecimals)), # decimal places
426
- 'price': quoteDecimals, # significant digits
491
+ 'amount': amountPrecision, # decimal places
492
+ 'price': 5, # significant digits
427
493
  },
428
494
  'limits': {
429
495
  'leverage': {
@@ -630,7 +696,7 @@ class hyperliquid(Exchange, ImplicitAPI):
630
696
  market = self.market(symbol)
631
697
  request = {
632
698
  'type': 'l2Book',
633
- 'coin': market['base'],
699
+ 'coin': market['base'] if market['swap'] else market['id'],
634
700
  }
635
701
  response = self.publicPostInfo(self.extend(request, params))
636
702
  #
@@ -686,7 +752,7 @@ class hyperliquid(Exchange, ImplicitAPI):
686
752
  request = {
687
753
  'type': 'candleSnapshot',
688
754
  'req': {
689
- 'coin': market['base'],
755
+ 'coin': market['base'] if market['swap'] else market['id'],
690
756
  'interval': timeframe,
691
757
  'startTime': since,
692
758
  'endTime': until,
@@ -789,6 +855,9 @@ class hyperliquid(Exchange, ImplicitAPI):
789
855
  return self.parse_trades(response, market, since, limit)
790
856
 
791
857
  def amount_to_precision(self, symbol, amount):
858
+ market = self.market(symbol)
859
+ if market['spot']:
860
+ return super(hyperliquid, self).amount_to_precision(symbol, amount)
792
861
  return self.decimal_to_precision(amount, ROUND, self.markets[symbol]['precision']['amount'], self.precisionMode)
793
862
 
794
863
  def price_to_precision(self, symbol: str, price) -> str:
@@ -1167,6 +1236,72 @@ class hyperliquid(Exchange, ImplicitAPI):
1167
1236
  #
1168
1237
  return response
1169
1238
 
1239
+ def cancel_orders_for_symbols(self, orders: List[CancellationRequest], params={}):
1240
+ """
1241
+ cancel multiple orders for multiple symbols
1242
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s
1243
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s-by-cloid
1244
+ :param CancellationRequest[] orders: each order should contain the parameters required by cancelOrder namely id and symbol
1245
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1246
+ :param str [params.vaultAddress]: the vault address
1247
+ :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1248
+ """
1249
+ self.check_required_credentials()
1250
+ self.load_markets()
1251
+ nonce = self.milliseconds()
1252
+ request = {
1253
+ 'nonce': nonce,
1254
+ # 'vaultAddress': vaultAddress,
1255
+ }
1256
+ cancelReq = []
1257
+ cancelAction = {
1258
+ 'type': '',
1259
+ 'cancels': [],
1260
+ }
1261
+ cancelByCloid = False
1262
+ for i in range(0, len(orders)):
1263
+ order = orders[i]
1264
+ clientOrderId = self.safe_string(order, 'clientOrderId')
1265
+ if clientOrderId is not None:
1266
+ cancelByCloid = True
1267
+ id = self.safe_string(order, 'id')
1268
+ symbol = self.safe_string(order, 'symbol')
1269
+ if symbol is None:
1270
+ raise ArgumentsRequired(self.id + ' cancelOrdersForSymbols() requires a symbol argument in each order')
1271
+ if id is not None and cancelByCloid:
1272
+ raise BadRequest(self.id + ' cancelOrdersForSymbols() all orders must have either id or clientOrderId')
1273
+ assetKey = 'asset' if cancelByCloid else 'a'
1274
+ idKey = 'cloid' if cancelByCloid else 'o'
1275
+ market = self.market(symbol)
1276
+ cancelObj = {}
1277
+ cancelObj[assetKey] = self.parse_to_numeric(market['baseId'])
1278
+ cancelObj[idKey] = clientOrderId if cancelByCloid else self.parse_to_numeric(id)
1279
+ cancelReq.append(cancelObj)
1280
+ cancelAction['type'] = 'cancelByCloid' if cancelByCloid else 'cancel'
1281
+ cancelAction['cancels'] = cancelReq
1282
+ vaultAddress = self.format_vault_address(self.safe_string(params, 'vaultAddress'))
1283
+ signature = self.sign_l1_action(cancelAction, nonce, vaultAddress)
1284
+ request['action'] = cancelAction
1285
+ request['signature'] = signature
1286
+ if vaultAddress is not None:
1287
+ params = self.omit(params, 'vaultAddress')
1288
+ request['vaultAddress'] = vaultAddress
1289
+ response = self.privatePostExchange(self.extend(request, params))
1290
+ #
1291
+ # {
1292
+ # "status":"ok",
1293
+ # "response":{
1294
+ # "type":"cancel",
1295
+ # "data":{
1296
+ # "statuses":[
1297
+ # "success"
1298
+ # ]
1299
+ # }
1300
+ # }
1301
+ # }
1302
+ #
1303
+ return response
1304
+
1170
1305
  def edit_order(self, id: str, symbol: str, type: str, side: str, amount: Num = None, price: Num = None, params={}):
1171
1306
  """
1172
1307
  edit a trade order
@@ -2153,6 +2288,11 @@ class hyperliquid(Exchange, ImplicitAPI):
2153
2288
  return [self.walletAddress, params]
2154
2289
  raise ArgumentsRequired(self.id + ' ' + methodName + '() requires a user parameter inside \'params\' or the wallet address set')
2155
2290
 
2291
+ def coin_to_market_id(self, coin: Str):
2292
+ if coin.find('/') > -1:
2293
+ return coin # spot
2294
+ return coin + '/USDC:USDC'
2295
+
2156
2296
  def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
2157
2297
  if not response:
2158
2298
  return None # fallback to default error handler