大家好!
今天在算上证指数的周期。但是我没想出来算法来判断。要求:
1) 波峰波谷交替出现
2) 波峰波谷之间涨跌幅在20%以上。
我的想法是滚动寻找前后45天的最大值和最小值,然后删除重复的波峰和波谷,然后再删除波谷大于相邻波峰的记录。但是这样做和绘图直接判断的结果并不一致。
我尝试了两天,没能成功。请高手帮忙指点迷津:
数据在附件中。
我的程序代码如下:
libname data ".";
proc datasets lib=work kill;quit;
data Index;
set data.index;
if indexcd=1;
index=Clsindex;
keep date index ;
run;
%let dstin=index;
%let window=45;/*采用月份来衡量*/
data _null_;
set &dstin. nobs=t;
call symput("n",t);
stop;
run;
%put &n.;
data dst;
set &dstin.;
xx=1;
run;
%macro split;
data dstout;
set _null_;
run;
%do k=1 %to &n.;
/*dm 'out; clear; log; clear;'; */
data h;
set dst;
if _n_ =&k.;
format d yymmdd10.;
d=date;
drop date;
run;
data tst;
merge dst h;
by xx;
run;
data tst;
set tst;
if abs(date-d)<&window.;
run;
proc sql;
create table topbottom as
select max(index) as max, min(index) as min
from tst;
quit;
data topbottom;
set topbottom;
xx=1;
run;
data d;
merge tst topbottom;
by xx;
if index=min then bt=1;else bt=0;
if index=max then top=1;else top=0;
if bt=1 or top=1;
keep date bt top;
run;
data dstout;
set dstout d;
run;
%end;
%mend;
%split;
proc sort data=dstout nodup;by date;run;
/*删除连续的波峰和波谷*/
data s;
merge dstout(in=a) &dstin;
by date;
if a=1;
run;
data s;
set s;
if bt^=lag(bt) then x+1;
run;
proc means data=s noprint;
var index;
class x;
output out=out min=min max=max;
run;
data m;
merge s out;
by x;
drop _type_ _freq_;
run;
data m;
set m;
if (bt=1 and index=min) or (top=1 and index=max);
drop x min max;
run;
/*删除相邻记录:波峰低于波谷*/
data m;
set m;
if bt=1 and index>lag(index) then delete;
if top=1 and index<lag(index) then delete;
run;