Code and Finance

Extending our model to price binary options

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.

Binary 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.

/attachments/binary_payoff.png

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

Simulation

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

Checking our results

Binary options can also be priced using the traditional Black Scholes model, using the following formula:

\begin{equation*} C = e^{-rT}N(d_2) \end{equation*}

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.