Advanced Crypto Price Simulations based on Monte Carlo

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.

Additional disclaimer: This is no investment advice or encouragement to buy crypto. Please, do your own research before investing. This tutorial is only for educational purposes.

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)   \begin{equation*} dS_{t} = \mu S_t dt + \sigma S_t dW_t.  \end{equation*}

Here, \mu denotes the mean and it’s the drift term. Furthermore, \sigma represents the variance, while it’s the diffusion term. Finally, the last term dW_t 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 S using the Geometric Brownian motion (GBM):

(2)   \begin{equation*} dS_{t} = \mu S_t dt + \sigma S_t dW_t.  \end{equation*}

Afterwards, we can solve it analytically:

(3)   \begin{equation*} S_{t} = S_0 \exp{(\mu - 0.5 \sigma^2) t + \sigma W_t}.  \end{equation*}

For more details have a look at [1].

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)   \begin{equation*} r_t = ln \frac{S_{t+1}}{S_t}.  \end{equation*}

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
#License: MIT License (http://opensource.org/licenses/MIT)

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)
        prices.append(Price) #Add random new price and add to list
        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.

Comparison simple Monte Carlo and Brownian motion
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.
Price dips ETH last 200 days
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 J dq_t (for details have a look at [2]):

(5)   \begin{equation*} dS_{t} = \mu S_t dt + \sigma S_t dW_t + J dq_t.  \end{equation*}

Here, J is the jump size which is J \sim N(\mu, \sigma^2) and it is log-normal. Furthermore, dq_t is a Poisson process. This means,

(6)   \begin{equation*}    dq_t =    \begin{cases}      1 & \text{with probability } P \\      0 & \text{with probability } 1-P.    \end{cases} \end{equation*}

We can calculate N(\mu, \sigma^2) using the following Numpy function.

sigma * np.random.randn() + mu

Afterwards, we can calculate the jump size J 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
#License: MIT License (http://opensource.org/licenses/MIT)

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
        prices.append(Price) #Add random new price and add to list
        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.
Brownian motion jumps
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.
Brownian motion jumps histogram
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

[1] 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

[2] 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

What do you think?

I’d like to hear what you think about this post.

Let me know by leaving a comment below and don’t forget to subscribe to this blog!