private static CalculationPeriod Create(DateTime periodStartDate, DateTime periodEndDate
                                                , CalculationPeriodFrequency frequency, BusinessDayAdjustments dateAdjustments
                                                , IBusinessCalendar paymentCalendar, bool isFirstPeriodCreated)
        {
            var calculationPeriod = new CalculationPeriod();
            //  Apply ROLL CONVENTION (NOT A BUSINESS DAY CONVENTION!) to unadjusted period start and end dates.
            //
            DateTime rollConventionPeriodStartDate = periodStartDate;
            DateTime rollConventionPeriodEndDate   = periodEndDate;
            var      frequencyPeriod = EnumHelper.Parse <PeriodEnum>(frequency.period, true);

            if (frequencyPeriod != PeriodEnum.D)//adjust if the frequency is NOT expressed in days
            {
                rollConventionPeriodStartDate = RollConventionEnumHelper.AdjustDate(frequency.rollConvention, periodStartDate);
                rollConventionPeriodEndDate   = RollConventionEnumHelper.AdjustDate(frequency.rollConvention, periodEndDate);
            }
            CalculationPeriodHelper.SetUnadjustedDates(calculationPeriod, rollConventionPeriodStartDate, rollConventionPeriodEndDate);
            //  Set adjusted period dates
            //
            DateTime adjustedPeriodStartDate = AdjustedDateHelper.ToAdjustedDate(paymentCalendar, rollConventionPeriodStartDate, dateAdjustments);
            DateTime adjustedPeriodEndDate   = AdjustedDateHelper.ToAdjustedDate(paymentCalendar, rollConventionPeriodEndDate, dateAdjustments);

            if (isFirstPeriodCreated)
            {
                adjustedPeriodEndDate = periodEndDate;
            }
            CalculationPeriodHelper.SetAdjustedDates(calculationPeriod, adjustedPeriodStartDate, adjustedPeriodEndDate);
            return(calculationPeriod);
        }
        private static void GeneratePeriodsBackward(DateTime firstRollDate, CalculationPeriodFrequency frequency,
                                                    BusinessDayAdjustments calculationPeriodDatesAdjustments,
                                                    CalculationPeriodsPrincipalExchangesAndStubs result,
                                                    DateTime adjustedEffectiveDate, StubPeriodTypeEnum?initialStubType
                                                    , IBusinessCalendar paymentCalendar)
        {
            DateTime periodEndDate               = firstRollDate;
            DateTime periodStartDate             = AddPeriod(periodEndDate, IntervalHelper.FromFrequency(frequency), -1);
            bool     encounteredShortInitialStub = false;

            //if (paymentCalendar == null)
            //{
            //    paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, calculationPeriodDatesAdjustments.businessCenters);
            //}
            do
            {
                var calculationPeriod = new CalculationPeriod();
                //  Apply ROLL CONVENTION (NOT A BUSINESS DAY CONVENTION!) to unadjusted period start and end dates.
                //
                DateTime rollConventionAdjustedPeriodStartDate = periodStartDate;
                DateTime rollConventionAdjustedPeriodEndDate   = periodEndDate;
                var      frequencyPeriod = EnumHelper.Parse <PeriodEnum>(frequency.period, true);
                if (frequencyPeriod != PeriodEnum.D)//adjust if the frequency is NOT expressed in days
                {
                    rollConventionAdjustedPeriodStartDate = RollConventionEnumHelper.AdjustDate(frequency.rollConvention, periodStartDate);
                    rollConventionAdjustedPeriodEndDate   = RollConventionEnumHelper.AdjustDate(frequency.rollConvention, periodEndDate);
                }
                CalculationPeriodHelper.SetUnadjustedDates(calculationPeriod, rollConventionAdjustedPeriodStartDate, rollConventionAdjustedPeriodEndDate);
                //  Set adjusted period dates
                //
                DateTime adjustedPeriodStartDate = AdjustedDateHelper.ToAdjustedDate(paymentCalendar, rollConventionAdjustedPeriodStartDate, calculationPeriodDatesAdjustments);
                DateTime adjustedPeriodEndDate   = AdjustedDateHelper.ToAdjustedDate(paymentCalendar, rollConventionAdjustedPeriodEndDate, calculationPeriodDatesAdjustments);
                CalculationPeriodHelper.SetAdjustedDates(calculationPeriod, adjustedPeriodStartDate, adjustedPeriodEndDate);
                //if (calculationPeriod.unadjustedStartDate > adjustedEffectiveDate)
                if (calculationPeriod.adjustedStartDate > adjustedEffectiveDate)
                {
                    result.InsertFirst(calculationPeriod);
                    periodEndDate   = periodStartDate;
                    periodStartDate = AddPeriod(periodEndDate, IntervalHelper.FromFrequency(frequency), -1);
                }
                //else if (calculationPeriod.unadjustedStartDate == adjustedEffectiveDate)//first period - not stub
                else if (calculationPeriod.adjustedStartDate == adjustedEffectiveDate)//first period - not stub
                {
                    result.InsertFirst(calculationPeriod);
                    break;
                }
                else//first period - short stub (merge with next period if a long stub specified)
                {
                    encounteredShortInitialStub = true;
                    //calculationPeriod.unadjustedStartDate = adjustedEffectiveDate;
                    calculationPeriod.adjustedStartDate = adjustedEffectiveDate;
                    result.InitialStubCalculationPeriod = calculationPeriod;
                    break;
                }
            } while (true);
            if (encounteredShortInitialStub && initialStubType == StubPeriodTypeEnum.LongInitial)
            {
                result.CreateLongInitialStub();
            }
        }
        private static CalculationPeriod CreateStub(DateTime periodStartDate, DateTime periodEndDate
                                                    , BusinessDayAdjustments dateAdjustments, IBusinessCalendar paymentCalendar)
        {
            var calculationPeriod = new CalculationPeriod();

            //  Apply ROLL CONVENTION (NOT A BUSINESS DAY CONVENTION!) to unadjusted period start and end dates.
            //
            CalculationPeriodHelper.SetUnadjustedDates(calculationPeriod, periodStartDate, periodEndDate);
            //  Set adjusted period dates
            //
            DateTime adjustedPeriodStartDate = AdjustedDateHelper.ToAdjustedDate(paymentCalendar, periodStartDate, dateAdjustments);
            DateTime adjustedPeriodEndDate   = AdjustedDateHelper.ToAdjustedDate(paymentCalendar, periodEndDate, dateAdjustments);

            CalculationPeriodHelper.SetAdjustedDates(calculationPeriod, adjustedPeriodStartDate, adjustedPeriodEndDate);
            return(calculationPeriod);
        }