00001 #include <iomanip> 00002 #include "simpleoption.h" 00003 #include "normal.h" 00004 #include "Secant.h" 00005 00006 void european_option_pair::init_calc_derived_attributes() const 00007 { 00008 option_pair::init_calc_derived_attributes(); 00009 00010 if (_S==0 || _tau==0) return; 00011 00012 _mu = _alpha - _sigma * _sigma * .5; 00013 _sqrt_tau = sqrt( _tau); 00014 _sigma_sqrt_tau = _sigma * _sqrt_tau; 00015 00016 _log_S_K = log( _S / _K); 00017 _Zk = (_log_S_K + _mu * _tau) / _sigma_sqrt_tau; 00018 _h = _Zk + _sigma_sqrt_tau; 00019 00020 _P_h = fast_normal_distribution_function( _h); 00021 00022 //_dh_dS = 1 / (_S * _sigma_sqrt_tau); 00023 00024 _dZk_dtau = -.5 * _Zk / _tau + _mu / _sigma_sqrt_tau; 00025 _dh_dtau = _dZk_dtau + .5 * _sigma_sqrt_tau / _tau; 00026 00027 _N_h = cumulative_normal_distribution_function( _h); 00028 _N_Zk = cumulative_normal_distribution_function( _Zk); 00029 00030 _exp_alpha_r_t = exp( (_alpha - _r)*_tau); 00031 _exp_r_t = exp( -_r * _tau); 00032 00033 _S_exp_alpha_r_t = _S * _exp_alpha_r_t; 00034 _K_exp_r_t = _K * _exp_r_t; 00035 00036 _C = _S_exp_alpha_r_t * _N_h - _K_exp_r_t * _N_Zk; 00037 _P = _C - _S * _exp_alpha_r_t + _K * _exp_r_t; 00038 00039 _dC_dS = _N_h * _exp_alpha_r_t; 00040 _dP_dS = _dC_dS - _exp_alpha_r_t; 00041 00042 _d2C_dS_dtau = (_alpha - _r ) * _dC_dS + _P_h * (_dh_dtau) * _exp_alpha_r_t; 00043 00044 _d2P_dS_dtau = _d2C_dS_dtau - (_alpha - _r) * _exp_alpha_r_t; 00045 00046 _d2C_dS2 = _exp_alpha_r_t * _P_h / (_S * _sigma_sqrt_tau); 00047 _d2P_dS2 = _d2C_dS2; 00048 00049 _d3C_dS2_dtau = (_alpha - _r) * _d2C_dS2 + _P_h * (-_h * _dh_dtau) / (_S * _sigma_sqrt_tau) - .5 / _tau * _d2C_dS2; 00050 00051 //_d3C_dS3 = - (_exp_alpha_r_t / _sigma_sqrt_tau) *( 1 / _S * h * _dh_ds * _P_h + 1 / (_S * _S) * _P_h); 00052 00053 _dh_dsigma = - (_log_S_K + _alpha * _tau) / ( _sigma * _sigma_sqrt_tau); 00054 _dZ_dsigma = _dh_dsigma - _sqrt_tau; 00055 00056 _dC_dsigma = _S * sqrt( _tau) * _exp_alpha_r_t * _P_h; 00057 _dP_dsigma = _dC_dsigma; 00058 00059 _d2C_dsigma2 = - _h *_dC_dsigma; 00060 _d2P_dsigma2 = _d2C_dsigma2; 00061 00062 _dC_dtau = -_r * _C + _alpha * _S * _dC_dS + _sigma * _sigma * _S * _S * .5 * _d2C_dS2; 00063 _dP_dtau = _dC_dtau - (_alpha - _r) * _exp_alpha_r_t * _S - _r * _exp_r_t * _K; 00064 00065 _d2C_dtau2 = -_r * _dC_dtau + _alpha * _S * _d2C_dS_dtau + _sigma * _sigma * _S * _S * .5 * _d3C_dS2_dtau; 00066 00067 _d2P_dtau2 = _d2C_dtau2 - (_alpha - _r) * (_alpha - _r) *_exp_alpha_r_t * _S - _r * _r * _exp_r_t * _K; 00068 } 00069 00070 SIMPOPTFNC ostream& STDCALL operator << ( ostream& os, const european_option_pair& rhs) { 00071 os << "S = " << setprecision(3) << rhs._S << endl; 00072 os << "K = " << setprecision(3) << rhs._K << endl; 00073 os << "Tau = " << rhs._tau << endl; 00074 os << "alpha = " << rhs._alpha << endl; 00075 os << "r = " << rhs._r << endl; 00076 os << "sigma = " << rhs._sigma << endl; 00077 os << "C = " << rhs._C << endl; 00078 os << "P = " << rhs._P << endl; 00079 os << "dC_dS = " << rhs._dC_dS << endl; 00080 os << "dP_dS = " << rhs._dP_dS << endl; 00081 os << "d2C_dS2 = " << rhs._d2C_dS2 << endl; 00082 os << "d2P_dS2 = " << rhs._d2P_dS2 << endl; 00083 os << "dC_dsigma = " << rhs._dC_dsigma << endl; 00084 os << "dP_dsigma = " << rhs._dP_dsigma << endl; 00085 os << "dC_dtau = " << rhs._dC_dtau << endl; 00086 os << "dP_dtau = " << rhs._dP_dtau << endl; 00087 os << "d2P_dtau2 = " << rhs._d2P_dtau2 << endl; 00088 return os; 00089 } 00090 00091 double european_option_pair::dC_dt_tau( double tau) { 00092 if (tau != _tau) put_tau( tau); 00093 return _dC_dtau; 00094 } 00095 00096 double european_option_pair::d2C_dt2_tau( double tau) { 00097 if (tau != _tau) put_tau( tau); 00098 return _d2C_dtau2; 00099 } 00100 00101 double european_option_pair::dP_dt_tau( double tau) { 00102 if (tau != _tau) put_tau( tau); 00103 return _dP_dtau; 00104 } 00105 00106 double european_option_pair::d2P_dt2_tau( double tau) { 00107 if (tau != _tau) put_tau( tau); 00108 return _d2P_dtau2; 00109 } 00110 00111 double european_option_pair::C_tau( double tau) { 00112 if (tau != _tau) put_tau( tau); 00113 return _C; 00114 } 00115 00116 double european_option_pair::P_tau( double tau) { 00117 if (tau != _tau) put_tau( tau); 00118 return _P; 00119 } 00120 double european_option_pair::dC_dsigma( double sigma) { 00121 if (sigma != _sigma) put_sigma( sigma); 00122 return _dC_dsigma; 00123 } 00124 00125 double european_option_pair::d2C_dsigma2( double sigma) { 00126 if (sigma != _sigma) put_sigma( sigma); 00127 return _d2C_dsigma2; 00128 } 00129 00130 double european_option_pair::dP_dsigma( double sigma) { 00131 if (sigma != _sigma) put_sigma( sigma); 00132 return _dP_dsigma; 00133 } 00134 00135 double european_option_pair::d2P_dsigma2( double sigma) { 00136 if (sigma != _sigma) put_sigma( sigma); 00137 return _d2P_dsigma2; 00138 } 00139 00140 void european_option_pair::set_call_immediate_exercise() const 00141 { 00142 _C = _S - _K; 00143 if (_C > 0) { 00144 _dC_dS = 1.0; 00145 } else { 00146 _C = 0; 00147 _dC_dS = 0; 00148 } 00149 00150 _d2C_dS_dtau = 0; 00151 _d2C_dS2 = 0; 00152 _d3C_dS2_dtau = 0; 00153 _dC_dsigma = 0; 00154 _d2C_dsigma2 = 0; 00155 _dC_dtau = 0; 00156 _d2C_dtau2 = 0; 00157 } 00158 00159 void european_option_pair::set_put_immediate_exercise() const 00160 { 00161 _P = _K - _S; 00162 if (_P > 0) { 00163 _dP_dS = -1.0; 00164 } else { 00165 _P = 0; 00166 _dP_dS = 0; 00167 } 00168 00169 _d2P_dS_dtau = 0; 00170 _d2P_dS2 = 0; 00171 _d3P_dS2_dtau = 0; 00172 _dP_dsigma = 0; 00173 _d2P_dsigma2 = 0; 00174 _dP_dtau = 0; 00175 _d2P_dtau2 = 0; 00176 } 00177
1.5.1