当前位置:文档之家› sas金融计算清华朱世武数据集char14

sas金融计算清华朱世武数据集char14

14.4.3 组合构建/*挑选1997年以前发行的A股股票,用到数据集:行情数据集compufin.quot和股本数据集compufin.shares*//*选择行情数据*/Data quot;length hexcd $6.;Set compufin.quot;Keep date clpr hexcd; /*选择保留变量, date为日期,clpr为收盘价*/if substr(hstocd,3,1)=6 or substr(hstocd,1,5)=21000;hexcd=substr(hstocd,3,6); /*将行情数据集中的股票代码转换为交易所最新代码*/ label hexcd='最新交易所代码';proc sort data=quot;by hexcd date;run;/*选择流通股本数据*/data shares;length hexcd $6.;set compufin.shares;keep date pubflt hexcd; /*选择变量,date为日期,pubflt为观测到的流通股本数*/ hexcd =substr(hstocd,3,6); /*转换股本观测数据集中的股票代码*/proc sort data=shares;by hexcd date;run;/*合并行情与股本数据*/data biao;merge quot shares;by hexcd date;run;/*对每个交易日都填上流通股本数据*/data a;set biao;if pubflt^=. then y=1;sumy+y; /*创建新变量sumy, 为变量y的累加变量,即对每支股票,每一次股本变动变量sumy都加上1, 后面要用到(实际上sumy还是起到了加标识的作用,它是站在整个数据集的角度上加的)*/data b;set a;keep sumy pubflt;if pubflt^=.; /*if保证了只保留数据集A中pubflt不等于.时的变量sumy和pubflt */run;data c;set a;drop pubflt; /*删除数据集A中的变量pubflt, 方便下面数据集c和b合并时,将股本填全,这是个很重要的技巧*/data biao2 (drop=y sumy);merge c b;by sumy;run;/*上面这里,在数据并不一一对应的情况下(同时c中没有pubflt这一变量),在新生成的biao2中,pubflt的值是对应于b中sumy相同的那个pubflt值。

这一过程实际上是为了用个别的pubflt填全整个数据集,这一实现方法需要注意。

同样的目的也可以通过retain等语句加以实现*//*生成最终表zongbiao*/data zongbiao;set biao2;where year(date)=1996; /*日期可以灵活控制,但最好用where语句*/proc sort data=zongbiao;by hexcd date;run;/*计算1996年每支股票的平均流通市值*/data mv(keep=clpr pubflt date hexcd mv);set zongbiao;mv=clpr*pubflt;proc means data=mv noprint;var mv;by hexcd;output out=mv mean=m_mv;run;/*由此得到的数据集mv, 其中有我们随机抽股票和按1996年平均流通市值抽股票需要的变量:股票代码hexcd和1996年各股票平均流通市值m_mv *//*选取股票方法一:随机抽取20支股票*/data mv;set mv;if substr(hexcd,1,1)^=0 and substr(hexcd,4,1)=6; /*只对复权价逻辑库stoindif中的股票抽取*/proc sql;create view _tmp_ asselect *, ranuni(1055) as _ran_ from mvorder by calculated _ran_;quit;data stocks;set _tmp_(obs = 20);drop _ran_;a='%a(';c=");";file " d:\genstock.txt";put a $ hexcd $ c $;run;/*选取股票方法二:按1996年股票平均流通市值m_mv均匀选取20只股票*/proc sort data= mv out=a;by m_mv;data b;set a nobs=nobs;n=round(nobs/20);t=_n_ - int( _n_ / n)*n;a='%a(';c=");";file " d:\genstock1.txt";put a $ hexcd $ c $;run;/* 将随机抽取的20支股票合并到一个数据集中*/data price;set stoindif.a1a0001;keep date;where 1997<=year(date)<=2000;%macro a(x);data a;set stoindif.a&x;where 1997<=year(date)<=2000;keep date clpr_r;data price;merge price a(rename=(clpr_r=p&x));by date;%mend a;%include "d:\genstock.txt";run;/*对抽取的20支股票随机赋权重:选择2000年最后一个交易日作为购买股票组合的日期,实际上是2000年12月29日*/data tprice;set price end=lastob; /*end为选项,lastob为自动变量*/if lastob=1; /*选择数据集price中的最后一个观测值,即2000年12月29日的数据*/drop date;run;proc iml;rv=uniform(repeat(0,20,1)); /*产生1列[0, 1]均匀分布的随机数20个*/sum=rv[+,]; /*向量rv列求和*/b=rv/sum; /*计算权重向量b */b=b#1000000; /*假设投资总额为100万元时,计算组合购买每去股票的金额*/use tprice;read all into tprice;b=b/t(tprice); /* t(tprice)为矩阵tprice转置,向量b为以2000年12月29日股票的收盘价为标准组合购买每支股票的股数*/create weight from b; /*由向量b创建的SAS数据集weight为购买每支股票的股数*/append from b;close weight;quit;/*计算1997~2000年3年间投资组合每一交易日的价值和对数收益率*/data dateinfo;set price;keep date; /*取数据集price中的日期变量作为下面计算出投资组合价值后的合并变量*/data return; /*去掉日期变量date,以便下面的矩阵运算*/set price;drop date;proc iml;use return;read all into clpr; /*创建组合中股票的价格矩阵clpr */close return;t=nrow(clpr); /*矩阵clpr的列数,实际上是交易日数*/do _i_=1 to t;do _j_=1 to 20;if clpr[_i_,_j_]=. then clpr[_i_,_j_]= clpr[_i_-1,_j_]; /*如果某支股票某一交易日没有交易的话,用前一个交易日的价格来替代该交易日价格*/end;end;use weight; /*创建组合中购买每支股票股数矩阵*/read all into weight;close weight;p_value = clpr * weight; /*计算组合的价值*/create p_value from p_value; /*创建组合价值SAS数据集p_value */append from p_value;close p_value;quit;data p_value (rename=(col1=p_value));merge dateinfo p_value; /* 为计算得出的组合价值添加交易日变量*/data compufin.return; /*计算各交易日组合的对数收益率*/set p_value;return=log(p_value)-log(lag(p_value));if return=. then delete;drop p_value;run;14.4.4 历史模拟法实现程序/* 创建宏变量nobs,其值为2000年的交易日数,即数据集a中的观测数*/data a;set compufin.return;where year(date)=2000;obs=_n_;keep date obs;run;data a;set a nobs=nobs;call symput('nobs', nobs); /* 创建宏变量nobs,其值为数据集a中的观测数*/%put &nobs; /* 显示宏变量nobs的值,这里为239 */run;data return;merge compufin.return a;by date;if obs=. Then obs=0;run;options nodate nonotes nosource; /* 系统选项:不在log窗口输出日期、注释和原程序*/ %macro calvar(days, prob, aa);%do i=1 %to &nobs; /* 计算2000年每个交易日的VaR值, 这里的宏变量nobs的值是前面得到的239 */data a;set return;if obs<&I; /* 计算某日的VaR时,选择该日(即2000年的第i日)前的历史数据*/ proc sort data=a out=b;by descending date;data b;set b;if _n_<=&days;/* 选择该日期(即2000年的第i日)前历史数据的数据,如480个或720个数据用于估计该日期的VaR */proc sort data=b;by return; /* 对选择的历史数据按收益率排序*/data c(keep=return rename=(return=var));set b;n=int(&days*&prob);if _n_ = n;/* 选择prob分位数,即为相应的VaR ,实际的VaR为相应的收变益率乘以100万元,这里为了简单起见,没有乘100万,但不影响结果*/data d;set return;where obs=&I; /* 选择所计算VaR值日期(即2000年的第i日)的实际收益率数据*/ data e;merge d c; /* 将用历史数据计算的风险值和该日的实际值合并到一个数据集中,以便后面的事后检验*/data e;set e;if return<var then flag=1; /* 如果实际值小于该日的VaR值时,设变量flag的值为1,否则为0 */else flag=0;proc append base=compufin.his&days&aa data=e;/* 将计算出2000年每个交易日的VaR值和实际值合并到同一个数据集his2000中。

相关主题