-
Return and Variance 7
-
Lecture1.1
-
Lecture1.2
-
Lecture1.3
-
Lecture1.4
-
Lecture1.5
-
Lecture1.6
-
Lecture1.7
-
-
Solving Equations 5
-
Lecture2.1
-
Lecture2.2
-
Lecture2.3
-
Lecture2.4
-
Lecture2.5
-
-
Capital Allocation Line 6
-
Lecture3.1
-
Lecture3.2
-
Lecture3.3
-
Lecture3.4
-
Lecture3.5
-
Lecture3.6
-
-
Diversification 3
-
Lecture4.1
-
Lecture4.2
-
Lecture4.3
-
-
Investment Sets 3
-
Lecture5.1
-
Lecture5.2
-
Lecture5.3
-
-
Portfolios 7
-
Lecture6.1
-
Lecture6.2
-
Lecture6.3
-
Lecture6.4
-
Lecture6.5
-
Lecture6.6
-
Lecture6.7
-
-
Capital and Security Market Lines 3
-
Lecture7.1
-
Lecture7.2
-
Lecture7.3
-
-
Arbitrage 3
-
Lecture8.1
-
Lecture8.2
-
Lecture8.3
-
-
Dividend Discount Model 2
-
Lecture9.1
-
Lecture9.2
-
-
Fixed Income 4
-
Lecture10.1
-
Lecture10.2
-
Lecture10.3
-
Lecture10.4
-
-
Duration and Immunization 4
-
Lecture11.1
-
Lecture11.2
-
Lecture11.3
-
Lecture11.4
-
Optimization
First, we need to make a constraint that says the sum of our weights (x) is equal to 1. The first line specifies an equality, the second specifies the function set equal to 0.
import scipy.optimize
con = {'type': 'eq',
'fun': lambda x: sum(x)-1}
I’m going to put the optimization function down first, and then explain each argument. We are trying to minimize the standard deviation.
scipy.optimize.minimize(lambda x: portfolioSTD(x,matrix),x0=[np.zeros(10)],bounds=[(0,1)]*10,constraints=con)
lambda x: portfolioSTD(x,matrix) is the way we specify our function as a one argument function, we are only plugging in x (the weights) and holding the covariance matrix fixed.
x0=[np.zeros(10)] makes a starting array where each weight is 0, this is a terrible guess, but we will improve the guess later.
bounds=[(0,1)]*10 restricts each weight to be between 0 and 1. We multiply by 10 so we have the bound for each weight.
constraints=con sets our constraint to what we created before.
Let’s see what the best portfolio looks like.
ar = scipy.optimize.minimize(lambda x: portfolioSTD(x,matrix),x0=[np.zeros(10)],bounds=[(0,1)]*10,constraints=con)["x"]
print(ar)
print(portfolioSTD(ar,matrix))
print(portfolioReturn(ar,rets))
And let’s plot it.
plt.scatter(portfolios[:,2],portfolios[:,1],c=portfolios[:,3],cmap=coolwarm)
plt.plot(bestPortfolios[:,2],bestPortfolios[:,1])
plt.plot(portfolioSTD(ar,matrix),portfolioReturn(ar,rets),'ko')
plt.ylim([.04,.075])
plt.xlabel("Standard Deviation")
plt.ylabel("Expected Return")
plt.title("Portfolio Sets")
plt.show()
This is the minimum variance portfolio, where the covariances and variances are optimized to give the least amount of total risk.
The plan now is to take the line we already have as starting points, and further optimize it to get the absolute best possible curve.
To begin, I will show you how we will change the optimization to optimize total return first.
con1 = {'type': 'eq',
'fun': lambda x: sum(x)-1}
ar = scipy.optimize.minimize(lambda x: -portfolioReturn(x,rets),x0=[np.zeros(10)],bounds=[(0,1)]*10,constraints=con1)["x"]
print(ar)
print(portfolioSTD(ar,matrix))
print(portfolioReturn(ar,rets))
First, notice I put a negative in front of portfolioReturn(), this is because we want to maximize it so we do the reverse of minimization. Also, notice that all the weight is in one stock the one with the highest return, which makes sense.
Challenge