19#include <boost/make_shared.hpp>
20#include <boost/test/unit_test.hpp>
27#include <oret/toplevelfixture.hpp>
28#include <ql/cashflows/iborcoupon.hpp>
29#include <ql/termstructures/yield/discountcurve.hpp>
30#include <ql/termstructures/yield/flatforward.hpp>
31#include <ql/time/calendars/unitedstates.hpp>
32#include <ql/time/daycounters/actual365fixed.hpp>
33#include <ql/time/daycounters/actualactual.hpp>
39using namespace boost::unit_test_framework;
49 asof_ = Date(18, July, 2016);
51 spotSP5 = Handle<Quote>(QuantLib::ext::shared_ptr<SimpleQuote>(
new SimpleQuote(2100)));
52 forecastSP5 = flatRateYts(0.03);
53 dividendSP5 = flatRateYts(0.01);
61 hUSD = Handle<IborIndex>(
parseIborIndex(
"USD-LIBOR-3M", flatRateYts(0.035)));
65 hSP5 = Handle<EquityIndex2>(QuantLib::ext::shared_ptr<EquityIndex2>(
66 new EquityIndex2(
"SP5", UnitedStates(UnitedStates::Settlement),
parseCurrency(
"USD"), spotSP5, forecastSP5, dividendSP5)));
68 IndexNameTranslator::instance().add(hSP5->name(),
"EQ-" + hSP5->name());
71 hUSD->addFixing(Date(14, July, 2016), 0.035);
72 hUSD->addFixing(Date(18, October, 2016), 0.037);
73 hSP5->addFixing(Date(18, October, 2016), 2100.0);
76 Handle<IborIndex> hUSD;
77 Handle<EquityIndex2> hSP5;
78 Handle<Quote> spotSP5;
79 Handle<YieldTermStructure> forecastSP5;
80 Handle<YieldTermStructure> dividendSP5;
83 Handle<YieldTermStructure> flatRateYts(Real forward) {
84 QuantLib::ext::shared_ptr<YieldTermStructure> yts(
new FlatForward(0, UnitedStates(UnitedStates::Settlement), forward, ActualActual(ActualActual::ISDA)));
85 return Handle<YieldTermStructure>(yts);
106 Integer settlementDays;
108 vector<double> notionals;
109 vector<double> spread;
112 QuantLib::ext::shared_ptr<ore::data::Swap> makeEquitySwap(
EquityReturnType returnType,
bool notionalReset =
false) {
117 LegData floatLegData(QuantLib::ext::make_shared<FloatingLegData>(index, days, isinarrears, spread), !isPayer, ccy,
118 floatSchedule, fixDC, notionals);
119 LegData eqLegData(QuantLib::ext::make_shared<EquityLegData>(returnType, dividendFactor,
EquityUnderlying(eqName),
120 initialPrice, notionalReset, settlementDays),
121 isPayer, ccy, eqSchedule, fixDC, notionals);
124 QuantLib::ext::shared_ptr<ore::data::Swap> swap(
new ore::data::Swap(env, eqLegData, floatLegData));
128 QuantLib::ext::shared_ptr<QuantLib::Swap> qlEquitySwap(
EquityReturnType returnType,
bool notionalReset =
false) {
130 QuantLib::ext::shared_ptr<TestMarket> market = QuantLib::ext::make_shared<TestMarket>();
138 Leg floatLeg = IborLeg(floatSchedule, *market->hUSD)
139 .withNotionals(notionals)
140 .withFixingDays(days)
144 Leg eqLeg =
EquityLeg(eqSchedule, *market->equityCurve(
"SP5"))
152 QuantLib::ext::shared_ptr<QuantLib::Swap> swap(
new QuantLib::Swap(floatLeg, eqLeg));
167 index =
"USD-LIBOR-3M";
169 dividendFactor = 1.0;
170 initialPrice = 2100.0;
174 notionals.push_back(10000000);
175 spread.push_back(0.0);
181BOOST_FIXTURE_TEST_SUITE(OREDataTestSuite, ore::test::TopLevelFixture)
183BOOST_AUTO_TEST_SUITE(EquitySwapTests)
187 BOOST_TEST_MESSAGE(
"Testing Equity Swap Price Return...");
190 QuantLib::ext::shared_ptr<TestMarket> market = QuantLib::ext::make_shared<TestMarket>();
191 Date today = market->asofDate();
192 Settings::instance().evaluationDate() = today;
195 QuantLib::ext::shared_ptr<ore::data::Swap> eqSwap = vars.makeEquitySwap(EquityReturnType::Price);
198 QuantLib::ext::shared_ptr<EngineData> engineData = QuantLib::ext::make_shared<EngineData>();
199 engineData->model(
"Swap") =
"DiscountedCashflows";
200 engineData->engine(
"Swap") =
"DiscountingSwapEngine";
201 QuantLib::ext::shared_ptr<EngineFactory> engineFactory = QuantLib::ext::make_shared<EngineFactory>(engineData, market);
204 QuantLib::ext::shared_ptr<Portfolio> portfolio(
new Portfolio());
205 eqSwap->id() =
"EQ_Swap";
207 portfolio->add(eqSwap);
208 portfolio->build(engineFactory);
210 QuantLib::ext::shared_ptr<QuantLib::Swap> qlSwap = vars.qlEquitySwap(EquityReturnType::Price);
212 auto dscEngine = QuantLib::ext::make_shared<DiscountingSwapEngine>(market->discountCurve(
"USD"));
213 qlSwap->setPricingEngine(dscEngine);
214 BOOST_TEST_MESSAGE(
"Leg 1 NPV: ORE = "
215 << QuantLib::ext::static_pointer_cast<QuantLib::Swap>(eqSwap->instrument()->qlInstrument())->legNPV(0)
216 <<
" QL = " << qlSwap->legNPV(0));
217 BOOST_TEST_MESSAGE(
"Leg 2 NPV: ORE = "
218 << QuantLib::ext::static_pointer_cast<QuantLib::Swap>(eqSwap->instrument()->qlInstrument())->legNPV(1)
219 <<
" QL = " << qlSwap->legNPV(1));
220 BOOST_CHECK_CLOSE(eqSwap->instrument()->NPV(), qlSwap->NPV(), 1E-8);
225 BOOST_TEST_MESSAGE(
"Testing Equity Swap Total Return...");
228 QuantLib::ext::shared_ptr<TestMarket> market = QuantLib::ext::make_shared<TestMarket>();
229 Date today = market->asofDate();
230 Settings::instance().evaluationDate() = today;
233 QuantLib::ext::shared_ptr<ore::data::Swap> eqSwap = vars.makeEquitySwap(EquityReturnType::Total);
236 QuantLib::ext::shared_ptr<EngineData> engineData = QuantLib::ext::make_shared<EngineData>();
237 engineData->model(
"Swap") =
"DiscountedCashflows";
238 engineData->engine(
"Swap") =
"DiscountingSwapEngine";
239 QuantLib::ext::shared_ptr<EngineFactory> engineFactory = QuantLib::ext::make_shared<EngineFactory>(engineData, market);
242 QuantLib::ext::shared_ptr<Portfolio> portfolio(
new Portfolio());
243 eqSwap->id() =
"EQ_Swap";
245 portfolio->add(eqSwap);
246 portfolio->build(engineFactory);
248 QuantLib::ext::shared_ptr<QuantLib::Swap> qlSwap = vars.qlEquitySwap(EquityReturnType::Total);
250 auto dscEngine = QuantLib::ext::make_shared<DiscountingSwapEngine>(market->discountCurve(
"USD"));
251 qlSwap->setPricingEngine(dscEngine);
252 BOOST_TEST_MESSAGE(
"Leg 1 NPV: ORE = "
253 << QuantLib::ext::static_pointer_cast<QuantLib::Swap>(eqSwap->instrument()->qlInstrument())->legNPV(0)
254 <<
" QL = " << qlSwap->legNPV(0));
255 BOOST_TEST_MESSAGE(
"Leg 2 NPV: ORE = "
256 << QuantLib::ext::static_pointer_cast<QuantLib::Swap>(eqSwap->instrument()->qlInstrument())->legNPV(1)
257 <<
" QL = " << qlSwap->legNPV(1));
258 BOOST_CHECK_CLOSE(eqSwap->instrument()->NPV(), qlSwap->NPV(), 1E-8);
263 BOOST_TEST_MESSAGE(
"Testing Equity Swap Notional Reset...");
266 QuantLib::ext::shared_ptr<TestMarket> market = QuantLib::ext::make_shared<TestMarket>();
267 Date today = market->asofDate();
269 Settings::instance().evaluationDate() = today + Period(4, Months);
272 QuantLib::ext::shared_ptr<ore::data::Swap> eqSwap = vars.makeEquitySwap(EquityReturnType::Total,
true);
275 QuantLib::ext::shared_ptr<EngineData> engineData = QuantLib::ext::make_shared<EngineData>();
276 engineData->model(
"Swap") =
"DiscountedCashflows";
277 engineData->engine(
"Swap") =
"DiscountingSwapEngine";
278 QuantLib::ext::shared_ptr<EngineFactory> engineFactory = QuantLib::ext::make_shared<EngineFactory>(engineData, market);
281 QuantLib::ext::shared_ptr<Portfolio> portfolio(
new Portfolio());
282 eqSwap->id() =
"EQ_Swap";
284 portfolio->add(eqSwap);
285 portfolio->build(engineFactory);
287 QuantLib::ext::shared_ptr<QuantLib::Swap> qlSwap = vars.qlEquitySwap(EquityReturnType::Total,
true);
289 BOOST_TEST_MESSAGE(
"Initial notional = " << eqSwap->notional());
292 market->equityCurve(
"SP5")->addFixing(Date(18, October, 2016), 2100);
294 auto dscEngine = QuantLib::ext::make_shared<DiscountingSwapEngine>(market->discountCurve(
"USD"));
295 qlSwap->setPricingEngine(dscEngine);
296 BOOST_TEST_MESSAGE(
"Leg 1 NPV: ORE = "
297 << QuantLib::ext::static_pointer_cast<QuantLib::Swap>(eqSwap->instrument()->qlInstrument())->legNPV(0)
298 <<
" QL = " << qlSwap->legNPV(0));
299 BOOST_TEST_MESSAGE(
"Leg 2 NPV: ORE = "
300 << QuantLib::ext::static_pointer_cast<QuantLib::Swap>(eqSwap->instrument()->qlInstrument())->legNPV(1)
301 <<
" QL = " << qlSwap->legNPV(1));
302 BOOST_CHECK_CLOSE(eqSwap->instrument()->NPV(), qlSwap->NPV(), 1E-8);
305BOOST_AUTO_TEST_SUITE_END()
307BOOST_AUTO_TEST_SUITE_END()
Engine builder for Swaps.
EquityLeg & withNotionalReset(bool)
EquityLeg & withNotionals(const std::vector< Real > ¬ionals)
EquityLeg & withInitialPrice(Real)
EquityLeg & withPaymentDayCounter(const DayCounter &dayCounter)
EquityLeg & withPaymentAdjustment(BusinessDayConvention convention)
EquityLeg & withReturnType(EquityReturnType)
Serializable object holding generic trade data, reporting dimensions.
Serializable object holding leg data.
static const string defaultConfiguration
Default configuration label.
map< pair< string, string >, QuantLib::Handle< QuantExt::EquityIndex2 > > equityCurves_
map< tuple< string, YieldCurveType, string >, Handle< YieldTermStructure > > yieldCurves_
map< pair< string, string >, Handle< IborIndex > > iborIndices_
Serializable schedule data.
Serializable object holding schedule Rules data.
Serializable Swap, Single and Cross Currency.
A class to hold pricing engine parameters.
DateGeneration::Rule parseDateGenerationRule(const string &s)
Convert text to QuantLib::DateGeneration::Rule.
Calendar parseCalendar(const string &s)
Convert text to QuantLib::Calendar.
QuantLib::ext::shared_ptr< IborIndex > parseIborIndex(const string &s, const Handle< YieldTermStructure > &h)
Convert std::string to QuantLib::IborIndex.
Date parseDate(const string &s)
Convert std::string to QuantLib::Date.
Currency parseCurrency(const string &s)
Convert text to QuantLib::Currency.
BusinessDayConvention parseBusinessDayConvention(const string &s)
Convert text to QuantLib::BusinessDayConvention.
Period parsePeriod(const string &s)
Convert text to QuantLib::Period.
DayCounter parseDayCounter(const string &s)
Convert text to QuantLib::DayCounter.
Map text representations to QuantLib/QuantExt types.
An implementation of the Market class that stores the required objects in maps.
Swap trade data model and serialization.
BOOST_AUTO_TEST_CASE(testEquitySwapPriceReturn)