2# cathy3212 我的问题后来解决了 不过还是谢谢你 把分儿给你吧 我是这么写的:
data finance.target3;
set finance.target2;
by stkcd;
if first.stkcd then n=1; else n+1; /* 对各个股票的时序观测编号 用于有名的筛选(因为计算波动率和贝塔只用60个月的数据) 这里多了一个n变量 */
run;
/* 利用宏来做循环 */
%macro caculate;
%do x=60 %to 204; /* 共17年 204个月 */
Data finance.temp;
Set finance.target3;
If &x-59<=n<=&x; /* 筛选出60个月的数据 1-60 2-61 等等,n是对各股票时序上的编号,事实上这一步是有问题的,因为可能截取的观察少于60,所以在后面对std的输出里面,利用自动生成的便利_freq_进行筛选*/
Per=&x;
run;
Proc reg data=finance.temp noprint outest=results;*滚动回归求beta,使用指数模型,;
Model ret_premium=m_retpre;
By stkcd per;
proc means data=finance.temp noprint;
by stkcd per;
var ret;
output out=results1 std=sigma; *估计标准差;
run;
Quit;
/* 以下部分是把每次的输出放到一起 append正是这个功能 */
%if &x=60 %then %do;
data finance.betas1;
set results;
run;
data finance.std;
set results1;
run;
%end;
%else %do;
Proc append base=finance.betas1 data=results; /* 讲data=中的数据集追加到base=数据集中*/
Proc append base=finance.std data=results1;
quit;
%end;%end; quit;
%mend caculate; /* 定义宏结束 */
%caculate; /* 宏的计算过程中会产生一些error,这不会有问题,因为后面针对观测不足的结果进行了剔除 */
/* 提取计算的劳动成果 */
data finance.betas2(keep=stkcd n beta);
set finance.betas1;
n=per+1; /* 挪一格的原因是用含这个月的过去60个月的数据得到的估计值 只能在后面一个月用 */
beta=m_retpre;
run;
data finance.std1(keep=stkcd n sigma freq);
set finance.std;
n=per+1;
rename _FREQ_=freq;
run;
data finance.std2(drop=freq);
set finance.std1;
if freq=60;
run; /*** 剔除观测少于60的值 @@@@@@@@@@@@@@ 很重要的一步 ***/