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.

@@ -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,
@@ -313,6 +315,7 @@ class hyperliquid(Exchange, ImplicitAPI):
313
315
  # ]
314
316
  # ]
315
317
  #
318
+ #
316
319
  meta = self.safe_dict(response, 0, {})
317
320
  meta = self.safe_list(meta, 'universe', [])
318
321
  assetCtxs = self.safe_dict(response, 1, {})
@@ -371,10 +374,70 @@ class hyperliquid(Exchange, ImplicitAPI):
371
374
  # },
372
375
  # ],
373
376
  # ]
377
+ # mainnet
378
+ # [
379
+ # {
380
+ # "canonical_tokens2":[
381
+ # 0,
382
+ # 1
383
+ # ],
384
+ # "spot_infos":[
385
+ # {
386
+ # "name":"PURR/USDC",
387
+ # "tokens":[
388
+ # 1,
389
+ # 0
390
+ # ]
391
+ # }
392
+ # ],
393
+ # "token_id_to_token":[
394
+ # [
395
+ # "0x6d1e7cde53ba9467b783cb7c530ce054",
396
+ # 0
397
+ # ],
398
+ # [
399
+ # "0xc1fb593aeffbeb02f85e0308e9956a90",
400
+ # 1
401
+ # ]
402
+ # ],
403
+ # "token_infos":[
404
+ # {
405
+ # "deployer":null,
406
+ # "spec":{
407
+ # "name":"USDC",
408
+ # "szDecimals":"8",
409
+ # "weiDecimals":"8"
410
+ # },
411
+ # "spots":[
412
+ # ]
413
+ # },
414
+ # {
415
+ # "deployer":null,
416
+ # "spec":{
417
+ # "name":"PURR",
418
+ # "szDecimals":"0",
419
+ # "weiDecimals":"5"
420
+ # },
421
+ # "spots":[
422
+ # 0
423
+ # ]
424
+ # }
425
+ # ]
426
+ # },
427
+ # [
428
+ # {
429
+ # "dayNtlVlm":"35001170.16631",
430
+ # "markPx":"0.15743",
431
+ # "midPx":"0.157555",
432
+ # "prevDayPx":"0.158"
433
+ # }
434
+ # ]
435
+ # ]
374
436
  #
437
+ # response differs depending on the environment(mainnet vs sandbox)
375
438
  first = self.safe_dict(response, 0, {})
376
- meta = self.safe_list(first, 'universe', [])
377
- tokens = self.safe_list(first, 'tokens', [])
439
+ meta = self.safe_list_2(first, 'universe', 'spot_infos', [])
440
+ tokens = self.safe_list_2(first, 'tokens', 'token_infos', [])
378
441
  markets = []
379
442
  for i in range(0, len(meta)):
380
443
  market = self.safe_dict(meta, i, {})
@@ -390,14 +453,16 @@ class hyperliquid(Exchange, ImplicitAPI):
390
453
  maker = self.safe_number(fees, 'maker')
391
454
  tokensPos = self.safe_list(market, 'tokens', [])
392
455
  baseTokenPos = self.safe_integer(tokensPos, 0)
393
- quoteTokenPos = self.safe_integer(tokensPos, 1)
456
+ # quoteTokenPos = self.safe_integer(tokensPos, 1)
394
457
  baseTokenInfo = self.safe_dict(tokens, baseTokenPos, {})
395
- quoteTokenInfo = self.safe_dict(tokens, quoteTokenPos, {})
396
- baseDecimals = self.safe_string(baseTokenInfo, 'szDecimals')
397
- quoteDecimals = self.safe_integer(quoteTokenInfo, 'szDecimals')
458
+ # quoteTokenInfo = self.safe_dict(tokens, quoteTokenPos, {})
459
+ innerBaseTokenInfo = self.safe_dict(baseTokenInfo, 'spec', baseTokenInfo)
460
+ # innerQuoteTokenInfo = self.safe_dict(quoteTokenInfo, 'spec', quoteTokenInfo)
461
+ amountPrecision = self.parse_number(self.parse_precision(self.safe_string(innerBaseTokenInfo, 'szDecimals')))
462
+ # quotePrecision = self.parse_number(self.parse_precision(self.safe_string(innerQuoteTokenInfo, 'szDecimals')))
398
463
  baseId = self.number_to_string(i + 10000)
