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;
}
Пример #2
0
    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;
    }
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
//! 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;
}
Пример #7
0
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;
}
Пример #8
0
    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;

}
Пример #10
0
    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_);
    }
Пример #11
0
    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();
    }