Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
cpicapfloor.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2019 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 <boost/make_shared.hpp>
20// clang-format off
21#include <boost/test/unit_test.hpp>
22#include <boost/test/data/test_case.hpp>
23// clang-format on
35#include <oret/datapaths.hpp>
36#include <oret/toplevelfixture.hpp>
37#include <tuple>
38
39using namespace QuantLib;
40using namespace boost::unit_test_framework;
41using namespace std;
42using namespace ore::data;
43
44using ore::test::TopLevelFixture;
45
47
48namespace {
49
50// Fixture used in test case below:
51// - sets a specific valuation date for the test
52// - provides conventions
53// - provides an engine factory for the test
54class F : public TopLevelFixture {
55public:
56 Date today;
57 QuantLib::ext::shared_ptr<Conventions> conventions = QuantLib::ext::make_shared<Conventions>();
58 QuantLib::ext::shared_ptr<EngineFactory> engineFactory;
59
60 F() {
61 today = Date(31, Dec, 2018);
62 Settings::instance().evaluationDate() = today;
63
64 conventions->fromFile(TEST_INPUT_FILE("conventions.xml"));
65 InstrumentConventions::instance().setConventions(conventions);
66
67 auto todaysMarketParams = QuantLib::ext::make_shared<TodaysMarketParameters>();
68 todaysMarketParams->fromFile(TEST_INPUT_FILE("todaysmarket.xml"));
69
70 auto curveConfigs = QuantLib::ext::make_shared<CurveConfigurations>();
71 curveConfigs->fromFile(TEST_INPUT_FILE("curveconfig.xml"));
72
73 string marketFile = TEST_INPUT_FILE("market.txt");
74 string fixingsFile = TEST_INPUT_FILE("fixings.txt");
75 auto loader = QuantLib::ext::make_shared<CSVLoader>(marketFile, fixingsFile, false);
76
77 bool continueOnError = false;
78 QuantLib::ext::shared_ptr<TodaysMarket> market = QuantLib::ext::make_shared<TodaysMarket>(
79 today, todaysMarketParams, loader, curveConfigs, continueOnError);
80
81 QuantLib::ext::shared_ptr<EngineData> engineData = QuantLib::ext::make_shared<EngineData>();
82 engineData->fromFile(TEST_INPUT_FILE("pricingengine.xml"));
83
84 engineFactory = QuantLib::ext::make_shared<EngineFactory>(engineData, market);
85
86 // Log::instance().registerLogger(QuantLib::ext::make_shared<FileLogger>(TEST_OUTPUT_FILE("log.txt")));
87 // Log::instance().setMask(255);
88 // Log::instance().switchOn();
89 }
90
91 ~F() {}
92};
93
94// Portfolios, designed such that trade NPVs should add up to zero
95// The first two cases consist of three trades:
96// 1) CPI Swap receiving a single zero coupon fixed flow and paying a single indexed redemption flow (resp. CPI coupons
97// plus indexed redemption)
98// 2) CPI Swap as above with capped indexed flow and flipped legs: pay zero coupon fixed, receive
99// capped indexed redemption (resp. capped CPI coupons plus capped indexed redemption), i.e. short embedded cap(s)
100// 3) standalone long CPI cap with indexed flow(s) above as underlying
101// The third portfolio has two trades
102// 1) A CPI Cap as CapFloor instrument
103// 2) A CPI Cap as Swap with a single CPI leg and "naked" option set to "Y"
104
105vector<string> testCases = {"portfolio_singleflow.xml", "portfolio_multiflow.xml", "portfolio_multiflow_naked.xml"};
106
107} // namespace
108
109BOOST_FIXTURE_TEST_SUITE(OREDataTestSuite, ore::test::TopLevelFixture)
110
111BOOST_AUTO_TEST_SUITE(CPICapFloorTests)
112
113BOOST_DATA_TEST_CASE_F(F, testCapConsistency, bdata::make(testCases), testCase) {
114
115 BOOST_TEST_MESSAGE("Testing " << testCase);
116
117 Portfolio p;
118 p.fromFile(TEST_INPUT_FILE(testCase));
119 Size n = p.size();
120
121 // Build the portfolio
122 p.build(engineFactory);
123 BOOST_CHECK_MESSAGE(p.size() == n, n << " trades expected after build, found " << p.size());
124 for (const auto& [tradeId, trade] : p.trades()) {
125 BOOST_TEST_MESSAGE("trade " << tradeId);
126 }
127
128 // Portfolios are designed such that trade NPVs should add up to zero
129 Real sum = 0.0;
130 Real minimumNPV = QL_MAX_REAL;
131 for (const auto& [tradeId, trade] : p.trades()) {
132 BOOST_CHECK_NO_THROW(trade->instrument()->NPV());
133 BOOST_TEST_MESSAGE("trade " << tradeId << " npv " << trade->instrument()->NPV());
134 sum += trade->instrument()->NPV();
135 minimumNPV = std::min(minimumNPV, fabs(trade->instrument()->NPV()));
136 auto cf = QuantLib::ext::dynamic_pointer_cast<ore::data::CapFloor>(trade);
137 if (cf)
138 BOOST_CHECK_NO_THROW(cf->additionalData());
139 }
140 BOOST_TEST_MESSAGE("minimum absolute NPV = " << minimumNPV);
141 Real tolerance = 1.0e-8 * minimumNPV;
142 BOOST_TEST_MESSAGE("tolerance = " << tolerance);
143 BOOST_TEST_MESSAGE("NPV sum = " << sum);
144 BOOST_CHECK_MESSAGE(fabs(sum) < tolerance, "portfolio NPV should be zero, found " << sum);
145}
146
147BOOST_AUTO_TEST_SUITE_END()
148
149BOOST_AUTO_TEST_SUITE_END()
Ibor cap, floor or collar trade data model and serialization.
BOOST_DATA_TEST_CASE_F(CommonVars, testCapFloorTermVolCurveInterpolation, bdata::make(interpolationTypes) *bdata::make(isMovingValues) *bdata::make(flatFirstPeriodValues), interpolationType, isMoving, flatFirstPeriod)
Serializable portfolio.
Definition: portfolio.hpp:43
const std::map< std::string, QuantLib::ext::shared_ptr< Trade > > & trades() const
Return the map tradeId -> trade.
Definition: portfolio.cpp:162
QuantLib::Size size() const
Portfolio size.
Definition: portfolio.hpp:68
void build(const QuantLib::ext::shared_ptr< EngineFactory > &, const std::string &context="unspecified", const bool emitStructuredError=true)
Call build on all trades in the portfolio, the context is included in error messages.
Definition: portfolio.cpp:122
void fromFile(const std::string &filename)
Definition: xmlutils.cpp:150
Currency and instrument specific conventions/defaults.
utility class to access CSV files
Market Datum Loader Implementation.
Curve configuration repository.
Pricing Engine Factory.
Real sum(const Cash &c, const Cash &d)
Portfolio class.
vector< string > curveConfigs
string conversion utilities
An concrete implementation of the Market class that loads todays market and builds the required curve...
A class to hold todays market configuration(s)