全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 SAS专版
1690 2
2011-06-20
悬赏 20 个论坛币 已解决
有N只股票过去10年的月度收益(比如 变量有stkcd trdmnt ret m_ret (股票代码 交易月份 月度收益 市场月度收益)),如何计算每个月的波动率(用过去20个月的收益数据计算),和beta (也用过去20个月的数据计算)

最佳答案

cathy3212 查看完整内容

data aa; input stkcd $ trdmnt $ ret m_ret; cards; 000002 199001 0.12 0.1 000002 199002 0.18 0.2 000002 199003 0.09 0.15 000002 199004 0.14 0.11 000002 199005 -0.21 -0.18 000002 199006 0.14 0.17 000002 199007 0.1 0.11 000002 199008 0.08 0.09 000002 199009 0.05 0.03 000002 199010 -0.12 -0.16 000002 199011 0.02 0.01 000002 199012 0.06 0.09 000002 199101 0.1 0.11 000002 199102 0.12 0.1 ...
二维码

扫码加我 拉你入群

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

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

全部回复
2011-6-20 13:15:22
data aa;
input stkcd $ trdmnt $ ret m_ret;
cards;
000002 199001 0.12 0.1
000002 199002 0.18 0.2
000002 199003 0.09 0.15
000002 199004 0.14 0.11
000002 199005 -0.21 -0.18
000002 199006 0.14 0.17
000002 199007 0.1 0.11
000002 199008 0.08 0.09
000002 199009 0.05 0.03
000002 199010 -0.12 -0.16
000002 199011 0.02 0.01
000002 199012 0.06 0.09
000002 199101 0.1 0.11
000002 199102 0.12 0.1
000002 199103 0.15 0.13
000004 199001 0.12 0.1
000004 199002 0.18 0.2
000004 199003 0.09 0.15
000004 199004 0.14 0.15
000004 199005 -0.21 -0.18
000004 199006 0.14 0.17
000004 199007 0.18 0.11
000004 199008 0.08 0.09
000004 199009 0.05 0.03
000004 199010 -0.12 -0.16
000004 199011 0.02 0.01
000004 199012 0.06 0.09
000004 199101 0.1 0.11
000004 199102 0.12 0.1
000004 199103 0.15 0.13
;
run;
/*首先给每个月份按时间顺序加上个序列的值,比如开始日期是199001,那让这一行的i=1*/
proc sort data=aa;
by trdmnt;
run;
data aa1;
set aa end=f;
if _n_=1 then i=1;
if _n_>1 and trdmnt>lag(trdmnt) then i+1;
if f then call symput("nn",i);
run;

proc sort data=aa1;
by stkcd trdmnt;
run;

data result;
input stkcd $ enddate $ beta std;
cards;
run;
%macro corvar;
%do j=4 %to &nn;
data mid;
set aa1;
if i<=&j and i>%eval(&j-4);
if i=&j then call symput("enddate",trdmnt);
run;

proc reg data=mid outest=eee1;
by stkcd;
model ret = m_ret;
run;

proc sql;
create table eee2 as select
stkcd
,std(ret) as std
from mid
group by stkcd;
quit;

data eee3;
merge eee1 eee2;
by stkcd;
rename m_ret=beta;
enddate="&enddate";
keep stkcd enddate m_ret std;
run;

proc append base=result data=eee3;
run;
%end;
%mend;
%corvar;

把我这个里面的4改成20就是你要的20个月份一起算啦,另波动率不知道是不是20个月的std如果不是的话,要得到相应正确的应该也不难。我的SAS也没有特别好,可能程序不是最简短的。。希望对你有所帮助
二维码

扫码加我 拉你入群

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

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

2011-6-25 01:57:03
2# cathy3212 我的问题后来解决了 不过还是谢谢你 把分儿给你吧 我是这么写的:

data finance.target3;
   set finance.target2;
   by stkcd;
   if first.stkcd then n=1; else n+1;  /*  对各个股票的时序观测编号 用于有名的筛选(因为计算波动率和贝塔只用60个月的数据) 这里多了一个n变量 */
run;


/* 利用宏来做循环 */

%macro caculate;
%do x=60 %to 204; /* 共17年 204个月 */
   Data finance.temp;
     Set finance.target3;
     If &x-59<=n<=&x;   /* 筛选出60个月的数据 1-60 2-61 等等,n是对各股票时序上的编号,事实上这一步是有问题的,因为可能截取的观察少于60,所以在后面对std的输出里面,利用自动生成的便利_freq_进行筛选*/
     Per=&x;
   run;

  Proc reg data=finance.temp noprint outest=results;*滚动回归求beta,使用指数模型,;
     Model ret_premium=m_retpre;
     By stkcd per;
  proc means data=finance.temp noprint;
     by stkcd per;
     var ret;  
     output out=results1 std=sigma; *估计标准差;
     run;
  Quit;
/* 以下部分是把每次的输出放到一起 append正是这个功能 */
  %if &x=60 %then %do;
    data finance.betas1;
     set results;
    run;
    data finance.std;
     set results1;
    run;
  %end;
  %else %do;
     Proc append base=finance.betas1 data=results; /* 讲data=中的数据集追加到base=数据集中*/
     Proc append base=finance.std data=results1;
   quit;
  %end;%end; quit;

%mend caculate;  /* 定义宏结束 */

%caculate;    /* 宏的计算过程中会产生一些error,这不会有问题,因为后面针对观测不足的结果进行了剔除 */

/* 提取计算的劳动成果 */
data finance.betas2(keep=stkcd n beta);
   set finance.betas1;
   n=per+1;   /* 挪一格的原因是用含这个月的过去60个月的数据得到的估计值 只能在后面一个月用 */
   beta=m_retpre;
run;

data finance.std1(keep=stkcd n sigma freq);
   set finance.std;
   n=per+1;
   rename _FREQ_=freq;
run;

data finance.std2(drop=freq);
   set finance.std1;
   if freq=60;
run;   /*** 剔除观测少于60的值 @@@@@@@@@@@@@@ 很重要的一步 ***/
二维码

扫码加我 拉你入群

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

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

相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

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