Example #1
0
    inline boost::shared_ptr<LongstaffSchwartzMultiPathPricer>
    MCAmericanPathEngine<RNG>::lsmPathPricer() const {

        boost::shared_ptr<StochasticProcessArray> processArray =
            boost::dynamic_pointer_cast<StochasticProcessArray>(this->process_);
        QL_REQUIRE(processArray && processArray->size()>0,
                   "Stochastic process array required");

        boost::shared_ptr<GeneralizedBlackScholesProcess> process =
            boost::dynamic_pointer_cast<GeneralizedBlackScholesProcess>(
               processArray->process(0));
        QL_REQUIRE(process, "generalized Black-Scholes process required");

        const TimeGrid theTimeGrid = this->timeGrid();

        const std::vector<Time> & times = theTimeGrid.mandatoryTimes();
        const Size numberOfTimes = times.size();

        const std::vector<Date> & fixings = this->arguments_.fixingDates;

        QL_REQUIRE(fixings.size() == numberOfTimes, "Invalid dates/times");

        std::vector<Size> timePositions(numberOfTimes);
        Array discountFactors(numberOfTimes);
        std::vector<Handle<YieldTermStructure> > forwardTermStructures(numberOfTimes);

        const Handle<YieldTermStructure> & riskFreeRate = process->riskFreeRate();

        for (Size i = 0; i < numberOfTimes; ++i) {
            timePositions[i] = theTimeGrid.index(times[i]);
            discountFactors[i] = riskFreeRate->discount(times[i]);
            forwardTermStructures[i] = Handle<YieldTermStructure>(
                boost::make_shared<ImpliedTermStructure>(riskFreeRate,
                                                         fixings[i]));
        }

        const Size polynomialOrder = 2;
        const LsmBasisSystem::PolynomType polynomType = LsmBasisSystem::Monomial;

        return boost::shared_ptr<LongstaffSchwartzMultiPathPricer> (
            new LongstaffSchwartzMultiPathPricer(this->arguments_.payoff,
                                                 timePositions,
                                                 forwardTermStructures,
                                                 discountFactors,
                                                 polynomialOrder,
                                                 polynomType));
    }
    inline
    boost::shared_ptr<typename MCPathBasketEngine<RNG,S>::path_pricer_type>
    MCPathBasketEngine<RNG,S>::pathPricer() const {

        boost::shared_ptr<PathPayoff> payoff = arguments_.payoff;
        QL_REQUIRE(payoff, "non-basket payoff given");

        boost::shared_ptr<GeneralizedBlackScholesProcess> process =
            boost::dynamic_pointer_cast<GeneralizedBlackScholesProcess>(
                                                       process_->process(0));
        QL_REQUIRE(process, "Black-Scholes process required");

        const TimeGrid theTimeGrid = timeGrid();

        const std::vector<Time> & times = theTimeGrid.mandatoryTimes();
        const Size numberOfTimes = times.size();

        const std::vector<Date> & fixings = this->arguments_.fixingDates;

        QL_REQUIRE(fixings.size() == numberOfTimes, "Invalid dates/times");

        std::vector<Size> timePositions(numberOfTimes);
        Array discountFactors(numberOfTimes);
        std::vector<Handle<YieldTermStructure> > forwardTermStructures(numberOfTimes);

        const Handle<YieldTermStructure> & riskFreeRate = process->riskFreeRate();

        for (Size i = 0; i < numberOfTimes; ++i) {
            timePositions[i] = theTimeGrid.index(times[i]);
            discountFactors[i] = riskFreeRate->discount(times[i]);
            forwardTermStructures[i] = Handle<YieldTermStructure>(
                        new ImpliedTermStructure(riskFreeRate, fixings[i]));
        }

        return boost::shared_ptr<
            typename MCPathBasketEngine<RNG,S>::path_pricer_type>(
                        new EuropeanPathMultiPathPricer(payoff, timePositions,
                                                        forwardTermStructures,
                                                        discountFactors));
    }
		//! \brief Calculate the NPV of the remaining cash flow at default time \f$ \tau \f$.
		//!
		//! The calculation method used here is based on CIR model.
		virtual Real defaultNPV(const MultiPath& path, Time defaultTime) const {
			//find short rate at default time
			TimeGrid timeGrid = path[0].timeGrid();

			auto defaultPos = timeGrid.index(defaultTime);
			Real shortRate = path[0][defaultPos];

			//calculate discount factor from reference time to the default time
			Time previousTime = timeGrid[0];
			Real discountFactor = 1.0;
			for (auto i = 0; i <= defaultPos; ++i){
				discountFactor *= std::exp(-path[0].value(i) * (timeGrid[i] - previousTime));
				previousTime = timeGrid[i];
			}

			boost::shared_ptr<const MCVanillaSwapUCVAEngine> engine = engine_.lock();
			VanillaSwap::arguments* arguments = dynamic_cast<VanillaSwap::arguments*>(engine->getArguments());
			Handle<YieldTermStructure> discountCurve = engine->discountCurve();

			Date referenceDate = discountCurve->referenceDate();
			std::vector<Date> fixedDates = arguments->fixedPayDates;
			std::vector<Date> floatingDates = arguments->floatingPayDates;
			// transfer payment Dates to Times
			std::vector<Real> fixedTimes;
			std::vector<Real> floatingTimes;
			for (int i = 0; i != fixedDates.size(); ++i){
				fixedTimes.push_back(engine->instrument()->fixedDayCount().yearFraction(referenceDate, fixedDates[i]));
			}
			for (int i = 0; i != floatingDates.size(); ++i){
				floatingTimes.push_back(engine->instrument()->floatingDayCount().yearFraction(referenceDate, floatingDates[i]));
			}
			// calculate the corresponding discount factors of each leg to default time
			std::vector<Real> fixedDiscountFactor;
			std::vector<Real> floatingDiscountFactor;
			int fixedIndex = 0;
			int floatingIndex = 0;
			for (int i = 0; i != fixedTimes.size(); ++i){
				if (fixedTimes[i] >= defaultTime){
					fixedDiscountFactor.push_back(engine->Model()->discountBond(0.0, fixedTimes[i] - defaultTime, shortRate));
				}
				else{
					++fixedIndex;
				}
			}
			for (int i = 0; i != floatingTimes.size(); ++i){
				if (floatingTimes[i] >= defaultTime){
					floatingDiscountFactor.push_back(engine->Model()->discountBond(0.0, floatingTimes[i] - defaultTime, shortRate));
				}
				else{
					++floatingIndex;
				}
			}

			//calculate the NPV(tau)
			Real NPVtau = 0.0;
			NPVtau += arguments->nominal * (1. - floatingDiscountFactor.back());
			for (int m = 0; m != floatingDiscountFactor.size(); ++m){
				NPVtau += arguments->nominal * arguments->floatingSpreads[m + floatingIndex] * floatingDiscountFactor[m];
			}
			for (int m = 0; m != fixedDiscountFactor.size(); ++m){
				NPVtau -= arguments->fixedCoupons[m + fixedIndex] * fixedDiscountFactor[m];
			}

			if (arguments->type == QuantLib::VanillaSwap::Payer){
				NPVtau = NPVtau;
			}
			else{
				NPVtau = -NPVtau;
			}
			return NPVtau * discountFactor;
		}
