Merge pull request #2397 from freqtrade/feat/new_args_system

require subcommand for all actions
This commit is contained in:
Matthias
2019-11-14 06:28:42 +01:00
committed by GitHub
39 changed files with 476 additions and 239 deletions

View File

@@ -252,6 +252,7 @@ def default_conf(testdatadir):
"db_url": "sqlite://",
"user_data_dir": Path("user_data"),
"verbosity": 3,
"strategy": "DefaultStrategy"
}
return configuration

View File

@@ -184,9 +184,9 @@ def test_setup_configuration_without_arguments(mocker, default_conf, caplog) ->
patched_configuration_load_config_file(mocker, default_conf)
args = [
'backtesting',
'--config', 'config.json',
'--strategy', 'DefaultStrategy',
'backtesting'
]
config = setup_configuration(get_args(args), RunMode.BACKTEST)
@@ -217,10 +217,10 @@ def test_setup_bt_configuration_with_arguments(mocker, default_conf, caplog) ->
)
args = [
'backtesting',
'--config', 'config.json',
'--strategy', 'DefaultStrategy',
'--datadir', '/foo/bar',
'backtesting',
'--ticker-interval', '1m',
'--enable-position-stacking',
'--disable-max-market-positions',
@@ -269,9 +269,9 @@ def test_setup_configuration_unlimited_stake_amount(mocker, default_conf, caplog
patched_configuration_load_config_file(mocker, default_conf)
args = [
'backtesting',
'--config', 'config.json',
'--strategy', 'DefaultStrategy',
'backtesting'
]
with pytest.raises(DependencyException, match=r'.*stake amount.*'):
@@ -286,9 +286,9 @@ def test_start(mocker, fee, default_conf, caplog) -> None:
patched_configuration_load_config_file(mocker, default_conf)
args = [
'backtesting',
'--config', 'config.json',
'--strategy', 'DefaultStrategy',
'backtesting'
]
args = get_args(args)
start_backtesting(args)
@@ -817,10 +817,10 @@ def test_backtest_start_timerange(default_conf, mocker, caplog, testdatadir):
patched_configuration_load_config_file(mocker, default_conf)
args = [
'backtesting',
'--config', 'config.json',
'--strategy', 'DefaultStrategy',
'--datadir', str(testdatadir),
'backtesting',
'--ticker-interval', '1m',
'--timerange', '1510694220-1510700340',
'--enable-position-stacking',
@@ -866,9 +866,9 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir):
patched_configuration_load_config_file(mocker, default_conf)
args = [
'backtesting',
'--config', 'config.json',
'--datadir', str(testdatadir),
'backtesting',
'--ticker-interval', '1m',
'--timerange', '1510694220-1510700340',
'--enable-position-stacking',

View File

@@ -15,9 +15,9 @@ def test_setup_configuration_without_arguments(mocker, default_conf, caplog) ->
patched_configuration_load_config_file(mocker, default_conf)
args = [
'edge',
'--config', 'config.json',
'--strategy', 'DefaultStrategy',
'edge'
]
config = setup_configuration(get_args(args), RunMode.EDGE)
@@ -45,10 +45,10 @@ def test_setup_edge_configuration_with_arguments(mocker, edge_conf, caplog) -> N
)
args = [
'edge',
'--config', 'config.json',
'--strategy', 'DefaultStrategy',
'--datadir', '/foo/bar',
'edge',
'--ticker-interval', '1m',
'--timerange', ':100',
'--stoplosses=-0.01,-0.10,-0.001'
@@ -79,9 +79,9 @@ def test_start(mocker, fee, edge_conf, caplog) -> None:
patched_configuration_load_config_file(mocker, edge_conf)
args = [
'edge',
'--config', 'config.json',
'--strategy', 'DefaultStrategy',
'edge'
]
args = get_args(args)
start_edge(args)

View File

@@ -26,7 +26,10 @@ from tests.conftest import (get_args, log_has, log_has_re, patch_exchange,
@pytest.fixture(scope='function')
def hyperopt(default_conf, mocker):
default_conf.update({'spaces': ['all']})
default_conf.update({
'spaces': ['all'],
'hyperopt': 'DefaultHyperOpt',
})
patch_exchange(mocker)
return Hyperopt(default_conf)
@@ -69,8 +72,9 @@ def test_setup_hyperopt_configuration_without_arguments(mocker, default_conf, ca
patched_configuration_load_config_file(mocker, default_conf)
args = [
'hyperopt',
'--config', 'config.json',
'hyperopt'
'--hyperopt', 'DefaultHyperOpt',
]
config = setup_configuration(get_args(args), RunMode.HYPEROPT)
@@ -100,9 +104,10 @@ def test_setup_hyperopt_configuration_with_arguments(mocker, default_conf, caplo
)
args = [
'--config', 'config.json',
'--datadir', '/foo/bar',
'hyperopt',
'--config', 'config.json',
'--hyperopt', 'DefaultHyperOpt',
'--datadir', '/foo/bar',
'--ticker-interval', '1m',
'--timerange', ':100',
'--enable-position-stacking',
@@ -157,7 +162,8 @@ def test_hyperoptresolver(mocker, default_conf, caplog) -> None:
'freqtrade.resolvers.hyperopt_resolver.HyperOptResolver._load_hyperopt',
MagicMock(return_value=hyperopt(default_conf))
)
x = HyperOptResolver(default_conf, ).hyperopt
default_conf.update({'hyperopt': 'DefaultHyperOpt'})
x = HyperOptResolver(default_conf).hyperopt
assert not hasattr(x, 'populate_indicators')
assert not hasattr(x, 'populate_buy_trend')
assert not hasattr(x, 'populate_sell_trend')
@@ -174,7 +180,15 @@ def test_hyperoptresolver_wrongname(mocker, default_conf, caplog) -> None:
default_conf.update({'hyperopt': "NonExistingHyperoptClass"})
with pytest.raises(OperationalException, match=r'Impossible to load Hyperopt.*'):
HyperOptResolver(default_conf, ).hyperopt
HyperOptResolver(default_conf).hyperopt
def test_hyperoptresolver_noname(default_conf):
default_conf['hyperopt'] = ''
with pytest.raises(OperationalException,
match="No Hyperopt set. Please use `--hyperopt` to specify "
"the Hyperopt class to use."):
HyperOptResolver(default_conf)
def test_hyperoptlossresolver(mocker, default_conf, caplog) -> None:
@@ -184,7 +198,7 @@ def test_hyperoptlossresolver(mocker, default_conf, caplog) -> None:
'freqtrade.resolvers.hyperopt_resolver.HyperOptLossResolver._load_hyperoptloss',
MagicMock(return_value=hl)
)
x = HyperOptLossResolver(default_conf, ).hyperoptloss
x = HyperOptLossResolver(default_conf).hyperoptloss
assert hasattr(x, "hyperopt_loss_function")
@@ -192,7 +206,7 @@ def test_hyperoptlossresolver_wrongname(mocker, default_conf, caplog) -> None:
default_conf.update({'hyperopt_loss': "NonExistingLossClass"})
with pytest.raises(OperationalException, match=r'Impossible to load HyperoptLoss.*'):
HyperOptLossResolver(default_conf, ).hyperopt
HyperOptLossResolver(default_conf).hyperopt
def test_start_not_installed(mocker, default_conf, caplog, import_fails) -> None:
@@ -203,8 +217,9 @@ def test_start_not_installed(mocker, default_conf, caplog, import_fails) -> None
patch_exchange(mocker)
args = [
'--config', 'config.json',
'hyperopt',
'--config', 'config.json',
'--hyperopt', 'DefaultHyperOpt',
'--epochs', '5'
]
args = get_args(args)
@@ -220,8 +235,9 @@ def test_start(mocker, default_conf, caplog) -> None:
patch_exchange(mocker)
args = [
'--config', 'config.json',
'hyperopt',
'--config', 'config.json',
'--hyperopt', 'DefaultHyperOpt',
'--epochs', '5'
]
args = get_args(args)
@@ -242,8 +258,9 @@ def test_start_no_data(mocker, default_conf, caplog) -> None:
patch_exchange(mocker)
args = [
'--config', 'config.json',
'hyperopt',
'--config', 'config.json',
'--hyperopt', 'DefaultHyperOpt',
'--epochs', '5'
]
args = get_args(args)
@@ -258,8 +275,9 @@ def test_start_filelock(mocker, default_conf, caplog) -> None:
patch_exchange(mocker)
args = [
'--config', 'config.json',
'hyperopt',
'--config', 'config.json',
'--hyperopt', 'DefaultHyperOpt',
'--epochs', '5'
]
args = get_args(args)
@@ -412,6 +430,7 @@ def test_start_calls_optimizer(mocker, default_conf, caplog, capsys) -> None:
patch_exchange(mocker)
default_conf.update({'config': 'config.json.example',
'hyperopt': 'DefaultHyperOpt',
'epochs': 1,
'timerange': None,
'spaces': 'all',
@@ -515,10 +534,12 @@ def test_buy_strategy_generator(hyperopt, testdatadir) -> None:
def test_generate_optimizer(mocker, default_conf) -> None:
default_conf.update({'config': 'config.json.example'})
default_conf.update({'timerange': None})
default_conf.update({'spaces': 'all'})
default_conf.update({'hyperopt_min_trades': 1})
default_conf.update({'config': 'config.json.example',
'hyperopt': 'DefaultHyperOpt',
'timerange': None,
'spaces': 'all',
'hyperopt_min_trades': 1,
})
trades = [
('TRX/BTC', 0.023117, 0.000233, 100)
@@ -582,6 +603,7 @@ def test_generate_optimizer(mocker, default_conf) -> None:
def test_clean_hyperopt(mocker, default_conf, caplog):
patch_exchange(mocker)
default_conf.update({'config': 'config.json.example',
'hyperopt': 'DefaultHyperOpt',
'epochs': 1,
'timerange': None,
'spaces': 'all',
@@ -598,6 +620,7 @@ def test_clean_hyperopt(mocker, default_conf, caplog):
def test_continue_hyperopt(mocker, default_conf, caplog):
patch_exchange(mocker)
default_conf.update({'config': 'config.json.example',
'hyperopt': 'DefaultHyperOpt',
'epochs': 1,
'timerange': None,
'spaces': 'all',
@@ -628,6 +651,7 @@ def test_print_json_spaces_all(mocker, default_conf, caplog, capsys) -> None:
patch_exchange(mocker)
default_conf.update({'config': 'config.json.example',
'hyperopt': 'DefaultHyperOpt',
'epochs': 1,
'timerange': None,
'spaces': 'all',
@@ -666,6 +690,7 @@ def test_print_json_spaces_roi_stoploss(mocker, default_conf, caplog, capsys) ->
patch_exchange(mocker)
default_conf.update({'config': 'config.json.example',
'hyperopt': 'DefaultHyperOpt',
'epochs': 1,
'timerange': None,
'spaces': 'roi stoploss',
@@ -705,6 +730,7 @@ def test_simplified_interface_roi_stoploss(mocker, default_conf, caplog, capsys)
patch_exchange(mocker)
default_conf.update({'config': 'config.json.example',
'hyperopt': 'DefaultHyperOpt',
'epochs': 1,
'timerange': None,
'spaces': 'roi stoploss',
@@ -747,6 +773,7 @@ def test_simplified_interface_all_failed(mocker, default_conf, caplog, capsys) -
patch_exchange(mocker)
default_conf.update({'config': 'config.json.example',
'hyperopt': 'DefaultHyperOpt',
'epochs': 1,
'timerange': None,
'spaces': 'all',
@@ -781,6 +808,7 @@ def test_simplified_interface_buy(mocker, default_conf, caplog, capsys) -> None:
patch_exchange(mocker)
default_conf.update({'config': 'config.json.example',
'hyperopt': 'DefaultHyperOpt',
'epochs': 1,
'timerange': None,
'spaces': 'buy',
@@ -827,6 +855,7 @@ def test_simplified_interface_sell(mocker, default_conf, caplog, capsys) -> None
patch_exchange(mocker)
default_conf.update({'config': 'config.json.example',
'hyperopt': 'DefaultHyperOpt',
'epochs': 1,
'timerange': None,
'spaces': 'sell',
@@ -875,6 +904,7 @@ def test_simplified_interface_failed(mocker, default_conf, caplog, capsys, metho
patch_exchange(mocker)
default_conf.update({'config': 'config.json.example',
'hyperopt': 'DefaultHyperOpt',
'epochs': 1,
'timerange': None,
'spaces': space,

View File

@@ -54,21 +54,30 @@ def test_load_strategy_base64(result, caplog, default_conf):
def test_load_strategy_invalid_directory(result, caplog, default_conf):
default_conf['strategy'] = 'SampleStrategy'
resolver = StrategyResolver(default_conf)
extra_dir = Path.cwd() / 'some/path'
resolver._load_strategy('SampleStrategy', config=default_conf, extra_dir=extra_dir)
assert log_has_re(r'Path .*' + r'some.*path.*' + r'.* does not exist', caplog)
assert 'adx' in resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
assert 'rsi' in resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
def test_load_not_found_strategy(default_conf):
strategy = StrategyResolver(default_conf)
default_conf['strategy'] = 'NotFoundStrategy'
with pytest.raises(OperationalException,
match=r"Impossible to load Strategy 'NotFoundStrategy'. "
r"This class does not exist or contains Python code errors."):
strategy._load_strategy(strategy_name='NotFoundStrategy', config=default_conf)
StrategyResolver(default_conf)
def test_load_strategy_noname(default_conf):
default_conf['strategy'] = ''
with pytest.raises(OperationalException,
match="No strategy set. Please use `--strategy` to specify "
"the strategy class to use."):
StrategyResolver(default_conf)
def test_strategy(result, default_conf):

View File

@@ -11,7 +11,7 @@ from freqtrade.configuration.cli_options import check_int_positive
# Parse common command-line-arguments. Used for all tools
def test_parse_args_none() -> None:
arguments = Arguments([])
arguments = Arguments(['trade'])
assert isinstance(arguments, Arguments)
x = arguments.get_parsed_arg()
assert isinstance(x, dict)
@@ -19,7 +19,7 @@ def test_parse_args_none() -> None:
def test_parse_args_defaults() -> None:
args = Arguments([]).get_parsed_arg()
args = Arguments(['trade']).get_parsed_arg()
assert args["config"] == ['config.json']
assert args["strategy_path"] is None
assert args["datadir"] is None
@@ -27,27 +27,27 @@ def test_parse_args_defaults() -> None:
def test_parse_args_config() -> None:
args = Arguments(['-c', '/dev/null']).get_parsed_arg()
args = Arguments(['trade', '-c', '/dev/null']).get_parsed_arg()
assert args["config"] == ['/dev/null']
args = Arguments(['--config', '/dev/null']).get_parsed_arg()
args = Arguments(['trade', '--config', '/dev/null']).get_parsed_arg()
assert args["config"] == ['/dev/null']
args = Arguments(['--config', '/dev/null',
args = Arguments(['trade', '--config', '/dev/null',
'--config', '/dev/zero'],).get_parsed_arg()
assert args["config"] == ['/dev/null', '/dev/zero']
def test_parse_args_db_url() -> None:
args = Arguments(['--db-url', 'sqlite:///test.sqlite']).get_parsed_arg()
args = Arguments(['trade', '--db-url', 'sqlite:///test.sqlite']).get_parsed_arg()
assert args["db_url"] == 'sqlite:///test.sqlite'
def test_parse_args_verbose() -> None:
args = Arguments(['-v']).get_parsed_arg()
args = Arguments(['trade', '-v']).get_parsed_arg()
assert args["verbosity"] == 1
args = Arguments(['--verbose']).get_parsed_arg()
args = Arguments(['trade', '--verbose']).get_parsed_arg()
assert args["verbosity"] == 1
@@ -69,7 +69,7 @@ def test_parse_args_invalid() -> None:
def test_parse_args_strategy() -> None:
args = Arguments(['--strategy', 'SomeStrategy']).get_parsed_arg()
args = Arguments(['trade', '--strategy', 'SomeStrategy']).get_parsed_arg()
assert args["strategy"] == 'SomeStrategy'
@@ -79,7 +79,7 @@ def test_parse_args_strategy_invalid() -> None:
def test_parse_args_strategy_path() -> None:
args = Arguments(['--strategy-path', '/some/path']).get_parsed_arg()
args = Arguments(['trade', '--strategy-path', '/some/path']).get_parsed_arg()
assert args["strategy_path"] == '/some/path'
@@ -98,8 +98,8 @@ def test_parse_args_backtesting_invalid() -> None:
def test_parse_args_backtesting_custom() -> None:
args = [
'-c', 'test_conf.json',
'backtesting',
'-c', 'test_conf.json',
'--ticker-interval', '1m',
'--strategy-list',
'DefaultStrategy',
@@ -108,7 +108,7 @@ def test_parse_args_backtesting_custom() -> None:
call_args = Arguments(args).get_parsed_arg()
assert call_args["config"] == ['test_conf.json']
assert call_args["verbosity"] == 0
assert call_args["subparser"] == 'backtesting'
assert call_args["command"] == 'backtesting'
assert call_args["func"] is not None
assert call_args["ticker_interval"] == '1m'
assert type(call_args["strategy_list"]) is list
@@ -117,8 +117,8 @@ def test_parse_args_backtesting_custom() -> None:
def test_parse_args_hyperopt_custom() -> None:
args = [
'-c', 'test_conf.json',
'hyperopt',
'-c', 'test_conf.json',
'--epochs', '20',
'--spaces', 'buy'
]
@@ -126,7 +126,7 @@ def test_parse_args_hyperopt_custom() -> None:
assert call_args["config"] == ['test_conf.json']
assert call_args["epochs"] == 20
assert call_args["verbosity"] == 0
assert call_args["subparser"] == 'hyperopt'
assert call_args["command"] == 'hyperopt'
assert call_args["spaces"] == ['buy']
assert call_args["func"] is not None
assert callable(call_args["func"])
@@ -134,8 +134,8 @@ def test_parse_args_hyperopt_custom() -> None:
def test_download_data_options() -> None:
args = [
'--datadir', 'datadir/directory',
'download-data',
'--datadir', 'datadir/directory',
'--pairs-file', 'file_with_pairs',
'--days', '30',
'--exchange', 'binance'
@@ -150,8 +150,8 @@ def test_download_data_options() -> None:
def test_plot_dataframe_options() -> None:
args = [
'-c', 'config.json.example',
'plot-dataframe',
'-c', 'config.json.example',
'--indicators1', 'sma10', 'sma100',
'--indicators2', 'macd', 'fastd', 'fastk',
'--plot-limit', '30',
@@ -186,7 +186,7 @@ def test_config_notallowed(mocker) -> None:
]
pargs = Arguments(args).get_parsed_arg()
assert pargs["config"] is None
assert "config" not in pargs
# When file exists:
mocker.patch.object(Path, "is_file", MagicMock(return_value=True))
@@ -195,7 +195,7 @@ def test_config_notallowed(mocker) -> None:
]
pargs = Arguments(args).get_parsed_arg()
# config is not added even if it exists, since create-userdir is in the notallowed list
assert pargs["config"] is None
assert "config" not in pargs
def test_config_notrequired(mocker) -> None:

View File

@@ -68,7 +68,7 @@ def test_load_config_file(default_conf, mocker, caplog) -> None:
def test__args_to_config(caplog):
arg_list = ['--strategy-path', 'TestTest']
arg_list = ['trade', '--strategy-path', 'TestTest']
args = Arguments(arg_list).get_parsed_arg()
configuration = Configuration(args)
config = {}
@@ -96,7 +96,7 @@ def test_load_config_max_open_trades_zero(default_conf, mocker, caplog) -> None:
default_conf['max_open_trades'] = 0
patched_configuration_load_config_file(mocker, default_conf)
args = Arguments([]).get_parsed_arg()
args = Arguments(['trade']).get_parsed_arg()
configuration = Configuration(args)
validated_conf = configuration.load_config()
@@ -121,7 +121,7 @@ def test_load_config_combine_dicts(default_conf, mocker, caplog) -> None:
configsmock
)
arg_list = ['-c', 'test_conf.json', '--config', 'test2_conf.json', ]
arg_list = ['trade', '-c', 'test_conf.json', '--config', 'test2_conf.json', ]
args = Arguments(arg_list).get_parsed_arg()
configuration = Configuration(args)
validated_conf = configuration.load_config()
@@ -187,7 +187,7 @@ def test_load_config_max_open_trades_minus_one(default_conf, mocker, caplog) ->
default_conf['max_open_trades'] = -1
patched_configuration_load_config_file(mocker, default_conf)
args = Arguments([]).get_parsed_arg()
args = Arguments(['trade']).get_parsed_arg()
configuration = Configuration(args)
validated_conf = configuration.load_config()
@@ -211,11 +211,10 @@ def test_load_config_file_exception(mocker) -> None:
def test_load_config(default_conf, mocker) -> None:
patched_configuration_load_config_file(mocker, default_conf)
args = Arguments([]).get_parsed_arg()
args = Arguments(['trade']).get_parsed_arg()
configuration = Configuration(args)
validated_conf = configuration.load_config()
assert validated_conf.get('strategy') == 'DefaultStrategy'
assert validated_conf.get('strategy_path') is None
assert 'edge' not in validated_conf
@@ -224,6 +223,7 @@ def test_load_config_with_params(default_conf, mocker) -> None:
patched_configuration_load_config_file(mocker, default_conf)
arglist = [
'trade',
'--strategy', 'TestStrategy',
'--strategy-path', '/some/path',
'--db-url', 'sqlite:///someurl',
@@ -243,6 +243,7 @@ def test_load_config_with_params(default_conf, mocker) -> None:
patched_configuration_load_config_file(mocker, conf)
arglist = [
'trade',
'--strategy', 'TestStrategy',
'--strategy-path', '/some/path'
]
@@ -259,6 +260,7 @@ def test_load_config_with_params(default_conf, mocker) -> None:
patched_configuration_load_config_file(mocker, conf)
arglist = [
'trade',
'--strategy', 'TestStrategy',
'--strategy-path', '/some/path'
]
@@ -275,6 +277,7 @@ def test_load_config_with_params(default_conf, mocker) -> None:
patched_configuration_load_config_file(mocker, conf)
arglist = [
'trade',
'--strategy', 'TestStrategy',
'--strategy-path', '/some/path'
]
@@ -293,6 +296,7 @@ def test_load_config_with_params(default_conf, mocker) -> None:
patched_configuration_load_config_file(mocker, conf)
arglist = [
'trade',
'--strategy', 'TestStrategy',
'--strategy-path', '/some/path'
]
@@ -303,6 +307,23 @@ def test_load_config_with_params(default_conf, mocker) -> None:
assert validated_conf.get('db_url') == DEFAULT_DB_DRYRUN_URL
@pytest.mark.parametrize("config_value,expected,arglist", [
(True, True, ['trade', '--dry-run']), # Leave config untouched
(False, True, ['trade', '--dry-run']), # Override config untouched
(False, False, ['trade']), # Leave config untouched
(True, True, ['trade']), # Leave config untouched
])
def test_load_dry_run(default_conf, mocker, config_value, expected, arglist) -> None:
default_conf['dry_run'] = config_value
patched_configuration_load_config_file(mocker, default_conf)
configuration = Configuration(Arguments(arglist).get_parsed_arg())
validated_conf = configuration.load_config()
assert validated_conf.get('dry_run') is expected
def test_load_custom_strategy(default_conf, mocker) -> None:
default_conf.update({
'strategy': 'CustomStrategy',
@@ -310,7 +331,7 @@ def test_load_custom_strategy(default_conf, mocker) -> None:
})
patched_configuration_load_config_file(mocker, default_conf)
args = Arguments([]).get_parsed_arg()
args = Arguments(['trade']).get_parsed_arg()
configuration = Configuration(args)
validated_conf = configuration.load_config()
@@ -322,6 +343,7 @@ def test_show_info(default_conf, mocker, caplog) -> None:
patched_configuration_load_config_file(mocker, default_conf)
arglist = [
'trade',
'--strategy', 'TestStrategy',
'--db-url', 'sqlite:///tmp/testdb',
]
@@ -338,9 +360,9 @@ def test_setup_configuration_without_arguments(mocker, default_conf, caplog) ->
patched_configuration_load_config_file(mocker, default_conf)
arglist = [
'backtesting',
'--config', 'config.json',
'--strategy', 'DefaultStrategy',
'backtesting'
]
args = Arguments(arglist).get_parsed_arg()
@@ -376,11 +398,11 @@ def test_setup_configuration_with_arguments(mocker, default_conf, caplog) -> Non
lambda x, *args, **kwargs: Path(x)
)
arglist = [
'backtesting',
'--config', 'config.json',
'--strategy', 'DefaultStrategy',
'--datadir', '/foo/bar',
'--userdir', "/tmp/freqtrade",
'backtesting',
'--ticker-interval', '1m',
'--enable-position-stacking',
'--disable-max-market-positions',
@@ -427,8 +449,8 @@ def test_setup_configuration_with_stratlist(mocker, default_conf, caplog) -> Non
patched_configuration_load_config_file(mocker, default_conf)
arglist = [
'--config', 'config.json',
'backtesting',
'--config', 'config.json',
'--ticker-interval', '1m',
'--export', '/bar/foo',
'--strategy-list',
@@ -568,7 +590,7 @@ def test_cli_verbose_with_params(default_conf, mocker, caplog) -> None:
# Prevent setting loggers
mocker.patch('freqtrade.loggers._set_loggers', MagicMock)
arglist = ['-vvv']
arglist = ['trade', '-vvv']
args = Arguments(arglist).get_parsed_arg()
configuration = Configuration(args)
@@ -620,7 +642,7 @@ def test_set_logfile(default_conf, mocker):
patched_configuration_load_config_file(mocker, default_conf)
arglist = [
'--logfile', 'test_file.log',
'trade', '--logfile', 'test_file.log',
]
args = Arguments(arglist).get_parsed_arg()
configuration = Configuration(args)
@@ -636,7 +658,7 @@ def test_load_config_warn_forcebuy(default_conf, mocker, caplog) -> None:
default_conf['forcebuy_enable'] = True
patched_configuration_load_config_file(mocker, default_conf)
args = Arguments([]).get_parsed_arg()
args = Arguments(['trade']).get_parsed_arg()
configuration = Configuration(args)
validated_conf = configuration.load_config()
@@ -847,8 +869,8 @@ def test_pairlist_resolving():
def test_pairlist_resolving_with_config(mocker, default_conf):
patched_configuration_load_config_file(mocker, default_conf)
arglist = [
'--config', 'config.json',
'download-data',
'--config', 'config.json',
]
args = Arguments(arglist).get_parsed_arg()
@@ -861,8 +883,8 @@ def test_pairlist_resolving_with_config(mocker, default_conf):
# Override pairs
arglist = [
'--config', 'config.json',
'download-data',
'--config', 'config.json',
'--pairs', 'ETH/BTC', 'XRP/BTC',
]
@@ -883,8 +905,8 @@ def test_pairlist_resolving_with_config_pl(mocker, default_conf):
mocker.patch.object(Path, "open", MagicMock(return_value=MagicMock()))
arglist = [
'--config', 'config.json',
'download-data',
'--config', 'config.json',
'--pairs-file', 'pairs.json',
]
@@ -905,8 +927,8 @@ def test_pairlist_resolving_with_config_pl_not_exists(mocker, default_conf):
mocker.patch.object(Path, "exists", MagicMock(return_value=False))
arglist = [
'--config', 'config.json',
'download-data',
'--config', 'config.json',
'--pairs-file', 'pairs.json',
]

View File

@@ -11,10 +11,16 @@ from freqtrade.freqtradebot import FreqtradeBot
from freqtrade.main import main
from freqtrade.state import State
from freqtrade.worker import Worker
from tests.conftest import (log_has, patch_exchange,
from tests.conftest import (log_has, log_has_re, patch_exchange,
patched_configuration_load_config_file)
def test_parse_args_None(caplog) -> None:
with pytest.raises(SystemExit):
main([])
assert log_has_re(r"Usage of Freqtrade requires a subcommand.*", caplog)
def test_parse_args_backtesting(mocker) -> None:
"""
Test that main() can start backtesting and also ensure we can pass some specific arguments
@@ -29,7 +35,7 @@ def test_parse_args_backtesting(mocker) -> None:
call_args = backtesting_mock.call_args[0][0]
assert call_args["config"] == ['config.json']
assert call_args["verbosity"] == 0
assert call_args["subparser"] == 'backtesting'
assert call_args["command"] == 'backtesting'
assert call_args["func"] is not None
assert callable(call_args["func"])
assert call_args["ticker_interval"] is None
@@ -45,7 +51,7 @@ def test_main_start_hyperopt(mocker) -> None:
call_args = hyperopt_mock.call_args[0][0]
assert call_args["config"] == ['config.json']
assert call_args["verbosity"] == 0
assert call_args["subparser"] == 'hyperopt'
assert call_args["command"] == 'hyperopt'
assert call_args["func"] is not None
assert callable(call_args["func"])
@@ -58,7 +64,7 @@ def test_main_fatal_exception(mocker, default_conf, caplog) -> None:
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock())
args = ['-c', 'config.json.example']
args = ['trade', '-c', 'config.json.example']
# Test Main + the KeyboardInterrupt exception
with pytest.raises(SystemExit):
@@ -75,7 +81,7 @@ def test_main_keyboard_interrupt(mocker, default_conf, caplog) -> None:
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock())
args = ['-c', 'config.json.example']
args = ['trade', '-c', 'config.json.example']
# Test Main + the KeyboardInterrupt exception
with pytest.raises(SystemExit):
@@ -95,7 +101,7 @@ def test_main_operational_exception(mocker, default_conf, caplog) -> None:
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock())
args = ['-c', 'config.json.example']
args = ['trade', '-c', 'config.json.example']
# Test Main + the KeyboardInterrupt exception
with pytest.raises(SystemExit):
@@ -114,15 +120,15 @@ def test_main_reload_conf(mocker, default_conf, caplog) -> None:
OperationalException("Oh snap!")])
mocker.patch('freqtrade.worker.Worker._worker', worker_mock)
patched_configuration_load_config_file(mocker, default_conf)
reconfigure_mock = mocker.patch('freqtrade.main.Worker._reconfigure', MagicMock())
reconfigure_mock = mocker.patch('freqtrade.worker.Worker._reconfigure', MagicMock())
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock())
args = Arguments(['-c', 'config.json.example']).get_parsed_arg()
args = Arguments(['trade', '-c', 'config.json.example']).get_parsed_arg()
worker = Worker(args=args, config=default_conf)
with pytest.raises(SystemExit):
main(['-c', 'config.json.example'])
main(['trade', '-c', 'config.json.example'])
assert log_has('Using config: config.json.example ...', caplog)
assert worker_mock.call_count == 4
@@ -141,7 +147,7 @@ def test_reconfigure(mocker, default_conf) -> None:
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock())
args = Arguments(['-c', 'config.json.example']).get_parsed_arg()
args = Arguments(['trade', '-c', 'config.json.example']).get_parsed_arg()
worker = Worker(args=args, config=default_conf)
freqtrade = worker.freqtrade

View File

@@ -281,8 +281,8 @@ def test_generate_profit_graph(testdatadir):
def test_start_plot_dataframe(mocker):
aup = mocker.patch("freqtrade.plot.plotting.load_and_plot_trades", MagicMock())
args = [
"--config", "config.json.example",
"plot-dataframe",
"--config", "config.json.example",
"--pairs", "ETH/BTC"
]
start_plot_dataframe(get_args(args))
@@ -323,8 +323,8 @@ def test_load_and_plot_trades(default_conf, mocker, caplog, testdatadir):
def test_start_plot_profit(mocker):
aup = mocker.patch("freqtrade.plot.plotting.plot_profit", MagicMock())
args = [
"--config", "config.json.example",
"plot-profit",
"--config", "config.json.example",
"--pairs", "ETH/BTC"
]
start_plot_profit(get_args(args))

View File

@@ -14,7 +14,7 @@ from tests.conftest import get_args, log_has, patch_exchange
def test_setup_utils_configuration():
args = [
'--config', 'config.json.example',
'list-exchanges', '--config', 'config.json.example',
]
config = setup_utils_configuration(get_args(args), RunMode.OTHER)
@@ -95,8 +95,8 @@ def test_list_timeframes(mocker, capsys):
# Test with --config config.json.example
args = [
'--config', 'config.json.example',
"list-timeframes",
'--config', 'config.json.example',
]
start_list_timeframes(get_args(args))
captured = capsys.readouterr()
@@ -139,8 +139,8 @@ def test_list_timeframes(mocker, capsys):
# Test with --one-column
args = [
'--config', 'config.json.example',
"list-timeframes",
'--config', 'config.json.example',
"--one-column",
]
start_list_timeframes(get_args(args))
@@ -182,8 +182,8 @@ def test_list_markets(mocker, markets, capsys):
# Test with --config config.json.example
args = [
'--config', 'config.json.example',
"list-markets",
'--config', 'config.json.example',
"--print-list",
]
start_list_markets(get_args(args), False)
@@ -208,8 +208,8 @@ def test_list_markets(mocker, markets, capsys):
patch_exchange(mocker, api_mock=api_mock, id="bittrex")
# Test with --all: all markets
args = [
'--config', 'config.json.example',
"list-markets", "--all",
'--config', 'config.json.example',
"--print-list",
]
start_list_markets(get_args(args), False)
@@ -221,8 +221,8 @@ def test_list_markets(mocker, markets, capsys):
# Test list-pairs subcommand: active pairs
args = [
'--config', 'config.json.example',
"list-pairs",
'--config', 'config.json.example',
"--print-list",
]
start_list_markets(get_args(args), True)
@@ -233,8 +233,8 @@ def test_list_markets(mocker, markets, capsys):
# Test list-pairs subcommand with --all: all pairs
args = [
'--config', 'config.json.example',
"list-pairs", "--all",
'--config', 'config.json.example',
"--print-list",
]
start_list_markets(get_args(args), True)
@@ -246,8 +246,8 @@ def test_list_markets(mocker, markets, capsys):
# active markets, base=ETH, LTC
args = [
'--config', 'config.json.example',
"list-markets",
'--config', 'config.json.example',
"--base", "ETH", "LTC",
"--print-list",
]
@@ -259,8 +259,8 @@ def test_list_markets(mocker, markets, capsys):
# active markets, base=LTC
args = [
'--config', 'config.json.example',
"list-markets",
'--config', 'config.json.example',
"--base", "LTC",
"--print-list",
]
@@ -272,8 +272,8 @@ def test_list_markets(mocker, markets, capsys):
# active markets, quote=USDT, USD
args = [
'--config', 'config.json.example',
"list-markets",
'--config', 'config.json.example',
"--quote", "USDT", "USD",
"--print-list",
]
@@ -285,8 +285,8 @@ def test_list_markets(mocker, markets, capsys):
# active markets, quote=USDT
args = [
'--config', 'config.json.example',
"list-markets",
'--config', 'config.json.example',
"--quote", "USDT",
"--print-list",
]
@@ -298,8 +298,8 @@ def test_list_markets(mocker, markets, capsys):
# active markets, base=LTC, quote=USDT
args = [
'--config', 'config.json.example',
"list-markets",
'--config', 'config.json.example',
"--base", "LTC", "--quote", "USDT",
"--print-list",
]
@@ -311,8 +311,8 @@ def test_list_markets(mocker, markets, capsys):
# active pairs, base=LTC, quote=USDT
args = [
'--config', 'config.json.example',
"list-pairs",
'--config', 'config.json.example',
"--base", "LTC", "--quote", "USD",
"--print-list",
]
@@ -324,8 +324,8 @@ def test_list_markets(mocker, markets, capsys):
# active markets, base=LTC, quote=USDT, NONEXISTENT
args = [
'--config', 'config.json.example',
"list-markets",
'--config', 'config.json.example',
"--base", "LTC", "--quote", "USDT", "NONEXISTENT",
"--print-list",
]
@@ -337,8 +337,8 @@ def test_list_markets(mocker, markets, capsys):
# active markets, base=LTC, quote=NONEXISTENT
args = [
'--config', 'config.json.example',
"list-markets",
'--config', 'config.json.example',
"--base", "LTC", "--quote", "NONEXISTENT",
"--print-list",
]
@@ -350,8 +350,8 @@ def test_list_markets(mocker, markets, capsys):
# Test tabular output
args = [
'--config', 'config.json.example',
"list-markets",
'--config', 'config.json.example',
]
start_list_markets(get_args(args), False)
captured = capsys.readouterr()
@@ -360,8 +360,8 @@ def test_list_markets(mocker, markets, capsys):
# Test tabular output, no markets found
args = [
'--config', 'config.json.example',
"list-markets",
'--config', 'config.json.example',
"--base", "LTC", "--quote", "NONEXISTENT",
]
start_list_markets(get_args(args), False)
@@ -372,8 +372,8 @@ def test_list_markets(mocker, markets, capsys):
# Test --print-json
args = [
'--config', 'config.json.example',
"list-markets",
'--config', 'config.json.example',
"--print-json"
]
start_list_markets(get_args(args), False)
@@ -384,8 +384,8 @@ def test_list_markets(mocker, markets, capsys):
# Test --print-csv
args = [
'--config', 'config.json.example',
"list-markets",
'--config', 'config.json.example',
"--print-csv"
]
start_list_markets(get_args(args), False)
@@ -396,8 +396,8 @@ def test_list_markets(mocker, markets, capsys):
# Test --one-column
args = [
'--config', 'config.json.example',
"list-markets",
'--config', 'config.json.example',
"--one-column"
]
start_list_markets(get_args(args), False)