20#include <ql/cashflows/cashflows.hpp>
21#include <ql/cashflows/iborcoupon.hpp>
22#include <ql/cashflows/simplecashflow.hpp>
29 : discountCurve_(discountCurve) {
35 QL_REQUIRE(
arguments_.exercise->type() == Exercise::American,
"not an American option");
38 Real bondPrice =
arguments_.bondQuantity * bond.NPV();
41 Date settlementDate = bond.calendar().advance(referenceDate, bond.settlementDays(), QuantLib::Days);
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)
52 QL_REQUIRE(currentNotional != Null<Real>(),
"IntrinsicAscotEngine::calculate(): could not determine current "
53 "notional, underlying bond must have at least one coupon");
56 upfrontLeg.push_back(QuantLib::ext::make_shared<SimpleCashFlow>(currentNotional, settlementDate));
57 Real upfrontLegNpv = CashFlows::npv(upfrontLeg, **
discountCurve_,
false, referenceDate, referenceDate);
60 Real assetLegNpv = CashFlows::npv(bond.cashflows(), **
discountCurve_,
false, referenceDate, referenceDate);
62 Real redemptionLegNpv = CashFlows::npv(bond.redemptions(), **
discountCurve_,
false, referenceDate, referenceDate);
67 Real strike =
arguments_.bondQuantity * (upfrontLegNpv + assetLegNpv - redemptionLegNpv) - fundingLegNpv;
70 results_.additionalResults[
"bondPrice"] = bondPrice;
71 results_.additionalResults[
"strike"] = strike;
72 results_.additionalResults[
"fundingLegNpv"] = fundingLegNpv;
73 results_.additionalResults[
"redemptionLegNpv"] = redemptionLegNpv *
arguments_.bondQuantity;
binomial engine for convertible bonds
const Instrument::results * results_
Handle< YieldTermStructure > discountCurve_
void calculate() const override
IntrinsicAscotEngine(const Handle< YieldTermStructure > &discountCurve)
intrinsic engine for Ascots
Swap::arguments * arguments_