楼主: xuyifengdzd
4231 7

[程序分享] 求助SAS编程问题涉及数据分类 [推广有奖]

  • 2关注
  • 0粉丝

硕士生

41%

还不是VIP/贵宾

-

威望
0
论坛币
29086 个
通用积分
33.7601
学术水平
1 点
热心指数
1 点
信用等级
1 点
经验
1487 点
帖子
38
精华
0
在线时间
273 小时
注册时间
2009-5-30
最后登录
2023-7-22

30论坛币
现有如下形式数据,不要计较其实际内容,只是借以说明问题。

nianfen
abcde
1996110.99110.99110.99110.99110.99
1997130.77130.77130.77130.77130.77
1997119.89119.89119.89119.89119.89
1997128.92128.92128.92128.92128.92
1997107.75107.75107.75107.75107.75
1997118.34118.34118.34118.34118.34
1998143.21143.21143.21143.21143.21
1998134.32134.32134.32134.32134.32
1998142.43142.43142.43142.43142.43
1998116.9116.9116.9116.9116.9
1998134.84134.84134.84134.84134.84
1999146146146146146
1999141.46141.46141.46141.46141.46
199998.1498.1498.1498.1498.14
199998.1598.1598.1598.1598.15


在每个时间段用变量abcde拟合出一条曲线,然后把这些曲线以时间为轴排列起来绘成一个曲面。
现在已经通过几个data步能够对单个时间段内的变量进行曲线的拟合,但是怎么实现这后面的步骤呢?
就是每个时间段自动拟合,然后绘图。最好是自动的,因为实际处理的时间点大约在2000个左右。
对单个表预处理的工作实在太庞大了
我是初学,实在不懂,希望大家不吝赐教。

这段时间考试比较忙,如果您回答了我的问题,我没及时做出反应请见谅。

关键词:sas编程问题 SAS编程 数据分类 data步 ABCD 求助 SAS 数据分类
沙发
crackman 发表于 2010-6-19 23:56:05 |只看作者 |坛友微信交流群

使用道具

藤椅
BraveMadMan 发表于 2010-6-20 02:17:53 |只看作者 |坛友微信交流群
为了更好的帮助你,建议楼主能更详细的描述你的问题。最好是将你已有的code贴出来

使用道具

板凳
xuyifengdzd 发表于 2010-6-20 09:33:58 |只看作者 |坛友微信交流群
3# BraveMadMan
源代码是老板未发表论文中的东西,实在不方便贴出,只能借用一下其他的。比如宋军老师《金融计量学》中NSS方法,代码如下
/*Nelsen-siegel,创建数据集bond */
PROC IMPORT OUT= WORK.bond
           DATAFILE= "D:\data\bond.xls"
     DBMS=EXCEL2000 REPLACE;
     GETNAMES=YES;
run;
data float;
set bond;
dif=yrdif-int(yrdif);   /* 非整数年份数 */
/*以下if语句的判断是对不同的债券进行的 */
if fre=1 then if dif=0 then do;  /*计算年付息频率为1,非整数年份数dif为0时的现金流 */
y=yrdif;  /*y为非整年份数dif为0时的现金流次数 */
a=coupond; /*a年付息频率为1时的现金流 */
end;
else do; /*计算年付息频率为1,非整数年份数dif不为0时的现金流次数 */
y=int(yrdif)+1;  /*y为非整数年份数不为0时的现金流次数 */
a=coupond;  /*a年付息频率为1时的现金流 */
end;
if fre=2 then if dif=0.5 then do; /*计算年付息频率为2, 非整数年份数dif为0.5时的现金流 */
y=yrdif*2; /*y为非整数年份数dif为0.5时的现金流次数 */
a=coupond/2; /* a年付息频率为2时的现金流 */
end;
else if dif>0.5 then do; /*计算年付息频率为2, 非整数年份数dif大于0.5时的现金流 */
y=int(yrdif)*2+2; /*非整数年份数dif大于0.5时的现金流次数 */
a=coupond/2;
end;
     
else do; /*计算年付息频率为2, 非整数年份数dif小于0.5时的现金流 */
y=int(yrdif)*2+1; /*y非整数年份数dif小于0.5时的现金流次数 */
a=coupond/2;
end;
array c{30};   /*30是最长期限现金流的期数*/
do i=1 to y;
/*以下if语句的判断是对不同的债券进行的 */
if i<y then c=a;  /*y为相应债券的现金流次数,此时为小于到期期数时的现金流 */
         else c=a+100; /*到期期数时的现金流 */
end;
do j=y+1 to 30; /*大于到期期数而小于30时的现金流为0 */
c[j]=0;
end;
run;
/*产生自2010年6月2日以后各现金流对应的时刻(年份数) */
data time(keep=name t1-t30);
set bond;
dif=yrdif-int(yrdif);
/*以下if语句的判断是对不同的债券进行的 */
if fre=1 then if dif=0 then do;
y=yrdif;  
a=1; /*当前时刻为付息日时,现金流对应的时刻应为年份数加1。变量a即为要加上的数 */
end;
else do; /*dif不等于0 */
y=int(yrdif)+1;
a=dif; /*a为求现金流对应的时刻时,需年份数加上的那个数 */
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; /*dif<0.5 */
y=int(yrdif)*2+1;
a=dif;
end;
array t{30};
do i=1 to y;
t=a+(1/fre)*(i-1);  /*现金流对应的时刻,fre为年付息频率 */
end;
do j=y+1 to 30;
t[j]=1; /*剩余的期限赋值为1,方便Nelsen Siegel模型的计算*/
end;
run;
    /*合并现金流与相对应时刻数据集*/
