optionpair.cpp

Go to the documentation of this file.
00001 
00002 
00003 #include "optionpair.h"
00004 
00005 #include <iomanip>
00006 #include <limits>
00007 
00008 #include "Bisection.h"
00009 #include "Secant.h"
00010 
00011 const double option_pair::NA = std::numeric_limits<double>::quiet_NaN();
00012 
00013 void option_pair::init_calc_derived_attributes() const
00014 {
00015   if (_S==0) return;
00016 
00017   if (_tau == 0) {
00018     set_call_immediate_exercise();
00019     set_put_immediate_exercise();
00020     return;
00021   }
00022 }
00023 
00024 OPTIONPAIRFNC ostream& STDCALL operator << ( ostream& os, const option_pair& rhs) {
00025   os << "S         = " << setprecision(3) << rhs._S << endl;
00026   os << "K         = " << setprecision(3) << rhs._K << endl;
00027   os << "Tau       = " << rhs._tau << endl;
00028   os << "alpha     = " << rhs._alpha << endl;
00029   os << "r         = " << rhs._r << endl;
00030   os << "sigma     = " << rhs._sigma << endl;
00031   os << "C         = " << rhs._C << endl;
00032   os << "P         = " << rhs._P << endl;
00033   os << "dC_dS     = " << rhs._dC_dS << endl;
00034   os << "dP_dS     = " << rhs._dP_dS << endl;
00035   os << "d2C_dS2   = " << rhs._d2C_dS2 << endl;
00036   os << "d2P_dS2   = " << rhs._d2P_dS2 << endl;
00037   os << "dC_dsigma = " << rhs._dC_dsigma << endl;
00038   os << "dP_dsigma = " << rhs._dP_dsigma << endl;
00039   os << "dC_dtau   = " << rhs._dC_dtau << endl;
00040   os << "dP_dtau   = " << rhs._dP_dtau << endl;
00041   return os;
00042 }
00043 
00044 double option_pair::C_sigma( double sigma) {
00045   if (sigma != _sigma) put_sigma( sigma);
00046   return _C;
00047 }
00048 
00049 double option_pair::P_sigma( double sigma) {
00050   if (sigma != _sigma) put_sigma( sigma);
00051   return _P;
00052 }
00053 
00054 void option_pair::set_call_immediate_exercise() const
00055 {
00056   _C = _S - _K;
00057   if (_C > 0) {
00058     _dC_dS = 1.0;
00059   } else {
00060     _C = 0;
00061     _dC_dS = 0;
00062   }
00063 
00064   _d2C_dS2 = 0;
00065   _dC_dtau = 0;
00066   _dC_dsigma = 0;
00067 }
00068 
00069 void option_pair::set_put_immediate_exercise() const
00070 {
00071   _P = _K - _S;
00072   if (_P > 0) {
00073     _dP_dS = -1.0;
00074   } else {
00075     _P = 0;
00076     _dP_dS = 0;
00077   }
00078 
00079   _d2P_dS2 = 0;
00080   _dP_dtau = 0;
00081   _dP_dsigma = 0;
00082 }
00083 
00084 #ifdef CHECK
00085 #undef CHECK
00086 #endif
00087 #ifdef linux
00088 #define CHECK(y,z,a) if (y) { _error_msg = __STRING(y)" at line "\
00089   __STRING(z)" in " a "::check_attributes"; \
00090   return (_erno = z);}
00091 #else
00092 #define CHECK(y,z,a) if (y) {_error_msg = #y" at line "\
00093   #z" in " #a"::check_attributes"; \
00094   return (_erno = z);}
00095 #endif
00096 
00097 int option_pair::strictly_check_attributes(
00098       double S,
00099       double K,
00100       double Tau,
00101       double Alpha,
00102       double R,
00103       double Sigma)
00104 {
00105   #define Funcname  "option_pair::check_attributes"
00106 
00107   _error_msg = "";
00108   _erno = 0;
00109 
00110   CHECK(S <=  0, __LINE__, Funcname);
00111   CHECK(K <=  0, __LINE__, Funcname);
00112   CHECK(Tau <=  0, __LINE__, Funcname);
00113   CHECK(R <  0, __LINE__, Funcname);
00114   CHECK(Sigma <=  0, __LINE__, Funcname);
00115   CHECK(is_NA(Sigma), __LINE__, Funcname);
00116 
00117   return 0;
00118 }
00119 
00134 double option_pair::call_implied_sigma(
00135                                        double call_price, 
00136                                        bool show_iterations) 
00137 {
00138   int erno;
00139 
00140   erno = strictly_check_attributes(
00141       _S,
00142       _K,
00143       _tau,
00144       _alpha,
00145       _r,
00146       _sigma);
00147 
00148   if (erno) {
00149     _C_implied_sigma = NA;
00150     throw std::domain_error( _error_msg);
00151   }
00152 
00153   if (call_price < call_intrinsic_value()) {
00154     _C_implied_sigma = NA;
00155     throw std::domain_error( "call_price < call_intrinsic_value in option_pair::call_implied_sigma");
00156   }
00157 
00158   _input_call_price = call_price;
00159 
00160   double sigma0, sigma1, price_sigma0, price_sigma1;
00161 
00162   sigma0 = .01;
00163   sigma1 = .50;
00164   
00165   stradle_value(
00166                 sigma0,
00167                 sigma1,
00168                 price_sigma0,
00169                 price_sigma1,
00170                 call_price,
00171                 *this, 
00172                 &option_pair::C_sigma,
00173                 true,
00174                 true,
00175                 1,
00176                 1e-5,
00177                 1e5);
00178   
00179   Bisection_Secant< option_pair, double > 
00180     solution( 
00181            sigma0, 
00182            sigma1, 
00183            price_sigma0,
00184            price_sigma1,
00185            call_price, 
00186            .0001, 
00187            .0001,
00188            100,
00189            *this, 
00190            &option_pair::C_sigma);
00191 
00192   solution.do_iteration( show_iterations);
00193 
00194   if (!solution.get_converged()) {
00195     _C_implied_sigma = NA;
00196     throw std::domain_error( "sigma did not converge in option_pair::call_implied_sigma");
00197   }
00198 
00199   return solution.get_x_mid();
00200 }
00201 
00202 
00203 
00218 double option_pair::put_implied_sigma(
00219                                        double put_price, 
00220                                        bool show_iterations) 
00221 {
00222   int erno;
00223 
00224   erno = strictly_check_attributes(
00225       _S,
00226       _K,
00227       _tau,
00228       _alpha,
00229       _r,
00230       _sigma);
00231 
00232   if (erno) {
00233     _P_implied_sigma = NA;
00234     throw std::domain_error( _error_msg);
00235   }
00236 
00237   if (put_price < put_intrinsic_value()) {
00238     _P_implied_sigma = NA;
00239     throw std::domain_error( "put_price < put_intrinsic_value in option_pair::put_implied_sigma");
00240   }
00241 
00242   _input_put_price = put_price;
00243 
00244   double sigma0, sigma1, price_sigma0, price_sigma1;
00245 
00246   sigma0 = .01;
00247   sigma1 = .50;
00248   
00249   stradle_value(
00250                 sigma0,
00251                 sigma1,
00252                 price_sigma0,
00253                 price_sigma1,
00254                 put_price,
00255                 *this, 
00256                 &option_pair::P_sigma,
00257                 true,
00258                 true,
00259                 1,
00260                 1e-5,
00261                 1e5);
00262   
00263   Bisection_Secant< option_pair, double > 
00264     solution( 
00265            sigma0, 
00266            sigma1, 
00267            price_sigma0,
00268            price_sigma1,
00269            put_price, 
00270            .0001, 
00271            .0001,
00272            100,
00273            *this, 
00274            &option_pair::P_sigma);
00275 
00276   solution.do_iteration( show_iterations);
00277 
00278   if (!solution.get_converged()) {
00279     _P_implied_sigma = NA;
00280     throw std::domain_error( "sigma did not converge in option_pair::put_implied_sigma");
00281   }
00282 
00283   return solution.get_x_mid();
00284 }
00285 

Generated on Fri Jan 7 12:36:18 2011 for public_options by  doxygen 1.5.1