19#include <ql/cashflows/cashflows.hpp>
20#include <ql/cashflows/fixedratecoupon.hpp>
21#include <ql/cashflows/floatingratecoupon.hpp>
22#include <ql/cashflows/iborcoupon.hpp>
23#include <ql/cashflows/inflationcoupon.hpp>
24#include <ql/cashflows/simplecashflow.hpp>
25#include <ql/utilities/dataformatters.hpp>
33class AmountGetter :
public AcyclicVisitor,
34 public Visitor<CashFlow>,
35 public Visitor<Coupon>,
36 public Visitor<IborCoupon> {
40 virtual ~AmountGetter() {}
42 Real amount()
const {
return amount_; }
43 virtual Real bpsFactor()
const {
return 0.0; }
44 void setCallAmount(
bool flag) {
callAmount_ = flag; }
46 void visit(CashFlow& c)
override;
47 void visit(
Coupon& c)
override;
48 void visit(IborCoupon& c)
override;
55void AmountGetter::visit(CashFlow& c) {
amount_ = c.amount(); }
59void AmountGetter::visit(IborCoupon& c) {
63 Handle<YieldTermStructure> forwardingCurve = c.iborIndex()->forwardingTermStructure();
64 QL_REQUIRE(!forwardingCurve.empty(),
"Forwarding curve is empty.");
67 DiscountFactor discAccStart = forwardingCurve->discount(c.accrualStartDate());
68 DiscountFactor discAccEnd = forwardingCurve->discount(c.accrualEndDate());
71 DayCounter indexBasis = c.iborIndex()->dayCounter();
72 DayCounter couponBasis = c.dayCounter();
73 if (indexBasis == couponBasis) {
74 fixingTimesDcf = (discAccStart / discAccEnd - 1);
76 Time indexDcf = indexBasis.yearFraction(c.accrualStartDate(), c.accrualEndDate());
77 fixingTimesDcf = (discAccStart / discAccEnd - 1) / indexDcf * c.accrualPeriod();
79 amount_ = (c.gearing() * fixingTimesDcf + c.spread() * c.accrualPeriod()) * c.nominal();
83class AdditionalAmountGetter :
public AmountGetter {
86 AdditionalAmountGetter() {}
87 Real bpsFactor()
const override {
return bpsFactor_; }
89 void visit(CashFlow& c)
override;
90 void visit(
Coupon& c)
override;
91 void visit(IborCoupon& c)
override;
97void AdditionalAmountGetter::visit(CashFlow& c) {
98 AmountGetter::visit(c);
102void AdditionalAmountGetter::visit(
Coupon& c) {
103 AmountGetter::visit(c);
107void AdditionalAmountGetter::visit(IborCoupon& c) {
108 AmountGetter::visit(c);
113class DiscountingSwapEngineMultiCurve::AmountImpl {
115 QuantLib::ext::shared_ptr<AmountGetter> amountGetter_;
120 boost::optional<bool> includeSettlementDateFlows,
121 Date settlementDate, Date npvDate)
122 : discountCurve_(discountCurve), minimalResults_(minimalResults),
123 includeSettlementDateFlows_(includeSettlementDateFlows), settlementDate_(settlementDate), npvDate_(npvDate),
124 impl_(new AmountImpl) {
129 impl_->amountGetter_.reset(
new AmountGetter);
131 impl_->amountGetter_.reset(
new AdditionalAmountGetter);
137 "term structure handle");
143 settlementDate = referenceDate;
145 QL_REQUIRE(settlementDate >= referenceDate,
"settlement date (" << settlementDate
147 "discount curve reference date ("
148 << referenceDate <<
")");
153 results_.errorEstimate = Null<Real>();
156 results_.valuationDate = referenceDate;
160 "discount curve reference date ("
161 << referenceDate <<
")");
168 results_.startDiscounts.resize(numLegs);
169 results_.endDiscounts.resize(numLegs);
172 bool includeRefDateFlows =
175 const Spread bp = 1.0e-4;
177 for (Size i = 0; i < numLegs; i++) {
184 impl_->amountGetter_->setCallAmount(
true);
186 for (Size j = 0; j < leg.size(); j++) {
190 if (leg[j]->hasOccurred(settlementDate, includeRefDateFlows)) {
194 DiscountFactor discount =
discountCurve_->discount(leg[j]->date());
195 leg[j]->accept(*(
impl_->amountGetter_));
196 results_.legNPV[i] +=
impl_->amountGetter_->amount() * discount;
197 results_.legBPS[i] +=
impl_->amountGetter_->bpsFactor() * discount;
202 impl_->amountGetter_->setCallAmount(
false);
const Instrument::results * results_
Handle< YieldTermStructure > discountCurve_
boost::optional< bool > includeSettlementDateFlows_
void calculate() const override
QuantLib::ext::shared_ptr< AmountImpl > impl_
DiscountingSwapEngineMultiCurve(const Handle< YieldTermStructure > &discountCurve=Handle< YieldTermStructure >(), bool minimalResults=true, boost::optional< bool > includeSettlementDateFlows=boost::none, Date settlementDate=Date(), Date npvDate=Date())
Swap engine employing assumptions to speed up calculation.
Swap::arguments * arguments_