@@ -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