Ejemplo n.º 1
0
def convert_parse_args(args: List[str]) -> Namespace:
    """
    Parse args passed to the script
    :param args: Cli arguments
    :return: args: Array with all arguments
    """
    arguments = Arguments(args, 'Convert datafiles')
    arguments.parser.add_argument(
        '-d',
        '--datadir',
        help='path to backtest data (default: %(default)s',
        dest='datadir',
        default=path.join('freqtrade', 'tests', 'testdata'),
        type=str,
        metavar='PATH',
    )
    arguments.parser.add_argument(
        '-n',
        '--norename',
        help='don'
        't rename files from BTC_<PAIR> to <PAIR>_BTC - '
        'Note that not renaming will overwrite source files',
        dest='norename',
        default=False,
        action='store_true')

    return arguments.parse_args()
Ejemplo n.º 2
0
def test_parse_args_backtesting_invalid() -> None:
    with pytest.raises(SystemExit, match=r'2'):
        Arguments(['backtesting --ticker-interval'], '').get_parsed_arg()

    with pytest.raises(SystemExit, match=r'2'):
        Arguments(['backtesting --ticker-interval', 'abc'],
                  '').get_parsed_arg()
Ejemplo n.º 3
0
def main(sysargv: List[str]) -> None:
    """
    This function will initiate the bot and start the trading loop.
    :return: None
    """
    arguments = Arguments(sysargv, 'Free, open source crypto trading bot')
    args: Namespace = 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)
        return

    worker = None
    return_code = 1
    try:
        # Load and run worker
        worker = Worker(args)
        worker.run()

    except KeyboardInterrupt:
        logger.info('SIGINT received, aborting ...')
        return_code = 0
    except OperationalException as e:
        logger.error(str(e))
        return_code = 2
    except BaseException:
        logger.exception('Fatal exception!')
    finally:
        if worker:
            worker.exit()
        sys.exit(return_code)
Ejemplo n.º 4
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
Ejemplo n.º 5
0
def test_parse_args_config() -> None:
    args = Arguments(['-c', '/dev/null'], '').get_parsed_arg()
    assert args.config == ['/dev/null']

    args = Arguments(['--config', '/dev/null'], '').get_parsed_arg()
    assert args.config == ['/dev/null']

    args = Arguments(['--config', '/dev/null', '--config', '/dev/zero'],
                     '').get_parsed_arg()
    assert args.config == ['/dev/null', '/dev/zero']
Ejemplo n.º 6
0
def test_testdata_dl_options() -> None:
    args = [
        '--pairs-file', 'file_with_pairs', '--export', 'export/folder',
        '--days', '30', '--exchange', 'binance'
    ]
    arguments = Arguments(args, '')
    arguments.testdata_dl_options()
    args = arguments.parse_args()
    assert args.pairs_file == 'file_with_pairs'
    assert args.export == 'export/folder'
    assert args.days == 30
    assert args.exchange == 'binance'
Ejemplo n.º 7
0
def main(sysargv: List[str]) -> None:
    """
    This function will initiate the bot and start the trading loop.
    :return: None
    """
    arguments = Arguments(
        sysargv,
        'Free, open source crypto trading bot'
    )
    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)
        return

    freqtrade = None
    return_code = 1
    try:
        # Load and validate configuration
        config = Configuration(args).get_config()

        # Init the bot
        freqtrade = FreqtradeBot(config)

        state = None
        while True:
            state = freqtrade.worker(old_state=state)
            if state == State.RELOAD_CONF:
                freqtrade = reconfigure(freqtrade, args)

    except KeyboardInterrupt:
        logger.info('SIGINT received, aborting ...')
        return_code = 0
    except OperationalException as e:
        logger.error(str(e))
        return_code = 2
    except BaseException:
        logger.exception('Fatal exception!')
    finally:
        if freqtrade:
            freqtrade.rpc.send_msg({
                'type': RPCMessageType.STATUS_NOTIFICATION,
                'status': 'process died'
            })
            freqtrade.cleanup()
        sys.exit(return_code)
