Scenario You are working for a corporation that uses fx futures to hedge currency risk. There is a current debate about whether you should be using futures options as well. You are charged with evaluating the pricing of futures options calls and puts. Your program will be useful for getting an understanding of the market and may also be a useful tool for trading.
Action You will be given an existing program that computes prices and hedges for futures options. This program reads futures and futures options prices off the Web and compares them with theoretical values, and is set up as a standalone program avoid security restrictions of Web browsers that give their applets limited access to files on the Web. (See Sun's Java security FAQ page http://java.sun.com/sfaq/ for an excellent discussion of these security restrictions.) The program is set up to price European calls and compare the theoretical price with the last trade; you will modify it to price American calls and compare the theoretical price with the opening price.
Concept Corporate hedging strategies represent one of the most important uses (and in some cases abuses) of option pricing theory. Hedging practices and expertise once found only in the most quantitative investment banks are now found in many corporations.
Instructions
javac FutOpStart.java FutOp.java ValHedge.java java FutOpStartThe first command is the normal command for compiling any applet or standalone Java application with multiple source files. The second command uses the Java run-time environment that comes with the Java Development Kit to run the application. The futures and options prices in the applet are downloaded from two files ( r_jy.html and r_oj.html) on my Web page that are (except for acknowledgement of the source) from corresponding files ( r_jy.html and r_oj.html) with delayed live price quotes that were posted on the CME web page. We could use that page in our analysis; because it is changing all the time some additional programming would be needed (for example, see the Challenger below).
Exhibit A: FutOpStart.java
// // Binomial futures option pricing program // import java.awt.*; import java.net.*; import java.io.*; public class FutOpStart { public static void main(String[] args) { FutOpFrame f1 = new FutOpFrame(); f1.setTitle("Futures Option Pricing Program"); f1.pack(); f1.show();}} class FutOpFrame extends Frame { int i,j,k; FutOp c1; ValHedge x; double futuresP,strikeP,optionP; String maturity, inputLine, futuresPs; URL optionsPage, futuresPage; BufferedReader futin, optin; TextField r, sigma, nper; Label[] tableBody; Label north; public FutOpFrame() { setLayout(new BorderLayout()); setBackground(new Color(245,255,245)); add("North",north = new Label( "Japanese Yen Futures Option Pricing Program: Call",Label.CENTER)); north.setForeground(Color.blue); Panel centr = new Panel(); centr.setLayout(new GridLayout(15,6)); centr.add(new Label("maturity",Label.CENTER)); centr.add(new Label("futuresP",Label.CENTER)); centr.add(new Label("strikeP",Label.CENTER)); centr.add(new Label("call:mkt",Label.CENTER)); centr.add(new Label("call:model",Label.CENTER)); centr.add(new Label("delta",Label.CENTER)); tableBody = new Label[84]; for(i=0,k=0;i<14;i++) { for(j=0;j<6;j++,k++) { centr.add(tableBody[k]=new Label("********",Label.CENTER));}} add("Center",centr); Panel south = new Panel(); south.setLayout(new GridLayout(1,6)); south.add(new Label("sigma (%) =")); south.add(sigma = new TextField("17",8)); south.add(new Label("r (%) =")); south.add(r = new TextField("5",8)); south.add(new Label("#periods =")); south.add(nper = new TextField("100",8)); add("South",south); c1 = new FutOp(); recalc();} void recalc() { // // Read in futures price for near contract // try { futuresPage = new URL("http://dybfin.wustl.edu/teaching/compufinj/homework/3/r_jy.html"); /* futuresPage = new URL("http://www.cme.com/cgi-bin/prices.cgi?prices/r_jy.html"); */ futin = new BufferedReader(new InputStreamReader(futuresPage.openStream())); while(!(futin.readLine().startsWith("STRIKE"))) {}; // remove up to the table header futin.readLine(); // skip one line inputLine = futin.readLine(); // read the near futures line /* System.out.println(inputLine); */ maturity = inputLine.substring(0,5); // extract maturity date as string /* System.out.println(maturity); */ futuresPs = inputLine.substring(33,39); futuresP = Double.valueOf(futuresPs).doubleValue(); // extract futures price /* System.out.println(futuresP); */ futin.close(); } catch(MalformedURLException e) { System.err.println("Error: bad URL"); System.exit(0); } catch(IOException e) { System.err.println("Error: Trouble opening or reading futuresPage"); System.exit(0);} // // Set parameters for the option pricing engine. Hardwiring days to // maturity is a cheat! See the Challenger for more information. // c1.newPars((double) 28.0/365.25, (int) text2double(nper), (double) text2double(r)/100.0, (double) text2double(sigma)/100.0); // // Read in corresponding futures options prices, compute theoretical value and delta, // and print // try { optionsPage = new URL("http://dybfin.wustl.edu/teaching/compufinj/homework/3/r_oj.html"); /* optionsPage = new URL("http://www.cme.com/cgi-bin/prices.cgi?prices/r_oj.html"); */ optin = new BufferedReader( new InputStreamReader(optionsPage.openStream())); while(!(optin.readLine().startsWith("OJ "+maturity))) {}; // remove up to the right maturity i=0;k=0; while( ((inputLine = optin.readLine()) != null) && ((inputLine.length()>40) && (k<14)) ) { /* System.out.println(inputLine); System.out.println("\"" + inputLine.substring(35,39) + "\""); System.out.println("\"" + inputLine.substring(32,39) + "\""); System.out.println("\"" + inputLine.substring(39,40) + "\""); */ try { optionP = Double.valueOf(inputLine.substring(32,40)).doubleValue(); strikeP = Double.valueOf(inputLine.substring(0,7)).doubleValue(); if(Math.abs(futuresP-strikeP)<futuresP/12.0) { (tableBody[6*k]).setText(maturity); (tableBody[6*k+1]).setText(futuresPs); (tableBody[6*k+2]).setText(inputLine.substring(0,4)); (tableBody[6*k+3]).setText(inputLine.substring(32,39)); x = c1.eurcall(futuresP,strikeP); /* System.out.println(futuresP); System.out.println(strikeP); System.out.println(x.value/100.0); System.out.println(x.delta); */ (tableBody[6*k+4]).setText(String.valueOf((float) Math.floor(1000.0 *(x.value/100.0) + 0.5)/1000.0)); (tableBody[6*k+5]).setText(String.valueOf((float) Math.floor(1000.0 *(x.delta) + 0.5)/1000.0)); (tableBody[6*k+3]).setForeground(Color.black); if(optionP > 1.05 *(x.value/100.0)) (tableBody[6*k+3]).setForeground(Color.red); if(optionP < .95 * (x.value/100.0)) (tableBody[6*k+3]).setForeground(Color.green); k++;} } catch(NumberFormatException e) {}} optin.close(); } catch(MalformedURLException e) { System.err.println("Error: bad URL"); System.exit(0); } catch(IOException e) { System.err.println("Error: Trouble opening optionsPage"); System.exit(0);}} public boolean handleEvent(Event event) { if(event.id == Event.WINDOW_DESTROY) { System.exit(0);} return super.handleEvent(event);} double text2double(TextField tf) { return Double.valueOf(tf.getText()).doubleValue();} public boolean action(Event ev, Object arg) { if(ev.target instanceof TextField) { recalc(); return true;} return false;}}
Exhibit B: FutOp.java
// // Binomial futures option pricing model: computational engine // public class FutOp { int nper; double tinc,disc,up,down,prcup,prcdn; double val[]; public FutOp() {} public void newPars(double ttm,int npers,double r,double sigma) { nper = npers; tinc = ttm/(double) nper; disc = Math.exp(-r * tinc); up = 1.0 + sigma * Math.sqrt(tinc); down = 1.0 - sigma * Math.sqrt(tinc); prcup = 0.5*disc; prcdn = 0.5*disc; val = new double[npers+1];} public ValHedge eurcall(double f0,double X) { int i,j; double futprice; ValHedge x1 = new ValHedge(); // initialize terminal payoffs // i is the number of up moves over the whole life for(i=0;i<=nper;i++) { futprice = f0 * Math.pow(up,(double) i) * Math.pow(down,(double) (nper-i)); val[i] = Math.max(futprice - X,0.0);} // compute prices back through the tree // j+1 is the number of periods from the end // i is the number of up moves from the start for(j=0;j<nper-1;j++) { for(i=0;i<nper-j;i++) { val[i] = prcdn * val[i] + prcup * val[i+1];}} x1.value = prcdn * val[0] + prcup * val[1]; x1.delta = (val[1]-val[0]) / (f0*(up-down)); return(x1);}}
Exhibit C: ValHedge.java
public class ValHedge { public double value; public double delta; public ValHedge() {}}