29#include <ql/cashflows/averagebmacoupon.hpp>
30#include <ql/cashflows/capflooredcoupon.hpp>
31#include <ql/cashflows/fixedratecoupon.hpp>
32#include <ql/cashflows/iborcoupon.hpp>
33#include <ql/payoff.hpp>
35#include <boost/algorithm/string/join.hpp>
46 if (maxEstimationTime_ != Null<Real>()) {
47 return time < maxEstimationTime_ || QuantLib::close_enough(time, maxEstimationTime_);
49 return QuantLib::close_enough(time, exactEstimationTime_);
54 if (maxEstimationTime_ != Null<Real>())
56 return time < exactEstimationTime_ || QuantLib::close_enough(time, exactEstimationTime_);
62 if (couponEndTime_ != Null<Real>() && couponStartTime_ != Null<Real>()) {
63 return std::max(0.0, std::min(1.0, (couponEndTime_ - time) / (couponEndTime_ - couponStartTime_)));
71 const Handle<YieldTermStructure>& discountCurve)
const {
72 return calculator_(lgm, t, state, discountCurve);
79 auto const& ts =
solver_->model()->parametrization()->termStructure();
80 auto const& c =
legs_[i][j];
81 Real payrec =
payer_[i] ? -1.0 : 1.0;
83 Real T =
solver_->model()->parametrization()->termStructure()->timeFromReference(c->date());
85 if (
auto cpn = QuantLib::ext::dynamic_pointer_cast<Coupon>(c)) {
87 if (
exercise_->type() == Exercise::American) {
95 info.
couponEndTime_ = ts->timeFromReference(cpn->accrualEndDate());
96 if (
auto ibor = QuantLib::ext::dynamic_pointer_cast<IborCoupon>(c)) {
99 const Handle<YieldTermStructure>& discountCurve) {
101 lgm.fixing(ibor->index(), ibor->fixingDate(), t, x) +
103 RandomVariable(x.size(), ibor->accrualPeriod() * ibor->nominal() * payrec) *
104 lgm.reducedDiscountBond(t, T, x, discountCurve);
107 }
else if (
auto fix = QuantLib::ext::dynamic_pointer_cast<FixedRateCoupon>(cpn)) {
110 const Handle<YieldTermStructure>& discountCurve) {
112 lgm.reducedDiscountBond(t, T, x, discountCurve);
115 }
else if (
auto on = QuantLib::ext::dynamic_pointer_cast<QuantExt::OvernightIndexedCoupon>(cpn)) {
118 const Handle<YieldTermStructure>& discountCurve) {
119 return lgm.compoundedOnRate(QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(on->index()), on->fixingDates(),
120 on->valueDates(), on->dt(), on->rateCutoff(), on->includeSpread(),
121 on->spread(), on->gearing(), on->lookback(), Null<Real>(), Null<Real>(),
122 false,
false, t, x) *
123 RandomVariable(x.size(), on->accrualPeriod() * on->nominal() * payrec) *
124 lgm.reducedDiscountBond(t, T, x, discountCurve);
127 }
else if (
auto av = QuantLib::ext::dynamic_pointer_cast<QuantExt::AverageONIndexedCoupon>(cpn)) {
130 const Handle<YieldTermStructure>& discountCurve) {
131 return lgm.averagedOnRate(QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(av->index()), av->fixingDates(),
132 av->valueDates(), av->dt(), av->rateCutoff(),
false, av->spread(),
133 av->gearing(), av->lookback(), Null<Real>(), Null<Real>(),
false,
false, t,
135 RandomVariable(x.size(), av->accrualPeriod() * av->nominal() * payrec) *
136 lgm.reducedDiscountBond(t, T, x, discountCurve);
139 }
else if (
auto bma = QuantLib::ext::dynamic_pointer_cast<QuantLib::AverageBMACoupon>(cpn)) {
142 const Handle<YieldTermStructure>& discountCurve) {
143 return lgm.averagedBmaRate(QuantLib::ext::dynamic_pointer_cast<BMAIndex>(bma->index()), bma->fixingDates(),
144 bma->accrualStartDate(), bma->accrualEndDate(),
false, bma->spread(),
145 bma->gearing(), Null<Real>(), Null<Real>(),
false, t, x) *
146 RandomVariable(x.size(), bma->accrualPeriod() * bma->nominal() * payrec) *
147 lgm.reducedDiscountBond(t, T, x, discountCurve);
150 }
else if (
auto cf = QuantLib::ext::dynamic_pointer_cast<QuantLib::CappedFlooredCoupon>(cpn)) {
151 auto und = cf->underlying();
152 if (
auto undibor = QuantLib::ext::dynamic_pointer_cast<QuantLib::IborCoupon>(und)) {
156 const Handle<YieldTermStructure>& discountCurve) {
157 RandomVariable cap(x.size(), cf->cap() == Null<Real>() ? QL_MAX_REAL : cf->cap());
158 RandomVariable floor(x.size(), cf->floor() == Null<Real>() ? -QL_MAX_REAL : cf->floor());
161 lgm.fixing(undibor->index(), undibor->fixingDate(), t, x) +
163 RandomVariable(x.size(), undibor->accrualPeriod() * undibor->nominal() * payrec) *
164 lgm.reducedDiscountBond(t, T, x, discountCurve);
168 }
else if (
auto cfon = QuantLib::ext::dynamic_pointer_cast<QuantExt::CappedFlooredOvernightIndexedCoupon>(cpn)) {
169 auto und = cfon->underlying();
172 const Handle<YieldTermStructure>& discountCurve) {
173 return lgm.compoundedOnRate(QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(und->index()),
174 und->fixingDates(), und->valueDates(), und->dt(), und->rateCutoff(),
175 und->includeSpread(), und->spread(), und->gearing(), und->lookback(),
176 cfon->cap(), cfon->floor(), cfon->localCapFloor(), cfon->nakedOption(), t,
178 RandomVariable(x.size(), cfon->accrualPeriod() * cfon->nominal() * payrec) *
179 lgm.reducedDiscountBond(t, T, x, discountCurve);
182 }
else if (
auto cfav = QuantLib::ext::dynamic_pointer_cast<QuantExt::CappedFlooredAverageONIndexedCoupon>(cpn)) {
183 auto und = cfav->underlying();
186 const Handle<YieldTermStructure>& discountCurve) {
187 return lgm.averagedOnRate(QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(und->index()), und->fixingDates(),
188 und->valueDates(), und->dt(), und->rateCutoff(), cfav->includeSpread(),
189 und->spread(), und->gearing(), und->lookback(), cfav->cap(), cfav->floor(),
190 cfav->localCapFloor(), cfav->nakedOption(), t, x) *
191 RandomVariable(x.size(), cfav->accrualPeriod() * cfav->nominal() * payrec) *
192 lgm.reducedDiscountBond(t, T, x, discountCurve);
195 }
else if (
auto cfbma = QuantLib::ext::dynamic_pointer_cast<QuantExt::CappedFlooredAverageBMACoupon>(cpn)) {
196 auto und = cfbma->underlying();
199 const Handle<YieldTermStructure>& discountCurve) {
200 return lgm.averagedBmaRate(QuantLib::ext::dynamic_pointer_cast<BMAIndex>(und->index()), und->fixingDates(),
201 und->accrualStartDate(), und->accrualEndDate(), cfbma->includeSpread(),
202 und->spread(), und->gearing(), cfbma->cap(), cfbma->floor(),
203 cfbma->nakedOption(), t, x) *
204 RandomVariable(x.size(), cfbma->accrualPeriod() * cfbma->nominal() * payrec) *
205 lgm.reducedDiscountBond(t, T, x, discountCurve);
208 }
else if (
auto sub = QuantLib::ext::dynamic_pointer_cast<QuantExt::SubPeriodsCoupon1>(cpn)) {
211 const Handle<YieldTermStructure>& discountCurve) {
212 return lgm.subPeriodsRate(sub->index(), sub->fixingDates(), t, x) *
213 RandomVariable(x.size(), sub->accrualPeriod() * sub->nominal() * payrec) *
214 lgm.reducedDiscountBond(t, T, x, discountCurve);
218 QL_REQUIRE(done,
"NumericLgmMultiLegOptionEngineBase: coupon type not handled, supported coupon types: Fix, "
219 "(capfloored) Ibor, (capfloored) ON comp, (capfloored) ON avg, BMA/SIFMA, subperiod. leg = "
220 << i <<
" cf = " << j);
226 const Handle<YieldTermStructure>& discountCurve) {
227 return RandomVariable(x.size(), c->amount() * payrec) * lgm.reducedDiscountBond(t, T, x, discountCurve);
238 "NumericLgmMultiLegOptionEngineBase: internal error: cashflow info: belongsToUnderlyingMaxTime_ is null. leg = "
239 << i <<
" cf = " << j);
241 "NumericLgmMultiLegOptionEngineBase: internal error: both maxEstimationTime_ and exactEstimationTime_ "
243 << i <<
" cf = " << j);
249 const Handle<YieldTermStructure>& discountCurve,
250 const QuantLib::ext::shared_ptr<RebatedExercise>& exercise,
const Date& d) {
251 if (exercise ==
nullptr)
253 if (exercise->type() == Exercise::American) {
256 t, lgm.
parametrization()->termStructure()->timeFromReference(exercise->rebatePaymentDate(d)), x);
258 auto f = std::find(exercise->dates().begin(), exercise->dates().end(), d);
259 QL_REQUIRE(f != exercise->dates().end(),
"NumericLgmMultiLegOptionEngine: internal error: exercise date "
260 << d <<
" from rebate payment not found amount exercise dates.");
261 Size index = std::distance(exercise->dates().begin(), f);
264 t, lgm.
parametrization()->termStructure()->timeFromReference(exercise->rebatePaymentDate(index)), x);
269 const QuantLib::ext::shared_ptr<LgmBackwardSolver>& solver,
const Handle<YieldTermStructure>& discountCurve,
270 const Size americanExerciseTimeStepsPerYear)
275 std::vector<std::string>& messages) {
281 const std::vector<Leg>& legs,
const std::vector<bool>& payer,
const std::vector<Currency>& currency,
282 const QuantLib::ext::shared_ptr<Exercise>& exercise,
const Settlement::Type& settlementType,
283 const Settlement::Method& settlementMethod, std::vector<std::string>& messages) {
285 bool isHandled =
true;
289 for (Size i = 1; i < currency.size(); ++i) {
290 if (currency[0] != currency[i]) {
291 messages.push_back(
"NumericLgmMultilegOptionEngine: can only handle single currency underlyings, got " +
292 currency[0].code() +
" on leg #1 and " + currency[i].code() +
" on leg #" +
293 std::to_string(i + 1));
298 for (Size i = 0; i < legs.size(); ++i) {
299 for (Size j = 0; j < legs[i].size(); ++j) {
300 if (
auto cpn = QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(legs[i][j])) {
301 if (cpn->index()->currency() != currency[0]) {
302 messages.push_back(
"NumericLgmMultilegOptionEngine: can only handle indices (" +
303 cpn->index()->name() +
") with same currency as unqiue pay currency (" +
312 for (Size i = 0; i < legs.size(); ++i) {
313 for (Size j = 0; j < legs[i].size(); ++j) {
314 if (
auto c = QuantLib::ext::dynamic_pointer_cast<Coupon>(legs[i][j])) {
315 if (!(QuantLib::ext::dynamic_pointer_cast<IborCoupon>(c) || QuantLib::ext::dynamic_pointer_cast<FixedRateCoupon>(c) ||
316 QuantLib::ext::dynamic_pointer_cast<QuantExt::OvernightIndexedCoupon>(c) ||
317 QuantLib::ext::dynamic_pointer_cast<QuantExt::AverageONIndexedCoupon>(c) ||
318 QuantLib::ext::dynamic_pointer_cast<QuantLib::AverageBMACoupon>(c) ||
319 QuantLib::ext::dynamic_pointer_cast<QuantExt::CappedFlooredOvernightIndexedCoupon>(c) ||
320 QuantLib::ext::dynamic_pointer_cast<QuantExt::CappedFlooredAverageONIndexedCoupon>(c) ||
321 QuantLib::ext::dynamic_pointer_cast<QuantExt::CappedFlooredAverageBMACoupon>(c) ||
322 QuantLib::ext::dynamic_pointer_cast<QuantExt::SubPeriodsCoupon1>(c) ||
323 (QuantLib::ext::dynamic_pointer_cast<QuantLib::CappedFlooredCoupon>(c) &&
324 QuantLib::ext::dynamic_pointer_cast<QuantLib::IborCoupon>(
325 QuantLib::ext::dynamic_pointer_cast<QuantLib::CappedFlooredCoupon>(c)->underlying())))) {
327 "NumericLgmMultilegOptionEngine: coupon type not handled, supported coupon types: Fix, "
328 "(capfloored) Ibor, (capfloored) ON comp, (capfloored) ON avg, BMA/SIFMA, subperiod. leg = " +
329 std::to_string(i) +
" cf = " + std::to_string(j));
341 std::vector<std::string> messages;
344 "NumericLgmMultiLegOptionEngineBase::calculate(): instrument is not handled: " << boost::join(messages,
", "));
350 for (Size i = 0; i <
legs_.size(); ++i) {
351 for (Size j = 0; j <
legs_[i].size(); ++j) {
361 auto rebatedExercise = QuantLib::ext::dynamic_pointer_cast<QuantExt::RebatedExercise>(
exercise_);
362 auto const& ts =
solver_->model()->parametrization()->termStructure();
363 Date refDate = ts->referenceDate();
367 enum class CashflowStatus { Open, Cached, Done };
369 std::vector<CashflowInfo> cashflows;
370 std::vector<CashflowStatus> cashflowStatus;
372 for (Size i = 0; i <
legs_.size(); ++i) {
373 for (Size j = 0; j <
legs_[i].size(); ++j) {
375 cashflowStatus.push_back(CashflowStatus::Open);
381 std::set<Real> optionTimes;
382 std::map<Real, Date> optionDates;
384 if (
exercise_->type() == Exercise::Bermudan ||
exercise_->type() == Exercise::European) {
385 for (
auto const& d :
exercise_->dates()) {
387 optionTimes.insert(ts->timeFromReference(d));
388 optionDates[ts->timeFromReference(d)] = d;
391 }
else if (
exercise_->type() == Exercise::American) {
392 QL_REQUIRE(
exercise_->dates().size() == 2,
"NumericLgmMultiLegOptionEngineBase::calculate(): internal error: "
393 "expected 2 dates for AmericanExercise, got "
395 Real t1 = std::max(0.0, ts->timeFromReference(
exercise_->dates().front()));
396 Real t2 = std::max(t1, ts->timeFromReference(
exercise_->dates().back()));
399 optionTimes.insert(t1);
400 for (Size i = 0; i <=
steps; ++i) {
401 optionTimes.insert(t1 +
static_cast<Real
>(i) * (t2 - t1) /
static_cast<Real
>(
steps));
404 QL_FAIL(
"NumericLgmMultiLegOptionEngineBase::calculate(): internal error: exercise type "
405 <<
static_cast<int>(
exercise_->type()) <<
" not handled.");
410 std::set<Real> requiredCfSimTimes;
412 for (
auto const& c : cashflows) {
413 if (Real t = c.requiredSimulationTime(); t != Null<Real>())
414 requiredCfSimTimes.insert(t);
419 std::set<Real> timeGrid{0.0};
420 timeGrid.insert(optionTimes.begin(), optionTimes.end());
421 timeGrid.insert(requiredCfSimTimes.begin(), requiredCfSimTimes.end());
431 std::vector<RandomVariable> cache(cashflows.size());
433 for (
auto it = timeGrid.rbegin(); it != timeGrid.rend(); ++it) {
436 Real t_to = (it != std::next(timeGrid.rend(), -1)) ? *std::next(it, 1) : t_from;
444 for (Size i = 0; i < cashflows.size(); ++i) {
445 if (cashflowStatus[i] == CashflowStatus::Done)
447 if (cashflows[i].isPartOfUnderlying(t_from)) {
449 bool isBrokenCoupon = !QuantLib::close_enough(cpnRatio.
at(0), 1.0);
450 if (cashflowStatus[i] == CashflowStatus::Cached) {
451 if (isBrokenCoupon) {
452 provisionalNpv += cache[i] * cpnRatio;
454 underlyingNpv += cache[i];
456 cashflowStatus[i] = CashflowStatus::Done;
458 }
else if (cashflows[i].canBeEstimated(t_from)) {
459 if (isBrokenCoupon) {
461 cashflowStatus[i] = CashflowStatus::Cached;
462 provisionalNpv += cache[i] * cpnRatio;
464 underlyingNpv += cashflows[i].pv(lgm, t_from, state,
discountCurve_);
465 cashflowStatus[i] = CashflowStatus::Done;
468 provisionalNpv += cashflows[i].pv(lgm, t_from, state,
discountCurve_) * cpnRatio;
470 }
else if (cashflows[i].mustBeEstimated(t_from) && cashflowStatus[i] == CashflowStatus::Open) {
472 cashflowStatus[i] = CashflowStatus::Cached;
478 if (optionTimes.find(t_from) != optionTimes.end()) {
481 exercise_->type() == Exercise::American ? Null<Date>() : optionDates.at(t_from));
482 optionNpv =
max(optionNpv, underlyingNpv + provisionalNpv + rebateNpv);
487 if (t_from != t_to) {
488 underlyingNpv =
solver_->rollback(underlyingNpv, t_from, t_to);
489 optionNpv =
solver_->rollback(optionNpv, t_from, t_to);
490 for (
auto& c : cache) {
491 if (!c.initialised())
493 c =
solver_->rollback(c, t_from, t_to);
496 if (it == std::next(timeGrid.rend(), -1))
497 provisionalNpv =
solver_->rollback(provisionalNpv, t_from, t_to);
505 for (
auto const& c : cache) {
513 if (rebatedExercise) {
514 for (Size i = 0; i < rebatedExercise->dates().size(); ++i) {
515 std::ostringstream d;
516 d << QuantLib::io::iso_date(rebatedExercise->dates()[i]);
524 const Real
sy,
const Size ny,
const Real
sx,
526 const Handle<YieldTermStructure>& discountCurve,
527 const Size americanExerciseTimeStepsPerYear)
529 discountCurve, americanExerciseTimeStepsPerYear) {
530 registerWith(
solver_->model());
535 const Real maxTime,
const QuantLib::FdmSchemeDesc scheme,
536 const Size stateGridPoints,
const Size timeStepsPerYear,
537 const Real mesherEpsilon,
538 const Handle<YieldTermStructure>& discountCurve,
539 const Size americanExerciseTimeStepsPerYear)
541 QuantLib::ext::make_shared<
LgmFdSolver>(model, maxTime, scheme, stateGridPoints, timeStepsPerYear, mesherEpsilon),
542 discountCurve, americanExerciseTimeStepsPerYear) {
543 registerWith(
solver_->model());
564 const Real
sy,
const Size ny,
const Real
sx,
const Size nx,
565 const Handle<YieldTermStructure>& discountCurve,
566 const Size americanExerciseTimeStepsPerYear)
568 discountCurve, americanExerciseTimeStepsPerYear) {
569 registerWith(
solver_->model());
574 const Real maxTime,
const QuantLib::FdmSchemeDesc scheme,
575 const Size stateGridPoints,
const Size timeStepsPerYear,
576 const Real mesherEpsilon,
577 const Handle<YieldTermStructure>& discountCurve,
578 const Size americanExerciseTimeStepsPerYear)
580 QuantLib::ext::make_shared<
LgmFdSolver>(model, maxTime, scheme, stateGridPoints, timeStepsPerYear, mesherEpsilon),
581 discountCurve, americanExerciseTimeStepsPerYear) {
582 registerWith(
solver_->model());
589 for (Size i = 0; i <
arguments_.payer.size(); ++i) {
605 const QuantLib::ext::shared_ptr<LinearGaussMarkovModel>& model,
const Real
sy,
const Size ny,
const Real
sx,
const Size nx,
606 const Handle<YieldTermStructure>& discountCurve,
const Size americanExerciseTimeStepsPerYear)
608 discountCurve, americanExerciseTimeStepsPerYear) {
609 registerWith(
solver_->model());
614 const QuantLib::ext::shared_ptr<LinearGaussMarkovModel>& model,
const Real maxTime,
const QuantLib::FdmSchemeDesc scheme,
615 const Size stateGridPoints,
const Size timeStepsPerYear,
const Real mesherEpsilon,
616 const Handle<YieldTermStructure>& discountCurve,
const Size americanExerciseTimeStepsPerYear)
618 QuantLib::ext::make_shared<
LgmFdSolver>(model, maxTime, scheme, stateGridPoints, timeStepsPerYear, mesherEpsilon),
619 discountCurve, americanExerciseTimeStepsPerYear) {
620 registerWith(
solver_->model());
627 for (Size i = 0; i <
arguments_.payer.size(); ++i) {
coupon paying the weighted average of the daily overnight rate
coupon paying a capped / floored average bma rate
const Instrument::results * results_
Numerical convolution solver for the LGM model.
Numerical FD solver for the LGM model.
QuantLib::ext::shared_ptr< IrLgm1fParametrization > parametrization() const
RandomVariable reducedDiscountBond(const Time t, const Time T, const RandomVariable &x, const Handle< YieldTermStructure > &discountCurve=Handle< YieldTermStructure >()) const
const std::vector< Leg > & legs() const
const Settlement::Type settlementType() const
const Settlement::Method settlementMethod() const
const QuantLib::ext::shared_ptr< Exercise > exercise() const
const std::vector< Currency > & currency() const
const std::vector< bool > & payer() const
QuantLib::ext::shared_ptr< LgmBackwardSolver > solver_
Handle< YieldTermStructure > discountCurve_
std::vector< Currency > currency_
CashflowInfo buildCashflowInfo(const Size i, const Size j) const
QuantLib::ext::shared_ptr< Exercise > exercise_
std::map< std::string, boost::any > additionalResults_
Size americanExerciseTimeStepsPerYear_
static bool instrumentIsHandled(const MultiLegOption &m, std::vector< std::string > &messages)
std::vector< bool > payer_
Settlement::Method settlementMethod_
Settlement::Type settlementType_
NumericLgmMultiLegOptionEngineBase(const QuantLib::ext::shared_ptr< LgmBackwardSolver > &solver, const Handle< YieldTermStructure > &discountCurve=Handle< YieldTermStructure >(), const Size americanExerciseTimeStepsPerYear=24)
void calculate() const override
NumericLgmMultiLegOptionEngine(const QuantLib::ext::shared_ptr< LinearGaussMarkovModel > &model, const Real sy, const Size ny, const Real sx, const Size nx, const Handle< YieldTermStructure > &discountCurve=Handle< YieldTermStructure >(), const Size americanExerciseTimeStepsPerYear=24)
NumericLgmNonstandardSwaptionEngine(const QuantLib::ext::shared_ptr< LinearGaussMarkovModel > &model, const Real sy, const Size ny, const Real sx, const Size nx, const Handle< YieldTermStructure > &discountCurve=Handle< YieldTermStructure >(), const Size americanExerciseTimeStepsPerYear=24)
void calculate() const override
NumericLgmSwaptionEngine(const QuantLib::ext::shared_ptr< LinearGaussMarkovModel > &model, const Real sy, const Size ny, const Real sx, const Size nx, const Handle< YieldTermStructure > &discountCurve=Handle< YieldTermStructure >(), const Size americanExerciseTimeStepsPerYear=24)
void calculate() const override
numeric convolution solver for the LGM model using RandoMVariable
std::map< std::string, boost::any > getAdditionalResultsMap(const LgmCalibrationInfo &info)
RandomVariable getRebatePv(const LgmVectorised &lgm, const Real t, const RandomVariable &x, const Handle< YieldTermStructure > &discountCurve, const QuantLib::ext::shared_ptr< RebatedExercise > &exercise, const Date &d)
CompiledFormula min(CompiledFormula x, const CompiledFormula &y)
CompiledFormula max(CompiledFormula x, const CompiledFormula &y)
coupon paying the compounded daily overnight rate, copy of QL class, added includeSpread flag
more flexible version of ql class
JY INF index sigma component.
Real couponRatio(const Real time) const
bool isPartOfUnderlying(const Real optionTime) const
Real belongsToUnderlyingMaxTime_
Real exactEstimationTime_
std::function< RandomVariable(const LgmVectorised &, const Real, const RandomVariable &, const Handle< YieldTermStructure > &)> calculator_
bool mustBeEstimated(const Real optionTime) const
bool canBeEstimated(const Real optionTime) const
Real requiredSimulationTime() const
RandomVariable pv(const LgmVectorised &lgm, const Real t, const RandomVariable &state, const Handle< YieldTermStructure > &discountCurve) const
Real at(const Size i) const
Coupon with a number of sub-periods.
Swap::arguments * arguments_
std::vector< Size > steps