binomial_option Class Reference

#include <binomial.h>

Inheritance diagram for binomial_option:

Inheritance graph
[legend]
Collaboration diagram for binomial_option:

Collaboration graph
[legend]
List of all members.

Detailed Description

This is the classic binomial option algorithm.

Definition at line 88 of file binomial.h.

Public Member Functions

virtual const char * get_class_name ()
void set_null ()
virtual void init_calc_derived_attributes () const
 : This function calculates the values of the American Put and the American Call. It calls several virtual function. The function are virtual, so that child classes can implement different versions of the algorithm. The final value of the American call is stored as C, and the final value of the American put is stored as P.
void init (const binomial_option &rhs)
binomial_optionoperator= (const binomial_option &rhs)
 binomial_option (const binomial_option &rhs)
void init (double S, double K, double Tau, double Alpha=0, double R=0.05, double Sigma=0.2, int NumberIterations=100)
 binomial_option (double S=0, double K=0, double Tau=0, double Alpha=0, double R=0.05, double Sigma=0.2, int NumberIterations=100)
void deinit ()
virtual ~binomial_option ()
int get_NumberIterations () const
double get_Scap () const
double get_Ccap () const
double get_dt () const
double get_mu () const
double get_exp_r_t () const
double get_sqrt_tau () const
double get_sigma_sqrt_tau () const
double get_u () const
double get_v () const
const std::vector< double > & get_call_grid () const
const std::vector< double > & get_put_grid () const
const std::vector< double > & get_S_grid () const
void put_NumberIterations (int NumberIterations)
void init_simple_attributes (const binomial_option &rhs)
double C_tau (double tau)
double P_tau (double tau)
double C_sigma (double sigma)
 this function serves as a function pointer for calls to Bisection
double P_sigma (double sigma)
 this function serves as a function pointer for calls to Bisection
virtual double call_intrinsic_value () const
virtual double put_intrinsic_value () const
virtual double call_implied_sigma (double call_price, bool show_iterations=false)
 This is a wrapper for the secant algortihm. This function returns the implied volatility of a call. If there is an error, _C_implied_sigma is set to a NA = not a number, and an exception is thrown.
virtual double put_implied_sigma (double call_price, bool show_iterations=false)
 This is a wrapper for the secant algortihm. This function returns the implied volatility of a put. If there is an error, _P_implied_sigma is set to a NA = not a number, and an exception is thrown.

Static Public Member Functions

static const char * get_error_msg ()
static int get_erno ()
static int check_attributes (double S, double K, double Tau, double Alpha, double R, double Sigma, int NumberIterations)

Protected Member Functions

int strictly_check_attributes (double S, double K, double Tau, double Alpha, double R, double Sigma, int NumberIterations)
virtual double S (int i, int j) const
 This function calculates the price at a given point of the price grid. It is a virtual function so that it can be overloaded for other similar solutions for American option pricing.
virtual int get_grid_offset (int i, int j) const
 This function takes two subscripts, and maps it to a single subscript. It enables a two dimensional matrix to be stored as a one dimensional array. It uses the standard C-style storage. K = i * (NumberIncrement+1) + j, where i is the offset in time, j is the price offset, and NumberIncrement+1, is the dimension of the square matrix.
virtual int get_max_j (int i) const
 This function returns the maximum value of j, at time i. This function allows loops of this form to execute:.
virtual int get_min_j (int i) const
 This function returns the minimum value of j, at time i. This function allows loops of this form to execute:.
virtual void allocate_price_vectors () const
 This function allocates the arrays for storing call prices, put prices, and S prices. It is organized as a C-style square matrix, of dimensions (NumberIterations+1). The smaller index, is for price, so _S_grid[i*_Numberiterations + j] represents the price at time of, of the j'th element of price. This function is virtual, so that it can be overloaded for other pricing algorithms, such as grid relaxation.
virtual void solve_call_put () const
 This function does the classic binomial options calculation.
