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))
def rel_yearly_performance(self): idx = GetDatetimeLastDayOfYear(self.active_return.index) gfunc = lambda x: x.year df = self.active_return.groupby(gfunc).agg({ 'cum_return': lambda x: stats.cum_returns_final( self.portfolio_return.reindex(x.index)), 'benchmark_return': lambda x: stats.cum_returns_final( self.benchmark_return.reindex(x.index)), 'volatility': lambda x: np.std(x, ddof=1) * 250**0.5, 'sharp_ratio': lambda x: stats.sharpe_ratio(x, simple_interest=True), 'maxdd': stats.max_drawdown, 'IR': partial(stats.information_ratio, factor_returns=0), 'monthly_win_rate': partial(stats.win_rate, factor_returns=0, period='monthly'), 'weekly_win_rate': partial(stats.win_rate, factor_returns=0, period='weekly'), 'daily_win_rate': partial(stats.win_rate, factor_returns=0, period='daily') }) df.insert(2, 'active_return', df['cum_return'] - df['benchmark_return']) df.index = idx return df
def abs_yearly_performance(self): idx = GetDatetimeLastDayOfYear(self.portfolio_return.index) gfunc = lambda x: x.year df = self.portfolio_return.groupby(gfunc).agg({ 'cum_return': (lambda x: stats.cum_returns_final( self.portfolio_return.reindex(x.index)) - stats. cum_returns_final(self.benchmark_return.reindex(x.index))), 'volatility': lambda x: np.std(x, ddof=1) * 250**0.5, 'sharp_ratio': lambda x: stats.sharpe_ratio(x, simple_interest=True), 'maxdd': stats.max_drawdown, 'IR': lambda x: stats.information_ratio(x, self.benchmark_return), 'monthly_win_rate': lambda x: stats.win_rate(x, self.benchmark_return, 'monthly'), 'weekly_win_rate': lambda x: stats.win_rate(x, self.benchmark_return, 'weekly'), 'daily_win_rate': lambda x: stats.win_rate(x, self.benchmark_return, 'daily') }) df.index = idx return df
def rel_yearly_performance(self): func_dict = { 'cum_return': lambda x: stats.cum_returns_final( self.portfolio_ret.reindex(x.index)), 'benchmark_return': lambda x: stats.cum_returns_final( self.benchmark_ret.reindex(x.index)), 'volatility': lambda x: np.std(x, ddof=1) * 250**0.5, 'sharp_ratio': lambda x: stats.sharpe_ratio(x, simple_interest=True), 'maxdd': stats.max_drawdown, 'IR': partial(stats.information_ratio, factor_returns=0), 'monthly_win_rate': partial(stats.win_rate, factor_returns=0, period='monthly'), 'weekly_win_rate': partial(stats.win_rate, factor_returns=0, period='weekly'), 'daily_win_rate': partial(stats.win_rate, factor_returns=0, period='daily') } df = resample_func(self.active_return, convert_to='1y', func=func_dict) df.insert(2, 'active_return', df['cum_return'] - df['benchmark_return']) return df
def portfolio_performance_comparison_with_index(weights, daily_returns, index_weights, index_daily_returns, overall_returns=None, overall_index_returns=None, previous_weights=None): """ Performance of a portfolio compared with index returns """ statistics = portfolio_performance(weights, daily_returns, overall_returns, previous_weights=previous_weights) returns = np.matmul(daily_returns, weights) index_statistics = portfolio_performance(index_weights, index_daily_returns, overall_index_returns) index_returns = np.matmul(index_daily_returns, index_weights) index_returns = np.reshape(index_returns, returns.shape) # Add statistics present in COMPARATIVE_STAT_FUNCS comparative_statistics = list([]) comparative_statistics.append(nan_to_zero(stats.sharpe_ratio(returns)) - stats.sharpe_ratio(index_returns)) comparative_statistics.append(nan_to_zero(stats.sortino_ratio(returns)) - stats.sortino_ratio(index_returns)) comparative_statistics.append(nan_to_zero(stats.omega_ratio(returns)) - stats.omega_ratio(index_returns)) comparative_statistics.append(nan_to_zero(stats.calmar_ratio(returns)) - stats.calmar_ratio(index_returns)) comparative_statistics.append(nan_to_zero(stats.tail_ratio(returns)) - stats.tail_ratio(index_returns)) comparative_statistics.append(nan_to_zero(ssd(returns)) - nan_to_zero(ssd(index_returns))) comparative_statistics.append(stats.alpha(returns, index_returns)) comparative_statistics.append(stats.beta(returns, index_returns)) comparative_statistics.append(tracking_error(returns, index_returns) * np.sqrt(parameters.DAYS_IN_YEAR)) comparative_statistics.append(stats.excess_sharpe(returns, index_returns) * np.sqrt(parameters.DAYS_IN_YEAR)) comparative_statistics.append(np.count_nonzero(weights)) statistics.extend(comparative_statistics) return statistics, index_statistics
def YearlyPerformance(self): monthlyRet = self.MonthlyRet(False) # 单边做多模型月度收益率 benchmarkMonthlyRet = self.BenchmarkMonthlyRet() hedgeMonthlyRet = self.MonthlyRet(True) # 对冲组合月收益率 a = stats.aggregate_returns(monthlyRet, 'yearly') # 多头组合分年收益 b = stats.aggregate_returns(benchmarkMonthlyRet, 'yearly') # 基准组合分年收益 _l = [] for i, year in enumerate(a.index): hedgeMonthlyRet_current_year = hedgeMonthlyRet.ix[str(year)] monthlyRet_current_year = monthlyRet.ix[str(year)] benchmarkMonthlyRet_current_year = benchmarkMonthlyRet.ix[str( year)] hdSharp_current_year = stats.sharpe_ratio( hedgeMonthlyRet_current_year, annualization=12) hdMaxDown_current_year = stats.max_drawdown( hedgeMonthlyRet_current_year) hdReturn_current_year = stats.annual_return( hedgeMonthlyRet_current_year, annualization=12) hdWinRate_current_year = stats.win_rate( monthlyRet_current_year, benchmarkMonthlyRet_current_year) _l.append([ hdSharp_current_year, hdReturn_current_year, hdMaxDown_current_year, hdWinRate_current_year ]) # 计算全年收益表现 hdSharp_all = stats.sharpe_ratio(hedgeMonthlyRet, annualization=12) hdMaxDown_all = stats.max_drawdown(hedgeMonthlyRet) hdReturn_all = stats.annual_return(hedgeMonthlyRet, annualization=12) hdWinRate_all = stats.win_rate(hedgeMonthlyRet, benchmarkMonthlyRet) _l.append([hdSharp_all, hdReturn_all, hdMaxDown_all, hdWinRate_all]) result = pd.DataFrame(_l, columns=['夏普比率', '年化收益', '最大回撤', '胜率'], index=list(a.index) + ['All']) return result
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
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
def abs_yearly_performance(self): func_dict = { 'cum_return': lambda x: stats.cum_returns_final( self.portfolio_ret.reindex(x.index)), 'volatility': lambda x: np.std(x, ddof=1) * 250**0.5, 'sharp_ratio': lambda x: stats.sharpe_ratio(x, simple_interest=True), 'maxdd': stats.max_drawdown, 'IR': lambda x: stats.information_ratio(x, self.benchmark_ret), 'monthly_win_rate': lambda x: stats.win_rate(x, 0.0, 'monthly'), 'weekly_win_rate': lambda x: stats.win_rate(x, 0.0, 'weekly'), 'daily_win_rate': lambda x: stats.win_rate(x, 0.0, 'daily') } df = resample_func(self.portfolio_ret, convert_to='1y', func=func_dict) return df
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 }
def SharpRatio(self, simple_interest=True, hedge=True): ret = self.activeRet if hedge else self.Ret return stats.sharpe_ratio(ret, risk_free=self.FreeRate, period=self.Freq, simple_interest=simple_interest)
def rel_sharp_ratio(self): return stats.sharpe_ratio(self.active_return, simple_interest=True)
def abs_sharp_ratio(self): return stats.sharpe_ratio(self.portfolio_return, simple_interest=True)