compounding() публичный Метод

public compounding ( ) : Compounding
Результат Compounding
        public static double modifiedDuration(List <CashFlow> cashflows, InterestRate y, Date settlementDate)
        {
            if (cashflows.Count == 0)
            {
                return(0.0);
            }

            double     P    = 0.0;
            double     dPdy = 0.0;
            double     r    = y.rate();
            int        N    = (int)y.frequency();
            DayCounter dc   = y.dayCounter();

            foreach (CashFlow cf in cashflows.Where(cf => !cf.hasOccurred(settlementDate)))
            {
                double t = dc.yearFraction(settlementDate, cf.date());
                double c = cf.amount();
                double B = y.discountFactor(t);

                P += c * B;

                switch (y.compounding())
                {
                case Compounding.Simple:
                    dPdy -= c * B * B * t;
                    break;

                case Compounding.Compounded:
                    dPdy -= c * t * B / (1 + r / N);
                    break;

                case Compounding.Continuous:
                    dPdy -= c * B * t;
                    break;

                case Compounding.SimpleThenCompounded:
                    if (t <= 1.0 / N)
                    {
                        dPdy -= c * B * B * t;
                    }
                    else
                    {
                        dPdy -= c * t * B / (1 + r / N);
                    }
                    break;

                default:
                    throw new ArgumentException("unknown compounding convention (" + y.compounding() + ")");
                }
            }

            if (P == 0.0) // no cashflows
            {
                return(0.0);
            }

            return(-dPdy / P); // reverse derivative sign
        }
 public static double macaulayDuration(List <CashFlow> cashflows, InterestRate y, Date settlementDate)
 {
     if (y.compounding() != Compounding.Compounded)
     {
         throw new ArgumentException("compounded rate required");
     }
     return((1.0 + y.rate() / (int)y.frequency()) * modifiedDuration(cashflows, y, settlementDate));
 }
Пример #3
0
        public static double macaulayDuration(Leg leg, InterestRate y, bool includeSettlementDateFlows,
                                              Date settlementDate, Date npvDate)
        {
            Utils.QL_REQUIRE(y.compounding() == Compounding.Compounded, () => "compounded rate required");

            return((1.0 + y.rate() / (int)y.frequency()) *
                   modifiedDuration(leg, y, includeSettlementDateFlows, settlementDate, npvDate));
        }
        protected override double zeroYieldImpl(double t)
        {
            // to be fixed: user-defined daycounter should be used
            InterestRate zeroRate     = originalCurve_.link.zeroRate(t, comp_, freq_, true);
            InterestRate spreadedRate = new InterestRate(zeroRate.value() + spread_.value(), zeroRate.dayCounter(),
                                                         zeroRate.compounding(), zeroRate.frequency());

            return(spreadedRate.equivalentRate(t, Compounding.Continuous, Frequency.NoFrequency).value());
        }
Пример #5
0
        protected override double zeroYieldImpl(double t)
        {
            double       spread       = calcSpread(t);
            InterestRate zeroRate     = originalCurve_.link.zeroRate(t, compounding_, frequency_, true);
            InterestRate spreadedRate = new InterestRate(zeroRate.value() + spread,
                                                         zeroRate.dayCounter(),
                                                         zeroRate.compounding(),
                                                         zeroRate.frequency());

            return(spreadedRate.equivalentRate(Compounding.Continuous, Frequency.NoFrequency, t).value());
        }
Пример #6
0
        //! Basis-point sensitivity of the cash flows.
        // The result is the change in NPV due to a uniform
        // 1-basis-point change in the rate paid by the cash
        // flows. The change for each coupon is discounted according
        // to the given constant interest rate.  The result is
        // affected by the choice of the interest-rate compounding
        // and the relative frequency and day counter.

        public static double bps(Leg leg, InterestRate yield, bool includeSettlementDateFlows,
                                 Date settlementDate = null, Date npvDate = null)
        {
            if (leg.empty())
            {
                return(0.0);
            }

            if (settlementDate == null)
            {
                settlementDate = Settings.evaluationDate();
            }

            if (npvDate == null)
            {
                npvDate = settlementDate;
            }

            FlatForward flatRate = new FlatForward(settlementDate, yield.rate(), yield.dayCounter(),
                                                   yield.compounding(), yield.frequency());

            return(bps(leg, flatRate, includeSettlementDateFlows, settlementDate, npvDate));
        }
