Hello,
How to count the number of trading days in the past 3 months, using CRSP daily data ?
Thanks
OK, I get that r-square sub (i,k) is r-square for the i'th stock and k'th month. But what is the model from which each monthly r-square is calculated? Is it the capm value or something else? Where are you getting the r-square?
More generally, regarding you initial question, here's how to get the number of trading days in the prior three calendar months:
data want;
set dsf;
by permno;
retain trdays_3months;
if dif(month(date))^=0 or first.permno=1 then trdays_3months=ifn(dif3(permno)=0,dif3(_n_),.);
run;
This program:
Edited additional note:
This program assume that each stock has at least one trading day per month. This is, if a stock is delisted for at least one month, then the period after relisting will have erroneous values for the first 3 months.
You're extremely lucky to have a WRDS consultant on this forum - me.
I take it you really mean the number of days the market was active, rather than the number of days a particular stock traded, right?
What does "last 3 months" mean? Last three calendar months? If the current trading date is in the middle of August, then do you want the number of trading days in May, June, and July?
Hi @mkeintz
Nice to hear from a wrds expert. I am calculating the sigma ratio defined as follows: daily variation of returns computed as an annualized 3-month rolling sample standard deviation, using daily stock price data from CRSP.
If there are fewer than five nonzero observations over the 3 months used in the rolling window computation, SIGMA will be counted as missing and replace with the cross-sectional mean of SIGMA.
Therefore, I need the number of days a particular stock traded, rather than the number of days the market was active.
So for each date t, I need to calculate the number of trading days for each stock for the past three calendar month of the date t.
Yes. If the current trading date is in the middle of August, I want the number of trading days in May, June, and July for each stock in the data.
Looking forward to your help 🙂
OK, I get that r-square sub (i,k) is r-square for the i'th stock and k'th month. But what is the model from which each monthly r-square is calculated? Is it the capm value or something else? Where are you getting the r-square?
More generally, regarding you initial question, here's how to get the number of trading days in the prior three calendar months:
data want;
set dsf;
by permno;
retain trdays_3months;
if dif(month(date))^=0 or first.permno=1 then trdays_3months=ifn(dif3(permno)=0,dif3(_n_),.);
run;
This program:
Edited additional note:
This program assume that each stock has at least one trading day per month. This is, if a stock is delisted for at least one month, then the period after relisting will have erroneous values for the first 3 months.
Hi @mkeintz
Thank you very much for your kind help and detailed advice. Your program works!
The return here is the (price-price_lag)/price_lag
In addition to your program, may I also ask how to implement the additional requirement ?
if there are fewer than five nonzero observations over the prior 3 calendar months used in the rolling window computation (which is
trdays_3months < 5)
, SIGMA will be counted as missing and replace with the cross-sectional mean of SIGMA. I have already calculated SIGMA in my data and set as missing if less than 5 nonzero observations over the prior 3 calendar months.
Thanks again 🙂
Regarding setting sigma to missing when trdays_3months<5, I wouldn't shift implementing that rule to the calculation of trdays_3months. I'd keep it right where you apparently have it - when you calculate sigma. BUT ... you can do that in the same step as in this code:
data want (drop=m);
set dsf;
by permno;
retain trdays_3months 0 m 0;
/* To hold three separate sums of monthly squared returns */
array mretsq{0:2} _temporary_ (3*0);
if dif(month(date))^=0 or first.permno=1 then do;
trdays_3months=ifn(dif3(permno)=0,dif3(_n_),.);
retsquare_3months=sum(of mretsq{*});
if trdays_3months>=5 then sigma=sqrt( (252/(N-1))*retsquare_3months );
/* Point to next element of array mretsq, and zero it out */
m=mod(m+1,3);
mretsq{m}=0;
end;
mretsq{m}+ret**2;
run;
This code declare a 3-element temporary array MRETSQ, to hold sum-of-squared-returns for each of the last three months. It's a temporary array, so (1) no new variables are output to the new data set, and (2) values are automatically retained for record to record. The variable m is used to identify which element of the array to add the current record (element 0, element 1, or element 2). But the actual adding of the current record to the monthly total takes place AFTER the code for discovering a change in month. That's because you want to generate sigma for prior three months without contamination from the current record (i.e. the first record of the new month).
So the if/then statement is now the same IF test, but has a "then do" group instead of a single "then" action. The do group includes calculation of two new variables: retsquare_3months, and sigma. And it also rotates M to the next mretsq element, by using the mod function.
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.