Skip to content

Commit d4fdf6d

Browse files
damienbarkerjenkins
authored andcommitted
QPR-12235 avoid crash in callable swap if underling NPV = 0, add check to schedule for firstdate < lastDate
1 parent a92b192 commit d4fdf6d

2 files changed

Lines changed: 10 additions & 2 deletions

File tree

OREData/ored/portfolio/schedule.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,8 @@ Schedule makeSchedule(const ScheduleRules& data, const Date& openEndDateReplacem
337337

338338
Date firstDate = parseDate(data.firstDate());
339339
Date lastDate = parseDate(data.lastDate());
340+
QL_REQUIRE(firstDate <= lastDate, "Schedule::makeSchedule firstDate must be before lastDate");
341+
340342
Period tenor = parsePeriod(data.tenor());
341343

342344
// defaults

QuantExt/qle/pricingengines/numericlgmmultilegoptionengine.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,8 +321,11 @@ void NumericLgmMultiLegOptionEngineBase::calculate() const {
321321
// transfer relevant cashflow amounts to exercise into npv
322322

323323
for (auto const& cf : option->second) {
324-
underlyingNpv1 += underlyingNpv2[cf];
325-
underlyingNpv2.erase(cf);
324+
auto npv2Cf = underlyingNpv2.find(cf);
325+
if (npv2Cf != underlyingNpv2.end()) {
326+
underlyingNpv1 += npv2Cf->second;
327+
underlyingNpv2.erase(cf);
328+
}
326329
}
327330

328331
// update the option value (exercise value including rebate vs. continuation value)
@@ -334,6 +337,9 @@ void NumericLgmMultiLegOptionEngineBase::calculate() const {
334337
// rollback
335338

336339
if (t_from != t_to) {
340+
// if the underlyingNpv1 is 0 here we break and npv gets set to 0
341+
if (QuantLib::close_enough(underlyingNpv1.at(0), 0.0))
342+
break;
337343
underlyingNpv1 = rollback(underlyingNpv1, t_from, t_to);
338344
for (auto& c : underlyingNpv2) {
339345
c.second = rollback(c.second, t_from, t_to);

0 commit comments

Comments
 (0)