/*@@@@@@@@@@@@@@@@@@@@@@@@ test.cpp @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 Random Option Pricing
 Summer 2002
 Authors: A. Korobchevsky
          S. Ferrando
 Ryerson University ALL RIGHTS RESERVED
 
 Purpose: Tests the binomial underlying
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/

#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cstring>

#include "../../Rng/GSL_RandomGen.h" 
#include "../../Und/Binom.h"




/********************************** main ******************************
 * Function: main
 * Purpose: tests the binom underline. The program generate a large 
 *   number of paths. Each path number of appearences is compared with 
 *   it's theoretical probability. All underlying parameters are hardcoded  
 * C.L arguments: Random generator codename
 *                mt - mt19937
 *                taus - tausworthe
 *                gfsr - gfsr4
 * Return: N/A
 *********************************************************************/

// BEGIN All
int main(int argc, char **argv)
{ char gen_desc[10];

  if (argc == 2) 
    strcpy(gen_desc, argv[1]);
  else 
    strcpy(gen_desc, "mt");
  Binom binom(gen_desc);
 
  binom.U = 1.2;
  binom.D = 0.9;
  binom.r = 0;
  binom.T = 1.0;
  binom.N = 3;
  binom.P = 0.5;

  int S = 100;
  int M = 100000;
  
  /* State counters; array not used for clarity */
  int UUU = 0; int UUD = 0; int UDU = 0; int UDD = 0;
  int DUU = 0; int DUD = 0; int DDU = 0; int DDD = 0;
 
  cout << "Generator: " << binom.gen->getName() << endl;

  for (int j = 1; j <= M; j++)
  { double ST = S;
    string status = ""; 

    for (int i = 1; i <= binom.N; i++)
    { double STnew =  binom.next(ST);
      if (ST < STnew)
        status += "U";
      else 
	status += "D";
      ST = STnew;
    }
    
    if (status == "UUU")
      UUU++;
    else if (status == "UUD")
      UUD++;
    else if (status == "UDU")
      UDU++;
    else if (status == "UDD")
      UDD++;
    else if (status == "DUU")
      DUU++;
    else if (status == "DUD")
      DUD++;
    else if (status == "DDU")
      DDU++;
    else if (status == "DDD")
      DDD++;
  }

  cout << "Total simulations: " << M << endl;
  cout << "Status: UUU, hits: " << UUU << ", prob. = " << (1 - binom.P) * (1 -  binom.P) * (1 -  binom.P) << endl;  
  cout << "Status: UUD, hits: " << UUD << ", prob. = " << (1 - binom.P) * (1 -  binom.P) * binom.P << endl; 
  cout << "Status: UDU, hits: " << UDU << ", prob. = " << (1 - binom.P) *  binom.P * (1 -  binom.P) << endl; 
  cout << "Status: UDD, hits: " << UDD << ", prob. = " << (1 - binom.P) *  binom.P * binom.P << endl; 
  cout << "Status: DUU, hits: " << DUU << ", prob. = " << binom.P * (1 -  binom.P) * (1 -  binom.P) << endl; 
  cout << "Status: DUD, hits: " << DUD << ", prob. = " << binom.P * (1 -  binom.P) * binom.P << endl; 
  cout << "Status: UUU, hits: " << DDU << ", prob. = " << binom.P * binom.P * (1 -  binom.P) << endl; 
  cout << "Status: UUU, hits: " << DDD << ", prob. = " << binom.P * binom.P * binom.P << endl;  
  return 0;
}

// END All
