From 6a9a8f927e2d7f4560bb4d226f1f7b28f0f01a27 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 25 May 2020 20:46:31 +0200 Subject: [PATCH] Rename some methods, improve some testing --- freqtrade/optimize/optimize_reports.py | 10 +-- tests/optimize/test_backtesting.py | 93 ++++++++++++++++++++++++- tests/optimize/test_optimize_reports.py | 12 ++-- 3 files changed, 102 insertions(+), 13 deletions(-) diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index 655f79f78..b8465ad2e 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -78,7 +78,7 @@ def _generate_result_line(result: DataFrame, max_open_trades: int, first_column: } -def generate_pair_results(data: Dict[str, Dict], stake_currency: str, max_open_trades: int, +def generate_pair_metrics(data: Dict[str, Dict], stake_currency: str, max_open_trades: int, results: DataFrame, skip_nan: bool = False) -> List[Dict]: """ Generates and returns a list for the given backtest data and the results dataframe @@ -184,7 +184,7 @@ def generate_text_table_sell_reason(sell_reason_stats: List[Dict[str, Any]], return tabulate(output, headers=headers, tablefmt="orgtbl", stralign="right") -def generate_strategy_summary(stake_currency: str, max_open_trades: int, +def generate_strategy_metrics(stake_currency: str, max_open_trades: int, all_results: Dict) -> List[Dict]: """ Generate summary per strategy @@ -249,12 +249,12 @@ def generate_edge_table(results: dict) -> str: def show_backtest_results(config: Dict, btdata: Dict[str, DataFrame], all_results: Dict[str, DataFrame]): for strategy, results in all_results.items(): - pair_results = generate_pair_results(btdata, stake_currency=config['stake_currency'], + pair_results = generate_pair_metrics(btdata, stake_currency=config['stake_currency'], max_open_trades=config['max_open_trades'], results=results, skip_nan=False) sell_reason_stats = generate_sell_reason_stats(max_open_trades=config['max_open_trades'], results=results) - left_open_results = generate_pair_results(btdata, stake_currency=config['stake_currency'], + left_open_results = generate_pair_metrics(btdata, stake_currency=config['stake_currency'], max_open_trades=config['max_open_trades'], results=results.loc[results['open_at_end']], skip_nan=True) @@ -282,7 +282,7 @@ def show_backtest_results(config: Dict, btdata: Dict[str, DataFrame], if len(all_results) > 1: # Print Strategy summary table - strategy_results = generate_strategy_summary(stake_currency=config['stake_currency'], + strategy_results = generate_strategy_metrics(stake_currency=config['stake_currency'], max_open_trades=config['max_open_trades'], all_results=all_results) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 943da7925..ace82d28b 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -665,9 +665,9 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir): mocker.patch.multiple('freqtrade.optimize.optimize_reports', generate_text_table=gen_table_mock, generate_text_table_strategy=gen_strattable_mock, - generate_pair_results=MagicMock(), + generate_pair_metrics=MagicMock(), generate_sell_reason_stats=sell_reason_mock, - generate_strategy_summary=gen_strat_summary, + generate_strategy_metrics=gen_strat_summary, ) patched_configuration_load_config_file(mocker, default_conf) @@ -712,3 +712,92 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir): for line in exists: assert log_has(line, caplog) + + +@pytest.mark.filterwarnings("ignore:deprecated") +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'), + '--ticker-interval', '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/--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 ...', + '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 diff --git a/tests/optimize/test_optimize_reports.py b/tests/optimize/test_optimize_reports.py index 6e0dc5441..8bef6e2cc 100644 --- a/tests/optimize/test_optimize_reports.py +++ b/tests/optimize/test_optimize_reports.py @@ -6,8 +6,8 @@ from arrow import Arrow from freqtrade.edge import PairInfo from freqtrade.optimize.optimize_reports import ( - generate_pair_results, generate_edge_table, generate_sell_reason_stats, - generate_text_table, generate_text_table_sell_reason, generate_strategy_summary, + generate_pair_metrics, generate_edge_table, generate_sell_reason_stats, + generate_text_table, generate_text_table_sell_reason, generate_strategy_metrics, generate_text_table_strategy, store_backtest_result) from freqtrade.strategy.interface import SellType from tests.conftest import patch_exchange @@ -38,13 +38,13 @@ def test_generate_text_table(default_conf, mocker): ' 15.00 | 0:20:00 | 2 | 0 | 0 |' ) - pair_results = generate_pair_results(data={'ETH/BTC': {}}, stake_currency='BTC', + pair_results = generate_pair_metrics(data={'ETH/BTC': {}}, stake_currency='BTC', max_open_trades=2, results=results) assert generate_text_table(pair_results, stake_currency='BTC') == result_str -def test_generate_pair_results(default_conf, mocker): +def test_generate_pair_metrics(default_conf, mocker): results = pd.DataFrame( { @@ -58,7 +58,7 @@ def test_generate_pair_results(default_conf, mocker): } ) - pair_results = generate_pair_results(data={'ETH/BTC': {}}, stake_currency='BTC', + pair_results = generate_pair_metrics(data={'ETH/BTC': {}}, stake_currency='BTC', max_open_trades=2, results=results) assert isinstance(pair_results, list) assert len(pair_results) == 2 @@ -174,7 +174,7 @@ def test_generate_text_table_strategy(default_conf, mocker): ' 45.00 | 0:20:00 | 3 | 0 | 0 |' ) - strategy_results = generate_strategy_summary(stake_currency='BTC', + strategy_results = generate_strategy_metrics(stake_currency='BTC', max_open_trades=2, all_results=results)