1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 2008, 2009 Ferdinando Ametrano 5 Copyright (C) 2005 Toyin Akin 6 Copyright (C) 2007 StatPro Italia srl 7 8 This file is part of QuantLib, a free-software/open-source library 9 for financial quantitative analysts and developers - http://quantlib.org/ 10 11 QuantLib is free software: you can redistribute it and/or modify it 12 under the terms of the QuantLib license. You should have received a 13 copy of the license along with this program; if not, please email 14 <quantlib-dev@lists.sf.net>. The license is also available online at 15 <http://quantlib.org/license.shtml>. 16 17 This program is distributed in the hope that it will be useful, but WITHOUT 18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 19 FOR A PARTICULAR PURPOSE. See the license for more details. 20 */ 21 22 #include <ql/termstructures/yield/bondhelpers.hpp> 23 #include <ql/pricingengines/bond/discountingbondengine.hpp> 24 #include <ql/time/schedule.hpp> 25 #include <ql/settings.hpp> 26 #include <ql/utilities/null_deleter.hpp> 27 28 namespace QuantLib { 29 BondHelper(const Handle<Quote> & price,const ext::shared_ptr<Bond> & bond,const Bond::Price::Type priceType)30 BondHelper::BondHelper(const Handle<Quote>& price, 31 const ext::shared_ptr<Bond>& bond, 32 const Bond::Price::Type priceType) 33 : RateHelper(price), bond_(ext::make_shared<Bond>(*bond)), priceType_(priceType) { 34 35 // the bond's last cashflow date, which can be later than 36 // bond's maturity date because of adjustment 37 latestDate_ = bond_->cashflows().back()->date(); 38 earliestDate_ = bond_->nextCashFlowDate(); 39 40 bond_->setPricingEngine( 41 ext::make_shared<DiscountingBondEngine>(termStructureHandle_)); 42 } 43 BondHelper(const Handle<Quote> & price,const ext::shared_ptr<Bond> & bond,const bool useCleanPrice)44 BondHelper::BondHelper(const Handle<Quote>& price, 45 const ext::shared_ptr<Bond>& bond, 46 const bool useCleanPrice) 47 : RateHelper(price), bond_(ext::make_shared<Bond>(*bond)) { 48 49 // the bond's last cashflow date, which can be later than 50 // bond's maturity date because of adjustment 51 latestDate_ = bond_->cashflows().back()->date(); 52 earliestDate_ = bond_->nextCashFlowDate(); 53 54 bond_->setPricingEngine( 55 ext::make_shared<DiscountingBondEngine>(termStructureHandle_)); 56 57 priceType_ = useCleanPrice ? Bond::Price::Clean : Bond::Price::Dirty; 58 } 59 setTermStructure(YieldTermStructure * t)60 void BondHelper::setTermStructure(YieldTermStructure* t) { 61 // do not set the relinkable handle as an observer - 62 // force recalculation when needed 63 termStructureHandle_.linkTo( 64 ext::shared_ptr<YieldTermStructure>(t, null_deleter()), false); 65 66 BootstrapHelper<YieldTermStructure>::setTermStructure(t); 67 } 68 impliedQuote() const69 Real BondHelper::impliedQuote() const { 70 QL_REQUIRE(termStructure_ != 0, "term structure not set"); 71 // we didn't register as observers - force calculation 72 bond_->recalculate(); 73 74 switch (priceType_) { 75 case Bond::Price::Clean: 76 return bond_->cleanPrice(); 77 break; 78 79 case Bond::Price::Dirty: 80 return bond_->dirtyPrice(); 81 break; 82 83 default: 84 QL_FAIL("This price type isn't implemented."); 85 } 86 } 87 accept(AcyclicVisitor & v)88 void BondHelper::accept(AcyclicVisitor& v) { 89 Visitor<BondHelper>* v1 = 90 dynamic_cast<Visitor<BondHelper>*>(&v); 91 if (v1 != 0) 92 v1->visit(*this); 93 else 94 BootstrapHelper<YieldTermStructure>::accept(v); 95 } 96 FixedRateBondHelper(const Handle<Quote> & price,Natural settlementDays,Real faceAmount,const Schedule & schedule,const std::vector<Rate> & coupons,const DayCounter & dayCounter,BusinessDayConvention paymentConvention,Real redemption,const Date & issueDate,const Calendar & paymentCalendar,const Period & exCouponPeriod,const Calendar & exCouponCalendar,const BusinessDayConvention exCouponConvention,bool exCouponEndOfMonth,const Bond::Price::Type priceType)97 FixedRateBondHelper::FixedRateBondHelper( 98 const Handle<Quote>& price, 99 Natural settlementDays, 100 Real faceAmount, 101 const Schedule& schedule, 102 const std::vector<Rate>& coupons, 103 const DayCounter& dayCounter, 104 BusinessDayConvention paymentConvention, 105 Real redemption, 106 const Date& issueDate, 107 const Calendar& paymentCalendar, 108 const Period& exCouponPeriod, 109 const Calendar& exCouponCalendar, 110 const BusinessDayConvention exCouponConvention, 111 bool exCouponEndOfMonth, 112 const Bond::Price::Type priceType) 113 : BondHelper(price, 114 ext::shared_ptr<Bond>( 115 new FixedRateBond(settlementDays, faceAmount, schedule, 116 coupons, dayCounter, paymentConvention, 117 redemption, issueDate, paymentCalendar, 118 exCouponPeriod, exCouponCalendar, 119 exCouponConvention, exCouponEndOfMonth)), 120 priceType) { 121 fixedRateBond_ = ext::dynamic_pointer_cast<FixedRateBond>(bond_); 122 } 123 FixedRateBondHelper(const Handle<Quote> & price,Natural settlementDays,Real faceAmount,const Schedule & schedule,const std::vector<Rate> & coupons,const DayCounter & dayCounter,BusinessDayConvention paymentConvention,Real redemption,const Date & issueDate,const Calendar & paymentCalendar,const Period & exCouponPeriod,const Calendar & exCouponCalendar,const BusinessDayConvention exCouponConvention,bool exCouponEndOfMonth,const bool useCleanPrice)124 FixedRateBondHelper::FixedRateBondHelper( 125 const Handle<Quote>& price, 126 Natural settlementDays, 127 Real faceAmount, 128 const Schedule& schedule, 129 const std::vector<Rate>& coupons, 130 const DayCounter& dayCounter, 131 BusinessDayConvention paymentConvention, 132 Real redemption, 133 const Date& issueDate, 134 const Calendar& paymentCalendar, 135 const Period& exCouponPeriod, 136 const Calendar& exCouponCalendar, 137 const BusinessDayConvention exCouponConvention, 138 bool exCouponEndOfMonth, 139 const bool useCleanPrice) 140 : BondHelper(price, 141 ext::shared_ptr<Bond>( 142 new FixedRateBond(settlementDays, faceAmount, schedule, 143 coupons, dayCounter, paymentConvention, 144 redemption, issueDate, paymentCalendar, 145 exCouponPeriod, exCouponCalendar, 146 exCouponConvention, exCouponEndOfMonth)), 147 useCleanPrice ? Bond::Price::Clean : Bond::Price::Dirty) { 148 fixedRateBond_ = ext::dynamic_pointer_cast<FixedRateBond>(bond_); 149 } 150 accept(AcyclicVisitor & v)151 void FixedRateBondHelper::accept(AcyclicVisitor& v) { 152 Visitor<FixedRateBondHelper>* v1 = 153 dynamic_cast<Visitor<FixedRateBondHelper>*>(&v); 154 if (v1 != 0) 155 v1->visit(*this); 156 else 157 BondHelper::accept(v); 158 } 159 CPIBondHelper(const Handle<Quote> & price,Natural settlementDays,Real faceAmount,const bool growthOnly,Real baseCPI,const Period & observationLag,const ext::shared_ptr<ZeroInflationIndex> & cpiIndex,CPI::InterpolationType observationInterpolation,const Schedule & schedule,const std::vector<Rate> & fixedRate,const DayCounter & accrualDayCounter,BusinessDayConvention paymentConvention,const Date & issueDate,const Calendar & paymentCalendar,const Period & exCouponPeriod,const Calendar & exCouponCalendar,const BusinessDayConvention exCouponConvention,bool exCouponEndOfMonth,const Bond::Price::Type priceType)160 CPIBondHelper::CPIBondHelper( 161 const Handle<Quote>& price, 162 Natural settlementDays, 163 Real faceAmount, 164 const bool growthOnly, 165 Real baseCPI, 166 const Period& observationLag, 167 const ext::shared_ptr<ZeroInflationIndex>& cpiIndex, 168 CPI::InterpolationType observationInterpolation, 169 const Schedule& schedule, 170 const std::vector<Rate>& fixedRate, 171 const DayCounter& accrualDayCounter, 172 BusinessDayConvention paymentConvention, 173 const Date& issueDate, 174 const Calendar& paymentCalendar, 175 const Period& exCouponPeriod, 176 const Calendar& exCouponCalendar, 177 const BusinessDayConvention exCouponConvention, 178 bool exCouponEndOfMonth, 179 const Bond::Price::Type priceType) 180 : BondHelper(price, 181 ext::shared_ptr<Bond>( 182 new CPIBond(settlementDays, faceAmount, growthOnly, baseCPI, 183 observationLag, cpiIndex, observationInterpolation, 184 schedule, fixedRate, accrualDayCounter, paymentConvention, 185 issueDate, paymentCalendar, exCouponPeriod, exCouponCalendar, 186 exCouponConvention, exCouponEndOfMonth)), 187 priceType) { 188 cpiBond_ = ext::dynamic_pointer_cast<CPIBond>(bond_); 189 } 190 CPIBondHelper(const Handle<Quote> & price,Natural settlementDays,Real faceAmount,const bool growthOnly,Real baseCPI,const Period & observationLag,const ext::shared_ptr<ZeroInflationIndex> & cpiIndex,CPI::InterpolationType observationInterpolation,const Schedule & schedule,const std::vector<Rate> & fixedRate,const DayCounter & accrualDayCounter,BusinessDayConvention paymentConvention,const Date & issueDate,const Calendar & paymentCalendar,const Period & exCouponPeriod,const Calendar & exCouponCalendar,const BusinessDayConvention exCouponConvention,bool exCouponEndOfMonth,const bool useCleanPrice)191 CPIBondHelper::CPIBondHelper( 192 const Handle<Quote>& price, 193 Natural settlementDays, 194 Real faceAmount, 195 const bool growthOnly, 196 Real baseCPI, 197 const Period& observationLag, 198 const ext::shared_ptr<ZeroInflationIndex>& cpiIndex, 199 CPI::InterpolationType observationInterpolation, 200 const Schedule& schedule, 201 const std::vector<Rate>& fixedRate, 202 const DayCounter& accrualDayCounter, 203 BusinessDayConvention paymentConvention, 204 const Date& issueDate, 205 const Calendar& paymentCalendar, 206 const Period& exCouponPeriod, 207 const Calendar& exCouponCalendar, 208 const BusinessDayConvention exCouponConvention, 209 bool exCouponEndOfMonth, 210 const bool useCleanPrice) 211 : BondHelper(price, 212 ext::shared_ptr<Bond>( 213 new CPIBond(settlementDays, faceAmount, growthOnly, baseCPI, 214 observationLag, cpiIndex, observationInterpolation, 215 schedule, fixedRate, accrualDayCounter, paymentConvention, 216 issueDate, paymentCalendar, exCouponPeriod, exCouponCalendar, 217 exCouponConvention, exCouponEndOfMonth)), 218 useCleanPrice ? Bond::Price::Clean : Bond::Price::Dirty) { 219 cpiBond_ = ext::dynamic_pointer_cast<CPIBond>(bond_); 220 } 221 accept(AcyclicVisitor & v)222 void CPIBondHelper::accept(AcyclicVisitor& v) { 223 Visitor<CPIBondHelper>* v1 = 224 dynamic_cast<Visitor<CPIBondHelper>*>(&v); 225 if (v1 != 0) 226 v1->visit(*this); 227 else 228 BondHelper::accept(v); 229 } 230 231 } 232