have Arguments return a dict instead of Namespace

This commit is contained in:
Matthias 2019-09-12 20:16:39 +02:00
parent 52b186eabe
commit e6ccc1427c
6 changed files with 56 additions and 60 deletions

View File

@ -3,7 +3,6 @@ This module contains the configuration class
"""
import logging
import warnings
from argparse import Namespace
from copy import deepcopy
from pathlib import Path
from typing import Any, Callable, Dict, List, Optional
@ -28,7 +27,7 @@ class Configuration:
Reuse this class for the bot, backtesting, hyperopt and every script that required configuration
"""
def __init__(self, args: Namespace, runmode: RunMode = None) -> None:
def __init__(self, args: Dict[str, Any], runmode: RunMode = None) -> None:
self.args = args
self.config: Optional[Dict[str, Any]] = None
self.runmode = runmode
@ -82,7 +81,7 @@ class Configuration:
:return: Configuration dictionary
"""
# Load all configs
config: Dict[str, Any] = Configuration.from_files(self.args.config)
config: Dict[str, Any] = Configuration.from_files(self.args["config"])
self._process_common_options(config)
@ -107,13 +106,13 @@ class Configuration:
the -v/--verbose, --logfile options
"""
# Log level
if 'verbosity' in self.args and self.args.verbosity:
config.update({'verbosity': self.args.verbosity})
if 'verbosity' in self.args and self.args["verbosity"]:
config.update({'verbosity': self.args["verbosity"]})
else:
config.update({'verbosity': 0})
if 'logfile' in self.args and self.args.logfile:
config.update({'logfile': self.args.logfile})
if 'logfile' in self.args and self.args["logfile"]:
config.update({'logfile': self.args["logfile"]})
setup_logging(config)
@ -122,15 +121,15 @@ class Configuration:
self._process_logging_options(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"] != constants.DEFAULT_STRATEGY or not config.get('strategy'):
config.update({'strategy': self.args["strategy"]})
self._args_to_config(config, argname='strategy_path',
logstring='Using additional Strategy lookup path: {}')
if ('db_url' in self.args and self.args.db_url and
self.args.db_url != constants.DEFAULT_DB_PROD_URL):
config.update({'db_url': self.args.db_url})
if ('db_url' in self.args and self.args["db_url"] and
self.args["db_url"] != constants.DEFAULT_DB_PROD_URL):
config.update({'db_url': self.args["db_url"]})
logger.info('Parameter --db-url detected ...')
if config.get('dry_run', False):
@ -153,7 +152,7 @@ class Configuration:
config['max_open_trades'] = float('inf')
# Support for sd_notify
if 'sd_notify' in self.args and self.args.sd_notify:
if 'sd_notify' in self.args and self.args["sd_notify"]:
config['internals'].update({'sd_notify': True})
def _process_datadir_options(self, config: Dict[str, Any]) -> None:
@ -162,12 +161,12 @@ class Configuration:
--user-data, --datadir
"""
# Check exchange parameter here - otherwise `datadir` might be wrong.
if "exchange" in self.args and self.args.exchange:
config['exchange']['name'] = self.args.exchange
if "exchange" in self.args and self.args["exchange"]:
config['exchange']['name'] = self.args["exchange"]
logger.info(f"Using exchange {config['exchange']['name']}")
if 'user_data_dir' in self.args and self.args.user_data_dir:
config.update({'user_data_dir': self.args.user_data_dir})
if 'user_data_dir' in self.args and self.args["user_data_dir"]:
config.update({'user_data_dir': self.args["user_data_dir"]})
elif 'user_data_dir' not in config:
# Default to cwd/user_data (legacy option ...)
config.update({'user_data_dir': str(Path.cwd() / "user_data")})
@ -176,8 +175,8 @@ class Configuration:
config['user_data_dir'] = create_userdata_dir(config['user_data_dir'], create_dir=False)
logger.info('Using user-data directory: %s ...', config['user_data_dir'])
if 'datadir' in self.args and self.args.datadir:
config.update({'datadir': create_datadir(config, self.args.datadir)})
if 'datadir' in self.args and self.args["datadir"]:
config.update({'datadir': create_datadir(config, self.args["datadir"])})
else:
config.update({'datadir': create_datadir(config, None)})
logger.info('Using data directory: %s ...', config.get('datadir'))
@ -192,12 +191,12 @@ class Configuration:
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:
if 'use_max_market_positions' in self.args and not self.args["use_max_market_positions"]:
config.update({'use_max_market_positions': False})
logger.info('Parameter --disable-max-market-positions detected ...')
logger.info('max_open_trades set to unlimited ...')
elif 'max_open_trades' in self.args and self.args.max_open_trades:
config.update({'max_open_trades': self.args.max_open_trades})
elif 'max_open_trades' in self.args and self.args["max_open_trades"]:
config.update({'max_open_trades': self.args["max_open_trades"]})
logger.info('Parameter --max_open_trades detected, '
'overriding max_open_trades to: %s ...', config.get('max_open_trades'))
else:
@ -229,12 +228,12 @@ class Configuration:
logstring='Storing backtest results to {} ...')
# Edge section:
if 'stoploss_range' in self.args and self.args.stoploss_range:
txt_range = eval(self.args.stoploss_range)
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]})
config['edge'].update({'stoploss_range_max': txt_range[1]})
config['edge'].update({'stoploss_range_step': txt_range[2]})
logger.info('Parameter --stoplosses detected: %s ...', self.args.stoploss_range)
logger.info('Parameter --stoplosses detected: %s ...', self.args["stoploss_range"])
# Hyperopt section
self._args_to_config(config, argname='hyperopt',
@ -254,7 +253,7 @@ class Configuration:
self._args_to_config(config, argname='print_all',
logstring='Parameter --print-all detected ...')
if 'print_colorized' in self.args and not self.args.print_colorized:
if 'print_colorized' in self.args and not self.args["print_colorized"]:
logger.info('Parameter --no-color detected ...')
config.update({'print_colorized': False})
else:
@ -324,9 +323,9 @@ class Configuration:
sample: logfun=len (prints the length of the found
configuration instead of the content)
"""
if argname in self.args and getattr(self.args, argname):
if argname in self.args and self.args[argname]:
config.update({argname: getattr(self.args, argname)})
config.update({argname: self.args[argname]})
if logfun:
logger.info(logstring.format(logfun(config[argname])))
else:
@ -346,8 +345,8 @@ class Configuration:
if "pairs" in config:
return
if "pairs_file" in self.args and self.args.pairs_file:
pairs_file = Path(self.args.pairs_file)
if "pairs_file" in self.args and self.args["pairs_file"]:
pairs_file = Path(self.args["pairs_file"])
logger.info(f'Reading pairs file "{pairs_file}".')
# Download pairs from the pairs file if no config is specified
# or if pairs file is specified explicitely
@ -358,7 +357,7 @@ class Configuration:
config['pairs'].sort()
return
if "config" in self.args and self.args.config:
if "config" in self.args and self.args["config"]:
logger.info("Using pairlist from configuration.")
config['pairs'] = config.get('exchange', {}).get('pair_whitelist')
else:

View File

@ -32,12 +32,12 @@ def main(sysargv: List[str] = None) -> None:
worker = None
try:
arguments = Arguments(sysargv)
args: Namespace = arguments.get_parsed_arg()
args = arguments.get_parsed_arg()
# A subcommand has been issued.
# Means if Backtesting or Hyperopt have been called we exit the bot
if hasattr(args, 'func'):
args.func(args)
if 'func' in args:
args['func'](args)
# TODO: fetch return_code as returned by the command function here
return_code = 0
else:

View File

@ -1,5 +1,4 @@
import logging
from argparse import Namespace
from typing import Any, Dict
from filelock import FileLock, Timeout
@ -12,7 +11,7 @@ from freqtrade.utils import setup_utils_configuration
logger = logging.getLogger(__name__)
def setup_configuration(args: Namespace, method: RunMode) -> Dict[str, Any]:
def setup_configuration(args: Dict[str, Any], method: RunMode) -> Dict[str, Any]:
"""
Prepare the configuration for the Hyperopt module
:param args: Cli args from Arguments()
@ -28,7 +27,7 @@ def setup_configuration(args: Namespace, method: RunMode) -> Dict[str, Any]:
return config
def start_backtesting(args: Namespace) -> None:
def start_backtesting(args: Dict[str, Any]) -> None:
"""
Start Backtesting script
:param args: Cli args from Arguments()
@ -47,7 +46,7 @@ def start_backtesting(args: Namespace) -> None:
backtesting.start()
def start_hyperopt(args: Namespace) -> None:
def start_hyperopt(args: Dict[str, Any]) -> None:
"""
Start hyperopt script
:param args: Cli args from Arguments()
@ -85,7 +84,7 @@ def start_hyperopt(args: Namespace) -> None:
# Same in Edge and Backtesting start() functions.
def start_edge(args: Namespace) -> None:
def start_edge(args: Dict[str, Any]) -> None:
"""
Start Edge script
:param args: Cli args from Arguments()

View File

@ -1,18 +1,18 @@
from argparse import Namespace
from typing import Any, Dict
from freqtrade import OperationalException
from freqtrade.state import RunMode
from freqtrade.utils import setup_utils_configuration
def validate_plot_args(args: Namespace):
args_tmp = vars(args)
if not args_tmp.get('datadir') and not args_tmp.get('config'):
def validate_plot_args(args: Dict[str, Any]):
if not args.get('datadir') and not args.get('config'):
raise OperationalException(
"You need to specify either `--datadir` or `--config` "
"for plot-profit and plot-dataframe.")
def start_plot_dataframe(args: Namespace) -> None:
def start_plot_dataframe(args: Dict[str, Any]) -> None:
"""
Entrypoint for dataframe plotting
"""
@ -24,7 +24,7 @@ def start_plot_dataframe(args: Namespace) -> None:
load_and_plot_trades(config)
def start_plot_profit(args: Namespace) -> None:
def start_plot_profit(args: Dict[str, Any]) -> None:
"""
Entrypoint for plot_profit
"""

View File

@ -1,6 +1,5 @@
import logging
import sys
from argparse import Namespace
from pathlib import Path
from typing import Any, Dict, List
@ -16,7 +15,7 @@ from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
def setup_utils_configuration(args: Namespace, method: RunMode) -> Dict[str, Any]:
def setup_utils_configuration(args: Dict[str, Any], method: RunMode) -> Dict[str, Any]:
"""
Prepare the configuration for utils subcommands
:param args: Cli args from Arguments()
@ -33,34 +32,34 @@ def setup_utils_configuration(args: Namespace, method: RunMode) -> Dict[str, Any
return config
def start_list_exchanges(args: Namespace) -> None:
def start_list_exchanges(args: Dict[str, Any]) -> None:
"""
Print available exchanges
:param args: Cli args from Arguments()
:return: None
"""
if args.print_one_column:
if args['print_one_column']:
print('\n'.join(available_exchanges()))
else:
print(f"Exchanges supported by ccxt and available for Freqtrade: "
f"{', '.join(available_exchanges())}")
def start_create_userdir(args: Namespace) -> None:
def start_create_userdir(args: Dict[str, Any]) -> None:
"""
Create "user_data" directory to contain user data strategies, hyperopts, ...)
:param args: Cli args from Arguments()
:return: None
"""
if "user_data_dir" in args and args.user_data_dir:
create_userdata_dir(args.user_data_dir, create_dir=True)
if "user_data_dir" in args and args["user_data_dir"]:
create_userdata_dir(args["user_data_dir"], create_dir=True)
else:
logger.warning("`create-userdir` requires --userdir to be set.")
sys.exit(1)
def start_download_data(args: Namespace) -> None:
def start_download_data(args: Dict[str, Any]) -> None:
"""
Download data (former download_backtest_data.py script)
"""

View File

@ -4,17 +4,16 @@ Main Freqtrade worker class.
import logging
import time
import traceback
from argparse import Namespace
from typing import Any, Callable, Optional
from typing import Any, Callable, Dict, Optional
import sdnotify
from freqtrade import (constants, OperationalException, TemporaryError,
__version__)
from freqtrade import (OperationalException, TemporaryError, __version__,
constants)
from freqtrade.configuration import Configuration
from freqtrade.freqtradebot import FreqtradeBot
from freqtrade.state import State
from freqtrade.rpc import RPCMessageType
from freqtrade.state import State
logger = logging.getLogger(__name__)
@ -24,7 +23,7 @@ class Worker:
Freqtradebot worker class
"""
def __init__(self, args: Namespace, config=None) -> None:
def __init__(self, args: Dict[str, Any], config=None) -> None:
"""
Init all variables and objects the bot needs to work
"""