Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
cpicapfloorengines.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2018 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/*
20 Copyright (C) 2011 Chris Kenyon
21
22
23 This file is part of QuantLib, a free-software/open-source library
24 for financial quantitative analysts and developers - http://quantlib.org/
25
26 QuantLib is free software: you can redistribute it and/or modify it
27 under the terms of the QuantLib license. You should have received a
28 copy of the license along with this program; if not, please email
29 <quantlib-dev@lists.sf.net>. The license is also available online at
30 <http://quantlib.org/license.shtml>.
31
32 This program is distributed in the hope that it will be useful, but WITHOUT
33 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
34 FOR A PARTICULAR PURPOSE. See the license for more details.
35 */
36
37/*!
38 \file cpicapfloorengines.cpp
39 \brief Extended version of the QuantLib engine, strike adjustment for seasoned CPI Cap/Floor pricing
40 \ingroup PricingEngines
41 */
42
43#include <ql/time/daycounters/actualactual.hpp>
44
45#include <ql/experimental/inflation/cpicapfloortermpricesurface.hpp>
47
48using namespace QuantLib;
49
50namespace QuantExt {
51
52InterpolatingCPICapFloorEngine::InterpolatingCPICapFloorEngine(const Handle<CPICapFloorTermPriceSurface>& priceSurf)
53 : priceSurf_(priceSurf) {
54 registerWith(priceSurf_);
55}
56
58 Real npv = 0.0;
59
60 // RL change, adjusted strike, this is shared code between cpiblackcapfloorengine and this engine
61 Handle<ZeroInflationIndex> zii(arguments_.index);
62 Handle<ZeroInflationTermStructure> zits = zii->zeroInflationTermStructure();
63 Date baseDate = zits->baseDate();
64 Real baseCPI = arguments_.baseCPI;
65 Real baseFixing = zii->fixing(baseDate);
66 Date adjustedMaturity = arguments_.payDate - arguments_.observationLag;
67
68 QL_DEPRECATED_DISABLE_WARNING
69 bool isInterpolated = arguments_.observationInterpolation == CPI::Linear ||
70 (arguments_.observationInterpolation == CPI::AsIndex && zii->interpolated());
71 QL_DEPRECATED_ENABLE_WARNING
72
73 if (isInterpolated) {
74 std::pair<Date, Date> ipm = inflationPeriod(adjustedMaturity, zii->frequency());
75 adjustedMaturity = ipm.first;
76 }
77 Date adjustedStart = arguments_.startDate - arguments_.observationLag;
78 if (isInterpolated) {
79 std::pair<Date, Date> ips = inflationPeriod(adjustedStart, zii->frequency());
80 adjustedStart = ips.first;
81 }
82 Real timeFromStart = zits->dayCounter().yearFraction(adjustedStart, adjustedMaturity);
83 Real timeFromBase = zits->dayCounter().yearFraction(baseDate, adjustedMaturity);
84 Real strike = pow(baseCPI / baseFixing * pow(1.0 + arguments_.strike, timeFromStart), 1.0 / timeFromBase) - 1.0;
85 // end of RL change
86
87 // what is the difference between the observationLag of the surface
88 // and the observationLag of the cap/floor?
89 // \TODO next line will fail if units are different
90 Period lagDiff = arguments_.observationLag - priceSurf_->observationLag();
91 // next line will fail if units are different if Period() is not well written
92 QL_REQUIRE(lagDiff >= Period(0, Months), "InterpolatingCPICapFloorEngine: "
93 "lag difference must be non-negative: "
94 << lagDiff);
95
96 // we now need an effective maturity to use in the price surface because this uses
97 // maturity of calibration instruments as its time axis, N.B. this must also
98 // use the roll because the surface does
99 Date effectiveMaturity = arguments_.payDate - lagDiff;
100
101 // what interpolation do we use? Index / flat / linear
102 if (arguments_.observationInterpolation == CPI::AsIndex) {
103 // same as index means we can just use the price surface
104 // since this uses the index
105 if (arguments_.type == Option::Call) {
106 npv = priceSurf_->capPrice(effectiveMaturity, strike);
107 } else {
108 npv = priceSurf_->floorPrice(effectiveMaturity, strike);
109 }
110
111 } else {
112 std::pair<Date, Date> dd = inflationPeriod(effectiveMaturity, arguments_.index->frequency());
113 Real priceStart = 0.0;
114
115 if (arguments_.type == Option::Call) {
116 priceStart = priceSurf_->capPrice(dd.first, strike);
117 } else {
118 priceStart = priceSurf_->floorPrice(dd.first, strike);
119 }
120
121 // if we use a flat index vs the interpolated one ...
122 if (arguments_.observationInterpolation == CPI::Flat) {
123 // then use the price for the first day in the period because the value cannot change after then
124 npv = priceStart;
125
126 } else {
127 // linear interpolation will be very close
128 Real priceEnd = 0.0;
129 if (arguments_.type == Option::Call) {
130 priceEnd = priceSurf_->capPrice((dd.second + Period(1, Days)), strike);
131 } else {
132 priceEnd = priceSurf_->floorPrice((dd.second + Period(1, Days)), strike);
133 }
134
135 npv = priceStart + (priceEnd - priceStart) * (effectiveMaturity - dd.first) /
136 ((dd.second + Period(1, Days)) - dd.first); // can't get to next period'
137 }
138 }
139 results_.value = npv * arguments_.nominal;
140}
141
142} // namespace QuantExt
const Instrument::results * results_
Definition: cdsoption.cpp:81
virtual void calculate() const override
QuantLib::Handle< QuantLib::CPICapFloorTermPriceSurface > priceSurf_
InterpolatingCPICapFloorEngine(const QuantLib::Handle< QuantLib::CPICapFloorTermPriceSurface > &)
Extended version of the QuantLib engine, strike adjustment for seasoned CPI Cap/Floor pricing.
CompiledFormula pow(CompiledFormula x, const CompiledFormula &y)
Swap::arguments * arguments_