Add tests for rejected signals
This commit is contained in:
		| @@ -298,6 +298,7 @@ A backtesting result will look like that: | |||||||
| | Avg. Duration Winners | 4:23:00             | | | Avg. Duration Winners | 4:23:00             | | ||||||
| | Avg. Duration Loser   | 6:55:00             | | | Avg. Duration Loser   | 6:55:00             | | ||||||
| | Zero Duration Trades  | 4.6% (20)           | | | Zero Duration Trades  | 4.6% (20)           | | ||||||
|  | | Rejected Buy signals  | 3089                | | ||||||
| |                       |                     | | |                       |                     | | ||||||
| | Min balance           | 0.00945123 BTC      | | | Min balance           | 0.00945123 BTC      | | ||||||
| | Max balance           | 0.01846651 BTC      | | | Max balance           | 0.01846651 BTC      | | ||||||
| @@ -386,6 +387,7 @@ It contains some useful key metrics about performance of your strategy on backte | |||||||
| | Avg. Duration Winners | 4:23:00             | | | Avg. Duration Winners | 4:23:00             | | ||||||
| | Avg. Duration Loser   | 6:55:00             | | | Avg. Duration Loser   | 6:55:00             | | ||||||
| | Zero Duration Trades  | 4.6% (20)           | | | Zero Duration Trades  | 4.6% (20)           | | ||||||
|  | | Rejected Buy signals  | 3089                | | ||||||
| |                       |                     | | |                       |                     | | ||||||
| | Min balance           | 0.00945123 BTC      | | | Min balance           | 0.00945123 BTC      | | ||||||
| | Max balance           | 0.01846651 BTC      | | | Max balance           | 0.01846651 BTC      | | ||||||
| @@ -416,6 +418,7 @@ It contains some useful key metrics about performance of your strategy on backte | |||||||
| - `Days win/draw/lose`: Winning / Losing days (draws are usually days without closed trade). | - `Days win/draw/lose`: Winning / Losing days (draws are usually days without closed trade). | ||||||
| - `Avg. Duration Winners` / `Avg. Duration Loser`: Average durations for winning and losing trades. | - `Avg. Duration Winners` / `Avg. Duration Loser`: Average durations for winning and losing trades. | ||||||
| - `Zero Duration Trades`: A number of trades that completed within same candle as they opened and had `trailing_stop_loss` sell reason. A significant amount of such trades may indicate that strategy is exploiting trailing stoploss behavior in backtesting and produces unrealistic results. | - `Zero Duration Trades`: A number of trades that completed within same candle as they opened and had `trailing_stop_loss` sell reason. A significant amount of such trades may indicate that strategy is exploiting trailing stoploss behavior in backtesting and produces unrealistic results. | ||||||
|  | - `Rejected Buy signals`: Buy signals that could not be acted upon due to max_open_trades being reached. | ||||||
| - `Min balance` / `Max balance`: Lowest and Highest Wallet balance during the backtest period. | - `Min balance` / `Max balance`: Lowest and Highest Wallet balance during the backtest period. | ||||||
| - `Drawdown`: Maximum drawdown experienced. For example, the value of 50% means that from highest to subsequent lowest point, a 50% drop was experienced). | - `Drawdown`: Maximum drawdown experienced. For example, the value of 50% means that from highest to subsequent lowest point, a 50% drop was experienced). | ||||||
| - `Drawdown high` / `Drawdown low`: Profit at the beginning and end of the largest drawdown period. A negative low value means initial capital lost. | - `Drawdown high` / `Drawdown low`: Profit at the beginning and end of the largest drawdown period. A negative low value means initial capital lost. | ||||||
|   | |||||||
| @@ -338,11 +338,8 @@ class Backtesting: | |||||||
|         return trades |         return trades | ||||||
|  |  | ||||||
|     def trade_slot_available(self, max_open_trades: int, open_trade_count: int) -> bool: |     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. | ||||||
|             # Always allow trades when max_open_trades is enabled. |         if max_open_trades <= 0 or open_trade_count < max_open_trades: | ||||||
|             return True |  | ||||||
|         if open_trade_count < max_open_trades: |  | ||||||
|  |  | ||||||
|             return True |             return True | ||||||
|         # Rejected trade |         # Rejected trade | ||||||
|         self.rejected_trades += 1 |         self.rejected_trades += 1 | ||||||
| @@ -454,7 +451,7 @@ class Backtesting: | |||||||
|             'results': results, |             'results': results, | ||||||
|             'config': self.strategy.config, |             'config': self.strategy.config, | ||||||
|             'locks': PairLocks.get_all_locks(), |             'locks': PairLocks.get_all_locks(), | ||||||
|             'rejected': self.rejected_trades, |             'rejected_signals': self.rejected_trades, | ||||||
|             'final_balance': self.wallets.get_total(self.strategy.config['stake_currency']), |             'final_balance': self.wallets.get_total(self.strategy.config['stake_currency']), | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -355,7 +355,7 @@ def generate_strategy_stats(btdata: Dict[str, DataFrame], | |||||||
|         'starting_balance': starting_balance, |         'starting_balance': starting_balance, | ||||||
|         'dry_run_wallet': starting_balance, |         'dry_run_wallet': starting_balance, | ||||||
|         'final_balance': content['final_balance'], |         'final_balance': content['final_balance'], | ||||||
|         'rejected_signals': content['rejected'], |         'rejected_signals': content['rejected_signals'], | ||||||
|         'max_open_trades': max_open_trades, |         'max_open_trades': max_open_trades, | ||||||
|         'max_open_trades_setting': (config['max_open_trades'] |         'max_open_trades_setting': (config['max_open_trades'] | ||||||
|                                     if config['max_open_trades'] != float('inf') else -1), |                                     if config['max_open_trades'] != float('inf') else -1), | ||||||
| @@ -562,8 +562,6 @@ def text_table_add_metrics(strat_results: Dict) -> str: | |||||||
|                                                    strat_results['stake_currency'])), |                                                    strat_results['stake_currency'])), | ||||||
|             ('Total trade volume', round_coin_value(strat_results['total_volume'], |             ('Total trade volume', round_coin_value(strat_results['total_volume'], | ||||||
|                                                     strat_results['stake_currency'])), |                                                     strat_results['stake_currency'])), | ||||||
|             ('Rejected Buy signals', strat_results.get('rejected_signals', 'N/A')), |  | ||||||
|  |  | ||||||
|             ('', ''),  # Empty line to improve readability |             ('', ''),  # Empty line to improve readability | ||||||
|             ('Best Pair', f"{strat_results['best_pair']['key']} " |             ('Best Pair', f"{strat_results['best_pair']['key']} " | ||||||
|                           f"{round(strat_results['best_pair']['profit_sum_pct'], 2)}%"), |                           f"{round(strat_results['best_pair']['profit_sum_pct'], 2)}%"), | ||||||
| @@ -582,6 +580,7 @@ def text_table_add_metrics(strat_results: Dict) -> str: | |||||||
|             ('Avg. Duration Winners', f"{strat_results['winner_holding_avg']}"), |             ('Avg. Duration Winners', f"{strat_results['winner_holding_avg']}"), | ||||||
|             ('Avg. Duration Loser', f"{strat_results['loser_holding_avg']}"), |             ('Avg. Duration Loser', f"{strat_results['loser_holding_avg']}"), | ||||||
|             ('Zero Duration Trades', zero_duration_trades), |             ('Zero Duration Trades', zero_duration_trades), | ||||||
|  |             ('Rejected Buy signals', strat_results.get('rejected_signals', 'N/A')), | ||||||
|             ('', ''),  # Empty line to improve readability |             ('', ''),  # Empty line to improve readability | ||||||
|  |  | ||||||
|             ('Min balance', round_coin_value(strat_results['csum_min'], |             ('Min balance', round_coin_value(strat_results['csum_min'], | ||||||
|   | |||||||
| @@ -831,6 +831,7 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir): | |||||||
|         'results': pd.DataFrame(columns=BT_DATA_COLUMNS), |         'results': pd.DataFrame(columns=BT_DATA_COLUMNS), | ||||||
|         'config': default_conf, |         'config': default_conf, | ||||||
|         'locks': [], |         'locks': [], | ||||||
|  |         'rejected_signals': 20, | ||||||
|         'final_balance': 1000, |         'final_balance': 1000, | ||||||
|         }) |         }) | ||||||
|     mocker.patch('freqtrade.plugins.pairlistmanager.PairListManager.whitelist', |     mocker.patch('freqtrade.plugins.pairlistmanager.PairListManager.whitelist', | ||||||
| @@ -938,12 +939,14 @@ def test_backtest_start_multi_strat_nomock(default_conf, mocker, caplog, testdat | |||||||
|             'results': result1, |             'results': result1, | ||||||
|             'config': default_conf, |             'config': default_conf, | ||||||
|             'locks': [], |             'locks': [], | ||||||
|  |             'rejected_signals': 20, | ||||||
|             'final_balance': 1000, |             'final_balance': 1000, | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
|             'results': result2, |             'results': result2, | ||||||
|             'config': default_conf, |             'config': default_conf, | ||||||
|             'locks': [], |             'locks': [], | ||||||
|  |             'rejected_signals': 20, | ||||||
|             'final_balance': 1000, |             'final_balance': 1000, | ||||||
|         } |         } | ||||||
|     ]) |     ]) | ||||||
|   | |||||||
| @@ -441,6 +441,7 @@ def test_hyperopt_format_results(hyperopt): | |||||||
|         'config': hyperopt.config, |         'config': hyperopt.config, | ||||||
|         'locks': [], |         'locks': [], | ||||||
|         'final_balance': 0.02, |         'final_balance': 0.02, | ||||||
|  |         'rejected_signals': 2, | ||||||
|         'backtest_start_time': 1619718665, |         'backtest_start_time': 1619718665, | ||||||
|         'backtest_end_time': 1619718665, |         'backtest_end_time': 1619718665, | ||||||
|         } |         } | ||||||
| @@ -593,6 +594,7 @@ def test_generate_optimizer(mocker, hyperopt_conf) -> None: | |||||||
|                                  }), |                                  }), | ||||||
|         'config': hyperopt_conf, |         'config': hyperopt_conf, | ||||||
|         'locks': [], |         'locks': [], | ||||||
|  |         'rejected_signals': 20, | ||||||
|         'final_balance': 1000, |         'final_balance': 1000, | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -79,6 +79,7 @@ def test_generate_backtest_stats(default_conf, testdatadir): | |||||||
|         'config': default_conf, |         'config': default_conf, | ||||||
|         'locks': [], |         'locks': [], | ||||||
|         'final_balance': 1000.02, |         'final_balance': 1000.02, | ||||||
|  |         'rejected_signals': 20, | ||||||
|         'backtest_start_time': Arrow.utcnow().int_timestamp, |         'backtest_start_time': Arrow.utcnow().int_timestamp, | ||||||
|         'backtest_end_time': Arrow.utcnow().int_timestamp, |         'backtest_end_time': Arrow.utcnow().int_timestamp, | ||||||
|         } |         } | ||||||
| @@ -126,6 +127,7 @@ def test_generate_backtest_stats(default_conf, testdatadir): | |||||||
|         'config': default_conf, |         'config': default_conf, | ||||||
|         'locks': [], |         'locks': [], | ||||||
|         'final_balance': 1000.02, |         'final_balance': 1000.02, | ||||||
|  |         'rejected_signals': 20, | ||||||
|         'backtest_start_time': Arrow.utcnow().int_timestamp, |         'backtest_start_time': Arrow.utcnow().int_timestamp, | ||||||
|         'backtest_end_time': Arrow.utcnow().int_timestamp, |         'backtest_end_time': Arrow.utcnow().int_timestamp, | ||||||
|         } |         } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user