double call_intrinsic_value (double S, double exp_alpha_r_t, double exp_r_t) const
 This function calculates the intrinsic value of an American call. The value is the maximum of:.
double put_intrinsic_value (double S, double exp_alpha_r_t, double exp_r_t) const
 This function calculates the intrinsic value of an American put. The value is the maximum of:.

Protected Attributes

int _NumberIterations
double _Scap
double _Ccap
double _dt
double _mu
double _exp_r_t
double _sqrt_tau
double _sigma_sqrt_tau
double _u
double _v
std::vector< double > _call_grid
std::vector< double > _put_grid
std::vector< double > _S_grid

Static Protected Attributes

static const char * _error_msg
static int _erno


Member Function Documentation

double binomial_option::S ( int  i,
int  j 
) const [protected, virtual]

This function calculates the price at a given point of the price grid. It is a virtual function so that it can be overloaded for other similar solutions for American option pricing.

assumptions: i>=0, i<=NumberIncrement j>=get_min_j() and j<=get_max_j()
changes: nothing
returns: The price of the stock at element, (i,j) of the price grid description:This function calculates the price at a given point of the price grid. It is a virtual function so that it can be overloaded for other similar solutions for American option pricing.

Definition at line 34 of file binomial.cpp.

References _Ccap, option_pair::_S, and _Scap.

Referenced by solve_call_put().

00034                                              {
00035   return _S * exp( i * _Ccap + j * _Scap);
00036 }

int binomial_option::get_grid_offset ( int  i,
int  j 
) const [protected, virtual]

This function takes two subscripts, and maps it to a single subscript. It enables a two dimensional matrix to be stored as a one dimensional array. It uses the standard C-style storage. K = i * (NumberIncrement+1) + j, where i is the offset in time, j is the price offset, and NumberIncrement+1, is the dimension of the square matrix.

assumption: NumberIterations > 0
returns: the offset of the tuple (i, j)
changes: nothing
description: This function takes two subscripts, and maps it to a single subscript. It enables a two dimensional matrix to be stored as a one dimensional array. It uses the standard C-style storage. K = i * (NumberIncrement+1) + j, where i is the offset in time, j is the price offset, and NumberIncrement+1, is the dimension of the square matrix.

Definition at line 63 of file binomial.cpp.

References _NumberIterations.

Referenced by solve_call_put().

00063                                                         {
00064   return (i*(_NumberIterations+1)+j);
00065 }

int binomial_option::get_max_j ( int  i  )  const [protected, virtual]

This function returns the maximum value of j, at time i. This function allows loops of this form to execute:.

      for (i=NumberIncrement;i>=0;i==) { 
         for (j=get_min_j(); j<=get_max_j(); j++) {
           use an grid algorithm to solve for option price
         }
      }
      
This function is virtual so that different grid relaxation algorithms can be implemented in child classes.

Assumptions: NumberIterations > 0
Returns: the maximum allowed of the price subscript, j, for a given time subscript, i.
Changes: nothing
Description:This function returns the maximum value of j, at time i. This function allows loops of this form to execute:

      for (i=NumberIncrement;i>=0;i==) { 
         for (j=get_min_j(); j<=get_max_j(); j++) {
           use an grid algorithm to solve for option price
         }
      }
      
This function is virtual so that different grid relaxation algorithms can be implemented in child classes.

Definition at line 111 of file binomial.cpp.

Referenced by solve_call_put().

00111                                            {
00112   return i;
00113 }

int binomial_option::get_min_j ( int  i  )  const [protected, virtual]

This function returns the minimum value of j, at time i. This function allows loops of this form to execute:.

      for (i=NumberIncrement;i>=0;i==) { 
         for (j=get_min_j(); j<=get_max_j(); j++) {
           use an grid algorithm to solve for option price
         }
      }
      
This function is virtual so that different grid relaxation algorithms can be implemented in child classes.

