@@ -961,7 +961,7 @@ def price_get_one_pip(self, pair: str, price: float) -> float:
961961 return 1 / pow (10 , precision )
962962
963963 def get_min_pair_stake_amount (
964- self , pair : str , price : float , stoploss : float , leverage : float | None = 1.0
964+ self , pair : str , price : float , stoploss : float , leverage : float = 1.0
965965 ) -> float | None :
966966 return self ._get_stake_amount_limit (pair , price , stoploss , "min" , leverage )
967967
@@ -980,7 +980,7 @@ def _get_stake_amount_limit(
980980 price : float ,
981981 stoploss : float ,
982982 limit : Literal ["min" , "max" ],
983- leverage : float | None = 1.0 ,
983+ leverage : float = 1.0 ,
984984 ) -> float | None :
985985 isMin = limit == "min"
986986
@@ -989,6 +989,8 @@ def _get_stake_amount_limit(
989989 except KeyError :
990990 raise ValueError (f"Can't get market information for symbol { pair } " )
991991
992+ stake_limits = []
993+ limits = market ["limits" ]
992994 if isMin :
993995 # reserve some percent defined in config (5% default) + stoploss
994996 margin_reserve : float = 1.0 + self ._config .get (
@@ -998,11 +1000,12 @@ def _get_stake_amount_limit(
9981000 # it should not be more than 50%
9991001 stoploss_reserve = max (min (stoploss_reserve , 1.5 ), 1 )
10001002 else :
1003+ # is_max
10011004 margin_reserve = 1.0
10021005 stoploss_reserve = 1.0
1006+ if max_from_tiers := self ._get_max_notional_from_tiers (pair , leverage = leverage ):
1007+ stake_limits .append (max_from_tiers )
10031008
1004- stake_limits = []
1005- limits = market ["limits" ]
10061009 if limits ["cost" ][limit ] is not None :
10071010 stake_limits .append (
10081011 self ._contracts_to_amount (pair , limits ["cost" ][limit ]) * stoploss_reserve
@@ -3361,42 +3364,22 @@ def get_max_leverage(self, pair: str, stake_amount: float | None) -> float:
33613364 pair_tiers = self ._leverage_tiers [pair ]
33623365
33633366 if stake_amount == 0 :
3364- return self ._leverage_tiers [pair ][0 ]["maxLeverage" ] # Max lev for lowest amount
3365-
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" ]
3367+ return pair_tiers [0 ]["maxLeverage" ] # Max lev for lowest amount
3368+
3369+ # Find the appropriate tier based on stake_amount
3370+ prior_max_lev = None
3371+ for tier in pair_tiers :
3372+ min_stake = tier ["minNotional" ] / (prior_max_lev or tier ["maxLeverage" ])
3373+ max_stake = tier ["maxNotional" ] / tier ["maxLeverage" ]
3374+ prior_max_lev = tier ["maxLeverage" ]
3375+ # Adjust notional by leverage to do a proper comparison
3376+ if min_stake <= stake_amount <= max_stake :
3377+ return tier ["maxLeverage" ]
3378+
3379+ # else: # if on the last tier
3380+ if stake_amount > max_stake :
3381+ # If stake is > than max tradeable amount
3382+ raise InvalidOrderException (f"Amount { stake_amount } too high for { pair } " )
34003383
34013384 raise OperationalException (
34023385 "Looped through all tiers without finding a max leverage. Should never be reached"
@@ -3411,6 +3394,23 @@ def get_max_leverage(self, pair: str, stake_amount: float | None) -> float:
34113394 else :
34123395 return 1.0
34133396
3397+ def _get_max_notional_from_tiers (self , pair : str , leverage : float ) -> float | None :
3398+ """
3399+ get max_notional from leverage_tiers
3400+ :param pair: The base/quote currency pair being traded
3401+ :param leverage: The leverage to be used
3402+ :return: The maximum notional value for the given leverage or None if not found
3403+ """
3404+ if self .trading_mode != TradingMode .FUTURES :
3405+ return None
3406+ if pair not in self ._leverage_tiers :
3407+ return None
3408+ pair_tiers = self ._leverage_tiers [pair ]
3409+ for tier in reversed (pair_tiers ):
3410+ if leverage <= tier ["maxLeverage" ]:
3411+ return tier ["maxNotional" ]
3412+ return None
3413+
34143414 @retrier
34153415 def _set_leverage (
34163416 self ,
0 commit comments