12-02-2015 12:25 AM
Sorry for possibly asking a very basic question. I am quite new to coding in SAS.
As I can see there is a standard SAS FCMP procedure to calculate the Black Scholes Implied Volatility for individual option data.
But my problem is that I have a data table of intraday option trading data that lists all the required fields, i.e. strike price, time to expiry, equity price, interest rate and volatility. Is there any way i can code so that I can calculate the implied volatility for these individual entries.
I understand that possibly i need to use some kind of loop to do so, but i am not able to understand how to pass values within procedures in SAS. Any help will be highly appreciated.
12-02-2015 11:58 AM - edited 12-02-2015 11:59 AM
First of all, I think, the example (from the SAS 9.2 documentation) in your link is flawed: The array OPTS has 5 dimensions, but only 4 variables and initial values have been specified. This is not literally an error, but it causes an unnecessary note in the log. It is particularly odd that they present an output where the computed result of the SOLVE function is missing. Moreover, they use the DATE() function (=current date at run time), so that you can't really replicate their example as the result would depend on when you run it.
Not surprisingly, they corrected all this in the SAS 9.4 documentation:
However, it is still strange to me that they present an example of a function call where the arguments (opt_price, strike, etc.) are hardcoded in the PROC FCMP step. Wouldn't it make much more sense, if users like you were able to apply the function to their data without having to modify the PROC FCMP code?
Well, it takes only a few changes to their code to create at least a draft version of what I think that function should look like:
proc fcmp outlib=work.funcs.test; function blksch(strike, time, eq_price, intrate, volty); return(blkshclprc(strike, time/365.25, eq_price, intrate, volty)); endsub; function implvola(opt_price, strike, eq_price, intrate, time); array opts initial abconv relconv maxiter status (.5 .001 1.0e-6 100 -1); bsvolty=solve("blksch", opts, opt_price, strike, time, eq_price, intrate, .); return(bsvolty); endsub; run; options cmplib=work.funcs;
With this definition of the new function IMPLVOLA you're in a position to compute the implied volatility for a given option price, strike price, equity price, interest rate and time to expiry (in days):
data have; input opt_price strike eq_price intrate time; cards; 5 50 50 .05 93 ; data want; set have; impl_vola=implvola(opt_price, strike, eq_price, intrate, time); run; proc print; format impl_vola best12.; run;
As you can see, the result matches the value in the example. I haven't done further tests of my function definition, though.
Unfortunately, I have no experience using the Black-Scholes formula. Therefore, I am not sure how sensitive the above function is to the initial value (opts=initial), which is set to .5 in the code. I cannot rule out that there are realistic input data which would require a different initial value to make the SOLVE algorithm converge.
That said, I was also a bit surprised to read that your data contains "all the required fields, i.e. strike price, time to expiry, equity price, interest rate and volatility." Do you refer to realized volatility? However, you did not mention option price, but this would be a required argument in order to calculate the implied volatility.