UpperTriangularIndexPairMatrix UpperTriangleVanillaSwaptionQuotes::get_UpperTriangularSwaptionIndexMatrix() const { if(LMM::WARNLMM ()) std::cout<<LMM::WARN_MSG << "UpperTriangleVanillaSwaptionQuotes::get_UpperTriangularSwaptionIndexMatrix() generate matrix copy, DO NOT USE IN A LOOP" << std::endl; size_t nbRow = upperTriangleVanillaSwaptionQuotes_.size1(); size_t nbCol = upperTriangleVanillaSwaptionQuotes_.size2(); assert(nbRow == nbCol); UpperTriangularIndexPairMatrix swap_indices_matrix(nbRow,nbCol ); for(size_t k=0;k<nbRow;++k)//not use first row firt column { swap_indices_matrix(0,k)=std::pair<size_t,size_t>(-1,-1); swap_indices_matrix(k,0)=std::pair<size_t,size_t>(-1,-1); } for(size_t iExpirity = 1; iExpirity<nbRow; ++iExpirity) // row { for(size_t jTenor = 1; jTenor<nbCol-iExpirity; ++jTenor) // col { std::pair<size_t,size_t> swap_pair_indice; const VanillaSwap swap = upperTriangleVanillaSwaptionQuotes_(iExpirity,jTenor).first.getUnderlyingSwap(); swap_pair_indice.first = swap.get_indexStart(); swap_pair_indice.second = swap.get_indexEnd(); swap_indices_matrix(iExpirity,jTenor) = swap_pair_indice; } } return swap_indices_matrix; }
MakeCapFloor::operator shared_ptr<CapFloor>() const { VanillaSwap swap = makeVanillaSwap_; Leg leg = swap.floatingLeg(); if (firstCapletExcluded_) leg.erase(leg.begin()); // only leaves the last coupon if (asOptionlet_ && leg.size() > 1) { Leg::iterator end = leg.end(); // Sun Studio needs an lvalue leg.erase(leg.begin(), --end); } std::vector<Rate> strikeVector(1, strike_); if (strike_ == Null<Rate>()) { // temporary patch... // should be fixed for every CapFloor::Engine shared_ptr<BlackCapFloorEngine> temp = dynamic_pointer_cast<BlackCapFloorEngine>(engine_); QL_REQUIRE(temp, "cannot calculate ATM without a BlackCapFloorEngine"); Handle<YieldTermStructure> discountCurve = temp->termStructure(); strikeVector[0] = CashFlows::atmRate(leg, **discountCurve, false, discountCurve->referenceDate()); } shared_ptr<CapFloor> capFloor(new CapFloor(capFloorType_, leg, strikeVector)); capFloor->setPricingEngine(engine_); return capFloor; }
double LmmVanillaSwapPricer::pvFixedLeg( const LMM::Index indexValuationDate, const VanillaSwap & vanillaSwap, const std::vector<double> & numeraire) const { assert(indexValuationDate <= vanillaSwap.get_indexStart()); //YY TODO: this test too slow, esp: within MC simulation assert(pLMMTenorStructure_->get_horizon() >= vanillaSwap.get_indexEnd()); // if not cannot price this swap; const double calculatedAnuity = this->annuity(indexValuationDate,vanillaSwap,numeraire); return vanillaSwap.get_strike()*calculatedAnuity; }
double LmmVanillaSwapPricer::swapNPV_Analytical_2(const VanillaSwap& vanillaSwap, const std::vector<double>& liborsInitValue) const // initLibor[i] = L_i[T_0] { assert(pLMMTenorStructure_->get_horizon()+1 == liborsInitValue.size()); assert(pLMMTenorStructure_->get_horizon() >= vanillaSwap.get_indexEnd()); // if not cannot price this swap; size_t horizon = pLMMTenorStructure_->get_horizon(); const double & floatingLegdelta_T = vanillaSwap.get_floatingLegTenorType().YearFraction(); const double & fixedLegdelta_T = vanillaSwap.get_fixedLegTenorType().YearFraction(); //! ZC[i] = P(T_0,T_i) std::vector<double> ZC(horizon+2); ZC[0] = 1.0; for(size_t i=1; i<ZC.size(); ++i) { ZC[i] = ZC[i-1]/(1+floatingLegdelta_T*liborsInitValue[i-1]); } //! numeraire std::vector<double> numeraire(ZC.size() ); // determinisitc IR for(size_t i=0; i<ZC.size(); ++i) { numeraire[i] = 1.0/ZC[i]; } //! pvFloatingLeg: 1 - 1 const std::vector<LMM::Index>& floatingLegPaymentIndexSchedule = vanillaSwap.get_floatingLegPaymentIndexSchedule(); //size_t floatingLegTenorLmmTenorRatio = vanillaSwap.get_floatingLegTenorLmmTenorRatio(); LMM::Index indexFloatingLegStart = floatingLegPaymentIndexSchedule.front(); LMM::Index indexFloatingLegEnd = floatingLegPaymentIndexSchedule.back(); double pvFloatingLegValue = ZC[indexFloatingLegStart-1] - ZC[indexFloatingLegEnd]; ////! pvFloatingLeg: exact //double pvFloatingLeg = 0.0; //const std::vector<LMM::Index>& floatingLegPaymentIndexSchedule = vanillaSwap.get_floatingLegPaymentIndexSchedule(); //for(size_t itr = 0; itr < floatingLegPaymentIndexSchedule.size(); ++itr) //{ // //! At time T_{i+1}, pay: L_i(T_i) // size_t floatingLegPaymentIndex = floatingLegPaymentIndexSchedule[itr]; // = i+1 // size_t indexLibor = floatingLegPaymentIndex-1; // =i, because : floatingTenor = lmmTenor // pvFloatingLeg += floatingLegdelta_T*initLibor[indexLibor]*ZC[floatingLegPaymentIndex]; //} LMM::Index indexValuationDate = 0; double pvFixedLegValue = pvFixedLeg(indexValuationDate,vanillaSwap,numeraire); return pvFloatingLegValue - pvFixedLegValue; }
double LmmVanillaSwapPricer::annuity( const LMM::Index indexValuationDate, const VanillaSwap & vanillaSwap, const std::vector<double> & numeraire) const { assert(indexValuationDate <= vanillaSwap.get_indexStart()); //YY TODO: this test too slow, esp: within MC simulation assert(pLMMTenorStructure_->get_horizon() >= vanillaSwap.get_indexEnd()); // if not cannot price this swap; double price = 0.0; const std::vector<LMM::Index>& fixedLegPaymentIndexSchedule = vanillaSwap.get_fixedLegPaymentIndexSchedule(); for(size_t itr = 0; itr < fixedLegPaymentIndexSchedule.size(); ++itr) { size_t fixedLegPaymentIndex = fixedLegPaymentIndexSchedule[itr]; double delta_T = vanillaSwap.get_DeltaTFixedLeg(itr); //std::cout << "numeraire[indexValuationDate]/numeraire[fixedLegPaymentIndex] = " << numeraire[indexValuationDate]/numeraire[fixedLegPaymentIndex] << std::endl; price += delta_T*numeraire[indexValuationDate]/numeraire[fixedLegPaymentIndex]; } return price; }
//! Annuity at time 0 double LmmVanillaSwapPricer::annuity0(const VanillaSwap& vanillaSwap, const std::vector<double>& liborsInitValue) const { assert(pLMMTenorStructure_->get_horizon()+1 == liborsInitValue.size()); assert(pLMMTenorStructure_->get_horizon() >= vanillaSwap.get_indexEnd()); // if not cannot price this swap; size_t horizon = pLMMTenorStructure_->get_horizon(); const double & fixedLegdelta_T = vanillaSwap.get_fixedLegTenorType().YearFraction(); const double & floatingLegdelta_T = vanillaSwap.get_floatingLegTenorType().YearFraction(); //! ZC[i] = P(T_0,T_i) std::vector<double> ZC(vanillaSwap.get_indexEnd()+1); ZC[0] = 1.0; for(size_t i=1; i<ZC.size(); ++i) { size_t indexLibor = i-1; //double deltaT = vanillaSwap.get_DeltaTFloatLeg(indexLibor); // YY bug double deltaT = floatingLegdelta_T; ZC[i] = ZC[i-1]/(1+deltaT*liborsInitValue[indexLibor]); } double price = 0.0; const std::vector<LMM::Index>& fixedLegPaymentIndexSchedule = vanillaSwap.get_fixedLegPaymentIndexSchedule(); for(size_t itr = 0; itr < fixedLegPaymentIndexSchedule.size(); ++itr) { size_t fixedLegPaymentIndex = fixedLegPaymentIndexSchedule[itr]; double delta_T = vanillaSwap.get_DeltaTFixedLeg(itr); //std::cout << "numeraire[indexValuationDate]/numeraire[fixedLegPaymentIndex] = " << numeraire[indexValuationDate]/numeraire[fixedLegPaymentIndex] << std::endl; price += delta_T*ZC[fixedLegPaymentIndex]; } return price; }
double LmmVanillaSwapPricer::swapRate_Analytical(const VanillaSwap& vanillaSwap, const std::vector<double>& liborsInitValue) const { assert(pLMMTenorStructure_->get_horizon()+1 == liborsInitValue.size()); assert(pLMMTenorStructure_->get_horizon() >= vanillaSwap.get_indexEnd()); // if not cannot price this swap; size_t horizon = pLMMTenorStructure_->get_horizon(); const double & fixedLegdelta_T = vanillaSwap.get_fixedLegTenorType().YearFraction(); const double & floatingLegdelta_T = vanillaSwap.get_floatingLegTenorType().YearFraction(); //! ZC[i] = P(T_0,T_i) std::vector<double> ZC(vanillaSwap.get_indexEnd()+1); ZC[0] = 1.0; for(size_t i=1; i<ZC.size(); ++i) { size_t indexLibor = i-1; //double deltaT = vanillaSwap.get_DeltaTFloatLeg(indexLibor); // YY bug double deltaT = floatingLegdelta_T; ZC[i] = ZC[i-1]/(1+deltaT*liborsInitValue[indexLibor]); } //! pvFloatingLeg: 1 - 1 double pvFloatingLegValue = ZC[vanillaSwap.get_indexStart()] - ZC[vanillaSwap.get_indexEnd()]; //! pvAnnuity double pvAnnuity = annuity0(vanillaSwap, liborsInitValue); //! swapRate return pvFloatingLegValue / pvAnnuity; }
void BlackStyleSwaptionEngine<Spec>::calculate() const { static const Spread basisPoint = 1.0e-4; Date exerciseDate = arguments_.exercise->date(0); // the part of the swap preceding exerciseDate should be truncated // to avoid taking into account unwanted cashflows VanillaSwap swap = *arguments_.swap; Rate strike = swap.fixedRate(); // using the discounting curve // swap.iborIndex() might be using a different forwarding curve swap.setPricingEngine(boost::shared_ptr<PricingEngine>(new DiscountingSwapEngine(discountCurve_, false))); Rate atmForward = swap.fairRate(); // Volatilities are quoted for zero-spreaded swaps. // Therefore, any spread on the floating leg must be removed // with a corresponding correction on the fixed leg. if (swap.spread()!=0.0) { Spread correction = swap.spread() * std::fabs(swap.floatingLegBPS()/swap.fixedLegBPS()); strike -= correction; atmForward -= correction; results_.additionalResults["spreadCorrection"] = correction; } else { results_.additionalResults["spreadCorrection"] = 0.0; } results_.additionalResults["strike"] = strike; results_.additionalResults["atmForward"] = atmForward; // using the discounting curve swap.setPricingEngine(boost::shared_ptr<PricingEngine>( new DiscountingSwapEngine(discountCurve_, false))); Real annuity; switch(arguments_.settlementType) { case Settlement::Physical: { annuity = std::fabs(swap.fixedLegBPS())/basisPoint; break; } case Settlement::Cash: { const Leg& fixedLeg = swap.fixedLeg(); boost::shared_ptr<FixedRateCoupon> firstCoupon = boost::dynamic_pointer_cast<FixedRateCoupon>(fixedLeg[0]); DayCounter dayCount = firstCoupon->dayCounter(); Real fixedLegCashBPS = CashFlows::bps(fixedLeg, InterestRate(atmForward, dayCount, Compounded, Annual), false, discountCurve_->referenceDate()) ; annuity = std::fabs(fixedLegCashBPS/basisPoint); break; } default: QL_FAIL("unknown settlement type"); } results_.additionalResults["annuity"] = annuity; // the swap length calculation might be improved using the value date // of the exercise date Time swapLength = vol_->swapLength(exerciseDate, arguments_.floatingPayDates.back()); results_.additionalResults["swapLength"] = swapLength; Real variance = vol_->blackVariance(exerciseDate, swapLength, strike); // once the deprecated methods allowing to override the displacement // are gone, we can avoid this and directly read the displacement // from the volatility structure Real displacement = displacement_ == Null<Real>() ? vol_->shift(exerciseDate, swapLength) : displacement_; Real stdDev = std::sqrt(variance); results_.additionalResults["stdDev"] = stdDev; Option::Type w = (arguments_.type==VanillaSwap::Payer) ? Option::Call : Option::Put; results_.value = Spec().value(w, strike, atmForward, stdDev, annuity, displacement); Time exerciseTime = vol_->timeFromReference(exerciseDate); results_.additionalResults["vega"] = Spec().vega( strike, atmForward, stdDev, exerciseTime, annuity, displacement); }
void LgmSwaptionEngineAD::calculate() const { // collect data needed for core computation routine QL_REQUIRE(arguments_.settlementType == Settlement::Physical, "cash-settled swaptions not yet implemented ..."); Date settlement = model_->termStructure()->referenceDate(); if (arguments_.exercise->dates().back() <= settlement) { // swaption is expired, possibly generated swap is not // valued results_.value = 0.0; return; } int idxMax = static_cast<int>(arguments_.exercise->dates().size()) - 1; int minIdxAlive = static_cast<int>( std::upper_bound(arguments_.exercise->dates().begin(), arguments_.exercise->dates().end(), settlement) - arguments_.exercise->dates().begin()); VanillaSwap swap = *arguments_.swap; int callput = arguments_.type == VanillaSwap::Payer ? 1 : -1; Schedule fixedSchedule = swap.fixedSchedule(); Schedule floatSchedule = swap.floatingSchedule(); Date expiry0; std::vector<int> fix_startidxes, float_startidxes; std::vector<Date> expiryDates; for (int idx = minIdxAlive; idx <= idxMax; ++idx) { expiry0 = arguments_.exercise->dates()[idx]; expiryDates.push_back(expiry0); Size j1 = std::upper_bound(fixedSchedule.dates().begin(), fixedSchedule.dates().end(), expiry0 - 1) - fixedSchedule.dates().begin(); Size k1 = std::upper_bound(floatSchedule.dates().begin(), floatSchedule.dates().end(), expiry0 - 1) - floatSchedule.dates().begin(); fix_startidxes.push_back(j1); float_startidxes.push_back(k1); } std::vector<double> float_mults, index_acctimes, float_spreads, fix_cpn; std::vector<Date> floatt1Dates, floatt2Dates, floattpDates; std::vector<Date> fixtpDates; for (Size i = 0; i < arguments_.floatingFixingDates.size(); ++i) { float_mults.push_back(arguments_.nominal * arguments_.floatingAccrualTimes[i]); float_spreads.push_back(arguments_.floatingSpreads[i]); boost::shared_ptr<IborIndex> index = arguments_.swap->iborIndex(); Date d1 = index->valueDate(arguments_.floatingFixingDates[i]); Date d2 = index->maturityDate(d1); double acctime = index->dayCounter().yearFraction(d1, d2, d1, d2); floatt1Dates.push_back(d1); floatt2Dates.push_back(d2); floattpDates.push_back(arguments_.floatingPayDates[i]); index_acctimes.push_back(acctime); } for (Size i = 0; i < arguments_.fixedCoupons.size(); ++i) { fix_cpn.push_back(arguments_.fixedCoupons[i]); fixtpDates.push_back(arguments_.fixedPayDates[i]); } // join all dates and fill index vectors std::vector<Date> allDates; std::vector<double> allTimes; // with settlement as first entry ! std::vector<int> expiries, floatt1s, floatt2s, floattps, fixtps; std::vector<double> modpar; allDates.reserve(expiryDates.size() + floatt1Dates.size() + floatt2Dates.size() + floattpDates.size() + fixtpDates.size()); allTimes.reserve(allDates.size()); modpar.reserve(3 * allDates.size()); allDates.push_back(settlement); allDates.insert(allDates.end(), expiryDates.begin(), expiryDates.end()); allDates.insert(allDates.end(), floatt1Dates.begin(), floatt1Dates.end()); allDates.insert(allDates.end(), floatt2Dates.begin(), floatt2Dates.end()); allDates.insert(allDates.end(), floattpDates.begin(), floattpDates.end()); allDates.insert(allDates.end(), fixtpDates.begin(), fixtpDates.end()); std::sort(allDates.begin(), allDates.end()); allDates.erase(unique(allDates.begin(), allDates.end()), allDates.end()); for (Size i = 0; i < allDates.size(); ++i) { allTimes.push_back( model_->termStructure()->timeFromReference(allDates[i])); } for (Size i = 0; i < allDates.size(); ++i) { modpar.push_back(model_->parametrization()->H(allTimes[i])); } for (Size i = 0; i < allDates.size(); ++i) { modpar.push_back(model_->parametrization()->zeta(allTimes[i])); } for (Size i = 0; i < allDates.size(); ++i) { modpar.push_back(model_->termStructure()->discount(allTimes[i])); } for (Size i = 0; i < expiryDates.size(); ++i) { expiries.push_back( std::find(allDates.begin(), allDates.end(), expiryDates[i]) - allDates.begin()); } for (Size i = 0; i < floatt1Dates.size(); ++i) { floatt1s.push_back( std::find(allDates.begin(), allDates.end(), floatt1Dates[i]) - allDates.begin()); } for (Size i = 0; i < floatt2Dates.size(); ++i) { floatt2s.push_back( std::find(allDates.begin(), allDates.end(), floatt2Dates[i]) - allDates.begin()); } for (Size i = 0; i < floattpDates.size(); ++i) { floattps.push_back( std::find(allDates.begin(), allDates.end(), floattpDates[i]) - allDates.begin()); } for (Size i = 0; i < fixtpDates.size(); ++i) { fixtps.push_back( std::find(allDates.begin(), allDates.end(), fixtpDates[i]) - allDates.begin()); } // call core computation routine and set results int ntimes = allTimes.size(); int nexpiries = expiries.size(); int nfloats = floatt1s.size(); int nfixs = fix_cpn.size(); double res = 0.0; std::vector<Real> dres(3*ntimes); int integration_pts = integrationPoints_; double std_devs = stddevs_; lgm_swaption_engine_ad_(&ntimes, &allTimes[0], &modpar[0], &nexpiries, &expiries[0], &callput, &nfloats, &float_startidxes[0], &float_mults[0], &index_acctimes[0], &float_spreads[0], &floatt1s[0], &floatt2s[0], &floattps[0], &fix_startidxes[0], &nfixs, &fix_cpn[0], &fixtps[0], &integration_pts, &std_devs, &res, &dres[0]); results_.value = res; std::vector<Real> H_sensitivity(dres.begin(),dres.begin()+ntimes); std::vector<Real> zeta_sensitivity(dres.begin()+ntimes,dres.begin()+2*ntimes); std::vector<Real> discount_sensitivity(dres.begin()+2*ntimes,dres.begin()+3*ntimes); results_.additionalResults["sensitivityTimes"] = allTimes; results_.additionalResults["sensitivityH"] = H_sensitivity; results_.additionalResults["sensitivityZeta"] = zeta_sensitivity; results_.additionalResults["sensitivityDiscount"] = discount_sensitivity; }
void Gaussian1dSwaptionEngine::calculate() const { QL_REQUIRE(arguments_.settlementType == Settlement::Physical, "cash-settled swaptions not yet implemented ..."); Date settlement = model_->termStructure()->referenceDate(); if (arguments_.exercise->dates().back() <= settlement) { // swaption is expired, possibly generated swap is not // valued results_.value = 0.0; return; } int idx = static_cast<int>(arguments_.exercise->dates().size()) - 1; int minIdxAlive = static_cast<int>( std::upper_bound(arguments_.exercise->dates().begin(), arguments_.exercise->dates().end(), settlement) - arguments_.exercise->dates().begin()); VanillaSwap swap = *arguments_.swap; Option::Type type = arguments_.type == VanillaSwap::Payer ? Option::Call : Option::Put; Schedule fixedSchedule = swap.fixedSchedule(); Schedule floatSchedule = swap.floatingSchedule(); Array npv0(2 * integrationPoints_ + 1, 0.0), npv1(2 * integrationPoints_ + 1, 0.0); Array z = model_->yGrid(stddevs_, integrationPoints_); Array p(z.size(), 0.0); Date expiry1 = Null<Date>(), expiry0; Time expiry1Time = Null<Real>(), expiry0Time; do { if (idx == minIdxAlive - 1) expiry0 = settlement; else expiry0 = arguments_.exercise->dates()[idx]; expiry0Time = std::max( model_->termStructure()->timeFromReference(expiry0), 0.0); Size j1 = std::upper_bound(fixedSchedule.dates().begin(), fixedSchedule.dates().end(), expiry0 - 1) - fixedSchedule.dates().begin(); Size k1 = std::upper_bound(floatSchedule.dates().begin(), floatSchedule.dates().end(), expiry0 - 1) - floatSchedule.dates().begin(); // a lazy object is not thread safe, neither is the caching // in gsrprocess. therefore we trigger computations here such // that neither lazy object recalculation nor write access // during caching occurs in the parallized loop below. // this is known to work for the gsr and markov functional // model implementations of Gaussian1dModel #ifdef _OPENMP if (expiry0 > settlement) { for (Size l = k1; l < arguments_.floatingCoupons.size(); l++) { model_->forwardRate(arguments_.floatingFixingDates[l], expiry0, 0.0, arguments_.swap->iborIndex()); model_->zerobond(arguments_.floatingPayDates[l], expiry0, 0.0, discountCurve_); } for (Size l = j1; l < arguments_.fixedCoupons.size(); l++) { model_->zerobond(arguments_.fixedPayDates[l], expiry0, 0.0, discountCurve_); } model_->numeraire(expiry0Time, 0.0, discountCurve_); } #endif #pragma omp parallel for default(shared) firstprivate(p) if(expiry0>settlement) for (Size k = 0; k < (expiry0 > settlement ? npv0.size() : 1); k++) { Real price = 0.0; if (expiry1Time != Null<Real>()) { Array yg = model_->yGrid(stddevs_, integrationPoints_, expiry1Time, expiry0Time, expiry0 > settlement ? z[k] : 0.0); CubicInterpolation payoff0( z.begin(), z.end(), npv1.begin(), CubicInterpolation::Spline, true, CubicInterpolation::Lagrange, 0.0, CubicInterpolation::Lagrange, 0.0); for (Size i = 0; i < yg.size(); i++) { p[i] = payoff0(yg[i], true); } CubicInterpolation payoff1( z.begin(), z.end(), p.begin(), CubicInterpolation::Spline, true, CubicInterpolation::Lagrange, 0.0, CubicInterpolation::Lagrange, 0.0); for (Size i = 0; i < z.size() - 1; i++) { price += model_->gaussianShiftedPolynomialIntegral( 0.0, payoff1.cCoefficients()[i], payoff1.bCoefficients()[i], payoff1.aCoefficients()[i], p[i], z[i], z[i], z[i + 1]); } if (extrapolatePayoff_) { if (flatPayoffExtrapolation_) { price += model_->gaussianShiftedPolynomialIntegral( 0.0, 0.0, 0.0, 0.0, p[z.size() - 2], z[z.size() - 2], z[z.size() - 1], 100.0); price += model_->gaussianShiftedPolynomialIntegral( 0.0, 0.0, 0.0, 0.0, p[0], z[0], -100.0, z[0]); } else { if (type == Option::Call) price += model_->gaussianShiftedPolynomialIntegral( 0.0, payoff1.cCoefficients()[z.size() - 2], payoff1.bCoefficients()[z.size() - 2], payoff1.aCoefficients()[z.size() - 2], p[z.size() - 2], z[z.size() - 2], z[z.size() - 1], 100.0); if (type == Option::Put) price += model_->gaussianShiftedPolynomialIntegral( 0.0, payoff1.cCoefficients()[0], payoff1.bCoefficients()[0], payoff1.aCoefficients()[0], p[0], z[0], -100.0, z[0]); } } } npv0[k] = price; if (expiry0 > settlement) { Real floatingLegNpv = 0.0; for (Size l = k1; l < arguments_.floatingCoupons.size(); l++) { floatingLegNpv += arguments_.nominal * arguments_.floatingAccrualTimes[l] * (arguments_.floatingSpreads[l] + model_->forwardRate( arguments_.floatingFixingDates[l], expiry0, z[k], arguments_.swap->iborIndex())) * model_->zerobond(arguments_.floatingPayDates[l], expiry0, z[k], discountCurve_); } Real fixedLegNpv = 0.0; for (Size l = j1; l < arguments_.fixedCoupons.size(); l++) { fixedLegNpv += arguments_.fixedCoupons[l] * model_->zerobond(arguments_.fixedPayDates[l], expiry0, z[k], discountCurve_); } npv0[k] = std::max(npv0[k], (type == Option::Call ? 1.0 : -1.0) * (floatingLegNpv - fixedLegNpv) / model_->numeraire(expiry0Time, z[k], discountCurve_)); } } npv1.swap(npv0); expiry1 = expiry0; expiry1Time = expiry0Time; } while (--idx >= minIdxAlive - 1); results_.value = npv1[0] * model_->numeraire(0.0, 0.0, discountCurve_); }
NonstandardSwap::NonstandardSwap(const VanillaSwap &fromVanilla) : Swap(2), type_((VanillaSwap::Type)fromVanilla.type()), fixedNominal_(std::vector<Real>(fromVanilla.fixedLeg().size(), fromVanilla.nominal())), floatingNominal_(std::vector<Real>(fromVanilla.floatingLeg().size(), fromVanilla.nominal())), fixedSchedule_(fromVanilla.fixedSchedule()), fixedRate_(std::vector<Real>(fromVanilla.fixedLeg().size(), fromVanilla.fixedRate())), fixedDayCount_(fromVanilla.fixedDayCount()), floatingSchedule_(fromVanilla.floatingSchedule()), iborIndex_(fromVanilla.iborIndex()), spread_(std::vector<Real>(fromVanilla.floatingLeg().size(), fromVanilla.spread())), gearing_(std::vector<Real>(fromVanilla.floatingLeg().size(), 1.0)), singleSpreadAndGearing_(true), floatingDayCount_(fromVanilla.floatingDayCount()), paymentConvention_(fromVanilla.paymentConvention()), intermediateCapitalExchange_(false), finalCapitalExchange_(false) { init(); }