MCOV

Open Source Monte Carlo Option Valuer
Home
Contact
Download
Releases
Installation
Read-Me
License

Monte Carlo
Strategy Objects
C++ Classes

C++ Files
mcovaluer.h
mcovaluer.cxx
mcov.cxx

mcovaluer.h

C++ Header File for MCOV Software

This is the mcovaluer.h file that comes with a MCOV distribution (without the license section)...

// ================================================================
//  mcovaluer.h  -  Monte Carlo Option Valuer
//
//  mcoValuer (and supporting classes) -
//    used to determine the value of a financial option 
//      using a Monte Carlo method.
//
//  See copyright notice and license at end of this file.
//
//  'price' is for the underlying instrument (stock, future, etc.)
//  'bid' is what is received when the option is sold

#ifndef _mcovalue_h_guard
#define _mcovalue_h_guard

#include <iostream>
#include <sstream>

using namespace std;

// ----------------------------------------------------------------
//  Purpose of the Monte Carlo Option Valuer
//
//  An object of the mcoValuer class can be used to estimate
//  the value of an American-Style option (one that can be 
//  exercised at any time) to a person with a particular
//  strategy for deciding when to sell the option.
//
// ------------------------------------------------------
//  The Monte Carlo Method
//
//  The MCOV software uses a Monte Carlo method.  The price 
//  of the underlying instrument (stock/future/index) is 
//  projected, day by day, until the option is sold or 
//  expires.  When this happens, the value of the option 
//  is estimated; if the option was not sold, this value 
//  is zero.  This process is repeated many times, 
//  generating many different values for the option.  
//
//  The MCOV software estimates the value of the option 
//  as the average of the set of generated values (some 
//  of which are zero).
//
//  A new day is projected from the latest day by:
//    - picking a 'prototype' day from the price-history
//    - identifying the changes during the prototype day
//        (starting from the previous close)
//    - applying the same changes to the latest day to
//        project the new day
//
//  The user of the application will generally use 
//  price-history data that includes some amount of the 
//  past up to today, plus, perhaps, additional data from 
//  other periods in the past.
//
//  When an option is sold or expires, and its value is
//  estimated, a simplistic method is used to estimate
//  the remaining time value.  Therefore, The MCOV 
//  software works best if the option is sold when the 
//  time value is relatively low: 
//    - because the option will expire soon, or, 
//    - because the option is very deep in the money.
//
//
// ------------------------------------------------------
//  Strategies and Strategy Objects
//
//  The MCOV software is controlled by strategy objects
//  that make various decisions or estimates:
//    - was the option sold in the latest day?
//    - price of underlying instrument when option sold
//    - bid for the option when it was sold
//    - day to use as a prototype to project the next day
//    - how to project the next day using a prototype day
//
//  Strategies may be modified or replaced by subclassing
//  the default strategy classes (or the base classes).
//  Strategy classes depend upon the dayset (the history
//  and the projected days) being composed of the correct
//  type of day-object.  A day-factory class may be
//  subclassed to construct the correct type of day.
//
//  Only a very simple set of strategies are currently
//  included in the MCOV software, and they are used
//  by default:
//    - the option is sold just before it expires (if it is
//        in the money)
//    - the bid for the option is estimated be 99% of the
//        the intrinsic value
//    - prototype days are picked at random from the history
//    - day-objects store closing-price and change-ratio
//        ( close / previous-close )
//    - the closing-price of a day being projected is the
//        previous close multiplied by the change-ratio
//        of the prototype day
//
//  Much more sophisticated and subtle stategies can be
//  developed, particularly in relation to the process 
//  of picking prototype days.
//
//
// ------------------------------------------------------
//  Application of the MCOV Classes
//
//  In a simple application of the MCOV classes:
//
//    - an mcoValuer object is created, which reads a
//        specified price-history file
//
//    - an object is created which describes an option
//
//    - the option-object is passed to a function of
//        the mcoValuer object, which estimates the
//        value of the option
//
//    - an error-status object is checked, and if an
//        error occurred, a message is printed; otherwise,
//        the value of the option is printed.
//
//
// ------------------------------------------------------
//  Notes about the C++
//
//  If an error occurs, the software records the information 
//  in a singleton instance of mcoErr rather than throwing
//  an exception (which some compilers may not support).
//
//  Downcasting (casting *base to *derived) in classes that KNOW
//  the type that they require is done with C-style casts rather 
//  than dynamic-casts (which some compilers may not support).  
//  This can only be a problem if an mcoValuer is constructed 
//  with a combination of day-factory and strategies that is 
//  inappropriate.  Therefore, testing for this situation should 
//  be done once (per strategy, perhaps), rather than every time 
//  a day (for instance) is referenced.
//
// ------------------------------------------------------
//  Design Patterns and Flexibility
//
//  mcoDay is a very simple subclass of mcoDayBase - the only
//  fundamental (as opposed to derived) attributes are:
//    - the day-number, and, 
//    - the closing-price. 
//  mcoDay or mcoDayBase may be subclassed to hold more 
//  information about a day for an underlying instrument.
//
//  A new day subclass is used by passing an instance of a new
//  new subclass of mcoDayFactoryBase (an Abstract Factory) to 
//  the mcoValuer constructor.
//  
//  Functions that answer various questions are encapsulated in
//  in Strategy classes, which may be subclassed.  If the user
//  of the valuer wants to use their own strategies, Strategy
//  objects may be passed to the mcoValuer constructor.  A
//  particular strategy subclass will depend on the Valuer's
//  dayset containing days of a particular subclass.
//
//  Singletons - classes that will have only one instance:
//    - random number generator
//    - error-status
//
//
// ----------------------------------------------------------------
//  Classes  (subclassing shown by indentation)

