コード例 #1
0
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
コード例 #2
0
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(['trade']).get_parsed_arg()
    configuration = Configuration(args)
    validated_conf = configuration.load_config()

    assert validated_conf['max_open_trades'] == 0
    assert 'internals' in validated_conf
コード例 #3
0
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['dry_run'] is expected
    assert validated_conf['runmode'] == (RunMode.DRY_RUN if expected else RunMode.LIVE)
コード例 #4
0
def test_load_config(default_conf, mocker) -> None:
    del default_conf['strategy_path']
    patched_configuration_load_config_file(mocker, default_conf)

    args = Arguments(['trade']).get_parsed_arg()
    configuration = Configuration(args)
    validated_conf = configuration.load_config()

    assert validated_conf.get('strategy_path') is None
    assert 'edge' not in validated_conf
コード例 #5
0
def test_load_config_invalid_pair(default_conf) -> None:
    """
    Test the configuration validator with an invalid PAIR format
    """
    conf = deepcopy(default_conf)
    conf['exchange']['pair_whitelist'].append('ETH-BTC')

    with pytest.raises(ValidationError, match=r'.*does not match.*'):
        configuration = Configuration(Namespace())
        configuration._validate_config(conf)
コード例 #6
0
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(['trade']).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)
コード例 #7
0
def test_setup_configuration_with_arguments(mocker, default_conf,
                                            caplog) -> None:
    patched_configuration_load_config_file(mocker, default_conf)
    mocker.patch('freqtrade.configuration.configuration.create_datadir',
                 lambda c, x: x)
    mocker.patch('freqtrade.configuration.configuration.create_userdata_dir',
                 lambda x, *args, **kwargs: Path(x))
    arglist = [
        'backtesting', '--config', 'config.json', '--strategy',
        'DefaultStrategy', '--datadir', '/foo/bar', '--userdir',
        "/tmp/freqtrade", '--ticker-interval', '1m',
        '--enable-position-stacking', '--disable-max-market-positions',
        '--timerange', ':100', '--export', '/bar/foo', '--stake-amount',
        'unlimited'
    ]

    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 directory: {} ...'.format("/foo/bar"), caplog)
    assert log_has(
        'Using user-data directory: {} ...'.format(Path("/tmp/freqtrade")),
        caplog)
    assert 'user_data_dir' in config

    assert 'timeframe' in config
    assert log_has(
        'Parameter -i/--timeframe detected ... Using timeframe: 1m ...',
        caplog)

    assert 'position_stacking' in config
    assert log_has('Parameter --enable-position-stacking detected ...', caplog)

    assert 'use_max_market_positions' in config
    assert log_has('Parameter --disable-max-market-positions detected ...',
                   caplog)
    assert log_has('max_open_trades set to unlimited ...', caplog)

    assert 'timerange' in config
    assert log_has(
        'Parameter --timerange detected: {} ...'.format(config['timerange']),
        caplog)

    assert 'export' in config
    assert log_has(
        'Parameter --export detected: {} ...'.format(config['export']), caplog)
    assert 'stake_amount' in config
    assert config['stake_amount'] == 'unlimited'
コード例 #8
0
def test_check_exchange(default_conf, caplog) -> None:
    configuration = Configuration(Namespace())

    # Test a valid exchange
    default_conf.get('exchange').update({'name': 'BITTREX'})
    assert configuration.check_exchange(default_conf)

    # Test a valid exchange
    default_conf.get('exchange').update({'name': 'binance'})
    assert configuration.check_exchange(default_conf)

    # Test a invalid exchange
    default_conf.get('exchange').update({'name': 'unknown_exchange'})
    configuration.config = default_conf

    with pytest.raises(OperationalException,
                       match=r'.*Exchange "unknown_exchange" not supported.*'):
        configuration.check_exchange(default_conf)

    # 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 "
        "in a future version.", caplog.record_tuples)
