2018-07-29 14:09:44 +00:00
|
|
|
# pragma pylint: disable=missing-docstring, protected-access, invalid-name
|
2018-03-02 15:22:00 +00:00
|
|
|
|
2018-02-04 06:42:03 +00:00
|
|
|
import json
|
2018-07-04 07:31:35 +00:00
|
|
|
from argparse import Namespace
|
2018-07-19 19:12:27 +00:00
|
|
|
import logging
|
2018-03-06 03:44:27 +00:00
|
|
|
from unittest.mock import MagicMock
|
2018-03-17 21:44:47 +00:00
|
|
|
|
|
|
|
import pytest
|
2018-12-06 05:57:07 +00:00
|
|
|
from jsonschema import validate, ValidationError, Draft4Validator
|
2018-02-04 06:42:03 +00:00
|
|
|
|
2018-07-30 11:57:51 +00:00
|
|
|
from freqtrade import constants
|
2018-07-04 07:31:35 +00:00
|
|
|
from freqtrade import OperationalException
|
2018-02-04 06:42:03 +00:00
|
|
|
from freqtrade.arguments import Arguments
|
2018-07-19 19:12:27 +00:00
|
|
|
from freqtrade.configuration import Configuration, set_loggers
|
2018-07-04 07:31:35 +00:00
|
|
|
from freqtrade.constants import DEFAULT_DB_DRYRUN_URL, DEFAULT_DB_PROD_URL
|
2018-03-04 10:06:40 +00:00
|
|
|
from freqtrade.tests.conftest import log_has
|
2018-02-04 06:42:03 +00:00
|
|
|
|
|
|
|
|
2018-03-30 20:14:35 +00:00
|
|
|
def test_load_config_invalid_pair(default_conf) -> None:
|
2018-07-30 12:40:52 +00:00
|
|
|
default_conf['exchange']['pair_whitelist'].append('ETH-BTC')
|
2018-02-04 06:42:03 +00:00
|
|
|
|
|
|
|
with pytest.raises(ValidationError, match=r'.*does not match.*'):
|
2018-05-31 19:04:10 +00:00
|
|
|
configuration = Configuration(Namespace())
|
2018-07-30 12:40:52 +00:00
|
|
|
configuration._validate_config(default_conf)
|
2018-02-04 06:42:03 +00:00
|
|
|
|
|
|
|
|
2018-03-30 20:14:35 +00:00
|
|
|
def test_load_config_missing_attributes(default_conf) -> None:
|
2018-07-30 12:40:52 +00:00
|
|
|
default_conf.pop('exchange')
|
2018-02-04 06:42:03 +00:00
|
|
|
|
|
|
|
with pytest.raises(ValidationError, match=r'.*\'exchange\' is a required property.*'):
|
2018-05-31 19:04:10 +00:00
|
|
|
configuration = Configuration(Namespace())
|
2018-07-30 12:40:52 +00:00
|
|
|
configuration._validate_config(default_conf)
|
2018-02-04 06:42:03 +00:00
|
|
|
|
|
|
|
|
2018-06-03 22:48:26 +00:00
|
|
|
def test_load_config_incorrect_stake_amount(default_conf) -> None:
|
2018-07-30 12:40:52 +00:00
|
|
|
default_conf['stake_amount'] = 'fake'
|
2018-06-03 22:48:26 +00:00
|
|
|
|
|
|
|
with pytest.raises(ValidationError, match=r'.*\'fake\' does not match \'unlimited\'.*'):
|
2018-06-03 22:52:54 +00:00
|
|
|
configuration = Configuration(Namespace())
|
2018-07-30 12:40:52 +00:00
|
|
|
configuration._validate_config(default_conf)
|
2018-06-03 22:48:26 +00:00
|
|
|
|
|
|
|
|
2018-02-04 06:42:03 +00:00
|
|
|
def test_load_config_file(default_conf, mocker, caplog) -> None:
|
|
|
|
file_mock = mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
|
|
|
read_data=json.dumps(default_conf)
|
|
|
|
))
|
|
|
|
|
2018-05-31 19:04:10 +00:00
|
|
|
configuration = Configuration(Namespace())
|
2018-02-04 06:42:03 +00:00
|
|
|
validated_conf = configuration._load_config_file('somefile')
|
|
|
|
assert file_mock.call_count == 1
|
|
|
|
assert validated_conf.items() >= default_conf.items()
|
|
|
|
assert 'internals' in validated_conf
|
2018-03-04 10:06:40 +00:00
|
|
|
assert log_has('Validating configuration ...', caplog.record_tuples)
|
2018-02-04 06:42:03 +00:00
|
|
|
|
|
|
|
|
2018-05-03 08:48:25 +00:00
|
|
|
def test_load_config_max_open_trades_zero(default_conf, mocker, caplog) -> None:
|
2018-07-30 12:40:52 +00:00
|
|
|
default_conf['max_open_trades'] = 0
|
2018-05-03 08:48:25 +00:00
|
|
|
file_mock = mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
2018-07-30 12:40:52 +00:00
|
|
|
read_data=json.dumps(default_conf)
|
2018-05-03 08:48:25 +00:00
|
|
|
))
|
|
|
|
|
2018-05-31 19:04:10 +00:00
|
|
|
Configuration(Namespace())._load_config_file('somefile')
|
2018-05-03 08:48:25 +00:00
|
|
|
assert file_mock.call_count == 1
|
|
|
|
assert log_has('Validating configuration ...', caplog.record_tuples)
|
|
|
|
|
|
|
|
|
2018-11-14 10:37:53 +00:00
|
|
|
def test_load_config_max_open_trades_minus_one(default_conf, mocker, caplog) -> None:
|
|
|
|
default_conf['max_open_trades'] = -1
|
|
|
|
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
|
|
|
read_data=json.dumps(default_conf)
|
|
|
|
))
|
|
|
|
|
|
|
|
args = Arguments([], '').get_parsed_arg()
|
|
|
|
configuration = Configuration(args)
|
|
|
|
validated_conf = configuration.load_config()
|
|
|
|
print(validated_conf)
|
|
|
|
|
|
|
|
assert validated_conf['max_open_trades'] > 999999999
|
|
|
|
assert validated_conf['max_open_trades'] == float('inf')
|
|
|
|
assert log_has('Validating configuration ...', caplog.record_tuples)
|
|
|
|
|
|
|
|
|
2018-06-08 00:01:38 +00:00
|
|
|
def test_load_config_file_exception(mocker) -> None:
|
2018-03-06 03:44:27 +00:00
|
|
|
mocker.patch(
|
|
|
|
'freqtrade.configuration.open',
|
|
|
|
MagicMock(side_effect=FileNotFoundError('File not found'))
|
|
|
|
)
|
2018-05-31 19:04:10 +00:00
|
|
|
configuration = Configuration(Namespace())
|
2018-03-06 03:44:27 +00:00
|
|
|
|
2018-06-08 00:01:38 +00:00
|
|
|
with pytest.raises(OperationalException, match=r'.*Config file "somefile" not found!*'):
|
2018-03-06 03:44:27 +00:00
|
|
|
configuration._load_config_file('somefile')
|
|
|
|
|
|
|
|
|
2018-02-04 06:42:03 +00:00
|
|
|
def test_load_config(default_conf, mocker) -> None:
|
|
|
|
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
|
|
|
read_data=json.dumps(default_conf)
|
|
|
|
))
|
|
|
|
|
|
|
|
args = Arguments([], '').get_parsed_arg()
|
|
|
|
configuration = Configuration(args)
|
2018-03-03 21:39:39 +00:00
|
|
|
validated_conf = configuration.load_config()
|
2018-02-04 06:42:03 +00:00
|
|
|
|
2018-03-27 16:29:51 +00:00
|
|
|
assert validated_conf.get('strategy') == 'DefaultStrategy'
|
|
|
|
assert validated_conf.get('strategy_path') is None
|
2018-12-03 19:31:25 +00:00
|
|
|
assert 'edge' not in validated_conf
|
2018-02-04 06:42:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_load_config_with_params(default_conf, mocker) -> None:
|
|
|
|
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
|
|
|
read_data=json.dumps(default_conf)
|
|
|
|
))
|
2018-05-31 19:04:10 +00:00
|
|
|
arglist = [
|
2018-02-04 06:42:03 +00:00
|
|
|
'--dynamic-whitelist', '10',
|
2018-03-24 19:44:04 +00:00
|
|
|
'--strategy', 'TestStrategy',
|
2018-03-27 16:29:51 +00:00
|
|
|
'--strategy-path', '/some/path',
|
2018-06-07 03:27:55 +00:00
|
|
|
'--db-url', 'sqlite:///someurl',
|
2018-02-04 06:42:03 +00:00
|
|
|
]
|
2018-05-31 19:04:10 +00:00
|
|
|
args = Arguments(arglist, '').get_parsed_arg()
|
2018-02-04 06:42:03 +00:00
|
|
|
configuration = Configuration(args)
|
2018-03-03 21:39:39 +00:00
|
|
|
validated_conf = configuration.load_config()
|
2018-02-04 06:42:03 +00:00
|
|
|
|
2018-12-04 19:23:03 +00:00
|
|
|
assert validated_conf.get('pairlist', {}).get('method') == 'VolumePairList'
|
|
|
|
assert validated_conf.get('pairlist', {}).get('config').get('number_assets') == 10
|
2018-03-27 16:29:51 +00:00
|
|
|
assert validated_conf.get('strategy') == 'TestStrategy'
|
|
|
|
assert validated_conf.get('strategy_path') == '/some/path'
|
2018-06-07 03:27:55 +00:00
|
|
|
assert validated_conf.get('db_url') == 'sqlite:///someurl'
|
2018-03-27 16:29:51 +00:00
|
|
|
|
2018-06-16 18:55:35 +00:00
|
|
|
conf = default_conf.copy()
|
|
|
|
conf["dry_run"] = False
|
|
|
|
del conf["db_url"]
|
|
|
|
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
|
|
|
read_data=json.dumps(conf)
|
|
|
|
))
|
|
|
|
|
|
|
|
arglist = [
|
2018-07-29 14:09:44 +00:00
|
|
|
'--strategy', 'TestStrategy',
|
|
|
|
'--strategy-path', '/some/path'
|
|
|
|
]
|
2018-06-16 18:55:35 +00:00
|
|
|
args = Arguments(arglist, '').get_parsed_arg()
|
|
|
|
|
|
|
|
configuration = Configuration(args)
|
|
|
|
validated_conf = configuration.load_config()
|
|
|
|
assert validated_conf.get('db_url') == DEFAULT_DB_PROD_URL
|
|
|
|
|
|
|
|
# Test dry=run with ProdURL
|
|
|
|
conf = default_conf.copy()
|
|
|
|
conf["dry_run"] = True
|
|
|
|
conf["db_url"] = DEFAULT_DB_PROD_URL
|
|
|
|
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
|
|
|
read_data=json.dumps(conf)
|
|
|
|
))
|
|
|
|
|
|
|
|
arglist = [
|
|
|
|
'--strategy', 'TestStrategy',
|
|
|
|
'--strategy-path', '/some/path'
|
|
|
|
]
|
|
|
|
args = Arguments(arglist, '').get_parsed_arg()
|
|
|
|
|
|
|
|
configuration = Configuration(args)
|
|
|
|
validated_conf = configuration.load_config()
|
|
|
|
assert validated_conf.get('db_url') == DEFAULT_DB_DRYRUN_URL
|
|
|
|
|
2018-03-27 16:29:51 +00:00
|
|
|
|
|
|
|
def test_load_custom_strategy(default_conf, mocker) -> None:
|
2018-07-30 12:40:52 +00:00
|
|
|
default_conf.update({
|
2018-03-27 16:29:51 +00:00
|
|
|
'strategy': 'CustomStrategy',
|
|
|
|
'strategy_path': '/tmp/strategies',
|
|
|
|
})
|
|
|
|
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
2018-07-30 12:40:52 +00:00
|
|
|
read_data=json.dumps(default_conf)
|
2018-03-27 16:29:51 +00:00
|
|
|
))
|
|
|
|
|
|
|
|
args = Arguments([], '').get_parsed_arg()
|
|
|
|
configuration = Configuration(args)
|
|
|
|
validated_conf = configuration.load_config()
|
|
|
|
|
|
|
|
assert validated_conf.get('strategy') == 'CustomStrategy'
|
|
|
|
assert validated_conf.get('strategy_path') == '/tmp/strategies'
|
2018-02-04 06:42:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_show_info(default_conf, mocker, caplog) -> None:
|
|
|
|
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
|
|
|
read_data=json.dumps(default_conf)
|
|
|
|
))
|
2018-05-31 19:04:10 +00:00
|
|
|
arglist = [
|
2018-02-04 06:42:03 +00:00
|
|
|
'--dynamic-whitelist', '10',
|
2018-03-24 19:44:04 +00:00
|
|
|
'--strategy', 'TestStrategy',
|
2018-06-07 03:27:55 +00:00
|
|
|
'--db-url', 'sqlite:///tmp/testdb',
|
2018-02-04 06:42:03 +00:00
|
|
|
]
|
2018-05-31 19:04:10 +00:00
|
|
|
args = Arguments(arglist, '').get_parsed_arg()
|
2018-02-04 06:42:03 +00:00
|
|
|
|
|
|
|
configuration = Configuration(args)
|
2018-03-03 21:39:39 +00:00
|
|
|
configuration.get_config()
|
|
|
|
|
2018-03-04 10:06:40 +00:00
|
|
|
assert log_has(
|
2018-12-03 19:00:18 +00:00
|
|
|
'Parameter --dynamic-whitelist has been deprecated, '
|
|
|
|
'and will be completely replaced by the whitelist dict in the future. '
|
|
|
|
'For now: using dynamically generated whitelist based on VolumePairList. '
|
2018-03-03 21:39:39 +00:00
|
|
|
'(not applicable with Backtesting and Hyperopt)',
|
|
|
|
caplog.record_tuples
|
|
|
|
)
|
2018-06-07 03:27:55 +00:00
|
|
|
assert log_has('Using DB: "sqlite:///tmp/testdb"', caplog.record_tuples)
|
|
|
|
assert log_has('Dry run is enabled', caplog.record_tuples)
|
2018-02-09 07:35:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> None:
|
|
|
|
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
|
|
|
read_data=json.dumps(default_conf)
|
|
|
|
))
|
2018-05-31 19:04:10 +00:00
|
|
|
arglist = [
|
2018-02-09 07:35:38 +00:00
|
|
|
'--config', 'config.json',
|
2018-03-24 19:44:04 +00:00
|
|
|
'--strategy', 'DefaultStrategy',
|
2018-02-09 07:35:38 +00:00
|
|
|
'backtesting'
|
|
|
|
]
|
|
|
|
|
2018-05-31 19:04:10 +00:00
|
|
|
args = Arguments(arglist, '').get_parsed_arg()
|
2018-02-09 07:35:38 +00:00
|
|
|
|
|
|
|
configuration = Configuration(args)
|
|
|
|
config = configuration.get_config()
|
|
|
|
assert 'max_open_trades' in config
|
|
|
|
assert 'stake_currency' in config
|
|
|
|
assert 'stake_amount' in config
|
|
|
|
assert 'exchange' in config
|
|
|
|
assert 'pair_whitelist' in config['exchange']
|
|
|
|
assert 'datadir' in config
|
2018-03-04 10:06:40 +00:00
|
|
|
assert log_has(
|
2018-06-02 08:32:05 +00:00
|
|
|
'Using data folder: {} ...'.format(config['datadir']),
|
2018-02-09 07:35:38 +00:00
|
|
|
caplog.record_tuples
|
|
|
|
)
|
|
|
|
assert 'ticker_interval' in config
|
2018-03-04 10:06:40 +00:00
|
|
|
assert not log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples)
|
2018-02-09 07:35:38 +00:00
|
|
|
|
|
|
|
assert 'live' not in config
|
2018-03-04 10:06:40 +00:00
|
|
|
assert not log_has('Parameter -l/--live detected ...', caplog.record_tuples)
|
2018-02-09 07:35:38 +00:00
|
|
|
|
2018-07-17 18:26:59 +00:00
|
|
|
assert 'position_stacking' not in config
|
|
|
|
assert not log_has('Parameter --enable-position-stacking detected ...', caplog.record_tuples)
|
2018-02-09 07:35:38 +00:00
|
|
|
|
|
|
|
assert 'refresh_pairs' not in config
|
2018-03-04 10:06:40 +00:00
|
|
|
assert not log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog.record_tuples)
|
2018-02-09 07:35:38 +00:00
|
|
|
|
|
|
|
assert 'timerange' not in config
|
|
|
|
assert 'export' not in config
|
|
|
|
|
|
|
|
|
|
|
|
def test_setup_configuration_with_arguments(mocker, default_conf, caplog) -> None:
|
|
|
|
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
|
|
|
read_data=json.dumps(default_conf)
|
|
|
|
))
|
2019-01-01 13:07:40 +00:00
|
|
|
mocker.patch('freqtrade.configuration.Configuration._create_datadir', lambda s, c, x: x)
|
2018-02-09 07:35:38 +00:00
|
|
|
|
2018-05-31 19:04:10 +00:00
|
|
|
arglist = [
|
2018-02-09 07:35:38 +00:00
|
|
|
'--config', 'config.json',
|
2018-03-24 19:44:04 +00:00
|
|
|
'--strategy', 'DefaultStrategy',
|
2018-02-09 07:35:38 +00:00
|
|
|
'--datadir', '/foo/bar',
|
|
|
|
'backtesting',
|
2018-02-03 16:15:40 +00:00
|
|
|
'--ticker-interval', '1m',
|
2018-02-09 07:35:38 +00:00
|
|
|
'--live',
|
2018-07-17 18:26:59 +00:00
|
|
|
'--enable-position-stacking',
|
2018-07-17 19:05:03 +00:00
|
|
|
'--disable-max-market-positions',
|
2018-02-09 07:35:38 +00:00
|
|
|
'--refresh-pairs-cached',
|
|
|
|
'--timerange', ':100',
|
|
|
|
'--export', '/bar/foo'
|
|
|
|
]
|
|
|
|
|
2018-05-31 19:04:10 +00:00
|
|
|
args = Arguments(arglist, '').get_parsed_arg()
|
2018-02-09 07:35:38 +00:00
|
|
|
|
|
|
|
configuration = Configuration(args)
|
|
|
|
config = configuration.get_config()
|
|
|
|
assert 'max_open_trades' in config
|
|
|
|
assert 'stake_currency' in config
|
|
|
|
assert 'stake_amount' in config
|
|
|
|
assert 'exchange' in config
|
|
|
|
assert 'pair_whitelist' in config['exchange']
|
|
|
|
assert 'datadir' in config
|
2018-03-04 10:06:40 +00:00
|
|
|
assert log_has(
|
2018-06-02 08:32:05 +00:00
|
|
|
'Using data folder: {} ...'.format(config['datadir']),
|
2018-02-09 07:35:38 +00:00
|
|
|
caplog.record_tuples
|
|
|
|
)
|
|
|
|
assert 'ticker_interval' in config
|
2018-03-04 10:06:40 +00:00
|
|
|
assert log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples)
|
|
|
|
assert log_has(
|
2018-03-24 09:21:59 +00:00
|
|
|
'Using ticker_interval: 1m ...',
|
2018-02-09 07:35:38 +00:00
|
|
|
caplog.record_tuples
|
|
|
|
)
|
|
|
|
|
|
|
|
assert 'live' in config
|
2018-03-04 10:06:40 +00:00
|
|
|
assert log_has('Parameter -l/--live detected ...', caplog.record_tuples)
|
2018-02-09 07:35:38 +00:00
|
|
|
|
2018-07-17 18:26:59 +00:00
|
|
|
assert 'position_stacking'in config
|
|
|
|
assert log_has('Parameter --enable-position-stacking detected ...', caplog.record_tuples)
|
2018-07-17 19:05:03 +00:00
|
|
|
|
|
|
|
assert 'use_max_market_positions' in config
|
|
|
|
assert log_has('Parameter --disable-max-market-positions detected ...', caplog.record_tuples)
|
|
|
|
assert log_has('max_open_trades set to unlimited ...', caplog.record_tuples)
|
2018-02-09 07:35:38 +00:00
|
|
|
|
|
|
|
assert 'refresh_pairs'in config
|
2018-03-04 10:06:40 +00:00
|
|
|
assert log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog.record_tuples)
|
2018-02-09 07:35:38 +00:00
|
|
|
assert 'timerange' in config
|
2018-03-04 10:06:40 +00:00
|
|
|
assert log_has(
|
2018-02-09 07:35:38 +00:00
|
|
|
'Parameter --timerange detected: {} ...'.format(config['timerange']),
|
|
|
|
caplog.record_tuples
|
|
|
|
)
|
|
|
|
|
|
|
|
assert 'export' in config
|
2018-03-04 10:06:40 +00:00
|
|
|
assert log_has(
|
2018-02-09 07:35:38 +00:00
|
|
|
'Parameter --export detected: {} ...'.format(config['export']),
|
|
|
|
caplog.record_tuples
|
|
|
|
)
|
2018-03-04 08:51:22 +00:00
|
|
|
|
|
|
|
|
2018-07-28 04:40:39 +00:00
|
|
|
def test_setup_configuration_with_stratlist(mocker, default_conf, caplog) -> None:
|
|
|
|
"""
|
|
|
|
Test setup_configuration() function
|
|
|
|
"""
|
|
|
|
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
|
|
|
read_data=json.dumps(default_conf)
|
|
|
|
))
|
|
|
|
|
|
|
|
arglist = [
|
|
|
|
'--config', 'config.json',
|
|
|
|
'backtesting',
|
|
|
|
'--ticker-interval', '1m',
|
|
|
|
'--export', '/bar/foo',
|
|
|
|
'--strategy-list',
|
|
|
|
'DefaultStrategy',
|
|
|
|
'TestStrategy'
|
|
|
|
]
|
|
|
|
|
|
|
|
args = Arguments(arglist, '').get_parsed_arg()
|
|
|
|
|
|
|
|
configuration = Configuration(args)
|
|
|
|
config = configuration.get_config()
|
|
|
|
assert 'max_open_trades' in config
|
|
|
|
assert 'stake_currency' in config
|
|
|
|
assert 'stake_amount' in config
|
|
|
|
assert 'exchange' in config
|
|
|
|
assert 'pair_whitelist' in config['exchange']
|
|
|
|
assert 'datadir' in config
|
|
|
|
assert log_has(
|
|
|
|
'Using data folder: {} ...'.format(config['datadir']),
|
|
|
|
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 'strategy_list' in config
|
|
|
|
assert log_has('Using strategy list of 2 Strategies', caplog.record_tuples)
|
|
|
|
|
|
|
|
assert 'position_stacking' not in config
|
|
|
|
|
|
|
|
assert 'use_max_market_positions' not in config
|
|
|
|
|
|
|
|
assert 'timerange' not in config
|
|
|
|
|
|
|
|
assert 'export' in config
|
|
|
|
assert log_has(
|
|
|
|
'Parameter --export detected: {} ...'.format(config['export']),
|
|
|
|
caplog.record_tuples
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2018-03-05 07:12:34 +00:00
|
|
|
def test_hyperopt_with_arguments(mocker, default_conf, caplog) -> None:
|
2018-03-04 08:51:22 +00:00
|
|
|
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
|
|
|
read_data=json.dumps(default_conf)
|
|
|
|
))
|
2018-05-31 19:04:10 +00:00
|
|
|
arglist = [
|
2018-03-04 08:51:22 +00:00
|
|
|
'hyperopt',
|
2018-03-05 07:12:34 +00:00
|
|
|
'--epochs', '10',
|
2018-03-04 08:51:22 +00:00
|
|
|
'--spaces', 'all',
|
|
|
|
]
|
2018-05-31 19:04:10 +00:00
|
|
|
args = Arguments(arglist, '').get_parsed_arg()
|
2018-03-04 08:51:22 +00:00
|
|
|
|
|
|
|
configuration = Configuration(args)
|
|
|
|
config = configuration.get_config()
|
2018-03-05 07:12:34 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
|
2018-03-04 08:51:22 +00:00
|
|
|
assert 'spaces' in config
|
2018-03-04 08:58:20 +00:00
|
|
|
assert config['spaces'] == ['all']
|
2018-03-04 10:06:40 +00:00
|
|
|
assert log_has('Parameter -s/--spaces detected: [\'all\']', caplog.record_tuples)
|
2018-03-30 20:14:35 +00:00
|
|
|
|
|
|
|
|
2018-10-04 18:35:28 +00:00
|
|
|
def test_check_exchange(default_conf, caplog) -> None:
|
2018-05-31 19:04:10 +00:00
|
|
|
configuration = Configuration(Namespace())
|
2018-03-30 20:14:35 +00:00
|
|
|
|
|
|
|
# Test a valid exchange
|
2018-07-30 12:40:52 +00:00
|
|
|
default_conf.get('exchange').update({'name': 'BITTREX'})
|
|
|
|
assert configuration.check_exchange(default_conf)
|
2018-03-30 20:14:35 +00:00
|
|
|
|
|
|
|
# Test a valid exchange
|
2018-07-30 12:40:52 +00:00
|
|
|
default_conf.get('exchange').update({'name': 'binance'})
|
|
|
|
assert configuration.check_exchange(default_conf)
|
2018-03-30 20:14:35 +00:00
|
|
|
|
|
|
|
# Test a invalid exchange
|
2018-07-30 12:40:52 +00:00
|
|
|
default_conf.get('exchange').update({'name': 'unknown_exchange'})
|
|
|
|
configuration.config = default_conf
|
2018-03-30 20:14:35 +00:00
|
|
|
|
|
|
|
with pytest.raises(
|
|
|
|
OperationalException,
|
|
|
|
match=r'.*Exchange "unknown_exchange" not supported.*'
|
|
|
|
):
|
2018-07-30 12:40:52 +00:00
|
|
|
configuration.check_exchange(default_conf)
|
2018-07-19 19:12:27 +00:00
|
|
|
|
2018-10-04 18:35:28 +00:00
|
|
|
# Test ccxt_rate_limit depreciation
|
|
|
|
default_conf.get('exchange').update({'name': 'binance'})
|
|
|
|
default_conf['exchange']['ccxt_rate_limit'] = True
|
|
|
|
configuration.check_exchange(default_conf)
|
|
|
|
assert log_has("`ccxt_rate_limit` has been deprecated in favor of "
|
|
|
|
"`ccxt_config` and `ccxt_async_config` and will be removed "
|
2018-10-06 07:23:40 +00:00
|
|
|
"in a future version.",
|
2018-10-04 18:35:28 +00:00
|
|
|
caplog.record_tuples)
|
|
|
|
|
2018-07-19 19:12:27 +00:00
|
|
|
|
|
|
|
def test_cli_verbose_with_params(default_conf, mocker, caplog) -> None:
|
|
|
|
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
|
|
|
read_data=json.dumps(default_conf)))
|
|
|
|
# Prevent setting loggers
|
|
|
|
mocker.patch('freqtrade.configuration.set_loggers', MagicMock)
|
|
|
|
arglist = ['-vvv']
|
|
|
|
args = Arguments(arglist, '').get_parsed_arg()
|
|
|
|
|
|
|
|
configuration = Configuration(args)
|
|
|
|
validated_conf = configuration.load_config()
|
|
|
|
|
|
|
|
assert validated_conf.get('verbosity') == 3
|
|
|
|
assert log_has('Verbosity set to 3', caplog.record_tuples)
|
|
|
|
|
|
|
|
|
|
|
|
def test_set_loggers() -> None:
|
|
|
|
# Reset Logging to Debug, otherwise this fails randomly as it's set globally
|
|
|
|
logging.getLogger('requests').setLevel(logging.DEBUG)
|
|
|
|
logging.getLogger("urllib3").setLevel(logging.DEBUG)
|
|
|
|
logging.getLogger('ccxt.base.exchange').setLevel(logging.DEBUG)
|
|
|
|
logging.getLogger('telegram').setLevel(logging.DEBUG)
|
|
|
|
|
|
|
|
previous_value1 = logging.getLogger('requests').level
|
|
|
|
previous_value2 = logging.getLogger('ccxt.base.exchange').level
|
|
|
|
previous_value3 = logging.getLogger('telegram').level
|
|
|
|
|
|
|
|
set_loggers()
|
|
|
|
|
|
|
|
value1 = logging.getLogger('requests').level
|
|
|
|
assert previous_value1 is not value1
|
|
|
|
assert value1 is logging.INFO
|
|
|
|
|
|
|
|
value2 = logging.getLogger('ccxt.base.exchange').level
|
|
|
|
assert previous_value2 is not value2
|
|
|
|
assert value2 is logging.INFO
|
|
|
|
|
|
|
|
value3 = logging.getLogger('telegram').level
|
|
|
|
assert previous_value3 is not value3
|
|
|
|
assert value3 is logging.INFO
|
|
|
|
|
|
|
|
set_loggers(log_level=2)
|
|
|
|
|
|
|
|
assert logging.getLogger('requests').level is logging.DEBUG
|
|
|
|
assert logging.getLogger('ccxt.base.exchange').level is logging.INFO
|
|
|
|
assert logging.getLogger('telegram').level is logging.INFO
|
|
|
|
|
|
|
|
set_loggers(log_level=3)
|
|
|
|
|
|
|
|
assert logging.getLogger('requests').level is logging.DEBUG
|
|
|
|
assert logging.getLogger('ccxt.base.exchange').level is logging.DEBUG
|
|
|
|
assert logging.getLogger('telegram').level is logging.INFO
|
2018-07-30 11:57:51 +00:00
|
|
|
|
|
|
|
|
2018-10-10 18:13:56 +00:00
|
|
|
def test_load_config_warn_forcebuy(default_conf, mocker, caplog) -> None:
|
|
|
|
default_conf['forcebuy_enable'] = True
|
|
|
|
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
|
|
|
read_data=json.dumps(default_conf)
|
|
|
|
))
|
|
|
|
|
|
|
|
args = Arguments([], '').get_parsed_arg()
|
|
|
|
configuration = Configuration(args)
|
|
|
|
validated_conf = configuration.load_config()
|
|
|
|
|
|
|
|
assert validated_conf.get('forcebuy_enable')
|
|
|
|
assert log_has('`forcebuy` RPC message enabled.', caplog.record_tuples)
|
|
|
|
|
|
|
|
|
2018-07-30 11:57:51 +00:00
|
|
|
def test_validate_default_conf(default_conf) -> None:
|
2018-12-06 05:57:07 +00:00
|
|
|
validate(default_conf, constants.CONF_SCHEMA, Draft4Validator)
|
2019-01-01 13:07:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test__create_datadir(mocker, default_conf, caplog) -> None:
|
|
|
|
mocker.patch('os.path.isdir', MagicMock(return_value=False))
|
|
|
|
md = MagicMock()
|
|
|
|
mocker.patch('os.makedirs', md)
|
|
|
|
cfg = Configuration(Namespace())
|
|
|
|
cfg._create_datadir(default_conf, '/foo/bar')
|
|
|
|
assert md.call_args[0][0] == "/foo/bar"
|
|
|
|
assert log_has('Created data directory: /foo/bar', caplog.record_tuples)
|