Optimal weights for an index

Use this forum to post questions about syntax problems or general programming issues. Questions on implementing a particular aspect of econometrics should go in "Econometrics Issues" below.
PeterF
Posts: 63
Joined: Thu Apr 12, 2012 2:03 pm

Optimal weights for an index

Unread post by PeterF »

Hello,

I have four series of security prices, which should be combined to an index. The weights of the index should be set that the ratio of the mean to the standard deviation of the index returns is maximized. The restrictions on the weights are to be positive and to add-up to unity.

I have tried the following code

Code: Select all

nonlin(parmset=base) w1 w2 w3 w4
nonlin(parmset=constraint) w1>=0.0 w2>=0.0 w3>=0.0 w4>=0.0 w1+w2+w3+w4==1.0
*
comp w1=0.80
comp w2=0.10
comp w3=0.05
comp w4=0.05
*
* calculate the price of the index
*
set index = log(w1*s1+w2*s2+w3*s3+w4*s4)
set ret  = 100*(index-index{1})
statistics(noprint) ret
comp mw = %mean
set retsq = (ret-mw)**2
statistics(noprint) retsq
comp std =sqrt(%mean)
frml sharpe = mw/std
maximize(parmset=base+constraint,method=simplex,iters=400) sharpe
However, the solution I get is not correct as the weights do not add-up to 1.0. Would I have to use frml instead of the set instructions? How could I calculate the mean and standard deviation for FRMLs as RATS only provides the mean and variance for series?

Thank you for any help to solve my problem.

Best regards
Peter
TomDoan
Posts: 7814
Joined: Wed Nov 01, 2006 4:36 pm

Re: Optimal weights for an index

Unread post by TomDoan »

Because the optimand is a function of full sample statistics, you can't use MAXIMIZE, which requires that it be a sum of individual values. Instead, you need to use FIND with METHOD=BFGS (METHOD=SIMPLEX can't handle the constraints).

Code: Select all

nonlin(parmset=base) w1 w2 w3 w4
nonlin(parmset=constraint) w1>=0.0 w2>=0.0 w3>=0.0 w4>=0.0 w1+w2+w3+w4==1.0
*
comp w1=0.80
comp w2=0.10
comp w3=0.05
comp w4=0.05
*
dec real sharpe
find(method=bfgs,parmset=base+constraint) maximum sharpe
   set index = log(w1*s1+w2*s2+w3*s3+w4*s4)
   set ret  = 100*(index-index{1})
   statistics(noprint) ret
   comp mw = %mean
   * Isn't std just sqrt(%variance*(%nobs-1)/%nobs) from the first STATISTICS?
   set retsq = (ret-mw)**2
   statistics(noprint) retsq
   comp std =sqrt(%mean)
   compute sharpe=mw/std
end find
PeterF
Posts: 63
Joined: Thu Apr 12, 2012 2:03 pm

Re: Optimal weights for an index

Unread post by PeterF »

Dear Tom,

first, thank you very much for the very quick help. Second, yes, std is just sqrt(%variance*(%nobs-1)/%nobs) from the first STATISTICS, which would reduce the code by a few lines.

Best regards
Peter
PeterF
Posts: 63
Joined: Thu Apr 12, 2012 2:03 pm

Re: Optimal weights for an index

Unread post by PeterF »

Dear Tom,

sorry that I have to come back to this topic. I copied the instructions from your reply and got the SR10 error message. To trace the error, I have included statements to display the weights w1 to w4 as well as mean and standard deviation. I noticed that the weighting factors remained unchanged and after a few iterations, series ind and ret had no observations. What could solve this problem?

Best regards

Peter
TomDoan
Posts: 7814
Joined: Wed Nov 01, 2006 4:36 pm

Re: Optimal weights for an index

Unread post by TomDoan »

It's possible for W's to go slightly negative during the estimation process until the penalty functions strongly kick in. That might cause a few data points to drop out. Put a TRACE option on the FIND to see what's happening there.

The adjustment below will reject any set of parameters that loses data points versus the initial sample.

Code: Select all

nonlin(parmset=base) w1 w2 w3 w4
nonlin(parmset=constraint) w1>=0.0 w2>=0.0 w3>=0.0 w4>=0.0 w1+w2+w3+w4==1.0
*
comp w1=0.80
comp w2=0.10
comp w3=0.05
comp w4=0.05
*
dec real sharpe
set index = log(w1*s1+w2*s2+w3*s3+w4*s4)
set ret  = 100*(index-index{1})
stats ret
compute fullnobs=%nobs
find(method=bfgs,parmset=base+constraint,trace) maximum sharpe
   set index = log(w1*s1+w2*s2+w3*s3+w4*s4)
   set ret  = 100*(index-index{1})
   statistics(noprint) ret
   if %nobs<fullnobs {
      compute sharpe=%na
      next
   }
   comp mw = %mean
   comp std = sqrt(%variance*(%nobs-1)/%nobs)
   compute sharpe=mw/std
end find
Post Reply