proc printto log = "/scratch/bocconi/amanconi/kim_skinner.log"; run;

libname t "/scratch/bocconi/amanconi";

/* 
	The file crsp_with_gvkey contains links between Compustat's GVKEY
	identifiers and CRSP's PERMNO identifiers. It has been downloaded 
	from the CRSP/Compustat merged database in January 2021. 
	Each row of this file corresponds to a unique GVKEY-PERMNO-datadate.
*/
data link;
set t.crsp_with_gvkey;
keep gvkey lpermno datadate;
run;

data link;
set link;
if gvkey ^= "";
rename lpermno = permno;
rename datadate = date;
run;

proc sort data=link nodupkey; by permno date; run;

/* 
	The file ncusip_link contains links between CRSP's PERMNO
	identifiers and historical CUSIP codes, reported as the variable
	NCUSIP in CRSP monthly stocks in January 2021. Each row of this file 
	corresponds to a unique PERMNO-NCUSIP-calendar month.
*/
data codes;
set t.ncusip_link;
run;

data index;
set crsp.msi;
keep date ewretd;
if year(date) >= 1969;
run;

* Use CRSP monthly stocks from 1969 onwards, replacing returns with error codes by a missing value;
data crsp;
set crsp.msf;
keep permno date ret vol shrout;
if year(date) >= 1969;
if ret <= -1 then ret = .;
run;

* Winsorize returns;
proc sort data = crsp; by date; run;

proc univariate data = crsp noprint;
by date; 
var ret;
output out = outliers pctlpts = 1 99 pctlpre = r pctlname = _1 _99;
run;
quit;

proc sort data = crsp; by date; run;
proc sort data = outliers; by date; run;

data crsp;
merge crsp outliers;
by date;

if ret < r_1 and ret ^= . then ret = r_1;
if ret > r_99 and ret ^= . then ret = r_99;

trvol = vol/(10*shrout);

run;

proc datasets library=work noprint; delete outliers; run; quit;

proc sort data=crsp; by date; run;
proc sort data=index; by date; run;

data crsp;
merge crsp index; 
by date; 
aret = ret - ewretd;
run;

proc sort data=crsp; by permno date; run;
proc sort data=codes; by permno date; run;

* Focus on common stocks (share codes 10 and 11);
data crsp;
merge crsp codes;
by permno date; 
if shrcd = 10 or shrcd = 11;
run;

* Cleanup;
proc datasets library = work noprint; delete codes index; run; quit;

proc sort data = crsp; by permno date; run;

* Macro to compute rolling statistics;
%macro rollstats;

%do y = 1970 %to 2020;

	%do m = 1 %to 12;

		data crsp_sub;
		set crsp;
		if 1 <= intck("MONTH",date,mdy(&m,15,&y)) <= 12;
		run;

		proc sort data=crsp_sub; by permno; run;

		proc univariate data = crsp_sub noprint;
		by permno;
		var ret;
		output out = retstat std = return_std_dev1 skewness = return_skewness1;
		run;
		quit;
		
		proc univariate data = crsp_sub noprint;
		by permno;
		var ret;
		output out = arstat mean=return1;
		run;
		quit;

		proc univariate data = crsp_sub noprint;
		by permno;
		var trvol;
		output out = volstat mean=turnover1; 
		run;
		quit;

		proc sort data=arstat; by permno; run;
		proc sort data=retstat; by permno; run;
		proc sort data=volstat; by permno; run;

		data retstat;
		merge arstat retstat volstat;
		by permno;
		year = &y;
		month = &m;
		run;

		proc sql;
			
			create table retstat as
				select r.*, l.gvkey 
				from retstat as r
				left join link as l
				on r.permno = l.permno
				and r.year = year(l.date)
				and r.month = month(l.date);

		quit;

		%if &y = 1970 and &m = 1 %then %do;
			data t.kimskinner(label = "Kim and Skinner (2012) variables");
			set retstat;
			label 	return1 = "Moving-average market-adjusted return (12-month window)"
					return_std_dev1 = "Moving-stdev of returns (12-month window)"
					return_skewness1 = "Moving-skewness of returns (12-month window)"
					turnover1 = "Moving average share turnover (% of outstanding shares, 12-month window)";
			run;
		%end;
		%else %do;
			proc append base=t.kimskinner data=retstat; run;
		%end;

		proc datasets library=work noprint; delete crsp_sub arstat retstat volstat; run; quit;

	%end;

%end;

%mend;

%rollstats;

* Export to a Stata file;
proc export data = t.kimskinner outfile="/scratch/bocconi/amanconi/crsp_kim_skinner_v3.dta"; run; 

proc printto; run;
