Пример #1
0
    CreditDefaultSwap::CreditDefaultSwap(Protection::Side side,
                                         Real notional,
                                         Rate upfront,
                                         Rate runningSpread,
                                         const Schedule& schedule,
                                         BusinessDayConvention convention,
                                         const DayCounter& dayCounter,
                                         bool settlesAccrual,
                                         bool paysAtDefaultTime,
                                         const Date& protectionStart,
                                         const Date& upfrontDate,
                                         const boost::shared_ptr<Claim>& claim)
    : side_(side), notional_(notional), upfront_(upfront),
      runningSpread_(runningSpread), settlesAccrual_(settlesAccrual),
      paysAtDefaultTime_(paysAtDefaultTime), claim_(claim),
      protectionStart_(protectionStart == Null<Date>() ? schedule[0] :
                                                         protectionStart) {
        QL_REQUIRE(protectionStart_ <= schedule[0],
                   "protection can not start after accrual");
        leg_ = FixedRateLeg(schedule)
            .withNotionals(notional)
            .withCouponRates(runningSpread, dayCounter)
            .withPaymentAdjustment(convention);
        Date d = upfrontDate == Null<Date>() ? schedule[0] : upfrontDate;
        upfrontPayment_.reset(new SimpleCashFlow(notional*upfront, d));
        QL_REQUIRE(upfrontPayment_->date() >= protectionStart_,
                   "upfront can not be due before contract start");

        if (!claim_)
            claim_ = boost::shared_ptr<Claim>(new FaceValueClaim);
        registerWith(claim_);
    }
Пример #2
0
    FixedRateBond::FixedRateBond(Natural settlementDays,
                                 Real faceAmount,
                                 const Schedule& schedule,
                                 const std::vector<Rate>& coupons,
                                 const DayCounter& accrualDayCounter,
                                 BusinessDayConvention paymentConvention,
                                 Real redemption,
                                 const Date& issueDate,
                                 const Calendar& paymentCalendar)
     : Bond(settlementDays,
            paymentCalendar==Calendar() ? schedule.calendar() : paymentCalendar,
            issueDate),
      frequency_(schedule.tenor().frequency()),
      dayCounter_(accrualDayCounter) {

        maturityDate_ = schedule.endDate();

        cashflows_ = FixedRateLeg(schedule)
            .withNotionals(faceAmount)
            .withCouponRates(coupons, accrualDayCounter)
            .withPaymentCalendar(calendar_)
            .withPaymentAdjustment(paymentConvention);

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

        QL_ENSURE(!cashflows().empty(), "bond with no cashflows!");
        QL_ENSURE(redemptions_.size() == 1, "multiple redemptions created");
    }
    AmortizingFixedRateBond::AmortizingFixedRateBond(
                                      Natural settlementDays,
                                      const Calendar& calendar,
                                      Real initialFaceAmount,
                                      const Date& startDate,
                                      const Period& bondTenor,
                                      const Frequency& sinkingFrequency,
                                      const Rate coupon,
                                      const DayCounter& accrualDayCounter,
                                      BusinessDayConvention paymentConvention,
                                      const Date& issueDate)
    : Bond(settlementDays, calendar, issueDate),
      frequency_(sinkingFrequency),
      dayCounter_(accrualDayCounter) {

        maturityDate_ = startDate + bondTenor;

        cashflows_ =
            FixedRateLeg(sinkingSchedule(startDate, bondTenor,
                                         sinkingFrequency, calendar))
            .withNotionals(sinkingNotionals(bondTenor,
                                            sinkingFrequency, coupon,
                                            initialFaceAmount))
            .withCouponRates(coupon, accrualDayCounter)
            .withPaymentAdjustment(paymentConvention);

        addRedemptionsToCashflows();
    }
Пример #4
0
    NthToDefault::NthToDefault(
        const boost::shared_ptr<Basket>& basket,
        Size n,
        Protection::Side side,
        const Schedule& premiumSchedule,
        Rate upfrontRate,
        Rate premiumRate,
        const DayCounter& dayCounter,
        Real nominal,
        bool settlePremiumAccrual
        )
    : basket_(basket), n_(n),
      side_(side), nominal_(nominal),
      premiumSchedule_(premiumSchedule), premiumRate_(premiumRate), 
      upfrontRate_(upfrontRate), 
      dayCounter_(dayCounter), settlePremiumAccrual_(settlePremiumAccrual)
    {
		QL_REQUIRE(n_ <= basket_->size(), 
			"NTD order provided is larger than the basket size.");

        // Basket inception must lie before contract protection start.
        QL_REQUIRE(basket->refDate() <= premiumSchedule.startDate(),
            //using the start date of the schedule might be wrong, think of the CDS rule
            "Basket did not exist before contract start.");

        premiumLeg_ = FixedRateLeg(premiumSchedule)
            .withNotionals(nominal)
            .withCouponRates(premiumRate, dayCounter)
            .withPaymentAdjustment(Unadjusted);

        registerWith(basket_);
    }
