/********************************************************************* */
/*  Program        : 0.Qfactorconstruction.sas                                          */
/*  Description    : Construct the Hou, Xue, and Zhang (2015) q-factors */
/*                   (q_me, q_IA, q_ROE), monthly and annualized.              */
/*                                                                                                          */
/*  Input : WRDS (quarterly and annual Compustat; signon required)      */
/*          data\ SAS datasets from 0.DataDownload.sas:                            */
/*          monthret_ff, factor, ccmxpf_linktable                                        */
/*  Output: output\ SAS datasets:                                                            */
/*          q_factor  (monthly q_me, q_IA, q_ROE)                                   */
/*          Q_factory (annualized q_mey, q_IAy, q_ROEy)                        */
/*                          (sometimes, y_me, y_IA, y_ROE)                            */
/*          portret, portret2 (18 portfolio returns; used later to                     */
/*          construct the base assets)                                                          */
/********************************************************************* */

/************************************************************************/
/*Three data sets: Monthly CRSP + Annual Compustat + Quarterly Compustat                  */
/*                 From January 1972 to December 2012  (OP)                                                */
/*                -Financial firms & Firms with negative book equity                                      */
/************************************************************************/

/************************************************************************/
/*1. Annual Compustat: AT                                                                                            */
/*2. Quarterly Compustat: IBQ, TXDITCQ, SEQQ, CEQQ, PSTKQ, ATQ, LTQ, RDQ      */
/*3. CRSP: Monthly return, Dividends, and Prices                                                            */
/************************************************************************/
%let projpath = D:\SAS\TFP\Dispersion_replication;
libname myq "&projpath.\output";
libname mydisp "&projpath.\data";
/*1. Download data */ 
/*1-1. Quarterly Compustat */ 
%let wrds=wrds.wharton.upenn.edu 4016;
options comamid=TCP remote=WRDS;
signon username=_prompt_;
rsubmit;
%let beg_date = '01JAN1965'd;
%let end_date = '31DEC2019'd;
libname compm '/wrds/comp/sasdata/nam';
proc sql;
     create table comp1(keep = fyearq fqtr fyr datadate gvkey datacqtr atq ibq seqq ceqq pstkq ltq rdq txditcq pstkrq ) as
	 select a.* from mycompq.Compustat_fundq2 as a
	 where indfmt='INDL' 
     and datafmt='STD' 
     and popsrc='D' 
     and consol='C'
     and (&beg_date <= datadate <= &end_date) ;
quit;
data comp1;
set comp1 (keep = fyearq fqtr fyr datadate gvkey datacqtr atq ibq seqq ceqq pstkq ltq rdq txditcq pstkrq);
if fyr > 0;
if fyr <= 5 then cyear = fyearq + 1;
else cyear = fyearq;

/*begin and end dates for fiscal year;*/
date1 = MDY(fyr,1,cyear);
endfyr = intnx('month',date1,0,'end'); format endfyr date9.;
begfyr = intnx('month',endfyr,-11,'beg'); format begfyr date9.;

keep gvkey begfyr endfyr fyearq fqtr fyr datadate datacqtr atq ibq seqq ceqq pstkq ltq rdq txditcq pstkrq;
run;
proc download data=comp1 out=myq.compustat_fundq;
run;
endrsubmit;
proc sort data=myq.compustat_fundq;
by gvkey fyearq fqtr;
run;
/*1-2. Annual Compustat */
rsubmit;
%let beg_date = '01JAN1965'd;
%let end_date = '31DEC2019'd;
libname compm '/wrds/comp/sasdata/nam';
proc sql;
     create table comp3(keep = fyear gvkey datadate at fyr sich) as
	 select a.* from mycomp.Compustat_funda as a
	 where indfmt='INDL' 
     and datafmt='STD' 
     and popsrc='D' 
     and consol='C'
     and (&beg_date <= datadate <= &end_date) ;
quit;
proc download data=comp3 out=myq.compustat_funda;
run;
endrsubmit;
signoff;
proc sort data=myq.compustat_funda;
     by gvkey fyear;
