Skip to main content

Portfolio Optimization for Pension Funds

Project description

PenFolioOp

Portfolio Optimizations for Pension Funds

codecov tests docs License: MIT

Conventions

In this framework, for convenience, we make use of the following conventions:

expected_returns $\mathbf{R}$ is an array of the expected returns of the assets and the liabilities.

$$ \mathbf{R} = \begin{bmatrix} R_1 \ R_2 \ \vdots \ R_n \ R_L \end{bmatrix} = \begin{bmatrix} \mathbf{R}_{A} \ R_L \end{bmatrix} $$

covariance_matrix $\Sigma$ is the covariance matrix of the asset and the liability returns.

$$ \Sigma = \begin{bmatrix} \Sigma_{A} & \Sigma_{AL} \ \Sigma_{AL} & \sigma^{2}_{L} \end{bmatrix}, $$

where $\Sigma_{A}$ is the covariance matrix of the asset returns, $\Sigma_{AL}$ is a vector of the covariance between the asset and liability returns, and $\sigma^{2}_{L}$ is the variance of the liability returns.

The output of the optimization process is a weight vector $\mathbf{W}$ consisting of the optimal asset weights, and the liability weight is always set to -1. The optimization process aims to find the asset weights that maximize or minimize the chosen objective function while satisfying the specified constraints.

$$ \mathbf{W} = \begin{bmatrix} w_1 \ w_2 \ \vdots \ w_n \ -1 \end{bmatrix} = \begin{bmatrix} \mathbf{W}_{A} \ -1 \end{bmatrix} $$

surplus_return $\mathbf{R}_{S}$ is the return of the portfolio minus the return of the liabilities.

$$R_{S} = R_{P} - R_{L} = W_{A} ^ {T}R_{A} - R_{L} = W ^ {T} R$$

surplus_variance $\sigma^{2}_{S}$ is the variance of the surplus returns: $\sigma^{2}_{S} = W_{A}^{T} \Sigma_{A} W_{A} - 2 W_{A}^{T} \Sigma_{AL} + \sigma^{2}_{L} = W^{T} \Sigma W $

Optimizers

With the defined surplus return and variance, we can now outline the optimization problems. All the optimizers are subject to these general constraints:

$$ \begin{align*} (1) &\quad& \sum_{i=1}^{n_{assets}} w_{i} = \mathrm{SUM}(W_{A}) = 1, \ (2) &\quad& w_{i} \geq 0, \quad \forall i \in {1, \ldots, n_{assets}}, \ (3) &\quad& w_{L} = -1 \end{align*} $$

optimizer formulation constraints
max_surplus_return_optimizer $\underset{\mathbf{W}}{\mathrm{maximize}} \quad \mathbf{W}^{T}\mathbf{R}$ $\mathbf{W}^{T} \mathbf{\Sigma} \mathbf{W} \leq$ surplus_risk_upper_limit
min_surplus_variance_optimizer $\underset{\mathbf{W}}{\mathrm{minimize}} \quad \mathbf{W}^{T} \mathbf{\Sigma} \mathbf{W}$ $\mathbf{W}^{T}\mathbf{R} \geq$ surplus_return_lower_limit
max_surplus_sharpe_ratio_optimizer $\underset{\mathbf{W}}{\mathrm{maximize}} \quad \frac{\mathbf{W}^{T}\mathbf{R}}{\sqrt{\mathbf{W}^{T} \mathbf{\Sigma} \mathbf{W}}}$ None
surplus_mean_variance_optimizer $\underset{\mathbf{W}}{\mathrm{maximize}} \ \quad \mathbf{W}^{T}\mathbf{R} - \frac{\lambda}{2} \mathbf{W}^{T} \mathbf{\Sigma} \mathbf{W}$ None

In the above table, $\lambda$ is a risk aversion parameter that balances the trade-off between maximizing surplus returns and minimizing surplus risk. In addition to the above optimizers, the user can also call the efficient_frontier function to compute the weights of the efficient frontier portfolio. These portfolios can be found by varying the surplus_return_lower_limit in the following min_surplus_variance_optimizer optimizer. In this case, the user needs to provide a range of values for the surplus_return_lower_limit parameter.

Additional Constraints

Asset weight constraints can be applied to ensure that the portfolio adheres to specific investment guidelines.

Example

Usage of the library is straightforward. You can create a portfolio object, define your assets, and then use the optimizers to find the optimal asset weights based on your constraints and objectives. The first step is to create a Portfolio object with your assets, their expected returns, and covariances. The last item in the list of assets should be the liability, which is treated differently ,from the other assets in the optimization process. The optimizaters always set the liability weight to -1 and require the other asset weights to be between 0 and 1 and sum to 1.

The user can then define additional constraints on the asset weights, such as requiring a minimum or maximum weight for certain assets or limiting the weight of one or more assets to be less than another.

For a comprehensive description of the constraints, refer to the API documentation.

import numpy as np

from penfolioop.portfolio import Portfolio
from penfolioop.optimizers import max_surplus_return_optimizer

names = ['Asset A', 'Asset B', 'Asset C', 'Liability']
expected_returns = np.array([0.05, 0.07, 0.06, 0.04])
covariance_matrix = np.array([[0.0001, 0.00005, 0.00002, 0.00003],
               [0.00005, 0.0002, 0.00001, 0.00004],
               [0.00002, 0.00001, 0.00015, 0.00002],
               [0.00003, 0.00004, 0.00002, 0.0001]]

portfolio = Portfolio(names=names, expected_returns=expected_returns, covariance_matrix=covariance_matrix)

constraints = [
    {
        'left_indices': ['Asset A', 'Asset B'],
        'operator': '>=',
        'right_value': 0.5
    }
    {
        'left_indices': ['Asset C'],
        'operator': '<=',
        'right_index': ['Asset B']
    }
]

weights = max_surplus_return_optimizer(portfolio=portfolio, asset_constraints=constraints, surplus_risk_upper_limit=0.0001)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

penfolioop-0.2.1.tar.gz (12.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

penfolioop-0.2.1-py3-none-any.whl (14.3 kB view details)

Uploaded Python 3

File details

Details for the file penfolioop-0.2.1.tar.gz.

File metadata

  • Download URL: penfolioop-0.2.1.tar.gz
  • Upload date:
  • Size: 12.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.14

File hashes

Hashes for penfolioop-0.2.1.tar.gz
Algorithm Hash digest
SHA256 8e5889526e81db91e8283bf45f39d36f9d593b222647015b171d9c0d3b16bd1a
MD5 fa819212b98a4f880889746f984f5efe
BLAKE2b-256 0dfcbc5e3ec3fdf898cbd97a42f3c8565bef9091c597d1d9d2d9ac8b7176d022

See more details on using hashes here.

File details

Details for the file penfolioop-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: penfolioop-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 14.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.14

File hashes

Hashes for penfolioop-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c8024306986ab9a20c63f0f738e5a29d41a7f3b1afdb4371524771e03965bc8e
MD5 fc0b8963ef79aec4bac561e427094b30
BLAKE2b-256 74c6fbeb22ffe3c902402091ab77ed5b5eb57eba048fce63474d11096c817f57

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page