Esempio n. 1
0
    def __test_returns(self):
        p = Performance()
        df = pd.DataFrame(index=pd.date_range('2010-01-01', periods=10),
                          columns=[
                              'returns',
                          ])
        df['returns'] = [
            0.1, 0.1, 0.1, -0.156, -0.1, 0.1, 0.1, 0.1, -0.11, -0.1
        ]
        #print(df)
        r = df['returns']

        ret = p.calc_period_return(r)
        ret_annual = p.calc_annual_return(r)
        print(stats.cum_returns_final(r))

        #收益率
        self.assertEqual(ret, stats.cum_returns_final(r))
        self.assertEqual(ret_annual, stats.annual_return(r))

        #print('标准差-年化波动率',)
        #print(stats.annual_volatility(df['returns']))

        #波动率,夏普比
        self.assertEqual(p.calc_volatility(r), stats.annual_volatility(r))
        self.assertEqual(p.calc_sharpe(r), stats.sharpe_ratio(r))
Esempio n. 2
0
def ret_vol_combos(ret1, ret2, nsteps, period='monthly', rebal_period=3):
    """Return and volatility that results from combining two return series in proportions from 0 to 100%.

    Args:
     - ret1: return series 1 (sequence of period returns, such as output by computePortfolioReturns())
     - ret2: return series 2
     - nsteps: number of steps to take in allocation to the returns, between 0 and 100%
     - period: return interval in `ret1`, `ret2`: {'daily', 'weekly', 'monthly'}
     - rebal_period: interval for rebalancing the allocation; expressed as number of periods of type `period`

     Return:
      - Dataframe with results for each allocation between 0 and 100%
        - annualized return
        - annualized standard deviation
        - annualized downside deviation
      - Date range of returns used for these results
    """
    # convert period returns to wr's
    ret1 = ret1.copy() + 1
    ret2 = ret2.copy() + 1

    # combine the two return sequences
    combined = pd.concat([ret1, ret2], axis=1, join='inner')
    # Note: the concat/join ensures we have the same date range for both return sequences;
    # computing the date range here ensures that it accurately reflects dates to compute results
    date_range = DateRange(
        min(combined.index).date(),
        max(combined.index).date())

    stepsize = 1 / nsteps
    return_list = []
    vol_list = []
    downside_list = []
    w1_list = []
    for ix in range(nsteps + 1):
        w1 = 1 - ix * stepsize
        w2 = ix * stepsize
        res = rfp.pf_period_returns(combined, [w1, w2], rebal_period,
                                    f'combined_{w1:4.2}')
        # print(res.head())
        ann_ret = estats.annual_return(res.values, period=period)
        ann_vol = estats.annual_volatility(res.values, period=period)
        ann_downside = estats.downside_risk(
            res.values,
            period=period)  # option to add `required_return` parameter
        #print(w1, w2, ann_ret, ann_vol)
        return_list.append(ann_ret[0])
        vol_list.append(ann_vol[0])
        downside_list.append(ann_downside[0])
        w1_list.append(w1)

    df = pd.DataFrame({
        'w1': w1_list,
        'ann_ret': return_list,
        'standard_dev': vol_list,
        'downside_dev': downside_list
    })
    return df, date_range
Esempio n. 3
0
    def get_summary(self, freq='m'):
        if freq == 'm':
            monthlyRet = self.MonthlyRet(False)
            monthlyBenchmarkRet = self.BenchmarkMonthlyRet()
            hedgeMonthlyRet = self.MonthlyRet()

            _dict = {
                'annual_return':
                stats.annual_return(hedgeMonthlyRet, annualization=12),
                'annual_vol':
                stats.annual_volatility(hedgeMonthlyRet, annualization=12),
                'IR':
                stats.information_ratio(monthlyRet, monthlyBenchmarkRet),
                't_stats':
                stats_scp.ttest_1samp(hedgeMonthlyRet, 0)[0],
                'win_rate':
                stats.win_rate(monthlyRet, monthlyBenchmarkRet),
                'max_drawdown':
                stats.max_drawdown(hedgeMonthlyRet),
                'drawn_down_start':
                pf.timeseries.get_top_drawdowns(hedgeMonthlyRet, 1)[0][0],
                'draw_down_end':
                pf.timeseries.get_top_drawdowns(hedgeMonthlyRet, 1)[0][1],
            }
        else:
            _dict = {
                'annual_return':
                stats.annual_return(self.activeRet, annualization=12),
                'annual_vol':
                stats.annual_volatility(self.activeRet, annualization=12),
                'IR':
                stats.information_ratio(self.Ret, self.BenchmarkRet),
                't_stats':
                stats_scp.ttest_1samp(self.activeRet, 0)[0],
                'win_rate':
                stats.win_rate(self.Ret, self.BenchmarkRet),
                'max_drawdown':
                stats.max_drawdown(self.activeRet),
                'drawn_down_start':
                pf.timeseries.get_top_drawdowns(self.activeRet, 1)[0],
                'draw_down_end':
                pf.timeseries.get_top_drawdowns(self.activeRet, 1)[1],
            }
        return pd.Series(_dict)
