Skip to content

Portfolio Optimization (PO) API Reference

Data

Data model for Portfolio Optimization use case.

PopData

Bases: UcData

Input data for the Portfolio Optimization use case.

This class defines the historical return data and configuration used to construct a portfolio selection problem.

Attributes:

Name Type Description
name Literal['portfolio_optimization']

Identifier of the use case.

returns NumPyArray

Historical returns with shape (n_assets, n_periods).

Each entry represents the return of an asset in a given time period: r = (price_t / price_{t-1}) - 1

Values are dimensionless (e.g. 0.01 = 1% return per period).

asset_names list[str]

Names of the assets. Must match the first dimension of returns.

pick_n int

Number of assets to select in the optimization.

risk_aversion float

Trade-off parameter between risk and return: higher → more emphasis on minimizing risk lower → more emphasis on maximizing return

Notes
  • All returns are assumed to be on the same time scale (e.g. daily).
  • The model derives expected returns and covariance from this data.

mu_sigma: tuple[np.ndarray, np.ndarray] cached property

Compute expected returns (mu) and covariance matrix (sigma).

This function derives the key statistical inputs for mean-variance portfolio optimization from historical return data.

Returns:

Name Type Description
mu ndarray

Expected return per asset, computed as the average return over time: mu[i] = E[r_i]

sigma ndarray

Covariance matrix of asset returns with shape (n_assets, n_assets): sigma[i, j] = Cov(r_i, r_j)

The covariance captures both: - individual asset risk (variance when i == j) - interaction between assets (correlation when i != j)

plot(*, ax: Axes | None = None) -> Axes

Plot cumulative returns per asset over time.

Each asset is shown as a growth curve of 1 unit invested.

Returns:

Type Description
Axes

to_string() -> str

Return a human-readable summary of the dataset.

from_returns(returns: np.ndarray, asset_names: list[str], pick_n: int, risk_aversion: float = 1.0) -> PopData staticmethod

Create PopData from historical returns.

Parameters:

Name Type Description Default
returns ndarray

2D array of historical returns with shape (n_assets, n_periods).

required
asset_names list[str]

Names of the assets.

required
pick_n int

Number of assets to select.

required
risk_aversion float

Risk aversion parameter, by default 1.0.

1.0

Returns:

Type Description
PopData

Portfolio optimization data instance.

Raises:

Type Description
ValueError

If returns is not a 2D array, asset_names length does not match the number of rows in returns, pick_n is not in [1, n_assets], or asset_names contains duplicates.

generate_random(n_assets: int = 5, n_periods: int = 100, pick_n: int | None = None, risk_aversion: float = 1.0, seed: int | None = None) -> PopData staticmethod

Generate a random portfolio optimization instance.

Parameters:

Name Type Description Default
n_assets int

Number of assets, by default 5.

5
n_periods int

Number of time periods, by default 100.

100
pick_n int | None

Number of assets to select. Defaults to n_assets // 2 if None.

None
risk_aversion float

Risk aversion parameter, by default 1.0.

1.0
seed int | None

Random seed for reproducibility, by default None.

None

Returns:

Type Description
PopData

A randomly generated data instance.

Examples:

>>> data = PopData.generate_random(n_assets=5, seed=42)

Formulation

Formulation for Portfolio Optimization use case.

PopFormulation

Bases: UcFormulation[PopData, PopSolution]

Discrete Portfolio Optimization based on Mean-Variance principles.

This formulation selects a fixed number of assets in order to balance expected return and portfolio risk. It is inspired by the classical Markowitz model but uses binary decision variables instead of continuous weights.

Mathematical Formulation

Decision Variables: x[i] in {0,1}: 1 if asset i is selected, 0 otherwise

Model Parameters: mu[i] : expected return of asset i sigma[i,j] : covariance between asset i and j lambda : risk aversion parameter

Objective: minimize lambda * sum_{i,j} sigma_{ij} x_i x_j - sum_i mu_i x_i

where:
- the first term represents portfolio risk
- the second term represents expected return

Constraints: 1. Select exactly pick_n assets: sum_i x[i] == pick_n

Notes
  • This is a discrete (combinatorial) variant of portfolio optimization.
  • Selected assets are equally weighted in the interpretation step.
  • The quadratic term x_i x_j captures interactions between selected assets.

to_string(data: PopData) -> str staticmethod

Format the formulation as a human-readable description.

This method provides a structured summary of the optimization problem, including the meaning of key parameters used in the model.

Parameters:

Name Type Description Default
data PopData

The problem data.

required

Returns:

Type Description
str

Formatted description of the formulation.

formulate(data: PopData) -> Model staticmethod

Formulate the Portfolio Optimization problem as an optimization model.

Parameters:

Name Type Description Default
data PopData

The problem data.

required

Returns:

Type Description
Model

A Luna optimization model representing the portfolio selection problem.

interpret(solution: Solution, data: PopData) -> PopSolution staticmethod

Extract solution from solver result.

Parameters:

Name Type Description Default
solution Solution

The solver solution.

required
data PopData

The original problem data.

required

Returns:

Type Description
PopSolution

Structured solution with metrics.

Raises:

Type Description
NoSolutionFoundError

If no feasible solution was found.

Solution

Solution model for Portfolio Optimization use case.

PopSolution

Bases: UcSolution

Solution for the Portfolio Optimization use case.

This object contains both the discrete selection result of the optimization model and derived financial metrics for the resulting portfolio.

Attributes:

Name Type Description
name str

Solution identifier.

selected_assets list[str]

Names of assets selected by the optimization model.

expected_return float

Expected return of the resulting portfolio (mean return per period), assuming equal weighting of all selected assets.

portfolio_risk float

Portfolio variance (risk) per period, computed from the covariance matrix and assuming equal weighting. This is NOT the standard deviation.

is_valid bool

Whether the solution satisfies the model constraint (exactly pick_n assets selected).

objective_value float

Value of the optimization objective function: lambda * risk - return

This is a model-specific score used for optimization and is not directly interpretable as a financial quantity.

Notes
  • All reported metrics are based on equal weighting of selected assets.
  • Returns and risk are expressed per time period of the input data.
  • The square root of portfolio_risk corresponds to portfolio volatility.

plot(data: PopData, *, ax: Axes | None = None) -> Axes

Plot portfolio selection on top of asset return curves.

Selected assets are highlighted, unselected assets are greyed out. A summary of portfolio performance is shown for comparison.

Parameters:

Name Type Description Default
data PopData

Input data used for the optimization.

required
ax Axes | None

Optional matplotlib axes.

None

Returns:

Type Description
Axes

to_string() -> str

Return a human-readable summary of the portfolio solution.

The reported metrics describe the performance of an equally weighted portfolio consisting of the selected assets.

Instance

Instance model for Po use case.

PopInstance

Bases: UcInstance[PopData, PopFormulation, PopSolution]

Instance combining data and formulation for Po.

Collection

Collection of Portfolio Optimization instances.

PopStockCollection

Bases: UcInstanceCollection[PopInstance]

Collection of Portfolio Optimization instances.

create_custom_portfolio(min_n_assets: int, max_n_assets: int, pick_n: int, risk_aversion: float = 1.0, days: int = 180, seed: int | None = None) -> PopStockCollection staticmethod

Create a custom portfolio with specified parameters.

Randomly samples N assets from the predefined pool and fetches real market data from Yahoo Finance.

Parameters:

Name Type Description Default
min_n_assets int

Minimum number of assets to sample from the pool

required
max_n_assets int

Maximum number of assets to sample from the pool

required
pick_n int

Number of assets to select in the portfolio

required
risk_aversion float

Risk aversion parameter (default: 1.0)

1.0
days int

Number of days of historical data to fetch (default: 180)

180
seed int | None

Random seed for reproducibility (default: None)

None

Returns:

Type Description
PopStockCollection

Collection of portfolio instances with varying number of assets