Select a Chapter: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Back to the Main Page
Chapter Nine listings: 6 classes

import javax.swing.JOptionPane;

public class IO
{
     private static String itsTitle = "";

     /** Change the title displayed on message dialogs. */

     public static void setTitle (String givenTitle)
     {    itsTitle = givenTitle;
     }    //======================

     /** Display a message to the user of the software. */

     public static void say (Object message)
     {    JOptionPane.showMessageDialog (null, message, 
                              itsTitle, JOptionPane.PLAIN_MESSAGE);
     }    //======================

     /** Display prompt to the user; wait for the user to enter:
      *    (a) for askLine, a string of characters; 
      *    (b) for askInt, a whole number; 
      *    (c) for askDouble, a decimal number;
      *  Return that value; but return "" or zero on null input. */


     public static String askLine (String prompt)
     {    String s = JOptionPane.showInputDialog (prompt);
          return s == null  ?  ""  :  s;
     }  //======================


     public static double askDouble (String prompt)
     {    for (;;)
               try
               {    String s = askLine (prompt).trim();
                    return s.length() == 0 ? 0 : Double.parseDouble (s);
               }catch (NumberFormatException e)
               {    prompt = "Badly-formed number: " + prompt;
               }
     }  //======================


     public static int askInt (String prompt)
     {    for (;;)
               try
               {    String s = askLine (prompt).trim();
                    return s.length() == 0  ?  0 : Integer.parseInt (s);
               }catch (NumberFormatException e)
               {    prompt = "Badly-formed integer: " + prompt;
               }
     }  //======================
}


import java.io.*;

public class Buffin extends BufferedReader
{    
     private static boolean temp;
     /////////////////////////////////
     private boolean isKeyboard;


     /** Connect to the disk file with the given name.  If this
      *  cannot be done, connect to the keyboard instead. */

     public Buffin (String filename)
     {    super (openFile (filename));
          isKeyboard = temp;
     }    //======================


     private static Reader openFile (String filename)
     {    try
          {    temp = false;
               return new FileReader (filename);  // IOException here
          }catch (IOException e)
          {    temp = true;
               return new InputStreamReader (System.in);
          }
     }    //======================


     /** Read one line from the file and return it.  
      *  Return null if at the end of the file. */

     public String readLine()
     {    if (isKeyboard)
          {    System.out.print (" input> ");
               System.out.flush();  // flush the output buffer
          }
          try
          {    return super.readLine(); // in BufferedReader
          }catch (IOException e)
          {    System.out.println ("Cannot read from the file");
               return null;
          }
     }    //======================
}     


public class Investor
{
     /** Ask the user how much money to invest and how much to
      *  add or subtract monthly.  Then process a sequence of
      *  investment decisions for as long as the user wants. 
      *  Developed by Dr. William C. Jones       January 2001 */

     public static void main (String[] args)
     {    IO.say ("This program tests your success at investing.");
          Portfolio wealth = new Portfolio();
          System.out.println (wealth.describeInvestmentChoices());

          InvestmentManager agent = new InvestmentManager();
          agent.askInitialSetup (wealth);
          agent.processInvestmentDecisions (wealth);
          System.exit (0);
     }    //======================
}     


class InvestmentManager  // Helper class for Investor application
{
     /** Get the starting values for the portfolio.  */

     public void askInitialSetup (Portfolio wealth)
     {    double value = IO.askDouble ("Invest how much initially?");
          wealth.addToMoneyMarket (value);
          IO.say ("Initially it is all in the money market.");
          value = IO.askDouble ("How much do you add each month "
                   + "(Use a negative number for a withdrawal)? ");
          wealth.setMonthlyDeposit (value);
     }    //======================


     /** Repeatedly get user input on re-allocating investments
      *  and update the portfolio's status correspondingly. */

     public void processInvestmentDecisions (Portfolio wealth)
     {    int days = Asset.MONTH;  // trading days in one month
          char choice = this.askUsersMenuChoice();
          while (choice != 'S' && choice != 's')  // S means STOP
          {    if (choice == 'Y' || choice == 'y')
                    wealth.reallocateAssets();
               int answer = IO.askInt ("How many days before the "
                       + "next decision \n(ENTER if no change)? ");
               if (answer > 0)   // ENTER returns zero
                    days = answer;
               wealth.letTimePass (days);
               System.out.println (wealth.getCurrentValues());
               choice = this.askUsersMenuChoice();
          }
     }    //======================


     /** Get the first letter of user's choice from the menu.  */

