00001 #ifndef stringify_defined
00002 #define stringify_defined
00003 #include <iostream>
00004 #include <sstream>
00005 #include <string>
00006 #include <stdexcept>
00007
00008 inline std::string stringify(
00009 const char *funcname,
00010 const char* _file,
00011 const char *_error_msg,
00012 int _line,
00013 int _erno)
00014 {
00015 std::ostringstream o;
00016 o << _error_msg
00017 << " in function "
00018 << funcname
00019 << " at line "
00020 << _line <<
00021 " of file "
00022 << _file;
00023
00024 return o.str();
00025 }
00026 #endif
00027
00028 #ifndef BINOMIAL_H
00029 #define BINOMIAL_H
00030
00031 #if defined( WIN32) && !defined(__NT__)
00032 #define __NT__
00033 #endif
00034
00035 #if defined( __NT__) && !defined(WIN32)
00036 #define WIN32
00037 #endif
00038
00039 #if defined(ALLSTATIC) && defined(BINOMIALDLL)
00040 #error ALLSTATIC and BINOMIALDLL are mutually exclusive
00041 #endif
00042
00043 #if defined(ALLSTATIC) || defined(BINOMIALSTATIC)
00044 #undef BINOMIALPTR
00045 #define BINOMIALPTR
00046 #define BINOMIALFNC
00047 #elif !defined(BINOMIALPTR)
00048 #ifdef __NT__
00049 #ifdef BINOMIALDLL
00050 #define BINOMIALPTR __declspec(dllexport)
00051 #define BINOMIALFNC __declspec(dllexport)
00052 #else
00053 #define BINOMIALPTR __declspec(dllimport)
00054 #define BINOMIALFNC __declspec(dllimport)
00055 #endif
00056 #else
00057 #define BINOMIALFNC
00058 #define BINOMIALPTR
00059 #endif
00060 #endif
00061
00062 #ifdef __GNUC__
00063 #ifdef BINOMIALFNC
00064 #undef BINOMIALFNC
00065 #endif
00066 #define BINOMIALFNC
00067 #endif
00068
00069 #ifdef WIN32
00070 #define STDCALL __stdcall
00071 #else
00072 #define STDCALL
00073 #endif
00074
00075 #ifdef WIN32
00076 #pragma warning(disable : 4251) //4251=needs to have dll-interface
00077 #endif
00078
00079 #include <vector>
00080 #include <iostream>
00081 #include <math.h>
00082
00083 #include "optionpair.h"
00084
00085 using namespace std;
00086
00088 class BINOMIALPTR binomial_option: public option_pair {
00089 protected:
00090
00091
00092
00093 int _NumberIterations;
00094
00095
00096 mutable double _Scap;
00097 mutable double _Ccap;
00098 mutable double _dt;
00099 mutable double _mu;
00100 mutable double _exp_r_t;
00101 mutable double _sqrt_tau;
00102 mutable double _sigma_sqrt_tau;
00103 mutable double _u;
00104 mutable double _v;
00105 mutable std::vector<double> _call_grid;
00106 mutable std::vector<double> _put_grid;
00107 mutable std::vector<double> _S_grid;
00108
00109
00110 int strictly_check_attributes(
00111 double S,
00112 double K,
00113 double Tau,
00114 double Alpha,
00115 double R,
00116 double Sigma,
00117 int NumberIterations);
00118 virtual double S( int i, int j) const;
00119 virtual int get_grid_offset( int i, int j) const;
00120 virtual int get_max_j( int i) const;
00121 virtual int get_min_j( int i) const;
00122 virtual void allocate_price_vectors() const;
00123 virtual void solve_call_put() const;
00125 inline double call_intrinsic_value( double S, double exp_alpha_r_t, double exp_r_t) const {
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 }
00133 inline double put_intrinsic_value( double S, double exp_alpha_r_t, double exp_r_t) const {
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 }
00140
00141
00142 static const char *_error_msg;
00143 static int _erno;
00144
00145 public:
00146
00147 static const char *get_error_msg() { return _error_msg;}
00148 static int get_erno() { return _erno;}
00149 virtual const char *get_class_name() { return "binomial_option";}
00150
00151 static int check_attributes(
00152 double S,
00153 double K,
00154 double Tau,
00155 double Alpha,
00156 double R,
00157 double Sigma,
00158 int NumberIterations);
00159
00160 void set_null() {
00161 option_pair::set_null();
00162 _NumberIterations = 100;
00163 _Scap = 0;
00164 _Ccap = 0;
00165 _dt = 0;
00166 _mu = 0;
00167 _exp_r_t = 0;
00168 _sqrt_tau = 0;
00169 _sigma_sqrt_tau = 0;
00170 _u = 0;
00171 _v = 0;
00172 _call_grid.erase( _call_grid.begin() , _call_grid.end());
00173 _put_grid.erase( _put_grid.begin() , _put_grid.end());
00174 _S_grid.erase( _S_grid.begin() , _S_grid.end());
00175 }
00176
00177 virtual void init_calc_derived_attributes() const;
00178
00179 void init( const binomial_option& rhs) {
00180 _S = rhs._S;
00181 _K = rhs._K;
00182 _tau = rhs._tau;
00183 _alpha = rhs._alpha;
00184 _r = rhs._r;
00185 _sigma = rhs._sigma;
00186 _NumberIterations = rhs._NumberIterations;
00187 _C = rhs._C;
00188 _P = rhs._P;
00189 _dC_dS = rhs._dC_dS;
00190 _dP_dS = rhs._dP_dS;
00191 _d2C_dS2 = rhs._d2C_dS2;
00192 _d2P_dS2 = rhs._d2P_dS2;
00193 _dC_dtau = rhs._dC_dtau;
00194 _dP_dtau = rhs._dP_dtau;
00195 _dC_dsigma = rhs._dC_dsigma;
00196 _dP_dsigma = rhs._dP_dsigma;
00197 _calc_call = rhs._calc_call;
00198 _calc_put = rhs._calc_put;
00199 _input_call_price = rhs._input_call_price;
00200 _input_put_price = rhs._input_put_price;
00201 _C_implied_sigma = rhs._C_implied_sigma;
00202 _P_implied_sigma = rhs._P_implied_sigma;
00203 _Scap = rhs._Scap;
00204 _Ccap = rhs._Ccap;
00205 _dt = rhs._dt;
00206 _mu = rhs._mu;
00207 _exp_r_t = rhs._exp_r_t;
00208 _sqrt_tau = rhs._sqrt_tau;
00209 _sigma_sqrt_tau = rhs._sigma_sqrt_tau;
00210 _u = rhs._u;
00211 _v = rhs._v;
00212 _call_grid = rhs._call_grid;
00213 _put_grid = rhs._put_grid;
00214 _S_grid = rhs._S_grid;
00215 }
00216
00217 binomial_option& operator = ( const binomial_option& rhs) {
00218 init( rhs);
00219 return *this;
00220 }
00221
00222 binomial_option( const binomial_option& rhs) {
00223 init( rhs);
00224 }
00225
00226 void init(
00227 double S,
00228 double K,
00229 double Tau,
00230 double Alpha = 0,
00231 double R = 0.05,
00232 double Sigma = 0.2,
00233 int NumberIterations = 100)
00234 {
00235 const char* funcname = "binomial_option::init";
00236
00237 check_attributes(
00238 S,
00239 K,
00240 Tau,
00241 Alpha,
00242 R,
00243 Sigma,
00244 NumberIterations);
00245
00246 if (_erno) {
00247 cerr << _error_msg << std::endl;
00248 throw std::domain_error( stringify(
00249 funcname,
00250 __FILE__,
00251 _error_msg,
00252 __LINE__,
00253 _erno ));
00254 }
00255
00256
00257 _S = S;
00258 _K = K;
00259 _tau = Tau;
00260
00261
00262 _alpha = Alpha;
00263 _r = R;
00264 _sigma = Sigma;
00265 _NumberIterations = NumberIterations;
00266
00267 init_calc_derived_attributes();
00268 }
00269
00270 binomial_option(
00271 double S = 0,
00272 double K = 0,
00273 double Tau = 0,
00274 double Alpha = 0,
00275 double R = 0.05,
00276 double Sigma = 0.2,
00277 int NumberIterations = 100)
00278 {
00279 set_null();
00280
00281 init(
00282 S,
00283 K,
00284 Tau,
00285 Alpha,
00286 R,
00287 Sigma,
00288 NumberIterations);
00289 }
00290
00291 void deinit() { set_null();}
00292
00293 virtual ~binomial_option() { deinit();}
00294
00295
00296
00297 int get_NumberIterations() const { return _NumberIterations;}
00298 double get_Scap() const { return _Scap;}
00299 double get_Ccap() const { return _Ccap;}
00300 double get_dt() const { return _dt;}
00301 double get_mu() const { return _mu;}
00302 double get_exp_r_t() const { return _exp_r_t;}
00303 double get_sqrt_tau() const { return _sqrt_tau;}
00304 double get_sigma_sqrt_tau() const { return _sigma_sqrt_tau;}
00305 double get_u() const { return _u;}
00306 double get_v() const { return _v;}
00307 const std::vector<double>& get_call_grid() const { return _call_grid;}
00308 const std::vector<double>& get_put_grid() const { return _put_grid;}
00309 const std::vector<double>& get_S_grid() const { return _S_grid;}
00310
00311
00312
00313 void put_NumberIterations(int NumberIterations) {
00314 const char* funcname = "put_NumberIterations";
00315
00316 check_attributes(
00317 _S,
00318 _K,
00319 _tau,
00320 _alpha,
00321 _r,
00322 _sigma,
00323 NumberIterations);
00324 if (_erno) {
00325 cerr << _error_msg << std::endl;
00326 throw std::domain_error( stringify(
00327 funcname,
00328 __FILE__,
00329 _error_msg,
00330 __LINE__,
00331 _erno ));
00332 }
00333
00334 _NumberIterations = NumberIterations;
00335
00336 init_calc_derived_attributes();
00337 }
00338
00339 void init_simple_attributes( const binomial_option& rhs) {
00340 _NumberIterations = rhs._NumberIterations;
00341 _Scap = rhs._Scap;
00342 _Ccap = rhs._Ccap;
00343 _dt = rhs._dt;
00344 _mu = rhs._mu;
00345 _exp_r_t = rhs._exp_r_t;
00346 _sqrt_tau = rhs._sqrt_tau;
00347 _sigma_sqrt_tau = rhs._sigma_sqrt_tau;
00348 _u = rhs._u;
00349 _v = rhs._v;
00350 _call_grid = rhs._call_grid;
00351 _put_grid = rhs._put_grid;
00352 _S_grid = rhs._S_grid;
00353 }
00354
00355 double C_tau( double tau);
00356 double P_tau( double tau);
00357 double C_sigma( double sigma);
00358 double P_sigma( double sigma);
00359 virtual double call_intrinsic_value() const;
00360 virtual double put_intrinsic_value() const;
00361 virtual double call_implied_sigma( double call_price, bool show_iterations=false);
00362 virtual double put_implied_sigma( double call_price, bool show_iterations=false);
00363 };
00364
00365
00366
00367 #endif