예제 #1
0
const Real Gaussian1dModel::swapAnnuity(const Date &fixing, const Period &tenor,
                                        const Date &referenceDate, const Real y,
                                        boost::shared_ptr<SwapIndex> swapIdx) const {

    QL_REQUIRE(swapIdx != NULL, "no swap index given");

    calculate();

    Handle<YieldTermStructure> ytsd =
        swapIdx->discountingTermStructure(); // might be empty, then use
    // model curve

    boost::shared_ptr<VanillaSwap> underlying =
        underlyingSwap(swapIdx, fixing, tenor);

    Schedule sched = underlying->fixedSchedule();

    Real annuity = 0.0;
    for (unsigned int j = 1; j < sched.size(); j++) {
        annuity += zerobond(sched.calendar().adjust(
                                sched.date(j), underlying->paymentConvention()),
                            referenceDate, y, ytsd) *
                   swapIdx->dayCounter().yearFraction(sched.date(j - 1),
                           sched.date(j));
    }
    return annuity;
}
예제 #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");
    }
예제 #3
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_);
    }
예제 #4
0
    //------------------------------------------------------------------------
    RiskyFloatingBond::RiskyFloatingBond(
                            std::string name,
                            Currency ccy,
                            Real recoveryRate,
                            Handle<DefaultProbabilityTermStructure> defaultTS,
                            Schedule schedule,
                            boost::shared_ptr<IborIndex> index,
                            Integer fixingDays,
                            Real spread,
                            std::vector<Real> notionals,
                            Handle<YieldTermStructure> yieldTS,
                            Natural settlementDays)
    : RiskyBond(name, ccy, recoveryRate, defaultTS, yieldTS,
                settlementDays, schedule.calendar()),
          schedule_(schedule),
          index_(index),
          fixingDays_(fixingDays),
          spread_(spread),
          notionals_(notionals) {

        // FIXME: Take paymentConvention into account
        std::vector<Date> dates = schedule_.dates();
        Real previousNotional = notionals_.front();
        for (Size i = 1; i < dates.size(); i++) {
            Real currentNotional = (i < notionals_.size() ?
                             notionals_[i] :
                             notionals_.back());
            boost::shared_ptr<CashFlow> interest (new
                   IborCoupon(dates[i], previousNotional, dates[i-1], dates[i],
                              fixingDays_, index_, 1.0, spread_));
            boost::shared_ptr<CashFlow> amortization(new
                 AmortizingPayment(previousNotional - currentNotional, dates[i]));
            previousNotional = currentNotional;

            leg_.push_back(interest);
            interestLeg_.push_back(interest);
            if (amortization->amount() != 0){
                leg_.push_back(amortization);
                redemptionLeg_.push_back(amortization);
            }
        }

        boost::shared_ptr<CashFlow> redemption(new
                 Redemption(previousNotional, schedule_.dates().back()));
        leg_.push_back(redemption);
        redemptionLeg_.push_back(redemption);

        boost::shared_ptr<IborCouponPricer>
            fictitiousPricer(new
                BlackIborCouponPricer(Handle<OptionletVolatilityStructure>()));
        setCouponPricer(leg_,fictitiousPricer);
    }
