|
20 | 20 |
|
21 | 21 | #include <boost/make_shared.hpp> |
22 | 22 | #include <boost/test/unit_test.hpp> |
| 23 | +#include <boost/test/data/test_case.hpp> |
| 24 | +#include <oret/datapaths.hpp> |
23 | 25 | #include <ored/marketdata/marketimpl.hpp> |
24 | 26 | #include <ored/portfolio/builders/equityforward.hpp> |
25 | 27 | #include <ored/portfolio/builders/equityoption.hpp> |
@@ -211,6 +213,103 @@ BOOST_AUTO_TEST_CASE(testMultiCcyComposite) { |
211 | 213 | BOOST_CHECK_CLOSE(npv_usd_composite, npv_eurCall * 1.25 + npv_usdCall / 1.0, 0.01); |
212 | 214 | } |
213 | 215 |
|
| 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 | + |
214 | 313 | BOOST_AUTO_TEST_SUITE_END() |
215 | 314 |
|
216 | 315 | BOOST_AUTO_TEST_SUITE_END() |
0 commit comments