Esempio n. 1
0
def plottingMonthlyRetDist(returns, ax, title="Distribution of Monthly Returns"):
    x_axis_formatter = FuncFormatter(zero_dec_percentage)
    ax.xaxis.set_major_formatter(FuncFormatter(x_axis_formatter))
    ax.tick_params(axis='x', which='major', labelsize=10)

    monthlyRetTable = aggregateReturns(returns, 'monthly')
    monthlyRetTable = np.exp(monthlyRetTable) - 1.

    if len(monthlyRetTable) > 1:
        ax.hist(
            monthlyRetTable,
            color='orange',
            alpha=0.8,
            bins=20
        )

    ax.axvline(
        monthlyRetTable.mean(),
        color='steelblue',
        linestyle='--',
        lw=4,
        alpha=1.0
    )

    ax.axvline(0.0, color='black', linestyle='-', lw=3, alpha=0.75)
    ax.legend(['mean'], loc='best')
    ax.set_ylabel('Number of months')
    ax.set_xlabel('Returns')
    ax.set_title(title)
    return ax
Esempio n. 2
0
def plottingAnnualReturns(returns, ax, title='Annual Returns'):
    x_axis_formatter = FuncFormatter(zero_dec_percentage)
    ax.xaxis.set_major_formatter(FuncFormatter(x_axis_formatter))
    ax.tick_params(axis='x', which='major', labelsize=10)

    annulaReturns = pd.DataFrame(aggregateReturns(returns, 'yearly'))
    annulaReturns = np.exp(annulaReturns) - 1.

    ax.axvline(annulaReturns.values.mean(),
               color='steelblue',
               linestyle='--',
               lw=4,
               alpha=0.7)

    annulaReturns.sort_index(ascending=False).plot(
        ax=ax,
        kind='barh',
        alpha=0.7
    )

    ax.axvline(0.0, color='black', linestyle='-', lw=3)

    ax.set_ylabel('Year')
    ax.set_xlabel('Returns')
    ax.set_title(title)
    ax.legend(['mean'], loc='best')
    return ax
Esempio n. 3
0
def plottingMonthlyRetDist(returns,
                           ax,
                           title="Distribution of Monthly Returns"):
    x_axis_formatter = FuncFormatter(zero_dec_percentage)
    ax.xaxis.set_major_formatter(FuncFormatter(x_axis_formatter))
    ax.tick_params(axis='x', which='major', labelsize=10)

    monthlyRetTable = aggregateReturns(returns, 'monthly')
    monthlyRetTable = np.exp(monthlyRetTable) - 1.

    if len(monthlyRetTable) > 1:
        ax.hist(
            monthlyRetTable,
            color='orange',
            alpha=0.8,
            bins=20
        )

    ax.axvline(
        monthlyRetTable.mean(),
        color='steelblue',
        linestyle='--',
        lw=4,
        alpha=1.0
    )

    ax.axvline(0.0, color='black', linestyle='-', lw=3, alpha=0.75)
    ax.legend(['mean'], loc='best')
    ax.set_ylabel('Number of months')
    ax.set_xlabel('Returns')
    ax.set_title(title)
    return ax
Esempio n. 4
0
def plottingAnnualReturns(returns, ax, title='Annual Returns'):
    x_axis_formatter = FuncFormatter(zero_dec_percentage)
    ax.xaxis.set_major_formatter(FuncFormatter(x_axis_formatter))
    ax.tick_params(axis='x', which='major', labelsize=10)

    annulaReturns = pd.DataFrame(aggregateReturns(returns, 'yearly'))
    annulaReturns = np.exp(annulaReturns) - 1.

    ax.axvline(annulaReturns.values.mean(),
               color='steelblue',
               linestyle='--',
               lw=4,
               alpha=0.7)

    annulaReturns.sort_index(ascending=False).plot(
        ax=ax,
        kind='barh',
        alpha=0.7
    )

    ax.axvline(0.0, color='black', linestyle='-', lw=3)

    ax.set_ylabel('Year')
    ax.set_xlabel('Returns')
    ax.set_title(title)
    ax.legend(['mean'], loc='best')
    return ax
