Track Rejected Trades

closes #3423
This commit is contained in:
Matthias 2021-05-23 09:36:02 +02:00
parent 02faeb60a3
commit 7f125315b0
2 changed files with 23 additions and 5 deletions

View File

@ -177,6 +177,7 @@ class Backtesting:
Trade.use_db = False Trade.use_db = False
PairLocks.reset_locks() PairLocks.reset_locks()
Trade.reset_trades() Trade.reset_trades()
self.rejected_trades = 0
self.dataprovider.clear_cache() self.dataprovider.clear_cache()
def _get_ohlcv_as_lists(self, processed: Dict[str, DataFrame]) -> Dict[str, Tuple]: def _get_ohlcv_as_lists(self, processed: Dict[str, DataFrame]) -> Dict[str, Tuple]:
@ -336,6 +337,17 @@ class Backtesting:
trades.append(trade1) trades.append(trade1)
return trades 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, def backtest(self, processed: Dict,
start_date: datetime, end_date: datetime, start_date: datetime, end_date: datetime,
max_open_trades: int = 0, position_stacking: bool = False, 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. # without positionstacking, we can only have one open trade per pair.
# max_open_trades must be respected # max_open_trades must be respected
# don't open on the last row # don't open on the last row
if ((position_stacking or len(open_trades[pair]) == 0) if (
and (max_open_trades <= 0 or open_trade_count_start < max_open_trades) (position_stacking or len(open_trades[pair]) == 0)
and tmp != end_date and self.trade_slot_available(max_open_trades, open_trade_count_start)
and row[BUY_IDX] == 1 and row[SELL_IDX] != 1 and tmp != end_date
and not PairLocks.is_pair_locked(pair, row[DATE_IDX])): 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) trade = self._enter_trade(pair, row)
if trade: if trade:
# TODO: hacky workaround to avoid opening > max_open_trades # TODO: hacky workaround to avoid opening > max_open_trades
@ -439,6 +454,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,
'final_balance': self.wallets.get_total(self.strategy.config['stake_currency']), 'final_balance': self.wallets.get_total(self.strategy.config['stake_currency']),
} }

View File

@ -355,6 +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'],
'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),
@ -561,6 +562,7 @@ 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']} "