From 7f125315b059cc529750415945366474efa5ac7b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 23 May 2021 09:36:02 +0200 Subject: [PATCH] Track Rejected Trades closes #3423 --- freqtrade/optimize/backtesting.py | 26 +++++++++++++++++++++----- freqtrade/optimize/optimize_reports.py | 2 ++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index aff09921c..642ed2b76 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -177,6 +177,7 @@ class Backtesting: Trade.use_db = False PairLocks.reset_locks() Trade.reset_trades() + self.rejected_trades = 0 self.dataprovider.clear_cache() def _get_ohlcv_as_lists(self, processed: Dict[str, DataFrame]) -> Dict[str, Tuple]: @@ -336,6 +337,17 @@ class Backtesting: trades.append(trade1) return trades + def trade_slot_available(self, max_open_trades: int, open_trade_count: int) -> bool: + if max_open_trades <= 0: + # Always allow trades when max_open_trades is enabled. + return True + if open_trade_count < max_open_trades: + + return True + # Rejected trade + self.rejected_trades += 1 + return False + def backtest(self, processed: Dict, start_date: datetime, end_date: datetime, max_open_trades: int = 0, position_stacking: bool = False, @@ -397,11 +409,14 @@ class Backtesting: # without positionstacking, we can only have one open trade per pair. # max_open_trades must be respected # don't open on the last row - if ((position_stacking or len(open_trades[pair]) == 0) - and (max_open_trades <= 0 or open_trade_count_start < max_open_trades) - and tmp != end_date - and row[BUY_IDX] == 1 and row[SELL_IDX] != 1 - and not PairLocks.is_pair_locked(pair, row[DATE_IDX])): + if ( + (position_stacking or len(open_trades[pair]) == 0) + and self.trade_slot_available(max_open_trades, open_trade_count_start) + and tmp != end_date + and row[BUY_IDX] == 1 + and row[SELL_IDX] != 1 + and not PairLocks.is_pair_locked(pair, row[DATE_IDX]) + ): trade = self._enter_trade(pair, row) if trade: # TODO: hacky workaround to avoid opening > max_open_trades @@ -439,6 +454,7 @@ class Backtesting: 'results': results, 'config': self.strategy.config, 'locks': PairLocks.get_all_locks(), + 'rejected': self.rejected_trades, 'final_balance': self.wallets.get_total(self.strategy.config['stake_currency']), } diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index ce6758210..ddccfd1dc 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -355,6 +355,7 @@ def generate_strategy_stats(btdata: Dict[str, DataFrame], 'starting_balance': starting_balance, 'dry_run_wallet': starting_balance, 'final_balance': content['final_balance'], + 'rejected_signals': content['rejected'], 'max_open_trades': max_open_trades, 'max_open_trades_setting': (config['max_open_trades'] if config['max_open_trades'] != float('inf') else -1), @@ -561,6 +562,7 @@ def text_table_add_metrics(strat_results: Dict) -> str: strat_results['stake_currency'])), ('Total trade volume', round_coin_value(strat_results['total_volume'], strat_results['stake_currency'])), + ('Rejected Buy signals', strat_results.get('rejected_signals', 'N/A')), ('', ''), # Empty line to improve readability ('Best Pair', f"{strat_results['best_pair']['key']} "