Esempio n. 5
0
def plottingMonthlyReturnsHeapmap(returns, ax, title='Monthly Returns (%)'):
    x_axis_formatter = FuncFormatter(integer_format)
    ax.xaxis.set_major_formatter(FuncFormatter(x_axis_formatter))
    monthlyRetTable = pd.DataFrame(aggregateReturns(returns, 'monthly'))
    monthlyRetTable = monthlyRetTable.unstack()
    monthlyRetTable.columns = monthlyRetTable.columns.droplevel()
    sns.heatmap((np.exp(monthlyRetTable.fillna(0)) - 1.0) * 100.0,
                annot=True,
                fmt=".1f",
                annot_kws={"size": 9},
                alpha=1.0,
                center=0.0,
                cbar=False,
                cmap=matplotlib.cm.RdYlGn_r,
                ax=ax)
    ax.set_ylabel('Year')
    ax.set_xlabel('Month')
    ax.set_title(title)
    return ax
Esempio n. 6
0
def plottingMonthlyReturnsHeapmap(returns, ax, title='Monthly Returns (%)'):
    x_axis_formatter = FuncFormatter(integer_format)
    ax.xaxis.set_major_formatter(FuncFormatter(x_axis_formatter))
    monthlyRetTable = pd.DataFrame(aggregateReturns(returns, 'monthly'))
    monthlyRetTable = monthlyRetTable.unstack()
    monthlyRetTable.columns = monthlyRetTable.columns.droplevel()
    sns.heatmap((np.exp(monthlyRetTable.fillna(0)) - 1.0) * 100.0,
                annot=True,
                fmt=".1f",
                annot_kws={"size": 9},
                alpha=1.0,
                center=0.0,
                cbar=False,
                cmap=matplotlib.cm.RdYlGn_r,
                ax=ax)
    ax.set_ylabel('Year')
    ax.set_xlabel('Month')
    ax.set_title(title)
    return ax
