简体   繁体   中英

Calculating value weighted returns in SAS

I have some data in the following format:

COMPNAME DATA CAP RETURN

I have found some code that will construct and calculate the value-weighted return based on the data.

This works great and is below:

PROC SUMMARY NWAY DATA = Data1 ; CLASS DATE ;

VAR RETURN / WEIGHT = CAP ;

OUTPUT
   OUT = MKTRET
   MEAN (RETURN) = MONTHLYRETURN
RUN;

The extension that I would like to make is in my head a little bit complicated.

I want to make the weights based on the market capitalization in June.

So this will be a buy and hold portfolios. The actual data has 100's of companies but to give a representative example for two companies with the sole explanation of how the weights will evolve...

Say for example I have two companies, A and B.

The CAP of A is £100m and B is £100m.

In July of one year, I would invest 50% in A and 50% in B.

The returns in July are 10% and -10%.

Therefore I would invest 55% and 45%.

It will go on like this until next June when I will re-balance again based on the market capitalisation...

10% monthly return is pretty speculative!

When the two companies differ by more than 200 you will need to also sell and buy to equalize the companies.

Presume the rates per month are simulated and stored in a data set. You can generate a simulated ledger as follows

  • add returns
  • compare balances
    • equalize by splitting 200 investment if balances are close enough
    • equalize by investing all 200 in one and selling and buying

Of course, a portfolio with more than 2 companies becomes a more complicated balancing act to achieve mathematical balance.

data simurate(label="Future expectation is not an indicator of past performance :)");
  do month = 1 to 60;
  do company = 1 to 2;
    return = round (sin(company+month/4) / 12, 0.001); %* random return rate for month;
    output; 
  end;
  end;    
run;

data want;
  if 0 then set simurate;

  declare hash lookup (dataset:'simurate');
  lookup.defineKey ('company', 'month');
  lookup.defineData('return');
  lookup.defineDone();


  month = 0;
  bal1 = 0; bal2 = 0;
  output;

  do month = 1 to 60;

    lookup.find(key:1, key:month);  rate1 = return;
    ret1 = round(bal1 * rate1, 0.0001);

    lookup.find(key:2, key:month);  rate2 = return;
    ret2 = round(bal1 * rate2, 0.0001);

    bal1 + ret1;
    bal2 + ret2;

    goal = mean(bal1,bal2) + 100;

    sel1 = 0; buy1 = 0;
    sel2 = 0; buy2 = 0;

    if abs(bal1-bal2) <= 200 then do;
      * difference between balances after returns is < 200;
      * balances can be equalized simple investment split;
      inv1 = goal - bal1;
      inv2 = goal - bal2;
    end;
    else if bal1 < bal2 then do;
      * sell bal2 as needed to equalize;
      inv1 = 200;
      inv2 = 0;
      buy1 = goal - 200 - bal1;
      sel2 = bal2 - goal;
    end;
    else do;
      inv2 = 200;
      inv1 = 0;
      buy2 = goal - 200 - bal2;
      sel1 = bal1 - goal;      
    end;

    bal1 + (buy1 - sel1 + inv1);
    bal2 + (buy2 - sel2 + inv2);

    output;

  end;
  stop;
  drop company return ;
  format bal: 10.4 rate: 5.3;
run;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM