1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 2004 Jeff Yu 5 Copyright (C) 2004 M-Dimension Consulting Inc. 6 Copyright (C) 2005, 2006, 2007, 2008 StatPro Italia srl 7 Copyright (C) 2007, 2008, 2009 Ferdinando Ametrano 8 Copyright (C) 2007 Chiara Fornarola 9 Copyright (C) 2008 Simon Ibbotson 10 11 This file is part of QuantLib, a free-software/open-source library 12 for financial quantitative analysts and developers - http://quantlib.org/ 13 14 QuantLib is free software: you can redistribute it and/or modify it 15 under the terms of the QuantLib license. You should have received a 16 copy of the license along with this program; if not, please email 17 <quantlib-dev@lists.sf.net>. The license is also available online at 18 <http://quantlib.org/license.shtml>. 19 20 This program is distributed in the hope that it will be useful, but WITHOUT 21 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 22 FOR A PARTICULAR PURPOSE. See the license for more details. 23 */ 24 25 /*! \file bond.hpp 26 \brief concrete bond class 27 */ 28 29 #ifndef quantlib_bond_hpp 30 #define quantlib_bond_hpp 31 32 #include <ql/instrument.hpp> 33 34 #include <ql/time/calendar.hpp> 35 #include <ql/cashflow.hpp> 36 #include <ql/compounding.hpp> 37 38 #include <vector> 39 40 namespace QuantLib { 41 42 class DayCounter; 43 44 //! Base bond class 45 /*! Derived classes must fill the uninitialized data members. 46 47 \warning Most methods assume that the cash flows are stored 48 sorted by date, the redemption(s) being after any 49 cash flow at the same date. In particular, if there's 50 one single redemption, it must be the last cash flow, 51 52 \ingroup instruments 53 54 \test 55 - price/yield calculations are cross-checked for consistency. 56 - price/yield calculations are checked against known good 57 values. 58 */ 59 class Bond : public Instrument { 60 public: 61 //! Bond price information 62 class Price { 63 public: 64 enum Type { Dirty, Clean }; Price()65 Price() : amount_(Null<Real>()) {} Price(Real amount,Type type)66 Price(Real amount, Type type) : amount_(amount), type_(type) {} amount() const67 Real amount() const { 68 QL_REQUIRE(amount_ != Null<Real>(), "no amount given"); 69 return amount_; 70 } type() const71 Type type() const { return type_; } 72 private: 73 Real amount_; 74 Type type_; 75 }; 76 77 //! constructor for amortizing or non-amortizing bonds. 78 /*! Redemptions and maturity are calculated from the coupon 79 data, if available. Therefore, redemptions must not be 80 included in the passed cash flows. 81 */ 82 Bond(Natural settlementDays, 83 const Calendar& calendar, 84 const Date& issueDate = Date(), 85 const Leg& coupons = Leg()); 86 87 //! old constructor for non amortizing bonds. 88 /*! \warning The last passed cash flow must be the bond 89 redemption. No other cash flow can have a date 90 later than the redemption date. 91 */ 92 Bond(Natural settlementDays, 93 const Calendar& calendar, 94 Real faceAmount, 95 const Date& maturityDate, 96 const Date& issueDate = Date(), 97 const Leg& cashflows = Leg()); 98 99 class arguments; 100 class results; 101 class engine; 102 103 //! \name Instrument interface 104 //@{ 105 bool isExpired() const; 106 //@} 107 //! \name Observable interface 108 //@{ 109 void deepUpdate(); 110 //@} 111 //! \name Inspectors 112 //@{ 113 Natural settlementDays() const; 114 const Calendar& calendar() const; 115 116 const std::vector<Real>& notionals() const; 117 virtual Real notional(Date d = Date()) const; 118 119 /*! \note returns all the cashflows, including the redemptions. */ 120 const Leg& cashflows() const; 121 /*! returns just the redemption flows (not interest payments) */ 122 const Leg& redemptions() const; 123 /*! returns the redemption, if only one is defined */ 124 const ext::shared_ptr<CashFlow>& redemption() const; 125 126 Date startDate() const; 127 Date maturityDate() const; 128 Date issueDate() const; 129 130 bool isTradable(Date d = Date()) const; 131 Date settlementDate(Date d = Date()) const; 132 //@} 133 134 //! \name Calculations 135 //@{ 136 137 //! theoretical clean price 138 /*! The default bond settlement is used for calculation. 139 140 \warning the theoretical price calculated from a flat term 141 structure might differ slightly from the price 142 calculated from the corresponding yield by means 143 of the other overload of this function. If the 144 price from a constant yield is desired, it is 145 advisable to use such other overload. 146 */ 147 Real cleanPrice() const; 148 149 //! theoretical dirty price 150 /*! The default bond settlement is used for calculation. 151 152 \warning the theoretical price calculated from a flat term 153 structure might differ slightly from the price 154 calculated from the corresponding yield by means 155 of the other overload of this function. If the 156 price from a constant yield is desired, it is 157 advisable to use such other overload. 158 */ 159 Real dirtyPrice() const; 160 161 //! theoretical settlement value 162 /*! The default bond settlement date is used for calculation. */ 163 Real settlementValue() const; 164 165 //! theoretical bond yield 166 /*! The default bond settlement and theoretical price are used 167 for calculation. 168 */ 169 Rate yield(const DayCounter& dc, 170 Compounding comp, 171 Frequency freq, 172 Real accuracy = 1.0e-8, 173 Size maxEvaluations = 100, 174 Real guess = 0.05, 175 Bond::Price::Type priceType = Bond::Price::Clean) const; 176 177 //! clean price given a yield and settlement date 178 /*! The default bond settlement is used if no date is given. */ 179 Real cleanPrice(Rate yield, 180 const DayCounter& dc, 181 Compounding comp, 182 Frequency freq, 183 Date settlementDate = Date()) const; 184 185 //! dirty price given a yield and settlement date 186 /*! The default bond settlement is used if no date is given. */ 187 Real dirtyPrice(Rate yield, 188 const DayCounter& dc, 189 Compounding comp, 190 Frequency freq, 191 Date settlementDate = Date()) const; 192 193 //! settlement value as a function of the clean price 194 /*! The default bond settlement date is used for calculation. */ 195 Real settlementValue(Real cleanPrice) const; 196 197 //! yield given a (clean) price and settlement date 198 /*! The default bond settlement is used if no date is given. */ 199 Rate yield(Real cleanPrice, 200 const DayCounter& dc, 201 Compounding comp, 202 Frequency freq, 203 Date settlementDate = Date(), 204 Real accuracy = 1.0e-8, 205 Size maxEvaluations = 100, 206 Real guess = 0.05, 207 Bond::Price::Type priceType = Bond::Price::Clean) const; 208 209 //! accrued amount at a given date 210 /*! The default bond settlement is used if no date is given. */ 211 virtual Real accruedAmount(Date d = Date()) const; 212 //@} 213 214 /*! Expected next coupon: depending on (the bond and) the given date 215 the coupon can be historic, deterministic or expected in a 216 stochastic sense. When the bond settlement date is used the coupon 217 is the already-fixed not-yet-paid one. 218 219 The current bond settlement is used if no date is given. 220 */ 221 virtual Rate nextCouponRate(Date d = Date()) const; 222 223 //! Previous coupon already paid at a given date 224 /*! Expected previous coupon: depending on (the bond and) the given 225 date the coupon can be historic, deterministic or expected in a 226 stochastic sense. When the bond settlement date is used the coupon 227 is the last paid one. 228 229 The current bond settlement is used if no date is given. 230 */ 231 Rate previousCouponRate(Date d = Date()) const; 232 233 Date nextCashFlowDate(Date d = Date()) const; 234 Date previousCashFlowDate(Date d = Date()) const; 235 236 protected: 237 void setupExpired() const; 238 void setupArguments(PricingEngine::arguments*) const; 239 void fetchResults(const PricingEngine::results*) const; 240 241 /*! This method can be called by derived classes in order to 242 build redemption payments from the existing cash flows. 243 It must be called after setting up the cashflows_ vector 244 and will fill the notionalSchedule_, notionals_, and 245 redemptions_ data members. 246 247 If given, the elements of the redemptions vector will 248 multiply the amount of the redemption cash flow. The 249 elements will be taken in base 100, i.e., a redemption 250 equal to 100 does not modify the amount. 251 252 \pre The cashflows_ vector must contain at least one 253 coupon and must be sorted by date. 254 */ 255 void addRedemptionsToCashflows(const std::vector<Real>& redemptions 256 = std::vector<Real>()); 257 258 /*! This method can be called by derived classes in order to 259 build a bond with a single redemption payment. It will 260 fill the notionalSchedule_, notionals_, and redemptions_ 261 data members. 262 */ 263 void setSingleRedemption(Real notional, 264 Real redemption, 265 const Date& date); 266 267 /*! This method can be called by derived classes in order to 268 build a bond with a single redemption payment. It will 269 fill the notionalSchedule_, notionals_, and redemptions_ 270 data members. 271 */ 272 void setSingleRedemption(Real notional, 273 const ext::shared_ptr<CashFlow>& redemption); 274 275 /*! used internally to collect notional information from the 276 coupons. It should not be called by derived classes, 277 unless they already provide redemption cash flows (in 278 which case they must set up the redemptions_ data member 279 independently). It will fill the notionalSchedule_ and 280 notionals_ data members. 281 */ 282 void calculateNotionalsFromCashflows(); 283 284 Natural settlementDays_; 285 Calendar calendar_; 286 std::vector<Date> notionalSchedule_; 287 std::vector<Real> notionals_; 288 Leg cashflows_; // all cashflows 289 Leg redemptions_; // the redemptions 290 291 Date maturityDate_, issueDate_; 292 mutable Real settlementValue_; 293 }; 294 295 class Bond::arguments : public PricingEngine::arguments { 296 public: 297 Date settlementDate; 298 Leg cashflows; 299 Calendar calendar; 300 void validate() const; 301 }; 302 303 class Bond::results : public Instrument::results { 304 public: 305 Real settlementValue; reset()306 void reset() { 307 settlementValue = Null<Real>(); 308 Instrument::results::reset(); 309 } 310 }; 311 312 class Bond::engine : public GenericEngine<Bond::arguments, 313 Bond::results> {}; 314 315 316 // inline definitions 317 settlementDays() const318 inline Natural Bond::settlementDays() const { 319 return settlementDays_; 320 } 321 calendar() const322 inline const Calendar& Bond::calendar() const { 323 return calendar_; 324 } 325 notionals() const326 inline const std::vector<Real>& Bond::notionals() const { 327 return notionals_; 328 } 329 cashflows() const330 inline const Leg& Bond::cashflows() const { 331 return cashflows_; 332 } 333 redemptions() const334 inline const Leg& Bond::redemptions() const { 335 return redemptions_; 336 } 337 issueDate() const338 inline Date Bond::issueDate() const { 339 return issueDate_; 340 } 341 342 } 343 344 #endif 345