class mcoOption;             // An option on a stock/future/index

class mcoValuer;             // Object to value an option

class mcoDayBase;            // Base: day of underlying instrument
  class mcoDay;              // Day based on close-price

class mcoDaySet;             // Days - history and projection

class mcoTryStrategy;        // Base: strategies used in tries
  class mcoSellStratBase;    // When to sell, results
    class mcoSellStrategy1;  // Simple: sell at expiry
  class mcoPDayStratBase;    // Picking/using prototype days
    class mcoPDayStrategy1;  // Simple: random day

class mcoDayFactoryBase;     // Base: return a new day
  class mcoDayFactory;       // Default: return new mcoDay

class mcoErr;                // Error status, message (singleton) 
class mcoRand;               // Random number generator (singleton) 

class mcoSentry;             // Ensure mcoValuer objects deleted 


// ================================================================
//  mcoOption  -  Option on an underlying financial instrument
//
//  This class will generally not be subclassed; if you want to
//  maintain data about the (state of) the option, add attributes
//  to your subclass days and/or strategies.
//
//  initialize() will be called by an mcoValuer function.

class mcoOption {

  char    m_put_call;
  double  m_strike_price;
  long    m_days_to_expiry;  // At time option bought/created.

  long    m_iday_expiry;  // Set by user of object.

public:

  mcoOption (char put_call, 
             double strike_price, long days_to_expiry);
  virtual ~mcoOption (void) {}

  void set_iday_expiry (long x) { m_iday_expiry = x; }

  char   put_call       (void) const { return m_put_call;       }
  double strike_price   (void) const { return m_strike_price;   }
  long   days_to_expiry (void) const { return m_days_to_expiry; }
  long   iday_expiry    (void) const { return m_iday_expiry;    }

  bool  initialize (mcoDaySet *dayset);  // called by mcoValuer

};


// ================================================================
// mcoValuer  -  Object to determine the value of an option
//
// If strategy or factory objects are passed to the constructor,
// they are owned by the caller - they will not be deleted upon
// destruction.

class mcoValuer {

  mcoDaySet  * m_dayset;

  mcoSellStratBase  * m_sell_strategy;
  mcoPDayStratBase  * m_pday_strategy;
  mcoDayFactoryBase * m_day_factory;

  bool   m_owns_sell_strategy;
  bool   m_owns_pday_strategy;
  bool   m_owns_day_factory;

protected:

  void cleanup (void);
  double do_try (mcoOption *opt);

public:

