SAS中文论坛

标题: 继续请教,非常感谢 [打印本页]

作者: shiyiming    时间: 2009-8-21 13:49
标题: 继续请教,非常感谢
首先感谢hopewell对我上一个问题的解答,上次那个问题是我整个问题的一个小环节,所以这次我还需要继续请教,呵呵。我整个的问题是这样的:我想计算股价超常收益率,算法是这样的:
我将中国所有上市公司历年所有交易日的收益率算好,并将上证综指每个交易日的收益率对应列在每个上市公司收益率后面,总共有700多万条观测,假如单只股票的收益率变量名是syl,上证综指的收益率变量是szzzsyl,然后我考察的对股票股价产生影响的事件日标为1,这个标示变量变量名是inb,如果发生了事件,这个变量为1。数据集的大致样子如下:

syl /   szzzsyl   /  inb
0.2  / 0.2      /     0
0.1 /  0.12 /        0
0.3  / 0.1      /     0
.........
0.2 /  0.2    /       1
0.1  / 0.09     /    0
0.3  / 0.12 /        0
..........
0.1  / 0.09    /     0
0.11 /0.21   /      0
0.11/ 0.10  /       1
0.1  / 0.21    /     0
..........
..........

我现在要做的问题是找到inb=1的事件日,然后找到从这一交易日往后数100个交易日,往前数30个交易日,先用-100到-31这70个交易日的syl和szzzsyl的数值估算一个回归模型,syl=a+b*szzzsyl,然后用估算出来的a和b测算从-30到+30这60个交易日应该“正常”的收益率,比如用syl'来表示,并用syl中实际的-30到+30交易日的收益率减去这60个交易日测算出来的收益率,就是syl-syl',二者的差作为超常收益。不知道sas能不能实现这样的过程?怎样实现呢?

顺便我还想请教一下,如果我想学习一下SAS里这种类似的编程,应该看哪些书比较好?(最好不要手册,太枯燥了,实在看不下去,最好带些讲解的)多谢!
作者: shiyiming    时间: 2009-8-23 18:00
标题: Re: 继续请教,非常感谢
没对回归方程进行检验,没测过对大型数据的效率
[code:1slywkf7]
/* 创建模拟数据 */
data raw(drop=i);
        do stock_number=601398,601857,600028;
                date='31dec007'd;
                do i=1 to 365*3;
                        date+1;
                        syl=round(ranuni(123),0.01);
                        szzzsyl=round(ranuni(123),0.01);
                        if mod(i,90)=45 then inb=1;
                        else inb=0;
                        output;
                end;
        end;
        format date yymmdd10.;
run;

