def plot_percentiles(self, *args, **kwargs): out = super().plot_percentiles(*args, **kwargs) a = out[1] def num2month(pos, num): month = [ '', 'J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D', '', '' ] return month[num] if self.frequency == 'M': a.xaxis.set_major_formatter(_FuncFormatter(num2month)) a.set_xlim(0.5, 12.5) a.set_xlabel('Month of year') return out
def earnings(returns, start_balance=1e5, mode="comp", grayscale=False, figsize=(10, 6), title='Portfolio Earnings', fontname='Arial', lw=1.5, subtitle=True, savefig=None, show=True): colors = _GRAYSCALE_COLORS if grayscale else _FLATUI_COLORS alpha = .5 if grayscale else .8 returns = _utils.make_portfolio(returns, start_balance, mode) if figsize is None: size = list(_plt.gcf().get_size_inches()) figsize = (size[0], size[0]*.55) fig, ax = _plt.subplots(figsize=figsize) fig.suptitle(title, fontsize=14, y=.995, fontname=fontname, fontweight='bold', color='black') if subtitle: ax.set_title("\n%s - %s ; P&L: %s (%s) " % ( returns.index.date[1:2][0].strftime('%e %b \'%y'), returns.index.date[-1:][0].strftime('%e %b \'%y'), _utils._score_str("${:,}".format( round(returns.values[-1]-returns.values[0], 2))), _utils._score_str("{:,}%".format( round((returns.values[-1]/returns.values[0]-1)*100, 2))) ), fontsize=12, color='gray') mx = returns.max() returns_max = returns[returns == mx] ix = returns_max[~_np.isnan(returns_max)].index[0] returns_max = _np.where(returns.index == ix, mx, _np.nan) ax.plot(returns.index, returns_max, marker='o', lw=0, alpha=alpha, markersize=12, color=colors[0]) ax.plot(returns.index, returns, color=colors[1], lw=1 if grayscale else lw) ax.set_ylabel('Value of ${:,.0f}'.format(start_balance), fontname=fontname, fontweight='bold', fontsize=12) ax.yaxis.set_major_formatter(_FuncFormatter(_core.format_cur_axis)) ax.yaxis.set_label_coords(-.1, .5) fig.set_facecolor('white') ax.set_facecolor('white') fig.autofmt_xdate() try: _plt.subplots_adjust(hspace=0) except Exception: pass try: fig.tight_layout(w_pad=0, h_pad=0) except Exception: pass if savefig: if isinstance(savefig, dict): _plt.savefig(**savefig) else: _plt.savefig(savefig) if show: _plt.show(fig) _plt.close() if not show: return fig
def plot_returns_bars(returns, benchmark=None, returns_label="Strategy", hline=None, hlw=None, hlcolor="red", hllabel="", resample="A", title="Returns", match_volatility=False, log_scale=False, figsize=(10, 6), grayscale=False, fontname='Arial', ylabel=True, subtitle=True, savefig=None, show=True): if match_volatility and benchmark is None: raise ValueError('match_volatility requires passing of ' 'benchmark.') if match_volatility and benchmark is not None: bmark_vol = benchmark.loc[returns.index].std() returns = (returns / returns.std()) * bmark_vol # --------------- colors, _, _ = _get_colors(grayscale) df = _pd.DataFrame(index=returns.index, data={returns_label: returns}) if isinstance(benchmark, _pd.Series): df['Benchmark'] = benchmark[benchmark.index.isin(returns.index)] df = df[['Benchmark', returns_label]] df = df.dropna() if resample is not None: df = df.resample(resample).apply(_stats.comp).resample(resample).last() # --------------- fig, ax = _plt.subplots(figsize=figsize) ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['bottom'].set_visible(False) ax.spines['left'].set_visible(False) # use a more precise date string for the x axis locations in the toolbar fig.suptitle(title + "\n", y=.99, fontweight="bold", fontname=fontname, fontsize=14, color="black") if subtitle: ax.set_title("\n%s - %s " % (df.index.date[:1][0].strftime('%Y'), df.index.date[-1:][0].strftime('%Y')), fontsize=12, color='gray') if benchmark is None: colors = colors[1:] df.plot(kind='bar', ax=ax, color=colors) fig.set_facecolor('white') ax.set_facecolor('white') try: ax.set_xticklabels(df.index.year) years = sorted(list(set(df.index.year))) except AttributeError: ax.set_xticklabels(df.index) years = sorted(list(set(df.index))) # ax.fmt_xdata = _mdates.DateFormatter('%Y-%m-%d') # years = sorted(list(set(df.index.year))) if len(years) > 10: mod = int(len(years) / 10) _plt.xticks( _np.arange(len(years)), [str(year) if not i % mod else '' for i, year in enumerate(years)]) # rotate and align the tick labels so they look better fig.autofmt_xdate() if hline: if grayscale: hlcolor = 'gray' ax.axhline(hline, ls="--", lw=hlw, color=hlcolor, label=hllabel, zorder=2) ax.axhline(0, ls="--", lw=1, color="#000000", zorder=2) if isinstance(benchmark, _pd.Series) or hline: ax.legend(fontsize=12) _plt.yscale("symlog" if log_scale else "linear") ax.set_xlabel('') if ylabel: ax.set_ylabel("Returns", fontname=fontname, fontweight='bold', fontsize=12, color="black") ax.yaxis.set_label_coords(-.1, .5) ax.yaxis.set_major_formatter(_FuncFormatter(format_pct_axis)) try: _plt.subplots_adjust(hspace=0, bottom=0, top=1) except Exception: pass try: fig.tight_layout() except Exception: pass if savefig: if isinstance(savefig, dict): _plt.savefig(**savefig) else: _plt.savefig(savefig) if show: _plt.show(block=False) _plt.close() if not show: return fig return None
def plot_longest_drawdowns(returns, periods=5, lw=1.5, fontname='Arial', grayscale=False, log_scale=False, figsize=(10, 6), ylabel=True, subtitle=True, compounded=True, savefig=None, show=True): colors = ['#348dc1', '#003366', 'red'] if grayscale: colors = ['#000000'] * 3 dd = _stats.to_drawdown_series(returns.fillna(0)) dddf = _stats.drawdown_details(dd) longest_dd = dddf.sort_values(by='days', ascending=False, kind='mergesort')[:periods] fig, ax = _plt.subplots(figsize=figsize) ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['bottom'].set_visible(False) ax.spines['left'].set_visible(False) fig.suptitle("Worst %.0f Drawdown Periods\n" % periods, y=.99, fontweight="bold", fontname=fontname, fontsize=14, color="black") if subtitle: ax.set_title("\n%s - %s " % (returns.index.date[:1][0].strftime('%e %b \'%y'), returns.index.date[-1:][0].strftime('%e %b \'%y')), fontsize=12, color='gray') fig.set_facecolor('white') ax.set_facecolor('white') series = _stats.compsum(returns) if compounded else returns.cumsum() ax.plot(series, lw=lw, label="Backtest", color=colors[0]) highlight = 'black' if grayscale else 'red' for _, row in longest_dd.iterrows(): ax.axvspan(*_mdates.datestr2num([str(row['start']), str(row['end'])]), color=highlight, alpha=.1) # rotate and align the tick labels so they look better fig.autofmt_xdate() # use a more precise date string for the x axis locations in the toolbar ax.fmt_xdata = _mdates.DateFormatter('%Y-%m-%d') ax.axhline(0, ls="--", lw=1, color="#000000", zorder=2) _plt.yscale("symlog" if log_scale else "linear") if ylabel: ax.set_ylabel("Cumulative Returns", fontname=fontname, fontweight='bold', fontsize=12, color="black") ax.yaxis.set_label_coords(-.1, .5) ax.yaxis.set_major_formatter(_FuncFormatter(format_pct_axis)) # ax.yaxis.set_major_formatter(_plt.FuncFormatter( # lambda x, loc: "{:,}%".format(int(x*100)))) fig.autofmt_xdate() try: _plt.subplots_adjust(hspace=0, bottom=0, top=1) except Exception: pass try: fig.tight_layout() except Exception: pass if savefig: if isinstance(savefig, dict): _plt.savefig(**savefig) else: _plt.savefig(savefig) if show: _plt.show(block=False) _plt.close() if not show: return fig return None
def plot_timeseries(returns, benchmark=None, title="Returns", compound=False, cumulative=True, fill=False, returns_label="Strategy", hline=None, hlw=None, hlcolor="red", hllabel="", percent=True, match_volatility=False, log_scale=False, resample=None, lw=1.5, figsize=(10, 6), ylabel="", grayscale=False, fontname="Arial", subtitle=True, savefig=None, show=True): colors, ls, alpha = _get_colors(grayscale) returns.fillna(0, inplace=True) if isinstance(benchmark, _pd.Series): benchmark.fillna(0, inplace=True) if match_volatility and benchmark is None: raise ValueError('match_volatility requires passing of ' 'benchmark.') if match_volatility and benchmark is not None: bmark_vol = benchmark.std() returns = (returns / returns.std()) * bmark_vol # --------------- if compound is True: if cumulative: returns = _stats.compsum(returns) if isinstance(benchmark, _pd.Series): benchmark = _stats.compsum(benchmark) else: returns = returns.cumsum() if isinstance(benchmark, _pd.Series): benchmark = benchmark.cumsum() if resample: returns = returns.resample(resample) returns = returns.last() if compound is True else returns.sum() if isinstance(benchmark, _pd.Series): benchmark = benchmark.resample(resample) benchmark = benchmark.last( ) if compound is True else benchmark.sum() # --------------- fig, ax = _plt.subplots(figsize=figsize) ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['bottom'].set_visible(False) ax.spines['left'].set_visible(False) fig.suptitle(title + "\n", y=.99, fontweight="bold", fontname=fontname, fontsize=14, color="black") if subtitle: ax.set_title("\n%s - %s " % (returns.index.date[:1][0].strftime('%e %b \'%y'), returns.index.date[-1:][0].strftime('%e %b \'%y')), fontsize=12, color='gray') fig.set_facecolor('white') ax.set_facecolor('white') if isinstance(benchmark, _pd.Series): ax.plot(benchmark, lw=lw, ls=ls, label="Benchmark", color=colors[0]) alpha = .25 if grayscale else 1 ax.plot(returns, lw=lw, label=returns_label, color=colors[1], alpha=alpha) if fill: ax.fill_between(returns.index, 0, returns, color=colors[1], alpha=.25) # rotate and align the tick labels so they look better fig.autofmt_xdate() # use a more precise date string for the x axis locations in the toolbar # ax.fmt_xdata = _mdates.DateFormatter('%Y-%m-%d') if hline: if grayscale: hlcolor = 'black' ax.axhline(hline, ls="--", lw=hlw, color=hlcolor, label=hllabel, zorder=2) ax.axhline(0, ls="-", lw=1, color='gray', zorder=1) ax.axhline(0, ls="--", lw=1, color='white' if grayscale else 'black', zorder=2) if isinstance(benchmark, _pd.Series) or hline: ax.legend(fontsize=12) _plt.yscale("symlog" if log_scale else "linear") if percent: ax.yaxis.set_major_formatter(_FuncFormatter(format_pct_axis)) # ax.yaxis.set_major_formatter(_plt.FuncFormatter( # lambda x, loc: "{:,}%".format(int(x*100)))) ax.set_xlabel('') if ylabel: ax.set_ylabel(ylabel, fontname=fontname, fontweight='bold', fontsize=12, color="black") ax.yaxis.set_label_coords(-.1, .5) try: _plt.subplots_adjust(hspace=0, bottom=0, top=1) except Exception: pass try: fig.tight_layout() except Exception: pass if savefig: if isinstance(savefig, dict): _plt.savefig(**savefig) else: _plt.savefig(savefig) if show: _plt.show(block=False) _plt.close() if not show: return fig return None
def plot_longest_drawdowns(returns, dicclrs, periods=5, lw=1.5, fontname='Avenir Next', grayscale=False, log_scale=False, figsize=(10, 6), ylabel=True, subtitle=True, compounded=True, savefig=None, show=True): #colors = ['#348dc1', '#003366', 'red'] #inially colors = [dicclrs['arquant'], '#b5583c', dicclrs['background']] #ARQuant, Brown, Light Peach if grayscale: colors = ['#000000'] * 3 import matplotlib.pyplot as plt import matplotlib.dates as _mdates import quantstats.stats as _stats from matplotlib.ticker import (FormatStrFormatter as _FormatStrFormatter, FuncFormatter as _FuncFormatter) dd = _stats.to_drawdown_series(returns.fillna(0)) dddf = _stats.drawdown_details(dd) longest_dd = dddf.sort_values(by='days', ascending=False, kind='mergesort')[:periods] fig, ax = plt.subplots(figsize=figsize) ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['bottom'].set_visible(False) ax.spines['left'].set_visible(False) # fig.suptitle("Top %.0f Drawdown Periods\n" % # periods, y=1.1, x=0.25, # fontweight="normal", fontname=fontname, # fontsize=18, color=dicclrs['plotname']) if subtitle: # plt.rc('text', usetex=True) # plt.title(r'\fontsize{30pt}{3em}\selectfont{}{Mean WRFv3.5 LHF\r}{\fontsize{18pt}{3em}\selectfont{}(September 16 - October 30, 2012)}') plt.title( "", loc='left', #Top %.0f Drawdown Periods\n %periods fontweight="medium", fontname=fontname, fontsize=18, color=dicclrs['plotname']) dates = " Top %.0f Drawdown Periods | %s - %s " % ( periods, returns.index.date[:1][0].strftime('%e %b \'%y'), returns.index.date[-1:][0].strftime('%e %b \'%y')) import json with open('slide2.txt', 'w') as outfile: json.dump(dates, outfile) # plt.title(dates, loc='center') # plt.text(0.45, 0.97, dates, # fontdict=dict(fontweight='normal', fontname=fontname, # fontsize=14, color=dicclrs['dates']), # transform=fig.transFigure # ) #Plot the line fig.set_facecolor('white') ax.set_facecolor('white') series = _stats.compsum(returns) if compounded else returns.cumsum() ax.plot(series, lw=lw, label="Backtest", color=colors[0]) #PLot spans highlight = 'black' if grayscale else dicclrs[ 'background'] # it was initially 'red' for _, row in longest_dd.iterrows(): ax.axvspan(*_mdates.datestr2num([str(row['start']), str(row['end'])]), color=highlight, alpha=.5) ## Horizontal line for 0% ax.axhline(0, ls="-", lw=1, color="#000000", zorder=2) ## X -axis # rotate and align the tick labels so they look better # fig.autofmt_xdate() fig.autofmt_xdate(bottom=0.2, rotation=0, ha='center', which=None) # use a more precise date string for the x axis locations in the toolbar ax.fmt_xdata = _mdates.DateFormatter('%Y-%m-%d') ax.xaxis.set_tick_params(labelsize=8, color=dicclrs['dates']) ## Y -axis plt.yscale("symlog" if log_scale else "linear") if ylabel: ax.set_ylabel("Cumulative Returns", fontname=fontname, fontweight='medium', fontsize=12, color="black") ax.yaxis.set_label_coords(-.075, .5) ax.yaxis.set_major_formatter(_FuncFormatter(format_pct_axis)) # ax.yaxis.set_major_formatter(plt.FuncFormatter( # lambda x, loc: "{:,}%".format(int(x*100)))) ax.yaxis.set_tick_params(labelsize=8) try: plt.subplots_adjust(hspace=0, bottom=0, top=1) except Exception: pass try: fig.tight_layout() except Exception: pass if savefig: if isinstance(savefig, dict): plt.savefig(**savefig, dpi=300) else: plt.savefig(savefig, dpi=300) if show: plt.show(block=False) plt.close() if not show: return fig return None
''' from __future__ import division from . import _np from . import _signal import scipy.constants as _const from matplotlib import pyplot as _plt _plt.ioff() from matplotlib.ticker import FuncFormatter as _FuncFormatter from matplotlib.widgets import Cursor as _Cursor def _seconds_formatter(t, pos): '''Assume that t is in seconds''' return '%02d:%02d' % (t // 60, t % 60) _x_axis_formatter = _FuncFormatter(_seconds_formatter) _line_props = [{'color': '0'}, {'color': '0.5'}] #detect screen resolution import Tkinter as _Tk _root = _Tk.Tk() _res = (_root.winfo_screenwidth() / float(_root.winfo_screenmmwidth()) * 1000 * _const.inch) _root.destroy() class plotEEG: def __init__(self, signals, ylabels, t, t_res=30, title = False): """Function to Plot EEG-Signals in of several channels Def: PlotEEG(signals, ylabels, t, t_res, title = False) Interaction:
from . import _np from . import _signal import scipy.constants as _const from matplotlib import pyplot as _plt _plt.ioff() from matplotlib.ticker import FuncFormatter as _FuncFormatter from matplotlib.widgets import Cursor as _Cursor def _seconds_formatter(t, pos): '''Assume that t is in seconds''' return '%02d:%02d' % (t // 60, t % 60) _x_axis_formatter = _FuncFormatter(_seconds_formatter) _line_props = [{'color': 'k'}, {'color': 'r'}] #detect screen resolution import Tkinter as _Tk _root = _Tk.Tk() _res = (_root.winfo_screenwidth() / float(_root.winfo_screenmmwidth()) * 1000 * _const.inch) _root.destroy() class plotEEG: def __init__(self, signals, ylabels, t, t_res=30, title=False): """Function to Plot EEG-Signals in of several channels Def: PlotEEG(signals, ylabels, t, t_res, title = False)