Пример #7
0
        public void testBrazilianCached()
        {
            //("Testing Brazilian public bond prices against cached values...");

             CommonVars vars = new CommonVars();

             double faceAmount = 1000.0;
             double redemption = 100.0;
             Date issueDate = new Date(1, Month.January, 2007);

             Date today = new Date(6, Month.June, 2007);
             Settings.setEvaluationDate(today);

             // NTN-F maturity dates
             InitializedList<Date> maturityDates = new InitializedList<Date>(6);
             maturityDates[0] = new Date(1, Month.January, 2008);
             maturityDates[1] = new Date(1, Month.January, 2010);
             maturityDates[2] = new Date(1, Month.July, 2010);
             maturityDates[3] = new Date(1, Month.January, 2012);
             maturityDates[4] = new Date(1, Month.January, 2014);
             maturityDates[5] = new Date(1, Month.January, 2017);

             // NTN-F yields
             InitializedList<double> yields = new InitializedList<double>(6);
             yields[0] = 0.114614;
             yields[1] = 0.105726;
             yields[2] = 0.105328;
             yields[3] = 0.104283;
             yields[4] = 0.103218;
             yields[5] = 0.102948;

             // NTN-F prices
             InitializedList<double> prices = new InitializedList<double>(6);
             prices[0] = 1034.63031372;
             prices[1] = 1030.09919487;
             prices[2] = 1029.98307160;
             prices[3] = 1028.13585068;
             prices[4] = 1028.33383817;
             prices[5] = 1026.19716497;

             int settlementDays = 1;
             vars.faceAmount = 1000.0;

             // The tolerance is high because Andima truncate yields
             double tolerance = 1.0e-4;

             InitializedList<InterestRate> couponRates = new InitializedList<InterestRate>(1);
             couponRates[0] = new InterestRate(0.1, new Thirty360(), Compounding.Compounded, Frequency.Annual);

             for (int bondIndex = 0; bondIndex < maturityDates.Count; bondIndex++)
             {

            // plain
            InterestRate yield = new InterestRate(yields[bondIndex], new Business252(new Brazil()),
                                                  Compounding.Compounded, Frequency.Annual);

            Schedule schedule = new Schedule(new Date(1, Month.January, 2007),
                              maturityDates[bondIndex], new Period(Frequency.Semiannual),
                              new Brazil(Brazil.Market.Settlement),
                              BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                              DateGeneration.Rule.Backward, false);

            FixedRateBond bond = new FixedRateBond(settlementDays,
                                                   faceAmount,
                                                   schedule,
                                                   couponRates,
                                                   BusinessDayConvention.Following,
                                                   redemption,
                                                   issueDate);

            double cachedPrice = prices[bondIndex];

            double price = vars.faceAmount * (bond.cleanPrice(yield.rate(),
                                                         yield.dayCounter(),
                                                         yield.compounding(),
                                                         yield.frequency(),
                                                         today) + bond.accruedAmount(today)) / 100;
            if (Math.Abs(price - cachedPrice) > tolerance)
            {
               Assert.Fail("failed to reproduce cached price:\n"
                           + "    calculated: " + price + "\n"
                           + "    expected:   " + cachedPrice + "\n"
                           + "    error:      " + (price - cachedPrice) + "\n"
                           );
            }
             }
        }
Пример #8
0
        // creator
        public override List <CashFlow> value()
        {
            if (couponRates_.Count == 0)
            {
                throw new ArgumentException("no coupon rates given");
            }
            if (notionals_.Count == 0)
            {
                throw new ArgumentException("no nominals given");
            }

            List <CashFlow> leg = new List <CashFlow>();

            Calendar schCalendar = schedule_.calendar();

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

            if (exCouponPeriod_ != null)
            {
                exCouponDate = exCouponCalendar_.advance(paymentDate,
                                                         -exCouponPeriod_,
                                                         exCouponAdjustment_,
                                                         exCouponEndOfMonth_);
            }
            if (schedule_.isRegular(1))
            {
                if (!(firstPeriodDC_ == null || firstPeriodDC_ == rate.dayCounter()))
                {
                    throw new ArgumentException("regular first coupon does not allow a first-period day count");
                }
                leg.Add(new FixedRateCoupon(nominal, paymentDate, rate, start, end, start, end, exCouponDate));
            }
            else
            {
                Date refer = end - schedule_.tenor();
                refer = schCalendar.adjust(refer, schedule_.businessDayConvention());
                InterestRate r = new InterestRate(rate.rate(),
                                                  (firstPeriodDC_ == null || firstPeriodDC_.empty()) ? rate.dayCounter() : firstPeriodDC_,
                                                  rate.compounding(), rate.frequency());
                leg.Add(new FixedRateCoupon(nominal, paymentDate, r, start, end, refer, end, exCouponDate));
            }

            // regular periods
            for (int i = 2; i < schedule_.Count - 1; ++i)
            {
                start       = end; end = schedule_[i];
                paymentDate = calendar_.adjust(end, paymentAdjustment_);
                if (exCouponPeriod_ != null)
                {
                    exCouponDate = exCouponCalendar_.advance(paymentDate,
                                                             -exCouponPeriod_,
                                                             exCouponAdjustment_,
                                                             exCouponEndOfMonth_);
                }
                if ((i - 1) < couponRates_.Count)
                {
                    rate = couponRates_[i - 1];
                }
                else
                {
                    rate = couponRates_.Last();
                }
                if ((i - 1) < notionals_.Count)
                {
                    nominal = notionals_[i - 1];
                }
                else
                {
                    nominal = notionals_.Last();
                }

                leg.Add(new FixedRateCoupon(nominal, paymentDate, rate, start, end, start, end, exCouponDate));
            }

            if (schedule_.Count > 2)
            {
                // last period might be short or long
                int N = schedule_.Count;
                start       = end; end = schedule_[N - 1];
                paymentDate = calendar_.adjust(end, paymentAdjustment_);
                if (exCouponPeriod_ != null)
                {
                    exCouponDate = exCouponCalendar_.advance(paymentDate,
                                                             -exCouponPeriod_,
                                                             exCouponAdjustment_,
                                                             exCouponEndOfMonth_);
                }

                if ((N - 2) < couponRates_.Count)
                {
                    rate = couponRates_[N - 2];
                }
                else
                {
                    rate = couponRates_.Last();
                }
                if ((N - 2) < notionals_.Count)
                {
                    nominal = notionals_[N - 2];
                }
                else
                {
                    nominal = notionals_.Last();
                }

                if (schedule_.isRegular(N - 1))
                {
                    leg.Add(new FixedRateCoupon(nominal, paymentDate, rate, start, end, start, end, exCouponDate));
                }
                else
                {
                    Date refer = start + schedule_.tenor();
                    refer = schCalendar.adjust(refer, schedule_.businessDayConvention());
                    leg.Add(new FixedRateCoupon(nominal, paymentDate, rate, start, end, start, refer, exCouponDate));
                }
            }
            return(leg);
        }
