Skip to content

Commit 9dd1ce7

Browse files
committed
fix: improve get_max_leverage logic
1 parent 0a0a842 commit 9dd1ce7

File tree

2 files changed

+15
-35
lines changed

2 files changed

+15
-35
lines changed

freqtrade/exchange/exchange.py

Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3363,40 +3363,20 @@ def get_max_leverage(self, pair: str, stake_amount: float | None) -> float:
33633363
if stake_amount == 0:
33643364
return pair_tiers[0]["maxLeverage"] # Max lev for lowest amount
33653365

3366-
for tier_index in range(len(pair_tiers)):
3367-
tier = pair_tiers[tier_index]
3368-
lev = tier["maxLeverage"]
3369-
3370-
if tier_index < len(pair_tiers) - 1:
3371-
next_tier = pair_tiers[tier_index + 1]
3372-
next_floor = next_tier["minNotional"] / next_tier["maxLeverage"]
3373-
if next_floor > stake_amount: # Next tier min too high for stake amount
3374-
return min((tier["maxNotional"] / stake_amount), lev)
3375-
#
3376-
# With the two leverage tiers below,
3377-
# - a stake amount of 150 would mean a max leverage of (10000 / 150) = 66.66
3378-
# - stakes below 133.33 = max_lev of 75
3379-
# - stakes between 133.33-200 = max_lev of 10000/stake = 50.01-74.99
3380-
# - stakes from 200 + 1000 = max_lev of 50
3381-
#
3382-
# {
3383-
# "min": 0, # stake = 0.0
3384-
# "max": 10000, # max_stake@75 = 10000/75 = 133.33333333333334
3385-
# "lev": 75,
3386-
# },
3387-
# {
3388-
# "min": 10000, # stake = 200.0
3389-
# "max": 50000, # max_stake@50 = 50000/50 = 1000.0
3390-
# "lev": 50,
3391-
# }
3392-
#
3393-
3394-
else: # if on the last tier
3395-
if stake_amount > tier["maxNotional"]:
3396-
# If stake is > than max tradeable amount
3397-
raise InvalidOrderException(f"Amount {stake_amount} too high for {pair}")
3398-
else:
3399-
return tier["maxLeverage"]
3366+
# Find the appropriate tier based on stake_amount
3367+
prior_max_lev = None
3368+
for tier in pair_tiers:
3369+
min_stake = tier["minNotional"] / (prior_max_lev or tier["maxLeverage"])
3370+
max_stake = tier["maxNotional"] / tier["maxLeverage"]
3371+
prior_max_lev = tier["maxLeverage"]
3372+
# Adjust notional by leverage to do a proper comparison
3373+
if min_stake <= stake_amount <= max_stake:
3374+
return tier["maxLeverage"]
3375+
3376+
# else: # if on the last tier
3377+
if stake_amount > max_stake:
3378+
# If stake is > than max tradeable amount
3379+
raise InvalidOrderException(f"Amount {stake_amount} too high for {pair}")
34003380

34013381
raise OperationalException(
34023382
"Looped through all tiers without finding a max leverage. Should never be reached"

tests/exchange/test_exchange.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5902,7 +5902,7 @@ def test_get_max_leverage_futures(default_conf, mocker, leverage_tiers):
59025902
assert exchange.get_max_leverage("XRP/USDT:USDT", 1.0) == 20.0
59035903
assert exchange.get_max_leverage("BNB/USDT:USDT", 100.0) == 75.0
59045904
assert exchange.get_max_leverage("BTC/USDT:USDT", 170.30) == 125.0
5905-
assert pytest.approx(exchange.get_max_leverage("XRP/USDT:USDT", 99999.9)) == 5.000005
5905+
assert pytest.approx(exchange.get_max_leverage("XRP/USDT:USDT", 99999.9)) == 20
59065906
assert pytest.approx(exchange.get_max_leverage("BNB/USDT:USDT", 1500)) == 33.333333333333333
59075907
assert exchange.get_max_leverage("BTC/USDT:USDT", 300000000) == 2.0
59085908
assert exchange.get_max_leverage("BTC/USDT:USDT", 600000000) == 1.0 # Last tier

0 commit comments

Comments
 (0)