我正在运行宏循环以递归地去除大于99.5百分位的股票回报来计算波动率模型。我试图将循环设置为运行,直到没有观察到z得分(假设百分位数的标准正常值)大于2.58。但由于某些原因,尽管条件为真,但循环不会评估。这是我使用的代码:
%macro delete_jump;
%let z_max=10.0;
%let i=0;
%let crit=%sysfunc(quantile(%str(NORMAL),0.995,0,1));
%put The critical value is &crit.;
%do %while((&z_max. > &crit.) and (&i. < 30));
%put max=&z_max.;
proc expand data=crsp_data out=crsp_data(drop=time);
convert ret_nojmp=ret_vol / transformout=(movstd &hist_pd. trimleft &hist_pd.);
convert ret_nojmp=ret_ma / transformout=(movave &hist_pd. trimleft &hist_pd.);
by ticker;
run;
data crsp_data(drop=ret_vol ret_ma);
set crsp_data(drop=zscore);
zscore=(ret_nojmp-ret_ma) / ret_vol;
if quantile("NORMAL",0.01,0,1) < zscore < quantile("NORMAL",0.99,0,1) then ret_nojmp=ret;
else ret_nojmp = .;
run;
proc sql;
select max(abs(zscore)) into :z_max
from crsp_data;
quit;
%let i=%eval(&i.+1);
%end;
%mend delete_jump;
我设置z = 10来初始化循环,我只是一个计数器,所以我可以在一段时间后逃脱。当它到达那一点时,日志文件说明如下:
MLOGIC(DELETE_JUMP): Beginning execution.
MLOGIC(DELETE_JUMP): %LET (variable name is Z_MAX)
MLOGIC(DELETE_JUMP): %LET (variable name is I)
MLOGIC(DELETE_JUMP): %LET (variable name is CRIT)
MLOGIC(DELETE_JUMP): %PUT The critical value is &crit.
SYMBOLGEN: Macro variable CRIT resolves to 2.57582930354889
The critical value is 2.57582930354889
SYMBOLGEN: Macro variable Z_MAX resolves to 10.0
SYMBOLGEN: Macro variable CRIT resolves to 2.57582930354889
SYMBOLGEN: Macro variable I resolves to 0
MLOGIC(DELETE_JUMP): %DO %WHILE((&z_max. > &crit.) and (&i. < 30)) loop
beginning; condition is FALSE. Loop will not be executed.
MLOGIC(DELETE_JUMP): Ending execution.
我尝试拆分条件并硬编码CRIT的值,但它从不执行循环。任何想法都表示赞赏。
答案 0 :(得分:1)
问题似乎是%do while
在内部使用%eval
,这只适用于整数比较,但是您要比较两位小数。替换如下,它应该按预期工作:
%do %while(%sysevalf(&z_max. > &crit.) and (&i. < 30));