SAS中文论坛

标题: 用sas计算Exponential Moving Average (EMA) [打印本页]

作者: shiyiming    时间: 2008-7-12 19:14
标题: 用sas计算Exponential Moving Average (EMA)
借人气,再与大家探讨一个问题,用sas计算Exponential Moving Average (EMA),公式如下:
EMA(current) = ( (Price(current) - EMA(prev) ) x Multiplier) + EMA(prev)
其中Multiplier=(2 / (Time periods + 1) )
EMA的初始值为前n天的收盘价的平均值。
有兴趣的朋友探讨一下阿,相关的公式和定义要是我说的不明白,可以知在百度里搜索一下阿,谢谢
作者: shiyiming    时间: 2008-7-12 22:15
标题: Re: 万恶的lag函数
data Shangzhenzhishu;
input date yymmdd10. Oppr Hipr Lopr Clpr vol;
format date yymmdd10.;
cards;
1990-12-19 96.05 99.98 95.79 99.98 126000
1990-12-20 104.30 104.39 99.98 104.39 19700
1990-12-21 109.07 109.13 103.73 109.13 2800
1990-12-24 113.57 114.55 109.13 114.55 3200
1990-12-25 120.09 120.25 114.55 120.25 1500
1990-12-26 125.27 125.27 120.25 125.27 10000
1990-12-27 125.27 125.28 125.27 125.28 6600
1990-12-28 126.39 126.45 125.28 126.45 10800
1990-12-31 126.56 127.61 126.48 127.61 7800
;
run;
data try;
set Shangzhenzhishu;
t=_n_;
m=2/(t+1);
run;
data miean;
set try (obs=5);
keep Clpr;
run;
proc means data=miean mean;
output out=em1;
run;
data em1;
set em1;
where _stat_="MEAN";
keep clpr;
run;
data ema;
retain b1 109.66;
set try;
run;
data ema;
retain ema ;
set ema;
if _n_=1 then do;
ema=(( clpr - b1 )*m + b1);
end;
bema=lag(ema);
run;
data new;
retain bema3;
set ema;
if _n_ ne 1 then ema=(( clpr -  bema3 )*m +  bema3);
bema3=lag(ema);
run;
data end;
set ema;
keep ema bema2;
run;
我已经偏写到最后一步了,取前五个数据的收盘价格为初始值,计算,可是lag函数无效了,
无论你是设定中间变量还是直接调用,你休想在下一行数据中调用它进行计算,这个lag失效了,完全不是像要得到的结果。 <!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( -->
作者: shiyiming    时间: 2008-7-13 08:41
标题: Re: 用sas计算Exponential Moving Average (EMA)
我的思路是这样的,以3日EMA为例,但不知道为什么却运行不成功,我们相互借鉴下阿
%macro ema;
data _null_;
set shangzhenzhishu nobs=nobs;
number=nobs;
call symput('n',number);
data TempEMA(keep=date EMA clpr);
format EMA 10.2;
set shangzhenzhishu;
array rr{3};
do i=1 to 3;
if i^=1 then rr(i)=lag(rr(i-1));
else rr(i)=clpr;
end;
if _n_=3 then EMA=(rr1+rr2+rr3)/3;
ab=lag(EMA);
%do i=4 %to &amp;n;
if _n_=&amp;i then EMA=(clpr-ab)*(2/(3+1))+ab;
ab=lag(ema);
%end;
run;
%mend ema;
%ema
作者: shiyiming    时间: 2008-7-13 12:18
标题: Re: 用sas计算Exponential Moving Average (EMA)
data Shangzhenzhishu;
input date yymmdd10. Oppr Hipr Lopr Clpr vol;
format date yymmdd10.;
cards;
1990-12-19 96.05 99.98 95.79 99.98 126000
1990-12-20 104.30 104.39 99.98 104.39 19700
1990-12-21 109.07 109.13 103.73 109.13 2800
1990-12-24 113.57 114.55 109.13 114.55 3200
1990-12-25 120.09 120.25 114.55 120.25 1500
1990-12-26 125.27 125.27 120.25 125.27 10000
1990-12-27 125.27 125.28 125.27 125.28 6600
1990-12-28 126.39 126.45 125.28 126.45 10800
1990-12-31 126.56 127.61 126.48 127.61 7800
;
run;
data try;
set Shangzhenzhishu;
keep clpr date;
run;
data try2;
retain sum1;
set try(obs=3);
run;
proc means data=try2 mean noprint;
output out=try3;
run;
data try4;
set try3;
where _STAT_=&quot;MEAN&quot;;
keep clpr;
run;
data _null_;
set try4;
if _n_=1 then call symput(&quot;ema0&quot;,clpr);
run;
%put &amp;ema0;
%macro try6;

data try5;
b1=lag(ema);
retain EMA b1;
b1=lag(ema);
set try;
b1=lag(ema);
if _n_=1 then do;
EMA=((clpr-&amp;ema0)*(2/(3+1))+&amp;ema0); b1=(ema);;
end;
b1=lag(ema);
if _n_ ne 1 then do
EMA=((clpr-b1)*(2/(3+1))+b1);
b1=lag(ema);
end;
b1=lag(ema);
run;
%mend try6;
%try6;
我写的不对,问题关键在于如何调用上面一个ema,进行本部的计算,lag的位置,放几个,我不懂,好像这个和数据部的内部机制有关,就是说有可能lag函数要在写完这行数据后才其效果,而这个时候因为没有lag值那么ema就是空的了,要详细查看lag的说明,否则无法读上一个值。或者使用 proc iml
作者: shiyiming    时间: 2008-7-13 12:23
标题: Re: 用sas计算Exponential Moving Average (EMA)
经过向sas同道“谁敢横刀老马”求教,这个问题已经圆满解决,关键是加retain语句,新的程序比原来更简洁!~在此再次感谢“谁敢横刀老马”,由于他的智慧,丰富了大家的智慧!~以3日EMA为例:
                data TempEMA(keep=date ab EMA rr1 rr2 rr3 clpr);
        retain ab;
        format EMA 10.2;
        set shangzhenzhishu nobs=nobs;
        array rr{3};
        do i=1 to 3;
        if i^=1 then rr(i)=lag(rr(i-1));
        else rr(i)=clpr;
        end;
        if _n_=3 then EMA=(rr1+rr2+rr3)/3;
        if _n_&gt;3 then EMA=(clpr-ab)*(2/(3+1))+ab;
        ab=EMA;
        run;
作者: shiyiming    时间: 2008-7-13 12:54
标题: Re: 用sas计算Exponential Moving Average (EMA)
写的太好了,用一个retain语句解决问题了,用一个数组求平均值,太好了 <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->
作者: shiyiming    时间: 2008-7-13 12:58
标题: Re: 用sas计算Exponential Moving Average (EMA)
<!-- m --><a class="postlink" href="http://support.sas.com/kb/25/027.html">http://support.sas.com/kb/25/027.html</a><!-- m -->
可以才参考sas网站上的这个例子,retain在计算移动平均有很大的用处!~
作者: shiyiming    时间: 2008-7-24 09:30
标题: Re: 用sas计算Exponential Moving Average (EMA)
稍微改改 <!-- s:lol: --><img src="{SMILIES_PATH}/icon_lol.gif" alt=":lol:" title="Laughing" /><!-- s:lol: -->  
data TempEMA(keep=date EMA clpr);
retain ab ;
retain total 0;
format EMA 10.2;
set shangzhenzhishu nobs=nobs;
if _n_&lt;4 then total=total+clpr;
if _n_=3 then EMA=total/3;
if _n_&gt;3 then EMA=(clpr-ab)*(2/(3+1))+ab;
ab=EMA;
run;
proc print data=TempEMA;
run;




欢迎光临 SAS中文论坛 (https://mysas.net/forum/) Powered by Discuz! X3.2