| 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 }; |
| 65 | Price() : amount_(Null<Real>()) {} |
| 66 | Price(Real amount, Type type) : amount_(amount), type_(type) {} |
| 67 | Real amount() const { |
| 68 | QL_REQUIRE(amount_ != Null<Real>(), "no amount given" ); |
| 69 | return amount_; |
| 70 | } |
| 71 | 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 | 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 | 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 override; |
| 106 | //@} |
| 107 | //! \name Observable interface |
| 108 | //@{ |
| 109 | void deepUpdate() override; |
| 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 override; |
| 238 | void setupArguments(PricingEngine::arguments*) const override; |
| 239 | void fetchResults(const PricingEngine::results*) const override; |
| 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 override; |
| 301 | }; |
| 302 | |
| 303 | class Bond::results : public Instrument::results { |
| 304 | public: |
| 305 | Real settlementValue; |
| 306 | void reset() override { |
| 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 | |
| 318 | inline Natural Bond::settlementDays() const { |
| 319 | return settlementDays_; |
| 320 | } |
| 321 | |
| 322 | inline const Calendar& Bond::calendar() const { |
| 323 | return calendar_; |
| 324 | } |
| 325 | |
| 326 | inline const std::vector<Real>& Bond::notionals() const { |
| 327 | return notionals_; |
| 328 | } |
| 329 | |
| 330 | inline const Leg& Bond::cashflows() const { |
| 331 | return cashflows_; |
| 332 | } |
| 333 | |
| 334 | inline const Leg& Bond::redemptions() const { |
| 335 | return redemptions_; |
| 336 | } |
| 337 | |
| 338 | inline Date Bond::issueDate() const { |
| 339 | return issueDate_; |
| 340 | } |
| 341 | |
| 342 | } |
| 343 | |
| 344 | #endif |
| 345 | |