I want to know how to run this program. in other word the data file name and the variable that I must include in the data
/***********************************************************************/
/* */
/* Program: Option-Based Factors */
/* Author : Luis Palacios, WRDS */
/* Date : 03/01/2010 */
/* Revised : 03/29/2010 */
/* Steps : */
/* - Get Daily option prices for all S&P500 options */
/* - S&P500 (SPX) secid in optionmetrics is 108105 */
/* - Filters applied on 1st trading day of month */
/* - Keep options expiring in the following month */
/* - Keep only options with available prices */
/* - Keep options with standard settlements */
/* */
/* Notes on SPX Options: */
/* - Expiration: Saturday Following the 3rd Friday of Expiration Month */
/* - Exercise Style: European exercisable on last bus day bef. exp. */
/* */
/* Example: %optionfactor(begyear=1996,endyear=2009, */
/* flag=C,atm_otm=OTM,outfile=myfinalOTM); */
/* ******************************************************************* */
%macro optionfactor
(begyear=1996,endyear=2012,flag=C,atm_otm=OTM,outfile=myfinalOTM,sp500_id=108105);
data a1;
set %do i=&begyear %to &endyear; OPTIONM.OPPRCD&i
(keep = date secid exdate strike_price best_bid best_offer optionid
exdate ss_flag cp_flag where = (secid=&sp500_id)) %end; ;
month = month(date);
year = year(date) ;
/* Keep Options with Standard Settlment, i.e. 0 Special. Settl. Flag */
if ss_flag='0' and cp_flag="&flag" and best_bid>0 and best_offer>0;
/* Mid-Price */
price = (best_bid + best_offer)/2;
/* Strike Price Adjustment */
strike=strike_price/1000;
/* Standard SPX option expire Saturday (weekday=7)following the third Friday of the expiration month */
if weekday(exdate)=7; * it eliminates non standard-date options;
drop ss_flag cp_flag best_bid best_offer strike_price;
run;
/* Sort Dataset to Keep First Observation per Month */
proc sort data=a1 out=a1; by optionid year month date; run;
/* Use Data from the First Trading Day of the Month */
/* Keep only Options that Expire in the Following Month */
data a2; set a1;
by optionid year month date;
if first.month;
if intck('month',date,exdate)=1;
run;
/* Get Price of the underlying index (S&P 500) */
data b1;
set %do i=&begyear %to &endyear %by 1;
optionm.secprd&i (where = (secid=&sp500_id)) %end; ;
month = month(date);
year = year(date);
/* CLOSE is closing price at the end of the day */
keep date year month close secid;
run;
/* Sort Price Data */
proc sort data=b1 out=b1; by secid year month date; run;
/* Keep data on first day of the month */
data b2; set b1;
by secid year month date;
if first.month;
run;
/* Add Risk-Free Rate for Present Value Calculation */
proc sql;
create table b3 as
select a.rf, b.*
from ff.factors_monthly as a, b2 as b
where a.year=b.year and a.month=b.month;
quit;
/* Merge Option data with price data to identify moneyness */
/* Discount Rate for Strike Price of options expiring at 'exdate' */
%let discount = (( 1 + b.rf) ** ( -(a.exdate-a.date)/30 )) ;
/* Select option whose Strike Price PV is closest to current price */
proc sql;
create table _list as
select a.date, a.secid, a.price, a.exdate, a.strike , b.close,
a.optionid, a.strike*&discount - b.close as diff
from a2 as a, b3 as b
where a.date=b.date
group by a.date
having abs(diff)=min(abs(diff));
quit;
%if &atm_otm=ATM %then %goto finalstep;
/* Next Step is for OTM options Exclusively */
%else %if &atm_otm=OTM %then %do;
%if &flag=C %then %let sign = < ;
%else %if &flag=P %then %let sign = > ;
%end;
proc sql undo_policy=none;
create table _list2 as
select b.*, ((a.close + abs(a.diff)) - b.strike) as diff2
from _list(keep=date strike close diff) as a, a2 as b
where a.date=b.date and
( a.close + abs(a.diff) ) &sign b.strike /* Out the money OTM PUT sign is positive, OTM CALL sign is negative */
and
a.strike &sign b.strike
group by a.date
having abs(diff2)=min(abs(diff2)) ;
quit;
/* Final Step bookmark */
%finalstep:
%if &atm_otm=ATM %then %let inputfile= _list ;
%else %if &atm_otm=OTM %then %let inputfile= _list2 ;
/* For selected options grab prices at the beg. of the next month */
proc sql;
create table &outfile as
select intnx('month',a.date,0,'end') as DATE format yymmddn8.,
(b.price/a.price)-1 as Factor_Ret "Option-Based Factor" format percentn8.2,
"&flag" as flag, "&atm_otm" as money
from &inputfile as a, a1 as b
where a.optionid=b.optionid and intck('month',a.date,b.date)=1
group by a.date
having b.date=min(b.date)
order by a.date ;
quit;
You need a LIBNAME statement that defines a folder identified as OPTIONM:
libname OPTIONM 'path to folder';
WIthin that folder, you need SAS data sets covering the range of years that you would like to analyze:
OPRCD1996.sas7bdat
OPRCD1997.sas7bdat
...
OPRCD2012.sas7bdat
The range of years needed can change, depending on the values supplied when calling the macro. The default ranges from 1996 to 2012, but you can override that by specifying begyear= and endyear=.
so I need a number of folder equal to the number of year that I have form 1996 to 2012. then 17 .sas7bdat???
You just need one folder. The name of the folder doesn't matter, but you have to include it in the LIBNAME statement.
All the SAS data sets need to reside in that folder.
Registration is open! SAS is returning to Vegas for an AI and analytics experience like no other! Whether you're an executive, manager, end user or SAS partner, SAS Innovate is designed for everyone on your team. Register for just $495 by 12/31/2023.
If you are interested in speaking, there is still time to submit a session idea. More details are posted on the website.
Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.
Find more tutorials on the SAS Users YouTube channel.