// 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.