def test_start(mocker, fee, default_conf, caplog) -> None: start_mock = MagicMock() mocker.patch('freqtrade.exchange.Exchange.get_fee', fee) patch_exchange(mocker) mocker.patch('freqtrade.optimize.backtesting.Backtesting.start', start_mock) patched_configuration_load_config_file(mocker, default_conf) args = [ 'backtesting', '--config', 'config.json', '--strategy', 'DefaultStrategy', ] pargs = get_args(args) start_backtesting(pargs) assert log_has('Starting freqtrade in Backtesting mode', caplog) assert start_mock.call_count == 1
def test_start_no_data(mocker, hyperopt_conf) -> None: patched_configuration_load_config_file(mocker, hyperopt_conf) mocker.patch('freqtrade.data.history.load_pair_history', MagicMock(return_value=pd.DataFrame)) mocker.patch( 'freqtrade.optimize.hyperopt.get_timerange', MagicMock(return_value=(datetime(2017, 12, 10), datetime(2017, 12, 13)))) patch_exchange(mocker) args = [ 'hyperopt', '--config', 'config.json', '--hyperopt', 'DefaultHyperOpt', '--hyperopt-loss', 'SharpeHyperOptLossDaily', '--epochs', '5' ] pargs = get_args(args) with pytest.raises(OperationalException, match='No data found. Terminating.'): start_hyperopt(pargs)
def test_download_data_no_pairs(mocker, caplog): mocker.patch.object(Path, "exists", MagicMock(return_value=False)) mocker.patch('freqtrade.utils.refresh_backtest_ohlcv_data', MagicMock(return_value=["ETH/BTC", "XRP/BTC"])) patch_exchange(mocker) mocker.patch('freqtrade.exchange.Exchange.markets', PropertyMock(return_value={})) args = [ "download-data", "--exchange", "binance", ] pargs = get_args(args) pargs['config'] = None with pytest.raises(OperationalException, match=r"Downloading data requires a list of pairs\..*"): start_download_data(pargs)
def test_create_datadir(caplog, mocker): # Ensure that caplog is empty before starting ... # Should prevent random failures. caplog.clear() # Added assert here to analyze random test-failures ... assert len(caplog.record_tuples) == 0 cud = mocker.patch("freqtrade.commands.deploy_commands.create_userdata_dir", MagicMock()) csf = mocker.patch("freqtrade.commands.deploy_commands.copy_sample_files", MagicMock()) args = [ "create-userdir", "--userdir", "/temp/freqtrade/test" ] start_create_userdir(get_args(args)) assert cud.call_count == 1 assert csf.call_count == 1 assert len(caplog.record_tuples) == 0
def test_download_data_keyboardInterrupt(mocker, caplog, markets): dl_mock = mocker.patch( 'freqtrade.commands.data_commands.refresh_backtest_ohlcv_data', MagicMock(side_effect=KeyboardInterrupt)) patch_exchange(mocker) mocker.patch('freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets)) args = [ "download-data", "--exchange", "binance", "--pairs", "ETH/BTC", "XRP/BTC", ] with pytest.raises(SystemExit): start_download_data(get_args(args)) assert dl_mock.call_count == 1
def test_start_not_installed(mocker, default_conf, import_fails) -> None: start_mock = MagicMock() patched_configuration_load_config_file(mocker, default_conf) mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock) patch_exchange(mocker) args = [ 'hyperopt', '--config', 'config.json', '--hyperopt', 'DefaultHyperOpt', '--hyperopt-path', str(Path(__file__).parent / "hyperopts"), '--epochs', '5' ] pargs = get_args(args) with pytest.raises(OperationalException, match=r"Please ensure that the hyperopt dependencies"): start_hyperopt(pargs)
def test_backtest_start_timerange(default_conf, mocker, caplog, testdatadir): default_conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC'] async def load_pairs(pair, timeframe, since): return _load_pair_as_ticks(pair, timeframe) api_mock = MagicMock() api_mock.fetch_ohlcv = load_pairs patch_exchange(mocker, api_mock) mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', MagicMock()) mocker.patch( 'freqtrade.optimize.backtesting.Backtesting._generate_text_table', MagicMock()) patched_configuration_load_config_file(mocker, default_conf) args = [ 'backtesting', '--config', 'config.json', '--strategy', 'DefaultStrategy', '--datadir', str(testdatadir), '--ticker-interval', '1m', '--timerange', '1510694220-1510700340', '--enable-position-stacking', '--disable-max-market-positions' ] args = get_args(args) start_backtesting(args) # check the logs, that will contain the backtest result exists = [ 'Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...', 'Ignoring max_open_trades (--disable-max-market-positions was used) ...', 'Parameter --timerange detected: 1510694220-1510700340 ...', f'Using data directory: {testdatadir} ...', 'Using stake_currency: BTC ...', 'Using stake_amount: 0.001 ...', 'Loading data from 2017-11-14T20:57:00+00:00 ' 'up to 2017-11-14T22:58:00+00:00 (0 days)..', 'Backtesting with data from 2017-11-14T21:17:00+00:00 ' 'up to 2017-11-14T22:58:00+00:00 (0 days)..', 'Parameter --enable-position-stacking detected ...' ] for line in exists: assert log_has(line, caplog)
def test_start_new_config(mocker, caplog, exchange): wt_mock = mocker.patch.object(Path, "write_text", MagicMock()) mocker.patch.object(Path, "exists", MagicMock(return_value=True)) unlink_mock = mocker.patch.object(Path, "unlink", MagicMock()) mocker.patch('freqtrade.commands.build_config_commands.ask_user_overwrite', return_value=True) sample_selections = { 'max_open_trades': 3, 'stake_currency': 'USDT', 'stake_amount': 100, 'fiat_display_currency': 'EUR', 'timeframe': '15m', 'dry_run': True, 'trading_mode': 'spot', 'margin_mode': '', 'exchange_name': exchange, 'exchange_key': 'sampleKey', 'exchange_secret': 'Samplesecret', 'telegram': False, 'telegram_token': 'asdf1244', 'telegram_chat_id': '1144444', 'api_server': False, 'api_server_listen_addr': '127.0.0.1', 'api_server_username': '******', 'api_server_password': '******', } mocker.patch('freqtrade.commands.build_config_commands.ask_user_config', return_value=sample_selections) args = [ "new-config", "--config", "coolconfig.json" ] start_new_config(get_args(args)) assert log_has_re("Writing config to .*", caplog) assert wt_mock.call_count == 1 assert unlink_mock.call_count == 1 result = rapidjson.loads(wt_mock.call_args_list[0][0][0], parse_mode=rapidjson.PM_COMMENTS | rapidjson.PM_TRAILING_COMMAS) assert result['exchange']['name'] == exchange assert result['timeframe'] == '15m'
def test_convert_data_trades(mocker, testdatadir): ohlcv_mock = mocker.patch("freqtrade.commands.data_commands.convert_ohlcv_format") trades_mock = mocker.patch("freqtrade.commands.data_commands.convert_trades_format") args = [ "convert-trade-data", "--format-from", "jsongz", "--format-to", "json", "--datadir", str(testdatadir), ] pargs = get_args(args) pargs['config'] = None start_convert_data(pargs, False) assert ohlcv_mock.call_count == 0 assert trades_mock.call_count == 1 assert trades_mock.call_args[1]['convert_from'] == 'jsongz' assert trades_mock.call_args[1]['convert_to'] == 'json' assert trades_mock.call_args[1]['erase'] is False
def test_download_data_trades(mocker, caplog): dl_mock = mocker.patch('freqtrade.commands.data_commands.refresh_backtest_trades_data', MagicMock(return_value=[])) convert_mock = mocker.patch('freqtrade.commands.data_commands.convert_trades_to_ohlcv', MagicMock(return_value=[])) patch_exchange(mocker) mocker.patch( 'freqtrade.exchange.Exchange.markets', PropertyMock(return_value={}) ) args = [ "download-data", "--exchange", "kraken", "--pairs", "ETH/BTC", "XRP/BTC", "--days", "20", "--dl-trades" ] start_download_data(get_args(args)) assert dl_mock.call_args[1]['timerange'].starttype == "date" assert dl_mock.call_count == 1 assert convert_mock.call_count == 1
def test_backtest_start_timerange(default_conf, mocker, caplog, testdatadir): patch_exchange(mocker) mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest') mocker.patch('freqtrade.optimize.backtesting.generate_backtest_stats') mocker.patch('freqtrade.optimize.backtesting.show_backtest_results') mocker.patch('freqtrade.pairlist.pairlistmanager.PairListManager.whitelist', PropertyMock(return_value=['UNITTEST/BTC'])) patched_configuration_load_config_file(mocker, default_conf) args = [ 'backtesting', '--config', 'config.json', '--strategy', 'DefaultStrategy', '--datadir', str(testdatadir), '--timeframe', '1m', '--timerange', '1510694220-1510700340', '--enable-position-stacking', '--disable-max-market-positions' ] args = get_args(args) start_backtesting(args) # check the logs, that will contain the backtest result exists = [ 'Parameter -i/--timeframe detected ... Using timeframe: 1m ...', 'Ignoring max_open_trades (--disable-max-market-positions was used) ...', 'Parameter --timerange detected: 1510694220-1510700340 ...', f'Using data directory: {testdatadir} ...', 'Using stake_currency: BTC ...', 'Using stake_amount: 0.001 ...', 'Loading data from 2017-11-14T20:57:00+00:00 ' 'up to 2017-11-14T22:58:00+00:00 (0 days)..', 'Backtesting with data from 2017-11-14T21:17:00+00:00 ' 'up to 2017-11-14T22:58:00+00:00 (0 days)..', 'Parameter --enable-position-stacking detected ...' ] for line in exists: assert log_has(line, caplog)
def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> None: patched_configuration_load_config_file(mocker, default_conf) args = ['--config', 'config.json', '--strategy', 'DefaultStrategy', 'edge'] config = setup_configuration(get_args(args), RunMode.EDGE) assert config['runmode'] == RunMode.EDGE 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(config['datadir']), caplog) assert 'ticker_interval' in config assert not log_has_re('Parameter -i/--ticker-interval detected .*', caplog) assert 'timerange' not in config assert 'stoploss_range' not in config
def test_start_not_installed(mocker, default_conf, import_fails) -> None: start_mock = MagicMock() patched_configuration_load_config_file(mocker, default_conf) mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock) patch_exchange(mocker) args = [ 'hyperopt', '--config', 'config.json', '--strategy', 'HyperoptableStrategy', '--epochs', '5', '--hyperopt-loss', 'SharpeHyperOptLossDaily', ] pargs = get_args(args) with pytest.raises(OperationalException, match=r"Please ensure that the hyperopt dependencies"): start_hyperopt(pargs)
def test_setup_bt_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) args = [ 'backtesting', '--config', 'config.json', '--strategy', 'DefaultStrategy', '--datadir', '/foo/bar', '--timeframe', '1m', '--enable-position-stacking', '--disable-max-market-positions', '--timerange', ':100', '--export', '/bar/foo', '--export-filename', 'foo_bar.json', '--fee', '0', ] config = setup_optimize_configuration(get_args(args), RunMode.BACKTEST) 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 config['runmode'] == RunMode.BACKTEST assert log_has('Using data directory: {} ...'.format(config['datadir']), caplog) 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 'exportfilename' in config assert isinstance(config['exportfilename'], Path) assert log_has( 'Storing backtest results to {} ...'.format(config['exportfilename']), caplog) assert 'fee' in config assert log_has( 'Parameter --fee detected, setting fee to: {} ...'.format( config['fee']), caplog)
def test_hyperopt_list(mocker, capsys, caplog, saved_hyperopt_results, saved_hyperopt_results_legacy, tmpdir): csv_file = Path(tmpdir) / "test.csv" for res in (saved_hyperopt_results, saved_hyperopt_results_legacy): mocker.patch( 'freqtrade.optimize.hyperopt_tools.HyperoptTools.load_previous_results', MagicMock(return_value=res) ) args = [ "hyperopt-list", "--no-details", "--no-color", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 1/12", " 2/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 10/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", "--best", "--no-details", "--no-color", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 1/12", " 5/12", " 10/12"]) assert all(x not in captured.out for x in [" 2/12", " 3/12", " 4/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", "--profitable", "--no-details", "--no-color", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 2/12", " 10/12"]) assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", "--profitable", "--no-color", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 2/12", " 10/12", "Best result:", "Buy hyperspace params", "Sell hyperspace params", "ROI table", "Stoploss"]) assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", "--no-color", "--min-trades", "20", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 3/12", " 6/12", " 7/12", " 9/12", " 11/12"]) assert all(x not in captured.out for x in [" 1/12", " 2/12", " 4/12", " 5/12", " 8/12", " 10/12", " 12/12"]) args = [ "hyperopt-list", "--profitable", "--no-details", "--no-color", "--max-trades", "20", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 2/12", " 10/12"]) assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", "--profitable", "--no-details", "--no-color", "--min-avg-profit", "0.11", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 2/12"]) assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 10/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", "--no-color", "--max-avg-profit", "0.10", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 1/12", " 3/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12"]) assert all(x not in captured.out for x in [" 2/12", " 4/12", " 10/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", "--no-color", "--min-total-profit", "0.4", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 10/12"]) assert all(x not in captured.out for x in [" 1/12", " 2/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", "--no-color", "--max-total-profit", "0.4", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 1/12", " 2/12", " 3/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12"]) assert all(x not in captured.out for x in [" 4/12", " 10/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", "--no-color", "--min-objective", "0.1", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 10/12"]) assert all(x not in captured.out for x in [" 1/12", " 2/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", "--max-objective", "0.1", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 1/12", " 2/12", " 3/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12"]) assert all(x not in captured.out for x in [" 4/12", " 10/12", " 12/12"]) args = [ "hyperopt-list", "--profitable", "--no-details", "--no-color", "--min-avg-time", "2000", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 10/12"]) assert all(x not in captured.out for x in [" 1/12", " 2/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", "--no-color", "--max-avg-time", "1500", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 2/12", " 6/12"]) assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 7/12", " 8/12" " 9/12", " 10/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", "--no-color", "--export-csv", str(csv_file), ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() log_has("CSV file created: test_file.csv", caplog) assert csv_file.is_file() line = csv_file.read_text() assert ('Best,1,2,-1.25%,-1.2222,-0.00125625,,-2.51,"3,930.0 m",0.43662' in line or "Best,1,2,-1.25%,-1.2222,-0.00125625,,-2.51,2 days 17:30:00,0.43662" in line) csv_file.unlink()
def test_start_list_strategies(capsys): args = [ "list-strategies", "--strategy-path", str(Path(__file__).parent.parent / "strategy" / "strats"), "-1" ] pargs = get_args(args) # pargs['config'] = None start_list_strategies(pargs) captured = capsys.readouterr() assert "TestStrategyLegacyV1" in captured.out assert "legacy_strategy_v1.py" not in captured.out assert CURRENT_TEST_STRATEGY in captured.out # Test regular output args = [ "list-strategies", "--strategy-path", str(Path(__file__).parent.parent / "strategy" / "strats"), '--no-color', ] pargs = get_args(args) # pargs['config'] = None start_list_strategies(pargs) captured = capsys.readouterr() assert "TestStrategyLegacyV1" in captured.out assert "legacy_strategy_v1.py" in captured.out assert CURRENT_TEST_STRATEGY in captured.out # Test color output args = [ "list-strategies", "--strategy-path", str(Path(__file__).parent.parent / "strategy" / "strats"), ] pargs = get_args(args) # pargs['config'] = None start_list_strategies(pargs) captured = capsys.readouterr() assert "TestStrategyLegacyV1" in captured.out assert "legacy_strategy_v1.py" in captured.out assert CURRENT_TEST_STRATEGY in captured.out assert "LOAD FAILED" in captured.out # Recursive assert "TestStrategyNoImplements" not in captured.out # Test recursive args = [ "list-strategies", "--strategy-path", str(Path(__file__).parent.parent / "strategy" / "strats"), '--no-color', '--recursive-strategy-search' ] pargs = get_args(args) # pargs['config'] = None start_list_strategies(pargs) captured = capsys.readouterr() assert "TestStrategyLegacyV1" in captured.out assert "legacy_strategy_v1.py" in captured.out assert "StrategyTestV2" in captured.out assert "TestStrategyNoImplements" in captured.out assert str( Path("broken_strats/broken_futures_strategies.py")) in captured.out
def test_list_markets(mocker, markets, capsys): api_mock = MagicMock() api_mock.markets = markets patch_exchange(mocker, api_mock=api_mock, id='bittrex') # Test with no --config args = [ "list-markets", ] pargs = get_args(args) pargs['config'] = None with pytest.raises(OperationalException, match=r"This command requires a configured exchange.*"): start_list_markets(pargs, False) # Test with --config config_bittrex.json.example args = [ "list-markets", '--config', 'config_bittrex.json.example', "--print-list", ] start_list_markets(get_args(args), False) captured = capsys.readouterr() assert ("Exchange Bittrex has 10 active markets: " "BLK/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/ETH, LTC/USD, NEO/BTC, " "TKN/BTC, XLTCUSDT, XRP/BTC.\n" in captured.out) patch_exchange(mocker, api_mock=api_mock, id="binance") # Test with --exchange args = [ "list-markets", "--exchange", "binance" ] pargs = get_args(args) pargs['config'] = None start_list_markets(pargs, False) captured = capsys.readouterr() assert re.match("\nExchange Binance has 10 active markets:\n", captured.out) patch_exchange(mocker, api_mock=api_mock, id="bittrex") # Test with --all: all markets args = [ "list-markets", "--all", '--config', 'config_bittrex.json.example', "--print-list", ] start_list_markets(get_args(args), False) captured = capsys.readouterr() assert ("Exchange Bittrex has 12 markets: " "BLK/BTC, BTT/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/ETH, LTC/USD, LTC/USDT, NEO/BTC, " "TKN/BTC, XLTCUSDT, XRP/BTC.\n" in captured.out) # Test list-pairs subcommand: active pairs args = [ "list-pairs", '--config', 'config_bittrex.json.example', "--print-list", ] start_list_markets(get_args(args), True) captured = capsys.readouterr() assert ("Exchange Bittrex has 9 active pairs: " "BLK/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/ETH, LTC/USD, NEO/BTC, TKN/BTC, XRP/BTC.\n" in captured.out) # Test list-pairs subcommand with --all: all pairs args = [ "list-pairs", "--all", '--config', 'config_bittrex.json.example', "--print-list", ] start_list_markets(get_args(args), True) captured = capsys.readouterr() assert ("Exchange Bittrex has 11 pairs: " "BLK/BTC, BTT/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/ETH, LTC/USD, LTC/USDT, NEO/BTC, " "TKN/BTC, XRP/BTC.\n" in captured.out) # active markets, base=ETH, LTC args = [ "list-markets", '--config', 'config_bittrex.json.example', "--base", "ETH", "LTC", "--print-list", ] start_list_markets(get_args(args), False) captured = capsys.readouterr() assert ("Exchange Bittrex has 6 active markets with ETH, LTC as base currencies: " "ETH/BTC, ETH/USDT, LTC/BTC, LTC/ETH, LTC/USD, XLTCUSDT.\n" in captured.out) # active markets, base=LTC args = [ "list-markets", '--config', 'config_bittrex.json.example', "--base", "LTC", "--print-list", ] start_list_markets(get_args(args), False) captured = capsys.readouterr() assert ("Exchange Bittrex has 4 active markets with LTC as base currency: " "LTC/BTC, LTC/ETH, LTC/USD, XLTCUSDT.\n" in captured.out) # active markets, quote=USDT, USD args = [ "list-markets", '--config', 'config_bittrex.json.example', "--quote", "USDT", "USD", "--print-list", ] start_list_markets(get_args(args), False) captured = capsys.readouterr() assert ("Exchange Bittrex has 3 active markets with USDT, USD as quote currencies: " "ETH/USDT, LTC/USD, XLTCUSDT.\n" in captured.out) # active markets, quote=USDT args = [ "list-markets", '--config', 'config_bittrex.json.example', "--quote", "USDT", "--print-list", ] start_list_markets(get_args(args), False) captured = capsys.readouterr() assert ("Exchange Bittrex has 2 active markets with USDT as quote currency: " "ETH/USDT, XLTCUSDT.\n" in captured.out) # active markets, base=LTC, quote=USDT args = [ "list-markets", '--config', 'config_bittrex.json.example', "--base", "LTC", "--quote", "USDT", "--print-list", ] start_list_markets(get_args(args), False) captured = capsys.readouterr() assert ("Exchange Bittrex has 1 active market with LTC as base currency and " "with USDT as quote currency: XLTCUSDT.\n" in captured.out) # active pairs, base=LTC, quote=USDT args = [ "list-pairs", '--config', 'config_bittrex.json.example', "--base", "LTC", "--quote", "USD", "--print-list", ] start_list_markets(get_args(args), True) captured = capsys.readouterr() assert ("Exchange Bittrex has 1 active pair with LTC as base currency and " "with USD as quote currency: LTC/USD.\n" in captured.out) # active markets, base=LTC, quote=USDT, NONEXISTENT args = [ "list-markets", '--config', 'config_bittrex.json.example', "--base", "LTC", "--quote", "USDT", "NONEXISTENT", "--print-list", ] start_list_markets(get_args(args), False) captured = capsys.readouterr() assert ("Exchange Bittrex has 1 active market with LTC as base currency and " "with USDT, NONEXISTENT as quote currencies: XLTCUSDT.\n" in captured.out) # active markets, base=LTC, quote=NONEXISTENT args = [ "list-markets", '--config', 'config_bittrex.json.example', "--base", "LTC", "--quote", "NONEXISTENT", "--print-list", ] start_list_markets(get_args(args), False) captured = capsys.readouterr() assert ("Exchange Bittrex has 0 active markets with LTC as base currency and " "with NONEXISTENT as quote currency.\n" in captured.out) # Test tabular output args = [ "list-markets", '--config', 'config_bittrex.json.example', ] start_list_markets(get_args(args), False) captured = capsys.readouterr() assert ("Exchange Bittrex has 10 active markets:\n" in captured.out) # Test tabular output, no markets found args = [ "list-markets", '--config', 'config_bittrex.json.example', "--base", "LTC", "--quote", "NONEXISTENT", ] start_list_markets(get_args(args), False) captured = capsys.readouterr() assert ("Exchange Bittrex has 0 active markets with LTC as base currency and " "with NONEXISTENT as quote currency.\n" in captured.out) # Test --print-json args = [ "list-markets", '--config', 'config_bittrex.json.example', "--print-json" ] start_list_markets(get_args(args), False) captured = capsys.readouterr() assert ('["BLK/BTC","ETH/BTC","ETH/USDT","LTC/BTC","LTC/ETH","LTC/USD","NEO/BTC",' '"TKN/BTC","XLTCUSDT","XRP/BTC"]' in captured.out) # Test --print-csv args = [ "list-markets", '--config', 'config_bittrex.json.example', "--print-csv" ] start_list_markets(get_args(args), False) captured = capsys.readouterr() assert ("Id,Symbol,Base,Quote,Active,Is pair" in captured.out) assert ("blkbtc,BLK/BTC,BLK,BTC,True,True" in captured.out) assert ("USD-LTC,LTC/USD,LTC,USD,True,True" in captured.out) # Test --one-column args = [ "list-markets", '--config', 'config_bittrex.json.example', "--one-column" ] start_list_markets(get_args(args), False) captured = capsys.readouterr() assert re.search(r"^BLK/BTC$", captured.out, re.MULTILINE) assert re.search(r"^LTC/USD$", captured.out, re.MULTILINE) mocker.patch('freqtrade.exchange.Exchange.markets', PropertyMock(side_effect=ValueError)) # Test --one-column args = [ "list-markets", '--config', 'config_bittrex.json.example', "--one-column" ] with pytest.raises(OperationalException, match=r"Cannot get markets.*"): start_list_markets(get_args(args), False)
def test_hyperopt_list(mocker, capsys, hyperopt_results): mocker.patch( 'freqtrade.optimize.hyperopt.Hyperopt.load_previous_results', MagicMock(return_value=hyperopt_results) ) args = [ "hyperopt-list", "--no-details" ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 1/12", " 2/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 10/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", "--best", "--no-details" ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 1/12", " 5/12", " 10/12"]) assert all(x not in captured.out for x in [" 2/12", " 3/12", " 4/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", "--profitable", "--no-details" ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 2/12", " 10/12"]) assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", "--no-color", "--min-trades", "20" ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 3/12", " 6/12", " 7/12", " 9/12", " 11/12"]) assert all(x not in captured.out for x in [" 1/12", " 2/12", " 4/12", " 5/12", " 8/12", " 10/12", " 12/12"]) args = [ "hyperopt-list", "--profitable", "--no-details", "--max-trades", "20" ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 2/12", " 10/12"]) assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", "--profitable", "--no-details", "--min-avg-profit", "0.11" ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 2/12"]) assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 10/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", "--max-avg-profit", "0.10" ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 1/12", " 3/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12"]) assert all(x not in captured.out for x in [" 2/12", " 4/12", " 10/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", "--min-total-profit", "0.4" ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 10/12"]) assert all(x not in captured.out for x in [" 1/12", " 2/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", "--max-total-profit", "0.4" ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 1/12", " 2/12", " 3/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12"]) assert all(x not in captured.out for x in [" 4/12", " 10/12", " 12/12"]) args = [ "hyperopt-list", "--profitable", "--no-details", "--min-avg-time", "2000" ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 10/12"]) assert all(x not in captured.out for x in [" 1/12", " 2/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", "--max-avg-time", "1500" ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 2/12", " 6/12"]) assert all(x not in captured.out for x in [" 1/12", " 3/12", " 4/12", " 5/12", " 7/12", " 8/12" " 9/12", " 10/12", " 11/12", " 12/12"])
def test_hyperopt_show(mocker, capsys, saved_hyperopt_results): mocker.patch( 'freqtrade.optimize.hyperopt_tools.HyperoptTools.load_previous_results', MagicMock(return_value=saved_hyperopt_results) ) mocker.patch('freqtrade.commands.hyperopt_commands.show_backtest_result') args = [ "hyperopt-show", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_show(pargs) captured = capsys.readouterr() assert " 12/12" in captured.out args = [ "hyperopt-show", "--best" ] pargs = get_args(args) pargs['config'] = None start_hyperopt_show(pargs) captured = capsys.readouterr() assert " 10/12" in captured.out args = [ "hyperopt-show", "-n", "1" ] pargs = get_args(args) pargs['config'] = None start_hyperopt_show(pargs) captured = capsys.readouterr() assert " 1/12" in captured.out args = [ "hyperopt-show", "--best", "-n", "2" ] pargs = get_args(args) pargs['config'] = None start_hyperopt_show(pargs) captured = capsys.readouterr() assert " 5/12" in captured.out args = [ "hyperopt-show", "--best", "-n", "-1" ] pargs = get_args(args) pargs['config'] = None start_hyperopt_show(pargs) captured = capsys.readouterr() assert " 10/12" in captured.out args = [ "hyperopt-show", "--best", "-n", "-4" ] pargs = get_args(args) pargs['config'] = None with pytest.raises(OperationalException, match="The index of the epoch to show should be greater than -4."): start_hyperopt_show(pargs) args = [ "hyperopt-show", "--best", "-n", "4" ] pargs = get_args(args) pargs['config'] = None with pytest.raises(OperationalException, match="The index of the epoch to show should be less than 4."): start_hyperopt_show(pargs)
def test_hyperopt_list(mocker, capsys, caplog, hyperopt_results): mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.load_previous_results', MagicMock(return_value=hyperopt_results)) args = [ "hyperopt-list", "--no-details", "--no-color", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [ " 1/12", " 2/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 10/12", " 11/12", " 12/12" ]) args = [ "hyperopt-list", "--best", "--no-details", "--no-color", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 1/12", " 5/12", " 10/12"]) assert all(x not in captured.out for x in [ " 2/12", " 3/12", " 4/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12" ]) args = [ "hyperopt-list", "--profitable", "--no-details", "--no-color", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 2/12", " 10/12"]) assert all(x not in captured.out for x in [ " 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12" ]) args = [ "hyperopt-list", "--profitable", "--no-color", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [ " 2/12", " 10/12", "Best result:", "Buy hyperspace params", "Sell hyperspace params", "ROI table", "Stoploss" ]) assert all(x not in captured.out for x in [ " 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12" ]) args = [ "hyperopt-list", "--no-details", "--no-color", "--min-trades", "20", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 3/12", " 6/12", " 7/12", " 9/12", " 11/12"]) assert all( x not in captured.out for x in [" 1/12", " 2/12", " 4/12", " 5/12", " 8/12", " 10/12", " 12/12"]) args = [ "hyperopt-list", "--profitable", "--no-details", "--no-color", "--max-trades", "20", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 2/12", " 10/12"]) assert all(x not in captured.out for x in [ " 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12" ]) args = [ "hyperopt-list", "--profitable", "--no-details", "--no-color", "--min-avg-profit", "0.11", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 2/12"]) assert all(x not in captured.out for x in [ " 1/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 10/12", " 11/12", " 12/12" ]) args = [ "hyperopt-list", "--no-details", "--no-color", "--max-avg-profit", "0.10", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [ " 1/12", " 3/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12" ]) assert all(x not in captured.out for x in [" 2/12", " 4/12", " 10/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", "--no-color", "--min-total-profit", "0.4", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 10/12"]) assert all(x not in captured.out for x in [ " 1/12", " 2/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12" ]) args = [ "hyperopt-list", "--no-details", "--no-color", "--max-total-profit", "0.4", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [ " 1/12", " 2/12", " 3/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12" ]) assert all(x not in captured.out for x in [" 4/12", " 10/12", " 12/12"]) args = [ "hyperopt-list", "--no-details", "--no-color", "--min-objective", "0.1", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 10/12"]) assert all(x not in captured.out for x in [ " 1/12", " 2/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12" ]) args = [ "hyperopt-list", "--no-details", "--max-objective", "0.1", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [ " 1/12", " 2/12", " 3/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12" ]) assert all(x not in captured.out for x in [" 4/12", " 10/12", " 12/12"]) args = [ "hyperopt-list", "--profitable", "--no-details", "--no-color", "--min-avg-time", "2000", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 10/12"]) assert all(x not in captured.out for x in [ " 1/12", " 2/12", " 3/12", " 4/12", " 5/12", " 6/12", " 7/12", " 8/12", " 9/12", " 11/12", " 12/12" ]) args = [ "hyperopt-list", "--no-details", "--no-color", "--max-avg-time", "1500", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() assert all(x in captured.out for x in [" 2/12", " 6/12"]) assert all(x not in captured.out for x in [ " 1/12", " 3/12", " 4/12", " 5/12", " 7/12", " 8/12" " 9/12", " 10/12", " 11/12", " 12/12" ]) args = [ "hyperopt-list", "--no-details", "--no-color", "--export-csv", "test_file.csv", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_list(pargs) captured = capsys.readouterr() log_has("CSV file created: test_file.csv", caplog) f = Path("test_file.csv") assert 'Best,1,2,-1.25%,-1.2222,-0.00125625,,-2.51,"3,930.0 m",0.43662' in f.read_text( ) assert f.is_file() f.unlink()
def test_start_new_hyperopt_DefaultHyperopt(mocker, caplog): args = ["new-hyperopt", "--hyperopt", "DefaultHyperopt"] with pytest.raises(OperationalException, match=r"DefaultHyperopt is not allowed as name\."): start_new_hyperopt(get_args(args))
def test_start_new_strategy_DefaultStrat(mocker, caplog): args = ["new-strategy", "--strategy", "DefaultStrategy"] with pytest.raises(OperationalException, match=r"DefaultStrategy is not allowed as name\."): start_new_strategy(get_args(args))
def test_backtest_start_multi_strat_nomock(default_conf, mocker, caplog, testdatadir, capsys): default_conf.update({ "use_sell_signal": True, "sell_profit_only": False, "sell_profit_offset": 0.0, "ignore_roi_if_buy_signal": False, }) patch_exchange(mocker) result1 = pd.DataFrame({'pair': ['XRP/BTC', 'LTC/BTC'], 'profit_ratio': [0.0, 0.0], 'profit_abs': [0.0, 0.0], 'open_date': pd.to_datetime(['2018-01-29 18:40:00', '2018-01-30 03:30:00', ], utc=True ), 'close_date': pd.to_datetime(['2018-01-29 20:45:00', '2018-01-30 05:35:00', ], utc=True), 'trade_duration': [235, 40], 'is_open': [False, False], 'stake_amount': [0.01, 0.01], 'open_rate': [0.104445, 0.10302485], 'close_rate': [0.104969, 0.103541], 'sell_reason': [SellType.ROI, SellType.ROI] }) result2 = pd.DataFrame({'pair': ['XRP/BTC', 'LTC/BTC', 'ETH/BTC'], 'profit_ratio': [0.03, 0.01, 0.1], 'profit_abs': [0.01, 0.02, 0.2], 'open_date': pd.to_datetime(['2018-01-29 18:40:00', '2018-01-30 03:30:00', '2018-01-30 05:30:00'], utc=True ), 'close_date': pd.to_datetime(['2018-01-29 20:45:00', '2018-01-30 05:35:00', '2018-01-30 08:30:00'], utc=True), 'trade_duration': [47, 40, 20], 'is_open': [False, False, False], 'stake_amount': [0.01, 0.01, 0.01], 'open_rate': [0.104445, 0.10302485, 0.122541], 'close_rate': [0.104969, 0.103541, 0.123541], 'sell_reason': [SellType.ROI, SellType.ROI, SellType.STOP_LOSS] }) backtestmock = MagicMock(side_effect=[ { 'results': result1, 'config': default_conf, 'locks': [], 'rejected_signals': 20, 'final_balance': 1000, }, { 'results': result2, 'config': default_conf, 'locks': [], 'rejected_signals': 20, 'final_balance': 1000, } ]) mocker.patch('freqtrade.plugins.pairlistmanager.PairListManager.whitelist', PropertyMock(return_value=['UNITTEST/BTC'])) mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', backtestmock) patched_configuration_load_config_file(mocker, default_conf) args = [ 'backtesting', '--config', 'config.json', '--datadir', str(testdatadir), '--strategy-path', str(Path(__file__).parents[1] / 'strategy/strats'), '--timeframe', '1m', '--timerange', '1510694220-1510700340', '--enable-position-stacking', '--disable-max-market-positions', '--breakdown', 'day', '--strategy-list', 'StrategyTestV2', 'TestStrategyLegacyV1', ] args = get_args(args) start_backtesting(args) # check the logs, that will contain the backtest result exists = [ 'Parameter -i/--timeframe detected ... Using timeframe: 1m ...', 'Ignoring max_open_trades (--disable-max-market-positions was used) ...', 'Parameter --timerange detected: 1510694220-1510700340 ...', f'Using data directory: {testdatadir} ...', 'Loading data from 2017-11-14 20:57:00 ' 'up to 2017-11-14 22:58:00 (0 days).', 'Backtesting with data from 2017-11-14 21:17:00 ' 'up to 2017-11-14 22:58:00 (0 days).', 'Parameter --enable-position-stacking detected ...', 'Running backtesting for Strategy StrategyTestV2', 'Running backtesting for Strategy TestStrategyLegacyV1', ] for line in exists: assert log_has(line, caplog) captured = capsys.readouterr() assert 'BACKTESTING REPORT' in captured.out assert 'SELL REASON STATS' in captured.out assert 'DAY BREAKDOWN' in captured.out assert 'LEFT OPEN TRADES REPORT' in captured.out assert '2017-11-14 21:17:00 -> 2017-11-14 22:58:00 | Max open trades : 1' in captured.out assert 'STRATEGY SUMMARY' in captured.out
def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir): patch_exchange(mocker) backtestmock = MagicMock() mocker.patch('freqtrade.pairlist.pairlistmanager.PairListManager.whitelist', PropertyMock(return_value=['UNITTEST/BTC'])) mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', backtestmock) text_table_mock = MagicMock() sell_reason_mock = MagicMock() strattable_mock = MagicMock() strat_summary = MagicMock() mocker.patch.multiple('freqtrade.optimize.optimize_reports', text_table_bt_results=text_table_mock, text_table_strategy=strattable_mock, generate_pair_metrics=MagicMock(), generate_sell_reason_stats=sell_reason_mock, generate_strategy_metrics=strat_summary, ) patched_configuration_load_config_file(mocker, default_conf) args = [ 'backtesting', '--config', 'config.json', '--datadir', str(testdatadir), '--strategy-path', str(Path(__file__).parents[1] / 'strategy/strats'), '--timeframe', '1m', '--timerange', '1510694220-1510700340', '--enable-position-stacking', '--disable-max-market-positions', '--strategy-list', 'DefaultStrategy', 'TestStrategyLegacy', ] args = get_args(args) start_backtesting(args) # 2 backtests, 4 tables assert backtestmock.call_count == 2 assert text_table_mock.call_count == 4 assert strattable_mock.call_count == 1 assert sell_reason_mock.call_count == 2 assert strat_summary.call_count == 1 # check the logs, that will contain the backtest result exists = [ 'Parameter -i/--timeframe detected ... Using timeframe: 1m ...', 'Ignoring max_open_trades (--disable-max-market-positions was used) ...', 'Parameter --timerange detected: 1510694220-1510700340 ...', f'Using data directory: {testdatadir} ...', 'Using stake_currency: BTC ...', 'Using stake_amount: 0.001 ...', 'Loading data from 2017-11-14T20:57:00+00:00 ' 'up to 2017-11-14T22:58:00+00:00 (0 days)..', 'Backtesting with data from 2017-11-14T21:17:00+00:00 ' 'up to 2017-11-14T22:58:00+00:00 (0 days)..', 'Parameter --enable-position-stacking detected ...', 'Running backtesting for Strategy DefaultStrategy', 'Running backtesting for Strategy TestStrategyLegacy', ] for line in exists: assert log_has(line, caplog)
def test_hyperopt_show(mocker, capsys, saved_hyperopt_results): mocker.patch( 'freqtrade.optimize.hyperopt_tools.HyperoptTools._test_hyperopt_results_exist', return_value=True) def fake_iterator(*args, **kwargs): yield from [saved_hyperopt_results] mocker.patch( 'freqtrade.optimize.hyperopt_tools.HyperoptTools._read_results', side_effect=fake_iterator) mocker.patch('freqtrade.commands.hyperopt_commands.show_backtest_result') args = [ "hyperopt-show", ] pargs = get_args(args) pargs['config'] = None start_hyperopt_show(pargs) captured = capsys.readouterr() assert " 12/12" in captured.out args = ["hyperopt-show", "--best"] pargs = get_args(args) pargs['config'] = None start_hyperopt_show(pargs) captured = capsys.readouterr() assert " 10/12" in captured.out args = ["hyperopt-show", "-n", "1"] pargs = get_args(args) pargs['config'] = None start_hyperopt_show(pargs) captured = capsys.readouterr() assert " 1/12" in captured.out args = ["hyperopt-show", "--best", "-n", "2"] pargs = get_args(args) pargs['config'] = None start_hyperopt_show(pargs) captured = capsys.readouterr() assert " 5/12" in captured.out args = ["hyperopt-show", "--best", "-n", "-1"] pargs = get_args(args) pargs['config'] = None start_hyperopt_show(pargs) captured = capsys.readouterr() assert " 10/12" in captured.out args = ["hyperopt-show", "--best", "-n", "-4"] pargs = get_args(args) pargs['config'] = None with pytest.raises( OperationalException, match="The index of the epoch to show should be greater than -4."): start_hyperopt_show(pargs) args = ["hyperopt-show", "--best", "-n", "4"] pargs = get_args(args) pargs['config'] = None with pytest.raises( OperationalException, match="The index of the epoch to show should be less than 4."): start_hyperopt_show(pargs)
def test_list_timeframes(mocker, capsys): api_mock = MagicMock() api_mock.timeframes = {'1m': 'oneMin', '5m': 'fiveMin', '30m': 'thirtyMin', '1h': 'hour', '1d': 'day', } patch_exchange(mocker, api_mock=api_mock, id='bittrex') args = [ "list-timeframes", ] pargs = get_args(args) pargs['config'] = None with pytest.raises(OperationalException, match=r"This command requires a configured exchange.*"): start_list_timeframes(pargs) # Test with --config config_bittrex.json.example args = [ "list-timeframes", '--config', 'config_bittrex.json.example', ] start_list_timeframes(get_args(args)) captured = capsys.readouterr() assert re.match("Timeframes available for the exchange `Bittrex`: " "1m, 5m, 30m, 1h, 1d", captured.out) # Test with --exchange bittrex args = [ "list-timeframes", "--exchange", "bittrex", ] start_list_timeframes(get_args(args)) captured = capsys.readouterr() assert re.match("Timeframes available for the exchange `Bittrex`: " "1m, 5m, 30m, 1h, 1d", captured.out) api_mock.timeframes = {'1m': '1m', '5m': '5m', '15m': '15m', '30m': '30m', '1h': '1h', '6h': '6h', '12h': '12h', '1d': '1d', '3d': '3d', } patch_exchange(mocker, api_mock=api_mock, id='binance') # Test with --exchange binance args = [ "list-timeframes", "--exchange", "binance", ] start_list_timeframes(get_args(args)) captured = capsys.readouterr() assert re.match("Timeframes available for the exchange `Binance`: " "1m, 5m, 15m, 30m, 1h, 6h, 12h, 1d, 3d", captured.out) # Test with --one-column args = [ "list-timeframes", '--config', 'config_bittrex.json.example', "--one-column", ] start_list_timeframes(get_args(args)) captured = capsys.readouterr() assert re.search(r"^1m$", captured.out, re.MULTILINE) assert re.search(r"^5m$", captured.out, re.MULTILINE) assert re.search(r"^1h$", captured.out, re.MULTILINE) assert re.search(r"^1d$", captured.out, re.MULTILINE) # Test with --exchange binance --one-column args = [ "list-timeframes", "--exchange", "binance", "--one-column", ] start_list_timeframes(get_args(args)) captured = capsys.readouterr() assert re.search(r"^1m$", captured.out, re.MULTILINE) assert re.search(r"^5m$", captured.out, re.MULTILINE) assert re.search(r"^1h$", captured.out, re.MULTILINE) assert re.search(r"^1d$", captured.out, re.MULTILINE)
def test_start_test_pairlist(mocker, caplog, tickers, default_conf, capsys): patch_exchange(mocker, mock_markets=True) mocker.patch.multiple( 'freqtrade.exchange.Exchange', exchange_has=MagicMock(return_value=True), get_tickers=tickers, ) default_conf['pairlists'] = [ { "method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume", }, { "method": "PrecisionFilter" }, { "method": "PriceFilter", "low_price_ratio": 0.02 }, ] patched_configuration_load_config_file(mocker, default_conf) args = [ 'test-pairlist', '-c', 'config_examples/config_bittrex.example.json' ] start_test_pairlist(get_args(args)) assert log_has_re(r"^Using resolved pairlist VolumePairList.*", caplog) assert log_has_re(r"^Using resolved pairlist PrecisionFilter.*", caplog) assert log_has_re(r"^Using resolved pairlist PriceFilter.*", caplog) captured = capsys.readouterr() assert re.match(r"Pairs for .*", captured.out) assert re.match("['ETH/BTC', 'TKN/BTC', 'BLK/BTC', 'LTC/BTC', 'XRP/BTC']", captured.out) args = [ 'test-pairlist', '-c', 'config_examples/config_bittrex.example.json', '--one-column', ] start_test_pairlist(get_args(args)) captured = capsys.readouterr() assert re.match(r"ETH/BTC\nTKN/BTC\nBLK/BTC\nLTC/BTC\nXRP/BTC\n", captured.out) args = [ 'test-pairlist', '-c', 'config_examples/config_bittrex.example.json', '--print-json', ] start_test_pairlist(get_args(args)) captured = capsys.readouterr() try: json_pairs = json.loads(captured.out) assert 'ETH/BTC' in json_pairs assert 'TKN/BTC' in json_pairs assert 'BLK/BTC' in json_pairs assert 'LTC/BTC' in json_pairs assert 'XRP/BTC' in json_pairs except json.decoder.JSONDecodeError: pytest.fail( f'Expected well formed JSON, but failed to parse: {captured.out}')
def test_backtest_start_multi_strat_nomock_detail(default_conf, mocker, caplog, testdatadir, capsys): # Tests detail-data loading default_conf.update({ "use_sell_signal": True, "sell_profit_only": False, "sell_profit_offset": 0.0, "ignore_roi_if_buy_signal": False, }) patch_exchange(mocker) result1 = pd.DataFrame({'pair': ['XRP/BTC', 'LTC/BTC'], 'profit_ratio': [0.0, 0.0], 'profit_abs': [0.0, 0.0], 'open_date': pd.to_datetime(['2018-01-29 18:40:00', '2018-01-30 03:30:00', ], utc=True ), 'close_date': pd.to_datetime(['2018-01-29 20:45:00', '2018-01-30 05:35:00', ], utc=True), 'trade_duration': [235, 40], 'is_open': [False, False], 'stake_amount': [0.01, 0.01], 'open_rate': [0.104445, 0.10302485], 'close_rate': [0.104969, 0.103541], 'sell_reason': [SellType.ROI, SellType.ROI] }) result2 = pd.DataFrame({'pair': ['XRP/BTC', 'LTC/BTC', 'ETH/BTC'], 'profit_ratio': [0.03, 0.01, 0.1], 'profit_abs': [0.01, 0.02, 0.2], 'open_date': pd.to_datetime(['2018-01-29 18:40:00', '2018-01-30 03:30:00', '2018-01-30 05:30:00'], utc=True ), 'close_date': pd.to_datetime(['2018-01-29 20:45:00', '2018-01-30 05:35:00', '2018-01-30 08:30:00'], utc=True), 'trade_duration': [47, 40, 20], 'is_open': [False, False, False], 'stake_amount': [0.01, 0.01, 0.01], 'open_rate': [0.104445, 0.10302485, 0.122541], 'close_rate': [0.104969, 0.103541, 0.123541], 'sell_reason': [SellType.ROI, SellType.ROI, SellType.STOP_LOSS] }) backtestmock = MagicMock(side_effect=[ { 'results': result1, 'config': default_conf, 'locks': [], 'rejected_signals': 20, 'final_balance': 1000, }, { 'results': result2, 'config': default_conf, 'locks': [], 'rejected_signals': 20, 'final_balance': 1000, } ]) mocker.patch('freqtrade.plugins.pairlistmanager.PairListManager.whitelist', PropertyMock(return_value=['XRP/ETH'])) mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', backtestmock) patched_configuration_load_config_file(mocker, default_conf) args = [ 'backtesting', '--config', 'config.json', '--datadir', str(testdatadir), '--strategy-path', str(Path(__file__).parents[1] / 'strategy/strats'), '--timeframe', '5m', '--timeframe-detail', '1m', '--strategy-list', 'StrategyTestV2' ] args = get_args(args) start_backtesting(args) # check the logs, that will contain the backtest result exists = [ 'Parameter -i/--timeframe detected ... Using timeframe: 5m ...', 'Parameter --timeframe-detail detected, using 1m for intra-candle backtesting ...', f'Using data directory: {testdatadir} ...', 'Loading data from 2019-10-11 00:00:00 ' 'up to 2019-10-13 11:10:00 (2 days).', 'Backtesting with data from 2019-10-11 01:40:00 ' 'up to 2019-10-13 11:10:00 (2 days).', 'Running backtesting for Strategy StrategyTestV2', ] for line in exists: assert log_has(line, caplog) captured = capsys.readouterr() assert 'BACKTESTING REPORT' in captured.out assert 'SELL REASON STATS' in captured.out assert 'LEFT OPEN TRADES REPORT' in captured.out
def test_backtest_start_multi_strat_nomock(default_conf, mocker, caplog, testdatadir, capsys): patch_exchange(mocker) backtestmock = MagicMock(side_effect=[ pd.DataFrame({'pair': ['XRP/BTC', 'LTC/BTC'], 'profit_percent': [0.0, 0.0], 'profit_abs': [0.0, 0.0], 'open_time': pd.to_datetime(['2018-01-29 18:40:00', '2018-01-30 03:30:00', ], utc=True ), 'close_time': pd.to_datetime(['2018-01-29 20:45:00', '2018-01-30 05:35:00', ], utc=True), 'open_index': [78, 184], 'close_index': [125, 192], 'trade_duration': [235, 40], 'open_at_end': [False, False], 'open_rate': [0.104445, 0.10302485], 'close_rate': [0.104969, 0.103541], 'sell_reason': [SellType.ROI, SellType.ROI] }), pd.DataFrame({'pair': ['XRP/BTC', 'LTC/BTC', 'ETH/BTC'], 'profit_percent': [0.03, 0.01, 0.1], 'profit_abs': [0.01, 0.02, 0.2], 'open_time': pd.to_datetime(['2018-01-29 18:40:00', '2018-01-30 03:30:00', '2018-01-30 05:30:00'], utc=True ), 'close_time': pd.to_datetime(['2018-01-29 20:45:00', '2018-01-30 05:35:00', '2018-01-30 08:30:00'], utc=True), 'open_index': [78, 184, 185], 'close_index': [125, 224, 205], 'trade_duration': [47, 40, 20], 'open_at_end': [False, False, False], 'open_rate': [0.104445, 0.10302485, 0.122541], 'close_rate': [0.104969, 0.103541, 0.123541], 'sell_reason': [SellType.ROI, SellType.ROI, SellType.STOP_LOSS] }), ]) mocker.patch('freqtrade.pairlist.pairlistmanager.PairListManager.whitelist', PropertyMock(return_value=['UNITTEST/BTC'])) mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', backtestmock) patched_configuration_load_config_file(mocker, default_conf) args = [ 'backtesting', '--config', 'config.json', '--datadir', str(testdatadir), '--strategy-path', str(Path(__file__).parents[1] / 'strategy/strats'), '--timeframe', '1m', '--timerange', '1510694220-1510700340', '--enable-position-stacking', '--disable-max-market-positions', '--strategy-list', 'DefaultStrategy', 'TestStrategyLegacy', ] args = get_args(args) start_backtesting(args) # check the logs, that will contain the backtest result exists = [ 'Parameter -i/--timeframe detected ... Using timeframe: 1m ...', 'Ignoring max_open_trades (--disable-max-market-positions was used) ...', 'Parameter --timerange detected: 1510694220-1510700340 ...', f'Using data directory: {testdatadir} ...', 'Using stake_currency: BTC ...', 'Using stake_amount: 0.001 ...', 'Loading data from 2017-11-14T20:57:00+00:00 ' 'up to 2017-11-14T22:58:00+00:00 (0 days)..', 'Backtesting with data from 2017-11-14T21:17:00+00:00 ' 'up to 2017-11-14T22:58:00+00:00 (0 days)..', 'Parameter --enable-position-stacking detected ...', 'Running backtesting for Strategy DefaultStrategy', 'Running backtesting for Strategy TestStrategyLegacy', ] for line in exists: assert log_has(line, caplog) captured = capsys.readouterr() assert 'BACKTESTING REPORT' in captured.out assert 'SELL REASON STATS' in captured.out assert 'LEFT OPEN TRADES REPORT' in captured.out assert 'STRATEGY SUMMARY' in captured.out
def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir): default_conf['ask_strategy'].update({ "use_sell_signal": True, "sell_profit_only": False, "sell_profit_offset": 0.0, "ignore_roi_if_buy_signal": False, }) patch_exchange(mocker) backtestmock = MagicMock( return_value={ 'results': pd.DataFrame(columns=BT_DATA_COLUMNS), 'config': default_conf, 'locks': [], 'rejected_signals': 20, 'final_balance': 1000, }) mocker.patch('freqtrade.plugins.pairlistmanager.PairListManager.whitelist', PropertyMock(return_value=['UNITTEST/BTC'])) mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', backtestmock) text_table_mock = MagicMock() sell_reason_mock = MagicMock() strattable_mock = MagicMock() strat_summary = MagicMock() mocker.patch.multiple( 'freqtrade.optimize.optimize_reports', text_table_bt_results=text_table_mock, text_table_strategy=strattable_mock, generate_pair_metrics=MagicMock(), generate_sell_reason_stats=sell_reason_mock, generate_strategy_comparison=strat_summary, generate_daily_stats=MagicMock(), ) patched_configuration_load_config_file(mocker, default_conf) args = [ 'backtesting', '--config', 'config.json', '--datadir', str(testdatadir), '--strategy-path', str(Path(__file__).parents[1] / 'strategy/strats'), '--timeframe', '1m', '--timerange', '1510694220-1510700340', '--enable-position-stacking', '--disable-max-market-positions', '--strategy-list', 'DefaultStrategy', 'TestStrategyLegacy', ] args = get_args(args) start_backtesting(args) # 2 backtests, 4 tables assert backtestmock.call_count == 2 assert text_table_mock.call_count == 4 assert strattable_mock.call_count == 1 assert sell_reason_mock.call_count == 2 assert strat_summary.call_count == 1 # check the logs, that will contain the backtest result exists = [ 'Parameter -i/--timeframe detected ... Using timeframe: 1m ...', 'Ignoring max_open_trades (--disable-max-market-positions was used) ...', 'Parameter --timerange detected: 1510694220-1510700340 ...', f'Using data directory: {testdatadir} ...', 'Loading data from 2017-11-14 20:57:00 ' 'up to 2017-11-14 22:58:00 (0 days).', 'Backtesting with data from 2017-11-14 21:17:00 ' 'up to 2017-11-14 22:58:00 (0 days).', 'Parameter --enable-position-stacking detected ...', 'Running backtesting for Strategy DefaultStrategy', 'Running backtesting for Strategy TestStrategyLegacy', ] for line in exists: assert log_has(line, caplog)