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
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 & dumber these plots! Such authors must have lost their mind, IMO. The correct plot must be "conic", like in my OP above.
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.
Here is one https://people.sc.fsu.edu/~jburkard...on_simulation/brownian_motion_simulation.html That implementation uses a crude pseudorandom number generator, so you might want to substitute a better one like WELL.
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; }
This stupid software reformats the source code in code block.... 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:
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?