Portfolio Optimizations for Pension Funds
In this framework, for convenience, we make use of the following conventions:
expected_returns
covariance_matrix
where
The output of the optimization process is a weight vector
surplus_return
surplus_variance
With the defined surplus return and variance, we can now outline the optimization problems. All the optimizers are subject to these general constraints:
optimizer | formulation | constraints |
---|---|---|
max_surplus_return_optimizer |
surplus_risk_upper_limit
|
|
min_surplus_variance_optimizer |
surplus_return_lower_limit
|
|
max_surplus_sharpe_ratio_optimizer |
None |
|
surplus_mean_variance_optimizer |
None |
In the above table, 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.
Asset weight constraints can be applied to ensure that the portfolio adheres to specific investment guidelines.
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)