Assumptions: NumberIterations > 0
Returns: the minimum allowed of the price subscript, j, for a given time subscript, i.
Changes: nothing
Description:This function returns the minimum value of j, at time i. This function allows loops of this form to execute:

      for (i=NumberIncrement;i>=0;i==) { 
         for (j=get_min_j(); j<=get_max_j(); j++) {
           use an grid algorithm to solve for option price
         }
      }
      
This function is virtual so that different grid relaxation algorithms can be implemented in child classes.

Definition at line 87 of file binomial.cpp.

Referenced by solve_call_put().

00087                                            {
00088   return 0;
00089 }

void binomial_option::allocate_price_vectors (  )  const [protected, virtual]

This function allocates the arrays for storing call prices, put prices, and S prices. It is organized as a C-style square matrix, of dimensions (NumberIterations+1). The smaller index, is for price, so _S_grid[i*_Numberiterations + j] represents the price at time of, of the j'th element of price. This function is virtual, so that it can be overloaded for other pricing algorithms, such as grid relaxation.

assumptions: _NumberIterations > 0
changes: _call_grid, _put_grid, _S_grid.
returns: nothing.
description: This function allocates the arrays for storing call prices, put prices, and S prices. It is organized as a C-style square matrix, of dimensions (NumberIterations+1). The smaller index, is for price, so _S_grid[i*_Numberiterations + j] represents the price at time of, of the j'th element of price. This function is virtual, so that it can be overloaded for other pricing algorithms, such as grid relaxation.

Definition at line 44 of file binomial.cpp.

References _call_grid, _NumberIterations, _put_grid, and _S_grid.

Referenced by init_calc_derived_attributes().

00044                                                    {
00045   unsigned int sz = (_NumberIterations+1) * (_NumberIterations+1);
00046   if (_call_grid.size() != sz) {
00047     std::vector<double> foo( sz); foo.swap( _call_grid);
00048   }
00049   if (_put_grid.size() != sz) {
00050     std::vector<double> foo( sz); foo.swap( _put_grid);
00051   }
00052   if (_S_grid.size() != sz) {
00053     std::vector<double> foo( sz); foo.swap( _S_grid);
00054   }
00055 }

void binomial_option::solve_call_put (  )  const [protected, virtual]

This function does the classic binomial options calculation.

assumptions: alpha, r, tau, NumberIncrement, S, and K all have reasonable values.
changes: the values of the price grids, several temporary variables and the values of C and P.
description: This function does the classic binomial options calculation.

Definition at line 120 of file binomial.cpp.

References option_pair::_alpha, option_pair::_C, option_pair::_calc_call, option_pair::_calc_put, _call_grid, _dt, _exp_r_t, option_pair::_K, _NumberIterations, option_pair::_P, _put_grid, option_pair::_r, _S_grid, _Scap, call_intrinsic_value(), get_grid_offset(), get_max_j(), get_min_j(), put_intrinsic_value(), and S().

Referenced by init_calc_derived_attributes().

