Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Functions
defaultableequityjumpdiffusionmodel.cpp File Reference
#include <qle/models/defaultableequityjumpdiffusionmodel.hpp>
#include "toplevelfixture.hpp"
#include <ql/currencies/europe.hpp>
#include <ql/math/randomnumbers/mt19937uniformrng.hpp>
#include <ql/models/marketmodels/browniangenerators/sobolbrowniangenerator.hpp>
#include <ql/option.hpp>
#include <ql/pricingengines/blackformula.hpp>
#include <ql/quotes/simplequote.hpp>
#include <ql/termstructures/credit/flathazardrate.hpp>
#include <ql/termstructures/volatility/equityfx/blackconstantvol.hpp>
#include <ql/termstructures/yield/flatforward.hpp>
#include <ql/time/calendars/nullcalendar.hpp>
#include <ql/time/daycounters/actual365fixed.hpp>
#include <ql/timegrid.hpp>
#include <boost/test/unit_test.hpp>

Go to the source code of this file.

Functions

 BOOST_AUTO_TEST_CASE (test_zero_p)
 
 BOOST_AUTO_TEST_CASE (test_nonzero_p)
 

Function Documentation

◆ BOOST_AUTO_TEST_CASE() [1/2]

BOOST_AUTO_TEST_CASE ( test_zero_p  )

Definition at line 116 of file defaultableequityjumpdiffusionmodel.cpp.

116 {
117
118 BOOST_TEST_MESSAGE("Test defaultable equity jump diffusion model calibration with closed form bootstrap for p=0");
119
120 Real S0 = 100.0;
121 std::vector<Real> stepTimes = {1.0, 2.0, 3.0, 4.0, 5.0};
122
123 Handle<YieldTermStructure> rate(QuantLib::ext::make_shared<FlatForward>(0, NullCalendar(), 0.01, Actual365Fixed()));
124 Handle<YieldTermStructure> dividend(QuantLib::ext::make_shared<FlatForward>(0, NullCalendar(), 0.02, Actual365Fixed()));
125 Handle<BlackVolTermStructure> vol(QuantLib::ext::make_shared<BlackConstantVol>(0, NullCalendar(), 0.3, Actual365Fixed()));
126 Handle<DefaultProbabilityTermStructure> creditCurve(
127 QuantLib::ext::make_shared<FlatHazardRate>(0, NullCalendar(), 0.0050, Actual365Fixed()));
128
129 auto equity = QuantLib::ext::make_shared<EquityIndex2>("myEqIndex", NullCalendar(), EURCurrency(),
130 Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(S0)), rate, dividend);
131
132 std::vector<Real> strikes;
133 for (auto const& t : stepTimes) {
134 Real forward = equity->equitySpot()->value() * equity->equityDividendCurve()->discount(t) /
135 equity->equityForecastCurve()->discount(t);
136 strikes.push_back(forward);
137 }
138
139 /* for smaller etas (like 0.5) the mc simulation will produce higher call prices than the market because
140 - in the model calibration we assume that after a jump to default the equity does not contribute
141 to the option payoff
142 - in the mc simulation the equity might contribute to the call payoff for eta << 1, if the after-jump
143 equity price is still above the strike (atm forward)
144 */
145
146 std::vector<Real> etas = {1.0, 0.9, 0.8};
147
148 for (auto const& eta : etas) {
149
150 std::vector<Real> resultDefaultableBonds, resultEquityOptions;
151 // mode does not matter, since p=0 and we don't enforce Fokker-Planck bootstrap
152 auto modelBuilder = QuantLib::ext::make_shared<DefaultableEquityJumpDiffusionModelBuilder>(
153 stepTimes, equity, vol, creditCurve, 0.0, eta, false, 24, 100, 1E-4, 1.5, Null<Real>(),
154 DefaultableEquityJumpDiffusionModelBuilder::BootstrapMode::Simultaneously, false);
155 auto model = *modelBuilder->model();
156
157 runMcSimulation(model, 100000, 121, 5 * 24, stepTimes, strikes, resultDefaultableBonds, resultEquityOptions);
158
159 Real tol = 0.1; // 0.1 percent
160 BOOST_TEST_MESSAGE(std::right << std::setw(5) << "p" << std::setw(5) << "eta" << std::setw(5) << "t"
161 << std::setw(16) << "h0" << std::setw(16) << "sigma" << std::setw(16) << "bond mc"
162 << std::setw(16) << "bond mkt" << std::setw(16) << "equityCall mc"
163 << std::setw(16) << "equityCall mkt" << std::setw(16) << "bond err %"
164 << std::setw(16) << "eqCall err %");
165 for (Size i = 0; i < stepTimes.size(); ++i) {
166 Real bondMarket = rate->discount(stepTimes[i]) * creditCurve->survivalProbability(stepTimes[i]);
167 Real eqOptionMarket =
168 blackFormula(Option::Call, strikes[i], strikes[i],
169 std::sqrt(vol->blackVariance(stepTimes[i], strikes[i])), rate->discount(stepTimes[i]));
170 BOOST_TEST_MESSAGE(std::right
171 << std::setw(5) << 0.0 << std::setw(5) << eta << std::setw(5) << stepTimes[i]
172 << std::setw(16) << model->h0()[i] << std::setw(16) << model->sigma()[i] << std::setw(16)
173 << resultDefaultableBonds[i] << std::setw(16) << bondMarket << std::setw(16)
174 << resultEquityOptions[i] << std::setw(16) << eqOptionMarket << std::setw(16)
175 << 100.0 * (resultDefaultableBonds[i] - bondMarket) / bondMarket << std::setw(16)
176 << 100.0 * (resultEquityOptions[i] - eqOptionMarket) / eqOptionMarket);
177 BOOST_CHECK_CLOSE(resultDefaultableBonds[i], bondMarket, tol);
178 BOOST_CHECK_CLOSE(resultEquityOptions[i], eqOptionMarket, tol);
179 }
180 BOOST_TEST_MESSAGE("done.");
181 }
182}
vector< Real > strikes

