Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
nonstandardinflationcouponpricer.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2021 Quaternion Risk Management Ltd
3
4 This file is part of ORE, a free-software/open-source library
5 for transparent pricing and risk analysis - http://opensourcerisk.org
6
7 ORE is free software: you can redistribute it and/or modify it
8 under the terms of the Modified BSD License. You should have received a
9 copy of the license along with this program.
10 The license is also available online at <http://opensourcerisk.org>
11
12 This program is distributed on the basis that it will form a useful
13 contribution to risk analytics and model standardisation, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
16*/
17
18/*
19 Copyright (C) 2009 Chris Kenyon
20
21 This file is part of QuantLib, a free-software/open-source library
22 for financial quantitative analysts and developers - http://quantlib.org/
23
24 QuantLib is free software: you can redistribute it and/or modify it
25 under the terms of the QuantLib license. You should have received a
26 copy of the license along with this program; if not, please email
27 <quantlib-dev@lists.sf.net>. The license is also available online at
28 <http://quantlib.org/license.shtml>.
29
30 This program is distributed in the hope that it will be useful, but WITHOUT
31 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
32 FOR A PARTICULAR PURPOSE. See the license for more details.
33 */
34
35#include <ql/pricingengines/blackformula.hpp>
36#include <ql/termstructures/volatility/inflation/yoyinflationoptionletvolatilitystructure.hpp>
38
39namespace QuantExt {
40
42 const Handle<YieldTermStructure>& nominalTermStructure)
43 : nominalTermStructure_(std::move(nominalTermStructure)) {
44 registerWith(nominalTermStructure_);
45}
46
48 const Handle<YoYOptionletVolatilitySurface>& capletVol, const Handle<YieldTermStructure>& nominalTermStructure)
49 : capletVol_(capletVol), nominalTermStructure_(nominalTermStructure) {
50 registerWith(capletVol_);
51 registerWith(nominalTermStructure_);
52}
53
54void NonStandardYoYInflationCouponPricer::setCapletVolatility(const Handle<YoYOptionletVolatilitySurface>& capletVol) {
55 QL_REQUIRE(!capletVol.empty(), "empty capletVol handle");
56 capletVol_ = capletVol;
57 registerWith(capletVol_);
58}
59
61 Real floorletPrice = optionletPrice(Option::Put, effectiveFloor);
62 return gearing_ * floorletPrice;
63}
64
66 Real capletPrice = optionletPrice(Option::Call, effectiveCap);
67 return gearing_ * capletPrice;
68}
69
71 return gearing_ * optionletRate(Option::Put, effectiveFloor);
72}
73
75 return gearing_ * optionletRate(Option::Call, effectiveCap);
76}
77
78Real NonStandardYoYInflationCouponPricer::optionletPriceImp(Option::Type, Real, Real, Real) const {
79 QL_FAIL("you must implement this to get a vol-dependent price");
80}
81
82Real NonStandardYoYInflationCouponPricer::optionletPrice(Option::Type optionType, Real effStrike) const {
83 QL_REQUIRE(discount_ != Null<Real>(), "no nominal term structure provided");
84 return optionletRate(optionType, effStrike) * coupon_->accrualPeriod() * discount_;
85}
86
87Real NonStandardYoYInflationCouponPricer::optionletRate(Option::Type optionType, Real effStrike) const {
88 Date fixingDate = coupon_->fixingDate();
89 if (fixingDate <= Settings::instance().evaluationDate()) {
90 // the amount is determined
91 Real a, b;
92 if (optionType == Option::Call) {
93 a = coupon_->indexFixing();
94 b = effStrike;
95 } else {
96 a = effStrike;
97 b = coupon_->indexFixing();
98 }
99 return std::max(a - b, 0.0);
100 } else {
101 // not yet determined, use Black/DD1/Bachelier/whatever from Impl
102 QL_REQUIRE(!capletVolatility().empty(), "missing optionlet volatility");
103 Real stdDev = std::sqrt(capletVolatility()->totalVariance(fixingDate, effStrike));
104 return optionletPriceImp(optionType, effStrike, adjustedFixing(), stdDev);
105 }
106}
107
109
110 if (fixing == Null<Rate>())
111 fixing = coupon_->indexFixing();
112
113 // no adjustment
114 return fixing;
115}
116
118 coupon_ = dynamic_cast<const NonStandardYoYInflationCoupon*>(&coupon);
119 QL_REQUIRE(coupon_, "year-on-year inflation coupon needed");
122 paymentDate_ = coupon_->date();
123
124 // past or future fixing is managed in YoYInflationIndex::fixing()
125 // use yield curve from index (which sets discount)
126
127 discount_ = 1.0;
128 if (paymentDate_ > nominalTermStructure_->referenceDate()) {
129 if (nominalTermStructure_.empty()) {
130 // allow to extract rates, but mark the discount as invalid for prices
131 discount_ = Null<Real>();
132 } else {
133 discount_ = nominalTermStructure_->discount(paymentDate_);
134 }
135 }
136}
137
139 QL_REQUIRE(discount_ != Null<Real>(), "no nominal term structure provided");
140 return swapletRate() * coupon_->accrualPeriod() * discount_;
141}
142
144 // This way we do not require the index to have
145 // a yield curve, i.e. we do not get the problem
146 // that a discounting-instrument-pricer is used
147 // with a different yield curve
148 return gearing_ * adjustedFixing() + spread_;
149}
150
151//=========================================================================
152// vol-dependent pricers, note that these do not discount
153//=========================================================================
154
155Real NonStandardBlackYoYInflationCouponPricer::optionletPriceImp(Option::Type optionType, Real effStrike, Real forward,
156 Real stdDev) const {
157
158 return blackFormula(optionType, effStrike, forward, stdDev);
159}
160
162 Real forward, Real stdDev) const {
163
164 return blackFormula(optionType, effStrike + 1.0, forward + 1.0, stdDev);
165}
166
167Real NonStandardBachelierYoYInflationCouponPricer::optionletPriceImp(Option::Type optionType, Real effStrike,
168 Real forward, Real stdDev) const {
169 return bachelierBlackFormula(optionType, effStrike, forward, stdDev);
170}
171
172} // namespace QuantExt
Real optionletPriceImp(Option::Type, Real strike, Real forward, Real stdDev) const override
Real optionletPriceImp(Option::Type, Real strike, Real forward, Real stdDev) const override
Real optionletPriceImp(Option::Type, Real strike, Real forward, Real stdDev) const override
Coupon paying a YoY-inflation type index
Real gearing() const
index gearing, i.e. multiplicative coefficient for the index
Spread spread() const
spread paid over the fixing of the underlying index
virtual void initialize(const InflationCoupon &) override
virtual Real capletPrice(Rate effectiveCap) const override
virtual Rate floorletRate(Rate effectiveFloor) const override
NonStandardYoYInflationCouponPricer(const Handle< YieldTermStructure > &nominalTermStructure)
virtual Rate adjustedFixing(Rate fixing=Null< Rate >()) const
virtual Real optionletPrice(Option::Type optionType, Real effStrike) const
virtual Handle< YoYOptionletVolatilitySurface > capletVolatility() const
virtual Real optionletRate(Option::Type optionType, Real effStrike) const
virtual Real optionletPriceImp(Option::Type, Real strike, Real forward, Real stdDev) const
virtual Real floorletPrice(Rate effectiveFloor) const override
virtual void setCapletVolatility(const Handle< YoYOptionletVolatilitySurface > &capletVol)
Handle< YoYOptionletVolatilitySurface > capletVol_
data
virtual Rate capletRate(Rate effectiveCap) const override
pricer for the generalized (nonstandard) yoy coupon the payoff of the coupon is: N * (alpha * I_t/I_s...