Plots and hyperopt

This commit is contained in:
Nicolas Papp 2022-04-11 16:41:48 -03:00
parent 178240aa6c
commit c8e4687833
3 changed files with 34 additions and 14 deletions

View File

@ -445,6 +445,9 @@ def _calc_drawdown_series(profit_results: pd.DataFrame, *, date_col: str, value_
cumulative_balance = starting_balance + max_drawdown_df['cumulative'] cumulative_balance = starting_balance + max_drawdown_df['cumulative']
max_balance = starting_balance + max_drawdown_df['high_value'] max_balance = starting_balance + max_drawdown_df['high_value']
max_drawdown_df['drawdown_relative'] = ((max_balance - cumulative_balance) / max_balance) max_drawdown_df['drawdown_relative'] = ((max_balance - cumulative_balance) / max_balance)
else:
# This is not completely accurate,
max_drawdown_df['drawdown_relative'] = ((max_drawdown_df['high_value'] - max_drawdown_df['cumulative']) / max_drawdown_df['high_value'])
return max_drawdown_df return max_drawdown_df

View File

@ -1,6 +1,7 @@
import logging import logging
from pathlib import Path from pathlib import Path
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional
from numpy import number
import pandas as pd import pandas as pd
@ -158,12 +159,12 @@ def add_profit(fig, row, data: pd.DataFrame, column: str, name: str) -> make_sub
def add_max_drawdown(fig, row, trades: pd.DataFrame, df_comb: pd.DataFrame, def add_max_drawdown(fig, row, trades: pd.DataFrame, df_comb: pd.DataFrame,
timeframe: str) -> make_subplots: timeframe: str, starting_balance: number) -> make_subplots:
""" """
Add scatter points indicating max drawdown Add scatter points indicating max drawdown
""" """
try: try:
_, highdate, lowdate, _, _, max_drawdown = calculate_max_drawdown(trades) _, highdate, lowdate, _, _, max_drawdown = calculate_max_drawdown(trades, starting_balance=starting_balance)
drawdown = go.Scatter( drawdown = go.Scatter(
x=[highdate, lowdate], x=[highdate, lowdate],
@ -188,22 +189,33 @@ def add_max_drawdown(fig, row, trades: pd.DataFrame, df_comb: pd.DataFrame,
return fig return fig
def add_underwater(fig, row, trades: pd.DataFrame) -> make_subplots: def add_underwater(fig, row, trades: pd.DataFrame, starting_balance: number) -> make_subplots:
""" """
Add underwater plot Add underwater plots
""" """
try: try:
underwater = calculate_underwater(trades, value_col="profit_abs") underwater = calculate_underwater(trades, value_col="profit_abs", starting_balance=starting_balance)
underwater = go.Scatter( underwater_plot = go.Scatter(
x=underwater['date'], x=underwater['date'],
y=underwater['drawdown'], y=underwater['drawdown'],
name="Underwater Plot", name="Underwater Plot",
fill='tozeroy', fill='tozeroy',
fillcolor='#cc362b', fillcolor='#cc362b',
line={'color': '#cc362b'}, line={'color': '#cc362b'}
) )
fig.add_trace(underwater, row, 1)
underwater_plot_relative = go.Scatter(
x=underwater['date'],
y=(-underwater['drawdown_relative']),
name="Underwater Plot (%)",
fill='tozeroy',
fillcolor='green',
line={'color': 'green'}
)
fig.add_trace(underwater_plot, row, 1)
fig.add_trace(underwater_plot_relative, row+1, 1)
except ValueError: except ValueError:
logger.warning("No trades found - not plotting underwater plot") logger.warning("No trades found - not plotting underwater plot")
return fig return fig
@ -506,7 +518,8 @@ def generate_candlestick_graph(pair: str, data: pd.DataFrame, trades: pd.DataFra
def generate_profit_graph(pairs: str, data: Dict[str, pd.DataFrame], def generate_profit_graph(pairs: str, data: Dict[str, pd.DataFrame],
trades: pd.DataFrame, timeframe: str, stake_currency: str) -> go.Figure: trades: pd.DataFrame, timeframe: str, stake_currency: str,
starting_balance: number) -> go.Figure:
# Combine close-values for all pairs, rename columns to "pair" # Combine close-values for all pairs, rename columns to "pair"
try: try:
df_comb = combine_dataframes_with_mean(data, "close") df_comb = combine_dataframes_with_mean(data, "close")
@ -530,8 +543,8 @@ def generate_profit_graph(pairs: str, data: Dict[str, pd.DataFrame],
name='Avg close price', name='Avg close price',
) )
fig = make_subplots(rows=5, cols=1, shared_xaxes=True, fig = make_subplots(rows=6, cols=1, shared_xaxes=True,
row_heights=[1, 1, 1, 0.5, 1], row_heights=[1, 1, 1, 0.5, 0.75, 0.75],
vertical_spacing=0.05, vertical_spacing=0.05,
subplot_titles=[ subplot_titles=[
"AVG Close Price", "AVG Close Price",
@ -539,6 +552,7 @@ def generate_profit_graph(pairs: str, data: Dict[str, pd.DataFrame],
"Profit per pair", "Profit per pair",
"Parallelism", "Parallelism",
"Underwater", "Underwater",
"Relative Drawdown",
]) ])
fig['layout'].update(title="Freqtrade Profit plot") fig['layout'].update(title="Freqtrade Profit plot")
fig['layout']['yaxis1'].update(title='Price') fig['layout']['yaxis1'].update(title='Price')
@ -546,14 +560,16 @@ def generate_profit_graph(pairs: str, data: Dict[str, pd.DataFrame],
fig['layout']['yaxis3'].update(title=f'Profit {stake_currency}') fig['layout']['yaxis3'].update(title=f'Profit {stake_currency}')
fig['layout']['yaxis4'].update(title='Trade count') fig['layout']['yaxis4'].update(title='Trade count')
fig['layout']['yaxis5'].update(title='Underwater Plot') fig['layout']['yaxis5'].update(title='Underwater Plot')
fig['layout']['yaxis6'].update(title='Underwater Plot Relative (%)', tickformat=',.2%')
fig['layout']['xaxis']['rangeslider'].update(visible=False) fig['layout']['xaxis']['rangeslider'].update(visible=False)
fig.update_layout(modebar_add=["v1hovermode", "toggleSpikeLines"]) fig.update_layout(modebar_add=["v1hovermode", "toggleSpikeLines"])
fig.add_trace(avgclose, 1, 1) fig.add_trace(avgclose, 1, 1)
fig = add_profit(fig, 2, df_comb, 'cum_profit', 'Profit') fig = add_profit(fig, 2, df_comb, 'cum_profit', 'Profit')
fig = add_max_drawdown(fig, 2, trades, df_comb, timeframe) fig = add_max_drawdown(fig, 2, trades, df_comb, timeframe, starting_balance)
fig = add_parallelism(fig, 4, trades, timeframe) fig = add_parallelism(fig, 4, trades, timeframe)
fig = add_underwater(fig, 5, trades) # Two rows consumed
fig = add_underwater(fig, 5, trades, starting_balance)
for pair in pairs: for pair in pairs:
profit_col = f'cum_profit_{pair}' profit_col = f'cum_profit_{pair}'
@ -668,7 +684,7 @@ def plot_profit(config: Dict[str, Any]) -> None:
# this could be useful to gauge the overall market trend # this could be useful to gauge the overall market trend
fig = generate_profit_graph(plot_elements['pairs'], plot_elements['ohlcv'], fig = generate_profit_graph(plot_elements['pairs'], plot_elements['ohlcv'],
trades, config['timeframe'], trades, config['timeframe'],
config.get('stake_currency', '')) config.get('stake_currency', ''), config['available_capital'])
store_plot_file(fig, filename='freqtrade-profit-plot.html', store_plot_file(fig, filename='freqtrade-profit-plot.html',
directory=config['user_data_dir'] / 'plot', directory=config['user_data_dir'] / 'plot',
auto_open=config.get('plot_auto_open', False)) auto_open=config.get('plot_auto_open', False))

View File

@ -85,6 +85,7 @@ def test_loss_calculation_has_limited_profit(hyperopt_conf, hyperopt_results) ->
"SharpeHyperOptLoss", "SharpeHyperOptLoss",
"SharpeHyperOptLossDaily", "SharpeHyperOptLossDaily",
"MaxDrawDownHyperOptLoss", "MaxDrawDownHyperOptLoss",
"MaxDrawDownRelativeHyperOptLoss",
"CalmarHyperOptLoss", "CalmarHyperOptLoss",
"ProfitDrawDownHyperOptLoss", "ProfitDrawDownHyperOptLoss",