00001 #include <iostream>
00002 #include <iomanip>
00003
00004 #include "american_option_approximation.h"
00005 #include "GridSearch.h"
00006
00007 void american_option_approximation::init_calc_derived_attributes() const
00008 {
00009 european_option_pair::init_calc_derived_attributes();
00010
00011 if ((_alpha - _r) >= 0) {
00012 _call_early_exercise = false;
00013 _put_early_exercise = true;
00014 } else {
00015 _call_early_exercise = true;
00016 _put_early_exercise = true;
00017 }
00018
00019 _optvar.init( dynamic_cast<const european_option_pair&>( *this));
00020
00021 _put_tau = _call_tau = _tau;
00022
00023 if (_call_early_exercise) {
00024 GridSearch< european_option_pair, double > path(
00025 100,
00026 0,
00027 .01*_tau,
00028 _optvar,
00029 &european_option_pair::C_tau);
00030
00031
00032 path.do_iteration( false);
00033
00034 _optvar.put_tau( _call_tau = path.get_x_max());
00035 set_call( _optvar);
00036 }
00037
00038 if (_put_early_exercise) {
00039 GridSearch< european_option_pair, double > path(
00040 100,
00041 0,
00042 .01*_tau,
00043 _optvar,
00044 &european_option_pair::P_tau);
00045
00046
00047 path.do_iteration( false);
00048
00049 _optvar.put_tau( _put_tau = path.get_x_max());
00050 set_put( _optvar);
00051 }
00052 }
00053
00054 void american_option_approximation::set_call( const european_option_pair& rhs) const
00055 {
00056 _C = rhs._C;
00057 _dC_dS = rhs._dC_dS;
00058 _d2C_dS_dtau = rhs._d2C_dS_dtau;
00059 _d2C_dS2 = rhs._d2C_dS2;
00060 _d3C_dS2_dtau = rhs._d3C_dS2_dtau;
00061 _dC_dsigma = rhs._dC_dsigma;
00062 _d2C_dsigma2 = rhs._d2C_dsigma2;
00063 _dC_dtau = rhs._dC_dtau;
00064 _d2C_dtau2 = rhs._d2C_dtau2;
00065 }
00066
00067 void american_option_approximation::set_put( const european_option_pair& rhs) const
00068 {
00069 _P = rhs._P;
00070 _dP_dS = rhs._dP_dS;
00071 _d2P_dS_dtau = rhs._d2P_dS_dtau;
00072 _d2P_dS2 = rhs._d2P_dS2;
00073 _d3P_dS2_dtau = rhs._d3P_dS2_dtau;
00074 _dP_dsigma = rhs._dP_dsigma;
00075 _d2P_dsigma2 = rhs._d2P_dsigma2;
00076 _dP_dtau = rhs._dP_dtau;
00077 _d2P_dtau2 = rhs._d2P_dtau2;
00078 }
00079
00080 AMERICANAPPROXFNC ostream& STDCALL operator << ( ostream& os, const american_option_approximation& rhs) {
00081 os << "S = " << setprecision(3) << rhs._S << endl;
00082 os << "K = " << setprecision(3) << rhs._K << endl;
00083 os << "Tau = " << rhs._tau << endl;
00084 os << "alpha = " << rhs._alpha << endl;
00085 os << "r = " << rhs._r << endl;
00086 os << "sigma = " << rhs._sigma << endl;
00087 os << "C = " << rhs._C << endl;
00088 os << "P = " << rhs._P << endl;
00089 os << "dC_dS = " << rhs._dC_dS << endl;
00090 os << "dP_dS = " << rhs._dP_dS << endl;
00091 os << "d2C_dS2 = " << rhs._d2C_dS2 << endl;
00092 os << "d2P_dS2 = " << rhs._d2P_dS2 << endl;
00093 os << "dC_dsigma = " << rhs._dC_dsigma << endl;
00094 os << "dP_dsigma = " << rhs._dP_dsigma << endl;
00095 os << "dC_dtau = " << rhs._dC_dtau << endl;
00096 os << "dP_dtau = " << rhs._dP_dtau << endl;
00097 os << "d2P_dtau2 = " << rhs._d2P_dtau2 << endl;
00098 os << "call_tau = " << rhs._call_tau << endl;
00099 os << "put_tau = " << rhs._put_tau << endl;
00100
00101 return os;
00102 }
00103
00104 double american_option_approximation::call_intrinsic_value() const {
00105 double tmp = _S - _K;
00106 tmp = (tmp>0)? tmp : 0;
00107
00108 double tmp2 = _S*exp((_alpha - _r)*_tau) - _K * exp( -_r * _tau);
00109 return (tmp2 > tmp) ? tmp2 : tmp;
00110 }
00111
00112 double american_option_approximation::put_intrinsic_value() const {
00113 double tmp = _K - _S;
00114 tmp = (tmp>0)? tmp : 0;
00115
00116 double tmp2 = _K * exp( -_r * _tau) - _S*exp((_alpha - _r)*_tau);
00117 return (tmp2 > tmp) ? tmp2 : tmp;
00118 }