예제 #1
0
 /*! Forecasting index values requires an inflation term
  *  structure.  The inflation term structure (ITS) defines the
  *  usual lag (not the index).  I.e.  an ITS is always relatve
  *  to a base date that is earlier than its asof date.  This
  *  must be so because indices are available only with a lag.
  *  However, the index availability lag only sets a minimum
  *  lag for the ITS.  An ITS may be relative to an earlier
  *  date, e.g. an index may have a 2-month delay in
  *  publication but the inflation swaps may take as their base
  *  the index 3 months before.
  */
 public override double fixing(Date fixingDate, bool forecastTodaysFixing = false)
 {
     return(0);
 }
예제 #2
0
 public override bool isValidFixingDate(Date fixingDate)
 {
     return(true);
 }
예제 #3
0
        public override List <CashFlow> value()
        {
            Utils.QL_REQUIRE(!notionals_.empty(), () => "no notional given");

            int             n   = schedule_.Count - 1;
            List <CashFlow> leg = new List <CashFlow>(n + 1);

            if (n > 0)
            {
                Utils.QL_REQUIRE(!fixedRates_.empty() || !spreads_.empty(), () => "no fixedRates or spreads given");

                Date refStart, start, refEnd, end;

                for (int i = 0; i < n; ++i)
                {
                    refStart = start = schedule_.date(i);
                    refEnd   = end = schedule_.date(i + 1);
                    Date paymentDate = paymentCalendar_.adjust(end, paymentAdjustment_);

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

                    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 (Utils.Get(fixedRates_, i, 1.0).IsEqual(0.0))
                    {
                        // fixed coupon
                        leg.Add(new FixedRateCoupon(paymentDate, Utils.Get(notionals_, i, 0.0),
                                                    Utils.effectiveFixedRate(spreads_, caps_, floors_, i),
                                                    paymentDayCounter_, start, end, refStart, refEnd, exCouponDate));
                    }
                    else
                    {
                        // zero inflation coupon
                        if (Utils.noOption(caps_, floors_, i))
                        {
                            // just swaplet
                            CPICoupon coup;

                            coup = new CPICoupon(baseCPI_, // all have same base for ratio
                                                 paymentDate,
                                                 Utils.Get(notionals_, i, 0.0),
                                                 start, end,
                                                 Utils.Get(fixingDays_, i, 0),
                                                 index_, observationLag_,
                                                 observationInterpolation_,
                                                 paymentDayCounter_,
                                                 Utils.Get(fixedRates_, i, 0.0),
                                                 Utils.Get(spreads_, i, 0.0),
                                                 refStart, refEnd, exCouponDate);

                            // in this case you can set a pricer
                            // straight away because it only provides computation - not data
                            CPICouponPricer pricer = new CPICouponPricer();
                            coup.setPricer(pricer);
                            leg.Add(coup);
                        }
                        else
                        {
                            // cap/floorlet
                            Utils.QL_FAIL("caps/floors on CPI coupons not implemented.");
                        }
                    }
                }
            }

            // in CPI legs you always have a notional flow of some sort
            Date     pDate      = paymentCalendar_.adjust(schedule_.date(n), paymentAdjustment_);
            Date     fixingDate = pDate - observationLag_;
            CashFlow xnl        = new CPICashFlow
                                      (Utils.Get(notionals_, n, 0.0), index_,
                                      new Date(), // is fake, i.e. you do not have one
                                      baseCPI_, fixingDate, pDate,
                                      subtractInflationNominal_, observationInterpolation_,
                                      index_.frequency());

            leg.Add(xnl);

            return(leg);
        }
예제 #4
0
        // Index interface
        // The forecastTodaysFixing parameter (required by the Index interface) is currently ignored.
        public override double fixing(Date fixingDate, bool forecastTodaysFixing = false)
        {
            Date today                     = Settings.Instance.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())[lim.Key];
                    Utils.QL_REQUIRE(limFirstFix != null, () => "Missing " + name() + " fixing for " + lim.Key);
                    double?limSecondFix =
                        IndexManager.Instance.getHistory(name())[lim.Value + 1];
                    Utils.QL_REQUIRE(limSecondFix != null, () => "Missing " + name() + " fixing for " + lim.Value + 1);
                    double?limBefFirstFix =
                        IndexManager.Instance.getHistory(name())[limBef.Key];
                    Utils.QL_REQUIRE(limBefFirstFix != null, () => "Missing " + name() + " fixing for " + limBef.Key);
                    double?limBefSecondFix =
                        IndexManager.Instance.getHistory(name())[limBef.Value + 1];
                    Utils.QL_REQUIRE(limBefSecondFix != null, () => "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())[fixingDate];
                    Utils.QL_REQUIRE(pastFixing != null, () => "Missing " + name() + " fixing for " + fixingDate);
                    Date   previousDate   = fixingDate - new Period(1, TimeUnit.Years);
                    double?previousFixing = IndexManager.Instance.getHistory(name())[previousDate];
                    Utils.QL_REQUIRE(previousFixing != null, () => "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())[lim.Key];
                    Utils.QL_REQUIRE(limFirstFix != null, () => "Missing " + name() + " fixing for " + lim.Key);
                    double?limSecondFix = IndexManager.Instance.getHistory(name())[lim.Value + 1];
                    Utils.QL_REQUIRE(limSecondFix != null, () => "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())[fixingDate];
                    Utils.QL_REQUIRE(pastFixing != null, () => "Missing " + name() + " fixing for " + fixingDate);
                    return(pastFixing.Value);
                }
            }
        }
예제 #5
0
 //! utility method, calls indexFixing
 public double indexObservation(Date onDate)
 {
     return(indexFixing(onDate));
 }