Simulating stock prices using GBM

I'm in need of a well tested code snippet (C/C++ or similar language) for generating stock prices for simulations (Monte Carlo etc).
Although I already have a GBM implementation, but I now discovered that it unfortunately does generate buggy data, so I'm in need for one that works correctly and was well tested.

It seems to me that either the algorithm used in GBM (for example the "Ito lemma" part) is generally incorrect, or I must have got a buggy implementation. Of course the latter case is more probable b/c
it's hard to believe that nobody in the whole world has discovered that the GBM algorithm is incorrect.

Today I tried this code, but it too is generating wrong results :vomit:

gbm.png
 
EASYLANGUAGE CODE TO CREATE SYNTHETIC PRICES (see attachment for context)
Code:
// Synthetic Price Generator
// (c) 2014 John F. Ehlers
Vars:
    Pink(0),
    Hi(0),
    Lo(0);

//Note: Pink[1] means the value of Pink one bar ago

Pink = .004*Random(100) + .996*Pink [1];
If Currentbar = 1 Then Pink = 50;

Value1 = .5*Random(.25) + .5*Value1[1];
Value2 = .5*Random(.25) + .5*Value2[1];

Hi = Pink + Value1;
Lo = Pink - Value2;

Plot1(Hi);
Plot2(Lo);
 

Attachments

EASYLANGUAGE CODE TO CREATE SYNTHETIC PRICES (see attachment for context)
Code:
// Synthetic Price Generator
// (c) 2014 John F. Ehlers
Vars:
    Pink(0),
    Hi(0),
    Lo(0);

//Note: Pink[1] means the value of Pink one bar ago

Pink = .004*Random(100) + .996*Pink [1];
If Currentbar = 1 Then Pink = 50;

Value1 = .5*Random(.25) + .5*Value1[1];
Value2 = .5*Random(.25) + .5*Value2[1];

Hi = Pink + Value1;
Lo = Pink - Value2;

Plot1(Hi);
Plot2(Lo);
@ph1l, thanks, but this does not look to be a GBM algorithm. It uses some "wild" constants w/o any logical explanations.
I need to generate millions of such random stock prices for Monte Carlo simulations, ie. it's not about plotting them on the screen.

A correct GBM algorithm must behave very realistic in terms of stochastics and probability, and must use standard parameters like initial price, drift rate (r), volatility (HV or IV), time (DTE) etc. as described on the said wikipedia page on GBM.

Btw, the Python example code (and the plot it generates) on the above wiki page is IMO similarly unusable as it looks similarly much like an unscientific trash code w/o logic in it :-(
W/o logic, b/c who in the world would start with an initial price near zero?... Only an idiot coder or a wanna-be "scientist".
A similar idiotic plot by a "mathematician and finance quantitative analyst", ie. a "bank expert", is here: https://quantgirluk.github.io/Understanding-Quantitative-Finance/geometric_brownian_motion.html
dumb_GBM_plot.png

Dumb & dumber these plots! :)
Such authors must have lost their mind, IMO. :)
The correct plot must be "conic", like in my OP above.
 
Last edited:
What makes you think it's wrong?
Did you check the mu and sigma parameters?
You asked the right question! :)

I came from a different angle to the conclusion that the GBM algorithm must be wrong.
Or the GBM implementations I so far have tested.
I'm almost 100% sure it's wrong, but the explanation (and proof) is not that easy... but I'll give the proof soon.

I could write a scientific paper and it would be a sensation and I would become famous like Black, Scholes, Merton, Bachelier, Einstein, Newton et al. :) ...but the crude reality is: I'm living in wrong times in a highly ignorant sicko SHC and society... :)

Imagine: all the GBM simulations out there in the World are wrong! Including in nuclear research... :),
And nobody but me knows it!... :)

Btw, I found this bug in GBM after this posting of mine in the other thread recently where we had a fruitful discussion, I must say.
 
Last edited:
Here's the said algorithm from the initial posting as a basis for analysis & discussion.
It can be compiled with any C++11 or newer compiler:

Code:
/*
  GBMgen_B.cpp
  A GBM algorithm

  algo_link: https://codereview.stackexchange.com/questions/177574/generating-stock-prices-using-geometric-brownian-motion/177677#177677

  2023-07-27-Th: converted to this simple C++ pgm (as a simple C function) by @earth_imperator for posting on ET for discussion

  Status:  Algorithm is maybe incorrect --> check & test & verify...
           IMO _one_ of the causes is a missing "reset after each sequence"
           (IMO missing in nearly all GBM implementations & descriptions)

  Compile: g++ -Wall -Wextra -O2 -std=c++11 -o GBMgen_B.exe GBMgen_B.cpp -lm

  Example run:

$ ./GBMgen_B.exe
Cmdline: ./GBMgen_B.exe
GBMgen_B:
  algo_link: https://codereview.stackexchange.com/questions/177574/generating-stock-prices-using-geometric-brownian-motion/177677#177677
  params:    r=0.040000 s=0.200000 t=0.750000 n=2 S=100.000000 nGen=30 fPrint=1 seed=1690554792
  internals: drift=1.007528 vol=0.122474
  gen_algo:  St = St * drift * exp(vol * rndSND)
98.367702
91.369361
81.443924
89.576659
99.130322
94.066995
102.134197
104.453017
80.286436
99.622408
100.212109
124.228467
130.914490
135.390449
152.850097
172.552860
179.420843
162.930775
171.451668
144.015227
137.126149
145.258968
141.828304
106.580764
92.925408
93.851267
95.736064
96.592048
83.877916
98.405973

*/

