Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Functions
cpiswap.cpp File Reference
#include <boost/make_shared.hpp>
#include <boost/test/unit_test.hpp>
#include <ored/marketdata/marketimpl.hpp>
#include <ored/portfolio/builders/swap.hpp>
#include <ored/portfolio/enginedata.hpp>
#include <ored/portfolio/portfolio.hpp>
#include <ored/portfolio/swap.hpp>
#include <ored/utilities/indexparser.hpp>
#include <ored/utilities/log.hpp>
#include <oret/toplevelfixture.hpp>
#include <ql/cashflows/cpicoupon.hpp>
#include <ql/cashflows/cpicouponpricer.hpp>
#include <ql/cashflows/iborcoupon.hpp>
#include <ql/indexes/inflation/ukrpi.hpp>
#include <ql/termstructures/inflation/inflationhelpers.hpp>
#include <ql/termstructures/inflation/piecewisezeroinflationcurve.hpp>
#include <ql/termstructures/yield/discountcurve.hpp>
#include <ql/time/calendars/unitedkingdom.hpp>
#include <ql/time/daycounters/actual365fixed.hpp>
#include <ql/time/daycounters/actualactual.hpp>

Go to the source code of this file.

Functions

 BOOST_AUTO_TEST_CASE (testCPISwapPrice)
 

Function Documentation

◆ BOOST_AUTO_TEST_CASE()

BOOST_AUTO_TEST_CASE ( testCPISwapPrice  )

Definition at line 180 of file cpiswap.cpp.

