Example #1
0
        private static TermStructure CalcCurveFromMaturity(DateTime Maturity, DateTime StartDate, double CouponRate,
                                                           NextWorkingDayConvention nextDay, int Freq, Dictionary <DateTime, DateTime> Holidays,
                                                           bool FixedCashPayments)
        {
            List <TermPoint> points = new List <TermPoint>();

            DateTime pointDate = Maturity;
            bool     lastPoint = true;

            while (pointDate > StartDate)
            {
                if (lastPoint)
                {
                    // Only do the last point once, decrement the date next time around
                    lastPoint = false;
                }
                else
                {
                    pointDate = pointDate.AddMonths(-(12 / Freq));
                }

                TermPoint point = new TermPoint();
                point.Rate      = CouponRate;
                point.PointDate = pointDate;
                int month = point.PointDate.Month;

                point.PayDate = GetWorkingDayDate(1, pointDate.AddDays(-1), Holidays, nextDay);

                if (!FixedCashPayments)
                {
                    point.PointDate = point.PayDate;
                }

                points.Add(point);
            }
            ;

            TermStructure ts = new TermStructure();

            for (int i = points.Count - 1; i >= 0; i--)
            {
                ts.Points.Add(points[i]);
            }

            return(ts);
        }
Example #2
0
        internal static double AccruedForDaysInPeriod(DateTime AccrueFrom, DateTime AccrueTo, TermStructure ts, double Rate, bool FixedCashPayments)
        {
            double    ret         = 0;
            TermPoint periodStart = ts.Points[0];
            TermPoint periodEnd   = null;

            if (AccrueTo > ts.Points[0].PointDate && AccrueFrom < ts.Points[ts.PointCount - 1].PointDate)
            {
                // Find the applicable period
                foreach (TermPoint point in ts.Points)
                {
                    if (point.PointDate <= AccrueFrom)
                    {
                        periodStart = point;
                    }
                    else if (point.PointDate >= AccrueTo)
                    {
                        periodEnd = point;
                        break;
                    }
                }
                // If the caller has asked for Accrued to a point past the end of the term structure it is not valid
                // and the PeriodEnd variable will be equal to zero
                if (periodEnd == null)
                {
                    throw new Exception(string.Format("AccrueTo data [{0}] is past the end of the curve [{1}].", AccrueTo.ToString("dd MMM yy"), ts.Points[ts.PointCount - 1].PointDate.ToString("dd MMM yy")));
                }

                int days         = DaysBetween(AccrueFrom, AccrueTo, ts.DayCount);
                int periodLength = DaysBetween(periodStart.PointDate, periodEnd.PointDate, ts.DayCount);
                int freq         = (int)Math.Round((double)365 / periodLength, 0);

                // We need to get the rate of the point to which we are accrueing up to
                // A rate quoted within the Curve is the portion of rate for that period. So the rate according to the curve for a
                // semi annual bond paying 5% would be 2.5%
                if (Rate == 0)
                {
                    Rate = periodEnd.Amount;
                }

                if (FixedCashPayments)
                {
                    if (periodLength > 366)
                    {
                        // it's longer than a year.
                        // We need to work out the accrued as if a coupon "was" paid each year
                        // This will take account of when a Feb 29 occurrs

                        // Split the accrued to before and after an imaginary paydate being one year before the real pay date
                        DateTime couponPoint2 = periodEnd.PointDate;
                        do
                        {
                            DateTime couponPoint = couponPoint2.AddYears(-1);
                            periodLength = DaysBetween(couponPoint, couponPoint2, ts.DayCount);

                            if (couponPoint < AccrueTo)
                            {
                                if (couponPoint2 < AccrueTo)
                                {
                                    // We have done the part up to AccrueTo
                                    if (AccrueFrom < couponPoint)
                                    {
                                        days = DaysBetween(couponPoint, couponPoint2, ts.DayCount);
                                    }
                                    else
                                    {
                                        days = DaysBetween(AccrueFrom, couponPoint, ts.DayCount);
                                    }
                                }
                                else
                                {
                                    // Work out accrued from the CouponPoint to the AccrueTo date
                                    if (AccrueFrom < couponPoint)
                                    {
                                        days = DaysBetween(couponPoint, AccrueTo, ts.DayCount);
                                    }
                                    else
                                    {
                                        days = DaysBetween(AccrueFrom, AccrueTo, ts.DayCount);
                                    }
                                }
                                ret += (Rate * days / periodLength);
                            }
                            couponPoint2 = couponPoint;
                        } while (couponPoint2 < AccrueFrom);
                    }
                    else
                    {
                        if (periodLength != 0)
                        {
                            ret += (Rate / freq) * (days / periodLength);
                        }
                    }
                }
                else
                {
                    switch (ts.DayCount)
                    {
                    case DayCountConvention.e30_360:
                    case DayCountConvention.e30E_360:
                    case DayCountConvention.e30E1_360:
                    case DayCountConvention.eActual_360:
                        ret = Rate * days / 360;
                        break;

                    case DayCountConvention.eActual_365:
                    case DayCountConvention.eActualNL_365:
                        ret = Rate * days / 365;
                        break;

                    case DayCountConvention.eActual_Actual:
                        // Check for leap years
                        int year1 = (int)DateTime.Parse("1 Jan " + AccrueTo.AddYears(1).Year).Subtract(DateTime.Parse("1 Jan " + AccrueFrom.Year)).TotalDays;

                        if (year1 == 731)
                        {     // it goes into two years one of which is a leap year
                              // A bit different for this
                              // This assumes that the period is <= 1 year, ie, cannot span more than 2 adjacent years

                            // Days = startpoint up to the first of next year
                            days = (int)DateTime.Parse("1 Jan " + periodEnd.PointDate.Year).Subtract(periodStart.PointDate).TotalDays;
                            // Days2 = the first of the next year to the end point
                            int days2 = (int)periodEnd.PointDate.Subtract(DateTime.Parse("1 Jan " + periodEnd.PointDate.Year)).TotalDays;

                            // Number of days in each seperate period which falls in each year
                            year1 = (int)DateTime.Parse("1 Jan " + periodEnd.PointDate.Year).Subtract(DateTime.Parse("1 Jan " + periodStart.PointDate.Year)).TotalDays;
                            int year2 = (int)DateTime.Parse("1 Jan " + periodEnd.PointDate.Year + 1).Subtract(DateTime.Parse("1 Jan " + periodEnd.PointDate.Year)).TotalDays;

                            ret = (((Rate / year1) * days)) + (((Rate / year2) * days2));
                        }
                        else
                        {
                            ret = (Rate * days) / year1;
                        }
                        break;
                    }
                }
            }

            return(ret);
        }