399
464
  markets.append(self.safe_market_structure({
400
- 'id': baseId,
465
+ 'id': marketName,
401
466
  'symbol': symbol,
402
467
  'base': base,
403
468
  'quote': quote,
@@ -407,14 +472,15 @@ class hyperliquid(Exchange, ImplicitAPI):
407
472
  'settleId': None,
408
473
  'type': 'spot',
409
474
  'spot': True,
475
+ 'subType': None,
410
476
  'margin': None,
411
477
  'swap': False,
412
478
  'future': False,
413
479
  'option': False,
414
480
  'active': True,
415
481
  'contract': False,
416
- 'linear': True,
417
- 'inverse': False,
482
+ 'linear': None,
483
+ 'inverse': None,
418
484
  'taker': taker,
419
485
  'maker': maker,
420
486
  'contractSize': None,
@@ -423,8 +489,8 @@ class hyperliquid(Exchange, ImplicitAPI):
423
489
  'strike': None,
424
490
  'optionType': None,
425
491
  'precision': {
426
- 'amount': self.parse_number(self.parse_precision(baseDecimals)), # decimal places
427
- 'price': quoteDecimals, # significant digits
492
+ 'amount': amountPrecision, # decimal places
493
+ 'price': 5, # significant digits
428
494
  },
429
495
  'limits': {
430
496
  'leverage': {
@@ -631,7 +697,7 @@ class hyperliquid(Exchange, ImplicitAPI):
631
697
  market = self.market(symbol)
632
698
  request = {
633
699
  'type': 'l2Book',
634
- 'coin': market['base'],
700
+ 'coin': market['base'] if market['swap'] else market['id'],
635
701
  }
636
702
  response = await self.publicPostInfo(self.extend(request, params))
637
703
  #
@@ -687,7 +753,7 @@ class hyperliquid(Exchange, ImplicitAPI):
687
753
  request = {
688
754
  'type': 'candleSnapshot',
689
755
  'req': {
690
- 'coin': market['base'],
756
+ 'coin': market['base'] if market['swap'] else market['id'],
691
757
  'interval': timeframe,
692
758
  'startTime': since,
693
759
  'endTime': until,
@@ -790,6 +856,9 @@ class hyperliquid(Exchange, ImplicitAPI):
790
856
  return self.parse_trades(response, market, since, limit)
791
857
 
792
858
  def amount_to_precision(self, symbol, amount):
859
+ market = self.market(symbol)
860
+ if market['spot']:
861
+ return super(hyperliquid, self).amount_to_precision(symbol, amount)
793
862
  return self.decimal_to_precision(amount, ROUND, self.markets[symbol]['precision']['amount'], self.precisionMode)
794
863
 
795
864
  def price_to_precision(self, symbol: str, price) -> str:
@@ -1168,6 +1237,72 @@ class hyperliquid(Exchange, ImplicitAPI):
1168
1237
  #
1169
1238
  return response
1170
1239
 
1240
+ async def cancel_orders_for_symbols(self, orders: List[CancellationRequest], params={}):
1241
+ """
1242
+ cancel multiple orders for multiple symbols
1243
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s
1244
+ :see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s-by-cloid
1245
+ :param CancellationRequest[] orders: each order should contain the parameters required by cancelOrder namely id and symbol
1246
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1247
+ :param str [params.vaultAddress]: the vault address
1248
+ :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1249
+ """
1250
+ self.check_required_credentials()
1251
+ await self.load_markets()
1252
+ nonce = self.milliseconds()
1253
+ request = {
1254
+ 'nonce': nonce,
1255
+ # 'vaultAddress': vaultAddress,
1256
+ }
1257
+ cancelReq = []
1258
+ cancelAction = {
1259
+ 'type': '',
1260
+ 'cancels': [],
1261
+ }
1262
+ cancelByCloid = False
1263
+ for i in range(0, len(orders)):
1264
+ order = orders[i]
1265
+ clientOrderId = self.safe_string(order, 'clientOrderId')
1266
+ if clientOrderId is not None:
1267
+ cancelByCloid = True
1268
+ id = self.safe_string(order, 'id')
1269
+ symbol = self.safe_string(order, 'symbol')
1270
+ if symbol is None:
1271
+ raise ArgumentsRequired(self.id + ' cancelOrdersForSymbols() requires a symbol argument in each order')
1272
+ if id is not None and cancelByCloid:
1273
+ raise BadRequest(self.id + ' cancelOrdersForSymbols() all orders must have either id or clientOrderId')
1274
+ assetKey = 'asset' if cancelByCloid else 'a'
1275
+ idKey = 'cloid' if cancelByCloid else 'o'
1276
+ market = self.market(symbol)
1277
+ cancelObj = {}
1278
+ cancelObj[assetKey] = self.parse_to_numeric(market['baseId'])
1279
+ cancelObj[idKey] = clientOrderId if cancelByCloid else self.parse_to_numeric(id)
1280
+ cancelReq.append(cancelObj)
1281
+ cancelAction['type'] = 'cancelByCloid' if cancelByCloid else 'cancel'
1282
+ cancelAction['cancels'] = cancelReq
1283
+ vaultAddress = self.format_vault_address(self.safe_string(params, 'vaultAddress'))
1284
+ signature = self.sign_l1_action(cancelAction, nonce, vaultAddress)
1285
+ request['action'] = cancelAction
1286
+ request['signature'] = signature
1287
+ if vaultAddress is not None:
1288
+ params = self.omit(params, 'vaultAddress')
1289
+ request['vaultAddress'] = vaultAddress
1290
+ response = await self.privatePostExchange(self.extend(request, params))
1291
+ #
1292
+ # {
1293
+ # "status":"ok",
1294
+ # "response":{
1295
+ # "type":"cancel",
1296
+ # "data":{
1297
+ # "statuses":[
1298
+ # "success"
1299
+ # ]
1300
+ # }
1301
+ # }
1302
+ # }
1303
+ #
1304
+ return response
1305
+
1171
1306
  async def edit_order(self, id: str, symbol: str, type: str, side: str, amount: Num = None, price: Num = None, params={}):
1172
1307
  """
1173
1308
  edit a trade order
@@ -2154,6 +2289,11 @@ class hyperliquid(Exchange, ImplicitAPI):
2154
2289
  return [self.walletAddress, params]
2155
2290
  raise ArgumentsRequired(self.id + ' ' + methodName + '() requires a user parameter inside \'params\' or the wallet address set')
2156
2291
 
2292
+ def coin_to_market_id(self, coin: Str):
2293
+ if coin.find('/') > -1:
2294
+ return coin # spot
2295
+ return coin + '/USDC:USDC'
2296
+
2157
2297
  def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
2158
2298
  if not response:
2159
2299
  return None # fallback to default error handler