Scenario You are managing a fixed-income portfolio, and you would like to explore adding value by selling interest rate caps and related products to corporations whose management would like to hedge some interest rate risk. To evaluate these deals, you require a valuation of caps, floors, and collars.
Action You will be given a program that uses a binomial option pricing model to price caps. You will modify the program to value floors as well.
Concept This problem set illustrates the versatility of the binomial model and in particular its usefulness in valuing interest-dependent claims. You will be making more extensive changes than in the previous homeworks.
Instructions
Extra for Experts
Challenger
Program Files
Conceptually, the binomial model in this Homework is almost identical to the binomial model in Homework 1. However, the underlying variable that is changing through the binomial tree is the short-maturity interest rate rather than a stock price. Because the interest rate is varying through the tree, so is the one-period discount factor used to compute the prices of up- and down-states.
Exhibit A: the HTML file Caplet.html
<HTML> <HEAD> <TITLE>Binomial Cap Pricing Program</TITLE> </HEAD> <BODY> <APPLET CODE=Caplet.class WIDTH=400 HEIGHT=100> </APPLET> </BODY> </HTML>
Exhibit B: the program file Caplet.java
// // Fixed income binomial cap pricing applet // import java.applet.*; import java.awt.*; public class Caplet extends Applet { F_I_bin c2; double caprate,rzero; Label capval; TextField interest_rate, capped_level; public Caplet() { setLayout(new GridLayout(3,2)); add(new Label("Interest rate (%) =")); add(interest_rate = new TextField("5",10)); add(new Label("Capped level (%) =")); add(capped_level = new TextField("5.5",10)); add(new Label("Cap value (per $100 face) =")); add(capval = new Label("**********")); c2 = new F_I_bin((double) 2.0, (int) 24, (double) 0.01, (double) 0.05, (double) 0.125, (int) 5001); recalc();} public boolean action(Event ev, Object arg) { if(ev.target instanceof TextField) { recalc(); return true;} return false;} double text2double(TextField tf) { return Double.valueOf(tf.getText()).doubleValue();} void recalc() { capval.setText(String.valueOf((float) (100 * c2.cap(text2double(capped_level)/100.0, text2double(interest_rate)/100.0))));}} // // Fixed-income binomial option pricing engine // class F_I_bin { int nper; double tinc,up,down,sigma,rbar,kappa,prfact; double [] r,val; public F_I_bin(double ttm,int nper,double sigma,double rbar,double kappa, int maxternodes) { this.nper=nper; tinc = ttm/(double) nper; this.sigma = sigma; up = sigma*Math.sqrt(tinc); this.rbar = rbar; this.kappa = kappa; prfact = kappa*Math.sqrt(tinc)/(2.0*sigma); val = new double[maxternodes]; r = new double[maxternodes];} double 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 = Math.min((double) 1.0,Math.max((double) 0.0,prup)); val[i] = (prup*val[i+1]+(1.0-prup)*val[i])*Math.exp(-r[i]*tinc);}} return(val[0]);} double 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 = Math.min((double) 1.0,Math.max((double) 0.0,prup)); val[i] = (prup*val[i+1]+(1.0-prup)*val[i])*Math.exp(-r[i]*tinc) + Math.max((double) 0.0,(r[i]-level)*tinc);}} return(val[0]);}}