 # Advanced Crypto Price Simulations based on Monte Carlo

In this post I will deepen crypto price simulations based on Monte Carlo. Therefore, a Brownian motion model including jump diffussion will be considered. Furthermore, we will use the cryptocurrency Ethereum for price simulations to compare various methods.

### Theoretical Introduction

Let’s start with some definitions. A differential equation that contains a stochastic term is called a stochastic differential equation. Furthermore, a stochastic process is a collection of random variables. For example, a Random walk is a stochastic process. A stochastic differential equation can have the following form:

(1) Here, denotes the mean and it’s the drift term. Furthermore, represents the variance, while it’s the diffusion term. Finally, the last term denotes a Wiener process. It is a continuous-time stochastic process like the Brownian motion.

### Brownian Motion

In physics a Brownian motion describes the random motion of particles in a fluid. This motion is caused by the collision of particles among themselves. Therefore, it is used in physics and finance to model random behavior that’s evolving over time. Hence, it is used to model uncertainty.

Let’s consider the following stochastic differential equation for the change in price using the Geometric Brownian motion (GBM):

(2) Afterwards, we can solve it analytically:

(3) For more details have a look at .

### Compare Brownian Motion with simple Monte Carlo

Let’s compare the method from the Simple Monte Carlo article with the Brownian motion approach. Here, the returns are calculated as log-returns and therefore defined as:

(4) Hence, the Python snippet for the log-return, mean and volatility looks like the following.

returns = np.log(df.close) - np.log(df.close.shift(1)) #logarithmic return
meanReturn = np.mean(returns)
volatility = returns.std()

Therefore, we use the following Python snippet which we can add to the script from the Simple Monte Carlo article.

#Author: johannes <info@numex-blog.com>, 29.12.17

while (sim < numberSimulations):

prices = [] #Empty list for each new simulation
days = 0 #reset days counter
prices.append(lastPrice) #Fill list with initial price
timeStep = 1

while (days < predictedDays):

drift = (meanReturn - volatility**2/2)*timeStep
shock = volatility * np.random.normal() * timeStep**0.5

Price = prices[days] * np.exp(drift+shock)
days = days + 1 #increment days counter

results[str(sim)] = pd.Series(prices).values #Add column to pandas data frame
sim = sim + 1 #increment simulation counter
Furthermore, we need some input data to run the simulation:

• Cryptocurrency: Ethereum,
• Initial price (Kraken): 950.89 € (29.01.18),
• Volatility of logarithmic daily return of past time frame (200 days): 6.29 %,
• Number of simulations per method: 5000,
• Simulated time period: 30 days. Let’s have a look the results. It is abvious, that the price prediction using the Brownian motion is more optimistic compared to the simple Monte Carlo simulation. Furthermore, for the Brownian motion simulation the 25 % quantile is 915.63 €, while the the 75 % quantile is 1444.55 €. For the simple Monte Carlo simulation the 25 % quantile is 711.38 €, while the the 75 % quantile is 1133.85 €.

In addition, there are some limitations regarding the Brownian motion:

• The price movement is continuous e.g. price swings are not considered.
• Also, it assumes a constant volatility over time.

Therefore, let us analyse the price swings (jumps) of the cryptocurrency Ethereum within a past period (04.02.2018 minus 200 days).

### Price Jump Analysis of Ethereum

First, let’s have a look at the price of the last 200 days (04.02.2018 minus 200 days) of the cryptocurrency Ethereum. I marked the significant price dips with black lines. Here we are just consider plummeting NOT surging prices. We recognize 7 price jumps within the considered time period.

1234567
71 €142 €74 €284 €148 €129 €123 €
Therefore, we can calculate the following in order to tune the input data for the simulations:

• Probability of a jump: 0.035 (7 events/200 days),
• Mean jump size: 138.71 €,
• Volatility of jump size: 65.8 €.
#Probability of a jump
probability = 0.035

jumps = [70.96, 141.93, 74.19, 283.87, 148.38, 129.03, 122.58]
volatilityJumps = np.std(jumps)
meanSizeJumps = np.mean(jumps)

#Mean jump size
mu = -meanSizeJumps

#Volatility of the jump size
sigma = volatilityJumps

### Merton’s Jump Diffusion Model

