Super User
Posts: 10,679

# Get Tangency Portfolio - Mean Variance Model

Please don't reply . Just give someone who need it .
```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 !!!! */
/************************************/
/************************************/
/************************************/
/************************************/

```
SAS Super FREQ
Posts: 4,165

## Re: Get Tangency Portfolio - Mean Variance Model

@Ksharp

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) */

Super User
Posts: 10,679

## Re: Get Tangency Portfolio - Mean Variance Model

```@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;

```
Super User
Posts: 10,679

## Re: Get Tangency Portfolio - Mean Variance Model

@Rick_SAS

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;``````

Discussion stats
• 3 replies
• 477 views
• 3 likes
• 2 in conversation