Discretionary Accruals
Posted: 22 August 2015 11:09 AM   [ Ignore ]
Newbie
Rank
Total Posts:  12
Joined  2015-08-04

Hi, I am in the process of replicating a paper that calculates discretionary accruals. I have found code for these calculations; however, my descriptive statistics are off from the paper that I am replicating. I have found other discretionary accrual codes from wrds and a few other creditable websites, but I am still getting the same results. I have winsoried the 1st and 99th %iles; however, should I be doing any other processes to the data before calculating the discretionary accruals such as proc standard. Any ideas? Thanks.
-jc

Profile
 
 
Posted: 22 August 2015 01:35 PM   [ Ignore ]   [ # 1 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  901
Joined  2011-09-19

hi Jc,

Sounds like useful code in general—feel free to paste your code here, and I’ll take a look.

Best,

Joost

 Signature 

To reply/post new questions: Please use the group WRDS/SAS on Google Groups! http://groups.google.com/d/forum/wrdssas

Profile
 
 
Posted: 22 August 2015 02:18 PM   [ Ignore ]   [ # 2 ]
Newbie
Rank
Total Posts:  12
Joined  2015-08-04

Would you like the log and the code or just the code? Thanks!
jc

Profile
 
 
Posted: 22 August 2015 02:32 PM   [ Ignore ]   [ # 3 ]
Newbie
Rank
Total Posts:  12
Joined  2015-08-04

Below is the code for the data gathering portion….....

data comp0;
set school.comp818;
  if mcap =. then mcap=mkvalt;
  cyear=year(datadate);
  cnum=substr(cusip,1,6);
if ib =. then ib=ibc;
if xidoc=. then xidoc=0;
if AT=. then delete;
if at=0 then delete;
  ROA= IB/AT;
if xad=. then xad=0;
if xrd=. then xrd=0;
if sale=0 or sale=. then delete;
  if mcap gt 0 then size = log (mcap);
if mcap le 0 then size = 0;
if dltt=. then dltt=0;
lev=dltt/at;
SIC2 = int(sich/100);
 
run;

*just to confirm there are no duplicated firm-year obs.*;
proc sort data=comp0 out=comp1 nodupkeys;
  by fyear gvkey;
run;

***create additional measure of mcap*****;
data comp1;
set comp1;
  if txdb=. then txdb=0;
  if dcvt=. then dcvt=0;
  if che=.  then che=0;
  if pstkl=. then pstkl=0;
  Book= AT-LT-pstkl+txdb+dcvt;
  m2b= (AT-book+mcap)/AT;
  if m2b=. then m2b= mcap/ceq;
run;

***********get the lag variables for regression****;

  proc sort data=comp1;
  by gvkey fyear;
  run;

  data comp1a;
  set comp1;
  lgvkey   = lag (GVKEY);
  lfyear   = lag (fyear);
  lat = lag (AT);
  lsale   = lag (sale);
  lrect   = lag (rect);
  linvt   = lag (invt);
  lag_roa = lag (roa);

if GVKEY ne lgvkey OR FYEAR ne (lfyear+1) then do;
  lat   = .;
  lsale   = .;
  lrect   = .;
  linvt   = .;
ldrev = .;
  lag_roa = .;
end;
run;


data comp1a;
set comp1a;
  TA     = (ibc-oancf+xidoc)/lat; 
  rcpatl   = 1/lat;
  rev   = sale/lat;
drev   = (sale-lsale)/lat;
drevadj   = (sale-lsale-rect+lrect)/lat;
  ppe   = ppegt/lat;
IBL   = IB/lat;
CFO   = (OANCF-XIDOC)/lat;
  COGSa   = COGS/lat;
dinv   = (invt-linvt)/lat;
  PROD   = sum(cogsa, dinv);
  discexp   = (sum (xsga,XAD,xrd))/lat;
lrev     = lsale/lat;
run;

proc sort data=comp1a;
  by gvkey fyear;
  run;

data comp1a;
set comp1a;
ldrev   = lag (drev);
prioribl = lag (IBL);
if GVKEY ne lgvkey OR FYEAR ne (lfyear+1) then do;
  ldrev   = .;
  prioribl   = .;
end;
run;

****delete observations with missing data*****;

data compcomplete;  *comp with full observations**;
set comp1a;
if TA=. then delete;
if rcpatl=. then delete;
if rev=. then delete;
if lrev=. then delete;
if drev=. then delete;
if drevadj=. then delete;
if ppe=. then delete;
if ibl=. then delete;
if cfo=. then delete;
if cogsa=. then delete;
if ldrev=. then delete;
if prioribl=. then delete;
run;

**merge kld and compustat****

****merge compustat and kld with cnum****;
proc sort data=perm.fkld9109edited out=test;
by cyear cnum;
run;

proc sort data=compcomplete out=comp1asortcnum;
by cyear cnum;
run;

data mergercnum;
merge test (in=a) comp1asortcnum (in=b);
by cyear cnum;
if a and b;
run;

***merge compustat and kld with tic****;
proc sort data=perm.fkld9109edited out=test1;
by cyear tic;
run;

proc sort data=compcomplete out=comp1asortcnum2;
by cyear tic;
run;

data mergertic;
merge test1 (in=a) comp1asortcnum2 (in=b);
by cyear tic;
if a and b;
run;

****append and delete duplicates***;

data all;
set mergercnum mergertic;
run;

proc sort data=all out=zfinal nodupkeys;
by cyear gvkey;
run;


***merging with crsp***;

data crsp1;
set school.stocknames (keep = cusip permco st_date);
cnum = substr(cusip,1,6);
run;

proc sort data=crsp1 nodupkey;
by cnum;
run;

proc sort data=zfinal out=zfinal1;
by cnum;
run;

data appendcrsp;
merge zfinal1 (in=a) crsp1(in=b);
by cnum;
if a and b;
run;

*calculate firm age based on begin price in crsp and datadate from comp*;

data age;
set appendcrsp;
start=year(st_date);
firmageyears = cyear-start;
if firmageyears ge 0 then
firmagelog   = log (1+firmageyears);
if firmagelog =. then firmagelog=0;
if firmageyears =. then firmageyears=0;
run;

**WINSORIZE***;
proc sort data=age;
by fyear sic2;
run;

***winsor***;

%winsor(dsetin=age, dsetout=winsor, byvar=none,
vars= TA CFO PROD discexp rcpatl rev lrev drev ldrev drevadj ppe CSR_Score
  Size M2B lag_roa xrd prioribl xad sale Big Lev cgov_score
    firmagelog firmageyears, type=winsor, pctl=1 99);

 

Profile
 
 
Posted: 22 August 2015 02:35 PM   [ Ignore ]   [ # 4 ]
Newbie
Rank
Total Posts:  12
Joined  2015-08-04

Here is the regression and residual gathering code….. the majority of the code came from this website..
http://www.bhwang.com/a_research/z_codes/Discretionary Accruals (Code).txt

*****ABS*****;
proc sort data=winsor out=compu; by fyear; run;

data compu; set compu;
if sic2=32 and fyear=1996 then delete;
run;

data compu; set compu;
if sic2=14 and fyear=2001 then delete;
run;

%let dep=TA;
%let ind=sic2;
proc sort data=compu nodupkey out=compu1; by gvkey fyear;
 
proc sort data=compu1; by fyear &ind;
proc univariate data=compu1 noprint;
var &dep;         
by fyear &ind;
output out=count n=obs_int;
proc reg data=compu1 noprint outest=parms;
model &dep; = rcpatl drev ppe;     
by fyear &ind;
data parms; merge parms count; by fyear &ind;
if obs_int >= 8;
alpha = rcpatl;
beta = drev;
gamma = ppe;
keep &ind; fyear intercept alpha beta gamma obs_int;
proc datasets; delete count; run; quit;
data compu1; merge compu1 parms (in=m1); by fyear &ind;
if m1;
fitted = intercept+(alpha*rcpatl)+(beta*drev)+(gamma*ppe);
AAC_int = &dep;-fitted;     
abs_AAC_int = abs(AAC_int);
*keep gvkey fyear &ind; aac_int abs_AAC_int obs_int ROA lag_ROA;
proc datasets; delete parms; run; quit;

proc sort data=compu nodupkey out=compu2; by gvkey fyear;
   
proc sort data=compu2; by fyear &ind;
proc univariate data=compu2 noprint;
var &dep;         
by fyear &ind;
output out=count n=obs_noint;
proc reg data=compu2 noprint outest=parms;
model &dep; = rcpatl drevadj ppe lag_roa / noint;     
by fyear &ind;
data parms; merge parms count; by fyear &ind;
if obs_noint >= 8;
alpha = rcpatl;
beta = drevadj;
gamma = ppe;
theta   =  lag_roa;
keep &ind; fyear alpha beta gamma theta obs_noint;
proc datasets; delete count; run; quit;
data compu2; merge compu2 parms (in=m1); by fyear &ind;
if m1;
fitted   = (alpha*rcpatl)+(beta*drevadj)+(gamma*ppe)+ (theta*lag_roa);
AAC_noint   = &dep;-fitted;     
abs_AAC_noint   = abs(AAC_noint);
proc datasets; delete parms; run; quit;

proc sort data=compu1; by gvkey fyear;
proc sort data=compu2; by gvkey fyear;

data perm.AAC; merge compu1 compu2; by gvkey fyear;
run;

*CFO*;
%let dep=CFO;
proc sort data=compu nodupkey out=compu1; by gvkey fyear;
proc sort data=compu1; by fyear sic2;
proc univariate data=compu1 noprint;
var &dep;         
by fyear sic2;
output out=count n=obs_int;
proc reg data=compu1 noprint outest=parms;
model &dep; = rcpATl REV dREV;     
by fyear sic2;
data parms; merge parms count; by fyear sic2;
if obs_int >= 8;
alpha = rcpATl;
beta = REV;
gamma = drev;
keep sic2 fyear alpha beta gamma;
proc datasets; delete count; run; quit;
data compu1; merge compu1 parms (in=m1); by fyear sic2;
if m1;
fitted = (alpha*rcpatl)+(beta*rev)+(gamma*drev);
ACFO_int = &dep;-fitted;     
abs_ACFO_int = abs(ACFO_int);
keep gvkey fyear sic2 ACFO_int abs_ACFO_int;
proc datasets; delete parms; run; quit;
proc sort data=compu1; by gvkey fyear;
data perm.ACFO; set compu1;
run;

****************************************************************;
* GOAL: GET PROD. COSTS MANAGEMENT     ;
****************************************************************;
proc sort data=compu out=compu; by fyear;

%let dep=prod;
proc sort data=compu nodupkey out=compu1; by gvkey fyear;
proc sort data=compu1; by fyear sic2;
proc univariate data=compu1 noprint;
var &dep;         
by fyear sic2;
output out=count n=obs_int;
proc reg data=compu1 noprint outest=parms;
model &dep; =rcpATl REV dREV ldrev ;     
by fyear sic2;
data parms; merge parms count; by fyear sic2;
if obs_int >= 8;
alpha = rcpatl;
beta = rev;
gamma = drev;
theta = ldrev;
keep sic2 fyear alpha beta gamma theta;
proc datasets; delete count; run; quit;
data compu1; merge compu1 parms (in=m1); by fyear sic2;
if m1;
fitted = (alpha*rcpatl)+(beta*rev)+(gamma*drev)+(theta*ldrev);
APRO_int = &dep;-fitted;     
abs_APRO_int= abs(APRO_int);
keep gvkey fyear sic2 APRO_int abs_APRO_int;
proc datasets; delete parms; run; quit;
proc sort data=compu1; by gvkey fyear;
data perm.APRO; set compu1;
run;

****************************************************************;
* GOAL: GET DISCR. EXPENSES MANAGEMENT     ;
****************************************************************;
proc sort data=compu out=compu; by fyear;

%let dep=discexp;
proc sort data=compu nodupkey out=compu1; by gvkey fyear;

proc sort data=compu1; by fyear sic2;
proc univariate data=compu1 noprint;
var &dep;         
by fyear sic2;
output out=count n=obs_int;
proc reg data=compu1 (where=(nmiss(ldrev)=0)) noprint outest=parms;
model &dep; = rcpATl lrev / stb;     
by fyear sic2;
data parms; merge parms count; by fyear sic2;
if obs_int >= 8;
alpha = rcpATl;
beta = lrev;
keep sic2 fyear alpha beta;
proc datasets; delete count; run; quit;
data compu1; merge compu1 parms (in=m1); by fyear sic2;
if m1;
fitted = (alpha*rcpATl)+(beta*lrev);
AEXP_int = &dep;-fitted;     
abs_AEXP_int= abs(AEXP_int);
keep gvkey fyear sic2 AEXP_int abs_AEXP_int;
proc datasets; delete parms; run; quit;
proc sort data=compu1; by gvkey fyear;
data perm.AEXP; set compu1;
run;

****re-merge all data sets****;

proc sort data=perm.acfo out=acfos;
by gvkey fyear;
run;

proc sort data=perm.apro out=apros;
by gvkey fyear;
run;

proc sort data=perm.aexp out=aexps;
by gvkey fyear;
run;

proc sort data=perm.aac out=aaacs;
by gvkey fyear;
run;

data merger;
merge acfos (in=a) apros (in=b);
by gvkey fyear;
if a and b;
run;

data merger;
merge merger (in=a) aexps (in=b);
by gvkey fyear;
if a and b;
rename ACFO_int =r_cfo;
rename Apro_int =r_prod;
rename Aexp_int =r_disx;
run;

data merger;
merge merger (in=a) aaacs (in=b);
by gvkey fyear;
if a and b;
rename aac_noint =daadj;
run;

proc sort data=merger out=comp3winsor nodupkeys;
by gvkey fyear;
run;

data comp3winsor1;
set comp3winsor;
  Combined_RAM = r_cfo- r_prod+r_disx;
  if combined_RAM=. then delete;
abs_DAA= abs(daadj);
run;

Profile
 
 
Posted: 22 August 2015 05:26 PM   [ Ignore ]   [ # 5 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  901
Joined  2011-09-19

ok, that is a lot of code smile

What are the values that are different? Are those the winsorized variables (first block of code), or the regression output, or both? And what is the benchmark? (What paper are you comparing against?)

Best,

Joost

 Signature 

To reply/post new questions: Please use the group WRDS/SAS on Google Groups! http://groups.google.com/d/forum/wrdssas

Profile
 
 
Posted: 22 August 2015 06:15 PM   [ Ignore ]   [ # 6 ]
Newbie
Rank
Total Posts:  12
Joined  2015-08-04

Hi, you are right! It is a lot of code! Here is a breakdown of the output that I receive:


Variable         N           Mean       Median
ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ
abs_DAA       17604       0.050       0.032
daadj         17604       -0.009       -0.004
Positive_DAA   8127         0.044       0.030
Negative_DA   9477       -0.055       -0.034
r_cfo           17604       0.054       0.056
r_prod         17604       -0.124       -0.108
r_disx         17604       0.127       0.086
Combined_RAM 17604       0.305       0.245
CSR_Score     17604       -0.100       0.000

Kim et. al 2012 results:

Variable         N           Mean       Median
ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ
abs_DAA       18160       0.2         .103
daadj         18160         .005       .019
Positive_DAA   8127         .178       .111
Negative_DA   9477         -.231       -.093
r_cfo           18160         .129       .080
r_prod         18160       -.096       -.063
r_disx         18160       -.059       -.062
Combined_RAM 18160       .238       .072
CSR_Score     18160       -.05       0.000


*****Are those the winsorized variables (first block of code), or the regression output, or both?
Yes, the paper states that they winsorize the continuous variables which is what I am doing in the first block of code and then winsorizing the regression output as well. I didn’t realize that part was cut off from the code, but in my sas program i winsor the residuals from the regression.

The paper I am replicating is Kim et al. 2012, “Is earnings management associated with CSR?” 

Thanks,
jc

Profile
 
 
Posted: 29 August 2015 09:10 AM   [ Ignore ]   [ # 7 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  901
Joined  2011-09-19

hi jc,

I have replicated the accruals part without matching with KLD. It needs more ‘debugging’, but I don’t have time to look in more detail. In any case my numbers are close to yours.

I am assuming you have comp.funda, comp.company, etc. available locally. I am also using Clay’s Array macros (see http://www.sascommunity.org/wiki/Tight_Looping_with_Macro_Arrays )
zipfile: http://www.sascommunity.org/mwiki/images/e/ec/Clay-TightLooping-macros.zip

Note: the forum software has added a semicolon to all macro variables—these need to be removed - ie, the last character (semicolon) here: &fundaVars;

Main code—%getFunda macro in next post

%let fundaVars mkvalt datadate cusip sich ceq ib xidoc at ib ibc xad xrd sale dltt lt txdb dcvt che pstkl cogs xsga OANCF ppegt rect invt;
%
getFunda(dsout=da.a_fundavars=&fundaVars;, laggedvars=, year1=1996year2=2013);

/* variables where missing values need to be zero */
%let replWithZero xidoc xad xrd dltt txdb dcvt che pstkl;

data da.a_funda;
set da.a_funda;
/* keep if sale > 0, at > 0 */
if sale and at 0;
/* for xidoc, xad, etc, set missings to 0 */
%do_over(values=&replWithZero;, phrase= if ? eq then ? = 0;);
/* create variables */
mcap mkvalt;
cyear=year(datadate);
cnum=substr(cusip,1,6);
lev=dltt/at;
SIC2 int(sich/100);
if 
ib =. then ib=ibc;
roa ibat;
if 
mcap gt 0 then size log (mcap);
if 
mcap le 0 then size 0;
BookAT-LT-pstkl+txdb+dcvt;
m2b= (AT-book+mcap)/AT;
if 
m2b=. then m2bmcap/ceq;
run;

/*just to confirm there are no duplicated firm-year obs.*/
proc sort data=da.a_funda  nodupkeysby fyear gvkeyrun;

/* lagged values for: at sale rect invt roa */
%let lagVars at sale rect invt roa;

/* self join to get lagged values at_l, sale_l, rect_l, etc*/
proc sql;
 
create table da.b_funda as select a.*, %do_over(values=&lagVars;, between=commaphrase=b.? as ?_l)
 
from da.a_funda ada.a_funda b
 where a
.gvkey b.gvkey and a.fyear-b.fyear;
quit;

/* construct more variables */
data da.b_funda;
set da.b_funda;
TA      = (ibc-oancf+xidoc)/at_l;  
rcpat_l  1/at_l;
rev     sale/at_l;
drev    = (sale-sale_l)/at_l;
drevadj = (sale-sale_l-rect+rect_l)/at_l;
ppe     ppegt/at_l;
IBL     IB/at_l
CFO     = (OANCF-XIDOC)/at_l;
COGSa   COGS/at_l;
dinv    = (invt-invt_l)/at_l;
PROD    sum(cogsadinv);
discexp = (sum (xsga,XAD,xrd))/at_l;
rev_l    sale_l/at_l;
run;

/* lagged values for drev and ibl */
proc sql;
 
create table da.c_funda as select a.*, b.drev as drev_lb.ibl as ibl_l
 from da
.b_funda ada.b_funda b
 where a
.gvkey b.gvkey and a.fyear-b.fyear;
quit;

data da.c_funda;
set da.c_funda;
/* these variables may not be missing (cmiss counts missing variables)*/
if cmiss  (of ta rcpat_l rev rev_l drev drevadj ppe ibl cfo cogsa drev_l ibl_leq 0;
run;

/* winsorize -- is the varlist complete? */
%let winsVars TA CFO PROD discexp rcpat_l rev rev_l drev drev_l drevadj ppe Size M2B roa_l xrd ibl xad sale Lev 
%
winsor(dsetin=da.c_fundadsetout=da.c_funda_winsbyvar=nonevars=&winsVars;, type=winsorpctl=1 99);


/* accruals */

/* drop some industries */
data da.d_accruals;
set da.c_funda_wins;
if 
sic2=32 and fyear=1996 then delete;
if 
sic2=14 and fyear=2001 then delete;
run;

proc sort data=da.d_accrualsby fyear sic2;run;

/* regression by industry-year -- added edf for degrees of freemdom 
 edf + #params (4) will equal the number of obs (no need for proc univariate to count)
*/
proc reg data=da.d_accruals noprint edf outest=da.e_parms;
model ta rcpat_l drev ppe;      
by fyear sic2;
run;

/* another model (no intercept) */
proc reg data=da.d_accruals noprint edf outest=da.e_parms_noint;
model ta rcpat_l drev ppe  noint;      
by fyear sic2;
run;

/* append fitted value, error and abs error to dataset */
proc sql;
 
create table da.f_model1 as 
 
/* fitted value computed as sum of coefficients in b multiplied by values in a */
 
select a.*, b.intercept b.rcpat_l a.rcpat_l b.drev a.drev b.ppe a.ppe as fitted,
 
/* abnormal accruals are ta - fitted */
 
a.ta calculated fitted as AAC_int
 
/* absolute abnormal accruals */
 
abs (calculated AAC_int) as abs_AAC_int
 from da
.d_accruals a left join da.e_parms b
 on a
.sic2 b.sic2 and a.fyear b.fyear
 
/* only if more than 8 obs */
 
and b._EDF_ ;
quit;

/* append model with no intercept */
proc sql;
 
create table da.f_model2 as 
 
/* fitted value computed as sum of coefficients in b multiplied by values in a */
 
select a.*, /* b.intercept + */ b.rcpat_l a.rcpat_l b.drev a.drev b.ppe a.ppe as fitted_noint,
 
/* abnormal accruals are ta - fitted */
 
a.ta calculated fitted_noint as AAC_noint
 
/* absolute abnormal accruals */
 
abs (calculated AAC_noint) as abs_AAC_noint
 from da
.f_model1 a left join da.e_parms_noint b
 on a
.sic2 b.sic2 and a.fyear b.fyear
 
/* only if more than 8 obs (no intercept, so 1 more degree of freedom) */
 
and b._EDF_ ;
quit;

/* daadj is aac_noint, abs_DAA= abs(daadj); */
proc means data=da.f_model2 n mean median ;
var 
AAC_noint abs_AAC_noint ;
run

Output

Variable         N      Mean       Median
abs_AAC_noint   66539   0.0737     0.0435 
AAC_noint       66539   0.0140    
-0.0054 

Hope this helps,

Joost

 Signature 

To reply/post new questions: Please use the group WRDS/SAS on Google Groups! http://groups.google.com/d/forum/wrdssas

Profile
 
 
Posted: 29 August 2015 09:12 AM   [ Ignore ]   [ # 8 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  901
Joined  2011-09-19

continued

macro used (to get Funda data, and some extra vars):

Note: the forum software has added a semicolon to all macro variables—these need to be removed - ie, the last character (semicolon) here: &laggedVars;

/* 
 Use this macro to create a 'starting' dataset based on Funda
 1. retrieves compustat Funda variables gvkey, fyear, datadate and &vars; from year1 to year2
 2. gets &laggedvars; for the previous years (typically lagged assets, sales, marketcap) (need to be in &vars;)
 3. creates key (gvkey || fyear) and appends some common firm identifiers (permno, cusip, ibes_ticker)
 Add 1 more year if lagged data is needed (a self join is used to get lagged data)
 invoke as:
 %getFunda(dsout=a_funda1, vars=at sale ceq csho prcc_f, laggedvars=at, year1=1990, year2=2013);
 dependencies: uses Clay macros (%do_over)
*/

%macro getFunda(dsout=, vars=, laggedvars=, year1=2010year2=2013);

/* Funda data */
data getf_1 (keep key gvkey fyear datadate &vars;);
set comp.funda;
if &
year1; <= fyear <= &year2;
if 
indfmt='INDL' and datafmt='STD' and popsrc='D' and consol='C' ;
key gvkey || fyear;
run;

/*  Keep first record in case of multiple records; */
proc sort data =getf_1 nodupkeyby gvkey fyear;run;

/* Add lagged assets */
%if "&laggedvars;" ne "" %then %do;
 
/* add lagged vars */
 
proc sql;
  
create table getf_2 as
  
select a.*, %do_over(values=&laggedvars;, between=commaphrase=b.? as ?_lag
  
from  getf_1 a left join  getf_1 b
  on a
.gvkey b.gvkey and a.fyear -b.fyear;
 
quit;
%
end;
%else %do;
 
/* do not add lagged vars */
 
data getf_2set getf_1run;
%
end;

/* Permno as of datadate*/
proc sql
  
create table getf_3 as 
  
select a.*, b.lpermno as permno
  from getf_2 a left join crsp
.ccmxpf_linktable b 
    on a
.gvkey eq b.gvkey 
    
and b.lpermno ne 
    and 
b.linktype in ("LC" "LN" "LU" "LX" "LD" "LS"
    and 
b.linkprim IN ("C""P")  
    and ((
a.datadate >= b.LINKDT) or b.LINKDT eq .B) and  
       ((
a.datadate <= b.LINKENDDT) or b.LINKENDDT eq .E)   ; 
quit

/* retrieve historic cusip */
proc sql;
  
create table getf_4 as
  
select a.*, b.ncusip
  from getf_3 a
crsp.dsenames b
  where 
        a
.permno b.PERMNO
    
and b.namedt <= a.datadate <= b.nameendt
    
and b.ncusip ne "";
  
quit;
 
/* force unique records */
proc sort data=getf_4 nodupkeyby key;run;
 
/* get ibes ticker */
proc sql;
  
create table &dsout; as
  
select distinct a.*, b.ticker as ibes_ticker
  from getf_4 a left join ibes
.idsum b
  on 
        a
.NCUSIP b.CUSIP
    
and a.datadate b.SDATES ;
quit;

/* force unique records */
proc sort data=&dsoutnodupkeyby key;run;

/*cleanup */
proc datasets library=workdelete getf_1 getf_4quit;
%
mend
 Signature 

To reply/post new questions: Please use the group WRDS/SAS on Google Groups! http://groups.google.com/d/forum/wrdssas

Profile
 
 
Posted: 31 August 2015 08:42 PM   [ Ignore ]   [ # 9 ]
Newbie
Rank
Total Posts:  12
Joined  2015-08-04

Hi, I was not expecting you to do that! Thanks so much for doing all that coding and work.  This is my first time at replication and it is reassuring to see that you get similar results to me. Thanks again for your help! This forum has been very useful!
-jc

Profile
 
 
Posted: 01 September 2015 07:04 AM   [ Ignore ]   [ # 10 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  901
Joined  2011-09-19

hi Jc,

You’re welcome—this code is probably useful in general, so it made sense to spend time on it.

It is quite possible I made mistakes here (for example, errors in constructing the variables). If that is the case, hopefully - over time - others can point these mistakes out. There is similar code (Jones model, accruals are calculated through balance sheet items) in a macro here: http://www.wrds.us/index.php/repository/view/7

Best,

Joost

 Signature 

To reply/post new questions: Please use the group WRDS/SAS on Google Groups! http://groups.google.com/d/forum/wrdssas

Profile
 
 
Posted: 19 November 2015 06:54 PM   [ Ignore ]   [ # 11 ]
Newbie
Rank
Total Posts:  6
Joined  2015-11-19

Hi Joost ,

I have a quick question regarding to Adam Yore’s code that estimates abnormal accruals
http://www.wrds.us/index.php/repository/view/7

Do you know what is he referring to in a proc sql as “company.company”?


Joost Impink - 01 September 2015 07:04 AM

hi Jc,

You’re welcome—this code is probably useful in general, so it made sense to spend time on it.

It is quite possible I made mistakes here (for example, errors in constructing the variables). If that is the case, hopefully - over time - others can point these mistakes out. There is similar code (Jones model, accruals are calculated through balance sheet items) in a macro here: http://www.wrds.us/index.php/repository/view/7

Best,

Joost

Profile
 
 
Posted: 20 November 2015 11:26 AM   [ Ignore ]   [ # 12 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  901
Joined  2011-09-19

hi nsjb,

Yes, that is my doing; it should be comp.company. I updated it.

Best,

Joost

 Signature 

To reply/post new questions: Please use the group WRDS/SAS on Google Groups! http://groups.google.com/d/forum/wrdssas

Profile
 
 
Posted: 20 November 2015 08:47 PM   [ Ignore ]   [ # 13 ]
Newbie
Rank
Total Posts:  6
Joined  2015-11-19

Thanks for the clarification Joost!

Profile