Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
inflationcapfloorengines.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2019 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
20
21#include <ql/pricingengines/blackformula.hpp>
22#include <ql/termstructures/volatility/inflation/yoyinflationoptionletvolatilitystructure.hpp>
23
24namespace QuantExt {
25
27 const ext::shared_ptr<QuantLib::YoYInflationIndex>& index,
28 const Handle<QuantLib::YoYOptionletVolatilitySurface>& volatility, const Handle<YieldTermStructure>& discountCurve)
29 : index_(index), volatility_(volatility), discountCurve_(discountCurve) {
30 registerWith(index_);
31 registerWith(volatility_);
32 registerWith(discountCurve_);
33}
34
35void YoYInflationCapFloorEngine::setVolatility(const Handle<QuantLib::YoYOptionletVolatilitySurface>& v) {
36 if (!volatility_.empty())
37 unregisterWith(volatility_);
38 volatility_ = v;
39 registerWith(volatility_);
40 update();
41}
42
44
45 // copy black version then adapt to others
46
47 Real value = 0.0, vega = 0.0;
48 Size optionlets = arguments_.startDates.size();
49 std::vector<Real> values(optionlets, 0.0);
50 std::vector<Real> stdDevs(optionlets, 0.0);
51 std::vector<Real> forwards(optionlets, 0.0);
52 YoYInflationCapFloor::Type type = arguments_.type;
53
54 Handle<YoYInflationTermStructure> yoyTS = index()->yoyInflationTermStructure();
55 Handle<YieldTermStructure> discountTS = discountCurve_;
56 QL_REQUIRE(!discountTS.empty(), "YoYInflationCapFloorEngine: No discount curve given.");
57 Date settlement = discountTS->referenceDate();
58
59 for (Size i = 0; i < optionlets; ++i) {
60 Date paymentDate = arguments_.payDates[i];
61 if (paymentDate > settlement) { // discard expired caplets
62 DiscountFactor d = arguments_.nominals[i] * arguments_.gearings[i] * discountTS->discount(paymentDate) *
63 arguments_.accrualTimes[i];
64
65 // We explicitly have the index and assume that
66 // the fixing is natural, i.e. no convexity adjustment.
67 // If that was required then we would also need
68 // nominal vols in the pricing engine, i.e. a different engine.
69 // This also means that we do not need the coupon to have
70 // a pricing engine to return the swaplet rate and then
71 // the adjusted fixing in the instrument.
72 forwards[i] = yoyTS->yoyRate(arguments_.fixingDates[i], Period(0, Days));
73 Rate forward = forwards[i];
74
75 Date fixingDate = arguments_.fixingDates[i];
76 Time sqrtTime = 0.0;
77 if (fixingDate > volatility_->baseDate()) {
78 sqrtTime = std::sqrt(volatility_->timeFromBase(fixingDate));
79 }
80
81 if (type == YoYInflationCapFloor::Cap || type == YoYInflationCapFloor::Collar) {
82 Rate strike = arguments_.capRates[i];
83 if (sqrtTime > 0.0) {
84 stdDevs[i] = std::sqrt(volatility_->totalVariance(fixingDate, strike, Period(0, Days)));
85 }
86
87 // sttDev=0 for already-fixed dates so everything on forward
88 values[i] = optionletImpl(Option::Call, strike, forward, stdDevs[i], d);
89 vega += optionletVegaImpl(Option::Call, strike, forward, stdDevs[i], sqrtTime, d);
90 }
91 if (type == YoYInflationCapFloor::Floor || type == YoYInflationCapFloor::Collar) {
92 Rate strike = arguments_.floorRates[i];
93 if (sqrtTime > 0.0) {
94 stdDevs[i] = std::sqrt(volatility_->totalVariance(fixingDate, strike, Period(0, Days)));
95 }
96 Real floorlet = optionletImpl(Option::Put, strike, forward, stdDevs[i], d);
97 Real floorletVega = optionletVegaImpl(Option::Call, strike, forward, stdDevs[i], sqrtTime, d);
98 if (type == YoYInflationCapFloor::Floor) {
99 values[i] = floorlet;
100 vega -= floorletVega;
101 } else {
102 // a collar is long a cap and short a floor
103 values[i] -= floorlet;
104 vega -= optionletVegaImpl(Option::Call, strike, forward, stdDevs[i], sqrtTime, d);
105 }
106 }
107 value += values[i];
108 }
109 }
110 results_.value = value;
111
112 results_.additionalResults["vega"] = vega;
113 results_.additionalResults["optionletsPrice"] = values;
114 results_.additionalResults["optionletsAtmForward"] = forwards;
115 if (type != YoYInflationCapFloor::Collar)
116 results_.additionalResults["optionletsStdDev"] = stdDevs;
117}
118
119//======================================================================
120// pricer implementations
121//======================================================================
123 const ext::shared_ptr<QuantLib::YoYInflationIndex>& index,
124 const Handle<QuantLib::YoYOptionletVolatilitySurface>& volatility, const Handle<YieldTermStructure>& discountCurve)
125 : YoYInflationCapFloorEngine(index, volatility, discountCurve) {}
126
127Real YoYInflationBlackCapFloorEngine::optionletImpl(Option::Type type, Rate strike, Rate forward, Real stdDev,
128 Real d) const {
129 return blackFormula(type, strike, forward, stdDev, d);
130}
131
132Real YoYInflationBlackCapFloorEngine::optionletVegaImpl(Option::Type type, Rate strike, Rate forward, Real stdDev,
133 Real sqrtTime, Real d) const {
134 return blackFormulaStdDevDerivative(type, strike, forward, stdDev, d) * sqrtTime;
135}
136
137YoYInflationUnitDisplacedBlackCapFloorEngine ::YoYInflationUnitDisplacedBlackCapFloorEngine(
138 const ext::shared_ptr<QuantLib::YoYInflationIndex>& index,
139 const Handle<QuantLib::YoYOptionletVolatilitySurface>& volatility, const Handle<YieldTermStructure>& discountCurve)
140 : YoYInflationCapFloorEngine(index, volatility, discountCurve) {}
141
142Real YoYInflationUnitDisplacedBlackCapFloorEngine::optionletImpl(Option::Type type, Rate strike, Rate forward,
143 Real stdDev, Real d) const {
144 // could use displacement parameter in blackFormula but this is clearer
145 return blackFormula(type, strike + 1.0, forward + 1.0, stdDev, d);
146}
147
148Real YoYInflationUnitDisplacedBlackCapFloorEngine::optionletVegaImpl(Option::Type type, Rate strike, Rate forward,
149 Real stdDev, Real sqrtTime, Real d) const {
150 return blackFormulaStdDevDerivative(type, strike + 1.0, forward + 1.0, stdDev, d) * sqrtTime;
151}
152
154 const ext::shared_ptr<QuantLib::YoYInflationIndex>& index,
155 const Handle<QuantLib::YoYOptionletVolatilitySurface>& volatility, const Handle<YieldTermStructure>& discountCurve)
156 : YoYInflationCapFloorEngine(index, volatility, discountCurve) {}
157
158Real YoYInflationBachelierCapFloorEngine::optionletImpl(Option::Type type, Rate strike, Rate forward, Real stdDev,
159 Real d) const {
160 return bachelierBlackFormula(type, strike, forward, stdDev, d);
161}
162
163Real YoYInflationBachelierCapFloorEngine::optionletVegaImpl(Option::Type type, Rate strike, Rate forward, Real stdDev,
164 Real sqrtTime, Real d) const {
165 return bachelierBlackFormulaStdDevDerivative(strike, forward, stdDev, d) * sqrtTime;
166}
167
168} // namespace QuantExt
const Instrument::results * results_
Definition: cdsoption.cpp:81
virtual Real optionletImpl(Option::Type, Real strike, Real forward, Real stdDev, Real d) const override
YoYInflationBachelierCapFloorEngine(const ext::shared_ptr< QuantLib::YoYInflationIndex > &, const Handle< QuantLib::YoYOptionletVolatilitySurface > &, const Handle< YieldTermStructure > &discountCurve)
virtual Real optionletVegaImpl(Option::Type type, Rate strike, Rate forward, Real stdDev, Real sqrtTime, Real d) const override
virtual Real optionletImpl(Option::Type, Real strike, Real forward, Real stdDev, Real d) const override
YoYInflationBlackCapFloorEngine(const ext::shared_ptr< QuantLib::YoYInflationIndex > &, const Handle< QuantLib::YoYOptionletVolatilitySurface > &, const Handle< YieldTermStructure > &discountCurve)
virtual Real optionletVegaImpl(Option::Type type, Rate strike, Rate forward, Real stdDev, Real sqrtTime, Real d) const override
Base YoY inflation cap/floor engine.
virtual Real optionletVegaImpl(Option::Type type, Rate strike, Rate forward, Real stdDev, Real sqrtTime, Real d) const =0
YoYInflationCapFloorEngine(const ext::shared_ptr< QuantLib::YoYInflationIndex > &, const Handle< QuantLib::YoYOptionletVolatilitySurface > &vol, const Handle< YieldTermStructure > &discountCurve)
virtual Real optionletImpl(Option::Type type, Rate strike, Rate forward, Real stdDev, Real d) const =0
descendents only need to implement this
void setVolatility(const Handle< QuantLib::YoYOptionletVolatilitySurface > &vol)
ext::shared_ptr< QuantLib::YoYInflationIndex > index() const
ext::shared_ptr< QuantLib::YoYInflationIndex > index_
Handle< QuantLib::YoYOptionletVolatilitySurface > volatility_
virtual Real optionletImpl(Option::Type, Real strike, Real forward, Real stdDev, Real d) const override
virtual Real optionletVegaImpl(Option::Type type, Rate strike, Rate forward, Real stdDev, Real sqrtTime, Real d) const override
Inflation cap/floor engines from QuantLib, with optional external discount curve.
Swap::arguments * arguments_