  mcoValuer (const char *hist_file,
             mcoSellStratBase  *ss =0,
             mcoPDayStratBase  *ps =0,
             mcoDayFactoryBase *df =0,
             long max_hist =5000,
             long max_proj =100);
  virtual ~mcoValuer (void);

  virtual double option_value (mcoOption *opt,
                               long num_tries =2000);

};

// ================================================================
//  mcoDayBase  -  Base class for a day.
//
//  An instance of a subclass of mcoDayBase holds information
//  about one day for the underlying instrument (stock, future).
//
//  Days MUST be created and set in chronological order because
//  the constructor of a subclass of mcoDayBase may derive values
//  by referring to other days in the DaySet.
//
//  set() functions in subclasses MUST do the setting by 
//  calling set() functions in the parent-class so that
//  derived-values and the is_set flag get set.
//
//  Subclasses may override the  set(const char *)  function
//  to set the day from a string (such as a record from a file).
//
//  In subclasses, an overriding reset() must call this reset().

class mcoDayBase {

    // unchanging attributes set during construction
  mcoDaySet  * m_parent;
  long         m_iday;       // index used by parent

    // attributes set when day is 'set'
  long         m_daynum;     // -1 if it is not set
  bool         m_is_set;

public:

  mcoDayBase (mcoDaySet *parent, long iday)
               : m_parent(parent), m_iday(iday) {
    m_daynum = -1;
    m_is_set = false;
  }

  virtual ~mcoDayBase (void) {}

  void set_daynum (long x) { m_daynum = x; }
  void set_is_set (bool sis =true);

  mcoDaySet  * parent  (void) const { return m_parent;  }
  long         iday    (void) const { return m_iday;    }
  long         daynum  (void) const { return m_daynum; }
  bool         is_set  (void) const { return m_is_set;  }

  virtual void  reset (void) { set_is_set(false); }

  virtual bool set (const string& str) { return true; }

};

// ================================================================
//  mcoDay  -  a simple day based on the daily close-price
//
//  People wishing to define new day classes may subclass
//  this class or its parent (mcoDayBase).

class mcoDay : public mcoDayBase {

    // fundamental attributes
  double   m_price_close;

    // derived attributes (from this and other days)
  double   m_close_chg1;          // close / close-1-day-back

protected:

  void  calc_close_chg1 (void);
  mcoDay * day (long iday);       // downcast to this type

public:

  mcoDay (mcoDaySet *parent, long iday)
                        : mcoDayBase(parent,iday) {}
  virtual ~mcoDay (void) {}

  double  price_close (void) const { return m_price_close; }
  double  close_chg1  (void) const { return m_close_chg1;  }

  virtual void  reset (void) {
    m_price_close = m_close_chg1 = 0.0;
    mcoDayBase::reset();
  }

  void set (long daynum, double prc_close);

    // set from non-comment record from an xxx.mcod file
  virtual bool  set (const string& str);

};

// ----------------------------------------------------------------
//  mcoDaySet  -  Set of days - history and projection
//
//  Days MUST be created and set in chronological order.
//  Projected days may be reset, and then projected days
//  may be set again (in chronological order).
//
//  The history some history up until today (or yesterday).  
//  It may also contain days from periods in the past that
//  the user would like to use in the Monte Carlo simulation.
//
//  history_is_set() MUST be called after all history days
//  have been set and before the first projected day is set.

class mcoDaySet {

  mcoDayBase  ** m_day;        // Array of pointers to days.

  long    m_max_hist;     // Maximum days of history in m_day.
  long    m_max_proj;     // Maximum days that can be projected.
  long    m_num_hist;     // Number of days of history.
  long    m_num_proj;     // Number of days projected.

  bool    m_history_is_set;

protected:

  void cleanup (void);
  bool read_hist (const char *histfile, mcoDayFactoryBase *df);

public:

  mcoDaySet (const char *hist_file,
             mcoDayFactoryBase *df =0,
             long max_hist_days =5000, 
             long max_proj_days = 100);
  virtual ~mcoDaySet (void);

  long  max_hist (void) const { return m_max_hist; }
  long  max_proj (void) const { return m_max_proj; }
  long  num_hist (void) const { return m_num_hist; }
  long  num_proj (void) const { return m_num_proj; }
  long  max_day  (void) const { return m_max_hist+m_max_proj; }
  long  num_day  (void) const { return m_num_hist+m_max_proj; }
  long  num_set  (void) const { return m_num_hist+m_num_proj; }

