1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 2016 Stefano Fondi 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/averageois/arithmeticaverageois.hpp> 21 #include <ql/experimental/averageois/averageoiscouponpricer.hpp> 22 #include <ql/cashflows/overnightindexedcoupon.hpp> 23 #include <ql/cashflows/fixedratecoupon.hpp> 24 25 namespace QuantLib { 26 ArithmeticAverageOIS(Type type,Real nominal,const Schedule & fixedLegSchedule,Rate fixedRate,const DayCounter & fixedDC,const ext::shared_ptr<OvernightIndex> & overnightIndex,const Schedule & overnightLegSchedule,Spread spread,Real meanReversionSpeed,Real volatility,bool byApprox)27 ArithmeticAverageOIS::ArithmeticAverageOIS( 28 Type type, 29 Real nominal, 30 const Schedule& fixedLegSchedule, 31 Rate fixedRate, 32 const DayCounter& fixedDC, 33 const ext::shared_ptr<OvernightIndex>& overnightIndex, 34 const Schedule& overnightLegSchedule, 35 Spread spread, 36 Real meanReversionSpeed, 37 Real volatility, 38 bool byApprox) 39 : Swap(2), type_(type), 40 nominals_(std::vector<Real>(1, nominal)), 41 fixedLegPaymentFrequency_(fixedLegSchedule.tenor().frequency()), 42 overnightLegPaymentFrequency_(overnightLegSchedule.tenor().frequency()), 43 fixedRate_(fixedRate), fixedDC_(fixedDC), 44 overnightIndex_(overnightIndex), 45 spread_(spread), byApprox_(byApprox), mrs_(meanReversionSpeed), 46 vol_(volatility) { 47 48 initialize(fixedLegSchedule, overnightLegSchedule); 49 50 } 51 ArithmeticAverageOIS(Type type,const std::vector<Real> & nominals,const Schedule & fixedLegSchedule,Rate fixedRate,const DayCounter & fixedDC,const ext::shared_ptr<OvernightIndex> & overnightIndex,const Schedule & overnightLegSchedule,Spread spread,Real meanReversionSpeed,Real volatility,bool byApprox)52 ArithmeticAverageOIS::ArithmeticAverageOIS( 53 Type type, 54 const std::vector<Real>& nominals, 55 const Schedule& fixedLegSchedule, 56 Rate fixedRate, 57 const DayCounter& fixedDC, 58 const ext::shared_ptr<OvernightIndex>& overnightIndex, 59 const Schedule& overnightLegSchedule, 60 Spread spread, 61 Real meanReversionSpeed, 62 Real volatility, 63 bool byApprox) 64 : Swap(2), type_(type), nominals_(nominals), 65 fixedLegPaymentFrequency_(fixedLegSchedule.tenor().frequency()), 66 overnightLegPaymentFrequency_(overnightLegSchedule.tenor().frequency()), 67 fixedRate_(fixedRate), fixedDC_(fixedDC), overnightIndex_(overnightIndex), spread_(spread), 68 byApprox_(byApprox), mrs_(meanReversionSpeed), vol_(volatility) { 69 70 initialize(fixedLegSchedule, overnightLegSchedule); 71 72 } 73 initialize(const Schedule & fixedLegSchedule,const Schedule & overnightLegSchedule)74 void ArithmeticAverageOIS::initialize(const Schedule& fixedLegSchedule, 75 const Schedule& overnightLegSchedule) { 76 if (fixedDC_==DayCounter()) 77 fixedDC_ = overnightIndex_->dayCounter(); 78 legs_[0] = FixedRateLeg(fixedLegSchedule) 79 .withNotionals(nominals_) 80 .withCouponRates(fixedRate_, fixedDC_); 81 82 legs_[1] = OvernightLeg(overnightLegSchedule, overnightIndex_) 83 .withNotionals(nominals_) 84 .withSpreads(spread_); 85 86 ext::shared_ptr<FloatingRateCouponPricer> arithmeticPricer( 87 new ArithmeticAveragedOvernightIndexedCouponPricer(mrs_, vol_, byApprox_)); 88 89 for (Size i = 0; i < legs_[1].size(); i++) { 90 ext::shared_ptr<OvernightIndexedCoupon> 91 c = ext::dynamic_pointer_cast<OvernightIndexedCoupon> (legs_[1][i]); 92 c->setPricer(arithmeticPricer); 93 } 94 95 for (Size j=0; j<2; ++j) { 96 for (Leg::iterator i = legs_[j].begin(); i!= legs_[j].end(); ++i) 97 registerWith(*i); 98 } 99 100 switch (type_) { 101 case Payer: 102 payer_[0] = -1.0; 103 payer_[1] = +1.0; 104 break; 105 case Receiver: 106 payer_[0] = +1.0; 107 payer_[1] = -1.0; 108 break; 109 default: 110 QL_FAIL("Unknown overnight-swap type"); 111 } 112 } 113 fairRate() const114 Real ArithmeticAverageOIS::fairRate() const { 115 static Spread basisPoint = 1.0e-4; 116 calculate(); 117 return fixedRate_ - NPV_/(fixedLegBPS()/basisPoint); 118 } 119 fairSpread() const120 Spread ArithmeticAverageOIS::fairSpread() const { 121 static Spread basisPoint = 1.0e-4; 122 calculate(); 123 return spread_ - NPV_/(overnightLegBPS()/basisPoint); 124 } 125 fixedLegBPS() const126 Real ArithmeticAverageOIS::fixedLegBPS() const { 127 calculate(); 128 QL_REQUIRE(legBPS_[0] != Null<Real>(), "result not available"); 129 return legBPS_[0]; 130 } 131 overnightLegBPS() const132 Real ArithmeticAverageOIS::overnightLegBPS() const { 133 calculate(); 134 QL_REQUIRE(legBPS_[1] != Null<Real>(), "result not available"); 135 return legBPS_[1]; 136 } 137 fixedLegNPV() const138 Real ArithmeticAverageOIS::fixedLegNPV() const { 139 calculate(); 140 QL_REQUIRE(legNPV_[0] != Null<Real>(), "result not available"); 141 return legNPV_[0]; 142 } 143 overnightLegNPV() const144 Real ArithmeticAverageOIS::overnightLegNPV() const { 145 calculate(); 146 QL_REQUIRE(legNPV_[1] != Null<Real>(), "result not available"); 147 return legNPV_[1]; 148 } 149 150 } 151