run;
proc sort data=myq.compustat_funda out=myq.compustat_funda;
  by gvkey descending fyear;
run;
data myq.compustat_funda;
  set myq.compustat_funda;
  by gvkey descending fyear;
  retain sic;
  if first.gvkey | not missing(sich) then
  sic=sich;
run;
proc sort data=myq.compustat_funda;
  by gvkey fyear;
run;
data myq.compustat_funda;
  set myq.compustat_funda;
  by gvkey fyear;
  retain sic1;
  if first.gvkey | not missing(sic) then
  sic1=sic;
run;
proc sort data=myq.compustat_funda;
  by gvkey fyear;
run;
data myq.compustat_funda(drop = sic);
     set myq.compustat_funda;
     rename sic1=sic;
run;
/*Add sic to quarterly compustat*/
proc sql;
create table myq.compustat_fundq as
select a.*, b.sic
from myq.compustat_fundq as a left join myq.compustat_funda as b 
on a.gvkey=b.gvkey and a.fyearq = b.fyear;
quit;
/*Filters: drop negative book value of equity & financial firms*/
data myq.compustat_fundq;
     set myq.compustat_fundq;
     by gvkey fyearq fqtr;
	 PS = coalesce(pstkrq,pstkq,0);
	 SH = coalesce(seqq,ceqq+pstkq,atq-ltq);
	 if missing(txditcq) then txditcq=0;
	 BE = SH + txditcq - PS;
	 if BE>=0;
	 if sic<6000 or sic>6999;
run;
/*Make fyear-fquarter series (fyq)*/
data myq.compustat_fundq;
  set myq.compustat_fundq;
  fdate = yyq(fyearq,fqtr);
  format fdate date9.; 
  fyq = intck("qtr",'1jan1960'd,fdate);
  by gvkey;
run;
proc sql;
create table myq.compustat_fundq as
select a.* , b.be as l_be
from myq.compustat_fundq as a left join myq.compustat_fundq as b
on a.gvkey = b.gvkey and a.fyq - 1 = b.fyq;
quit;
/*Estimate quarterly ROE*/
data myq.compustat_fundq;
     set myq.compustat_fundq;
     by gvkey;
	 roe=ibq/l_be;
	 if roe ne .;
	 year=year(datadate);
	 cqtr=qtr(datadate);
	 if rdq ne .;
run;
proc sort data=myq.compustat_fundq; by gvkey fyearq fqtr; run;
/*Estimate asset growth*/
proc sql;
create table myq.compustat_funda as
select a.* , b.at as l_at
from myq.compustat_funda as a left join myq.compustat_funda as b
on a.gvkey = b.gvkey and a.fyear - 1 = b.fyear;
quit;
data myq.compustat_funda1;
     set myq.compustat_funda;
     by gvkey;
	 g_at=(at-l_at)/l_at;
	 if g_at ne .;
	 if sic<6000 or sic >6999;
run;
data myq.compustat_funda1;
set myq.compustat_funda1;
if fyr > 0;
if fyr <= 5 then cyear = fyear + 1;
else cyear = fyear;
year = year(datadate);
/*begin and end dates for fiscal year;*/
date1 = MDY(fyr,1,cyear);
endfyr = intnx('month',date1,0,'end'); format endfyr date9.;
begfyr = intnx('month',endfyr,-11,'beg'); format begfyr date9.;
run;
proc sort data=myq.compustat_funda1; by gvkey fyear; run;
/*1-3. CRSP monthly return */
/*mydisp.monthret_ff: 1963 to 2018*/
data myq.monthret_ff; 
     set mydisp.monthret_ff;
run;
data myq.crsp(keep=permno date prc ret exret ME siccd lme exchcd shrcd nyse5bp nyse10bp nyse20bp);
     set myq.monthret_ff;
     by permno;
     LME=lag(me);
     if first.permno then LME=me/(1+ret);
	 if (exchcd=1 or exchcd=2 or exchcd=3);
	 if (shrcd=10 or shrcd=11);
	 if (siccd<6000 or siccd>6999);
