Plots and hyperopt
This commit is contained in:
parent
178240aa6c
commit
c8e4687833
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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))
|
||||||
|
@ -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",
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user