コード例 #9
0
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)))

    arglist = [
        '--config', 'config.json', '--strategy', 'DefaultStrategy',
        '--datadir', '/foo/bar', 'backtesting', '--ticker-interval', '1m',
        '--live', '--enable-position-stacking',
        '--disable-max-market-positions', '--refresh-pairs-cached',
        '--timerange', ':100', '--export', '/bar/foo'
    ]

    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 'live' in config
    assert log_has('Parameter -l/--live detected ...', caplog.record_tuples)

    assert 'position_stacking' in config
    assert log_has('Parameter --enable-position-stacking detected ...',
                   caplog.record_tuples)

    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)

    assert 'refresh_pairs' in config
    assert log_has('Parameter -r/--refresh-pairs-cached detected ...',
                   caplog.record_tuples)
    assert 'timerange' in config
    assert log_has(
        'Parameter --timerange detected: {} ...'.format(config['timerange']),
        caplog.record_tuples)

    assert 'export' in config
    assert log_has(
        'Parameter --export detected: {} ...'.format(config['export']),
        caplog.record_tuples)
コード例 #10
0
def test_load_config_missing_attributes(default_conf) -> None:
    """
    Test the configuration validator with a missing attribute
    """
    conf = deepcopy(default_conf)
    conf.pop('exchange')

    with pytest.raises(ValidationError,
                       match=r'.*\'exchange\' is a required property.*'):
        configuration = Configuration(Namespace())
        configuration._validate_config(conf)
コード例 #11
0
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)
コード例 #12
0
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()
    configuration = Configuration(args)
    validated_conf = configuration.load_config()

    assert validated_conf['max_open_trades'] == 0
    assert 'internals' in validated_conf
    assert log_has('Validating configuration ...', caplog.record_tuples)
コード例 #13
0
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)
    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
コード例 #14
0
def test_load_config_file_exception(mocker) -> None:
    """
    Test Configuration._load_config_file() method
    """
    mocker.patch('freqtrade.configuration.open',
                 MagicMock(side_effect=FileNotFoundError('File not found')))
    configuration = Configuration(Namespace())

    with pytest.raises(OperationalException,
                       match=r'.*Config file "somefile" not found!*'):
        configuration._load_config_file('somefile')
コード例 #15
0
def test_load_config_incorrect_stake_amount(default_conf) -> None:
    """
    Test the configuration validator with a missing attribute
    """
    conf = deepcopy(default_conf)
    conf['stake_amount'] = 'fake'

    with pytest.raises(ValidationError,
                       match=r'.*\'fake\' does not match \'unlimited\'.*'):
        configuration = Configuration(Namespace())
        configuration._validate_config(conf)
コード例 #16
0
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)))

    configuration = Configuration(Namespace())
    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
    assert log_has('Validating configuration ...', caplog.record_tuples)
