from IPython.core.display import HTML
HTML(open("styles/custom.css", "r").read())
%%script glpsol -m /dev/stdin
# Example: PortfolioMAD.mod Portfolio Optimization using Mean Absolute Deviation
/* Stock Data */
set S; # Set of stocks
param r{S}; # Means of projected returns
param cov{S,S}; # Covariance of projected returns
param r_portfolio
default (1/card(S))*sum{i in S} r[i]; # Lower bound on portfolio return
/* Generate sample data */
/* Cholesky Lower Triangular Decomposition of the Covariance Matrix */
param c{i in S, j in S : i >= j} :=
if i = j then
sqrt(cov[i,i]-(sum {k in S : k < i} (c[i,k]*c[i,k])))
else
(cov[i,j]-sum{k in S : k < j} c[i,k]*c[j,k])/c[j,j];
/* Because there is no way to seed the PRNG, a workaround */
param utc := prod {1..2} (gmtime()-1000000000);
param seed := utc - 100000*floor(utc/100000);
check sum{1..seed} Uniform01() > 0;
/* Normal random variates */
param N default 5000;
set T := 1..N;
param zn{j in S, t in T} := Normal(0,1);
param rt{i in S, t in T} := r[i] + sum {j in S : j <= i} c[i,j]*zn[j,t];
/* MAD Optimization */
var w{S} >= 0; # Portfolio Weights with Bounds
var y{T} >= 0; # Positive deviations (non-negative)
var z{T} >= 0; # Negative deviations (non-negative)
minimize MAD: (1/card(T))*sum {t in T} (y[t] + z[t]);
s.t. C1: sum {s in S} w[s]*r[s] >= r_portfolio;
s.t. C2: sum {s in S} w[s] = 1;
s.t. C3 {t in T}: (y[t] - z[t]) = sum{s in S} (rt[s,t]-r[s])*w[s];
solve;
/* Report */
/* Input Data */
printf "Stock Data\n\n";
printf " Return Variance\n";
printf {i in S} "%5s %7.4f %7.4f\n", i, r[i], cov[i,i];
printf "\nCovariance Matrix\n\n";
printf " ";
printf {j in S} " %7s ", j;
printf "\n";
for {i in S} {
printf "%5s " ,i;
printf {j in S} " %7.4f ", cov[i,j];
printf "\n";
}
/* MAD Optimal Portfolio */
printf "\nMinimum Absolute Deviation (MAD) Portfolio\n\n";
printf " Return = %7.4f\n",r_portfolio;
printf " Variance = %7.4f\n\n", sum {i in S, j in S} w[i]*w[j]*cov[i,j];
printf " Weight\n";
printf {s in S} "%5s %7.4f\n", s, w[s];
printf "\n";
table tab0 {s in S} OUT "JSON" "Optimal Portfolio" "PieChart":
s, w[s]~PortfolioWeight;
table tab1 {s in S} OUT "JSON" "Asset Return versus Volatility" "ScatterChart":
sqrt(cov[s,s])~StDev, r[s]~Return;
table tab2 {s in S} OUT "JSON" "Portfolio Weights" "ColumnChart":
s~Stock, w[s]~PortfolioWeight;
table tab3 {t in T} OUT "JSON" "Simulated Portfolio Return" "LineChart":
t~month, (y[t] - z[t])~PortfolioReturn;
/* Simulated Return data in Matlab Format */
/*
printf "\nrt = [ ... \n";
for {t in T} {
printf {s in S} "%9.4f",rt[s,t];
printf "; ...\n";
}
printf "];\n\n";
*/
data;
/* Data for monthly returns on four selected stocks for a three
year period ending December 4, 2009 */
param N := 200;
param r_portfolio := 0.01;
param : S : r :=
AAPL 0.0308
GE -0.0120
GS 0.0027
XOM 0.0018 ;
param cov :
AAPL GE GS XOM :=
AAPL 0.0158 0.0062 0.0088 0.0022
GE 0.0062 0.0136 0.0064 0.0011
GS 0.0088 0.0064 0.0135 0.0008
XOM 0.0022 0.0011 0.0008 0.0022 ;
end;