run;
proc sort data = myq.crsp;
    by date;
run;
proc univariate data=myq.crsp noprint;
    var lme;
	by date;
	output out=myq.tlmc sum=tlmc;
run;
data myq.crsp2; merge myq.tlmc myq.crsp;
    by date;
	wi = lme/tlmc;
run;

/*2. Construct portfolio: I/A and Size */ 
/***********************************************************************/
/*At the end of June t, split stocks using NYSE median breakpoint into                          */
/*2 groups: Small and Big. Independently, at the end of June t, break                              */
/*all stocks into 3 I/A groups using NYSE bp for the low 30%, middle 40%                    */
/*, high 30% of the ranked values of I/A for the fiscal year ending in                               */
/*calendar year t-1.                                                                                                        */
/*In addition, independently, at the beginning of each month, sort all                               */
/*stocks into 3 groups based on NYSE bp for the low 30%, middel 40%, and                   */
/*high 30% of the ranked values of ROE. Earnings data in Compustat quar-                     */
/*terly files are used in the months immediately after the most recent                                */
/*public quarterly earnings announcement dates. Also, require the end of                           */
/*the fiscal quarter that correspons to its most recently announced                                     */
/*quarterly earnings to be within 6 months prior to the pf formation.                                 */
/************************************************************************/

/*2-1.Create a data for each June*/
proc sql;
create table myq.crsp_june as
select a.*
from myq.crsp2(where=(month(date)=6)) as a;
quit;

/*2-2.Merging CRSP and Compustat*/
/*Annual Compustat + CCM linktable*/
proc sql;
create table myq.ccm
as select * from myq.compustat_funda1 as a, mydisp.ccmxpf_linktable as b
where a.gvkey = b.gvkey
and b.LINKTYPE in ("LU","LC","LD","LF","LN","LS")
/*LO: links to trading company but no linking trading issues exists.*/
/*LX: links to foreign company with an issue trading on US exchanges.*/
and b.LINKPRIM in ("P", "C")
/*LO: links to trading company but no linking trading issues exists.*/
/*LX: links to foreign company with an issue trading on US exchanges.*/
/*Entire fiscal years within link date range*/
and (b.LINKDT<=a.endfyr or b.LINKDT = .B)
and (a.endfyr<=b.LINKENDDT or b.LINKENDDT=.E);
quit;
/* Cleaning Compustat Data for no relevant duplicates  
/* 1. 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; */
proc sort data=myq.ccm out=myq.ccm2;
          by datadate lpermno descending linkprim gvkey;
run;
data myq.ccm2a;
     set myq.ccm2;
     by datadate lpermno descending linkprim gvkey;
     if first.lpermno;
run;
proc sort data=myq.ccm2a nodupkey; by datadate lpermno; run;
/* 2. However, there other type of duplicates within the year                */
/* Some companies 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;     */
proc sort data=myq.ccm2a; by lpermno fyear datadate ; run;
data myq.ccm2b ;
     set myq.ccm2a;
     by lpermno year datadate ;
     if last.year =1 ;
run;
proc sort data=myq.ccm2b nodupkey; by lpermno datadate; run;
/* End cleaning Compustat        */

/*Merge above CCM merged compustat with CRSP at June of every year*/
/*Match fiscal year ending calendar year t-1 with June t          */
proc sql;
create table myq.ccm2b_june as                 
select a.*, b.g_at, b.datadate, b.fyear, b.fyr, b.gvkey
from myq.crsp_june as a , myq.ccm2b as b
where a.permno=b.lpermno
and intnx('month',a.date,0,'E')=
    intnx('month',intnx('year',b.datadate,0,'E'),6,'E')
