Introduction to Monte Carlo Simulation

What is Monte Carlo Simulation?

Monte Carlo simulation uses random sampling and statistical modelling to estimate mathematical functions and mimic the operations of complex systems [i]. Named after the Monte Carlo Casino in Monaco, this method was first used systematically by scientists working on the atom bomb in World War II. It was first developed by mathematician Stanislaw Ulam[ii] and in modern day it is frequently used in decision making processes in a wide range of fields from energy to finance to engineering and more.

But how does this relate to the field of quant trading?

In quantitative trading, Monte Carlo simulation is a form of backtest used to model possible movements of an asset’s price and to predict future prices. It helps traders understand the probability of different outcomes so that they can make an informed decision.  The method uses a random number from 0 to 1 which represents a probability on how your portfolio might do in the first year, second year so on. Then it re-randomises again and goes through the same process over and over. Of all of the thousands or hundreds of models that are run, a trader will look at the percentage of outcomes that were successful. Overall, it simulates many potential outcomes, provides the trader with the probability of success and helps measure the robustness of a trading system.

Getting Technical: The Calculation of Monte Carlo

Let’s take a closer look at the math behind Monte Carlo simulation. Using this method, you can calculate the price today by taking yesterday’s prices multiplied by e to the power of drift plus the random value. Drift is the direction rates of return have been headed in the past and the random value represents volatility.

Put simply… r is the return of the asset price between yesterday and today. So we will try to predict today’s price by taking yesterday’s price times the log return of the asset. In this equation, r is unknown so the first step is to use Brownian motion to model r.

What is Brownian motion?

In physics, Brownian motion is a process used to describe random movement[iii] and in finance, it is used to model randomness. There are two parts to random movement – a deterministic component and a random stochastic component[iv]. These two components combine to create the observed movement. Brownian motion has been applied to the price of an asset because it is said that price follows a continuous Brownian motion. In today’s example, the deterministic component will be the drift and the stochastic component will be the volatility.

To model r, we use drift and the random component which represents volatility. The Brownian motion is:

First you need drift. This is the direction rates of return have been headed in the past. Drift is calculated by taking the average daily return minus half of the variance (this is the expected daily return of the instrument we are trading). Remember, the equation looks like this:

Next you need to add volatility. The volatility or the random value is calculated by taking the standard deviation of Z and random number from 0-1. Since we are running a series of potential outcomes, we will use multiple random numbers between 0-1. These random numbers from 0 to 1 will be our probabilities as a percent and Z is the number of standard deviations away from the mean.

Once you have those two pieces of the puzzle (drift and random value) you can move on to running the simulation. You will repeat the simulation a few hundred or even thousands of times to model possible movements of an asset’s price to help predict future prices.

Applying Monte Carlo Simulation in Python

All of these calculations can be done using Python and a few libraries. Most professional traders will run a Monte Carlo simulation in their trading strategy of as part of their vetting process before releasing it on the live market. In today’s example, we will just run through a general example on the daily rate of the EUR/USD.

The initial step is to import the required libraries for the Monte Carlo simulation. Pandas and numpy will be used for data manipulation and matplotlib will be used for plotting the price of the instrument and our returns. I will be importing the FXCMpy wrapper so that I can easily pull FXCM historical data. Lastly, Scipy’s norm.ppf is used to obtain Z.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import norm
%matplotlib inline
import fxcmpy
import datetime as dt

We need to connect to a demo account to pull the historical data we will need for the simulation. If you have not done this step yet, follow the instructions on this page and revert back.  The data pulled will be the bid close from May of 2017 until December of 2018.

socket = fxcmpy.fxcmpy(config_file = 'fxcm.cfg')
instrument = 'EUR/USD'
data = socket.get_candles(instrument=instrument, period = 'H1', start = dt.datetime(2017,5,7), end = dt.datetime(2018, 12, 10))['bidclose']
data.plot(figsize=(12, 7));


We just charted the daily rate of the EUR/USD over the test period. We will calculate the historical log returns as a daily percent change using the below code. Logarithmic returns are calculated by taking the log of the simple returns as a percent. We can then verify that it is calculated by printing out the last 5 or the tail of the log returns.