00120                                            {
00121   int i, j, k;
00122   int l, m;
00123   double intrinsic_value, tau, exp_alpha_r_tau, exp_r_tau;
00124    
00125   _exp_r_t = exp( -_r * _dt);
00126 
00127   i = _NumberIterations;
00128   for (j=get_min_j(i); j<=get_max_j(i); j++) {
00129     k = get_grid_offset( i, j);
00130     _S_grid[ k] = S( i, j);
00131     _call_grid[ k] = (_S_grid[k] > _K)? (_S_grid[k] - _K):0;
00132     _put_grid[ k] = (_S_grid[k] > _K)? 0:(_K - _S_grid[k]);
00133   }
00134 
00135   int jmin, jmax;
00136   std::vector<double>::iterator ps, pslead, ps_end;
00137   double ds;
00138 
00139   for (--i; i>=0; --i) {
00140     jmin = get_min_j(i);
00141     jmax = get_max_j(i);
00142     
00143     ps = _S_grid.begin() + get_grid_offset( i, jmin);
00144     pslead = ps + 1;
00145     ps_end = _S_grid.begin() + get_grid_offset( i, jmax);
00146 
00147     *ps = S(i, jmin);
00148     ds = exp( _Scap);
00149 
00150     while (ps != ps_end) {
00151       *pslead ++ = ds * *ps ++;
00152     }
00153   }
00154 
00155   for (i = _NumberIterations-1; i>=0; --i) {
00156     tau = (_NumberIterations - i) * _dt;
00157     exp_alpha_r_tau = exp( (_alpha - _r)*tau);
00158     exp_r_tau = exp( - _r * tau);
00159 
00160     for (j=get_min_j(i); j<=get_max_j(i); j++) {
00161       k = get_grid_offset( i, j);
00162       l = get_grid_offset( i+1, j);
00163       m = get_grid_offset( i+1, j+1);
00164 
00165       //_S_grid[ k] = S( i, j);
00166       
00167       if (_calc_call) {
00168         _call_grid[ k] = .5*(_call_grid[ l]+_call_grid[ m]) * _exp_r_t;
00169         intrinsic_value = call_intrinsic_value( _S_grid[k], exp_alpha_r_tau, exp_r_tau);
00170         if (_call_grid[ k] < intrinsic_value) {
00171           _call_grid[ k] = intrinsic_value;
00172         }
00173       }
00174 
00175       if (_calc_put) {
00176         _put_grid[ k] = .5*(_put_grid[ l]+_put_grid[ m]) * _exp_r_t;
00177         intrinsic_value = put_intrinsic_value( _S_grid[k], exp_alpha_r_tau, exp_r_tau);
00178         if (_put_grid[ k] < intrinsic_value) {
00179           _put_grid[ k] = intrinsic_value;
00180         }
00181       }
00182     }
00183   }
00184 
00185   k = get_grid_offset( 0, 0);
00186   _C = _call_grid[k];
00187   _P = _put_grid[k];
00188 }

double binomial_option::call_intrinsic_value ( double  S,
double  exp_alpha_r_t,
double  exp_r_t 
) const [inline, protected]

This function calculates the intrinsic value of an American call. The value is the maximum of:.

  1. The value immedieate exericise
  2. The value of exercise at expiration
  3. 0

Definition at line 125 of file binomial.h.

00125                                                                                               { 
00126       double amval = S - _K;
00127       if (amval < 0) amval = 0;
00128       double euval = S * exp_alpha_r_t - _K * exp_r_t;
00129       if (euval < 0) euval = 0;
00130       return (amval > euval)? amval : euval;
00131     }

double binomial_option::put_intrinsic_value ( double  S,
double  exp_alpha_r_t,
double  exp_r_t 
) const [inline, protected]

This function calculates the intrinsic value of an American put. The value is the maximum of:.

  1. The value immedieate exericise
  2. The value of exercise at expiration
  3. 0

Definition at line 133 of file binomial.h.

00133                                                                                              { 
00134       double amval = _K - S;
00135       if (amval < 0) amval = 0;
00136       double euval = _K * exp_r_t - S * exp_alpha_r_t;
00137       if (euval < 0) euval = 0;
00138       return (amval > euval)? amval : euval;
00139     }

void binomial_option::init_calc_derived_attributes (  )  const [virtual]

: This function calculates the values of the American Put and the American Call. It calls several virtual function. The function are virtual, so that child classes can implement different versions of the algorithm. The final value of the American call is stored as C, and the final value of the American put is stored as P.

assumptions: alpha, r, tau, NumberIncrement, S, and K all have reasonable values
changes: the values of all derived attributes, including C the call price, and P the put price

Reimplemented from option_pair.

Definition at line 14 of file binomial.cpp.

References option_pair::_alpha, _Ccap, _dt, _NumberIterations, _Scap, option_pair::_sigma, option_pair::_tau, _u, _v, allocate_price_vectors(), and solve_call_put().

