Set required_profit for stoploss guard, allowing to ignore small stoplosses.

closes #7076
This commit is contained in:
Matthias 2022-07-27 19:52:39 +02:00
parent 2595e40e47
commit cc3ead9d7b
3 changed files with 9 additions and 5 deletions

View File

@ -50,6 +50,8 @@ This applies across all pairs, unless `only_per_pair` is set to true, which will
Similarly, this protection will by default look at all trades (long and short). For futures bots, setting `only_per_side` will make the bot only consider one side, and will then only lock this one side, allowing for example shorts to continue after a series of long stoplosses. Similarly, this protection will by default look at all trades (long and short). For futures bots, setting `only_per_side` will make the bot only consider one side, and will then only lock this one side, allowing for example shorts to continue after a series of long stoplosses.
`required_profit` will determine the required relative profit (or loss) for stoplosses to consider. This should normally not be set and defaults to 0.0 - which means all losing stoplosses will be triggering a block.
The below example stops trading for all pairs for 4 candles after the last trade if the bot hit stoploss 4 times within the last 24 candles. The below example stops trading for all pairs for 4 candles after the last trade if the bot hit stoploss 4 times within the last 24 candles.
``` python ``` python
@ -61,6 +63,7 @@ def protections(self):
"lookback_period_candles": 24, "lookback_period_candles": 24,
"trade_limit": 4, "trade_limit": 4,
"stop_duration_candles": 4, "stop_duration_candles": 4,
"required_profit": 0.0,
"only_per_pair": False, "only_per_pair": False,
"only_per_side": False "only_per_side": False
} }

View File

@ -23,13 +23,14 @@ class StoplossGuard(IProtection):
self._trade_limit = protection_config.get('trade_limit', 10) self._trade_limit = protection_config.get('trade_limit', 10)
self._disable_global_stop = protection_config.get('only_per_pair', False) self._disable_global_stop = protection_config.get('only_per_pair', False)
self._only_per_side = protection_config.get('only_per_side', False) self._only_per_side = protection_config.get('only_per_side', False)
self._profit_limit = protection_config.get('required_profit', 0.0)
def short_desc(self) -> str: def short_desc(self) -> str:
""" """
Short method description - used for startup-messages Short method description - used for startup-messages
""" """
return (f"{self.name} - Frequent Stoploss Guard, {self._trade_limit} stoplosses " return (f"{self.name} - Frequent Stoploss Guard, {self._trade_limit} stoplosses "
f"within {self.lookback_period_str}.") f"with profit < {self._profit_limit:.2%} within {self.lookback_period_str}.")
def _reason(self) -> str: def _reason(self) -> str:
""" """
@ -49,7 +50,7 @@ class StoplossGuard(IProtection):
trades = [trade for trade in trades1 if (str(trade.exit_reason) in ( trades = [trade for trade in trades1 if (str(trade.exit_reason) in (
ExitType.TRAILING_STOP_LOSS.value, ExitType.STOP_LOSS.value, ExitType.TRAILING_STOP_LOSS.value, ExitType.STOP_LOSS.value,
ExitType.STOPLOSS_ON_EXCHANGE.value) ExitType.STOPLOSS_ON_EXCHANGE.value)
and trade.close_profit and trade.close_profit < 0)] and trade.close_profit and trade.close_profit < self._profit_limit)]
if self._only_per_side: if self._only_per_side:
# Long or short trades only # Long or short trades only

View File

@ -424,7 +424,7 @@ def test_MaxDrawdown(mocker, default_conf, fee, caplog):
@pytest.mark.parametrize("protectionconf,desc_expected,exception_expected", [ @pytest.mark.parametrize("protectionconf,desc_expected,exception_expected", [
({"method": "StoplossGuard", "lookback_period": 60, "trade_limit": 2, "stop_duration": 60}, ({"method": "StoplossGuard", "lookback_period": 60, "trade_limit": 2, "stop_duration": 60},
"[{'StoplossGuard': 'StoplossGuard - Frequent Stoploss Guard, " "[{'StoplossGuard': 'StoplossGuard - Frequent Stoploss Guard, "
"2 stoplosses within 60 minutes.'}]", "2 stoplosses with profit < 0.00% within 60 minutes.'}]",
None None
), ),
({"method": "CooldownPeriod", "stop_duration": 60}, ({"method": "CooldownPeriod", "stop_duration": 60},
@ -442,9 +442,9 @@ def test_MaxDrawdown(mocker, default_conf, fee, caplog):
None None
), ),
({"method": "StoplossGuard", "lookback_period_candles": 12, "trade_limit": 2, ({"method": "StoplossGuard", "lookback_period_candles": 12, "trade_limit": 2,
"stop_duration": 60}, "required_profit": -0.05, "stop_duration": 60},
"[{'StoplossGuard': 'StoplossGuard - Frequent Stoploss Guard, " "[{'StoplossGuard': 'StoplossGuard - Frequent Stoploss Guard, "
"2 stoplosses within 12 candles.'}]", "2 stoplosses with profit < -5.00% within 12 candles.'}]",
None None
), ),
({"method": "CooldownPeriod", "stop_duration_candles": 5}, ({"method": "CooldownPeriod", "stop_duration_candles": 5},