def plot_ltd(self, ax=None, style='k', label='ltd', show_dd=1, title=True, legend=1): ltd = self.ltd_rets ax = ltd.plot(ax=ax, style=style, label=label) if show_dd: dd = self.drawdowns dd.plot(style='r', label='drawdowns', alpha=.5, ax=ax) ax.fill_between(dd.index, 0, dd.values, facecolor='red', alpha=.25) fmt = PercentFormatter AxesFormat().Y.percent().X.label("").apply(ax) legend and ax.legend(loc='upper left', prop={'size': 12}) # show the actualy date and value mdt, mdd = self.maxdd_dt, self.maxdd bbox_props = dict(boxstyle="round", fc="w", ec="0.5", alpha=0.25) try: dtstr = '{0}'.format(mdt.to_period()) except: # assume daily dtstr = '{0}'.format(hasattr(mdt, 'date') and mdt.date() or mdt) ax.text(mdt, dd[mdt], "{1} \n {0}".format(fmt(mdd), dtstr).strip(), ha="center", va="top", size=8, bbox=bbox_props) if title is True: pf = new_percent_formatter(1, parens=False, trunc_dot_zeros=True) ff = new_float_formatter(precision=1, parens=False, trunc_dot_zeros=True) total = pf(self.ltd_ann) vol = pf(self.std_ann) sh = ff(self.sharpe_ann) mdd = pf(self.maxdd) title = 'ret$\mathregular{_{ann}}$ %s vol$\mathregular{_{ann}}$ %s sharpe %s maxdd %s' % ( total, vol, sh, mdd) title and ax.set_title(title, fontdict=dict(fontsize=10, fontweight='bold')) return ax
def plot_hist(self, ax=None, **histplot_kwargs): pf = new_percent_formatter(precision=1, parens=False, trunc_dot_zeros=1) ff = new_float_formatter(precision=1, parens=False, trunc_dot_zeros=1) ax = self.rets.hist(ax=ax, **histplot_kwargs) AxesFormat().X.percent(1).apply(ax) m, s, sk, ku = pf(self.mean), pf(self.std), ff(self.skew), ff( self.kurtosis) txt = ( "$\mathregular{\mu}$=%s $\mathregular{\sigma}$=%s skew=%s kurt=%s" % (m, s, sk, ku)) bbox = dict(facecolor="white", alpha=0.5) ax.text( 0, 1, txt, fontdict={"fontweight": "bold"}, bbox=bbox, ha="left", va="top", transform=ax.transAxes, ) return ax
def plot_hist(self, ax=None, **histplot_kwargs): pf = new_percent_formatter(precision=1, parens=False, trunc_dot_zeros=1) ff = new_float_formatter(precision=1, parens=False, trunc_dot_zeros=1) ax = self.rets.hist(ax=ax, **histplot_kwargs) AxesFormat().X.percent(1).apply(ax) m, s, sk, ku = pf(self.mean), pf(self.std), ff(self.skew), ff(self.kurtosis) txt = '$\mathregular{\mu}$=%s $\mathregular{\sigma}$=%s skew=%s kurt=%s' % (m, s, sk, ku) bbox = dict(facecolor='white', alpha=0.5) ax.text(0, 1, txt, fontdict={'fontweight': 'bold'}, bbox=bbox, ha='left', va='top', transform=ax.transAxes) return ax
def plot_return_on_dollar(rets, title='Return on $1', show_maxdd=0, figsize=None, ax=None, append=0, label=None, **plot_args): """ Show the cumulative return of specified rets and max drawdowns if selected.""" crets = (1. + returns_cumulative(rets, expanding=1)) if isinstance(crets, pd.DataFrame): tmp = crets.copy() for c in tmp.columns: s = tmp[c] fv = s.first_valid_index() fi = s.index.get_loc(fv) if fi != 0: tmp.ix[fi - 1, c] = 1. else: if not s.index.freq: # no frequency set freq = guess_freq(s.index) s = s.asfreq(freq) first = s.index.shift(-1)[0] tmp = pd.concat([pd.DataFrame({c: [1.]}, index=[first]), tmp]) crets = tmp if append: toadd = crets.index.shift(1)[-1] crets = pd.concat([crets, pd.DataFrame(np.nan, columns=crets.columns, index=[toadd])]) else: fv = crets.first_valid_index() fi = crets.index.get_loc(fv) if fi != 0: crets = crets.copy() crets.iloc[fi - 1] = 1. else: if not crets.index.freq: first = crets.asfreq(guess_freq(crets.index)).index.shift(-1)[0] else: first = crets.index.shift(-1)[0] tmp = pd.Series([1.], index=[first]) tmp = tmp.append(crets) crets = tmp if append: toadd = pd.Series(np.nan, index=[crets.index.shift(1)[-1]]) crets = crets.append(toadd) ax = crets.plot(figsize=figsize, title=title, ax=ax, label=label, **plot_args) AxesFormat().Y.apply_format(new_float_formatter()).X.label("").apply(ax) #ax.tick_params(labelsize=14) if show_maxdd: # find the max drawdown available by using original rets if isinstance(rets, pd.DataFrame): iterator = rets.iteritems() else: iterator = iter([('', rets)]) for c, col in iterator: dd, dt = max_drawdown(col, inc_date=1) lbl = c and c + ' maxdd' or 'maxdd' # get cret to place annotation correctly if isinstance(crets, pd.DataFrame): amt = crets.ix[dt, c] else: amt = crets[dt] bbox_props = dict(boxstyle="round", fc="w", ec="0.5", alpha=0.7) # sub = lambda c: c and len(c) > 2 and c[:2] or c try: dtstr = '{0}'.format(dt.to_period()) except: dtstr = '{0}'.format(dt) ax.text(dt, amt, "mdd {0}".format(dtstr).strip(), ha="center", va="center", size=10, bbox=bbox_props) plt.tight_layout()
def pad_positive_wrapper(fmtfct): """Ensure that numbers are aligned in table by appending a blank space to postive values if 'parenthesis' are used to denote negative numbers""" def check_and_append(*args, **kwargs): result = fmtfct(*args, **kwargs) if fmtfct.parens and not result.endswith(')'): result += ' ' return result return check_and_append IntFormatter = pad_positive_wrapper(fmt.new_int_formatter(nan='-')) FloatFormatter = pad_positive_wrapper(fmt.new_float_formatter(nan='-')) PercentFormatter = pad_positive_wrapper(fmt.new_percent_formatter(nan='-')) ThousandsFormatter = pad_positive_wrapper(fmt.new_thousands_formatter(nan='-')) MillionsFormatter = pad_positive_wrapper(fmt.new_millions_formatter(nan='-')) BillionsFormatter = pad_positive_wrapper(fmt.new_billions_formatter(nan='-')) # Don't attempt to pad DynamicNumberFormatter = fmt.DynamicNumberFormat(nan='-', pcts=1, trunc_dot_zeros=1) DollarCentsFormatter = pad_positive_wrapper(fmt.new_float_formatter(prefix='$', nan='-')) DollarFormatter = pad_positive_wrapper(fmt.new_int_formatter(prefix='$', nan='-')) ThousandDollarsFormatter = pad_positive_wrapper(fmt.new_thousands_formatter(prefix='$', nan='-')) MillionDollarsFormatter = pad_positive_wrapper(fmt.new_millions_formatter(prefix='$', nan='-')) BillionDollarsFormatter = pad_positive_wrapper(fmt.new_billions_formatter(prefix='$', nan='-')) YmdFormatter = fmt.new_datetime_formatter('%Y%m%d', True) Y_m_dFormatter = fmt.new_datetime_formatter('%Y_%m_%d', True) mdYFormatter = fmt.new_datetime_formatter('%m/%d/%Y', True)
def pad_positive_wrapper(fmtfct): """Ensure that numbers are aligned in table by appending a blank space to postive values if 'parenthesis' are used to denote negative numbers""" def check_and_append(*args, **kwargs): result = fmtfct(*args, **kwargs) if fmtfct.parens and not result.endswith(')'): result += ' ' return result return check_and_append IntFormatter = pad_positive_wrapper(fmt.new_int_formatter(nan='-')) FloatFormatter = pad_positive_wrapper(fmt.new_float_formatter(nan='-')) PercentFormatter = pad_positive_wrapper(fmt.new_percent_formatter(nan='-')) ThousandsFormatter = pad_positive_wrapper(fmt.new_thousands_formatter(nan='-')) MillionsFormatter = pad_positive_wrapper(fmt.new_millions_formatter(nan='-')) BillionsFormatter = pad_positive_wrapper(fmt.new_billions_formatter(nan='-')) # Don't attempt to pad DynamicNumberFormatter = fmt.DynamicNumberFormat(method='col', nan='-', pcts=1, trunc_dot_zeros=1) DollarCentsFormatter = pad_positive_wrapper( fmt.new_float_formatter(prefix='$', nan='-')) DollarFormatter = pad_positive_wrapper( fmt.new_int_formatter(prefix='$', nan='-')) ThousandDollarsFormatter = pad_positive_wrapper(
def pad_positive_wrapper(fmtfct): """Ensure that numbers are aligned in table by appending a blank space to postive values if 'parenthesis' are used to denote negative numbers""" def check_and_append(*args, **kwargs): result = fmtfct(*args, **kwargs) if fmtfct.parens and not result.endswith(")"): result += " " return result return check_and_append IntFormatter = pad_positive_wrapper(fmt.new_int_formatter(nan="-")) FloatFormatter = pad_positive_wrapper(fmt.new_float_formatter(nan="-")) PercentFormatter = pad_positive_wrapper(fmt.new_percent_formatter(nan="-")) ThousandsFormatter = pad_positive_wrapper(fmt.new_thousands_formatter(nan="-")) MillionsFormatter = pad_positive_wrapper(fmt.new_millions_formatter(nan="-")) BillionsFormatter = pad_positive_wrapper(fmt.new_billions_formatter(nan="-")) # Don't attempt to pad DynamicNumberFormatter = fmt.DynamicNumberFormat(method="col", nan="-", pcts=1, trunc_dot_zeros=1) DollarCentsFormatter = pad_positive_wrapper(fmt.new_float_formatter(prefix="$", nan="-")) DollarFormatter = pad_positive_wrapper(fmt.new_int_formatter(prefix="$", nan="-")) ThousandDollarsFormatter = pad_positive_wrapper(fmt.new_thousands_formatter(prefix="$", nan="-")) MillionDollarsFormatter = pad_positive_wrapper(fmt.new_millions_formatter(prefix="$", nan="-")) BillionDollarsFormatter = pad_positive_wrapper(fmt.new_billions_formatter(prefix="$", nan="-")) YmdFormatter = fmt.new_datetime_formatter("%Y%m%d", True) Y_m_dFormatter = fmt.new_datetime_formatter("%Y-%m-%d", True) mdYFormatter = fmt.new_datetime_formatter("%m/%d/%Y", True)
def pad_positive_wrapper(fmtfct): """Ensure that numbers are aligned in table by appending a blank space to postive values if 'parenthesis' are used to denote negative numbers""" def check_and_append(*args, **kwargs): result = fmtfct(*args, **kwargs) if fmtfct.parens and not result.endswith(")"): result += " " return result return check_and_append IntFormatter = pad_positive_wrapper(fmt.new_int_formatter(nan="-")) FloatFormatter = pad_positive_wrapper(fmt.new_float_formatter(nan="-")) PercentFormatter = pad_positive_wrapper(fmt.new_percent_formatter(nan="-")) ThousandsFormatter = pad_positive_wrapper(fmt.new_thousands_formatter(nan="-")) MillionsFormatter = pad_positive_wrapper(fmt.new_millions_formatter(nan="-")) BillionsFormatter = pad_positive_wrapper(fmt.new_billions_formatter(nan="-")) # Don't attempt to pad DynamicNumberFormatter = fmt.DynamicNumberFormat(method="col", nan="-", pcts=1, trunc_dot_zeros=1) DollarCentsFormatter = pad_positive_wrapper( fmt.new_float_formatter(prefix="$", nan="-")) DollarFormatter = pad_positive_wrapper( fmt.new_int_formatter(prefix="$", nan="-")) ThousandDollarsFormatter = pad_positive_wrapper(