The code below calculates mean variances frontiers for two cases (1) when there are no restrictions on the portfolio weights and (2) when we impose the restriction that no weights can be negative.
The latter case requires a numerical minimization routine. This notebook uses the packages JuMP (for the interface) and Ipopt (for the optimization algorithm).
In [1]:
using Dates, LinearAlgebra, JuMP, Ipopt
include("jlFiles/printmat.jl")
Out[1]:
In [2]:
using Plots
#pyplot(size=(600,400)) #use pyplot or gr
gr(size=(480,320))
default(fmt = :svg)
In [3]:
μ = [11.5; 9.5; 6]/100 #expected returns
Σ = [166 34 58; #covariance matrix
34 64 4;
58 4 100]/100^2
Rf = 0.03
printblue("μ:")
printmat(μ)
printblue("Σ:")
printmat(Σ)
printblue("Rf:")
printlnPs(Rf)
In [4]:
include("jlFiles/MvCalculations.jl")
Out[4]:
In [5]:
μstar = range(0.04,stop=0.15,length=201)
L = length(μstar)
StdRp = fill(NaN,L)
for i = 1:L
StdRp[i] = MVCalc(μstar[i],μ,Σ)[1]
end
plot( StdRp*100,μstar*100,
linecolor = :red,
linewidth = 2,
label = "MVF",
legend = :topleft,
xlim = (0,15),
ylim = (0,15),
title = "MVF (no portfolio constraints)",
xlabel = "Std(Rp), %",
ylabel = "ERp, %" )
scatter!(sqrt.(diag(Σ))*100,μ*100,color=:red,label="assets")
Out[5]:
In [6]:
function MeanVarNoSSPs(μ,Σ,μstar) #MV with no short-sales, numerical minimization
n = length(μ)
if minimum(μ) <= μstar <= maximum(μ) #try only if feasible
model = Model(optimizer_with_attributes(Ipopt.Optimizer,"print_level" => 1))
@variable(model,w[i=1:n] >= 0.0) #no short sales
@objective(model,Min,w'*Σ*w) #minimize portfolio variance
@constraint(model,sum(w) == 1.0) #w sums to 1
@constraint(model,w'*μ == μstar) #mean equals μstar
optimize!(model)
if has_values(model)
w_p = value.(w)
StdRp = sqrt(w_p'Σ*w_p)
end
else
(w_p,StdRp) = (NaN,NaN)
end
return StdRp,w_p
end
Out[6]:
In [7]:
Std_no_ss = fill(NaN,length(μstar))
for i = 1:length(μstar)
Std_no_ss[i] = MeanVarNoSSPs(μ,Σ,μstar[i])[1] #[1] to get first output
end
In [8]:
plot( [StdRp Std_no_ss]*100,μstar*100,
linecolor = [:red :green],
linestyle = [:solid :dash],
linewidth = 2,
label = ["no constraints" "no short sales"],
xlim = (0,15),
ylim = (0,15),
legend = :topleft,
title = "MVF (with/without constraints)",
xlabel = "Std(Rp), %",
ylabel = "ERp, %" )
scatter!(sqrt.(diag(Σ))*100,μ*100,color=:red,label="assets")
Out[8]:
In [ ]: