Skip to content

Dynamic Portfolio Optimization API Reference

Data

Data model for Dynamic Portfolio Optimization use case.

DynamicPoData

Bases: UcData

Data for the Dynamic Portfolio Optimization use case.

Models a multi-period portfolio selection problem where an investor rebalances a portfolio over several time steps, incurring transaction costs when changing asset selections between periods.

Attributes:

  • name (Literal['dynamic_portfolio_optimization']) –

    Identifier for this data type.

  • tickers (list[str]) –

    Names of the available assets.

  • expected_returns (NumPyArray) –

    Float 2D NumPyArry - Expected returns per asset for each time step. Shape: [n_time_steps][n_assets].

  • covariance_matrices (NumPyArray) –

    2d NumPyArray - Covariance matrices for each time step. Each element is an [n_assets x n_assets] array.

  • n_assets (int) –

    Number of available assets.

  • n_time_steps (int) –

    Number of time periods.

  • pick_n (int) –

    Number of assets to select per period.

  • risk_aversion (float) –

    Risk aversion parameter (higher = more risk-averse).

  • transaction_cost (float) –

    Transaction cost as a percentage (applied when changing positions).

from_returns(returns: NDArray[np.float64], tickers: list[str], pick_n: int, window: int = 10, risk_aversion: float = 1.0, transaction_cost: float = 0.01) -> DynamicPoData staticmethod

Create a Dynamic Portfolio Optimization instance from raw return data.

This function transforms a static asset return matrix into a time-dependent optimization dataset by estimating expected returns and covariance matrices over a rolling window.

Each time step represents a re-estimation point where market statistics are computed from the most recent historical observations.

Parameters:

  • returns (NDArray[float64]) –

    Asset return matrix with shape (T, N), where: - T = number of time steps - N = number of assets Each entry represents a period return of an asset.

  • tickers (list[str]) –

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

  • pick_n (int) –

    Number of assets to select at each time step.

  • window (int, default: 10 ) –

    Size of the rolling window used to estimate statistics.

    For each time step t, only returns from: [t - window, ..., t - 1] are used to compute: - expected return μ[t] - covariance matrix Σ[t]

    This ensures that parameter estimation is based only on past data.

  • risk_aversion (float, default: 1.0 ) –

    Trade-off parameter between expected return and risk.

  • transaction_cost (float, default: 0.01 ) –

    Cost incurred when changing asset selections between consecutive time steps.

Returns:

  • DynamicPoData

    A time-dependent dataset containing: - expected_returns[t]: expected return vector at time t - covariance_matrices[t]: covariance matrix at time t - discrete time steps aligned with rolling estimation

Notes
  • The first window observations are used only for initialization and do not appear in the output.
  • Each time step t corresponds to a decision point where a portfolio can be re-optimized.
  • This construction avoids lookahead bias in statistical estimation, but the optimization over all time steps is still performed jointly in an offline setting.

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

Plot cumulative asset performance over time for the dynamic portfolio data.

Each asset's return series is converted into a cumulative growth curve, representing the evolution of an initial investment of 1 unit over time.

This visualization provides a baseline view of how individual assets evolve across multiple time steps in the dynamic setting.

Parameters:

  • ax (Axes | None, default: None ) –

    Optional matplotlib axes to draw on. If None, a new figure and axes are created.

Returns:

  • Axes

    Matplotlib axes containing the cumulative return plots for all assets.

Notes
  • Each curve represents the compounded growth of an asset over time.
  • The plot does not incorporate portfolio selection or optimization results.
  • Intended as a data-level overview of temporal return dynamics.

to_string() -> str

Return a string describing the dynamic portfolio optimization data.

generate_random(n_assets: int = 4, n_time_steps: int = 2, pick_n: int = 2, seed: int | None = None) -> DynamicPoData staticmethod

Generate a random Dynamic Portfolio Optimization instance.

Parameters:

  • n_assets (int, default: 4 ) –

    Number of assets (default: 4).

  • n_time_steps (int, default: 2 ) –

    Number of time periods (default: 2).

  • pick_n (int, default: 2 ) –

    Number of assets to select per period (default: 2).

  • seed (int | None, default: None ) –

    Random seed for reproducibility (default: None).

Returns:

Formulation

Formulation for Dynamic Portfolio Optimization use case.

DynamicPoFormulation

Bases: UcFormulation[DynamicPoData, DynamicPoSolution]

Formulation for the Dynamic Portfolio Optimization problem.

Selects pick_n assets at each time step to maximize risk-adjusted returns while penalizing portfolio changes between consecutive periods via transaction costs.

Mathematical Formulation

Decision Variables: x[t,i] in {0,1} -- asset i is selected at time step t z[t,i] in {0,1} -- indicates a change in asset i between t-1 and t (t>0)

