예제 #1
0
	crosscurrencyswap::crosscurrencyswap(
		Type type,
		Currency fixedCurrency,
		Real fixedLegnominal,
		const Schedule& fixedSchedule,
		Rate fixedRate,
		const DayCounter& fixedDayCount,
		const boost::shared_ptr<IborIndex>& fixedIborIndex,
		Currency floatCurrency,
		Real floatLegnominal,
		const Schedule& floatSchedule,
		const boost::shared_ptr<IborIndex>& floatIborIndex,
		Spread spread,
		const DayCounter& floatingDayCount,
		boost::optional<BusinessDayConvention> paymentConvention)
		: Swap(2), type_(type), fixedCurrency_(fixedCurrency),Fixedlegnominal_(fixedLegnominal),
		fixedSchedule_(fixedSchedule), fixedRate_(fixedRate),
		fixedDayCount_(fixedDayCount),
		fixedIborIndex_(fixedIborIndex),
		floatCurrency_(floatCurrency),
		Floatlegnominal_(floatLegnominal),
		floatingSchedule_(floatSchedule), floatIborIndex_(floatIborIndex), spread_(spread),
		floatingDayCount_(floatingDayCount) {

			if (paymentConvention)
				paymentConvention_ = *paymentConvention;
			else
				paymentConvention_ = floatingSchedule_.businessDayConvention();

			legs_[0] = FixedRateLeg(fixedSchedule_)
				.withNotionals(Fixedlegnominal_)
				.withCouponRates(fixedRate_, fixedDayCount_)
				.withPaymentAdjustment(paymentConvention_);

			legs_[1] = IborLeg(floatingSchedule_, floatIborIndex_)
				.withNotionals(Floatlegnominal_)
				.withPaymentDayCounter(floatingDayCount_)
				.withPaymentAdjustment(paymentConvention_)
				.withSpreads(spread_);
			for (Leg::const_iterator i = legs_[1].begin(); i < legs_[1].end(); ++i)
				registerWith(*i);

			switch (type_) {
		  case Payer:
			  payer_[0] = -1.0;
			  payer_[1] = +1.0;
			  break;
		  case Receiver:
			  payer_[0] = +1.0;
			  payer_[1] = -1.0;
			  break;
		  default:
			  QL_FAIL("Unknown Cross Currency Swap type");
			}
	}
예제 #2
0
	std::vector<Real> cap_floor(Date evaluationDate,
		CapFloor::Type type,
		Real strike,
		Real nominal,
		Schedule schedule,
		Natural fixingDays,
		BusinessDayConvention convention,
		boost::shared_ptr<IborIndex> index,
		boost::shared_ptr<YieldTermStructure> termStructure,
		Volatility volatility) {

			Date todaysDate = evaluationDate;
			Settings::instance().evaluationDate() = todaysDate;
			std::vector<Real> nominals = std::vector<Real>(1, nominal);		

			/*Make Leg*/
			Leg leg = IborLeg(schedule, index)
				.withNotionals(nominals)
				.withPaymentDayCounter(index->dayCounter())
				.withPaymentAdjustment(convention)
				.withFixingDays(fixingDays);

			/*Make Engine*/
			Handle<Quote> vol(boost::shared_ptr<Quote>(new SimpleQuote(volatility)));
			boost::shared_ptr<PricingEngine> engine = 
				boost::shared_ptr<PricingEngine>(new BlackCapFloorEngine(Handle<YieldTermStructure>(termStructure), vol));

			/*Pricing*/
			boost::shared_ptr<CapFloor> testProduct;
			switch (type) {
			case CapFloor::Cap:
				testProduct = boost::shared_ptr<CapFloor>(new Cap(leg, std::vector<Rate>(1, strike)));
				break;
			case CapFloor::Floor:
				testProduct = boost::shared_ptr<CapFloor>(new Floor(leg, std::vector<Rate>(1, strike)));
				break;
			default:
				QL_FAIL("unknown cap/floor type");
			}

			testProduct->setPricingEngine(engine);

			std::vector<Real> rst;
			rst.push_back(testProduct->NPV());		
			return rst;

	}
예제 #3
0
    void IBOROISBasisSwap::initialize() {
		
        legs_[0] = IborLeg(floatingSchedule_, iborIndex_)
            .withNotionals(nominals_)
			.withPaymentDayCounter(floatingDayCount_)
            .withPaymentAdjustment(paymentConvention_);

        legs_[1] = OvernightLeg(overnightSchedule_, overnightIndex_)
            .withNotionals(nominals_)
			.withPaymentDayCounter(overnightDayCount_)
			.withPaymentAdjustment(paymentConvention_)
            .withSpreads(spread_);
		if(arithmeticAveragedCoupon_) {
			boost::shared_ptr<FloatingRateCouponPricer> arithmeticPricer(
								new ArithmeticAveragedOvernightIndexedCouponPricer());
			for(Size i = 0; i < legs_[1].size(); i++) {
				boost::shared_ptr<OvernightIndexedCoupon> c =
					boost::dynamic_pointer_cast<OvernightIndexedCoupon> (legs_[1][i]);
				c->setPricer(arithmeticPricer);
			}
		}

        for (Size j=0; j<2; ++j) {
            for (Leg::iterator i = legs_[j].begin(); i!= legs_[j].end(); ++i)
                registerWith(*i);
        }

        switch (type_) {
          case Payer:
            payer_[0] = -1.0;
            payer_[1] = +1.0;
            break;
          case Receiver:
            payer_[0] = +1.0;
            payer_[1] = -1.0;
            break;
          default:
            QL_FAIL("Unknown overnight-basis-swap type");
        }
    }
예제 #4
0
    FloatingCatBond::FloatingCatBond(
                           Natural settlementDays,
                           Real faceAmount,
                           const Schedule& schedule,
                           const boost::shared_ptr<IborIndex>& iborIndex,
                           const DayCounter& paymentDayCounter,
                           boost::shared_ptr<NotionalRisk> notionalRisk,
                           BusinessDayConvention paymentConvention,
                           Natural fixingDays,
                           const std::vector<Real>& gearings,
                           const std::vector<Spread>& spreads,
                           const std::vector<Rate>& caps,
                           const std::vector<Rate>& floors,
                           bool inArrears,
                           Real redemption,
                           const Date& issueDate)
        : CatBond(settlementDays, schedule.calendar(), issueDate, notionalRisk) {

        maturityDate_ = schedule.endDate();

        cashflows_ = IborLeg(schedule, iborIndex)
            .withNotionals(faceAmount)
            .withPaymentDayCounter(paymentDayCounter)
            .withPaymentAdjustment(paymentConvention)
            .withFixingDays(fixingDays)
            .withGearings(gearings)
            .withSpreads(spreads)
            .withCaps(caps)
            .withFloors(floors)
            .inArrears(inArrears);

        addRedemptionsToCashflows(std::vector<Real>(1, redemption));

        QL_ENSURE(!cashflows().empty(), "bond with no cashflows!");
        QL_ENSURE(redemptions_.size() == 1, "multiple redemptions created");

        registerWith(iborIndex);
    }
예제 #5
0
    MakeCms::operator boost::shared_ptr<Swap>() const {

        Date startDate;
        if (effectiveDate_ != Date())
            startDate = effectiveDate_;
        else {
            Natural fixingDays = iborIndex_->fixingDays();
            Date refDate = Settings::instance().evaluationDate();
            // if the evaluation date is not a business day
            // then move to the next business day
            refDate = floatCalendar_.adjust(refDate);
            Date spotDate = floatCalendar_.advance(refDate,
                                                   fixingDays*Days);
            startDate = spotDate+forwardStart_;
        }

        Date terminationDate = startDate+swapTenor_;

        Schedule cmsSchedule(startDate, terminationDate,
                             cmsTenor_, cmsCalendar_,
                             cmsConvention_,
                             cmsTerminationDateConvention_,
                             cmsRule_, cmsEndOfMonth_,
                             cmsFirstDate_, cmsNextToLastDate_);

        Schedule floatSchedule(startDate, terminationDate,
                               floatTenor_, floatCalendar_,
                               floatConvention_,
                               floatTerminationDateConvention_,
                               floatRule_ , floatEndOfMonth_,
                               floatFirstDate_, floatNextToLastDate_);

        Leg cmsLeg = CmsLeg(cmsSchedule, swapIndex_)
            .withNotionals(nominal_)
            .withPaymentDayCounter(cmsDayCount_)
            .withPaymentAdjustment(cmsConvention_)
            .withFixingDays(swapIndex_->fixingDays())
            .withGearings(cmsGearing_)
            .withSpreads(cmsSpread_)
            .withCaps(cmsCap_)
            .withFloors(cmsFloor_);
        if (couponPricer_)
            setCouponPricer(cmsLeg, couponPricer_);

        Rate usedSpread = iborSpread_;
        if (useAtmSpread_) {
            QL_REQUIRE(!iborIndex_->forwardingTermStructure().empty(),
                       "null term structure set to this instance of " <<
                       iborIndex_->name());
            QL_REQUIRE(!swapIndex_->forwardingTermStructure().empty(),
                       "null term structure set to this instance of " <<
                       swapIndex_->name());
            QL_REQUIRE(couponPricer_,
                       "no CmsCouponPricer set (yet)");
            Leg floatLeg = IborLeg(floatSchedule, iborIndex_)
                .withNotionals(nominal_)
                .withPaymentDayCounter(floatDayCount_)
                .withPaymentAdjustment(floatConvention_)
                .withFixingDays(iborIndex_->fixingDays());

            Swap temp(cmsLeg, floatLeg);
            temp.setPricingEngine(engine_);

            Real npv = temp.legNPV(0)+temp.legNPV(1);

            usedSpread = -npv/temp.legBPS(1)*1e-4;
        } else {
            QL_REQUIRE(usedSpread != Null<Spread>(),
                       "null spread set");
        }

        Leg floatLeg = IborLeg(floatSchedule, iborIndex_)
            .withNotionals(nominal_)
            .withPaymentDayCounter(floatDayCount_)
            .withPaymentAdjustment(floatConvention_)
            .withFixingDays(iborIndex_->fixingDays())
            .withSpreads(usedSpread);

        boost::shared_ptr<Swap> swap;
        if (payCms_)
            swap = boost::shared_ptr<Swap>(new Swap(cmsLeg, floatLeg));
        else
            swap = boost::shared_ptr<Swap>(new Swap(floatLeg, cmsLeg));
        swap->setPricingEngine(engine_);
        return swap;
    }
