Date: Tue, 16 Jul 1996 13:34:16 -0400 (EDT) From: S. To: "Donald P. Cram" Subject: prices and divs and returns On Tue, 16 Jul 1996, Donald P. Cram wrote: > I edited your original statement to say that the PROC SORT was to use > a BY and the PROC MEANS was to use a CLASS. If that is not correct, please It's fine. As to your other problem (working with raw prices and dividends), I actually had a slightly different thing already going with CRSP events and it was easily warped to your intent, as follows (with the embedded caveats of course): data prices; set crsp.msf; /* monthly stock prices and returns */ where cusip='96154810'; /* using one cusip for demo purposes */ yr = year(date); /* the DATE of a dividend is the record date, not the end of the month. so, to merge with prices date, you have to create yr and mo variables */ mo = month(date); price = abs(prc); keep cusip date yr mo price /* ret--keep this to verify your work*/ ; proc sort; by cusip yr mo; data rawdivs; set crsp.mse; /* our monthly events dataset */ where cusip='96154810' AND event='DIST' AND distcd < 1999; /* EVENT is the variable saying which CRSP structure the obs is from ['NAME' for NAMES(), 'DIST' for DISTS(), etc ] DISTCD begins with a 1 for plain old dividends. 1999 is missing info */ yr = year(date); mo = month(date); keep cusip date yr mo divamt; /* you may need to keep more */ proc sort; by cusip yr mo; /* now add up all dividends for the month--many companies pay special divs so it's not rare for this to be the case. However, this code would fail if there are months where one dividend is paid before a split and one dividend is paid after. you'd really want to adjust them all to occur on beginning of month pre-split terms, but then you'd also need to keep around a variable with the end of month price on pre-split terms too. ouch. if you're serious about doing things this way, don, you'll have to take the above into account. Not to mention other weird things I'm sure you'll encounter. */ proc means data=rawdivs noprint; by cusip yr mo; var divamt; id date; output out=divs(drop=_type_ _freq_) sum=totdiv; proc sort data=divs; by cusip yr mo; data returns; merge divs prices; by cusip yr mo; if totdiv=. then totdiv=0.0; /* treat no div as $0 */ proc sort; by cusip date; data returns; set returns; by cusip; lprice = lag(price); if first.cusip then return = .; else return = (price + totdiv) / lprice - 1.0; drop lprice; proc print; Date: Tue, 16 Jul 1996 13:42:22 -0400 (EDT) From: S. To: "Donald P. Cram" Subject: one more thing I almost forgot. The fragment I just sent you is going to screw up months with a stock split, even if there is no dividend. oops-- that's what I get for trying to excise a piece of code from its context. anyway, you should by now have more than enough ideas to proceed. -S.