<a id="skfolio-descriptor-ewresidualvolatility"></a>

# skfolio.descriptor.EWResidualVolatility

<a id="skfolio.descriptor.EWResidualVolatility"></a>

### *class* skfolio.descriptor.EWResidualVolatility(half_life=40.0, beta_half_life=60.0, min_periods=None, eps=1e-12)

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]](#r5416aa9231c8-1).

* **Parameters:**
  **half_life** *float, default=40.0*
  : EWMA half-life in observations for the residual variance estimator.

  **beta_half_life** *float, default=60.0*
  : EWMA half-life in observations for the beta estimator.

  **min_periods** *int, 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.

  **eps** *float, 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_periods` valid returns.

### Methods

| [`fit_transform`](#skfolio.descriptor.EWResidualVolatility.fit_transform)(X[, y])         | Compute exponentially weighted CAPM residual volatility.         |
|--------------------------------------------------------------------------------|------------------------------------------------------------------|
| [`get_metadata_routing`](#skfolio.descriptor.EWResidualVolatility.get_metadata_routing)()        | Get metadata routing of this object.                             |
| [`get_params`](#skfolio.descriptor.EWResidualVolatility.get_params)([deep])            | Get parameters for this estimator.                               |
| [`partial_fit_transform`](#skfolio.descriptor.EWResidualVolatility.partial_fit_transform)(X[, y]) | Update EWMA state and return residual volatility for this batch. |
| [`set_params`](#skfolio.descriptor.EWResidualVolatility.set_params)(\*\*params)        | Set the parameters of this estimator.                            |

#### SEE ALSO
[`EWResidualDownsideVolatility`](https://skfolio.org/generated/skfolio.descriptor.EWResidualDownsideVolatility.html.md#skfolio.descriptor.EWResidualDownsideVolatility)
: Downside 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_mask` of
[`AssetPanel`](https://skfolio.org/generated/skfolio.containers.AssetPanel.html.md#skfolio.containers.AssetPanel)). If no estimable asset has both finite
returns and finite `market_cap` at an observation, the market return is undefined
and a `ValueError` is raised.

### References

* <a id='r5416aa9231c8-1'>**[1]**</a> “The cross-section of volatility and expected returns” The Journal of Finance. Ang, A., Hodrick, R. J., Xing, Y., & Zhang, X. (2006).

### Examples

```pycon
>>> from skfolio.datasets import make_synthetic_characteristics
>>> from skfolio.descriptor import EWResidualVolatility
>>>
>>> X = make_synthetic_characteristics()
>>>
>>> descriptor = EWResidualVolatility()
>>> residual_volatility = descriptor.fit_transform(X)
```

<a id="skfolio.descriptor.EWResidualVolatility.fit_transform"></a>

#### fit_transform(X, y=None, \*\*fit_params)

Compute exponentially weighted CAPM residual volatility.

* **Parameters:**
  **X** *AssetPanel*
  : Input panel containing `returns` and `market_cap`.

  **y** *None*
  : Ignored. Present for compatibility with scikit-learn’s API.

  **\*\*fit_params** *dict*
  : Additional fit parameters. Ignored.
* **Returns:**
  **residual_volatility** *ndarray of shape (n_observations, n_assets)*
  : Residual return volatility for each observation and asset.

<a id="skfolio.descriptor.EWResidualVolatility.get_metadata_routing"></a>

#### get_metadata_routing()

Get metadata routing of this object.

Please check [User Guide](https://skfolio.org/user_guide/metadata_routing.html.md#metadata-routing) on how the routing
mechanism works.

* **Returns:**
  **routing** *MetadataRequest*
  : A `MetadataRequest` encapsulating
    routing information.

<a id="skfolio.descriptor.EWResidualVolatility.get_params"></a>

#### get_params(deep=True)

Get parameters for this estimator.

* **Parameters:**
  **deep** *bool, default=True*
  : If True, will return the parameters for this estimator and
    contained subobjects that are estimators.
* **Returns:**
  **params** *dict*
  : Parameter names mapped to their values.

<a id="skfolio.descriptor.EWResidualVolatility.partial_fit_transform"></a>

#### 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_transform` to start from a clean state.

* **Parameters:**
  **X** *AssetPanel*
  : Input panel containing `returns` and `market_cap`.

  **y** *None*
  : Ignored. Present for compatibility with scikit-learn’s API.

  **\*\*fit_params** *dict*
  : Additional fit parameters. Ignored.
* **Returns:**
  **residual_volatility** *ndarray of shape (n_observations, n_assets)*
  : Residual return volatility for each observation and asset.

<a id="skfolio.descriptor.EWResidualVolatility.set_params"></a>

#### 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:**
  **\*\*params** *dict*
  : Estimator parameters.
* **Returns:**
  **self** *estimator instance*
  : Estimator instance.