예제 #6
0
    AssetSwap::AssetSwap(bool parSwap,
                         const boost::shared_ptr<Bond>& bond,
                         Real bondCleanPrice,
                         Real nonParRepayment,
                         Real gearing,
                         const boost::shared_ptr<IborIndex>& iborIndex,
                         Spread spread,
                         const DayCounter& floatingDayCounter,
                         Date dealMaturity,
                         bool payBondCoupon)
    : Swap(2), bond_(bond), bondCleanPrice_(bondCleanPrice),
      nonParRepayment_(nonParRepayment), spread_(spread), parSwap_(parSwap)
    {
        Schedule tempSch(bond_->settlementDate(),
                         bond_->maturityDate(),
                         iborIndex->tenor(),
                         iborIndex->fixingCalendar(),
                         iborIndex->businessDayConvention(),
                         iborIndex->businessDayConvention(),
                         DateGeneration::Backward,
                         false); // endOfMonth
        if (dealMaturity==Date())
            dealMaturity = bond_->maturityDate();
        QL_REQUIRE(dealMaturity <= tempSch.dates().back(),
                   "deal maturity " << dealMaturity <<
                   " cannot be later than (adjusted) bond maturity " <<
                   tempSch.dates().back());

        // the following might become an input parameter
        BusinessDayConvention paymentAdjustment = Following;

        Date finalDate = tempSch.calendar().adjust(
            dealMaturity, paymentAdjustment);
        Schedule schedule = tempSch.until(finalDate);

        // bondCleanPrice must be the (forward) clean price
        // at the floating schedule start date
        upfrontDate_ = schedule.startDate();
        Real dirtyPrice = bondCleanPrice_ +
                          bond_->accruedAmount(upfrontDate_);

        Real notional = bond_->notional(upfrontDate_);
        /* In the market asset swap, the bond is purchased in return for
           payment of the full price. The notional of the floating leg is
           then scaled by the full price. */
        if (!parSwap_)
            notional *= dirtyPrice/100.0;

        if (floatingDayCounter==DayCounter())
            legs_[1] = IborLeg(schedule, iborIndex)
                .withNotionals(notional)
                .withPaymentAdjustment(paymentAdjustment)
                .withGearings(gearing)
                .withSpreads(spread);
        else
            legs_[1] = IborLeg(schedule, iborIndex)
                .withNotionals(notional)
                .withPaymentDayCounter(floatingDayCounter)
                .withPaymentAdjustment(paymentAdjustment)
                .withGearings(gearing)
                .withSpreads(spread);

        for (Leg::const_iterator i=legs_[1].begin(); i<legs_[1].end(); ++i)
            registerWith(*i);

        const Leg& bondLeg = bond_->cashflows();
        Leg::const_iterator i = bondLeg.begin();
        // skip bond redemption
        for (; i<bondLeg.end()-1 && (*i)->date()<=dealMaturity; ++i) {
            // whatever might be the choice for the discounting engine
            // bond flows on upfrontDate_ must be discarded
            bool upfrontDateBondFlows = false;
            if (!(*i)->hasOccurred(upfrontDate_, upfrontDateBondFlows))
                legs_[0].push_back(*i);
        }
        // if the first skipped cashflow is not the redemption
        // and it is a coupon then add the accrued coupon
        if (i<bondLeg.end()-1) {
            shared_ptr<Coupon> c = boost::dynamic_pointer_cast<Coupon>(*i);
            if (c) {
                shared_ptr<CashFlow> accruedCoupon(new
                    SimpleCashFlow(c->accruedAmount(dealMaturity), finalDate));
                legs_[0].push_back(accruedCoupon);
            }
        }
        // add the nonParRepayment_
        shared_ptr<CashFlow> nonParRepaymentFlow(new
            SimpleCashFlow(nonParRepayment_, finalDate));
        legs_[0].push_back(nonParRepaymentFlow);

        QL_REQUIRE(!legs_[0].empty(),
                   "empty bond leg to start with");

        // special flows
        if (parSwap_) {
            // upfront on the floating leg
            Real upfront = (dirtyPrice-100.0)/100.0*notional;
            shared_ptr<CashFlow> upfrontCashFlow(new
                SimpleCashFlow(upfront, upfrontDate_));
            legs_[1].insert(legs_[1].begin(), upfrontCashFlow);
            // backpayment on the floating leg
            // (accounts for non-par redemption, if any)
            Real backPayment = notional;
            shared_ptr<CashFlow> backPaymentCashFlow(new
                SimpleCashFlow(backPayment, finalDate));
            legs_[1].push_back(backPaymentCashFlow);
        } else {
            // final notional exchange
            shared_ptr<CashFlow> finalCashFlow (new
                SimpleCashFlow(notional, finalDate));
            legs_[1].push_back(finalCashFlow);
        }

        QL_REQUIRE(!legs_[0].empty(), "empty bond leg");
        for (Leg::const_iterator i=legs_[0].begin(); i<legs_[0].end(); ++i)
            registerWith(*i);

        if (payBondCoupon) {
            payer_[0]=-1.0;
            payer_[1]=+1.0;
        } else {
            payer_[0]=+1.0;
            payer_[1]=-1.0;
        }
    }
