Improve backtesting metrics

This commit is contained in:
Matthias 2021-02-17 20:19:03 +01:00
parent 7913166453
commit f04f07299c
2 changed files with 47 additions and 28 deletions

View File

@ -252,11 +252,12 @@ A backtesting result will look like that:
| Max open trades | 3 | | Max open trades | 3 |
| | | | | |
| Total trades | 429 | | Total trades | 429 |
| Starting capital | 0.01000000 BTC | | Starting balance | 0.01000000 BTC |
| End capital | 0.01762792 BTC | | Final balance | 0.01762792 BTC |
| Absolute profit | 0.00762792 BTC | | Absolute profit | 0.00762792 BTC |
| Total Profit % | 76.2% | | Total profit % | 76.2% |
| Trades per day | 3.575 | | Trades per day | 3.575 |
| Avg. stake amount | 0.001 |
| Total trade volume | 0.429 BTC | | Total trade volume | 0.429 BTC |
| | | | | |
| Best Pair | LSK/BTC 26.26% | | Best Pair | LSK/BTC 26.26% |
@ -269,7 +270,12 @@ 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 |
| | | | | |
| Max Drawdown | 50.63% | | Min balance | 0.00945123 BTC |
| Max balance | 0.01846651 BTC |
| Drawdown | 50.63% |
| Drawdown | 0.0015 BTC |
| Drawdown high | 0.0013 BTC |
| Drawdown low | -0.0002 BTC |
| Drawdown Start | 2019-02-15 14:10:00 | | Drawdown Start | 2019-02-15 14:10:00 |
| Drawdown End | 2019-04-11 18:15:00 | | Drawdown End | 2019-04-11 18:15:00 |
| Market change | -5.88% | | Market change | -5.88% |
@ -333,11 +339,12 @@ It contains some useful key metrics about performance of your strategy on backte
| Max open trades | 3 | | Max open trades | 3 |
| | | | | |
| Total trades | 429 | | Total trades | 429 |
| Starting capital | 0.01000000 BTC | | Starting balance | 0.01000000 BTC |
| End capital | 0.01762792 BTC | | Final balance | 0.01762792 BTC |
| Absolute profit | 0.00762792 BTC | | Absolute profit | 0.00762792 BTC |
| Total Profit % | 76.2% | | Total profit % | 76.2% |
| Trades per day | 3.575 | | Trades per day | 3.575 |
| Avg. stake amount | 0.001 |
| Total trade volume | 0.429 BTC | | Total trade volume | 0.429 BTC |
| | | | | |
| Best Pair | LSK/BTC 26.26% | | Best Pair | LSK/BTC 26.26% |
@ -350,7 +357,12 @@ 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 |
| | | | | |
| Max Drawdown | 50.63% | | Min balance | 0.00945123 BTC |
| Max balance | 0.01846651 BTC |
| Drawdown | 50.63% |
| Drawdown | 0.0015 BTC |
| Drawdown high | 0.0013 BTC |
| Drawdown low | -0.0002 BTC |
| Drawdown Start | 2019-02-15 14:10:00 | | Drawdown Start | 2019-02-15 14:10:00 |
| Drawdown End | 2019-04-11 18:15:00 | | Drawdown End | 2019-04-11 18:15:00 |
| Market change | -5.88% | | Market change | -5.88% |
@ -361,18 +373,21 @@ It contains some useful key metrics about performance of your strategy on backte
- `Backtesting from` / `Backtesting to`: Backtesting range (usually defined with the `--timerange` option). - `Backtesting from` / `Backtesting to`: Backtesting range (usually defined with the `--timerange` option).
- `Max open trades`: Setting of `max_open_trades` (or `--max-open-trades`) - or number of pairs in the pairlist (whatever is lower). - `Max open trades`: Setting of `max_open_trades` (or `--max-open-trades`) - or number of pairs in the pairlist (whatever is lower).
- `Total trades`: Identical to the total trades of the backtest output table. - `Total trades`: Identical to the total trades of the backtest output table.
- `Starting capital`: Start capital - as given by dry-run-wallet (config or command line). - `Starting balance`: Start balance - as given by dry-run-wallet (config or command line).
- `End capital`: Final capital - starting capital + absolute profit. - `End balance`: Final balance - starting balance + absolute profit.
- `Absolute profit`: Profit made in stake currency. - `Absolute profit`: Profit made in stake currency.
- `Total Profit %`: Total profit. Aligned to the `TOTAL` row's `Tot Profit %` from the first table. Calculated as `(End capital Starting capital) / Starting capital`. - `Total profit %`: Total profit. Aligned to the `TOTAL` row's `Tot Profit %` from the first table. Calculated as `(End capital Starting capital) / Starting capital`.
- `Trades per day`: Total trades divided by the backtesting duration in days (this will give you information about how many trades to expect from the strategy). - `Trades per day`: Total trades divided by the backtesting duration in days (this will give you information about how many trades to expect from the strategy).
- `Avg. stake amount`: Average stake amount, either `stake_amount` or the average when using dynamic stake amount.
- `Total trade volume`: Volume generated on the exchange to reach the above profit. - `Total trade volume`: Volume generated on the exchange to reach the above profit.
- `Best Pair` / `Worst Pair`: Best and worst performing pair, and it's corresponding `Cum Profit %`. - `Best Pair` / `Worst Pair`: Best and worst performing pair, and it's corresponding `Cum Profit %`.
- `Best Trade` / `Worst Trade`: Biggest winning trade and biggest losing trade - `Best Trade` / `Worst Trade`: Biggest winning trade and biggest losing trade
- `Best day` / `Worst day`: Best and worst day based on daily profit. - `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). - `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.
- `Max Drawdown`: Maximum drawdown experienced. For example, the value of 50% means that from highest to subsequent lowest point, a 50% drop was experienced). - `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.
- `Drawdown Start` / `Drawdown End`: Start and end datetime for this largest drawdown (can also be visualized via the `plot-dataframe` sub-command). - `Drawdown Start` / `Drawdown End`: Start and end datetime for this largest drawdown (can also be visualized via the `plot-dataframe` sub-command).
- `Market change`: Change of the market during the backtest period. Calculated as average of all pairs changes from the first to the last candle using the "close" column. - `Market change`: Change of the market during the backtest period. Calculated as average of all pairs changes from the first to the last candle using the "close" column.

View File

@ -278,6 +278,7 @@ def generate_backtest_stats(btdata: Dict[str, DataFrame],
'left_open_trades': left_open_results, 'left_open_trades': left_open_results,
'total_trades': len(results), 'total_trades': len(results),
'total_volume': results['stake_amount'].sum(), 'total_volume': results['stake_amount'].sum(),
'avg_stake_amount': results['stake_amount'].mean(),
'profit_mean': results['profit_ratio'].mean() if len(results) > 0 else 0, 'profit_mean': results['profit_ratio'].mean() if len(results) > 0 else 0,
'profit_total': results['profit_abs'].sum() / starting_balance, 'profit_total': results['profit_abs'].sum() / starting_balance,
'profit_total_abs': results['profit_abs'].sum(), 'profit_total_abs': results['profit_abs'].sum(),
@ -295,6 +296,7 @@ def generate_backtest_stats(btdata: Dict[str, DataFrame],
'pairlist': list(btdata.keys()), 'pairlist': list(btdata.keys()),
'stake_amount': config['stake_amount'], 'stake_amount': config['stake_amount'],
'stake_currency': config['stake_currency'], 'stake_currency': config['stake_currency'],
'stake_currency_decimals': decimals_per_coin(config['stake_currency']),
'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'],
@ -334,8 +336,8 @@ def generate_backtest_stats(btdata: Dict[str, DataFrame],
'drawdown_end': drawdown_end, 'drawdown_end': drawdown_end,
'drawdown_end_ts': drawdown_end.timestamp() * 1000, 'drawdown_end_ts': drawdown_end.timestamp() * 1000,
'max_drawdown_low': low_val + starting_balance, 'max_drawdown_low': low_val,
'max_drawdown_high': high_val + starting_balance, 'max_drawdown_high': high_val,
}) })
csum_min, csum_max = calculate_csum(results, starting_balance) csum_min, csum_max = calculate_csum(results, starting_balance)
@ -446,14 +448,16 @@ def text_table_add_metrics(strat_results: Dict) -> str:
('Max open trades', strat_results['max_open_trades']), ('Max open trades', strat_results['max_open_trades']),
('', ''), # Empty line to improve readability ('', ''), # Empty line to improve readability
('Total trades', strat_results['total_trades']), ('Total trades', strat_results['total_trades']),
('Starting capital', round_coin_value(strat_results['starting_balance'], ('Starting balance', round_coin_value(strat_results['starting_balance'],
strat_results['stake_currency'])), strat_results['stake_currency'])),
('End capital', round_coin_value(strat_results['final_balance'], ('Final balance', round_coin_value(strat_results['final_balance'],
strat_results['stake_currency'])), strat_results['stake_currency'])),
('Absolute profit ', round_coin_value(strat_results['profit_total_abs'], ('Absolute profit ', round_coin_value(strat_results['profit_total_abs'],
strat_results['stake_currency'])), 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']), ('Trades per day', strat_results['trades_per_day']),
('Avg. stake amount', round_coin_value(strat_results['avg_stake_amount'],
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'])),
@ -474,18 +478,18 @@ def text_table_add_metrics(strat_results: Dict) -> str:
('Avg. Duration Loser', f"{strat_results['loser_holding_avg']}"), ('Avg. Duration Loser', f"{strat_results['loser_holding_avg']}"),
('', ''), # Empty line to improve readability ('', ''), # Empty line to improve readability
('Abs Profit Min', round_coin_value(strat_results['csum_min'], ('Min balance', round_coin_value(strat_results['csum_min'],
strat_results['stake_currency'])), strat_results['stake_currency'])),
('Abs Profit Max', round_coin_value(strat_results['csum_max'], ('Max balance', round_coin_value(strat_results['csum_max'],
strat_results['stake_currency'])), strat_results['stake_currency'])),
('Max Drawdown', f"{round(strat_results['max_drawdown'] * 100, 2)}%"), ('Drawdown', f"{round(strat_results['max_drawdown'] * 100, 2)}%"),
('Max Drawdown', round_coin_value(strat_results['max_drawdown_abs'], ('Drawdown', round_coin_value(strat_results['max_drawdown_abs'],
strat_results['stake_currency'])),
('Drawdown high', round_coin_value(strat_results['max_drawdown_high'],
strat_results['stake_currency'])),
('Drawdown low', round_coin_value(strat_results['max_drawdown_low'],
strat_results['stake_currency'])), strat_results['stake_currency'])),
('Max Drawdown high', round_coin_value(strat_results['max_drawdown_high'],
strat_results['stake_currency'])),
('Max Drawdown low', round_coin_value(strat_results['max_drawdown_low'],
strat_results['stake_currency'])),
('Drawdown Start', strat_results['drawdown_start'].strftime(DATETIME_PRINT_FORMAT)), ('Drawdown Start', strat_results['drawdown_start'].strftime(DATETIME_PRINT_FORMAT)),
('Drawdown End', strat_results['drawdown_end'].strftime(DATETIME_PRINT_FORMAT)), ('Drawdown End', strat_results['drawdown_end'].strftime(DATETIME_PRINT_FORMAT)),
('Market change', f"{round(strat_results['market_change'] * 100, 2)}%"), ('Market change', f"{round(strat_results['market_change'] * 100, 2)}%"),