order by date;
quit;
/*Construct portfolio by Size and I/A as of each June t*/
proc univariate data=myq.ccm2b_june noprint;
where exchcd=1 and shrcd in (10,11) and exchcd in (1,2,3);
var ME;
by date; * at june;
output out=myq.nyse_me  median = SIZEMEDN  ;
run;
proc univariate data=myq.ccm2b_june noprint;
where exchcd=1 and shrcd in (10,11) and exchcd in (1,2,3);
var g_at;
by date; /* at June */
output out=myq.nyse_ia  pctlpts=30 70 pctlpre=IA;
run;
/* Use Breakpoints to classify stock only at end of all June's */
proc sql;
create table myq.ccm3_june as
select a.*, b.sizemedn, c.IA30, c.IA70
from myq.ccm2b_june as a, myq.nyse_me as b, myq.nyse_ia as c
where a.date=b.date=c.date;
quit;

/*3. Construct portfolio: ROE*/ 
/*3-1.Merging CRSP and Compustat*/
/*Quarterly Compustat + CCM linktable*/
proc sql;
create table myq.ccqm
as select * from myq.compustat_fundq as a, mydisp.ccmxpf_linktable as b
where a.gvkey = b.gvkey
and b.LINKTYPE in ("LU","LC","LD","LF","LN","LS")
/*LO: links to trading company but no linking trading issues exists.*/
/*LX: links to foreign company with an issue trading on US exchanges.*/
and b.LINKPRIM in ("P", "C")
/*LO: links to trading company but no linking trading issues exists.*/
/*LX: links to foreign company with an issue trading on US exchanges.*/
/*Entire fiscal years within link date range*/
and (b.LINKDT<=a.endfyr or b.LINKDT = .B)
and (a.endfyr<=b.LINKENDDT or b.LINKENDDT=.E);
quit;
/* Cleaning Compustat Data for no relevant duplicates  
/* 1. 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; */
proc sort data=myq.ccqm out=myq.ccqm2;
          by datadate lpermno descending linkprim gvkey;
run;
data myq.ccqm2a;
     set myq.ccqm2;
     by datadate lpermno descending linkprim gvkey;
     if first.lpermno;
run;
proc sort data=myq.ccqm2a nodupkey; by datadate lpermno; run;
proc sort data=myq.ccqm2a nodupkey; by lpermno datadate; run;
/* End cleaning Compustat        */

/*Merge above CCM merged quarterly compustat with CRSP at the beginning of each month*/
/*After the most recent public quarterly earnings announcement dates, earnings data  */
/*is directly used. EX. RDQ=March 5 at t. Then, it is used at the beginning of April */
/*In addition, require the end of the fiscal quarter that corresponds to its most re-*/
/*cently announced quarterly earnings to be within 6 months prior to the pf formation*/
proc sql;
create table myq.ccqm2a1 as
select a.* , b.rdq as f_rdq
from myq.ccqm2a as a left join myq.ccqm2a as b
on a.lpermno = b.lpermno and a.fyq + 1 = b.fyq;
quit;
proc sql;
create table myq.ccqm2a1_f2rdq as
select a.* , b.rdq as f2_rdq
from myq.ccqm2a1 as a left join myq.ccqm2a as b
on a.lpermno = b.lpermno and a.fyq + 2 = b.fyq;
quit;
proc sql;
create table myq.ccqm2a1_f3rdq as
select a.* , b.rdq as f3_rdq
from myq.ccqm2a1_f2rdq as a left join myq.ccqm2a as b
on a.lpermno = b.lpermno and a.fyq + 3 = b.fyq;
quit;
proc sql;
create table myq.ccqm2a1_f4rdq as
select a.* , b.rdq as f4_rdq
from myq.ccqm2a1_f3rdq as a left join myq.ccqm2a as b
on a.lpermno = b.lpermno and a.fyq + 4 = b.fyq;
quit;
proc sql;
create table myq.ccqm2a1_f5rdq as
select a.* , b.rdq as f5_rdq
from myq.ccqm2a1_f4rdq as a left join myq.ccqm2a as b
on a.lpermno = b.lpermno and a.fyq + 5 = b.fyq;
quit;
proc sql;
create table myq.ccqm2a1_f6rdq as
select a.* , b.rdq as f6_rdq
from myq.ccqm2a1_f5rdq as a left join myq.ccqm2a as b
on a.lpermno = b.lpermno and a.fyq + 6 = b.fyq;
quit;
proc sql;
create table myq.ccqm2a2 as
select a.*, intck('month',a.rdq,a.f_rdq) as nummonth1, intck('month',a.rdq,a.f2_rdq) as nummonth2, intck('month',a.rdq,a.f3_rdq) as nummonth3, intck('month',a.rdq,a.f4_rdq) as nummonth4,
       intck('month',a.rdq,a.f5_rdq) as nummonth5, intck('month',a.rdq,a.f6_rdq) as nummonth6
