264 {
265
266 BOOST_TEST_MESSAGE("Testing QuantExt Forward Bond pricing. Case 4");
267
268 SavedSettings backup;
269
270 Settings::instance().evaluationDate() = Date(8, Dec, 2016);
271 Date today = Settings::instance().evaluationDate();
272 Settings::instance().includeReferenceDateEvents() = true;
273
274
275 Handle<Quote> rateQuote(QuantLib::ext::make_shared<SimpleQuote>(0.02));
276 Handle<Quote> issuerSpreadQuote(QuantLib::ext::make_shared<SimpleQuote>(0.00));
277 DayCounter dc = Actual365Fixed();
278 Handle<YieldTermStructure> yts(QuantLib::ext::make_shared<FlatForward>(today, rateQuote, dc, Compounded, Semiannual));
279 Handle<DefaultProbabilityTermStructure> dpts(QuantLib::ext::make_shared<FlatHazardRate>(today, issuerSpreadQuote, dc));
280 Handle<Quote> bondSpecificSpread(QuantLib::ext::make_shared<SimpleQuote>(0.000));
281
282
283 Date startDate = today;
284 Date endDate = startDate + Period(10, Years);
285 Period tenor = 6 * Months;
286 Calendar calendar = WeekendsOnly();
287 BusinessDayConvention bdc = Following;
288 BusinessDayConvention bdcEnd = bdc;
289 DateGeneration::Rule rule = DateGeneration::Forward;
290 bool endOfMonth = false;
291 Date firstDate, lastDate;
292 Schedule schedule(startDate, endDate, tenor, calendar, bdc, bdcEnd, rule, endOfMonth, firstDate, lastDate);
293
294 Real redemption = 100.0;
295 Real couponRate = 0.04;
296 bool settlementDirty = true;
297 Real compensationPayment = 0.0;
298 Date compensationPaymentDate = today;
299 Leg leg =
300 FixedRateLeg(schedule).withNotionals(redemption).withCouponRates(couponRate, dc).withPaymentAdjustment(bdc);
301
302 QuantLib::ext::shared_ptr<QuantLib::Bond> bond(QuantLib::ext::make_shared<QuantLib::Bond>(0, WeekendsOnly(), today, leg));
303 Handle<Quote> recovery(QuantLib::ext::make_shared<SimpleQuote>(0.0));
304 QuantLib::ext::shared_ptr<PricingEngine> pricingEngine(
305 QuantLib::ext::make_shared<QuantExt::DiscountingRiskyBondEngine>(yts, dpts, recovery, bondSpecificSpread, 2 * Months));
306 bond->setPricingEngine(pricingEngine);
307
308 Real price = bond->NPV();
309 BOOST_TEST_MESSAGE("Bond price = " << std::setprecision(12) << price);
310
311
312 Handle<Quote> discountQuote(QuantLib::ext::make_shared<SimpleQuote>(0.01));
313 Handle<YieldTermStructure> discountTS(
314 QuantLib::ext::make_shared<FlatForward>(today, discountQuote, dc, Compounded, Semiannual));
315 Handle<Quote> incomeQuote(QuantLib::ext::make_shared<SimpleQuote>(0.005));
316 Handle<YieldTermStructure> incomeTS(
317 QuantLib::ext::make_shared<FlatForward>(today, incomeQuote, dc, Compounded, Semiannual));
318
319
320
321 Date fwdMaturityDate = today + 7 * Months + 7 * Days;
322
323
324 Real strikePrice = 98.0;
325 QuantLib::ext::shared_ptr<Payoff> payoff = QuantLib::ext::make_shared<QuantExt::ForwardBondTypePayoff>(Position::Long, strikePrice);
326
327
328 QuantLib::ext::shared_ptr<QuantExt::ForwardBond> fwdBond(
330 compensationPayment, compensationPaymentDate));
331
333 discountTS, incomeTS, yts, bondSpecificSpread, dpts, recovery, 2 * Months));
334 fwdBond->setPricingEngine(fwdBondEngine);
335
336 BOOST_TEST_MESSAGE("Forward Bond price = " << std::setprecision(12) << fwdBond->NPV());
337 BOOST_CHECK_CLOSE((fwdBond->NPV() / (discountTS->discount(fwdMaturityDate)) + strikePrice) *
338 (incomeTS->discount(fwdMaturityDate)),
339 bond->NPV() - (0.04 * 100.0 * 182 / 365 * (yts->discount(Date(8, Jun, 2017))) *
340 (dpts->survivalProbability(Date(8, Jun, 2017)))),
341 0.000001);
342 BOOST_TEST_MESSAGE("Present discount factors:");
343
344 BOOST_TEST_MESSAGE("ytsDiscountFactors = " << std::setprecision(12) << yts->discount(Date(8, Jun, 2017)));
345 BOOST_TEST_MESSAGE("ytsDiscountFactors = " << std::setprecision(12)
346 << yts->discount(Date(8, Jun, 2017) + 1 * Days));
347 BOOST_TEST_MESSAGE("ytsDiscountFactors = " << std::setprecision(12)
348 << yts->discount(Date(8, Jun, 2017) + 5 * Days));
349
350 BOOST_TEST_MESSAGE("incDiscountFactors = " << std::setprecision(12) << incomeTS->discount(Date(8, Jun, 2017)));
351 BOOST_TEST_MESSAGE("incDiscountFactors = " << std::setprecision(12)
352 << incomeTS->discount(Date(8, Jun, 2017) + 1 * Days));
353 BOOST_TEST_MESSAGE("incDiscountFactors = " << std::setprecision(12)
354 << incomeTS->discount(Date(8, Jun, 2017) + 5 * Days));
355
356 BOOST_TEST_MESSAGE("disDiscountFactors = " << std::setprecision(12) << discountTS->discount(Date(8, Jun, 2017)));
357 BOOST_TEST_MESSAGE("disDiscountFactors = " << std::setprecision(12)
358 << discountTS->discount(Date(8, Jun, 2017) + 1 * Days));
359 BOOST_TEST_MESSAGE("disDiscountFactors = " << std::setprecision(12)
360 << discountTS->discount(Date(8, Jun, 2017) + 5 * Days));
361}