proc iml; /* the number of assets */ n=2; /* riskless rate - Government's bond rate */ f=0.02 ; /* Start Calculated */ /* two assets and populate data */ asset=j(100,n,.); call randseed(1234); call randgen(asset,'normal'); /* the expect return of two assets (mean) */ return=asset[:,]; /* the variance and covariance of two assets */ cov=cov(asset); /* the variance of portfolio */ new_cov=2#cov-diag(vecdiag(cov)); col=col(new_cov); row=row(new_cov); idx=loc(col>=row); p_cov=row[idx]||col[idx]||new_cov[idx]; /* p[1] is expect return of porfolio p[2] is variance of porfolio */ p=j(1,2,.); /* the tangency portfolio */ start max_slope(x) global(f,p,p_cov,return); p[1]=(return#x)[+]; p[2]=(x[p_cov[,1]]#x[p_cov[,2]]#p_cov[,3])[+]; /*riskless rate's variance is zero*/ k=(p[1]-f)/p[2]; return (k); finish; ods output IterHist=IterHist; con=repeat({0,1,1},1,n)||{. .,. .,0 1}; x=j(1,n,1/n); optn={1 3}; call nlptr(xres,rc,"max_slope",x,optn,con); quit; /************************************/ /************************************/ /************************************/ /************************************/ /* Test if it is tangency portfolio */ /* Take two assets above for example*/ data _null_; set IterHist; call symputx('k',OptCrit); call symputx('f','0.02'); run; proc iml; /* The same code as above. Start */ n=2; f=0.02 ; asset=j(100,n,.); call randseed(1234); call randgen(asset,'normal'); return=asset[:,]; cov=cov(asset); new_cov=2#cov-diag(vecdiag(cov)); col=col(new_cov); row=row(new_cov); idx=loc(col>=row); p_cov=row[idx]||col[idx]||new_cov[idx]; /* The same code as above. End*/ p=j(100,2); x=j(1,n,.); do i=1 to 100; x[1]=0.01#i; x[2]=1-x[1]; p[i,1]=(return#x)[+]; p[i,2]=(x[p_cov[,1]]#x[p_cov[,2]]#p_cov[,3])[+]; end; create test from p[c={return variance}]; append from p; close; quit; ods graphics/reset; proc sgplot data=test; series x=variance y=return/ lineattrs=(thickness=2) legendlabel='Portfolio' curvelabel='Efficient Frontier'; lineparm x=0 y=&f slope=&k/ legendlabel='Tangency Portfolio' lineattrs=graphdata2(thickness=2); refline &f / axis=y; xaxis label='Portfolio Variance'; yaxis label='Portfolio Return'; run; /* Bingo !!!! */ /************************************/ /************************************/ /************************************/ /************************************/
Thanks for this program. If I used correlated assets, I don't seem to get the correct tangency curve. What needs to change if you use the following?
Sigma = {1 0.2, 0.2 1};
mu = {0 0};
asset = randnormal(100, mu, Sigma); /* generate obs from MVN(mu, Sigma) */
@Rick, You are right. I just simulate lots of portfolios ,and can't guarantee you get efficient portfolio frontier. If you want get that efficient portfolio frontier, you need solve lots of optimize problem. Something like : return=asset[:,]; start min_variance(x) global(cov); /*a portfolio 's variance*/ k=x*cov*x`; return (k); finish; do r=0.01 to 0.1; /*constraint portfolio's return is 0.01,0.02,0.03,0.04...........*/ /* return*x`=0.01,0.02,0.03,0.04 */ /*change the following CON, I forgot syntax*/ con=repeat({0,1,1},1,n)||{. .,. .,0 return}; x=j(1,n,1/n); optn={1 3}; call nlptr(xres,rc,"min_variance",x,optn,con); print xres ; end;
Finally I have some time to go through.
Better make mu great than 0 .
The code above is too old.
You can get my new code at SAS Global Forum 2017 ,
Search "Get Tangency Portfolio" at SGF2017.
proc iml;
Sigma = {1 0.2, 0.2 1};
mu = {0.2 0.2};
asset = randnormal(10000, mu, Sigma); /* generate obs from MVN(mu, Sigma) */
/* the expect return of two assets (mean) */
return=asset[:,];
/* the variance and covariance of two assets */
cov=cov(asset);
start min_variance(x) global(cov);
return (x*cov*x`);
finish;
x=j(1,2,0.5);
optn={0 1 0.001};
do r=0.02 to 0.34 by 0.02;
con={ 0 0 . .,
1 1 . .}//
(return||0||r);
call nlpnrr(rc,xres,"min_variance",x,optn,con);
r_cov=r_cov//(r||xres*cov*xres`);
end;
print r_cov;
call series x=r_cov[,2] y=r_cov[,1];
quit;
Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.
Register today!Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.
Find more tutorials on the SAS Users YouTube channel.