Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
analyticjycpicapfloorengine.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
19#include <ql/cashflows/simplecashflow.hpp>
20#include <ql/pricingengines/blackformula.hpp>
23
24using namespace QuantExt::CrossAssetAnalytics;
25using QuantLib::DiscountFactor;
26using QuantLib::Real;
27using QuantLib::SimpleCashFlow;
28using QuantLib::Size;
29using std::max;
30using std::pow;
31using std::sqrt;
32
33namespace QuantExt {
34
35AnalyticJyCpiCapFloorEngine::AnalyticJyCpiCapFloorEngine(const QuantLib::ext::shared_ptr<CrossAssetModel>& model, Size index)
36 : model_(model), index_(index) {}
37
39
40 // If the pay date has occurred, nothing to do.
41 SimpleCashFlow cf(0.0, arguments_.payDate);
42 if (cf.hasOccurred()) {
43 results_.value = 0.0;
44 return;
45 }
46
47 // Discount factor to pay date will be needed below.
48 Size irIdx = model_->ccyIndex(model_->infjy(index_)->currency());
49 DiscountFactor df = model_->irlgm1f(irIdx)->termStructure()->discount(arguments_.payDate);
50
51 QL_DEPRECATED_DISABLE_WARNING
52 bool interpolate = arguments_.observationInterpolation == CPI::Linear ||
53 (arguments_.observationInterpolation == CPI::AsIndex && arguments_.index->interpolated());
54 QL_DEPRECATED_ENABLE_WARNING
55 // Get the time to expiry. This determines if we use the JY model or look for an inflation index fixing.
56 auto zts = model_->infjy(index_)->realRate()->termStructure();
57 Real t = inflationYearFraction(arguments_.index->frequency(), interpolate, zts->dayCounter(), zts->baseDate(),
58 arguments_.fixDate);
59
60 // If time to expiry is non-positive, we return the discounted value of the settled amount.
61 // CPICapFloor should really have its own day counter for going from strike rate to k. We use t here.
62 Real k = pow(1.0 + arguments_.strike, t);
63 if (t <= 0.0) {
64 auto cpiAtExpiry = arguments_.index->fixing(arguments_.fixDate);
65 if (arguments_.type == Option::Call) {
66 results_.value = max(cpiAtExpiry / arguments_.baseCPI - k, 0.0);
67 } else {
68 results_.value = max(k - cpiAtExpiry / arguments_.baseCPI, 0.0);
69 }
70 results_.value *= arguments_.nominal * df;
71 return;
72 }
73
74 // Section 13, Book. ZCII Cap. Note that there is a difference between the base CPI value associated with the
75 // inflation term structures and used as a starting point in the CAM evolution vs. the contractual base CPI in
76 // the CPICapFloor instrument. The former is curveBaseCpi below and the latter is arguments_.baseCPI.
77
78 // Calculate the variance, \Sigma^2_I in the book.
79 Real H_n_t = Hz(irIdx).eval(*model_, t);
80 Real H_r_t = Hy(index_).eval(*model_, t);
81 Real v = integral(*model_, P(LC(H_n_t, -1.0, Hz(irIdx)), LC(H_n_t, -1.0, Hz(irIdx)), az(irIdx), az(irIdx)), 0.0, t);
82 v += integral(*model_, P(LC(H_r_t, -1.0, Hy(index_)), LC(H_r_t, -1.0, Hy(index_)), ay(index_), ay(index_)), 0.0, t);
83 v += integral(*model_, P(sy(index_), sy(index_)), 0.0, t);
84 v -= 2 *
86 P(rzy(irIdx, index_), LC(H_r_t, -1.0, Hy(index_)), LC(H_n_t, -1.0, Hz(irIdx)), ay(index_), az(irIdx)),
87 0.0, t);
88 v += 2 * integral(*model_, P(rzy(irIdx, index_, 1), LC(H_n_t, -1.0, Hz(irIdx)), az(irIdx), sy(index_)), 0.0, t);
89 v -= 2 *
90 integral(*model_, P(ryy(index_, index_, 0, 1), LC(H_r_t, -1.0, Hy(index_)), ay(index_), sy(index_)), 0.0, t);
91
92 // Calculate the forward CPI, F_I(0,T) in the book.
93 Real fwd = arguments_.index->fixing(arguments_.fixDate);
94
95 // Get adjusted nominal and strike, \tilde{N} and \tilde{K} from the book.
96 Real adjNominal = arguments_.nominal / arguments_.baseCPI;
97 Real adjStrike = k * arguments_.baseCPI;
98
99 results_.value = adjNominal * blackFormula(arguments_.type, adjStrike, fwd, sqrt(v), df);
100}
101
102} // namespace QuantExt
Analytic Jarrow Yildrim (JY) CPI cap floor engine.
const Instrument::results * results_
Definition: cdsoption.cpp:81
const QuantLib::ext::shared_ptr< CrossAssetModel > model_
AnalyticJyCpiCapFloorEngine(const QuantLib::ext::shared_ptr< CrossAssetModel > &model, QuantLib::Size index)
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)
RandomVariable sqrt(RandomVariable x)
CompiledFormula pow(CompiledFormula x, const CompiledFormula &y)
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.
Swap::arguments * arguments_