Lindo Systems

MODEL:
! Black/Derman/Toy binomial interest rate model(bdtbonds);
! Construct an interest rate tree/network to match
  a given yield-to-maturity curve and volatilities.
  In the BDT model, possible future short rates are modeled
  as a binary (recombining)tree where each node has the
  two features:
    Prob[rate goes up] = Prob{rate goes down] = .5, and
    For each period i: uprate/downrate = constant.
  The network, with time going left to right, looks like:
          3 ...
         /
        2
       / \
      1   3 ...
       \ /
        2
         \
          3 ...;
! Keywords: Black/Derman/Toy, option pricing, yield curve, 
    binomial option pricing, interest rate, derivative, bonds;
SETS:
 PORM:   ! Set of Periods or Maturities;
   YTM,  ! Yield To Maturity of Zero Coupon Bond; 
   VOL,  ! Volatility of Yield To Maturity of ZCB;
   YTMU,
   YTMD;
ENDSETS
DATA:
! Yield to maturity(YTM) of zero coupon bond(ZCB)
  from 2005;
 YTM = .0326 .0358 .0363 .0368  .0373  .0381  .0389;
! The one period volatility of YTM of ZCB;
 VOL =   .0    .05  .06   .065   .068    .07   .071;
! YTM = .1 .11 .12 .125 .13;
! VOL = .2 .19 .18 .17 .16;
ENDDATA
!-------------------------------------------------;
SETS:
 STATE( PORM, PORM)| &1 #GE# &2:
   FSRATE; ! (OUTPUT:)Future short rate in period t, state s;
 MXS( PORM, PORM, PORM)|&1#GE# &2 #AND# &2 #GE# &3:
   PRICE; ! Price of a ZCB of maturity m, in period t,  state s;
ENDSETS

!For each maturity, price in period 1 must be consistent with its YTM;
@FOR( PORM( m):
  PRICE( m, 1, 1)*( 1 + YTM( m))^m = 1;
  );

! Short rate ratios must be constant  
      (Note: C/B=B/A <=> AC=BB);
 @FOR( PORM(t):
  @FOR( PORM( s)| s #GT# 2 #AND# s #LE# t:
   FSRATE( t, s) * FSRATE( t, s-2) =
    FSRATE( t, s-1) * FSRATE( t, s-1); 
   FSRATE( t, s) >= FSRATE( t,s-1);
     );
    );

! Compute prices for each period and state. The bond
   maturing this period determines the short rate...;
@FOR( PORM( t):
  @FOR( PORM(s)| s #LE# t:
   @FREE( PRICE( t, t, s));
   PRICE( t, t, s) = 1/( 1 + FSRATE( t, s));
      );
   );
 ! For longer maturity bonds...;
@FOR( MXS( m, t, s) | m #GT# t:
   @FREE( PRICE( m, t, s));
   PRICE( m, t, s) = 
    .5 * ( PRICE(m, t + 1, s) + PRICE(m, t + 1, s + 1))/( 1 + FSRATE( t, s));
    );

  ! Match the volatilities for each maturity;
@FOR( PORM( m)| m #GT# 1:
  .5 * ( @LOG( YTMU( m)) - @LOG( YTMD( m))) = VOL( m);
    );

 ! For periods > 1, compute YTM's for each maturity;
@FOR( PORM( m)| m #GT# 1:
  (1+YTMU(m))^(m-1) = 1/PRICE(m,2,2);
  (1+YTMD(m))^(m-1) = 1/PRICE(m,2,1);
   );

 DATA:
  ! Write the future spot rate network to a file;
  @TEXT( 'forwrdr.dat') = FSRATE;
 ENDDATA
END