# Path: tia/analysis/perf.py
# def returns_cumulative(returns, geometric=True, expanding=False):
#     """ return the cumulative return
# 
#     Parameters
#     ----------
#     returns : DataFrame or Series
#     geometric : bool, default is True
#                 If True, geometrically link returns
#     expanding : bool default is False
#                 If True, return expanding series/frame of returns
#                 If False, return the final value(s)
#     """
#     if expanding:
#         if geometric:
#             return (1. + returns).cumprod() - 1.
#         else:
#             return returns.cumsum()
#     else:
#         if geometric:
#             return (1. + returns).prod() - 1.
#         else:
#             return returns.sum()
# 
# def max_drawdown(returns=None, geometric=True, dd=None, inc_date=False):
#     """
#     compute the max draw down.
#     returns: period return Series or DataFrame
#     dd: drawdown Series or DataFrame (mutually exclusive with returns)
#     """
#     if (returns is None and dd is None) or (returns is not None and dd is not None):
#         raise ValueError('returns and drawdowns are mutually exclusive')
# 
#     if returns is not None:
#         dd = drawdowns(returns, geometric=geometric)
# 
#     if isinstance(dd, pd.DataFrame):
#         vals = [max_drawdown(dd=dd[c], inc_date=inc_date) for c in dd.columns]
#         cols = ['maxxdd'] + (inc_date and ['maxdd_dt'] or [])
#         res = pd.DataFrame(vals, columns=cols, index=dd.columns)
#         return res if inc_date else res.maxdd
#     else:
#         mddidx = dd.idxmin()
#         # if mddidx == dd.index[0]:
#         # # no maxff
#         #    return 0 if not inc_date else (0, None)
#         #else:
#         sub = dd[:mddidx]
#         start = sub[::-1].idxmax()
#         mdd = dd[mddidx]
#         # return start, mddidx, mdd
#         return mdd if not inc_date else (mdd, mddidx)
# 
# def guess_freq(index):
#     # admittedly weak way of doing this...This needs to be abolished
#     if isinstance(index, (pd.Series, pd.DataFrame)):
#         index = index.index
# 
#     if hasattr(index, 'freqstr') and index.freqstr:
#         return index.freqstr[0]
#     elif len(index) < 3:
#         raise Exception('cannot guess frequency with less than 3 items')
#     else:
#         lb = min(7, len(index))
#         idx_zip = lambda: zip(index[-lb:-1], index[-(lb-1):])
# 
#         diff = min([t2 - t1 for t1, t2, in idx_zip()])
#         if diff.days <= 1:
#             if 5 in index.dayofweek or 6 in index.dayofweek:
#                 return 'D'
#             else:
#                 return 'B'
#         elif diff.days == 7:
#             return 'W'
#         else:
#             diff = min([t2.month - t1.month for t1, t2, in idx_zip()])
#             if diff == 1:
#                 return 'M'
#             diff = min([t2.year - t1.year for t1, t2, in idx_zip()])
#             if diff == 1:
#                 return 'A'
# 
#             strs = ','.join([i.strftime('%Y-%m-%d') for i in index[-lb:]])
#             raise Exception('unable to determine frequency, last %s dates %s' % (lb, strs))
# 
# Path: tia/util/mplot.py
# class AxesFormat(DeferredExecutionMixin):
#     def __init__(self):
#         super(AxesFormat, self).__init__()
#         self.X = _XAxisFormat(self)
#         self.Y = _YAxisFormat(self)
#         self.axes = None
# 
#     def apply(self, axes=None):
#         self.axes = axes or plt.gca()
#         self.X()
#         self.Y()
#         self()
# 
#     def tight_layout(self, pad=1.08, h_pad=None, w_pad=None, rect=None):
#         plt.tight_layout(pad, h_pad, w_pad, rect)
#         return self
# 
# Path: tia/util/fmt.py
# def new_float_formatter(precision=2, commas=True, parens=True, prefix=None, suffix=None, coerce=True, nan='nan',
#                         trunc_dot_zeros=0):
#     return NumberFormat(**locals())


import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from tia.analysis.perf import returns_cumulative, max_drawdown, guess_freq
from tia.util.mplot import AxesFormat
from tia.util.fmt import new_float_formatter
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:

