/// <summary>
        /// Gets the unadjusted dates from a meta date scheduler.
        /// </summary>
        /// <param name="metaScheduleDefinition"></param>
        /// <param name="startDate"></param>
        /// <returns></returns>
        public static List <DateTime> GetUnadjustedDates(List <Triplet <Period, Period, RollConventionEnum> > metaScheduleDefinition,
                                                         DateTime startDate)
        {
            var offsetsFromStartDateForRollPeriods = new List <Pair <int, RollConventionEnum> >();

            foreach (var metaScheduleEntry in metaScheduleDefinition)
            {
                var numberOfRolls = (int)IntervalHelper.Div(metaScheduleEntry.Second, metaScheduleEntry.First);
                if (metaScheduleEntry.First.period != PeriodEnum.M)
                {
                    throw new System.Exception("Only month-expressed periods are supported.");
                }
                var rollsEveryNMonths = int.Parse(metaScheduleEntry.First.periodMultiplier);
                while (numberOfRolls-- > 0)
                {
                    var lastOffset = 0;
                    if (offsetsFromStartDateForRollPeriods.Count > 0)
                    {
                        lastOffset = offsetsFromStartDateForRollPeriods[offsetsFromStartDateForRollPeriods.Count - 1].First;
                    }
                    lastOffset += rollsEveryNMonths;
                    offsetsFromStartDateForRollPeriods.Add(new Pair <int, RollConventionEnum>(lastOffset, metaScheduleEntry.Third));
                }
            }
            //  Generates dates from a list of month-expressed offsets.
            //
            var result = (from offset in offsetsFromStartDateForRollPeriods
                          let rollDateUnadjusted = startDate.AddMonths(offset.First)
                                                   select RollConventionEnumHelper.AdjustDate(offset.Second, rollDateUnadjusted)).ToList();

            return(RemoveDuplicates(result));
        }
