ccxt 4.4.93__py2.py3-none-any.whl → 4.4.94__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.
- ccxt/__init__.py +1 -1
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/bybit.py +2 -2
- ccxt/async_support/coinbase.py +4 -1
- ccxt/async_support/coinmetro.py +15 -3
- ccxt/async_support/htx.py +5 -1
- ccxt/async_support/hyperliquid.py +124 -32
- ccxt/async_support/okx.py +10 -3
- ccxt/async_support/wavesexchange.py +12 -2
- ccxt/base/exchange.py +42 -20
- ccxt/bybit.py +2 -2
- ccxt/coinbase.py +4 -1
- ccxt/coinmetro.py +14 -3
- ccxt/htx.py +5 -1
- ccxt/hyperliquid.py +124 -32
- ccxt/okx.py +10 -3
- ccxt/pro/__init__.py +1 -1
- ccxt/test/tests_async.py +17 -15
- ccxt/test/tests_sync.py +17 -15
- ccxt/wavesexchange.py +12 -2
- {ccxt-4.4.93.dist-info → ccxt-4.4.94.dist-info}/METADATA +4 -4
- {ccxt-4.4.93.dist-info → ccxt-4.4.94.dist-info}/RECORD +26 -26
- {ccxt-4.4.93.dist-info → ccxt-4.4.94.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.93.dist-info → ccxt-4.4.94.dist-info}/WHEEL +0 -0
- {ccxt-4.4.93.dist-info → ccxt-4.4.94.dist-info}/top_level.txt +0 -0
ccxt/base/exchange.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
|
7
|
-
__version__ = '4.4.
|
7
|
+
__version__ = '4.4.94'
|
8
8
|
|
9
9
|
# -----------------------------------------------------------------------------
|
10
10
|
|
@@ -3808,8 +3808,7 @@ class Exchange(object):
|
|
3808
3808
|
|
3809
3809
|
def safe_ticker(self, ticker: dict, market: Market = None):
|
3810
3810
|
open = self.omit_zero(self.safe_string(ticker, 'open'))
|
3811
|
-
close = self.omit_zero(self.
|
3812
|
-
last = self.omit_zero(self.safe_string(ticker, 'last'))
|
3811
|
+
close = self.omit_zero(self.safe_string_2(ticker, 'close', 'last'))
|
3813
3812
|
change = self.omit_zero(self.safe_string(ticker, 'change'))
|
3814
3813
|
percentage = self.omit_zero(self.safe_string(ticker, 'percentage'))
|
3815
3814
|
average = self.omit_zero(self.safe_string(ticker, 'average'))
|
@@ -3818,29 +3817,52 @@ class Exchange(object):
|
|
3818
3817
|
quoteVolume = self.safe_string(ticker, 'quoteVolume')
|
3819
3818
|
if vwap is None:
|
3820
3819
|
vwap = Precise.string_div(self.omit_zero(quoteVolume), baseVolume)
|
3821
|
-
|
3822
|
-
|
3823
|
-
|
3824
|
-
|
3825
|
-
|
3826
|
-
|
3827
|
-
|
3828
|
-
if average is None:
|
3820
|
+
# calculate open
|
3821
|
+
if change is not None:
|
3822
|
+
if close is None and average is not None:
|
3823
|
+
close = Precise.string_add(average, Precise.string_div(change, '2'))
|
3824
|
+
if open is None and close is not None:
|
3825
|
+
open = Precise.string_sub(close, change)
|
3826
|
+
elif percentage is not None:
|
3827
|
+
if close is None and average is not None:
|
3828
|
+
openAddClose = Precise.string_mul(average, '2')
|
3829
|
+
# openAddClose = open * (1 + (100 + percentage)/100)
|
3830
|
+
denominator = Precise.string_add('2', Precise.string_div(percentage, '100'))
|
3831
|
+
calcOpen = open if (open is not None) else Precise.string_div(openAddClose, denominator)
|
3832
|
+
close = Precise.string_mul(calcOpen, Precise.string_add('1', Precise.string_div(percentage, '100')))
|
3833
|
+
if open is None and close is not None:
|
3834
|
+
open = Precise.string_div(close, Precise.string_add('1', Precise.string_div(percentage, '100')))
|
3835
|
+
# change
|
3836
|
+
if change is None:
|
3837
|
+
if close is not None and open is not None:
|
3838
|
+
change = Precise.string_sub(close, open)
|
3839
|
+
elif close is not None and percentage is not None:
|
3840
|
+
change = Precise.string_mul(Precise.string_div(percentage, '100'), Precise.string_div(close, '100'))
|
3841
|
+
elif open is not None and percentage is not None:
|
3842
|
+
change = Precise.string_mul(open, Precise.string_div(percentage, '100'))
|
3843
|
+
# calculate things according to "open"(similar can be done with "close")
|
3844
|
+
if open is not None:
|
3845
|
+
# percentage(using change)
|
3846
|
+
if percentage is None and change is not None:
|
3847
|
+
percentage = Precise.string_mul(Precise.string_div(change, open), '100')
|
3848
|
+
# close(using change)
|
3849
|
+
if close is None and change is not None:
|
3850
|
+
close = Precise.string_add(open, change)
|
3851
|
+
# close(using average)
|
3852
|
+
if close is None and average is not None:
|
3853
|
+
close = Precise.string_mul(average, '2')
|
3854
|
+
# average
|
3855
|
+
if average is None and close is not None:
|
3829
3856
|
precision = 18
|
3830
3857
|
if market is not None and self.is_tick_precision():
|
3831
3858
|
marketPrecision = self.safe_dict(market, 'precision')
|
3832
3859
|
precisionPrice = self.safe_string(marketPrecision, 'price')
|
3833
3860
|
if precisionPrice is not None:
|
3834
3861
|
precision = self.precision_from_string(precisionPrice)
|
3835
|
-
average = Precise.string_div(Precise.string_add(
|
3836
|
-
if (percentage is None) and (change is not None) and (open is not None) and Precise.string_gt(open, '0'):
|
3837
|
-
percentage = Precise.string_mul(Precise.string_div(change, open), '100')
|
3838
|
-
if (change is None) and (percentage is not None) and (open is not None):
|
3839
|
-
change = Precise.string_div(Precise.string_mul(percentage, open), '100')
|
3840
|
-
if (open is None) and (last is not None) and (change is not None):
|
3841
|
-
open = Precise.string_sub(last, change)
|
3862
|
+
average = Precise.string_div(Precise.string_add(open, close), '2', precision)
|
3842
3863
|
# timestamp and symbol operations don't belong in safeTicker
|
3843
3864
|
# they should be done in the derived classes
|
3865
|
+
closeParsed = self.parse_number(self.omit_zero(close))
|
3844
3866
|
return self.extend(ticker, {
|
3845
3867
|
'bid': self.parse_number(self.omit_zero(self.safe_string(ticker, 'bid'))),
|
3846
3868
|
'bidVolume': self.safe_number(ticker, 'bidVolume'),
|
@@ -3849,8 +3871,8 @@ class Exchange(object):
|
|
3849
3871
|
'high': self.parse_number(self.omit_zero(self.safe_string(ticker, 'high'))),
|
3850
3872
|
'low': self.parse_number(self.omit_zero(self.safe_string(ticker, 'low'))),
|
3851
3873
|
'open': self.parse_number(self.omit_zero(open)),
|
3852
|
-
'close':
|
3853
|
-
'last':
|
3874
|
+
'close': closeParsed,
|
3875
|
+
'last': closeParsed,
|
3854
3876
|
'change': self.parse_number(change),
|
3855
3877
|
'percentage': self.parse_number(percentage),
|
3856
3878
|
'average': self.parse_number(average),
|
ccxt/bybit.py
CHANGED
@@ -3751,7 +3751,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
3751
3751
|
isTakeProfit = takeProfitPrice is not None
|
3752
3752
|
orderRequest = self.create_order_request(symbol, type, side, amount, price, params, enableUnifiedAccount)
|
3753
3753
|
defaultMethod = None
|
3754
|
-
if isTrailingAmountOrder or isStopLoss or isTakeProfit:
|
3754
|
+
if (isTrailingAmountOrder or isStopLoss or isTakeProfit) and not market['spot']:
|
3755
3755
|
defaultMethod = 'privatePostV5PositionTradingStop'
|
3756
3756
|
else:
|
3757
3757
|
defaultMethod = 'privatePostV5OrderCreate'
|
@@ -3827,7 +3827,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
3827
3827
|
isLimit = lowerCaseType == 'limit'
|
3828
3828
|
isBuy = side == 'buy'
|
3829
3829
|
defaultMethod = None
|
3830
|
-
if isTrailingAmountOrder or isStopLossTriggerOrder or isTakeProfitTriggerOrder:
|
3830
|
+
if (isTrailingAmountOrder or isStopLossTriggerOrder or isTakeProfitTriggerOrder) and not market['spot']:
|
3831
3831
|
defaultMethod = 'privatePostV5PositionTradingStop'
|
3832
3832
|
else:
|
3833
3833
|
defaultMethod = 'privatePostV5OrderCreate'
|
ccxt/coinbase.py
CHANGED
@@ -13,6 +13,7 @@ from ccxt.base.errors import AuthenticationError
|
|
13
13
|
from ccxt.base.errors import PermissionDenied
|
14
14
|
from ccxt.base.errors import ArgumentsRequired
|
15
15
|
from ccxt.base.errors import BadRequest
|
16
|
+
from ccxt.base.errors import InsufficientFunds
|
16
17
|
from ccxt.base.errors import InvalidOrder
|
17
18
|
from ccxt.base.errors import OrderNotFound
|
18
19
|
from ccxt.base.errors import NotSupported
|
@@ -332,12 +333,14 @@ class coinbase(Exchange, ImplicitAPI):
|
|
332
333
|
'rate_limit_exceeded': RateLimitExceeded, # 429 Rate limit exceeded
|
333
334
|
'internal_server_error': ExchangeError, # 500 Internal server error
|
334
335
|
'UNSUPPORTED_ORDER_CONFIGURATION': BadRequest,
|
335
|
-
'INSUFFICIENT_FUND':
|
336
|
+
'INSUFFICIENT_FUND': InsufficientFunds,
|
336
337
|
'PERMISSION_DENIED': PermissionDenied,
|
337
338
|
'INVALID_ARGUMENT': BadRequest,
|
338
339
|
'PREVIEW_STOP_PRICE_ABOVE_LAST_TRADE_PRICE': InvalidOrder,
|
340
|
+
'PREVIEW_INSUFFICIENT_FUND': InsufficientFunds,
|
339
341
|
},
|
340
342
|
'broad': {
|
343
|
+
'Insufficient balance in source account': InsufficientFunds,
|
341
344
|
'request timestamp expired': InvalidNonce, # {"errors":[{"id":"authentication_error","message":"request timestamp expired"}]}
|
342
345
|
'order with self orderID was not found': OrderNotFound, # {"error":"unknown","error_details":"order with self orderID was not found","message":"order with self orderID was not found"}
|
343
346
|
},
|
ccxt/coinmetro.py
CHANGED
@@ -220,6 +220,7 @@ class coinmetro(Exchange, ImplicitAPI):
|
|
220
220
|
'options': {
|
221
221
|
'currenciesByIdForParseMarket': None,
|
222
222
|
'currencyIdsListForParseMarket': ['QRDO'],
|
223
|
+
'skippedMarkets': ['VXVUSDT'], # broken markets which do not have enough info in API
|
223
224
|
},
|
224
225
|
'features': {
|
225
226
|
'spot': {
|
@@ -439,9 +440,12 @@ class coinmetro(Exchange, ImplicitAPI):
|
|
439
440
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
440
441
|
:returns dict[]: an array of objects representing market data
|
441
442
|
"""
|
442
|
-
|
443
|
+
promises = []
|
444
|
+
promises.append(self.publicGetMarkets(params))
|
443
445
|
if self.safe_value(self.options, 'currenciesByIdForParseMarket') is None:
|
444
|
-
self.fetch_currencies()
|
446
|
+
promises.append(self.fetch_currencies())
|
447
|
+
responses = promises
|
448
|
+
response = responses[0]
|
445
449
|
#
|
446
450
|
# [
|
447
451
|
# {
|
@@ -457,7 +461,14 @@ class coinmetro(Exchange, ImplicitAPI):
|
|
457
461
|
# ...
|
458
462
|
# ]
|
459
463
|
#
|
460
|
-
|
464
|
+
skippedMarkets = self.safe_list(self.options, 'skippedMarkets', [])
|
465
|
+
result = []
|
466
|
+
for i in range(0, len(response)):
|
467
|
+
market = self.parse_market(response[i])
|
468
|
+
if self.in_array(market['id'], skippedMarkets):
|
469
|
+
continue
|
470
|
+
result.append(market)
|
471
|
+
return result
|
461
472
|
|
462
473
|
def parse_market(self, market: dict) -> Market:
|
463
474
|
id = self.safe_string(market, 'pair')
|
ccxt/htx.py
CHANGED
@@ -6576,12 +6576,16 @@ class htx(Exchange, ImplicitAPI):
|
|
6576
6576
|
paginate = False
|
6577
6577
|
paginate, params = self.handle_option_and_params(params, 'fetchFundingRateHistory', 'paginate')
|
6578
6578
|
if paginate:
|
6579
|
-
return self.fetch_paginated_call_cursor('fetchFundingRateHistory', symbol, since, limit, params, '
|
6579
|
+
return self.fetch_paginated_call_cursor('fetchFundingRateHistory', symbol, since, limit, params, 'current_page', 'page_index', 1, 50)
|
6580
6580
|
self.load_markets()
|
6581
6581
|
market = self.market(symbol)
|
6582
6582
|
request: dict = {
|
6583
6583
|
'contract_code': market['id'],
|
6584
6584
|
}
|
6585
|
+
if limit is not None:
|
6586
|
+
request['page_size'] = limit
|
6587
|
+
else:
|
6588
|
+
request['page_size'] = 50 # max
|
6585
6589
|
response = None
|
6586
6590
|
if market['inverse']:
|
6587
6591
|
response = self.contractPublicGetSwapApiV1SwapHistoricalFundingRate(self.extend(request, params))
|
ccxt/hyperliquid.py
CHANGED
@@ -353,6 +353,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
353
353
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
354
354
|
:returns dict: an associative dictionary of currencies
|
355
355
|
"""
|
356
|
+
if self.check_required_credentials(False):
|
357
|
+
self.handle_builder_fee_approval()
|
356
358
|
request: dict = {
|
357
359
|
'type': 'meta',
|
358
360
|
}
|
@@ -626,6 +628,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
626
628
|
'quote': quote,
|
627
629
|
'settle': None,
|
628
630
|
'baseId': baseId,
|
631
|
+
'baseName': baseName,
|
629
632
|
'quoteId': quoteId,
|
630
633
|
'settleId': None,
|
631
634
|
'type': 'spot',
|
@@ -728,6 +731,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
728
731
|
'quote': quote,
|
729
732
|
'settle': settle,
|
730
733
|
'baseId': baseId,
|
734
|
+
'baseName': baseName,
|
731
735
|
'quoteId': quoteId,
|
732
736
|
'settleId': settleId,
|
733
737
|
'type': 'swap',
|
@@ -784,6 +788,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
784
788
|
:param str [params.user]: user address, will default to self.walletAddress if not provided
|
785
789
|
:param str [params.type]: wallet type, ['spot', 'swap'], defaults to swap
|
786
790
|
:param str [params.marginMode]: 'cross' or 'isolated', for margin trading, uses self.options.defaultMarginMode if not passed, defaults to None/None/None
|
791
|
+
:param str [params.subAccountAddress]: sub account user address
|
787
792
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
788
793
|
"""
|
789
794
|
userAddress = None
|
@@ -793,9 +798,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
793
798
|
marginMode = None
|
794
799
|
marginMode, params = self.handle_margin_mode_and_params('fetchBalance', params)
|
795
800
|
isSpot = (type == 'spot')
|
796
|
-
reqType = 'spotClearinghouseState' if (isSpot) else 'clearinghouseState'
|
797
801
|
request: dict = {
|
798
|
-
'type':
|
802
|
+
'type': 'spotClearinghouseState' if (isSpot) else 'clearinghouseState',
|
799
803
|
'user': userAddress,
|
800
804
|
}
|
801
805
|
response = self.publicPostInfo(self.extend(request, params))
|
@@ -879,7 +883,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
879
883
|
market = self.market(symbol)
|
880
884
|
request: dict = {
|
881
885
|
'type': 'l2Book',
|
882
|
-
'coin': market['
|
886
|
+
'coin': market['baseName'] if market['swap'] else market['id'],
|
883
887
|
}
|
884
888
|
response = self.publicPostInfo(self.extend(request, params))
|
885
889
|
#
|
@@ -1112,7 +1116,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1112
1116
|
request: dict = {
|
1113
1117
|
'type': 'candleSnapshot',
|
1114
1118
|
'req': {
|
1115
|
-
'coin': market['
|
1119
|
+
'coin': market['baseName'] if market['swap'] else market['id'],
|
1116
1120
|
'interval': self.safe_string(self.timeframes, timeframe, timeframe),
|
1117
1121
|
'startTime': since,
|
1118
1122
|
'endTime': until,
|
@@ -1175,6 +1179,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1175
1179
|
:param int [params.until]: timestamp in ms of the latest trade
|
1176
1180
|
:param str [params.address]: wallet address that made trades
|
1177
1181
|
:param str [params.user]: wallet address that made trades
|
1182
|
+
:param str [params.subAccountAddress]: sub account user address
|
1178
1183
|
:returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
1179
1184
|
"""
|
1180
1185
|
userAddress = None
|
@@ -1353,6 +1358,67 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1353
1358
|
}
|
1354
1359
|
return self.sign_user_signed_action(messageTypes, message)
|
1355
1360
|
|
1361
|
+
def build_approve_builder_fee_sig(self, message):
|
1362
|
+
messageTypes: dict = {
|
1363
|
+
'HyperliquidTransaction:ApproveBuilderFee': [
|
1364
|
+
{'name': 'hyperliquidChain', 'type': 'string'},
|
1365
|
+
{'name': 'maxFeeRate', 'type': 'string'},
|
1366
|
+
{'name': 'builder', 'type': 'address'},
|
1367
|
+
{'name': 'nonce', 'type': 'uint64'},
|
1368
|
+
],
|
1369
|
+
}
|
1370
|
+
return self.sign_user_signed_action(messageTypes, message)
|
1371
|
+
|
1372
|
+
def approve_builder_fee(self, builder: str, maxFeeRate: str):
|
1373
|
+
nonce = self.milliseconds()
|
1374
|
+
isSandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
|
1375
|
+
payload: dict = {
|
1376
|
+
'hyperliquidChain': 'Testnet' if isSandboxMode else 'Mainnet',
|
1377
|
+
'maxFeeRate': maxFeeRate,
|
1378
|
+
'builder': builder,
|
1379
|
+
'nonce': nonce,
|
1380
|
+
}
|
1381
|
+
sig = self.build_approve_builder_fee_sig(payload)
|
1382
|
+
action = {
|
1383
|
+
'hyperliquidChain': payload['hyperliquidChain'],
|
1384
|
+
'signatureChainId': '0x66eee',
|
1385
|
+
'maxFeeRate': payload['maxFeeRate'],
|
1386
|
+
'builder': payload['builder'],
|
1387
|
+
'nonce': nonce,
|
1388
|
+
'type': 'approveBuilderFee',
|
1389
|
+
}
|
1390
|
+
request: dict = {
|
1391
|
+
'action': action,
|
1392
|
+
'nonce': nonce,
|
1393
|
+
'signature': sig,
|
1394
|
+
'vaultAddress': None,
|
1395
|
+
}
|
1396
|
+
#
|
1397
|
+
# {
|
1398
|
+
# "status": "ok",
|
1399
|
+
# "response": {
|
1400
|
+
# "type": "default"
|
1401
|
+
# }
|
1402
|
+
# }
|
1403
|
+
#
|
1404
|
+
return self.privatePostExchange(request)
|
1405
|
+
|
1406
|
+
def handle_builder_fee_approval(self):
|
1407
|
+
buildFee = self.safe_bool(self.options, 'builderFee', True)
|
1408
|
+
if not buildFee:
|
1409
|
+
return False # skip if builder fee is not enabled
|
1410
|
+
approvedBuilderFee = self.safe_bool(self.options, 'approvedBuilderFee', False)
|
1411
|
+
if approvedBuilderFee:
|
1412
|
+
return True # skip if builder fee is already approved
|
1413
|
+
try:
|
1414
|
+
builder = self.safe_string(self.options, 'builder', '0x6530512A6c89C7cfCEbC3BA7fcD9aDa5f30827a6')
|
1415
|
+
maxFeeRate = self.safe_string(self.options, 'feeRate', '0.01%')
|
1416
|
+
self.approve_builder_fee(builder, maxFeeRate)
|
1417
|
+
self.options['approvedBuilderFee'] = True
|
1418
|
+
except Exception as e:
|
1419
|
+
self.options['builderFee'] = False # disable builder fee if an error occurs
|
1420
|
+
return True
|
1421
|
+
|
1356
1422
|
def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
1357
1423
|
"""
|
1358
1424
|
create a trade order
|
@@ -1372,6 +1438,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1372
1438
|
:param str [params.clientOrderId]: client order id,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
|
1373
1439
|
:param str [params.slippage]: the slippage for market order
|
1374
1440
|
:param str [params.vaultAddress]: the vault address for order
|
1441
|
+
:param str [params.subAccountAddress]: sub account user address
|
1375
1442
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1376
1443
|
"""
|
1377
1444
|
self.load_markets()
|
@@ -1390,6 +1457,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1390
1457
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1391
1458
|
"""
|
1392
1459
|
self.load_markets()
|
1460
|
+
self.handle_builder_fee_approval()
|
1393
1461
|
request = self.create_orders_request(orders, params)
|
1394
1462
|
response = self.privatePostExchange(request)
|
1395
1463
|
#
|
@@ -1553,10 +1621,10 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1553
1621
|
'type': 'order',
|
1554
1622
|
'orders': orderReq,
|
1555
1623
|
'grouping': grouping,
|
1556
|
-
# 'brokerCode': 1, # cant
|
1557
1624
|
}
|
1558
|
-
if
|
1559
|
-
|
1625
|
+
if self.safe_bool(self.options, 'approvedBuilderFee', False):
|
1626
|
+
wallet = self.safe_string_lower(self.options, 'builder', '0x6530512A6c89C7cfCEbC3BA7fcD9aDa5f30827a6')
|
1627
|
+
orderAction['builder'] = {'b': wallet, 'f': self.safe_integer(self.options, 'feeInt', 10)}
|
1560
1628
|
signature = self.sign_l1_action(orderAction, nonce, vaultAddress)
|
1561
1629
|
request: dict = {
|
1562
1630
|
'action': orderAction,
|
@@ -1581,6 +1649,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1581
1649
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1582
1650
|
:param str [params.clientOrderId]: client order id,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
|
1583
1651
|
:param str [params.vaultAddress]: the vault address for order
|
1652
|
+
:param str [params.subAccountAddress]: sub account user address
|
1584
1653
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1585
1654
|
"""
|
1586
1655
|
orders = self.cancel_orders([id], symbol, params)
|
@@ -1598,6 +1667,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1598
1667
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1599
1668
|
:param string|str[] [params.clientOrderId]: client order ids,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
|
1600
1669
|
:param str [params.vaultAddress]: the vault address
|
1670
|
+
:param str [params.subAccountAddress]: sub account user address
|
1601
1671
|
:returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
1602
1672
|
"""
|
1603
1673
|
self.check_required_credentials()
|
@@ -1636,7 +1706,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1636
1706
|
})
|
1637
1707
|
cancelAction['cancels'] = cancelReq
|
1638
1708
|
vaultAddress = None
|
1639
|
-
vaultAddress, params = self.
|
1709
|
+
vaultAddress, params = self.handle_option_and_params_2(params, 'cancelOrders', 'vaultAddress', 'subAccountAddress')
|
1640
1710
|
vaultAddress = self.format_vault_address(vaultAddress)
|
1641
1711
|
signature = self.sign_l1_action(cancelAction, nonce, vaultAddress)
|
1642
1712
|
request['action'] = cancelAction
|
@@ -1680,6 +1750,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1680
1750
|
:param CancellationRequest[] orders: each order should contain the parameters required by cancelOrder namely id and symbol, example [{"id": "a", "symbol": "BTC/USDT"}, {"id": "b", "symbol": "ETH/USDT"}]
|
1681
1751
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1682
1752
|
:param str [params.vaultAddress]: the vault address
|
1753
|
+
:param str [params.subAccountAddress]: sub account user address
|
1683
1754
|
:returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
1684
1755
|
"""
|
1685
1756
|
self.check_required_credentials()
|
@@ -1716,7 +1787,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1716
1787
|
cancelAction['type'] = 'cancelByCloid' if cancelByCloid else 'cancel'
|
1717
1788
|
cancelAction['cancels'] = cancelReq
|
1718
1789
|
vaultAddress = None
|
1719
|
-
vaultAddress, params = self.
|
1790
|
+
vaultAddress, params = self.handle_option_and_params_2(params, 'cancelOrdersForSymbols', 'vaultAddress', 'subAccountAddress')
|
1720
1791
|
vaultAddress = self.format_vault_address(vaultAddress)
|
1721
1792
|
signature = self.sign_l1_action(cancelAction, nonce, vaultAddress)
|
1722
1793
|
request['action'] = cancelAction
|
@@ -1746,6 +1817,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1746
1817
|
:param number timeout: time in milliseconds, 0 represents cancel the timer
|
1747
1818
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1748
1819
|
:param str [params.vaultAddress]: the vault address
|
1820
|
+
:param str [params.subAccountAddress]: sub account user address
|
1749
1821
|
:returns dict: the api result
|
1750
1822
|
"""
|
1751
1823
|
self.check_required_credentials()
|
@@ -1761,7 +1833,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1761
1833
|
'time': nonce + timeout,
|
1762
1834
|
}
|
1763
1835
|
vaultAddress = None
|
1764
|
-
vaultAddress, params = self.
|
1836
|
+
vaultAddress, params = self.handle_option_and_params_2(params, 'cancelAllOrdersAfter', 'vaultAddress', 'subAccountAddress')
|
1765
1837
|
vaultAddress = self.format_vault_address(vaultAddress)
|
1766
1838
|
signature = self.sign_l1_action(cancelAction, nonce, vaultAddress)
|
1767
1839
|
request['action'] = cancelAction
|
@@ -1904,6 +1976,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1904
1976
|
:param float [params.triggerPrice]: The price at which a trigger order is triggered at
|
1905
1977
|
:param str [params.clientOrderId]: client order id,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
|
1906
1978
|
:param str [params.vaultAddress]: the vault address for order
|
1979
|
+
:param str [params.subAccountAddress]: sub account user address
|
1907
1980
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1908
1981
|
"""
|
1909
1982
|
self.load_markets()
|
@@ -2023,7 +2096,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2023
2096
|
market = self.market(symbol)
|
2024
2097
|
request: dict = {
|
2025
2098
|
'type': 'fundingHistory',
|
2026
|
-
'coin': market['
|
2099
|
+
'coin': market['baseName'],
|
2027
2100
|
}
|
2028
2101
|
if since is not None:
|
2029
2102
|
request['startTime'] = since
|
@@ -2071,6 +2144,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2071
2144
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2072
2145
|
:param str [params.user]: user address, will default to self.walletAddress if not provided
|
2073
2146
|
:param str [params.method]: 'openOrders' or 'frontendOpenOrders' default is 'frontendOpenOrders'
|
2147
|
+
:param str [params.subAccountAddress]: sub account user address
|
2074
2148
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
2075
2149
|
"""
|
2076
2150
|
userAddress = None
|
@@ -2159,6 +2233,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2159
2233
|
:param int [limit]: the maximum number of open orders structures to retrieve
|
2160
2234
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2161
2235
|
:param str [params.user]: user address, will default to self.walletAddress if not provided
|
2236
|
+
:param str [params.subAccountAddress]: sub account user address
|
2162
2237
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
2163
2238
|
"""
|
2164
2239
|
userAddress = None
|
@@ -2195,6 +2270,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2195
2270
|
:param str symbol: unified symbol of the market the order was made in
|
2196
2271
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2197
2272
|
:param str [params.user]: user address, will default to self.walletAddress if not provided
|
2273
|
+
:param str [params.subAccountAddress]: sub account user address
|
2198
2274
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2199
2275
|
"""
|
2200
2276
|
userAddress = None
|
@@ -2420,6 +2496,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2420
2496
|
:param int [limit]: the maximum number of trades structures to retrieve
|
2421
2497
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2422
2498
|
:param int [params.until]: timestamp in ms of the latest trade
|
2499
|
+
:param str [params.subAccountAddress]: sub account user address
|
2423
2500
|
:returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
2424
2501
|
"""
|
2425
2502
|
userAddress = None
|
@@ -2540,6 +2617,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2540
2617
|
:param str[] [symbols]: list of unified market symbols
|
2541
2618
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2542
2619
|
:param str [params.user]: user address, will default to self.walletAddress if not provided
|
2620
|
+
:param str [params.subAccountAddress]: sub account user address
|
2543
2621
|
:returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
|
2544
2622
|
"""
|
2545
2623
|
self.load_markets()
|
@@ -2680,6 +2758,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2680
2758
|
:param str symbol: unified market symbol of the market the position is held in, default is None
|
2681
2759
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2682
2760
|
:param str [params.leverage]: the rate of leverage, is required if setting trade mode(symbol)
|
2761
|
+
:param str [params.vaultAddress]: the vault address
|
2762
|
+
:param str [params.subAccountAddress]: sub account user address
|
2683
2763
|
:returns dict: response from the exchange
|
2684
2764
|
"""
|
2685
2765
|
if symbol is None:
|
@@ -2700,7 +2780,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2700
2780
|
'leverage': leverage,
|
2701
2781
|
}
|
2702
2782
|
vaultAddress = None
|
2703
|
-
vaultAddress, params = self.
|
2783
|
+
vaultAddress, params = self.handle_option_and_params_2(params, 'setMarginMode', 'vaultAddress', 'subAccountAddress')
|
2704
2784
|
if vaultAddress is not None:
|
2705
2785
|
if vaultAddress.startswith('0x'):
|
2706
2786
|
vaultAddress = vaultAddress.replace('0x', '')
|
@@ -2749,7 +2829,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2749
2829
|
'leverage': leverage,
|
2750
2830
|
}
|
2751
2831
|
vaultAddress = None
|
2752
|
-
vaultAddress, params = self.
|
2832
|
+
vaultAddress, params = self.handle_option_and_params_2(params, 'setLeverage', 'vaultAddress', 'subAccountAddress')
|
2753
2833
|
vaultAddress = self.format_vault_address(vaultAddress)
|
2754
2834
|
signature = self.sign_l1_action(updateAction, nonce, vaultAddress)
|
2755
2835
|
request: dict = {
|
@@ -2781,6 +2861,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2781
2861
|
:param str symbol: unified market symbol
|
2782
2862
|
:param float amount: amount of margin to add
|
2783
2863
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2864
|
+
:param str [params.vaultAddress]: the vault address
|
2865
|
+
:param str [params.subAccountAddress]: sub account user address
|
2784
2866
|
:returns dict: a `margin structure <https://docs.ccxt.com/#/?id=add-margin-structure>`
|
2785
2867
|
"""
|
2786
2868
|
return self.modify_margin_helper(symbol, amount, 'add', params)
|
@@ -2794,6 +2876,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2794
2876
|
:param str symbol: unified market symbol
|
2795
2877
|
:param float amount: the amount of margin to remove
|
2796
2878
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2879
|
+
:param str [params.vaultAddress]: the vault address
|
2880
|
+
:param str [params.subAccountAddress]: sub account user address
|
2797
2881
|
:returns dict: a `margin structure <https://docs.ccxt.com/#/?id=reduce-margin-structure>`
|
2798
2882
|
"""
|
2799
2883
|
return self.modify_margin_helper(symbol, amount, 'reduce', params)
|
@@ -2813,7 +2897,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2813
2897
|
'ntli': sz,
|
2814
2898
|
}
|
2815
2899
|
vaultAddress = None
|
2816
|
-
vaultAddress, params = self.
|
2900
|
+
vaultAddress, params = self.handle_option_and_params_2(params, 'modifyMargin', 'vaultAddress', 'subAccountAddress')
|
2817
2901
|
vaultAddress = self.format_vault_address(vaultAddress)
|
2818
2902
|
signature = self.sign_l1_action(updateAction, nonce, vaultAddress)
|
2819
2903
|
request: dict = {
|
@@ -2908,28 +2992,31 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2908
2992
|
transferRequest['vaultAddress'] = vaultAddress
|
2909
2993
|
transferResponse = self.privatePostExchange(transferRequest)
|
2910
2994
|
return transferResponse
|
2911
|
-
#
|
2912
|
-
self.check_address(toAccount)
|
2995
|
+
# transfer between main account and subaccount
|
2913
2996
|
if code is not None:
|
2914
2997
|
code = code.upper()
|
2915
2998
|
if code != 'USDC':
|
2916
2999
|
raise NotSupported(self.id + ' transfer() only support USDC')
|
2917
|
-
|
2918
|
-
|
2919
|
-
|
2920
|
-
|
2921
|
-
|
3000
|
+
isDeposit = False
|
3001
|
+
subAccountAddress = None
|
3002
|
+
if fromAccount == 'main':
|
3003
|
+
subAccountAddress = toAccount
|
3004
|
+
isDeposit = True
|
3005
|
+
elif toAccount == 'main':
|
3006
|
+
subAccountAddress = fromAccount
|
3007
|
+
else:
|
3008
|
+
raise NotSupported(self.id + ' transfer() only support main <> subaccount transfer')
|
3009
|
+
self.check_address(subAccountAddress)
|
3010
|
+
usd = self.parse_to_int(Precise.string_mul(self.number_to_string(amount), '1000000'))
|
3011
|
+
action = {
|
3012
|
+
'type': 'subAccountTransfer',
|
3013
|
+
'subAccountUser': subAccountAddress,
|
3014
|
+
'isDeposit': isDeposit,
|
3015
|
+
'usd': usd,
|
2922
3016
|
}
|
2923
|
-
sig = self.
|
3017
|
+
sig = self.sign_l1_action(action, nonce)
|
2924
3018
|
request: dict = {
|
2925
|
-
'action':
|
2926
|
-
'hyperliquidChain': payload['hyperliquidChain'],
|
2927
|
-
'signatureChainId': '0x66eee', # check self out
|
2928
|
-
'destination': toAccount,
|
2929
|
-
'amount': str(amount),
|
2930
|
-
'time': nonce,
|
2931
|
-
'type': 'usdSend',
|
2932
|
-
},
|
3019
|
+
'action': action,
|
2933
3020
|
'nonce': nonce,
|
2934
3021
|
'signature': sig,
|
2935
3022
|
}
|
@@ -3074,6 +3161,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
3074
3161
|
:param str symbol: unified market symbol
|
3075
3162
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3076
3163
|
:param str [params.user]: user address, will default to self.walletAddress if not provided
|
3164
|
+
:param str [params.subAccountAddress]: sub account user address
|
3077
3165
|
:returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
|
3078
3166
|
"""
|
3079
3167
|
self.load_markets()
|
@@ -3180,6 +3268,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
3180
3268
|
:param int [limit]: max number of ledger entries to return
|
3181
3269
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3182
3270
|
:param int [params.until]: timestamp in ms of the latest ledger entry
|
3271
|
+
:param str [params.subAccountAddress]: sub account user address
|
3183
3272
|
:returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
|
3184
3273
|
"""
|
3185
3274
|
self.load_markets()
|
@@ -3267,6 +3356,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
3267
3356
|
:param int [limit]: the maximum number of deposits structures to retrieve
|
3268
3357
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3269
3358
|
:param int [params.until]: the latest time in ms to fetch withdrawals for
|
3359
|
+
:param str [params.subAccountAddress]: sub account user address
|
3270
3360
|
:returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
|
3271
3361
|
"""
|
3272
3362
|
self.load_markets()
|
@@ -3308,6 +3398,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
3308
3398
|
:param int [limit]: the maximum number of withdrawals structures to retrieve
|
3309
3399
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3310
3400
|
:param int [params.until]: the latest time in ms to fetch withdrawals for
|
3401
|
+
:param str [params.subAccountAddress]: sub account user address
|
3311
3402
|
:returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
|
3312
3403
|
"""
|
3313
3404
|
self.load_markets()
|
@@ -3405,6 +3496,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
3405
3496
|
:param int [since]: the earliest time in ms to fetch funding history for
|
3406
3497
|
:param int [limit]: the maximum number of funding history structures to retrieve
|
3407
3498
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3499
|
+
:param str [params.subAccountAddress]: sub account user address
|
3408
3500
|
:returns dict: a `funding history structure <https://docs.ccxt.com/#/?id=funding-history-structure>`
|
3409
3501
|
"""
|
3410
3502
|
self.load_markets()
|
@@ -3495,7 +3587,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
3495
3587
|
|
3496
3588
|
def handle_public_address(self, methodName: str, params: dict):
|
3497
3589
|
userAux = None
|
3498
|
-
userAux, params = self.
|
3590
|
+
userAux, params = self.handle_option_and_params_2(params, methodName, 'user', 'subAccountAddress')
|
3499
3591
|
user = userAux
|
3500
3592
|
user, params = self.handle_option_and_params(params, methodName, 'address', userAux)
|
3501
3593
|
if (user is not None) and (user != ''):
|
@@ -3562,7 +3654,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
3562
3654
|
def parse_create_edit_order_args(self, id: Str, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
3563
3655
|
market = self.market(symbol)
|
3564
3656
|
vaultAddress = None
|
3565
|
-
vaultAddress, params = self.
|
3657
|
+
vaultAddress, params = self.handle_option_and_params_2(params, 'createOrder', 'vaultAddress', 'subAccountAddress')
|
3566
3658
|
vaultAddress = self.format_vault_address(vaultAddress)
|
3567
3659
|
symbol = market['symbol']
|
3568
3660
|
order = {
|