Merge pull request #6851 from eSeR1805/feat_bt_cancel_entry_reporting

BT: Reporting canceled trade entries
This commit is contained in:
Matthias 2022-05-17 07:05:26 +02:00 committed by GitHub
commit 6fd003c655
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 20 additions and 0 deletions

View File

@ -320,6 +320,7 @@ A backtesting result will look like that:
| Avg. Duration Loser | 6:55:00 | | Avg. Duration Loser | 6:55:00 |
| Rejected Entry signals | 3089 | | Rejected Entry signals | 3089 |
| Entry/Exit Timeouts | 0 / 0 | | Entry/Exit Timeouts | 0 / 0 |
| Canceled Trade Entries | 123 |
| | | | | |
| Min balance | 0.00945123 BTC | | Min balance | 0.00945123 BTC |
| Max balance | 0.01846651 BTC | | Max balance | 0.01846651 BTC |
@ -416,6 +417,7 @@ It contains some useful key metrics about performance of your strategy on backte
| Avg. Duration Loser | 6:55:00 | | Avg. Duration Loser | 6:55:00 |
| Rejected Entry signals | 3089 | | Rejected Entry signals | 3089 |
| Entry/Exit Timeouts | 0 / 0 | | Entry/Exit Timeouts | 0 / 0 |
| Canceled Trade Entries | 123 |
| | | | | |
| Min balance | 0.00945123 BTC | | Min balance | 0.00945123 BTC |
| Max balance | 0.01846651 BTC | | Max balance | 0.01846651 BTC |
@ -447,6 +449,7 @@ It contains some useful key metrics about performance of your strategy on backte
- `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.
- `Rejected Entry signals`: Trade entry signals that could not be acted upon due to `max_open_trades` being reached. - `Rejected Entry signals`: Trade entry signals that could not be acted upon due to `max_open_trades` being reached.
- `Entry/Exit Timeouts`: Entry/exit orders which did not fill (only applicable if custom pricing is used). - `Entry/Exit Timeouts`: Entry/exit orders which did not fill (only applicable if custom pricing is used).
- `Canceled Trade Entries`: Number of trades that have been canceled by user request via `adjust_entry_price`.
- `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.
- `Max % of account underwater`: Maximum percentage your account has decreased from the top since the simulation started. - `Max % of account underwater`: Maximum percentage your account has decreased from the top since the simulation started.
Calculated as the maximum of `(Max Balance - Current Balance) / (Max Balance)`. Calculated as the maximum of `(Max Balance - Current Balance) / (Max Balance)`.

View File

@ -297,6 +297,7 @@ class Backtesting:
self.rejected_trades = 0 self.rejected_trades = 0
self.timedout_entry_orders = 0 self.timedout_entry_orders = 0
self.timedout_exit_orders = 0 self.timedout_exit_orders = 0
self.canceled_trade_entries = 0
self.dataprovider.clear_cache() self.dataprovider.clear_cache()
if enable_protections: if enable_protections:
self._load_protections(self.strategy) self._load_protections(self.strategy)
@ -884,6 +885,7 @@ class Backtesting:
return True return True
elif self.check_order_replace(trade, order, current_time, row): elif self.check_order_replace(trade, order, current_time, row):
# delete trade due to user request # delete trade due to user request
self.canceled_trade_entries += 1
return True return True
# default maintain trade # default maintain trade
return False return False
@ -1087,6 +1089,7 @@ class Backtesting:
'rejected_signals': self.rejected_trades, 'rejected_signals': self.rejected_trades,
'timedout_entry_orders': self.timedout_entry_orders, 'timedout_entry_orders': self.timedout_entry_orders,
'timedout_exit_orders': self.timedout_exit_orders, 'timedout_exit_orders': self.timedout_exit_orders,
'canceled_trade_entries': self.canceled_trade_entries,
'final_balance': self.wallets.get_total(self.strategy.config['stake_currency']), 'final_balance': self.wallets.get_total(self.strategy.config['stake_currency']),
} }

View File

