Skip to content

Syntax bugs fixed, Fixing issue #69 #72

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions quantstats_lumi/_plotting/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,16 +482,18 @@ def plot_histogram(

if benchmark is not None:
if isinstance(returns, _pd.Series):
print("benchmark is not None and returns is a series")
combined_returns = (
benchmark.to_frame()
.join(returns.to_frame())
_pd.DataFrame(benchmark)
.join(_pd.DataFrame(returns))
.stack()
.reset_index()
.rename(columns={"level_1": "", 0: "Returns"})
)
elif isinstance(returns, _pd.DataFrame):
print("benchmark is not None and returns is a dataframe")
combined_returns = (
benchmark.to_frame()
_pd.DataFrame(benchmark)
.join(returns)
.stack()
.reset_index()
Expand Down
10 changes: 8 additions & 2 deletions quantstats_lumi/_plotting/wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,8 @@ def histogram(
returns = _utils._prepare_returns(returns)
if benchmark is not None:
benchmark = _utils._prepare_returns(benchmark)

print("prepared returns")

if resample == "W":
title = "Weekly "
elif resample == "ME":
Expand All @@ -640,6 +641,8 @@ def histogram(
title = "Annual "
else:
title = ""

print("title")

return _core.plot_histogram(
returns,
Expand Down Expand Up @@ -1085,7 +1088,11 @@ def monthly_returns_detailedview(
annual_dd_font_rate=0.8,
savefig=None,
show=True,
prepare_returns=True,
):
if prepare_returns:
returns = _utils._prepare_returns(returns)

fig = _core.monthly_heatmap_detailedview(
returns,
grayscale=grayscale,
Expand All @@ -1099,6 +1106,5 @@ def monthly_returns_detailedview(
savefig=savefig,
show=show,
)

if not show:
return fig
64 changes: 62 additions & 2 deletions quantstats_lumi/reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,27 @@ def _get_trading_periods(periods_per_year=365):

def _match_dates(returns, benchmark):
"""match dates of returns and benchmark"""
print(type(returns), type(benchmark))
if isinstance(returns, _pd.DataFrame):
print('1.1', returns[returns.columns[0]].ne(0).idxmax())
loc = max(returns[returns.columns[0]].ne(0).idxmax(), benchmark.ne(0).idxmax())
else:
elif isinstance(returns, _pd.Series) and isinstance(benchmark, _pd.Series):
print('1.1', returns.ne(0).idxmax())
print('1.1', benchmark.ne(0).idxmax())
loc = max(returns.ne(0).idxmax(), benchmark.ne(0).idxmax())
else:
print('1.2', returns.ne(0).idxmax())
print('1.2', benchmark.iloc[:, 0].ne(0).idxmax())
print("----------")
loc = max(returns.ne(0).idxmax(), benchmark.iloc[:, 0].ne(0).idxmax())

print('1.3', 'Subset returns')
returns = returns.loc[loc:]
print('1.3', 'Subset returns')

print('1.4', 'Subset benchmark')
benchmark = benchmark.loc[loc:]
print('1.4', 'Subset benchmark')

return returns, benchmark

Expand Down Expand Up @@ -133,6 +148,8 @@ def html(
if match_dates:
returns = returns.dropna()
returns = _utils._prepare_returns(returns)

print("Returns prepared")

strategy_title = kwargs.get("strategy_title", "Strategy")
if (
Expand All @@ -141,37 +158,52 @@ def html(
and isinstance(strategy_title, str)
):
strategy_title = list(returns.columns)

print("Strategy title set")

if benchmark is not None:
benchmark_title = kwargs.get("benchmark_title", "Benchmark")
print('1', benchmark_title)

if kwargs.get("benchmark_title") is None:
if isinstance(benchmark, str):
benchmark_title = benchmark
elif isinstance(benchmark, _pd.Series):
benchmark_title = benchmark.name
elif isinstance(benchmark, _pd.DataFrame):
benchmark_title = benchmark[benchmark.columns[0]].name

print('2', benchmark_title)

tpl = tpl.replace(
"{{benchmark_title}}", f"Benchmark is {benchmark_title.upper()} | "
)
benchmark = _utils._prepare_benchmark(benchmark, returns.index, rf)
print("3. Benchmark prepared")

if match_dates is True:
print("4. Matching dates")
returns, benchmark = _match_dates(returns, benchmark)
print("5. Matched dates")
else:
benchmark_title = None

print("Benchmark prepared")

date_range = returns.index.strftime("%e %b, %Y")
tpl = tpl.replace("{{date_range}}", date_range[0] + " - " + date_range[-1])
tpl = tpl.replace("{{title}}", title)
tpl = tpl.replace("{{v}}", __version__)

print("Date range set")

if benchmark is not None:
benchmark.name = benchmark_title
if isinstance(returns, _pd.Series):
returns.name = strategy_title
elif isinstance(returns, _pd.DataFrame):
returns.columns = strategy_title

print("Benchmark name set")

mtrx = metrics(
returns=returns,
Expand All @@ -187,6 +219,8 @@ def html(
benchmark_title=benchmark_title,
strategy_title=strategy_title,
)[2:]

print("Metrics calculated")

mtrx.index.name = "Metric"
tpl = tpl.replace("{{metrics}}", _html_table(mtrx))
Expand Down Expand Up @@ -235,6 +269,8 @@ def html(
sortino = mtrx.loc["Sortino", strategy_title]
# Add the Sharpe to the template
tpl = tpl.replace("{{sortino}}", sortino)

print("Summary metrics added")


if isinstance(returns, _pd.DataFrame):
Expand All @@ -251,6 +287,8 @@ def html(
tpl = tpl.replace(
"<tr><td></td><td></td></tr>", '<tr><td colspan="2"><hr></td></tr>'
)

print("Table formatting done")

if parameters is not None:
tpl = tpl.replace("{{parameters_section}}", parameters_section(parameters))
Expand Down Expand Up @@ -284,6 +322,8 @@ def html(
yoy.index.name = "Year"
tpl = tpl.replace("{{eoy_title}}", "<h3>EOY Returns</h3>")
tpl = tpl.replace("{{eoy_table}}", _html_table(yoy))

print("EOY table added")

if isinstance(returns, _pd.Series):
dd = _stats.to_drawdown_series(returns)
Expand All @@ -310,6 +350,8 @@ def html(
dd_html_table + f"<h3>{col}</h3><br>" + StringIO(html_str).read()
)
tpl = tpl.replace("{{dd_info}}", dd_html_table)

print("Drawdown info added")

active = kwargs.get("active_returns", False)
# plots
Expand All @@ -330,6 +372,8 @@ def html(
prepare_returns=False,
)
tpl = tpl.replace(placeholder_returns, _embed_figure(figfile, figfmt))

print("Returns plot added")

if benchmark is not None and show_match_volatility:
figfile = _utils._file_stream()
Expand Down Expand Up @@ -362,6 +406,8 @@ def html(
prepare_returns=False,
)
tpl = tpl.replace("{{eoy_returns}}", _embed_figure(figfile, figfmt))

print("Yearly returns plot added")

figfile = _utils._file_stream()
_plots.histogram(
Expand All @@ -377,6 +423,8 @@ def html(
prepare_returns=False,
)
tpl = tpl.replace("{{monthly_dist}}", _embed_figure(figfile, figfmt))

print("Histo returns plot added")

figfile = _utils._file_stream()
_plots.daily_returns(
Expand All @@ -392,6 +440,8 @@ def html(
active=active,
)
tpl = tpl.replace("{{daily_returns}}", _embed_figure(figfile, figfmt))

print("Daily returns plot added")

if benchmark is not None:
figfile = _utils._file_stream()
Expand Down Expand Up @@ -424,6 +474,8 @@ def html(
periods_per_year=win_year,
)
tpl = tpl.replace("{{rolling_vol}}", _embed_figure(figfile, figfmt))

print("Rolling volatility plot added")

figfile = _utils._file_stream()
_plots.rolling_sharpe(
Expand Down Expand Up @@ -452,6 +504,8 @@ def html(
periods_per_year=win_year,
)
tpl = tpl.replace("{{rolling_sortino}}", _embed_figure(figfile, figfmt))

print("Rolling sortino plot added")

figfile = _utils._file_stream()
if isinstance(returns, _pd.Series):
Expand Down Expand Up @@ -498,6 +552,8 @@ def html(
ylabel=False,
)
tpl = tpl.replace("{{dd_plot}}", _embed_figure(figfile, figfmt))

print("Drawdown plot added")

figfile = _utils._file_stream()
if isinstance(returns, _pd.Series):
Expand Down Expand Up @@ -534,6 +590,8 @@ def html(
embed.append(figfile)
tpl = tpl.replace("{{monthly_heatmap}}", _embed_figure(embed, figfmt))

print("Monthly heatmap added")

figfile = _utils._file_stream()

if isinstance(returns, _pd.Series):
Expand Down Expand Up @@ -567,6 +625,8 @@ def html(
)
embed.append(figfile)
tpl = tpl.replace("{{returns_dist}}", _embed_figure(embed, figfmt))

print("Returns distribution added")

tpl = _regex.sub(r"\{\{(.*?)\}\}", "", tpl)
tpl = tpl.replace("white-space:pre;", "")
Expand Down
2 changes: 2 additions & 0 deletions quantstats_lumi/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,9 @@ def _prepare_benchmark(benchmark=None, period="max", rf=0.0, prepare_returns=Tru
return None

if isinstance(benchmark, str):
print("Downloading benchmark...")
benchmark = download_returns(benchmark)
print("Benchmark downloaded.")

elif isinstance(benchmark, _pd.DataFrame):
benchmark = benchmark[benchmark.columns[0]].copy()
Expand Down