Beispiel #1
0
    CPILeg::operator Leg() const {

        QL_REQUIRE(!notionals_.empty(), "no notional given");
        Size n = schedule_.size()-1;
        Calendar calendar = schedule_.calendar();
        Leg leg;
        leg.reserve(n+1);   // +1 for notional, we always have some sort ...
        if (n>0) {
            QL_REQUIRE(!fixedRates_.empty() || !spreads_.empty(),
                       "no fixedRates or spreads given");

            Date refStart, start, refEnd, end;

            for (Size i=0; i<n; ++i) {
                refStart = start = schedule_.date(i);
                refEnd   =   end = schedule_.date(i+1);
                Date paymentDate = calendar.adjust(end, paymentAdjustment_);
                if (i==0   && !schedule_.isRegular(i+1)) {
                    BusinessDayConvention bdc = schedule_.businessDayConvention();
                    refStart = schedule_.calendar().adjust(end - schedule_.tenor(), bdc);
                }
                if (i==n-1 && !schedule_.isRegular(i+1)) {
                    BusinessDayConvention bdc = schedule_.businessDayConvention();
                    refEnd = schedule_.calendar().adjust(start + schedule_.tenor(), bdc);
                }
                if (detail::get(fixedRates_, i, 1.0) == 0.0) { // fixed coupon
                    leg.push_back(boost::shared_ptr<CashFlow>
                                  (new FixedRateCoupon
                                   (paymentDate, detail::get(notionals_, i, 0.0),
                                    detail::effectiveFixedRate(spreads_,caps_,floors_,i),
                                    paymentDayCounter_, start, end, refStart, refEnd)));
                } else { // zero inflation coupon
                    if (detail::noOption(caps_, floors_, i)) { // just swaplet
                        boost::shared_ptr<CPICoupon> coup;

                        coup = boost::shared_ptr<CPICoupon>
                            (new CPICoupon(baseCPI_,    // all have same base for ratio
                                     paymentDate,
                                     detail::get(notionals_, i, 0.0),
                                     start, end,
                                     detail::get(fixingDays_, i, 0.0),
                                     index_, observationLag_,
                                     observationInterpolation_,
                                     paymentDayCounter_,
                                     detail::get(fixedRates_, i, 0.0),
                                     detail::get(spreads_, i, 0.0),
                                     refStart, refEnd));

                        // in this case you can set a pricer
                        // straight away because it only provides computation - not data
                        boost::shared_ptr<CPICouponPricer> pricer
                            (new CPICouponPricer);
                        coup->setPricer(pricer);
                        leg.push_back(boost::dynamic_pointer_cast<CashFlow>(coup));

                    } else  {     // cap/floorlet
                        QL_FAIL("caps/floors on CPI coupons not implemented.");
                    }
                }
            }
        }

        // in CPI legs you always have a notional flow of some sort
        Date paymentDate = calendar.adjust(schedule_.date(n), paymentAdjustment_);
        Date fixingDate = paymentDate - observationLag_;
        boost::shared_ptr<CashFlow> xnl(new CPICashFlow
                          (detail::get(notionals_, n, 0.0), index_,
                           Date(), // is fake, i.e. you do not have one
                           baseCPI_, fixingDate, paymentDate,
                           subtractInflationNominal_, observationInterpolation_,
                           index_->frequency())
                         );
        leg.push_back(xnl);


        return leg;
    }
