Binomial distribution source code in C++

Hi,
since binomial distribution is important also in the finance world,
here the source code of a small commandline utility program for
on the fly calculating a table of the distribution values:
Code:
/*
  binomial.cpp
  Author: U.M. (user botpro at www.elitetrader.com )

  Compile:
    g++ -Wall -O2 binomial.cpp -o binomial.exe
 
  Run:
    ./binomial.exe
   
  See also:
    https://en.wikipedia.org/wiki/Binomial_distribution#Example

  Example:
    For the above wiki example of a biased coin game:

Binomial distribution (where any event is independent of any previous event(s))
p=0.3000(30.00%) n=6 :
  k    p(k)      p(0..k)    p(k+1..n)
  0   0.11765    0.11765    0.88235
  1   0.30253    0.42017    0.57983
  2   0.32413    0.74431    0.25569
  3   0.18522    0.92953    0.07047
  4   0.05953    0.98906    0.01094
  5   0.01021    0.99927    0.00073
  6   0.00073    1.00000    0.00000
p(k)      means: p for exact k consecutive successes in n plays
p(0..k)   means: p for at at most k consecutive successes in n plays
p(k+1..n) means: p for at least k consecutive successes in n plays
*/

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <string>

using namespace std;


int usage(const string AsPgmName, const int AiRc = 1)
  {
    printf("Usage: %s p n\n", AsPgmName.c_str());
    printf("where p=probability for success (p must be between 0 and 1), n=number of plays or events\n");
    printf("Some examples for p:\n"
           "  fair dice game:         p=0.16667\n"
           "  fair coin tossing game: p=0.5\n"
           "  stock price rising:     p=0.5\n");
    return AiRc;
  }

int main(int argc, char* argv[])
  {
    printf("Binomial distribution (where any event is independent of any previous event(s))\n");
    if (argc < 3) return usage(argv[0], 1);

    const double p = atof(argv[1]);
    const size_t n = atoi(argv[2]);
   
    const double q = 1.0 - p;
    printf("p=%.4f(%.2f%%) n=%zu :\n", p, p * 100.0, n);
    printf("  k    p(k)      p(0..k)    p(k+1..n)\n");
   
    double pk = pow(q, n), s = 0;
    for (size_t i = 0; i <= n; ++i)
      {
        if (i)
          pk = double(n - i + 1) / double(i) * p / q * pk;
        s += pk;
        printf("%3zu   %.5f    %.5f   %8.5f\n", i, pk, s, 1.0 - s);
      }
   
    printf("p(k)      means: p for exact k consecutive successes in n plays\n"); 
    printf("p(0..k)   means: p for at most k consecutive successes in n plays\n"); 
    printf("p(k+1..n) means: p for at least k consecutive successes in n plays\n");
 
    return 0;
  }
 
