Пример #1
0
        public override double swapletRate()
        {
            OvernightIndex index = coupon_.index() as OvernightIndex;

            List <Date>   fixingDates = coupon_.fixingDates();
            List <double> dt          = coupon_.dt();

            int n = dt.Count;
            int i = 0;

            double compoundFactor = 1.0;

            // already fixed part
            Date today = Settings.evaluationDate();

            while (fixingDates[i] < today && i < n)
            {
                // rate must have been fixed
                double?pastFixing = IndexManager.instance().getHistory(index.name()).value()[fixingDates[i]];

                Utils.QL_REQUIRE(pastFixing != null, () => "Missing " + index.name() + " fixing for " + fixingDates[i].ToString());

                compoundFactor *= (1.0 + pastFixing.GetValueOrDefault() * dt[i]);
                ++i;
            }

            // today is a border case
            if (fixingDates[i] == today && i < n)
            {
                // might have been fixed
                try
                {
                    double?pastFixing = IndexManager.instance().getHistory(index.name()).value()[fixingDates[i]];

                    if (pastFixing != null)
                    {
                        compoundFactor *= (1.0 + pastFixing.GetValueOrDefault() * dt[i]);
                        ++i;
                    }
                    else
                    {
                        // fall through and forecast
                    }
                }
                catch (Exception)
                {
                    // fall through and forecast
                }
            }

            // forward part using telescopic property in order
            // to avoid the evaluation of multiple forward fixings
            if (i < n)
            {
                Handle <YieldTermStructure> curve = index.forwardingTermStructure();
                Utils.QL_REQUIRE(!curve.empty(), () => "null term structure set to this instance of" + index.name());

                List <Date> dates         = coupon_.valueDates();
                double      startDiscount = curve.link.discount(dates[i]);
                double      endDiscount   = curve.link.discount(dates[n]);

                compoundFactor *= startDiscount / endDiscount;
            }

            double rate = (compoundFactor - 1.0) / coupon_.accrualPeriod();

            return(coupon_.gearing() * rate + coupon_.spread());
        }
