Deprecate protections from config
This commit is contained in:
parent
ceed3c663b
commit
a661e0db6e
@ -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).
|
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.
|
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
|
### 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.
|
A migration from a previous setup is pretty simple, and can be accomplished by converting the protections entry to a property.
|
||||||
|
@ -15,6 +15,10 @@ All protection end times are rounded up to the next candle to avoid sudden, unex
|
|||||||
!!! Note "Backtesting"
|
!!! Note "Backtesting"
|
||||||
Protections are supported by backtesting and hyperopt, but must be explicitly enabled by using the `--enable-protections` flag.
|
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
|
### Available Protections
|
||||||
|
|
||||||
* [`StoplossGuard`](#stoploss-guard) Stop trading if a certain amount of stoploss occurred within a certain time window.
|
* [`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.
|
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
|
||||||
protections = [
|
@property
|
||||||
{
|
def protections(self):
|
||||||
"method": "StoplossGuard",
|
return [
|
||||||
"lookback_period_candles": 24,
|
{
|
||||||
"trade_limit": 4,
|
"method": "StoplossGuard",
|
||||||
"stop_duration_candles": 4,
|
"lookback_period_candles": 24,
|
||||||
"only_per_pair": False
|
"trade_limit": 4,
|
||||||
}
|
"stop_duration_candles": 4,
|
||||||
]
|
"only_per_pair": False
|
||||||
|
}
|
||||||
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! Note
|
!!! 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.
|
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
|
``` python
|
||||||
protections = [
|
@property
|
||||||
{
|
def protections(self):
|
||||||
"method": "MaxDrawdown",
|
return [
|
||||||
"lookback_period_candles": 48,
|
{
|
||||||
"trade_limit": 20,
|
"method": "MaxDrawdown",
|
||||||
"stop_duration_candles": 12,
|
"lookback_period_candles": 48,
|
||||||
"max_allowed_drawdown": 0.2
|
"trade_limit": 20,
|
||||||
},
|
"stop_duration_candles": 12,
|
||||||
]
|
"max_allowed_drawdown": 0.2
|
||||||
|
},
|
||||||
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Low Profit Pairs
|
#### 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.
|
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
|
``` python
|
||||||
protections = [
|
@property
|
||||||
{
|
def protections(self):
|
||||||
"method": "LowProfitPairs",
|
return [
|
||||||
"lookback_period_candles": 6,
|
{
|
||||||
"trade_limit": 2,
|
"method": "LowProfitPairs",
|
||||||
"stop_duration": 60,
|
"lookback_period_candles": 6,
|
||||||
"required_profit": 0.02
|
"trade_limit": 2,
|
||||||
}
|
"stop_duration": 60,
|
||||||
]
|
"required_profit": 0.02
|
||||||
|
}
|
||||||
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Cooldown Period
|
#### 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".
|
The below example will stop trading a pair for 2 candles after closing a trade, allowing this pair to "cool down".
|
||||||
|
|
||||||
``` python
|
``` python
|
||||||
protections = [
|
@property
|
||||||
{
|
def protections(self):
|
||||||
"method": "CooldownPeriod",
|
return [
|
||||||
"stop_duration_candles": 2
|
{
|
||||||
}
|
"method": "CooldownPeriod",
|
||||||
]
|
"stop_duration_candles": 2
|
||||||
|
}
|
||||||
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! Note
|
!!! Note
|
||||||
@ -136,39 +148,42 @@ from freqtrade.strategy import IStrategy
|
|||||||
|
|
||||||
class AwesomeStrategy(IStrategy)
|
class AwesomeStrategy(IStrategy)
|
||||||
timeframe = '1h'
|
timeframe = '1h'
|
||||||
protections = [
|
|
||||||
{
|
@property
|
||||||
"method": "CooldownPeriod",
|
def protections(self):
|
||||||
"stop_duration_candles": 5
|
return [
|
||||||
},
|
{
|
||||||
{
|
"method": "CooldownPeriod",
|
||||||
"method": "MaxDrawdown",
|
"stop_duration_candles": 5
|
||||||
"lookback_period_candles": 48,
|
},
|
||||||
"trade_limit": 20,
|
{
|
||||||
"stop_duration_candles": 4,
|
"method": "MaxDrawdown",
|
||||||
"max_allowed_drawdown": 0.2
|
"lookback_period_candles": 48,
|
||||||
},
|
"trade_limit": 20,
|
||||||
{
|
"stop_duration_candles": 4,
|
||||||
"method": "StoplossGuard",
|
"max_allowed_drawdown": 0.2
|
||||||
"lookback_period_candles": 24,
|
},
|
||||||
"trade_limit": 4,
|
{
|
||||||
"stop_duration_candles": 2,
|
"method": "StoplossGuard",
|
||||||
"only_per_pair": False
|
"lookback_period_candles": 24,
|
||||||
},
|
"trade_limit": 4,
|
||||||
{
|
"stop_duration_candles": 2,
|
||||||
"method": "LowProfitPairs",
|
"only_per_pair": False
|
||||||
"lookback_period_candles": 6,
|
},
|
||||||
"trade_limit": 2,
|
{
|
||||||
"stop_duration_candles": 60,
|
"method": "LowProfitPairs",
|
||||||
"required_profit": 0.02
|
"lookback_period_candles": 6,
|
||||||
},
|
"trade_limit": 2,
|
||||||
{
|
"stop_duration_candles": 60,
|
||||||
"method": "LowProfitPairs",
|
"required_profit": 0.02
|
||||||
"lookback_period_candles": 24,
|
},
|
||||||
"trade_limit": 4,
|
{
|
||||||
"stop_duration_candles": 2,
|
"method": "LowProfitPairs",
|
||||||
"required_profit": 0.01
|
"lookback_period_candles": 24,
|
||||||
}
|
"trade_limit": 4,
|
||||||
]
|
"stop_duration_candles": 2,
|
||||||
|
"required_profit": 0.01
|
||||||
|
}
|
||||||
|
]
|
||||||
# ...
|
# ...
|
||||||
```
|
```
|
||||||
|
@ -110,3 +110,6 @@ def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None:
|
|||||||
"Please remove 'ticker_interval' from your configuration to continue operating."
|
"Please remove 'ticker_interval' from your configuration to continue operating."
|
||||||
)
|
)
|
||||||
config['timeframe'] = config['ticker_interval']
|
config['timeframe'] = config['ticker_interval']
|
||||||
|
|
||||||
|
if 'protections' in config:
|
||||||
|
logger.warning("DEPRECATED: Setting 'protections' in the configuration is deprecated.")
|
||||||
|
@ -1330,7 +1330,7 @@ def test_process_removed_setting(mocker, default_conf, caplog):
|
|||||||
'sectionB', 'somesetting')
|
'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."
|
message = "DEPRECATED: Please use 'timeframe' instead of 'ticker_interval."
|
||||||
config = deepcopy(default_conf)
|
config = deepcopy(default_conf)
|
||||||
process_temporary_deprecated_settings(config)
|
process_temporary_deprecated_settings(config)
|
||||||
@ -1352,6 +1352,17 @@ def test_process_deprecated_ticker_interval(mocker, default_conf, caplog):
|
|||||||
process_temporary_deprecated_settings(config)
|
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):
|
def test_flat_vars_to_nested_dict(caplog):
|
||||||
|
|
||||||
test_args = {
|
test_args = {
|
||||||
|
Loading…
Reference in New Issue
Block a user