Пример #5
0
    FixedRateBond::FixedRateBond(Natural settlementDays,
                                 const Calendar& calendar,
                                 Real faceAmount,
                                 const Date& startDate,
                                 const Date& maturityDate,
                                 const Period& tenor,
                                 const std::vector<Rate>& coupons,
                                 const DayCounter& accrualDayCounter,
                                 BusinessDayConvention accrualConvention,
                                 BusinessDayConvention paymentConvention,
                                 Real redemption,
                                 const Date& issueDate,
                                 const Date& stubDate,
                                 DateGeneration::Rule rule,
                                 bool endOfMonth,
                                 const Calendar& paymentCalendar)
     : Bond(settlementDays,
            paymentCalendar==Calendar() ? calendar : paymentCalendar,
            issueDate),
      frequency_(tenor.frequency()), dayCounter_(accrualDayCounter) {

        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_, tenor,
                          calendar, accrualConvention, accrualConvention,
                          rule, endOfMonth,
                          firstDate, nextToLastDate);

        cashflows_ = FixedRateLeg(schedule)
            .withNotionals(faceAmount)
            .withCouponRates(coupons, accrualDayCounter)
            .withPaymentCalendar(calendar_)
            .withPaymentAdjustment(paymentConvention);

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

        QL_ENSURE(!cashflows().empty(), "bond with no cashflows!");
        QL_ENSURE(redemptions_.size() == 1, "multiple redemptions created");
    }
Пример #6
0
    CreditDefaultSwap::CreditDefaultSwap(Protection::Side side,
                                         Real notional,
                                         Rate spread,
                                         const Schedule& schedule,
                                         BusinessDayConvention convention,
                                         const DayCounter& dayCounter,
                                         bool settlesAccrual,
                                         bool paysAtDefaultTime,
                                         const Date& protectionStart,
                                         const boost::shared_ptr<Claim>& claim,
										 const DayCounter& lastPeriodDayCounter,
										 const Natural standardCdsStartDelayDays,
										 const Natural standardCdsUpfrontDelayDays)
    : side_(side), notional_(notional), upfront_(boost::none),
      runningSpread_(spread), settlesAccrual_(settlesAccrual),
      paysAtDefaultTime_(paysAtDefaultTime), claim_(claim),
      protectionStart_(protectionStart == Null<Date>() ? schedule[0] :
                                                         protectionStart) {

        Date d = schedule[0];
        try {
            if (schedule.rule() ==
                DateGeneration::CDS) { // a standard CDS is identified
                                       // by the schedule rule
                Date evalDate = Settings::instance().evaluationDate();
                if (protectionStart == Null<Date>())
                    protectionStart_ =
                        evalDate + standardCdsStartDelayDays; // if
                // protection
                // start is
                // given it
                // is not set
                // here
                d = schedule.calendar().advance(
                    evalDate, standardCdsUpfrontDelayDays * Days,
                    schedule.businessDayConvention(), schedule.endOfMonth());
                QL_REQUIRE(protectionStart_ >= schedule[0],
                           "protection must start on or after "
                           "accrual start for standard CDS");
            }
        } catch (...) {
            QL_REQUIRE(protectionStart_ <= schedule[0],
                       "protection can not start after accrual "
                       "for non standard CDS");
        }

        leg_ = FixedRateLeg(schedule)
                   .withNotionals(notional)
                   .withCouponRates(spread, dayCounter)
                   .withPaymentAdjustment(convention)
                   .withLastPeriodDayCounter(lastPeriodDayCounter);
        upfrontPayment_.reset(new SimpleCashFlow(0.0, d));

        if (!claim_)
            claim_ = boost::shared_ptr<Claim>(new FaceValueClaim);
        registerWith(claim_);
    }
Пример #7
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");
			}
	}
