43 {
45 if (lastRelevantFixingDate <= Settings::instance().evaluationDate()) {
46
47 Real a, b;
48 if (optionType == Option::Call) {
50 b = effStrike;
51 } else {
52 a = effStrike;
54 }
55 return gearing_ * std::max(a - b, 0.0);
56 } else {
57
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");
66 Real stdDev;
67 Real effectiveTime =
capletVolatility()->timeFromReference(fixingDates.back());
69
70 stdDev =
capletVolatility()->volatility(fixingDates.back(), effStrike) * std::sqrt(effectiveTime);
71 } else {
72
73
74
75
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);
84 }
85 if (optionType == Option::Type::Call)
87 else
89 Real fixing = shiftedLn ? blackFormula(optionType, effStrike,
forwardRate_, stdDev, 1.0, shift)
90 : bachelierBlackFormula(optionType, effStrike,
forwardRate_, stdDev, 1.0);
92 }
93}
bool effectiveVolatilityInput() const
Handle< OptionletVolatilityStructure > capletVolatility() const
Filter close_enough(const RandomVariable &x, const RandomVariable &y)