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]);}