Ejemplo n.º 8
0
def test_show_info(default_conf, mocker, caplog) -> None:
    """
    Test Configuration.show_info()
    """
    mocker.patch('freqtrade.configuration.open',
                 mocker.mock_open(read_data=json.dumps(default_conf)))

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

    configuration = Configuration(args)
    configuration.get_config()

    assert log_has(
        'Parameter --dynamic-whitelist detected. '
        'Using dynamically generated whitelist. '
        '(not applicable with Backtesting and Hyperopt)', caplog.record_tuples)

    assert log_has('Using DB: "sqlite:///tmp/testdb"', caplog.record_tuples)
    assert log_has('Dry run is enabled', caplog.record_tuples)
Ejemplo n.º 9
0
def test_show_info(default_conf, mocker, caplog) -> None:
    """
    Test Configuration.show_info()
    """
    mocker.patch('freqtrade.configuration.open',
                 mocker.mock_open(read_data=json.dumps(default_conf)))

    args = [
        '--dynamic-whitelist', '10', '--strategy', 'TestStrategy',
        '--dry-run-db'
    ]
    args = Arguments(args, '').get_parsed_arg()

    configuration = Configuration(args)
    configuration.get_config()

    assert log_has(
        'Parameter --dynamic-whitelist detected. '
        'Using dynamically generated whitelist. '
        '(not applicable with Backtesting and Hyperopt)', caplog.record_tuples)

    assert log_has('Parameter --dry-run-db detected ...', caplog.record_tuples)

    assert log_has('Dry_run will use the DB file: "tradesv3.dry_run.sqlite"',
                   caplog.record_tuples)

    # Test the Dry run condition
    configuration.config.update({'dry_run': False})
    configuration._load_common_config(configuration.config)
    assert log_has('Dry run is disabled. (--dry_run_db ignored)',
                   caplog.record_tuples)
Ejemplo n.º 10
0
def test_load_config_combine_dicts(default_conf, mocker, caplog) -> None:
    conf1 = deepcopy(default_conf)
    conf2 = deepcopy(default_conf)
    del conf1['exchange']['key']
    del conf1['exchange']['secret']
    del conf2['exchange']['name']
    conf2['exchange']['pair_whitelist'] += ['NANO/BTC']

    config_files = [conf1, conf2]

    configsmock = MagicMock(side_effect=config_files)
    mocker.patch('freqtrade.configuration.Configuration._load_config_file',
                 configsmock)

    arg_list = [
        '-c',
        'test_conf.json',
        '--config',
        'test2_conf.json',
    ]
    args = Arguments(arg_list, '').get_parsed_arg()
    configuration = Configuration(args)
    validated_conf = configuration.load_config()

    exchange_conf = default_conf['exchange']
    assert validated_conf['exchange']['name'] == exchange_conf['name']
    assert validated_conf['exchange']['key'] == exchange_conf['key']
    assert validated_conf['exchange']['secret'] == exchange_conf['secret']
    assert validated_conf['exchange']['pair_whitelist'] != conf1['exchange'][
        'pair_whitelist']
    assert validated_conf['exchange']['pair_whitelist'] == conf2['exchange'][
        'pair_whitelist']

    assert 'internals' in validated_conf
    assert log_has('Validating configuration ...', caplog.record_tuples)
Ejemplo n.º 11
0
def test_reconfigure(mocker, default_conf) -> None:
    patch_exchange(mocker)
    mocker.patch.multiple(
        'freqtrade.freqtradebot.FreqtradeBot',
        _init_modules=MagicMock(),
        worker=MagicMock(side_effect=OperationalException('Oh snap!')),
        cleanup=MagicMock(),
    )
    mocker.patch('freqtrade.configuration.Configuration._load_config_file',
                 lambda *args, **kwargs: default_conf)
    mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())

    freqtrade = FreqtradeBot(default_conf)

    # Renew mock to return modified data
    conf = deepcopy(default_conf)
    conf['stake_amount'] += 1
    mocker.patch('freqtrade.configuration.Configuration._load_config_file',
                 lambda *args, **kwargs: conf)

    # reconfigure should return a new instance
    freqtrade2 = reconfigure(
        freqtrade,
        Arguments(['-c', 'config.json.example'], '').get_parsed_arg())

    # Verify we have a new instance with the new config
    assert freqtrade is not freqtrade2
    assert freqtrade.config['stake_amount'] + 1 == freqtrade2.config[
        'stake_amount']
