内容发布更新时间 : 2024/11/9 4:58:05星期一 下面是文章的全部内容请认真阅读。
/*
*************************************************************************** */
/* ********* W R D S R E S E A R C H A P P L I C A T I O N S ************* */ /*
*************************************************************************** */
/* Program : fama_french_factors_replication.sas */
/* Authors : Luis Palacios (WRDS), PremalVora (Penn State) */ /* Date : 04/2009 */
/* Last modified : 08/2011 */
/* Description : Replicates Fama-French (1993) SMB & HML Factors */ /*
*************************************************************************** */
%letcomp=compq; %letcrsp=crspq; libnamemyh '~';
/************************ Part 1: Compustat ****************************/ /* CompustatXpressFeed Variables: */ /* AT = Total Assets */
/* PSTKL = Preferred Stock Liquidating Value */
/* TXDITC = Deferred Taxes and Investment Tax Credit */ /* PSTKRV = Preferred Stock Redemption Value */ /* CEQ = Common/Ordinary Equity - Total */
/* PSTK = Preferred/Preference Stock (Capital) - Total */
/* In calculating Book Equity, incorporate Preferred Stock (PS) values */ /* use the redemption value of PS, or the liquidation value */ /* or the par value (in that order) (FF,JFE, 1993, p. 8) */ /* USe Balance Sheet Deferred Taxes TXDITC if available */
/* Flag for number of years in Compustat (<2 likely backfilled data) */ %letvars = AT PSTKL TXDITC PSTKRV CEQ PSTK ; datacomp;
set&comp..funda
(keep= gvkeydatadate&varsindfmtdatafmtpopsrcconsol); bygvkeydatadate;
where indfmt='INDL'and datafmt='STD'and popsrc='D'and consol='C' and datadate>='01Jan1959'd;
/* Two years of accounting data before 1962 */ PS = coalesce(PSTKRV,PSTKL,PSTK,0); ifmissing(TXDITC) thenTXDITC = 0 ; BE = CEQ + TXDITC - PS ; ifBE<0 thenBE=.;
year= year(datadate);
labelBE='Book Value of Equity FYear t-1'; dropindfmtdatafmtpopsrcconsolps&vars; retaincount;
iffirst.gvkey thencount=1; elsecount = count+1; run;
/************************ Part 2: CRSP **********************************/ /* Create a CRSP Subsample with Monthly Stock and Event Variables */ /* This procedure creates a SAS dataset named \ /* Restrictions will be applied later */
/* Select variables from the CRSP monthly stock and event datasets */ %letmsevars=ticker ncusipshrcdexchcd;
%letmsfvars = prc ret retxshroutcfacprcfacshr;
%include'/wrds/crsp/samples/crspmerge.sas'; %crspmerge(s=m,start=01jan1959,end=30jun2011,
sfvars=&msfvars,sevars=&msevars,filters=exchcd in(1,2,3));
/* CRSP_M is sorted by date and permno and has historical returns */ /* as well as historical share codes and exchange codes */ /* Add CRSP delisting returns */ procsql; create table crspm2 as select a.*, b.dlret,
sum(1,ret)*sum(1,dlret)-1 as retadj \ abs(a.prc)*a.shrout as MEq 'Market Value of Equity'
fromCrsp_m a leftjoin &crsp..msedelist(where=(missing(dlret)=0)) b ona.permno=b.permno and
intnx('month',a.date,0,'E')=intnx('month',b.DLSTDT,0,'E') order bya.date, a.permco, MEq; quit;
/* There are cases when the same firm (permco) has two or more */ /* securities (permno) at same date. For the purpose of ME for */ /* the firm, we aggregated all ME for a given permco, date. This */ /* aggregated ME will be assigned to the Permno with the largest ME */ datacrspm2a (drop= Meq); setcrspm2; bydatepermcoMeq; retainME;
iffirst.permco and last.permco thendo; ME=meq;
output; /* most common case where a firm has a unique permno*/ end; elsedo;
iffirst.permco thenME=meq; elseME=sum(meq,ME);
iflast.permco thenoutput; end; run;
/* There should be no duplicates*/
procsort data=crspm2a nodupkey; bypermnodate;run; /* The next step does 2 things: */
/* - Create weights for later calculation of VW returns. */ /* Each firm's monthly return RET t willl be weighted by */ /* ME(t-1) = ME(t-2) * (1 + RETX (t-1)) */
/* where RETX is the without-dividend return. */
/* - Create a File with December t-1 Market Equity (ME) */
datacrspm3 (keep=permno dateretadjweight_port ME exchcdshrcdcumretx) decme (keep= permno dateME rename=(me=DEC_ME) ) ; setcrspm2a; bypermno date;
retainweight_portcumretxme_base; Lpermno=lag(permno); LME=lag(me);
iffirst.permno thendo;
LME=me/(1+retx); cumretx=sum(1,retx); me_base=LME;weight_port=.;end; elsedo;
ifmonth(date)=7 thendo; weight_port= LME;
me_base=LME; /* lag ME also at the end of June */ cumretx=sum(1,retx); end; elsedo;
ifLME>0 thenweight_port=cumretx*me_base;
elseweight_port=.;
cumretx=cumretx*sum(1,retx); end; end;
outputcrspm3;
ifmonth(date)=12 and ME>0 thenoutputdecme; run;
/* Create a file with data for each June with ME from previous December */ procsql;
create table crspjune as select a.*, b.DEC_ME
from crspm3 (where=(month(date)=6)) as a, decme as b where a.permno=b.permno and
intck('month',b.date,a.date)=6; quit;
/*************** Part 3: Merging CRSP and Compustat ***********/ /* Add Permno to Compustat sample */ procsql;
create table ccm1 as
select a.*, b.lpermno as permno, b.linkprim from comp as a, &crsp..ccmxpf_linktable as b where a.gvkey=b.gvkey
and substr(b.linktype,1,1)='L'and linkprim in('P','C')
and (intnx('month',intnx('year',a.datadate,0,'E'),6,'E') >= b.linkdt) and (b.linkenddt>= intnx('month',intnx('year',a.datadate,0,'E'),6,'E') or missing(b.linkenddt))
order bya.datadate, permno, b.linkprimdesc; quit;
/* Cleaning Compustat Data for no relevant duplicates */
/* Eliminating overlapping matching : few cases where different gvkeys */ /* for same permno-date --- some of them are not 'primary' matches in CCM */ /* Use linkprim='P' for selecting just one gvkey-permno-date combination */ dataccm1a; setccm1;
bydatadatepermno descending linkprim; iffirst.permno; run;
/* Sanity Check -- No Duplicates */
procsort data=ccm1a nodupkey; bypermno yeardatadate; run;
/* 2. However, there other type of duplicates within the year */
/* Some companiess change fiscal year end in the middle of the calendar year */
/* In these cases, there are more than one annual record for accounting data */
/* We will be selecting the last annual record in a given calendar year */ dataccm2a ; setccm1a; bypermno yeardatadate; iflast.year; run;
/* Sanity Check -- No Duplicates */
procsort data=ccm2a nodupkey; bypermnodatadate; run; /* Finalize Compustat Sample */
/* Merge CRSP with Compustat data, at June of every year */ /* Match fiscal year ending calendar year t-1 with June t */ procsql; create table ccm2_june as
select a.*, b.BE, (1000*b.BE)/a.DEC_ME as BEME, b.count, b.datadate,
intck('month',b.datadate, a.date) as dist from crspjune a, ccm2a b