  long iday_last_set   (void) const { return m_num_hist-1; }
  long iday_hist_first (void) const { return 0;            }
  long iday_hist_last  (void) const { return m_num_hist-1; }
  long iday_proj_first (void) const { return m_num_hist;   }
  long iday_proj_last  (void) const { 
                           return m_num_hist+m_num_proj-1; }

  mcoDayBase * day (long iday) const { return (m_day[iday]); }

  void note_day_is_set (long iday);

  void history_is_set (void) { m_history_is_set = true; }

  void reset_projection (void);

};

// ================================================================
//  mcoTryStrategy  -  Base class of strategies used in tries.
//
//  If a dayset is not passed into the constructor, it must
//  be set via set_dayset() before the strategy is used.
//
//  This is a pure virtual base class for the strategy.
//
//  Subclasses will generally depend on a particular subclass
//  of mcoDayBase being used in the dayset, and they may define
//  a function to do the downcast.  

class mcoTryStrategy {

  mcoDaySet   * m_dayset;      // not owned by this strategy

protected:

  mcoDaySet * dayset (void) const { return m_dayset; }

public:

  mcoTryStrategy (mcoDaySet *ds =0) : m_dayset(ds) {}
  virtual ~mcoTryStrategy (void) {}
  void set_dayset (mcoDaySet *ds) { m_dayset = ds; }

};


// ================================================================
//  mcoSellStratBase  -  In a try: Should I sell today?
//
//  The virtual function  sell_this_day()  is called after
//  each day is projected.  It determines whether the option
//  was sold during this day:
//     if sold: return price of underlying instrument (ex. stock)
//     if not sold: return 0.0
//
//  The virtual function  option_bid()  is called, if the option
//  was sold, after the loop of days - ie. after the day the 
//  option expires has been projected.  It returns the bid - the
//  price received for the option when it was sold.  This function
//  is called after the loop so that, if the option is sold early,
//  the remaining days can be used in the estimation of time value
//  received when the option was sold.
//
//  The rem_time_value() function returns the remaining-time-value
//  component of the bid for the option at the time it is sold.
//  This is sort of weird, inasmuch as the purpose of this file
//  of classes is to estimate time-value of the option.  This can
//  be done fairly simply, however, if the strategy is to sell
//  the option when if is close to expiry; if the option is sold
//  just before expiry, the time-value is zero.
//
//  Subclasses must beware of 'postdictive errors' - for example, 
//  using the close-price to decide to sell earlier than the close.
//  It is subtle, however - because we don't store every tick,
//  we have to use the data we have to make deductions about
//  the value we want to determine.  If all we know are closes,
//  it might be acceptable to assume that a sale during the day
//  occurred between the close and the previous close (even
//  though this is not necessarily true).
//
//  This is a pure virtual base class for the strategy.

class mcoSellStratBase : public mcoTryStrategy {

public:

  mcoSellStratBase (mcoDaySet *ds =0) : mcoTryStrategy(ds) {}
  virtual ~mcoSellStratBase (void) {}

  virtual double price_if_sold (mcoOption *opt) =0;   // or 0.0
  virtual double rem_time_value (mcoOption *opt, double price) =0;
  virtual double option_bid (mcoOption *opt, double price) =0;

};


// ----------------------------------------------------------------
//  mcoSellStrategy1  -  In a try: Should I sell today?
//
//  In this simple implementation of this strategy:
//     Sell just before option expires
//
//  This strategy uses days of type:  mcoDay

class mcoSellStrategy1 : public mcoSellStratBase {

public:

  mcoSellStrategy1 (mcoDaySet *ds =0) : mcoSellStratBase(ds) {}
  virtual ~mcoSellStrategy1 (void) {}

  mcoDay * day (long iday) const { 
    return ( (mcoDay*) dayset()->day(iday) );
  }

  virtual double price_if_sold (mcoOption *opt);   // or 0.0
  virtual double rem_time_value (mcoOption *opt, double price);
  virtual double option_bid (mcoOption *opt, double price);

};

