add "cfg" argument for overriding any config from command line
This commit is contained in:
parent
5f6eae52a2
commit
79e70016e0
@ -10,7 +10,7 @@ from freqtrade.commands.cli_options import AVAILABLE_CLI_OPTIONS
|
||||
from freqtrade.constants import DEFAULT_CONFIG
|
||||
|
||||
|
||||
ARGS_COMMON = ["verbosity", "logfile", "version", "config", "datadir", "user_data_dir"]
|
||||
ARGS_COMMON = ["verbosity", "logfile", "version", "config", "cfg", "datadir", "user_data_dir"]
|
||||
|
||||
ARGS_STRATEGY = ["strategy", "strategy_path"]
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
"""
|
||||
Definition of cli arguments used in arguments.py
|
||||
"""
|
||||
import argparse
|
||||
from argparse import ArgumentTypeError
|
||||
|
||||
from freqtrade import __version__, constants
|
||||
@ -38,6 +39,50 @@ class Arg:
|
||||
self.kwargs = kwargs
|
||||
|
||||
|
||||
class SetDictFromArgAction(argparse.Action):
|
||||
"""
|
||||
argparse action to split an argument into KEY=VALUE form
|
||||
on the first = and append to a dictionary.
|
||||
"""
|
||||
|
||||
def __call__(self, parser, args, values, option_string=None):
|
||||
for key_value in values:
|
||||
try:
|
||||
(k, v) = key_value.split("=", 2)
|
||||
except ValueError as ex:
|
||||
raise argparse.ArgumentError(self, f"could not parse argument \"{values[0]}\" as k=v format")
|
||||
d = self.set_dict_path_value(getattr(args, self.dest) or {}, k, v)
|
||||
setattr(args, self.dest, d)
|
||||
|
||||
@staticmethod
|
||||
def set_dict_path_value(obj, key, value):
|
||||
root_obj = obj
|
||||
keys = key.split('.')
|
||||
latest = keys.pop()
|
||||
for k in keys:
|
||||
obj[k] = obj.get(k, {})
|
||||
obj = obj[k]
|
||||
latest_key, *value_type = latest.split(':')
|
||||
value_type = value_type[0] if len(value_type) > 0 else None
|
||||
if value_type is None or value_type == "str":
|
||||
value = value
|
||||
elif value_type == "int":
|
||||
value = int(value)
|
||||
elif value_type == "float":
|
||||
value = float(value)
|
||||
elif value_type == "bool":
|
||||
if value == "True" or value == "true" or value == "1":
|
||||
value = True
|
||||
elif value == "False" or value == "false" or value == "0":
|
||||
value = False
|
||||
else:
|
||||
raise ArgumentTypeError(f"Argument '{key}' has unknown value '{value}'. Must be (true|false|True|False|1|0)")
|
||||
else:
|
||||
raise Exception(f"Unsupported arg type '{value_type}'")
|
||||
obj[latest_key] = value
|
||||
return root_obj
|
||||
|
||||
|
||||
# List of available command line options
|
||||
AVAILABLE_CLI_OPTIONS = {
|
||||
# Common options
|
||||
@ -530,4 +575,12 @@ AVAILABLE_CLI_OPTIONS = {
|
||||
help='Do not print epoch details header.',
|
||||
action='store_true',
|
||||
),
|
||||
}
|
||||
"cfg": Arg(
|
||||
'--cfg',
|
||||
nargs='+',
|
||||
metavar="KEY=VALUE",
|
||||
action=SetDictFromArgAction,
|
||||
help='Set any config value.',
|
||||
# action='store_const'
|
||||
),
|
||||
}
|
@ -93,6 +93,9 @@ class Configuration:
|
||||
# Load all configs
|
||||
config: Dict[str, Any] = self.load_from_files(self.args.get("config", []))
|
||||
|
||||
if 'cfg' in self.args:
|
||||
config = deep_merge_dicts(self.args['cfg'] or {}, config)
|
||||
|
||||
# Keep a copy of the original configuration file
|
||||
config['original_config'] = deepcopy(config)
|
||||
|
||||
|
@ -35,6 +35,30 @@ def test_setup_utils_configuration():
|
||||
assert config['exchange']['secret'] == ''
|
||||
|
||||
|
||||
def test_cfg_argument_replaces_configuration():
|
||||
args = [
|
||||
'list-exchanges', '--config', 'config_bittrex.json.example',
|
||||
]
|
||||
|
||||
# Check original config
|
||||
config = setup_utils_configuration(get_args(args), RunMode.OTHER)
|
||||
assert config['dry_run'] is True
|
||||
assert config['exchange']['key'] == ''
|
||||
assert config['stake_amount'] == 0.05
|
||||
assert config['timeframe'] == '5m'
|
||||
|
||||
args = [
|
||||
'list-exchanges', '--config', 'config_bittrex.json.example',
|
||||
'--cfg', 'stake_amount:float=0.1', 'timeframe=15m', 'exchange.sandbox:bool=true',
|
||||
]
|
||||
|
||||
# Check original config
|
||||
config = setup_utils_configuration(get_args(args), RunMode.OTHER)
|
||||
assert config['stake_amount'] == 0.1
|
||||
assert config['timeframe'] == '15m'
|
||||
assert config['exchange']['sandbox'] is True
|
||||
|
||||
|
||||
def test_start_trading_fail(mocker, caplog):
|
||||
|
||||
mocker.patch("freqtrade.worker.Worker.run", MagicMock(side_effect=OperationalException))
|
||||
|
Loading…
Reference in New Issue
Block a user