diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 46b2aac19..3f867df22 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -120,6 +120,16 @@ class Backtesting(object): ]) return tabulate(tabular_data, headers=headers, floatfmt=floatfmt, tablefmt="pipe") + def _generate_text_table_sell_reason(self, data: Dict[str, Dict], results: DataFrame) -> str: + """ + Generate small table outlining Backtest results + """ + tabular_data = [] + headers = ['Sell Reason', 'Count'] + for reason, count in results['sell_reason'].value_counts().iteritems(): + tabular_data.append([reason.value, count]) + return tabulate(tabular_data, headers=headers, tablefmt="pipe") + def _store_backtest_result(self, recordfilename: Optional[str], results: DataFrame) -> None: records = [(t.pair, t.profit_percent, t.open_time.timestamp(), @@ -319,20 +329,32 @@ class Backtesting(object): self._store_backtest_result(self.config.get('exportfilename'), results) logger.info( - '\n================================================= ' - 'BACKTESTING REPORT' - ' ==================================================\n' + '\n' + '=' * 49 + + ' BACKTESTING REPORT ' + + '=' * 50 + '\n' '%s', self._generate_text_table( data, results ) ) + # logger.info( + # results[['sell_reason']].groupby('sell_reason').count() + # ) logger.info( - '\n=============================================== ' - 'LEFT OPEN TRADES REPORT' - ' ===============================================\n' + '\n' + '=' * 4 + + ' SELL READON STATS ' + + '=' * 4 + '\n' + '%s \n', + self._generate_text_table_sell_reason(data, results) + + ) + + logger.info( + '\n' + '=' * 47 + + ' LEFT OPEN TRADES REPORT ' + + '=' * 47 + '\n' '%s', self._generate_text_table( data, diff --git a/freqtrade/tests/optimize/test_backtesting.py b/freqtrade/tests/optimize/test_backtesting.py index c71930782..d3fc233ce 100644 --- a/freqtrade/tests/optimize/test_backtesting.py +++ b/freqtrade/tests/optimize/test_backtesting.py @@ -404,6 +404,35 @@ def test_generate_text_table(default_conf, mocker): assert backtesting._generate_text_table(data={'ETH/BTC': {}}, results=results) == result_str +def test_generate_text_table_sell_reason(default_conf, mocker): + """ + Test Backtesting.generate_text_table_sell_reason() method + """ + patch_exchange(mocker) + backtesting = Backtesting(default_conf) + + results = pd.DataFrame( + { + 'pair': ['ETH/BTC', 'ETH/BTC', 'ETH/BTC'], + 'profit_percent': [0.1, 0.2, 0.3], + 'profit_abs': [0.2, 0.4, 0.5], + 'trade_duration': [10, 30, 10], + 'profit': [2, 0, 0], + 'loss': [0, 0, 1], + 'sell_reason': [SellType.ROI, SellType.ROI, SellType.STOP_LOSS] + } + ) + + result_str = ( + '| Sell Reason | Count |\n' + '|:--------------|--------:|\n' + '| roi | 2 |\n' + '| stop_loss | 1 |' + ) + assert backtesting._generate_text_table_sell_reason( + data={'ETH/BTC': {}}, results=results) == result_str + + def test_backtesting_start(default_conf, mocker, caplog) -> None: """ Test Backtesting.start() method