Пример #2
0
        public override double fixing(Date fixingDate, bool forecastTodaysFixing)
        {
            Date today                     = Settings.evaluationDate();
            Date todayMinusLag             = today - availabilityLag_;
            KeyValuePair <Date, Date> limm = Utils.inflationPeriod(todayMinusLag, frequency_);
            Date lastFix                   = limm.Key - 1;

            Date flatMustForecastOn   = lastFix + 1;
            Date interpMustForecastOn = lastFix + 1 - new Period(frequency_);


            if (interpolated() && fixingDate >= interpMustForecastOn)
            {
                return(forecastFixing(fixingDate));
            }

            if (!interpolated() && fixingDate >= flatMustForecastOn)
            {
                return(forecastFixing(fixingDate));
            }

            // four cases with ratio() and interpolated()
            if (ratio())
            {
                if (interpolated())
                {
                    // IS ratio, IS interpolated
                    KeyValuePair <Date, Date> lim = Utils.inflationPeriod(fixingDate, frequency_);
                    Date fixMinus1Y = new NullCalendar().advance(fixingDate, new Period(-1, TimeUnit.Years), BusinessDayConvention.ModifiedFollowing);
                    KeyValuePair <Date, Date> limBef = Utils.inflationPeriod(fixMinus1Y, frequency_);
                    double dp    = lim.Value + 1 - lim.Key;
                    double dpBef = limBef.Value + 1 - limBef.Key;
                    double dl    = fixingDate - lim.Key;
                    // potentially does not work on 29th Feb
                    double dlBef = fixMinus1Y - limBef.Key;
                    // get the four relevant fixings
                    // recall that they are stored flat for every day
                    double?limFirstFix =
                        IndexManager.instance().getHistory(name()).value()[lim.Key];
                    if (limFirstFix == null)
                    {
                        throw new ApplicationException("Missing " + name() + " fixing for "
                                                       + lim.Key);
                    }
                    double?limSecondFix =
                        IndexManager.instance().getHistory(name()).value()[lim.Value + 1];
                    if (limSecondFix == null)
                    {
                        throw new ApplicationException("Missing " + name() + " fixing for "
                                                       + lim.Value + 1);
                    }
                    double?limBefFirstFix =
                        IndexManager.instance().getHistory(name()).value()[limBef.Key];
                    if (limBefFirstFix == null)
                    {
                        throw new ApplicationException("Missing " + name() + " fixing for "
                                                       + limBef.Key);
                    }
                    double?limBefSecondFix =
                        IndexManager.instance().getHistory(name()).value()[limBef.Value + 1];
                    if (limBefSecondFix == null)
                    {
                        throw new ApplicationException("Missing " + name() + " fixing for "
                                                       + limBef.Value + 1);
                    }

                    double linearNow = limFirstFix.Value + (limSecondFix.Value - limFirstFix.Value) * dl / dp;
                    double linearBef = limBefFirstFix.Value + (limBefSecondFix.Value - limBefFirstFix.Value) * dlBef / dpBef;
                    double wasYES    = linearNow / linearBef - 1.0;

                    return(wasYES);
                }
                else
                {
                    // IS ratio, NOT interpolated
                    double?pastFixing =
                        IndexManager.instance().getHistory(name()).value()[fixingDate];
                    if (pastFixing == null)
                    {
                        throw new ApplicationException("Missing " + name() + " fixing for "
                                                       + fixingDate);
                    }
                    Date   previousDate   = fixingDate - new Period(1, TimeUnit.Years);
                    double?previousFixing =
                        IndexManager.instance().getHistory(name()).value()[previousDate];
                    if (previousFixing == null)
                    {
                        throw new ApplicationException("Missing " + name() + " fixing for "
                                                       + previousDate);
                    }

                    return(pastFixing.Value / previousFixing.Value - 1.0);
                }
            }
            else
            {
                // NOT ratio
                if (interpolated())
                {
                    // NOT ratio, IS interpolated
                    KeyValuePair <Date, Date> lim = Utils.inflationPeriod(fixingDate, frequency_);
                    double dp          = lim.Value + 1 - lim.Key;
                    double dl          = fixingDate - lim.Key;
                    double?limFirstFix =
                        IndexManager.instance().getHistory(name()).value()[lim.Key];
                    if (limFirstFix == null)
                    {
                        throw new ApplicationException("Missing " + name() + " fixing for "
                                                       + lim.Key);
                    }
                    double?limSecondFix =
                        IndexManager.instance().getHistory(name()).value()[lim.Value + 1];
                    if (limSecondFix == null)
                    {
                        throw new ApplicationException("Missing " + name() + " fixing for "
                                                       + lim.Value + 1);
                    }
                    double linearNow = limFirstFix.Value + (limSecondFix.Value - limFirstFix.Value) * dl / dp;

                    return(linearNow);
                }
                else
                {
                    // NOT ratio, NOT interpolated
                    // so just flat
                    double?pastFixing =
                        IndexManager.instance().getHistory(name()).value()[fixingDate];
                    if (pastFixing == null)
                    {
                        throw new ApplicationException("Missing " + name() + " fixing for "
                                                       + fixingDate);
                    }
                    return(pastFixing.Value);
                }
            }

            // QL_FAIL("YoYInflationIndex::fixing, should never get here");
        }
Пример #3
0
 //! clears all stored historical fixings
 public void clearFixings()
 {
     IndexManager.instance().clearHistory(name());
 }
Пример #4
0
 //! returns the fixing TimeSeries
 public ObservableValue <TimeSeries <double> > timeSeries()
 {
     return(IndexManager.instance().getHistory(name()));
 }
Пример #5
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
        }
Пример #6
0
 // Clears all stored historical fixings
 public void clearFixings()
 {
     checkNativeFixingsAllowed();
     IndexManager.instance().clearHistory(name());
 }
Пример #7
0
 // Returns the fixing TimeSeries
 public TimeSeries <double?> timeSeries()
 {
     return(IndexManager.instance().getHistory(name()));
 }