예제 #5
0
    //------------------------------------------------------------------------
    RiskyFixedBond::RiskyFixedBond(
                            const std::string& name,
                            const Currency& ccy,
                            Real recoveryRate,
                            const Handle<DefaultProbabilityTermStructure>& defaultTS,
                            const Schedule& schedule,
                            Real rate,
                            const DayCounter& dayCounter,
                            BusinessDayConvention paymentConvention,
                            const std::vector<Real>& notionals,
                            const Handle<YieldTermStructure>& yieldTS,
                            Natural settlementDays)
    : RiskyBond(name, ccy, recoveryRate, defaultTS, yieldTS,
                settlementDays, schedule.calendar()),
          schedule_(schedule),
          rate_(rate),
          dayCounter_(dayCounter),
          // paymentConvention_(paymentConvention),
          notionals_(notionals) {
        // FIXME: Take paymentConvention into account
        std::vector<Date> dates = schedule_.dates();
        Real previousNotional = notionals_.front();
        for (Size i = 1; i < dates.size(); i++) {
            Real currentNotional = (i < notionals_.size() ?
                             notionals_[i] :
                             notionals_.back());
            boost::shared_ptr<CashFlow> interest (new
                   FixedRateCoupon(dates[i], previousNotional,
                                   rate_, dayCounter_, dates[i-1], dates[i]));
            boost::shared_ptr<CashFlow> amortization(new
                 AmortizingPayment(previousNotional - currentNotional, dates[i]));
            previousNotional = currentNotional;

            leg_.push_back(interest);
            interestLeg_.push_back(interest);
            if (amortization->amount() != 0){
                leg_.push_back(amortization);
                redemptionLeg_.push_back(amortization);
            }
        }

        boost::shared_ptr<CashFlow> redemption(new
                 Redemption(previousNotional, schedule_.dates().back()));
        leg_.push_back(redemption);
        redemptionLeg_.push_back(redemption);
    }
예제 #6
0
    CPIBond::CPIBond(Natural settlementDays,
                     Real faceAmount,
                     bool growthOnly,
                     Real baseCPI,
                     const Period& observationLag,
                     const boost::shared_ptr<ZeroInflationIndex>& cpiIndex,
                     CPI::InterpolationType observationInterpolation,
                     const Schedule& schedule,
                     const std::vector<Rate>& fixedRate,
                     const DayCounter& accrualDayCounter,
                     BusinessDayConvention paymentConvention,
                     const Date& issueDate)
    : Bond(settlementDays, schedule.calendar(), issueDate),
    frequency_(schedule.tenor().frequency()),
    dayCounter_(accrualDayCounter),
    growthOnly_(growthOnly),
    baseCPI_(baseCPI),
    observationLag_(observationLag),
    cpiIndex_(cpiIndex),
    observationInterpolation_(observationInterpolation)
    {

        maturityDate_ = schedule.endDate();

        // a CPIleg know about zero legs and inclusion of base inflation notional
        cashflows_ = CPILeg(schedule, cpiIndex_,
                            baseCPI_, observationLag_)
        .withNotionals(faceAmount)
        .withFixedRates(fixedRate)
        .withPaymentDayCounter(accrualDayCounter)
        .withPaymentAdjustment(paymentConvention)
        .withObservationInterpolation(observationInterpolation_)
        .withSubtractInflationNominal(growthOnly_);

        registerWith(cpiIndex_);
        Leg::const_iterator i;
        for (i = cashflows_.begin(); i < cashflows_.end(); ++i) {
            registerWith(*i);
        }
    };
예제 #7
0
    CallableBond::CallableBond(Natural settlementDays,
                               const Schedule& schedule,
                               const DayCounter& paymentDayCounter,
                               const Date& issueDate,
                               const CallabilitySchedule& putCallSchedule)
    : Bond(settlementDays, schedule.calendar(), issueDate),
      paymentDayCounter_(paymentDayCounter), putCallSchedule_(putCallSchedule) {

        maturityDate_ = schedule.dates().back();

        if (!putCallSchedule_.empty()) {
            Date finalOptionDate = Date::minDate();
            for (Size i=0; i<putCallSchedule_.size();++i) {
                finalOptionDate=std::max(finalOptionDate,
                                         putCallSchedule_[i]->date());
            }
            QL_REQUIRE(finalOptionDate <= maturityDate_ ,
                       "Bond cannot mature before last call/put date");
        }

        // derived classes must set cashflows_ and frequency_
    }
예제 #8
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);
    }
    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!");
    }
예제 #10
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;
        }
    }
예제 #11
0
 FixedRateLeg::FixedRateLeg(const Schedule& schedule)
 : schedule_(schedule), paymentCalendar_(schedule.calendar()),
   paymentAdjustment_(Following), paymentLag_(0) {}