滚动窗口中的相关性,非矩阵数据

时间:2014-04-02 18:18:38

标签: sas

编辑:我正在研究解决方案,到目前为止一直非常成功。我将在完成并完全运行后立即将其发布以供将来参考。

我正在研究股票回报,并且一直在思考这个问题。我仍然是SAS的新手,这对我来说特别具有挑战性。

我有以下数据集(简化)。

PERMNO DATE       RETURN   
10078  1995JAN02   0.012000
10104  1995JAN02   0.050000
10107  1995JAN02  -0.019000
10078  1995JAN03   0.002000
10104  1995JAN03   0.004000
10107  1995JAN03  -0.009000
...    
10078  1996JAN02  -0.011000  
10104  1996JAN02  -0.020000
10107  1996JAN02   0.010000 
...
10078  2013JAN03   0.050000
10104  2013JAN03   0.012000  
10107  2013JAN03  -0.034000 

PERMNO标识一只股票,DATE标识一个日期(yyyymmmdd),RETURN是每日股票回报。

我仅针对三只股票(10078,10104,10107)简化了这个例子。

我的目标是在三个不同的股票之间建立每日相关矩阵,并将一年观察窗口(大约252个过去观察值)输出到日常文件中。

鉴于我的数据集,这应该从1996JAN03开始(粗略地)。因此,第一天它应该计算所有不同1995JAN02的{​​{1}}和1996JAN02之间所有观察值之间的相关系数(所以PROC CORR)。即然后我应该能够输出以下矩阵

PERMNO

第二天 10078 10104 10107 10078 1 0.1 0.3 10104 0.1 1 0.2 10107 0.3 0.2 1 ,我应该能够使用1996JAN041995JAN03之间的观察输出相同的矩阵。重要的是,最终过程能够处理1996JAN03中的不匹配数据集。即如果一只股票只有DATE之后的价格,那么它应该只使用这些日期,如果其中一只股票没有1995JAN05的记录,它应该能够忽略该观察和使用只有剩下的“匹配”。

我的问题与此Calculating rolling correlations in SAS非常相似,但我的数据并未组织为矩阵。我很想应用建议的方法(仍在研究它)但我必须将我的数据“转换”成矩阵 - 如果这是最有效的方式,我愿意这样做(但我需要帮助我真的不知道怎么做,虽然我可以描述预期的输出。)

(如果您有解决方案,请随意跳过以下部分) 我曾想过要解决这个问题(但尚未转换为SAS代码)是(假设有n股):

  1. 计算唯一1995SET05的数量(可通过PROC SQL实现);
  2. 定义开始日期(PERMNO);
  3. 创建一个执行以下步骤(4-8)的宏:
  4. 对于每个1996JAN02,在开始日期之后获取该PERMNO的日期列表(可能通过PROC SQL);
  5. 对于步骤4中的每个PERMNO,迭代剩余的股票(因为输出是三角矩阵,我可以转到n - 1 - j剩余股票,其中j是从1到1的当前股票n)并使用return1和return2创建一个表,其中包含(当前日期 - 1)和(当前日期 - 253个观察值)之间的匹配日期;
  6. 计算步骤5中创建的表的PROC CORR。
  7. 将此输出(以某种方式)保存到该特定日期的数据集,并继续执行此操作,直到我在开始日期之后已经耗尽了此库存的所有日期;
  8. 转到下一个DATE
  9. 通过PROC EXPORT写入数据集。
  10. 然而,这是MATLAB-y或VBA-y,它们是我熟悉的语言,当然也不是SAS中最有效的方法。

    我事先感谢你的帮助。

1 个答案:

答案 0 :(得分:0)

感谢@Joe和这个paper on calculating correlations with PROC EXPAND的ETS指针,我无法达到初始目标但是非常接近它 - 我可以输出如下数据集(取出一些字段用于简化):

     date  permno1  permno2  ret1  ret2   rho
1996JAN02    10078    10104  0.01  0.02  0.34

要了解有关PROC EXPAND的更多信息,我建议使用以下paper

首先,我得到表中所有现有permno的列表,然后使用宏迭代它们。然后我将初始表中的所有返回值从两个permnos中提取到两个表(company1和company2)中,然后完全连接这些表。对于两家公司都没有退货的日期,记录将被删除。对于两只股票中只有一只股票被交易的日期,因为该观察对于计算任何一天两只股票之间的相关性是无用的。然后我通过PROC EXPAND应用相关公式,通过计算几个具有必要计算的新字段(将很快更新,并提供更好的解释)。拥有所有必要的字段,我计算rho,将结果数据集合并为一个全方位的数据集并循环到下一个公司。

这个代码每个公司大约需要2分钟,因为有大约970家公司需要一天才能完全运行 - 但它确实有效!如果您对此代码有任何意见,我将非常乐意听到它们。

proc sql noprint;
    create table permnolist as
    select distinct permno
    from pricescorrel;
quit;

data permnolist;
    set permnolist;
    by permno;
    permnoid + 1;
run;

%MACRO correlpairs();

    proc sql noprint;
        select distinct max(permnoid)
        into :ttl_id
        from permnolist;
    quit;

    %do ii=1 %to &ttl_id;

        proc sql noprint;
            select distinct permno
            into :permnoa
            from permnolist
            where permnoid = ⅈ
        quit;

        %do jj=&ii %to &ttl_id;

            proc sql noprint;
                select distinct permno
                into :permnob
                from permnolist
                where permnoid = &jj;
            quit;

            proc sql noprint;
                create table company1 as
                select date as olddate, *
                from pricescorrel 
                where permno = &permnoa;
            quit;

            proc sql noprint;
                create table company2 as
                select date as olddate, *
                from pricescorrel 
                where permno = &permnob;
            quit;

            proc sql noprint;
                create table merged as
                select coalesce(a.olddate, b.olddate) as date,
                        a.permno as permno1,
                        b.permno as permno2,
                        a.ret as ret1,
                        b.ret as ret2
                from company1 as a
                    full join company2 as b
                    on a.olddate = b.olddate;
            quit;

            data merged;
                set merged;
                OBS = 1;
                if nmiss(of ret1 -- ret2) > 1 then
                    delete;
                else
                    if nmiss(of ret1 -- ret2) > 0 then
                        do;
                            ret1 = . ;
                            ret2 = . ;
                            OBS = . ;
                        end;
                R12 = ret1 * ret2;
            run;

            proc expand DATA = merged OUT = mergedout METHOD = none;
                convert ret1 = C1SUM / TRANSFORMOUT = (movsum 252);
                convert ret2 = C2SUM / TRANSFORMOUT = (movsum 252);
                convert R12 = C12SUM / TRANSFORMOUT = (movsum 252);
                convert OBS = N / TRANSFORMOUT = (movsum 252);
                convert ret1 = C1CSS / TRANSFORMOUT = (movcss 252);
                convert ret2 = C2CSS / TRANSFORMOUT = (movcss 252);
            run;

            data mergedout(keep=date obs N permno1 permno2 ret1 ret2 rho);
                set mergedout;
                if missing(rho) then
                    delete;
                rho = (C12SUM - (C1SUM * C2SUM)/N) / (sqrt(C1CSS) * sqrt(C2CSS));
                rho = lag(rho);
            run;

            proc datasets nolist;
                append base=mydat
                data=mergedout;
            quit;

            proc datasets library = work nolist;
                delete mergedout;
            run;
        %end;
    %end;
proc export
    data=mydat 
    outfile="mergedout.csv"  
    dbms=csv replace;
run;
%mend;
%correlpairs();