Would u help me to calculate 48 sets of returns (2*3*2*2*2)
NOW I HAVE
Objective
Calculate the one-week and one-month returns (using the RET column) for stocks that break out to a new high or new low each day, weighted by market capitalization and arithmetic average. This results in 24 sets of returns:
2 * 3 * 2 * 2 = 24
More portfolio flag/column explanation
Calculate daily market capitalization:
Assign stocks to quartiles:
Calculate weighted and arithmetic average returns for each set of stocks:
Output
A table with the following category
2 new highs and lows (Max vs Min )portfolio Breakout
*3 sizes (Small vs Mid vs Big)
*2 weighting methods (Market capitalization-weighted return vs equal-weighted)
*2 groups of stocks (all stocks vs those that have reached new highs or lows)
*2 Return type (one-week or one-month)
table may seems like the following
Additional notes
DM'LOG; CLEAR; OUT; CLEAR; ODSRESULTS; CLEAR;';
%LET FOLDER=%STR(C:\USERS\ALAIN\ONEDRIVE\桌面\HIGH);
LIBNAME HIGH "&FOLDER";
DATA HH;
SET HIGH.HH;
IF CFACPR=0 THEN DELETE;
RUN;
/*
DATA HH;
SET HH;
IF _N_ <=1000;
RUN;
*/
PROC SORT
DATA=HH (KEEP =SHRCD EXCHCD PERMNO DATE PRC CFACPR SHROUT CFACSHR RET
WHERE =( SHRCD IN (10,11) AND EXCHCD IN (1,2,3,31,32,33) )
)
OUT=HL(DROP=SHRCD EXCHCD );
BY PERMNO DATE;
RUN;
DATA HL;
SET HL;
BY PERMNO DATE;
RETAIN H L 0;
P=ABS(DIVIDE (PRC, CFACPR));
IF FIRST.PERMNO THEN H = P;
IF FIRST.PERMNO THEN L = P;
H = MAX(H, P);
L = MIN(L, P);
DROP PRC CFACPR;
RUN; /* PERMNO DATE SHROUT CFACSHR H L P */
DATA MK (DROP=_:);
SET HL;
BY PERMNO DATE;
RETAIN _FIRST_DATE_QUALIFIED .
_H .
_H_DATE .
_L .
_L_DATE .
PORTFOLIO
;
LENGTH PORTFOLIO $11;
IF FIRST.PERMNO THEN DO;
CALL MISSING(OF _:);
_FIRST_DATE_QUALIFIED=INTNX('YEAR',DATE,1,'SAME')+1;
END;
IF _H=. THEN _H=P;
IF _L=. THEN _L=P;
IF P ^=. THEN DO;
IF P > _H AND DATE >= INTNX('MONTH', _H_DATE, 1, 'SAME') THEN DO;
_H=P;
_H_DATE=DATE;
PORTFOLIO='MAX';
END;
ELSE IF P < _L AND DATE >= INTNX('MONTH', _L_DATE, 1, 'SAME') THEN DO;
_L=P;
_L_DATE=DATE;
PORTFOLIO='MIN';
END;
ELSE PORTFOLIO='COMPARISON';
END;
IF DATE >= _FIRST_DATE_QUALIFIED THEN DO;
H = _H;
H_DATE = _H_DATE;
L = _L;
L_DATE = _L_DATE;
END;
IF DATE < _FIRST_DATE_QUALIFIED THEN DO;
PORTFOLIO = 'UNQUALIFIED';
END;
FORMAT H_DATE L_DATE YYMMDD10. ;
RUN;
DATA MV;
SET MK;
BY PERMNO DATE;
RETAIN
MV
LAST_MONTH_END;
LAST_MONTH_END = INTNX('MONTH', DATE, -1, 'END');
FORMAT LAST_MONTH_END YYMMDD10. ;
MV = P * (SHROUT*CFACSHR) ;
RUN;
data LMV;
set MV ;
by permno date ;
lag_MV = lag(MV);
if first.permno then call missing(lag_MV,previous_MV);
else if month(date) ne month(lag(date)) then previous_MV=lag_MV;
retain previous_MV;
/* drop lag_MV;*/
run;
PROC SORT DATA=LMV;
BY DATE PERMNO DESCENDING previous_MV;
RUN;
PROC RANK DATA=LMV OUT=RANKED_DATA GROUPS=4 TIES=LOW;
BY DATE;
VAR previous_MV;
RANKS QUARTILE;
RUN;
/*
proc contents data=RANKED_DATA;
run;
*/
DATA SMB;
SET RANKED_DATA;
RETAIN
SIZE
;
LENGTH SIZE $6;
IF QUARTILE = 0 THEN SIZE = 'SMALL';
else IF QUARTILE = 1 THEN SIZE = 'MID';
else IF QUARTILE IN (2,3) THEN SIZE ='BIG';
ELSE SIZE ='NOSIZE';
RUN;
data filtered_data;
set SMB;
where date between '24OCT1979'd and '01NOV1979'd;
run;
PROC EXPORT DATA= WORK.FILTERED_DATA
OUTFILE= "C:\Users\alain\OneDrive\桌面\check.xls"
DBMS=EXCEL REPLACE;
SHEET="check";
RUN;
/*
DATA See;
SET SMB(OBS=500);
PUT (_ALL_) (+0);
RUN;
Thank you for providing a lot of information including your current code and data upfront. What normally works best in the forums here is asking for help for targeted challenges. I feel your request is a bit too broad - but who knows, may be someone in your field has already done something similar and is willing to share actual code or at least give you pointers how to proceed.
You would likely get more people helping if:
1. Share less data. Just a representative sample that's sufficient for the problem.
2. Explain in as much detail as you can the logic required to get from your sample data to the desired result.
3. Show the desired result based on your sample data. This allows us to test the code we propose.
A lot of people won't download data shared via a link. The attached create_data.sas file is data step code that creates a table Have with the source data you shared via link.
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9.
Early bird rate extended! Save $200 when you sign up by March 31.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.