Пример #8
0
	RepoCompoundingSwap::RepoCompoundingSwap(
		Type type,
		Real nominal,
		const Schedule& fixedSchedule,
		Rate fixedRate,
		const DayCounter& fixedDayCount,
		const Schedule& floatSchedule,
		const boost::shared_ptr<RepoChina>& iborIndex,
		Spread rateSpread,
		Spread couponSpread,
		const DayCounter& floatingDayCount,
		boost::optional<BusinessDayConvention> paymentConvention)
		: Swap(2), type_(type), nominal_(nominal),
		fixedSchedule_(fixedSchedule), fixedRate_(fixedRate),
		fixedDayCount_(fixedDayCount),
		floatingSchedule_(floatSchedule), iborIndex_(iborIndex), rateSpread_(rateSpread), couponSpread_(couponSpread),
		floatingDayCount_(floatingDayCount) {

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

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

			legs_[1] = SubPeriodsCouponLeg(floatingSchedule_, iborIndex_)
				.withNotionals(nominal_)
				.withPaymentDayCounter(floatingDayCount_)
				.withPaymentAdjustment(paymentConvention_)
				.withRateSpreads(rateSpread_)
				.withCouponSpreads(couponSpread_);
			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 repo-compounding-swap type");
			}
	}
  OvernightIndexedSwap::OvernightIndexedSwap(
                    Type type,
                    Real nominal,
                    const Schedule& schedule,
                    Rate fixedRate,
                    const DayCounter& fixedDC,
                    const boost::shared_ptr<OvernightIndex>& overnightIndex,
                    Spread spread)
      : Swap(2), type_(type), nominal_(nominal),
        paymentFrequency_(schedule.tenor().frequency()),
        //schedule_(schedule),
        fixedRate_(fixedRate), fixedDC_(fixedDC),
        overnightIndex_(overnightIndex), spread_(spread) {

        if (fixedDC_==DayCounter())
            fixedDC_ = overnightIndex_->dayCounter();
        legs_[0] = FixedRateLeg(schedule)
            .withNotionals(nominal_)
            .withCouponRates(fixedRate_, fixedDC_);

        legs_[1] = OvernightLeg(schedule, overnightIndex_)
            .withNotionals(nominal_)
            .withSpreads(spread_);

        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-swap type");
        }
    }
Пример #10
0
    CallableFixedRateBond::CallableFixedRateBond(
                              Natural settlementDays,
                              Real faceAmount,
                              const Schedule& schedule,
                              const std::vector<Rate>& coupons,
                              const DayCounter& accrualDayCounter,
                              BusinessDayConvention paymentConvention,
                              Real redemption,
                              const Date& issueDate,
                              const CallabilitySchedule& putCallSchedule)
    : CallableBond(settlementDays, schedule, accrualDayCounter,
                   issueDate, putCallSchedule) {

        frequency_ = schedule.tenor().frequency();

        bool isZeroCouponBond = (coupons.size() == 1 && close(coupons[0], 0.0));

        if (!isZeroCouponBond) {
            cashflows_ =
                FixedRateLeg(schedule)
                .withNotionals(faceAmount)
                .withCouponRates(coupons, accrualDayCounter)
                .withPaymentAdjustment(paymentConvention);

            addRedemptionsToCashflows(std::vector<Real>(1, redemption));
        } else {
            Date redemptionDate = calendar_.adjust(maturityDate_,
                                                   paymentConvention);
            setSingleRedemption(faceAmount, redemption, redemptionDate);
        }

        // used for impliedVolatility() calculation
        boost::shared_ptr<SimpleQuote> dummyVolQuote(new SimpleQuote(0.));
        blackVolQuote_.linkTo(dummyVolQuote);
        blackEngine_ = boost::shared_ptr<PricingEngine>(
                   new BlackCallableFixedRateBondEngine(blackVolQuote_,
                                                        blackDiscountCurve_));
    }
    AmortizingFixedRateBond::AmortizingFixedRateBond(
                                      Natural settlementDays,
                                      const std::vector<Real>& notionals,
                                      const Schedule& schedule,
                                      const std::vector<Rate>& coupons,
                                      const DayCounter& accrualDayCounter,
                                      BusinessDayConvention paymentConvention,
                                      const Date& issueDate)
    : Bond(settlementDays, schedule.calendar(), issueDate),
      frequency_(schedule.tenor().frequency()),
      dayCounter_(accrualDayCounter) {

        maturityDate_ = schedule.endDate();

        cashflows_ = FixedRateLeg(schedule)
            .withNotionals(notionals)
            .withCouponRates(coupons, accrualDayCounter)
            .withPaymentAdjustment(paymentConvention);

        addRedemptionsToCashflows();

        QL_ENSURE(!cashflows().empty(), "bond with no cashflows!");
    }