# Path: tia/analysis/perf.py
# def returns_cumulative(returns, geometric=True, expanding=False):
#     """ return the cumulative return
# 
#     Parameters
#     ----------
#     returns : DataFrame or Series
#     geometric : bool, default is True
#                 If True, geometrically link returns
#     expanding : bool default is False
#                 If True, return expanding series/frame of returns
#                 If False, return the final value(s)
#     """
#     if expanding:
#         if geometric:
#             return (1. + returns).cumprod() - 1.
#         else:
#             return returns.cumsum()
#     else:
#         if geometric:
#             return (1. + returns).prod() - 1.
#         else:
#             return returns.sum()
# 
# def max_drawdown(returns=None, geometric=True, dd=None, inc_date=False):
#     """
#     compute the max draw down.
#     returns: period return Series or DataFrame
#     dd: drawdown Series or DataFrame (mutually exclusive with returns)
#     """
#     if (returns is None and dd is None) or (returns is not None and dd is not None):
#         raise ValueError('returns and drawdowns are mutually exclusive')
# 
#     if returns is not None:
#         dd = drawdowns(returns, geometric=geometric)
# 
#     if isinstance(dd, pd.DataFrame):
#         vals = [max_drawdown(dd=dd[c], inc_date=inc_date) for c in dd.columns]
#         cols = ['maxxdd'] + (inc_date and ['maxdd_dt'] or [])
#         res = pd.DataFrame(vals, columns=cols, index=dd.columns)
#         return res if inc_date else res.maxdd
#     else:
#         mddidx = dd.idxmin()
#         # if mddidx == dd.index[0]:
#         # # no maxff
#         #    return 0 if not inc_date else (0, None)
#         #else:
#         sub = dd[:mddidx]
#         start = sub[::-1].idxmax()
#         mdd = dd[mddidx]
#         # return start, mddidx, mdd
#         return mdd if not inc_date else (mdd, mddidx)
# 
# def guess_freq(index):
#     # admittedly weak way of doing this...This needs to be abolished
#     if isinstance(index, (pd.Series, pd.DataFrame)):
#         index = index.index
# 
#     if hasattr(index, 'freqstr') and index.freqstr:
#         return index.freqstr[0]
#     elif len(index) < 3:
#         raise Exception('cannot guess frequency with less than 3 items')
#     else:
#         lb = min(7, len(index))
#         idx_zip = lambda: zip(index[-lb:-1], index[-(lb-1):])
# 
#         diff = min([t2 - t1 for t1, t2, in idx_zip()])
#         if diff.days <= 1:
#             if 5 in index.dayofweek or 6 in index.dayofweek:
#                 return 'D'
#             else:
#                 return 'B'
#         elif diff.days == 7:
#             return 'W'
#         else:
#             diff = min([t2.month - t1.month for t1, t2, in idx_zip()])
#             if diff == 1:
#                 return 'M'
#             diff = min([t2.year - t1.year for t1, t2, in idx_zip()])
#             if diff == 1:
#                 return 'A'
# 
#             strs = ','.join([i.strftime('%Y-%m-%d') for i in index[-lb:]])
#             raise Exception('unable to determine frequency, last %s dates %s' % (lb, strs))
# 
# Path: tia/util/mplot.py
# class AxesFormat(DeferredExecutionMixin):
#     def __init__(self):
#         super(AxesFormat, self).__init__()
#         self.X = _XAxisFormat(self)
#         self.Y = _YAxisFormat(self)
#         self.axes = None
# 
#     def apply(self, axes=None):
#         self.axes = axes or plt.gca()
#         self.X()
#         self.Y()
#         self()
# 
#     def tight_layout(self, pad=1.08, h_pad=None, w_pad=None, rect=None):
#         plt.tight_layout(pad, h_pad, w_pad, rect)
#         return self
# 
# Path: tia/util/fmt.py
# def new_float_formatter(precision=2, commas=True, parens=True, prefix=None, suffix=None, coerce=True, nan='nan',
#                         trunc_dot_zeros=0):
#     return NumberFormat(**locals())


# Path: tia/analysis/plots.py
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from tia.analysis.perf import returns_cumulative, max_drawdown, guess_freq
from tia.util.mplot import AxesFormat
from tia.util.fmt import new_float_formatter

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]