Skip to content

Commit d0ea9d4

Browse files
Sebastien Bouvardjenkins
authored andcommitted
QPR-12223 Unit Testing for pricing based on referencedata and XML and modification indent referencedata.xsd
1 parent 41d7574 commit d0ea9d4

4 files changed

Lines changed: 191 additions & 22 deletions

File tree

OREData/ored/portfolio/referencedata.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -508,8 +508,11 @@ XMLNode* PortfolioBasketReferenceDatum::toXML(XMLDocument& doc) const {
508508
XMLNode* node = ReferenceDatum::toXML(doc);
509509
XMLNode* rdNode = XMLUtils::addChild(doc, node, type() + "ReferenceData");
510510
XMLUtils::appendNode(node, rdNode);
511-
XMLUtils::addChild(doc, rdNode, "Components");
512-
//I need to add back the trade object but it is a shared_ptr Trade so need to convert into XML
511+
XMLNode* cNode = XMLUtils::addChild(doc, rdNode, "Components");
512+
for (auto& u : tradecomponents_) {
513+
auto test = u->toXML(doc);
514+
XMLUtils::appendNode(cNode, test);
515+
}
513516

514517
return node;
515518
}

OREData/test/compositetrade.cpp

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
#include <boost/make_shared.hpp>
2222
#include <boost/test/unit_test.hpp>
23+
#include <boost/test/data/test_case.hpp>
24+
#include <oret/datapaths.hpp>
2325
#include <ored/marketdata/marketimpl.hpp>
2426
#include <ored/portfolio/builders/equityforward.hpp>
2527
#include <ored/portfolio/builders/equityoption.hpp>
@@ -211,6 +213,103 @@ BOOST_AUTO_TEST_CASE(testMultiCcyComposite) {
211213
BOOST_CHECK_CLOSE(npv_usd_composite, npv_eurCall * 1.25 + npv_usdCall / 1.0, 0.01);
212214
}
213215

