Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
fxswap.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2016 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#include <boost/test/unit_test.hpp>
26#include <oret/toplevelfixture.hpp>
27#include <ql/termstructures/volatility/equityfx/blackconstantvol.hpp>
28#include <ql/termstructures/yield/flatforward.hpp>
29#include <ql/time/daycounters/actualactual.hpp>
30
31using namespace QuantLib;
32using namespace boost::unit_test_framework;
33using namespace std;
34using namespace ore::data;
35using namespace ore::data;
36using namespace ore::data;
37
38// FX Swap test
39namespace {
40
41class TestMarket : public MarketImpl {
42public:
43 TestMarket() : MarketImpl(false) {
44 asof_ = Date(3, Feb, 2015);
45
46 QuantLib::ext::shared_ptr<Conventions> conventions = InstrumentConventions::instance().conventions();
47
48 // add conventions
49 QuantLib::ext::shared_ptr<ore::data::Convention> usdChfConv(
50 new ore::data::FXConvention("USD-CHF-FX", "0", "USD", "CHF", "10000", "USD,CHF"));
51 QuantLib::ext::shared_ptr<ore::data::Convention> usdGbpConv(
52 new ore::data::FXConvention("USD-GBP-FX", "0", "USD", "GBP", "10000", "USD,GBP"));
53 QuantLib::ext::shared_ptr<ore::data::Convention> usdEurConv(
54 new ore::data::FXConvention("USD-EUR-FX", "0", "USD", "EUR", "10000", "USD,EUR"));
55
56 conventions->add(usdChfConv);
57 conventions->add(usdGbpConv);
58 conventions->add(usdEurConv);
59 InstrumentConventions::instance().setConventions(conventions);
60
61 // build discount
62 yieldCurves_[make_tuple(Market::defaultConfiguration, YieldCurveType::Discount, "EUR")] = flatRateYts(0.02);
63 yieldCurves_[make_tuple(Market::defaultConfiguration, YieldCurveType::Discount, "USD")] = flatRateYts(0.03);
64 yieldCurves_[make_tuple(Market::defaultConfiguration, YieldCurveType::Discount, "CHF")] = flatRateYts(0.04);
65 yieldCurves_[make_tuple(Market::defaultConfiguration, YieldCurveType::Discount, "GBP")] = flatRateYts(0.05);
66
67 // add fx rates
68 std::map<std::string, Handle<Quote>> quotes;
69 quotes["EURUSD"] = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(1.2));
70 quotes["EURGBP"] = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(1.4));
71 quotes["EURCHF"] = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(1.3));
72 fx_ = QuantLib::ext::make_shared<FXTriangulation>(quotes);
73
74 // build fx vols
75 fxVols_[make_pair(Market::defaultConfiguration, "EURUSD")] = flatRateFxv(0.10);
76 fxVols_[make_pair(Market::defaultConfiguration, "EURCHF")] = flatRateFxv(0.20);
77 fxVols_[make_pair(Market::defaultConfiguration, "EURGBP")] = flatRateFxv(0.20);
78 }
79
80private:
81 Handle<YieldTermStructure> flatRateYts(Real forward) {
82 QuantLib::ext::shared_ptr<YieldTermStructure> yts(new FlatForward(0, NullCalendar(), forward, ActualActual(ActualActual::ISDA)));
83 return Handle<YieldTermStructure>(yts);
84 }
85 Handle<BlackVolTermStructure> flatRateFxv(Volatility forward) {
86 QuantLib::ext::shared_ptr<BlackVolTermStructure> fxv(new BlackConstantVol(0, NullCalendar(), forward, ActualActual(ActualActual::ISDA)));
87 return Handle<BlackVolTermStructure>(fxv);
88 }
89};
90} // namespace
91
92namespace {
93
94void test(string nearDate, string farDate, string nearBoughtCurrency, double nearBoughtAmount, string nearSoldCurrency,
95 double nearSoldAmount, double farBoughtAmount, double farSoldAmount, const QuantLib::ext::shared_ptr<Market>& market) {
96
97 // build market
98 Settings::instance().evaluationDate() = market->asofDate();
99 // fxswap's npv should equal that of two separate fxforwards
100 // build first fxforward
101 Envelope env1("FxForward1");
102
103 QuantLib::ext::shared_ptr<EngineData> engineData = QuantLib::ext::make_shared<EngineData>();
104 engineData->model("FxForward") = "DiscountedCashflows";
105 engineData->engine("FxForward") = "DiscountingFxForwardEngine";
106 QuantLib::ext::shared_ptr<EngineFactory> engineFactory = QuantLib::ext::make_shared<EngineFactory>(engineData, market);
107 // this trade has buyer and seller switched so that it returns it's npv in the same currency as the second forward
108 // fxswap_npv= - fxfor1_npv + fxfor2_npv
109 FxForward fxFor1(env1, nearDate, nearSoldCurrency, nearSoldAmount, nearBoughtCurrency, nearBoughtAmount);
110
111 fxFor1.build(engineFactory);
112
113 // build second fxforward
114 Envelope env2("FxForward2");
115 FxForward fxFor2(env2, farDate, nearSoldCurrency, farBoughtAmount, nearBoughtCurrency, farSoldAmount);
116 fxFor2.build(engineFactory);
117
118 // build fx swap
119
120 Envelope env3("FxSwap");
121
122 FxSwap fxswap(env3, nearDate, farDate, nearBoughtCurrency, nearBoughtAmount, nearSoldCurrency, nearSoldAmount,
123 farBoughtAmount, farSoldAmount);
124 fxswap.build(engineFactory);
125 fxswap.instrument()->NPV();
126 Real fx1 = fxFor1.instrument()->NPV();
127 Real fx2 = fxFor2.instrument()->NPV();
128 Real npvForward = fx2 - fx1;
129 if (fxswap.instrument()->NPV() != npvForward)
130 BOOST_FAIL("The FxSwap has NPV: " << fxswap.instrument()->NPV()
131 << ", which does not equal the sum of two Fxforwards: " << npvForward);
132}
133} // namespace
134
135BOOST_FIXTURE_TEST_SUITE(OREDataTestSuite, ore::test::TopLevelFixture)
136
137BOOST_AUTO_TEST_SUITE(FXSwapTests)
138
140
141 BOOST_TEST_MESSAGE("Testing FXSwap...");
142
143 QuantLib::ext::shared_ptr<Market> market = QuantLib::ext::make_shared<TestMarket>();
144
145 string nearDate = "2015-10-27";
146 string farDate = "2015-11-03";
147 string nearBoughtCurrency = "EUR";
148 Real nearBoughtAmount = 224557621.490000;
149 string nearSoldCurrency = "USD";
150 Real nearSoldAmount = 250000000.000000;
151 Real farBoughtAmount = 250018000.00;
152 Real farSoldAmount = 224552207.77;
153
154 test(nearDate, farDate, nearBoughtCurrency, nearBoughtAmount, nearSoldCurrency, nearSoldAmount, farBoughtAmount,
155 farSoldAmount, market);
156
157 nearDate = "2015-07-14";
158 farDate = "2015-11-16";
159 nearBoughtCurrency = "CHF";
160 nearBoughtAmount = 97000000;
161 nearSoldCurrency = "USD";
162 nearSoldAmount = 103718911.06;
163 farBoughtAmount = 103923787.150000;
164 farSoldAmount = 96737000.000000;
165
166 test(nearDate, farDate, nearBoughtCurrency, nearBoughtAmount, nearSoldCurrency, nearSoldAmount, farBoughtAmount,
167 farSoldAmount, market);
168
169 nearDate = "2015-08-04";
170 farDate = "2015-11-30";
171 nearBoughtCurrency = "GBP";
172 nearBoughtAmount = 100227439.19;
173 nearSoldCurrency = "USD";
174 nearSoldAmount = 156000000;
175 farBoughtAmount = 156148000.000000;
176 farSoldAmount = 100400372.110000;
177
178 test(nearDate, farDate, nearBoughtCurrency, nearBoughtAmount, nearSoldCurrency, nearSoldAmount, farBoughtAmount,
179 farSoldAmount, market);
180}
181
182BOOST_AUTO_TEST_SUITE_END()
183
184BOOST_AUTO_TEST_SUITE_END()
Serializable object holding generic trade data, reporting dimensions.
Definition: envelope.hpp:51
Container for storing FX Spot quote conventions.
Serializable FX Swap.
Definition: fxswap.hpp:36
static const string defaultConfiguration
Default configuration label.
Definition: market.hpp:296
Market Implementation.
Definition: marketimpl.hpp:53
map< pair< string, string >, Handle< BlackVolTermStructure > > fxVols_
Definition: marketimpl.hpp:214
QuantLib::ext::shared_ptr< FXTriangulation > fx_
Definition: marketimpl.hpp:206
map< tuple< string, YieldCurveType, string >, Handle< YieldTermStructure > > yieldCurves_
Definition: marketimpl.hpp:208
A class to hold pricing engine parameters.
FX Forward data model and serialization.
FX Option data model and serialization.
FX Swap data model and serialization.
An implementation of the Market class that stores the required objects in maps.
BOOST_AUTO_TEST_CASE(testFXSwap)
Definition: fxswap.cpp:139