Binomial distribution source code in C++

Discussion in 'App Development' started by botpro, Feb 14, 2016.

  1. botpro

    botpro

    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: Feb 14, 2016
  2. botpro

    botpro

    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: Feb 14, 2016
  3. botpro

    botpro

    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: Feb 14, 2016
  4. K-Pia

    K-Pia

    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.
     
  5. botpro

    botpro

    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.
     
  6. Butterfly

    Butterfly

    in markets, price movements are not independent, they are serial, and so are returns of financial instruments
     
  7. botpro

    botpro

    Which formula do you suggest to use for such calculations?