Esempio n. 4
0
def default_stats_spec(period='weekly', ann_rf_rate=0):
    """Generate specs for some standard statistics, given annual risk-free rate and return period of data."""
    per_rf_rate = _ann_rate_to_period_rate(ann_rf_rate, period)

    stats_spec = {
        'Annual Return':
        lambda x: estats.annual_return(x, period),
        'Max Drawdown':
        estats.max_drawdown,
        'Annual Volatility':
        lambda x: estats.annual_volatility(x, period),
        'Sharpe Ratio':
        lambda x: estats.sharpe_ratio(x, risk_free=per_rf_rate, period=period),
        'Downside Volatility':
        lambda x: estats.downside_risk(x, period=period),
        'Sortino Ratio':
        lambda x: estats.sortino_ratio(x, period=period)
    }
    return stats_spec
Esempio n. 5
0
 def total_performance(self):
     """策略全局表现"""
     win_rate_func = lambda x, y: stats.win_rate(
         x, factor_returns=0, period=y)
     df = pd.DataFrame(
         [[
             self.abs_total_return, self.total_benchmark_return,
             self.rel_total_return
         ],
          [
              self.abs_maxdrawdown,
              stats.max_drawdown(self.benchmark_return),
              self.rel_maxdrawdown
          ],
          [
              self.abs_annual_volatility,
              stats.annual_volatility(self.benchmark_return),
              self.rel_annual_volatility
          ],
          [
              self.abs_annual_return,
              stats.annual_return(self.benchmark_return),
              self.rel_annual_return
          ],
          [
              self.abs_sharp_ratio,
              stats.sharpe_ratio(self.benchmark_return,
                                 simple_interest=True), self.rel_sharp_ratio
          ],
          [
              win_rate_func(self.portfolio_return, 'monthly'),
              win_rate_func(self.benchmark_return, 'monthly'),
              win_rate_func(self.active_return, 'monthly')
          ]],
         columns=['portfolio', 'benchmark', 'hedge'],
         index=[
             'total_return', 'maxdd', 'volatility', 'annual_return',
             'sharp', 'win_rate'
         ])
     return df
def portfolio_performance(weights, daily_returns, overall_returns=None, previous_weights=None):
    """
    Calculates performance of a portfolio
    """
    returns = np.matmul(daily_returns, weights)
    # Add statistics present in SIMPLE_STAT_FUNCS
    statistics = list([])
    statistics.append(stats.annual_return(returns))
    statistics.append(stats.annual_volatility(returns))
    statistics.append(nan_to_zero(stats.sharpe_ratio(returns)))
    statistics.append(stats.sortino_ratio(returns))
    statistics.append(stats.omega_ratio(returns))
    statistics.append(stats.calmar_ratio(returns))
    statistics.append(stats.tail_ratio(returns))
    statistics.append(ssd(returns))
    statistics.append(scipy.stats.skew(returns))
    statistics.append(scipy.stats.kurtosis(returns))
    statistics.append(turnover(weights, previous_weights))

    if overall_returns is not None:
        overall_returns.extend(returns)
    return statistics
Esempio n. 7
0
    def calc(self, df):
        print('计算绩效')
        df['equity'] = (df['returns'] + 1).cumprod()
        df['bench_equity'] = (df['bench_returns'] + 1).cumprod()

        self.period_return = df['equity'][-1] - 1
        self.benchmark_return = df['bench_equity'][-1] - 1

        self.trading_days = len(df)  #交易天数
        self.annu_return = self.period_return * 252 / self.trading_days
        self.bench_annu_return = self.benchmark_return * 252 / self.trading_days

        # 波动率
        self.volatility = stats.annual_volatility(df['returns'])

        # 夏普比率
        self.sharpe = stats.sharpe_ratio(df['returns'])
        # 最大回撤
        self.max_drawdown = stats.max_drawdown(df['returns'].values)

        #信息比率
        # self.information = stats.information_ratio(df['returns'].values,df['benchmark_returns'].values)

        self.alpha, self.beta = stats.alpha_beta_aligned(
            df['returns'].values, df['bench_returns'].values)

        return {
            'returns': self.period_return,
            'annu_returns': self.annu_return,
            'bench_returns': self.benchmark_return,
            'bench_annu_returns': self.bench_annu_return,
            'trading_days': self.trading_days,
            'max_drawdown': self.max_drawdown,
            'volatility': self.volatility,
            'sharpe': self.sharpe,
            'alpha': self.alpha,
            'beta': self.beta
        }
Esempio n. 8
0
 def AnnualVol(self, hedge=True):
     ret = self.activeRet if hedge else self.Ret
     return stats.annual_volatility(ret, period=self.Freq)
Esempio n. 9
0
 def rel_annual_volatility(self):
     return stats.annual_volatility(self.active_return)
Esempio n. 10
0
 def abs_annual_volatility(self):
     return stats.annual_volatility(self.portfolio_return)