boost::shared_ptr<IRDLSCallablePricer>
MCIRDLSLSEngine::lsmPathPricer() const {
	
    boost::shared_ptr<StochasticProcessArray> processArray =
        boost::dynamic_pointer_cast<StochasticProcessArray>(this->process_);
    QL_REQUIRE(processArray && processArray->size()>0,
               "Stochastic process array required");


	boost::shared_ptr<PayoffLeg> payoffLeg = arguments_.payoffLeg;
    QL_REQUIRE(payoffLeg, "IRDLS payoffLeg given");

	//const Handle<YieldTermStructure> &df=arguments_.df;
	//Frequency freq = arguments_.freq;

    const TimeGrid theTimeGrid = this->timeGrid();

    const std::vector<Time> & times = theTimeGrid.mandatoryTimes();
    const Size numberOfTimes = times.size();

    const std::vector<Date> & fixings = this->arguments_.fixingDates;
	std::vector<Date> remainfixings;

	Date today = Settings::instance().evaluationDate();
	const Size numberOfFixings = fixings.size();
	for(Size i=0;i<numberOfFixings;++i){
		if(fixings[i]>today){
			remainfixings.push_back(fixings[i]);
		}
	}
    const Size numberOfRemainFixings = remainfixings.size();

	additionalStats_.resize(numberOfTimes);

    QL_REQUIRE(numberOfRemainFixings == numberOfTimes, "Invalid dates/times");

    std::vector<Size> timePositions(numberOfTimes);
    Array discountFactors(numberOfTimes);
    //std::vector<Handle<YieldTermStructure> > forwardTermStructures(numberOfTimes);

    //const Handle<YieldTermStructure> & riskFreeRate = process->riskFreeRate();

	for (Size i = 0; i < numberOfTimes; ++i){
        timePositions[i] = theTimeGrid.index(times[i]);
        discountFactors[i] = discountTS_->discount(times[i]);
	}
      //  forwardTermStructures[i] = Handle<YieldTermStructure>(
        //            new ImpliedTermStructure(riskFreeRate, fixings[i]));
    

    const Size polynomialOrder = 2;
    const LsmBasisSystem::PolynomType polynomType = LsmBasisSystem::Monomial;

    return boost::shared_ptr<IRDLSCallablePricer> (
							new IRDLSCallablePricer(payoffLeg,
													 timePositions,
													 process_,
													 discountFactors,
													 additionalStats_,
													 polynomialOrder,
													 polynomType));
}