Add short/long metrics to backtest result
This commit is contained in:
parent
0a50017c84
commit
5a8824171c
@ -371,42 +371,48 @@ The last element of the backtest report is the summary metrics table.
|
|||||||
It contains some useful key metrics about performance of your strategy on backtesting data.
|
It contains some useful key metrics about performance of your strategy on backtesting data.
|
||||||
|
|
||||||
```
|
```
|
||||||
=============== SUMMARY METRICS ===============
|
================ SUMMARY METRICS ===============
|
||||||
| Metric | Value |
|
| Metric | Value |
|
||||||
|-----------------------+---------------------|
|
|------------------------+---------------------|
|
||||||
| Backtesting from | 2019-01-01 00:00:00 |
|
| Backtesting from | 2019-01-01 00:00:00 |
|
||||||
| Backtesting to | 2019-05-01 00:00:00 |
|
| Backtesting to | 2019-05-01 00:00:00 |
|
||||||
| Max open trades | 3 |
|
| Max open trades | 3 |
|
||||||
| | |
|
| | |
|
||||||
| Total/Daily Avg Trades| 429 / 3.575 |
|
| Total/Daily Avg Trades | 429 / 3.575 |
|
||||||
| Starting balance | 0.01000000 BTC |
|
| Starting balance | 0.01000000 BTC |
|
||||||
| Final balance | 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% |
|
||||||
| Avg. stake amount | 0.001 BTC |
|
| Avg. stake amount | 0.001 BTC |
|
||||||
| Total trade volume | 0.429 BTC |
|
| Total trade volume | 0.429 BTC |
|
||||||
| | |
|
| | |
|
||||||
| Best Pair | LSK/BTC 26.26% |
|
| Long / Short | 352 / 77 |
|
||||||
| Worst Pair | ZEC/BTC -10.18% |
|
| Total profit Long % | 1250.58% |
|
||||||
| Best Trade | LSK/BTC 4.25% |
|
| Total profit Short % | -15.02% |
|
||||||
| Worst Trade | ZEC/BTC -10.25% |
|
| Absolute profit Long | 0.00838792 BTC |
|
||||||
| Best day | 0.00076 BTC |
|
| Absolute profit Short | -0.00076 BTC |
|
||||||
| Worst day | -0.00036 BTC |
|
| | |
|
||||||
| Days win/draw/lose | 12 / 82 / 25 |
|
| Best Pair | LSK/BTC 26.26% |
|
||||||
| Avg. Duration Winners | 4:23:00 |
|
| Worst Pair | ZEC/BTC -10.18% |
|
||||||
| Avg. Duration Loser | 6:55:00 |
|
| Best Trade | LSK/BTC 4.25% |
|
||||||
| Rejected Buy signals | 3089 |
|
| Worst Trade | ZEC/BTC -10.25% |
|
||||||
| | |
|
| Best day | 0.00076 BTC |
|
||||||
| Min balance | 0.00945123 BTC |
|
| Worst day | -0.00036 BTC |
|
||||||
| Max balance | 0.01846651 BTC |
|
| Days win/draw/lose | 12 / 82 / 25 |
|
||||||
| Drawdown | 50.63% |
|
| Avg. Duration Winners | 4:23:00 |
|
||||||
| Drawdown | 0.0015 BTC |
|
| Avg. Duration Loser | 6:55:00 |
|
||||||
| Drawdown high | 0.0013 BTC |
|
| Rejected Buy signals | 3089 |
|
||||||
| Drawdown low | -0.0002 BTC |
|
| | |
|
||||||
| Drawdown Start | 2019-02-15 14:10:00 |
|
| Min balance | 0.00945123 BTC |
|
||||||
| Drawdown End | 2019-04-11 18:15:00 |
|
| Max balance | 0.01846651 BTC |
|
||||||
| Market change | -5.88% |
|
| 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 End | 2019-04-11 18:15:00 |
|
||||||
|
| Market change | -5.88% |
|
||||||
|
================================================
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -430,6 +436,9 @@ It contains some useful key metrics about performance of your strategy on backte
|
|||||||
- `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.
|
||||||
- `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.
|
||||||
|
- `Long / Short`: Split long/short values (Only shown when short trades were made).
|
||||||
|
- `Total profit Long %` / `Absolute profit Long`: Profit long trades only (Only shown when short trades were made).
|
||||||
|
- `Total profit Short %` / `Absolute profit Short`: Profit short trades only (Only shown when short trades were made).
|
||||||
|
|
||||||
### Daily / Weekly / Monthly breakdown
|
### Daily / Weekly / Monthly breakdown
|
||||||
|
|
||||||
|
@ -415,20 +415,20 @@ def generate_strategy_stats(btdata: Dict[str, DataFrame],
|
|||||||
return {}
|
return {}
|
||||||
config = content['config']
|
config = content['config']
|
||||||
max_open_trades = min(config['max_open_trades'], len(btdata.keys()))
|
max_open_trades = min(config['max_open_trades'], len(btdata.keys()))
|
||||||
starting_balance = config['dry_run_wallet']
|
start_balance = config['dry_run_wallet']
|
||||||
stake_currency = config['stake_currency']
|
stake_currency = config['stake_currency']
|
||||||
|
|
||||||
pair_results = generate_pair_metrics(btdata, stake_currency=stake_currency,
|
pair_results = generate_pair_metrics(btdata, stake_currency=stake_currency,
|
||||||
starting_balance=starting_balance,
|
starting_balance=start_balance,
|
||||||
results=results, skip_nan=False)
|
results=results, skip_nan=False)
|
||||||
|
|
||||||
buy_tag_results = generate_tag_metrics("buy_tag", starting_balance=starting_balance,
|
buy_tag_results = generate_tag_metrics("buy_tag", starting_balance=start_balance,
|
||||||
results=results, skip_nan=False)
|
results=results, skip_nan=False)
|
||||||
|
|
||||||
sell_reason_stats = generate_sell_reason_stats(max_open_trades=max_open_trades,
|
sell_reason_stats = generate_sell_reason_stats(max_open_trades=max_open_trades,
|
||||||
results=results)
|
results=results)
|
||||||
left_open_results = generate_pair_metrics(btdata, stake_currency=stake_currency,
|
left_open_results = generate_pair_metrics(btdata, stake_currency=stake_currency,
|
||||||
starting_balance=starting_balance,
|
starting_balance=start_balance,
|
||||||
results=results.loc[results['is_open']],
|
results=results.loc[results['is_open']],
|
||||||
skip_nan=True)
|
skip_nan=True)
|
||||||
daily_stats = generate_daily_stats(results)
|
daily_stats = generate_daily_stats(results)
|
||||||
@ -460,8 +460,12 @@ def generate_strategy_stats(btdata: Dict[str, DataFrame],
|
|||||||
'avg_stake_amount': results['stake_amount'].mean() if len(results) > 0 else 0,
|
'avg_stake_amount': results['stake_amount'].mean() if len(results) > 0 else 0,
|
||||||
'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_median': results['profit_ratio'].median() if len(results) > 0 else 0,
|
'profit_median': results['profit_ratio'].median() if len(results) > 0 else 0,
|
||||||
'profit_total': results['profit_abs'].sum() / starting_balance,
|
'profit_total': results['profit_abs'].sum() / start_balance,
|
||||||
|
'profit_total_long': results.loc[~results['is_short'], 'profit_abs'].sum() / start_balance,
|
||||||
|
'profit_total_short': results.loc[results['is_short'], 'profit_abs'].sum() / start_balance,
|
||||||
'profit_total_abs': results['profit_abs'].sum(),
|
'profit_total_abs': results['profit_abs'].sum(),
|
||||||
|
'profit_total_long_abs': results.loc[~results['is_short'], 'profit_abs'].sum(),
|
||||||
|
'profit_total_short_abs': results.loc[results['is_short'], 'profit_abs'].sum(),
|
||||||
'backtest_start': min_date.strftime(DATETIME_PRINT_FORMAT),
|
'backtest_start': min_date.strftime(DATETIME_PRINT_FORMAT),
|
||||||
'backtest_start_ts': int(min_date.timestamp() * 1000),
|
'backtest_start_ts': int(min_date.timestamp() * 1000),
|
||||||
'backtest_end': max_date.strftime(DATETIME_PRINT_FORMAT),
|
'backtest_end': max_date.strftime(DATETIME_PRINT_FORMAT),
|
||||||
@ -477,8 +481,8 @@ def generate_strategy_stats(btdata: Dict[str, DataFrame],
|
|||||||
'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']),
|
'stake_currency_decimals': decimals_per_coin(config['stake_currency']),
|
||||||
'starting_balance': starting_balance,
|
'starting_balance': start_balance,
|
||||||
'dry_run_wallet': starting_balance,
|
'dry_run_wallet': start_balance,
|
||||||
'final_balance': content['final_balance'],
|
'final_balance': content['final_balance'],
|
||||||
'rejected_signals': content['rejected_signals'],
|
'rejected_signals': content['rejected_signals'],
|
||||||
'max_open_trades': max_open_trades,
|
'max_open_trades': max_open_trades,
|
||||||
@ -522,7 +526,7 @@ def generate_strategy_stats(btdata: Dict[str, DataFrame],
|
|||||||
'max_drawdown_high': high_val,
|
'max_drawdown_high': high_val,
|
||||||
})
|
})
|
||||||
|
|
||||||
csum_min, csum_max = calculate_csum(results, starting_balance)
|
csum_min, csum_max = calculate_csum(results, start_balance)
|
||||||
strat_stats.update({
|
strat_stats.update({
|
||||||
'csum_min': csum_min,
|
'csum_min': csum_min,
|
||||||
'csum_max': csum_max
|
'csum_max': csum_max
|
||||||
@ -711,6 +715,19 @@ def text_table_add_metrics(strat_results: Dict) -> str:
|
|||||||
best_trade = max(strat_results['trades'], key=lambda x: x['profit_ratio'])
|
best_trade = max(strat_results['trades'], key=lambda x: x['profit_ratio'])
|
||||||
worst_trade = min(strat_results['trades'], key=lambda x: x['profit_ratio'])
|
worst_trade = min(strat_results['trades'], key=lambda x: x['profit_ratio'])
|
||||||
|
|
||||||
|
short_metrics = [
|
||||||
|
('', ''), # Empty line to improve readability
|
||||||
|
('Long / Short',
|
||||||
|
f"{strat_results.get('trade_count_long', 'total_trades')} / "
|
||||||
|
f"{strat_results.get('trade_count_short', 0)}"),
|
||||||
|
('Total profit Long %', f"{strat_results['profit_total_long']:.2%}"),
|
||||||
|
('Total profit Short %', f"{strat_results['profit_total_short']:.2%}"),
|
||||||
|
('Absolute profit Long', round_coin_value(strat_results['profit_total_long_abs'],
|
||||||
|
strat_results['stake_currency'])),
|
||||||
|
('Absolute profit Short', round_coin_value(strat_results['profit_total_short_abs'],
|
||||||
|
strat_results['stake_currency'])),
|
||||||
|
] if strat_results.get('trade_count_short', 0) > 0 else []
|
||||||
|
|
||||||
# Newly added fields should be ignored if they are missing in strat_results. hyperopt-show
|
# Newly added fields should be ignored if they are missing in strat_results. hyperopt-show
|
||||||
# command stores these results and newer version of freqtrade must be able to handle old
|
# command stores these results and newer version of freqtrade must be able to handle old
|
||||||
# results with missing new fields.
|
# results with missing new fields.
|
||||||
@ -721,9 +738,7 @@ def text_table_add_metrics(strat_results: Dict) -> str:
|
|||||||
('', ''), # Empty line to improve readability
|
('', ''), # Empty line to improve readability
|
||||||
('Total/Daily Avg Trades',
|
('Total/Daily Avg Trades',
|
||||||
f"{strat_results['total_trades']} / {strat_results['trades_per_day']}"),
|
f"{strat_results['total_trades']} / {strat_results['trades_per_day']}"),
|
||||||
('Long / Short',
|
|
||||||
f"{strat_results.get('trade_count_long', 'total_trades')} / "
|
|
||||||
f"{strat_results.get('trade_count_short', 0)}"),
|
|
||||||
('Starting balance', round_coin_value(strat_results['starting_balance'],
|
('Starting balance', round_coin_value(strat_results['starting_balance'],
|
||||||
strat_results['stake_currency'])),
|
strat_results['stake_currency'])),
|
||||||
('Final balance', round_coin_value(strat_results['final_balance'],
|
('Final balance', round_coin_value(strat_results['final_balance'],
|
||||||
@ -738,6 +753,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'])),
|
||||||
|
*short_metrics,
|
||||||
('', ''), # 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"{strat_results['best_pair']['profit_sum']:.2%}"),
|
f"{strat_results['best_pair']['profit_sum']:.2%}"),
|
||||||
|
Loading…
Reference in New Issue
Block a user