Пример #9
0
      public static double macaulayDuration(Leg leg,InterestRate y, bool includeSettlementDateFlows,
                                            Date settlementDate, Date npvDate) 
      {
         Utils.QL_REQUIRE( y.compounding() == Compounding.Compounded, () => "compounded rate required" );

         return (1.0+y.rate()/(int)y.frequency()) *
               modifiedDuration(leg, y, includeSettlementDateFlows, settlementDate, npvDate);
      }
      public void testConversions()
      {
         InterestRateData[] cases = {
         // data from "Option Pricing Formulas", Haug, pag.181-182
         // Rate,Compounding,        Frequency,   Time, Compounding2,      Frequency2,  Rate2, precision
         new InterestRateData(0.0800, Compounding.Compounded, Frequency.Quarterly, 1.00, Compounding.Continuous, Frequency.Annual,     0.0792, 4),
         new InterestRateData(0.1200, Compounding.Continuous, Frequency.Annual,    1.00, Compounding.Compounded, Frequency.Annual,     0.1275, 4),
         new InterestRateData(0.0800, Compounding.Compounded, Frequency.Quarterly, 1.00, Compounding.Compounded, Frequency.Annual,     0.0824, 4),
         new InterestRateData(0.0700, Compounding.Compounded, Frequency.Quarterly, 1.00, Compounding.Compounded, Frequency.Semiannual, 0.0706, 4),
         // undocumented, but reasonable :)
         new InterestRateData(0.0100, Compounding.Compounded, Frequency.Annual,            1.00,   Compounding.Simple,     Frequency.Annual,           0.0100, 4),
         new InterestRateData(0.0200, Compounding.Simple,     Frequency.Annual,            1.00,   Compounding.Compounded, Frequency.Annual,           0.0200, 4),
         new InterestRateData(0.0300, Compounding.Compounded, Frequency.Semiannual,        0.50,   Compounding.Simple,     Frequency.Annual,           0.0300, 4),
         new InterestRateData(0.0400, Compounding.Simple,     Frequency.Annual,            0.50,   Compounding.Compounded, Frequency.Semiannual,       0.0400, 4),
         new InterestRateData(0.0500, Compounding.Compounded, Frequency.EveryFourthMonth,  1.0/3,  Compounding.Simple,     Frequency.Annual,           0.0500, 4),
         new InterestRateData(0.0600, Compounding.Simple,     Frequency.Annual,            1.0/3,  Compounding.Compounded, Frequency.EveryFourthMonth, 0.0600, 4),
         new InterestRateData(0.0500, Compounding.Compounded, Frequency.Quarterly,         0.25,   Compounding.Simple,     Frequency.Annual,           0.0500, 4),
         new InterestRateData(0.0600, Compounding.Simple,     Frequency.Annual,            0.25,   Compounding.Compounded, Frequency.Quarterly,        0.0600, 4),
         new InterestRateData(0.0700, Compounding.Compounded, Frequency.Bimonthly,         1.0/6,  Compounding.Simple,     Frequency.Annual,           0.0700, 4),
         new InterestRateData(0.0800, Compounding.Simple,     Frequency.Annual,            1.0/6,  Compounding.Compounded, Frequency.Bimonthly,        0.0800, 4),
         new InterestRateData(0.0900, Compounding.Compounded, Frequency.Monthly,           1.0/12, Compounding.Simple,     Frequency.Annual,           0.0900, 4),
         new InterestRateData(0.1000, Compounding.Simple,     Frequency.Annual,            1.0/12, Compounding.Compounded, Frequency.Monthly,          0.1000, 4),

         new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.25, Compounding.Simple,     Frequency.Annual,     0.0300, 4),
         new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.25, Compounding.Simple,     Frequency.Semiannual, 0.0300, 4),
         new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.25, Compounding.Simple,     Frequency.Quarterly,  0.0300, 4),
         new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.50, Compounding.Simple,     Frequency.Annual,     0.0300, 4),
         new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.50, Compounding.Simple,     Frequency.Semiannual, 0.0300, 4),
         new InterestRateData(0.0300, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.75, Compounding.Compounded, Frequency.Semiannual, 0.0300, 4),

         new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.25, Compounding.SimpleThenCompounded, Frequency.Quarterly,  0.0400, 4),
         new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.25, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.0400, 4),
         new InterestRateData(0.0400, Compounding.Simple, Frequency.Semiannual, 0.25, Compounding.SimpleThenCompounded, Frequency.Annual,     0.0400, 4),

         new InterestRateData(0.0400, Compounding.Compounded, Frequency.Quarterly,  0.50, Compounding.SimpleThenCompounded, Frequency.Quarterly,  0.0400, 4),
         new InterestRateData(0.0400, Compounding.Simple,     Frequency.Semiannual, 0.50, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.0400, 4),
         new InterestRateData(0.0400, Compounding.Simple,     Frequency.Semiannual, 0.50, Compounding.SimpleThenCompounded, Frequency.Annual,     0.0400, 4),

         new InterestRateData(0.0400, Compounding.Compounded, Frequency.Quarterly,  0.75, Compounding.SimpleThenCompounded, Frequency.Quarterly,  0.0400, 4),
         new InterestRateData(0.0400, Compounding.Compounded, Frequency.Semiannual, 0.75, Compounding.SimpleThenCompounded, Frequency.Semiannual, 0.0400, 4),
         new InterestRateData(0.0400, Compounding.Simple,     Frequency.Semiannual, 0.75, Compounding.SimpleThenCompounded, Frequency.Annual,     0.0400, 4)
         };

         Rounding roundingPrecision;
         double r3;
         double r2;
         Date d1 = Date.Today;
         Date d2;
         InterestRate ir;
         InterestRate ir2;
         InterestRate ir3;
         InterestRate expectedIR;
         double compoundf;
         double error;
         double disc;

         for (int i = 0; i < cases.Length-1 ; i++)
         {
            ir = new InterestRate(cases[i].r, new Actual360(), cases[i].comp, cases[i].freq);
            d2 = d1 + new Period((int)(360 * cases[i].t + 0.5) ,TimeUnit.Days);
            roundingPrecision = new Rounding(cases[i].precision);

            // check that the compound factor is the inverse of the discount factor
            compoundf = ir.compoundFactor(d1, d2);
            disc = ir.discountFactor(d1, d2);
            error = Math.Abs(disc - 1.0 / compoundf);
            if (error > 1e-15)
               Assert.Fail(ir + "  1.0/compound_factor: " + 1.0 / compoundf);

            // check that the equivalent InterestRate with *same* daycounter,
            // compounding, and frequency is the *same* InterestRate
            ir2 = ir.equivalentRate(d1, d2, ir.dayCounter(), ir.compounding(), ir.frequency());
            error = Math.Abs(ir.rate() - ir2.rate());
            if (error > 1e-15)
               Assert.Fail("original interest rate: " + ir + " equivalent interest rate: " + ir2 + " rate error: " + error);
            if (ir.dayCounter() != ir2.dayCounter())
               Assert.Fail("day counter error original interest rate: " + ir + " equivalent interest rate: " + ir2);
            if (ir.compounding() != ir2.compounding())
               Assert.Fail("compounding error original interest rate: " + ir + " equivalent interest rate: " + ir2);
            if (ir.frequency() != ir2.frequency())
               Assert.Fail("frequency error original interest rate: " + ir + " equivalent interest rate: " + ir2);

            // check that the equivalent rate with *same* daycounter,
            // compounding, and frequency is the *same* rate
            r2 = ir.equivalentRate(d1, d2, ir.dayCounter(), ir.compounding(), ir.frequency()).rate();
            error = Math.Abs(ir.rate() - r2);
            if (error > 1e-15)
               Assert.Fail("original rate: " + ir + " equivalent rate: " + r2 + " error: " + error);

            // check that the equivalent InterestRate with *different*
            // compounding, and frequency is the *expected* InterestRate
            ir3 = ir.equivalentRate(d1, d2, ir.dayCounter(), cases[i].comp2, cases[i].freq2);
            expectedIR = new InterestRate(cases[i].expected, ir.dayCounter(), cases[i].comp2, cases[i].freq2);
            r3 = roundingPrecision.Round(ir3.rate());
            error = Math.Abs(r3 - expectedIR.rate());
            if (error > 1.0e-17)
               Assert.Fail("original interest rate: " + ir + " calculated equivalent interest rate: " + ir3 + " truncated equivalent rate: " + r3 + " expected equivalent interest rate: " + expectedIR + " rate error: " + error);
            if (ir3.dayCounter() != expectedIR.dayCounter())
               Assert.Fail("day counter error original interest rate: " + ir3 + " equivalent interest rate: " + expectedIR);
            if (ir3.compounding() != expectedIR.compounding())
               Assert.Fail("compounding error original interest rate: " + ir3 + " equivalent interest rate: " + expectedIR);
            if (ir3.frequency() != expectedIR.frequency())
               Assert.Fail("frequency error original interest rate: " + ir3 + " equivalent interest rate: " + expectedIR);

            // check that the equivalent rate with *different*
            // compounding, and frequency is the *expected* rate
            r3 = ir.equivalentRate(d1, d2, ir.dayCounter(), cases[i].comp2, cases[i].freq2).rate();
            r3 = roundingPrecision.Round(r3);
            error = Math.Abs(r3 - cases[i].expected);
            if (error > 1.0e-17)
               Assert.Fail("calculated equivalent rate: " + r3 + " expected equivalent rate: " + cases[i].expected + " error: " + error);

         }

      }
      public static double modifiedDuration(List<CashFlow> cashflows, InterestRate y, Date settlementDate) 
      {
         if (cashflows.Count == 0)
            return 0.0;

         double P = 0.0;
         double dPdy = 0.0;
         double r = y.rate();
         int N = (int)y.frequency();
         DayCounter dc = y.dayCounter();

         foreach (CashFlow cf in cashflows.Where(cf => !cf.hasOccurred(settlementDate))) 
         {

            double t = dc.yearFraction(settlementDate, cf.date());
            double c = cf.amount();
            double B = y.discountFactor(t);

            P += c * B;

            switch (y.compounding()) 
            {
               case Compounding.Simple:
                  dPdy -= c * B * B * t;
                  break;
                  
               case Compounding.Compounded:
                  dPdy -= c * t * B / (1 + r / N);
                  break;
                  
               case Compounding.Continuous:
                  dPdy -= c * B * t;
                  break;
                  
               case Compounding.SimpleThenCompounded:
                  if (t <= 1.0 / N)
                     dPdy -= c * B * B * t;
                  else
                     dPdy -= c * t * B / (1 + r / N);
                     break;
                    
               default:
                  throw new ArgumentException("unknown compounding convention (" + y.compounding() + ")");
            }
         }
         
         if (P == 0.0) // no cashflows
            return 0.0;
            
         return -dPdy / P; // reverse derivative sign
      }
      //! Cash-flow convexity
      /*! The convexity of a string of cash flows is defined as
	            \f[
	            C = \frac{1}{P} \frac{\partial^2 P}{\partial y^2}
	            \f]
	            where \f$ P \f$ is the present value of the cash flows according to the given IRR \f$ y \f$.
	        */
      public static double convexity(List<CashFlow> cashflows, InterestRate rate, Date settlementDate = null) 
        {
           if (cashflows.Count == 0)
              return 0.0;

           if (settlementDate == null) settlementDate = Settings.evaluationDate();

           DayCounter dayCounter = rate.dayCounter();

           double P = 0;
           double d2Pdy2 = 0;
           double y = rate.rate();
           int N = (int)rate.frequency();

           
           foreach (CashFlow cashflow in cashflows.Where(cashflow => !cashflow.hasOccurred(settlementDate))) 
           {
              double t = dayCounter.yearFraction(settlementDate, cashflow.date());
              double c = cashflow.amount();
              double B = rate.discountFactor(t);

              P += c * B;

              switch (rate.compounding()) 
              {
                 case Compounding.Simple:
                    d2Pdy2 += c * 2.0 * B * B * B * t * t;
                    break;
                    
                 case Compounding.Compounded:
                    d2Pdy2 += c * B * t * (N * t + 1) / (N * (1 + y / N) * (1 + y / N));
                    break;
                    
                 case Compounding.Continuous:
                    d2Pdy2 += c * B * t * t;
                    break;
                    
                 case Compounding.SimpleThenCompounded:
                    if (t <= 1.0 / N)
                       d2Pdy2 += c * 2.0 * B * B * B * t * t;
                    else
                       d2Pdy2 += c * B * t * (N * t + 1) / (N * (1 + y / N) * (1 + y / N));
                    break;
                    
                 default:
                    throw new ArgumentException("unknown compounding convention (" + rate.compounding() + ")");
              }
           }

           // no cashflows
           
           if (P == 0) return 0;
           return d2Pdy2 / P;
        }
 // Basis-point sensitivity of the cash flows.
   // The result is the change in NPV due to a uniform 1-basis-point change in the rate paid by the cash flows. The change for each coupon is discounted according
   //  to the given constant interest rate.  The result is affected by the choice of the interest-rate compounding and the relative frequency and day counter.
 public static double bps(List<CashFlow> cashflows, InterestRate irr, Date settlementDate = null) {
       if (settlementDate == null)
           settlementDate = Settings.evaluationDate();
       var flatRate = new FlatForward(settlementDate, irr.rate(), irr.dayCounter(), irr.compounding(), irr.frequency());
       return bps(cashflows, flatRate, settlementDate, settlementDate);
   }
 public static double macaulayDuration(List<CashFlow> cashflows, InterestRate y, Date settlementDate) 
 {
    if (y.compounding() != Compounding.Compounded) throw new ArgumentException("compounded rate required");
    return (1.0 + y.rate() / (int)y.frequency()) * modifiedDuration(cashflows, y, settlementDate);
 }
        // Basis-point sensitivity of the cash flows.
        // The result is the change in NPV due to a uniform 1-basis-point change in the rate paid by the cash flows. The change for each coupon is discounted according
        //  to the given constant interest rate.  The result is affected by the choice of the interest-rate compounding and the relative frequency and day counter.
        public static double bps(List <CashFlow> cashflows, InterestRate irr, Date settlementDate = null)
        {
            if (settlementDate == null)
            {
                settlementDate = Settings.evaluationDate();
            }
            var flatRate = new FlatForward(settlementDate, irr.rate(), irr.dayCounter(), irr.compounding(), irr.frequency());

            return(bps(cashflows, flatRate, settlementDate, settlementDate));
        }
        //! Cash-flow convexity

        /*! The convexity of a string of cash flows is defined as
         *            \f[
         *            C = \frac{1}{P} \frac{\partial^2 P}{\partial y^2}
         *            \f]
         *            where \f$ P \f$ is the present value of the cash flows according to the given IRR \f$ y \f$.
         */
        public static double convexity(List <CashFlow> cashflows, InterestRate rate, Date settlementDate = null)
        {
            if (cashflows.Count == 0)
            {
                return(0.0);
            }

            if (settlementDate == null)
            {
                settlementDate = Settings.evaluationDate();
            }

            DayCounter dayCounter = rate.dayCounter();

            double P      = 0;
            double d2Pdy2 = 0;
            double y      = rate.rate();
            int    N      = (int)rate.frequency();


            foreach (CashFlow cashflow in cashflows.Where(cashflow => !cashflow.hasOccurred(settlementDate)))
            {
                double t = dayCounter.yearFraction(settlementDate, cashflow.date());
                double c = cashflow.amount();
                double B = rate.discountFactor(t);

                P += c * B;

                switch (rate.compounding())
                {
                case Compounding.Simple:
                    d2Pdy2 += c * 2.0 * B * B * B * t * t;
                    break;

                case Compounding.Compounded:
                    d2Pdy2 += c * B * t * (N * t + 1) / (N * (1 + y / N) * (1 + y / N));
                    break;

                case Compounding.Continuous:
                    d2Pdy2 += c * B * t * t;
                    break;

                case Compounding.SimpleThenCompounded:
                    if (t <= 1.0 / N)
                    {
                        d2Pdy2 += c * 2.0 * B * B * B * t * t;
                    }
                    else
                    {
                        d2Pdy2 += c * B * t * (N * t + 1) / (N * (1 + y / N) * (1 + y / N));
                    }
                    break;

                default:
                    throw new ArgumentException("unknown compounding convention (" + rate.compounding() + ")");
                }
            }

            // no cashflows

            if (P == 0)
            {
                return(0);
            }
            return(d2Pdy2 / P);
        }
