Monte Carlo Options Pricing in Two Lines of Python
By: Aaa Quants
Tags: Trading, Python, Data Science, Quantitative Finance, Options Trading

Whether it’s for protecting capital, earning profit from speculation or buying time to decide, options provide a wonderful tool for investors and traders. We can think of options as a kind of insurance and simply put, we insure an underlying instrument against a price drop or increase.

Like with a car insurance, if the car is very expensive, the insurance will be more expensive. The same is true if the period of the insurance is longer or the driver is inexperienced. In options lingo, we call the former expiry and the latter volatility.

To be more precise, we can’t really check how good a driver will be in the future (or how reckless they might be), so we guess the level of their driving skills and call this implied volatility.

A call option gives you the right (but not the obligation) to buy one (or multiple) shares of the underlying stock for a specific price — the strike price. So, if you hold a call option with a strike price of $100 and the spot price of the stock goes up to $105 you could “exercise” your option and buy the stock for $100 and immediately sell it again for $105 making a profit of $5 minus the premium paid for the option.

Put options work in a similar fashion, only now we have the right (but not the obligation) to sell one (or multiple) shares of the underlying stock for a specific price. So, if you hold a put option with a strike of $100 and the price drops to $95 you could exercise your option to sell the stock short for $100 and immediately buy it back for $95; making a $5 profit minus the options premium. We can see that with put options we can make money when the market goes down.

However, most of the time options are not exercised but simply traded on an exchange. While it is quite clear how much an option is worth when it is exercised, when we trade it we need to dive a bit deeper into the mathematics.

Options pricing

The parameters such as expiry and volatility can now give us some ideas on the fair price to pay for our option when we trade it on an exchange.

For the most common type of options, also known as vanilla options, there exists a closed-form solution — based on the famous Black-Scholes equation. The Black-Scholes equation is a stochastic partial-differential equation similar to the heat equation in physics. It requires a solid understanding of stochastic calculus to find the analytic solution as shown below for a call option:

This is nice, but it is not exactly easy and intuitive to understand what’s going on here unless you are a devoted math-whizz. Monte Carlo (MC) simulations can give us not only a more intuitive understanding of the reasoning behind options pricing but also an easier way to pricing the following:

A. Options with non-normal return distributions;

B. More complex (exotic) options contracts

In this article, we will show you the principle of pricing vanilla options with Monte Carlo simulations. As a sequel to this, we will look at the more complex cases A and B in next article.

Option Types

Whilst we are only talking about pricing vanilla options in this article we would like to make you aware of the “universe” of different contracts that exist out there.

As mentioned above, options roughly fall into two categories: vanilla and exotic.

Vanilla options are equivalent to our good old car insurance. They can be divided into American and European styles. American style means the options can be exercised any time before and including the day of expiration. On the other hand, European style options can only be redeemed or exercised on expiry.

There exists a wide range of exotic options. They are similar to vanilla options but with some special features. Binary options, for example, have a very simple, binary payoff structure and for that reason they are very popular with retail traders. Once you understand the process of building a MC pricing engine for vanilla options, it will be quite intuitive to build them for various types of exotic options as well.

Monte Carlo

Have a look at the formula below, which was taken from a research paper on building a closed form solution for barrier options, a type of exotic options. This is only one of 14 pages of dense mathematics and probably inaccessible for most quantitatively inclined traders unless you have a PhD in maths.

Closed-form solution for Barrier Options.

However, the caveat of most of the analytical approaches is that they assume a normal distribution of returns in the underlying. This is well-known to be a weak assumption, to say the least. In plain English, a normal distribution greatly underestimates the “tail risk”, i.e. the risk of a large adverse price movement.

Monte Carlo simulation can provide an alternative approach and whilst computationally more intensive and somewhat slower, it is very versatile in finding answers to more complex problems. Furthermore, it will really help us to understand the underlying principles of pricing options contracts.

Python in Action

Let’s start building a Monte Carlo options simulation in Python. You will see at the end that the whole simulation can be reduced to a mere two lines of code. Not bad for something that sounds so complex, right?

To start with, let’s define some parameters.

We will set our expiry to 252 days in the future, which is the approximate number of trading days in one year. We will run 100000 simulations, which sounds a lot but the Numpy package handles it quite fast. The starting price of our underlying stock is $100. The strike price is $100 as well. Finally, we assume an annualised volatility of 15% for the price of our underlying security. Since we cannot predict the future, this value is likely not to be accurate going forward but rather the current consensus of what traders think the volatility will be. It is therefore called implied volatility.