Пример #12
0
    //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    void MidPointCDOEngine::calculate() const {
        Date today = Settings::instance().evaluationDate();

        results_.premiumValue = 0.0;
        results_.upfrontPremiumValue = 0.0;
        results_.protectionValue = 0.0;
        results_.expectedTrancheLoss.clear();

        // set remainingBasket_, results_.remainingNotional,
        // vector results_.expectedTrancheLoss for all schedule dates
        initialize();

        const vector<Date>& dates = arguments_.schedule.dates();
        if (dates.front() > today)
            results_.upfrontPremiumValue =
                arguments_.upfrontRate * results_.remainingNotional;

        vector<boost::shared_ptr<CashFlow> > premiumLeg =
            FixedRateLeg(arguments_.schedule)
            .withCouponRates(arguments_.runningRate, arguments_.dayCounter)
            .withPaymentAdjustment(arguments_.paymentConvention)
            .withNotionals(1.0);

        Real e1 = 0;
        if (dates[0] > today)
            e1 = expectedTrancheLoss (dates[0]);

        for (Size i = 0; i < premiumLeg.size(); i++) {
            boost::shared_ptr<Coupon> coupon =
                boost::dynamic_pointer_cast<Coupon>(premiumLeg[i]);
            Date paymentDate = coupon->date();
            Date startDate = std::max(coupon->accrualStartDate(),
                                      arguments_.yieldTS->referenceDate());
            Date endDate = coupon->accrualEndDate();
            Date defaultDate = startDate + (endDate-startDate)/2;
            if (paymentDate <= today)
                continue;

            Real e2 = expectedTrancheLoss(paymentDate);

            results_.premiumValue += (results_.remainingNotional - e2)
                * coupon->amount()
                * arguments_.yieldTS->discount(paymentDate);

            Real discount = arguments_.yieldTS->discount(defaultDate);
            results_.premiumValue += coupon->accruedAmount(defaultDate)
                * discount * (e2 - e1);
            results_.protectionValue += discount * (e2 - e1);

            e1 = e2;
        }

        if (arguments_.side == Protection::Buyer) {
            results_.protectionValue *= -1;
            results_.premiumValue *= -1;
            results_.upfrontPremiumValue *= -1;
        }

        results_.value = results_.premiumValue - results_.protectionValue
            + results_.upfrontPremiumValue;

        results_.errorEstimate = Null<Real>();
    }
