import java.util.*; import java.awt.*; import jsr166y.*; import extra166y.*; import DPJRuntime.Framework.*; import DPJRuntime.Framework.ArrayOps.*; import java.util.concurrent.atomic.*; /** * Code, a test-harness for invoking and driving the Applications * Demonstrator classes. * * <p>To do: * <ol> * <li>Very long delay prior to connecting to the server.</li> * <li>Some text output seem to struggle to get out, without * the user tapping ENTER on the keyboard!</li> * </ol> * * @author H W Yau * @version $Revision: 1.12 $ $Date: 1999/02/16 19:13:38 $ */ public class AppDemo extends Universal { //------------------------------------------------------------------------ // Class variables. //------------------------------------------------------------------------ public static double JGFavgExpectedReturnRateMC =0.0; /** * A class variable. */ public static boolean DEBUG=true; /** * The prompt to write before any debug messages. */ protected static String prompt="AppDemo> "; public static final int Serial=1; //------------------------------------------------------------------------ // Instance variables. //------------------------------------------------------------------------ /** * Directory in which to find the historical rates. */ private String dataDirname; /** * Name of the historical rate to model. */ private String dataFilename; /** * The number of time-steps which the Monte Carlo simulation should * run for. */ private int nTimeStepsMC=0; /** * The number of Monte Carlo simulations to run. */ private int nRunsMC=0; /** * The default duration between time-steps, in units of a year. */ private double dTime = 1.0/365.0; /** * Flag to determine whether initialisation has already taken place. */ private boolean initialised=false; /** * Variable to determine which deployment scenario to run. */ private int runMode; region Cont; // ...for the containers region Tasks; // ...for the tasks region Results; // ...for the results private DisjointArray<ToTask<Tasks>,Cont> tasks; private DisjointArray<ResultWrapper<Results>,Cont> results; public AppDemo(String dataDirname, String dataFilename, int nTimeStepsMC, int nRunsMC) { this.dataDirname = dataDirname; this.dataFilename = dataFilename; this.nTimeStepsMC = nTimeStepsMC; this.nRunsMC = nRunsMC; this.initialised = false; set_prompt(prompt); set_DEBUG(DEBUG); } /** * Single point of contact for running this increasingly bloated * class. Other run modes can later be defined for whether a new rate * should be loaded in, etc. * Note that if the <code>hostname</code> is set to the string "none", * then the demonstrator runs in purely serial mode. */ /** * Initialisation and Run methods. */ PriceStock psMC; double pathStartValue = 100.0; double avgExpectedReturnRateMC = 0.0; double avgVolatilityMC = 0.0; ToInitAllTasks initAllTasks = null; //public void initSerial() { public void initParallel() { try{ // // Measure the requested path rate. // read from the file and store the data in an array // rateP contains the entire data as an array RatePath rateP = new RatePath(dataDirname, dataFilename); // for debugging purpose rateP.dbgDumpFields(); ReturnPath returnP = rateP.getReturnCompounded(); returnP.estimatePath(); returnP.dbgDumpFields(); // get expected return rate and volatility double expectedReturnRate = returnP.get_expectedReturnRate(); double volatility = returnP.get_volatility(); // Now prepare for MC runs. // initialize basic task information with the computed values in ReturnPath initAllTasks = new ToInitAllTasks(returnP, nTimeStepsMC, pathStartValue); String slaveClassName = "MonteCarlo.PriceStock"; // // Now create the tasks. initTasks(nRunsMC); // } catch( DemoException demoEx ) { dbgPrintln(demoEx.toString()); System.exit(-1); } } public void runParallel() { results = tasks.<ResultWrapper<Results>,reads Root,Tasks> withMapping(new TaskToResultWrapper()); } public static <region R1,R2>void incPathValue(double[]<R1> operand, double[]<R2> result) reads R1 writes R2 { for (int i = 0; i < operand.length; ++i) { result[i] += operand[i]; } } final class ResultWrapper<region R> { double avgReturnRate in this; double avgVolatility in this; double[]<this> pathValue in this; ToResult<R> result; ResultWrapper(ToResult<R> result) reads R writes this { avgReturnRate = result.get_expectedReturnRate(); avgVolatility = result.get_volatility(); this.pathValue = new double[result.get_pathValue().length]<this>; incPathValue(result.get_pathValue(), this.pathValue); //this.pathValue = result.get_pathValue(); this.result = result; } } final class TaskToResultWrapper implements DisjointObjectToObject<ToTask<Tasks>, ResultWrapper<Results>,reads Root, Tasks> { public <region R>ResultWrapper<R> op(final ToTask<Tasks> task) reads Root, Tasks writes R { PriceStock<R> ps = new PriceStock<R>(); ps.setInitAllTasks(initAllTasks); ps.setTask(task); ps.run(); return new ResultWrapper<R>(ps.getResult()); } } public void processParallel() { // // Process the results. System.out.println("processParallel"); try { processResults(); } catch( DemoException demoEx ) { dbgPrintln(demoEx.toString()); System.exit(-1); } } //------------------------------------------------------------------------ /** * Generates the parameters for the given Monte Carlo simulation. * * @param nRunsMC the number of tasks, and hence Monte Carlo paths to * produce. */ private void initTasks(int nRunsMC) { tasks = new DisjointArray.Creator<ToTask<Tasks>, Cont>().create(nRunsMC, ToTask.class); tasks = tasks.<pure>withIndexedMapping(new InitTask()); } final class InitTask implements DisjointIntAndObjectToObject<ToTask<Tasks>, ToTask<Tasks>, pure> { public <region R>ToTask<R> op(int index, final ToTask<Tasks> unused) pure { String header="MC run "+String.valueOf(index); ToTask<R> task = new ToTask<R>(header, (long)(index*11)); return task; } } /** * Method for doing something with the Monte Carlo simulations. * It's probably not mathematically correct, but shall take an average over * all the simulated rate paths. * * @exception DemoException thrown if there is a problem with reading in * any values. */ private class ResultReducer implements Reducer<ResultWrapper<Results>,pure> { public ResultWrapper<Results> op(final ResultWrapper<Results> A, final ResultWrapper<Results> B) writes A, B { A.avgReturnRate += B.avgReturnRate; A.avgVolatility += B.avgVolatility; for (int i = 0; i < A.pathValue.length; ++i) { A.pathValue[i] += B.pathValue[i]; } return A; } } private void processResults() throws DemoException { ResultWrapper<Results> first = results.get(0); if (nRunsMC != results.size()) { errPrintln("Fatal: TaskRunner managed to finish with no all the results gathered in!"); System.exit(-1); } // Create an instance of a RatePath, for accumulating the results of the // Monte Carlo simulations. RatePath<Results> avgMCrate = new RatePath<Results>(nTimeStepsMC, "MC", 19990109, 19991231, dTime); ResultWrapper<Results> result = results.<pure>reduce(new ResultReducer(), first); double avgExpectedReturnRateMC = result.avgReturnRate; double avgVolatilityMC = result.avgVolatility; // ******************************************************************** // final result avgMCrate.inc_pathValue(result.pathValue); //avgMCrate.set_pathValue(result.pathValue); avgMCrate.inc_pathValue((double)1.0/((double)nRunsMC)); avgExpectedReturnRateMC /= nRunsMC; avgVolatilityMC /= nRunsMC; // ******************************************************************** JGFavgExpectedReturnRateMC = avgExpectedReturnRateMC; dbgPrintln("Average over "+nRunsMC+": expectedReturnRate="+ avgExpectedReturnRateMC+" volatility="+avgVolatilityMC + JGFavgExpectedReturnRateMC); } // //------------------------------------------------------------------------ // Accessor methods for class AppDemo. // Generated by 'makeJavaAccessor.pl' script. HWY. 20th January 1999. //------------------------------------------------------------------------ /** * Accessor method for private instance variable <code>dataDirname</code>. * * @return Value of instance variable <code>dataDirname</code>. */ public String get_dataDirname() { return(this.dataDirname); } /** * Set method for private instance variable <code>dataDirname</code>. * * @param dataDirname the value to set for the instance variable <code>dataDirname</code>. */ public void set_dataDirname(String dataDirname) { this.dataDirname = dataDirname; } /** * Accessor method for private instance variable <code>dataFilename</code>. * * @return Value of instance variable <code>dataFilename</code>. */ public String get_dataFilename() { return(this.dataFilename); } /** * Set method for private instance variable <code>dataFilename</code>. * * @param dataFilename the value to set for the instance variable <code>dataFilename</code>. */ public void set_dataFilename(String dataFilename) { this.dataFilename = dataFilename; } /** * Accessor method for private instance variable <code>nTimeStepsMC</code>. * * @return Value of instance variable <code>nTimeStepsMC</code>. */ public int get_nTimeStepsMC() { return(this.nTimeStepsMC); } /** * Set method for private instance variable <code>nTimeStepsMC</code>. * * @param nTimeStepsMC the value to set for the instance variable <code>nTimeStepsMC</code>. */ public void set_nTimeStepsMC(int nTimeStepsMC) { this.nTimeStepsMC = nTimeStepsMC; } /** * Accessor method for private instance variable <code>nRunsMC</code>. * * @return Value of instance variable <code>nRunsMC</code>. */ public int get_nRunsMC() { return(this.nRunsMC); } /** * Set method for private instance variable <code>nRunsMC</code>. * * @param nRunsMC the value to set for the instance variable <code>nRunsMC</code>. */ public void set_nRunsMC(int nRunsMC) { this.nRunsMC = nRunsMC; } //------------------------------------------------------------------------ // Hack to get around the fact that Java doesn't let us say C<R>.class private class ParallelArrayMaker<type T<region TR>> { <region R>ParallelArray<T<R>> create(int n, Class<T> cls) { Class<T<R>> cls1 = (Class<T<R>>) cls; return ParallelArray.<T<R>>create(n, cls1, ParallelArray.defaultExecutor()); } } }