Last edited:
FYI: I've edited this online code several times...
I think the "at least" and "at most" descriptions and interpretations could be wrong... ;-(
But the numerical results should be correct.
 
Last edited:
Here's an updated version with some more options. It even can print 2 barcharts ;-)
For disabling the barcharts just set these options to 0.
Code:
/*
  binomial.cpp

  2016-02-14-Su: v0.99: init
  2016-02-14-Su: v1.00: fixed the "at least", "at most" texts

  Author: U.M. (user botpro at www.elitetrader.com )

  Compile:
    g++ -Wall -O2 binomial.cpp -o binomial.exe

  Run:
    ./binomial.exe

  See also:
    https://en.wikipedia.org/wiki/Binomial_distribution#Example

  Example:
    For the above wiki example of a biased coin game:
      Binomial distribution (where any event is independent of any previous event(s))
      p=0.3000(30.00%) n=6 :
        k    p(k)      p(0..k)    p(k+1..n)
        0   0.11765    0.11765    0.88235
        1   0.30253    0.42017    0.57983
        2   0.32413    0.74431    0.25569
        3   0.18522    0.92953    0.07047
        4   0.05953    0.98906    0.01094
        5   0.01021    0.99927    0.00073
        6   0.00073    1.00000    0.00000
      p(k)      means: p for exact k consecutive successes in n plays
      p(0..k)   means: p for up to k consecutive successes in n plays
      p(k+1..n) means: p for at least k+1 consecutive successes in n plays
*/

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <string>
#include <vector>

using namespace std;


int usage(const string AsPgmName, const int AiRc = 1)
  {
    printf("Usage: %s p n [fChart1 [fChart2 [cChart1 [cChart2]]]]\n", AsPgmName.c_str());
    printf("where p=probability for success (p must be between 0 and 1), n=number of plays or events\n");
    printf("fChart1/fChart2: printing a horizontal barchart; default is 1\n");
    printf("cChart1/cChart2: the character to use for barchart, default is *\n");
    printf("Some examples for p:\n"
           "  fair dice game:         p=0.16667\n"
           "  fair coin tossing game: p=0.5\n"
           "  stock price rising:     p=0.5\n"
           "  hitting a roulette nbr: p=0.02778\n");
    return AiRc;
  }

string mk_chartline(const double pk, const double ps, const size_t n, const bool fChart1, const bool fChart2,
                    const char cChart1, const char cChart2)
  {
    const size_t nmax = 75;   // that many stars make up 100%
    const size_t n1   = size_t(pk * nmax + 0.5);
    const size_t n2   = size_t(ps * nmax + 0.5);

    string s1;
    if (fChart1) s1 = string(n1, cChart1);

    string sp;
    if (fChart1 && fChart2)
      {
        const size_t nsp = size_t(max(0.0, double(nmax) / 1.5 - n1 + 0.5));
        if (nsp) sp = string(nsp, ' ');
      }

    string s2;
    if (fChart2) s2 = string(n2, cChart2);;

    return s1 + sp + s2;
  }

int main(int argc, char* argv[])
  {
    printf("Binomial distribution (where any event is independent of any previous event(s))\n");
    if (argc < 3) return usage(argv[0], 1);

    const double p       = atof(argv[1]);
    const size_t n       = atoi(argv[2]);
    const bool   fChart1 = argc > 3 ? atoi(argv[3]) != 0 : true;
    const bool   fChart2 = argc > 4 ? atoi(argv[4]) != 0 : true;
    const char   cChart1 = argc > 5 ? *argv[5] : '*';
    const char   cChart2 = argc > 6 ? *argv[6] : '*';


    const double q = 1.0 - p;
    printf("p=%.4f(%.2f%%) n=%zu :\n", p, p * 100.0, n);
    printf("  k    p(k)      p(0..k)    p(k+1..n)\n");

    double pk = pow(q, n), s = 0;
    for (size_t i = 0; i <= n; ++i)
      {
        if (i)
          pk *= double(n - i + 1) / double(i) * p / q;
        s += pk;
    
        const string sCharts = mk_chartline(pk, s, n, fChart1, fChart2, cChart1, cChart2);
        printf("%3zu   %.5f    %.5f   %8.5f   %s\n", i, pk, s, 1.0 - s, sCharts.c_str());
      }

    printf("p(k)      means: p for exact k consecutive successes in n plays\n");
    printf("p(0..k)   means: p for up to k consecutive successes in n plays\n");
    printf("p(k+1..n) means: p for at least k+1 consecutive successes in n plays\n");

    return 0;
  }

Here's an example:
Code:
./binomial.exe 0.6 30 1 0 .
Binomial distribution (where any event is independent of any previous event(s))
p=0.6000(60.00%) n=30 :
  k    p(k)      p(0..k)    p(k+1..n)
  0   0.00000    0.00000    1.00000   
  1   0.00000    0.00000    1.00000   
  2   0.00000    0.00000    1.00000   
  3   0.00000    0.00000    1.00000   
  4   0.00000    0.00000    1.00000   
  5   0.00000    0.00000    1.00000   
  6   0.00001    0.00001    0.99999   
  7   0.00004    0.00005    0.99995   
  8   0.00017    0.00022    0.99978   
  9   0.00063    0.00086    0.99914   
10   0.00200    0.00285    0.99715   
11   0.00545    0.00830    0.99170   
12   0.01294    0.02124    0.97876   .
13   0.02687    0.04811    0.95189   ..
14   0.04895    0.09706    0.90294   ....
15   0.07831    0.17537    0.82463   ......
16   0.11013    0.28550    0.71450   ........
17   0.13604    0.42153    0.57847   ..........
18   0.14738    0.56891    0.43109   ...........
19   0.13962    0.70853    0.29147   ..........
20   0.11519    0.82371    0.17629   .........
21   0.08228    0.90599    0.09401   ......
22   0.05049    0.95648    0.04352   ....
23   0.02634    0.98282    0.01718   ..
24   0.01152    0.99434    0.00566   .
25   0.00415    0.99849    0.00151   
26   0.00120    0.99969    0.00031   
27   0.00027    0.99995    0.00005   
28   0.00004    1.00000    0.00000   
29   0.00000    1.00000    0.00000   
30   0.00000    1.00000    0.00000   
p(k)      means: p for exact k consecutive successes in n plays
p(0..k)   means: p for up to k consecutive successes in n plays
p(k+1..n) means: p for at least k+1 consecutive successes in n plays
 
Last edited:
You tell people to Keep It Simple, Stupid.
Why don't you follow your own principle ?
In addition, you're waistin' your time...
Greeks are useful but that ?
A binomial Distribution ?!

Log Normal is a better description.
But it depends the underlying.
Not all securities are such.
But binomial ? Coin toss.
Nothing else.
 
You tell people to Keep It Simple, Stupid.
Why don't you follow your own principle ?
In addition, you're waistin' your time...
Greeks are useful but that ?
A binomial Distribution ?!

Log Normal is a better description.
But it depends the underlying.
Not all securities are such.
But binomial ? Coin toss.
Nothing else.
Binomial distribution is good for calculating cumulated probabilities of independent events.
It's also a building block for statistical trading systems.

The option Greeks are useful for those who use it. I don't use them, so I don't need them.
 
Back
Top