ccxt 4.2.86__py2.py3-none-any.whl → 4.2.88__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 +1 -1
- ccxt/ascendex.py +16 -6
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ascendex.py +16 -6
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/binance.py +28 -11
- ccxt/async_support/bingx.py +39 -3
- ccxt/async_support/bitfinex.py +2 -0
- ccxt/async_support/bitfinex2.py +18 -4
- ccxt/async_support/bitflyer.py +18 -0
- ccxt/async_support/bitget.py +37 -22
- ccxt/async_support/bitopro.py +2 -0
- ccxt/async_support/bitrue.py +16 -8
- ccxt/async_support/bitvavo.py +2 -0
- ccxt/async_support/btcmarkets.py +1 -1
- ccxt/async_support/btcturk.py +2 -1
- ccxt/async_support/coinex.py +182 -58
- ccxt/async_support/cryptocom.py +1 -1
- ccxt/async_support/currencycom.py +1 -1
- ccxt/async_support/delta.py +8 -6
- ccxt/async_support/digifinex.py +9 -7
- ccxt/async_support/exmo.py +15 -15
- ccxt/async_support/gate.py +23 -20
- ccxt/async_support/hitbtc.py +31 -7
- ccxt/async_support/htx.py +2 -2
- ccxt/async_support/huobijp.py +1 -1
- ccxt/async_support/hyperliquid.py +242 -16
- ccxt/async_support/idex.py +1 -1
- ccxt/async_support/krakenfutures.py +4 -5
- ccxt/async_support/kucoin.py +7 -4
- ccxt/async_support/kucoinfutures.py +2 -2
- ccxt/async_support/lbank.py +2 -0
- ccxt/async_support/mexc.py +4 -4
- ccxt/async_support/oceanex.py +1 -1
- ccxt/async_support/okx.py +29 -15
- ccxt/async_support/phemex.py +6 -4
- ccxt/async_support/wazirx.py +1 -1
- ccxt/async_support/zonda.py +2 -0
- ccxt/base/exchange.py +22 -3
- ccxt/base/types.py +12 -0
- ccxt/binance.py +28 -11
- ccxt/bingx.py +39 -3
- ccxt/bitfinex.py +2 -0
- ccxt/bitfinex2.py +18 -4
- ccxt/bitflyer.py +18 -0
- ccxt/bitget.py +37 -22
- ccxt/bitopro.py +2 -0
- ccxt/bitrue.py +16 -8
- ccxt/bitvavo.py +2 -0
- ccxt/btcmarkets.py +1 -1
- ccxt/btcturk.py +2 -1
- ccxt/coinex.py +182 -58
- ccxt/cryptocom.py +1 -1
- ccxt/currencycom.py +1 -1
- ccxt/delta.py +8 -6
- ccxt/digifinex.py +9 -7
- ccxt/exmo.py +15 -15
- ccxt/gate.py +23 -20
- ccxt/hitbtc.py +31 -7
- ccxt/htx.py +2 -2
- ccxt/huobijp.py +1 -1
- ccxt/hyperliquid.py +241 -16
- ccxt/idex.py +1 -1
- ccxt/krakenfutures.py +4 -5
- ccxt/kucoin.py +7 -4
- ccxt/kucoinfutures.py +2 -2
- ccxt/lbank.py +2 -0
- ccxt/mexc.py +4 -4
- ccxt/oceanex.py +1 -1
- ccxt/okx.py +29 -15
- ccxt/phemex.py +6 -4
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/kucoin.py +10 -6
- ccxt/test/base/test_last_price.py +0 -1
- ccxt/test/base/test_shared_methods.py +1 -2
- ccxt/test/base/test_status.py +1 -1
- ccxt/wazirx.py +1 -1
- ccxt/zonda.py +2 -0
- {ccxt-4.2.86.dist-info → ccxt-4.2.88.dist-info}/METADATA +5 -6
- {ccxt-4.2.86.dist-info → ccxt-4.2.88.dist-info}/RECORD +82 -82
- {ccxt-4.2.86.dist-info → ccxt-4.2.88.dist-info}/WHEEL +0 -0
- {ccxt-4.2.86.dist-info → ccxt-4.2.88.dist-info}/top_level.txt +0 -0
ccxt/async_support/gate.py
CHANGED
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.gate import ImplicitAPI
|
8
8
|
import asyncio
|
9
9
|
import hashlib
|
10
|
-
from ccxt.base.types import Balances, Currency, FundingHistory, Greeks, Int, Leverage, Leverages, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
10
|
+
from ccxt.base.types import Balances, Currency, FundingHistory, Greeks, Int, Leverage, Leverages, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import ExchangeError
|
13
13
|
from ccxt.base.errors import PermissionDenied
|
@@ -1824,7 +1824,7 @@ class gate(Exchange, ImplicitAPI):
|
|
1824
1824
|
await self.load_markets()
|
1825
1825
|
currency = self.currency(code)
|
1826
1826
|
request = {
|
1827
|
-
'currency': currency['id'],
|
1827
|
+
'currency': currency['id'], # todo: currencies have network-junctions
|
1828
1828
|
}
|
1829
1829
|
response = await self.privateWalletGetDepositAddress(self.extend(request, params))
|
1830
1830
|
addresses = self.safe_value(response, 'multichain_addresses')
|
@@ -1871,7 +1871,7 @@ class gate(Exchange, ImplicitAPI):
|
|
1871
1871
|
rawNetwork = self.safe_string_upper(params, 'network')
|
1872
1872
|
params = self.omit(params, 'network')
|
1873
1873
|
request = {
|
1874
|
-
'currency': currency['id'],
|
1874
|
+
'currency': currency['id'], # todo: currencies have network-junctions
|
1875
1875
|
}
|
1876
1876
|
response = await self.privateWalletGetDepositAddress(self.extend(request, params))
|
1877
1877
|
#
|
@@ -3346,7 +3346,7 @@ class gate(Exchange, ImplicitAPI):
|
|
3346
3346
|
currency = None
|
3347
3347
|
if code is not None:
|
3348
3348
|
currency = self.currency(code)
|
3349
|
-
request['currency'] = currency['id']
|
3349
|
+
request['currency'] = currency['id'] # todo: currencies have network-junctions
|
3350
3350
|
if limit is not None:
|
3351
3351
|
request['limit'] = limit
|
3352
3352
|
if since is not None:
|
@@ -3378,7 +3378,7 @@ class gate(Exchange, ImplicitAPI):
|
|
3378
3378
|
currency = None
|
3379
3379
|
if code is not None:
|
3380
3380
|
currency = self.currency(code)
|
3381
|
-
request['currency'] = currency['id']
|
3381
|
+
request['currency'] = currency['id'] # todo: currencies have network-junctions
|
3382
3382
|
if limit is not None:
|
3383
3383
|
request['limit'] = limit
|
3384
3384
|
if since is not None:
|
@@ -3405,7 +3405,7 @@ class gate(Exchange, ImplicitAPI):
|
|
3405
3405
|
await self.load_markets()
|
3406
3406
|
currency = self.currency(code)
|
3407
3407
|
request = {
|
3408
|
-
'currency': currency['id'],
|
3408
|
+
'currency': currency['id'], # todo: currencies have network-junctions
|
3409
3409
|
'address': address,
|
3410
3410
|
'amount': self.currency_to_precision(code, amount),
|
3411
3411
|
}
|
@@ -3418,7 +3418,7 @@ class gate(Exchange, ImplicitAPI):
|
|
3418
3418
|
request['chain'] = network
|
3419
3419
|
params = self.omit(params, 'network')
|
3420
3420
|
else:
|
3421
|
-
request['chain'] = currency['id']
|
3421
|
+
request['chain'] = currency['id'] # todo: currencies have network-junctions
|
3422
3422
|
response = await self.privateWithdrawalsPostWithdrawals(self.extend(request, params))
|
3423
3423
|
#
|
3424
3424
|
# {
|
@@ -4762,7 +4762,7 @@ class gate(Exchange, ImplicitAPI):
|
|
4762
4762
|
toId = self.convert_type_to_account(toAccount)
|
4763
4763
|
truncated = self.currency_to_precision(code, amount)
|
4764
4764
|
request = {
|
4765
|
-
'currency': currency['id'],
|
4765
|
+
'currency': currency['id'], # todo: currencies have network-junctions
|
4766
4766
|
'amount': truncated,
|
4767
4767
|
}
|
4768
4768
|
if not (fromId in self.options['accountsByType']):
|
@@ -4783,7 +4783,7 @@ class gate(Exchange, ImplicitAPI):
|
|
4783
4783
|
request['currency_pair'] = market['id']
|
4784
4784
|
params = self.omit(params, 'symbol')
|
4785
4785
|
if (toId == 'futures') or (toId == 'delivery') or (fromId == 'futures') or (fromId == 'delivery'):
|
4786
|
-
request['settle'] = currency['id']
|
4786
|
+
request['settle'] = currency['id'] # todo: currencies have network-junctions
|
4787
4787
|
response = await self.privateWalletPostTransfers(self.extend(request, params))
|
4788
4788
|
#
|
4789
4789
|
# according to the docs(however actual response seems to be an empty string '')
|
@@ -5396,7 +5396,7 @@ class gate(Exchange, ImplicitAPI):
|
|
5396
5396
|
await self.load_markets()
|
5397
5397
|
currency = self.currency(code)
|
5398
5398
|
request = {
|
5399
|
-
'currency': currency['id'].upper(),
|
5399
|
+
'currency': currency['id'].upper(), # todo: currencies have network-junctions
|
5400
5400
|
'amount': self.currency_to_precision(code, amount),
|
5401
5401
|
}
|
5402
5402
|
market = self.market(symbol)
|
@@ -5423,7 +5423,7 @@ class gate(Exchange, ImplicitAPI):
|
|
5423
5423
|
await self.load_markets()
|
5424
5424
|
currency = self.currency(code)
|
5425
5425
|
request = {
|
5426
|
-
'currency': currency['id'].upper(),
|
5426
|
+
'currency': currency['id'].upper(), # todo: currencies have network-junctions
|
5427
5427
|
'amount': self.currency_to_precision(code, amount),
|
5428
5428
|
}
|
5429
5429
|
response = await self.privateMarginPostCrossRepayments(self.extend(request, params))
|
@@ -5460,7 +5460,7 @@ class gate(Exchange, ImplicitAPI):
|
|
5460
5460
|
await self.load_markets()
|
5461
5461
|
currency = self.currency(code)
|
5462
5462
|
request = {
|
5463
|
-
'currency': currency['id'].upper(),
|
5463
|
+
'currency': currency['id'].upper(), # todo: currencies have network-junctions
|
5464
5464
|
'amount': self.currency_to_precision(code, amount),
|
5465
5465
|
}
|
5466
5466
|
response = None
|
@@ -5503,7 +5503,7 @@ class gate(Exchange, ImplicitAPI):
|
|
5503
5503
|
await self.load_markets()
|
5504
5504
|
currency = self.currency(code)
|
5505
5505
|
request = {
|
5506
|
-
'currency': currency['id'].upper(),
|
5506
|
+
'currency': currency['id'].upper(), # todo: currencies have network-junctions
|
5507
5507
|
'amount': self.currency_to_precision(code, amount),
|
5508
5508
|
}
|
5509
5509
|
response = await self.privateMarginPostCrossLoans(self.extend(request, params))
|
@@ -5651,7 +5651,7 @@ class gate(Exchange, ImplicitAPI):
|
|
5651
5651
|
raise NotSupported(self.id + ' modifyMarginHelper() not support self market type')
|
5652
5652
|
return self.parse_margin_modification(response, market)
|
5653
5653
|
|
5654
|
-
def parse_margin_modification(self, data, market: Market = None):
|
5654
|
+
def parse_margin_modification(self, data, market: Market = None) -> MarginModification:
|
5655
5655
|
#
|
5656
5656
|
# {
|
5657
5657
|
# "value": "11.9257",
|
@@ -5684,14 +5684,17 @@ class gate(Exchange, ImplicitAPI):
|
|
5684
5684
|
total = self.safe_number(data, 'margin')
|
5685
5685
|
return {
|
5686
5686
|
'info': data,
|
5687
|
-
'amount': None,
|
5688
|
-
'code': self.safe_value(market, 'quote'),
|
5689
5687
|
'symbol': market['symbol'],
|
5688
|
+
'type': None,
|
5689
|
+
'amount': None,
|
5690
5690
|
'total': total,
|
5691
|
+
'code': self.safe_value(market, 'quote'),
|
5691
5692
|
'status': 'ok',
|
5693
|
+
'timestamp': None,
|
5694
|
+
'datetime': None,
|
5692
5695
|
}
|
5693
5696
|
|
5694
|
-
async def reduce_margin(self, symbol: str, amount, params={}):
|
5697
|
+
async def reduce_margin(self, symbol: str, amount, params={}) -> MarginModification:
|
5695
5698
|
"""
|
5696
5699
|
remove margin from a position
|
5697
5700
|
:see: https://www.gate.io/docs/developers/apiv4/en/#update-position-margin
|
@@ -5703,7 +5706,7 @@ class gate(Exchange, ImplicitAPI):
|
|
5703
5706
|
"""
|
5704
5707
|
return await self.modify_margin_helper(symbol, -amount, params)
|
5705
5708
|
|
5706
|
-
async def add_margin(self, symbol: str, amount, params={}):
|
5709
|
+
async def add_margin(self, symbol: str, amount, params={}) -> MarginModification:
|
5707
5710
|
"""
|
5708
5711
|
add margin
|
5709
5712
|
:see: https://www.gate.io/docs/developers/apiv4/en/#update-position-margin
|
@@ -5993,7 +5996,7 @@ class gate(Exchange, ImplicitAPI):
|
|
5993
5996
|
if (type == 'spot') or (type == 'margin'):
|
5994
5997
|
if code is not None:
|
5995
5998
|
currency = self.currency(code)
|
5996
|
-
request['currency'] = currency['id']
|
5999
|
+
request['currency'] = currency['id'] # todo: currencies have network-junctions
|
5997
6000
|
if (type == 'swap') or (type == 'future'):
|
5998
6001
|
defaultSettle = 'usdt' if (type == 'swap') else 'btc'
|
5999
6002
|
settle = self.safe_string_lower(params, 'settle', defaultSettle)
|
@@ -6751,7 +6754,7 @@ class gate(Exchange, ImplicitAPI):
|
|
6751
6754
|
await self.load_markets()
|
6752
6755
|
currency = self.currency(code)
|
6753
6756
|
request = {
|
6754
|
-
'underlying': currency['code'] + '_USDT',
|
6757
|
+
'underlying': currency['code'] + '_USDT', # todo: currency['id'].upper() & network junctions
|
6755
6758
|
}
|
6756
6759
|
response = await self.publicOptionsGetContracts(self.extend(request, params))
|
6757
6760
|
#
|
ccxt/async_support/hitbtc.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.async_support.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.hitbtc import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Currency, Int, Leverage, MarginMode, MarginModes, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
9
|
+
from ccxt.base.types import Balances, Currency, Int, Leverage, MarginMode, MarginModes, MarginModification, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import ExchangeError
|
12
12
|
from ccxt.base.errors import PermissionDenied
|
@@ -1658,7 +1658,7 @@ class hitbtc(Exchange, ImplicitAPI):
|
|
1658
1658
|
request['from'] = self.iso8601(since)
|
1659
1659
|
request, params = self.handle_until_option('till', request, params)
|
1660
1660
|
if limit is not None:
|
1661
|
-
request['limit'] = limit
|
1661
|
+
request['limit'] = min(limit, 1000)
|
1662
1662
|
price = self.safe_string(params, 'price')
|
1663
1663
|
params = self.omit(params, 'price')
|
1664
1664
|
response = None
|
@@ -2999,7 +2999,7 @@ class hitbtc(Exchange, ImplicitAPI):
|
|
2999
2999
|
'previousFundingDatetime': None,
|
3000
3000
|
}
|
3001
3001
|
|
3002
|
-
async def modify_margin_helper(self, symbol: str, amount, type, params={}):
|
3002
|
+
async def modify_margin_helper(self, symbol: str, amount, type, params={}) -> MarginModification:
|
3003
3003
|
await self.load_markets()
|
3004
3004
|
market = self.market(symbol)
|
3005
3005
|
leverage = self.safe_string(params, 'leverage')
|
@@ -3052,19 +3052,43 @@ class hitbtc(Exchange, ImplicitAPI):
|
|
3052
3052
|
'type': type,
|
3053
3053
|
})
|
3054
3054
|
|
3055
|
-
def parse_margin_modification(self, data, market: Market = None):
|
3055
|
+
def parse_margin_modification(self, data, market: Market = None) -> MarginModification:
|
3056
|
+
#
|
3057
|
+
# addMargin/reduceMargin
|
3058
|
+
#
|
3059
|
+
# {
|
3060
|
+
# "symbol": "BTCUSDT_PERP",
|
3061
|
+
# "type": "isolated",
|
3062
|
+
# "leverage": "8.00",
|
3063
|
+
# "created_at": "2022-03-30T23:34:27.161Z",
|
3064
|
+
# "updated_at": "2022-03-30T23:34:27.161Z",
|
3065
|
+
# "currencies": [
|
3066
|
+
# {
|
3067
|
+
# "code": "USDT",
|
3068
|
+
# "margin_balance": "7.000000000000",
|
3069
|
+
# "reserved_orders": "0",
|
3070
|
+
# "reserved_positions": "0"
|
3071
|
+
# }
|
3072
|
+
# ],
|
3073
|
+
# "positions": null
|
3074
|
+
# }
|
3075
|
+
#
|
3056
3076
|
currencies = self.safe_value(data, 'currencies', [])
|
3057
3077
|
currencyInfo = self.safe_value(currencies, 0)
|
3078
|
+
datetime = self.safe_string(data, 'updated_at')
|
3058
3079
|
return {
|
3059
3080
|
'info': data,
|
3081
|
+
'symbol': market['symbol'],
|
3060
3082
|
'type': None,
|
3061
3083
|
'amount': None,
|
3084
|
+
'total': None,
|
3062
3085
|
'code': self.safe_string(currencyInfo, 'code'),
|
3063
|
-
'symbol': market['symbol'],
|
3064
3086
|
'status': None,
|
3087
|
+
'timestamp': self.parse8601(datetime),
|
3088
|
+
'datetime': datetime,
|
3065
3089
|
}
|
3066
3090
|
|
3067
|
-
async def reduce_margin(self, symbol: str, amount, params={}):
|
3091
|
+
async def reduce_margin(self, symbol: str, amount, params={}) -> MarginModification:
|
3068
3092
|
"""
|
3069
3093
|
remove margin from a position
|
3070
3094
|
:see: https://api.hitbtc.com/#create-update-margin-account-2
|
@@ -3080,7 +3104,7 @@ class hitbtc(Exchange, ImplicitAPI):
|
|
3080
3104
|
raise BadRequest(self.id + ' reduceMargin() on hitbtc requires the amount to be 0 and that will remove the entire margin amount')
|
3081
3105
|
return await self.modify_margin_helper(symbol, amount, 'reduce', params)
|
3082
3106
|
|
3083
|
-
async def add_margin(self, symbol: str, amount, params={}):
|
3107
|
+
async def add_margin(self, symbol: str, amount, params={}) -> MarginModification:
|
3084
3108
|
"""
|
3085
3109
|
add margin
|
3086
3110
|
:see: https://api.hitbtc.com/#create-update-margin-account-2
|
ccxt/async_support/htx.py
CHANGED
@@ -2834,7 +2834,7 @@ class htx(Exchange, ImplicitAPI):
|
|
2834
2834
|
untilSeconds = self.parse_to_int(until / 1000) if (until is not None) else None
|
2835
2835
|
if market['contract']:
|
2836
2836
|
if limit is not None:
|
2837
|
-
request['size'] = limit # when using limit: from & to are ignored
|
2837
|
+
request['size'] = min(limit, 2000) # when using limit: from & to are ignored
|
2838
2838
|
# https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-kline-data
|
2839
2839
|
else:
|
2840
2840
|
limit = 2000 # only used for from/to calculation
|
@@ -2898,7 +2898,7 @@ class htx(Exchange, ImplicitAPI):
|
|
2898
2898
|
useHistorical, params = self.handle_option_and_params(params, 'fetchOHLCV', 'useHistoricalEndpointForSpot', True)
|
2899
2899
|
if not useHistorical:
|
2900
2900
|
if limit is not None:
|
2901
|
-
request['size'] = min(
|
2901
|
+
request['size'] = min(limit, 2000) # max 2000
|
2902
2902
|
response = await self.spotPublicGetMarketHistoryKline(self.extend(request, params))
|
2903
2903
|
else:
|
2904
2904
|
# "from & to" only available for the self endpoint
|
ccxt/async_support/huobijp.py
CHANGED
@@ -927,7 +927,7 @@ class huobijp(Exchange, ImplicitAPI):
|
|
927
927
|
'period': self.safe_string(self.timeframes, timeframe, timeframe),
|
928
928
|
}
|
929
929
|
if limit is not None:
|
930
|
-
request['size'] = limit
|
930
|
+
request['size'] = min(limit, 2000)
|
931
931
|
response = await self.marketGetHistoryKline(self.extend(request, params))
|
932
932
|
#
|
933
933
|
# {
|
@@ -5,7 +5,8 @@
|
|
5
5
|
|
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, Int, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Trade, TransferEntry
|
9
10
|
from typing import List
|
10
11
|
from ccxt.base.errors import ExchangeError
|
11
12
|
from ccxt.base.errors import ArgumentsRequired
|
@@ -32,7 +33,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
32
33
|
'pro': True,
|
33
34
|
'has': {
|
34
35
|
'CORS': None,
|
35
|
-
'spot':
|
36
|
+
'spot': True,
|
36
37
|
'margin': False,
|
37
38
|
'swap': True,
|
38
39
|
'future': True,
|
@@ -165,6 +166,10 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
165
166
|
'taker': self.parse_number('0.00035'),
|
166
167
|
'maker': self.parse_number('0.0001'),
|
167
168
|
},
|
169
|
+
'spot': {
|
170
|
+
'taker': self.parse_number('0.00035'),
|
171
|
+
'maker': self.parse_number('0.0001'),
|
172
|
+
},
|
168
173
|
},
|
169
174
|
'requiredCredentials': {
|
170
175
|
'apiKey': False,
|
@@ -192,6 +197,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
192
197
|
'commonCurrencies': {
|
193
198
|
},
|
194
199
|
'options': {
|
200
|
+
'defaultType': 'swap',
|
195
201
|
'sandboxMode': False,
|
196
202
|
'defaultSlippage': 0.05,
|
197
203
|
'zeroAddress': '0x0000000000000000000000000000000000000000',
|
@@ -257,6 +263,22 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
257
263
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
258
264
|
:returns dict[]: an array of objects representing market data
|
259
265
|
"""
|
266
|
+
rawPromises = [
|
267
|
+
self.fetch_swap_markets(params),
|
268
|
+
self.fetch_spot_markets(params),
|
269
|
+
]
|
270
|
+
promises = await asyncio.gather(*rawPromises)
|
271
|
+
swapMarkets = promises[0]
|
272
|
+
spotMarkets = promises[1]
|
273
|
+
return self.array_concat(swapMarkets, spotMarkets)
|
274
|
+
|
275
|
+
async def fetch_swap_markets(self, params={}) -> List[Market]:
|
276
|
+
"""
|
277
|
+
retrieves data on all swap markets for hyperliquid
|
278
|
+
:see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-asset-contexts-includes-mark-price-current-funding-open-interest-etc
|
279
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
280
|
+
:returns dict[]: an array of objects representing market data
|
281
|
+
"""
|
260
282
|
request = {
|
261
283
|
'type': 'metaAndAssetCtxs',
|
262
284
|
}
|
@@ -304,6 +326,129 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
304
326
|
result.append(data)
|
305
327
|
return self.parse_markets(result)
|
306
328
|
|
329
|
+
async def fetch_spot_markets(self, params={}) -> List[Market]:
|
330
|
+
"""
|
331
|
+
retrieves data on all spot markets for hyperliquid
|
332
|
+
:see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-asset-contexts-includes-mark-price-current-funding-open-interest-etc
|
333
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
334
|
+
:returns dict[]: an array of objects representing market data
|
335
|
+
"""
|
336
|
+
request = {
|
337
|
+
'type': 'spotMetaAndAssetCtxs',
|
338
|
+
}
|
339
|
+
response = await self.publicPostInfo(self.extend(request, params))
|
340
|
+
#
|
341
|
+
# [
|
342
|
+
# {
|
343
|
+
# 'tokens': [
|
344
|
+
# {
|
345
|
+
# 'name': 'USDC',
|
346
|
+
# 'szDecimals': '8',
|
347
|
+
# 'weiDecimals': '8',
|
348
|
+
# },
|
349
|
+
# {
|
350
|
+
# 'name': 'PURR',
|
351
|
+
# 'szDecimals': '0',
|
352
|
+
# 'weiDecimals': '5',
|
353
|
+
# },
|
354
|
+
# ],
|
355
|
+
# 'universe': [
|
356
|
+
# {
|
357
|
+
# 'name': 'PURR/USDC',
|
358
|
+
# 'tokens': [
|
359
|
+
# 1,
|
360
|
+
# 0,
|
361
|
+
# ],
|
362
|
+
# },
|
363
|
+
# ],
|
364
|
+
# },
|
365
|
+
# [
|
366
|
+
# {
|
367
|
+
# 'dayNtlVlm': '264250385.14640012',
|
368
|
+
# 'markPx': '0.018314',
|
369
|
+
# 'midPx': '0.0182235',
|
370
|
+
# 'prevDayPx': '0.017427',
|
371
|
+
# },
|
372
|
+
# ],
|
373
|
+
# ]
|
374
|
+
#
|
375
|
+
first = self.safe_dict(response, 0, {})
|
376
|
+
meta = self.safe_list(first, 'universe', [])
|
377
|
+
tokens = self.safe_list(first, 'tokens', [])
|
378
|
+
markets = []
|
379
|
+
for i in range(0, len(meta)):
|
380
|
+
market = self.safe_dict(meta, i, {})
|
381
|
+
marketName = self.safe_string(market, 'name')
|
382
|
+
marketParts = marketName.split('/')
|
383
|
+
baseName = self.safe_string(marketParts, 0)
|
384
|
+
quoteId = self.safe_string(marketParts, 1)
|
385
|
+
base = self.safe_currency_code(baseName)
|
386
|
+
quote = self.safe_currency_code(quoteId)
|
387
|
+
symbol = base + '/' + quote
|
388
|
+
fees = self.safe_dict(self.fees, 'spot', {})
|
389
|
+
taker = self.safe_number(fees, 'taker')
|
390
|
+
maker = self.safe_number(fees, 'maker')
|
391
|
+
tokensPos = self.safe_list(market, 'tokens', [])
|
392
|
+
baseTokenPos = self.safe_integer(tokensPos, 0)
|
393
|
+
quoteTokenPos = self.safe_integer(tokensPos, 1)
|
394
|
+
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')
|
398
|
+
baseId = self.number_to_string(i + 10000)
|
399
|
+
markets.append(self.safe_market_structure({
|
400
|
+
'id': baseId,
|
401
|
+
'symbol': symbol,
|
402
|
+
'base': base,
|
403
|
+
'quote': quote,
|
404
|
+
'settle': None,
|
405
|
+
'baseId': baseId,
|
406
|
+
'quoteId': quoteId,
|
407
|
+
'settleId': None,
|
408
|
+
'type': 'spot',
|
409
|
+
'spot': True,
|
410
|
+
'margin': None,
|
411
|
+
'swap': False,
|
412
|
+
'future': False,
|
413
|
+
'option': False,
|
414
|
+
'active': True,
|
415
|
+
'contract': False,
|
416
|
+
'linear': True,
|
417
|
+
'inverse': False,
|
418
|
+
'taker': taker,
|
419
|
+
'maker': maker,
|
420
|
+
'contractSize': None,
|
421
|
+
'expiry': None,
|
422
|
+
'expiryDatetime': None,
|
423
|
+
'strike': None,
|
424
|
+
'optionType': None,
|
425
|
+
'precision': {
|
426
|
+
'amount': self.parse_number(self.parse_precision(baseDecimals)), # decimal places
|
427
|
+
'price': quoteDecimals, # significant digits
|
428
|
+
},
|
429
|
+
'limits': {
|
430
|
+
'leverage': {
|
431
|
+
'min': None,
|
432
|
+
'max': None,
|
433
|
+
},
|
434
|
+
'amount': {
|
435
|
+
'min': None,
|
436
|
+
'max': None,
|
437
|
+
},
|
438
|
+
'price': {
|
439
|
+
'min': None,
|
440
|
+
'max': None,
|
441
|
+
},
|
442
|
+
'cost': {
|
443
|
+
'min': None,
|
444
|
+
'max': None,
|
445
|
+
},
|
446
|
+
},
|
447
|
+
'created': None,
|
448
|
+
'info': market,
|
449
|
+
}))
|
450
|
+
return markets
|
451
|
+
|
307
452
|
def parse_market(self, market) -> Market:
|
308
453
|
#
|
309
454
|
# {
|
@@ -398,12 +543,17 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
398
543
|
:see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-a-users-state
|
399
544
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
400
545
|
:param str [params.user]: user address, will default to self.walletAddress if not provided
|
546
|
+
:param str [params.type]: wallet type, ['spot', 'swap'], defaults to swap
|
401
547
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
402
548
|
"""
|
403
549
|
userAddress = None
|
404
550
|
userAddress, params = self.handle_public_address('fetchBalance', params)
|
551
|
+
type = None
|
552
|
+
type, params = self.handle_market_type_and_params('fetchBalance', None, params)
|
553
|
+
isSpot = (type == 'spot')
|
554
|
+
reqType = 'spotClearinghouseState' if (isSpot) else 'clearinghouseState'
|
405
555
|
request = {
|
406
|
-
'type':
|
556
|
+
'type': reqType,
|
407
557
|
'user': userAddress,
|
408
558
|
}
|
409
559
|
response = await self.publicPostInfo(self.extend(request, params))
|
@@ -426,7 +576,35 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
426
576
|
# "time": "1704261007014",
|
427
577
|
# "withdrawable": "100.0"
|
428
578
|
# }
|
579
|
+
# spot
|
580
|
+
#
|
581
|
+
# {
|
582
|
+
# "balances":[
|
583
|
+
# {
|
584
|
+
# "coin":"USDC",
|
585
|
+
# "hold":"0.0",
|
586
|
+
# "total":"1481.844"
|
587
|
+
# },
|
588
|
+
# {
|
589
|
+
# "coin":"PURR",
|
590
|
+
# "hold":"0.0",
|
591
|
+
# "total":"999.65004"
|
592
|
+
# }
|
593
|
+
# }
|
429
594
|
#
|
595
|
+
balances = self.safe_list(response, 'balances')
|
596
|
+
if balances is not None:
|
597
|
+
spotBalances = {'info': response}
|
598
|
+
for i in range(0, len(balances)):
|
599
|
+
balance = balances[i]
|
600
|
+
code = self.safe_currency_code(self.safe_string(balance, 'coin'))
|
601
|
+
account = self.account()
|
602
|
+
total = self.safe_string(balance, 'total')
|
603
|
+
free = self.safe_string(balance, 'hold')
|
604
|
+
account['total'] = total
|
605
|
+
account['free'] = free
|
606
|
+
spotBalances[code] = account
|
607
|
+
return self.safe_balance(spotBalances)
|
430
608
|
data = self.safe_dict(response, 'marginSummary', {})
|
431
609
|
result = {
|
432
610
|
'info': response,
|
@@ -915,6 +1093,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
915
1093
|
:param str symbol: unified symbol of the market the order was made in
|
916
1094
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
917
1095
|
:param str [params.clientOrderId]: client order id,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
|
1096
|
+
:param str [params.vaultAddress]: the vault address for order
|
918
1097
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
919
1098
|
"""
|
920
1099
|
return await self.cancel_orders([id], symbol, params)
|
@@ -928,6 +1107,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
928
1107
|
:param str [symbol]: unified market symbol
|
929
1108
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
930
1109
|
:param string|str[] [params.clientOrderId]: client order ids,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
|
1110
|
+
:param str [params.vaultAddress]: the vault address
|
931
1111
|
:returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
932
1112
|
"""
|
933
1113
|
self.check_required_credentials()
|
@@ -1377,7 +1557,10 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1377
1557
|
coin = self.safe_string(entry, 'coin')
|
1378
1558
|
marketId = None
|
1379
1559
|
if coin is not None:
|
1380
|
-
|
1560
|
+
if coin.find('/') > -1:
|
1561
|
+
marketId = coin
|
1562
|
+
else:
|
1563
|
+
marketId = coin + '/USDC:USDC'
|
1381
1564
|
if self.safe_string(entry, 'id') is None:
|
1382
1565
|
market = self.safe_market(marketId, None)
|
1383
1566
|
else:
|
@@ -1772,7 +1955,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1772
1955
|
#
|
1773
1956
|
return response
|
1774
1957
|
|
1775
|
-
async def add_margin(self, symbol: str, amount, params={}):
|
1958
|
+
async def add_margin(self, symbol: str, amount, params={}) -> MarginModification:
|
1776
1959
|
"""
|
1777
1960
|
add margin
|
1778
1961
|
:see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#update-isolated-margin
|
@@ -1783,7 +1966,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1783
1966
|
"""
|
1784
1967
|
return await self.modify_margin_helper(symbol, amount, 'add', params)
|
1785
1968
|
|
1786
|
-
async def reduce_margin(self, symbol: str, amount, params={}):
|
1969
|
+
async def reduce_margin(self, symbol: str, amount, params={}) -> MarginModification:
|
1787
1970
|
"""
|
1788
1971
|
:see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#update-isolated-margin
|
1789
1972
|
remove margin from a position
|
@@ -1794,7 +1977,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1794
1977
|
"""
|
1795
1978
|
return await self.modify_margin_helper(symbol, amount, 'reduce', params)
|
1796
1979
|
|
1797
|
-
async def modify_margin_helper(self, symbol: str, amount, type, params={}):
|
1980
|
+
async def modify_margin_helper(self, symbol: str, amount, type, params={}) -> MarginModification:
|
1798
1981
|
await self.load_markets()
|
1799
1982
|
market = self.market(symbol)
|
1800
1983
|
asset = self.parse_to_int(market['baseId'])
|
@@ -1828,10 +2011,27 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1828
2011
|
# 'status': 'ok'
|
1829
2012
|
# }
|
1830
2013
|
#
|
1831
|
-
return response
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
2014
|
+
return self.extend(self.parse_margin_modification(response, market), {
|
2015
|
+
'code': self.safe_string(response, 'status'),
|
2016
|
+
})
|
2017
|
+
|
2018
|
+
def parse_margin_modification(self, data, market: Market = None) -> MarginModification:
|
2019
|
+
#
|
2020
|
+
# {
|
2021
|
+
# 'type': 'default'
|
2022
|
+
# }
|
2023
|
+
#
|
2024
|
+
return {
|
2025
|
+
'info': data,
|
2026
|
+
'symbol': self.safe_symbol(None, market),
|
2027
|
+
'type': None,
|
2028
|
+
'amount': None,
|
2029
|
+
'total': None,
|
2030
|
+
'code': self.safe_string(market, 'settle'),
|
2031
|
+
'status': None,
|
2032
|
+
'timestamp': None,
|
2033
|
+
'datetime': None,
|
2034
|
+
}
|
1835
2035
|
|
1836
2036
|
async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
|
1837
2037
|
"""
|
@@ -1839,23 +2039,49 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1839
2039
|
:see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#l1-usdc-transfer
|
1840
2040
|
:param str code: unified currency code
|
1841
2041
|
:param float amount: amount to transfer
|
1842
|
-
:param str fromAccount: account to transfer from
|
1843
|
-
:param str toAccount: account to transfer to
|
2042
|
+
:param str fromAccount: account to transfer from *spot, swap*
|
2043
|
+
:param str toAccount: account to transfer to *swap, spot or address*
|
1844
2044
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2045
|
+
:param str [params.vaultAddress]: the vault address for order
|
1845
2046
|
:returns dict: a `transfer structure <https://docs.ccxt.com/#/?id=transfer-structure>`
|
1846
2047
|
"""
|
1847
2048
|
self.check_required_credentials()
|
1848
2049
|
await self.load_markets()
|
2050
|
+
isSandboxMode = self.safe_bool(self.options, 'sandboxMode')
|
2051
|
+
nonce = self.milliseconds()
|
2052
|
+
if self.in_array(fromAccount, ['spot', 'swap', 'perp']):
|
2053
|
+
# handle swap <> spot account transfer
|
2054
|
+
if not self.in_array(toAccount, ['spot', 'swap', 'perp']):
|
2055
|
+
raise NotSupported(self.id + 'transfer() only support spot <> swap transfer')
|
2056
|
+
vaultAddress = self.format_vault_address(self.safe_string(params, 'vaultAddress'))
|
2057
|
+
params = self.omit(params, 'vaultAddress')
|
2058
|
+
toPerp = (toAccount == 'perp') or (toAccount == 'swap')
|
2059
|
+
action = {
|
2060
|
+
'type': 'spotUser',
|
2061
|
+
'classTransfer': {
|
2062
|
+
'usdc': amount,
|
2063
|
+
'toPerp': toPerp,
|
2064
|
+
},
|
2065
|
+
}
|
2066
|
+
signature = self.sign_l1_action(action, nonce, vaultAddress)
|
2067
|
+
innerRequest = {
|
2068
|
+
'action': self.extend(action, params),
|
2069
|
+
'nonce': nonce,
|
2070
|
+
'signature': signature,
|
2071
|
+
}
|
2072
|
+
if vaultAddress is not None:
|
2073
|
+
innerRequest['vaultAddress'] = vaultAddress
|
2074
|
+
transferResponse = await self.privatePostExchange(innerRequest)
|
2075
|
+
return transferResponse
|
2076
|
+
# handle sub-account/different account transfer
|
1849
2077
|
self.check_address(toAccount)
|
1850
2078
|
if code is not None:
|
1851
2079
|
code = code.upper()
|
1852
2080
|
if code != 'USDC':
|
1853
2081
|
raise NotSupported(self.id + 'withdraw() only support USDC')
|
1854
|
-
isSandboxMode = self.safe_bool(self.options, 'sandboxMode')
|
1855
|
-
nonce = self.milliseconds()
|
1856
2082
|
payload = {
|
1857
2083
|
'destination': toAccount,
|
1858
|
-
'amount':
|
2084
|
+
'amount': self.number_to_string(amount),
|
1859
2085
|
'time': nonce,
|
1860
2086
|
}
|
1861
2087
|
sig = self.build_transfer_sig(payload)
|