216+
BOOST_AUTO_TEST_CASE(testCompositeReferenceData) {
217+
BOOST_TEST_MESSAGE("Testing Composite Trade with and w/o reference data...");
218+
219+
SavedSettings backup;
220+
221+
InstrumentConventions::instance().setConventions(QuantLib::ext::make_shared<Conventions>());
222+
223+
// build CompositeTrade with referencedata
224+
auto rdm = QuantLib::ext::make_shared<BasicReferenceDataManager>(TEST_INPUT_FILE("reference_data.xml"));
225+
auto ptfReferenceDatum = boost::dynamic_pointer_cast<PortfolioBasketReferenceDatum>(rdm->getData("PortfolioBasket", "MSFDSJP"));
226+
auto refData = ptfReferenceDatum->getTrades();
227+
QuantLib::ext::shared_ptr<Trade> eqRefCall = refData[0];
228+
QuantLib::ext::shared_ptr<Trade> eqRefPut = refData[1];
229+
230+
Envelope env("CP1");
231+
CompositeTrade RefData("EUR", {eqRefCall, eqRefPut}, "Mean", 0.0, env);
232+
RefData.id() = "Reference Data Test";
233+
234+
// build market
235+
QuantLib::ext::shared_ptr<Market> market = QuantLib::ext::make_shared<TestMarket>();
236+
Settings::instance().evaluationDate() = market->asofDate();
237+
Date expiry = market->asofDate() + 6 * Months + 1 * Days;
238+
ostringstream o;
239+
o << QuantLib::io::iso_date(expiry);
240+
string exp_str = o.str();
241+
242+
// build CompositeTrade without referencedata
243+
OptionData callData("Long", "Call", "European", true, vector<string>(1, exp_str));
244+
OptionData putData("Short", "Put", "European", true, vector<string>(1, exp_str));
245+
//Envelope env("CP1");
246+
TradeStrike tradeStrike(95.0, "EUR");
247+
QuantLib::ext::shared_ptr<Trade> eqCall =
248+
QuantLib::ext::make_shared<EquityOption>(env, callData, EquityUnderlying("eurCorp"), "EUR", 1.0, tradeStrike);
249+
eqCall->id() = "Long Call";
250+
QuantLib::ext::shared_ptr<Trade> eqPut =
251+
QuantLib::ext::make_shared<EquityOption>(env, putData, EquityUnderlying("eurCorp"), "EUR", 1.0, tradeStrike);
252+
eqPut->id() = "Short Put";
253+
CompositeTrade noRefData("EUR", {eqCall, eqPut}, "Mean", 0.0, env);
254+
noRefData.id() = "No Reference Data Test";
255+
256+
// Build and price
257+
QuantLib::ext::shared_ptr<EngineData> engineData = QuantLib::ext::make_shared<EngineData>();
258+
engineData->model("EquityOption") = "BlackScholesMerton";
259+
engineData->engine("EquityOption") = "AnalyticEuropeanEngine";
260+
QuantLib::ext::shared_ptr<EngineFactory> engineFactory =
261+
QuantLib::ext::make_shared<EngineFactory>(engineData, market);
262+
263+
noRefData.build(engineFactory);
264+
RefData.build(engineFactory);
265+
266+
Real npv_composite_NoRefData = noRefData.instrument()->NPV();
267+
Real npv_composite_RefData = RefData.instrument()->NPV();
268+
269+
BOOST_CHECK_CLOSE(npv_composite_NoRefData, npv_composite_RefData, 0.01);
270+
BOOST_CHECK_CLOSE(noRefData.notional(), RefData.notional(), 0.01);
271+
}
272+
273+
BOOST_AUTO_TEST_CASE(testConstructionWithCompositeTradeReferenceData) {
274+
275+
// CompoiteTrade with Reference Data
276+
auto rdm = QuantLib::ext::make_shared<BasicReferenceDataManager>(TEST_INPUT_FILE("reference_data.xml"));
277+
auto ptfReferenceDatum =
278+
boost::dynamic_pointer_cast<PortfolioBasketReferenceDatum>(rdm->getData("PortfolioBasket", "MSFDSJP"));
279+
280+
string xmlRefData = ptfReferenceDatum->toXMLString();
281+
PortfolioBasketReferenceDatum xmlPortfolioBasket("MSFDSJP");
282+
xmlPortfolioBasket.fromXMLString(xmlRefData);
283+
284+
BOOST_CHECK_EQUAL(ptfReferenceDatum->id(), xmlPortfolioBasket.id());
285+
BOOST_CHECK_EQUAL(ptfReferenceDatum->getTrades()[0]->notional(), xmlPortfolioBasket.getTrades()[0]->notional());
286+
BOOST_CHECK_EQUAL(ptfReferenceDatum->getTrades()[1]->notional(), xmlPortfolioBasket.getTrades()[1]->notional());
287+
BOOST_CHECK_EQUAL(ptfReferenceDatum->getTrades()[0]->id(), xmlPortfolioBasket.getTrades()[0]->id());
288+
BOOST_CHECK_EQUAL(ptfReferenceDatum->getTrades()[1]->id(), xmlPortfolioBasket.getTrades()[1]->id());
289+
290+
auto refData = ptfReferenceDatum->getTrades();
291+
QuantLib::ext::shared_ptr<Trade> eqRefCall = refData[0];
292+
QuantLib::ext::shared_ptr<Trade> eqRefPut = refData[1];
293+
294+
Envelope env("CP1");
295+
CompositeTrade compRefData("EUR", {eqRefCall, eqRefPut}, "Mean", 0.0, env);
296+
297+
// Use toXml to serialise to string
298+
string xmlStr = compRefData.toXMLString();
299+
CompositeTrade xmlComposite;
300+
xmlComposite.fromXMLString(xmlStr);
301+
302+
BOOST_CHECK_EQUAL(compRefData.id(), xmlComposite.id());
303+
BOOST_CHECK_EQUAL(compRefData.currency(), xmlComposite.currency());
304+
BOOST_CHECK_EQUAL(compRefData.notionalCalculation(), xmlComposite.notionalCalculation());
305+
BOOST_CHECK_EQUAL(compRefData.trades()[0]->tradeType(), xmlComposite.trades()[0]->tradeType());
306+
BOOST_CHECK_EQUAL(compRefData.trades()[0]->notional(), xmlComposite.trades()[0]->notional());
307+
BOOST_CHECK_EQUAL(compRefData.trades()[1]->tradeType(), xmlComposite.trades()[1]->tradeType());
308+
BOOST_CHECK_EQUAL(compRefData.trades()[1]->notional(), xmlComposite.trades()[1]->notional());
309+
310+
311+
}
312+
214313
BOOST_AUTO_TEST_SUITE_END()
215314