Пример #17
0
        //! Cash-flow convexity
        public static double convexity(Leg leg, InterestRate yield, bool includeSettlementDateFlows,
                                       Date settlementDate = null, Date npvDate = null)
        {
            if (leg.empty())
            {
                return(0.0);
            }

            if (settlementDate == null)
            {
                settlementDate = Settings.evaluationDate();
            }

            if (npvDate == null)
            {
                npvDate = settlementDate;
            }

            DayCounter dc = yield.dayCounter();

            double P        = 0.0;
            double t        = 0.0;
            double d2Pdy2   = 0.0;
            double r        = yield.rate();
            int    N        = (int)yield.frequency();
            Date   lastDate = npvDate;


            for (int i = 0; i < leg.Count; ++i)
            {
                if (leg[i].hasOccurred(settlementDate, includeSettlementDateFlows))
                {
                    continue;
                }

                double c = leg[i].amount();
                if (leg[i].tradingExCoupon(settlementDate))
                {
                    c = 0.0;
                }

                t += getStepwiseDiscountTime(leg[i], dc, npvDate, lastDate);

                double B = yield.discountFactor(t);
                P += c * B;
                switch (yield.compounding())
                {
                case  Compounding.Simple:
                    d2Pdy2 += c * 2.0 * B * B * B * t * t;
                    break;

                case Compounding.Compounded:
                    d2Pdy2 += c * B * t * (N * t + 1) / (N * (1 + r / N) * (1 + r / N));
                    break;

                case Compounding.Continuous:
                    d2Pdy2 += c * B * t * t;
                    break;

                case Compounding.SimpleThenCompounded:
                    if (t <= 1.0 / N)
                    {
                        d2Pdy2 += c * 2.0 * B * B * B * t * t;
                    }
                    else
                    {
                        d2Pdy2 += c * B * t * (N * t + 1) / (N * (1 + r / N) * (1 + r / N));
                    }
                    break;

                default:
                    Utils.QL_FAIL("unknown compounding convention (" + yield.compounding() + ")");
                    break;
                }
                lastDate = leg[i].date();
            }

            if (P.IsEqual(0.0))
            {
                // no cashflows
                return(0.0);
            }

            return(d2Pdy2 / P);
        }
