forwardingTermStructure() private method

private forwardingTermStructure ( ) : Handle
return Handle
Example #1
0
        public VanillaSwap value()
        {
            Date startDate;

            if (effectiveDate_ != null)
            {
                startDate = effectiveDate_;
            }
            else
            {
                int  fixingDays    = iborIndex_.fixingDays();
                Date referenceDate = Settings.evaluationDate();
                Date spotDate      = floatCalendar_.advance(referenceDate, new Period(fixingDays, TimeUnit.Days));
                startDate = spotDate + forwardStart_;
            }

            Date endDate;

            if (terminationDate_ != null)
            {
                endDate = terminationDate_;
            }
            else
            {
                endDate = startDate + swapTenor_;
            }


            Schedule fixedSchedule = new Schedule(startDate, endDate,
                                                  fixedTenor_, fixedCalendar_,
                                                  fixedConvention_, fixedTerminationDateConvention_,
                                                  fixedRule_, fixedEndOfMonth_,
                                                  fixedFirstDate_, fixedNextToLastDate_);

            Schedule floatSchedule = new Schedule(startDate, endDate,
                                                  floatTenor_, floatCalendar_,
                                                  floatConvention_, floatTerminationDateConvention_,
                                                  floatRule_, floatEndOfMonth_,
                                                  floatFirstDate_, floatNextToLastDate_);

            double?usedFixedRate = fixedRate_;

            if (fixedRate_ == null)         // calculate a fair fixed rate if no fixed rate is provided
            {
                if (iborIndex_.forwardingTermStructure().empty())
                {
                    throw new ArgumentException("no forecasting term structure set to " + iborIndex_.name());
                }
                VanillaSwap temp = new VanillaSwap(type_, nominal_, fixedSchedule, 0.0, fixedDayCount_,
                                                   floatSchedule, iborIndex_, floatSpread_, floatDayCount_);
                temp.setPricingEngine(new DiscountingSwapEngine(iborIndex_.forwardingTermStructure()));
                usedFixedRate = temp.fairRate();
            }

            VanillaSwap swap = new VanillaSwap(type_, nominal_, fixedSchedule, usedFixedRate.Value, fixedDayCount_,
                                               floatSchedule, iborIndex_, floatSpread_, floatDayCount_);

            swap.setPricingEngine(engine_);
            return(swap);
        }
Example #2
0
        public LiborForwardModelProcess(int size, IborIndex index, IDiscretization disc)
            : base(disc)
        {
            size_              = size;
            index_             = index;
            initialValues_     = new InitializedList <double>(size_);
            fixingTimes_       = new InitializedList <double>(size);
            fixingDates_       = new InitializedList <Date>(size_);
            accrualStartTimes_ = new InitializedList <double>(size);
            accrualEndTimes_   = new InitializedList <double>(size);
            accrualPeriod_     = new InitializedList <double>(size_);
            m1 = new Vector(size_);
            m2 = new Vector(size_);
            DayCounter       dayCounter = index.dayCounter();
            IList <CashFlow> flows      = cashFlows(1);

            if (!(size_ == flows.Count))
            {
                throw new ArgumentException("wrong number of cashflows");
            }

            Date       settlement = index_.forwardingTermStructure().link.referenceDate();
            Date       startDate;
            IborCoupon iborcoupon = (IborCoupon)flows[0];

            startDate = iborcoupon.fixingDate();

            for (int i = 0; i < size_; ++i)
            {
                IborCoupon coupon = (IborCoupon)flows[i];

                if (!(coupon.date() == coupon.accrualEndDate()))
                {
                    throw new ArgumentException("irregular coupon types are not suppported");
                }

                initialValues_[i] = coupon.rate();
                accrualPeriod_[i] = coupon.accrualPeriod();

                fixingDates_[i]       = coupon.fixingDate();
                fixingTimes_[i]       = dayCounter.yearFraction(startDate, coupon.fixingDate());
                accrualStartTimes_[i] = dayCounter.yearFraction(settlement, coupon.accrualStartDate());
                accrualEndTimes_[i]   = dayCounter.yearFraction(settlement, coupon.accrualEndDate());
            }
        }
