1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 2007, 2008, 2009, 2010 Ferdinando Ametrano 5 Copyright (C) 2007 Chiara Fornarola 6 Copyright (C) 2009 StatPro Italia srl 7 Copyright (C) 2009 Nathan Abbott 8 9 This file is part of QuantLib, a free-software/open-source library 10 for financial quantitative analysts and developers - http://quantlib.org/ 11 12 QuantLib is free software: you can redistribute it and/or modify it 13 under the terms of the QuantLib license. You should have received a 14 copy of the license along with this program; if not, please email 15 <quantlib-dev@lists.sf.net>. The license is also available online at 16 <http://quantlib.org/license.shtml>. 17 18 This program is distributed in the hope that it will be useful, but WITHOUT 19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 20 FOR A PARTICULAR PURPOSE. See the license for more details. 21 */ 22 23 /*! \file bondfunctions.hpp 24 \brief bond functions 25 */ 26 27 #ifndef quantlib_bond_functions_hpp 28 #define quantlib_bond_functions_hpp 29 30 #include <ql/cashflows/cashflows.hpp> 31 #include <ql/cashflows/duration.hpp> 32 #include <ql/cashflow.hpp> 33 #include <ql/interestrate.hpp> 34 #include <ql/instruments/bond.hpp> 35 #include <ql/shared_ptr.hpp> 36 37 namespace QuantLib { 38 39 // forward declarations 40 class Bond; 41 class DayCounter; 42 class YieldTermStructure; 43 44 //! Bond adapters of CashFlows functions 45 /*! See CashFlows for functions' documentation. 46 47 These adapters calls into CashFlows functions passing as input the 48 Bond cashflows, the dirty price (i.e. npv) calculated from clean 49 price, the bond settlement date (unless another date is given), zero 50 ex-dividend days, and excluding any cashflow on the settlement date. 51 52 Prices are always clean, as per market convention. 53 */ 54 struct BondFunctions { 55 //! \name Date inspectors 56 //@{ 57 static Date startDate(const Bond& bond); 58 static Date maturityDate(const Bond& bond); 59 static bool isTradable(const Bond& bond, 60 Date settlementDate = Date()); 61 //@} 62 63 //! \name CashFlow inspectors 64 //@{ 65 static Leg::const_reverse_iterator 66 previousCashFlow(const Bond& bond, 67 Date refDate = Date()); 68 static Leg::const_iterator nextCashFlow(const Bond& bond, 69 Date refDate = Date()); 70 static Date previousCashFlowDate(const Bond& bond, 71 Date refDate = Date()); 72 static Date nextCashFlowDate(const Bond& bond, 73 Date refDate = Date()); 74 static Real previousCashFlowAmount(const Bond& bond, 75 Date refDate = Date()); 76 static Real nextCashFlowAmount(const Bond& bond, 77 Date refDate = Date()); 78 //@} 79 80 //! \name Coupon inspectors 81 //@{ 82 static Rate previousCouponRate(const Bond& bond, 83 Date settlementDate = Date()); 84 static Rate nextCouponRate(const Bond& bond, 85 Date settlementDate = Date()); 86 static Date accrualStartDate(const Bond& bond, 87 Date settlementDate = Date()); 88 static Date accrualEndDate(const Bond& bond, 89 Date settlementDate = Date()); 90 static Date referencePeriodStart(const Bond& bond, 91 Date settlementDate = Date()); 92 static Date referencePeriodEnd(const Bond& bond, 93 Date settlementDate = Date()); 94 static Time accrualPeriod(const Bond& bond, 95 Date settlementDate = Date()); 96 static Date::serial_type accrualDays(const Bond& bond, 97 Date settlementDate = Date()); 98 static Time accruedPeriod(const Bond& bond, 99 Date settlementDate = Date()); 100 static Date::serial_type accruedDays(const Bond& bond, 101 Date settlementDate = Date()); 102 static Real accruedAmount(const Bond& bond, 103 Date settlementDate = Date()); 104 //@} 105 106 //! \name YieldTermStructure functions 107 //@{ 108 static Real cleanPrice(const Bond& bond, 109 const YieldTermStructure& discountCurve, 110 Date settlementDate = Date()); 111 static Real bps(const Bond& bond, 112 const YieldTermStructure& discountCurve, 113 Date settlementDate = Date()); 114 static Rate atmRate(const Bond& bond, 115 const YieldTermStructure& discountCurve, 116 Date settlementDate = Date(), 117 Real cleanPrice = Null<Real>()); 118 //@} 119 120 //! \name Yield (a.k.a. Internal Rate of Return, i.e. IRR) functions 121 //@{ 122 static Real cleanPrice(const Bond& bond, 123 const InterestRate& yield, 124 Date settlementDate = Date()); 125 static Real cleanPrice(const Bond& bond, 126 Rate yield, 127 const DayCounter& dayCounter, 128 Compounding compounding, 129 Frequency frequency, 130 Date settlementDate = Date()); 131 static Real dirtyPrice(const Bond& bond, 132 const InterestRate& yield, 133 Date settlementDate = Date()); 134 static Real dirtyPrice(const Bond& bond, 135 Rate yield, 136 const DayCounter& dayCounter, 137 Compounding compounding, 138 Frequency frequency, 139 Date settlementDate = Date()); 140 static Real bps(const Bond& bond, 141 const InterestRate& yield, 142 Date settlementDate = Date()); 143 static Real bps(const Bond& bond, 144 Rate yield, 145 const DayCounter& dayCounter, 146 Compounding compounding, 147 Frequency frequency, 148 Date settlementDate = Date()); 149 static Rate yield(const Bond& bond, 150 Real price, 151 const DayCounter& dayCounter, 152 Compounding compounding, 153 Frequency frequency, 154 Date settlementDate = Date(), 155 Real accuracy = 1.0e-10, 156 Size maxIterations = 100, 157 Rate guess = 0.05, 158 Bond::Price::Type priceType = Bond::Price::Clean); 159 template <typename Solver> yieldQuantLib::BondFunctions160 static Rate yield(const Solver& solver, 161 const Bond& bond, 162 Real price, 163 const DayCounter& dayCounter, 164 Compounding compounding, 165 Frequency frequency, 166 Date settlementDate = Date(), 167 Real accuracy = 1.0e-10, 168 Rate guess = 0.05, 169 Bond::Price::Type priceType = Bond::Price::Clean) { 170 if (settlementDate == Date()) 171 settlementDate = bond.settlementDate(); 172 173 QL_REQUIRE(BondFunctions::isTradable(bond, settlementDate), 174 "non tradable at " << settlementDate << 175 " (maturity being " << bond.maturityDate() << ")"); 176 177 Real dirtyPrice = price; 178 179 if (priceType == Bond::Price::Clean) 180 dirtyPrice += bond.accruedAmount(settlementDate); 181 182 dirtyPrice /= 100.0 / bond.notional(settlementDate); 183 184 return CashFlows::yield<Solver>(solver, bond.cashflows(), 185 dirtyPrice, dayCounter, compounding, 186 frequency, false, settlementDate, 187 settlementDate, accuracy, guess); 188 } 189 static Time duration(const Bond& bond, 190 const InterestRate& yield, 191 Duration::Type type = Duration::Modified, 192 Date settlementDate = Date() ); 193 static Time duration(const Bond& bond, 194 Rate yield, 195 const DayCounter& dayCounter, 196 Compounding compounding, 197 Frequency frequency, 198 Duration::Type type = Duration::Modified, 199 Date settlementDate = Date() ); 200 static Real convexity(const Bond& bond, 201 const InterestRate& yield, 202 Date settlementDate = Date()); 203 static Real convexity(const Bond& bond, 204 Rate yield, 205 const DayCounter& dayCounter, 206 Compounding compounding, 207 Frequency frequency, 208 Date settlementDate = Date()); 209 static Real basisPointValue(const Bond& bond, 210 const InterestRate& yield, 211 Date settlementDate = Date()); 212 static Real basisPointValue(const Bond& bond, 213 Rate yield, 214 const DayCounter& dayCounter, 215 Compounding compounding, 216 Frequency frequency, 217 Date settlementDate = Date()); 218 static Real yieldValueBasisPoint(const Bond& bond, 219 const InterestRate& yield, 220 Date settlementDate = Date()); 221 static Real yieldValueBasisPoint(const Bond& bond, 222 Rate yield, 223 const DayCounter& dayCounter, 224 Compounding compounding, 225 Frequency frequency, 226 Date settlementDate = Date()); 227 //@} 228 229 //! \name Z-spread functions 230 //@{ 231 static Real cleanPrice(const Bond& bond, 232 const ext::shared_ptr<YieldTermStructure>& discount, 233 Spread zSpread, 234 const DayCounter& dayCounter, 235 Compounding compounding, 236 Frequency frequency, 237 Date settlementDate = Date()); 238 static Spread zSpread(const Bond& bond, 239 Real cleanPrice, 240 const ext::shared_ptr<YieldTermStructure>&, 241 const DayCounter& dayCounter, 242 Compounding compounding, 243 Frequency frequency, 244 Date settlementDate = Date(), 245 Real accuracy = 1.0e-10, 246 Size maxIterations = 100, 247 Rate guess = 0.0); 248 //@} 249 250 }; 251 252 } 253 254 #endif 255