options nosource;* Rolling Beta Regression Program Notes:* Rolling sample periods move forward one month at a time (per loop iteration)* Default case uses 2 years or 24 months of daily data and the sample periods overlap.* The program parameters can be changed to use a different sample length.* In the RRLOOP macro routine below the regression coefficients are estimated by starting with* a sample period of &YEAR1 to &YEAR1 + &NYEAR and progresses forward to end at &YEAR2. * YEAR1 and YEAR2 are defined using START_YEAR and END_YEAR macro variables, and NYEAR= SAMPLE_YEAR* To use end of year (December) only estimation, change MM loop to: %do mm = 12 %to 12;* Code below also can be changed to use other regression models such as the F-F 3 factor model.* Change PROC REG and the DATA step before the APPEND accordingly.* Output dataset includes DATE1 and DATE2 that defines each row sample period* Example PERMNO date1 date2 _DEPVAR_ alpha beta _RMSE_ _RSQ_ nobs 10104 2002-02-01 2004-01-31 retrf -.000284893 1.57198 0.025787 0.38637 503 2002-03-01 2004-02-29 retrf -.000476811 1.56050 0.025747 0.37886 503 2002-04-01 2004-03-31 retrf 0.000030706 1.61115 0.023942 0.42828 506 2002-05-01 2004-04-30 retrf 0.000285565 1.60345 0.023432 0.43471 505 10107 2002-02-01 2004-01-31 retrf -.000347769 1.35198 0.014412 0.59856 503 2002-03-01 2004-02-29 retrf -.000356315 1.34827 0.014413 0.59231 503 2002-04-01 2004-03-31 retrf -.000399233 1.32516 0.014328 0.58590 506 2002-05-01 2004-04-30 retrf -.000094302 1.30637 0.014258 0.57960 505*********************************************************************************;I put the following macro into my code set, but SAS does not run. I even do not know the error. the log show nothing expect these original codes. Did I miss anything? The dataset I used is MSF2. So I change the in_ds=MSF2, it still does not work. My libname is C:/DATA.*****************************************************;%macro RRLOOP (year1= 2001, year2= 2005, nyear= 2, in_ds=temp1, out_ds=work.out_ds); %local date1 date2 date1f date2f yy mm; /*Extra step to be sure to start with clean, null datasets for appending*/proc datasets nolist lib=work; delete all_ds oreg_ds1;run; /*Loop for years and months*/ %do yy = &year1 %to &year2; %do mm = 1 %to 12; /*Set date2 for mm-yy end point and date1 as 24 months prior*/ %let xmonths= %eval(12 * &nyear); *Sample period length in months; %let date2=%sysfunc(mdy(&mm,1,&yy)); %let date2= %sysfunc (intnx(month, &date2, 0,end)); *Make the DATE2 last day of the month; %let date1 = %sysfunc (intnx(month, &date2, -&xmonths+1, begin)); *set DATE1 as first (begin) day; /*FYI --- INTNX quirk in SYSFUNC: do not use quotes with 'month' 'end' and 'begin'*/ /*An extra step to be sure the loop starts with a clean (empty) dataset for combining results*/proc datasets nolist lib=work; delete oreg_ds1;run; /*Regression model estimation -- creates output set with coefficient estimates*/proc reg noprint data=&in_ds outest=oreg_ds1 edf; where date between &date1 and &date2; *Restricted to DATE1- DATE2 data range in the loop; model retrf = vwretdrf; by permno;run; /*Store DATE1 and DATE2 as dataset variablesand rename regression coefficients as ALPHA and BETA;*/data oreg_ds1; set oreg_ds1; date1=&date1; date2=&date2; rename intercept=alpha vwretdrf=beta; nobs= _p_ + _edf_; format date1 date2 yymmdd10.;run; /*Append loop results to dataset with all date1-date2 observations*/proc datasets lib=work; append base=all_ds data=oreg_ds1;run; %end; % /*MM month loop*/ %end; % /*YY year loop*/ /*Save results in final dataset*/data &out_ds; set all_ds;run; %mend RRLOOP;**********************************;The primary output of this program is a data set with these items:
| CRSP Permanent Number=10107 | ||||
| date1 | date2 | _RMSE_ Intercept | VWRETD | regobs |
| 01JAN2002 | 31DEC2004 | 0.057470 -.005836843 | 0.97255 | 36 |
| 01FEB2002 | 31JAN2005 | 0.057446 -.004874504 | 0.95958 | 36 |
| 01MAR2002 | 28FEB2005 | 0.057358 -.004550887 | 0.92014 | 36 |
| 01APR2002 | 31MAR2005 | 0.057448 -.005048308 | 0.92846 | 36 |
| 01MAY2002 | 30APR2005 | 0.056784 -.000042066 | 0.81758 | 36 |
| 01JUN2002 | 31MAY2005 | 0.056721 0.000278585 | 0.80891 | 36 |
| 01JUL2002 | 30JUN2005 | 0.051923 -.006355348 | 0.99118 | 36 |
| 01AUG2002 | 31JUL2005 | 0.051481 -.004585000 | 0.91877 | 36 |
| 01SEP2002 | 31AUG2005 | 0.053227 -.002505193 | 0.89010 | 36 |
| 01OCT2002 | 30SEP2005 | 0.054340 -.003183394 | 0.84427 | 36 |
| 01NOV2002 | 31OCT2005 | 0.045522 -.003110266 | 0.52825 | 36 |
| 01DEC2002 | 30NOV2005 | 0.045962 -.002508023 | 0.50723 | 36 |
| 01JAN2003 | 31DEC2005 | 0.044918 0.000198639 | 0.35030 | 36 |
You have:
%macro RRLOOP (year1= 2001, year2= 2005, nyear= 2, in_ds=temp1, out_ds=work.out_ds);
You may want this:
%macro RRLOOP (year1= , year2= , nyear= , in_ds=, out_ds=);
….
….
%mend RRLOOP;
%RRLOOP (year1= 2001, year2= 2005, nyear= 2, in_ds=temp1, out_ds=work.out_ds);
You only define the macro, but never call it. So nothing happens.
Using options nosource while developing code is also not a very bright thing to do, as it greatly reduces the usefulness of the log.
Use of line comments such as in this line can have very unexpected results with macros:
proc reg noprint data=&in_ds outest=oreg_ds1 edf; where date between &date1 and &date2; *Restricted to DATE1- DATE2 data range in the loop;
Inside the body of a macro you should use: %* comment text;
Or stick with the /* comment */ statement.
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
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.