Example #3
0
        public List <CashFlow> cashFlows(double amount)
        {
            Date refDate = index_.forwardingTermStructure().link.referenceDate();

            Schedule schedule = new Schedule(refDate,
                                             refDate + new Period(index_.tenor().length() * size_,
                                                                  index_.tenor().units()),
                                             index_.tenor(), index_.fixingCalendar(),
                                             index_.businessDayConvention(),
                                             index_.businessDayConvention(),
                                             DateGeneration.Rule.Forward, false);

            IborLeg cashflows = (IborLeg) new IborLeg(schedule, index_)
                                .withFixingDays(index_.fixingDays())
                                .withPaymentDayCounter(index_.dayCounter())
                                .withNotionals(amount)
                                .withPaymentAdjustment(index_.businessDayConvention());

            return(cashflows.value());
        }
Example #4
0
        public RangeAccrualFloatersCoupon(Date paymentDate,
                                          double nominal,
                                          IborIndex index,
                                          Date startDate,
                                          Date endDate,
                                          int fixingDays,
                                          DayCounter dayCounter,
                                          double gearing,
                                          double spread,
                                          Date refPeriodStart,
                                          Date refPeriodEnd,
                                          Schedule observationsSchedule,
                                          double lowerTrigger,
                                          double upperTrigger)
            : base(paymentDate, nominal, startDate, endDate, fixingDays, index, gearing, spread, refPeriodStart, refPeriodEnd,
                   dayCounter)
        {
            observationsSchedule_ = observationsSchedule;
            lowerTrigger_         = lowerTrigger;
            upperTrigger_         = upperTrigger;

            Utils.QL_REQUIRE(lowerTrigger_ < upperTrigger, () => "lowerTrigger_>=upperTrigger");
            Utils.QL_REQUIRE(observationsSchedule_.startDate() == startDate, () => "incompatible start date");
            Utils.QL_REQUIRE(observationsSchedule_.endDate() == endDate, () => "incompatible end date");

            observationDates_ = new List <Date>(observationsSchedule_.dates());
            observationDates_.RemoveAt(observationDates_.Count - 1); //remove end date
            observationDates_.RemoveAt(0);                           //remove start date
            observationsNo_ = observationDates_.Count;

            Handle <YieldTermStructure> rateCurve = index.forwardingTermStructure();
            Date referenceDate = rateCurve.link.referenceDate();

            startTime_        = dayCounter.yearFraction(referenceDate, startDate);
            endTime_          = dayCounter.yearFraction(referenceDate, endDate);
            observationTimes_ = new List <double>();
            for (int i = 0; i < observationsNo_; i++)
            {
                observationTimes_.Add(dayCounter.yearFraction(referenceDate, observationDates_[i]));
            }
        }
Example #5
0
        public LiborForwardModelProcess(int size, IborIndex index, IDiscretization disc)
            : base(disc)
        {
            size_ = size;
            index_ = index;
            initialValues_ = new InitializedList<double>(size_);
            fixingTimes_ = new InitializedList<double>(size);
            fixingDates_ = new InitializedList<Date>(size_);
            accrualStartTimes_ = new InitializedList<double>(size);
            accrualEndTimes_ = new InitializedList<double>(size);
            accrualPeriod_ = new InitializedList<double>(size_);
            m1 = new Vector(size_);
            m2 = new Vector(size_);
            DayCounter dayCounter = index.dayCounter();
            IList<CashFlow> flows = cashFlows(1);

            if(!(size_ == flows.Count))
                    throw new ArgumentException( "wrong number of cashflows");

            Date settlement = index_.forwardingTermStructure().link.referenceDate();
            Date startDate;
            IborCoupon iborcoupon = (IborCoupon)flows[0];
            startDate = iborcoupon.fixingDate();

            for (int i = 0; i < size_; ++i)
            {
                IborCoupon coupon = (IborCoupon)flows[i];

                if(!(coupon.date() == coupon.accrualEndDate()))
                    throw new ArgumentException("irregular coupon types are not suppported");

                initialValues_[i]=coupon.rate();
                accrualPeriod_[i]=coupon.accrualPeriod();

                fixingDates_[i]=coupon.fixingDate();
                fixingTimes_[i]=dayCounter.yearFraction(startDate, coupon.fixingDate());
                accrualStartTimes_[i]=dayCounter.yearFraction(settlement, coupon.accrualStartDate());
                accrualEndTimes_[i]=dayCounter.yearFraction(settlement, coupon.accrualEndDate());
            }
        }
