Simple Monte Carlo Options Pricer In Python

Pre-Requisites:

Below is a list of pre-requisite knowledge to get the most out of this tutorial.

Required:

  • Calculus
  • Probability and Statistics
  • Very basic programming

Recommended:

  • Stochastic Processes
  • Stochastic Calculus or an introductory asset pricing class

Understanding The Math

Before diving into the code, we’ll cover some of the basic financial mathematics necessary to understand the model.

Assumptions

In our model we will make the following assumptions.

  • The expected return is a fixed rate of the current share price
  • The stock follows a random-walk behavior

The Stock Price Evolution Model

We will be using a stochastic differential equation as the model of our stock price evolution. It will consist of a component representing the expected return on the stock Sₜ over an infinitesimal period of time dt, represented by:

Black-Scholes Option Pricing Model

The Black-Scholes option pricing model tells us the the price of a vanilla option with a compounding rate r , expiration T and payoff function f is:

Solving for Expectation

In order to finish deriving an expression for our fair options price, we must solve the expression within the expected payoff function. To begin with, we will use a risk-neutral stochastic differential equation (see stock price evolution model) for the expectation of Sₜ:

Final Expression

Our final expression for the fair price of the option will be the above expression multiplied by e⁻ʳᵗ to complete our original black Scholes model.

The Code

import math
import random

class SimpleMCPricer():
def __init__(self, expiry, strike, spot, vol, r, paths):
#The sigma value on the left side of the exponent
self.variance = vol**2 * expiry
#The sigma value on the right side of the e exponent
self.root_Variance = math.sqrt(self.variance)
#Corresponds to the (-1/2 * sigma^2)
self.itoCorr = -0.5*self.variance
##Corresponds to S0e^(rT - 1/2 sigma^2T)
self.movedSpot = spot*math.exp(r*expiry + self.itoCorr)
self.runningSum = 0
##Simulate for all paths
for i in range(0,paths):
thisGauss = random.randrange(0,1000,1)
thisGauss = thisGauss/1000
##Our rootVariance already has been multiplied by the expiry
thisSpot = self.movedSpot*math.exp(self.root_Variance*thisGauss)
#Determine payoff of this specific path
thisPayoff = thisSpot - strike
#Value of option is zero is our price is less than the strike
thisPayoff = thisPayoff if thisPayoff > 0 else 0
self.runningSum+=thisPayoff

self.mean = self.runningSum/paths
self.mean*= math.exp(-r * expiry)

def getMean(self):
return round(self.mean,2)

Run the Model!

Let us run the model on an option with expiration in 2 years, with a strike price of 32 dollars, a current price of 30 dollars, a 10% volatility parameter, and a 3% rate of return. We will simulate 1,000,000 paths and determine the fair price.

model = SimpleMCPricer(2,32,30,.1,0.03,1000000)
model.getMean()
1.79

Sources and Further Reading

[1] C++ Design Patterns and Derivatives Pricing, Mark S. Joshi

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store