◆ BOOST_AUTO_TEST_CASE() [2/2]

BOOST_AUTO_TEST_CASE ( test_nonzero_p  )

Definition at line 184 of file defaultableequityjumpdiffusionmodel.cpp.

184 {
185
186 BOOST_TEST_MESSAGE("Test defaultable equity jump diffusion model calibration with Fokker-Planck bootstrap");
187
188 Real S0 = 100.0;
189 std::vector<Real> stepTimes = {1.0, 2.0, 3.0, 4.0, 5.0};
190
191 Handle<YieldTermStructure> rate(QuantLib::ext::make_shared<FlatForward>(0, NullCalendar(), 0.01, Actual365Fixed()));
192 Handle<YieldTermStructure> dividend(QuantLib::ext::make_shared<FlatForward>(0, NullCalendar(), 0.02, Actual365Fixed()));
193 Handle<BlackVolTermStructure> vol(QuantLib::ext::make_shared<BlackConstantVol>(0, NullCalendar(), 0.3, Actual365Fixed()));
194 Handle<DefaultProbabilityTermStructure> creditCurve(
195 QuantLib::ext::make_shared<FlatHazardRate>(0, NullCalendar(), 0.0050, Actual365Fixed()));
196
197 auto equity = QuantLib::ext::make_shared<EquityIndex2>("myEqIndex", NullCalendar(), EURCurrency(),
198 Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(S0)), rate, dividend);
199
200 std::vector<Real> strikes;
201 for (auto const& t : stepTimes) {
202 Real forward = equity->equitySpot()->value() * equity->equityDividendCurve()->discount(t) /
203 equity->equityForecastCurve()->discount(t);
204 strikes.push_back(forward);
205 }
206
207 /* see above for a comment on small etas in the test */
208
209 std::vector<DefaultableEquityJumpDiffusionModelBuilder::BootstrapMode> modes = {
210 DefaultableEquityJumpDiffusionModelBuilder::BootstrapMode::Alternating,
211 DefaultableEquityJumpDiffusionModelBuilder::BootstrapMode::Simultaneously};
212 std::vector<Real> ps = {0.0, 0.5};
213 std::vector<Real> etas = {1.0, 0.9};
214
215 for (auto const& mode : modes) {
216 BOOST_TEST_MESSAGE(
217 "Bootstrap mode = " << (mode == DefaultableEquityJumpDiffusionModelBuilder::BootstrapMode::Alternating
218 ? "Alternating"
219 : "Simultaneously"));
220 for (auto const& p : ps) {
221 for (auto const& eta : etas) {
222
223 std::vector<Real> resultDefaultableBonds, resultEquityOptions;
224 auto modelBuilder = QuantLib::ext::make_shared<DefaultableEquityJumpDiffusionModelBuilder>(
225 stepTimes, equity, vol, creditCurve, p, eta, false, 24, 400, 1E-5, 1.5, Null<Real>(), mode, true);
226 auto model = *modelBuilder->model();
227
228 runMcSimulation(model, 100000, 121, 5 * 24, stepTimes, strikes, resultDefaultableBonds,
229 resultEquityOptions);
230
231 Real tol = 0.2; // 0.2 percent
232 BOOST_TEST_MESSAGE(std::right << std::setw(5) << "p" << std::setw(5) << "eta" << std::setw(5) << "t"
233 << std::setw(16) << "h0" << std::setw(16) << "sigma" << std::setw(16)
234 << "bond mc" << std::setw(16) << "bond mkt" << std::setw(16)
235 << "equityCall mc" << std::setw(16) << "equityCall mkt" << std::setw(16)
236 << "bond err %" << std::setw(16) << "eqCall err %");
237 for (Size i = 0; i < stepTimes.size(); ++i) {
238 Real bondMarket = rate->discount(stepTimes[i]) * creditCurve->survivalProbability(stepTimes[i]);
239 Real eqOptionMarket = blackFormula(Option::Call, strikes[i], strikes[i],
240 std::sqrt(vol->blackVariance(stepTimes[i], strikes[i])),
241 rate->discount(stepTimes[i]));
242 BOOST_TEST_MESSAGE(std::right
243 << std::setw(5) << p << std::setw(5) << eta << std::setw(5) << stepTimes[i]
244 << std::setw(16) << model->h0()[i] << std::setw(16) << model->sigma()[i]
245 << std::setw(16) << resultDefaultableBonds[i] << std::setw(16) << bondMarket
246 << std::setw(16) << resultEquityOptions[i] << std::setw(16) << eqOptionMarket
247 << std::setw(16) << 100.0 * (resultDefaultableBonds[i] - bondMarket) / bondMarket
248 << std::setw(16)
249 << 100.0 * (resultEquityOptions[i] - eqOptionMarket) / eqOptionMarket);
250 BOOST_CHECK_CLOSE(resultDefaultableBonds[i], bondMarket, tol);
251 BOOST_CHECK_CLOSE(resultEquityOptions[i], eqOptionMarket, tol);
252 }
253 BOOST_TEST_MESSAGE("done.");
254 }
255 }
256 }
257}