Пример #13
0
    //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    void MonteCarloCDOEngine2::calculate() const {
        Date today = Settings::instance().evaluationDate();

        results_.protectionValue = 0.0;
        results_.premiumValue = 0.0;
        results_.expectedTrancheLoss.clear();

        // set remainingBasket_, results_.remainingNotional,
        initialize();

        const vector<Date>& dates = arguments_.schedule.dates();
        if (dates.front() > today)
            results_.upfrontPremiumValue =
                arguments_.upfrontRate * results_.remainingNotional;

        Real tmax = ActualActual().yearFraction(today, dates.back());
        //Real tmin = ActualActual().yearFraction(today, dates.front());
        QL_REQUIRE(tmax >= 0, "tmax < 0");

        vector<boost::shared_ptr<CashFlow> > premiumLeg =
            FixedRateLeg(arguments_.schedule)
            .withNotionals(1.0)
            .withCouponRates(arguments_.runningRate, arguments_.dayCounter)
            .withPaymentAdjustment(arguments_.paymentConvention);

        boost::shared_ptr<Pool> pool = remainingBasket_->pool();

        vector<Real> premiumValue(samples_, 0.0);
        vector<Real> protectionValue(samples_, 0.0);
        vector<Real> value(samples_, 0.0);
        vector<Real> fairPremium(samples_, 0.0);
        vector<vector<Real> > cumulativeTrancheLoss(samples_, vector<Real>());

        for (Size i = 0; i < samples_; i++) { //================================

            /******************************************************************
             * (1) Compute default times
             ******************************************************************/
            rdm_->nextSequence(tmax);

            /******************************************************************
             * (2) Cumulative tranche loss to schedule dates
             ******************************************************************/
            cumulativeTrancheLoss[i].resize(dates.size(), 0.0);
            remainingBasket_->updateScenarioLoss();
            for (Size k = 0; k < dates.size(); k++)
                cumulativeTrancheLoss[i][k]
                    = remainingBasket_->scenarioTrancheLoss(dates[k]);

            /*****************************************************************
             * (3) Contribution of this scenario to the protection leg
             *     - Loop through all incremental tranche loss events between
             *       start and end date
             *     - Pay and discount these increments as they occur
             *****************************************************************/
            vector<Loss> increments = remainingBasket_->scenarioIncrementalTrancheLosses(dates.front(), dates.back());
            for (Size k = 0; k < increments.size(); k++)
                protectionValue[i] += increments[k].amount
                    * arguments_.yieldTS->discount(increments[k].time);

            /*****************************************************************
             * (4) Contribution of this scenario to the premium leg
             *     - Loop through all coupon periods
             *     - Pay coupon at period end on effective notional
             *     - Effective notional:
             *       - Start with remaining notional minus cumulative loss
             *         on the tranche until period start =: N
             *       - Reduce N for each loss in the period by subtracting the
             *         the incremental tranche loss weighted with the time
             *         to period end
             *****************************************************************/
            for (Size j = 0; j < premiumLeg.size(); j++) {
                boost::shared_ptr<Coupon> coupon =
                    boost::dynamic_pointer_cast<Coupon>(premiumLeg[j]);
                Date startDate = std::max(coupon->accrualStartDate(),
                                          arguments_.yieldTS->referenceDate());
                Date endDate = coupon->accrualEndDate();
                Date paymentDate = coupon->date();
                if (paymentDate <= today)
                    continue;
                Real t1 = ActualActual().yearFraction(today, startDate);
                Real t2 = ActualActual().yearFraction(today, endDate);
                Real PL = cumulativeTrancheLoss[i][j];
                Real N = results_.remainingNotional - PL;
                for (Size k = 0; k < increments.size(); k++) {
                    Real t = increments[k].time;
                    if (t <= t1) continue;
                    if (t >= t2) break;
                    N -= (t2-t) / (t2-t1) * increments[k].amount;
                }
                Real discount = arguments_.yieldTS->discount(paymentDate);
                premiumValue[i] += N * coupon->amount() * discount;
            }

            /*****************
             * Aggregate
             *****************/
            results_.premiumValue += premiumValue[i];
            results_.protectionValue += protectionValue[i];
            value[i] = premiumValue[i] - protectionValue[i]
                + results_.upfrontPremiumValue;
            for (Size k = 0; k < dates.size(); k++)
                results_.expectedTrancheLoss[k] += cumulativeTrancheLoss[i][k];

            /*
            cout.setf (ios::fixed, ios::floatfield);
            cout << setprecision(0);
            for (Size k = 0; k < dates.size(); k++)
                cout << setw(3) << cumulativeTrancheLoss[i][k] << " ";
            cout << endl;

            cout << setprecision(2);
            for (Size k = 0; k < pool->size(); k++) {
                const string name = pool->names()[k];
                Real t =  pool->getTime(name);
                if (t < 6)
                    cout << setw(10) << name << " " << setw(5) << t << endl;
            }
            */
        } // end of loop over samples ==========================================

        /*****************************************
         * Expected values, normalize, switch sign
         *****************************************/
        results_.premiumValue /= samples_;
        results_.protectionValue /= samples_;
        for (Size k = 0; k < dates.size(); k++)
            results_.expectedTrancheLoss[k] /= samples_;

        if (arguments_.side == Protection::Buyer) {
            results_.protectionValue *= -1;
            results_.premiumValue *= -1;
            results_.upfrontPremiumValue *= -1;
        }

        results_.value = results_.premiumValue - results_.protectionValue
            + results_.upfrontPremiumValue;

        /*************************************************
         * Error estimates - NPV
         *************************************************/
        Real avg = 0.0;
        Real var = 0.0;
        for (Size i = 0; i < samples_; i++) {
            var += value[i] * value[i];
            avg += value[i];
        }
        avg /= samples_;
        var /= samples_;
        results_.errorEstimate = sqrt(var - avg * avg);

        /*****************************************************
         * Error estimates - fair premium
         * http://math.nyu.edu/~atm262/files/spring06/ircm/cdo
         *****************************************************/
        /*
        Real x = 0.0, xx = 0.0, y = 0.0, yy = 0.0, xy = 0.0;
        for (Size i = 0; i < samples_; i++) {
            Real dx = protectionValue[i] - results_.upfrontPremiumValue;
            Real dy = premiumValue[i];
            x += dx;
            xx += dx * dx;
            y += dy;
            yy += dy * dy;
            xy += dx * dy;
        }
        x /= samples_;
        y /= samples_;
        xx /= samples_;
        yy /= samples_;
        xy /= samples_;

        Real v = x*x/(y*y) * (xx/(x*x) + yy/(y*y) - 2.0 * xy/(x*y));
        Real stdFairPremium = sqrt(v) * arguments_.runningRate;
        */
    }
Пример #14
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");
        }
    }