EuropeanOption.cpp

This example calculates European options using different methods while testing call-put parity.
#include <ql/quantlib.hpp> using namespace QuantLib; // This will be included in the library after a bit of redesign class WeightedPayoff { public: WeightedPayoff(Option::Type type, Time maturity, Real strike, Real s0, Volatility sigma, Rate r, Rate q) : type_(type), maturity_(maturity), strike_(strike), s0_(s0), sigma_(sigma),r_(r), q_(q){} Real operator()(Real x) const { Real nuT = (r_-q_-0.5*sigma_*sigma_)*maturity_; return QL_EXP(-r_*maturity_) *PlainVanillaPayoff(type_, strike_)(s0_*QL_EXP(x)) *QL_EXP(-(x - nuT)*(x -nuT)/(2*sigma_*sigma_*maturity_)) /QL_SQRT(2.0*M_PI*sigma_*sigma_*maturity_); } private: Option::Type type_; Time maturity_; Real strike_; Real s0_; Volatility sigma_; Rate r_,q_; }; int main(int, char* []) { try { QL_IO_INIT std::cout << "Using " << QL_VERSION << std::endl << std::endl; // our option Option::Type type(Option::Call); Real underlying = 7; Real strike = 8; Spread dividendYield = 0.05; Rate riskFreeRate = 0.05; Date todaysDate(15, May, 1998); Date settlementDate(17, May, 1998); Date exerciseDate(17, May, 1999); DayCounter rateDayCounter = Actual365(); Time maturity = rateDayCounter.yearFraction(settlementDate, exerciseDate); Volatility volatility = 0.10; std::cout << "option type = " << OptionTypeFormatter::toString(type) << std::endl; std::cout << "Time to maturity = " << maturity << std::endl; std::cout << "Underlying price = " << underlying << std::endl; std::cout << "Strike = " << strike << std::endl; std::cout << "Risk-free interest rate = " << riskFreeRate << std::endl; std::cout << "dividend yield = " << dividendYield << std::endl; std::cout << "Volatility = " << volatility << std::endl; std::cout << std::endl; Date midlifeDate(19, November, 1998); std::vector<Date> exDates(2); exDates[0]=midlifeDate; exDates[1]=exerciseDate; boost::shared_ptr<Exercise> exercise( new EuropeanExercise(exerciseDate)); boost::shared_ptr<Exercise> amExercise( new AmericanExercise(settlementDate, exerciseDate)); boost::shared_ptr<Exercise> berExercise(new BermudanExercise(exDates)); RelinkableHandle<Quote> underlyingH( boost::shared_ptr<Quote>(new SimpleQuote(underlying))); // bootstrap the yield/dividend/vol curves RelinkableHandle<TermStructure> flatTermStructure( boost::shared_ptr<TermStructure>( new FlatForward(todaysDate, settlementDate, riskFreeRate, rateDayCounter))); RelinkableHandle<TermStructure> flatDividendTS( boost::shared_ptr<TermStructure>( new FlatForward(todaysDate, settlementDate, dividendYield, rateDayCounter))); RelinkableHandle<BlackVolTermStructure> flatVolTS( boost::shared_ptr<BlackVolTermStructure>( new BlackConstantVol(settlementDate, volatility))); std::vector<Date> dates(4); dates[0] = settlementDate.plusMonths(1); dates[1] = exerciseDate; dates[2] = exerciseDate.plusMonths(6); dates[3] = exerciseDate.plusMonths(12); std::vector<Real> strikes(4); strikes[0] = underlying*0.9; strikes[1] = underlying; strikes[2] = underlying*1.1; strikes[3] = underlying*1.2; Matrix vols(4,4); vols[0][0] = volatility*1.1; vols[0][1] = volatility; vols[0][2] = volatility*0.9; vols[0][3] = volatility*0.8; vols[1][0] = volatility*1.1; vols[1][1] = volatility; vols[1][2] = volatility*0.9; vols[1][3] = volatility*0.8; vols[2][0] = volatility*1.1; vols[2][1] = volatility; vols[2][2] = volatility*0.9; vols[2][3] = volatility*0.8; vols[3][0] = volatility*1.1; vols[3][1] = volatility; vols[3][2] = volatility*0.9; vols[3][3] = volatility*0.8; RelinkableHandle<BlackVolTermStructure> blackSurface( boost::shared_ptr<BlackVolTermStructure>( new BlackVarianceSurface(settlementDate, dates, strikes, vols))); boost::shared_ptr<StrikedTypePayoff> payoff(new PlainVanillaPayoff(type, strike)); boost::shared_ptr<BlackScholesProcess> stochasticProcess(new BlackScholesProcess(underlyingH, flatDividendTS, flatTermStructure, // blackSurface flatVolTS)); EuropeanOption option(stochasticProcess, payoff, exercise); std::string method; Real value, discrepancy, rightValue, relativeDiscrepancy; std::cout << std::endl << std::endl; // write column headings std::cout << "Method\t\tValue\tEstimatedError\tDiscrepancy" "\tRel. Discr." << std::endl; // method: Black-Scholes Engine method = "Black-Scholes"; option.setPricingEngine(boost::shared_ptr<PricingEngine>( new AnalyticEuropeanEngine())); rightValue = value = option.NPV(); discrepancy = QL_FABS(value-rightValue); relativeDiscrepancy = discrepancy/rightValue; std::cout << method << "\t" << DecimalFormatter::toString(value, 4) << "\t" << "N/A\t\t" << DecimalFormatter::toString(discrepancy, 6) << "\t" << DecimalFormatter::toString(relativeDiscrepancy, 6) << std::endl; // method: Integral method = "Integral"; option.setPricingEngine(boost::shared_ptr<PricingEngine>( new IntegralEngine())); value = option.NPV(); discrepancy = QL_FABS(value-rightValue); relativeDiscrepancy = discrepancy/rightValue; std::cout << method << "\t" << DecimalFormatter::toString(value, 4) << "\t" << "N/A\t\t" << DecimalFormatter::toString(discrepancy, 6) << "\t" << DecimalFormatter::toString(relativeDiscrepancy, 6) << std::endl; /* // method: Integral method = "Binary Cash"; option.setPricingEngine(boost::shared_ptr<PricingEngine>( new IntegralCashOrNothingEngine(1.0))); value = option.NPV(); discrepancy = QL_FABS(value-rightValue); relativeDiscrepancy = discrepancy/rightValue; std::cout << method << "\t" << DecimalFormatter::toString(value, 4) << "\t" << "N/A\t\t" << DecimalFormatter::toString(discrepancy, 6) << "\t" << DecimalFormatter::toString(relativeDiscrepancy, 6) << std::endl; // method: Integral method = "Binary Asset"; option.setPricingEngine(boost::shared_ptr<PricingEngine>( new IntegralAssetOrNothingEngine())); value = option.NPV(); discrepancy = QL_FABS(value-rightValue); relativeDiscrepancy = discrepancy/rightValue; std::cout << method << "\t" << DecimalFormatter::toString(value, 4) << "\t" << "N/A\t\t" << DecimalFormatter::toString(discrepancy, 6) << "\t" << DecimalFormatter::toString(relativeDiscrepancy, 6) << std::endl; */ Size timeSteps = 801; // Binomial Method (JR) method = "Binomial (JR)"; option.setPricingEngine(boost::shared_ptr<PricingEngine>( new BinomialVanillaEngine<JarrowRudd>(timeSteps))); value = option.NPV(); discrepancy = QL_FABS(value-rightValue); relativeDiscrepancy = discrepancy/rightValue; std::cout << method << "\t" << DecimalFormatter::toString(value, 4) << "\t" << "N/A\t\t" << DecimalFormatter::toString(discrepancy, 6) << "\t" << DecimalFormatter::toString(relativeDiscrepancy, 6) << std::endl; // Binomial Method (CRR) method = "Binomial (CRR)"; option.setPricingEngine(boost::shared_ptr<PricingEngine>( new BinomialVanillaEngine<CoxRossRubinstein>(timeSteps))); value = option.NPV(); discrepancy = QL_FABS(value-rightValue); relativeDiscrepancy = discrepancy/rightValue; std::cout << method << "\t" << DecimalFormatter::toString(value, 4) << "\t" << "N/A\t\t" << DecimalFormatter::toString(discrepancy, 6) << "\t" << DecimalFormatter::toString(relativeDiscrepancy, 6) << std::endl; // Equal Probability Additive Binomial Tree (EQP) method = "Additive (EQP)"; option.setPricingEngine(boost::shared_ptr<PricingEngine>( new BinomialVanillaEngine<AdditiveEQPBinomialTree>(timeSteps))); value = option.NPV(); discrepancy = QL_FABS(value-rightValue); relativeDiscrepancy = discrepancy/rightValue; std::cout << method << "\t" << DecimalFormatter::toString(value, 4) << "\t" << "N/A\t\t" << DecimalFormatter::toString(discrepancy, 6) << "\t" << DecimalFormatter::toString(relativeDiscrepancy, 6) << std::endl; // Equal Jumps Additive Binomial Tree (Trigeorgis) method = "Bin. Trigeorgis"; option.setPricingEngine(boost::shared_ptr<PricingEngine>( new BinomialVanillaEngine<Trigeorgis>(timeSteps))); value = option.NPV(); discrepancy = QL_FABS(value-rightValue); relativeDiscrepancy = discrepancy/rightValue; std::cout << method << "\t" << DecimalFormatter::toString(value, 4) << "\t" << "N/A\t\t" << DecimalFormatter::toString(discrepancy, 6) << "\t" << DecimalFormatter::toString(relativeDiscrepancy, 6) << std::endl; // Tian Binomial Tree (third moment matching) method = "Binomial Tian"; option.setPricingEngine(boost::shared_ptr<PricingEngine>( new BinomialVanillaEngine<Tian>(timeSteps))); value = option.NPV(); discrepancy = QL_FABS(value-rightValue); relativeDiscrepancy = discrepancy/rightValue; std::cout << method << "\t" << DecimalFormatter::toString(value, 4) << "\t" << "N/A\t\t" << DecimalFormatter::toString(discrepancy, 6) << "\t" << DecimalFormatter::toString(relativeDiscrepancy, 6) << std::endl; // Leisen-Reimer Binomial Tree method = "Binomial LR"; option.setPricingEngine(boost::shared_ptr<PricingEngine>( new BinomialVanillaEngine<LeisenReimer>(timeSteps))); value = option.NPV(); discrepancy = QL_FABS(value-rightValue); relativeDiscrepancy = discrepancy/rightValue; std::cout << method << "\t" << DecimalFormatter::toString(value, 4) << "\t" << "N/A\t\t" << DecimalFormatter::toString(discrepancy, 6) << "\t" << DecimalFormatter::toString(relativeDiscrepancy, 6) << std::endl; // Finite Differences Method: not implemented /*method = "Finite Diff."; option.setPricingEngine(boost::shared_ptr<PricingEngine>( new FDVanillaEngine())); value = option.NPV(); discrepancy = QL_FABS(value-rightValue); relativeDiscrepancy = discrepancy/rightValue; std::cout << method << "\t" << DecimalFormatter::toString(value, 4) << "\t" << "N/A\t\t" << DecimalFormatter::toString(discrepancy, 6) << "\t" << DecimalFormatter::toString(relativeDiscrepancy, 6) << std::endl;*/ // Monte Carlo Method timeSteps = 1; method = "MC (crude)"; Size mcSeed = 42; boost::shared_ptr<PricingEngine> mcengine1; mcengine1 = MakeMCEuropeanEngine<PseudoRandom>().withStepsPerYear(timeSteps) .withTolerance(0.02) .withSeed(mcSeed); option.setPricingEngine(mcengine1); value = option.NPV(); Real errorEstimate = option.errorEstimate(); discrepancy = QL_FABS(value-rightValue); relativeDiscrepancy = discrepancy/rightValue; std::cout << method << "\t" << DecimalFormatter::toString(value, 4) << "\t" << DecimalFormatter::toString(errorEstimate, 4) << "\t\t" << DecimalFormatter::toString(discrepancy, 6) << "\t" << DecimalFormatter::toString(relativeDiscrepancy, 6) << std::endl; method = "MC (Sobol)"; timeSteps = 1; Size nSamples = 32768; // 2^15 boost::shared_ptr<PricingEngine> mcengine2; mcengine2 = MakeMCEuropeanEngine<LowDiscrepancy>().withStepsPerYear(timeSteps) .withSamples(nSamples); option.setPricingEngine(mcengine2); value = option.NPV(); discrepancy = QL_FABS(value-rightValue); relativeDiscrepancy = discrepancy/rightValue; std::cout << method << "\t" << DecimalFormatter::toString(value, 4) << "\t" << "N/A\t\t" << DecimalFormatter::toString(discrepancy, 6) << "\t" << DecimalFormatter::toString(relativeDiscrepancy, 6) << std::endl; return 0; } catch (std::exception& e) { std::cout << e.what() << std::endl; return 1; } catch (...) { std::cout << "unknown error" << std::endl; return 1; } }
00001 00019 #include <ql/quantlib.hpp> 00020 00021 using namespace QuantLib; 00022 00023 // This will be included in the library after a bit of redesign 00024 class WeightedPayoff { 00025 public: 00026 WeightedPayoff(Option::Type type, 00027 Time maturity, 00028 Real strike, 00029 Real s0, 00030 Volatility sigma, 00031 Rate r, 00032 Rate q) 00033 : type_(type), maturity_(maturity), 00034 strike_(strike), 00035 s0_(s0), 00036 sigma_(sigma),r_(r), q_(q){} 00037 00038 Real operator()(Real x) const { 00039 Real nuT = (r_-q_-0.5*sigma_*sigma_)*maturity_; 00040 return QL_EXP(-r_*maturity_) 00041 *PlainVanillaPayoff(type_, strike_)(s0_*QL_EXP(x)) 00042 *QL_EXP(-(x - nuT)*(x -nuT)/(2*sigma_*sigma_*maturity_)) 00043 /QL_SQRT(2.0*M_PI*sigma_*sigma_*maturity_); 00044 } 00045 private: 00046 Option::Type type_; 00047 Time maturity_; 00048 Real strike_; 00049 Real s0_; 00050 Volatility sigma_; 00051 Rate r_,q_; 00052 }; 00053 00054 00055 int main(int, char* []) 00056 { 00057 try { 00058 QL_IO_INIT 00059 00060 std::cout << "Using " << QL_VERSION << std::endl << std::endl; 00061 00062 // our option 00063 Option::Type type(Option::Call); 00064 Real underlying = 7; 00065 Real strike = 8; 00066 Spread dividendYield = 0.05; 00067 Rate riskFreeRate = 0.05; 00068 00069 Date todaysDate(15, May, 1998); 00070 Date settlementDate(17, May, 1998); 00071 Date exerciseDate(17, May, 1999); 00072 DayCounter rateDayCounter = Actual365(); 00073 Time maturity = rateDayCounter.yearFraction(settlementDate, 00074 exerciseDate); 00075 00076 Volatility volatility = 0.10; 00077 std::cout << "option type = " << OptionTypeFormatter::toString(type) 00078 << std::endl; 00079 std::cout << "Time to maturity = " << maturity 00080 << std::endl; 00081 std::cout << "Underlying price = " << underlying 00082 << std::endl; 00083 std::cout << "Strike = " << strike 00084 << std::endl; 00085 std::cout << "Risk-free interest rate = " << riskFreeRate 00086 << std::endl; 00087 std::cout << "dividend yield = " << dividendYield 00088 << std::endl; 00089 std::cout << "Volatility = " << volatility 00090 << std::endl; 00091 std::cout << std::endl; 00092 00093 Date midlifeDate(19, November, 1998); 00094 std::vector<Date> exDates(2); 00095 exDates[0]=midlifeDate; 00096 exDates[1]=exerciseDate; 00097 00098 boost::shared_ptr<Exercise> exercise( 00099 new EuropeanExercise(exerciseDate)); 00100 boost::shared_ptr<Exercise> amExercise( 00101 new AmericanExercise(settlementDate, 00102 exerciseDate)); 00103 boost::shared_ptr<Exercise> berExercise(new BermudanExercise(exDates)); 00104 00105 00106 RelinkableHandle<Quote> underlyingH( 00107 boost::shared_ptr<Quote>(new SimpleQuote(underlying))); 00108 00109 // bootstrap the yield/dividend/vol curves 00110 RelinkableHandle<TermStructure> flatTermStructure( 00111 boost::shared_ptr<TermStructure>( 00112 new FlatForward(todaysDate, settlementDate, 00113 riskFreeRate, rateDayCounter))); 00114 RelinkableHandle<TermStructure> flatDividendTS( 00115 boost::shared_ptr<TermStructure>( 00116 new FlatForward(todaysDate, settlementDate, 00117 dividendYield, rateDayCounter))); 00118 RelinkableHandle<BlackVolTermStructure> flatVolTS( 00119 boost::shared_ptr<BlackVolTermStructure>( 00120 new BlackConstantVol(settlementDate, volatility))); 00121 00122 std::vector<Date> dates(4); 00123 dates[0] = settlementDate.plusMonths(1); 00124 dates[1] = exerciseDate; 00125 dates[2] = exerciseDate.plusMonths(6); 00126 dates[3] = exerciseDate.plusMonths(12); 00127 std::vector<Real> strikes(4); 00128 strikes[0] = underlying*0.9; 00129 strikes[1] = underlying; 00130 strikes[2] = underlying*1.1; 00131 strikes[3] = underlying*1.2; 00132 00133 Matrix vols(4,4); 00134 vols[0][0] = volatility*1.1; 00135 vols[0][1] = volatility; 00136 vols[0][2] = volatility*0.9; 00137 vols[0][3] = volatility*0.8; 00138 vols[1][0] = volatility*1.1; 00139 vols[1][1] = volatility; 00140 vols[1][2] = volatility*0.9; 00141 vols[1][3] = volatility*0.8; 00142 vols[2][0] = volatility*1.1; 00143 vols[2][1] = volatility; 00144 vols[2][2] = volatility*0.9; 00145 vols[2][3] = volatility*0.8; 00146 vols[3][0] = volatility*1.1; 00147 vols[3][1] = volatility; 00148 vols[3][2] = volatility*0.9; 00149 vols[3][3] = volatility*0.8; 00150 00151 RelinkableHandle<BlackVolTermStructure> blackSurface( 00152 boost::shared_ptr<BlackVolTermStructure>( 00153 new BlackVarianceSurface(settlementDate, dates, 00154 strikes, vols))); 00155 00156 00157 boost::shared_ptr<StrikedTypePayoff> payoff(new 00158 PlainVanillaPayoff(type, strike)); 00159 00160 boost::shared_ptr<BlackScholesProcess> stochasticProcess(new 00161 BlackScholesProcess(underlyingH, flatDividendTS, 00162 flatTermStructure, 00163 // blackSurface 00164 flatVolTS)); 00165 00166 EuropeanOption option(stochasticProcess, payoff, exercise); 00167 00168 00169 std::string method; 00170 Real value, discrepancy, rightValue, relativeDiscrepancy; 00171 00172 std::cout << std::endl << std::endl; 00173 00174 // write column headings 00175 std::cout << "Method\t\tValue\tEstimatedError\tDiscrepancy" 00176 "\tRel. Discr." << std::endl; 00177 00178 // method: Black-Scholes Engine 00179 method = "Black-Scholes"; 00180 option.setPricingEngine(boost::shared_ptr<PricingEngine>( 00181 new AnalyticEuropeanEngine())); 00182 rightValue = value = option.NPV(); 00183 discrepancy = QL_FABS(value-rightValue); 00184 relativeDiscrepancy = discrepancy/rightValue; 00185 std::cout << method << "\t" 00186 << DecimalFormatter::toString(value, 4) << "\t" 00187 << "N/A\t\t" 00188 << DecimalFormatter::toString(discrepancy, 6) << "\t" 00189 << DecimalFormatter::toString(relativeDiscrepancy, 6) 00190 << std::endl; 00191 00192 00193 // method: Integral 00194 method = "Integral"; 00195 option.setPricingEngine(boost::shared_ptr<PricingEngine>( 00196 new IntegralEngine())); 00197 value = option.NPV(); 00198 discrepancy = QL_FABS(value-rightValue); 00199 relativeDiscrepancy = discrepancy/rightValue; 00200 std::cout << method << "\t" 00201 << DecimalFormatter::toString(value, 4) << "\t" 00202 << "N/A\t\t" 00203 << DecimalFormatter::toString(discrepancy, 6) << "\t" 00204 << DecimalFormatter::toString(relativeDiscrepancy, 6) 00205 << std::endl; 00206 00207 /* 00208 // method: Integral 00209 method = "Binary Cash"; 00210 option.setPricingEngine(boost::shared_ptr<PricingEngine>( 00211 new IntegralCashOrNothingEngine(1.0))); 00212 value = option.NPV(); 00213 discrepancy = QL_FABS(value-rightValue); 00214 relativeDiscrepancy = discrepancy/rightValue; 00215 std::cout << method << "\t" 00216 << DecimalFormatter::toString(value, 4) << "\t" 00217 << "N/A\t\t" 00218 << DecimalFormatter::toString(discrepancy, 6) << "\t" 00219 << DecimalFormatter::toString(relativeDiscrepancy, 6) 00220 << std::endl; 00221 00222 // method: Integral 00223 method = "Binary Asset"; 00224 option.setPricingEngine(boost::shared_ptr<PricingEngine>( 00225 new IntegralAssetOrNothingEngine())); 00226 value = option.NPV(); 00227 discrepancy = QL_FABS(value-rightValue); 00228 relativeDiscrepancy = discrepancy/rightValue; 00229 std::cout << method << "\t" 00230 << DecimalFormatter::toString(value, 4) << "\t" 00231 << "N/A\t\t" 00232 << DecimalFormatter::toString(discrepancy, 6) << "\t" 00233 << DecimalFormatter::toString(relativeDiscrepancy, 6) 00234 << std::endl; 00235 00236 */ 00237 Size timeSteps = 801; 00238 00239 // Binomial Method (JR) 00240 method = "Binomial (JR)"; 00241 option.setPricingEngine(boost::shared_ptr<PricingEngine>( 00242 new BinomialVanillaEngine<JarrowRudd>(timeSteps))); 00243 value = option.NPV(); 00244 discrepancy = QL_FABS(value-rightValue); 00245 relativeDiscrepancy = discrepancy/rightValue; 00246 std::cout << method << "\t" 00247 << DecimalFormatter::toString(value, 4) << "\t" 00248 << "N/A\t\t" 00249 << DecimalFormatter::toString(discrepancy, 6) << "\t" 00250 << DecimalFormatter::toString(relativeDiscrepancy, 6) 00251 << std::endl; 00252 00253 00254 // Binomial Method (CRR) 00255 method = "Binomial (CRR)"; 00256 option.setPricingEngine(boost::shared_ptr<PricingEngine>( 00257 new BinomialVanillaEngine<CoxRossRubinstein>(timeSteps))); 00258 value = option.NPV(); 00259 discrepancy = QL_FABS(value-rightValue); 00260 relativeDiscrepancy = discrepancy/rightValue; 00261 std::cout << method << "\t" 00262 << DecimalFormatter::toString(value, 4) << "\t" 00263 << "N/A\t\t" 00264 << DecimalFormatter::toString(discrepancy, 6) << "\t" 00265 << DecimalFormatter::toString(relativeDiscrepancy, 6) 00266 << std::endl; 00267 00268 // Equal Probability Additive Binomial Tree (EQP) 00269 method = "Additive (EQP)"; 00270 option.setPricingEngine(boost::shared_ptr<PricingEngine>( 00271 new BinomialVanillaEngine<AdditiveEQPBinomialTree>(timeSteps))); 00272 value = option.NPV(); 00273 discrepancy = QL_FABS(value-rightValue); 00274 relativeDiscrepancy = discrepancy/rightValue; 00275 std::cout << method << "\t" 00276 << DecimalFormatter::toString(value, 4) << "\t" 00277 << "N/A\t\t" 00278 << DecimalFormatter::toString(discrepancy, 6) << "\t" 00279 << DecimalFormatter::toString(relativeDiscrepancy, 6) 00280 << std::endl; 00281 00282 // Equal Jumps Additive Binomial Tree (Trigeorgis) 00283 method = "Bin. Trigeorgis"; 00284 option.setPricingEngine(boost::shared_ptr<PricingEngine>( 00285 new BinomialVanillaEngine<Trigeorgis>(timeSteps))); 00286 value = option.NPV(); 00287 discrepancy = QL_FABS(value-rightValue); 00288 relativeDiscrepancy = discrepancy/rightValue; 00289 std::cout << method << "\t" 00290 << DecimalFormatter::toString(value, 4) << "\t" 00291 << "N/A\t\t" 00292 << DecimalFormatter::toString(discrepancy, 6) << "\t" 00293 << DecimalFormatter::toString(relativeDiscrepancy, 6) 00294 << std::endl; 00295 00296 // Tian Binomial Tree (third moment matching) 00297 method = "Binomial Tian"; 00298 option.setPricingEngine(boost::shared_ptr<PricingEngine>( 00299 new BinomialVanillaEngine<Tian>(timeSteps))); 00300 value = option.NPV(); 00301 discrepancy = QL_FABS(value-rightValue); 00302 relativeDiscrepancy = discrepancy/rightValue; 00303 std::cout << method << "\t" 00304 << DecimalFormatter::toString(value, 4) << "\t" 00305 << "N/A\t\t" 00306 << DecimalFormatter::toString(discrepancy, 6) << "\t" 00307 << DecimalFormatter::toString(relativeDiscrepancy, 6) 00308 << std::endl; 00309 00310 // Leisen-Reimer Binomial Tree 00311 method = "Binomial LR"; 00312 option.setPricingEngine(boost::shared_ptr<PricingEngine>( 00313 new BinomialVanillaEngine<LeisenReimer>(timeSteps))); 00314 value = option.NPV(); 00315 discrepancy = QL_FABS(value-rightValue); 00316 relativeDiscrepancy = discrepancy/rightValue; 00317 std::cout << method << "\t" 00318 << DecimalFormatter::toString(value, 4) << "\t" 00319 << "N/A\t\t" 00320 << DecimalFormatter::toString(discrepancy, 6) << "\t" 00321 << DecimalFormatter::toString(relativeDiscrepancy, 6) 00322 << std::endl; 00323 00324 // Finite Differences Method: not implemented 00325 00326 /*method = "Finite Diff."; 00327 option.setPricingEngine(boost::shared_ptr<PricingEngine>( 00328 new FDVanillaEngine())); 00329 value = option.NPV(); 00330 discrepancy = QL_FABS(value-rightValue); 00331 relativeDiscrepancy = discrepancy/rightValue; 00332 std::cout << method << "\t" 00333 << DecimalFormatter::toString(value, 4) << "\t" 00334 << "N/A\t\t" 00335 << DecimalFormatter::toString(discrepancy, 6) << "\t" 00336 << DecimalFormatter::toString(relativeDiscrepancy, 6) 00337 << std::endl;*/ 00338 00339 00340 // Monte Carlo Method 00341 timeSteps = 1; 00342 00343 method = "MC (crude)"; 00344 Size mcSeed = 42; 00345 00346 boost::shared_ptr<PricingEngine> mcengine1; 00347 mcengine1 = 00348 MakeMCEuropeanEngine<PseudoRandom>().withStepsPerYear(timeSteps) 00349 .withTolerance(0.02) 00350 .withSeed(mcSeed); 00351 option.setPricingEngine(mcengine1); 00352 00353 value = option.NPV(); 00354 Real errorEstimate = option.errorEstimate(); 00355 discrepancy = QL_FABS(value-rightValue); 00356 relativeDiscrepancy = discrepancy/rightValue; 00357 std::cout << method << "\t" 00358 << DecimalFormatter::toString(value, 4) << "\t" 00359 << DecimalFormatter::toString(errorEstimate, 4) << "\t\t" 00360 << DecimalFormatter::toString(discrepancy, 6) << "\t" 00361 << DecimalFormatter::toString(relativeDiscrepancy, 6) 00362 << std::endl; 00363 00364 method = "MC (Sobol)"; 00365 timeSteps = 1; 00366 Size nSamples = 32768; // 2^15 00367 00368 boost::shared_ptr<PricingEngine> mcengine2; 00369 mcengine2 = 00370 MakeMCEuropeanEngine<LowDiscrepancy>().withStepsPerYear(timeSteps) 00371 .withSamples(nSamples); 00372 option.setPricingEngine(mcengine2); 00373 00374 value = option.NPV(); 00375 discrepancy = QL_FABS(value-rightValue); 00376 relativeDiscrepancy = discrepancy/rightValue; 00377 std::cout << method << "\t" 00378 << DecimalFormatter::toString(value, 4) << "\t" 00379 << "N/A\t\t" 00380 << DecimalFormatter::toString(discrepancy, 6) << "\t" 00381 << DecimalFormatter::toString(relativeDiscrepancy, 6) 00382 << std::endl; 00383 00384 return 0; 00385 } catch (std::exception& e) { 00386 std::cout << e.what() << std::endl; 00387 return 1; 00388 } catch (...) { 00389 std::cout << "unknown error" << std::endl; 00390 return 1; 00391 } 00392 }

QuantLib.org
QuantLib
Hosted by
SourceForge.net Logo
Documentation generated by
doxygen