1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 2010 Master IMAFA - Polytech'Nice Sophia - Université de Nice Sophia Antipolis 5 6 This file is part of QuantLib, a free-software/open-source library 7 for financial quantitative analysts and developers - http://quantlib.org/ 8 9 QuantLib is free software: you can redistribute it and/or modify it 10 under the terms of the QuantLib license. You should have received a 11 copy of the license along with this program; if not, please email 12 <quantlib-dev@lists.sf.net>. The license is also available online at 13 <http://quantlib.org/license.shtml>. 14 15 This program is distributed in the hope that it will be useful, but WITHOUT 16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 FOR A PARTICULAR PURPOSE. See the license for more details. 18 */ 19 20 #include <ql/experimental/exoticoptions/analyticamericanmargrabeengine.hpp> 21 #include <ql/pricingengines/vanilla/bjerksundstenslandengine.hpp> 22 #include <ql/exercise.hpp> 23 #include <ql/quotes/simplequote.hpp> 24 #include <ql/termstructures/yield/flatforward.hpp> 25 #include <ql/termstructures/volatility/equityfx/blackconstantvol.hpp> 26 #include <ql/time/calendars/nullcalendar.hpp> 27 28 namespace QuantLib { 29 AnalyticAmericanMargrabeEngine(const ext::shared_ptr<GeneralizedBlackScholesProcess> & process1,const ext::shared_ptr<GeneralizedBlackScholesProcess> & process2,Real correlation)30 AnalyticAmericanMargrabeEngine::AnalyticAmericanMargrabeEngine( 31 const ext::shared_ptr<GeneralizedBlackScholesProcess>& process1, 32 const ext::shared_ptr<GeneralizedBlackScholesProcess>& process2, 33 Real correlation) 34 : process1_(process1), process2_(process2), rho_(correlation) { 35 registerWith(process1_); 36 registerWith(process2_); 37 } 38 calculate() const39 void AnalyticAmericanMargrabeEngine::calculate() const { 40 41 QL_REQUIRE(arguments_.exercise->type() == Exercise::American, 42 "not an American option"); 43 44 ext::shared_ptr<AmericanExercise> exercise = 45 ext::dynamic_pointer_cast<AmericanExercise>(arguments_.exercise); 46 QL_REQUIRE(exercise, "not an American option"); 47 48 ext::shared_ptr<NullPayoff> payoff0 = 49 ext::dynamic_pointer_cast<NullPayoff>(arguments_.payoff); 50 QL_REQUIRE(payoff0, "not a null payoff"); 51 52 // The option can be priced as an American single-asset option 53 // with an adjusted process and payoff. 54 55 Date today = Settings::instance().evaluationDate(); 56 57 DayCounter rfdc = process1_->riskFreeRate()->dayCounter(); 58 Time t = rfdc.yearFraction(process1_->riskFreeRate()->referenceDate(), 59 arguments_.exercise->lastDate()); 60 61 Real s1 = process1_->stateVariable()->value(); 62 Real s2 = process2_->stateVariable()->value(); 63 64 ext::shared_ptr<SimpleQuote> spot(new SimpleQuote(arguments_.Q1*s1)); 65 66 ext::shared_ptr<StrikedTypePayoff> payoff( 67 new PlainVanillaPayoff(Option::Call, arguments_.Q2*s2)); 68 69 DiscountFactor dividendDiscount1 = 70 process1_->dividendYield()->discount(exercise->lastDate()); 71 Rate q1 = -std::log(dividendDiscount1)/t; 72 73 DiscountFactor dividendDiscount2 = 74 process2_->dividendYield()->discount(exercise->lastDate()); 75 Rate q2 = -std::log(dividendDiscount2)/t; 76 77 ext::shared_ptr<YieldTermStructure> qTS( 78 new FlatForward(today, q1, rfdc)); 79 80 ext::shared_ptr<YieldTermStructure> rTS( 81 new FlatForward(today, q2, rfdc)); 82 83 Real variance1 = process1_->blackVolatility()->blackVariance( 84 exercise->lastDate(), s1); 85 Real variance2 = process2_->blackVolatility()->blackVariance( 86 exercise->lastDate(), s2); 87 Real variance = variance1 + variance2 88 - 2*rho_*std::sqrt(variance1)*std::sqrt(variance2); 89 Volatility volatility = std::sqrt(variance/t); 90 91 ext::shared_ptr<BlackVolTermStructure> volTS( 92 new BlackConstantVol(today, NullCalendar(), volatility, rfdc)); 93 94 ext::shared_ptr<BlackScholesMertonProcess> stochProcess(new 95 BlackScholesMertonProcess(Handle<Quote>(spot), 96 Handle<YieldTermStructure>(qTS), 97 Handle<YieldTermStructure>(rTS), 98 Handle<BlackVolTermStructure>(volTS))); 99 100 ext::shared_ptr<PricingEngine> engine( 101 new BjerksundStenslandApproximationEngine(stochProcess)); 102 103 VanillaOption option(payoff, exercise); 104 option.setPricingEngine(engine); 105 106 results_.value = option.NPV(); 107 } 108 109 } 110