180 {
181
182 BOOST_TEST_MESSAGE("Testing CPI Swap Price...");
183
184 // build market
185 Date today(18, July, 2016);
186 Settings::instance().evaluationDate() = today;
187 QuantLib::ext::shared_ptr<TestMarket> market = QuantLib::ext::make_shared<TestMarket>();
188 Date marketDate = market->asofDate();
189 BOOST_CHECK_EQUAL(today, marketDate);
190 Settings::instance().evaluationDate() = marketDate;
191
192 // Test if GBP discount curve is empty
193 Handle<YieldTermStructure> dts = market->discountCurve("GBP");
194 QL_REQUIRE(!dts.empty(), "GBP discount curve not found");
195 BOOST_CHECK_CLOSE(market->discountCurve("GBP")->discount(today + 1 * Years), 0.9914, 0.0001);
196
197 // Test if GBP Libor curve is empty
198 Handle<IborIndex> iis = market->iborIndex("GBP-LIBOR-6M");
199 QL_REQUIRE(!iis.empty(), "GBP LIBOR 6M ibor Index not found");
200 BOOST_TEST_MESSAGE(
201 "CPISwap: Projected Libor fixing: " << market->iborIndex("GBP-LIBOR-6M")->forecastFixing(today + 1 * Years));
202
203 // Test if GBP discount curve is empty
204 Handle<ZeroInflationIndex> infidx = market->zeroInflationIndex("UKRPI");
205 QL_REQUIRE(!infidx.empty(), "UKRPI inflation index not found");
206 BOOST_TEST_MESSAGE("CPISwap: Projected UKRPI rate: " << infidx->fixing(today + 1 * Years));
207
208 // envelope
209 Envelope env("CP");
210
211 // Start/End date
212 Date startDate = today;
213 Date endDate = today + 5 * Years;
214
215 // date 2 string
216 std::ostringstream oss;
217 oss << io::iso_date(startDate);
218 string start(oss.str());
219 oss.str("");
220 oss.clear();
221 oss << io::iso_date(endDate);
222 string end(oss.str());
223
224 // Schedules
225 string conv = "MF";
226 string rule = "Forward";
227 ScheduleData scheduleLibor(ScheduleRules(start, end, "6M", "UK", conv, conv, rule));
228 ScheduleData scheduleCPI(ScheduleRules(start, end, "1Y", "UK", conv, conv, rule));
229
230 // Leg variables
231 bool isInArrears = false;
232 string dc = "ACT/ACT";
233 vector<Real> notional(1, 10000000);
234 string paymentConvention = "F";
235
236 // GBP Libor Leg
237 bool isPayerLibor = true;
238 string indexLibor = "GBP-LIBOR-6M";
239 vector<Real> spread(1, 0);
240 LegData legLibor(QuantLib::ext::make_shared<FloatingLegData>(indexLibor, 0, isInArrears, spread), isPayerLibor, "GBP",
241 scheduleLibor, "A365F", notional, vector<string>(), paymentConvention);
242
243 // GBP CPI Leg
244 bool isPayerCPI = false;
245 string indexCPI = "UKRPI";
246 Real baseCPI = 210.0;
247 string CPIlag = "2M";
248 std::vector<double> fixedRate(1, 0.02);
249 bool interpolated = false;
250 LegData legCPI(
251 QuantLib::ext::make_shared<CPILegData>(indexCPI, start, baseCPI, CPIlag, (interpolated ? "Linear" : "Flat"), fixedRate),
252 isPayerCPI, "GBP", scheduleCPI, dc, notional, vector<string>(), paymentConvention, false, true);
253
254 // Build swap trades
255 QuantLib::ext::shared_ptr<Trade> CPIswap(new ore::data::Swap(env, legLibor, legCPI));
256
257 // engine data and factory
258 QuantLib::ext::shared_ptr<EngineData> engineData = QuantLib::ext::make_shared<EngineData>();
259 engineData->model("Swap") = "DiscountedCashflows";
260 engineData->engine("Swap") = "DiscountingSwapEngine";
261 QuantLib::ext::shared_ptr<EngineFactory> engineFactory = QuantLib::ext::make_shared<EngineFactory>(engineData, market);
262
263 // build swaps and portfolio
264 QuantLib::ext::shared_ptr<Portfolio> portfolio(new Portfolio());
265 CPIswap->id() = "CPI_Swap";
266
267 portfolio->add(CPIswap);
268 portfolio->build(engineFactory);
269
270 // check CPI swap NPV against pure QL pricing
271 Schedule floatSchedule(startDate, endDate, 6 * Months, UnitedKingdom(), ModifiedFollowing, ModifiedFollowing,
272 DateGeneration::Forward, false);
273 Schedule cpiSchedule(startDate, endDate, 1 * Years, UnitedKingdom(), ModifiedFollowing, ModifiedFollowing,
274 DateGeneration::Forward, false);
275 Leg floatLeg = IborLeg(floatSchedule, *market->hGBP).withNotionals(10000000.0);
276 Leg cpiLeg = CPILeg(cpiSchedule, *market->hUKRPI, baseCPI, 2 * Months)
277 .withFixedRates(0.02)
278 .withNotionals(10000000)
280 .withPaymentDayCounter(ActualActual(ActualActual::ISDA))
281 .withPaymentAdjustment(Following);
282 auto pricer = QuantLib::ext::make_shared<CPICouponPricer>(market->hGBP->forwardingTermStructure());
283 for (auto const& c : cpiLeg) {
284 if (auto cpn = QuantLib::ext::dynamic_pointer_cast<CPICoupon>(c))
285 cpn->setPricer(pricer);
286 }
287
288 QuantLib::Swap qlSwap(floatLeg, cpiLeg);
289 auto dscEngine = QuantLib::ext::make_shared<DiscountingSwapEngine>(market->hGBP->forwardingTermStructure());
290 qlSwap.setPricingEngine(dscEngine);
291 BOOST_TEST_MESSAGE("Leg 1 NPV: ORE = "
292 << QuantLib::ext::static_pointer_cast<QuantLib::Swap>(CPIswap->instrument()->qlInstrument())->legNPV(0)
293 << " QL = " << qlSwap.legNPV(0));
294 BOOST_TEST_MESSAGE("Leg 2 NPV: ORE = "
295 << QuantLib::ext::static_pointer_cast<QuantLib::Swap>(CPIswap->instrument()->qlInstrument())->legNPV(1)
296 << " QL = " << qlSwap.legNPV(1));
297 BOOST_CHECK_CLOSE(CPIswap->instrument()->NPV(), qlSwap.NPV(), 1E-8); // this is 1E-10 rel diff
298}
CPILeg & withNotionals(Real notional)
CPILeg & withPaymentAdjustment(BusinessDayConvention)
CPILeg & withFixedRates(Real fixedRate)
CPILeg & withPaymentDayCounter(const DayCounter &)
CPILeg & withObservationInterpolation(CPI::InterpolationType)
Serializable object holding generic trade data, reporting dimensions.
Definition: envelope.hpp:51
Serializable object holding leg data.
Definition: legdata.hpp:844
Serializable portfolio.
Definition: portfolio.hpp:43
Serializable schedule data.
Definition: schedule.hpp:202
Serializable object holding schedule Rules data.
Definition: schedule.hpp:37
Serializable Swap, Single and Cross Currency.
Definition: swap.hpp:36
+ Here is the call graph for this function: