Skip to content

Instantly share code, notes, and snippets.

@masafumimori
Created March 26, 2023 06:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save masafumimori/74bd4cb00bc8115feb6bcaad8ab31b1c to your computer and use it in GitHub Desktop.
Save masafumimori/74bd4cb00bc8115feb6bcaad8ab31b1c to your computer and use it in GitHub Desktop.
import numpy as np
from scipy import stats as scipy_stats
class SharpeRatioCalculator:
"""
A class to calculate various Sharpe Ratio related metrics for a given array of returns.
This class is based on the work from:
https://github.com/rubenbriones/Probabilistic-Sharpe-Ratio
"""
def estimated_sharpe_ratio(self, returns):
"""
Calculate the sample Sharpe Ratio of the given returns.
Args:
returns (numpy.ndarray): The returns of the portfolio.
Returns:
float: The sample Sharpe Ratio.
"""
return returns.mean() / returns.std(ddof=1)
def ann_estimated_sharpe_ratio(self, returns=None, periods=261, *, sr=None):
"""
Calculate the annualized estimated Sharpe Ratio for a given array of returns or a given Sharpe Ratio.
Args:
returns (np.ndarray, optional): The array of returns.
periods (int, optional): The number of periods in a year. Default is 261, assuming daily returns.
sr (float, optional): The Sharpe Ratio to be annualized.
Returns:
float: The annualized estimated Sharpe Ratio.
"""
if sr is None:
sr = self.estimated_sharpe_ratio(returns)
return sr * np.sqrt(periods)
def estimated_sharpe_ratio_stdev(self, returns, *, sr=None):
"""
Calculate the standard deviation of the Sharpe Ratio for the given returns.
Args:
returns (numpy.ndarray): The returns of the portfolio.
sr (float, optional): The precomputed sample Sharpe Ratio. If not provided, it will be calculated.
Returns:
float: The standard deviation of the Sharpe Ratio.
"""
n = len(returns)
skew = scipy_stats.skew(returns)
kurtosis = scipy_stats.kurtosis(returns, fisher=False)
if sr is None:
sr = self.estimated_sharpe_ratio(returns)
sr_std = np.sqrt((1 + (0.5 * skew * sr) - ((kurtosis - 3) / 4) * sr ** 2) / (n - 1))
return sr_std
def probabilistic_sharpe_ratio(self, returns=None, sr_benchmark=0.0, *, sr=None, sr_std=None):
"""
Calculate the Probabilistic Sharpe Ratio for a given array of returns or a given Sharpe Ratio and its standard deviation.
Args:
returns (np.ndarray, optional): The array of returns.
sr_benchmark (float, optional): The benchmark Sharpe Ratio to compare against. Default is 0.0.
sr (float, optional): The Sharpe Ratio of the returns array.
sr_std (float, optional): The standard deviation of the Sharpe Ratio of the returns array.
Returns:
float: The Probabilistic Sharpe Ratio.
"""
if sr is None:
sr = self.estimated_sharpe_ratio(returns)
if sr_std is None:
sr_std = self.estimated_sharpe_ratio_stdev(returns, sr=sr)
psr = scipy_stats.norm.cdf((sr - sr_benchmark) / sr_std)
return psr
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment