fun: -1.0597540702789927
x: array([ 6.59141408e-01, 8.82635668e-02, 2.52595026e-01,
8.34564622e-17, -8.91214186e-17])
message: ‘Optimization terminated successfully.’
jac: array([ 3.27527523e-05, -1.61930919e-04, -2.88933516e-05,
1.51561590e+00, 1.24186277e-03, 0.00000000e+00])
nit: 6
Our main interest lies in getting the optimal portfolio composition. To this end, we access
the results object by providing the key of interest — i.e., x in our case. The optimization
yields a portfolio that only consists of three out of the five assets:
In [ 55 ]: opts[‘x’].round( 3 )
Out[55]: array([ 0.659, 0.088, 0.253, 0. , -0. ])
Using the portfolio weights from the optimization, the following statistics emerge:
In [ 56 ]: statistics(opts[‘x’]).round( 3 )
Out[56]: array([ 0.235, 0.222, 1.06 ])
The expected return is about 23.5%, the expected volatility is about 22.2%, and the
resulting optimal Sharpe ratio is 1.06.
Next, let us minimize the variance of the portfolio. This is the same as minimizing the
volatility, but we will define a function to minimize the variance:
In [ 57 ]: def min_func_variance(weights):
return statistics(weights)[ 1 ] ** 2
Everything else can remain the same for the call of the minimize function:
In [ 58 ]: optv = sco.minimize(min_func_variance, noa * [1. / noa,],
method=‘SLSQP’, bounds=bnds,
constraints=cons)
In [ 59 ]: optv
Out[59]: status: 0
success: True
njev: 9
nfev: 64
fun: 0.018286019968366075
x: array([ 1.07591814e-01, 2.49124471e-01, 1.09219925e-01,
1.01101853e-17, 5.34063791e-01])
message: ‘Optimization terminated successfully.’
jac: array([ 0.03636634, 0.03643877, 0.03613905, 0.05222051,
0.03676446, 0. ])
nit: 9
This time a fourth asset is added to the portfolio. This portfolio mix leads to the absolute
minimum variance portfolio:
In [ 60 ]: optv[‘x’].round( 3 )
Out[60]: array([ 0.108, 0.249, 0.109, 0. , 0.534])
For the expected return, volatility, and Sharpe ratio, we get:
In [ 61 ]: statistics(optv[‘x’]).round( 3 )
Out[61]: array([ 0.087, 0.135, 0.644])
Efficient Frontier
The derivation of all optimal portfolios — i.e., all portfolios with minimum volatility for a
given target return level (or all portfolios with maximum return for a given risk level) — is
similar to the previous optimizations. The only difference is that we have to iterate over
multiple starting conditions. The approach we take is that we fix a target return level and
derive for each such level those portfolio weights that lead to the minimum volatility
value. For the optimization, this leads to two conditions: one for the target return level