Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
analyticjyyoycapfloorengine.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2020 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/cashflows/simplecashflow.hpp>
22#include <ql/instruments/cpicapfloor.hpp>
23#include <ql/pricingengines/blackformula.hpp>
28
29using QuantLib::blackFormula;
30using QuantLib::CPICapFloor;
31using QuantLib::Date;
32using QuantLib::Handle;
33using QuantLib::NullCalendar;
34using QuantLib::Option;
35using QuantLib::Period;
36using QuantLib::Rate;
37using QuantLib::Real;
38using QuantLib::Settings;
39using QuantLib::SimpleCashFlow;
40using QuantLib::Size;
41using QuantLib::Unadjusted;
42using QuantLib::YoYInflationCapFloor;
43using QuantLib::YoYInflationIndex;
44using QuantLib::ZeroInflationIndex;
45using std::max;
46using std::pow;
47using std::sqrt;
48
49namespace QuantExt {
50
51AnalyticJyYoYCapFloorEngine::AnalyticJyYoYCapFloorEngine(const QuantLib::ext::shared_ptr<CrossAssetModel>& model, Size index,
52 bool indexIsInterpolated)
53 : model_(model), index_(index), indexIsInterpolated_(indexIsInterpolated) {}
54
56
57 QL_REQUIRE(model_, "AnalyticJyYoYCapFloorEngine requires a model.");
58
59 Date today = Settings::instance().evaluationDate();
60
61 auto type = arguments_.type;
62
63 // Shorten types below
64 const auto yoyCap = YoYInflationCapFloor::Cap;
65 const auto yoyFlr = YoYInflationCapFloor::Floor;
66 const auto yoyClr = YoYInflationCapFloor::Collar;
67
68 // Floor indicator used below.
69 Real indFlr = type == yoyFlr ? 1.0 : -1.0;
70
71 Size irIdx = model_->ccyIndex(model_->infjy(index_)->currency());
72 auto yts = model_->irlgm1f(irIdx)->termStructure();
73
74 // For each YoY optionlet, there are four scenarios:
75 // 1. The YoY optionlet payment has already occurred (depends on some settings) => skip it.
76 // 2. The underlying YoY rate is known but has not been paid. Deterministic discounted value.
77 // 3. The denominator in the underlying YoY rate is known but the numerator is not known. We have a CPI
78 // optionlet.
79 // 4. Both the denominator and numerator in the underlying YoY rate are not yet known. We have a "true" YoY
80 // optionlet.
81 // Both 3 and 4 are covered by the JY YoY optionlet formula from Chapter 13 of the book. In the case of 3, the
82 // formula for the mean and variance collapses to that of a CPI optionlet.
83 results_.value = 0.0;
84 for (Size i = 0; i < arguments_.payDates.size(); ++i) {
85
86 // Check for scenario 1.
87 const auto& payDate = arguments_.payDates[i];
88 SimpleCashFlow cf(0.0, payDate);
89 if (cf.hasOccurred())
90 continue;
91
92 // Discount to payment
93 auto df = yts->discount(payDate);
94
95 // Current optionlet values for brevity.
96 const auto& dt = arguments_.accrualTimes[i];
97 const auto& n = arguments_.nominals[i];
98 const auto& g = arguments_.gearings[i];
99 auto c = 1.0 + arguments_.capRates[i];
100 auto f = 1.0 + arguments_.floorRates[i];
101
102 // Check for scenario 2.
103 const auto& fixingDate = arguments_.fixingDates[i];
104 if (fixingDate <= today) {
105
106 Real payoff = 0.0;
107 auto yoyFixing = arguments_.index->fixing(fixingDate);
108
109 if (type == yoyCap || type == yoyClr) {
110 payoff = max(yoyFixing - c, 0.0);
111 }
112
113 if (type == yoyFlr || type == yoyClr) {
114 payoff += indFlr * max(f - yoyFixing, 0.0);
115 }
116
117 results_.value += n * g * dt * payoff * df;
118 continue;
119 }
120
121 // If we get to here, we are in scenario 3 or 4.
122 Date denFixingDate = fixingDate - 1 * Years;
123 auto zts = model_->infjy(index_)->realRate()->termStructure();
124 auto S = inflationTime(denFixingDate, *zts, indexIsInterpolated_);
125 auto T = inflationTime(fixingDate, *zts, indexIsInterpolated_);
126
128 Real stdDev = sqrt(varianceLogRatio(S, T));
129
130 Real payoff = 0.0;
131 if (type == yoyCap || type == yoyClr) {
132 payoff = blackFormula(Option::Call, c, mean, stdDev, df, 0.0);
133 }
134 if (type == yoyFlr || type == yoyClr) {
135 payoff += indFlr * blackFormula(Option::Put, f, mean, stdDev, df, 0.0);
136 }
137
138 results_.value += n * g * dt * payoff;
139 }
140}
141
143
144 using namespace CrossAssetAnalytics;
145
146 // Short variable names for formula below.
147 auto i = model_->ccyIndex(model_->infjy(index_)->currency());
148 auto j = index_;
149
150 // H_n(S), H_n(T) and \zeta_n(S)
151 Real H_n_S = Hz(i).eval(*model_, S);
152 Real H_n_T = Hz(i).eval(*model_, T);
153 Real z_n_S = zetaz(i).eval(*model_, S);
154
155 // H_r(S), H_r(T) and \zeta_r(S)
156 Real H_r_S = Hy(j).eval(*model_, S);
157 Real H_r_T = Hy(j).eval(*model_, T);
158 Real z_r_S = zetay(j).eval(*model_, S);
159
160 // As per section 13 of book i.e. \nu = Var \left[ \ln \frac{I(T)}{I(S)} \right]
161 Real var = integral(*model_, P(az(i), az(i), LC(H_n_T, -1.0, Hz(i)), LC(H_n_T, -1.0, Hz(i))), S, T);
162 var += integral(*model_, P(ay(j), ay(j), LC(H_r_T, -1.0, Hy(j)), LC(H_r_T, -1.0, Hy(j))), S, T);
163 var += integral(*model_, P(sy(j), sy(j)), S, T);
164 var -= 2 * integral(*model_, P(rzy(i, j, 0), az(i), LC(H_n_T, -1.0, Hz(i)), ay(j), LC(H_r_T, -1.0, Hy(j))), S, T);
165 var += 2 * integral(*model_, P(rzy(i, j, 1), az(i), LC(H_n_T, -1.0, Hz(i)), sy(j)), S, T);
166 var -= 2 * integral(*model_, P(ryy(j, j, 0, 1), ay(j), LC(H_r_T, -1.0, Hy(j)), sy(j)), S, T);
167 var += (H_n_T - H_n_S) * (H_n_T - H_n_S) * z_n_S;
168 var += (H_r_T - H_r_S) * (H_r_T - H_r_S) * z_r_S;
169 var -= 2 * (H_n_T - H_n_S) * (H_r_T - H_r_S) * integral(*model_, P(rzy(i, j, 0), az(i), ay(j)), 0.0, S);
170
171 return var;
172}
173
174} // namespace QuantExt
Analytic Jarrow Yildrim (JY) CPI cap floor engine.
Analytic Jarrow Yildrim (JY) year on year cap floor engine.
const Instrument::results * results_
Definition: cdsoption.cpp:81
AnalyticJyYoYCapFloorEngine(const QuantLib::ext::shared_ptr< CrossAssetModel > &model, QuantLib::Size index, bool indexIsInterpolated)
QuantLib::Real varianceLogRatio(QuantLib::Time S, QuantLib::Time T) const
const QuantLib::ext::shared_ptr< CrossAssetModel > model_
analytics for the cross asset model
const LC1_< E1 > LC(QuantLib::Real c, QuantLib::Real c1, const E1 &e1)
Real integral(const CrossAssetModel &model, const E &e, const Real a, const Real b)
const P2_< E1, E2 > P(const E1 &e1, const E2 &e2)
some inflation related utilities.
Jarrow Yildrim (JY) pricer for capped or floored year on year (YoY) inflation coupons.
RandomVariable sqrt(RandomVariable x)
Real jyExpectedIndexRatio(const QuantLib::ext::shared_ptr< CrossAssetModel > &model, Size index, Time S, Time T, bool indexIsInterpolated)
Time inflationTime(const Date &date, const QuantLib::ext::shared_ptr< InflationTermStructure > &inflationTs, bool indexIsInterpolated, const DayCounter &dayCounter)
Definition: inflation.cpp:61
CompiledFormula max(CompiledFormula x, const CompiledFormula &y)
INF H component. May relate to real rate portion of JY model or z component of DK model.
QuantLib::Real eval(const CrossAssetModel &x, const QuantLib::Real t) const
Real eval(const CrossAssetModel &x, const Real t) const
INF alpha component. May relate to real rate portion of JY model or z component of DK model.
JY INF index sigma component.
INF zeta component. May relate to real rate portion of JY model or z component of DK model.
Real eval(const CrossAssetModel &x, const Real t) const
Real eval(const CrossAssetModel &x, const Real t) const
Swap::arguments * arguments_