Пример #18
0
      public static double modifiedDuration(Leg leg,InterestRate y, bool includeSettlementDateFlows,
                                            Date settlementDate,Date npvDate) 
      {
         if (leg.empty())
            return 0.0;

         if (settlementDate == null)
            settlementDate = Settings.evaluationDate();

         if (npvDate == null)
            npvDate = settlementDate;

         double P = 0.0;
         double t = 0.0;
         double dPdy = 0.0;
         double r = y.rate();
         int N = (int)y.frequency();
         Date lastDate = npvDate;
         Date refStartDate, refEndDate;
         DayCounter dc = y.dayCounter();

         for (int i=0; i<leg.Count; ++i) 
         {
            if (leg[i].hasOccurred(settlementDate, includeSettlementDateFlows))
               continue;

            double c = leg[i].amount();
				if (leg[i].tradingExCoupon(settlementDate))
				{
					c = 0.0;
				}
            Date couponDate = leg[i].date();
            Coupon coupon = leg[i] as Coupon;
            if (coupon != null) 
            {
               refStartDate = coupon.refPeriodStart;
               refEndDate = coupon.refPeriodEnd;
            } 
            else 
            {
               if (lastDate == npvDate) 
               {
                  // we don't have a previous coupon date,
                  // so we fake it
                  refStartDate = couponDate - new Period(1,TimeUnit.Years);
               } 
               else  
               {
                  refStartDate = lastDate;
               }
               refEndDate = couponDate;
            }
                
            t += dc.yearFraction(lastDate, couponDate, refStartDate, refEndDate);
                
            double B = y.discountFactor(t);
            P += c * B;
            switch (y.compounding()) 
            {
               case Compounding.Simple:
                  dPdy -= c * B*B * t;
                  break;
               case Compounding.Compounded:
                  dPdy -= c * t * B/(1+r/N);
                  break;
               case Compounding.Continuous:
                  dPdy -= c * B * t;
                  break;
               case Compounding.SimpleThenCompounded:
                  if (t<=1.0/N)
                     dPdy -= c * B*B * t;
                  else
                     dPdy -= c * t * B/(1+r/N);
                  break;
               default:
                  Utils.QL_FAIL("unknown compounding convention (" + y.compounding() + ")");
                  break;
            }
            lastDate = couponDate;
         }

         if (P == 0.0) // no cashflows
            return 0.0;
         return -dPdy/P; // reverse derivative sign
      }