     public char askUsersMenuChoice()
     {    String input = IO.askLine ("Enter YES (or anything "
                   + "starting with Y or y) to reallocate assets; "
                   + "\nEnter STOP (or anything starting with S "
                   + "or s) to stop); or"
                   + "\nPress ENTER or anything else to continue:");
          return  (input.length() == 0)  ?  ' '  :  input.charAt(0);
     }    //======================
}


import java.util.Random;   // goes at the top of the file

public class Portfolio
{
     public static final int NUM_ASSETS = 5;
     /////////////////////////////////
     private Asset[]  itsAsset = new Asset[NUM_ASSETS]; 
     private double[] itsValue = {0,0,0,0,0};
     private double   itsMonthlyDeposit = 0;
     private int      itsAgeInDays = 0;


     public Portfolio()
     {    itsAsset[0] = new Asset ("money mkt   ", 1.00020, 1.0001);
          itsAsset[1] = new Asset ("2-yr bonds  ", 1.00027, 1.004);
          itsAsset[2] = new Asset ("large caps  ", 1.00038, 1.011);
          itsAsset[3] = new Asset ("small caps  ", 1.00041, 1.015);
          itsAsset[4] = new Asset ("foreign     ", 1.00045, 1.020);
     }    //======================


     public void addToMoneyMarket (double amountAdded)
     {    itsValue[0] += amountAdded;
     }    //======================


     public void setMonthlyDeposit (double deposit)
     {    itsMonthlyDeposit = deposit;
     }    //======================


     /** Update the status for changes in price levels for 
      *  several days. */

     public void letTimePass (int numDays)
     {    for (;  numDays > 0;  numDays--)
          {    for (int k = 0;  k < NUM_ASSETS;  k++)
                    itsValue[k] *= itsAsset[k].oneDaysMultiplier();
               itsAgeInDays++;
               if (itsAgeInDays % Asset.MONTH == 0)
                    itsValue[0] += itsMonthlyDeposit;
          }
     }    //======================


     /** Return the values for each holding.  */

     public String getCurrentValues()
     {    String s = "\nname \t\tcurrent value \n";
          for (int k = 0;  k < NUM_ASSETS;  k++)
               s += itsAsset[k].getName() + "\t$"
                                + (int) (itsValue[k] + 0.5) + "\n";
          return s;
     }    //======================


     /** Return description of all available investment choices.  */

     public String describeInvestmentChoices()
     {    String s = Asset.getHeading() + "\n";
          for (int k = 0;  k < NUM_ASSETS;  k++)
               s += itsAsset[k].description();
          return s;
     }    //======================


     /** Accept a reallocation of investments by the user.  */

     public void reallocateAssets()
     {    IO.say ("How will you invest your current assets?"
                    + "\nUnallocated amounts go in a money market.");
          for (int k = 1;  k < NUM_ASSETS;  k++)
          {    double amount = IO.askDouble ("How much in "
                              + itsAsset[k].getName() + "? ");
               itsValue[0] += itsValue[k] - amount;
               itsValue[k] = amount;
          }
          IO.say ("That leaves $" + (int) (itsValue[0] + 0.5)
                         + " in the money market.");
     }    //======================
}


class Asset
{
     public static final int MONTH = 21;
     public static final int YEAR = 12 * MONTH;
     private static Random random = new Random();
     /////////////////////////////////
     private String itsName;
     private double itsReturn;
     private double itsRisk;


     public Asset (String name, double average, double volatility)
     {    itsName   = name;
          itsReturn = Math.log (average);
          itsRisk   = Math.log (volatility);
     }    //======================


     public String getName()
     {    return itsName;
     }    //======================


     public static String getHeading()
     { return "name\tgood year\tavg year\tbad year";
     }    //======================


     public String description()
     {    double rate = itsReturn * YEAR;
          double risk = itsRisk * Math.sqrt (YEAR);
                  return itsName + toPercent (rate + risk)
                 + "%\t" + toPercent (rate)
                 + "%\t\t" + toPercent (rate - risk) + "% \n";
     }    //======================


     private double toPercent (double par)
     {    return ((int)(1000 * Math.exp(par) + 0.5) - 1000) / 10.0;
     }    //======================


     public double oneDaysMultiplier()
     {    return random.nextInt (2) == 0   // 50-50 chance
                         ?  Math.exp (itsReturn + itsRisk)  
                         :  Math.exp (itsReturn - itsRisk);
     }    //======================
}     

All information Copyright (c)1999 - Dr. William C. Jones, Jr.
Layout and Design Copyright © Psumonix, LLC. All Rights Reserved.