예제 #7
0
    AssetSwap::AssetSwap(bool payBondCoupon,
                         const shared_ptr<Bond>& bond,
                         Real bondCleanPrice,
                         const shared_ptr<IborIndex>& iborIndex,
                         Spread spread,
                         const Schedule& floatSchedule,
                         const DayCounter& floatingDayCounter,
                         bool parSwap)
    : Swap(2), bond_(bond), bondCleanPrice_(bondCleanPrice),
      nonParRepayment_(100), spread_(spread), parSwap_(parSwap)
    {
        Schedule schedule = floatSchedule;
        if (floatSchedule.empty())
            schedule = Schedule(bond_->settlementDate(),
                                bond_->maturityDate(),
                                iborIndex->tenor(),
                                iborIndex->fixingCalendar(),
                                iborIndex->businessDayConvention(),
                                iborIndex->businessDayConvention(),
                                DateGeneration::Backward,
                                false); // endOfMonth

        // the following might become an input parameter
        BusinessDayConvention paymentAdjustment = Following;

        Date finalDate = schedule.calendar().adjust(
            schedule.endDate(), paymentAdjustment);
        Date adjBondMaturityDate = schedule.calendar().adjust(
            bond_->maturityDate(), paymentAdjustment);

        QL_REQUIRE(finalDate==adjBondMaturityDate,
                   "adjusted schedule end date (" <<
                   finalDate <<
                   ") must be equal to adjusted bond maturity date (" <<
                   adjBondMaturityDate << ")");

        // bondCleanPrice must be the (forward) clean price
        // at the floating schedule start date
        upfrontDate_ = schedule.startDate();
        Real dirtyPrice = bondCleanPrice_ +
                          bond_->accruedAmount(upfrontDate_);

        Real notional = bond_->notional(upfrontDate_);
        /* In the market asset swap, the bond is purchased in return for
           payment of the full price. The notional of the floating leg is
           then scaled by the full price. */
        if (!parSwap_)
            notional *= dirtyPrice/100.0;

        if (floatingDayCounter==DayCounter())
            legs_[1] = IborLeg(schedule, iborIndex)
                .withNotionals(notional)
                .withPaymentAdjustment(paymentAdjustment)
                .withSpreads(spread);
        else
            legs_[1] = IborLeg(schedule, iborIndex)
                .withNotionals(notional)
                .withPaymentDayCounter(floatingDayCounter)
                .withPaymentAdjustment(paymentAdjustment)
                .withSpreads(spread);

        for (Leg::const_iterator i=legs_[1].begin(); i<legs_[1].end(); ++i)
            registerWith(*i);

        const Leg& bondLeg = bond_->cashflows();
        for (Leg::const_iterator i=bondLeg.begin(); i<bondLeg.end(); ++i) {
            // whatever might be the choice for the discounting engine
            // bond flows on upfrontDate_ must be discarded
            bool upfrontDateBondFlows = false;
            if (!(*i)->hasOccurred(upfrontDate_, upfrontDateBondFlows))
                legs_[0].push_back(*i);
        }

        QL_REQUIRE(!legs_[0].empty(),
                   "empty bond leg to start with");

        // special flows
        if (parSwap_) {
            // upfront on the floating leg
            Real upfront = (dirtyPrice-100.0)/100.0*notional;
            shared_ptr<CashFlow> upfrontCashFlow(new
                SimpleCashFlow(upfront, upfrontDate_));
            legs_[1].insert(legs_[1].begin(), upfrontCashFlow);
            // backpayment on the floating leg
            // (accounts for non-par redemption, if any)
            Real backPayment = notional;
            shared_ptr<CashFlow> backPaymentCashFlow(new
                SimpleCashFlow(backPayment, finalDate));
            legs_[1].push_back(backPaymentCashFlow);
        } else {
            // final notional exchange
            shared_ptr<CashFlow> finalCashFlow(new
                SimpleCashFlow(notional, finalDate));
            legs_[1].push_back(finalCashFlow);
        }

        QL_REQUIRE(!legs_[0].empty(), "empty bond leg");
        for (Leg::const_iterator i=legs_[0].begin(); i<legs_[0].end(); ++i)
            registerWith(*i);

        if (payBondCoupon) {
            payer_[0]=-1.0;
            payer_[1]=+1.0;
        } else {
            payer_[0]=+1.0;
            payer_[1]=-1.0;
        }
    }
예제 #8
0
    FloatingRateBond::FloatingRateBond(
                           Natural settlementDays,
                           Real faceAmount,
                           const Date& startDate,
                           const Date& maturityDate,
                           Frequency couponFrequency,
                           const Calendar& calendar,
                           const ext::shared_ptr<IborIndex>& iborIndex,
                           const DayCounter& accrualDayCounter,
                           BusinessDayConvention accrualConvention,
                           BusinessDayConvention paymentConvention,
                           Natural fixingDays,
                           const std::vector<Real>& gearings,
                           const std::vector<Spread>& spreads,
                           const std::vector<Rate>& caps,
                           const std::vector<Rate>& floors,
                           bool inArrears,
                           Real redemption,
                           const Date& issueDate,
                           const Date& stubDate,
                           DateGeneration::Rule rule,
                           bool endOfMonth)
    : Bond(settlementDays, calendar, issueDate) {

        maturityDate_ = maturityDate;

        Date firstDate, nextToLastDate;
        switch (rule) {
          case DateGeneration::Backward:
            firstDate = Date();
            nextToLastDate = stubDate;
            break;
          case DateGeneration::Forward:
            firstDate = stubDate;
            nextToLastDate = Date();
            break;
          case DateGeneration::Zero:
          case DateGeneration::ThirdWednesday:
          case DateGeneration::Twentieth:
          case DateGeneration::TwentiethIMM:
            QL_FAIL("stub date (" << stubDate << ") not allowed with " <<
                    rule << " DateGeneration::Rule");
          default:
            QL_FAIL("unknown DateGeneration::Rule (" << Integer(rule) << ")");
        }

        Schedule schedule(startDate, maturityDate_, Period(couponFrequency),
                          calendar_, accrualConvention, accrualConvention,
                          rule, endOfMonth,
                          firstDate, nextToLastDate);

        cashflows_ = IborLeg(schedule, iborIndex)
            .withNotionals(faceAmount)
            .withPaymentDayCounter(accrualDayCounter)
            .withPaymentAdjustment(paymentConvention)
            .withFixingDays(fixingDays)
            .withGearings(gearings)
            .withSpreads(spreads)
            .withCaps(caps)
            .withFloors(floors)
            .inArrears(inArrears);

        addRedemptionsToCashflows(std::vector<Real>(1, redemption));

        QL_ENSURE(!cashflows().empty(), "bond with no cashflows!");
        QL_ENSURE(redemptions_.size() == 1, "multiple redemptions created");

        registerWith(iborIndex);
    }
