skfolio.attribution.Attribution#

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

Factor attribution result.

Result returned by predicted_factor_attribution, realized_factor_attribution or 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:
systematicComponent

Systematic component. Portfolio risk and return attributed to the portfolio’s factor exposures.

idioComponent

Idiosyncratic component. Portfolio risk and return not attributed to the factor exposures.

unattributedComponent 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.

totalComponent

Total portfolio risk and return after aggregating all attribution components.

factorsFactorBreakdown

Per-factor attribution with exposures, standalone statistics and contributions.

familiesFamilyBreakdown or None

Family-aggregated attribution. None when factor families are not provided.

assetsAssetBreakdown or None

Per-asset attribution with systematic/idiosyncratic decomposition. None when asset attribution is not computed.

asset_by_factor_contribAssetByFactorContribution or None

Asset-by-factor contribution breakdown. None when not computed.

is_realizedbool

True for realized (ex-post), False for predicted (ex-ante).

observationsndarray or None

Window end labels for rolling attribution. None for single-point.

Methods

asset_factor_df([metric, formatted, ...])

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

assets_df([formatted])

Return per-asset attribution as a DataFrame.

factors_df([formatted, confidence_level])

Return per-factor attribution as a DataFrame.

families_df([formatted, confidence_level])

Return family-aggregated attribution as a DataFrame.

plot_exposure([by_family, top_n, show_std])

Plot portfolio factor exposure by factor or family.

plot_return_contrib([by_family, top_n, ...])

Plot return contribution by factor or family.

plot_return_vs_vol_contrib([by_family, ...])

Plot return contribution against volatility contribution.

plot_vol_contrib([by_family, top_n, ...])

Plot volatility contribution by factor or family.

summary_df([formatted, confidence_level])

Return component-level attribution as a DataFrame.

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

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

Parameters:
metric{“vol_contrib”, “mu_contrib”}, default=”vol_contrib”

Contribution metric to display.

formattedbool, default=True

Format values as percentages.

observation_idxint or None

Observation index. Required for rolling attribution.

Returns:
DataFrame

Matrix with assets as rows and factors as columns.

assets_df(formatted=True)[source]#

Return per-asset attribution as a DataFrame.

Parameters:
formattedbool, 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.

factors_df(formatted=True, confidence_level=0.95)[source]#

Return per-factor attribution as a DataFrame.

Parameters:
formattedbool, default=True

Format volatility, return and variance-share columns as percentage strings.

confidence_levelfloat, 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).

families_df(formatted=True, confidence_level=0.95)[source]#

Return family-aggregated attribution as a DataFrame.

Parameters:
formattedbool, default=True

Format volatility, return and variance-share columns as percentage strings.

confidence_levelfloat, 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.

property is_rolling#

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

property n_assets#

Number of assets.

property n_factors#

Number of factors.

property n_families#

Number of factor families.

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

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_familybool, default=False

Aggregate factors by family.

top_nint 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_stdbool, 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.

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

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_familybool, default=False

Aggregate factors by family.

top_nint 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_idiobool, default=True

Include idiosyncratic component.

confidence_levelfloat 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.

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

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_familybool, default=False

Aggregate factors by family.

top_nint 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_idiobool, default=True

Include idiosyncratic component. Displayed with a diamond marker at a fixed size (no exposure-based sizing).

size_maxfloat, 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.

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

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_familybool, default=False

Aggregate factors by family.

top_nint 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_idiobool, default=True

Include idiosyncratic component.

Returns:
go.Figure

Plotly contribution chart.

summary_df(formatted=True, confidence_level=0.95)[source]#

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:
formattedbool, default=True

Format volatility, return and variance-share columns as percentage strings.

confidence_levelfloat, 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.