// cap.cc
//
// Fixed-income binomial option pricing engine
//
 ^
 |
 Comment lines
#include <math.h>
#include <iostream.h>
#include "cap.h"
 ^
 |
 The preprocessor substitutes the contents of the included file for the
 #include line before compilation takes place.  <> surrounds names of
 files found in the standard place for include files for this version
 of C++.

#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
 ^
 |
 These two definitions define substitutions to be made by the preprocessor
 everytime it sees the MIN and MAX.  These functions will not work if there
 is a function inside that is different each time it is evaluated (for
 example, if it gives the next random number or the next number from the
 user).  This is because the (a) or (b) returned would use a different call
 to the function than the (a) or (b) used in the test.

f_i_bin::f_i_bin(double ttm,int npers,double sigma,double rrbar,double k) {
 ^
 |
 This is the first line in the constructor f_i_bin that initializes an object
 of type f_i_bin.  The calculations below are for quantities that will be
 used again and again through the tree.  Default values are given in the
 type declaration in the header file.

  nper=npers;
   ^
   |
   npers is the number passed to this constructor (e.g. when f_i_bin c2;
   is reached, the default value 4 is passed to this constructor).  npers
   is the private variable defined in the type declaration of f_i_bin in
   the header file.

  tinc = ttm/(double) nper;
              ^
              |
              (double) is a ``type casting'' which says to convert nper
              (which is of type int) to double before dividing.

  sig = sigma;
  up = sigma*sqrt(tinc);
   ^
   |
   sqrt() is a function from the math library.  Its argument and result are
   both of type double.
   
  rbar = rrbar;
  kappa = k;
  prfact = kappa*sqrt(tinc)/(2.0*sig);}

 This is a function that will price a discount bond.  It is identical to
 the cap pricing formula below except that the terminal value is 1.0 rather
 than 0.0 and there is no intermediate cash flow.
 |
 v
double f_i_bin::bprice(double r0) {
  int i,j;
  double prup;
//initialize terminal payoffs
//i is the number of up moves
  for(i=0;i<=nper;i++) {
//  r[i] = r0 + up * (double)(2*i-nper);   not needed for this claim
    val[i] = 1.0;}
//compute prices back through the tree
//j is the number of periods from the end
//i is the number of up moves from the start
  for(j=1;j<=nper;j++) {for(i=0;i<=nper-j;i++) {
      r[i] = r0 + up * (double) (2*i-nper + j);
      prup = 0.5 + prfact*(rbar-r[i]);
      prup = MIN(1.0,MAX(0.0,prup));
      val[i] = (prup*val[i+1]+(1.0-prup)*val[i])*exp(-r[i]*tinc);}}
  return(val[0]);}

double f_i_bin::cap(double level,double r0) {
 ^
 |
 First line of the definition of the cap pricing function, which is
 a member function of an object of type f_i_bin.

  int i,j;
  double prup;
   ^
   |
   These are type declarations for some variables that will be needed
   later.

//initialize terminal payoffs
//i is the number of up moves
 ^
 |
 Comment lines

  for(i=0;i<=nper;i++) {
   ^
   |
   The for() has three arguments separated by semicolons.  The first
   is what is done before the first time through to initialize the
   loop.  The second is the test peformed before each pass through
   the loop.  If the test is false, the program goes to the first
   statement after the loop.  The third argument tells what to do
   after each time through (in this case, increase the counter i by
   1).  The loop is the statement after the for statement, or a
   series of statements in curly brackets, treated like a single
   statement.

//  r[i] = r0 + up * (double)(2*i-nper);   not needed for this claim
 ^
 |
 Since the terminal value is 0.0 independent of the interest rate, we
 do not have to compute the interest rate here.

    val[i] = 0.0;}


//compute prices back through the tree
//j is the number of periods from the end
//i is the number of up moves from the start
  for(j=1;j<=nper;j++) {for(i=0;i<=nper-j;i++) {
   ^
   |
   The ``outside'' loop (for(j...)) works backwards through the tree
   one period at a time.  The ``inside'' loop moves from node to node
   in the tree at a point in time.  We label each node at a point in
   time by i, the number of up moves since the start.

      r[i] = r0 + up * (double) (2*i-nper + j);
       ^
       |
       Since down=-up and the number of down moves is nper - j-i, the
       interest rate is r0 + up*i + down*(nper-j-i)
       = r0 + up * (2*i-nper + j).  The (double) makes sure the
       expression computed in parentheses is converted from int to
       double.
      prup = 0.5 + prfact*(rbar-r[i]);
      prup = MIN(1.0,MAX(0.0,prup));
       ^
       |
       The probability of an up from the mean-reverting model is
       forced to be between 0 and 1 to avoid arbitrage.

      val[i] = (prup*val[i+1]+(1.0-prup)*val[i])*exp(-r[i]*tinc)
        + MAX(0.0,(r[i]-level)*tinc);}}
       ^
       |
       The value of the option (pre-cash flow) equals the value of
       a claim to the option tomorrow (from the option pricing
       formula) plus the cash flow now (given by MAX(...) for the
       cap).
  return(val[0]);}
   ^
   |
   When the loop is done, we are at the start of the tree and val
   has only one important element, the first one, corresponding to
   0 ups after 0 periods.  This contains the value of the cap,
   which is returned as the value of the function.