The idea behind Merton’s jump diffusion model is that price movements underlie sudden changes. Therefore, it adds a jump component to the Brownian motion model. Hence, we can use it to model sudden changes in crypto or stock prices. The relevant differential equation differs from the Brownian motion equation by the last term (for details have a look at ):

(5) Here, is the jump size which is and it is log-normal. Furthermore, is a Poisson process. This means,

(6) We can calculate using the following Numpy function.

sigma * np.random.randn() + mu

Afterwards, we can calculate the jump size using the following code.

def jump(probability, meanSize, volatility):
jumpsize = meanSize + volatility*np.random.randn()
return decision(probability)*jumpsize

Furthermore, we can map the occurrence of an event under consideration of a probability (Poisson process) using the following Python function.

def decision(probability):
return int(np.random.random() < probability)

### Set up the Python Script

Now, let’s run the jump diffusion simulation. Therefore, we use the following input data:

• Date: 11.02.18,
• Last price: 683.48 €,
• Coin: Ethereum (ETH),
• Exchange: Kraken
• Past time frame: 200 days
• Volatility in time Frame: 0.0616
• Simulated time frame: 60 days.

In case you need some help to run Python scripts have a look at the HOWTO.

In order to run the simulation, the remaining Python code can be found in this article. Just add the following code snippet.

#Author: johannes <info@numex-blog.com>, 22.12.17

results = pd.DataFrame()

sim = 0

while (sim < numberSimulations):

prices = [] #Empty list for each new simulation
days = 0 #reset days counter
prices.append(lastPrice) #Fill list with initial price
timeStep = 1

while (days < predictedDays):

drift = (meanReturn - volatility**2/2)*timeStep
shock = volatility * np.random.normal() * timeStep**0.5
jmp = jump(probability, mu, sigma)

Price = prices[days] * np.exp(drift+shock)
Price = Price + jmp
days = days + 1 #increment days counter

if(prices[-1] > 0):
results[str(sim)] = pd.Series(prices).values #Add column to pandas data frame

sim = sim + 1 #increment simulation counter

### Interpreting the Results

First, let us compare the Brownian motion simulation with the Brownian motion including the jump diffusion. Therefore, we simulate 5000 price progressions for both types of simulations. The final prices are in a similar price range. But the final price of the Brownian motion with jumps can go below a price of 0. Therefore, price progressions with a final price below 0 are excluded.

Afterwards, we plot the histograms of both simulations to get a better picture of the results. Furthermore, let’s highlight the 25 % and 75 % quantiles. Now, we can see it more clearly, the Brownian motion simulations are more progressive, while the jump diffusion simulations consider downtrends. Therefore, the jump diffusion results are more conservative.

• Brownian motion and jump diffusion: quantile 25 %: 362.16 € and quantile 75 %: 936.41 €.
• Brownian motion: quantile 25 %: 661.59 € and quantile 75 %: 1248.87 €.

### Conclusion

Stochastic differential equations can be used to simulate prices of stocks and cryptocurrencies. A Brownian motion simulation can be used to model the random behavior that’s evolving over time. By adding a jump difussion component, discontinuous downward trends are considered.

Here, we considered just negative jumps. Furthermore, we counter a too strong uptrend in the price. Hence, the Brownian motion simulations are more progressive, while the jump diffusion simulations consider downtrends which makes them more conservative and realistic.

In general cryptocurrency prices are still extremely volatile. Therefore, it is questionable in what way future prices can be simulated. Futhermore, be careful with too long simulation time frames.

Finally, all simulations still have a constant volatility, which is a strong simplification. I will tackle this issue in future post.

In case you need some help to run Python scripts have a look at the HOWTO.

### Sources

 Reddy, Krishna and Clinton, Vaughan, Simulating Stock Prices Using Geometric Brownian Motion: Evidence from Australian Companies, Australasian Accounting, Business and Finance Journal, 10(3), 2016, 23-47. doi:10.14453/aabfj.v10i3.3

 Alvaro Cartea and Marcelo G. Figueroa, Pricing in Electricity Markets: a mean reverting jump diffusion model with seasonality: Birkbeck College and University of London, 2005. https://e-archivo.uc3m.es/bitstream/handle/10016/12137/pricing_cartea_2005.pdf