Performance Utilities

Scenario-based return diagnostics live in pyvallocation.utils.performance. The helpers generate scenario P&L vectors and condensed reports (mean, volatility, VaR, CVaR, effective scenario count) using the same single-period algebra as the rest of the library. They feature prominently in the <no title> notebook.

Performance summaries for single-period scenario analysis.

pyvallocation.utils.performance.drawdown_quantile(weights, invariants, horizon, *, confidence=0.95, n_paths=1000, p=None, reprice=None, seed=None)[source]

Compute the maximum drawdown distribution via path simulation.

Simulates full wealth paths, computes the maximum peak-to-trough drawdown of each path, and returns summary statistics.

Parameters:
  • weights – Portfolio weights.

  • invariants – Invariant scenarios (T, N).

  • horizon – Path length in invariant time steps.

  • confidence – Quantile level for the drawdown statistic.

  • n_paths – Number of simulated paths.

  • p – Optional scenario probabilities.

  • reprice – Repricing callable (default reprice_exp).

  • seed – Random seed.

Returns:

pd.Series – Keys max_dd_mean, max_dd_median, max_dd_{confidence}, max_dd_worst.

Parameters:
  • weights (numpy.ndarray | pandas.Series | pandas.DataFrame)

  • invariants (numpy.ndarray | pandas.DataFrame | pandas.Series)

  • horizon (int)

  • confidence (float)

  • n_paths (int)

  • p (numpy.ndarray | pandas.Series | Sequence[float] | None)

  • seed (int | None)

Return type:

pandas.Series

pyvallocation.utils.performance.horizon_report(weights, invariants, *, horizons=(4, 13, 26, 52), n_simulations=5000, p=None, reprice=None, confidence=0.95, seed=None)[source]

Compare risk metrics across multiple projection horizons.

For each horizon, bootstraps invariants via project_scenarios(), reprices, and computes performance_report().

Parameters:
  • weights – Portfolio weights.

  • invariants – Invariant scenarios (T, N).

  • horizons – Sequence of horizon lengths (in invariant time steps).

  • n_simulations – Scenarios per horizon.

  • p – Optional scenario probabilities.

  • reprice – Repricing callable (default reprice_exp).

  • confidence – Confidence level for VaR/CVaR.

  • seed – Base random seed (incremented per horizon for independence).

Returns:

pd.DataFrame – Rows = horizons, columns = mean, stdev, VaR, CVaR, ENS.

Parameters:
  • weights (numpy.ndarray | pandas.Series | pandas.DataFrame)

  • invariants (numpy.ndarray | pandas.DataFrame | pandas.Series)

  • horizons (Sequence[int])

  • n_simulations (int)

  • p (numpy.ndarray | pandas.Series | Sequence[float] | None)

  • confidence (float)

  • seed (int | None)

Return type:

pandas.DataFrame

pyvallocation.utils.performance.performance_report(weights, scenarios, *, probabilities=None, confidence=0.95, demean=False)[source]

Summarise mean, volatility, VaR, CVaR, and ENS for a single allocation.

Parameters:
  • weights – Allocation vector (numpy array or pandas Series/DataFrame with a single column). Labels are aligned with scenarios when present.

  • scenarios – Scenario matrix R with shape (T, N) (NumPy or pandas).

  • probabilities – Optional scenario weights p. When omitted a uniform distribution is used.

  • confidence – Confidence level for VaR/CVaR (e.g. 0.95 means 5% tail). Defaults to 0.95.

  • demean – If True the scenario P&L is demeaned before VaR/CVaR are computed.

Returns:

pd.Series – Series containing the portfolio mean, standard deviation, VaR, CVaR, and effective number of scenarios.

Raises:

ValueError – If inputs are inconsistent (e.g. mismatched dimensions or invalid probabilities).

Parameters:
  • weights (numpy.ndarray | pandas.Series | pandas.DataFrame)

  • scenarios (numpy.ndarray | pandas.DataFrame | pandas.Series)

  • probabilities (numpy.ndarray | pandas.Series | Sequence[float] | None)

  • confidence (float)

  • demean (bool)

Return type:

pandas.Series

Notes

VaR and CVaR follow the loss convention: profitable scenarios appear as negative numbers (gains) while losses are positive.

Examples

>>> import numpy as np
>>> from pyvallocation.utils.performance import performance_report
>>> scenarios = np.array([[0.02, 0.00], [0.02, 0.00]])
>>> performance_report([0.5, 0.5], scenarios).round(4)
mean      0.0100
stdev     0.0000
VaR95    -0.0100
CVaR95   -0.0100
ENS       2.0000
dtype: float64
pyvallocation.utils.performance.scenario_pnl(weights, scenarios)[source]

Compute scenario-by-scenario portfolio P&L.

Parameters:
  • weights – Portfolio weights. Accepts numpy arrays, pandas Series/DataFrames, or a mapping asset -> weight.

  • scenarios – Scenario matrix R of shape (T, N) (NumPy or pandas). When a pandas object is supplied, the returned object preserves the original index/columns.

Returns:

ArrayLike – Scenario P&L with shape (T,) or (T, M) depending on the number of portfolios supplied.

Raises:

ValueError – If scenario dimensions are inconsistent with the weight vector/matrix.

Parameters:
  • weights (numpy.ndarray | pandas.Series | pandas.DataFrame)

  • scenarios (numpy.ndarray | pandas.DataFrame | pandas.Series)

Return type:

numpy.ndarray | pandas.DataFrame | pandas.Series

Examples

>>> import numpy as np
>>> from pyvallocation.utils.performance import scenario_pnl
>>> scenarios = np.array([[0.02, 0.00], [0.00, 0.02]])
>>> scenario_pnl([0.5, 0.5], scenarios)
array([0.01, 0.01])