1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 2010 Klaus Spanderen 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/pricingengines/basket/kirkengine.hpp> 21 #include <ql/pricingengines/blackcalculator.hpp> 22 #include <ql/pricingengines/blackformula.hpp> 23 #include <ql/math/functional.hpp> 24 #include <ql/exercise.hpp> 25 26 namespace QuantLib { 27 KirkEngine(const ext::shared_ptr<BlackProcess> & process1,const ext::shared_ptr<BlackProcess> & process2,Real correlation)28 KirkEngine::KirkEngine( 29 const ext::shared_ptr<BlackProcess>& process1, 30 const ext::shared_ptr<BlackProcess>& process2, 31 Real correlation) 32 : process1_(process1), process2_(process2), rho_(correlation) { 33 registerWith(process1_); 34 registerWith(process2_); 35 } 36 calculate() const37 void KirkEngine::calculate() const { 38 39 QL_REQUIRE(arguments_.exercise->type() == Exercise::European, 40 "not a European option"); 41 42 ext::shared_ptr<EuropeanExercise> exercise = 43 ext::dynamic_pointer_cast<EuropeanExercise>(arguments_.exercise); 44 QL_REQUIRE(exercise, "not a European exercise"); 45 46 ext::shared_ptr<SpreadBasketPayoff> spreadPayoff = 47 ext::dynamic_pointer_cast<SpreadBasketPayoff>(arguments_.payoff); 48 QL_REQUIRE(spreadPayoff," spread payoff expected"); 49 50 ext::shared_ptr<PlainVanillaPayoff> payoff = 51 ext::dynamic_pointer_cast<PlainVanillaPayoff>( 52 spreadPayoff->basePayoff()); 53 QL_REQUIRE(payoff, "non-plain payoff given"); 54 const Real strike = payoff->strike(); 55 56 const Real f1 = process1_->stateVariable()->value(); 57 const Real f2 = process2_->stateVariable()->value(); 58 59 // use atm vols 60 const Real variance1 = process1_->blackVolatility()->blackVariance( 61 exercise->lastDate(), f1); 62 const Real variance2 = process2_->blackVolatility()->blackVariance( 63 exercise->lastDate(), f2); 64 65 const DiscountFactor riskFreeDiscount = 66 process1_->riskFreeRate()->discount(exercise->lastDate()); 67 68 const Real f = f1/(f2 + strike); 69 const Real v 70 = std::sqrt(variance1 71 + variance2*square<Real>()(f2/(f2+strike)) 72 - 2*rho_*std::sqrt(variance1*variance2) 73 *(f2/(f2+strike))); 74 75 BlackCalculator black( 76 ext::make_shared<PlainVanillaPayoff>( 77 payoff->optionType(),1.0), 78 f, v, riskFreeDiscount); 79 80 results_.value = (f2 + strike)*black.value(); 81 } 82 } 83 84