QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
amortizingfixedratebond.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2008 Simon Ibbotson
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
20#include <ql/instruments/bonds/amortizingfixedratebond.hpp>
21#include <ql/cashflows/cashflowvectors.hpp>
22#include <ql/cashflows/simplecashflow.hpp>
23#include <ql/time/schedule.hpp>
24
25namespace QuantLib {
26
28 Natural settlementDays,
29 const std::vector<Real>& notionals,
30 const Schedule& schedule,
31 const std::vector<Rate>& coupons,
32 const DayCounter& accrualDayCounter,
33 BusinessDayConvention paymentConvention,
34 const Date& issueDate,
35 const Period& exCouponPeriod,
36 const Calendar& exCouponCalendar,
37 const BusinessDayConvention exCouponConvention,
38 bool exCouponEndOfMonth,
39 const std::vector<Real>& redemptions,
40 Natural paymentLag)
41 : Bond(settlementDays, schedule.calendar(), issueDate),
42 frequency_(schedule.tenor().frequency()),
43 dayCounter_(accrualDayCounter) {
44
45 maturityDate_ = schedule.endDate();
46
47 cashflows_ = FixedRateLeg(schedule)
49 .withCouponRates(coupons, accrualDayCounter)
50 .withPaymentAdjustment(paymentConvention)
51 .withExCouponPeriod(exCouponPeriod,
52 exCouponCalendar,
53 exCouponConvention,
54 exCouponEndOfMonth)
55 .withPaymentLag(paymentLag);
56
58
59 QL_ENSURE(!cashflows().empty(), "bond with no cashflows!");
60 }
61
62
63 Schedule sinkingSchedule(const Date& startDate,
64 const Period& bondLength,
65 const Frequency& frequency,
66 const Calendar& paymentCalendar) {
67 Date maturityDate = startDate + bondLength;
68 Schedule retVal(startDate, maturityDate, Period(frequency),
69 paymentCalendar, Unadjusted, Unadjusted,
71 return retVal;
72 }
73
74 namespace {
75
76 std::pair<Integer,Integer> daysMinMax(const Period& p) {
77 switch (p.units()) {
78 case Days:
79 return std::make_pair(p.length(), p.length());
80 case Weeks:
81 return std::make_pair(7*p.length(), 7*p.length());
82 case Months:
83 return std::make_pair(28*p.length(), 31*p.length());
84 case Years:
85 return std::make_pair(365*p.length(), 366*p.length());
86 default:
87 QL_FAIL("unknown time unit (" << Integer(p.units()) << ")");
88 }
89 }
90
91 bool isSubPeriod(const Period& subPeriod,
92 const Period& superPeriod,
93 Integer& numSubPeriods) {
94
95 std::pair<Integer, Integer> superDays(daysMinMax(superPeriod));
96 std::pair<Integer, Integer> subDays(daysMinMax(subPeriod));
97
98 //obtain the approximate time ratio
99 Real minPeriodRatio =
100 ((Real)superDays.first)/((Real)subDays.second);
101 Real maxPeriodRatio =
102 ((Real)superDays.second)/((Real)subDays.first);
103 auto lowRatio = static_cast<Integer>(std::floor(minPeriodRatio));
104 auto highRatio = static_cast<Integer>(std::ceil(maxPeriodRatio));
105
106 try {
107 for(Integer i=lowRatio; i <= highRatio; ++i) {
108 Period testPeriod = subPeriod * i;
109 if(testPeriod == superPeriod) {
110 numSubPeriods = i;
111 return true;
112 }
113 }
114 } catch(Error&) {
115 return false;
116 }
117
118 return false;
119 }
120
121 }
122
123 std::vector<Real> sinkingNotionals(const Period& bondLength,
124 const Frequency& sinkingFrequency,
125 Rate couponRate,
126 Real initialNotional) {
127 Integer nPeriods;
128 QL_REQUIRE(isSubPeriod(Period(sinkingFrequency), bondLength, nPeriods),
129 "Bond frequency is incompatible with the maturity tenor");
130
131 std::vector<Real> notionals(nPeriods+1);
132 notionals.front() = initialNotional;
133 Real coupon = couponRate / static_cast<Real>(sinkingFrequency);
134 Real compoundedInterest = 1.0;
135 Real totalValue = std::pow(1.0+coupon, nPeriods);
136 for (Size i = 0; i < (Size)nPeriods-1; ++i) {
137 compoundedInterest *= (1.0 + coupon);
138 Real currentNotional = 0.0;
139 if(coupon < 1.0e-12) {
140 currentNotional = initialNotional*(1.0 - (i+1.0)/nPeriods);
141 } else {
142 currentNotional =
143 initialNotional*(compoundedInterest - (compoundedInterest-1.0)/(1.0 - 1.0/totalValue));
144 }
145 notionals[i+1] = currentNotional;
146 }
147 notionals.back() = 0.0;
148
149 return notionals;
150 }
151
152}
AmortizingFixedRateBond(Natural settlementDays, const std::vector< Real > &notionals, const Schedule &schedule, const std::vector< Rate > &coupons, const DayCounter &accrualDayCounter, BusinessDayConvention paymentConvention=Following, const Date &issueDate=Date(), const Period &exCouponPeriod=Period(), const Calendar &exCouponCalendar=Calendar(), BusinessDayConvention exCouponConvention=Unadjusted, bool exCouponEndOfMonth=false, const std::vector< Real > &redemptions={ 100.0 }, Natural paymentLag=0)
Base bond class.
Definition: bond.hpp:59
const std::vector< Real > & notionals() const
Definition: bond.hpp:326
void addRedemptionsToCashflows(const std::vector< Real > &redemptions=std::vector< Real >())
Definition: bond.cpp:304
const Leg & cashflows() const
Definition: bond.hpp:330
Leg cashflows_
Definition: bond.hpp:288
const Leg & redemptions() const
Definition: bond.hpp:334
Date maturityDate_
Definition: bond.hpp:291
calendar class
Definition: calendar.hpp:61
Concrete date class.
Definition: date.hpp:125
day counter class
Definition: daycounter.hpp:44
helper class building a sequence of fixed rate coupons
FixedRateLeg & withNotionals(Real)
FixedRateLeg & withPaymentAdjustment(BusinessDayConvention)
FixedRateLeg & withCouponRates(Rate, const DayCounter &paymentDayCounter, Compounding comp=Simple, Frequency freq=Annual)
FixedRateLeg & withPaymentLag(Natural lag)
FixedRateLeg & withExCouponPeriod(const Period &, const Calendar &, BusinessDayConvention, bool endOfMonth=false)
Payment schedule.
Definition: schedule.hpp:40
const Date & endDate() const
Definition: schedule.hpp:184
Frequency
Frequency of events.
Definition: frequency.hpp:37
BusinessDayConvention
Business Day conventions.
QL_REAL Real
real number
Definition: types.hpp:50
unsigned QL_INTEGER Natural
positive integer
Definition: types.hpp:43
QL_INTEGER Integer
integer number
Definition: types.hpp:35
Real Rate
interest rates
Definition: types.hpp:70
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
Schedule sinkingSchedule(const Date &startDate, const Period &bondLength, const Frequency &frequency, const Calendar &paymentCalendar)
returns a schedule for French amortization
std::vector< Real > sinkingNotionals(const Period &bondLength, const Frequency &sinkingFrequency, Rate couponRate, Real initialNotional)
returns a sequence of notionals for French amortization