Example #2
0
        /// <summary>
        /// Gets the unadjusted date schedule.
        /// </summary>
        /// <param name="effectiveDate">The effective date.</param>
        /// <param name="intervalToTerminationDate">The interval to termination date.</param>
        /// <param name="periodInterval">The period interval.</param>
        /// <returns></returns>
        public static List <DateTime> GetUnadjustedDateSchedule(DateTime effectiveDate,
                                                                Period intervalToTerminationDate, Period periodInterval)
        {
            Double divisor = IntervalHelper.Div(intervalToTerminationDate, periodInterval);

            // The divisor has to be a whole number (i.e. the period must roll to the term date interval
            if (System.Math.Abs(divisor % 1) > Tolerance)
            {
                throw new ArithmeticException("The period frequency will not roll to the supplied termination date interval");
            }
            DateTime termDate    = intervalToTerminationDate.Add(effectiveDate);
            var      periodDates = new List <DateTime>();
            //DateTime periodStartDate = effectiveDate;
            int multiplier = periodInterval.GetPeriodMultiplier();

            periodDates.Add(effectiveDate);
            for (int i = 1; i < divisor; i++)
            {
                var periodEndDate = DateAdd(effectiveDate, periodInterval.period, multiplier * i);
                periodDates.Add(periodEndDate);
            }
            periodDates.Add(termDate);
            return(periodDates);
        }
        //<Interval, Interval, RollConventionEnum>

        /// <summary>
        /// With custom roll schedule
        /// </summary>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <param name="rollsMetaSchedule"></param>
        /// <param name="backwardGeneration"></param>
        /// <returns></returns>
        public static List <DateTime> GetUnadjustedDates3(DateTime startDate, DateTime endDate,
                                                          List <MetaScheduleItem> rollsMetaSchedule,
                                                          bool backwardGeneration)
        {
            var results = new List <DateTime>();

            if (backwardGeneration)//from end date to start date
            {
                //  reverse the meta schedule
                //
                var reversedRollsMetaScheduleParam = new List <MetaScheduleItem>(rollsMetaSchedule);
                reversedRollsMetaScheduleParam.Reverse();
                var offsetFromPrevScheduleItem = 0;
                foreach (var metaScheduleItem in reversedRollsMetaScheduleParam)
                {
                    var numberOfRolls = (int)IntervalHelper.Div(metaScheduleItem.Period, metaScheduleItem.RollFrequency);
                    if (metaScheduleItem.RollFrequency.period != PeriodEnum.M)
                    {
                        throw new System.Exception("Month periods are the only ones supported.");
                    }
                    var rollsEveryNMonths = int.Parse(metaScheduleItem.RollFrequency.periodMultiplier);
                    var rollNumber        = 1;
                    var offsetInMonths    = 0;
                    while (numberOfRolls-- > 0)
                    {
                        offsetInMonths = rollNumber * rollsEveryNMonths;
                        var rollDateUnadjusted   = endDate.AddMonths(-offsetInMonths + offsetFromPrevScheduleItem);
                        var rollDateRollAdjusted = RollConventionEnumHelper.AdjustDate(metaScheduleItem.RollConvention, rollDateUnadjusted);
                        results.Insert(0, rollDateRollAdjusted);
                        ++rollNumber;
                    }
                    offsetFromPrevScheduleItem -= offsetInMonths;
                }

                results.Insert(0, startDate);
                results.Add(endDate);
            }
            else//from start date to end date.
            {
                //DateTime rollDate = startDate;
                results.Add(startDate);
                var offsetFromPrevScheduleItem = 0;
                foreach (var metaScheduleItem in rollsMetaSchedule)
                {
                    var numberOfRolls = (int)IntervalHelper.Div(metaScheduleItem.Period, metaScheduleItem.RollFrequency);
                    if (metaScheduleItem.RollFrequency.period != PeriodEnum.M)
                    {
                        throw new System.Exception("Month periods are the only ones supported.");
                    }
                    var rollsEveryNMonths = int.Parse(metaScheduleItem.RollFrequency.periodMultiplier);
                    var rollNumber        = 1;
                    var offsetInMonths    = 0;
                    while (numberOfRolls-- > 0)
                    {
                        offsetInMonths = rollNumber * rollsEveryNMonths;
                        var rollDateUnadjusted   = startDate.AddMonths(offsetInMonths + +offsetFromPrevScheduleItem);
                        var rollDateRollAdjusted = RollConventionEnumHelper.AdjustDate(metaScheduleItem.RollConvention, rollDateUnadjusted);
                        results.Add(rollDateRollAdjusted);
                        ++rollNumber;
                    }
                    offsetFromPrevScheduleItem += offsetInMonths;
                }
                results.Add(endDate);
            }
            return(RemoveDuplicates(results));
        }
        /// <summary>
        /// Gets the unadjusted dates.
        /// </summary>
        /// <param name="metaScheduleDefinition">The meta schedule definition.</param>
        /// <param name="startDate">The start date.</param>
        /// <param name="endDate">The end date.</param>
        /// <param name="defaultInterval">The default interval.</param>
        /// <param name="defaultRollConvention">The default roll convention.</param>
        /// <param name="fromStartDate">if set to <c>true</c> [from start date].</param>
        /// <returns></returns>
        public static DateTime[] GetUnadjustedDates
            (List <Triplet <Period, Period, RollConventionEnum> > metaScheduleDefinition
            , DateTime startDate
            , DateTime endDate
            , Period defaultInterval
            , RollConventionEnum defaultRollConvention
            , Boolean fromStartDate
            )
        {
            DateTime        firstReg;
            DateTime        lastReg;
            var             result = new List <DateTime>();
            List <DateTime> additionalDates;
            DateTime        fromDate           = startDate;
            DateTime        toDate             = endDate;
            int             intervalMulitplier = 1;

            if (!fromStartDate)
            {
                fromDate           = endDate;
                toDate             = startDate;
                intervalMulitplier = intervalMulitplier * -1;
            }
            var offsetsFromStartDateForRollPeriods = new List <Pair <Period, RollConventionEnum> >();

            foreach (var metaScheduleEntry in metaScheduleDefinition)
            {
                var numberOfRolls = (int)IntervalHelper.Div(metaScheduleEntry.Second, metaScheduleEntry.First);
                if (numberOfRolls == 0)
                {
                    throw new System.Exception("Invalid period interval specified. The period interval is greater than the duration interval");
                }
                if (!fromStartDate)
                {
                    metaScheduleEntry.First.periodMultiplier = (Convert.ToInt32(metaScheduleEntry.First.periodMultiplier) * intervalMulitplier).ToString(CultureInfo.InvariantCulture);
                }
                while (numberOfRolls-- > 0)
                {
                    offsetsFromStartDateForRollPeriods.Add(new Pair <Period, RollConventionEnum>(metaScheduleEntry.First, metaScheduleEntry.Third));
                }
            }
            if (offsetsFromStartDateForRollPeriods.Count > 0)
            {
                //  Generates dates from a list of intervals expressed as offsets.
                DateTime referenceDate = fromDate;
                foreach (var offset in offsetsFromStartDateForRollPeriods)
                {
                    if (referenceDate == fromDate)
                    {
                        result.Add(fromDate);
                    }
                    DateTime rollDateUnadjusted = offset.First.Add(referenceDate);
                    DateTime rollConventionDate = DateScheduler.ApplyRollConventionToDate(offset.Second, rollDateUnadjusted);
                    if ((fromStartDate && rollConventionDate > toDate) || (!fromStartDate && rollConventionDate < toDate))
                    {
                        result.Add(toDate);
                        break;
                    }
                    result.Add(rollConventionDate);
                    referenceDate = rollDateUnadjusted;
                }
                // if end date falls after the meta data schedule provided use the defaults
                if (result.Count > 0)
                {
                    if ((fromStartDate && result[result.Count - 1] < toDate) || (!fromStartDate && result[result.Count - 1] > toDate))
                    {
                        if (result[result.Count - 1] < endDate)
                        {
                            additionalDates = fromStartDate ? new List <DateTime>(DateScheduler.GetUnadjustedDatesFromEffectiveDate(result[result.Count - 1], toDate, defaultInterval, defaultRollConvention, out firstReg, out lastReg)) : new List <DateTime>(DateScheduler.GetUnadjustedDatesFromTerminationDate(toDate, result[result.Count - 1], defaultInterval, defaultRollConvention, out firstReg, out lastReg));
                            result.AddRange(additionalDates);
                            result.Sort();
                        }
                    }
                }
            }
            else
            {
                additionalDates = fromStartDate ? new List <DateTime>(DateScheduler.GetUnadjustedDatesFromEffectiveDate(startDate, toDate, defaultInterval, defaultRollConvention, out firstReg, out lastReg)) : new List <DateTime>(DateScheduler.GetUnadjustedDatesFromTerminationDate(startDate, toDate, defaultInterval, defaultRollConvention, out firstReg, out lastReg));
                result.AddRange(additionalDates);
            }
            result = RemoveDuplicates(result);
            result.Sort();
            return(result.ToArray());
        }