Esempio n. 7
0
def createPerformanceTearSheet(prices=None, returns=None, benchmark=None, benchmarkReturns=None, plot=True):

    if prices is not None and not isinstance(prices, pd.Series):
        raise TypeError("prices series should be a pandas time series.")
    elif returns is not None and prices is not None:
        raise ValueError("prices series and returns series can't be both set.")

    if benchmark is not None and not (isinstance(benchmark, pd.Series) or isinstance(benchmark, str)):
        raise TypeError("benchmark series should be a pandas time series or a string ticker.")

    if returns is None:
        returns = np.log(prices / prices.shift(1))
        returns.fillna(0, inplace=True)
        returns = returns[~np.isinf(returns)]

    if benchmark is not None and isinstance(benchmark, str) and benchmarkReturns is None:
        startDate = advanceDateByCalendar("China.SSE", prices.index[0], '-1b', BizDayConventions.Preceding)

        benchmarkPrices = get_benchmark_data(benchmark,
                                             start_date=startDate.strftime('%Y-%m-%d'),
                                             end_data=returns.index[-1].strftime("%Y-%m-%d"))

        # do the linear interpolation on the target time line
        date_index = prices.index
        new_index = benchmarkPrices.index.union(date_index)
        benchmarkPrices = benchmarkPrices.reindex(new_index)
        benchmarkPrices = benchmarkPrices.interpolate().ix[date_index].dropna()

        benchmarkReturns = np.log(benchmarkPrices['closePrice'] / benchmarkPrices['closePrice'].shift(1))
        benchmarkReturns.name = benchmark
        benchmarkReturns.fillna(0, inplace=True)
        benchmarkReturns.index = pd.to_datetime(benchmarkReturns.index.date)
    elif benchmark is not None and isinstance(benchmark, pd.Series):
        benchmarkReturns = np.log(benchmark / benchmark.shift(1))
        try:
            benchmarkReturns.name = benchmark.name
        except AttributeError:
            benchmarkReturns.name = "benchmark"
        benchmarkReturns.dropna(inplace=True)
        benchmarkReturns.index = pd.to_datetime(benchmarkReturns.index.date)

    aggregateDaily = aggregateReturns(returns)
    drawDownDaily = drawDown(aggregateDaily)

    # perf metric
    annualRet = annualReturn(aggregateDaily)
    annualVol = annualVolatility(aggregateDaily)
    sortino = sortinoRatio(aggregateDaily)
    sharp = sharpRatio(aggregateDaily)
    maxDrawDown = np.min(drawDownDaily['draw_down'])
    winningDays = np.sum(aggregateDaily > 0.)
    lossingDays = np.sum(aggregateDaily < 0.)

    perf_metric = pd.DataFrame([annualRet, annualVol, sortino, sharp, maxDrawDown, winningDays, lossingDays],
                                index=['annual_return',
                                       'annual_volatiltiy',
                                       'sortino_ratio',
                                       'sharp_ratio',
                                       'max_draw_down',
                                       'winning_days',
                                       'lossing_days'],
                                columns=['metrics'])

    perf_df = pd.DataFrame(index=aggregateDaily.index)
    perf_df['daily_return'] = aggregateDaily
    perf_df['daily_cum_return'] = np.exp(aggregateDaily.cumsum()) - 1.0
    perf_df['daily_draw_down'] = drawDownDaily['draw_down']

    if benchmarkReturns is not None:
        perf_df['benchmark_return'] = benchmarkReturns
        perf_df['benchmark_cum_return'] = benchmarkReturns.cumsum()
        perf_df.dropna(inplace=True)
        perf_df['benchmark_cum_return'] = np.exp(perf_df['benchmark_cum_return']
                                                     - perf_df['benchmark_cum_return'][0]) - 1.0
        perf_df['access_return'] = aggregateDaily - benchmarkReturns
        perf_df['access_cum_return'] = (1.0 + perf_df['daily_cum_return']) \
                                           / (1.0 + perf_df['benchmark_cum_return']) - 1.0
        perf_df.fillna(0.0, inplace=True)
        accessDrawDownDaily = drawDown(perf_df['access_return'])
    else:
        accessDrawDownDaily = None

    if 'benchmark_cum_return' in perf_df:
        benchmarkCumReturns = perf_df['benchmark_cum_return']
        benchmarkCumReturns.name = benchmarkReturns.name
        accessCumReturns = perf_df['access_cum_return']
        accessReturns = perf_df['access_return']

        index = perf_df.index

        length1 = len(bizDatesList('China.SSE', index[0], index[-1]))
        length2 = len(perf_df)
        factor = length1 / float(length2)

        rb = RollingBeta(perf_df['daily_return'], perf_df['benchmark_return'], [1, 3, 6], factor=factor)
        rs = RollingSharp(perf_df['daily_return'], [1, 3, 6], factor=factor)
    else:
        benchmarkCumReturns = None
        accessReturns = None
        accessCumReturns = None

    if len(perf_df['daily_return']) > APPROX_BDAYS_PER_MONTH and benchmarkCumReturns is not None:
        rollingRisk = pd.concat([pd.concat(rs, axis=1), pd.concat(rb, axis=1)], axis=1)
    else:
        rollingRisk = None

    if plot:
        verticalSections = 2
        plt.figure(figsize=(16, 7 * verticalSections))
        gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)

        axRollingReturns = plt.subplot(gs[0, :])
        axDrawDown = plt.subplot(gs[1, :], sharex=axRollingReturns)

        plottingRollingReturn(perf_df['daily_cum_return'], benchmarkCumReturns, axRollingReturns)
        plottingDrawdownPeriods(perf_df['daily_cum_return'], drawDownDaily, 5, axDrawDown)

        if rollingRisk is not None:
            plt.figure(figsize=(16, 7 * verticalSections))
            gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)
            axRollingBeta = plt.subplot(gs[0, :])
            axRollingSharp = plt.subplot(gs[1, :])

            bmName = benchmarkReturns.name
            plottingRollingBeta(rb, bmName, ax=axRollingBeta)
            plottingRollingSharp(rs, ax=axRollingSharp)

        plt.figure(figsize=(16, 7 * verticalSections))
        gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)

        axUnderwater = plt.subplot(gs[0, :])
        axMonthlyHeatmap = plt.subplot(gs[1, 0])
        axAnnualReturns = plt.subplot(gs[1, 1])
        axMonthlyDist = plt.subplot(gs[1, 2])

        plottingUnderwater(drawDownDaily['draw_down'], axUnderwater)
        plottingMonthlyReturnsHeapmap(returns, axMonthlyHeatmap)
        plottingAnnualReturns(returns, axAnnualReturns)
        plottingMonthlyRetDist(returns, axMonthlyDist)

    if accessReturns is not None and plot:
         plt.figure(figsize=(16, 7 * verticalSections))
         gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)
         axRollingAccessReturns = plt.subplot(gs[0, :])
         axAccessDrawDown = plt.subplot(gs[1, :], sharex=axRollingAccessReturns)
         plottingRollingReturn(accessCumReturns, None, axRollingAccessReturns, title='Access Cumulative Returns w.r.t. ' + benchmarkReturns.name)
         plottingDrawdownPeriods(accessCumReturns, accessDrawDownDaily, 5, axAccessDrawDown, title=('Top 5 Drawdown periods w.r.t. ' + benchmarkReturns.name))

         plt.figure(figsize=(16, 7 * verticalSections))
         gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)

         axAccessUnderwater = plt.subplot(gs[0, :])
         axAccessMonthlyHeatmap = plt.subplot(gs[1, 0])
         axAccessAnnualReturns = plt.subplot(gs[1, 1])
         axAccessMonthlyDist = plt.subplot(gs[1, 2])

         plottingUnderwater(accessDrawDownDaily['draw_down'], axAccessUnderwater, title='Underwater Plot w.r.t. '
                                                                                        + benchmarkReturns.name)
         plottingMonthlyReturnsHeapmap(accessReturns, ax=axAccessMonthlyHeatmap, title='Monthly Access Returns (%)')
         plottingAnnualReturns(accessReturns, ax=axAccessAnnualReturns, title='Annual Access Returns')
         plottingMonthlyRetDist(accessReturns, ax=axAccessMonthlyDist, title='Distribution of Monthly Access Returns')

    return perf_metric, perf_df, rollingRisk
