Valuing a Bond Call Option with a Binomial Tree

Overview


Populating the Rate Tree


Once a rate tree has been calibrated to the current rate environment (see calibration) we next need to populate the bond values on each node of the tree. Typically, the value of the bond is just the average of the discounted bond value at the two subsequent nodes of the tree (plus any coupons). The following code populates those values for a zero coupon bond that pays $100 in 2 periods.


let sr = await import('/lib/finance/tree-models/binomial/v1.0.0/short-rate.mjs');

let discounts = [1/1.035,100/108];
let tree = sr.calibrate(0.1, discounts);
let boundary = [...tree[tree.length-1].map(p=>({value:100})),{value:100}];
tree.push(boundary);
for(let i=tree.length-2;i>=0;i--){
  tree[i].forEach((p,j)=>{
    p.value = 0.5*(tree[i+1][j].value * (1/(1+p.rate)) + tree[i+1][j+1].value* (1/(1+p.rate)))
  });
}
					


If the bond has a call option that allows the holder to call the bond at $95 dollars at the first period, we add the logic to replace the value with 95 if the value exceeds that.


let sr = await import('/lib/finance/tree-models/binomial/v1.0.0/short-rate.mjs');

let discounts = [1/1.035,100/108];
let tree = sr.calibrate(0.1, discounts);
let boundary = [...tree[tree.length-1].map(p=>({value:100})),{value:100}];
tree.push(boundary);
for(let i=tree.length-2;i>=0;i--){
  tree[i].forEach((p,j)=>{
    let value = 0.5*(tree[i+1][j].value * (1/(1+p.rate)) + tree[i+1][j+1].value* (1/(1+p.rate)))
    if(value > 95) p.value = 95;
    else p.value = 95;
  });
}
					
Try it!


Valuing the Embedded Option


The value of the option is the difference value of the bond without the option, and then bond with the option.

Contents