If the option is European, it can only be used (exercised) at the maturity date. If the option is American, it can be used at any date up to and including the maturity date.

We use the following notation:

- : Price of the underlying, eg stock price.
- : Exercise price.
- : Risk free interest rate.
- : Standard deviation of the underlying asset, eg stock.
- : Current date.
- : Maturity date.
- : Time to maturity.

and a put option is worth

This can be used in solving the pde above, since they define a boundary condition for the pde.

was shown by Black and Scholes to have an analytical solution of the following functional form

where

Similarly, the price for a put option is

// file: black_scholes_call // author: Bernt A Oedegaard // Calculation of the Black Scholes option price formula. #include <cmath> // mathematical library #include "normdist.h" // this defines the normal distribution double option_price_call_black_scholes( double S, // spot price double X, // Strike (exercise) price, double r, // interest rate double sigma, double time) { double time_sqrt = sqrt(time); double d1 = (log(S/X)+r*time)/(sigma*time_sqrt) + 0.5*sigma*time_sqrt; double d2 = d1-(sigma*time_sqrt); double c = S * N(d1) - X * exp(-r*time) * N(d2); return c; };

In trading of options, a number of partial derivatives of the option price formula is important.

Delta

The first derivative of the option price with respect to the underlying is
called the delta of the option price. It is the derivative most people
will run into, since it is important in hedging of options.

Since delta is often used, here is a subroutine that calculates it

// file: black_scholes_delta_call.cc // author: Bernt A Oedegaard // The delta of the Black - Scholes formula #include <cmath> #include "normdist.h" double option_price_delta_call_black_scholes(double S, // spot price double X, // Strike (exercise) price, double r, // interest rate double sigma, // volatility double time){ // time to maturity double time_sqrt = sqrt(time); double d1 = (log(S/X)+r*time)/(sigma*time_sqrt) + 0.5*sigma*time_sqrt; double delta = N(d1); return delta; };

The remaining derivatives are more seldom used, but all of them are relevant.

Gamma

Theta

The partial with respect to time-to-maturity.

Vega

Rho

Computer algorithm, Black Scholes partials.

Here is the algorithm that calculates all the above derivatives.

// black_scholes_partials_call.cc // author: Bernt A Oedegaard // The partial derivatives of the Black - Scholes formula #include <cmath> #include "normdist.h" void option_price_partials_call_black_scholes( double S, // spot price double X, // Strike (exercise) price, double r, // interest rate double sigma, // volatility double time, // time to maturity double& Delta, // partial wrt S double& Gamma, // second prt wrt S double& Theta, // partial wrt time double& Vega, // partial wrt sigma double& Rho){ // partial wrt r double time_sqrt = sqrt(time); double d1 = (log(S/X)+r*time)/(sigma*time_sqrt) + 0.5*sigma*time_sqrt; double d2 = d1-(sigma*time_sqrt); Delta = N(d1); Gamma = n(d1)/(S*sigma*time_sqrt); Theta =- (S*sigma*n(d1)) / (2*time_sqrt) - r*X*exp( -r*time)*N(d2); Vega = S * time_sqrt * n(d1); Rho = X * time * exp(-r * time) * N(d2); };

Implied Volatility.

In calculation of the option pricing formulas, in particular the Black Scholes
formula, the only unknown is the standard deviation of the underlying stock. A
common problem in option pricing is to find the implied volatility, given the
observed price quoted in the market. For example, given , the price of a
call option, the following equation should be solved for the value of

Unfortunately, this equation has no closed form solution, which means the equation must be numerically solved to find . What is probably the algorithmic simplest way to solve this is to use a binomial search algorithm, which is implemented in the following. We start by bracketing the sigma by finding a high sigma that makes the BS price higher than the observed price, and then, given the bracketing interval, we search for the volatility in a systematic way.

// file black_scholes_imp_vol_bisect.cc // author: Bernt A Oedegaard // calculate implied volatility of Black Scholes formula #include "fin_algoritms.h" #include <cmath> double option_price_implied_volatility_call_black_scholes_bisections( double S, double X, double r, double time, double option_price) { // check for arbitrage violations: // if price at almost zero volatility greater than price, return 0 double sigma_low=0.0001; double price = option_price_call_black_scholes(S,X,r,sigma_low,time); if (price>option_price) return 0.0; // simple binomial search for the implied volatility. // relies on the value of the option increasing in volatility const double ACCURACY = 1.0e-5; // make this smaller for higher accuracy const int MAX_ITERATIONS = 100; const double HIGH_VALUE = 1e10; const double ERROR = -1e40; // want to bracket sigma. first find a maximum sigma by finding a sigma // with a estimated price higher than the actual price. double sigma_high=0.3; price = option_price_call_black_scholes(S,X,r,sigma_high,time); while (price < option_price) { sigma_high = 2.0 * sigma_high; // keep doubling. price = option_price_call_black_scholes(S,X,r,sigma_high,time); if (sigma_high>HIGH_VALUE) return ERROR; // panic, something wrong. }; for (int i=0;i<MAX_ITERATIONS;i++){ double sigma = (sigma_low+sigma_high)*0.5; price = option_price_call_black_scholes(S,X,r,sigma,time); double test = (price-option_price); if (fabs(test)<ACCURACY) { return sigma; }; if (test < 0.0) { sigma_low = sigma; } else { sigma_high = sigma; } }; return ERROR; };

is the equation we want to solve, given a first guess , we iterate by

until

where is the desired accuracy.

In our case

and, each new iteration will calculate

Note that to use Newton-Raphson we need the derivative of the option price. For the Black-Scholes formula this is known, and we can use this. But for pricing formulas like the binomial, where the partial derivatives are not that easy to calculate, simple bisection is the preferred algorithm.

// file black_scholes_imp_vol_newt.cc // author: Bernt A Oedegaard // calculate implied volatility of Black Scholes formula using newton steps #include "fin_algoritms.h" #include "normdist.h" #include <cmath> double option_price_implied_volatility_call_black_scholes_newton( double S, double X, double r, double time, double option_price) { // check for arbitrage violations: // if price at almost zero volatility greater than price, return 0 double sigma_low = 1e-5; double price = option_price_call_black_scholes(S,X,r,sigma_low,time); if (price > option_price) return 0.0; const int MAX_ITERATIONS = 100; const double ACCURACY = 1.0e-4; double t_sqrt = sqrt(time); double sigma = (option_price/S)/(0.398*t_sqrt); // find initial value for (int i=0;i<MAX_ITERATIONS;i++){ price = option_price_call_black_scholes(S,X,r,sigma,time); double diff = option_price -price; if (fabs(diff)<ACCURACY) return sigma; double d1 = (log(S/X)+r*time)/(sigma*t_sqrt) + 0.5*sigma*t_sqrt; double vega = S * t_sqrt * n(d1); sigma = sigma + diff/vega; }; return -99e10; // something screwy happened, should throw exception };