예제 #9
0
    void NonstandardSwap::init() {

        QL_REQUIRE(fixedNominal_.size() == fixedRate_.size(),
                   "Fixed nominal size ("
                       << fixedNominal_.size()
                       << ") does not match fixed rate size ("
                       << fixedRate_.size() << ")");

        QL_REQUIRE(fixedNominal_.size() == fixedSchedule_.size() - 1,
                   "Fixed nominal size (" << fixedNominal_.size()
                                          << ") does not match schedule size ("
                                          << fixedSchedule_.size() << ") - 1");

        QL_REQUIRE(floatingNominal_.size() == floatingSchedule_.size() - 1,
                   "Floating nominal size ("
                       << floatingNominal_.size()
                       << ") does not match schedule size ("
                       << floatingSchedule_.size() << ") - 1");

        QL_REQUIRE(floatingNominal_.size() == spread_.size(),
                   "Floating nominal size (" << floatingNominal_.size()
                                             << ") does not match spread size ("
                                             << spread_.size() << ")");

        QL_REQUIRE(floatingNominal_.size() == gearing_.size(),
                   "Floating nominal size ("
                       << floatingNominal_.size()
                       << ") does not match gearing size (" << gearing_.size()
                       << ")");

        // if the gearing is zero then the ibor leg will be set up with fixed
        // coupons which makes trouble here in this context. We therefore use
        // a dirty trick and enforce the gearing to be non zero.
        for (Size i = 0; i < gearing_.size(); ++i) {
            if (close(gearing_[i], 0.0))
                gearing_[i] = QL_EPSILON;
        }

        legs_[0] = FixedRateLeg(fixedSchedule_)
                       .withNotionals(fixedNominal_)
                       .withCouponRates(fixedRate_, fixedDayCount_)
                       .withPaymentAdjustment(paymentConvention_);

        legs_[1] = IborLeg(floatingSchedule_, iborIndex_)
                       .withNotionals(floatingNominal_)
                       .withPaymentDayCounter(floatingDayCount_)
                       .withPaymentAdjustment(paymentConvention_)
                       .withSpreads(spread_)
                       .withGearings(gearing_);

        if (intermediateCapitalExchange_) {
            for (Size i = 0; i < legs_[0].size() - 1; i++) {
                Real cap = fixedNominal_[i + 1] - fixedNominal_[i];
                if (!close(cap, 0.0)) {
                    std::vector<boost::shared_ptr<CashFlow> >::iterator it1 =
                        legs_[0].begin();
                    std::advance(it1, i + 1);
                    legs_[0].insert(
                        it1, boost::shared_ptr<CashFlow>(
                                 new Redemption(cap, legs_[0][i]->date())));
                    std::vector<Real>::iterator it2 = fixedNominal_.begin();
                    std::advance(it2, i + 1);
                    fixedNominal_.insert(it2, fixedNominal_[i]);
                    i++;
                }
            }
            for (Size i = 0; i < legs_[1].size() - 1; i++) {
                Real cap = floatingNominal_[i + 1] - floatingNominal_[i];
                if (!close(cap, 0.0)) {
                    std::vector<boost::shared_ptr<CashFlow> >::iterator it1 =
                        legs_[1].begin();
                    std::advance(it1, i + 1);
                    legs_[1].insert(
                        it1, boost::shared_ptr<CashFlow>(
                                 new Redemption(cap, legs_[1][i]->date())));
                    std::vector<Real>::iterator it2 = floatingNominal_.begin();
                    std::advance(it2, i + 1);
                    floatingNominal_.insert(it2, floatingNominal_[i]);
                    i++;
                }
            }
        }

        if (finalCapitalExchange_) {
            legs_[0].push_back(boost::shared_ptr<CashFlow>(
                new Redemption(fixedNominal_.back(), legs_[0].back()->date())));
            fixedNominal_.push_back(fixedNominal_.back());
            fixedRate_.push_back(0.0);
            legs_[1].push_back(boost::shared_ptr<CashFlow>(new Redemption(
                floatingNominal_.back(), legs_[1].back()->date())));
            floatingNominal_.push_back(floatingNominal_.back());
        }

        for (Leg::const_iterator i = legs_[1].begin(); i < legs_[1].end(); ++i)
            registerWith(*i);

        switch (type_) {
        case VanillaSwap::Payer:
            payer_[0] = -1.0;
            payer_[1] = +1.0;
            break;
        case VanillaSwap::Receiver:
            payer_[0] = +1.0;
            payer_[1] = -1.0;
            break;
        default:
            QL_FAIL("Unknown nonstandard-swap type");
        }
    }
