1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 2014 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/analytictwoassetcorrelationengine.hpp> 21 #include <ql/math/distributions/bivariatenormaldistribution.hpp> 22 #include <ql/exercise.hpp> 23 24 using std::log; 25 26 namespace QuantLib { 27 AnalyticTwoAssetCorrelationEngine(const ext::shared_ptr<GeneralizedBlackScholesProcess> & p1,const ext::shared_ptr<GeneralizedBlackScholesProcess> & p2,const Handle<Quote> & correlation)28 AnalyticTwoAssetCorrelationEngine::AnalyticTwoAssetCorrelationEngine( 29 const ext::shared_ptr<GeneralizedBlackScholesProcess>& p1, 30 const ext::shared_ptr<GeneralizedBlackScholesProcess>& p2, 31 const Handle<Quote>& correlation) 32 : p1_(p1), p2_(p2), correlation_(correlation) { 33 registerWith(p1_); 34 registerWith(p2_); 35 registerWith(correlation_); 36 } 37 calculate() const38 void AnalyticTwoAssetCorrelationEngine::calculate() const { 39 BivariateCumulativeNormalDistributionDr78 M(correlation_->value()); 40 41 const ext::shared_ptr<PlainVanillaPayoff> payoff = 42 ext::dynamic_pointer_cast<PlainVanillaPayoff>(arguments_.payoff); 43 QL_REQUIRE(payoff, "non-plain payoff given"); 44 QL_REQUIRE(payoff->strike()>0.0, "strike must be positive"); 45 ext::shared_ptr<Exercise> exercise = arguments_.exercise; 46 Real strike = payoff->strike();//X1 47 Real spot = p1_->x0(); 48 QL_REQUIRE(spot >= 0.0, "negative or null underlying given"); 49 50 Volatility sigma1 = 51 p1_->blackVolatility()->blackVol(p1_->time(exercise->lastDate()), 52 payoff->strike()); 53 Volatility sigma2 = 54 p2_->blackVolatility()->blackVol(p2_->time(exercise->lastDate()), 55 payoff->strike()); 56 57 Time T = p2_->time(arguments_.exercise->lastDate()); 58 59 Real s1=p1_->x0(); 60 Real s2=p2_->x0(); 61 Rate q1= p1_->dividendYield()->zeroRate(T, Continuous, NoFrequency); 62 Rate q2= p2_->dividendYield()->zeroRate(T, Continuous, NoFrequency); 63 Rate r=p1_->riskFreeRate()->zeroRate(T, Continuous, NoFrequency); 64 Rate b1=r-q1; 65 Rate b2=r-q2; 66 Real rho = correlation_->value(); 67 68 Real y1=(log(s1/strike)+(b1-(sigma1*sigma1)/2)*T)/(sigma1*std::sqrt(T)); 69 Real y2=(log(s2/arguments_.X2)+(b2-(sigma2*sigma2)/2)*T)/(sigma2*std::sqrt(T)); 70 71 switch (payoff->optionType()) { 72 case Option::Call: 73 results_.value=s2*std::exp((b2-r)*T)*M(y2+sigma2*std::sqrt(T),y1+rho*sigma2*std::sqrt(T))-arguments_.X2*std::exp(-r*T)*M(y2,y1); 74 break; 75 case Option::Put: 76 results_.value=arguments_.X2*std::exp(-r*T)*M(-y2,-y1)-s2*std::exp((b2-r)*T)*M(-y2-sigma2*std::sqrt(T),-y1-rho*sigma2*std::sqrt(T)); 77 break; 78 default: 79 QL_FAIL("unknown option type"); 80 } 81 } 82 83 } 84