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 OPTIONPAIR_H
00029 #define OPTIONPAIR_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(OPTIONPAIRDLL)
00040 #error ALLSTATIC and OPTIONPAIRDLL are mutually exclusive
00041 #endif
00042
00043 #if defined(ALLSTATIC) || defined(OPTIONPAIRSTATIC)
00044 #undef OPTIONPAIRPTR
00045 #define OPTIONPAIRPTR
00046 #define OPTIONPAIRFNC
00047 #elif !defined(OPTIONPAIRPTR)
00048 #ifdef __NT__
00049 #ifdef OPTIONPAIRDLL
00050 #define OPTIONPAIRPTR __declspec(dllexport)
00051 #define OPTIONPAIRFNC __declspec(dllexport)
00052 #else
00053 #define OPTIONPAIRPTR __declspec(dllimport)
00054 #define OPTIONPAIRFNC __declspec(dllimport)
00055 #endif
00056 #else
00057 #define OPTIONPAIRFNC
00058 #define OPTIONPAIRPTR
00059 #endif
00060 #endif
00061
00062 #ifdef __GNUC__
00063 #ifdef OPTIONPAIRFNC
00064 #undef OPTIONPAIRFNC
00065 #endif
00066 #define OPTIONPAIRFNC
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 <math.h>
00080 #include <string.h>
00081
00082 using namespace std;
00083
00102 class OPTIONPAIRPTR option_pair {
00103 protected:
00104
00105 double _S;
00106 double _K;
00107 double _tau;
00108
00109
00110 double _alpha;
00111 double _r;
00112 double _sigma;
00113
00114
00115 mutable double _C;
00116 mutable double _P;
00117 mutable double _dC_dS;
00118 mutable double _dP_dS;
00119 mutable double _d2C_dS2;
00120 mutable double _d2P_dS2;
00121 mutable double _dC_dtau;
00122 mutable double _dP_dtau;
00123 mutable double _dC_dsigma;
00124 mutable double _dP_dsigma;
00125 mutable bool _calc_call;
00126 mutable bool _calc_put;
00127 mutable double _input_call_price;
00128 mutable double _input_put_price;
00129 mutable double _C_implied_sigma;
00130 mutable double _P_implied_sigma;
00131
00132
00133 static int strictly_check_attributes(
00134 double S,
00135 double K,
00136 double Tau,
00137 double Alpha,
00138 double R,
00139 double Sigma);
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 "option_pair";}
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
00159 void set_null() {
00160 _S = 0;
00161 _K = 0;
00162 _tau = 0;
00163 _alpha = 0;
00164 _r = 0.05;
00165 _sigma = 0.2;
00166 _C = 0;
00167 _P = 0;
00168 _dC_dS = 0;
00169 _dP_dS = 0;
00170 _d2C_dS2 = 0;
00171 _d2P_dS2 = 0;
00172 _dC_dtau = 0;
00173 _dP_dtau = 0;
00174 _dC_dsigma = 0;
00175 _dP_dsigma = 0;
00176 _calc_call = true;
00177 _calc_put = true;
00178 _input_call_price = NA;
00179 _input_put_price = NA;
00180 _C_implied_sigma = NA;
00181 _P_implied_sigma = NA;
00182 }
00183
00184 virtual void init_calc_derived_attributes() const;
00185
00186 void init( const option_pair& rhs) {
00187 _S = rhs._S;
00188 _K = rhs._K;
00189 _tau = rhs._tau;
00190 _alpha = rhs._alpha;
00191 _r = rhs._r;
00192 _sigma = rhs._sigma;
00193 _C = rhs._C;
00194 _P = rhs._P;
00195 _dC_dS = rhs._dC_dS;
00196 _dP_dS = rhs._dP_dS;
00197 _d2C_dS2 = rhs._d2C_dS2;
00198 _d2P_dS2 = rhs._d2P_dS2;
00199 _dC_dtau = rhs._dC_dtau;
00200 _dP_dtau = rhs._dP_dtau;
00201 _dC_dsigma = rhs._dC_dsigma;
00202 _dP_dsigma = rhs._dP_dsigma;
00203 _calc_call = rhs._calc_call;
00204 _calc_put = rhs._calc_put;
00205 _input_call_price = rhs._input_call_price;
00206 _input_put_price = rhs._input_put_price;
00207 _C_implied_sigma = rhs._C_implied_sigma;
00208 _P_implied_sigma = rhs._P_implied_sigma;
00209 }
00210
00211 option_pair& operator = ( const option_pair& rhs) {
00212 init( rhs);
00213 return *this;
00214 }
00215
00216 option_pair( const option_pair& rhs) {
00217 init( rhs);
00218 }
00219
00220 void init(
00221 double S,
00222 double K,
00223 double Tau,
00224 double Alpha = 0,
00225 double R = 0.05,
00226 double Sigma = 0.2)
00227 {
00228 const char* funcname = "option_pair::init";
00229
00230 check_attributes(
00231 S,
00232 K,
00233 Tau,
00234 Alpha,
00235 R,
00236 Sigma);
00237
00238 if (_erno) {
00239 cerr << _error_msg << std::endl;
00240 throw std::domain_error( stringify(
00241 funcname,
00242 __FILE__,
00243 _error_msg,
00244 __LINE__,
00245 _erno ));
00246 }
00247
00248
00249 _S = S;
00250 _K = K;
00251 _tau = Tau;
00252
00253
00254 _alpha = Alpha;
00255 _r = R;
00256 _sigma = Sigma;
00257
00258 init_calc_derived_attributes();
00259 }
00260
00261 option_pair(
00262 double S = 0,
00263 double K = 0,
00264 double Tau = 0,
00265 double Alpha = 0,
00266 double R = 0.05,
00267 double Sigma = 0.2)
00268 {
00269 set_null();
00270
00271 init(
00272 S,
00273 K,
00274 Tau,
00275 Alpha,
00276 R,
00277 Sigma);
00278 }
00279
00280 void deinit() { set_null();}
00281
00282 virtual ~option_pair() { deinit();}
00283
00284
00285
00286 double get_S() const { return _S;}
00287 double get_K() const { return _K;}
00288 double get_tau() const { return _tau;}
00289 double get_alpha() const { return _alpha;}
00290 double get_r() const { return _r;}
00291 double get_sigma() const { return _sigma;}
00292 double get_C() const { return _C;}
00293 double get_P() const { return _P;}
00294 double get_dC_dS() const { return _dC_dS;}
00295 double get_dP_dS() const { return _dP_dS;}
00296 double get_d2C_dS2() const { return _d2C_dS2;}
00297 double get_d2P_dS2() const { return _d2P_dS2;}
00298 double get_dC_dtau() const { return _dC_dtau;}
00299 double get_dP_dtau() const { return _dP_dtau;}
00300 double get_dC_dsigma() const { return _dC_dsigma;}
00301 double get_dP_dsigma() const { return _dP_dsigma;}
00302 bool get_calc_call() const { return _calc_call;}
00303 bool get_calc_put() const { return _calc_put;}
00304 double get_input_call_price() const { return _input_call_price;}
00305 double get_input_put_price() const { return _input_put_price;}
00306 double get_C_implied_sigma() const { return _C_implied_sigma;}
00307 double get_P_implied_sigma() const { return _P_implied_sigma;}
00308
00309
00310
00311 void put_S(double S) {
00312 const char* funcname = "put_S";
00313
00314 check_attributes(
00315 S,
00316 _K,
00317 _tau,
00318 _alpha,
00319 _r,
00320 _sigma);
00321 if (_erno) {
00322 cerr << _error_msg << std::endl;
00323 throw std::domain_error( stringify(
00324 funcname,
00325 __FILE__,
00326 _error_msg,
00327 __LINE__,
00328 _erno ));
00329 }
00330
00331 _S = S;
00332
00333 init_calc_derived_attributes();
00334 }
00335
00336 void put_K(double K) {
00337 const char* funcname = "put_K";
00338
00339 check_attributes(
00340 _S,
00341 K,
00342 _tau,
00343 _alpha,
00344 _r,
00345 _sigma);
00346 if (_erno) {
00347 cerr << _error_msg << std::endl;
00348 throw std::domain_error( stringify(
00349 funcname,
00350 __FILE__,
00351 _error_msg,
00352 __LINE__,
00353 _erno ));
00354 }
00355
00356 _K = K;
00357
00358 init_calc_derived_attributes();
00359 }
00360
00361 void put_tau(double Tau) {
00362 const char* funcname = "put_tau";
00363
00364 check_attributes(
00365 _S,
00366 _K,
00367 Tau,
00368 _alpha,
00369 _r,
00370 _sigma);
00371 if (_erno) {
00372 cerr << _error_msg << std::endl;
00373 throw std::domain_error( stringify(
00374 funcname,
00375 __FILE__,
00376 _error_msg,
00377 __LINE__,
00378 _erno ));
00379 }
00380
00381 _tau = Tau;
00382
00383 init_calc_derived_attributes();
00384 }
00385
00386 void put_alpha(double Alpha) {
00387 const char* funcname = "put_alpha";
00388
00389 check_attributes(
00390 _S,
00391 _K,
00392 _tau,
00393 Alpha,
00394 _r,
00395 _sigma);
00396 if (_erno) {
00397 cerr << _error_msg << std::endl;
00398 throw std::domain_error( stringify(
00399 funcname,
00400 __FILE__,
00401 _error_msg,
00402 __LINE__,
00403 _erno ));
00404 }
00405
00406 _alpha = Alpha;
00407
00408 init_calc_derived_attributes();
00409 }
00410
00411 void put_r(double R) {
00412 const char* funcname = "put_r";
00413
00414 check_attributes(
00415 _S,
00416 _K,
00417 _tau,
00418 _alpha,
00419 R,
00420 _sigma);
00421 if (_erno) {
00422 cerr << _error_msg << std::endl;
00423 throw std::domain_error( stringify(
00424 funcname,
00425 __FILE__,
00426 _error_msg,
00427 __LINE__,
00428 _erno ));
00429 }
00430
00431 _r = R;
00432
00433 init_calc_derived_attributes();
00434 }
00435
00436 void put_sigma(double Sigma) {
00437 const char* funcname = "put_sigma";
00438
00439 check_attributes(
00440 _S,
00441 _K,
00442 _tau,
00443 _alpha,
00444 _r,
00445 Sigma);
00446 if (_erno) {
00447 cerr << _error_msg << std::endl;
00448 throw std::domain_error( stringify(
00449 funcname,
00450 __FILE__,
00451 _error_msg,
00452 __LINE__,
00453 _erno ));
00454 }
00455
00456 _sigma = Sigma;
00457
00458 init_calc_derived_attributes();
00459 }
00460
00461 void init_simple_attributes( const option_pair& rhs) {
00462 _S = rhs._S;
00463 _K = rhs._K;
00464 _tau = rhs._tau;
00465 _alpha = rhs._alpha;
00466 _r = rhs._r;
00467 _sigma = rhs._sigma;
00468 _C = rhs._C;
00469 _P = rhs._P;
00470 _dC_dS = rhs._dC_dS;
00471 _dP_dS = rhs._dP_dS;
00472 _d2C_dS2 = rhs._d2C_dS2;
00473 _d2P_dS2 = rhs._d2P_dS2;
00474 _dC_dtau = rhs._dC_dtau;
00475 _dP_dtau = rhs._dP_dtau;
00476 _dC_dsigma = rhs._dC_dsigma;
00477 _dP_dsigma = rhs._dP_dsigma;
00478 _calc_call = rhs._calc_call;
00479 _calc_put = rhs._calc_put;
00480 _input_call_price = rhs._input_call_price;
00481 _input_put_price = rhs._input_put_price;
00482 _C_implied_sigma = rhs._C_implied_sigma;
00483 _P_implied_sigma = rhs._P_implied_sigma;
00484 }
00485
00486 virtual double call_intrinsic_value() const = 0;
00487 virtual double put_intrinsic_value() const = 0;
00488 virtual double call_implied_sigma( double call_price, bool show_iterations=false);
00489 virtual double put_implied_sigma( double call_price, bool show_iterations=false);
00490 friend OPTIONPAIRFNC ostream& STDCALL operator << (ostream& os, const option_pair& rhs);
00492 double C_sigma( double sigma);
00494 double P_sigma( double sigma);
00495 void set_call_immediate_exercise() const;
00496 void set_put_immediate_exercise() const;
00497 static const double NA;
00498 static bool is_NA( const double& tst) { return memcmp( &tst, &NA, sizeof(double))==0;}
00499 };
00500
00501
00502 OPTIONPAIRFNC double STDCALL lookup_month_rate( int ccyymm);
00503 OPTIONPAIRFNC void STDCALL deinit_month_rate();
00504
00505 #endif