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

# skfolio.portfolio.Portfolio

<a id="skfolio.portfolio.Portfolio"></a>

### *class* skfolio.portfolio.Portfolio(X, weights, previous_weights=None, transaction_costs=None, management_fees=None, risk_free_rate=0, name=None, tag=None, annualization_factor=None, fitness_measures=None, compounded=False, weight_drift=False, sample_weight=None, min_acceptable_return=None, value_at_risk_beta=0.95, entropic_risk_measure_theta=1, entropic_risk_measure_beta=0.95, cvar_beta=0.95, evar_beta=0.95, drawdown_at_risk_beta=0.95, cdar_beta=0.95, edar_beta=0.95, fallback_chain=None, \*\*kwargs)

Portfolio class.

`Portfolio` is returned by the `predict` method of Optimization estimators.

By default, each observation is evaluated at the target `weights`. Portfolio
returns are the dot product of those weights and the asset returns, minus
transaction costs and management fees. This constant-weight convention
(`weight_drift=False`) is consistent with the optimizer’s linear portfolio return
definition and evaluates allocation skill independently of subsequent changes in
weights caused by relative asset returns.

With `weight_drift=True`, the portfolio starts at the target weights and holds the
resulting positions throughout the observation window of `X`. Position values
change with asset returns, so portfolio weights evolve with the relative
performance of the assets. Combined with `compounded=True`, this produces a
compounded wealth path for evaluating realized capital growth and other
path-dependent quantities.