// ================================================================
//  mcoPDaytStratBase  -  For a day: pick/apply a prototype day
//
//  prototype_iday() identifies a day to act as a prototype
//  for deciding what will happen on the day being projected.
//
//  apply_prototype() initializes the day being projected
//  using the prototype day.
//
//  If a dayset is not passed into the constructor, it must
//  be set via set_dayset() before the strategy is used.
//
//  This is a pure virtual base class for the strategy.

class mcoPDayStratBase : public mcoTryStrategy {

public:

  mcoPDayStratBase (mcoDaySet *ds =0) : mcoTryStrategy(ds) {}
  virtual ~mcoPDayStratBase (void) {}

  virtual long  prototype_iday (void) =0;
  virtual void  apply_prototype (long iday_proto) =0;

};
// ----------------------------------------------------------------
//  mcoPDayStrategy1  -  For a day: pick/apply a prototype day
//
//  This strategy uses days of type:  mcoDay

class mcoPDayStrategy1 : public mcoPDayStratBase {

public:

  mcoPDayStrategy1 (mcoDaySet *ds =0) : mcoPDayStratBase(ds) {}
  virtual ~mcoPDayStrategy1 (void) {}

  mcoDay * day (long iday) const { 
    return ( (mcoDay*) dayset()->day(iday) );
  }

  virtual long prototype_iday (void);
  virtual void apply_prototype (long iday_proto);

};

// ================================================================
//  mcoDayFactoryBase  -  Base class: return a new day

class mcoDayFactoryBase {
public:
  mcoDayFactoryBase (void) {}
  virtual ~mcoDayFactoryBase (void) {}
  virtual mcoDayBase * new_day (mcoDaySet *ds, long iday) =0;
};

// ----------------------------------------------------------------
//  mcoDayFactory  -  Default factory: return new mcoDay

class mcoDayFactory : public mcoDayFactoryBase {
public:
  mcoDayFactory (void) {}
  virtual ~mcoDayFactory (void) {}
  virtual mcoDayBase * new_day (mcoDaySet *ds, long iday) {
    return new mcoDay(ds,iday);
  }
};

// ================================================================
//  mcoErr  -  Error status, message - a singleton.
//
//  ex.  if ( mcoErr::instance()->is_err() ) then...

class mcoErr {

  static mcoErr * m_instance;

  string          m_msg;

protected:

  mcoErr (void) { m_msg = ""; }   // non-public constructor

public:

  ~mcoErr (void) { m_instance = 0; }

  static mcoErr *instance (void) {
    if (!m_instance) m_instance = new mcoErr;
    return m_instance;
  }

  bool         is_err (void) const { return m_msg.length(); }
  char const * msg    (void) const { return m_msg.c_str();  }

  void append (const string& str) { m_msg += str; }

  void append (long lval) {
    ostringstream ost;
    ost << lval;
    append (ost.str());
  }

  void append (int ival) {
    long lval = ival;
    append (lval);
  }

  void append (double dval) {
    ostringstream ost;
    ost << dval;
    append (ost.str());
  }

  void append (float fval) {
    double dval = fval;
    append (dval);
  }

  void err (const string& str) {
    m_msg = "";
    append (str);
  }

};


// ================================================================
//  mcoRand  -  Random number generator - a singleton.
//
//  This is actually an odd sort of singleton in that there is
//  no need to ever create one; all data and methods are static.
//  Because the constructor is not public, an instance cannot be
//  defined (unless this class or a subclass was to do it).

class mcoRand {

  static bool  m_is_setup;

protected:

  mcoRand (void) {}   // constructor not public.

public:

  virtual ~mcoRand (void) {}

  static long randnum (long maxnum);  // num between 0 and maxnum.

};


// ================================================================
//  mcoSentry  -  Ensure that mcoValuer objects are deleted.
//
//  Used by application functions in which an mcoValuer object
//  should be deleted when the function returns.

class mcoSentry {

  mcoValuer   * m_mcov;

public:

  mcoSentry (mcoValuer *mcov) : m_mcov(mcov) {}
  ~mcoSentry (void) { if (m_mcov) delete m_mcov; }

};


// ================================================================
#endif
// ================================================================