config validation moved to configuration file
This commit is contained in:
parent
3c99e3b7c7
commit
29305dd070
@ -58,6 +58,7 @@ class Configuration(object):
|
||||
config['internals'] = {}
|
||||
|
||||
logger.info('Validating configuration ...')
|
||||
self._validate_config_schema(config)
|
||||
self._validate_config(config)
|
||||
|
||||
# Set strategy if not specified in config and or if it's non default
|
||||
@ -291,7 +292,7 @@ class Configuration(object):
|
||||
|
||||
return config
|
||||
|
||||
def _validate_config(self, conf: Dict[str, Any]) -> Dict[str, Any]:
|
||||
def _validate_config_schema(self, conf: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""
|
||||
Validate the configuration follow the Config Schema
|
||||
:param conf: Config in JSON format
|
||||
@ -309,6 +310,35 @@ class Configuration(object):
|
||||
best_match(Draft4Validator(constants.CONF_SCHEMA).iter_errors(conf)).message
|
||||
)
|
||||
|
||||
def _validate_config(self, conf: Dict[str, Any]) -> None:
|
||||
"""
|
||||
Validate the configuration consistency
|
||||
:param conf: Config in JSON format
|
||||
:return: Returns None if everything is ok, otherwise throw an exception
|
||||
"""
|
||||
|
||||
# validating trailing stoploss
|
||||
self._validate_trailing_stoploss(conf)
|
||||
|
||||
def _validate_trailing_stoploss(self, conf: Dict[str, Any]) -> None:
|
||||
# Skip if trailing stoploss is not activated
|
||||
if not conf.get('trailing_stop', False):
|
||||
return
|
||||
|
||||
tsl_positive = float(conf.get('trailing_stop_positive', 0))
|
||||
tsl_offset = float(conf.get('trailing_stop_positive_offset', 0))
|
||||
tsl_only_offset = conf.get('trailing_only_offset_is_reached', False)
|
||||
|
||||
if tsl_only_offset:
|
||||
if tsl_positive == 0.0:
|
||||
raise OperationalException(
|
||||
f'The config trailing_only_offset_is_reached need '
|
||||
'trailing_stop_positive_offset to be more than 0 in your config.')
|
||||
if tsl_positive > 0 and 0 < tsl_offset <= tsl_positive:
|
||||
raise OperationalException(
|
||||
f'The config trailing_stop_positive_offset need '
|
||||
'to be greater than trailing_stop_positive_offset in your config.')
|
||||
|
||||
def get_config(self) -> Dict[str, Any]:
|
||||
"""
|
||||
Return the config. Use this method to get the bot config
|
||||
|
@ -449,33 +449,6 @@ def test_validate_order_types(default_conf, mocker):
|
||||
Exchange(default_conf)
|
||||
|
||||
|
||||
def test_validate_tsl(default_conf, mocker):
|
||||
api_mock = MagicMock()
|
||||
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
|
||||
mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={}))
|
||||
mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())
|
||||
mocker.patch('freqtrade.exchange.Exchange.name', 'Bittrex')
|
||||
default_conf['trailing_stop'] = True
|
||||
default_conf['trailing_stop_positive'] = 0
|
||||
default_conf['trailing_stop_positive_offset'] = 0
|
||||
default_conf['trailing_only_offset_is_reached'] = False
|
||||
|
||||
Exchange(default_conf)
|
||||
|
||||
default_conf['trailing_only_offset_is_reached'] = True
|
||||
with pytest.raises(OperationalException,
|
||||
match=r'The config trailing_only_offset_is_reached need '
|
||||
'trailing_stop_positive_offset to be more than 0 in your config.'):
|
||||
Exchange(default_conf)
|
||||
|
||||
default_conf['trailing_stop_positive_offset'] = 0.01
|
||||
default_conf['trailing_stop_positive'] = 0.015
|
||||
with pytest.raises(OperationalException,
|
||||
match=r'The config trailing_stop_positive_offset need '
|
||||
'to be greater than trailing_stop_positive_offset in your config.'):
|
||||
Exchange(default_conf)
|
||||
|
||||
|
||||
def test_validate_order_types_not_in_config(default_conf, mocker):
|
||||
api_mock = MagicMock()
|
||||
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
|
||||
|
@ -13,6 +13,7 @@ from freqtrade import OperationalException, constants
|
||||
from freqtrade.arguments import Arguments
|
||||
from freqtrade.configuration import Configuration, set_loggers
|
||||
from freqtrade.constants import DEFAULT_DB_DRYRUN_URL, DEFAULT_DB_PROD_URL
|
||||
from freqtrade.exchange import Exchange
|
||||
from freqtrade.state import RunMode
|
||||
from freqtrade.tests.conftest import log_has
|
||||
|
||||
@ -22,7 +23,7 @@ def test_load_config_invalid_pair(default_conf) -> None:
|
||||
|
||||
with pytest.raises(ValidationError, match=r'.*does not match.*'):
|
||||
configuration = Configuration(Namespace())
|
||||
configuration._validate_config(default_conf)
|
||||
configuration._validate_config_schema(default_conf)
|
||||
|
||||
|
||||
def test_load_config_missing_attributes(default_conf) -> None:
|
||||
@ -30,7 +31,7 @@ def test_load_config_missing_attributes(default_conf) -> None:
|
||||
|
||||
with pytest.raises(ValidationError, match=r'.*\'exchange\' is a required property.*'):
|
||||
configuration = Configuration(Namespace())
|
||||
configuration._validate_config(default_conf)
|
||||
configuration._validate_config_schema(default_conf)
|
||||
|
||||
|
||||
def test_load_config_incorrect_stake_amount(default_conf) -> None:
|
||||
@ -38,7 +39,7 @@ def test_load_config_incorrect_stake_amount(default_conf) -> None:
|
||||
|
||||
with pytest.raises(ValidationError, match=r'.*\'fake\' does not match \'unlimited\'.*'):
|
||||
configuration = Configuration(Namespace())
|
||||
configuration._validate_config(default_conf)
|
||||
configuration._validate_config_schema(default_conf)
|
||||
|
||||
|
||||
def test_load_config_file(default_conf, mocker, caplog) -> None:
|
||||
@ -573,3 +574,30 @@ def test__create_datadir(mocker, default_conf, caplog) -> None:
|
||||
cfg._create_datadir(default_conf, '/foo/bar')
|
||||
assert md.call_args[0][0] == "/foo/bar"
|
||||
assert log_has('Created data directory: /foo/bar', caplog.record_tuples)
|
||||
|
||||
|
||||
def test_validate_tsl(default_conf, mocker):
|
||||
mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={}))
|
||||
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock())
|
||||
mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())
|
||||
mocker.patch('freqtrade.exchange.Exchange.validate_ordertypes', MagicMock())
|
||||
mocker.patch('freqtrade.exchange.Exchange.name', 'Bittrex')
|
||||
default_conf['trailing_stop'] = True
|
||||
default_conf['trailing_stop_positive'] = 0
|
||||
default_conf['trailing_stop_positive_offset'] = 0
|
||||
default_conf['trailing_only_offset_is_reached'] = False
|
||||
|
||||
Exchange(default_conf)
|
||||
|
||||
default_conf['trailing_only_offset_is_reached'] = True
|
||||
with pytest.raises(OperationalException,
|
||||
match=r'The config trailing_only_offset_is_reached need '
|
||||
'trailing_stop_positive_offset to be more than 0 in your config.'):
|
||||
Exchange(default_conf)
|
||||
|
||||
default_conf['trailing_stop_positive_offset'] = 0.01
|
||||
default_conf['trailing_stop_positive'] = 0.015
|
||||
with pytest.raises(OperationalException,
|
||||
match=r'The config trailing_stop_positive_offset need '
|
||||
'to be greater than trailing_stop_positive_offset in your config.'):
|
||||
Exchange(default_conf)
|
||||
|
Loading…
Reference in New Issue
Block a user