Skip to content

markowitz.estimators.means

markowitz.estimators.means

Mean-return estimators.

CAPMReturns(*, risk_free_rate: float = 0.0, market_premium: float | None = None, annualize: bool = True, periods_per_year: int | None = None)

Bases: _BaseMean

CAPM-implied expected returns from per-asset OLS betas.

Source code in src/markowitz/estimators/means.py
def __init__(
    self,
    *,
    risk_free_rate: float = 0.0,
    market_premium: float | None = None,
    annualize: bool = True,
    periods_per_year: int | None = None,
) -> None:
    self.risk_free_rate = float(risk_free_rate)
    self.market_premium = market_premium
    self.annualize = bool(annualize)
    self.periods_per_year = periods_per_year

EWMAMean(*, halflife_years: float | None = None, lam: float | None = None, annualize: bool = True, periods_per_year: int | None = None)

Bases: _BaseMean

Exponentially weighted mean using RiskMetrics-style decay.

Source code in src/markowitz/estimators/means.py
def __init__(
    self,
    *,
    halflife_years: float | None = None,
    lam: float | None = None,
    annualize: bool = True,
    periods_per_year: int | None = None,
) -> None:
    if (halflife_years is None) == (lam is None):
        raise EstimatorConfigError("Exactly one of halflife_years or lam must be provided.")
    self.halflife_years = halflife_years
    self.lam = lam
    self.annualize = bool(annualize)
    self.periods_per_year = periods_per_year

ImpliedReturns(*, delta: float = 2.5)

Bases: _BaseMean

Reverse-optimization implied returns μ = δ · Σ · w.

Source code in src/markowitz/estimators/means.py
def __init__(self, *, delta: float = 2.5) -> None:
    if delta <= 0.0:
        raise EstimatorConfigError(f"delta must be positive; got {delta}")
    self.delta = float(delta)

JorionBayesStein(*, base_cov: np.ndarray | None = None, annualize: bool = True, periods_per_year: int | None = None)

Bases: _BaseMean

Bayes-Stein shrinkage of the sample mean toward the minimum-variance mean.

Source code in src/markowitz/estimators/means.py
def __init__(
    self,
    *,
    base_cov: np.ndarray | None = None,
    annualize: bool = True,
    periods_per_year: int | None = None,
) -> None:
    self.base_cov = base_cov
    self.annualize = bool(annualize)
    self.periods_per_year = periods_per_year

SampleMean(*, annualize: bool = True, periods_per_year: int | None = None)

Bases: _BaseMean

Plain sample mean μ̂ = mean(returns, axis=0).

Source code in src/markowitz/estimators/means.py
def __init__(
    self,
    *,
    annualize: bool = True,
    periods_per_year: int | None = None,
) -> None:
    self.annualize = bool(annualize)
    self.periods_per_year = periods_per_year