Files
strategy-lab/to_explore/pyquantnews/8_GeometricBrownianMotion.ipynb
David Brazda e3da60c647 daily update
2024-10-21 20:57:56 +02:00

7.9 KiB

No description has been provided for this image

This code simulates Geometric Brownian Motion (GBM) to model asset price paths over time, incorporating randomness and volatility in financial markets. It defines functions to generate a Wiener process (representing Brownian motion) and to compute GBM returns and price levels. Parameters such as initial stock price, volatility, drift, and the number of paths and time increments are used to create and visualize multiple simulated price trajectories. This is useful in practice for financial modeling, risk analysis, and forecasting asset prices.

In [ ]:
import numpy as np
import matplotlib.pyplot as plt

Define initial stock price, volatility, and drift parameters for the Brownian motion

In [ ]:
s0 = 131.00
sigma = 0.25
mu = 0.35

Define simulation parameters including number of paths, time increment, and total simulation time

In [ ]:
paths = 1000
delta = 1.0 / 252.0
time = 252 * 5

Generate a Wiener process (or Brownian motion) using normally distributed random values. This process simulates the random fluctuations of an asset's price over time, which is essential for modeling the stochastic component of Geometric Brownian Motion.

In [ ]:
def wiener_process(delta, sigma, time, paths):
    """Returns a Wiener process
    
    Parameters
    ----------
    delta : float
        The increment to downsample sigma
    sigma : float
        Percentage volatility
    time : int
        Number of samples to create
    paths : int
        Number of price simulations to create
    
    Returns
    -------
    wiener_process : np.array
    
    Notes
    -----
    This method returns a Wiener process. 
    The Wiener process is also called Brownian 
    motion. For more information about the 
    Wiener process check out the Wikipedia 
    page: http://en.wikipedia.org/wiki/Wiener_process
    """

    # Generate a Wiener process using normally distributed random values
    return sigma * np.random.normal(loc=0, scale=np.sqrt(delta), size=(time, paths))

Generate returns from a Geometric Brownian Motion (GBM) model by first creating a Wiener process to simulate random fluctuations.

In [ ]:
def gbm_returns(delta, sigma, time, mu, paths):
    """Returns returns from a Geometric brownian motion
    
    Parameters
    ----------
    delta : float
        The increment to downsample sigma
    sigma : float
        Percentage volatility
    time : int
        Number of samples to create
    mu : float
        Percentage drift
    paths : int
        Number of price simulations to create
    
    Returns
    -------
    gbm_returns : np.ndarray
    
    Notes
    -----
    This method constructs random Geometric Brownian 
    Motion (GBM).
    """

    # Generate Wiener process for the simulation
    process = wiener_process(delta, sigma, time, paths)

    # Apply the geometric Brownian motion formula to generate returns
    return np.exp(
        process + (mu - sigma**2 / 2) * delta
    )

Calculate price paths starting from an initial stock price (s0) using Geometric Brownian Motion (GBM)

In [ ]:
def gbm_levels(s0, delta, sigma, time, mu, paths):
    """Returns price paths starting at s0
    
    Parameters
    ----------
    s0 : float
        The starting stock price
    delta : float
        The increment to downsample sigma
    sigma : float
        Percentage volatility
    time : int
        Number of samples to create
    mu : float
        Percentage drift
    paths : int
        Number of price simulations to create
    
    Returns
    -------
    gbm_levels : np.ndarray
    """

    # Generate GBM returns for the given parameters
    returns = gbm_returns(delta, sigma, time, mu, paths)

    # Stack an array of ones with the returns and compute cumulative product to get price levels
    stacked = np.vstack([np.ones(paths), returns])
    return s0 * stacked.cumprod(axis=0)

Generate price paths using the defined GBM model and plot them

In [ ]:
price_paths = gbm_levels(s0, delta, sigma, time, mu, paths)
plt.plot(price_paths, linewidth=0.25)
plt.show()

Generate price paths with zero drift to observe behavior and plot them

In [ ]:
price_paths = gbm_levels(s0, delta, sigma, time, 0.0, paths)
plt.plot(price_paths, linewidth=0.25)
plt.show()

PyQuant News is where finance practitioners level up with Python for quant finance, algorithmic trading, and market data analysis. Looking to get started? Check out the fastest growing, top-selling course to get started with Python for quant finance. For educational purposes. Not investment advise. Use at your own risk.