Пример #19
0
        public static double modifiedDuration(Leg leg, InterestRate y, bool includeSettlementDateFlows,
                                              Date settlementDate, Date npvDate)
        {
            if (leg.empty())
            {
                return(0.0);
            }

            if (settlementDate == null)
            {
                settlementDate = Settings.evaluationDate();
            }

            if (npvDate == null)
            {
                npvDate = settlementDate;
            }

            double     P        = 0.0;
            double     t        = 0.0;
            double     dPdy     = 0.0;
            double     r        = y.rate();
            int        N        = (int)y.frequency();
            Date       lastDate = npvDate;
            DayCounter dc       = y.dayCounter();

            for (int i = 0; i < leg.Count; ++i)
            {
                if (leg[i].hasOccurred(settlementDate, includeSettlementDateFlows))
                {
                    continue;
                }

                double c = leg[i].amount();
                if (leg[i].tradingExCoupon(settlementDate))
                {
                    c = 0.0;
                }

                t += getStepwiseDiscountTime(leg[i], dc, npvDate, lastDate);

                double B = y.discountFactor(t);
                P += c * B;
                switch (y.compounding())
                {
                case Compounding.Simple:
                    dPdy -= c * B * B * t;
                    break;

                case Compounding.Compounded:
                    dPdy -= c * t * B / (1 + r / N);
                    break;

                case Compounding.Continuous:
                    dPdy -= c * B * t;
                    break;

                case Compounding.SimpleThenCompounded:
                    if (t <= 1.0 / N)
                    {
                        dPdy -= c * B * B * t;
                    }
                    else
                    {
                        dPdy -= c * t * B / (1 + r / N);
                    }
                    break;

                default:
                    Utils.QL_FAIL("unknown compounding convention (" + y.compounding() + ")");
                    break;
                }
                lastDate = leg[i].date();
            }

            if (P.IsEqual(0.0)) // no cashflows
            {
                return(0.0);
            }
            return(-dPdy / P); // reverse derivative sign
        }
