25#include <ql/cashflows/fixedratecoupon.hpp>
26#include <ql/currencies/america.hpp>
27#include <ql/pricingengines/swap/discountingswapengine.hpp>
28#include <ql/time/daycounters/thirty360.hpp>
37 const Schedule& fixedSchedule, Rate fixedRate,
const DayCounter& fixedDayCount,
39 const Schedule& bmaSchedule,
const QuantLib::ext::shared_ptr<BMAIndex>& bmaIndex,
40 const DayCounter& bmaDayCount)
41 : Swap(2), type_(type), nominal_(nominal), fixedRate_(fixedRate) {
43 legs_[0] = FixedRateLeg(fixedSchedule)
45 .withCouponRates(
fixedRate, fixedDayCount)
46 .withPaymentAdjustment(fixedSchedule.businessDayConvention());
48 legs_[1] = AverageBMALeg(bmaSchedule, bmaIndex)
50 .withPaymentDayCounter(bmaDayCount)
51 .withPaymentAdjustment(bmaSchedule.businessDayConvention());
53 for (Size j = 0; j < 2; ++j) {
54 for (Leg::iterator i = legs_[j].begin(); i != legs_[j].end(); ++i)
68 QL_FAIL(
"Unknown BMA-swap type");
84 QL_REQUIRE(legBPS_[0] != Null<Real>(),
"result not available");
90 QL_REQUIRE(legNPV_[0] != Null<Real>(),
"result not available");
96 QL_REQUIRE(
fairRate_ != Null<Rate>(),
"result not available");
102 QL_REQUIRE(legBPS_[1] != Null<Real>(),
"result not available");
108 QL_REQUIRE(legNPV_[1] != Null<Real>(),
"result not available");
113 static const Spread basisPoint = 1.0e-4;
115 Swap::fetchResults(r);
125 if (legBPS_[0] != Null<Real>())
131 Swap::results::reset();
136 const Period& forwardStart)
137 : swapTenor_(swapTenor), bmaIndex_(index),
fixedRate_(
fixedRate), forwardStart_(forwardStart),
138 settlementDays_(bmaIndex_->fixingDays()), fixedCalendar_(index->fixingCalendar()),
140 fixedConvention_(ModifiedFollowing), fixedTerminationDateConvention_(ModifiedFollowing),
141 bmaConvention_(ModifiedFollowing), bmaTerminationDateConvention_(ModifiedFollowing),
142 fixedRule_(DateGeneration::Backward), bmaRule_(DateGeneration::Backward), fixedEndOfMonth_(false),
143 bmaEndOfMonth_(false), fixedFirstDate_(Date()), fixedNextToLastDate_(Date()), bmaFirstDate_(Date()),
144 bmaNextToLastDate_(Date()), bmaDayCount_(index->dayCounter()) {}
147 QuantLib::ext::shared_ptr<FixedBMASwap> swap = *
this;
151MakeFixedBMASwap::operator QuantLib::ext::shared_ptr<FixedBMASwap>()
const {
155 if (effectiveDate_ != Date())
156 startDate = effectiveDate_;
158 Date refDate = Settings::instance().evaluationDate();
161 refDate = bmaCalendar_.adjust(refDate);
162 Date spotDate = bmaCalendar_.advance(refDate, settlementDays_ * Days);
163 startDate = spotDate + forwardStart_;
164 if (forwardStart_.length() < 0)
165 startDate = bmaCalendar_.adjust(startDate, Preceding);
167 startDate = bmaCalendar_.adjust(startDate, Following);
170 Date endDate = terminationDate_;
171 if (endDate == Date()) {
173 endDate = bmaCalendar_.advance(startDate, swapTenor_, ModifiedFollowing, bmaEndOfMonth_);
175 endDate = startDate + swapTenor_;
178 const Currency& curr = bmaIndex_->currency();
179 QL_REQUIRE(curr == USDCurrency(),
"Only USD is supported for fixed vs BMA swaps.");
184 if (fixedTenor_ != Period())
185 fixedTenor = fixedTenor_;
188 fixedTenor = 6 * Months;
190 Schedule fixedSchedule(startDate, endDate, fixedTenor, fixedCalendar_, fixedConvention_,
191 fixedTerminationDateConvention_, fixedRule_, fixedEndOfMonth_, fixedFirstDate_,
192 fixedNextToLastDate_);
194 Schedule bmaSchedule(startDate, endDate, bmaLegTenor_, bmaCalendar_, bmaConvention_, bmaTerminationDateConvention_,
195 bmaRule_, bmaEndOfMonth_, bmaFirstDate_, bmaNextToLastDate_);
197 DayCounter fixedDayCount;
198 if (fixedDayCount_ != DayCounter())
199 fixedDayCount = fixedDayCount_;
202 fixedDayCount = Thirty360(Thirty360::USA);
205 Rate usedFixedRate = fixedRate_;
206 if (fixedRate_ == Null<Rate>()) {
209 fixedDayCount, bmaSchedule, bmaIndex_, bmaDayCount_);
211 temp.setPricingEngine(
engine_);
213 QL_FAIL(
"Null fixed rate and no discounting curve provided to fixed vs BMA swap.");
217 QuantLib::ext::shared_ptr<FixedBMASwap> swap(
new FixedBMASwap(type_, nominal_, fixedSchedule, usedFixedRate, fixedDayCount,
218 bmaSchedule, bmaIndex_, bmaDayCount_));
221 swap->setPricingEngine(
engine_);
242 QL_REQUIRE(tenor.units() == Months,
"Average BMA Leg coupons should pay as a multiple of months.");
265 bool includeSettlementDateFlows =
false;
266 engine_ = QuantLib::ext::shared_ptr<PricingEngine>(
new DiscountingSwapEngine(d, includeSettlementDateFlows));
QuantLib::ext::shared_ptr< PricingEngine > engine_
swap paying a fixed rate against BMA coupons
Type type() const
"payer" or "receiver" refer to the BMA leg
const Leg & bmaLeg() const
FixedBMASwap(Type type, Real nominal, const Schedule &fixedSchedule, Rate fixedRate, const DayCounter &fixedDayCount, const Schedule &bmaSchedule, const QuantLib::ext::shared_ptr< BMAIndex > &bmaIndex, const DayCounter &bmaDayCount)
const Leg & fixedLeg() const
void fetchResults(const PricingEngine::results *) const override
MakeFixedBMASwap & withFixedLegNextToLastDate(const Date &d)
BusinessDayConvention fixedConvention_
MakeFixedBMASwap & withFixedLegTenor(const Period &t)
MakeFixedBMASwap & withPricingEngine(const QuantLib::ext::shared_ptr< PricingEngine > &engine)
Date fixedNextToLastDate_
MakeFixedBMASwap & withFixedLegRule(DateGeneration::Rule r)
DayCounter fixedDayCount_
MakeFixedBMASwap & withTerminationDate(const Date &)
MakeFixedBMASwap & withType(FixedBMASwap::Type type)
MakeFixedBMASwap & withFixedLegFirstDate(const Date &d)
MakeFixedBMASwap & withFixedLegDayCount(const DayCounter &dc)
MakeFixedBMASwap & withDiscountingTermStructure(const Handle< YieldTermStructure > &discountCurve)
MakeFixedBMASwap & withFixedLegTerminationDateConvention(BusinessDayConvention bdc)
QuantLib::ext::shared_ptr< PricingEngine > engine_
MakeFixedBMASwap & withSettlementDays(Natural settlementDays)
DateGeneration::Rule fixedRule_
MakeFixedBMASwap & withFixedLegConvention(BusinessDayConvention bdc)
MakeFixedBMASwap & withEffectiveDate(const Date &)
MakeFixedBMASwap & withNominal(Real n)
MakeFixedBMASwap & withFixedLegEndOfMonth(bool flag=true)
MakeFixedBMASwap & withBMALegTenor(const Period &tenor)
BusinessDayConvention fixedTerminationDateConvention_
MakeFixedBMASwap(const Period &swapTenor, const QuantLib::ext::shared_ptr< BMAIndex > &bmaIndex, Rate fixedRate=Null< Rate >(), const Period &forwardStart=0 *Days)
MakeFixedBMASwap & receiveFixed(bool flag=true)
MakeFixedBMASwap & withFixedLegCalendar(const Calendar &cal)
fixed vs averaged bma swap