예제 #1
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");
    }
예제 #2
0
 Autocall::Autocall(
                    const std::vector<Real>& notionals,
                    const Schedule& fixedSchedule,
                    const std::vector<Rate>& fixedCoupons,
                    const Schedule& callDates,
                    const std::vector<Real>& callLevels,
                    const std::vector<Real>& callPayments,
                    const Date& strikeDate,
                    const std::vector<Real>& strikeLevels,
                    const Autocall::RedemptionInfo& redemptionInfo,
                    const boost::shared_ptr<BasketPayoff>& underlyingType
                    )
 : MultiAssetOption(boost::shared_ptr<Payoff>(
                                              new PlainVanillaPayoff(Option::Call, callLevels.back())),
                    boost::shared_ptr<Exercise>(
                                                new EuropeanExercise(callDates.endDate()))),
 notionals_      ( notionals      ),
 fixedSchedule_  ( fixedSchedule  ),
 fixedCoupons_   ( fixedCoupons   ),
 callDates_      ( callDates      ),
 callLevels_     ( callLevels     ),
 callPayments_   ( callPayments   ),
 strikeDate_     ( strikeDate     ),
 strikeLevels_   ( strikeLevels   ),
 redemptionInfo_ ( redemptionInfo ),
 underlyingType_ ( underlyingType )
 {}
예제 #3
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);
        }
    };
예제 #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);
    }
    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!");
    }
예제 #6
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;
        }
    }