minor: configuration cleanup
This commit is contained in:
		| @@ -40,49 +40,20 @@ class Configuration(object): | ||||
|  | ||||
|         return self.config | ||||
|  | ||||
|     def load_config(self) -> Dict[str, Any]: | ||||
|     def _load_config_files(self) -> Dict[str, Any]: | ||||
|         """ | ||||
|         Extract information for sys.argv and load the bot configuration | ||||
|         :return: Configuration dictionary | ||||
|         Iterate through the config files passed in the args, | ||||
|         loading all of them and merging their contents. | ||||
|         """ | ||||
|         config: Dict[str, Any] = {} | ||||
|         # Now expecting a list of config filenames here, not a string | ||||
|  | ||||
|         # We expect here a list of config filenames | ||||
|         for path in self.args.config: | ||||
|             logger.info('Using config: %s ...', path) | ||||
|  | ||||
|             # Merge config options, overwriting old values | ||||
|             config = deep_merge_dicts(self._load_config_file(path), config) | ||||
|  | ||||
|         if 'internals' not in config: | ||||
|             config['internals'] = {} | ||||
|  | ||||
|         logger.info('Validating configuration ...') | ||||
|         validate_config_schema(config) | ||||
|         self._validate_config_consistency(config) | ||||
|  | ||||
|         # Set strategy if not specified in config and or if it's non default | ||||
|         if self.args.strategy != constants.DEFAULT_STRATEGY or not config.get('strategy'): | ||||
|             config.update({'strategy': self.args.strategy}) | ||||
|  | ||||
|         if self.args.strategy_path: | ||||
|             config.update({'strategy_path': self.args.strategy_path}) | ||||
|  | ||||
|         # Load Common configuration | ||||
|         config = self._load_common_config(config) | ||||
|  | ||||
|         # Load Optimize configurations | ||||
|         config = self._load_optimize_config(config) | ||||
|  | ||||
|         # Add plotting options if available | ||||
|         config = self._load_plot_config(config) | ||||
|  | ||||
|         # Set runmode | ||||
|         if not self.runmode: | ||||
|             # Handle real mode, infer dry/live from config | ||||
|             self.runmode = RunMode.DRY_RUN if config.get('dry_run', True) else RunMode.LIVE | ||||
|  | ||||
|         config.update({'runmode': self.runmode}) | ||||
|  | ||||
|         return config | ||||
|  | ||||
|     def _load_config_file(self, path: str) -> Dict[str, Any]: | ||||
| @@ -94,13 +65,50 @@ class Configuration(object): | ||||
|         try: | ||||
|             # Read config from stdin if requested in the options | ||||
|             with open(path) if path != '-' else sys.stdin as file: | ||||
|                 conf = json.load(file) | ||||
|                 config = json.load(file) | ||||
|         except FileNotFoundError: | ||||
|             raise OperationalException( | ||||
|                 f'Config file "{path}" not found!' | ||||
|                 ' Please create a config file or check whether it exists.') | ||||
|  | ||||
|         return conf | ||||
|         return config | ||||
|  | ||||
|     def _normalize_config(self, config: Dict[str, Any]) -> None: | ||||
|         """ | ||||
|         Make config more canonical -- i.e. for example add missing parts that we expect | ||||
|         to be normally in it... | ||||
|         """ | ||||
|         if 'internals' not in config: | ||||
|             config['internals'] = {} | ||||
|  | ||||
|     def load_config(self) -> Dict[str, Any]: | ||||
|         """ | ||||
|         Extract information for sys.argv and load the bot configuration | ||||
|         :return: Configuration dictionary | ||||
|         """ | ||||
|         # Load all configs | ||||
|         config: Dict[str, Any] = self._load_config_files() | ||||
|  | ||||
|         # Make resulting config more canonical | ||||
|         self._normalize_config(config) | ||||
|  | ||||
|         logger.info('Validating configuration ...') | ||||
|         validate_config_schema(config) | ||||
|         self._validate_config_consistency(config) | ||||
|  | ||||
|         # Load Common configuration | ||||
|         self._load_common_config(config) | ||||
|  | ||||
|         # Load Optimize configurations | ||||
|         self._load_optimize_config(config) | ||||
|  | ||||
|         # Add plotting options if available | ||||
|         self._load_plot_config(config) | ||||
|  | ||||
|         # Set runmode | ||||
|         self._load_runmode_config(config) | ||||
|  | ||||
|         return config | ||||
|  | ||||
|     def _load_logging_config(self, config: Dict[str, Any]) -> None: | ||||
|         """ | ||||
| @@ -118,16 +126,22 @@ class Configuration(object): | ||||
|  | ||||
|         setup_logging(config) | ||||
|  | ||||
|     def _load_common_config(self, config: Dict[str, Any]) -> Dict[str, Any]: | ||||
|     def _load_strategy_config(self, config: Dict[str, Any]) -> None: | ||||
|  | ||||
|         # Set strategy if not specified in config and or if it's non default | ||||
|         if self.args.strategy != constants.DEFAULT_STRATEGY or not config.get('strategy'): | ||||
|             config.update({'strategy': self.args.strategy}) | ||||
|  | ||||
|         if self.args.strategy_path: | ||||
|             config.update({'strategy_path': self.args.strategy_path}) | ||||
|  | ||||
|     def _load_common_config(self, config: Dict[str, Any]) -> None: | ||||
|         """ | ||||
|         Extract information for sys.argv and load common configuration | ||||
|         :return: configuration as dictionary | ||||
|         """ | ||||
|         self._load_logging_config(config) | ||||
|  | ||||
|         # Support for sd_notify | ||||
|         if 'sd_notify' in self.args and self.args.sd_notify: | ||||
|             config['internals'].update({'sd_notify': True}) | ||||
|         self._load_strategy_config(config) | ||||
|  | ||||
|         # Add dynamic_whitelist if found | ||||
|         if 'dynamic_whitelist' in self.args and self.args.dynamic_whitelist: | ||||
| @@ -157,6 +171,8 @@ class Configuration(object): | ||||
|                 config['db_url'] = constants.DEFAULT_DB_PROD_URL | ||||
|             logger.info('Dry run is disabled') | ||||
|  | ||||
|         logger.info(f'Using DB: "{config["db_url"]}"') | ||||
|  | ||||
|         if config.get('forcebuy_enable', False): | ||||
|             logger.warning('`forcebuy` RPC message enabled.') | ||||
|  | ||||
| @@ -164,32 +180,13 @@ class Configuration(object): | ||||
|         if config.get('max_open_trades') == -1: | ||||
|             config['max_open_trades'] = float('inf') | ||||
|  | ||||
|         logger.info(f'Using DB: "{config["db_url"]}"') | ||||
|         # Support for sd_notify | ||||
|         if 'sd_notify' in self.args and self.args.sd_notify: | ||||
|             config['internals'].update({'sd_notify': True}) | ||||
|  | ||||
|         # Check if the exchange set by the user is supported | ||||
|         check_exchange(config) | ||||
|  | ||||
|         return config | ||||
|  | ||||
|     def _args_to_config(self, config: Dict[str, Any], argname: str, | ||||
|                         logstring: str, logfun: Optional[Callable] = None) -> None: | ||||
|         """ | ||||
|         :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): | ||||
|  | ||||
|             config.update({argname: getattr(self.args, argname)}) | ||||
|             if logfun: | ||||
|                 logger.info(logstring.format(logfun(config[argname]))) | ||||
|             else: | ||||
|                 logger.info(logstring.format(config[argname])) | ||||
|  | ||||
|     def _load_datadir_config(self, config: Dict[str, Any]) -> None: | ||||
|         """ | ||||
|         Extract information for sys.argv and load datadir configuration: | ||||
| @@ -201,12 +198,11 @@ class Configuration(object): | ||||
|             config.update({'datadir': create_datadir(config, None)}) | ||||
|         logger.info('Using data directory: %s ...', config.get('datadir')) | ||||
|  | ||||
|     def _load_optimize_config(self, config: Dict[str, Any]) -> Dict[str, Any]: | ||||
|     def _load_optimize_config(self, config: Dict[str, Any]) -> None: | ||||
|         """ | ||||
|         Extract information for sys.argv and load Optimize configuration | ||||
|         :return: configuration as dictionary | ||||
|         """ | ||||
|  | ||||
|         # This will override the strategy configuration | ||||
|         self._args_to_config(config, argname='ticker_interval', | ||||
|                              logstring='Parameter -i/--ticker-interval detected ... ' | ||||
| @@ -285,14 +281,11 @@ class Configuration(object): | ||||
|         self._args_to_config(config, argname='hyperopt_min_trades', | ||||
|                              logstring='Parameter --min-trades detected: {}') | ||||
|  | ||||
|         return config | ||||
|  | ||||
|     def _load_plot_config(self, config: Dict[str, Any]) -> Dict[str, Any]: | ||||
|     def _load_plot_config(self, config: Dict[str, Any]) -> None: | ||||
|         """ | ||||
|         Extract information for sys.argv Plotting configuration | ||||
|         :return: configuration as dictionary | ||||
|         """ | ||||
|  | ||||
|         self._args_to_config(config, argname='pairs', | ||||
|                              logstring='Using pairs {}') | ||||
|  | ||||
| @@ -306,7 +299,14 @@ class Configuration(object): | ||||
|                              logstring='Limiting plot to: {}') | ||||
|         self._args_to_config(config, argname='trade_source', | ||||
|                              logstring='Using trades from: {}') | ||||
|         return config | ||||
|  | ||||
|     def _load_runmode_config(self, config: Dict[str, Any]) -> None: | ||||
|         if not self.runmode: | ||||
|             # Handle real mode, infer dry/live from config | ||||
|             self.runmode = RunMode.DRY_RUN if config.get('dry_run', True) else RunMode.LIVE | ||||
|             logger.info("Runmode set to {self.runmode}.") | ||||
|  | ||||
|         config.update({'runmode': self.runmode}) | ||||
|  | ||||
|     def _validate_config_consistency(self, conf: Dict[str, Any]) -> None: | ||||
|         """ | ||||
| @@ -336,3 +336,22 @@ class Configuration(object): | ||||
|             raise OperationalException( | ||||
|                 f'The config trailing_stop_positive_offset needs ' | ||||
|                 'to be greater than trailing_stop_positive_offset in your config.') | ||||
|  | ||||
|     def _args_to_config(self, config: Dict[str, Any], argname: str, | ||||
|                         logstring: str, logfun: Optional[Callable] = None) -> None: | ||||
|         """ | ||||
|         :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): | ||||
|  | ||||
|             config.update({argname: getattr(self.args, argname)}) | ||||
|             if logfun: | ||||
|                 logger.info(logstring.format(logfun(config[argname]))) | ||||
|             else: | ||||
|                 logger.info(logstring.format(config[argname])) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user