21#include <ql/pricingengines/blackformula.hpp>
22#include <ql/termstructures/volatility/optionlet/optionletvolatilitystructure.hpp>
28 QL_REQUIRE(
coupon_,
"BlackAverageBMACouponPricer: CappedFlooredAverageBMACoupon required");
30 index_ = ext::dynamic_pointer_cast<BMAIndex>(coupon.index());
34 QL_REQUIRE(c,
"BlackAverageBMACouponPricer: CappedFlooredAverageBMACoupon required");
36 QL_FAIL(
"BlackAverageBMACouponPricer: CappedFlooredAverageBMACoupon required");
45 if (lastRelevantFixingDate <= Settings::instance().evaluationDate()) {
48 if (optionType == Option::Call) {
55 return gearing_ * std::max(a - b, 0.0);
58 QL_REQUIRE(!
capletVolatility().empty(),
"BlackAverageBMACouponPricer: missing optionlet volatility");
60 QL_REQUIRE(!fixingDates.empty(),
61 "BlackAverageBMACouponPricer: internal error, got empty fixingDates, contact dev.");
62 fixingDates.erase(std::next(fixingDates.end(), -1));
63 QL_REQUIRE(!fixingDates.empty(),
"BlackAverageBMACouponPricer: empty fixing dates");
67 Real effectiveTime =
capletVolatility()->timeFromReference(fixingDates.back());
70 stdDev =
capletVolatility()->volatility(fixingDates.back(), effStrike) * std::sqrt(effectiveTime);
76 Real fixingStartTime =
capletVolatility()->timeFromReference(fixingDates.front());
77 Real fixingEndTime =
capletVolatility()->timeFromReference(fixingDates.back());
79 std::max(fixingDates.front(),
capletVolatility()->referenceDate() + 1), effStrike);
80 Real T = std::max(fixingStartTime, 0.0);
82 T += std::pow(fixingEndTime - T, 3.0) / std::pow(fixingEndTime - fixingStartTime, 2.0) / 3.0;
83 stdDev = sigma * std::sqrt(T);
85 if (optionType == Option::Type::Call)
89 Real fixing = shiftedLn ? blackFormula(optionType, effStrike,
forwardRate_, stdDev, 1.0, shift)
90 : bachelierBlackFormula(optionType, effStrike,
forwardRate_, stdDev, 1.0);
106 QL_FAIL(
"BlackAverageBMACouponPricer::swapletPrice() not provided");
109 QL_FAIL(
"BlackAverageBMACouponPricer::capletPrice() not provided");
112 QL_FAIL(
"BlackAverageBMACouponPricer::floorletPrice() not provided");
black average bma coupon pricer for capped / floored BMA coupons
Real capletPrice(Rate effectiveCap) const override
Rate floorletRate(Rate effectiveFloor) const override
const CappedFlooredAverageBMACoupon * coupon_
void initialize(const FloatingRateCoupon &coupon) override
Real optionletRate(Option::Type optionType, Real effStrike) const
Rate swapletRate() const override
Real floorletPrice(Rate effectiveFloor) const override
ext::shared_ptr< BMAIndex > index_
Real swapletPrice() const override
Rate capletRate(Rate effectiveCap) const override
bool effectiveVolatilityInput() const
Real effectiveCapletVolatility_
Handle< OptionletVolatilityStructure > capletVolatility() const
Real effectiveFloorletVolatility_
ext::shared_ptr< AverageBMACoupon > underlying() const
Filter close_enough(const RandomVariable &x, const RandomVariable &y)