diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index f6c4a52bb..258a45008 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -912,6 +912,7 @@ class FreqtradeBot(LoggingMixin): stake_amount=stake_amount, min_stake_amount=min_stake_amount, max_stake_amount=max_stake_amount, + trade_amount=trade.stake_amount if trade else None, ) return enter_limit_requested, stake_amount, leverage diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 82aa2b3e9..2b8b96cba 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -769,6 +769,7 @@ class Backtesting: stake_amount=stake_amount, min_stake_amount=min_stake_amount, max_stake_amount=max_stake_amount, + trade_amount=trade.stake_amount if trade else None ) return propose_rate, stake_amount_val, leverage, min_stake_amount diff --git a/freqtrade/wallets.py b/freqtrade/wallets.py index 0a9ecc638..97db3fba5 100644 --- a/freqtrade/wallets.py +++ b/freqtrade/wallets.py @@ -291,12 +291,17 @@ class Wallets: return self._check_available_stake_amount(stake_amount, available_amount) def validate_stake_amount(self, pair: str, stake_amount: Optional[float], - min_stake_amount: Optional[float], max_stake_amount: float): + min_stake_amount: Optional[float], max_stake_amount: float, + trade_amount: Optional[float]): if not stake_amount: logger.debug(f"Stake amount is {stake_amount}, ignoring possible trade for {pair}.") return 0 max_stake_amount = min(max_stake_amount, self.get_available_stake_amount()) + if trade_amount: + # if in a trade, then the resulting trade size cannot go beyond the max stake + # Otherwise we could no longer exit. + max_stake_amount = min(max_stake_amount, max_stake_amount - trade_amount) if min_stake_amount is not None and min_stake_amount > max_stake_amount: if self._log: diff --git a/tests/test_wallets.py b/tests/test_wallets.py index 73a34bbae..0117f7427 100644 --- a/tests/test_wallets.py +++ b/tests/test_wallets.py @@ -180,17 +180,17 @@ def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, balance_r assert result == 0 -@pytest.mark.parametrize('stake_amount,min_stake,stake_available,max_stake,expected', [ - (22, 11, 50, 10000, 22), - (100, 11, 500, 10000, 100), - (1000, 11, 500, 10000, 500), # Above stake_available - (700, 11, 1000, 400, 400), # Above max_stake, below stake available - (20, 15, 10, 10000, 0), # Minimum stake > stake_available - (9, 11, 100, 10000, 11), # Below min stake - (1, 15, 10, 10000, 0), # Below min stake and min_stake > stake_available - (20, 50, 100, 10000, 0), # Below min stake and stake * 1.3 > min_stake - (1000, None, 1000, 10000, 1000), # No min-stake-amount could be determined - +@pytest.mark.parametrize('stake_amount,min_stake,stake_available,max_stake,trade_amount,expected', [ + (22, 11, 50, 10000, None, 22), + (100, 11, 500, 10000, None, 100), + (1000, 11, 500, 10000, None, 500), # Above stake_available + (700, 11, 1000, 400, None, 400), # Above max_stake, below stake available + (20, 15, 10, 10000, None, 0), # Minimum stake > stake_available + (9, 11, 100, 10000, None, 11), # Below min stake + (1, 15, 10, 10000, None, 0), # Below min stake and min_stake > stake_available + (20, 50, 100, 10000, None, 0), # Below min stake and stake * 1.3 > min_stake + (1000, None, 1000, 10000, None, 1000), # No min-stake-amount could be determined + (2000, 15, 2000, 3000, 1500, 500), # Rebuy - resulting in too high stake amount. Adjusting. ]) def test_validate_stake_amount( mocker, @@ -199,13 +199,15 @@ def test_validate_stake_amount( min_stake, stake_available, max_stake, + trade_amount, expected, ): freqtrade = get_patched_freqtradebot(mocker, default_conf) mocker.patch("freqtrade.wallets.Wallets.get_available_stake_amount", return_value=stake_available) - res = freqtrade.wallets.validate_stake_amount('XRP/USDT', stake_amount, min_stake, max_stake) + res = freqtrade.wallets.validate_stake_amount( + 'XRP/USDT', stake_amount, min_stake, max_stake, trade_amount) assert res == expected