This annotated version has comments on all three files, but only for what is new in this program.
// fut.h // // Binomial futures option pricing model: declarations // #define MAXTERNODES 40 struct valhedge { double value; double delta;}; ^ | The new data type valhedge allows us to return the value and the hedge ratio in one object. A messier solution is to return values in the arguments or in locations pointed to by the arguments. class fut { public: fut(double ttm=.25,int npers=4,double r=.05,double sigma=.3); valhedge eurcall(double f0,double X); ^ | This function returns the value and hedge ration for a European call option on a futures price. private: int nper; double tinc,r1per,disc,disctm,up,down,pratio,prcup,prcdn; double val[MAXTERNODES];}; // futtest.cc // // Binomial futures option pricing model: test // #include <iostream.h> #include "fut.h" main() { fut c1; valhedge x; ^ | This is the declaration of an object x of type valhedge, that includes both the value and the hedge ratio. The result of call pricing will be stored here temporarily and its components will be printed separately. double futprice,strikeP; cout << "\nType the futures price, a space, the strike" << " price, and then ENTER.\n" << "Make the futures price negative to terminate." << "\n\n"; while(1) { cout << "futures-price strike-price: "; cin >> futprice >> strikeP; if(futprice < 0.0) { cout << endl; return(0);} if(!cin) { cout << "invalid input" << endl; return(1);} x = c1.eurcall(futprice,strikeP); ^ | The results of eurcall are temporarily stored here... cout << "call option value = " << x.value << "\n" ^ | ... and printed here... << "hedge (number of contracts) = " << x.delta ^ | ... and here. << "\n\n";}} // fut.cc // // Binomial futures option pricing model: implementation // #include <math.h> #include "fut.h" #define MAX(a,b) (((a) > (b)) ? (a) : (b)) fut::fut(double ttm,int npers,double r,double sigma) { nper = npers; tinc = ttm/(double) nper; r1per = exp(r * tinc); disc = 1.0/r1per; disctm = exp(-r * ttm); up = 1.0 + sigma * sqrt(tinc); ^ | Since the futures requires no initial investment, there is no interest returned. down = 1.0 - sigma * sqrt(tinc); prcup = 0.5*disc; prcdn = 0.5*disc;} valhedge fut::eurcall(double f0,double X) { int i,j; double futprice; valhedge x1; ^ | This declares the variable x1 in which we will store the result to be returned. // initialize terminal payoffs // i is the number of up moves over the whole life for(i=0;i<=nper;i++) { futprice = f0 * pow(up,(double) i) * pow(down,(double) (nper-i)); val[i] = MAX(futprice - X,0);} // compute prices back through the tree // j+1 is the number of periods from the end // i is the number of up moves from the start for(j=0;j<nper-1;j++) { for(i=0;i<nper-j;i++) { val[i] = prcdn * val[i] + prcup * val[i+1];}} ^ | This for loop (over j) does all of the steps except the actual valuation at the beginning, which is done separately afterwards, since we need to know val one period from the end to compute the hedge as well as the value. x1.value = prcdn * val[0] + prcup * val[1]; ^ | This computes the value at the initial node... x1.delta = (val[1]-val[0]) / (f0*(up-down)); ^ | ... and this computes the hedge ratio. return(x1);} ^ | An object of type valhedge is returned just like an object of a built-in type like double or int.