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 AMERICANAPPROX_H
00029 #define AMERICANAPPROX_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(AMERICANAPPROXDLL)
00040 #error ALLSTATIC and AMERICANAPPROXDLL are mutually exclusive
00041 #endif
00042
00043 #if defined(ALLSTATIC) || defined(AMERICANAPPROXSTATIC)
00044 #undef AMERICANAPPROXPTR
00045 #define AMERICANAPPROXPTR
00046 #define AMERICANAPPROXFNC
00047 #elif !defined(AMERICANAPPROXPTR)
00048 #ifdef __NT__
00049 #ifdef AMERICANAPPROXDLL
00050 #define AMERICANAPPROXPTR __declspec(dllexport)
00051 #define AMERICANAPPROXFNC __declspec(dllexport)
00052 #else
00053 #define AMERICANAPPROXPTR __declspec(dllimport)
00054 #define AMERICANAPPROXFNC __declspec(dllimport)
00055 #endif
00056 #else
00057 #define AMERICANAPPROXFNC
00058 #define AMERICANAPPROXPTR
00059 #endif
00060 #endif
00061
00062 #ifdef __GNUC__
00063 #ifdef AMERICANAPPROXFNC
00064 #undef AMERICANAPPROXFNC
00065 #endif
00066 #define AMERICANAPPROXFNC
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 "simpleoption.h"
00080
00081 using namespace std;
00082
00083 typedef unsigned int uint;
00084
00086 class AMERICANAPPROXPTR american_option_approximation: public european_option_pair {
00087 protected:
00088
00089
00090
00091 double _vega_epsilon;
00092 uint _max_iter;
00093
00094
00095 mutable european_option_pair _optvar;
00096 mutable bool _call_early_exercise;
00097 mutable bool _put_early_exercise;
00098 mutable double _call_tau;
00099 mutable double _put_tau;
00100
00101
00102 static const char *_error_msg;
00103 static int _erno;
00104
00105 public:
00106
00107 static const char *get_error_msg() { return _error_msg;}
00108 static int get_erno() { return _erno;}
00109 virtual const char *get_class_name() { return "american_option_approximation";}
00110
00111 static int check_attributes(
00112 double S,
00113 double K,
00114 double Tau,
00115 double Alpha,
00116 double R,
00117 double Sigma,
00118 double Vega_epsilon,
00119 uint Max_iter);
00120
00121 void set_null() {
00122 european_option_pair::set_null();
00123 _vega_epsilon = 1e-5;
00124 _max_iter = 100;
00125 _optvar.set_null();
00126 _call_early_exercise = 0;
00127 _put_early_exercise = 0;
00128 _call_tau = 0;
00129 _put_tau = 0;
00130 }
00131
00132 virtual void init_calc_derived_attributes() const;
00133
00134 void init( const american_option_approximation& rhs) {
00135 _S = rhs._S;
00136 _K = rhs._K;
00137 _tau = rhs._tau;
00138 _alpha = rhs._alpha;
00139 _r = rhs._r;
00140 _sigma = rhs._sigma;
00141 _vega_epsilon = rhs._vega_epsilon;
00142 _max_iter = rhs._max_iter;
00143 _C = rhs._C;
00144 _P = rhs._P;
00145 _dC_dS = rhs._dC_dS;
00146 _dP_dS = rhs._dP_dS;
00147 _d2C_dS2 = rhs._d2C_dS2;
00148 _d2P_dS2 = rhs._d2P_dS2;
00149 _dC_dtau = rhs._dC_dtau;
00150 _dP_dtau = rhs._dP_dtau;
00151 _dC_dsigma = rhs._dC_dsigma;
00152 _dP_dsigma = rhs._dP_dsigma;
00153 _calc_call = rhs._calc_call;
00154 _calc_put = rhs._calc_put;
00155 _input_call_price = rhs._input_call_price;
00156 _input_put_price = rhs._input_put_price;
00157 _C_implied_sigma = rhs._C_implied_sigma;
00158 _P_implied_sigma = rhs._P_implied_sigma;
00159 _mu = rhs._mu;
00160 _sqrt_tau = rhs._sqrt_tau;
00161 _sigma_sqrt_tau = rhs._sigma_sqrt_tau;
00162 _log_S_K = rhs._log_S_K;
00163 _Zk = rhs._Zk;
00164 _dZk_dtau = rhs._dZk_dtau;
00165 _h = rhs._h;
00166 _dh_dtau = rhs._dh_dtau;
00167 _N_h = rhs._N_h;
00168 _N_Zk = rhs._N_Zk;
00169 _exp_alpha_r_t = rhs._exp_alpha_r_t;
00170 _exp_r_t = rhs._exp_r_t;
00171 _S_exp_alpha_r_t = rhs._S_exp_alpha_r_t;
00172 _K_exp_r_t = rhs._K_exp_r_t;
00173 _d3C_dS2_dtau = rhs._d3C_dS2_dtau;
00174 _d3P_dS2_dtau = rhs._d3P_dS2_dtau;
00175 _dh_dsigma = rhs._dh_dsigma;
00176 _dZ_dsigma = rhs._dZ_dsigma;
00177 _d2C_dsigma2 = rhs._d2C_dsigma2;
00178 _d2P_dsigma2 = rhs._d2P_dsigma2;
00179 _dC_dtau = rhs._dC_dtau;
00180 _dP_dtau = rhs._dP_dtau;
00181 _d2C_dtau2 = rhs._d2C_dtau2;
00182 _d2P_dtau2 = rhs._d2P_dtau2;
00183 _d2C_dS_dtau = rhs._d2C_dS_dtau;
00184 _d2P_dS_dtau = rhs._d2P_dS_dtau;
00185 _P_h = rhs._P_h;
00186 _optvar = rhs._optvar;
00187 _call_early_exercise = rhs._call_early_exercise;
00188 _put_early_exercise = rhs._put_early_exercise;
00189 _call_tau = rhs._call_tau;
00190 _put_tau = rhs._put_tau;
00191 }
00192
00193 american_option_approximation& operator = ( const american_option_approximation& rhs) {
00194 init( rhs);
00195 return *this;
00196 }
00197
00198 american_option_approximation( const american_option_approximation& rhs) {
00199 init( rhs);
00200 }
00201
00202 void init(
00203 double S,
00204 double K,
00205 double Tau,
00206 double Alpha = 0,
00207 double R = 0.05,
00208 double Sigma = 0.2,
00209 double Vega_epsilon = 1e-5,
00210 uint Max_iter = 100)
00211 {
00212 const char* funcname = "american_option_approximation::init";
00213
00214 check_attributes(
00215 S,
00216 K,
00217 Tau,
00218 Alpha,
00219 R,
00220 Sigma,
00221 Vega_epsilon,
00222 Max_iter);
00223
00224 if (_erno) {
00225 cerr << _error_msg << std::endl;
00226 throw std::domain_error( stringify(
00227 funcname,
00228 __FILE__,
00229 _error_msg,
00230 __LINE__,
00231 _erno ));
00232 }
00233
00234
00235 _S = S;
00236 _K = K;
00237 _tau = Tau;
00238
00239
00240 _alpha = Alpha;
00241 _r = R;
00242 _sigma = Sigma;
00243 _vega_epsilon = Vega_epsilon;
00244 _max_iter = Max_iter;
00245
00246 init_calc_derived_attributes();
00247 }
00248
00249 american_option_approximation(
00250 double S = 0,
00251 double K = 0,
00252 double Tau = 0,
00253 double Alpha = 0,
00254 double R = 0.05,
00255 double Sigma = 0.2,
00256 double Vega_epsilon = 1e-5,
00257 uint Max_iter = 100)
00258 {
00259 set_null();
00260
00261 init(
00262 S,
00263 K,
00264 Tau,
00265 Alpha,
00266 R,
00267 Sigma,
00268 Vega_epsilon,
00269 Max_iter);
00270 }
00271
00272 void deinit() { set_null();}
00273
00274 virtual ~american_option_approximation() { deinit();}
00275
00276
00277
00278 double get_vega_epsilon() const { return _vega_epsilon;}
00279 const uint& get_max_iter() const { return _max_iter;}
00280 const european_option_pair& get_optvar() const { return _optvar;}
00281 bool get_call_early_exercise() const { return _call_early_exercise;}
00282 bool get_put_early_exercise() const { return _put_early_exercise;}
00283 double get_call_tau() const { return _call_tau;}
00284 double get_put_tau() const { return _put_tau;}
00285
00286
00287
00288 void put_vega_epsilon(double Vega_epsilon) {
00289 const char* funcname = "put_vega_epsilon";
00290
00291 check_attributes(
00292 _S,
00293 _K,
00294 _tau,
00295 _alpha,
00296 _r,
00297 _sigma,
00298 Vega_epsilon,
00299 _max_iter);
00300 if (_erno) {
00301 cerr << _error_msg << std::endl;
00302 throw std::domain_error( stringify(
00303 funcname,
00304 __FILE__,
00305 _error_msg,
00306 __LINE__,
00307 _erno ));
00308 }
00309
00310 _vega_epsilon = Vega_epsilon;
00311
00312 init_calc_derived_attributes();
00313 }
00314
00315 void put_max_iter(uint Max_iter) {
00316 const char* funcname = "put_max_iter";
00317
00318 check_attributes(
00319 _S,
00320 _K,
00321 _tau,
00322 _alpha,
00323 _r,
00324 _sigma,
00325 _vega_epsilon,
00326 Max_iter);
00327 if (_erno) {
00328 cerr << _error_msg << std::endl;
00329 throw std::domain_error( stringify(
00330 funcname,
00331 __FILE__,
00332 _error_msg,
00333 __LINE__,
00334 _erno ));
00335 }
00336
00337 _max_iter = Max_iter;
00338
00339 init_calc_derived_attributes();
00340 }
00341
00342 void init_simple_attributes( const american_option_approximation& rhs) {
00343 _vega_epsilon = rhs._vega_epsilon;
00344 _call_early_exercise = rhs._call_early_exercise;
00345 _put_early_exercise = rhs._put_early_exercise;
00346 _call_tau = rhs._call_tau;
00347 _put_tau = rhs._put_tau;
00348 }
00349
00350 virtual double call_intrinsic_value() const;
00351 virtual double put_intrinsic_value() const;
00352 void set_call( const european_option_pair& rhs) const;
00353 void set_put( const european_option_pair& rhs) const;
00354 friend AMERICANAPPROXFNC ostream& STDCALL operator << (ostream& os, const american_option_approximation& rhs);
00355 };
00356
00357
00358 #endif