For options on other financial instruments than stocks, we have to allow for the fact that the underlying may have payouts during the life of the option. For example, in working with commodity options, there is often some storage costs if one wanted to hedge the option by buying the underlying.
Call and put prices for European options are then given by (see (Hull, 1997, pg 263))
// file: black_scholes_price_payout_call.cc
// author: Bernt A Oedegaard
// Calculation of the Black Scholes option price formula,
// special case where the underlying is paying out a yield of q.
#include <cmath> // mathematical library
#include "normdist.h" // this defines the normal distribution
double option_price_european_call_payout( double S, // spot price
double X, // Strike (exercise) price,
double r, // interest rate
double q, // yield on underlying
double sigma, // volatility
double time) { // time to maturity
double sigma_sqr = pow(sigma,2);
double time_sqrt = sqrt(time);
double d1 = (log(S/X) + (r-q + 0.5*sigma_sqr)*time)/(sigma*time_sqrt);
double d2 = d1-(sigma*time_sqrt);
double call_price = S * exp(-q*time)* N(d1) - X * exp(-r*time) * N(d2);
return call_price;
};
The case of continuous dividends is easiest to deal with. It corresponds to the continuous payouts we have looked at previously. The problem is the fact that most dividends are paid at discrete dates.
// file: bserudiv.cc
// author: Bernt A Oedegaard
#include <cmath> // mathematical library
#include "fin_algoritms.h" // define the black scholes price
#include <vector>
double option_price_european_call_dividends( double S,
double X,
double r,
double sigma,
double time_to_maturity,
vector<double>& dividend_times,
vector<double>& dividend_amounts )
// reduce the current stock price by the amount of dividends.
{
for (int i=0;i<dividend_times.size();i++) {
if (dividend_times[i]<=time_to_maturity){
S -= dividend_amounts[i] * exp(-r*dividend_times[i]);
};
};
return option_price_call_black_scholes(S,X,r,sigma,time_to_maturity);
};