Ejemplo n.º 12
0
def test_hyperopt_with_arguments(mocker, default_conf, caplog) -> None:
    mocker.patch('freqtrade.configuration.open',
                 mocker.mock_open(read_data=json.dumps(default_conf)))
    arglist = [
        'hyperopt',
        '--epochs',
        '10',
        '--spaces',
        'all',
    ]
    args = Arguments(arglist, '').get_parsed_arg()

    configuration = Configuration(args)
    config = configuration.get_config()

    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)

    assert 'spaces' in config
    assert config['spaces'] == ['all']
    assert log_has('Parameter -s/--spaces detected: [\'all\']',
                   caplog.record_tuples)
Ejemplo n.º 13
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)))

    args = [
        '--dynamic-whitelist',
        '10',
        '--strategy',
        'TestStrategy',
        '--strategy-path',
        '/some/path',
        '--dry-run-db',
    ]
    args = Arguments(args, '').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('dry_run_db') is True
Ejemplo n.º 14
0
def test_main_reload_conf(mocker, default_conf, caplog) -> None:
    patch_exchange(mocker)
    mocker.patch('freqtrade.freqtradebot.FreqtradeBot.cleanup', MagicMock())
    # Simulate Running, reload, running workflow
    worker_mock = MagicMock(side_effect=[
        State.RUNNING, State.RELOAD_CONF, State.RUNNING,
        OperationalException("Oh snap!")
    ])
    mocker.patch('freqtrade.worker.Worker._worker', worker_mock)
    mocker.patch('freqtrade.configuration.Configuration._load_config_file',
                 lambda *args, **kwargs: default_conf)
    reconfigure_mock = mocker.patch('freqtrade.main.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()
    worker = Worker(args=args, config=default_conf)
    with pytest.raises(SystemExit):
        main(['-c', 'config.json.example'])

    assert log_has('Using config: config.json.example ...',
                   caplog.record_tuples)
    assert worker_mock.call_count == 4
    assert reconfigure_mock.call_count == 1
    assert isinstance(worker.freqtrade, FreqtradeBot)
Ejemplo n.º 15
0
def test_reconfigure(mocker, default_conf) -> None:
    patch_exchange(mocker)
    mocker.patch('freqtrade.freqtradebot.FreqtradeBot.cleanup', MagicMock())
    mocker.patch('freqtrade.worker.Worker._worker',
                 MagicMock(side_effect=OperationalException('Oh snap!')))
    mocker.patch('freqtrade.configuration.Configuration._load_config_file',
                 lambda *args, **kwargs: default_conf)
    mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
    mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock())

    args = Arguments(['-c', 'config.json.example'], '').get_parsed_arg()
    worker = Worker(args=args, config=default_conf)
    freqtrade = worker.freqtrade

    # Renew mock to return modified data
    conf = deepcopy(default_conf)
    conf['stake_amount'] += 1
    mocker.patch('freqtrade.configuration.Configuration._load_config_file',
                 lambda *args, **kwargs: conf)

    worker._config = conf
    # reconfigure should return a new instance
    worker._reconfigure()
    freqtrade2 = worker.freqtrade

    # Verify we have a new instance with the new config
    assert freqtrade is not freqtrade2
    assert freqtrade.config['stake_amount'] + 1 == freqtrade2.config[
        'stake_amount']