log_returns = np.log(1 + data.pct_change())
log_returns.tail()

The next step is to calculate the mean or the average daily return. The numpy function .mean can be used to calculate this.

u = log_returns.mean()
u

In the same way, the variance can be calculated using the .var function

var = log_returns.var()
var

Now that variance and the mean have been calculated, we can finish calculating drift. Remember that drift is the mean minus half the variance or.

drift = u - (0.5 * var)
drift

The next piece of the puzzle that needs to be calculated is the standard deviation of the log returns. This can easily be calculated and saved as stdev like the code below.

stdev = log_returns.std()
stdev

Remember our original equation we are using to solve for r?

So far we have calculated the drift and the standard deviation. Now we just need to calculate Z which is the distance from the mean in standard deviations. Essentially it is used to calculate the distance from the mean with each of these randomly generated probabilities. We will then run our random probabilities from 0 to 1 through the argument. We use norm from scipy using Norm.ppf which allows us to obtain Z. For example, if an event has 75% of occurring, then the distance from the event to the mean is 0.67 standard deviations.

norm.ppf(0.75)

So these are all of our randomly generated probabilities. We will run 10 iterations of potential rates for 1000 days. Therefore the daily rates output will be a multi-dimensional array of 1000 rows by ten columns. Np.exp will let us take e to the power of r which will be the drift plus the stdev that we already calculated times the norm.ppf (which is our standard deviation). The rand function will be used to fill it will probabilities from 0 to 1.

days = 1000
iterations = 10
daily_returns = np.exp(drift + stdev * norm.ppf(np.random.rand(days, iterations)))
daily_returns

The output is our random daily EUR/USD prices which is . A few more steps and this calculation is complete.   Remember how today’s price = yesterday’s price * .?  Since that is calculated, “yesterday’s price” needs to be pinpointed and then we just need to repeat the process and plot the results in order to finish the simulation. We will use the .iloc method to define our starting point at S0.

S0 = data.iloc[-1]
S0

With the first price pinpointed, it will be used as the starting point of each of the ten iterations. As mentioned before, the results of the Monte Carlo simulation will be calculated in an array so the starting point will be 1.13752 in the first row.  We need to set up the framework so we can run a loop through all of the iterations. The framework will be created using np.zeros_like and the arguments will be the daily returns or

price_list = np.zeros_like(daily_returns)
price_list[0] = S0
price_list

The object is set up so now we run a loop to fill it with the expected EUR/USD rates. The price today is equal to the price yesterday times the daily return. The loop looks like this:

for d in range(1, days):
     price_list[d] = price_list[d - 1] * daily_returns[d]
price_list

Then it is simply plotted out using matplotlib to show the ten possible paths of the currency pair over 1000 days.

plt.figure(figsize=(10,6))
plt.plot(price_list);

As you can see from the graph, the ten iterations show the potential rates (Y –axis) over the next 1,000 days (X-axis).  As mentioned earlier, this is just a general overview on the application of a Monte Carlo simulation on the rate of the EUR/USD. This method can be applied to trading strategies to help predict how a strategy may perform in the future. You can access the full code at Github here.

 

GET YOUR FREE API TOKEN AND START ALGO TRADING WITH PYTHON!

To generate your API token:

  1. Register for a free practice account here.
  2. Log into fxcm.com and click on the account ID in the upper right corner.
  3. Click token management and generate your token.

 

[i]Introduction to Monte Carlo Simulation https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2924739/

[ii] Monte Carlo Simulation by MIT OpenCourseWare https://www.youtube.com/watch?v=OgO1gpXSUzU

[iii] Understanding Brownian Motion  https://www.youtube.com/watch?v=8AAEbIRMMNg

[iv] Understanding Brownian Motion https://www.youtube.com/watch?v=8AAEbIRMMNg


Risk Warning: The FXCM Group does not guarantee accuracy and will not accept liability for any loss or damage which arise directly or indirectly from use of or reliance on information contained within the webinars. The FXCM Group may provide general commentary which is not intended as investment advice and must not be construed as such. FX/CFD trading carries a risk of losses in excess of your deposited funds and may not be suitable for all investors. Please ensure that you fully understand the risks involved.