#include <cstdio>
#include <ctime>
#include <cmath>
#include <random>

using namespace std;


/*-------------------------------------------------------------------------------------------
  Example call:
    GBMgen_B(0.04,      // r:      drift, ie. "riskless interest rate" / 100
             0.20,      // s:      volatility / 100
             0.75,      // t:      time (expiry) in years
             2,         // n:      "number of time steps"  ???  CHECK: IMO used wrongly in the code
             100.0,     // S:      initial stock price
             30,        // nGen:   generate that many stock prices
             true,      // fPrint: print to screen yes
             0          // seed:   0 means to use a random seed, else the user given seed will be used
             );         //         (useful in repeating the same sequence, esp. when debugging)
*/
void GBMgen_B(const double r, const double s, const double t, const size_t n, const double S,
              const size_t nGen, const bool fPrint, size_t seed)
  {
    const char* algo_link = "https://codereview.stackexchange.com/questions/177574/generating-stock-prices-using-geometric-brownian-motion/177677#177677";

    // if seed is zero then take a random seed, else use the given seed
    if (!seed) seed = time(0);

    const double drift = exp((r - 0.5 * s * s) * t / n);
    const double vol   = s * sqrt(t / n);    // MATH TRICK: it's equal to "sqrt(s * s * t / n)"

    default_random_engine rndgen;
    rndgen.seed(seed);

    normal_distribution<double> stdND(0.0, 1.0);    // u=0.0 s=1.0

    double St = S;

    printf("GBMgen_B:\n"
           "  algo_link: %s\n"
           "  params:    r=%lf s=%lf t=%lf n=%zu S=%lf nGen=%zu fPrint=%d seed=%zu\n"
           "  internals: drift=%lf vol=%lf\n"
           "  gen_algo:  St = St * drift * exp(vol * rndSND)\n",
                         algo_link,
                         r,    s,    t,    n,    S,    nGen,    fPrint,   seed,
                         drift,    vol);

    // generate nGen random stock prices:
    for (size_t i = 0; i < nGen; ++i)
      {
        const double rndSND = stdND(rndgen);
        St *= drift * exp(vol * rndSND);

        //...do something with the generated price in St,
        // f.e. add to an external array/vector or write to file and/or screen etc.
        if (fPrint) printf("%lf\n", St);
      }
  }

void print_cmdline(const int argc, char* argv[])
  {
    printf("Cmdline:");
    for (int i = 0; i < argc; ++i)
      printf(" %s", argv[i]);
    printf("\n");
  }

int main(int argc, char* argv[])
  { // Usage: ./GBMgen_B.exe [nGen [seed]]
    // The defaults are nGen=30 and seed=0
    // Passing a seed != 0 generates the same sequence

    print_cmdline(argc, argv);

    const size_t nGen = argc > 1 ? atoi(argv[1]) : 30;
    const size_t seed = argc > 2 ? atoi(argv[2]) : 0;
    //...

    GBMgen_B(0.04,      // r:      drift, ie. "riskless interest rate" / 100
             0.20,      // s:      volatility / 100
             0.75,      // t:      time (expiry) in years
             2,         // n:      "number of time steps"  ???  CHECK: IMO used wrongly in the code
             100.0,     // S:      initial stock price
             nGen,      // nGen:   generate that many stock prices
             true,      // fPrint: print to screen yes
             seed       // seed:   0 means to use a random seed
             );

    return 0;
  }
 
Last edited:
This stupid software reformats the source code in code block.... :mad:
Need to post original source file, but then this stupis software does not accept the file extension .cpp --> need to zip it or so... Will try...

Here's the ZIP file:
 

Attachments

Last edited:
Google 'jump diffusion". It's absent in the classic GBM model.

I'm in need of a well tested code snippet (C/C++ or similar language) for generating stock prices for simulations (Monte Carlo etc).
Although I already have a GBM implementation, but I now discovered that it unfortunately does generate buggy data, so I'm in need for one that works correctly and was well tested.

It seems to me that either the algorithm used in GBM (for example the "Ito lemma" part) is generally incorrect, or I must have got a buggy implementation. Of course the latter case is more probable b/c
it's hard to believe that nobody in the whole world has discovered that the GBM algorithm is incorrect.

Today I tried this code, but it too is generating wrong results :vomit:

View attachment 319797
 
Google 'jump diffusion". It's absent in the classic GBM model.
I know jump diffusion, but it's not the cause/reason here. JD not needed here.

Can you give me links to non-classic GBM models?
Do you mean Black's jump diffusion model?
 
Last edited:
Back
Top