Example #6
0
        public override void initialize(FloatingRateCoupon coupon)
        {
            coupon_ = coupon as RangeAccrualFloatersCoupon;
            Utils.QL_REQUIRE(coupon_ != null, () => "range-accrual coupon required");
            gearing_ = coupon_.gearing();
            spread_  = coupon_.spread();

            Date paymentDate = coupon_.date();

            IborIndex index = coupon_.index() as IborIndex;

            Utils.QL_REQUIRE(index != null, () => "invalid index");
            Handle <YieldTermStructure> rateCurve = index.forwardingTermStructure();

            discount_       = rateCurve.link.discount(paymentDate);
            accrualFactor_  = coupon_.accrualPeriod();
            spreadLegValue_ = spread_ * accrualFactor_ * discount_;

            startTime_        = coupon_.startTime();
            endTime_          = coupon_.endTime();
            observationTimes_ = coupon_.observationTimes();
            lowerTrigger_     = coupon_.lowerTrigger();
            upperTrigger_     = coupon_.upperTrigger();
            observationsNo_   = coupon_.observationsNo();

            List <Date> observationDates = coupon_.observationsSchedule().dates();

            Utils.QL_REQUIRE(observationDates.Count == observationsNo_ + 2, () => "incompatible size of initialValues vector");
            initialValues_ = new InitializedList <double>(observationDates.Count, 0.0);

            Calendar calendar = index.fixingCalendar();

            for (int i = 0; i < observationDates.Count; i++)
            {
                initialValues_[i] = index.fixing(
                    calendar.advance(observationDates[i], -coupon_.fixingDays, TimeUnit.Days));
            }
        }
Example #7
0
        public MakeVanillaSwap(Period swapTenor, IborIndex index, double? fixedRate, Period forwardStart) {
            swapTenor_ = swapTenor;
            iborIndex_ = index;
            fixedRate_ = fixedRate;
            forwardStart_ = forwardStart;
            effectiveDate_ = null;
            fixedCalendar_ = floatCalendar_ = index.fixingCalendar();
            
            type_ = VanillaSwap.Type.Payer;
            nominal_ = 1.0;
            fixedTenor_ = new Period(1, TimeUnit.Years);
            floatTenor_ = index.tenor();
            fixedConvention_ = fixedTerminationDateConvention_ = BusinessDayConvention.ModifiedFollowing;
            floatConvention_ = floatTerminationDateConvention_ = index.businessDayConvention();
            fixedRule_ = floatRule_ = DateGeneration.Rule.Backward;
            fixedEndOfMonth_ = floatEndOfMonth_ = false;
            fixedFirstDate_ = fixedNextToLastDate_ = floatFirstDate_ = floatNextToLastDate_ = null;
            floatSpread_ = 0.0;
            fixedDayCount_ = new Thirty360(Thirty360.Thirty360Convention.BondBasis);
            floatDayCount_ = index.dayCounter();

            engine_ = new DiscountingSwapEngine(index.forwardingTermStructure());
        }
Example #8
0
        public MakeVanillaSwap(Period swapTenor, IborIndex index, double?fixedRate, Period forwardStart)
        {
            swapTenor_     = swapTenor;
            iborIndex_     = index;
            fixedRate_     = fixedRate;
            forwardStart_  = forwardStart;
            effectiveDate_ = null;
            fixedCalendar_ = floatCalendar_ = index.fixingCalendar();

            type_            = VanillaSwap.Type.Payer;
            nominal_         = 1.0;
            fixedTenor_      = new Period(1, TimeUnit.Years);
            floatTenor_      = index.tenor();
            fixedConvention_ = fixedTerminationDateConvention_ = BusinessDayConvention.ModifiedFollowing;
            floatConvention_ = floatTerminationDateConvention_ = index.businessDayConvention();
            fixedRule_       = floatRule_ = DateGeneration.Rule.Backward;
            fixedEndOfMonth_ = floatEndOfMonth_ = false;
            fixedFirstDate_  = fixedNextToLastDate_ = floatFirstDate_ = floatNextToLastDate_ = null;
            floatSpread_     = 0.0;
            fixedDayCount_   = new Thirty360(Thirty360.Thirty360Convention.BondBasis);
            floatDayCount_   = index.dayCounter();

            engine_ = new DiscountingSwapEngine(index.forwardingTermStructure());
        }