@ -468,6 +468,7 @@ def generate_strategy_stats(pairlist: List[str],
'rejected_signals': content['rejected_signals'], 'rejected_signals': content['rejected_signals'],
'timedout_entry_orders': content['timedout_entry_orders'], 'timedout_entry_orders': content['timedout_entry_orders'],
'timedout_exit_orders': content['timedout_exit_orders'], 'timedout_exit_orders': content['timedout_exit_orders'],
'canceled_trade_entries': content['canceled_trade_entries'],
'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),
@ -801,6 +802,7 @@ def text_table_add_metrics(strat_results: Dict) -> str:
('Entry/Exit Timeouts', ('Entry/Exit Timeouts',
f"{strat_results.get('timedout_entry_orders', 'N/A')} / " f"{strat_results.get('timedout_entry_orders', 'N/A')} / "
f"{strat_results.get('timedout_exit_orders', 'N/A')}"), f"{strat_results.get('timedout_exit_orders', 'N/A')}"),
('Canceled Trade Entries', strat_results.get('canceled_trade_entries', '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'],

View File

@ -1168,6 +1168,7 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog, testdatadir):
'rejected_signals': 20, 'rejected_signals': 20,
'timedout_entry_orders': 0, 'timedout_entry_orders': 0,
'timedout_exit_orders': 0, 'timedout_exit_orders': 0,
'canceled_trade_entries': 0,
'final_balance': 1000, 'final_balance': 1000,
}) })
mocker.patch('freqtrade.plugins.pairlistmanager.PairListManager.whitelist', mocker.patch('freqtrade.plugins.pairlistmanager.PairListManager.whitelist',
@ -1280,6 +1281,7 @@ def test_backtest_start_multi_strat_nomock(default_conf, mocker, caplog, testdat
'rejected_signals': 20, 'rejected_signals': 20,
'timedout_entry_orders': 0, 'timedout_entry_orders': 0,
'timedout_exit_orders': 0, 'timedout_exit_orders': 0,
'canceled_trade_entries': 0,
'final_balance': 1000, 'final_balance': 1000,
}, },
{ {
@ -1289,6 +1291,7 @@ def test_backtest_start_multi_strat_nomock(default_conf, mocker, caplog, testdat
'rejected_signals': 20, 'rejected_signals': 20,
'timedout_entry_orders': 0, 'timedout_entry_orders': 0,
'timedout_exit_orders': 0, 'timedout_exit_orders': 0,
'canceled_trade_entries': 0,
'final_balance': 1000, 'final_balance': 1000,
} }
]) ])
@ -1431,6 +1434,7 @@ def test_backtest_start_nomock_futures(default_conf_usdt, mocker,
'rejected_signals': 20, 'rejected_signals': 20,
'timedout_entry_orders': 0, 'timedout_entry_orders': 0,
'timedout_exit_orders': 0, 'timedout_exit_orders': 0,
'canceled_trade_entries': 0,
'final_balance': 1000, 'final_balance': 1000,
}, },
{ {
@ -1440,6 +1444,7 @@ def test_backtest_start_nomock_futures(default_conf_usdt, mocker,
'rejected_signals': 20, 'rejected_signals': 20,
'timedout_entry_orders': 0, 'timedout_entry_orders': 0,
'timedout_exit_orders': 0, 'timedout_exit_orders': 0,
'canceled_trade_entries': 0,
'final_balance': 1000, 'final_balance': 1000,
} }
]) ])
@ -1534,6 +1539,7 @@ def test_backtest_start_multi_strat_nomock_detail(default_conf, mocker,
'rejected_signals': 20, 'rejected_signals': 20,
'timedout_entry_orders': 0, 'timedout_entry_orders': 0,
'timedout_exit_orders': 0, 'timedout_exit_orders': 0,
'canceled_trade_entries': 0,
'final_balance': 1000, 'final_balance': 1000,
}, },
{ {
@ -1543,6 +1549,7 @@ def test_backtest_start_multi_strat_nomock_detail(default_conf, mocker,
'rejected_signals': 20, 'rejected_signals': 20,
'timedout_entry_orders': 0, 'timedout_entry_orders': 0,
'timedout_exit_orders': 0, 'timedout_exit_orders': 0,
'canceled_trade_entries': 0,
'final_balance': 1000, 'final_balance': 1000,
} }
]) ])
@ -1606,6 +1613,7 @@ def test_backtest_start_multi_strat_caching(default_conf, mocker, caplog, testda
'rejected_signals': 20, 'rejected_signals': 20,
'timedout_entry_orders': 0, 'timedout_entry_orders': 0,
'timedout_exit_orders': 0, 'timedout_exit_orders': 0,
'canceled_trade_entries': 0,
'final_balance': 1000, 'final_balance': 1000,
}) })
mocker.patch('freqtrade.plugins.pairlistmanager.PairListManager.whitelist', mocker.patch('freqtrade.plugins.pairlistmanager.PairListManager.whitelist',

View File

@ -368,6 +368,7 @@ def test_hyperopt_format_results(hyperopt):
'rejected_signals': 2, 'rejected_signals': 2,
'timedout_entry_orders': 0, 'timedout_entry_orders': 0,
'timedout_exit_orders': 0, 'timedout_exit_orders': 0,
'canceled_trade_entries': 0,
'backtest_start_time': 1619718665, 'backtest_start_time': 1619718665,
'backtest_end_time': 1619718665, 'backtest_end_time': 1619718665,
} }
@ -438,6 +439,7 @@ def test_generate_optimizer(mocker, hyperopt_conf) -> None:
'rejected_signals': 20, 'rejected_signals': 20,
'timedout_entry_orders': 0, 'timedout_entry_orders': 0,
'timedout_exit_orders': 0, 'timedout_exit_orders': 0,
'canceled_trade_entries': 0,
'final_balance': 1000, 'final_balance': 1000,
} }

View File

@ -87,6 +87,7 @@ def test_generate_backtest_stats(default_conf, testdatadir, tmpdir):
'rejected_signals': 20, 'rejected_signals': 20,
'timedout_entry_orders': 0, 'timedout_entry_orders': 0,
'timedout_exit_orders': 0, 'timedout_exit_orders': 0,
'canceled_trade_entries': 0,
'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,
'run_id': '123', 'run_id': '123',
@ -139,6 +140,7 @@ def test_generate_backtest_stats(default_conf, testdatadir, tmpdir):
'rejected_signals': 20, 'rejected_signals': 20,
'timedout_entry_orders': 0, 'timedout_entry_orders': 0,
'timedout_exit_orders': 0, 'timedout_exit_orders': 0,
'canceled_trade_entries': 0,
'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,
'run_id': '124', 'run_id': '124',