216315
BOOST_AUTO_TEST_SUITE_END()
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?xml version="1.0"?>
2+
<ReferenceData>
3+
<ReferenceDatum id="MSFDSJP">
4+
<Type>PortfolioBasket</Type>
5+
<PortfolioBasketReferenceData>
6+
<Components>
7+
<Trade id="EqOption1">
8+
<TradeType>EquityOption</TradeType>
9+
<Envelope>
10+
<CounterParty>{{netting_set_id}}</CounterParty>
11+
<NettingSetId>{{netting_set_id}}</NettingSetId>
12+
<AdditionalFields>
13+
<valuation_date>2023-11-07</valuation_date>
14+
<im_model>SIMM</im_model>
15+
<post_regulations>SEC</post_regulations>
16+
<collect_regulations>SEC</collect_regulations>
17+
</AdditionalFields>
18+
</Envelope>
19+
<EquityOptionData>
20+
<OptionData>
21+
<LongShort>Long</LongShort>
22+
<OptionType>Call</OptionType>
23+
<Style>European</Style>
24+
<Settlement>Cash</Settlement>
25+
<ExerciseDates>
26+
<ExerciseDate>2016-08-04</ExerciseDate>
27+
</ExerciseDates>
28+
</OptionData>
29+
<Name>eurCorp</Name>
30+
<Currency>EUR</Currency>
31+
<Strike>95</Strike>
32+
<Quantity>1</Quantity>
33+
</EquityOptionData>
34+
</Trade>
35+
<Trade id="EqOption2">
36+
<TradeType>EquityOption</TradeType>
37+
<Envelope>
38+
<CounterParty>{{netting_set_id}}</CounterParty>
39+
<NettingSetId>{{netting_set_id}}</NettingSetId>
40+
<AdditionalFields>
41+
<valuation_date>2023-11-07</valuation_date>
42+
<im_model>SIMM</im_model>
43+
<post_regulations>SEC</post_regulations>
44+
<collect_regulations>SEC</collect_regulations>
45+
</AdditionalFields>
46+
</Envelope>
47+
<EquityOptionData>
48+
<OptionData>
49+
<LongShort>Short</LongShort>
50+
<OptionType>Put</OptionType>
51+
<Style>European</Style>
52+
<Settlement>Cash</Settlement>
53+
<ExerciseDates>
54+
<ExerciseDate>2016-08-04</ExerciseDate>
55+
</ExerciseDates>
56+
</OptionData>
57+
<Name>eurCorp</Name>
58+
<Currency>EUR</Currency>
59+
<Strike>95</Strike>
60+
<StrikeCurrency>EUR</StrikeCurrency>
61+
<Quantity>1</Quantity>
62+
</EquityOptionData>
63+
</Trade>
64+
</Components>
65+
</PortfolioBasketReferenceData>
66+
</ReferenceDatum>
67+
</ReferenceData>

xsd/referencedata.xsd

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -156,25 +156,25 @@
156156
</xs:sequence>
157157
</xs:complexType>
158158

159-
<xs:complexType name="portfolioBasketReferenceDatum">
160-
<xs:sequence>
161-
<xs:element name="Components">
162-
<xs:complexType>
163-
<xs:sequence>
164-
<xs:element name="Trade" maxOccurs="unbounded">
165-
<xs:complexType>
166-
<xs:sequence>
167-
<xs:element type="oreTradeType" name="TradeType"/>
168-
<xs:element type="envelope" name="Envelope" minOccurs="0"/>
169-
<xs:group ref="oreTradeData"/>
170-
</xs:sequence>
171-
<xs:attribute type="xs:string" name="id"/>
172-
</xs:complexType>
173-
</xs:element>
174-
</xs:sequence>
175-
</xs:complexType>
176-
</xs:element>
177-
</xs:sequence>
178-
</xs:complexType>
159+
<xs:complexType name="portfolioBasketReferenceDatum">
160+
<xs:sequence>
161+
<xs:element name="Components">
162+
<xs:complexType>
163+
<xs:sequence>
164+
<xs:element name="Trade" maxOccurs="unbounded">
165+
<xs:complexType>
166+
<xs:sequence>
167+
<xs:element type="oreTradeType" name="TradeType"/>
168+
<xs:element type="envelope" name="Envelope" minOccurs="0"/>
169+
<xs:group ref="oreTradeData"/>
170+
</xs:sequence>
171+
<xs:attribute type="xs:string" name="id"/>
172+
</xs:complexType>
173+
</xs:element>
174+
</xs:sequence>
175+
</xs:complexType>
176+
</xs:element>
177+
</xs:sequence>
178+
</xs:complexType>
179179

180180
</xs:schema>

0 commit comments

Comments
 (0)