diff --git a/quantstats_lumi/_plotting/core.py b/quantstats_lumi/_plotting/core.py index 1dee056..5f52a14 100644 --- a/quantstats_lumi/_plotting/core.py +++ b/quantstats_lumi/_plotting/core.py @@ -354,6 +354,14 @@ def plot_timeseries( _plt.yscale("symlog" if log_scale else "linear") + # Set y-axis limits to avoid blank space at the bottom and top + min_val = returns.min() + max_val = returns.max() + if benchmark is not None: + min_val = min(min_val, benchmark.min()) + max_val = max(max_val, benchmark.max()) + ax.set_ylim(bottom=min_val, top=max_val) + if percent: ax.yaxis.set_major_formatter(_FuncFormatter(format_pct_axis)) # ax.yaxis.set_major_formatter(_plt.FuncFormatter( @@ -940,6 +948,10 @@ def plot_longest_drawdowns( ax.axhline(0, ls="--", lw=1, color="#000000", zorder=2) _plt.yscale("symlog" if log_scale else "linear") + + # Set y-axis limits to avoid blank space at the bottom and top + ax.set_ylim(bottom=series.min(), top=series.max()) + if ylabel: ax.set_ylabel( "Cumulative Returns", @@ -994,6 +1006,7 @@ def plot_distribution( title=None, savefig=None, show=True, + log_scale=False, ): colors = _FLATUI_COLORS if grayscale: @@ -1057,6 +1070,7 @@ def plot_distribution( }, ) + _plt.yscale("symlog" if log_scale else "linear") ax.yaxis.set_major_formatter( _plt.FuncFormatter(lambda x, loc: "{:,}%".format(int(x * 100))) ) diff --git a/quantstats_lumi/_plotting/wrappers.py b/quantstats_lumi/_plotting/wrappers.py index 3f85f7d..c8108b2 100644 --- a/quantstats_lumi/_plotting/wrappers.py +++ b/quantstats_lumi/_plotting/wrappers.py @@ -589,6 +589,7 @@ def distribution( show=True, title=None, prepare_returns=True, + log_scale=True, ): if prepare_returns: returns = _utils._prepare_returns(returns) @@ -604,6 +605,7 @@ def distribution( compounded=compounded, savefig=savefig, show=show, + log_scale=log_scale, ) if not show: return fig diff --git a/quantstats_lumi/reports.py b/quantstats_lumi/reports.py index ce072c6..93bca3b 100644 --- a/quantstats_lumi/reports.py +++ b/quantstats_lumi/reports.py @@ -190,7 +190,7 @@ def html( tpl = tpl.replace("{{metrics}}", _html_table(mtrx)) # Add all of the summary metrics - + # CAGR # # Get the value of the "Strategy" column where the "Metric" column is "CAGR% (Annual Return)" cagr = mtrx.loc["CAGR% (Annual Return)", strategy_title] @@ -209,7 +209,7 @@ def html( max_drawdown = mtrx.loc["Max Drawdown", strategy_title] # Add the max drawdown to the template tpl = tpl.replace("{{max_drawdown}}", max_drawdown) - + # RoMaD # # Get the value of the "Strategy" column where the "Mteric" column is "RoMaD" romad = mtrx.loc["RoMaD", strategy_title] @@ -331,7 +331,7 @@ def html( if benchmark is not None: figfile = _utils._file_stream() - _plots.returns( + _plots.log_returns( returns, benchmark, match_volatility=True, @@ -464,6 +464,7 @@ def html( ylabel=False, compounded=compounded, prepare_returns=False, + log_scale=True, ) tpl = tpl.replace("{{dd_periods}}", _embed_figure(figfile, figfmt)) elif isinstance(returns, _pd.DataFrame): @@ -831,7 +832,7 @@ def parameters_section(parameters): # Make sure that the value is something that can be displayed if not isinstance(value, (int, float, str)): value = str(value) - + tpl += f"