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 variables
and 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.
Available on demand!
Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.
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.