48 {
49 Date today = Settings::instance().evaluationDate();
51
54 double EA = 0;
55 std::vector<Date> futureExpiries;
56 std::map<Date, Real> futureVols;
57 std::vector<double> spotVariances;
58 size_t n = flow->indices().size();
59 double atmUnderlyingCcy = 0;
60
61 for (const auto& [pricingDate, index] : flow->indices()) {
62 Date fixingDate = index->fixingCalendar().adjust(pricingDate, Preceding);
63 Real fxRate = (flow->fxIndex()) ? flow->fxIndex()->fixing(fixingDate) : 1.0;
67 res.
fixings.push_back(index->fixing(fixingDate) * fxRate);
68 if (pricingDate <= today) {
70 } else {
71 atmUnderlyingCcy = index->fixing(fixingDate);
73 res.
times.push_back(vol->timeFromReference(pricingDate));
74
75 double K = strike == Null<Real>() ? atmUnderlyingCcy : strike;
76 if (flow->useFuturePrice()) {
77 Date expiry = index->expiryDate();
78 futureExpiries.push_back(expiry);
79 if (futureVols.count(expiry) == 0) {
80 futureVols[expiry] = vol->blackVol(expiry, K);
81 }
82 } else {
83 spotVariances.push_back(
84 vol->blackVariance(res.
times.back(), K));
85 res.
spotVols.push_back(std::sqrt(spotVariances.back() / res.
times.back()));
86 }
88 }
89 }
90 res.
accruals /=
static_cast<double>(n);
91 EA /= static_cast<double>(n);
92
94
95 double EA2 = 0.0;
96
97 if (flow->useFuturePrice()) {
98
99 for (Size i = 0; i < res.
forwards.size(); ++i) {
100 Date e_i = futureExpiries[i];
101 Volatility v_i = futureVols.at(e_i);
104 for (Size j = 0; j < i; ++j) {
105 Date e_j = futureExpiries[j];
106 Volatility v_j = futureVols.at(e_j);
108 }
109 }
110 } else {
111
112 for (Size i = 0; i < res.
forwards.size(); ++i) {
114 for (Size j = 0; j < i; ++j) {
116 }
117 }
118 }
119 EA2 /= std::pow(static_cast<double>(n), 2.0);
121
122 QL_REQUIRE(!std::isinf(EA2),
123 "moment matching fails (EA2 = inf) - this is possibly due to too high input volatilities.");
124
125
126 if (!res.
times.empty()) {
128 double s = EA2 / (EA * EA);
129
130
131 if (s < 1.0 || QuantLib::close_enough(s, 1)) {
133 } else {
134 res.
sigma = std::sqrt(std::log(s) / res.
tn);
135 }
136 } else {
139 }
140 return res;
141}
CompiledFormula exp(CompiledFormula x)
std::vector< QuantLib::Date > indexExpiries
std::vector< QuantLib::Date > pricingDates
std::vector< Real > forwards
std::vector< QuantLib::Real > times
std::vector< Real > futureVols
std::vector< std::string > indexNames
std::vector< QuantLib::Real > fixings
std::vector< Real > spotVols