33 {
34
35 QL_REQUIRE(
arguments_.exercise->type() == Exercise::American,
"not an American option");
36
38 Real bondPrice =
arguments_.bondQuantity * bond.NPV();
39
41 Date settlementDate = bond.calendar().advance(referenceDate, bond.settlementDays(), QuantLib::Days);
42
43 Real currentNotional = Null<Real>();
44 for (auto const& c : bond.cashflows()) {
45 if (auto coupon = QuantLib::ext::dynamic_pointer_cast<QuantLib::Coupon>(c)) {
46 currentNotional = coupon->nominal();
47 if (c->date() > referenceDate)
48 break;
49 }
50 }
51
52 QL_REQUIRE(currentNotional != Null<Real>(), "IntrinsicAscotEngine::calculate(): could not determine current "
53 "notional, underlying bond must have at least one coupon");
54
55 Leg upfrontLeg;
56 upfrontLeg.push_back(QuantLib::ext::make_shared<SimpleCashFlow>(currentNotional, settlementDate));
57 Real upfrontLegNpv = CashFlows::npv(upfrontLeg, **
discountCurve_,
false, referenceDate, referenceDate);
58
59
60 Real assetLegNpv = CashFlows::npv(bond.cashflows(), **
discountCurve_,
false, referenceDate, referenceDate);
61
62 Real redemptionLegNpv = CashFlows::npv(bond.redemptions(), **
discountCurve_,
false, referenceDate, referenceDate);
63
64
66
67 Real strike =
arguments_.bondQuantity * (upfrontLegNpv + assetLegNpv - redemptionLegNpv) - fundingLegNpv;
68
70 results_.additionalResults[
"bondPrice"] = bondPrice;
71 results_.additionalResults[
"strike"] = strike;
72 results_.additionalResults[
"fundingLegNpv"] = fundingLegNpv;
73 results_.additionalResults[
"redemptionLegNpv"] = redemptionLegNpv *
arguments_.bondQuantity;
77}
const Instrument::results * results_
Swap::arguments * arguments_