| 用历史模拟法实现海量股票数据VAR计算 /* 创建宏变量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中。这里也可以用set语句,用set语句更容易控制,但用这里的append过程的效率更高 */ %end;  /* 结束%do循环 */ %mend calvar; %calvar (240, 0.05, 5);  %calvar (240, 0.01, 1); %calvar (480, 0.05, 5); /* 利用交易日前480天的数据,计算置信水平为95%的风险值*/ %calvar (480, 0.01, 1); %calvar (720, 0.05, 5); %calvar (720, 0.01, 1); run;     /*对历史模拟法计算的VaR进行事后检验 */ %macro bt(days, prob, aa); data a; set compufin.his&days&aa nobs=nobs; module="His+&days +&aa";  /* 标识所使用的历史模拟法 */ prob=&prob; records=nobs; /* 2000年总的记录天数,这里为239 天 */ default+flag; /* default为2000年中VaR的累加失效天数 */ shouldbe= round(records*&prob); /* 按相应概率应该失效的VaR天数 */ if _n_=nobs; /* 取数据集的最后一个观测值 */ proc append base=bt data=a; %mend bt; %bt(240,0.05,5); %bt(240,0.01,1); %bt(480,0.05,5); %bt(480,0.01,1); %bt(720,0.05,5); %bt(720,0.01,1); run; |