Objective (maximize): sum_t sum_i mu[t][i]x[t,i] - risk_aversion * sum_t sum_{i,j} sigma[t][i][j]x[t,i]*x[t,j] - transaction_cost * sum_{t>0} sum_i z[t,i]

Constraints: 1. Pick exactly pick_n assets per period: sum_i x[t,i] == pick_n for each t 2. Transaction cost linearization (for t>0): z[t,i] >= x[t,i] - x[t-1,i] z[t,i] >= x[t-1,i] - x[t,i]

to_string(data: DynamicPoData) -> str staticmethod

Format the formulation as a string.

Parameters:

Returns:

  • str

    String representation of the formulation.

formulate(data: DynamicPoData) -> Model staticmethod

Formulate the Dynamic Portfolio Optimization problem as an optimization model.

Encodes asset selection over time as a binary program that maximizes risk-adjusted returns subject to portfolio size and transaction cost linearization constraints.

Parameters:

  • data (DynamicPoData) –

    The problem data containing expected returns, covariance matrices, and cost parameters.

Returns:

  • Model

    A Luna optimization model representing the dynamic portfolio problem.

interpret(solution: Solution, data: DynamicPoData) -> DynamicPoSolution staticmethod

Extract solution from solver result.

Reconstructs the asset selection per period, computes portfolio return, risk, and transaction costs, and validates all constraints.

Parameters:

  • solution (Solution) –

    The solution containing variable assignments.

  • data (DynamicPoData) –

    The original problem data.

Returns:

  • DynamicPoSolution

    A structured solution object with: - selections: selected tickers per time step - portfolio_return: total expected return across all periods - portfolio_risk: total covariance-weighted risk across all periods - total_transaction_cost: total cost incurred by portfolio changes - is_valid: whether all constraints are satisfied

Raises:

Solution

Solution model for Dynamic Portfolio Optimization use case.

DynamicPoSolution

Bases: UcSolution

Solution for the Dynamic Portfolio Optimization use case.

Attributes:

  • name (Literal['dynamic_portfolio_optimization']) –

    Identifier for this solution type.

  • selections (list[list[str]]) –

    Selected asset tickers per time period.

  • portfolio_return (float) –

    Total expected portfolio return across all periods.

  • portfolio_risk (float) –

    Total portfolio risk (variance) across all periods.

  • is_valid (bool) –

    Whether the solution satisfies all constraints (exactly pick_n assets per period).

  • total_transaction_cost (float) –

    Total transaction costs incurred by portfolio changes across all periods.

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

Visualize selected assets and portfolio performance over time.

This plot overlays three components: 1. Individual asset cumulative return curves 2. Highlighted selected assets per time step 3. Constructed portfolio growth curve based on selected assets 4. Baseline average asset performance for comparison

The visualization is designed to mirror the Portfolio Optimization (PO) use case style, enabling direct comparison between static and dynamic portfolio selection behavior.

Parameters:

  • data (DynamicPoData) –

    Input dataset containing asset returns and covariance structure.

  • ax (Axes | None, default: None ) –

    Optional matplotlib axes to draw on. If None, a new figure and axes are created.

Returns:

  • Axes

    Matplotlib axes showing: - Selected vs unselected asset trajectories - Portfolio performance curve (dynamic selection) - Baseline average market performance

Notes
  • Selected assets are highlighted, unselected assets are de-emphasized.
  • The portfolio curve is constructed from period-wise selected assets.
  • This visualization aligns the dynamic model with the PO interpretation of growth-based portfolio evaluation.

to_string() -> str

Return a string describing the dynamic portfolio optimization solution.

Instance

Instance model for DynamicPo use case.

DynamicPoInstance

Bases: UcInstance[DynamicPoData, DynamicPoFormulation, DynamicPoSolution]

Instance combining data and formulation for DynamicPo.

Collection

Collection of Dynamic Portfolio Optimization instances.

DynamicPoCollection

Bases: UcInstanceCollection[DynamicPoInstance]

Collection of Dynamic Portfolio Optimization instances.

This collection provides methods to generate benchmark instances with various characteristics for testing and evaluation.

from_random(min_assets: int = 3, max_assets: int = 6, n_time_steps: int = 2, pick_n: int = 2, num_instances: int = 1, *, seed: int | None = None) -> DynamicPoCollection classmethod

Generate random Dynamic Portfolio Optimization instances.

Parameters:

  • min_assets (int, default: 3 ) –

    Minimum number of assets per instance (default: 3).

  • max_assets (int, default: 6 ) –

    Maximum number of assets per instance (default: 6).

  • n_time_steps (int, default: 2 ) –

    Number of time periods (default: 2).

  • pick_n (int, default: 2 ) –

    Number of assets to select per period (default: 2).

  • num_instances (int, default: 1 ) –

    Number of instances per asset count (default: 1).

  • seed (int | None, default: None ) –

    Random seed for reproducibility (default: None).

Returns: