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