Skip to content

Commit c27d96b

Browse files
mgronckijenkins
authored andcommitted
QPR-12340 fix put exercise logic
1 parent 47cc093 commit c27d96b

1 file changed

Lines changed: 13 additions & 2 deletions

File tree

QuantExt/qle/pricingengines/fddefaultableequityjumpdiffusionconvertiblebondengine.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,12 @@ void FdDefaultableEquityJumpDiffusionConvertibleBondEngine::calculate() const {
516516
cr = events.getCallData(i).mwCr(S[j], cr0);
517517
// compuate forced conversion value and update npv node
518518
Real forcedConversionValue = S[j] * cr * notional(grid[i]) / N0 + accrual(grid[i]);
519+
if (forcedConversionValue > c && forcedConversionValue < value[plane][j]) {
520+
// conversion is forced -> update flags
521+
if (!conversionIndicator.empty())
522+
conversionIndicator[plane][j] = 0.0;
523+
conversionExercised[plane][j] = false;
524+
}
519525
value[plane][j] = std::min(std::max(forcedConversionValue, c), value[plane][j]);
520526
if (!valueNoConversion.empty()) {
521527
valueNoConversion[plane][j] =
@@ -529,8 +535,13 @@ void FdDefaultableEquityJumpDiffusionConvertibleBondEngine::calculate() const {
529535
if (events.hasPut(i)) {
530536
Real c = getCallPriceAmount(events.getPutData(i), notional(t_from), accrual(t_from));
531537
for (Size j = 0; j < n; ++j) {
532-
if (!conversionExercised[plane][j])
533-
value[plane][j] = std::max(c, value[plane][j]);
538+
if (c > value[plane][j]) {
539+
// put is more favorable than conversion (if that happened above)
540+
value[plane][j] = c;
541+
if (!conversionIndicator.empty())
542+
conversionIndicator[plane][j] = 0.0;
543+
conversionExercised[plane][j] = false;
544+
}
534545
}
535546
if (!valueNoConversion.empty()) {
536547
for (Size j = 0; j < n; ++j) {

0 commit comments

Comments
 (0)