Example #9
0
        //===========================================================================//
        //                              BlackIborCouponPricer                        //
        //===========================================================================//

        public override void initialize(FloatingRateCoupon coupon)
        {
            coupon_ = coupon as IborCoupon;
            if (coupon_ == null)
            {
                throw new ApplicationException("Libor coupon required");
            }
            gearing_ = coupon_.gearing();
            spread_  = coupon_.spread();
            Date      paymentDate = coupon_.date();
            IborIndex index       = coupon_.index() as IborIndex;
            Handle <YieldTermStructure> rateCurve = index.forwardingTermStructure();

            if (paymentDate > rateCurve.link.referenceDate())
            {
                discount_ = rateCurve.link.discount(paymentDate);
            }
            else
            {
                discount_ = 1.0;
            }

            spreadLegValue_ = spread_ * coupon_.accrualPeriod() * discount_;
        }
Example #10
0
        protected override void initializeDates()
        {
            earliestDate_ = calendar_.advance(evaluationDate_, new Period(settlementDays_, TimeUnit.Days),
                                              BusinessDayConvention.Following);

            Date maturity = earliestDate_ + tenor_;

            // dummy BMA index with curve/swap arguments
            BMAIndex clonedIndex = new BMAIndex(termStructureHandle_);

            Schedule bmaSchedule = new MakeSchedule().from(earliestDate_).to(maturity)
                                   .withTenor(bmaPeriod_)
                                   .withCalendar(bmaIndex_.fixingCalendar())
                                   .withConvention(bmaConvention_)
                                   .backwards()
                                   .value();

            Schedule liborSchedule = new MakeSchedule().from(earliestDate_).to(maturity)
                                     .withTenor(iborIndex_.tenor())
                                     .withCalendar(iborIndex_.fixingCalendar())
                                     .withConvention(iborIndex_.businessDayConvention())
                                     .endOfMonth(iborIndex_.endOfMonth())
                                     .backwards()
                                     .value();

            swap_ = new BMASwap(BMASwap.Type.Payer, 100.0, liborSchedule, 0.75,             // arbitrary
                                0.0, iborIndex_, iborIndex_.dayCounter(), bmaSchedule, clonedIndex, bmaDayCount_);
            swap_.setPricingEngine(new DiscountingSwapEngine(iborIndex_.forwardingTermStructure()));

            Date d             = calendar_.adjust(swap_.maturityDate(), BusinessDayConvention.Following);
            int  w             = d.weekday();
            Date nextWednesday = (w >= 4) ? d + new Period((11 - w), TimeUnit.Days) :
                                 d + new Period((4 - w), TimeUnit.Days);

            latestDate_ = clonedIndex.valueDate(clonedIndex.fixingCalendar().adjust(nextWednesday));
        }
Example #11
0
        public MakeBasisSwap(Period swapTenor, IborIndex index1, IborIndex index2, Period forwardStart)
        {
            swapTenor_ = swapTenor;
             iborIndex1_ = index1;
             iborIndex2_ = index2;
             forwardStart_ = forwardStart;
             effectiveDate_ = null;
             float1Calendar_ = float2Calendar_ = index1.fixingCalendar();

             type_ = BasisSwap.Type.Payer;
             nominal_ = 1.0;
             float1Tenor_ = index1.tenor();
             float2Tenor_ = index2.tenor();
             float1Convention_ = float1TerminationDateConvention_ = index1.businessDayConvention();
             float2Convention_ = float2TerminationDateConvention_ = index2.businessDayConvention();
             float1Rule_ = float2Rule_ = DateGeneration.Rule.Backward;
             float1EndOfMonth_ = float2EndOfMonth_ = false;
             float1FirstDate_ = float1NextToLastDate_ = float2FirstDate_ = float2NextToLastDate_ = null;
             float1Spread_ = float2Spread_ = 0.0;
             float1DayCount_ = index1.dayCounter();
             float2DayCount_ = index2.dayCounter();

             engine_ = new DiscountingBasisSwapEngine(index1.forwardingTermStructure(), index2.forwardingTermStructure());
        }
