166 {
167
168
169
170 Date today = QuantLib::Settings::instance().evaluationDate();
171 Real T = ActualActual(ActualActual::ISDA).yearFraction(today, maturity);
172
173
174
176
177
178
179 QuantLib::ext::shared_ptr<Integrator> integrator;
183 integrator = QuantLib::ext::make_shared<SegmentIntegral>(
settings_.
steps);
184 } else {
185 QL_FAIL("GeneralisedReplicationVarianceSwapEngine: internal error, unknown scheme");
186 }
187
188
189
190 auto replication = [F, T, this](Real K) {
191 if (K < 1E-10)
192 return 0.0;
193 return blackFormula(K < F ? Option::Put : Option::Call, K, F,
194 std::sqrt(std::max(0.0,
process_->blackVolatility()->blackVariance(T, K,
true)))) /
195 (K * K);
196 };
197
198
199
200 Real lower = F, upper = F;
201
203 Real tmp = std::max(0.01, T);
204 Real stdDev = std::max(0.01,
process_->blackVolatility()->blackVol(tmp, F,
true)) * std::sqrt(tmp);
208 Size i = 0, j = 0;
214 "GeneralisedReplicatingVarianceSwapEngine(): far otm call / put prices do not go to zero, put("
215 << lower << ")=" << replication(lower)
216 <<
" (vol=" <<
process_->blackVolatility()->blackVol(T, lower,
true) <<
"), call(" << upper
217 << ")=" << replication(upper)
218 <<
", vol=" <<
process_->blackVolatility()->blackVol(T, upper,
true) <<
", threshold is "
220 } else {
221 QL_FAIL("GeneralisedReplicationVarianceSwapEngine: internal error, unknown bounds");
222 }
223
224
225
226 try {
227 Real res = 0.0;
229 res += integrator->operator()(replication, lower, F);
231 res += integrator->operator()(replication, F, upper);
232 return 2.0 / T * res;
233 } catch (const std::exception& e) {
234 QL_FAIL("GeneralisedReplicatingVarianceSwapEngine(): error during calculation, check volatility input and "
235 "resulting replication integrand: "
236 << e.what());
237 }
238}
Size maxPriceThresholdSteps
Filter close_enough(const RandomVariable &x, const RandomVariable &y)