Black-Scholes Price in SAS

Without going too deep into the theoretical side of the Black Scholes option price model, it states that assuming normally distributed returns of the underlying asset, constant volatility \sigma and constant risk free rate r, the price of a European call option C and a European put option P are respectively

    \begin{equation*} C = S_t N ( d_1 ) - N ( d_1 ) K e^{-r T} \qquad\text{and}\qquad P = K e^{-r T} N(-d2) - S_t N(-d1) \end{equation*}

where S_t is the spot price of the underlying asset, T is the time to maturity, N is the Normal Cumulative Distribution Function given in the usual way and d_1 and d_2 are given as

    \begin{equation*} d_1 = \frac{1}{\sigma \sqrt{T}} \left[\ln{\left(\frac{S_t}{K}\right)} + T \left(r + \frac{\sigma^2}{2} \right) \right] \qquad\text{and}\qquad d_2 = d_1 - \sigma \sqrt{T} \end{equation*}

An IML Module for calculating Black-Scholes Put/Call Prices

Below, I have written an IML function module, that calculates the Black-Scholes put/call price given the necessary input. As a sidenote, remember that a function module is an IML module, that returns a value, whereas a subroutine module does not.

proc iml;
start BS(S, K, r, T, sigma, putcall);
if upcase(putcall) not in ('C','P') then print ('Invalid Put/Call input');  /* Handle invalid Put/Call input */
 
d1 = (log(S/K) + (r + sigma##2/2)*T)/(sigma*sqrt(T));                       /* Calculate d1                  */
d2 = d1 - sigma * sqrt(T);                                                  /* Calculate d2                  */
 
if upcase(putcall) = 'C' then
price = S*cdf('normal', d1) - K*exp(-r*T)*cdf('normal', d2);                /* Calculate BS Call Price       */
else if upcase(putcall) = 'P' then
price  = K*exp(-r*T) * cdf('normal', -d2) - S*cdf('normal', -d1);           /* Calculate BS Put Price        */
 
return price;                                                               /* Return BS Price               */
finish BS;
quit;

Now, a Black-Scholes call price can easily be calculated like this

Call_Price = BS(100, 110, 0.05, 1, 0.2, 'C');

which gives the same price as the pre defined DATA step BLKSHCPRC function, called like this

data _null_;
   Call_Price = blkshclprc(110, 1, 100, 0.05, 0.2);
   put Call_Price;
run;

Like most DATA step functions, you can also call the BLKSHCPRC function from PROC IML.

You can download the entire program here