`weight_drift` changes the observation-level portfolio return series, while
`compounded` changes how that series is accumulated. See
[Backtesting and Evaluation](https://skfolio.org/user_guide/backtesting_and_evaluation.html.md#backtesting-and-evaluation).

* **Parameters:**
  **X** *array-like of shape (n_observations, n_assets)*
  : Price returns of the assets.
    If `X` is a DataFrame or another array containers that implements ‘columns’
    and ‘index’, the columns will be considered as assets names and the
    indices will be considered as observations.
    Otherwise, we use `["x0", "x1", ..., "x(n_assets - 1)"]` as asset names
    and `[0, 1, ..., n_observations]` as observations.
    `NaN` values are treated as zero returns for the portfolio return
    computation (e.g. non-investable assets, delisted assets or trading
    holidays), while the original `X` is preserved.

  **weights** *array-like of shape (n_assets,) | dict[str, float]*
  : Portfolio weights.
    If a dictionary is provided, its (key/value) pair must be the
    (asset name/asset weight) and `X` must be a DataFrame with assets names
    in columns.

  **transaction_costs** *float | dict[str, float] | array-like of shape (n_assets, ), optional*
  : Linear transaction costs of the assets. The Portfolio total transaction cost
    is:
    $$
    total\_cost = \sum_{i=1}^{N} c_{i} \times |w_{i} - w\_prev_{i}|
    <br/>
    $$
    <br/>
    with $c_{i}$ the transaction cost of asset i, $w_{i}$ its weight
    and $w\_prev_{i}$ its previous weight (defined in `previous_weights`).
    The float $total\_cost$ is used in the portfolio returns:
    $$
    ptf\_returns = R \cdot w - total\_cost
    <br/>
    $$
    <br/>
    with $R$ the matrix of assets returns and $w$ the vector of
    assets weights.
    <br/>
    If a float is provided, it is applied to each asset.
    If a dictionary is provided, its (key/value) pair must be the
    (asset name/asset weight) and `X` must be a DataFrame with assets names
    in columns.
    The default (`None`) means no transaction costs.
    <br/>
    #### WARNING
    To be consistent with the optimization problems, the periodicity of the
    transaction costs must match the periodicity of the
    returns `X`. For example, if `X` is composed of **daily** returns,
    the `transaction_costs` need to be expressed in **daily** transaction costs.

  **management_fees** *float | dict[str, float] | array-like of shape (n_assets, ), optional*
  : Linear management fees of the assets. The Portfolio total management cost
    is:
    $$
    total\_fee = \sum_{i=1}^{N} f_{i} \times w_{i}
    <br/>
    $$
    <br/>
    with $f_{i}$ the management fee of asset i and $w_{i}$ its weight.
    The float $total\_fee$ is used in the portfolio returns:
    $$
    ptf\_returns = R \cdot w - total\_fee
    <br/>
    $$
    <br/>
    with $R$ the matrix of assets returns and $w$ the vector of
    assets weights.
    <br/>
    If a float is provided, it is applied to each asset.
    If a dictionary is provided, its (key/value) pair must be the
    (asset name/asset weight) and `X` must be a DataFrame with assets names
    in columns.
    The default (`None`) means no management fees.
    <br/>
    #### WARNING
    To be consistent with the optimization problems, the periodicity of the
    management fees must match the periodicity of the
    returns `X`. For example, if `X` is composed of **daily** returns,
    the `management_fees` need to be expressed in **daily** fees.

  **previous_weights** *float | dict[str, float] | array-like of shape (n_assets, ), optional*
  : Previous portfolio weights.
    Previous weights are used to compute turnover and transaction costs.
    For named positions in assets absent from `X`, these calculations assume
    full liquidation. To specify their transaction costs, `transaction_costs`
    must be a single rate applied to all assets or a dictionary keyed by asset name.
    If a float is provided, it is applied to each asset.
    If a dictionary is provided, its (key/value) pair must be the
    (asset name/asset previous weight) and `X` must be a DataFrame with assets names
    in columns.
    The default (`None`) means no previous weights.

  **name** *str, optional*
  : Name of the portfolio.
    The default (`None`) is to use the object id.

  **tag** *str, optional*
  : Tag given to the portfolio.
    Tags are used to manipulate groups of Portfolios from a `Population`.

  **fitness_measures** *list[measures], optional*
  : List of fitness measures.
    Fitness measures are used to compute the portfolio fitness which is used to
    compute domination.
    The default (`None`) is to use the list [PerfMeasure.MEAN, RiskMeasure.VARIANCE]

  **annualization_factor** *float, default=252.0*
  : Factor used to annualize the below measures using the square-root rule:
    > * Annualized Mean = Mean \* factor
    > * Annualized Variance = Variance \* factor
    > * Annualized Semi-Variance = Semi-Variance \* factor
    > * Annualized Standard-Deviation = Standard-Deviation \* sqrt(factor)
    > * Annualized Semi-Deviation = Semi-Deviation \* sqrt(factor)
    > * Annualized Sharpe Ratio = Sharpe Ratio \* sqrt(factor)
    > * Annualized Sortino Ratio = Sortino Ratio \* sqrt(factor)

  **risk_free_rate** *float, default=0.0*
  : Risk-free rate. The default value is `0.0`.

  **compounded** *bool, default=False*
  : If `True`, cumulative returns are compounded.
    The default is `False`.

  **weight_drift** *bool, default=False*
  : If `True`, the portfolio starts at the target `weights` and the
    weights used for subsequent observations evolve with asset returns following
    the self-financing identity
    $u_{t+1} = u_t \circ (1 + r_t) / (1 + u_t \cdot r_t)$.
    Drift accumulates over the entire window of `X`, and the implicit cash position
    $1 - \sum_i w_i$ earns zero. The same transaction-cost and management-fee
    formulas are used with either setting. With the default (`False`), every
    observation is evaluated at the target `weights`. This attribute is read-only.
    See [Backtesting and Evaluation](https://skfolio.org/user_guide/backtesting_and_evaluation.html.md#backtesting-and-evaluation).

  **sample_weight** *ndarray of shape (n_observations,), optional*
  : Sample weights for each observation. If None, equal weights are assumed.

  **min_acceptable_return** *float, optional*
  : The minimum acceptable return used to distinguish “downside” and “upside”
    returns for the computation of lower partial moments:
    > * First Lower Partial Moment
    > * Semi-Variance
    > * Semi-Deviation
    <br/>
    The default (`None`) is to use the mean.

  **value_at_risk_beta** *float, default=0.95*
  : The confidence level of the Portfolio VaR (Value At Risk) which represents
    the return on the worst (1-beta)% observations.
    The default value is `0.95`.

  **entropic_risk_measure_theta** *float, default=1.0*
  : The risk aversion level of the Portfolio Entropic Risk Measure.
    The default value is `1.0`.

  **entropic_risk_measure_beta** *float, default=0.95*
  : The confidence level of the Portfolio Entropic Risk Measure.
    The default value is `0.95`.

  **cvar_beta** *float, default=0.95*
  : The confidence level of the Portfolio CVaR (Conditional Value at Risk) which
    represents the expected VaR on the worst (1-beta)% observations.
    The default value is `0.95`.

  **evar_beta** *float, default=0.95*
  : The confidence level of the Portfolio EVaR (Entropic Value at Risk).
    The default value is `0.95`.

  **drawdown_at_risk_beta** *float, default=0.95*
  : The confidence level of the Portfolio Drawdown at Risk (DaR) which represents
    the drawdown on the worst (1-beta)% observations.
    The default value is `0.95`.

  **cdar_beta** *float, default=0.95*
  : The confidence level of the Portfolio CDaR (Conditional Drawdown at Risk) which
    represents the expected drawdown on the worst (1-beta)% observations.
    The default value is `0.95`.

  **edar_beta** *float, default=0.95*
  : The confidence level of the Portfolio EDaR (Entropic Drawdown at Risk).
    The default value is `0.95`.

  **fallback_chain** *list[tuple[str, str]] | None, optional*
  : Sequence describing the optimization fallback attempts. Each element is
    a pair `(estimator_repr, outcome)` where:
    * `estimator_repr` is the string representation of the primary
      estimator or a fallback (e.g. `"EqualWeighted()"`,
      `"previous_weights"`).
    * `outcome` is `"success"` if that step produced a valid solution,
      otherwise the stringified error message.
    <br/>
    For successful fits without any fallback, this is `None`. When
    fallbacks are provided and the primary fails, the chain starts with
    `(primary_repr, primary_error)` and is followed by one entry per
    fallback that was attempted, ending with the first `"success"` or the
    last error if all fail. This is set by the optimization estimator and
    propagated to the resulting portfolio.
* **Attributes:**
  [`n_observations`](#skfolio.portfolio.Portfolio.n_observations) *float*
  : Number of observations.

  **mean** *float*
  : Mean of the portfolio returns.

  **annualized_mean** *float*
  : Mean annualized by $mean \times annualization\_factor$

  **mean_absolute_deviation** *float*
  : Mean Absolute Deviation. The deviation is the difference between the
    return and a minimum acceptable return (`min_acceptable_return`).

  **first_lower_partial_moment** *float*
  : First Lower Partial Moment. The First Lower Partial Moment is the mean of the
    returns below a minimum acceptable return (`min_acceptable_return`).

  **variance** *float*
  : Variance (Second Moment)

  **annualized_variance** *float*
  : Variance annualized by $variance \times annualization\_factor$

  **semi_variance** *float*
  : Semi-variance (Second Lower Partial Moment).
    The semi-variance is the variance of the returns below a minimum acceptable
    return (`min_acceptable_return`).

  **annualized_semi_variance** *float*
  : Semi-variance annualized by
    $semi\_variance \times annualization\_factor$

  **standard_deviation** *float*
  : Standard Deviation (Square Root of the Second Moment).

  **annualized_standard_deviation** *float*
  : Standard Deviation annualized by
    $standard\_deviation \times \sqrt{annualization\_factor}$

  **semi_deviation** *float*
  : Semi-deviation (Square Root of the Second Lower Partial Moment).
    The Semi Standard Deviation is the Standard Deviation of the returns below a
    minimum acceptable return (`min_acceptable_return`).

  **annualized_semi_deviation** *float*
  : Semi-deviation annualized by
    $semi\_deviation \times \sqrt{annualization\_factor}$

  **skew** *float*
  : Skew. The Skew is a measure of the lopsidedness of the distribution.
    A symmetric distribution have a Skew of zero.
    Higher Skew corresponds to longer right tail.

  **kurtosis** *float*
  : Kurtosis. It is a measure of the heaviness of the tail of the distribution.
    Higher Kurtosis corresponds to greater extremity of deviations (fat tails).

  **fourth_central_moment** *float*
  : Fourth Central Moment.

  **fourth_lower_partial_moment** *float*
  : Fourth Lower Partial Moment. It is a measure of the heaviness of the downside
    tail of the returns below a minimum acceptable return (`min_acceptable_return`).
    Higher Fourth Lower Partial Moment corresponds to greater extremity of downside
    deviations (downside fat tail).

  **worst_realization** *float*
  : Worst Realization which is the worst return.

  **value_at_risk** *float*
  : Historical VaR (Value at Risk).
    The VaR is the maximum loss at a given confidence level (`value_at_risk_beta`).

  **cvar** *float*
  : Historical CVaR (Conditional Value at Risk). The CVaR (or Tail VaR) represents
    the mean shortfall at a specified confidence level (`cvar_beta`).

  **entropic_risk_measure** *float*
  : Historical Entropic Risk Measure. It is a risk measure which depends on the
    risk aversion defined by the investor (`entropic_risk_measure_theta`) through
    the exponential utility function at a given confidence level
    (`entropic_risk_measure_beta`).

  **evar** *float*
  : Historical EVaR (Entropic Value at Risk). It is a coherent risk measure which
    is an upper bound for the VaR and the CVaR, obtained from the Chernoff
    inequality at a given confidence level (`evar_beta`). The EVaR can be
    represented by using the concept of relative entropy.

  **drawdown_at_risk** *float*
  : Historical Drawdown at Risk. It is the maximum drawdown at a given
    confidence level (`drawdown_at_risk_beta`).

  **cdar** *float*
  : Historical CDaR (Conditional Drawdown at Risk) at a given confidence level
    (`cdar_beta`).

  **max_drawdown** *float*
  : Maximum Drawdown.

  **average_drawdown** *float*
  : Average Drawdown.

  **edar** *float*
  : EDaR (Entropic Drawdown at Risk). It is a coherent risk measure which is an
    upper bound for the Drawdown at Risk and the CDaR, obtained from the Chernoff
    inequality at a given confidence level (`edar_beta`). The EDaR can be
    represented by using the concept of relative entropy.

  **ulcer_index** *float*
  : Ulcer Index

  **gini_mean_difference** *float*
  : Gini Mean Difference (GMD). It is the expected absolute difference between two
    realizations. The GMD is a superior measure of variability  for non-normal
    distribution than the variance. It can be used to form necessary conditions
    for second-degree stochastic dominance, while the variance cannot.

  **mean_absolute_deviation_ratio** *float*
  : Mean Absolute Deviation ratio.
    It is the excess mean (mean - risk_free_rate) divided by the MaD.

  **first_lower_partial_moment_ratio** *float*
  : First Lower Partial Moment ratio.
    It is the excess mean (mean - risk_free_rate) divided by the First Lower
    Partial Moment.

  **sharpe_ratio** *float*
  : Sharpe ratio.
    It is the excess mean (mean - risk_free_rate) divided by the standard-deviation.

  **annualized_sharpe_ratio** *float*
  : Sharpe ratio annualized by
    $sharpe\_ratio \times \sqrt{annualization\_factor}$.

  **sortino_ratio** *float*
  : Sortino ratio.
    It is the excess mean (mean - risk_free_rate) divided by the semi
    standard-deviation.

  **annualized_sortino_ratio** *float*
  : Sortino ratio annualized by
    $sortino\_ratio \times \sqrt{annualization\_factor}$.

  **value_at_risk_ratio** *float*
  : VaR ratio.
    It is the excess mean (mean - risk_free_rate) divided by the Value at Risk
    (VaR).

  **cvar_ratio** *float*
  : CVaR ratio.
    It is the excess mean (mean - risk_free_rate) divided by the Conditional Value
    at Risk (CVaR).

  **entropic_risk_measure_ratio** *float*
  : Entropic risk measure ratio.
    It is the excess mean (mean - risk_free_rate) divided by the Entropic risk
    measure.

  **evar_ratio** *float*
  : EVaR ratio.
    It is the excess mean (mean - risk_free_rate) divided by the EVaR (Entropic
    Value at Risk).

  **worst_realization_ratio** *float*
  : Worst Realization ratio.
    It is the excess mean (mean - risk_free_rate) divided by the Worst Realization
    (worst return).

  **drawdown_at_risk_ratio** *float*
  : Drawdown at Risk ratio.
    It is the excess mean (mean - risk_free_rate) divided by the drawdown at
    risk.

  **cdar_ratio** *float*
  : CDaR ratio.
    It is the excess mean (mean - risk_free_rate) divided by the CDaR (conditional
    drawdown at risk).

  **calmar_ratio** *float*
  : Calmar ratio.
    It is the excess mean (mean - risk_free_rate) divided by the Maximum Drawdown.

  **average_drawdown_ratio** *float*
  : Average Drawdown ratio.
    It is the excess mean (mean - risk_free_rate) divided by the Average Drawdown.

  **edar_ratio** *float*
  : EDaR ratio.
    It is the excess mean (mean - risk_free_rate) divided by the EDaR (Entropic
    Drawdown at Risk).

  **ulcer_index_ratio** *float*
  : Ulcer Index ratio.
    It is the excess mean (mean - risk_free_rate) divided by the Ulcer Index.

  **gini_mean_difference_ratio** *float*
  : Gini Mean Difference ratio.
    It is the excess mean (mean - risk_free_rate) divided by the Gini Mean
    Difference.

  **ending_weights** *ndarray of shape (n_assets,)*
  : Asset weights immediately after the final observation. With
    `weight_drift=False`, they equal the target `weights`. With
    `weight_drift=True`, they reflect the effect of asset returns through the final
    observation. They are calculated before transaction costs and management fees.
    In a sequential evaluation, the `ending_weights` of a successful `Portfolio`
    are used as `previous_weights` for the next optimization. A `FailedPortfolio`
    contains only NaN ending weights.

  [`turnover`](#skfolio.portfolio.Portfolio.turnover) *float*
  : Total absolute weight traded at the start of the period.

### Methods

| [`clear`](#skfolio.portfolio.Portfolio.clear)()                                           | Clear all measures, fitness, cumulative returns and drawdowns in slots.                                            |
|----------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------|
| [`contribution`](#skfolio.portfolio.Portfolio.contribution)(measure[, spacing, to_df])           | Compute the contribution of each asset to a given measure.                                                         |
| [`copy`](#skfolio.portfolio.Portfolio.copy)()                                            | Copy the Portfolio attributes without its measures values.                                                         |
| [`dominates`](#skfolio.portfolio.Portfolio.dominates)(other[, idx])                           | Portfolio domination.                                                                                              |
| [`expected_returns_from_assets`](#skfolio.portfolio.Portfolio.expected_returns_from_assets)(...)                 | Compute the portfolio expected return from expected asset returns, weights, management costs and transaction fees. |
| [`get_measure`](#skfolio.portfolio.Portfolio.get_measure)(measure)                              | Returns the value of a given measure.                                                                              |
| [`get_weight`](#skfolio.portfolio.Portfolio.get_weight)(asset)                                 | Get the weight of a given asset.                                                                                   |
| [`plot_composition`](#skfolio.portfolio.Portfolio.plot_composition)()                                | Plot the Portfolio composition.                                                                                    |
| [`plot_contribution`](#skfolio.portfolio.Portfolio.plot_contribution)(measure[, spacing])             | Plot the contribution of each asset to a given measure.                                                            |
| [`plot_cumulative_returns`](#skfolio.portfolio.Portfolio.plot_cumulative_returns)([log_scale, idx])         | Plot the Portfolio cumulative returns.                                                                             |
| [`plot_drawdowns`](#skfolio.portfolio.Portfolio.plot_drawdowns)([idx])                             | Plot the Portfolio drawdowns.                                                                                      |
| [`plot_returns`](#skfolio.portfolio.Portfolio.plot_returns)([idx])                               | Plot the Portfolio returns.                                                                                        |
| [`plot_returns_distribution`](#skfolio.portfolio.Portfolio.plot_returns_distribution)([percentile_cutoff])    | Plot the Portfolio returns distribution using Gaussian KDE.                                                        |
| [`plot_rolling_measure`](#skfolio.portfolio.Portfolio.plot_rolling_measure)([measure, window])           | Plot the measure over a rolling window.                                                                            |
| [`predicted_attribution`](#skfolio.portfolio.Portfolio.predicted_attribution)(factor_model[, ...])        | Ex-ante (predicted) factor risk and performance attribution.                                                       |
| [`realized_attribution`](#skfolio.portfolio.Portfolio.realized_attribution)(factor_model[, ...])         | Realized (ex-post) factor risk and performance attribution.                                                        |
| [`rolling_measure`](#skfolio.portfolio.Portfolio.rolling_measure)([measure, window])                | Compute the measure over a rolling window.                                                                         |
| [`rolling_realized_attribution`](#skfolio.portfolio.Portfolio.rolling_realized_attribution)(factor_model[, ...]) | Rolling realized (ex-post) factor risk and performance attribution.                                                |
| [`summary`](#skfolio.portfolio.Portfolio.summary)([formatted])                              | Portfolio summary of all its measures.                                                                             |
| [`variance_from_assets`](#skfolio.portfolio.Portfolio.variance_from_assets)(assets_covariance)           | Compute the Portfolio variance expectation from the assets covariance and weights.                                 |

<a id="skfolio.portfolio.Portfolio.annualization_factor"></a>

#### *property* annualization_factor

Portfolio annualization factor.

<a id="skfolio.portfolio.Portfolio.annualized_factor"></a>

#### *property* annualized_factor

Deprecated alias for `annualization_factor`.

<a id="skfolio.portfolio.Portfolio.clear"></a>

#### clear()

Clear all measures, fitness, cumulative returns and drawdowns in slots.

<a id="skfolio.portfolio.Portfolio.composition"></a>

#### *property* composition

DataFrame of portfolio composition (weights). Rows with zero weights are
filtered out. Use `weights_dict` to access all weights, including zeros.

<a id="skfolio.portfolio.Portfolio.contribution"></a>

#### contribution(measure, spacing=None, to_df=False)

Compute the contribution of each asset to a given measure.

With `weight_drift=True`, the contributions are finite-difference sensitivities
to the target weights. Because drifted returns are nonlinear in the target
weights, the contributions are not guaranteed to sum exactly to the measure.

* **Parameters:**
  **measure** *Measure*
  : The measure used for the contribution computation.

  **spacing** *float, optional*
  : Spacing “h” of the finite difference:
    $contribution(wi)= \frac{measure(wi-h) - measure(wi+h)}{2h}$

  **to_df** *bool, default=False*
  : If set to True, a DataFrame with asset names in index is returned,
    otherwise a numpy array is returned. When a DataFrame is returned, the
    values are sorted in descending order and assets with zero weights are
    removed.
* **Returns:**
  **values** *numpy array of shape (n_assets,) or DataFrame*
  : The measure contribution of each asset.

<a id="skfolio.portfolio.Portfolio.copy"></a>

#### copy()

Copy the Portfolio attributes without its measures values.

<a id="skfolio.portfolio.Portfolio.cumulative_returns"></a>

#### cumulative_returns

Portfolio cumulative returns array.
Non-compounded (arithmetic) cumulative returns start at 0.
Compounded (geometric) cumulative returns are expressed as a wealth index,
starting at 1.0 (i.e., the value of $1 invested).

<a id="skfolio.portfolio.Portfolio.cumulative_returns_df"></a>

#### *property* cumulative_returns_df

Portfolio cumulative returns Series.
Non-compounded (arithmetic) cumulative returns start at 0.
Compounded (geometric) cumulative returns are expressed as a wealth index,
starting at 1.0 (i.e., the value of $1 invested).

<a id="skfolio.portfolio.Portfolio.diversification"></a>

#### *property* diversification

Weighted average of volatility divided by the portfolio volatility.

<a id="skfolio.portfolio.Portfolio.dominates"></a>

#### dominates(other, idx=None)

Portfolio domination.

Returns true if each objective of the current portfolio fitness is not
strictly worse than the corresponding objective of the other portfolio fitness
and at least one objective is strictly better.

* **Parameters:**
  **other** *BasePortfolio*
  : The other portfolio.

  **idx** *slice | array, optional*
  : Indexes or slice indicating on which objectives the domination is performed.
    The default (`None`) is to use all objectives.
* **Returns:**
  **value** *bool*
  : Returns True if the Portfolio dominates the other one.

<a id="skfolio.portfolio.Portfolio.drawdowns"></a>

#### drawdowns

Portfolio drawdowns array.

<a id="skfolio.portfolio.Portfolio.drawdowns_df"></a>

#### *property* drawdowns_df

Portfolio drawdowns Series.

<a id="skfolio.portfolio.Portfolio.effective_number_assets"></a>

#### *property* effective_number_assets

Computes the effective number of assets, defined as the inverse of the
Herfindahl index.

$$
N_{eff} = \frac{1}{\Vert w \Vert_{2}^{2}}

$$

It quantifies portfolio concentration, with a higher value indicating a more
diversified portfolio.

* **Returns:**
  **value** *float*
  : Effective number of assets.

### References

* <a id='r52de0fa26f70-1'>**[1]**</a> “Banking and Financial Institutions Law in a Nutshell”. Lovett, William Anthony (1988)

<a id="skfolio.portfolio.Portfolio.ending_weights_dict"></a>

#### *property* ending_weights_dict

Dict mapping asset name to ending weight; includes zeros.

<a id="skfolio.portfolio.Portfolio.expected_returns_from_assets"></a>

#### expected_returns_from_assets(assets_expected_returns)

Compute the portfolio expected return from expected asset returns,
weights, management costs and transaction fees.

* **Parameters:**
  **assets_expected_returns** *ndarray of shape (n_assets,)*
  : The vector of expected asset returns.
* **Returns:**
  **value** *float*
  : The portfolio expected return.

<a id="skfolio.portfolio.Portfolio.fitness"></a>

#### fitness

Portfolio fitness.

<a id="skfolio.portfolio.Portfolio.fitness_measures"></a>

#### *property* fitness_measures

Portfolio fitness measures.

<a id="skfolio.portfolio.Portfolio.get_measure"></a>

#### get_measure(measure)

Returns the value of a given measure.

* **Parameters:**
  **measure** *PerfMeasure | RiskMeasure | ExtraRiskMeasure | RatioMeasure*
  : The input measure.
* **Returns:**
  **value** *float*
  : The measure value.

<a id="skfolio.portfolio.Portfolio.get_weight"></a>

#### get_weight(asset)

Get the weight of a given asset.

* **Parameters:**
  **asset** *str*
  : Name of the asset.
* **Returns:**
  **weight** *float*
  : Weight of the asset.

<a id="skfolio.portfolio.Portfolio.measures_df"></a>

#### *property* measures_df

DataFrame of all measures.

<a id="skfolio.portfolio.Portfolio.n_observations"></a>

#### *property* n_observations

Number of observations.

<a id="skfolio.portfolio.Portfolio.nonzero_assets"></a>

#### nonzero_assets

Invested asset $abs(weights) > 0.001%$.

<a id="skfolio.portfolio.Portfolio.nonzero_assets_index"></a>

#### nonzero_assets_index

Indices of invested asset $abs(weights) > 0.001%$.

<a id="skfolio.portfolio.Portfolio.plot_composition"></a>

#### plot_composition()

Plot the Portfolio composition.

* **Returns:**
  **plot** *Figure*
  : Returns the plot Figure object.

<a id="skfolio.portfolio.Portfolio.plot_contribution"></a>

#### plot_contribution(measure, spacing=None)

Plot the contribution of each asset to a given measure.

* **Parameters:**
  **measure** *Measure*
  : The measure used for the contribution computation.

  **spacing** *float, optional*
  : Spacing “h” of the finite difference:
    $contribution(wi)= \frac{measure(wi-h) - measure(wi+h)}{2h}$
* **Returns:**
  **plot** *Figure*
  : The plotly Figure of assets contribution to the measure.

<a id="skfolio.portfolio.Portfolio.plot_cumulative_returns"></a>

#### plot_cumulative_returns(log_scale=False, idx=None)

Plot the Portfolio cumulative returns.
Non-compounded (arithmetic) cumulative returns start at 0.
Compounded (geometric) cumulative returns are expressed as a wealth index,
starting at 1.0 (i.e., the value of $1 invested).

* **Parameters:**
  **log_scale** *bool, default=False*
  : If this is set to True, the cumulative returns are displayed with a
    logarithm scale on the y-axis. The cumulative returns must be compounded
    otherwise an exception is raised.

  **idx** *slice | array, optional*
  : Indexes or slice of the observations to plot.
    The default (`None`) is to plot all observations.
* **Returns:**
  **plot** *Figure*
  : Returns the plot Figure object.

<a id="skfolio.portfolio.Portfolio.plot_drawdowns"></a>

#### plot_drawdowns(idx=None)

Plot the Portfolio drawdowns.

* **Parameters:**
  **idx** *slice | array, optional*
  : Indexes or slice of the observations to plot.
    The default (`None`) is to plot all observations.
* **Returns:**
  **plot** *Figure*
  : Returns the plot Figure object.

<a id="skfolio.portfolio.Portfolio.plot_returns"></a>

#### plot_returns(idx=None)

Plot the Portfolio returns.

* **Parameters:**
  **idx** *slice | array, optional*
  : Indexes or slice of the observations to plot.
    The default (`None`) is to plot all observations.
* **Returns:**
  **plot** *Figure*
  : Returns the plot Figure object

<a id="skfolio.portfolio.Portfolio.plot_returns_distribution"></a>

#### plot_returns_distribution(percentile_cutoff=None)

Plot the Portfolio returns distribution using Gaussian KDE.

* **Parameters:**
  **percentile_cutoff** *float, default=None*
  : Percentile cutoff for tail truncation (percentile), in percent.
    If a float p is provided, the distribution support is truncated at the p-th
    and (100 - p)-th percentiles.
    If None, no truncation is applied (uses full min/max of returns).
* **Returns:**
  **plot** *Figure*
  : Returns the plot Figure object

<a id="skfolio.portfolio.Portfolio.plot_rolling_measure"></a>

#### plot_rolling_measure(measure=Sharpe Ratio, window=30)

Plot the measure over a rolling window.

* **Parameters:**
  **measure** *Measure, default = RatioMeasure.SHARPE_RATIO*
  : The measure.

  **window** *int, default=30*
  : The window size.
* **Returns:**
  **plot** *Figure*
  : Returns the plot Figure object

<a id="skfolio.portfolio.Portfolio.predicted_attribution"></a>

#### predicted_attribution(factor_model, compute_asset_breakdowns=True)

Ex-ante (predicted) factor risk and performance attribution.

Decomposes the portfolio’s predicted risk and expected return into contributions
from individual factors and an idiosyncratic component using the factor model’s
latest forecast estimates (`loading_matrix`, `factor_covariance`,
`idio_covariance`, `factor_mu`, `idio_mu`).

The annualization scaling uses `self.annualization_factor`.

Predicted attribution uses only these latest forecast estimates, so no
observation alignment is required. The `factor_model` may therefore cover a
different observation window than the portfolio.

The portfolio may hold a subset of the assets covered by the factor model and
weights are zero-filled for missing assets.

See [`predicted_factor_attribution`](https://skfolio.org/generated/skfolio.attribution.predicted_factor_attribution.html.md#skfolio.attribution.predicted_factor_attribution)
for the full mathematical description.

* **Parameters:**
  **factor_model** *FactorModel*
  : Factor model whose latest forecast estimates are used. Every asset in
    `self.assets` must appear in `factor_model.asset_names`.

  **compute_asset_breakdowns** *bool, default=True*
  : If `True`, compute per-asset systematic/idiosyncratic decomposition. Set to
    `False` for faster computation when only portfolio-level results are needed.
* **Returns:**
  **attribution** *Attribution*
  : Component-level, factor-level, and optionally asset-level attribution
    results.
* **Raises:**
  ValueError
  : If the portfolio is a failed portfolio or if it holds assets not covered by
    the factor model.

<a id="skfolio.portfolio.Portfolio.previous_weights_dict"></a>

#### *property* previous_weights_dict

Dict mapping asset name to previous weight; includes zeros.

<a id="skfolio.portfolio.Portfolio.realized_attribution"></a>

#### realized_attribution(factor_model, compute_asset_breakdowns=True, compute_uncertainty=True)

Realized (ex-post) factor risk and performance attribution.

Decomposes the portfolio’s realized risk and return into contributions from
individual factors and an idiosyncratic component using actual historical factor
returns, exposures, and residuals.

The annualization scaling uses `self.annualization_factor`.

Realized attribution uses the target weights when `weight_drift=False` and the
weights held during each observation when `weight_drift=True`.

Realized attribution is computed on the overlapping observation window between
the portfolio and the factor model. Portfolio observations outside the factor
model window, commonly caused by factor-model warmup or exposure lag, are
excluded. Missing portfolio observations inside the overlapping window raise
`ValueError`. Time-varying exposures follow the as-of indexing convention
described in
[`realized_factor_attribution`](https://skfolio.org/generated/skfolio.attribution.realized_factor_attribution.html.md#skfolio.attribution.realized_factor_attribution):
when `exposure_lag > 0`, exposures known at observation
$t-\ell$ are aligned with returns at observation $t$.

The portfolio may hold a subset of the assets covered by the factor model and
weights are zero-filled for missing assets.

See [`realized_factor_attribution`](https://skfolio.org/generated/skfolio.attribution.realized_factor_attribution.html.md#skfolio.attribution.realized_factor_attribution)
for the full mathematical description.

* **Parameters:**
  **factor_model** *FactorModel*
  : Factor model containing time-varying fields (`factor_returns`, `exposures`,
    `idio_returns`) that overlap with the portfolio’s observation period. Every
    asset in `self.assets` must appear in `factor_model.asset_names`.

  **compute_asset_breakdowns** *bool, default=True*
  : If `True`, compute per-asset systematic/idiosyncratic attribution. Set to
    `False` for faster computation when only portfolio-level results are needed.

  **compute_uncertainty** *bool, default=True*
  : If `True`, compute attribution uncertainty (standard errors on the factor
    and idiosyncratic mean-return split).
* **Returns:**
  **attribution** *Attribution*
  : Component-level, factor-level, and optionally asset-level attribution
    results.
* **Raises:**
  ValueError
  : If the portfolio is a failed portfolio, if it holds assets not covered by
    the factor model, if no portfolio observations overlap with the factor model
    or if portfolio observations are missing inside the overlapping window.

<a id="skfolio.portfolio.Portfolio.returns_df"></a>

#### *property* returns_df

Portfolio returns DataFrame.

<a id="skfolio.portfolio.Portfolio.rolling_measure"></a>

#### rolling_measure(measure=Sharpe Ratio, window=30)

Compute the measure over a rolling window.

* **Parameters:**
  **measure** *Measure, default=RatioMeasure.SHARPE_RATIO*
  : The measure. The default measure is the Sharpe Ratio.

  **window** *int, default=30*
  : The window size. The default value is `30` observations.
* **Returns:**
  **series** *pandas Series*
  : The rolling measure Series.

<a id="skfolio.portfolio.Portfolio.rolling_realized_attribution"></a>

#### rolling_realized_attribution(factor_model, window_size=60, step=21, compute_asset_breakdowns=True, compute_asset_factor_contribs=False, compute_uncertainty=True)

Rolling realized (ex-post) factor risk and performance attribution.

Computes [`realized_factor_attribution`](https://skfolio.org/generated/skfolio.attribution.realized_factor_attribution.html.md#skfolio.attribution.realized_factor_attribution)
over rolling windows, returning an [`Attribution`](https://skfolio.org/generated/skfolio.attribution.Attribution.html.md#skfolio.attribution.Attribution)
where all numeric fields carry an additional leading dimension for the number
of windows.

Rolling realized attribution is computed on the overlapping observation window
between the portfolio and the factor model. Portfolio observations outside the
factor model window, commonly caused by factor-model warmup or exposure lag, are
excluded. Missing portfolio observations inside the overlapping window raise
`ValueError`. Time-varying exposures follow the as-of indexing convention
described in
[`rolling_realized_factor_attribution`](https://skfolio.org/generated/skfolio.attribution.rolling_realized_factor_attribution.html.md#skfolio.attribution.rolling_realized_factor_attribution).

Each rolling window uses the target weights when `weight_drift=False` and the
weights held during its observations when `weight_drift=True`.

The portfolio may hold a subset of the assets covered by the factor model and
weights are zero-filled for missing assets.

See [`rolling_realized_factor_attribution`](https://skfolio.org/generated/skfolio.attribution.rolling_realized_factor_attribution.html.md#skfolio.attribution.rolling_realized_factor_attribution)
for the full mathematical description.

* **Parameters:**
  **factor_model** *FactorModel*
  : Factor model containing time-varying fields that overlap with the
    portfolio’s observation period.

  **window_size** *int, default=60*
  : Number of effective return periods in each rolling window.

  **step** *int, default=21*
  : Number of observations to advance between consecutive windows. The default
    of 21 produces approximately monthly output for daily data.

  **compute_asset_breakdowns** *bool, default=True*
  : If `True`, compute per-asset attribution for each window.

  **compute_asset_factor_contribs** *bool, default=False*
  : If `True`, compute asset-factor matrix for each window.

  **compute_uncertainty** *bool, default=True*
  : If `True`, compute per-window attribution uncertainty.
* **Returns:**
  **attribution** *Attribution*
  : Rolling attribution results.
* **Raises:**
  ValueError
  : If the portfolio is a failed portfolio, if it holds assets not covered by
    the factor model, if no portfolio observations overlap with the factor model
    or if `window_size` exceeds the number of overlapping observations.

<a id="skfolio.portfolio.Portfolio.sample_weight"></a>

#### *property* sample_weight

Observations sample weights.

<a id="skfolio.portfolio.Portfolio.sric"></a>

#### *property* sric

Sharpe Ratio Information Criterion (SRIC).

It is an unbiased estimator of the Sharpe Ratio adjusting for both sources of
bias which are noise fit and estimation error [[1]](#r26ec43111d95-1).

### References

* <a id='r26ec43111d95-1'>**[1]**</a> “Noise Fit, Estimation Error and a Sharpe Information Criterion”, Dirk Paulsen (2019)

<a id="skfolio.portfolio.Portfolio.summary"></a>

#### summary(formatted=True)

Portfolio summary of all its measures.

* **Parameters:**
  **formatted** *bool, default=True*
  : If this is set to True, the measures are formatted into rounded string
    with units.
* **Returns:**
  **summary** *series*
  : Portfolio summary.

<a id="skfolio.portfolio.Portfolio.turnover"></a>

#### *property* turnover

Total absolute weight traded at the start of the period.

In a sequential evaluation, `previous_weights` come from the last successful
Portfolio. With `weight_drift=False`, target turnover compares successive
target allocations. With `weight_drift=True`, executed turnover compares the
previous period’s ending weights with the new target allocation. When
`previous_weights` is None, it defaults to zero. Turnover includes the full
absolute weight of positions in assets absent from `X`.

<a id="skfolio.portfolio.Portfolio.variance_from_assets"></a>

#### variance_from_assets(assets_covariance)

Compute the Portfolio variance expectation from the assets covariance and
weights.

* **Parameters:**
  **assets_covariance** *ndarray of shape (n_assets,n_assets)*
  : The matrix of assets covariance expectation.
* **Returns:**
  **value** *float*
  : The Portfolio variance from the assets covariance.

<a id="skfolio.portfolio.Portfolio.weights_dict"></a>

#### *property* weights_dict

Dict mapping asset name to weight; includes zeros.

<a id="skfolio.portfolio.Portfolio.weights_per_observation"></a>

#### *property* weights_per_observation

DataFrame of asset weights at the start of each observation.

With `weight_drift=False`, every row contains the target `weights`. With
`weight_drift=True`, each row incorporates the effect of preceding asset
returns. `ending_weights` contains the weights immediately after the final
observation.

