Distance to default code
Posted: 19 April 2016 11:22 PM   [ Ignore ]
Total Posts:  6
Joined  2015-11-19

Hi guys,

I am trying to create distance to default following Bharath and Shumway (2008). Specifically, I am using the sas code provided by Shumway on his website:

I prepared the two datasets needed to run the macro with all the variables, but the code still always gives me 0 observation.

Has anyone tried their code before? Could you please let me know where I made a mistake?


Posted: 19 April 2016 11:24 PM   [ Ignore ]   [ # 1 ]
Total Posts:  6
Joined  2015-11-19

%let wrds=wrds.wharton.upenn.edu 4016;
options comamid=TCP remote=WRDS;
signon user=‘xxx’ password=_prompt_;

data compustat;
set comp.fundq;
if indfmt=‘INDL’;if consol=‘C’;
if datafmt=‘STD’;if popsrc=‘D’;
keep gvkeyn fyearq fyr datadate dlcq dlttq atq saleq;

proc sort data=compustat nodupkey; by gvkeyn fyearq; run;

data cnames; 
set crsp.msenames;
if shrcd in (10,11);
if siccd ne 0;
if siccd ne .;

data link; set crsp.CCMXPF_LINKTABLE; run;

data link1;
set link;
if usedflag=1;
if gvkeyn ne .;
if permno ne .;
if linktype in (“LU”, “LC”, “LD”, “LF”, “LN”, “LO”, “LS”, “LX”);
if linkenddt=.E then linkenddt = input (‘20150802’,  yymmdd8.);
if linkdt=.B then linkdt = input (‘19000101’,  yymmdd8.);
if linkprim in (“P”, “C”);

proc sort data=link1 nodupkey;
by gvkeyn permno linkdt linkenddt;

proc sort data=cnames nodupkey;
by permno namedt nameendt;

proc sql;
create table compustat1 as select a.*, b.permno
from compustat as a, link1 as b
where a.gvkeyn=b.gvkeyn and b.linkdt<=a.datadate<=b.linkenddt;

proc sql;
create table compustat1 as select a.*, b.siccd
from compustat1 as a, cnames as b
where a.permno=b.permno and b.namedt<=a.datadate<=b.nameendt;

data treasury; set frb.rates_monthly;

data riskfree;
set Treasury;
  rf= TB_M3/100;

proc sql;
create table compustat2 as select a.*, b.rf
from compustat1 as a, riskfree as b
where a.fyearq=year(b.date) and a.fyr=month(b.date);

data temp;
set compustat2;
keep permno;

proc sort data=temp nodupkey; by permno; run;

proc sql;
create table crsp as select a.permno, b.ret, b.date, b.prc, b.shrout
from temp as a, crsp.dsf as b
where a.permno=b.permno;

data crsp1;
set crsp;
if year(date)>1960;

data comp;
set compustat2;
if 1980<=year(datadate)<=2003;
if permno in (54594,10074,50906,10082,10154);
*if permno in (54594);

data dailycrsp;
set crsp1;
if permno in (54594,10074,50906,10082,10154);

proc download data = dailycrsp;
proc download data = comp;

data sampl;  set comp;
  cdt = 100*calyr + calmnth;
  f = 1000*(data45 + 0.5 * data51);
  if data45 < 0 or data51 < 0 then delete;
  drop data45 data51 calyr calmnth;

proc sort;  by permno cdt;

data kmv99; curdat = 0;

%macro itera(yyy,mmm);
  data one;
  set dailycrsp;
  if (100*(&yyy;-1) + &mmm;) <= (100*year(date) + month(date)) <= (100*&yyy; + &mmm;);
  e = abs(prc)*shrout;
  cdt = 100*year(date) + month(date);
  keep permno date cdt e;

  proc sort;  by permno cdt;

  data one;
  merge one sampl;
  by permno cdt;
if e ne . and f > 0;
  a = e + f;
  if a = . or permno = . or e = 0 then delete;

  proc sort;  by permno date;

* get volatility of total asset returns and look for large values;

  data one;  set one;  l1p = lag1(permno);  l1a = lag1(a);
  data one;  set one;  if l1p = permno then ra = log(a/l1a);
  proc means noprint data = one;  var ra f e;  by permno;  output out = bob;
  data bob1;  set bob;  if _stat_ = ‘STD’; if _freq_ < 50 then delete;
      va = sqrt(252)*RA;  if va < .01 then va = .01;  keep permno va;
  data bob2; set bob; if _stat_ = ‘MEAN’; if f > 100000 and e > 100000 then largev = 1;
      else largev = 0; keep largev permno;
  data one;  merge one bob1 bob2;  by permno;    if va = . then delete;
  if largev = 1 then do; f = f/10000; e = e/10000; a = a/10000; end;
  drop ra l1a l1p;

  data conv;  permno = 0;


%do j = 1 %to 15;
  proc model noprint data = one;  endogenous a;  exogenous r f VA e;
  e = a*probnorm((log(a/f) + (r+va*va/2))/VA) -
  f*exp(-r)*probnorm((log(a/f) + (r-va*va/2))/VA);  solve a/out=two;
  data two;  set two;  num = _n_;  keep a num;
  data one;  set one;  num = _n_;  drop a; 
  data two;  merge one two;  by num;  l1p = lag1(permno);  l1a = lag1(a);
  data two;  set two; if l1p = permno then ra = log(a/l1a);
  proc means noprint data = two;  var ra;  by permno;  output out = bob;
  data bar;  set bob; if _stat_ = ‘MEAN’;  mu = 252*ra;  keep permno mu;
  data bob;  set bob; if _stat_ = ‘STD’; va1 = sqrt(252)*RA;
          if va1 < 0.01 then va1 = 0.01; keep permno va1;
  data one;  merge two bob bar; by permno; vdif = va1 - va;
          if abs(vdif) < 0.001 and vdif ne . then conv = 1;
  data fin;  set one; if conv = 1;  assetvol = va1; proc sort; by permno descending date; 
  data fin;  set fin; if permno ne lag1(permno);  curdat = 100*&yyy; + &mmm;  iter = &j;
  data conv;  merge conv fin;  by permno;  drop va ra l1p l1a conv cdt num;
  data one;  set one; if conv ne 1;  va = va1;  drop va1;

  data kmv;
  merge kmv conv;
  by curdat;
if permno = 0 or curdat = 0 then delete;  drop va1;
edf = probnorm(-((log(a/f) + (mu-(assetvol**2)/2))/assetvol));
label edf = ‘expected default frequency’;
label curdat = ‘date in yyyymm format’;
label e = ‘market equity’;
label iter = ‘iterations required’;
label assetvol = ‘volatility of a’;
label f = ‘current debt + 0.5LTD’;
label vdif = ‘assetvol - penultimate VA’;
label a = ‘total firm value’;
label r = ‘risk-free rate’;
  label largev = ‘one if assets, equity and f deflated’;
  label mu = ‘expected asset return’;

%macro bob;
%do i = 1980 %to 2003;
  %do m = 1 %to 12;



Posted: 20 April 2016 10:37 AM   [ Ignore ]   [ # 2 ]
Total Posts:  901
Joined  2011-09-19


I have forwarded your question to the Google Group (I will post any replies here).

Best Regards,



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