discountFactor() public method

public discountFactor ( Date d1, Date d2 ) : double
d1 Date
d2 Date
return double
コード例 #1
0
        public static double simpleDuration(List <CashFlow> cashflows, InterestRate y, Date settlementDate)
        {
            if (cashflows.Count == 0)
            {
                return(0.0);
            }

            double     P = 0, dPdy = 0;
            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;
                dPdy += t * c * B;
            }


            // no cashflows
            if (P == 0.0)
            {
                return(0.0);
            }
            return(dPdy / P);
        }
コード例 #2
0
        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
        }
コード例 #3
0
ファイル: CashFlows.cs プロジェクト: ykim-otcfin/QLNet
        public static double simpleDuration(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 dPdy     = 0.0;
            double t        = 0.0;
            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;
                dPdy += t * c * B;

                lastDate = leg[i].date();
            }

            if (P.IsEqual(0.0)) // no cashflows
            {
                return(0.0);
            }
            return(dPdy / P);
        }
コード例 #4
0
ファイル: CashFlows.cs プロジェクト: ykim-otcfin/QLNet
        // NPV of the cash flows.
        // The NPV is the sum of the cash flows, each 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 npv(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;
            }

            double     npv      = 0.0;
            double     discount = 1.0;
            Date       lastDate = npvDate;
            DayCounter dc       = yield.dayCounter();

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

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

                double b = yield.discountFactor(getStepwiseDiscountTime(leg[i], dc, npvDate, lastDate));
                discount *= b;
                lastDate  = leg[i].date();

                npv += amount * discount;
            }
            return(npv);
        }
コード例 #5
0
      public static double simpleDuration(List<CashFlow> cashflows, InterestRate y, Date settlementDate) 
      {
         if (cashflows.Count == 0)
            return 0.0;

         double P = 0, dPdy = 0;
         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;
            dPdy += t * c * B;
         }


         // no cashflows
         if (P == 0.0) return 0.0;
         return dPdy / P;
      }
コード例 #6
0
ファイル: CashFlows.cs プロジェクト: akasolace/qlnet
      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
      }
コード例 #7
0
      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);

         }

      }
コード例 #8
0
        //! 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);
        }
コード例 #9
0
        public static double npv(List <CashFlow> leg, InterestRate y, bool includeSettlementDateFlows,
                                 Date settlementDate = null, Date npvDate = null)
        {
            if (leg == null || leg.empty())
            {
                return(0.0);
            }

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

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

            double npv = 0.0;
            double discount = 1.0;
            Date   lastDate = npvDate;
            Date   refStartDate, refEndDate;

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

                Date   couponDate = leg[i].date();
                double amount     = leg[i].amount();
                Coupon coupon     = leg[i] as Coupon;
                if (coupon != null)
                {
                    refStartDate = coupon.accrualStartDate();
                    refEndDate   = coupon.accrualEndDate();
                }
                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;
                }
                double b = y.discountFactor(lastDate, couponDate, refStartDate, refEndDate);
                discount *= b;
                lastDate  = couponDate;

                npv += amount * discount;
            }

            return(npv);
        }
コード例 #10
0
ファイル: CashFlows.cs プロジェクト: ykim-otcfin/QLNet
        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
        }
コード例 #11
0
ファイル: CashFlows.cs プロジェクト: ykim-otcfin/QLNet
        //! 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);
        }
コード例 #12
0
      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
      }
コード例 #13
0
      //! 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;
        }
コード例 #14
0
ファイル: CashFlows.cs プロジェクト: akasolace/qlnet
      public static double simpleDuration(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 dPdy = 0.0;
         double t = 0.0;
         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;
            dPdy += t * c * B;
                
            lastDate = couponDate;
         }
            
         if (P == 0.0) // no cashflows
            return 0.0;
         return dPdy/P;
      }
コード例 #15
0
 protected override double discountImpl(double t)
 {
     calculate();
     return(rate_.discountFactor(t));
 }
コード例 #16
0
ファイル: CashFlows.cs プロジェクト: akasolace/qlnet
      // NPV of the cash flows.
      // The NPV is the sum of the cash flows, each 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 npv(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;

         double npv = 0.0;
         double discount = 1.0;
         Date lastDate = npvDate;
         Date refStartDate, refEndDate;

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

            Date couponDate = leg[i].date();
            double amount = leg[i].amount();
				if (leg[i].tradingExCoupon(settlementDate))
				{
					amount = 0.0;
				}
            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;
            }
            
            double b = yield.discountFactor(lastDate, couponDate, refStartDate, refEndDate);
            discount *= b;
            lastDate = couponDate;

            npv += amount * discount;
        }
        return npv;
      }
コード例 #17
0
ファイル: Utils.cs プロジェクト: jmptrader/QLNet-1
        public static double dirtyPriceFromYield(double faceAmount, List <CashFlow> cashflows, double yield, DayCounter dayCounter,
                                                 Compounding compounding, Frequency frequency, Date settlement)
        {
            if (frequency == Frequency.NoFrequency || frequency == Frequency.Once)
            {
                frequency = Frequency.Annual;
            }

            InterestRate y = new InterestRate(yield, dayCounter, compounding, frequency);

            double price    = 0.0;
            double discount = 1.0;
            Date   lastDate = null;

            for (int i = 0; i < cashflows.Count - 1; ++i)
            {
                if (cashflows[i].hasOccurred(settlement))
                {
                    continue;
                }

                Date   couponDate = cashflows[i].Date;
                double amount     = cashflows[i].amount();
                if (lastDate == null)
                {
                    // first not-expired coupon
                    if (i > 0)
                    {
                        lastDate = cashflows[i - 1].Date;
                    }
                    else
                    {
                        if (cashflows[i].GetType().IsSubclassOf(typeof(Coupon)))
                        {
                            lastDate = ((Coupon)cashflows[i]).accrualStartDate();
                        }
                        else
                        {
                            lastDate = couponDate - new Period(1, TimeUnit.Years);
                        }
                    }
                    discount *= y.discountFactor(settlement, couponDate, lastDate, couponDate);
                }
                else
                {
                    discount *= y.discountFactor(lastDate, couponDate);
                }
                lastDate = couponDate;

                price += amount * discount;
            }

            CashFlow redemption = cashflows.Last();

            if (!redemption.hasOccurred(settlement))
            {
                Date   redemptionDate = redemption.Date;
                double amount         = redemption.amount();
                if (lastDate == null)
                {
                    // no coupons
                    lastDate  = redemptionDate - new Period(1, TimeUnit.Years);
                    discount *= y.discountFactor(settlement, redemptionDate, lastDate, redemptionDate);
                }
                else
                {
                    discount *= y.discountFactor(lastDate, redemptionDate);
                }

                price += amount * discount;
            }

            return(price / faceAmount * 100.0);
        }