Ejemplo n.º 16
0
def analyse_and_plot_pairs(config: Dict[str, Any]):
    """
    From arguments provided in cli:
    -Initialise backtest env
    -Get tickers data
    -Generate Dafaframes populated with indicators and signals
    -Load trades excecuted on same periods
    -Generate Plotly plot objects
    -Generate plot files
    :return: None
    """
    exchange = ExchangeResolver(config.get('exchange', {}).get('name'), config).exchange

    strategy = StrategyResolver(config).strategy
    if "pairs" in config:
        pairs = config["pairs"].split(',')
    else:
        pairs = config["exchange"]["pair_whitelist"]

    # Set timerange to use
    timerange = Arguments.parse_timerange(config["timerange"])
    ticker_interval = strategy.ticker_interval

    tickers = history.load_data(
        datadir=Path(str(config.get("datadir"))),
        pairs=pairs,
        ticker_interval=config['ticker_interval'],
        refresh_pairs=config.get('refresh_pairs', False),
        timerange=timerange,
        exchange=exchange,
        live=config.get("live", False),
    )

    pair_counter = 0
    for pair, data in tickers.items():
        pair_counter += 1
        logger.info("analyse pair %s", pair)
        tickers = {}
        tickers[pair] = data
        dataframe = generate_dataframe(strategy, tickers, pair)
        if config["trade_source"] == "DB":
            trades = load_trades_from_db(config["db_url"])
        elif config["trade_source"] == "file":
            trades = load_backtest_data(Path(config["exportfilename"]))

        trades = trades.loc[trades['pair'] == pair]
        trades = extract_trades_of_period(dataframe, trades)

        fig = generate_graph(
            pair=pair,
            data=dataframe,
            trades=trades,
            indicators1=config["indicators1"].split(","),
            indicators2=config["indicators2"].split(",")
        )

        generate_plot_file(fig, pair, ticker_interval)

    logger.info('End of ploting process %s plots generated', pair_counter)
Ejemplo n.º 17
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)))
    mocker.patch('freqtrade.configuration.Configuration._create_datadir',
                 lambda s, c, x: x)

    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)
Ejemplo n.º 18
0
    def start(self) -> None:
        timerange = Arguments.parse_timerange(None if self.config.get(
            'timerange') is None else str(self.config.get('timerange')))
        data = load_data(datadir=str(self.config.get('datadir')),
                         pairs=self.config['exchange']['pair_whitelist'],
                         ticker_interval=self.ticker_interval,
                         timerange=timerange)

        if self.has_space('buy'):
            self.analyze.populate_indicators = Hyperopt.populate_indicators  # type: ignore
        self.processed = self.tickerdata_to_dataframe(data)

        logger.info('Preparing Trials..')
        signal.signal(signal.SIGINT, self.signal_handler)
        # read trials file if we have one
        if os.path.exists(
                self.trials_file) and os.path.getsize(self.trials_file) > 0:
            self.trials = self.read_trials()

            self.current_tries = len(self.trials.results)
            self.total_tries += self.current_tries
            logger.info('Continuing with trials. Current: %d, Total: %d',
                        self.current_tries, self.total_tries)

        try:
            best_parameters = fmin(fn=self.generate_optimizer,
                                   space=self.hyperopt_space(),
                                   algo=tpe.suggest,
                                   max_evals=self.total_tries,
                                   trials=self.trials)

            results = sorted(self.trials.results, key=itemgetter('loss'))
            best_result = results[0]['result']

        except ValueError:
            best_parameters = {}
            best_result = 'Sorry, Hyperopt was not able to find good parameters. Please ' \
                          'try with more epochs (param: -e).'

        # Improve best parameter logging display
        if best_parameters:
            best_parameters = space_eval(self.hyperopt_space(),
                                         best_parameters)

        logger.info('Best parameters:\n%s',
                    json.dumps(best_parameters, indent=4))
        if 'roi_t1' in best_parameters:
            logger.info('ROI table:\n%s',
                        self.generate_roi_table(best_parameters))

        logger.info('Best Result:\n%s', best_result)

        # Store trials result to file to resume next time
        self.save_trials()
Ejemplo n.º 19
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)
Ejemplo n.º 20
0
def test_parse_args_hyperopt_custom() -> None:
    args = [
        '-c', 'test_conf.json', 'hyperopt', '--epochs', '20', '--spaces', 'buy'
    ]
    call_args = Arguments(args, '').get_parsed_arg()
    assert call_args.config == 'test_conf.json'
    assert call_args.epochs == 20
    assert call_args.loglevel == 0
    assert call_args.subparser == 'hyperopt'
    assert call_args.spaces == ['buy']
    assert call_args.func is not None