from myq.ccqm2a1_f6rdq as a;
quit;
data myq.ccqm2a21 ;
     set myq.ccqm2a2;
	 nummonth=min(6,coalesce(nummonth1,nummonth2,nummonth3,nummonth4,nummonth5,nummonth6));
run;
proc sql;
create table myq.ccqm2a_pf as                 
select a.*, b.roe, b.datadate, b.fyearq, b.fqtr, b.fyr, b.gvkey, b.rdq, b.f_rdq, b.nummonth, intck('month',b.datadate,a.date) as maxmonth, 
intnx('month',a.date,0,'b') as portdate format date9.
from myq.crsp2 as a , myq.ccqm2a21 as b
where a.permno=b.lpermno
and intck('month',b.rdq,a.date) between 0 and b.nummonth-1 
order by permno, date;
quit;
proc sort data=myq.ccqm2a_pf; by permno rdq date; run;
data myq.ccqm2a_pf1 ;
     set myq.ccqm2a_pf;
	 if rdq < date;
	 if maxmonth <7;
run;
proc sort data=myq.ccqm2a_pf1; by portdate; run;
/*Construct portfolio by Size and ROE at the beginning of each month*/
proc univariate data=myq.ccqm2a_pf1 noprint;
where exchcd=1 and shrcd in (10,11) and exchcd in (1,2,3);
var ROE;
by date; * at the beginning of each month;
output out=myq.nyse_roe  pctlpts=30 70 pctlpre=ROE  ;
run;
/* Use Breakpoints to classify stock only at end of all June's */
proc sql;
create table myq.ccqm_pfmonth as
select a.*, b.ROE30, b.ROE70
from myq.ccqm2a_pf1 as a, myq.nyse_roe as b
where a.date=b.date;
quit;

/*4.Merge Size & I/A bp + ROE bp*/
data myq.ccm4_june; 
     set myq.ccm3_june;
	 keep date me g_at datadate permno SIZEMEDN IA30 IA70 fyear fyr;
run; 
data myq.ccqm_pfmonth2;
     set myq.ccqm_pfmonth;
	 keep date portdate permno datadate ROE30 ROE70 fyearq fqtr fyr roe;
run;
proc sql;
create table myq.PF_breakpoint as
select a.*,
b.date as annual_date, b.g_at, b.sizemedn, b.IA30, b.IA70, b.me
from myq.ccqm_pfmonth2 as a, myq.ccm4_june as b
where a.permno=b.permno and intck('month',b.date,a.date) between 1 and 12
order by portdate;
quit;

/*5.Create portfolios at the beginning of each month*/
/*Size portfolios: S[mall] or B[ig]                 */
/*I/A portfolios: L[arge], M[iddle], or S[mall]     */
/*ROE portfolios: H[igh], N[ormal], or L[ow]        */
data myq.PF_sorting ;
     set myq.PF_breakpoint;
     if ME <= sizemedn                                 then SIZEPORT = 'S';
     else if ME > sizemedn                            then SIZEPORT = 'B';
     if g_at <= IA30                                      then IAPORT = 'S';
     else if g_at >  IA30 and g_at <= IA70     then IAPORT = 'M' ;
     else if g_at  > IA70                                then IAPORT = 'L';
     if roe <= roe30                                       then ROEport = 'L';
	 else if roe > ROE30 and roe <= ROE70   then ROEport = 'N';
	 else if roe > ROE70                                then ROEport = 'H';
