Simulating stock prices using GBM

Discussion in 'App Development' started by earth_imperator, Jul 27, 2023.

  1. M.W.

    M.W.

    You are expecting the GBM to perform functions it was never set out to perform. By the way, you still have not clarified what exactly you disagree with in provided solutions. You made similar outrageous claims about other models in the past and each time you were schooled and proven wrong...whats new this time?

     
    #11     Jul 28, 2023
  2. Elaborate & explain please.

    BS, I've always been right! Just show me where I was supposedly wrong.
     
    #12     Jul 28, 2023
  3. Sergio123

    Sergio123

    GBM by itself is just a base model. You need to add a dynamic risk free rate and simulate the option chain to develop an accurate real word Algo trading system. GBM.PNG
     
    #13     Jul 28, 2023
  4. @Sergio123, it's about GBM itself. The versions I so far tested are all buggy. It much looks like that the well known GBM algorithm(s) in use are all generally buggy in the first place.
    And a const r, q, s is ok for me.
     
    Last edited: Jul 28, 2023
    #14     Jul 28, 2023
  5. This looks very much professional. I'll study & test it. Thank you very much.

    Hmm. I just quickly skimmed over the code, but I'm not sure whether this is really a normal GBM algorithm.
    One has to know that there is also just "Brownian Motion" w/o the "Geometric" part, aka ABM, or Arithmetic Brownian Motion.
    Need to take more time to study it.

    Since there is not a single mentioning of "geometric", then I assume it's not GBM, othweise they would/should explicitly state "geometric". It's just missing.... :-(
     
    Last edited: Jul 28, 2023
    #15     Jul 28, 2023
  6. ph1l

    ph1l

    Here is one with geometric in the title.
    https://towardsdatascience.com/geometric-brownian-motion-559e25382a55
    Code:
    import matplotlib.pyplot as plt
    import numpy as np
    import math
    
    
    class GBM:
    
        def simulate(self):
            while(self.total_time > 0):
                dS = self.current_price*self.drift*self.time_period + self.current_price*self.volatility*np.random.normal(0, math.sqrt(self.time_period))
                self.prices.append(self.current_price + dS)
                self.current_price += dS
                self.total_time -= self.time_period
    
        def __init__(self, initial_price, drift, volatility, time_period, total_time):
            # Initialize fields
            self.initial_price = initial_price
            self.current_price = initial_price
            self.drift = drift
            self.volatility = volatility
            self.time_period = time_period
            self.total_time = total_time
            self.prices = []
            # Simulate the diffusion process
            self.simulate()   # Simulate the diffusion proces
    
    simulations = []
    n = 1000
    initial_price = 500
    drift = .24
    volatility = .4
    time_period = 1/365 # Daily
    total_time = 1
    
    for i in range(0, n):
        simulations.append(GBM(initial_price, drift, volatility, time_period, total_time))
    
    for sim in simulations:
        plt.plot(np.arange(0, len(sim.prices)), sim.prices)
    
    plt.show()
    
     
    #16     Jul 28, 2023
  7. @ph1l at al, there are many GBM articles and code on the net, but I need the opinion of experts with hands-on-experience about the quality of the code and algorithm used.
    If you are sure & convinced that the algorithm and code is correct then we can focus on it and test further.

    Can you math guys check/verify this new code linked by @ph1l with the wikipedia GBM page.
    What difference in the algorithm is there, if any?
     
    Last edited: Jul 28, 2023
    #17     Jul 28, 2023
  8. This algorithm & code is interesting as it doesn't use any log(), ln(), e(), or exp() :)
    That's very unusual and different from other GBM algos.
    I'm now going to test this GBM algo in my test framework...
     
    Last edited: Jul 29, 2023
    #18     Jul 29, 2023
  9. This algorithm cannot be correct b/c it generates negative stock prices! :) This never ever should happen :)
    Code:
    Settings used:
      n             = 1000
      initial_price = 500
      drift         = 0.0
      volatility    = 1.5
      time_period   = 0.5       # ie. 2 per year
      total_time    = 1.0       # 1 year
    
    Plot:
    pyGBM_wrong.png

    Maybe someone inform the author (Roman Paolucci) about this finding so that he maybe can try to fix his algorithm. Link to his article and code is in prev posting.
     
    Last edited: Jul 29, 2023
    #19     Jul 29, 2023
  10. ph1l

    ph1l

    Here's one where the author first codes standard Brownian motion.
    https://isquared.digital/blog/2020-04-16-brownian-motion/
    Then he uses that for drifted Brownian motion.
    https://isquared.digital/blog/2020-05-01-drifted-brownian-motion/
    And finally, he uses drifted Brownian motion to implement geometric Brownian motion
    https://isquared.digital/blog/2020-05-17-geometric-brownian-motion/#:~:text=Definition of Geometric Brownian Motion&text=This process follows a log,characteristic, they are never negative.
    including avoiding negative values.
    upload_2023-7-29_8-43-37.png
    Code:
    import numpy as np
    np.random.seed(1234)
    
    def brownian_motion(N, T, h):
        """
        Simulates a Brownian motion
        :param int N : the number of discrete steps
        :param int T: the number of continuous time steps
        :param float h: the variance of the increments
        """
        dt = 1. * T/N  # the normalizing constant
        random_increments = np.random.normal(0.0, 1.0 * h, N)*np.sqrt(dt)  # the epsilon values
        brownian_motion = np.cumsum(random_increments)  # calculate the brownian motion
        brownian_motion = np.insert(brownian_motion, 0, 0.0) # insert the initial condition
    
        return brownian_motion, random_increments
    
    Code:
    import numpy as np
    
    def drifted_brownian_motion(mu, sigma, N, T, seed=42):
        """Simulates a Brownian Motion with drift.
    
        :param float mu: drift coefficient
        :param float sigma: volatility coefficient
        :param int N : number of discrete steps
        :param int T: number of continuous time steps
        :param int seed: initial seed of the random generator
        :returns list: drifted Brownian motion
        """
        # set the seed
        np.random.seed(seed)
        # standard brownian motion
        W, _ = brownian_motion(N, T ,1.0)
        # the normalizing constant
        dt = 1. * T/N
        # generate the time steps
        time_steps = np.linspace(0.0, N*dt, N+1)
        # calculate the Brownian Motion with drift
        X = mu * time_steps + sigma * W
        return X
    
    Code:
    def geometric_brownian_motion(G0, mu, sigma, N, T):
        """Simulates a Geometric Brownian Motion.
    
        :param float G0: initial value
        :param float mu: drift coefficient
        :param float sigma: diffusion coefficient
        :param int N: number of discrete steps
        :param int T: number of continuous time steps
        :return list: the geometric Brownian Motion
        """
        # the normalizing constant
        dt = 1. * T/N
        # standard brownian motion
        W, _ = brownian_motion(N, T ,1.0)
        # generate the time steps
        time_steps = np.linspace(0.0, N*dt, N+1)
    
        # calculate the geometric brownian motion
        G = G0 * np.exp(mu * time_steps + sigma * W)
        # replace the initial value
        G[0] = G0
    
        return G
    
    [​IMG]
     
    Last edited: Jul 29, 2023
    #20     Jul 29, 2023
    earth_imperator likes this.