/sharpe_ratio_calculator.py Secret
Created
March 26, 2023 06:39
Star
You must be signed in to star a gist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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