Source code for qis.plots.derived.price_history
"""
how much history each instrument in a panel has: a horizontal bar per ticker from its first to
its last non-nan price. ``plot_price_history`` draws the bars, ``generate_price_history_report``
puts them beside a risk-adjusted performance table on one page.
"""
import matplotlib.pyplot as plt
import pandas as pd
import qis as qis
import qis.plots.utils as put
from typing import Optional, Tuple
[docs]
def generate_price_history_report(prices: pd.DataFrame,
figsize: Tuple[float, float] = (8.3, 11.7),
**kwargs
) -> plt.Figure:
fig, axs = plt.subplots(1, 2, figsize=figsize, tight_layout=True)
qis.plot_ra_perf_table(prices=prices,
title='Risk-Adjusted Performance',
ax=axs[0],
**kwargs)
plot_price_history(prices=prices,
title='Price History',
ax=axs[1],
**kwargs)
return fig
[docs]
def plot_price_history(prices: pd.DataFrame,
title: str = None,
#date_format: str = '%d-%b-%y',
ax: plt.Subplot = None,
**kwargs
) -> Optional[plt.Figure]:
start_dates = {}
end_dates = {}
durations = {}
for asset in prices.columns:
price = prices[asset].dropna()
if not price.empty:
start_dates[asset] = price.index[0]
end_dates[asset] = price.index[-1]
durations[asset] = qis.get_time_to_maturity(maturity_time=price.index[-1],
value_time=price.index[0])
start_dates = pd.Series(start_dates).rename('Start')
end_dates = pd.Series(end_dates).rename('End')
durations = pd.Series(durations).rename('Period')
df = pd.concat([start_dates, end_dates, durations], axis=1)
df = df.iloc[::-1] # reverse index
if ax is None:
width, height, _, _ = put.calc_df_table_size(df=df, min_rows=len(df.index), min_cols=len(df.index)//2)
fig, ax = plt.subplots(1, 1, figsize=(width, height), constrained_layout=True)
else:
fig = None
ax.hlines(df.index, xmin=df['Start'], xmax=df['End'])
# put.set_ax_tick_params(ax=ax)
put.set_ax_ticks_format(ax=ax, **qis.update_kwargs(kwargs, dict()))
if title is not None:
put.set_title(ax=ax, title=title, **kwargs)
ax.margins(x=0.015, y=0.015)
return fig