if missing(sizeport)=0 and missing(IAport)=0 and missing(ROEport)=0 then nonmissport=1;
else nonmissport=0;
keep permno portdate date sizeport IAport ROEport nonmissport;
run;
proc sql;
create table myq.PF_return as
select a.date, a.permno, a.ret, a.exret, a.wi,
b.sizeport, b.IAport, b.ROEport, b.portdate, b.nonmissport
from myq.crsp2 as a, myq.PF_sorting as b
where a.permno=b.permno 
and intnx('month',a.date,0,'E')=
    intnx('month',b.date,1,'E')
order by date , sizeport, IAport, ROEport;
quit;

/*6.Calculate Q-factors */
proc univariate noprint data=myq.PF_return;
    var ret;
    by date sizeport IAport ROEport;
    weight wi;
    output out = myq.portret mean = vwret n = N;
run;
proc transpose data=myq.portret(keep=date sizeport IAport ROEport vwret) out=myq.portret2 (drop=_name_ _label_);
by date;
ID sizeport IAport ROEport;
Var vwret;
run;
data myq.q_factor(keep=date q_me q_IA q_ROE);
     set myq.portret2;
	 q_small=(slh+sll+sln+smh+sml+smn+ssh+ssl+ssn)/9;
	 q_big=(blh+bll+bln+bmh+bml+bmn+bsh+bsl+bsn)/9;
	 q_me=q_small - q_big;
     q_large=(blh+bln+bll+slh+sll+sln)/6;
	 q_small=(bsh+bsl+bsn+ssh+ssl+ssn)/6;
	 q_IA=q_small - q_large;
	 q_high=(blh+bmh+bsh+slh+smh+ssh)/6;
	 q_low=(bll+bml+bsl+sll+sml+ssl)/6;
	 q_ROE=q_high - q_low;
run;
proc means data=myq.q_factor;
run;
data myq.q_factor;
     set myq.q_factor;
     if date > '01Jan1972'd;
run;
proc corr data=myq.q_factor;
var q_me q_IA q_ROE;
run;
/*Correlation check with FF5*/
proc sql;
create table myq.factors as
select a.*, b.mktrf, b.smb, b.hml, b.cma, b.rmw, b.umd
from myq.q_factor as a, mydisp.factor as b
where year(a.date)=b.year and month(a.date)=b.month;
quit;
proc corr data=myq.factors;
var mktrf smb hml cma rmw umd q_me q_ia q_roe;
run;
/*7.Annualize Q_factor*/
proc printto log = junk; run;
proc expand data = myq.portret2 out=myq.portret_y method=none;
    id date;
    convert blh = blhy      / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
	convert bll = blly        / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
	convert bln = blny      / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
	convert bmh = bmhy  / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
	convert bml = bmly    / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
	convert bmn = bmny  / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
	convert bsh = bshy     / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
	convert bsl = bsly      / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
	convert bsn = bsny    / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
	convert slh = slhy     / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
	convert sll = slly       / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
	convert sln = slny     / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
	convert smh = smhy / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
	convert sml = smly   / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
	convert smn = smny / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
	convert ssh = sshy    / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
	convert ssl = ssly     / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
	convert ssn = ssny   / transformin=(+1) transformout=(MOVPROD  12 -1 trimleft  11);
quit;
proc printto; run;
data myq.Q_factory(keep=date q_mey q_IAy q_ROEy);
     set myq.portret_y;
	 q_small=(slhy+slly+slny+smhy+smly+smny+sshy+ssly+ssny)/9;
	 q_big=(blhy+blly+blny+bmhy+bmly+bmny+bshy+bsly+bsny)/9;
	 q_mey=q_small - q_big;
     q_large=(blhy+blny+blly+slhy+slly+slny)/6;
	 q_small=(bshy+bsly+bsny+sshy+ssly+ssny)/6;
	 q_IAy=q_small - q_large;
	 q_high=(blhy+bmhy+bshy+slhy+smhy+sshy)/6;
	 q_low=(blly+bmly+bsly+slly+smly+ssly)/6;
	 q_ROEy=q_high - q_low;
run;
proc means data=myq.Q_factory;
run;
proc corr data=myq.Q_factory;
var q_mey q_IAy q_ROEy;
run;