Example #12
0
        public MakeBasisSwap(Period swapTenor, IborIndex index1, IborIndex index2, Period forwardStart)
        {
            swapTenor_      = swapTenor;
            iborIndex1_     = index1;
            iborIndex2_     = index2;
            forwardStart_   = forwardStart;
            effectiveDate_  = null;
            float1Calendar_ = float2Calendar_ = index1.fixingCalendar();

            type_             = BasisSwap.Type.Payer;
            nominal_          = 1.0;
            float1Tenor_      = index1.tenor();
            float2Tenor_      = index2.tenor();
            float1Convention_ = float1TerminationDateConvention_ = index1.businessDayConvention();
            float2Convention_ = float2TerminationDateConvention_ = index2.businessDayConvention();
            float1Rule_       = float2Rule_ = DateGeneration.Rule.Backward;
            float1EndOfMonth_ = float2EndOfMonth_ = false;
            float1FirstDate_  = float1NextToLastDate_ = float2FirstDate_ = float2NextToLastDate_ = null;
            float1Spread_     = float2Spread_ = 0.0;
            float1DayCount_   = index1.dayCounter();
            float2DayCount_   = index2.dayCounter();

            engine_ = new DiscountingBasisSwapEngine(index1.forwardingTermStructure(), index2.forwardingTermStructure());
        }
Example #13
0
 public Handle <YieldTermStructure> forwardingTermStructure()
 {
     return(iborIndex_.forwardingTermStructure());
 }
Example #14
0
        public VanillaSwap value()
        {
            Date startDate;

            if (effectiveDate_ != null)
            {
                startDate = effectiveDate_;
            }
            else
            {
                //int fixingDays = iborIndex_.fixingDays();
                Date refDate = Settings.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, new Period(settlementDays_, TimeUnit.Days));
                startDate = spotDate + forwardStart_;
                if (forwardStart_.length() < 0)
                {
                    startDate = floatCalendar_.adjust(startDate, BusinessDayConvention.Preceding);
                }
                else
                {
                    startDate = floatCalendar_.adjust(startDate, BusinessDayConvention.Following);
                }
            }

            Date endDate = terminationDate_;

            if (endDate == null)
            {
                if (floatEndOfMonth_)
                {
                    endDate = floatCalendar_.advance(startDate,
                                                     swapTenor_,
                                                     BusinessDayConvention.ModifiedFollowing,
                                                     floatEndOfMonth_);
                }
                else
                {
                    endDate = startDate + swapTenor_;
                }
            }

            Currency curr       = iborIndex_.currency();
            Period   fixedTenor = null;

            if (fixedTenor_ != null)
            {
                fixedTenor = fixedTenor_;
            }
            else
            {
                if ((curr == new EURCurrency()) ||
                    (curr == new USDCurrency()) ||
                    (curr == new CHFCurrency()) ||
                    (curr == new SEKCurrency()) ||
                    (curr == new GBPCurrency() && swapTenor_ <= new Period(1, TimeUnit.Years)))
                {
                    fixedTenor = new Period(1, TimeUnit.Years);
                }
                else if ((curr == new GBPCurrency() && swapTenor_ > new Period(1, TimeUnit.Years) ||
                          (curr == new JPYCurrency()) ||
                          (curr == new AUDCurrency() && swapTenor_ >= new Period(4, TimeUnit.Years))))
                {
                    fixedTenor = new Period(6, TimeUnit.Months);
                }
                else if ((curr == new HKDCurrency() ||
                          (curr == new AUDCurrency() && swapTenor_ < new Period(4, TimeUnit.Years))))
                {
                    fixedTenor = new Period(3, TimeUnit.Months);
                }
                else
                {
                    Utils.QL_FAIL("unknown fixed leg default tenor for " + curr);
                }
            }

            Schedule fixedSchedule = new Schedule(startDate, endDate,
                                                  fixedTenor, fixedCalendar_,
                                                  fixedConvention_, fixedTerminationDateConvention_,
                                                  fixedRule_, fixedEndOfMonth_,
                                                  fixedFirstDate_, fixedNextToLastDate_);

            Schedule floatSchedule = new Schedule(startDate, endDate,
                                                  floatTenor_, floatCalendar_,
                                                  floatConvention_, floatTerminationDateConvention_,
                                                  floatRule_, floatEndOfMonth_,
                                                  floatFirstDate_, floatNextToLastDate_);

            DayCounter fixedDayCount = null;

            if (fixedDayCount_ != null)
            {
                fixedDayCount = fixedDayCount_;
            }
            else
            {
                if (curr == new USDCurrency())
                {
                    fixedDayCount = new Actual360();
                }
                else if (curr == new EURCurrency() || curr == new CHFCurrency() || curr == new SEKCurrency())
                {
                    fixedDayCount = new Thirty360(Thirty360.Thirty360Convention.BondBasis);
                }
                else if (curr == new GBPCurrency() || curr == new JPYCurrency() || curr == new AUDCurrency() ||
                         curr == new HKDCurrency())
                {
                    fixedDayCount = new Actual365Fixed();
                }
                else
                {
                    Utils.QL_FAIL("unknown fixed leg day counter for " + curr);
                }
            }

            double?usedFixedRate = fixedRate_;

            if (fixedRate_ == null)
            {
                VanillaSwap temp = new VanillaSwap(type_, nominal_, fixedSchedule, 0.0, fixedDayCount,
                                                   floatSchedule, iborIndex_, floatSpread_, floatDayCount_);

                if (engine_ == null)
                {
                    Handle <YieldTermStructure> disc = iborIndex_.forwardingTermStructure();
                    Utils.QL_REQUIRE(!disc.empty(), () =>
                                     "null term structure set to this instance of " + iborIndex_.name());
                    bool           includeSettlementDateFlows = false;
                    IPricingEngine engine = new DiscountingSwapEngine(disc, includeSettlementDateFlows);
                    temp.setPricingEngine(engine);
                }
                else
                {
                    temp.setPricingEngine(engine_);
                }

                usedFixedRate = temp.fairRate();
            }

            VanillaSwap swap = new VanillaSwap(type_, nominal_, fixedSchedule, usedFixedRate.Value, fixedDayCount,
                                               floatSchedule, iborIndex_, floatSpread_, floatDayCount_);

            if (engine_ == null)
            {
                Handle <YieldTermStructure> disc          = iborIndex_.forwardingTermStructure();
                bool           includeSettlementDateFlows = false;
                IPricingEngine engine = new DiscountingSwapEngine(disc, includeSettlementDateFlows);
                swap.setPricingEngine(engine);
            }
            else
            {
                swap.setPricingEngine(engine_);
            }

            return(swap);
        }
