Don't allow DCA trades to go beyond max order size

closes  #7924
This commit is contained in:
Matthias 2022-12-23 16:09:35 +01:00
parent 2a7369b56a
commit ad0d7c9a9e
4 changed files with 22 additions and 13 deletions

View File

@ -912,6 +912,7 @@ class FreqtradeBot(LoggingMixin):
stake_amount=stake_amount, stake_amount=stake_amount,
min_stake_amount=min_stake_amount, min_stake_amount=min_stake_amount,
max_stake_amount=max_stake_amount, max_stake_amount=max_stake_amount,
trade_amount=trade.stake_amount if trade else None,
) )
return enter_limit_requested, stake_amount, leverage return enter_limit_requested, stake_amount, leverage

View File

@ -769,6 +769,7 @@ class Backtesting:
stake_amount=stake_amount, stake_amount=stake_amount,
min_stake_amount=min_stake_amount, min_stake_amount=min_stake_amount,
max_stake_amount=max_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 return propose_rate, stake_amount_val, leverage, min_stake_amount

View File

@ -291,12 +291,17 @@ class Wallets:
return self._check_available_stake_amount(stake_amount, available_amount) return self._check_available_stake_amount(stake_amount, available_amount)
def validate_stake_amount(self, pair: str, stake_amount: Optional[float], 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: if not stake_amount:
logger.debug(f"Stake amount is {stake_amount}, ignoring possible trade for {pair}.") logger.debug(f"Stake amount is {stake_amount}, ignoring possible trade for {pair}.")
return 0 return 0
max_stake_amount = min(max_stake_amount, self.get_available_stake_amount()) 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 min_stake_amount is not None and min_stake_amount > max_stake_amount:
if self._log: if self._log:

View File

@ -180,17 +180,17 @@ def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, balance_r
assert result == 0 assert result == 0
@pytest.mark.parametrize('stake_amount,min_stake,stake_available,max_stake,expected', [ @pytest.mark.parametrize('stake_amount,min_stake,stake_available,max_stake,trade_amount,expected', [
(22, 11, 50, 10000, 22), (22, 11, 50, 10000, None, 22),
(100, 11, 500, 10000, 100), (100, 11, 500, 10000, None, 100),
(1000, 11, 500, 10000, 500), # Above stake_available (1000, 11, 500, 10000, None, 500), # Above stake_available
(700, 11, 1000, 400, 400), # Above max_stake, below stake available (700, 11, 1000, 400, None, 400), # Above max_stake, below stake available
(20, 15, 10, 10000, 0), # Minimum stake > stake_available (20, 15, 10, 10000, None, 0), # Minimum stake > stake_available
(9, 11, 100, 10000, 11), # Below min stake (9, 11, 100, 10000, None, 11), # Below min stake
(1, 15, 10, 10000, 0), # Below min stake and min_stake > stake_available (1, 15, 10, 10000, None, 0), # Below min stake and min_stake > stake_available
(20, 50, 100, 10000, 0), # Below min stake and stake * 1.3 > min_stake (20, 50, 100, 10000, None, 0), # Below min stake and stake * 1.3 > min_stake
(1000, None, 1000, 10000, 1000), # No min-stake-amount could be determined (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( def test_validate_stake_amount(
mocker, mocker,
@ -199,13 +199,15 @@ def test_validate_stake_amount(
min_stake, min_stake,
stake_available, stake_available,
max_stake, max_stake,
trade_amount,
expected, expected,
): ):
freqtrade = get_patched_freqtradebot(mocker, default_conf) freqtrade = get_patched_freqtradebot(mocker, default_conf)
mocker.patch("freqtrade.wallets.Wallets.get_available_stake_amount", mocker.patch("freqtrade.wallets.Wallets.get_available_stake_amount",
return_value=stake_available) 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 assert res == expected