Beispiel #2
0
    FixedRateLeg::operator Leg() const {

        QL_REQUIRE(!couponRates_.empty(), "no coupon rates given");
        QL_REQUIRE(!notionals_.empty(), "no notional given");

        Leg leg;
        leg.reserve(schedule_.size()-1);

        // first period might be short or long
        Date start = schedule_.date(0), end = schedule_.date(1);
        Date paymentDate = paymentCalendar_.advance(end, paymentLag_, Days, paymentAdjustment_);
        Date exCouponDate;
        InterestRate rate = couponRates_[0];
        Real nominal = notionals_[0];

        if (exCouponPeriod_ != Period())
        {
            exCouponDate = exCouponCalendar_.advance(paymentDate,
                                                     -exCouponPeriod_,
                                                     exCouponAdjustment_,
                                                     exCouponEndOfMonth_);
        }
        Date ref = schedule_.hasTenor() &&
            schedule_.hasIsRegular() && !schedule_.isRegular(1) ?
            schedule_.calendar().advance(end,
                                         -schedule_.tenor(),
                                         schedule_.businessDayConvention(),
                                         schedule_.endOfMonth())
            : start;
        InterestRate r(rate.rate(),
                       firstPeriodDC_.empty() ? rate.dayCounter()
                       : firstPeriodDC_,
                       rate.compounding(), rate.frequency());
        leg.push_back(ext::shared_ptr<CashFlow>(new
            FixedRateCoupon(paymentDate, nominal, r,
                            start, end, ref, end, exCouponDate)));
        // regular periods
        for (Size i=2; i<schedule_.size()-1; ++i) {
            start = end; end = schedule_.date(i);
            Date paymentDate = paymentCalendar_.advance(end, paymentLag_, Days, paymentAdjustment_);
            if (exCouponPeriod_ != Period())
            {
                exCouponDate = exCouponCalendar_.advance(paymentDate,
                                                         -exCouponPeriod_,
                                                         exCouponAdjustment_,
                                                         exCouponEndOfMonth_);
            }
            if ((i-1) < couponRates_.size())
                rate = couponRates_[i-1];
            else
                rate = couponRates_.back();
            if ((i-1) < notionals_.size())
                nominal = notionals_[i-1];
            else
                nominal = notionals_.back();
            leg.push_back(ext::shared_ptr<CashFlow>(new
                FixedRateCoupon(paymentDate, nominal, rate,
                                start, end, start, end, exCouponDate)));
        }
        if (schedule_.size() > 2) {
            // last period might be short or long
            Size N = schedule_.size();
            start = end; end = schedule_.date(N-1);
            Date paymentDate = paymentCalendar_.advance(end, paymentLag_, Days, paymentAdjustment_);
            if (exCouponPeriod_ != Period())
            {
                exCouponDate = exCouponCalendar_.advance(paymentDate,
                                                         -exCouponPeriod_,
                                                         exCouponAdjustment_,
                                                         exCouponEndOfMonth_);
            }
            if ((N-2) < couponRates_.size())
                rate = couponRates_[N-2];
            else
                rate = couponRates_.back();
            if ((N-2) < notionals_.size())
                nominal = notionals_[N-2];
            else
                nominal = notionals_.back();
            InterestRate r( rate.rate(), lastPeriodDC_.empty() ?
                rate.dayCounter() :
                lastPeriodDC_ , rate.compounding(), rate.frequency() );
            if ((schedule_.hasIsRegular() && schedule_.isRegular(N - 1)) ||
                !schedule_.hasTenor()) {
                leg.push_back(ext::shared_ptr<CashFlow>(new
                    FixedRateCoupon(paymentDate, nominal, r,
                                    start, end, start, end, exCouponDate)));
            } else {
                Date ref = schedule_.calendar().advance(
                                            start,
                                            schedule_.tenor(),
                                            schedule_.businessDayConvention(),
                                            schedule_.endOfMonth());
                leg.push_back(ext::shared_ptr<CashFlow>(new
                    FixedRateCoupon(paymentDate, nominal, r,
                                    start, end, start, ref, exCouponDate)));
            }
        }
        return leg;
    }
    yoyInflationLeg::operator Leg() const {

        Size n = schedule_.size()-1;
        QL_REQUIRE(!notionals_.empty(), "no notional given");
        QL_REQUIRE(notionals_.size() <= n,
                   "too many nominals (" << notionals_.size() <<
                   "), only " << n << " required");
        QL_REQUIRE(gearings_.size()<=n,
                   "too many gearings (" << gearings_.size() <<
                   "), only " << n << " required");
        QL_REQUIRE(spreads_.size()<=n,
                   "too many spreads (" << spreads_.size() <<
                   "), only " << n << " required");
        QL_REQUIRE(caps_.size()<=n,
                   "too many caps (" << caps_.size() <<
                   "), only " << n << " required");
        QL_REQUIRE(floors_.size()<=n,
                   "too many floors (" << floors_.size() <<
                   "), only " << n << " required");

        Leg leg; leg.reserve(n);

        Calendar calendar = paymentCalendar_;

        Date refStart, start, refEnd, end;

        for (Size i=0; i<n; ++i) {
            refStart = start = schedule_.date(i);
            refEnd   =   end = schedule_.date(i+1);
            Date paymentDate = calendar.adjust(end, paymentAdjustment_);
            if (i==0 && schedule_.hasIsRegular() && !schedule_.isRegular(i+1)) {
                BusinessDayConvention bdc = schedule_.businessDayConvention();
                refStart = schedule_.calendar().adjust(end - schedule_.tenor(), bdc);
            }
            if (i==n-1 && schedule_.hasIsRegular() && !schedule_.isRegular(i+1)) {
                BusinessDayConvention bdc = schedule_.businessDayConvention();
                refEnd = schedule_.calendar().adjust(start + schedule_.tenor(), bdc);
            }
            if (detail::get(gearings_, i, 1.0) == 0.0) { // fixed coupon
                leg.push_back(ext::shared_ptr<CashFlow>(new
                            FixedRateCoupon(paymentDate,
                            detail::get(notionals_, i, 1.0),
                            detail::effectiveFixedRate(spreads_,caps_,
                                    floors_,i),
                                    paymentDayCounter_,
                                    start, end, refStart, refEnd)));
            } else { // yoy inflation coupon
                if (detail::noOption(caps_, floors_, i)) { // just swaplet
                    ext::shared_ptr<YoYInflationCoupon> coup(new
                            YoYInflationCoupon(
                            paymentDate,
                            detail::get(notionals_, i, 1.0),
                            start, end,
                            detail::get(fixingDays_, i, 0),
                            index_,
                            observationLag_,
                            paymentDayCounter_,
                            detail::get(gearings_, i, 1.0),
                            detail::get(spreads_, i, 0.0),
                            refStart, refEnd));

                    // in this case you can set a pricer
                    // straight away because it only provides computation - not data
                    ext::shared_ptr<YoYInflationCouponPricer> pricer(
                                            new YoYInflationCouponPricer);
                    coup->setPricer(pricer);
                    leg.push_back(ext::dynamic_pointer_cast<CashFlow>(coup));



                } else {    // cap/floorlet
                    leg.push_back(ext::shared_ptr<CashFlow>(new
                            CappedFlooredYoYInflationCoupon(
                            paymentDate,
                            detail::get(notionals_, i, 1.0),
                            start, end,
                            detail::get(fixingDays_, i, 0),
                            index_,
                            observationLag_,
                            paymentDayCounter_,
                            detail::get(gearings_, i, 1.0),
                            detail::get(spreads_, i, 0.0),
                            detail::get(caps_,   i, Null<Rate>()),
                            detail::get(floors_, i, Null<Rate>()),
                            refStart, refEnd)));
                }
            }
        }

        return leg;
    }