Esempio n. 8
0
def createPerformanceTearSheet(prices=None,
                               returns=None,
                               benchmark=None,
                               benchmarkReturns=None,
                               other_curves=None,
                               turn_over=None,
                               tc_cost=0.,
                               plot=True):

    if prices is not None and not isinstance(prices, pd.Series):
        raise TypeError("prices series should be a pandas time series.")
    elif returns is not None and prices is not None:
        raise ValueError("prices series and returns series can't be both set.")

    if benchmark is not None and not (isinstance(benchmark, pd.Series) or isinstance(benchmark, str)):
        raise TypeError("benchmark series should be a pandas time series or a string ticker.")

    if returns is None:
        returns = np.log(prices / prices.shift(1))
        returns.fillna(0, inplace=True)
        returns = returns[~np.isinf(returns)]

    if benchmark is not None and isinstance(benchmark, str) and benchmarkReturns is None:
        startDate = advanceDateByCalendar("China.SSE", prices.index[0], '-1b', BizDayConventions.Preceding)

        benchmarkPrices = get_benchmark_data(benchmark,
                                             start_date=startDate.strftime('%Y-%m-%d'),
                                             end_data=returns.index[-1].strftime("%Y-%m-%d"))

        # do the linear interpolation on the target time line
        date_index = prices.index
        new_index = benchmarkPrices.index.union(date_index)
        benchmarkPrices = benchmarkPrices.reindex(new_index)
        benchmarkPrices = benchmarkPrices.interpolate().ix[date_index].dropna()

        benchmarkReturns = np.log(benchmarkPrices['closePrice'] / benchmarkPrices['closePrice'].shift(1))
        benchmarkReturns.name = benchmark
        benchmarkReturns.fillna(0, inplace=True)
        benchmarkReturns.index = pd.to_datetime(benchmarkReturns.index.date)
    elif benchmark is not None and isinstance(benchmark, pd.Series):
        benchmarkReturns = np.log(benchmark / benchmark.shift(1))
        try:
            benchmarkReturns.name = benchmark.name
        except AttributeError:
            benchmarkReturns.name = "benchmark"
        benchmarkReturns.dropna(inplace=True)
        benchmarkReturns.index = pd.to_datetime(benchmarkReturns.index.date)

    aggregateDaily, aggregateDailyAfterTC = aggregateReturns(returns, turn_over, tc_cost)

    if aggregateDailyAfterTC is not None:
        aggregateDailyBeforeTC = aggregateDaily
        aggregateDaily = aggregateDailyAfterTC
    else:
        aggregateDailyBeforeTC = aggregateDaily

    drawDownDaily = drawDown(aggregateDaily)

    # perf metric
    annualRet = annualReturn(aggregateDaily)
    annualVol = annualVolatility(aggregateDaily)
    sortino = sortinoRatio(aggregateDaily)
    sharp = sharpRatio(aggregateDaily)
    maxDrawDown = np.min(drawDownDaily['draw_down'])
    winningDays = np.sum(aggregateDaily > 0.)
    lossingDays = np.sum(aggregateDaily < 0.)

    perf_metric = pd.DataFrame([annualRet, annualVol, sortino, sharp, maxDrawDown, winningDays, lossingDays],
                                index=['annual_return',
                                       'annual_volatiltiy',
                                       'sortino_ratio',
                                       'sharp_ratio',
                                       'max_draw_down',
                                       'winning_days',
                                       'lossing_days'],
                                columns=['metrics'])

    perf_df = pd.DataFrame(index=aggregateDaily.index)
    perf_df['daily_return'] = aggregateDaily
    perf_df['daily_return (w/o tc)'] = aggregateDailyBeforeTC
    perf_df['daily_cum_return'] = np.exp(aggregateDaily.cumsum()) - 1.0
    perf_df['daily_cum_return (w/o tc)'] = np.exp(aggregateDailyBeforeTC.cumsum()) - 1.0
    perf_df['daily_draw_down'] = drawDownDaily['draw_down']

    if benchmarkReturns is not None:
        perf_df['benchmark_return'] = benchmarkReturns
        perf_df['benchmark_cum_return'] = benchmarkReturns.cumsum()
        perf_df.fillna(0.0, inplace=True)
        perf_df['benchmark_cum_return'] = np.exp(perf_df['benchmark_cum_return']
                                                 - perf_df['benchmark_cum_return'][0]) - 1.0
        perf_df['access_return'] = aggregateDaily - perf_df['benchmark_return']
        perf_df['access_cum_return'] = (1.0 + perf_df['daily_cum_return']) \
                                       / (1.0 + perf_df['benchmark_cum_return']) - 1.0
        accessDrawDownDaily = drawDown(perf_df['access_return'])
    else:
        accessDrawDownDaily = None

    if 'benchmark_cum_return' in perf_df:
        benchmarkCumReturns = perf_df['benchmark_cum_return']
        benchmarkCumReturns.name = benchmarkReturns.name
        accessCumReturns = perf_df['access_cum_return']
        accessReturns = perf_df['access_return']

        index = perf_df.index

        length1 = len(bizDatesList('China.SSE', index[0], index[-1]))
        length2 = len(perf_df)
        factor = length1 / float(length2)

        rb = RollingBeta(perf_df['daily_return'], perf_df['benchmark_return'], [1, 3, 6], factor=factor)
        rs = RollingSharp(perf_df['daily_return'], [1, 3, 6], factor=factor)
    else:
        benchmarkCumReturns = None
        accessReturns = None
        accessCumReturns = None

    if len(perf_df['daily_return']) > APPROX_BDAYS_PER_MONTH and benchmarkCumReturns is not None:
        rollingRisk = pd.concat([pd.concat(rs, axis=1), pd.concat(rb, axis=1)], axis=1)
    else:
        rollingRisk = None

    if plot:
        verticalSections = 2
        plt.figure(figsize=(16, 7 * verticalSections))
        gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)

        axRollingReturns = plt.subplot(gs[0, :])
        axDrawDown = plt.subplot(gs[1, :])

        plottingRollingReturn(perf_df['daily_cum_return'],
                              perf_df['daily_cum_return (w/o tc)'],
                              benchmarkCumReturns,
                              other_curves, axRollingReturns)
        plottingDrawdownPeriods(perf_df['daily_cum_return'], drawDownDaily, 5, axDrawDown)

        if rollingRisk is not None:
            plt.figure(figsize=(16, 7 * verticalSections))
            gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)
            axRollingBeta = plt.subplot(gs[0, :])
            axRollingSharp = plt.subplot(gs[1, :])

            bmName = benchmarkReturns.name
            plottingRollingBeta(rb, bmName, ax=axRollingBeta)
            plottingRollingSharp(rs, ax=axRollingSharp)

        plt.figure(figsize=(16, 7 * verticalSections))
        gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)

        axUnderwater = plt.subplot(gs[0, :])
        axMonthlyHeatmap = plt.subplot(gs[1, 0])
        axAnnualReturns = plt.subplot(gs[1, 1])
        axMonthlyDist = plt.subplot(gs[1, 2])

        plottingUnderwater(drawDownDaily['draw_down'], axUnderwater)
        plottingMonthlyReturnsHeapmap(aggregateDaily, axMonthlyHeatmap)
        plottingAnnualReturns(aggregateDaily, axAnnualReturns)
        plottingMonthlyRetDist(aggregateDaily, axMonthlyDist)

    if accessReturns is not None and plot:
         plt.figure(figsize=(16, 7 * verticalSections))
         gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)
         axRollingAccessReturns = plt.subplot(gs[0, :])
         axAccessDrawDown = plt.subplot(gs[1, :], sharex=axRollingAccessReturns)
         plottingRollingReturn(accessCumReturns, None, None, None, axRollingAccessReturns, title='Access Cumulative Returns w.r.t. ' + benchmarkReturns.name)
         plottingDrawdownPeriods(accessCumReturns, accessDrawDownDaily, 5, axAccessDrawDown, title=('Top 5 Drawdown periods w.r.t. ' + benchmarkReturns.name))

         plt.figure(figsize=(16, 7 * verticalSections))
         gs = gridspec.GridSpec(verticalSections, 3, wspace=0.5, hspace=0.5)

         axAccessUnderwater = plt.subplot(gs[0, :])
         axAccessMonthlyHeatmap = plt.subplot(gs[1, 0])
         axAccessAnnualReturns = plt.subplot(gs[1, 1])
         axAccessMonthlyDist = plt.subplot(gs[1, 2])

         plottingUnderwater(accessDrawDownDaily['draw_down'], axAccessUnderwater, title='Underwater Plot w.r.t. '
                                                                                        + benchmarkReturns.name)
         plottingMonthlyReturnsHeapmap(accessReturns, ax=axAccessMonthlyHeatmap, title='Monthly Access Returns (%)')
         plottingAnnualReturns(accessReturns, ax=axAccessAnnualReturns, title='Annual Access Returns')
         plottingMonthlyRetDist(accessReturns, ax=axAccessMonthlyDist, title='Distribution of Monthly Access Returns')

    return perf_metric, perf_df, rollingRisk