Example #15
0
        //! Implemented in order to manage the case of par coupon
        public override double indexFixing()
        {
#if QL_USE_INDEXED_COUPON
            return(index_.fixing(fixingDate()));
#else
            if (isInArrears())
            {
                return(index_.fixing(fixingDate()));
            }
            else
            {
                Date today      = Settings.evaluationDate();
                Date fixingDate = this.fixingDate();

                TimeSeries <double> fixings = IndexManager.instance().getHistory(index_.name()).value();
                if (fixings.ContainsKey(fixingDate))
                {
                    return(fixings[fixingDate]);
                }
                else
                {
                    if (fixingDate < today)
                    {
                        // must have been fixed
                        if (IndexManager.MissingPastFixingCallBack == null)
                        {
                            throw new ArgumentException("Missing " + index_.name() + " fixing for " + fixingDate);
                        }
                        else
                        {
                            // try to load missing fixing from external source
                            double fixing = IndexManager.MissingPastFixingCallBack(index_, fixingDate);
                            // add to history
                            index_.addFixing(fixingDate, fixing);
                            return(fixing);
                        }
                    }
                    if (fixingDate == today)
                    {
                        // might have been fixed
                        // fall through and forecast
                    }
                }

                // forecast: 0) forecasting curve
                Handle <YieldTermStructure> termStructure = iborIndex_.forwardingTermStructure();
                if (termStructure.empty())
                {
                    throw new ApplicationException("null term structure set to this instance of " +
                                                   index_.name());
                }
                // forecast: 1) startDiscount
                Date   fixingValueDate = index_.fixingCalendar().advance(fixingDate, index_.fixingDays(), TimeUnit.Days);
                double startDiscount   = termStructure.link.discount(fixingValueDate);
                // forecast: 2) endDiscount
                Date   nextFixingDate      = index_.fixingCalendar().advance(accrualEndDate_, -fixingDays, TimeUnit.Days);
                Date   nextFixingValueDate = index_.fixingCalendar().advance(nextFixingDate, index_.fixingDays(), TimeUnit.Days);
                double endDiscount         = termStructure.link.discount(nextFixingValueDate);
                // forecast: 3) spanningTime
                double spanningTime = index_.dayCounter().yearFraction(fixingValueDate, nextFixingValueDate);
                if (!(spanningTime > 0.0))
                {
                    throw new ApplicationException("cannot calculate forward rate between " +
                                                   fixingValueDate + " and " + nextFixingValueDate +
                                                   ": non positive time using " + index_.dayCounter().name());
                }
                // forecast: 4) implied fixing
                return((startDiscount / endDiscount - 1.0) / spanningTime);
            }
#endif
        }