def _estimate_capm( returns: pd.Series, benchmark: pd.Series, rf: float, ) -> RegressionResults: returns, benchmark = align(adjust(returns, rf), adjust(benchmark, rf)) y = returns.to_numpy() x = sm.add_constant(benchmark.to_numpy()) return sm.OLS(y, x).fit()
def _estimate_trailing_capm( returns: pd.Series, benchmark: pd.Series, rf: float, window: int, ) -> RollingRegressionResults: returns, benchmark = align(adjust(returns, rf), adjust(benchmark, rf)) y = returns.to_numpy() x = sm.add_constant(benchmark.to_numpy()) return RollingOLS(y, x, window=window).fit()
def omega_ratio( returns: pd.Series, *, rf: float = 0.0, ) -> float: adjusted_returns = adjust(returns, rf) above = adjusted_returns[adjusted_returns > 0].sum() under = adjusted_returns[adjusted_returns < 0].sum() return -(above / under)
def sortino_ratio( returns: pd.Series, *, rf: float = 0.0, annualizer: Optional[float] = None, ) -> float: adjusted_returns = adjust(returns, rf) mr = mean_return(adjusted_returns, statistics=False, annualizer=1) dr = downside_risk(adjusted_returns, rf=0, annualizer=1) return (mr / dr) * np.sqrt(annualizer)
def sharpe_ratio( returns: pd.Series, *, rf: float = 0.0, annualizer: Optional[float] = None, ) -> float: adjusted_returns = adjust(returns, rf) mr = mean_return(adjusted_returns, statistics=False, annualizer=1) std = volatility(adjusted_returns, annualizer=1) return (mr / std) * np.sqrt(annualizer)
def trailing_sortino_ratio( returns: pd.Series, *, rf: float = 0.0, annualizer: Optional[float] = None, window: Optional[int] = None, ) -> pd.Series: adjusted_returns = adjust(returns, rf) mr = trailing_mean_return(adjusted_returns, statistics=False, annualizer=1, window=window) dr = trailing_downside_risk(adjusted_returns, rf=0, annualizer=1, window=window) return (mr / dr) * np.sqrt(annualizer)
def downside_risk( returns: pd.Series, *, mar: float = 0.0, annualizer: Optional[float] = None, ) -> float: adjusted_returns = adjust(returns, mar) returns_under_mar = np.clip( adjusted_returns, a_min=-np.inf, a_max=0 ) return np.sqrt((returns_under_mar ** 2).mean()) * np.sqrt(annualizer)
def excess_returns( returns: pd.Series, benchmark: pd.Series, ) -> pd.Series: return adjust(returns, benchmark)