<a id="skfolio-attribution-attribution"></a>

# skfolio.attribution.Attribution

<a id="skfolio.attribution.Attribution"></a>

### *class* skfolio.attribution.Attribution(systematic, idio, unattributed, total, factors, families=None, assets=None, asset_by_factor_contrib=None, is_realized=False, observations=None)

Factor attribution result.

Result returned by [`predicted_factor_attribution`](https://skfolio.org/generated/skfolio.attribution.predicted_factor_attribution.html.md#skfolio.attribution.predicted_factor_attribution),
[`realized_factor_attribution`](https://skfolio.org/generated/skfolio.attribution.realized_factor_attribution.html.md#skfolio.attribution.realized_factor_attribution) or [`rolling_realized_factor_attribution`](https://skfolio.org/generated/skfolio.attribution.rolling_realized_factor_attribution.html.md#skfolio.attribution.rolling_realized_factor_attribution).

Predicted and realized attribution expose the same decomposition: systematic,
idiosyncratic, total and per-factor attribution. Realized attribution may also
include `unattributed`, the difference between observed portfolio returns and
model-attributed returns. Rolling attribution uses the same fields with numeric
values indexed by `observations`.

* **Attributes:**
  **systematic** *Component*
  : Systematic component. Portfolio risk and return attributed to the portfolio’s
    factor exposures.

  **idio** *Component*
  : Idiosyncratic component. Portfolio risk and return not attributed to the factor
    exposures.

  **unattributed** *Component or None*
  : Difference between observed portfolio returns and model-attributed returns
    (systematic plus idiosyncratic). Captures effects outside the factor model:
    transaction costs, management fees, slippage, cash, intra-period trading
    and, for time-series factor models, the regression intercept. `None` for
    predicted attribution.

  **total** *Component*
  : Total portfolio risk and return after aggregating all attribution components.

  **factors** *FactorBreakdown*
  : Per-factor attribution with exposures, standalone statistics and contributions.

  **families** *FamilyBreakdown or None*
  : Family-aggregated attribution. `None` when factor families are not provided.

  **assets** *AssetBreakdown or None*
  : Per-asset attribution with systematic/idiosyncratic decomposition. `None` when
    asset attribution is not computed.

  **asset_by_factor_contrib** *AssetByFactorContribution or None*
  : Asset-by-factor contribution breakdown. `None` when not computed.

  **is_realized** *bool*
  : True for realized (ex-post), False for predicted (ex-ante).

  **observations** *ndarray or None*
  : Window end labels for rolling attribution. None for single-point.

### Methods

| [`asset_factor_df`](#skfolio.attribution.Attribution.asset_factor_df)([metric, formatted, ...])    | Return the asset-by-factor contribution as a DataFrame.   |
|-----------------------------------------------------------------------------------------------|-----------------------------------------------------------|
| [`assets_df`](#skfolio.attribution.Attribution.assets_df)([formatted])                       | Return per-asset attribution as a DataFrame.              |
| [`factors_df`](#skfolio.attribution.Attribution.factors_df)([formatted, confidence_level])    | Return per-factor attribution as a DataFrame.             |
| [`families_df`](#skfolio.attribution.Attribution.families_df)([formatted, confidence_level])   | Return family-aggregated attribution as a DataFrame.      |
| [`plot_exposure`](#skfolio.attribution.Attribution.plot_exposure)([by_family, top_n, show_std])  | Plot portfolio factor exposure by factor or family.       |
| [`plot_return_contrib`](#skfolio.attribution.Attribution.plot_return_contrib)([by_family, top_n, ...]) | Plot return contribution by factor or family.             |
| [`plot_return_vs_vol_contrib`](#skfolio.attribution.Attribution.plot_return_vs_vol_contrib)([by_family, ...]) | Plot return contribution against volatility contribution. |
| [`plot_vol_contrib`](#skfolio.attribution.Attribution.plot_vol_contrib)([by_family, top_n, ...])    | Plot volatility contribution by factor or family.         |
| [`summary_df`](#skfolio.attribution.Attribution.summary_df)([formatted, confidence_level])    | Return component-level attribution as a DataFrame.        |

<a id="skfolio.attribution.Attribution.asset_factor_df"></a>

#### asset_factor_df(metric='vol_contrib', formatted=True, observation_idx=None)

Return the asset-by-factor contribution as a DataFrame.

* **Parameters:**
  **metric** *{“vol_contrib”, “mu_contrib”}, default=”vol_contrib”*
  : Contribution metric to display.

  **formatted** *bool, default=True*
  : Format values as percentages.

  **observation_idx** *int or None*
  : Observation index. Required for rolling attribution.
* **Returns:**
  DataFrame
  : Matrix with assets as rows and factors as columns.

<a id="skfolio.attribution.Attribution.assets_df"></a>

#### assets_df(formatted=True)

Return per-asset attribution as a DataFrame.

* **Parameters:**
  **formatted** *bool, default=True*
  : Format volatility, return and variance-share columns as percentage strings.
* **Returns:**
  DataFrame
  : Per-asset weights, volatility and return contributions (total/systematic/idiosyncratic).
    Indexed by `Asset` for single-point attribution. For rolling:
    MultiIndex (Observation, Asset).
* **Raises:**
  ValueError
  : If asset attribution was not computed.

<a id="skfolio.attribution.Attribution.factors_df"></a>

#### factors_df(formatted=True, confidence_level=0.95)

Return per-factor attribution as a DataFrame.

* **Parameters:**
  **formatted** *bool, default=True*
  : Format volatility, return and variance-share columns as percentage strings.

  **confidence_level** *float, default=0.95*
  : When `formatted=True` and uncertainty data are present, merges mean return
    contribution with $\mu \pm z \times SE$ into one `(N% CI)` column.
* **Returns:**
  DataFrame
  : Per-factor attribution with exposures, standalone statistics, and
    contributions. Indexed by `Factor` for single-point attribution. For
    rolling: MultiIndex (Observation, Factor).

<a id="skfolio.attribution.Attribution.families_df"></a>

#### families_df(formatted=True, confidence_level=0.95)

Return family-aggregated attribution as a DataFrame.

* **Parameters:**
  **formatted** *bool, default=True*
  : Format volatility, return and variance-share columns as percentage strings.

  **confidence_level** *float, default=0.95*
  : When `formatted=True` and uncertainty data are present, merges mean return
    contribution with $\mu \pm z \times SE$ into one `(N% CI)` column.
* **Returns:**
  DataFrame
  : Family-aggregated exposures and contributions. Indexed by `Family` for
    single-point attribution. For rolling: MultiIndex (Observation, Family).
* **Raises:**
  ValueError
  : If `factor_families` was not provided.

<a id="skfolio.attribution.Attribution.is_rolling"></a>

#### *property* is_rolling

Whether this is rolling attribution (observations is not None).

<a id="skfolio.attribution.Attribution.n_assets"></a>

#### *property* n_assets

Number of assets.

<a id="skfolio.attribution.Attribution.n_factors"></a>

#### *property* n_factors

Number of factors.

<a id="skfolio.attribution.Attribution.n_families"></a>

#### *property* n_families

Number of factor families.

<a id="skfolio.attribution.Attribution.plot_exposure"></a>

#### plot_exposure(by_family=False, top_n=25, show_std=True)

Plot portfolio factor exposure by factor or family.

Single-point attribution shows signed exposure as a bar chart. Rolling
attribution shows exposure through time. For realized attribution,
`show_std=True` displays exposure standard deviation when available:
vertical error bars for single-point charts and +/- 1 standard deviation
bands for rolling charts.

* **Parameters:**
  **by_family** *bool, default=False*
  : Aggregate factors by family.

  **top_n** *int or None, default=25*
  : Maximum number of factors or families to show, sorted by absolute exposure.
    If there are more factors/families than `top_n`, the remaining components
    are aggregated into `Other`.

  **show_std** *bool, default=True*
  : If `True`, display exposure standard deviation when available. This applies
    to realized attribution and is ignored for predicted attribution, where
    exposure standard deviation is not computed.
* **Returns:**
  go.Figure
  : Plotly exposure chart.

<a id="skfolio.attribution.Attribution.plot_return_contrib"></a>

#### plot_return_contrib(by_family=False, top_n=25, include_idio=True, confidence_level=0.95)

Plot return contribution by factor or family.

When realized attribution includes per-factor standard errors
(`mu_contrib_uncertainty`), hover text shows the mean return SE and,
if `confidence_level` is not `None`, the corresponding confidence
interval. Single-point charts display vertical error bars. Rolling
charts display confidence bands around the contribution lines.

* **Parameters:**
  **by_family** *bool, default=False*
  : Aggregate factors by family.

  **top_n** *int or None, default=25*
  : Maximum number of factors or families to show, sorted by absolute
    return contribution.
    If there are more factors/families than `top_n`, the remaining
    components are aggregated into `Other`.

  **include_idio** *bool, default=True*
  : Include idiosyncratic component.

  **confidence_level** *float or None, default=0.95*
  : Confidence level for interval display. If `None`, error bars are
    not drawn and hover text omits the confidence interval line. The
    mean return SE is still shown when uncertainty data exist.
* **Returns:**
  go.Figure
  : Plotly contribution chart.

<a id="skfolio.attribution.Attribution.plot_return_vs_vol_contrib"></a>

#### plot_return_vs_vol_contrib(by_family=False, top_n=25, include_idio=True, size_max=50)

Plot return contribution against volatility contribution.

X-axis: volatility contribution, Y-axis: return contribution.
Factor marker sizes are proportional to absolute exposure.
The idiosyncratic point uses a fixed-size diamond marker when included.
Rolling attribution returns an animated scatter plot over time.

* **Parameters:**
  **by_family** *bool, default=False*
  : Aggregate factors by family.

  **top_n** *int or None, default=25*
  : Maximum number of factors or families to show, sorted by absolute
    volatility contribution.
    If there are more factors/families than `top_n`, the remaining
    components are aggregated into `Other`.

  **include_idio** *bool, default=True*
  : Include idiosyncratic component. Displayed with a diamond marker
    at a fixed size (no exposure-based sizing).

  **size_max** *float, default=50*
  : Maximum marker size for the largest absolute exposure. The
    idiosyncratic marker uses `0.4 * size_max`.
* **Returns:**
  go.Figure
  : Plotly scatter plot. Rolling attribution uses observation labels as
    animation frames.

<a id="skfolio.attribution.Attribution.plot_vol_contrib"></a>

#### plot_vol_contrib(by_family=False, top_n=25, include_idio=True)

Plot volatility contribution by factor or family.

Single-point attribution returns one bar trace. Rolling attribution
returns one line trace per displayed component with observations on the x-axis.

* **Parameters:**
  **by_family** *bool, default=False*
  : Aggregate factors by family.

  **top_n** *int or None, default=25*
  : Maximum number of factors or families to show, sorted by absolute
    volatility contribution.
    If there are more factors/families than `top_n`, the remaining
    components are aggregated into `Other`.

  **include_idio** *bool, default=True*
  : Include idiosyncratic component.
* **Returns:**
  go.Figure
  : Plotly contribution chart.

<a id="skfolio.attribution.Attribution.summary_df"></a>

#### summary_df(formatted=True, confidence_level=0.95)

Return component-level attribution as a DataFrame.

The summary reports volatility contribution, percentage of total variance and
return contribution for the systematic, idiosyncratic, optional unattributed,
and total components.

* **Parameters:**
  **formatted** *bool, default=True*
  : Format volatility, return and variance-share columns as percentage strings.

  **confidence_level** *float, default=0.95*
  : When `formatted=True` and uncertainty data are present, the mean return
    contribution is shown in one `{label} Contribution (N% CI)` column with
    values $\mu \pm z \times SE$.
* **Returns:**
  DataFrame
  : Indexed by `Component` for single-point attribution. Rolling attribution
    returns a MultiIndex with levels `Observation` and `Component`.