00014                                                          {
00015   _dt = _tau / _NumberIterations;
00016   _u = _alpha * _dt + log( 1 + sqrt( exp( _sigma * _sigma * _dt) - 1));
00017   _v = _alpha * _dt + log( 1 - sqrt( exp( _sigma * _sigma * _dt) - 1));
00018   _Scap = _u - _v;
00019   _Ccap = _v;
00020 
00021   //cout << .5*(exp(_u) + exp(_v)) << " " << exp( _alpha * _dt) << endl;
00022   
00023   allocate_price_vectors();
00024 
00025   solve_call_put();
00026 }

double binomial_option::call_implied_sigma ( double  call_price,
bool  show_iterations = false 
) [virtual]

This is a wrapper for the secant algortihm. This function returns the implied volatility of a call. If there is an error, _C_implied_sigma is set to a NA = not a number, and an exception is thrown.

assumes: These key attributes have been defined:

if the seed volatility is not provided, than a seed of .3 = 30% is used
the call_price is assumed to be greater than the intrinsic value of the call. If not then an exception of calss domain_error is called
throws: domain_error if a key attribute or parameter is illegal.
range_error if the value doesn't converge.
changes: all derived attributes

Reimplemented from option_pair.

Definition at line 261 of file binomial.cpp.

References option_pair::_alpha, option_pair::_C, option_pair::_C_implied_sigma, _error_msg, option_pair::_K, _NumberIterations, option_pair::_r, option_pair::_S, option_pair::_sigma, option_pair::_tau, option_pair::C_sigma(), option_pair::call_implied_sigma(), call_intrinsic_value(), Bisection_Secant< functor, real >::do_iteration(), Bisection< functor, real >::get_converged(), Bisection< functor, real >::get_x_mid(), option_pair::NA, stradle_value(), and strictly_check_attributes().

Referenced by main().

00262 {
00263   int erno;
00264 
00265   erno = strictly_check_attributes(
00266       _S,
00267       _K,
00268       _tau,
00269       _alpha,
00270       _r,
00271       _sigma,
00272       _NumberIterations);
00273 
00274   if (erno) {
00275     if (_sigma == 0) {
00276       _C = call_intrinsic_value();
00277       return NA;
00278     }
00279 
00280     _C_implied_sigma = NA;
00281     throw std::domain_error( _error_msg);
00282   }
00283 
00284   if (call_price < call_intrinsic_value()) {
00285     _C_implied_sigma = NA;
00286     throw std::domain_error( "call_price < call_intrinsic_value in binomial_option::call_implied_volatility");
00287   }
00288 
00289   double sigma0, sigma1, price_sigma0, price_sigma1;
00290 
00291   american_option_fudge aof( _S, _K, _tau, _alpha, _r, _sigma); 
00292   american_option_approximation aop( _S, _K, _tau, _alpha, _r, _sigma); 
00293 
00294   sigma0 = aof.call_implied_sigma( call_price);
00295 
00296   sigma1 = aop.call_implied_sigma( call_price);
00297 
00298   if (sigma1 == sigma0) sigma1 *= 1.1;
00299 
00300   option_pair *op = dynamic_cast< option_pair * > ( this);
00301 
00302   stradle_value(
00303                 sigma0,
00304                 sigma1,
00305                 price_sigma0,
00306                 price_sigma1,
00307                 call_price,
00308                 *op, 
00309                 &option_pair::C_sigma,
00310                 true,
00311                 true,
00312                 1,
00313                 1e-5,
00314                 1e5);
00315 
00316   Bisection_Secant< option_pair, double > 
00317     solution( 
00318            sigma0, 
00319            sigma1, 
00320            price_sigma0,
00321            price_sigma1,
00322            call_price, 
00323            .0001, 
00324            .0001,
00325            100,
00326            *op, 
00327            &option_pair::C_sigma);
00328 
00329   solution.do_iteration( show_iterations);
00330 
00331   if (!solution.get_converged()) {
00332     _C_implied_sigma = NA;
00333     throw std::domain_error( "sigma did not converge in option_pair::call_implied_sigma");
00334   }
00335   
00336   return solution.get_x_mid();
00337 }

