From 17cf9d33cfa848a20c4b9ff4d0fdf116f4c5603f Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 24 Apr 2019 20:44:36 +0200 Subject: [PATCH 1/9] add _args_to_conig --- freqtrade/configuration.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/freqtrade/configuration.py b/freqtrade/configuration.py index 6388a97ac..172010dd8 100644 --- a/freqtrade/configuration.py +++ b/freqtrade/configuration.py @@ -216,6 +216,14 @@ class Configuration(object): logger.info(f'Created data directory: {datadir}') return datadir + def _args_to_config(self, config, argname, configname, logstring) -> bool: + + if argname in self.args and getattr(self.args, argname): + + config.update({configname: getattr(self.args, argname)}) + + logger.info(logstring.format(config[configname])) + def _load_backtesting_config(self, config: Dict[str, Any]) -> Dict[str, Any]: # noqa: C901 """ Extract information for sys.argv and load Backtesting configuration @@ -232,9 +240,8 @@ class Configuration(object): config.update({'live': True}) logger.info('Parameter -l/--live detected ...') - if 'position_stacking' in self.args and self.args.position_stacking: - config.update({'position_stacking': True}) - logger.info('Parameter --enable-position-stacking detected ...') + self._args_to_config(config, 'position_stacking', 'position_stacking', + 'Parameter --enable-position-stacking detected ...') if 'use_max_market_positions' in self.args and not self.args.use_max_market_positions: config.update({'use_max_market_positions': False}) From 39f60c474002be0827987c3c6ba74d391ecacef6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 24 Apr 2019 21:02:05 +0200 Subject: [PATCH 2/9] Add some more arguments to args_to_config --- freqtrade/configuration.py | 60 ++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/freqtrade/configuration.py b/freqtrade/configuration.py index 172010dd8..395653213 100644 --- a/freqtrade/configuration.py +++ b/freqtrade/configuration.py @@ -216,13 +216,19 @@ class Configuration(object): logger.info(f'Created data directory: {datadir}') return datadir - def _args_to_config(self, config, argname, configname, logstring) -> bool: - + def _args_to_config(self, config, argname, configname, logstring, logfun=None) -> bool: + """ + logfun is applied to the configuration entry before passing + that entry to the log string using .format(). + sample: logfun=len (prints the length of the found configuration instead of the content) + """ if argname in self.args and getattr(self.args, argname): config.update({configname: getattr(self.args, argname)}) - - logger.info(logstring.format(config[configname])) + if logfun: + logger.info(logstring.format(logfun(config[configname]))) + else: + logger.info(logstring.format(config[configname])) def _load_backtesting_config(self, config: Dict[str, Any]) -> Dict[str, Any]: # noqa: C901 """ @@ -236,12 +242,11 @@ class Configuration(object): logger.info('Parameter -i/--ticker-interval detected ...') logger.info('Using ticker_interval: %s ...', config.get('ticker_interval')) - if 'live' in self.args and self.args.live: - config.update({'live': True}) - logger.info('Parameter -l/--live detected ...') + self._args_to_config(config, argname='live', configname='live', + logstring='Parameter -l/--live detected ...') - self._args_to_config(config, 'position_stacking', 'position_stacking', - 'Parameter --enable-position-stacking detected ...') + self._args_to_config(config, argname='position_stacking', configname='position_stacking', + logstring='Parameter --enable-position-stacking detected ...') if 'use_max_market_positions' in self.args and not self.args.use_max_market_positions: config.update({'use_max_market_positions': False}) @@ -254,14 +259,12 @@ class Configuration(object): else: logger.info('Using max_open_trades: %s ...', config.get('max_open_trades')) - if 'stake_amount' in self.args and self.args.stake_amount: - config.update({'stake_amount': self.args.stake_amount}) - logger.info('Parameter --stake_amount detected, overriding stake_amount to: %s ...', - config.get('stake_amount')) + self._args_to_config(config, argname='stake_amount', configname='stake_amount', + logstring='Parameter --stake_amount detected, ' + 'overriding stake_amount to: {} ...') - if 'timerange' in self.args and self.args.timerange: - config.update({'timerange': self.args.timerange}) - logger.info('Parameter --timerange detected: %s ...', self.args.timerange) + self._args_to_config(config, argname='timerange', configname='timerange', + logstring='Parameter --timerange detected: {} ...') if 'datadir' in self.args and self.args.datadir: config.update({'datadir': self._create_datadir(config, self.args.datadir)}) @@ -269,25 +272,20 @@ class Configuration(object): config.update({'datadir': self._create_datadir(config, None)}) logger.info('Using data folder: %s ...', config.get('datadir')) - if 'refresh_pairs' in self.args and self.args.refresh_pairs: - config.update({'refresh_pairs': True}) - logger.info('Parameter -r/--refresh-pairs-cached detected ...') + self._args_to_config(config, argname='refresh_pairs', configname='refresh_pairs', + logstring='Parameter -r/--refresh-pairs-cached detected ...') - if 'strategy_list' in self.args and self.args.strategy_list: - config.update({'strategy_list': self.args.strategy_list}) - logger.info('Using strategy list of %s Strategies', len(self.args.strategy_list)) + self._args_to_config(config, argname='strategy_list', configname='strategy_list', + logstring='Using strategy list of {} Strategies', logfun=len) - if 'ticker_interval' in self.args and self.args.ticker_interval: - config.update({'ticker_interval': self.args.ticker_interval}) - logger.info('Overriding ticker interval with Command line argument') + self._args_to_config(config, argname='ticker_interval', configname='ticker_interval', + logstring='Overriding ticker interval with Command line argument') - if 'export' in self.args and self.args.export: - config.update({'export': self.args.export}) - logger.info('Parameter --export detected: %s ...', self.args.export) + self._args_to_config(config, argname='export', configname='export', + logstring='Parameter --export detected: {} ...') - if 'export' in config and 'exportfilename' in self.args and self.args.exportfilename: - config.update({'exportfilename': self.args.exportfilename}) - logger.info('Storing backtest results to %s ...', self.args.exportfilename) + self._args_to_config(config, argname='exportfilename', configname='exportfilename', + logstring='Storing backtest results to {} ...') return config From d6276a15d2087d1bea30a1a796d8bd30a4b05724 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 24 Apr 2019 21:12:08 +0200 Subject: [PATCH 3/9] Convert all optimize to args_to_config --- freqtrade/configuration.py | 54 ++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/freqtrade/configuration.py b/freqtrade/configuration.py index 395653213..2b9b02630 100644 --- a/freqtrade/configuration.py +++ b/freqtrade/configuration.py @@ -216,7 +216,7 @@ class Configuration(object): logger.info(f'Created data directory: {datadir}') return datadir - def _args_to_config(self, config, argname, configname, logstring, logfun=None) -> bool: + def _args_to_config(self, config, argname, configname, logstring, logfun=None) -> None: """ logfun is applied to the configuration entry before passing that entry to the log string using .format(). @@ -230,7 +230,7 @@ class Configuration(object): else: logger.info(logstring.format(config[configname])) - def _load_backtesting_config(self, config: Dict[str, Any]) -> Dict[str, Any]: # noqa: C901 + def _load_backtesting_config(self, config: Dict[str, Any]) -> Dict[str, Any]: """ Extract information for sys.argv and load Backtesting configuration :return: configuration as dictionary @@ -295,9 +295,8 @@ class Configuration(object): :return: configuration as dictionary """ - if 'timerange' in self.args and self.args.timerange: - config.update({'timerange': self.args.timerange}) - logger.info('Parameter --timerange detected: %s ...', self.args.timerange) + self._args_to_config(config, argname='timerange', configname='timerange', + logstring='Parameter --timerange detected: {} ...') if 'stoploss_range' in self.args and self.args.stoploss_range: txt_range = eval(self.args.stoploss_range) @@ -306,9 +305,8 @@ class Configuration(object): config['edge'].update({'stoploss_range_step': txt_range[2]}) logger.info('Parameter --stoplosses detected: %s ...', self.args.stoploss_range) - if 'refresh_pairs' in self.args and self.args.refresh_pairs: - config.update({'refresh_pairs': True}) - logger.info('Parameter -r/--refresh-pairs-cached detected ...') + self._args_to_config(config, argname='refresh_pairs', configname='refresh_pairs', + logstring='Parameter -r/--refresh-pairs-cached detected ...') return config @@ -318,35 +316,29 @@ class Configuration(object): :return: configuration as dictionary """ - if "hyperopt" in self.args: - # Add the hyperopt file to use - config.update({'hyperopt': self.args.hyperopt}) + self._args_to_config(config, argname='hyperopt', configname='hyperopt', + logstring='Using Hyperopt file {}') - if 'epochs' in self.args and self.args.epochs: - config.update({'epochs': self.args.epochs}) - logger.info('Parameter --epochs detected ...') - logger.info('Will run Hyperopt with for %s epochs ...', config.get('epochs')) + self._args_to_config(config, argname='epochs', configname='epochs', + logstring='Parameter --epochs detected ... ' + 'Will run Hyperopt with for {} epochs ...' + ) - if 'spaces' in self.args and self.args.spaces: - config.update({'spaces': self.args.spaces}) - logger.info('Parameter -s/--spaces detected: %s', config.get('spaces')) + self._args_to_config(config, argname='spaces', configname='spaces', + logstring='Parameter -s/--spaces detected: {}') - if 'print_all' in self.args and self.args.print_all: - config.update({'print_all': self.args.print_all}) - logger.info('Parameter --print-all detected: %s', config.get('print_all')) + self._args_to_config(config, argname='print_all', configname='print_all', + logstring='Parameter --print-all detected ...') - if 'hyperopt_jobs' in self.args and self.args.hyperopt_jobs: - config.update({'hyperopt_jobs': self.args.hyperopt_jobs}) - logger.info('Parameter -j/--job-workers detected: %s', config.get('hyperopt_jobs')) + self._args_to_config(config, argname='hyperopt_jobs', configname='hyperopt_jobs', + logstring='Parameter -j/--job-workers detected: {}') - if 'refresh_pairs' in self.args and self.args.refresh_pairs: - config.update({'refresh_pairs': True}) - logger.info('Parameter -r/--refresh-pairs-cached detected ...') + self._args_to_config(config, argname='refresh_pairs', configname='refresh_pairs', + logstring='Parameter -r/--refresh-pairs-cached detected ...') - if 'hyperopt_random_state' in self.args and self.args.hyperopt_random_state is not None: - config.update({'hyperopt_random_state': self.args.hyperopt_random_state}) - logger.info("Parameter --random-state detected: %s", - config.get('hyperopt_random_state')) + self._args_to_config(config, argname='hyperopt_random_state', + configname='hyperopt_random_state', + logstring='Parameter --random-state detected: {}') return config From a0413b5d910e22fbb1a168cb7949c7a6a176b27d Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 24 Apr 2019 21:12:23 +0200 Subject: [PATCH 4/9] Only log one message per call --- freqtrade/tests/optimize/test_hyperopt.py | 5 +++-- freqtrade/tests/test_configuration.py | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/freqtrade/tests/optimize/test_hyperopt.py b/freqtrade/tests/optimize/test_hyperopt.py index 063d0e791..d45f806e5 100644 --- a/freqtrade/tests/optimize/test_hyperopt.py +++ b/freqtrade/tests/optimize/test_hyperopt.py @@ -137,7 +137,8 @@ def test_setup_hyperopt_configuration_with_arguments(mocker, default_conf, caplo ) assert 'epochs' in config - assert log_has('Parameter --epochs detected ...', caplog.record_tuples) + assert log_has('Parameter --epochs detected ... Will run Hyperopt with for 1000 epochs ...', + caplog.record_tuples) assert 'spaces' in config assert log_has( @@ -145,7 +146,7 @@ def test_setup_hyperopt_configuration_with_arguments(mocker, default_conf, caplo caplog.record_tuples ) assert 'print_all' in config - assert log_has('Parameter --print-all detected: True', caplog.record_tuples) + assert log_has('Parameter --print-all detected ...', caplog.record_tuples) def test_hyperoptresolver(mocker, default_conf, caplog) -> None: diff --git a/freqtrade/tests/test_configuration.py b/freqtrade/tests/test_configuration.py index 09041dd3d..663b4fbad 100644 --- a/freqtrade/tests/test_configuration.py +++ b/freqtrade/tests/test_configuration.py @@ -463,8 +463,8 @@ def test_hyperopt_with_arguments(mocker, default_conf, caplog) -> None: assert 'epochs' in config assert int(config['epochs']) == 10 - assert log_has('Parameter --epochs detected ...', caplog.record_tuples) - assert log_has('Will run Hyperopt with for 10 epochs ...', caplog.record_tuples) + assert log_has('Parameter --epochs detected ... Will run Hyperopt with for 10 epochs ...', + caplog.record_tuples) assert 'spaces' in config assert config['spaces'] == ['all'] From ca3b8ef2e7f1c9d745187bcbc59c4ae6dfc343b3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 24 Apr 2019 21:13:57 +0200 Subject: [PATCH 5/9] Remove duplicate argument --- freqtrade/configuration.py | 43 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/freqtrade/configuration.py b/freqtrade/configuration.py index 2b9b02630..5d4b1b9af 100644 --- a/freqtrade/configuration.py +++ b/freqtrade/configuration.py @@ -216,7 +216,7 @@ class Configuration(object): logger.info(f'Created data directory: {datadir}') return datadir - def _args_to_config(self, config, argname, configname, logstring, logfun=None) -> None: + def _args_to_config(self, config, argname, logstring, logfun=None) -> None: """ logfun is applied to the configuration entry before passing that entry to the log string using .format(). @@ -224,11 +224,11 @@ class Configuration(object): """ if argname in self.args and getattr(self.args, argname): - config.update({configname: getattr(self.args, argname)}) + config.update({argname: getattr(self.args, argname)}) if logfun: - logger.info(logstring.format(logfun(config[configname]))) + logger.info(logstring.format(logfun(config[argname]))) else: - logger.info(logstring.format(config[configname])) + logger.info(logstring.format(config[argname])) def _load_backtesting_config(self, config: Dict[str, Any]) -> Dict[str, Any]: """ @@ -242,10 +242,10 @@ class Configuration(object): logger.info('Parameter -i/--ticker-interval detected ...') logger.info('Using ticker_interval: %s ...', config.get('ticker_interval')) - self._args_to_config(config, argname='live', configname='live', + self._args_to_config(config, argname='live', logstring='Parameter -l/--live detected ...') - self._args_to_config(config, argname='position_stacking', configname='position_stacking', + self._args_to_config(config, argname='position_stacking', logstring='Parameter --enable-position-stacking detected ...') if 'use_max_market_positions' in self.args and not self.args.use_max_market_positions: @@ -259,11 +259,11 @@ class Configuration(object): else: logger.info('Using max_open_trades: %s ...', config.get('max_open_trades')) - self._args_to_config(config, argname='stake_amount', configname='stake_amount', + self._args_to_config(config, argname='stake_amount', logstring='Parameter --stake_amount detected, ' 'overriding stake_amount to: {} ...') - self._args_to_config(config, argname='timerange', configname='timerange', + self._args_to_config(config, argname='timerange', logstring='Parameter --timerange detected: {} ...') if 'datadir' in self.args and self.args.datadir: @@ -272,19 +272,19 @@ class Configuration(object): config.update({'datadir': self._create_datadir(config, None)}) logger.info('Using data folder: %s ...', config.get('datadir')) - self._args_to_config(config, argname='refresh_pairs', configname='refresh_pairs', + self._args_to_config(config, argname='refresh_pairs', logstring='Parameter -r/--refresh-pairs-cached detected ...') - self._args_to_config(config, argname='strategy_list', configname='strategy_list', + self._args_to_config(config, argname='strategy_list', logstring='Using strategy list of {} Strategies', logfun=len) - self._args_to_config(config, argname='ticker_interval', configname='ticker_interval', + self._args_to_config(config, argname='ticker_interval', logstring='Overriding ticker interval with Command line argument') - self._args_to_config(config, argname='export', configname='export', + self._args_to_config(config, argname='export', logstring='Parameter --export detected: {} ...') - self._args_to_config(config, argname='exportfilename', configname='exportfilename', + self._args_to_config(config, argname='exportfilename', logstring='Storing backtest results to {} ...') return config @@ -295,7 +295,7 @@ class Configuration(object): :return: configuration as dictionary """ - self._args_to_config(config, argname='timerange', configname='timerange', + self._args_to_config(config, argname='timerange', logstring='Parameter --timerange detected: {} ...') if 'stoploss_range' in self.args and self.args.stoploss_range: @@ -305,7 +305,7 @@ class Configuration(object): config['edge'].update({'stoploss_range_step': txt_range[2]}) logger.info('Parameter --stoplosses detected: %s ...', self.args.stoploss_range) - self._args_to_config(config, argname='refresh_pairs', configname='refresh_pairs', + self._args_to_config(config, argname='refresh_pairs', logstring='Parameter -r/--refresh-pairs-cached detected ...') return config @@ -316,28 +316,27 @@ class Configuration(object): :return: configuration as dictionary """ - self._args_to_config(config, argname='hyperopt', configname='hyperopt', + self._args_to_config(config, argname='hyperopt', logstring='Using Hyperopt file {}') - self._args_to_config(config, argname='epochs', configname='epochs', + self._args_to_config(config, argname='epochs', logstring='Parameter --epochs detected ... ' 'Will run Hyperopt with for {} epochs ...' ) - self._args_to_config(config, argname='spaces', configname='spaces', + self._args_to_config(config, argname='spaces', logstring='Parameter -s/--spaces detected: {}') - self._args_to_config(config, argname='print_all', configname='print_all', + self._args_to_config(config, argname='print_all', logstring='Parameter --print-all detected ...') - self._args_to_config(config, argname='hyperopt_jobs', configname='hyperopt_jobs', + self._args_to_config(config, argname='hyperopt_jobs', logstring='Parameter -j/--job-workers detected: {}') - self._args_to_config(config, argname='refresh_pairs', configname='refresh_pairs', + self._args_to_config(config, argname='refresh_pairs', logstring='Parameter -r/--refresh-pairs-cached detected ...') self._args_to_config(config, argname='hyperopt_random_state', - configname='hyperopt_random_state', logstring='Parameter --random-state detected: {}') return config From 87329c689d3345354dd49d6676edb8503eac9998 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 24 Apr 2019 21:24:00 +0200 Subject: [PATCH 6/9] Change ticker_interval too --- freqtrade/configuration.py | 7 +++---- freqtrade/tests/optimize/test_backtesting.py | 17 ++++++----------- freqtrade/tests/optimize/test_edge_cli.py | 18 ++++++++---------- freqtrade/tests/optimize/test_hyperopt.py | 11 ++++------- freqtrade/tests/test_configuration.py | 14 ++++---------- 5 files changed, 25 insertions(+), 42 deletions(-) diff --git a/freqtrade/configuration.py b/freqtrade/configuration.py index 5d4b1b9af..eea0bf5ae 100644 --- a/freqtrade/configuration.py +++ b/freqtrade/configuration.py @@ -237,10 +237,9 @@ class Configuration(object): """ # This will override the strategy configuration - if 'ticker_interval' in self.args and self.args.ticker_interval: - config.update({'ticker_interval': self.args.ticker_interval}) - logger.info('Parameter -i/--ticker-interval detected ...') - logger.info('Using ticker_interval: %s ...', config.get('ticker_interval')) + self._args_to_config(config, argname='ticker_interval', + logstring='Parameter -i/--ticker-interval detected ... ' + 'Using ticker_interval: {} ...') self._args_to_config(config, argname='live', logstring='Parameter -l/--live detected ...') diff --git a/freqtrade/tests/optimize/test_backtesting.py b/freqtrade/tests/optimize/test_backtesting.py index af0b07d6f..281ce2bfe 100644 --- a/freqtrade/tests/optimize/test_backtesting.py +++ b/freqtrade/tests/optimize/test_backtesting.py @@ -23,7 +23,7 @@ from freqtrade.optimize.backtesting import (Backtesting, setup_configuration, from freqtrade.state import RunMode from freqtrade.strategy.default_strategy import DefaultStrategy from freqtrade.strategy.interface import SellType -from freqtrade.tests.conftest import log_has, patch_exchange +from freqtrade.tests.conftest import log_has, log_has_re, patch_exchange def get_args(args) -> List[str]: @@ -190,7 +190,7 @@ def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> caplog.record_tuples ) assert 'ticker_interval' in config - assert not log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples) + assert not log_has_re('Parameter -i/--ticker-interval detected .*', caplog.record_tuples) assert 'live' not in config assert not log_has('Parameter -l/--live detected ...', caplog.record_tuples) @@ -242,11 +242,8 @@ def test_setup_bt_configuration_with_arguments(mocker, default_conf, caplog) -> caplog.record_tuples ) assert 'ticker_interval' in config - assert log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples) - assert log_has( - 'Using ticker_interval: 1m ...', - caplog.record_tuples - ) + assert log_has('Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...', + caplog.record_tuples) assert 'live' in config assert log_has('Parameter -l/--live detected ...', caplog.record_tuples) @@ -853,8 +850,7 @@ def test_backtest_start_live(default_conf, mocker, caplog): start(args) # check the logs, that will contain the backtest result exists = [ - 'Parameter -i/--ticker-interval detected ...', - 'Using ticker_interval: 1m ...', + 'Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...', 'Parameter -l/--live detected ...', 'Ignoring max_open_trades (--disable-max-market-positions was used) ...', 'Parameter --timerange detected: -100 ...', @@ -912,8 +908,7 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog): # check the logs, that will contain the backtest result exists = [ - 'Parameter -i/--ticker-interval detected ...', - 'Using ticker_interval: 1m ...', + 'Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...', 'Parameter -l/--live detected ...', 'Ignoring max_open_trades (--disable-max-market-positions was used) ...', 'Parameter --timerange detected: -100 ...', diff --git a/freqtrade/tests/optimize/test_edge_cli.py b/freqtrade/tests/optimize/test_edge_cli.py index a58620139..488d552c8 100644 --- a/freqtrade/tests/optimize/test_edge_cli.py +++ b/freqtrade/tests/optimize/test_edge_cli.py @@ -1,14 +1,15 @@ # pragma pylint: disable=missing-docstring, C0103, C0330 # pragma pylint: disable=protected-access, too-many-lines, invalid-name, too-many-arguments -from unittest.mock import MagicMock import json from typing import List -from freqtrade.edge import PairInfo +from unittest.mock import MagicMock + from freqtrade.arguments import Arguments -from freqtrade.optimize.edge_cli import (EdgeCli, setup_configuration, start) +from freqtrade.edge import PairInfo +from freqtrade.optimize.edge_cli import EdgeCli, setup_configuration, start from freqtrade.state import RunMode -from freqtrade.tests.conftest import log_has, patch_exchange +from freqtrade.tests.conftest import log_has, log_has_re, patch_exchange def get_args(args) -> List[str]: @@ -40,7 +41,7 @@ def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> caplog.record_tuples ) assert 'ticker_interval' in config - assert not log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples) + assert not log_has_re('Parameter -i/--ticker-interval detected .*', caplog.record_tuples) assert 'refresh_pairs' not in config assert not log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog.record_tuples) @@ -79,11 +80,8 @@ def test_setup_edge_configuration_with_arguments(mocker, edge_conf, caplog) -> N caplog.record_tuples ) assert 'ticker_interval' in config - assert log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples) - assert log_has( - 'Using ticker_interval: 1m ...', - caplog.record_tuples - ) + assert log_has('Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...', + caplog.record_tuples) assert 'refresh_pairs' in config assert log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog.record_tuples) diff --git a/freqtrade/tests/optimize/test_hyperopt.py b/freqtrade/tests/optimize/test_hyperopt.py index d45f806e5..aa3381e95 100644 --- a/freqtrade/tests/optimize/test_hyperopt.py +++ b/freqtrade/tests/optimize/test_hyperopt.py @@ -14,7 +14,7 @@ from freqtrade.optimize.hyperopt import Hyperopt, start, setup_configuration from freqtrade.optimize.default_hyperopt import DefaultHyperOpts from freqtrade.resolvers import StrategyResolver, HyperOptResolver from freqtrade.state import RunMode -from freqtrade.tests.conftest import log_has, patch_exchange +from freqtrade.tests.conftest import log_has, log_has_re, patch_exchange from freqtrade.tests.optimize.test_backtesting import get_args @@ -64,7 +64,7 @@ def test_setup_hyperopt_configuration_without_arguments(mocker, default_conf, ca caplog.record_tuples ) assert 'ticker_interval' in config - assert not log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples) + assert not log_has_re('Parameter -i/--ticker-interval detected .*', caplog.record_tuples) assert 'live' not in config assert not log_has('Parameter -l/--live detected ...', caplog.record_tuples) @@ -114,11 +114,8 @@ def test_setup_hyperopt_configuration_with_arguments(mocker, default_conf, caplo caplog.record_tuples ) assert 'ticker_interval' in config - assert log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples) - assert log_has( - 'Using ticker_interval: 1m ...', - caplog.record_tuples - ) + assert log_has('Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...', + caplog.record_tuples) assert 'position_stacking' in config assert log_has('Parameter --enable-position-stacking detected ...', caplog.record_tuples) diff --git a/freqtrade/tests/test_configuration.py b/freqtrade/tests/test_configuration.py index 663b4fbad..aee0dfadd 100644 --- a/freqtrade/tests/test_configuration.py +++ b/freqtrade/tests/test_configuration.py @@ -360,11 +360,8 @@ def test_setup_configuration_with_arguments(mocker, default_conf, caplog) -> Non caplog.record_tuples ) assert 'ticker_interval' in config - assert log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples) - assert log_has( - 'Using ticker_interval: 1m ...', - caplog.record_tuples - ) + assert log_has('Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...', + caplog.record_tuples) assert 'live' in config assert log_has('Parameter -l/--live detected ...', caplog.record_tuples) @@ -425,11 +422,8 @@ def test_setup_configuration_with_stratlist(mocker, default_conf, caplog) -> Non caplog.record_tuples ) assert 'ticker_interval' in config - assert log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples) - assert log_has( - 'Using ticker_interval: 1m ...', - caplog.record_tuples - ) + assert log_has('Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...', + caplog.record_tuples) assert 'strategy_list' in config assert log_has('Using strategy list of 2 Strategies', caplog.record_tuples) From 86313b337a6edb075066ea120d63a93a7219ce39 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 24 Apr 2019 21:27:32 +0200 Subject: [PATCH 7/9] Combine optimize configurations, eliminate duplicates --- freqtrade/configuration.py | 42 ++++++-------------------------------- 1 file changed, 6 insertions(+), 36 deletions(-) diff --git a/freqtrade/configuration.py b/freqtrade/configuration.py index eea0bf5ae..062c877ec 100644 --- a/freqtrade/configuration.py +++ b/freqtrade/configuration.py @@ -95,14 +95,8 @@ class Configuration(object): # Load Common configuration config = self._load_common_config(config) - # Load Backtesting - config = self._load_backtesting_config(config) - - # Load Edge - config = self._load_edge_config(config) - - # Load Hyperopt - config = self._load_hyperopt_config(config) + # Load Optimize configurations + config = self._load_optimize_config(config) # Set runmode if not self.runmode: @@ -230,9 +224,9 @@ class Configuration(object): else: logger.info(logstring.format(config[argname])) - def _load_backtesting_config(self, config: Dict[str, Any]) -> Dict[str, Any]: + def _load_optimize_config(self, config: Dict[str, Any]) -> Dict[str, Any]: """ - Extract information for sys.argv and load Backtesting configuration + Extract information for sys.argv and load Optimize configuration :return: configuration as dictionary """ @@ -286,17 +280,7 @@ class Configuration(object): self._args_to_config(config, argname='exportfilename', logstring='Storing backtest results to {} ...') - return config - - def _load_edge_config(self, config: Dict[str, Any]) -> Dict[str, Any]: - """ - Extract information for sys.argv and load Edge configuration - :return: configuration as dictionary - """ - - self._args_to_config(config, argname='timerange', - logstring='Parameter --timerange detected: {} ...') - + # Edge section: if 'stoploss_range' in self.args and self.args.stoploss_range: txt_range = eval(self.args.stoploss_range) config['edge'].update({'stoploss_range_min': txt_range[0]}) @@ -304,17 +288,7 @@ class Configuration(object): config['edge'].update({'stoploss_range_step': txt_range[2]}) logger.info('Parameter --stoplosses detected: %s ...', self.args.stoploss_range) - self._args_to_config(config, argname='refresh_pairs', - logstring='Parameter -r/--refresh-pairs-cached detected ...') - - return config - - def _load_hyperopt_config(self, config: Dict[str, Any]) -> Dict[str, Any]: - """ - Extract information for sys.argv and load Hyperopt configuration - :return: configuration as dictionary - """ - + # Hyperopt section self._args_to_config(config, argname='hyperopt', logstring='Using Hyperopt file {}') @@ -332,12 +306,8 @@ class Configuration(object): self._args_to_config(config, argname='hyperopt_jobs', logstring='Parameter -j/--job-workers detected: {}') - self._args_to_config(config, argname='refresh_pairs', - logstring='Parameter -r/--refresh-pairs-cached detected ...') - self._args_to_config(config, argname='hyperopt_random_state', logstring='Parameter --random-state detected: {}') - return config def _validate_config_schema(self, conf: Dict[str, Any]) -> Dict[str, Any]: From b4630c403d2aa88f1be79b80ec9510006a18e388 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 24 Apr 2019 21:32:33 +0200 Subject: [PATCH 8/9] Add typehints --- freqtrade/configuration.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/freqtrade/configuration.py b/freqtrade/configuration.py index 062c877ec..0eb773eb5 100644 --- a/freqtrade/configuration.py +++ b/freqtrade/configuration.py @@ -7,7 +7,7 @@ import os import sys from argparse import Namespace from logging.handlers import RotatingFileHandler -from typing import Any, Dict, List, Optional +from typing import Any, Callable, Dict, List, Optional from jsonschema import Draft4Validator, validators from jsonschema.exceptions import ValidationError, best_match @@ -17,7 +17,6 @@ from freqtrade.exchange import is_exchange_supported, supported_exchanges from freqtrade.misc import deep_merge_dicts from freqtrade.state import RunMode - logger = logging.getLogger(__name__) @@ -210,11 +209,16 @@ class Configuration(object): logger.info(f'Created data directory: {datadir}') return datadir - def _args_to_config(self, config, argname, logstring, logfun=None) -> None: + def _args_to_config(self, config: Dict[str, Any], argname: str, + logstring: str, logfun=Optional[Callable]) -> None: """ - logfun is applied to the configuration entry before passing - that entry to the log string using .format(). - sample: logfun=len (prints the length of the found configuration instead of the content) + :param config: Configuration dictionary + :param argname: Argumentname in self.args - will be copied to config dict. + :param logstring: Logging String + :param logfun: logfun is applied to the configuration entry before passing + that entry to the log string using .format(). + sample: logfun=len (prints the length of the found + configuration instead of the content) """ if argname in self.args and getattr(self.args, argname): From 22eb6cb5fa181e7fd1b2d64cdd53ccfc23a41325 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 24 Apr 2019 22:08:56 +0200 Subject: [PATCH 9/9] Fix typo in args_to_config --- freqtrade/configuration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/configuration.py b/freqtrade/configuration.py index 0eb773eb5..54862ff70 100644 --- a/freqtrade/configuration.py +++ b/freqtrade/configuration.py @@ -210,7 +210,7 @@ class Configuration(object): return datadir def _args_to_config(self, config: Dict[str, Any], argname: str, - logstring: str, logfun=Optional[Callable]) -> None: + logstring: str, logfun: Optional[Callable] = None) -> None: """ :param config: Configuration dictionary :param argname: Argumentname in self.args - will be copied to config dict.