Philip H. Dybvig
Washington University
Saint Louis, Missouri
|- r + deltaWe choose delta = sigma * sqrt(Delta t).
r -|
|- r - delta
The interest rate is not an asset! Therefore, we can't use the formula from the previous lecture to compute the risk-neutral probabilities or state prices. There are several approaches:
E[Delta r]=k(r*-r)Delta t,
then
pi*_u delta+(1-pi*_u)(-delta)=k(r*-r) Delta t
or
pi*_u=(1/2)+(k(r^*-r)Delta t)/2 delta.
A random walk (good for short maturities and non-critical applications) corresponds to k=0.
Another issue: use uneven spacing to make interest rate volatility a function of the interest rate. Fudge factors can fit today's yield curve. Stochastic volatility and additional factors are harder.
About Intermediate Cash Flows When a claim includes intermediate cash flows (as for a coupon bond or a cap), the claim is simply added in at the appropriate time. For example, if V indicates the ex-cashflow value and C the cashflow, we have, at some node at time t, V(t,r)=(pi*_u(V(t,r+delta)+C(t,r+delta))+pi*_d(V(t,r-delta)+ C(t,r-delta)))/(1+r)
// cap.h // // Fixed-income binomial option pricing include file // #ifndef MAXTERNODES #define MAXTERNODES 200 #endif class f_i_bin { public: f_i_bin(double ttm=.25,int npers=4,double sigma=.02, double rrbar=.07,double k=.125); double bprice(double r0); double cap(double level,double r0); private: int nper; double tinc,up,down,sig,rbar,kappa,prfact; double r[MAXTERNODES],val[MAXTERNODES];};
// captest.cc // // Fixed income binomial option pricing model: test // #include <iostream.h> #include "cap.h" main() { f_i_bin c2; double caprate,rzero; cout << "\nType the cap rate, a space, the initial" << " rate, and then ENTER." << "\n" << "Make the cap rate negative to terminate." << "\n\n"; cout << "State rates in percent per annum (without the " << "percent sign).\n\n"; while(1) { cout << "cap-rate initial-rate: "; cin >> caprate >> rzero; if(!cin) { cout << "\nError: expected cap-rate initial-rate\n" << "Terminating\n" << endl; return(1);} if(caprate<0.0) { cout << endl; return(0);} cout << "cap value = " << c2.cap(caprate/100.0,rzero/100.0) << "\n\n";}}
// cap.cc // // Fixed-income binomial option pricing engine // #include <math.h> #include <iostream.h> #include "cap.h" #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b))
f_i_bin::f_i_bin(double ttm,int npers,double sigma,double rrbar,double k) { nper=npers; tinc = ttm/(double) nper; sig = sigma; up = sigma*sqrt(tinc); rbar = rrbar; kappa = k; prfact = kappa*sqrt(tinc)/(2.0*sig);}
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) { 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] = 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++) { 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) + MAX(0.0,(r[i]-level)*tinc);}} return(val[0]);}