%macro create_syl(in_ds,out_ds,);
        options nomprint nosymbolgen;
        /* INNER MACRO: 提取(-M,+N)日数据 */
        %macro create_subds(stock_number,inb_date,start_day=30,end_day=100);
                /* 根据inb_date,start_day,end_day建立空日期记录 */
                data _temp_hi(drop=i);
                        hi_stock_number=&stock_number;
                        hi_date=&inb_date-(&start_day+1);
                        day_flag=-(&start_day+1);
                        do i=0 to &start_day+&end_day;
                                hi_date+1;
                                day_flag+1;
                                output;
                        end;
                        format hi_date yymmdd10.;
                run;
                /* 用hash iterator为空日期填补对应数据 */
                data _temp_syl(keep=stock_number date syl szzzsyl day_flag);
                        if _n_=1 then do;
                                declare hash h(dataset: '_temp_hi',ordered:'ascending',hashexp:10);
                                h.definekey('hi_stock_number','hi_date');
                                h.definedata('hi_stock_number','hi_date','day_flag');
                                h.definedone();
                                call missing(hi_stock_number,hi_date,day_flag);
                                declare hiter hi('h');
                        end;
                        set raw;
                        rc=hi.first();
                        do while (rc=0);
                                if hi_stock_number=stock_number and hi_date=date then output;
                                rc=hi.next();
                        end;
                run;
        %mend;

        /* INNER MACRO: 创建回归方程,并计算预测值 */
        %macro create_reg(start_day_reg=1,end_day_reg=10,start_day_expect=30,end_day_expect=30);
                /* 按相对日期start_day_reg,end_day_reg选取观测,建立回归方程 */
                ods _all_ close;
                ods output Reg.MODEL1.Fit.syl.ANOVA=_temp_reg_anova;
                ods output Reg.MODEL1.Fit.syl.FitStatistics=_temp_reg_fitstat;
                ods output Reg.MODEL1.Fit.syl.ParameterEstimates=_temp_reg_parameter;
                proc reg data=_temp_syl;
                        model syl=szzzsyl;
                run;
                quit;
                ods _all_ close;
                ods listing;
                /* 获取回归方程系数 */
                data _null_;
                        set _temp_reg_anova;
                        if _n_=1 then do;
                                call symput('f_value',put(round(fvalue,0.0001),best8.));
                                call symput('prob_f',put(round(probf,0.0001),best8.));
                        end;
                run;
                data _null_;
                        set _temp_reg_fitstat;
                        if _n_=1 then call symput('r_square',put(round(nvalue2,0.0001),best8.));
                run;
                data _null_;
                        set _temp_reg_parameter;
                        if _n_=1 then call symput('est_a',put(estimate,best8.));
                        if _n_=2 then call symput('est_b',put(estimate,best8.));
                run;
                /* 按回归方程计算预测数据 */
                data _temp_syl;
                        set _temp_syl;
                        if -&start_day_expect<=day_flag<=&end_day_expect then do;
                                est_syl=&est_a+&est_b*szzzsyl;
                                sum_est_syl+est_syl;
                                sum_syl+syl;
                                if day_flag=&end_day_expect then do;
                                        call symput('avg_syl_est',
                                                                put(round(sum_est_syl/%eval(&end_day_expect-&start_day_expect+1),0.0001),best8.));
                                        call symput('avg_syl',
                                                                put(round(sum_syl/%eval(&end_day_expect-&start_day_expect+1),0.0001),best8.));
                                end;
                        end;
                run;
                /* 拼接结果数据 */
                data final;
                        %if &inb_obs=1 %then %do; set _temp_inb_date; %end;
                        %else %do; set final; %end;
                        if _n_=&inb_obs then do;
                                avg_syl=&avg_syl;
                                avg_syl_est=&avg_syl_est;
                                avg_syl_diff=&avg_syl-&avg_syl_est;
                                est_a=&est_a;
                                est_b=&est_b;
                                f_value=&f_value;
                                prob_f=&prob_f;
                                r_square=&r_square;
                        end;
                run;
        %mend;

        /* 查找inb发生的日期 */
        data _temp_inb_date;
                set &in_ds(where=(inb=1));
                rename date=inb_date;
                keep stock_number date;
        run;

        /* 根据inb的日期执行回归运算 */
        %let dsid=%sysfunc(open(_temp_inb_date));
        %syscall set(dsid);
        %let nobs=%sysfunc(attrn(&dsid,nobs));
        %do inb_obs=1 %to &nobs;
                %let rc=%sysfunc(fetchobs(&dsid,&inb_obs));
                %create_subds(&stock_number,&inb_date)
                %create_reg()
        %end;
        %let rc=%sysfunc(close(&dsid));

        proc datasets library=work nolist nodetails;
                delete _temp: /memtype=data;
        run;
        quit;
%MEND;

%create_syl(raw,final)[/code:1slywkf7]
作者: shiyiming    时间: 2009-8-24 10:06
标题: Re: 继续请教,非常感谢
非常感谢hopewell
。。。。。。。。
我先研读一下这段程序。。。
嘎牛的

这个论坛真是不错啊,我问了好多人了,这个问题,都是帮不上忙
不讲那么多了,看懂程序先




欢迎光临 SAS中文论坛 (https://mysas.net/forum/) Powered by Discuz! X3.2