全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学
3241 14
2009-09-13
还是关于利率期限结构NSS模型参数估计的问题,我已将程序个环节给出并加以注释,但是运行时老是出错,现金流向量总是找不到,麻烦高手帮我修改一下小弟不胜感激!
程序代码如下:
/*建立基本数据表*/
data bonds040927(label='2004年9月27日上交所22只付息国债收盘价');
input name $8. enddate : yymmdd10. fre coupond price du term@;
format enddate yymmdd10.;
label
name='债券名称'
enddate='到期日'
fre='年付息频率'
coupond='票面利息'
price='市场价格'
du='久期'
term='年限';
cards;
96国债6  2006-6-14   1 11.83   114.85  1.90262 10
97国债4  2007-9-5    1 9.78    116.6   2.76666 10
99国债5  2007-8-20   1 3.28    98.48   2.9076  8
99国债8  2009-9-23   1 3.3     94.62   4.70122 10
21国债3  2008-4-24   1 3.27    96.66   3.81898 7
21国债7  2021-7-31   2 4.26    92.09   12.9768 20
21国债10 2011-9-25   1 2.95    89.13   6.44658 10
21国债12 2011-10-30  1 3.05    89.67   7.25293 10
21国债15 2008-12-18  1 3       94.16   4.72472 7
02国债3  2012-4-18   1 2.54    86      7.3555  10
02国债10 2009-8-16   1 2.39    90.71   4.77451 7
02国债13 2017-9-20   2 2.6     77.36   11.1914 15
02国债14 2007-10-24  1 2.65    95.96   3.84993 5
02国债15 2009-12-6   1 2.93    92.5    5.60126 7
03国债11 2010-2-19   1 2.66    90.65   5.63273 7
03国债3  2023-4-17   2 3.4     80.64   14.6887 20
03国债7  2010-8-20   1 2.66    89.69   5.63273 7
03国债8  2013-9-17   1 3.02    87.26   8.06064 10
03国债11 2010-11-19  1 3.5     93.7    6.36469 7
04国债3  2009-4-19   1 4.4164  99.92   4.61904 5
04国债4  2011-5-25   1 4.89    101.04  6.17962 7
04国债7  2011-8-25   1 4.71    99.97   6.20199 7
;
run;
/*现金流分解*/
data float(keep=name c1-c38);/*只保留现金流变量*/
set bonds040927;/*读取观测值*/
sdate='27sep2004'd;  
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{38}; /*定义现金流数组,变量个数大于现金流发生的次数*/  
do i=1 to y;
if i<y then c[i]=a;/*到期前的现金流*/  
         else c[i]=a+100;/*最后一次现金流*/
end;
do j=y+1 to 38;
c[j]=0;/*对某些债券,超过次数y的多余现金流记为0*/
end;
run;
/*  现金流对应的时刻 */
data time(keep=name t1-t38);
set bonds040927;
sdate='27sep2004'd;
edate=enddate;
yrdif=yrdif(sdate, edate, '30/360');
dif=yrdif-int(yrdif);
if Fre=1 then if dif=0 then do; /*年付息一次且剩余年限为整数*/
y=yrdif;  /*现金流发生的次数*/
a=1; /*当前时刻为付息日时,现金流对应的时刻应为年份数加1,变量a即为要加上的数*/
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;/*年付息两次,即每次加0.5*/
end;
else if dif>0.5 then do;/*剩余年限的小数部分超过0.5*/
y=int(yrdif)*2+2;
a=dif-0.5;/*现金流时刻应为当前年份加上超过0.5的那部分*/
end;
else do;
y=int(yrdif)*2+1;/*剩余年限的小数部分小于0.5*/
a=dif;/*现金流时刻应为当前年份加上小数部分*/
end;
array t{38};/*定义现金流发生时刻的数组,变量个数与现金流一致*/
do i=1 to y;
t[i]=a+(1/Fre)*(i-1);/*现金流发生的时间*/
end;
do j=y+1 to 38;
t[j]=1;/*超过的记为1,方便后续的计算*/
end;
run;
data float_time;
merge float time;/*合并现金流和时刻*/
run;
/*计算权重*/
data weight;
set bonds040927;
w=1/(du**0.5);/*权重设为久期的算术平方根的倒数*/
run;
data parameter;
set bonds040927;
proc iml;
reset deflib=work;
use bonds040927;
read all var{price} into pric; /*由SAS数据集bonds040927中变量price的所有观测值创建向量pric*/
read all var{du} into d; /*由久期的所有观测值创建向量d*/
use float;
read all var('c1':'c38') into flao; /*由所有现金流值创建矩阵floa*/
use time;
read all var('t1': 't38') into tim; /*由现金流对应的时刻值创建矩阵tim*/
use weight;
read all var{w} into wei; /*由所有权重w值创建向量wei*/
store pric d floa tim wei;
run;
proc iml;
reset deflib=work;
load pric d floa tim wei;
y=j(1099560,7); /*j(1099560,7)为元素全为1的矩阵共有1099560行,7列。1099560实际为控制循环的次数 */
A=j(38,1,1.);
/*确定参数范围及搜索步长*/
do b1=-0.086 to -0.076 by 0.001; /*b1为参数[-0.086 -0.076]为b1的优化范围*/
do b2=-0.109 to -0.098 by 0.001;
do b0=0.086 to 0.094 by 0.0005;
do t1=9 to 12 by 0.5;
do b3=0.042 to 0.054 by 0.002;
do t2=2.2 to 4 by 0.2;
i=(b1+0.086)/0.001*99960+(b2+0.109)/0.001*8330+(b0-0.086)/0.0005*490+(t1-9)/0.5*70+(b3-0.042)/0.002*10+(t2-2.2)/0.2+1; /*计算这是第几个循环,i为第几次循环*/
/*下面是目标函数*/
y[i,7]=ssq(((float*exp(-time*(b0+(b1+b2)*((1-exp(-time/t1))/(time/t1))-b2*exp(-time/t1)+b3*((1-exp(-time/t2))/(time/t2)-exp(-time/t2)))))*A-price)*wei)/22;
y[i,1]=b1;y[i,2]=b2;y[i,3]=b0;y[i,4]=b3;y[i,5]=t1;y[i,6]=t2;
end;
end;
end;
end;
end;
end;
create yyy from y;/*产生一个新的数据集根据这个数据集的结果来排序得到最小的目标函数即得到相应的参数*/
append from y;
quit;
proc sort data=yyy;
by col7;
run;
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

