Set required_profit for stoploss guard, allowing to ignore small stoplosses.
closes #7076
This commit is contained in:
parent
2595e40e47
commit
cc3ead9d7b
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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},
|
||||||
|
Loading…
Reference in New Issue
Block a user