Deprecate protections from config

This commit is contained in:
Matthias 2021-08-04 19:43:16 +02:00
parent ceed3c663b
commit a661e0db6e
4 changed files with 101 additions and 68 deletions

View File

@ -469,6 +469,10 @@ You can then run hyperopt as follows:
The protection space is not part of the default space, and is only available with the Parameters Hyperopt interface, not with the legacy hyperopt interface (which required separate hyperopt files).
Freqtrade will also automatically change the "--enable-protections" flag if the protection space is selected.
!!! Warning
If protections are defined as property, entries from the configuration will be ignored.
It is therefore recommended to not define protections in the configuration.
### Migrating from previous property setups
A migration from a previous setup is pretty simple, and can be accomplished by converting the protections entry to a property.

View File

@ -15,6 +15,10 @@ All protection end times are rounded up to the next candle to avoid sudden, unex
!!! Note "Backtesting"
Protections are supported by backtesting and hyperopt, but must be explicitly enabled by using the `--enable-protections` flag.
!!! Warning "Setting protections from the configuration"
Setting protections from the configuration via `"protections": [],` key should be considered deprecated and will be removed in a future version.
It is also no longer guaranteed that your protections apply to the strategy in cases where the strategy defines [protections as property](hyperopt.md#optimizing-protections).
### Available Protections
* [`StoplossGuard`](#stoploss-guard) Stop trading if a certain amount of stoploss occurred within a certain time window.
@ -47,15 +51,17 @@ This applies across all pairs, unless `only_per_pair` is set to true, which will
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
protections = [
{
"method": "StoplossGuard",
"lookback_period_candles": 24,
"trade_limit": 4,
"stop_duration_candles": 4,
"only_per_pair": False
}
]
@property
def protections(self):
return [
{
"method": "StoplossGuard",
"lookback_period_candles": 24,
"trade_limit": 4,
"stop_duration_candles": 4,
"only_per_pair": False
}
]
```
!!! Note
@ -69,15 +75,17 @@ protections = [
The below sample stops trading for 12 candles if max-drawdown is > 20% considering all pairs - with a minimum of `trade_limit` trades - within the last 48 candles. If desired, `lookback_period` and/or `stop_duration` can be used.
``` python
protections = [
{
"method": "MaxDrawdown",
"lookback_period_candles": 48,
"trade_limit": 20,
"stop_duration_candles": 12,
"max_allowed_drawdown": 0.2
},
]
@property
def protections(self):
return [
{
"method": "MaxDrawdown",
"lookback_period_candles": 48,
"trade_limit": 20,
"stop_duration_candles": 12,
"max_allowed_drawdown": 0.2
},
]
```
#### Low Profit Pairs
@ -88,15 +96,17 @@ If that ratio is below `required_profit`, that pair will be locked for `stop_dur
The below example will stop trading a pair for 60 minutes if the pair does not have a required profit of 2% (and a minimum of 2 trades) within the last 6 candles.
``` python
protections = [
{
"method": "LowProfitPairs",
"lookback_period_candles": 6,
"trade_limit": 2,
"stop_duration": 60,
"required_profit": 0.02
}
]
@property
def protections(self):
return [
{
"method": "LowProfitPairs",
"lookback_period_candles": 6,
"trade_limit": 2,
"stop_duration": 60,
"required_profit": 0.02
}
]
```
#### Cooldown Period
@ -106,12 +116,14 @@ protections = [
The below example will stop trading a pair for 2 candles after closing a trade, allowing this pair to "cool down".
``` python
protections = [
{
"method": "CooldownPeriod",
"stop_duration_candles": 2
}
]
@property
def protections(self):
return [
{
"method": "CooldownPeriod",
"stop_duration_candles": 2
}
]
```
!!! Note
@ -136,39 +148,42 @@ from freqtrade.strategy import IStrategy
class AwesomeStrategy(IStrategy)
timeframe = '1h'
protections = [
{
"method": "CooldownPeriod",
"stop_duration_candles": 5
},
{
"method": "MaxDrawdown",
"lookback_period_candles": 48,
"trade_limit": 20,
"stop_duration_candles": 4,
"max_allowed_drawdown": 0.2
},
{
"method": "StoplossGuard",
"lookback_period_candles": 24,
"trade_limit": 4,
"stop_duration_candles": 2,
"only_per_pair": False
},
{
"method": "LowProfitPairs",
"lookback_period_candles": 6,
"trade_limit": 2,
"stop_duration_candles": 60,
"required_profit": 0.02
},
{
"method": "LowProfitPairs",
"lookback_period_candles": 24,
"trade_limit": 4,
"stop_duration_candles": 2,
"required_profit": 0.01
}
]
@property
def protections(self):
return [
{
"method": "CooldownPeriod",
"stop_duration_candles": 5
},
{
"method": "MaxDrawdown",
"lookback_period_candles": 48,
"trade_limit": 20,
"stop_duration_candles": 4,
"max_allowed_drawdown": 0.2
},
{
"method": "StoplossGuard",
"lookback_period_candles": 24,
"trade_limit": 4,
"stop_duration_candles": 2,
"only_per_pair": False
},
{
"method": "LowProfitPairs",
"lookback_period_candles": 6,
"trade_limit": 2,
"stop_duration_candles": 60,
"required_profit": 0.02
},
{
"method": "LowProfitPairs",
"lookback_period_candles": 24,
"trade_limit": 4,
"stop_duration_candles": 2,
"required_profit": 0.01
}
]
# ...
```

View File

@ -110,3 +110,6 @@ def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None:
"Please remove 'ticker_interval' from your configuration to continue operating."
)
config['timeframe'] = config['ticker_interval']
if 'protections' in config:
logger.warning("DEPRECATED: Setting 'protections' in the configuration is deprecated.")

View File

@ -1330,7 +1330,7 @@ def test_process_removed_setting(mocker, default_conf, caplog):
'sectionB', 'somesetting')
def test_process_deprecated_ticker_interval(mocker, default_conf, caplog):
def test_process_deprecated_ticker_interval(default_conf, caplog):
message = "DEPRECATED: Please use 'timeframe' instead of 'ticker_interval."
config = deepcopy(default_conf)
process_temporary_deprecated_settings(config)
@ -1352,6 +1352,17 @@ def test_process_deprecated_ticker_interval(mocker, default_conf, caplog):
process_temporary_deprecated_settings(config)
def test_process_deprecated_protections(default_conf, caplog):
message = "DEPRECATED: Setting 'protections' in the configuration is deprecated."
config = deepcopy(default_conf)
process_temporary_deprecated_settings(config)
assert not log_has(message, caplog)
config['protections'] = []
process_temporary_deprecated_settings(config)
assert log_has(message, caplog)
def test_flat_vars_to_nested_dict(caplog):
test_args = {