data float_time;
merge float time;
run;
/*生成用于回归的系数矩阵*/
data regression(keep=name a bb cc d1-d3);  /*bb cc d1 d2 d3分别对应5个参数的系数*/
set float_time;
array c{30} ;
array t{30} ;
a=0;bb=0;cc=0;d1=0;d2=0;d3=0;  /*回归参数的初值赋为0*/
do i=1 to 30;
a=a+c;bb=bb+c*t;cc=cc+c*t**2;  /*现金流叠加 */
if t<5 then do td1=t**3;td2=0;td3=0;end;  
    else if t<8 then do td1=t**3-(t-5)**3;td2=(t-5)**3;td3=0;end;
         
else do td1=t**3-(t-5)**3;td2=(t-5)**3-(t-8)**3; td3=(t-8)**3; /* t>=8时*/
end;   
d1=d1+c*td1;d2=d2+c*td2;d3=d3+c*td3;
end;
run;
/*计算久期倒数总和,并将期赋给一个宏变量ddd,以备后用*/
data a (keep=sumdu1);
set bond end=end;
du1=1/du;
sumdu1+du1;
if end;
call symput('ddd',sumdu1); /*ddd为宏变量,其值为久期倒数总和(4.371),这里是为了以后自动调用*/
run;
/*产生回归系数矩阵 */
data regression(keep=name v bb cc d1-d3 w w1);
merge regression bond;
v=price-a; /*现价减去常数项*/
w=1/(1/du/&ddd)**2;  /*产生权重w,宏变量ddd的值是久期倒数总和*/
w1=(1/du/&ddd);
run;
Ods listing close; /*关闭LISTING */
Ods output ParameterEstimates(match_all persist=proc)= Estimates;
proc glm data=regression;
model v=bb cc d1 d2 d3/noint; /*noint为不要截矩选项 */
weight w;
run;
quit;
Ods listing; /*打开LISTING */
/*NELSEN-SIEGEL模型*/
/*将数据集生成相应的矩阵*/
proc iml;
reset deflib=work;
use bond;
read all var{price} into price; /*由SAS数据集bond中变量price的所有观测值创建向量price */
read all var{du} into du; /*由久期的所有观测值创建向量du */
use float_time;
read all var('c1': 'c37') into float; /*由所有现金流值创建矩阵float */
read all var('t1': 't37') into time; /*由现金流对应的时刻值创建矩阵time */
use regression;
read all var{w1} into wei; /*由所有权重w值创建向量wei */
store price du float time wei;
run;
/*通过循环计算出模型中的参数 */
proc iml;
reset deflib=work;
load price du float time wei;
y=j(1099560,7); /* j(1099560,7)为元素全为1的矩阵,共有1099560行,7列。1099560实际为控制循环的次数 */
A=j(30,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)/15;
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;
    /*计算理论价格和价差*/
proc iml;
reset deflib=work;
A=j(37,1,1.);
load float time price du wei;
x={-0.079 -0.107 0.093 0.048 10.5 3.2};
lprice=(float#exp(-time#(x[3]+(x[1]+x[2])#((1-exp(-time/x[5]))/(time/x[5]))-x[2]#exp(-time/x[5])+x[4]#((1-exp(-time/x[6]))/(time/x[6])-exp(-time/x[6])))))*A;/*计算理论价格*/
dif=(float#exp(-time#(x[3]+(x[1]+x[2])#((1-exp(-time/x[5]))/(time/x[5]))-x[2]#exp(-time/x[5])+x[4]#((1-exp(-time/x[6]))/(time/x[6])-exp(-time/x[6])))))*A-price;/*计算理论价格与市场价格的差*/
store dif lprice;
create dif from dif;
append from dif;
create lprice from lprice;
append from lprice;
print dif lprice ;
quit;
/*画图,利率期限结构图*/
data plot;
do i=0.1 to 20 by 0.1;
time =i;
b0=0.093;b1=-0.079;b2=-0.107;b3=0.048;t1=10.5;t2=3.2;
sr=b0+(b1+b2)*((1-exp(-time/t1))/(time/t1))-b2*exp(-time/t1)+b3*((1-exp(-time/t2))/(time/t2)-exp(-time/t2));
fr=b0+b1*exp(-time/t1)+b2*(time/t1)*exp(-time/t1)+b3*(time/t2)*exp(-time/t2);
output;
end;
run;
proc gplot data=plot;
symbol v='*' color=blue;
plot sr*time;
run;


现在的数据是个EXCEL表,其中包含了多个多个时间观测点的截面数据,每个时间点拟合一条曲线,然后把不同时间点的曲线在一个曲面上排列
就如利率期限结构的那样
1111.jpg

1111.jpg (30.99 KB)

1111.jpg

使用道具

报纸
BraveMadMan 发表于 2010-6-21 12:29:30 |只看作者 |坛友微信交流群
没想出来楼主这样作有什么特别之处?为什么不划五条二维的曲线呢?即使你强行划三维的,效果跟二维有什么不同吗?

使用道具

地板
xuyifengdzd 发表于 2010-6-24 13:43:40 |只看作者 |坛友微信交流群
5# BraveMadMan
问题就在于不是5条,是2500条曲线组成的一个曲面,如果手动画2500条曲线,再拟合的话工作量过大了,没有效率了

使用道具

7
saisai1111 发表于 2014-5-19 11:15:30 |只看作者 |坛友微信交流群
楼主有解决吗
我也遇到了同样的问题

使用道具

8
星eee 发表于 2014-7-23 16:56:58 |只看作者 |坛友微信交流群
很好的

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-28 07:43