예제 #10
0
	std::vector<Real> power_spread_swap(Date evaluationDate,
		Real notional,
		PowerSpreadSwap::Side side,
		Rate alpha,
		Schedule floatingSchedule,
		Schedule fixedSchedule,
		DayCounter dayCounter,
		BusinessDayConvention bdc,
		std::vector<Real> gearing,
		std::vector<Real> spread,
		std::vector<Real> caps,
		std::vector<Real> floors,
		bool isAvg,
		Date firstCallDate,
		Real pastFixing,
		Rate floatingFixingRate,
		Real floatingGearing,
		DayCounter floatingDayCounter,
		boost::shared_ptr<StochasticProcess1D> obs1Process,
		boost::shared_ptr<StochasticProcess1D> obs2Process,
		YieldCurveParams disc,
		Real rho12,
		Real rho1disc,
		Real rho2disc,
		Size numSimulation,
		Size numCalibration) {

			Date todaysDate = evaluationDate;
			Settings::instance().evaluationDate() = todaysDate;

			boost::shared_ptr<IborIndex> index1(new Euribor3M(Handle<YieldTermStructure>( disc.yts )));
			boost::shared_ptr<SpreadIndex> index(new SpreadIndex(index1, index1));

			boost::shared_ptr<Callability> callability(new 
				Callability(Callability::Price(notional, Callability::Price::Clean), Callability::Call, firstCallDate));
			CallabilitySchedule callSchedule;
			callSchedule.push_back(callability);

			boost::shared_ptr<StochasticProcess1D> discProcess(new 
				HullWhiteProcess(Handle<YieldTermStructure>(disc.yts), disc.hwParams.a, disc.hwParams.sigma));
			/***********************************************************************************/

			
			Leg floatingcashflows = IborLeg(floatingSchedule, index1)
				.withNotionals(notional)
				.withPaymentDayCounter(floatingDayCounter)
				.withPaymentAdjustment(bdc)
				.withSpreads(alpha)
				.withGearings(floatingGearing)
				.withPaymentAdjustment(bdc);
			
			
			PowerSpreadSwap testProduct(0, notional, side, floatingSchedule, floatingcashflows,
				alpha, 
				fixedSchedule, index, dayCounter, bdc, Null<Natural>(),
				gearing, spread, caps, floors, isAvg, 100.0, Date(), 
				callSchedule, Exercise::Bermudan);


			/*****Pricing Engine*****/
			std::vector<boost::shared_ptr<StochasticProcess1D> > pros;
			pros.push_back(discProcess);
			pros.push_back(obs1Process);
			pros.push_back(obs2Process);
			Matrix corr(3,3,1.0);
			corr[0][1] = corr[1][0] = rho1disc;
			corr[0][2] = corr[2][0] = rho2disc;
			corr[1][2] = corr[2][1] = rho12;

			boost::shared_ptr<StochasticProcessArray> processes(new StochasticProcessArray(pros, corr));

			boost::shared_ptr<PricingEngine> engine_lsmc(new MC_PowerSpread_Swap_Engine_LSMC<>(processes,
				0.03, //pastFixing
				0.03,
				256, //seed 
				numSimulation, //required samples
				numCalibration, //calibration samples
				true, //antithetic
				false,  //control variate
				false //brownian bridge
				));
			testProduct.setPricingEngine(engine_lsmc);

			std::vector<Real> rst;
			rst.push_back(testProduct.NPV());
			rst.push_back(testProduct.errorEstimate());
			return rst;

	}