Add short/long metrics to backtest result
This commit is contained in:
parent
0a50017c84
commit
5a8824171c
@ -371,9 +371,9 @@ 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.
|
||||
|
||||
```
|
||||
=============== SUMMARY METRICS ===============
|
||||
================ SUMMARY METRICS ===============
|
||||
| Metric | Value |
|
||||
|-----------------------+---------------------|
|
||||
|------------------------+---------------------|
|
||||
| Backtesting from | 2019-01-01 00:00:00 |
|
||||
| Backtesting to | 2019-05-01 00:00:00 |
|
||||
| Max open trades | 3 |
|
||||
@ -386,6 +386,12 @@ It contains some useful key metrics about performance of your strategy on backte
|
||||
| Avg. stake amount | 0.001 BTC |
|
||||
| Total trade volume | 0.429 BTC |
|
||||
| | |
|
||||
| Long / Short | 352 / 77 |
|
||||
| Total profit Long % | 1250.58% |
|
||||
| Total profit Short % | -15.02% |
|
||||
| Absolute profit Long | 0.00838792 BTC |
|
||||
| Absolute profit Short | -0.00076 BTC |
|
||||
| | |
|
||||
| Best Pair | LSK/BTC 26.26% |
|
||||
| Worst Pair | ZEC/BTC -10.18% |
|
||||
| Best Trade | LSK/BTC 4.25% |
|
||||
@ -406,7 +412,7 @@ It contains some useful key metrics about performance of your strategy on backte
|
||||
| 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 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.
|
||||
- `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
|
||||
|
||||
|
@ -415,20 +415,20 @@ def generate_strategy_stats(btdata: Dict[str, DataFrame],
|
||||
return {}
|
||||
config = content['config']
|
||||
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']
|
||||
|
||||
pair_results = generate_pair_metrics(btdata, stake_currency=stake_currency,
|
||||
starting_balance=starting_balance,
|
||||
starting_balance=start_balance,
|
||||
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)
|
||||
|
||||
sell_reason_stats = generate_sell_reason_stats(max_open_trades=max_open_trades,
|
||||
results=results)
|
||||
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']],
|
||||
skip_nan=True)
|
||||
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,
|
||||
'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_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_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_ts': int(min_date.timestamp() * 1000),
|
||||
'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_currency': config['stake_currency'],
|
||||
'stake_currency_decimals': decimals_per_coin(config['stake_currency']),
|
||||
'starting_balance': starting_balance,
|
||||
'dry_run_wallet': starting_balance,
|
||||
'starting_balance': start_balance,
|
||||
'dry_run_wallet': start_balance,
|
||||
'final_balance': content['final_balance'],
|
||||
'rejected_signals': content['rejected_signals'],
|
||||
'max_open_trades': max_open_trades,
|
||||
@ -522,7 +526,7 @@ def generate_strategy_stats(btdata: Dict[str, DataFrame],
|
||||
'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({
|
||||
'csum_min': csum_min,
|
||||
'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'])
|
||||
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
|
||||
# command stores these results and newer version of freqtrade must be able to handle old
|
||||
# results with missing new fields.
|
||||
@ -721,9 +738,7 @@ def text_table_add_metrics(strat_results: Dict) -> str:
|
||||
('', ''), # Empty line to improve readability
|
||||
('Total/Daily Avg Trades',
|
||||
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'],
|
||||
strat_results['stake_currency'])),
|
||||
('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'])),
|
||||
('Total trade volume', round_coin_value(strat_results['total_volume'],
|
||||
strat_results['stake_currency'])),
|
||||
*short_metrics,
|
||||
('', ''), # Empty line to improve readability
|
||||
('Best Pair', f"{strat_results['best_pair']['key']} "
|
||||
f"{strat_results['best_pair']['profit_sum']:.2%}"),
|
||||
|
Loading…
Reference in New Issue
Block a user