Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
fddefaultableequityjumppdiffusionconvertiblebondengine.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2021 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
22
23#include <ql/cashflows/coupon.hpp>
24#include <ql/currencies/europe.hpp>
25#include <ql/instruments/bonds/fixedratebond.hpp>
26#include <ql/quotes/simplequote.hpp>
27#include <ql/termstructures/credit/flathazardrate.hpp>
28#include <ql/termstructures/volatility/equityfx/blackconstantvol.hpp>
29#include <ql/termstructures/yield/flatforward.hpp>
30#include <ql/time/calendars/nullcalendar.hpp>
31#include <ql/time/calendars/target.hpp>
32#include <ql/time/daycounters/thirty360.hpp>
33
34#include "toplevelfixture.hpp"
35
36#include <boost/test/unit_test.hpp>
37
38#include <algorithm>
39#include <iomanip>
40
41using namespace QuantLib;
42using namespace QuantExt;
43
44BOOST_FIXTURE_TEST_SUITE(QuantExtTestSuite, qle::test::TopLevelFixture)
45
46BOOST_AUTO_TEST_SUITE(FdConvertibleBondEngine)
47
48BOOST_AUTO_TEST_CASE(test_vanilla_bond) {
49
50 BOOST_TEST_MESSAGE("Test vanilla bond pricing in fd defaultable equity jump diffusion convertible engine...");
51
52 Date today(9, February, 2021);
53 Settings::instance().evaluationDate() = today;
54
55 Real S0 = 100.0;
56 Handle<YieldTermStructure> rate(QuantLib::ext::make_shared<FlatForward>(0, NullCalendar(), 0.01, Actual365Fixed()));
57 Handle<YieldTermStructure> dividend(QuantLib::ext::make_shared<FlatForward>(0, NullCalendar(), 0.02, Actual365Fixed()));
58 Handle<BlackVolTermStructure> vol(QuantLib::ext::make_shared<BlackConstantVol>(0, NullCalendar(), 0.3, Actual365Fixed()));
59
60 Handle<YieldTermStructure> bondBenchmark(
61 QuantLib::ext::make_shared<FlatForward>(0, NullCalendar(), 0.03, Actual365Fixed()));
62 Handle<DefaultProbabilityTermStructure> creditCurve(
63 QuantLib::ext::make_shared<FlatHazardRate>(0, NullCalendar(), 0.0050, Actual365Fixed()));
64 Handle<Quote> bondRecoveryRate(QuantLib::ext::make_shared<SimpleQuote>(0.25));
65 Handle<Quote> securitySpread(QuantLib::ext::make_shared<SimpleQuote>(0.00));
66
67 auto equity = QuantLib::ext::make_shared<EquityIndex2>("myEqIndex", NullCalendar(), EURCurrency(),
68 Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(S0)), rate, dividend);
69
70 auto bond = QuantLib::ext::make_shared<FixedRateBond>(0, TARGET(), 100000.0, today, today + 5 * Years, 1 * Years,
71 std::vector<Real>(1, 0.05), Thirty360(Thirty360::BondBasis));
72
73 // vanilla pricing
74
75 auto vanillaEngine = QuantLib::ext::make_shared<DiscountingRiskyBondEngine>(bondBenchmark, creditCurve, bondRecoveryRate,
76 securitySpread, 1 * Years);
77 bond->setPricingEngine(vanillaEngine);
78 Real vanillaEngineNpv = bond->NPV();
79
80 // jd model
81
82 Real p = 0.0;
83 Real eta = 1.0;
84 std::vector<Real> stepTimes = {1.0, 2.0, 3.0, 4.0, 5.0};
85
86 auto modelBuilder = QuantLib::ext::make_shared<DefaultableEquityJumpDiffusionModelBuilder>(
87 stepTimes, equity, vol, creditCurve, p, eta, false, 24, 400, 1E-5, 1.5, Null<Real>(),
88 DefaultableEquityJumpDiffusionModelBuilder::BootstrapMode::Simultaneously, true);
89 auto model = modelBuilder->model();
90
91 auto cpns = bond->cashflows();
92 cpns.erase(
93 std::remove_if(cpns.begin(), cpns.end(),
94 [](QuantLib::ext::shared_ptr<CashFlow> c) { return QuantLib::ext::dynamic_pointer_cast<Coupon>(c) == nullptr; }),
95 cpns.end());
96
97 ConvertibleBond2::MakeWholeData d; // avoid linker problem on linux
98 auto convertibleBond =
99 QuantLib::ext::make_shared<ConvertibleBond2>(bond->settlementDays(), bond->calendar(), bond->issueDate(), cpns);
100 auto convertibleEngine = QuantLib::ext::make_shared<FdDefaultableEquityJumpDiffusionConvertibleBondEngine>(
101 model, bondBenchmark, securitySpread, Handle<DefaultProbabilityTermStructure>(), bondRecoveryRate,
102 Handle<FxIndex>(), false, 24, 100, 1E-4, 1.5);
103 convertibleBond->setPricingEngine(convertibleEngine);
104 Real convertibleEngineNpv = convertibleBond->NPV();
105
106 BOOST_TEST_MESSAGE("Vanilla Engine Bond NPV = "
107 << std::setprecision(10) << vanillaEngineNpv
108 << ", Convertible Engine Bond NPV = " << convertibleEngineNpv
109 << ", error=" << (convertibleEngineNpv - vanillaEngineNpv) / vanillaEngineNpv * 100.0 << "%");
110
111 BOOST_CHECK_CLOSE(vanillaEngineNpv, convertibleEngineNpv, 1E-3);
112}
113
114BOOST_AUTO_TEST_SUITE_END()
115
116BOOST_AUTO_TEST_SUITE_END()
Fixture that can be used at top level.