全部回复
2009-9-13 20:53:55
发个txt的
NSS.txt
大小:(5.13 KB)

 马上下载

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2009-9-13 20:55:12
麻烦帮我看下错误之处,屡次发问,真是不好意思啊! 2# shuiqq19840621
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2009-9-14 17:03:10
这是接在上次修改的后面部分
data w1;
set bonds040927 end=end;
Dur1=1/(dur**0.5);/*权重设为久期的算术平方根的倒数*/
sumDur1+Dur1;
if end;
call symput('ddd',sumDur1);
data w1(keep=w1);
merge bonds040927 w1;
w1=(1/(dur**0.5)/&ddd);
run;
proc iml;
reset deflib=work;
use bonds040927;
read all var{Cldirpr} into Cldirpr;
read all var{Dur} into Dur;
use float_time;
read all var('c1': 'c38') into float;
read all var('t1': 't38') into time;
use w1;
read all var{w1} into wei;
store Cldirpr Dur float time wei;
run;
quit;
proc iml;
reset deflib=work;
use bonds040927;
read all var{Cldirpr} into Cldirpr;
read all var{Dur} into Dur;
use float_time;
read all var('c1': 'c38') into float;
read all var('t1': 't38') into time;
use w1;
read all var{w1} into wei;
store Cldirpr Dur float time wei;
run;
quit;
proc iml;
reset deflib=work;
load Cldirpr Dur float time wei;
y=j(1099560,7);
A=j(38,1,1.);
do b1=-0.086 to -0.076 by 0.001;
do b2=-0.109 to -0.098 by 0.001;
do b0=0.086 to 0.094 by 0.0005;
do t1=9 to 12 by 0.5;
do b3=0.042 to 0.054 by 0.002;
do t2=2.2 to 4 by 0.2;
i=(b1+0.086)/0.001*99960+(b2+0.109)/0.001*8330+(b0-0.086)/0.0005*490+(t1-9)/0.5*70+(b3-0.042)/0.002*10+(t2-2.2)/0.2+1;
y[i,1]=b1;end; y[i,2]=b2;end; y[i,3]=b0;end; y[i,4]=b3;end; y[i,5]=t1;end; y[i,6]=t2;end;
y[i,7]=ssq((((float#exp(-time#(b0+(b1+b2)#((1-exp(-time/t1))/(time/t1))-b2#exp(-time/t1)+b3#((1-exp(-time/t2))/(time/t2)-exp(-time/t2)))))*A-Cldirpr)#wei)/22);
create yyy from y;
append from y;
quit;
proc sort data=yyy;
by col7;
run;
quit;

文件yyy里面的第一行就是所要的参数,即col1-col6
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2009-9-15 09:54:52
还是运行不出结果来
data bonds040927(label='2004年9月27日上交所22只付息国债收盘价');
input bdname $8. matdt:yymmdd10. freq coupond Cldirpr dur term;
format matdt yymmdd10.;
label
bdname='债券名称'
matdt='到期日'
freq='年付息频率'
coupond='票面利息'
Cldirpr='市场价格'
dur='久期'
term='年限';
cards;
96国债6  2006-6-14   1 11.83   114.85  1.90262 10
97国债4  2007-9-5    1 9.78    116.6   2.76666 10
99国债5  2007-8-20   1 3.28    98.48   2.9076  8
99国债8  2009-9-23   1 3.3     94.62   4.70122 10
21国债3  2008-4-24   1 3.27    96.66   3.81898 7
21国债7  2021-7-31   2 4.26    92.09   12.9768 20
21国债10 2011-9-25   1 2.95    89.13   6.44658 10
21国债12 2011-10-30  1 3.05    89.67   7.25293 10
21国债15 2008-12-18  1 3       94.16   4.72472 7
02国债3  2012-4-18   1 2.54    86      7.3555  10
02国债10 2009-8-16   1 2.39    90.71   4.77451 7
02国债13 2017-9-20   2 2.6     77.36   11.1914 15
02国债14 2007-10-24  1 2.65    95.96   3.84993 5
02国债15 2009-12-6   1 2.93    92.5    5.60126 7
03国债11 2010-2-19   1 2.66    90.65   5.63273 7
03国债3  2023-4-17   2 3.4     80.64   14.6887 20
03国债7  2010-8-20   1 2.66    89.69   5.63273 7
03国债8  2013-9-17   1 3.02    87.26   8.06064 10
03国债11 2010-11-19  1 3.5     93.7    6.36469 7
04国债3  2009-4-19   1 4.4164  99.92   4.61904 5
04国债4  2011-5-25   1 4.89    101.04  6.17962 7
04国债7  2011-8-25   1 4.71    99.97   6.20199 7
;
run;
/*  现金流分解 */
data float(keep=bdname c1-c38);
set bonds040927;
sdate='27sep2004'd;  
edate=Matdt;  
yrdif=yrdif(sdate, edate, '30/360');  
dif=yrdif-int(yrdif);  
if Freq=1 then if dif=0 then do;
y=yrdif;
a=coupond;
end;
else do;
y=int(yrdif)+1;  
a=coupond;
end;
if Freq=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{38};   
do i=1 to y;
if i<y then c[i]=a;  
         else c[i]=a+100;
end;
do j=y+1 to 38;
c[j]=0;
end;
run;
/*  现金流对应的时刻 */
data time(keep=bdname t1-t38);
set bonds040927;
sdate='27sep2004'd;
edate=Matdt;
yrdif=yrdif(sdate, edate, '30/360');
dif=yrdif-int(yrdif);
if Freq=1 then if dif=0 then do;
y=yrdif;  
a=1;
end;
else do;
y=int(yrdif)+1;
a=dif;
end;
if Freq=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{38};
do i=1 to y;
t[i]=a+(1/Freq)*(i-1);
end;
do j=y+1 to 38;
t[j]=1;
end;
run;
data float_time;
merge float time;
run;
/*计算权重*/
data weight;
set bonds040927 end=end;
Dur1=1/Dur;
sumDur1+Dur1;
if end;
call symput('ddd',sumDur1);
data weight(keep=weight);
merge bonds040927 weight;
weight=(1/Dur/&ddd);
run;
data w1;
set bonds040927 end=end;
Dur1=1/(dur**0.5);/*权重设为久期的算术平方根的倒数*/
sumDur1+Dur1;
if end;
call symput('ddd',sumDur1);
data w1(keep=w1);
merge bonds040927 w1;
w1=(1/(dur**0.5)/&ddd);
run;
proc iml;
reset deflib=work;
use bonds040927;
read all var{Cldirpr} into Cldirpr;
read all var{Dur} into Dur;
use float_time;
read all var('c1': 'c38') into float;
read all var('t1': 't38') into time;
use w1;
read all var{w1} into wei;
store Cldirpr Dur float time wei;
run;
quit;
proc iml;
reset deflib=work;
use bonds040927;
read all var{Cldirpr} into Cldirpr;
read all var{Dur} into Dur;
use float_time;
read all var('c1': 'c38') into float;
read all var('t1': 't38') into time;
use w1;
read all var{w1} into wei;
store Cldirpr Dur float time wei;
run;
quit;
proc iml;
reset deflib=work;
load Cldirpr Dur float time wei;
y=j(1099560,7);
A=j(38,1,1.);
do b1=-0.086 to -0.076 by 0.001;
do b2=-0.109 to -0.098 by 0.001;
do b0=0.086 to 0.094 by 0.0005;
do t1=9 to 12 by 0.5;
do b3=0.042 to 0.054 by 0.002;
do t2=2.2 to 4 by 0.2;
i=(b1+0.086)/0.001*99960+(b2+0.109)/0.001*8330+(b0-0.086)/0.0005*490+(t1-9)/0.5*70+(b3-0.042)/0.002*10+(t2-2.2)/0.2+1;
y[i,1]=b1;end; y[i,2]=b2;end; y[i,3]=b0;end; y[i,4]=b3;end; y[i,5]=t1;end; y[i,6]=t2;end;
y[i,7]=ssq((((float#exp(-time#(b0+(b1+b2)#((1-exp(-time/t1))/(time/t1))-b2#exp(-time/t1)+b3#((1-exp(-time/t2))/(time/t2)-exp(-time/t2)))))*A-Cldirpr)#wei)/22);
create yyy from y;
append from y;
quit;
proc sort data=yyy;
by col7;
run;
quit;
附件列表

NSS.txt

大小:4.25 KB

 马上下载

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2009-9-15 10:05:21
把下面这段删掉就行了
*计算权重*/
data weight;
set bonds040927 end=end;
Dur1=1/Dur;
sumDur1+Dur1;
if end;
call symput('ddd',sumDur1);
data weight(keep=weight);
merge bonds040927 weight;
weight=(1/Dur/&ddd);
run;
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

点击查看更多内容…
相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群