skfolio.descriptor.EWResidualVolatility#
- class skfolio.descriptor.EWResidualVolatility(half_life=40.0, beta_half_life=60.0, min_periods=None, eps=1e-12)[source]#
Exponentially weighted CAPM residual volatility descriptor.
Computes volatility of CAPM residuals with an EWMA variance estimate:
\[ \begin{aligned} \epsilon_i(t) &= r_i(t) - \hat\beta_i(t) \cdot r_m(t) \\[0.75em] S_{\epsilon,i}(t) &= \lambda_v \cdot S_{\epsilon,i}(t-1) + (1 - \lambda_v) \cdot \epsilon_i(t)^2 \\[0.75em] \text{output}_i(t) &= \sqrt{\frac{S_{\epsilon,i}(t)} {1 - \lambda_v^{n_i(t)}}} \end{aligned} \]where \(\hat\beta_i(t)\) is the EWMA beta estimated with decay \(\lambda_\beta = \exp(-\ln(2)/\text{beta\_half\_life})\) and the residual variance uses decay \(\lambda_v = \exp(-\ln(2)/\text{half\_life})\). The zero-initialized residual variance accumulator is bias-corrected at output time using each asset’s valid observation count \(n_i(t)\).
The market return \(r_m(t)\) is computed as the cap-weighted average of returns in the estimation universe.
Residual volatility isolates the part of return variation not explained by the market. This can be useful when market beta is already modeled separately and the intended signal is stock-specific risk after removing market exposure [1].
- Parameters:
- half_lifefloat, default=40.0
EWMA half-life in observations for the residual variance estimator.
- beta_half_lifefloat, default=60.0
EWMA half-life in observations for the beta estimator.
- min_periodsint, optional
Minimum number of valid returns required for each asset. Until an asset reaches this count, its output is NaN. This warm-up period avoids exposing early EWMA values before the residual volatility estimate has sufficiently converged from its zero initialization. If
None, defaults to \(\lceil\max(\text{half\_life}, \text{beta\_half\_life})\rceil\), with a minimum of 1.- epsfloat, default=1e-12
Small constant for numerical stability in \(1 / \text{Var}(r_m)\) when computing beta.
- Attributes:
- n_assets_int
Number of assets seen during fitting.
- asset_names_ndarray of shape (n_assets,)
Asset names seen during fitting.
- residual_volatility_ndarray of shape (n_assets,)
Last computed EWMA residual volatility. Contains NaN for inactive assets and assets that have not reached
min_periodsvalid returns.
Methods
fit_transform(X[, y])Compute exponentially weighted CAPM residual volatility.
Get metadata routing of this object.
get_params([deep])Get parameters for this estimator.
partial_fit_transform(X[, y])Update EWMA state and return residual volatility for this batch.
set_params(**params)Set the parameters of this estimator.
See also
EWResidualDownsideVolatilityDownside variant using semi-deviation of residuals.
Notes
NaNs are treated as missing observations. Active assets with missing returns keep their previous asset-specific EWMA state; inactive assets output NaN and restart their warm-up period when they become active again. Non-missing returns must be finite.
Market returns are computed from the estimation universe (
estimation_maskofAssetPanel). If no estimable asset has both finite returns and finitemarket_capat an observation, the market return is undefined and aValueErroris raised.References
[1]“The cross-section of volatility and expected returns” The Journal of Finance. Ang, A., Hodrick, R. J., Xing, Y., & Zhang, X. (2006).
Examples
>>> from skfolio.datasets import make_synthetic_characteristics >>> from skfolio.descriptor import EWResidualVolatility >>> >>> X = make_synthetic_characteristics() >>> >>> descriptor = EWResidualVolatility() >>> residual_volatility = descriptor.fit_transform(X)
- fit_transform(X, y=None, **fit_params)#
Compute exponentially weighted CAPM residual volatility.
- Parameters:
- XAssetPanel
Input panel containing
returnsandmarket_cap.- yNone
Ignored. Present for compatibility with scikit-learn’s API.
- **fit_paramsdict
Additional fit parameters. Ignored.
- Returns:
- residual_volatilityndarray of shape (n_observations, n_assets)
Residual return volatility for each observation and asset.
- get_metadata_routing()#
Get metadata routing of this object.
Please check User Guide on how the routing mechanism works.
- Returns:
- routingMetadataRequest
A
MetadataRequestencapsulating routing information.
- get_params(deep=True)#
Get parameters for this estimator.
- Parameters:
- deepbool, default=True
If True, will return the parameters for this estimator and contained subobjects that are estimators.
- Returns:
- paramsdict
Parameter names mapped to their values.
- partial_fit_transform(X, y=None, **fit_params)#
Update EWMA state and return residual volatility for this batch.
This method supports online updates by continuing from the current fitted state. Use
fit_transformto start from a clean state.- Parameters:
- XAssetPanel
Input panel containing
returnsandmarket_cap.- yNone
Ignored. Present for compatibility with scikit-learn’s API.
- **fit_paramsdict
Additional fit parameters. Ignored.
- Returns:
- residual_volatilityndarray of shape (n_observations, n_assets)
Residual return volatility for each observation and asset.
- set_params(**params)#
Set the parameters of this estimator.
The method works on simple estimators as well as on nested objects (such as
Pipeline). The latter have parameters of the form<component>__<parameter>so that it’s possible to update each component of a nested object.- Parameters:
- **paramsdict
Estimator parameters.
- Returns:
- selfestimator instance
Estimator instance.