Creating the Return Paths

Next comes the Monte Carlo part of our pricing model.

Once we have defined the parameters, we can now generate a large number of paths that the price of a stock could take from an initial starting price. To do this we create an array of 100,000 x 252 normally distributed random numbers, representing daily percentage returns of our underlying security.

We generate normally distributed random numbers with a standard deviation of 1 and therefore we need to scale them with our implied daily volatility. Volatility roughly increases with the square root of time, so in order to scale our daily returns we divide our annualised volatility by the square root of 252, the number of trading days in a year.

As mentioned previously, the assumption of normally distributed returns is very common in quant finance but not necessarily very good as it underestimates the probability of Black-Swan events. We can see that in the step above, we can easily substitute our normal distribution with any other distribution that may seem more realistic without paying much of a penalty for complexity.

The Price Cone

We can now visualise the price paths as the cumulative product of our returns. Be sure to add 1 to the returns, otherwise all paths will cause the returns to rapidly converge to zero. We finally multiply this with our starting price of $100 to get a realistic price cone.

Our plot shows that the price paths form a characteristic cone shape. Note that when a price path approaches zero, our total price changes in dollars for the same percentage change, will naturally be smaller too. This is the reason why the cone does not quite look symmetrical.

Distribution of Final Prices

Let’s plot what the distribution of prices at expiry looks like. From the histogram of the final prices in our paths we can see the previously mentioned asymmetry in the price distribution very clearly.

This distribution is very important in determining the price of our option as shown in the next section.

Pricing of a Vanilla Call Option

To price our vanilla call option, we calculate the differences between the final prices and our strike and set all prices that end up below the strike to zero. Prices below the strike are worthless at expiry, since we would exercise our right to buy the underlying for a price that is higher than the market price (and lose money). Our options price is now simply the average of all the final price differences as shown below.

We can see that in the case of a 1-year expiry, a strike and spot price of $100 and an annual implied volatility of 15%, our option is worth $5.96. Before we move on, we’d better verify that this is correct.

Verify the Call Price

Let’s use an online Black-Scholes options price calculator for verification. Note that this calculator uses the actual number of days in a year rather than the trading day. This is because in the analytic solution expiry is expressed as the number of days to expiry divided by the number of days in one year. So a 6 months expiry would give us a parameter of 0.5 for the analytical solution.

We can see that our solution is well within 1% accuracy, NICE!

If we increase the number of simulation paths to a million, our accuracy would be even better but also our simulation time.

Vanilla Put Option

We can now easily calculate the price of a vanilla put option. This time we set all the prices larger than the strike to zero and subtract the final values from the strike, otherwise we would be getting a negative result.

We can see that this also agrees well with the online calculator.

Including the Risk-Free Rate

In the current markets, interest rates are generally very close to zero and could be neglected. However, this is not always the case and you can see in the online calculator and the analytical Black-Scholes model that the risk-free rate (in the US this is the interest rate on the T-Bills) is considered in the pricing model. So let’s see how we can add this to our MC simulations. In order to do this, we wrap our entire simulation into a simple function. All we need to do now is to calculate a discount-factor D and multiply it with our strike price. Essentially, D denotes the amount of money we have lost by not holding cash at the amount of the strike price. In the calculation below we assume a risk-free rate of 2%.

After calculation, we’d better check online if our calculations are correct, and voila, a very good match!

Did you like what you read? Join us at Quantitative Trading Like a Pro: Essential Python Course, to learn more cool tricks!

Conclusion

As your homework, you can write the entire model in two lines of Python, one to produce the price cone and another to calculate the put or call price. I would encourage you to play with the simulations and see if you understand the underlying principles.

Stay tuned!

In the follow-up article we will show you how to price exotic (barrier) options in a few simple steps.

Happy trading!

Let’s connect!

AAA Quants: http://aaaquants.com/

A note from the Plain English team

Did you know that we have four publications? Show some love by giving them a follow: JavaScript in Plain English, AI in Plain English, UX in Plain English, Python in Plain English — thank you and keep learning! We’ve also launched a YouTube and would love for you to support us by subscribing to our Plain English channel

And as always, Plain English wants to help promote good content. If you have an article that you would like to submit to any of our publications, send an email to submissions@plainenglish.io with your Medium username and what you are interested in writing about and we will get back to you!