double binomial_option::put_implied_sigma ( double  call_price,
bool  show_iterations = false 
) [virtual]

This is a wrapper for the secant algortihm. This function returns the implied volatility of a put. If there is an error, _P_implied_sigma is set to a NA = not a number, and an exception is thrown.

assumes: These key attributes have been defined:

if the seed volatility is not provided, than a seed of .3 = 30% is used
the put_price is assumed to be greater than the intrinsic value of the put. If not then an exception of calss domain_error is puted
throws: domain_error if a key attribute or parameter is illegal.
range_error if the value doesn't converge.
changes: all derived attributes

Reimplemented from option_pair.

Definition at line 339 of file binomial.cpp.

References option_pair::_alpha, _error_msg, option_pair::_K, _NumberIterations, option_pair::_P, option_pair::_P_implied_sigma, option_pair::_r, option_pair::_S, option_pair::_sigma, option_pair::_tau, Bisection_Secant< functor, real >::do_iteration(), Bisection< functor, real >::get_converged(), Bisection< functor, real >::get_x_mid(), option_pair::NA, option_pair::P_sigma(), option_pair::put_implied_sigma(), put_intrinsic_value(), stradle_value(), and strictly_check_attributes().

00340 {
00341   int erno;
00342 
00343   erno = strictly_check_attributes(
00344       _S,
00345       _K,
00346       _tau,
00347       _alpha,
00348       _r,
00349       _sigma,
00350       _NumberIterations);
00351 
00352   if (erno) {
00353     if (_sigma == 0) {
00354       _P = put_intrinsic_value();
00355       return NA;
00356     }
00357 
00358     _P_implied_sigma = NA;
00359     throw std::domain_error( _error_msg);
00360   }
00361 
00362   if (put_price < put_intrinsic_value()) {
00363     _P_implied_sigma = NA;
00364     throw std::domain_error( "put_price < put_intrinsic_value in binomial_option::put_implied_volatility");
00365   }
00366 
00367   double sigma0, sigma1, price_sigma0, price_sigma1;
00368 
00369   american_option_fudge aof( _S, _K, _tau, _alpha, _r, _sigma); 
00370   american_option_approximation aop( _S, _K, _tau, _alpha, _r, _sigma); 
00371 
00372   sigma0 = aof.put_implied_sigma( put_price);
00373 
00374   sigma1 = aop.put_implied_sigma( put_price);
00375 
00376   if (sigma1 == sigma0) sigma1 *= 1.1;
00377 
00378   option_pair *op = dynamic_cast< option_pair * > ( this);
00379 
00380   stradle_value(
00381                 sigma0,
00382                 sigma1,
00383                 price_sigma0,
00384                 price_sigma1,
00385                 put_price,
00386                 *op, 
00387                 &option_pair::P_sigma,
00388                 true,
00389                 true,
00390                 1,
00391                 1e-5,
00392                 1e5);
00393 
00394   Bisection_Secant< option_pair, double > 
00395     solution( 
00396            sigma0, 
00397            sigma1, 
00398            price_sigma0,
00399            price_sigma1,
00400            put_price, 
00401            .0001, 
00402            .0001,
00403            100,
00404            *op, 
00405            &option_pair::P_sigma);
00406 
00407   solution.do_iteration( show_iterations);
00408 
00409   if (!solution.get_converged()) {
00410     _P_implied_sigma = NA;
00411     throw std::domain_error( "sigma did not converge in option_pair::put_implied_sigma");
00412   }
00413   
00414   return solution.get_x_mid();
00415 }


The documentation for this class was generated from the following files:
Generated on Fri Jan 7 12:36:19 2011 for public_options by  doxygen 1.5.1