コード例 #17
0
def test_load_config_with_params(default_conf, mocker) -> None:
    """
    Test Configuration.load_config() with cli params used
    """
    mocker.patch('freqtrade.configuration.open',
                 mocker.mock_open(read_data=json.dumps(default_conf)))

    arglist = [
        '--dynamic-whitelist',
        '10',
        '--strategy',
        'TestStrategy',
        '--strategy-path',
        '/some/path',
        '--db-url',
        'sqlite:///someurl',
    ]
    args = Arguments(arglist, '').get_parsed_arg()

    configuration = Configuration(args)
    validated_conf = configuration.load_config()

    assert validated_conf.get('dynamic_whitelist') == 10
    assert validated_conf.get('strategy') == 'TestStrategy'
    assert validated_conf.get('strategy_path') == '/some/path'
    assert validated_conf.get('db_url') == 'sqlite:///someurl'

    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 = [
        '--dynamic-whitelist', '10', '--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_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 = [
        '--dynamic-whitelist', '10', '--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
コード例 #18
0
def test_setup_configuration_with_arguments(mocker, default_conf,
                                            caplog) -> None:
    """
    Test setup_configuration() function
    """
    mocker.patch('freqtrade.configuration.open',
                 mocker.mock_open(read_data=json.dumps(default_conf)))

    args = [
        '--config', 'config.json', '--strategy', 'DefaultStrategy',
        '--datadir', '/foo/bar', 'backtesting', '--ticker-interval', '1',
        '--live', '--realistic-simulation', '--refresh-pairs-cached',
        '--timerange', ':100', '--export', '/bar/foo'
    ]

    args = Arguments(args, '').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(
        'Parameter --datadir detected: {} ...'.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: 1 ...', caplog.record_tuples)

    assert 'live' in config
    assert log_has('Parameter -l/--live detected ...', caplog.record_tuples)

    assert 'realistic_simulation' in config
    assert log_has('Parameter --realistic-simulation detected ...',
                   caplog.record_tuples)
    assert log_has('Using max_open_trades: 1 ...', caplog.record_tuples)

    assert 'refresh_pairs' in config
    assert log_has('Parameter -r/--refresh-pairs-cached detected ...',
                   caplog.record_tuples)
    assert 'timerange' in config
    assert log_has(
        'Parameter --timerange detected: {} ...'.format(config['timerange']),
        caplog.record_tuples)

    assert 'export' in config
    assert log_has(
        'Parameter --export detected: {} ...'.format(config['export']),
        caplog.record_tuples)
コード例 #19
0
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
    )
コード例 #20
0
def test_check_exchange(default_conf, caplog) -> None:
    configuration = Configuration(Namespace())

    # Test an officially supported by Freqtrade team exchange
    default_conf.get('exchange').update({'name': 'BITTREX'})
    assert configuration.check_exchange(default_conf)
    assert log_has_re(
        r"Exchange .* is officially supported by the Freqtrade development team\.",
        caplog.record_tuples)
    caplog.clear()

    # Test an officially supported by Freqtrade team exchange
    default_conf.get('exchange').update({'name': 'binance'})
    assert configuration.check_exchange(default_conf)
    assert log_has_re(
        r"Exchange .* is officially supported by the Freqtrade development team\.",
        caplog.record_tuples)
    caplog.clear()

    # Test an available exchange, supported by ccxt
    default_conf.get('exchange').update({'name': 'kraken'})
    assert configuration.check_exchange(default_conf)
    assert log_has_re(
        r"Exchange .* is supported by ccxt and .* not officially supported "
        r"by the Freqtrade development team\. .*", caplog.record_tuples)
    caplog.clear()

    # Test a 'bad' exchange, which known to have serious problems
    default_conf.get('exchange').update({'name': 'bitmex'})
    assert not configuration.check_exchange(default_conf)
    assert log_has_re(
        r"Exchange .* is known to not work with the bot yet\. "
        r"Use it only for development and testing purposes\.",
        caplog.record_tuples)
    caplog.clear()

    # Test a 'bad' exchange with check_for_bad=False
    default_conf.get('exchange').update({'name': 'bitmex'})
    assert configuration.check_exchange(default_conf, False)
    assert log_has_re(
        r"Exchange .* is supported by ccxt and .* not officially supported "
        r"by the Freqtrade development team\. .*", caplog.record_tuples)
    caplog.clear()

    # Test an invalid exchange
    default_conf.get('exchange').update({'name': 'unknown_exchange'})
    configuration.config = default_conf

    with pytest.raises(
            OperationalException,
            match=r'.*Exchange "unknown_exchange" is not supported by ccxt '
            r'and therefore not available for the bot.*'):
        configuration.check_exchange(default_conf)
コード例 #21
0
def test_load_config_max_open_trades_minus_one(default_conf, mocker, caplog) -> None:
    default_conf['max_open_trades'] = -1
    patched_configuration_load_config_file(mocker, default_conf)

    args = Arguments(['trade']).get_parsed_arg()
    configuration = Configuration(args)
    validated_conf = configuration.load_config()

    assert validated_conf['max_open_trades'] > 999999999
    assert validated_conf['max_open_trades'] == float('inf')
    assert "runmode" in validated_conf
    assert validated_conf['runmode'] == RunMode.DRY_RUN
コード例 #22
0
def test_pairlist_resolving():
    arglist = [
        'download-data', '--pairs', 'ETH/BTC', 'XRP/BTC', '--exchange',
        'binance'
    ]

    args = Arguments(arglist).get_parsed_arg()

    configuration = Configuration(args, RunMode.OTHER)
    config = configuration.get_config()

    assert config['pairs'] == ['ETH/BTC', 'XRP/BTC']
    assert config['exchange']['name'] == 'binance'
コード例 #23
0
def test_cli_verbose_with_params(default_conf, mocker, caplog) -> None:
    patched_configuration_load_config_file(mocker, default_conf)

    # Prevent setting loggers
    mocker.patch('freqtrade.loggers._set_loggers', MagicMock)
    arglist = ['trade', '-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)
コード例 #24
0
def test_load_custom_strategy(default_conf, mocker) -> None:
    default_conf.update({
        'strategy': 'CustomStrategy',
        'strategy_path': '/tmp/strategies',
    })
    patched_configuration_load_config_file(mocker, default_conf)

    args = Arguments(['trade']).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'
コード例 #25
0
def test_load_config_file_exception(mocker, caplog) -> None:
    """
    Test Configuration._load_config_file() method
    """
    mocker.patch('freqtrade.configuration.open',
                 MagicMock(side_effect=FileNotFoundError('File not found')))
    configuration = Configuration([])

    with pytest.raises(SystemExit):
        configuration._load_config_file('somefile')
    assert log_has(
        'Config file "somefile" not found. Please create your config file',
        caplog.record_tuples)
コード例 #26
0
def test_load_config_default_exchange_name(all_conf) -> None:
    """
    config['exchange']['name'] option is required
    so it cannot be omitted in the config
    """
    del all_conf['exchange']['name']

    assert 'name' not in all_conf['exchange']

    with pytest.raises(ValidationError,
                       match=r'\'name\' is a required property'):
        configuration = Configuration(Namespace())
        configuration._validate_config_schema(all_conf)
コード例 #27
0
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()

    assert validated_conf['max_open_trades'] > 999999999
    assert validated_conf['max_open_trades'] == float('inf')
    assert log_has('Validating configuration ...', caplog.record_tuples)
コード例 #28
0
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)
コード例 #29
0
def test__args_to_config(caplog):

    arg_list = ['trade', '--strategy-path', 'TestTest']
    args = Arguments(arg_list).get_parsed_arg()
    configuration = Configuration(args)
    config = {}
    with warnings.catch_warnings(record=True) as w:
        # No warnings ...
        configuration._args_to_config(config,
                                      argname="strategy_path",
                                      logstring="DeadBeef")
        assert len(w) == 0
        assert log_has("DeadBeef", caplog)
        assert config['strategy_path'] == "TestTest"

    configuration = Configuration(args)
    config = {}
    with warnings.catch_warnings(record=True) as w:
        # Deprecation warnings!
        configuration._args_to_config(config,
                                      argname="strategy_path",
                                      logstring="DeadBeef",
                                      deprecated_msg="Going away soon!")
        assert len(w) == 1
        assert issubclass(w[-1].category, DeprecationWarning)
        assert "DEPRECATED: Going away soon!" in str(w[-1].message)
        assert log_has("DeadBeef", caplog)
        assert config['strategy_path'] == "TestTest"
コード例 #30
0
def test_load_custom_strategy(default_conf, mocker) -> None:
    default_conf.update({
        'strategy': 'CustomStrategy',
        'strategy_path': '/tmp/strategies',
    })
    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('strategy') == 'CustomStrategy'
    assert validated_conf.get('strategy_path') == '/tmp/strategies'