Пример #20
0
      //! Basis-point sensitivity of the cash flows.
      // The result is the change in NPV due to a uniform
      // 1-basis-point change in the rate paid by the cash
      // flows. The change for each coupon is discounted according
      // to the given constant interest rate.  The result is
      // affected by the choice of the interest-rate compounding
      // and the relative frequency and day counter.

      public static double bps(Leg leg, InterestRate yield, bool includeSettlementDateFlows,
                               Date settlementDate = null, Date npvDate = null)
      {
         if (leg.empty())
            return 0.0;

         if (settlementDate == null)
            settlementDate = Settings.evaluationDate();

         if (npvDate == null)
            npvDate = settlementDate;

         FlatForward flatRate = new FlatForward(settlementDate, yield.rate(), yield.dayCounter(),
                                               yield.compounding(), yield.frequency());
         return bps(leg, flatRate, includeSettlementDateFlows, settlementDate, npvDate);
      }
Пример #21
0
        static void Main(string[] args)
        {
            // boost::timer timer;

             Date today = new Date(16,Month.October,2007);
             Settings.setEvaluationDate(today);

             Console.WriteLine();
             Console.WriteLine("Pricing a callable fixed rate bond using");
             Console.WriteLine("Hull White model w/ reversion parameter = 0.03");
             Console.WriteLine("BAC4.65 09/15/12  ISIN: US06060WBJ36");
             Console.WriteLine("roughly five year tenor, ");
             Console.WriteLine("quarterly coupon and call dates");
             Console.WriteLine("reference date is : " + today );

             /* Bloomberg OAS1: "N" model (Hull White)
               varying volatility parameter

               The curve entered into Bloomberg OAS1 is a flat curve,
               at constant yield = 5.5%, semiannual compounding.
               Assume here OAS1 curve uses an ACT/ACT day counter,
               as documented in PFC1 as a "default" in the latter case.
             */

             // set up a flat curve corresponding to Bloomberg flat curve

             double bbCurveRate = 0.055;
             DayCounter bbDayCounter = new ActualActual(ActualActual.Convention.Bond);
             InterestRate bbIR = new InterestRate(bbCurveRate,bbDayCounter,Compounding.Compounded ,Frequency.Semiannual);

             Handle<YieldTermStructure> termStructure = new Handle<YieldTermStructure>(flatRate( today,
                                                              bbIR.rate(),
                                                              bbIR.dayCounter(),
                                                              bbIR.compounding(),
                                                              bbIR.frequency()));
             // set up the call schedule

             CallabilitySchedule callSchedule = new CallabilitySchedule();
             double callPrice = 100.0;
             int numberOfCallDates = 24;
             Date callDate = new Date(15,Month.September,2006);

             for (int i=0; i< numberOfCallDates; i++)
             {
            Calendar nullCalendar = new NullCalendar();

            Callability.Price myPrice = new Callability.Price(callPrice, Callability.Price.Type.Clean);
            callSchedule.Add( new Callability(myPrice,Callability.Type.Call, callDate ));
            callDate = nullCalendar.advance(callDate, 3, TimeUnit.Months);
             }

             // set up the callable bond

             Date dated = new Date(16,Month.September,2004);
             Date issue = dated;
             Date maturity = new Date(15,Month.September,2012);
             int settlementDays = 3;  // Bloomberg OAS1 settle is Oct 19, 2007
             Calendar bondCalendar = new UnitedStates(UnitedStates.Market.GovernmentBond);
             double coupon = .0465;
             Frequency frequency = Frequency.Quarterly;
             double redemption = 100.0;
             double faceAmount = 100.0;

             /* The 30/360 day counter Bloomberg uses for this bond cannot
            reproduce the US Bond/ISMA (constant) cashflows used in PFC1.
            Therefore use ActAct(Bond)
             */
             DayCounter bondDayCounter = new ActualActual(ActualActual.Convention.Bond);

             // PFC1 shows no indication dates are being adjusted
             // for weekends/holidays for vanilla bonds
             BusinessDayConvention accrualConvention = BusinessDayConvention.Unadjusted;
             BusinessDayConvention paymentConvention = BusinessDayConvention.Unadjusted;

             Schedule sch = new Schedule( dated, maturity, new Period(frequency), bondCalendar,
                                      accrualConvention, accrualConvention,
                                      DateGeneration.Rule.Backward, false);

             int maxIterations = 1000;
             double accuracy = 1e-8;
             int gridIntervals = 40;
             double reversionParameter = .03;

             // output price/yield results for varying volatility parameter

             double sigma = Const.QL_Epsilon; // core dumps if zero on Cygwin

             ShortRateModel hw0 = new HullWhite(termStructure,reversionParameter,sigma);

             IPricingEngine engine0 = new TreeCallableFixedRateBondEngine(hw0, gridIntervals, termStructure);

             CallableFixedRateBond callableBond = new CallableFixedRateBond( settlementDays, faceAmount, sch,
                                                                         new InitializedList<double>(1, coupon),
                                                                         bondDayCounter, paymentConvention,
                                                                         redemption, issue, callSchedule);
             callableBond.setPricingEngine(engine0);

             Console.WriteLine("sigma/vol (%) = {0:0.00}", (100.0 * sigma));

             Console.WriteLine("QuantLib price/yld (%)  ");
             Console.WriteLine(  "{0:0.00} / {1:0.00} ", callableBond.cleanPrice() ,
                                                     100.0 * callableBond.yield(bondDayCounter,
                                                                                Compounding.Compounded,
                                                                                frequency,
                                                                                accuracy,
                                                                                maxIterations));
             Console.WriteLine("Bloomberg price/yld (%) ");
             Console.WriteLine("96.50 / 5.47");

             //

             sigma = .01;

             Console.WriteLine("sigma/vol (%) = {0:0.00}", (100.0 * sigma));

             ShortRateModel hw1 = new HullWhite(termStructure,reversionParameter,sigma);

             IPricingEngine engine1 = new TreeCallableFixedRateBondEngine(hw1,gridIntervals,termStructure);

             callableBond.setPricingEngine(engine1);

             Console.WriteLine("QuantLib price/yld (%)  ");
             Console.WriteLine(  "{0:0.00} / {1:0.00} ", callableBond.cleanPrice() ,
                                                     100.0 * callableBond.yield(bondDayCounter,
                                                                                Compounding.Compounded,
                                                                                frequency,
                                                                                accuracy,
                                                                                maxIterations));

             Console.WriteLine("Bloomberg price/yld (%) ");
             Console.WriteLine("95.68 / 5.66");

             //

             sigma = .03;

             Console.WriteLine("sigma/vol (%) = {0:0.00}", (100.0 * sigma));

             ShortRateModel hw2 = new HullWhite(termStructure, reversionParameter, sigma);

             IPricingEngine engine2 = new TreeCallableFixedRateBondEngine(hw2, gridIntervals, termStructure);

             callableBond.setPricingEngine(engine2);

             Console.WriteLine("QuantLib price/yld (%)  ");
             Console.WriteLine("{0:0.00} / {1:0.00} ", callableBond.cleanPrice(),
                                                     100.0 * callableBond.yield(bondDayCounter,
                                                                                Compounding.Compounded,
                                                                                frequency,
                                                                                accuracy,
                                                                                maxIterations));

             Console.WriteLine("Bloomberg price/yld (%) ");
             Console.WriteLine("92.34 / 6.49");

             //

             sigma = .06;

             Console.WriteLine("sigma/vol (%) = {0:0.00}", (100.0 * sigma));

             ShortRateModel hw3 = new HullWhite(termStructure, reversionParameter, sigma);

             IPricingEngine engine3 = new TreeCallableFixedRateBondEngine(hw3, gridIntervals, termStructure);

             callableBond.setPricingEngine(engine3);

             Console.WriteLine("QuantLib price/yld (%)  ");
             Console.WriteLine("{0:0.00} / {1:0.00} ", callableBond.cleanPrice(),
                                                     100.0 * callableBond.yield(bondDayCounter,
                                                                                Compounding.Compounded,
                                                                                frequency,
                                                                                accuracy,
                                                                                maxIterations));

             Console.WriteLine("Bloomberg price/yld (%) ");
             Console.WriteLine("87.16 / 7.83");

             //

             sigma = .12;

             Console.WriteLine("sigma/vol (%) = {0:0.00}", (100.0 * sigma));

             ShortRateModel hw4 = new HullWhite(termStructure, reversionParameter, sigma);

             IPricingEngine engine4 = new TreeCallableFixedRateBondEngine(hw4, gridIntervals, termStructure);

             callableBond.setPricingEngine(engine4);

             Console.WriteLine("QuantLib price/yld (%)  ");
             Console.WriteLine("{0:0.00} / {1:0.00} ", callableBond.cleanPrice(),
                                                     100.0 * callableBond.yield(bondDayCounter,
                                                                                Compounding.Compounded,
                                                                                frequency,
                                                                                accuracy,
                                                                                maxIterations));

             Console.WriteLine("Bloomberg price/yld (%) ");
             Console.WriteLine("77.31 / 10.65");
        }