SAS填补序列号的差距

时间:2017-07-05 17:58:21

标签: sas

我的数据集&RAWDATA类似于以下示例:

| Symbol | Date     | Time | BB | BO | MIDPRICE |
|--------|----------|------|----|----|----------|
| AAPL   | 20130102 | 2    | 2  | 3  | 2.5      |
| AAPL   | 20130102 | 3    | 1  | 3  | 1.5      |
| ...    |          |      |    |    |          |
| AAPL   | 20130102 | 100  | 3  | 4  |  3.5     |
| FB     | 20130102 | 1    | 3  | 6  | 4.5      |
| FB     | 20130102 | 3    | 3  | 5  | 4        |
| ...    |          |      |    |    |          |
| FB     | 20130102 | 100  | 3  | 4  |  3.5     |

在特定时间每个符号只有一行。

现在,我想处理这个数据集,以便时间变量从1开始并且是连续的。如果在特定时间没有记录,则在此时创建新记录,将所有值设置为上一记录。

正确的输出应该是:

| Symbol | Date     | Time | BB | BO | MIDPRICE |
|--------|----------|------|----|----|----------|
| AAPL   | 20130102 | 1    | 2  | 3  | 2.5      |
| AAPL   | 20130102 | 2    | 2  | 3  | 2.5      |
| AAPL   | 20130102 | 3    | 1  | 3  | 1.5      |
| ...    |          |      |    |    |          |
| AAPL   | 20130102 | 100  | 3  | 4  |  3.5     |
| FB     | 20130102 | 1    | 3  | 6  | 4.5      |
| FB     | 20130102 | 2    | 3  | 6  | 4.5      |
| FB     | 20130102 | 3    | 3  | 5  | 4        |
| ...    |          |      |    |    |          |
| FB     | 20130102 | 100  | 3  | 4  |  3.5     |

我已经尝试了以下代码,但它似乎不能正常运行:

/*
 * Macro to fill in the gap seconds
 */
%MACRO GAP_SEC(RAWDATA);
  data GAPDATA;
    SET &RAWDATA; by symbol date; 
    retain SYMBOL DATE TIME BB BO MIDPRICE;
    LAG_SYMBOL = lag(SYMBOL);
    LAG_DATE = lag(DATE);
    LAG_TIME = lag(TIME);
    LAG_BB = lag(BB);
    LAG_BO = lag(BO);
    LAG_MIDPRICE = lag(MIDPRICE);
    if first.symbol and first.date then 
   DO;
    if TIME NE 1; 
    N = TIME - 1; 
    DO WHILE(N>1);
    SYMBOL=SYMBOL;
    BB=BB;
    BO=BO;
    MIDPRICE = MIDPRICE;
    TIME=TIME-1;
    output;
    n=n-1;
    END;
   END;
else 
do;
    TIME_DIFF = TIME - LAG_TIME;
    if TIME_DIFF > 1 then 
        DO;
            M=TIME_DIFF;
            DO WHILE(M>1);
              SYMBOL = LAG_SYMBOL;
              TIME = TIME + 1;
              DATE = LAG_DATE;
              BB = LAG_BB;
              BO = LAG_BO;
              MIDPRICE = LAG_MIDPRICE;
              output;
              M=M-1;
            END;  
        END;
    end;
    drop LAG_SYMBOL LAG_DATE LAG_TIME LAG_BB LAG_BO LAG_MIDPRICE TIME_DIFF N M;
  run;
  /* Add new obs to original data set */
  proc append base=&RAWDATA data=GAPDATA;
  run;
  proc sort data=&RAWDATA force; by Symbol Date Time; run;
%mend;

它不会填补空白,它也会生成具有相同时间和相同符号的重复记录。 (请注意,在原始数据集中,每个符号在特定时间只有一条记录)。例如,数据集可能变为:

| Symbol | Date     | Time | BB | BO | MIDPRICE |
|--------|----------|------|----|----|----------|
| AAPL   | 20130102 | 2    | 2  | 3  | 2.5      |
| AAPL   | 20130102 | 2    | 2  | 3  | 2.5      |
| AAPL   | 20130102 | 3    | 1  | 3  | 1.5      |
| ...    |          |      |    |    |          |
| AAPL   | 20130102 | 100  | 3  | 4  |  3.5     |
| FB     | 20130102 | 1    | 3  | 6  | 4.5      |
| FB     | 20130102 | 1    | 3  | 6  | 4.5      |
| FB     | 20130102 | 3    | 3  | 5  | 4        |
| ...    |          |      |    |    |          |
| FB     | 20130102 | 100  | 3  | 4  |  3.5     |

我在这里做错了什么?

此外,我也希望所有符号同时结束。例如,最大时间可以是100 - 它不能无限增加。

更新:

如果时间1没有记录,我想先忽略它,并在后面的代码中做一些事情:

  set &RAWDATA; by Symbol;
    if not missing(Symbol);
    /* retain the price from last second */
    retain MIDPRICE CUM_RETURN; 
    LAG_MIDPRICE = lag(MIDPRICE);
    LAG_CUMRETURN = lag(CUM_RETURN);
    /* Make sure we are calculating the same ticker*/
    return_sec = (MIDPRICE - LAG_MIDPRICE) / LAG_MIDPRICE;
    if first.symbol then 
    do;
      CUM_RETURN = 0;
      return_sec = 0;
    end;
    CUM_RETURN  = sum(CUM_RETURN, return_sec);
    RMIN = 0.01/MIDPRICE;
    drop LAG_MIDPRICE LAG_CUMRETURN BB BO MIDPRICE CUM_RETURN RMIN;
  run;

如您所见,我稍后会计算符号的回报。因此,如果没有时间1,而不是将BB,BO或MIDPRICE设置为0,我想将时间1的return_sec设置为0,直到出现第一条记录。

1 个答案:

答案 0 :(得分:2)

使用SAS / ETS中的PROC EXPAND。这允许您扩展系列。 METHOD=STEP选项将带有最后一个非缺失值。

我修改了FB的示例数据,以测试不以100结尾的变量。

data have;
infile datalines delimiter="|";
informat symbol $6.
         date anydtdte.;
format date date9.;
input Symbol $ Date time bid offer mid;
datalines;
AAPL   | 20130102 | 2    | 2  | 3  | 2.5      
AAPL   | 20130102 | 3    | 1  | 3  | 1.5      
AAPL   | 20130102 | 100  | 3  | 4  |  3.5     
FB     | 20130102 | 1    | 3  | 6  | 4.5      
FB     | 20130102 | 3    | 3  | 5  | 4        
FB     | 20130102 | 90  | 3  | 4  |  3.5     
;

此数据步骤将最后一个值的值添加到100。

data have;
set have;
by symbol date;

if last.date then do;
    if time ^= 100 then do;
        do time=time to 100;
            output;
        end;
    end;
    else 
        output;
end;
else
    output;
run;

PROC EXPAND填补了空白。

proc expand data=have out=want to=day method=step;
by symbol date;
id time;
convert bid;
convert offer;
convert mid;
run;

PROC EXPAND尝试提供帮助并将时间设置为日期。只需更改格式即可。

proc datasets lib=work nolist;
modify want;
format time best.;
run;
quit;