Beispiel #4
0
    FixedRateLeg::operator Leg() const {

        QL_REQUIRE(!couponRates_.empty(), "no coupon rates given");
        QL_REQUIRE(!notionals_.empty(), "no notional given");

        Leg leg;
        leg.reserve(schedule_.size()-1);

        Calendar schCalendar = schedule_.calendar();

        // first period might be short or long
        Date start = schedule_.date(0), end = schedule_.date(1);
        Date paymentDate = calendar_.adjust(end, paymentAdjustment_);
        Date exCouponDate;
        InterestRate rate = couponRates_[0];
        Real nominal = notionals_[0];

        if (exCouponPeriod_ != Period())
        {
            exCouponDate = exCouponCalendar_.advance(paymentDate,
                                                     -exCouponPeriod_,
                                                     exCouponAdjustment_,
                                                     exCouponEndOfMonth_);
        }

        if (schedule_.isRegular(1)) {
            QL_REQUIRE(firstPeriodDC_.empty() ||
                       firstPeriodDC_ == rate.dayCounter(),
                       "regular first coupon "
                       "does not allow a first-period day count");
            shared_ptr<CashFlow> temp(new
                FixedRateCoupon(paymentDate, nominal, rate,
                                start, end, start, end, exCouponDate));
            leg.push_back(temp);
        } else {
            Date ref = end - schedule_.tenor();
            ref = schCalendar.adjust(ref, schedule_.businessDayConvention());
            InterestRate r(rate.rate(),
                           firstPeriodDC_.empty() ? rate.dayCounter()
                                                  : firstPeriodDC_,
                           rate.compounding(), rate.frequency());
            leg.push_back(shared_ptr<CashFlow>(new
                FixedRateCoupon(paymentDate, nominal, r,
                                start, end, ref, end, exCouponDate)));
        }
        // regular periods
        for (Size i=2; i<schedule_.size()-1; ++i) {
            start = end; end = schedule_.date(i);
            paymentDate = calendar_.adjust(end, paymentAdjustment_);
            if (exCouponPeriod_ != Period())
            {
                exCouponDate = exCouponCalendar_.advance(paymentDate,
                                                         -exCouponPeriod_,
                                                         exCouponAdjustment_,
                                                         exCouponEndOfMonth_);
            }
            if ((i-1) < couponRates_.size())
                rate = couponRates_[i-1];
            else
                rate = couponRates_.back();
            if ((i-1) < notionals_.size())
                nominal = notionals_[i-1];
            else
                nominal = notionals_.back();
            leg.push_back(shared_ptr<CashFlow>(new
                FixedRateCoupon(paymentDate, nominal, rate,
                                start, end, start, end, exCouponDate)));
        }
        if (schedule_.size() > 2) {
            // last period might be short or long
            Size N = schedule_.size();
            start = end; end = schedule_.date(N-1);
            paymentDate = calendar_.adjust(end, paymentAdjustment_);
            if (exCouponPeriod_ != Period())
            {
                exCouponDate = exCouponCalendar_.advance(paymentDate,
                                                         -exCouponPeriod_,
                                                         exCouponAdjustment_,
                                                         exCouponEndOfMonth_);
            }
            if ((N-2) < couponRates_.size())
                rate = couponRates_[N-2];
            else
                rate = couponRates_.back();
            if ((N-2) < notionals_.size())
                nominal = notionals_[N-2];
            else
                nominal = notionals_.back();
            if (schedule_.isRegular(N-1)) {
                leg.push_back(shared_ptr<CashFlow>(new
                    FixedRateCoupon(paymentDate, nominal, rate,
                                    start, end, start, end, exCouponDate)));
            } else {
                Date ref = start + schedule_.tenor();
                ref = schCalendar.adjust(ref, schedule_.businessDayConvention());
                leg.push_back(shared_ptr<CashFlow>(new
                    FixedRateCoupon(paymentDate, nominal, rate,
                                    start, end, start, ref, exCouponDate)));
            }
        }
        return leg;
    }