Include zero duration trades in backtesting report.

This commit is contained in:
Rokas Kupstys 2021-05-15 11:26:22 +03:00
parent d19b37c777
commit edcfa94093
2 changed files with 9 additions and 1 deletions

View File

@ -413,6 +413,7 @@ It contains some useful key metrics about performance of your strategy on backte
- `Best day` / `Worst day`: Best and worst day based on daily profit.
- `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.
- `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.
- `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 high` / `Drawdown low`: Profit at the beginning and end of the largest drawdown period. A negative low value means initial capital lost.

View File

@ -208,6 +208,8 @@ def generate_trading_stats(results: DataFrame) -> Dict[str, Any]:
winning_trades = results.loc[results['profit_ratio'] > 0]
draw_trades = results.loc[results['profit_ratio'] == 0]
losing_trades = results.loc[results['profit_ratio'] < 0]
zero_duration_trades = len(results.loc[(results['trade_duration'] == 0) &
(results['sell_reason'] == 'trailing_stop_loss')])
return {
'wins': len(winning_trades),
@ -219,6 +221,7 @@ def generate_trading_stats(results: DataFrame) -> Dict[str, Any]:
if not winning_trades.empty else timedelta()),
'loser_holding_avg': (timedelta(minutes=round(losing_trades['trade_duration'].mean()))
if not losing_trades.empty else timedelta()),
'zero_duration_trades': zero_duration_trades,
}
@ -496,6 +499,8 @@ def text_table_add_metrics(strat_results: Dict) -> str:
if len(strat_results['trades']) > 0:
best_trade = max(strat_results['trades'], key=lambda x: x['profit_ratio'])
worst_trade = min(strat_results['trades'], key=lambda x: x['profit_ratio'])
zero_duration_trades_percent =\
100.0 / strat_results['total_trades'] * strat_results['zero_duration_trades']
metrics = [
('Backtesting from', strat_results['backtest_start']),
('Backtesting to', strat_results['backtest_end']),
@ -508,7 +513,7 @@ def text_table_add_metrics(strat_results: Dict) -> str:
strat_results['stake_currency'])),
('Absolute profit ', round_coin_value(strat_results['profit_total_abs'],
strat_results['stake_currency'])),
('Total profit %', f"{round(strat_results['profit_total'] * 100, 2)}%"),
('Total profit %', f"{round(strat_results['profit_total'] * 100, 2):}%"),
('Trades per day', strat_results['trades_per_day']),
('Avg. stake amount', round_coin_value(strat_results['avg_stake_amount'],
strat_results['stake_currency'])),
@ -532,6 +537,8 @@ def text_table_add_metrics(strat_results: Dict) -> str:
f"{strat_results['draw_days']} / {strat_results['losing_days']}"),
('Avg. Duration Winners', f"{strat_results['winner_holding_avg']}"),
('Avg. Duration Loser', f"{strat_results['loser_holding_avg']}"),
('Zero Duration Trades', f"{zero_duration_trades_percent:.1f}% "
f"({strat_results['zero_duration_trades']})"),
('', ''), # Empty line to improve readability
('Min balance', round_coin_value(strat_results['csum_min'],