Ejemplo n.º 21
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
Ejemplo n.º 22
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)
Ejemplo n.º 23
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
    )
Ejemplo n.º 24
0
def test_parse_args_backtesting_custom() -> None:
    args = [
        '-c', 'test_conf.json', 'backtesting', '--live', '--ticker-interval',
        '1', '--refresh-pairs-cached'
    ]
    call_args = Arguments(args, '').get_parsed_arg()
    assert call_args.config == 'test_conf.json'
    assert call_args.live is True
    assert call_args.loglevel == logging.INFO
    assert call_args.subparser == 'backtesting'
    assert call_args.func is not None
    assert call_args.ticker_interval == 1
    assert call_args.refresh_pairs is True
Ejemplo n.º 25
0
def main(sysargv: List[str]) -> None:
    """
    This function will initiate the bot and start the trading loop.
    :return: None
    """
    arguments = Arguments(
        sysargv,
        'Simple High Frequency Trading Bot for crypto currencies'
    )
    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)
        return

    freqtrade = None
    return_code = 1
    try:
        # Load and validate configuration
        config = Configuration(args).get_config()

        # Init the bot
        freqtrade = FreqtradeBot(config)

        state = None
        while 1:
            state = freqtrade.worker(old_state=state)

    except KeyboardInterrupt:
        logger.info('SIGINT received, aborting ...')
        return_code = 0
    except BaseException:
        logger.exception('Fatal exception!')
    finally:
        if freqtrade:
            freqtrade.clean()
        sys.exit(return_code)
Ejemplo n.º 26
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)
Ejemplo n.º 27
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)
Ejemplo n.º 28
0
def test_load_config(default_conf, mocker) -> None:
    """
    Test Configuration.load_config() without any cli params
    """
    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 'dynamic_whitelist' not in validated_conf
Ejemplo n.º 29
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'
Ejemplo n.º 30
0
    def __init__(self, config: Dict[str, Any], exchange, strategy) -> None:

        self.config = config
        self.exchange = exchange
        self.strategy = strategy
        self.ticker_interval = self.strategy.ticker_interval
        self.tickerdata_to_dataframe = self.strategy.tickerdata_to_dataframe
        self.get_timeframe = get_timeframe
        self.advise_sell = self.strategy.advise_sell
        self.advise_buy = self.strategy.advise_buy

        self.edge_config = self.config.get('edge', {})
        self._cached_pairs: Dict[str, Any] = {}  # Keeps a list of pairs
        self._final_pairs: list = []

        # checking max_open_trades. it should be -1 as with Edge
        # the number of trades is determined by position size
        if self.config['max_open_trades'] != float('inf'):
            logger.critical('max_open_trades should be -1 in config !')

        if self.config['stake_amount'] != constants.UNLIMITED_STAKE_AMOUNT:
            raise OperationalException(
                'Edge works only with unlimited stake amount')

        self._capital_percentage: float = self.edge_config.get(
            'capital_available_percentage')
        self._allowed_risk: float = self.edge_config.get('allowed_risk')
        self._since_number_of_days: int = self.edge_config.get(
            'calculate_since_number_of_days', 14)
        self._last_updated: int = 0  # Timestamp of pairs last updated time
        self._refresh_pairs = True

        self._stoploss_range_min = float(
            self.edge_config.get('stoploss_range_min', -0.01))
        self._stoploss_range_max = float(
            self.edge_config.get('stoploss_range_max', -0.05))
        self._stoploss_range_step = float(
            self.edge_config.get('stoploss_range_step', -0.001))

        # calculating stoploss range
        self._stoploss_range = np.arange(self._stoploss_range_min,
                                         self._stoploss_range_max,
                                         self._stoploss_range_step)

        self._timerange: TimeRange = Arguments.parse_timerange(
            "%s-" % arrow.now().shift(
                days=-1 * self._since_number_of_days).format('YYYYMMDD'))

        self.fee = self.exchange.get_fee()