QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
zerocouponinflationswap.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2007, 2009 Chris Kenyon
5 Copyright (C) 2009 StatPro Italia srl
6 Copyright (C) 2021 Ralf Konrad Eckel
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/cashflows/zeroinflationcashflow.hpp>
23#include <ql/cashflows/simplecashflow.hpp>
24#include <ql/instruments/zerocouponinflationswap.hpp>
25#include <ql/time/calendars/nullcalendar.hpp>
26#include <utility>
27
28namespace QuantLib {
29
30 /* Generally inflation indices are available with a lag of 1month
31 and then observed with a lag of 2-3 months depending whether
32 they use an interpolated fixing or not. Here, we make the
33 swap use the interpolation of the index to avoid incompatibilities.
34 */
36 Type type,
37 Real nominal,
38 const Date& startDate, // start date of contract (only)
39 const Date& maturity, // this is pre-adjustment!
40 Calendar fixCalendar,
41 BusinessDayConvention fixConvention,
42 DayCounter dayCounter,
43 Rate fixedRate,
44 const ext::shared_ptr<ZeroInflationIndex>& infIndex,
45 const Period& observationLag,
46 CPI::InterpolationType observationInterpolation,
47 bool adjustInfObsDates,
48 Calendar infCalendar,
49 BusinessDayConvention infConvention)
50 : Swap(2), type_(type), nominal_(nominal), startDate_(startDate), maturityDate_(maturity),
51 fixCalendar_(std::move(fixCalendar)), fixConvention_(fixConvention), fixedRate_(fixedRate),
52 infIndex_(infIndex), observationLag_(observationLag),
53 observationInterpolation_(observationInterpolation), adjustInfObsDates_(adjustInfObsDates),
54 infCalendar_(std::move(infCalendar)), infConvention_(infConvention),
55 dayCounter_(std::move(dayCounter)) {
56 // first check compatibility of index and swap definitions
58 Period pShift(infIndex_->frequency());
59 QL_REQUIRE(observationLag_ - pShift >= infIndex_->availabilityLag(),
60 "inconsistency between swap observation lag "
61 << observationLag_ << ", interpolated index period "
62 << pShift << " and index availability " << infIndex_->availabilityLag()
63 << ": need (obsLag-index period) >= availLag");
64 } else {
65 QL_REQUIRE(infIndex_->availabilityLag() <= observationLag_,
66 "index tries to observe inflation fixings that do not yet exist: "
67 << " availability lag " << infIndex_->availabilityLag()
68 << " versus obs lag = " << observationLag_);
69 }
70
71 if (infCalendar_ == Calendar())
75
76 Date infPayDate = infCalendar_.adjust(maturity, infConvention_);
77 Date fixedPayDate = fixCalendar_.adjust(maturity, fixConvention_);
78
79 bool growthOnly = true;
80
81 auto inflationCashFlow =
82 ext::make_shared<ZeroInflationCashFlow>(nominal, infIndex, observationInterpolation_,
83 startDate, maturity, observationLag_,
84 infPayDate, growthOnly);
85
86 baseDate_ = inflationCashFlow->baseDate();
87 obsDate_ = inflationCashFlow->fixingDate();
88
89 // At this point the index may not be able to forecast
90 // i.e. do not want to force the existence of an inflation
91 // term structure before allowing users to create instruments.
92 Real T =
96 // N.B. the -1.0 is because swaps only exchange growth, not notionals as well
97 Real fixedAmount = nominal * (std::pow(1.0 + fixedRate, T) - 1.0);
98
99 auto fixedCashFlow = ext::make_shared<SimpleCashFlow>(fixedAmount, fixedPayDate);
100
101 legs_[0].push_back(fixedCashFlow);
102 legs_[1].push_back(inflationCashFlow);
103
104 registerWith(inflationCashFlow);
105
106 switch (type_) {
107 case Payer:
108 payer_[0] = +1.0;
109 payer_[1] = -1.0;
110 break;
111 case Receiver:
112 payer_[0] = -1.0;
113 payer_[1] = +1.0;
114 break;
115 default:
116 QL_FAIL("Unknown zero-inflation-swap type");
117 }
118 }
119
120
122 // What does this mean before or after trade date?
123 // Always means that NPV is zero for _this_ instrument
124 // if it was created with _this_ rate
125 // _knowing_ the time from base to obs (etc).
126
127 ext::shared_ptr<IndexedCashFlow> icf =
128 ext::dynamic_pointer_cast<IndexedCashFlow>(legs_[1].at(0));
129 QL_REQUIRE(icf,"failed to downcast to IndexedCashFlow in ::fairRate()");
130
131 // +1 because the IndexedCashFlow has growthOnly=true
132 Real growth = icf->amount() / icf->notional() + 1.0;
133 Real T =
134 inflationYearFraction(infIndex_->frequency(),
137
138 return std::pow(growth,1.0/T) - 1.0;
139
140 // we cannot use this simple definition because
141 // it does not work for already-issued instruments
142 // return infIndex_->zeroInflationTermStructure()->zeroRate(
143 // maturityDate(), observationLag(), infIndex_->interpolated());
144 }
145
146
148 calculate();
149 QL_REQUIRE(legNPV_[0] != Null<Real>(), "result not available");
150 return legNPV_[0];
151 }
152
154 calculate();
155 QL_REQUIRE(legNPV_[1] != Null<Real>(), "result not available");
156 return legNPV_[1];
157 }
158
160 return legs_[0];
161 }
162
164 return legs_[1];
165 }
166
167}
calendar class
Definition: calendar.hpp:61
Date adjust(const Date &, BusinessDayConvention convention=Following) const
Definition: calendar.cpp:84
Concrete date class.
Definition: date.hpp:125
day counter class
Definition: daycounter.hpp:44
void calculate() const override
Definition: instrument.hpp:129
template class providing a null value for a given type.
Definition: null.hpp:76
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
Interest rate swap.
Definition: swap.hpp:41
std::vector< Leg > legs_
Definition: swap.hpp:133
std::vector< Real > legNPV_
Definition: swap.hpp:135
std::vector< Real > payer_
Definition: swap.hpp:134
Rate fixedRate() const
in the above formula.
const Leg & fixedLeg() const
just one cashflow (that is not a coupon) in each leg
ext::shared_ptr< ZeroInflationIndex > infIndex_
ZeroCouponInflationSwap(Type type, Real nominal, const Date &startDate, const Date &maturity, Calendar fixCalendar, BusinessDayConvention fixConvention, DayCounter dayCounter, Rate fixedRate, const ext::shared_ptr< ZeroInflationIndex > &infIndex, const Period &observationLag, CPI::InterpolationType observationInterpolation, bool adjustInfObsDates=false, Calendar infCalendar=Calendar(), BusinessDayConvention infConvention=BusinessDayConvention())
const Leg & inflationLeg() const
just one cashflow (that is not a coupon) in each leg
BusinessDayConvention
Business Day conventions.
QL_REAL Real
real number
Definition: types.hpp:50
Real Rate
interest rates
Definition: types.hpp:70
bool isInterpolated(const ext::shared_ptr< ZeroInflationIndex > &index, const QuantLib::CPI::InterpolationType &type=QuantLib::CPI::AsIndex)
QuantLib::CPI::InterpolationType effectiveInterpolationType(const ext::shared_ptr< ZeroInflationIndex > &index, const QuantLib::CPI::InterpolationType &type=QuantLib::CPI::AsIndex)
Definition: any.hpp:35
Time inflationYearFraction(Frequency f, bool indexIsInterpolated, const DayCounter &dayCounter, const Date &d1, const Date &d2)
std::vector< ext::shared_ptr< CashFlow > > Leg
Sequence of cash-flows.
Definition: cashflow.hpp:78
STL namespace.
InterpolationType
when you observe an index, how do you interpolate between fixings?
@ Linear
linearly between bracketing fixings