Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
inflationcapfloor.cpp
Go to the documentation of this file.
1/*
2Copyright (C) 2016 Quaternion Risk Management Ltd
3All rights reserved.
4
5This file is part of ORE, a free-software/open-source library
6for transparent pricing and risk analysis - http://opensourcerisk.org
7
8ORE is free software: you can redistribute it and/or modify it
9under the terms of the Modified BSD License. You should have received a
10copy of the license along with this program.
11The license is also available online at <http://opensourcerisk.org>
12
13This program is distributed on the basis that it will form a useful
14contribution to risk analytics and model standardisation, but WITHOUT
15ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19#include <boost/make_shared.hpp>
20#include <boost/test/unit_test.hpp>
28#include <oret/toplevelfixture.hpp>
29#include <ql/indexes/inflation/euhicp.hpp>
30#include <ql/instruments/inflationcapfloor.hpp>
31#include <ql/pricingengines/inflation/inflationcapfloorengines.hpp>
32#include <ql/termstructures/inflation/inflationhelpers.hpp>
33#include <ql/termstructures/volatility/inflation/yoyinflationoptionletvolatilitystructure.hpp>
34#include <ql/termstructures/yield/discountcurve.hpp>
35#include <ql/termstructures/yield/flatforward.hpp>
36#include <ql/time/daycounters/actualactual.hpp>
38
39using namespace QuantLib;
40using namespace boost::unit_test_framework;
41using namespace std;
42using namespace ore::data;
43
44// FX Swap test
45class TestMarket : public MarketImpl {
46public:
47 TestMarket(Date asof) : MarketImpl(false) {
48 // valuation date
49
50 dc = ActualActual(ActualActual::ISDA);
51 bdc = Following;
52 cal = TARGET();
53
54 // Add EUR notional curve
55 Handle<YieldTermStructure> nominalTs(QuantLib::ext::make_shared<FlatForward>(0, cal, 0.005, dc));
56 yieldCurves_[make_tuple(Market::defaultConfiguration, YieldCurveType::Discount, "EUR")] = nominalTs;
57
58 // Add EUHICPXT YoY Inflation Curve
59 QuantLib::ext::shared_ptr<ZeroInflationIndex> zcindex = QuantLib::ext::shared_ptr<EUHICPXT>(new EUHICPXT());
60 ;
61 QuantLib::ext::shared_ptr<YoYInflationIndex> index =
62 QuantLib::ext::make_shared<QuantExt::YoYInflationIndexWrapper>(zcindex, false);
63
64 std::vector<Date> datesZCII = {asof + 1 * Years, asof + 2 * Years, asof + 5 * Years, asof + 10 * Years,
65 asof + 20 * Years};
66 std::vector<Rate> ratesZCII = {1.1625, 1.23211, 1.36019, 1.51199, 1.74773};
67
68 std::vector<QuantLib::ext::shared_ptr<YoYInflationTraits::helper>> instruments;
69 for (Size i = 0; i < datesZCII.size(); i++) {
70 Handle<Quote> quote(QuantLib::ext::shared_ptr<Quote>(new SimpleQuote(ratesZCII[i] / 100)));
71 QuantLib::ext::shared_ptr<YoYInflationTraits::helper> anInstrument =
72 QuantLib::ext::make_shared<YearOnYearInflationSwapHelper>(quote, Period(3, Months), datesZCII[i], cal, bdc, dc,
73 index, nominalTs);
74 instruments.push_back(anInstrument);
75 };
76 QuantLib::ext::shared_ptr<YoYInflationTermStructure> yoyTs = QuantLib::ext::shared_ptr<PiecewiseYoYInflationCurve<Linear>>(
77 new PiecewiseYoYInflationCurve<Linear>(asof, TARGET(), Actual365Fixed(), Period(3, Months), Monthly,
78 index->interpolated(), ratesZCII[0] / 100, instruments));
79
81 Handle<YoYInflationIndex>(QuantLib::ext::make_shared<QuantExt::YoYInflationIndexWrapper>(
82 parseZeroInflationIndex("EUHICPXT"), false, Handle<YoYInflationTermStructure>(yoyTs)));
83
84 // Add EUHICPXT yoy volatility term structure
85 QuantLib::ext::shared_ptr<QuantLib::ConstantYoYOptionletVolatility> volSurface =
86 QuantLib::ext::make_shared<QuantLib::ConstantYoYOptionletVolatility>(0.01, 0, cal, bdc, dc, Period(3, Months),
87 Monthly, index->interpolated(), -1.0, 100.0,
88 VolatilityType::Normal);
89
91 Handle<QuantExt::YoYOptionletVolatilitySurface>(volSurface);
92 }
93
94 BusinessDayConvention bdc;
95 DayCounter dc;
96 Calendar cal;
97};
98
99BOOST_FIXTURE_TEST_SUITE(OREDataTestSuite, ore::test::TopLevelFixture)
100
101BOOST_AUTO_TEST_SUITE(InflationCapFloorTests)
102
103BOOST_AUTO_TEST_CASE(testYoYCapFloor) {
104
105 BOOST_TEST_MESSAGE("Testing YoY Cap Price...");
106
107 // build market
108 Date today(18, July, 2016);
109 Settings::instance().evaluationDate() = today;
110
111 QuantLib::ext::shared_ptr<TestMarket> market = QuantLib::ext::make_shared<TestMarket>(today);
112 // Test if EUR yoy inflation curve is empty
113 Handle<YoYInflationIndex> infidx = market->yoyInflationIndex("EUHICPXT");
114 QL_REQUIRE(!infidx.empty(), "EUHICPXT inflation index not found");
115
116 // envelope
117 Envelope env("CP");
118
119 // Start/End date
120 Date startDate = today;
121 Date endDate = today + 5 * Years;
122
123 // date 2 string
124 std::ostringstream oss;
125 oss << io::iso_date(startDate);
126 string start(oss.str());
127 oss.str("");
128 oss.clear();
129 oss << io::iso_date(endDate);
130 string end(oss.str());
131
132 // Schedules
133 string conv = "F";
134 string rule = "Forward";
135 ScheduleData scheduleYY(ScheduleRules(start, end, "1Y", "TARGET", conv, conv, rule));
136
137 // Leg variables
138 string dc = "ACT/ACT";
139 vector<Real> notional(1, 10000000);
140 string paymentConvention = "F";
141
142 // EUR YoY Leg
143 bool isPayerYY = false;
144 string indexYY = "EUHICPXT";
145 string lag = "3M";
146 LegData legYY(QuantLib::ext::make_shared<YoYLegData>(indexYY, lag, 0), isPayerYY, "EUR", scheduleYY, dc, notional,
147 vector<string>(), paymentConvention, false, true);
148
149 std::vector<double> caps(1, 0.009);
150 // Build capfloor trades
151 QuantLib::ext::shared_ptr<Trade> yyCap(new ore::data::CapFloor(env, "Long", legYY, caps, std::vector<double>()));
152
153 // engine data and factory
154 QuantLib::ext::shared_ptr<EngineData> engineData = QuantLib::ext::make_shared<EngineData>();
155 engineData->model("YYCapFloor") = "YYCapModel";
156 engineData->engine("YYCapFloor") = "YYCapEngine";
157 QuantLib::ext::shared_ptr<EngineFactory> engineFactory = QuantLib::ext::make_shared<EngineFactory>(engineData, market);
158
159 // build capfloor and portfolio
160 QuantLib::ext::shared_ptr<Portfolio> portfolio(new Portfolio());
161 yyCap->id() = "YoY_Cap";
162
163 portfolio->add(yyCap);
164 portfolio->build(engineFactory);
165
166 // check YoY cap NPV against pure QL pricing
167 Schedule schedule(startDate, endDate, 1 * Years, TARGET(), Following, Following, DateGeneration::Forward, false);
168 Handle<YieldTermStructure> nominalTs = market->discountCurve("EUR");
169 Leg yyLeg =
170 yoyInflationLeg(schedule, TARGET(), market->yoyInflationIndex("EUHICPXT").currentLink(), Period(3, Months))
171 .withNotionals(10000000)
172 .withPaymentDayCounter(ActualActual(ActualActual::ISDA))
173 .withPaymentAdjustment(Following)
174 .withRateCurve(nominalTs);
175
176 QuantLib::ext::shared_ptr<YoYInflationCapFloor> qlCap(new YoYInflationCap(yyLeg, caps));
177
178 Handle<QuantLib::YoYOptionletVolatilitySurface> hovs = market->yoyCapFloorVol("EUHICPXT");
179 auto dscEngine = QuantLib::ext::make_shared<YoYInflationBachelierCapFloorEngine>(
180 market->yoyInflationIndex("EUHICPXT").currentLink(), hovs, nominalTs);
181 qlCap->setPricingEngine(dscEngine);
182 BOOST_CHECK_CLOSE(yyCap->instrument()->NPV(), qlCap->NPV(), 1E-8); // this is 1E-10 rel diff
183 BOOST_CHECK_NO_THROW(yyCap->additionalData());
184}
185
186BOOST_AUTO_TEST_SUITE_END()
187
188BOOST_AUTO_TEST_SUITE_END()
Ibor cap, floor or collar trade data model and serialization.
yoyInflationLeg & withRateCurve(const Handle< YieldTermStructure > &rateCurve)
yoyInflationLeg & withPaymentAdjustment(BusinessDayConvention)
yoyInflationLeg & withNotionals(Real notional)
yoyInflationLeg & withPaymentDayCounter(const DayCounter &)
Serializable cap, floor, collar.
Definition: capfloor.hpp:37
Serializable object holding generic trade data, reporting dimensions.
Definition: envelope.hpp:51
Serializable object holding leg data.
Definition: legdata.hpp:844
static const string defaultConfiguration
Default configuration label.
Definition: market.hpp:296
Market Implementation.
Definition: marketimpl.hpp:53
map< tuple< string, YieldCurveType, string >, Handle< YieldTermStructure > > yieldCurves_
Definition: marketimpl.hpp:208
map< pair< string, string >, Handle< YoYOptionletVolatilitySurface > > yoyCapFloorVolSurfaces_
Definition: marketimpl.hpp:221
map< pair< string, string >, Handle< YoYInflationIndex > > yoyInflationIndices_
Definition: marketimpl.hpp:223
Serializable portfolio.
Definition: portfolio.hpp:43
Serializable schedule data.
Definition: schedule.hpp:202
Serializable object holding schedule Rules data.
Definition: schedule.hpp:37
A class to hold pricing engine parameters.
QuantLib::ext::shared_ptr< ZeroInflationIndex > parseZeroInflationIndex(const string &s, const Handle< ZeroInflationTermStructure > &h)
Convert std::string to QuantLib::ZeroInflationIndex.
Map text representations to QuantLib/QuantExt types.
BOOST_AUTO_TEST_CASE(testYoYCapFloor)
Classes and functions for log message handling.
An implementation of the Market class that stores the required objects in maps.
Engine builder for year-on-year inflation caps/floors.
Portfolio class.