Source code for skfolio.attribution._model._component

"""Component Dataclass."""

# Copyright (c) 2023-2026
# Author: Hugo Delatte <hugo.delatte@skfoliolabs.com>
# SPDX-License-Identifier: BSD-3-Clause

from __future__ import annotations

from dataclasses import dataclass

from skfolio.typing import FloatArray

__all__ = ["Component"]


[docs] @dataclass(frozen=True) class Component: r"""Portfolio attribution component. Represents one component of the portfolio attribution: systematic, idiosyncratic, unattributed, or total. Each component stores volatility and return contributions, the percentage of total portfolio variance, standalone volatility, correlation with the portfolio and optional return uncertainty. For single-point attribution, fields are floats. For rolling attribution (from :func:`rolling_realized_factor_attribution`), fields are 1D arrays of shape `(n_windows,)`. Attributes ---------- vol_contrib : float or ndarray of shape (n_windows,) Volatility contribution to total portfolio volatility. pct_total_variance : float or ndarray of shape (n_windows,) Percentage of total portfolio variance. mu_contrib : float or ndarray of shape (n_windows,) Return contribution to total portfolio return (expected return for predicted attribution and mean return for realized attribution). vol : float or ndarray of shape (n_windows,) Standalone component volatility. corr_with_ptf : float or ndarray of shape (n_windows,) Correlation with portfolio returns. mu_uncertainty : float or ndarray of shape (n_windows,) or None Standard error of the mean return attribution, reflecting estimation uncertainty in the cross-sectional factor return regression. The systematic and idiosyncratic values are equal because their estimation errors sum to zero (the total portfolio return is observed). `None` when uncertainty is not computed. """ vol_contrib: float | FloatArray pct_total_variance: float | FloatArray mu_contrib: float | FloatArray vol: float | FloatArray corr_with_ptf: float | FloatArray mu_uncertainty: float | FloatArray | None = None @property def mu(self) -> float | FloatArray: """Standalone component return (expected return for predicted attribution and mean return for realized attribution). Components do not store a separate standalone return statistic. Unlike `vol`, the component-level return is already its contribution to total portfolio return, so `mu` is equal to `mu_contrib`. """ return self.mu_contrib