//
// 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"))) {};
    futin.readLine();                     // skip one line after table header
    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(); // 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))) {}; // find 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;}}
