Our model of pricing European options by Monte Carlo simulations can be used as the basis for pricing a variety of exotic options.
In our previous simulation we defined a way of distributing asset prices at maturity, and a way of assessing the value of an option at maturity with that price.
This simulation can be thought of generically like:
while i < num_iterations: S_T = generate_asset_price() payoffs += payoff_function(S_T) i += 1 option_price = exp(-r*T) * (payoffs / num_iterations)
By changing how we generate asset prices and how we assess an option's payoff, we can generate prices for some exotic options.
A binary option (also known as an all-or-nothing or digital option) is an option where the payoff is either some amount or nothing at all. The payoff is, usually, a fixed amount of cash or the value of the asset.
For our simulation, we're going to look at cash-or-nothing binary options. The payoff of the binary call and put options are shown below.
The payoff graph of the binary call is telling us that if the price of the stock is greater than or equal to $40.00 (our strike) then the option pays $1.00.
We can write a binary call's payoff as a python function:
def binary_call_payoff(K, S_T): if S_T >= K: return 1.0 else: return 0.0
Our asset's price is still going to follow a geometric Brownian motion, so we can use the generate_asset_price() function from the previous article.
def gbm(S, v, r, T): return S * exp((r - 0.5 * v**2) * T + v * sqrt(T) * random.gauss(0,1.0))
That's all we need to price binary cash-or-nothing calls. Putting it all together looks like this:
import random from math import exp, sqrt def gbm(S, v, r, T): return S * exp((r - 0.5 * v**2) * T + v * sqrt(T) * random.gauss(0,1.0)) def binary_call_payoff(K, S_T): if S_T >= K: return 1.0 else: return 0.0 # parameters S = 40.0 # asset price v = 0.2 # vol of 20% r = 0.01 # rate of 1% maturity = 0.5 K = 40.0 # ATM strike simulations = 50000 payoffs = 0.0 # run simultaion for i in xrange(simulations): S_T = gbm(S, v, r, maturity) payoffs += binary_call_payoff(K, S_T) # find prices option_price = exp(-r * maturity) * (payoffs / float(simulations)) print 'Price: %.8f' % option_price
Running this gives us a price of around $0.48413327, or around $0.484
Binary options can also be priced using the traditional Black Scholes model, using the following formula:
Where N is the cumulative normal distribution function, and d2 is given by the standard Black Scholes formula.
Let's test how accurate our price was by plugging in the parameters from our simulation:
>>> from scipy.stats import norm >>> from math import exp, log, sqrt >>> S, K, v, r, T = 100.0, 100.0, 0.2, 0.01, 0.5 >>> d2 = (log(S/K) + (r - 0.5 * v**2) * T) / v*sqrt(T) >>> print exp(-r * T) * norm.cdf(d2) 0.490489409105
So the Black Scholes formula gives us a price of around $0.490. Meaning our simulation was off by only $0.006.