In [1]:
using Dates, LinearAlgebra
include("jlFiles/printmat.jl")
include("jlFiles/printTable.jl")
Out[1]:
In [2]:
using Plots
#pyplot(size=(600,400)) #pyplot() or gr()
gr(size=(480,320))
default(fmt = :svg)
In [3]:
include("jlFiles/MvCalculations.jl")
Out[3]:
An investor who maximizes
$\text{E}U(R_{p}) =\text{E}R_{p}-\frac{k}{2} \text{Var}(R_{p})$,
subject to
$R_{p} = v'R^e + R_f$
will pick the portfolio weights (on the risky assets)
$v =\frac{1}{k}\Sigma^{-1}\mu^{e}$
The portfolio weight on the riskfree asset is $1-\mathbf{1}'v$
In [4]:
"""
Calculate optimal portfolio weights
"""
function OptimalPortfolio(μ,Σ,Rf,k)
μᵉ = μ .- Rf #expected excess returns
v = inv(Σ) * μᵉ/k #optimal weights risky assets, 1-sum(v) in riskfree
mup = v'μ + (1-sum(v))*Rf #expected return and std of optimal portfolio
StdRp = sqrt(v'Σ*v)
return v,mup,StdRp
end
Out[4]:
In [5]:
μ = [8.5; 6.5]/100 #means
Σ = [ 166 34; #covariance matrix
34 64]/100^2
Rf = 3/100 #riskfree rate
Out[5]:
In [6]:
k = 9 #illustrating the objective function
(n1,n2) = (21,23)
v1 = range(-0.5,stop=1.5,length=n1)
v2 = range(-0.5,stop=1.5,length=n2)
Util = fill(NaN,(n1,n2))
for i = 1:n1, j = 1:n2
#local v #only needed in REPL/script
v = [v1[i];v2[j]]
Util[i,j] = v'μ + (1-sum(v))*Rf - (k/2)*v'Σ*v
end
In [7]:
surface( v1,v2,Util',
size = (600,433),
legend = false,
xlims = (-0.5,1.5),
ylims = (-0.5,1.5),
zlims = (-0.13,0.05),
xlabel = "v1",
ylabel = "v2",
title = "Utility")
Out[7]:
In [8]:
vOpt, = OptimalPortfolio(μ,Σ,Rf,k) #find optimal portfolio
rowNames = ["Asset 1","Asset 2","Riskfree"]
printblue("optimal portfolio weights on risky assets and riskfree when k = $k:")
printTable([vOpt;(1-sum(vOpt))],[""],rowNames)
printblue("optimal portfolio weights on risky assets/their sum:")
printTable(vOpt/sum(vOpt),[""],rowNames)
wT, = MVTangencyP(μ,Σ,Rf)
printblue("Tangency portfolio:")
printTable(wT,[""],rowNames)
In [9]:
μ = [11.5; 9.5; 6]/100
Σ = [166 34 58;
34 64 4;
58 4 100]/100^2
Rf = 0.03
Out[9]:
In [10]:
(vD,muD,StdD) = OptimalPortfolio(μ,Σ,Rf,28) #high risk aversion
(vE,muE,StdE) = OptimalPortfolio(μ,Σ,Rf,8.8) #low risk aversion
(wT,muT,StdT) = MVTangencyP(μ,Σ,Rf) #tangency portfolio
rowNames = ["Asset 1","Asset 2","Asset 3","Riskfree"]
printblue("optimal portfolio weights")
xx = hcat([vD;(1-sum(vD))],[vE;(1-sum(vE))])
printTable(xx,["D","E"],rowNames)
printblue("optimal weights/tangency portfolio")
xx = [vD vE]./wT
printTable(xx,["D","E"],rowNames)
In [11]:
μstar = range(Rf,stop=0.15,length=101)
L = length(μstar)
StdRp = fill(NaN,(L,2)) #loop over required average returns (μstar)
for i = 1:L
StdRp[i,1] = MVCalc(μstar[i],μ,Σ)[1] #risky only
StdRp[i,2] = MVCalcRf(μstar[i],μ,Σ,Rf)[1] #risky and riskfree
end
In [12]:
plot( StdRp*100,μstar*100,
label = "",
linecolor = [:red :blue],
xlim = (0,15),
ylim = (0,15),
title = "Mean vs standard deviation",
xlabel = "Std(Rp), %",
ylabel = "ERp, %" )
scatter!(sqrt.(diag(Σ))*100,μ*100,color=:red,label="")
scatter!([StdD,StdE]*100,[muD,muE]*100,color=:black,marker=:star,label="optimal")
scatter!([StdT]*100,[muT]*100,color=:blue,marker=:utriangle,label="tangency",legend=:topleft)
Out[12]:
The cells below defines the Sharpe ratio on a portfolio. To normalise the portfolio, the weights on the $n$ risky assets a forced to sum to one (by setting the weight on asset $n$ to be $1-\sum_{i=1}^{n-1}w_{i}$). The optimization is over the $n-1$ first weights.
The Optim
package is used for the optimisation.
In [13]:
using Optim
In [14]:
function SRFn(wa,μ,Σ,Rf)
v = [wa;1-sum(wa)]
μᵉ = μ .- Rf #expected excess returns
muep = v'μᵉ
StdRp = sqrt(v'Σ*v)
SRp = muep/StdRp
return SRp
end
Out[14]:
In [15]:
Sol = optimize(wa -> -SRFn(wa,μ,Σ,Rf),zeros(2)) #maximise SR -> minimize -SR
v = Optim.minimizer(Sol)
v = [v;1-sum(v)]
println("Tangency and optimal")
printmat([wT v])
In [ ]: