标题: 请高手看一下我的宏程序有哪些问题 [打印本页] 作者: shiyiming 时间: 2010-3-20 14:44 标题: 请高手看一下我的宏程序有哪些问题 %macro a;/*创建宏程序*/
%do n=1%to 172;
data d;
set d;
if_n_=&n then call symput('date',settlement);/*提取时间附值于date宏
变量*/
run;
data selected;
set sorted;
if settlement=&date then output selected;
run;
/*对所选截面下数据进行现金流分解*/
data float(keep=name c1-c42);
set selected;
sdate=&date;
edate=enddate;
yrdif=yrdif(sdate,edate,'30/360');
dif=yrdif-int(yrdif);/*非整数年份数*/
if fre=1 then if dif=0 then do;
y=yrdif;
a=coupond;
end;
else do;
y=int(yrdif)+1;
a=coupond;
end;
if fre=2 then if dif=0.5 then do;
y=yrdif*2;
a=coupond/2;
end;
else if dif>0.5 then do;
y=int(yrdif)*2+2;
a=coupond/2;
end;
else do;
y=int(yrdif)*2+1;
a=coupond/2;
end;
array c{40};/*最长期债券付息次数的最大值为40*/
do i=1 to y;
if i<y then c[i]=a;
else c[i]=a+100;
end;
do j=y+1 to 40;
c[j]=0;
end;
run;
/*计算现金流所对应的时间*/
data time(keep=name t1-t42);
set selected;
sdate=&date;
edate=enddate;
yrdif=yrdif(sdate,enddate,'30/360');
dif=yrdif-int(yrdif);
if fre=1 then if dif=0 then do;
y=yrdif;
a=1;
end;
else do;
y=int(yrdif)+1;
a=dif;
end;
if fre=2 then if dif=0.5 then do;
y=yrdif*2;
a=0.5;
end;
else if dif>0.5 then do;
y=int(yrdif)*2+2;
a=dif-0.5;
end;
else do;
y=int(yrdif)*2+1;
a=dif;
end;
array t{40};
do i=1 to y;
t[i]=a+1/fre*(i-1);
end;
do j=y+1 to 40;
t[j]=1;
end;
run;
/*合并现金流及相应时刻数据集*/
data float_time;
merge float time;
run;
/*生成用于回归的系数矩阵*/
data regression(keep=name a bb cc d1-d3);
set float_time;
array c{40};
array t{40};
a=0;bb=0;cc=0;d1=0;d2=0;d3=0;
do i=1 to 40;
a=a+c[i];bb=bb+c[i]*t[i];cc=cc+c[i]*t[i]**2;
if t[i]<5 then do td1=t[i]**3;td2=0;td3=0;end;
else if t[i]<8 then do td1=t[i]**3-(t[i]-5)**3;
td2=(t[i]-5)**3;td3=0;end;
else do td1=t[i]**3-(t[i]-5)**3;td2=(t[i]-5)**3-(t[i]-8)**3;
td3=(t[i]-8)**3;end;
d1=d1+c[i]*td1;
d2=d2+c[i]*td2;
d3=d3+c[i]*td3;
end;
run;
/*计算用于加权的久期倒数之和并附值于变量ddd*/
data a(keep=sumdu1);
set selected end=end;
du1=1/du;
sumdu1+du1;
if end;
call symput('ddd',sumdu1);
run;
/*产生回归系数矩阵*/
data regression(keep=name v bb cc d1-d3 w);
merge regression selected;
v=price-a;
w=(1/du/&ddd);
run;
/*估计参数并将结果直接输出至数据集Estimates以备后来调用*/
ods listing close;
ods output ParameterEstimates=Estimates;
proc glm data=regression;
model v=bb cc d1 d2 d3/noint;
weight w;
run;
quit;
ods listing;
data a;
set Estimates;
if parameter='bb'then call symput('bb',Estimate);/*将bb估计结果附值
于宏变量bb*/
if parameter='cc' then call symput('cc',Estimate);
if parameter='d1' then call symput('d1',Estimate);
if parameter='d2' then call symput('d2',Estimate);
if parameter='d3' then call symput('d3',Estimate);
run;
/*根据估计结果计算出各期即期利率*/
data chart(keep=t dr sr_&n);/*t为时间变量,dr为贴现因子,sr为即期利率*/
bb=&bb;
cc=&cc;
d1=&d1;
d2=&d2;
d3=&d3;
/*输出一周即期利率*/
t=1/52;dr=1+(bb)*t+(cc)*t**2+(d1)*t**3;sr_&n=log(dr)/(-t);output;
/*输出一月即期利率*/
t=1/12;dr=1+(bb)*t+(cc)*t**2+(d1)*t**3;sr_&n=log(dr)/(-t);output;
/*输出半年即期利率*/
t=1/2;dr=1+(bb)*t+(cc)*t**2+(d1)*t**3;sr_&n=log(dr)/(-t);output;
/*输出1-20年即期利率*/
do t=1 to 20;
bb=&bb;
cc=&cc;
d1=&d1;
d2=&d2;
d3=&d3;
if t<=5 then do;
dr=1+(bb)*t+(cc)*t**2+(d1)*t**3;
end;
else if 5<t<=8 then
dr=1+(bb)*t+(cc)*t**2+d1*(t**3-(t-5)**3)+d2*(t-5)**3;
else
dr=1+(bb)*t+(cc)*t**2+d1*(t**3-(t-5)**3)+d2*((t-5)**3-(t-8)**3)+(d3)*
(t-8)**3;
if dr>0 then do;
sr_&n=log(dr)/(-t);/*sr_&n为连续时间即期利率*/
output;
end;
else sr_&n=.;
end;
run;
/*绘制截面期限结构图*/
proc gplot data=chart;
symbol i=join v='*'color=blue;
plot sr_&n*t;
run;
/*计算各债券的理论价格*/
data price(keep=name lprice);
set float_time;
array c{40};
array t{40};
bb=&bb;
cc=&cc;
d1=&d1;
d2=&d2;
d3=&d3;
sum=0;
do i=1 to 40;
if t[i]<5 then
sum=sum+(c[i]+c[i]*bb*t[i]+c[i]*cc*t[i]**2+c[i]*d1*t[i]**3);
else if t[i]<8 then
sum=sum+(c[i]+c[i]*bb*t[i]+c[i]*cc*t[i]**2+c[i]*d1*(t[i]**3-(t[i]-5)*
*3)+c[i]*d2*(t[i]-5)**3);
else
sum=sum+(c[i]+c[i]*bb*t[i]+c[i]*cc*t[i]**2+c[i]*d1*(t[i]**3-(t[i]
-5)**3)+c[i]*d2*((t[i]-5)**3-(t[i]-8)**3)+c[i]*d3*(t[i]-8)**3);
lprice=sum;
end;
run;
/*生成各期利率期限结构的汇总数据集*/
data store;
merge store chart;
by t;
run;
%end;
%mend;/*宏结束*/
%a;/*运行宏程序*/作者: shiyiming 时间: 2010-3-21 00:29 标题: Re: 请高手看一下我的宏程序有哪些问题 你的宏程序最大的问题就是太深奥太冗长太复杂。要想回答你的问题必须先要克服人类的几大弱点1.懒惰2.无知3.冷漠作者: shiyiming 时间: 2010-3-21 10:30 标题: Re: 请高手看一下我的宏程序有哪些问题 如果改成带参数的宏,可能更利于重用
<!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D --> 很少有人这么实在,把整段代码拷上来的,我本想好好研读一下的,但一是不清楚输入的数据,二是没金融的专业知识,看到第10行就犯懒了
<!-- s:? --><img src="{SMILIES_PATH}/icon_confused.gif" alt=":?" title="Confused" /><!-- s:? --> 被jingju11说中了2条作者: shiyiming 时间: 2010-3-22 11:18 标题: Re: 请高手看一下我的宏程序有哪些问题 我双目如电,早就忽略了这种帖子作者: shiyiming 时间: 2010-3-22 20:57 标题: Re: 请高手看一下我的宏程序有哪些问题 如果真是双目如电,就不应该忽略,而是揪出其中的妖魔鬼怪来作者: shiyiming 时间: 2010-3-26 00:02 标题: Re: 请高手看一下我的宏程序有哪些问题 if parameter='bb'then call symput('bb',Estimate);/*将bb估计结果附值
于宏变量bb*/
if 后面的 then 丢了吧?
这个程序仅一层循环,虽长,但应该容易理解的.不过,我也没有耐心细看