Exemplo n.º 1
0
        public static Lease Create(string id, string propertyReference, DateTime nextReviewDate, DateTime baseDate, Period tenor, string currency,
                                   Period paymentFrequency, string businessDayConvention, string businessCentersAsString)
        {
            var lease = new Lease
            {
                startDate = new IdentifiedDate {
                    id = "StartDate", Value = baseDate
                },
                leaseExpiryDate = new IdentifiedDate {
                    id = "MaturityDate", Value = tenor.Add(baseDate)
                },
                leaseTenor             = tenor,
                businessDayAdjustments = BusinessDayAdjustmentsHelper.Create(businessDayConvention, businessCentersAsString),
                currency = new IdentifiedCurrency {
                    id = "PaymentCurrency", Value = currency
                },
                leaseType         = "Standard",
                leaseIdentifier   = id,
                propertyReference = propertyReference,
                nextReviewDate    = new IdentifiedDate {
                    id = "NextReviewDate", Value = nextReviewDate
                },
                paymentFrequency = paymentFrequency,
            };

            return(lease);
        }
Exemplo n.º 2
0
 public static DateTime Add(DateTime dateTime, Period periodToAdd)
 {
     if (periodToAdd == null)
     {
         throw new ArgumentNullException(nameof(periodToAdd));
     }
     return(periodToAdd.Add(dateTime));
 }
Exemplo n.º 3
0
        public void Addition_With_IdenticalPeriodTypes()
        {
            Period p1  = Period.FromHours(3);
            Period p2  = Period.FromHours(2);
            Period sum = p1 + p2;

            Assert.AreEqual(5, sum.Hours);
            Assert.AreEqual(sum, Period.Add(p1, p2));
        }
 /// <summary>
 /// Gets the unadjusted calculation 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 List <CalculationPeriod> GetUnadjustedCalculationDateSchedule(DateTime effectiveDate, Period intervalToTerminationDate, Period periodInterval)
 {
     CalculationPeriodDates = null;
     PeriodInterval         = periodInterval;
     _effectiveDate         = effectiveDate;
     _termDate      = intervalToTerminationDate.Add(effectiveDate);
     RollConvention = RollConventionEnum.NONE;
     _unadjustedDateScheduleList = CalculationPeriodHelper.GenerateUnadjustedCalculationDates(effectiveDate, intervalToTerminationDate, periodInterval);
     return(_unadjustedDateScheduleList);
 }
Exemplo n.º 5
0
        /// <summary>
        /// Process a PPD Grid. The result is a Market structure that camn be published.
        /// </summary>
        /// <param name="logger">The logger</param>
        /// <param name="cache">The cache.</param>
        /// <param name="swapCurve">The latest rate curve</param>
        /// <param name="ppdGrid">The raw Points Per Day matrix supplied from the subscriber</param>
        /// <param name="id">The id to use in publishing the curve</param>
        /// <param name="nameSpace">The client namespace</param>
        /// <returns></returns>
        public static Market ProcessSwaption(ILogger logger, ICoreCache cache, Market swapCurve, SwaptionPPDGrid ppdGrid, string id, string nameSpace)
        {
            var mkt   = swapCurve;
            var curve = new SimpleRateCurve(mkt);
            // List the values so we can build our ATM vols
            var atmVols = new Dictionary <SimpleKey, decimal>();
            // Create a calendar to use to modify the date
            // default to be Sydney...
            IBusinessCalendar bc = BusinessCenterHelper.ToBusinessCalendar(cache, new[] { "AUSY" }, nameSpace); //BusinessCalendarHelper("AUSY");
            // Use some logic to get the spot date to use
            // LPM Spot lag is 2 days (modfollowing)
            DateTime spotDate = curve.GetSpotDate();

            // Extract each surface and build an ATM engine therefrom
            // Build a list of all possible engines
            foreach (string e in ExpiryKeys)
            {
                // Assume frequency = 4 months until 3 years tenor is reached
                Period expiration         = PeriodHelper.Parse(e);
                double expiryYearFraction = expiration.ToYearFraction();
                foreach (string t in TenorKeys)
                {
                    // Create a Swaprate for each expiry/tenor pair
                    // Assume frequency = 4 months until 3 years tenor is reached
                    double tenorYearFraction = PeriodHelper.Parse(t).ToYearFraction();
                    int    frequency         = tenorYearFraction < 4 ? 4 : 2;
                    // Calculation date
                    // Discount factors
                    // Offsets (elapsed days)
                    var rates = new SwapRate(logger, cache, nameSpace, "AUSY", curve.BaseDate, "ACT/365.FIXED", curve.GetDiscountFactors(), curve.GetDiscountFactorOffsets(), frequency, BusinessDayConventionEnum.MODFOLLOWING);
                    // Calculate the volatility given PPD and swap curve
                    DateTime expiry = bc.Roll(expiration.Add(spotDate), BusinessDayConventionEnum.FOLLOWING);
                    decimal  vol    = CalculateAtmVolatility(rates, expiry, ppdGrid, expiryYearFraction, tenorYearFraction);
                    atmVols.Add(new SimpleKey(e, t), vol);
                }
            }
            var vols = new object[atmVols.Count + 1, 3];
            var i    = 1;

            vols[0, 0] = "Expiry";
            vols[0, 1] = "Tenor";
            vols[0, 2] = "0";
            foreach (var key in atmVols.Keys)
            {
                vols[i, 0] = key.Expiry;
                vols[i, 1] = key.Tenor;
                vols[i, 2] = atmVols[key];
                i++;
            }
            DateTime buildDateTime = swapCurve.Items1[0].buildDateTime;
            var      volSurface    = new VolatilitySurface(vols, new VolatilitySurfaceIdentifier(id), curve.BaseDate, buildDateTime);

            return(CreateMarketDocument(volSurface.GetFpMLData()));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Gets the first regular period start date.
        /// </summary>
        /// <param name="periodInterval">The period interval.</param>
        /// <param name="rollConvention">The roll convention.</param>
        /// <param name="startDate">The start date.</param>
        /// <returns></returns>
        public static DateTime GetFirstRegularPeriodStartDate(Period periodInterval, RollConventionEnum rollConvention, DateTime startDate)
        {
            DateTime advDate = periodInterval.Add(startDate);
            DateTime regularPeriodStartDate = advDate;

            if (rollConvention != RollConventionEnum.NONE)
            {
                regularPeriodStartDate = RollConventionEnumHelper.AdjustDate(rollConvention, advDate);
            }
            return(regularPeriodStartDate);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Gets the unadjusted dates from effective date.
        /// </summary>
        /// <param name="effectiveDate">The effective date.</param>
        /// <param name="terminationDate">The termination date.</param>
        /// <param name="periodInterval">The period interval.</param>
        /// <param name="rollConvention">The roll convention.</param>
        /// <param name="firstRegularPeriodStartDate">The first regular period start date.</param>
        /// <param name="lastRegularPeriodEndDate">The last regular period end date.</param>
        /// <returns></returns>
        public static DateTime[] GetUnadjustedDatesFromEffectiveDate(DateTime effectiveDate, DateTime terminationDate, Period periodInterval, RollConventionEnum rollConvention, out DateTime firstRegularPeriodStartDate, out DateTime lastRegularPeriodEndDate)
        {
            lastRegularPeriodEndDate = terminationDate;
            DateTime firstRollDate = effectiveDate;
            var      periodDates   = new List <DateTime> {
                firstRollDate
            };
            DateTime nextRollDate       = periodInterval.Add(firstRollDate);
            DateTime rollConventionDate = ApplyRollConventionToDate(rollConvention, nextRollDate);

            firstRegularPeriodStartDate = DateTime.Compare(nextRollDate, rollConventionDate) == 0 ? firstRollDate : rollConventionDate;
            periodDates.Add(rollConventionDate);
            Boolean reachedEnd = false;

            while (!reachedEnd)
            {
                rollConventionDate = periodInterval.Add(rollConventionDate);
                rollConventionDate = ApplyRollConventionToDate(rollConvention, rollConventionDate);
                if (rollConventionDate <= terminationDate)
                {
                    if (rollConventionDate.Month == terminationDate.Month && rollConventionDate.Year == terminationDate.Year)
                    {
                        periodDates.Add(terminationDate);
                        reachedEnd = true;
                        lastRegularPeriodEndDate = rollConventionDate.Day == terminationDate.Day ? periodDates[periodDates.Count - 1] : periodDates[periodDates.Count - 2];
                    }
                    else
                    {
                        periodDates.Add(rollConventionDate);
                    }
                }
                else
                {
                    reachedEnd = true;
                    lastRegularPeriodEndDate = periodDates[periodDates.Count - 1];
                    periodDates.Add(terminationDate);
                }
            }
            periodDates.Sort();
            return(periodDates.ToArray());
        }
Exemplo n.º 8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PriceableZeroRate"/> class.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="baseDate">The base date.</param>
        /// <param name="amount">The amount of cash.</param>
        /// <param name="term">The term.</param>
        /// <param name="nodeStruct">The nodeStruct.</param>
        /// <param name="paymentCalendar">The payment calendar. If null, a new is constructed based on the business calendars.</param>
        /// <param name="fixedRate">The fixed rate.</param>
        public PriceableZeroRate(string id, DateTime baseDate, Decimal amount, Period term, ZeroRateNodeStruct nodeStruct,
                                 IBusinessCalendar paymentCalendar, BasicQuotation fixedRate)
            : base(id, baseDate, amount, nodeStruct.BusinessDayAdjustments, fixedRate)
        {
            ModelIdentifier  = "ZeroCouponRate";
            Adjust           = nodeStruct.AdjustDates;
            DayCountFraction = nodeStruct.DayCountFraction;
            RiskMaturityDate = !Adjust?term.Add(baseDate) : GetEffectiveDate(baseDate, paymentCalendar, term, nodeStruct.BusinessDayAdjustments.businessDayConvention);

            CompoundingFrequency = nodeStruct.CompoundingFrequency;
            AdjustedStartDate    = baseDate;
            YearFraction         = GetYearFraction(DayCountFraction.Value, AdjustedStartDate, RiskMaturityDate);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Gets the last regular period end date.
        /// </summary>
        /// <param name="periodInterval">The period interval.</param>
        /// <param name="rollConvention">The roll convention.</param>
        /// <param name="endDate">The end date.</param>
        /// <returns></returns>
        public static DateTime GetLastRegularPeriodEndDate(Period periodInterval, RollConventionEnum rollConvention, DateTime endDate)
        {
            int periodMultiplierAsInt = int.Parse(periodInterval.periodMultiplier);

            if (periodMultiplierAsInt > 0)
            {
                periodMultiplierAsInt = periodMultiplierAsInt * -1;
            }
            periodInterval.periodMultiplier = periodMultiplierAsInt.ToString(CultureInfo.InvariantCulture);
            DateTime advDate = periodInterval.Add(endDate);
            DateTime regularPeriodEndDate = advDate;

            if (rollConvention != RollConventionEnum.NONE)
            {
                regularPeriodEndDate = RollConventionEnumHelper.AdjustDate(rollConvention, advDate);
            }
            return(regularPeriodEndDate);
        }
Exemplo n.º 10
0
        public void AddEnclosedPeriodShouldReturnSamePeriod()
        {
            // Arrange

            var from   = new DateTime(1111);
            var to     = new DateTime(3333);
            var period = new Period(from, to);

            ICollection expected = new Period[] { period };

            // Act

            IEnumerable <Period> actual1 = period + period;
            IEnumerable <Period> actual2 = period.Add(period);

            // Assert

            CollectionAssert.AreEqual(expected, (ICollection)actual1.ToList());
            CollectionAssert.AreEqual(expected, (ICollection)actual2.ToList());
        }
Exemplo n.º 11
0
        /// <summary>
        /// Generates the unadjusted calculation dates.
        /// </summary>
        /// <param name="effectiveDate">The effective date.</param>
        /// <param name="intervalToTerminationDate">The interval to termination date.</param>
        /// <param name="periodInterval">The period interval.</param>
        /// <param name="rollConvention">The roll convention.</param>
        /// <returns></returns>
        public static List <CalculationPeriod> GenerateUnadjustedCalculationDates(DateTime effectiveDate, Period intervalToTerminationDate, Period periodInterval, RollConventionEnum rollConvention)
        {
            DateTime startDate = effectiveDate;

            // Adjust the effective date
            if (rollConvention != RollConventionEnum.NONE)
            {
                startDate = RollConventionEnumHelper.AdjustDate(rollConvention, effectiveDate);
            }
            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 ((divisor % 1) != 0)
            {
                throw new ArithmeticException("The period frequency will not roll to the supplied termination date interval");
            }
            DateTime           terminationDate = intervalToTerminationDate.Add(startDate);
            StubPeriodTypeEnum?stubPeriodType  = null;

            return(GenerateUnadjustedCalculationDates(startDate, terminationDate, effectiveDate, periodInterval, rollConvention, stubPeriodType));
        }
Exemplo n.º 12
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);
        }
Exemplo n.º 13
0
        ///<summary>
        ///</summary>
        ///<param name="discountCurve"></param>
        ///<param name="baseDate"></param>
        ///<param name="forwardRateTenor"></param>
        ///<param name="priceableXibor"></param>
        ///<returns></returns>
        public TermCurve ToPriceableXiborForwardCurve(TermCurve discountCurve, DateTime baseDate,
                                                      Period forwardRateTenor, PriceableXibor priceableXibor) //TODO
        {
            //CompoundingFrequency frequency = CompoundingFrequencyHelper.Create("Annual");
            var dates         = discountCurve.GetListTermDates();
            var yearFractions = new List <double>();

            foreach (var date in dates)
            {
                var yearFraction = (date - baseDate).TotalDays / 365.0;//TODO extend this with a general daycountraction.
                yearFractions.Add(yearFraction);
            }
            var midValues        = discountCurve.GetListMidValues();
            var discountFactors  = new List <double>(Array.ConvertAll(midValues.ToArray(), Convert.ToDouble));
            var forwardTermCurve = TermCurve.Create(new List <TermPoint>());
            var index            = 0;

            foreach (var startOfPeriodDateTime in dates)
            {
                var yearFractionsbeginPeriod  = yearFractions[index];
                var endOfPeriodDateTime       = forwardRateTenor.Add(startOfPeriodDateTime);
                var yearFractionAtEndOfPeriod = (endOfPeriodDateTime - baseDate).TotalDays / 365.0;
                //get df corresponding to end of period
                //
                IInterpolation interpolation = new LinearRateInterpolation();
                interpolation.Initialize(yearFractions.ToArray(), discountFactors.ToArray());
                var dfAtEndOfPeriod         = interpolation.ValueAt(yearFractionAtEndOfPeriod, true);
                var dfAtTheBeginingOfPeriod = discountFactors[index];
                var forwardRate             = (dfAtTheBeginingOfPeriod / dfAtEndOfPeriod - 1) /
                                              (yearFractionAtEndOfPeriod - yearFractionsbeginPeriod);
                var zeroPoint = TermPointFactory.Create(Convert.ToDecimal(forwardRate), startOfPeriodDateTime);
                forwardTermCurve.Add(zeroPoint);
                ++index;
            }
            return(forwardTermCurve);
        }
Exemplo n.º 14
0
        public void AddPeriodWithOverlappingToShouldReturnExtendedPeriod()
        {
            // Arrange

            var from1   = new DateTime(1111);
            var to1     = new DateTime(3333);
            var period1 = new Period(from1, to1);

            var from2   = new DateTime(2222);
            var to2     = new DateTime(4444);
            var period2 = new Period(from2, to2);

            ICollection expected = new Period[] { new Period(from1, to2) };

            // Act

            IEnumerable <Period> actual1 = period1 + period2;
            IEnumerable <Period> actual2 = period1.Add(period2);

            // Assert

            CollectionAssert.AreEqual(expected, (ICollection)actual1.ToList());
            CollectionAssert.AreEqual(expected, (ICollection)actual2.ToList());
        }
Exemplo n.º 15
0
        public void AddDistinctPeriodShouldReturnBothPeriods()
        {
            // Arrange

            var from1   = new DateTime(1111);
            var to1     = new DateTime(3333);
            var period1 = new Period(from1, to1);

            var from2   = new DateTime(4444);
            var to2     = new DateTime(6666);
            var period2 = new Period(from2, to2);

            ICollection expected = new Period[] { period1, period2 };

            // Act

            IEnumerable <Period> actual1 = period1 + period2;
            IEnumerable <Period> actual2 = period1.Add(period2);

            // Assert

            CollectionAssert.AreEqual(expected, (ICollection)actual1.ToList());
            CollectionAssert.AreEqual(expected, (ICollection)actual2.ToList());
        }
Exemplo n.º 16
0
        /// <summary>
        /// Convert the cap/floor PPD values to an ATM parVols structure
        /// This method then calls the bootstrapper <see cref="ProcessCapFloorPpd"/>
        /// to generate the capvol curve
        /// </summary>
        /// <param name="logger">The logger</param>
        /// <param name="cache">The cache.</param>
        /// <param name="rateCurve"></param>
        /// <param name="capFloor"></param>
        /// <param name="nameSpace"></param>
        /// <returns></returns>
        private static Market ProcessCapFloorPpd(ILogger logger, ICoreCache cache, string nameSpace, Market rateCurve, CapFloorATMMatrix capFloor)
        {
            var expiry          = capFloor.GetExpiries();
            var vols            = capFloor.GetVolatilities();
            var mkt             = rateCurve;
            var curve           = new SimpleRateCurve(mkt);
            var rawOffsets      = curve.GetDiscountFactorOffsets();
            var offsets         = Array.ConvertAll(rawOffsets, IntToDouble);
            var discountFactors = curve.GetDiscountFactors();
            var volType         = capFloor.GetVolatilityTypes();
            var atmVols         = new Dictionary <string, decimal>();
            var settings        = CreateCapFloorProperties(capFloor.GetVolatilitySettings());
            var bc = BusinessCenterHelper.ToBusinessCalendar(cache, new[] { "AUSY" }, nameSpace);

            // Use some logic to get the spot date to use
            // Step through each vol and convert ppd to ATM vol
            for (var i = 0; i < expiry.Length; i++)
            {
                // Create a Swaprate for each expiry
                // Assume frequency = 4 months until 4 years tenor is reached
                Period tv = PeriodHelper.Parse(expiry[i]);
                //double tvYearFraction = tv.ToYearFraction();
                //int frequency = tvYearFraction < 4 ? 4 : 2;
                const int frequency = 4;
                var       rates     = new SwapRate(logger, cache, nameSpace, "AUSY", curve.GetBaseDate(), "ACT/365.FIXED", discountFactors, curve.GetDiscountFactorOffsets(), frequency, BusinessDayConventionEnum.MODFOLLOWING);
                switch (volType[i])
                {
                case "ETO":
                {
                    DateTime spotDate       = settings.GetValue("Calculation Date", DateTime.MinValue);
                    var      rollConvention = settings.GetValue("RollConvention", BusinessDayConventionEnum.MODFOLLOWING);
                    DateTime etoDate        = bc.Roll(tv.Add(spotDate), rollConvention);
                    atmVols[expiry[i]] = CalculateATMVolatility(settings, spotDate, etoDate, offsets, discountFactors, vols[i][0]);
                }
                break;

                case "Cap/Floor":
                {
                    DateTime spotDate          = settings.GetValue("Calculation Date", DateTime.MinValue);
                    var      rollConvention    = settings.GetValue("RollConvention", BusinessDayConventionEnum.MODFOLLOWING);
                    DateTime expiryDate        = bc.Roll(tv.Add(spotDate), rollConvention);
                    string   tenor             = DateToTenor(spotDate, expiryDate);
                    double   tenorYearFraction = PeriodHelper.Parse(tenor).ToYearFraction();
                    // Add the caplet maturity to the expiry and then calculate the vol
                    atmVols[expiry[i]] = CalculateCAPATMVolatility(rates, spotDate, tenorYearFraction, vols[i][0]);
                }
                break;
                }
            }
            // Fudge to switch the PPD header to ATM
            // We've converted so we want the new name
            var headers = capFloor.GetHeaders();

            for (var i = 0; i < headers.Length; i++)
            {
                if (!headers[i].Contains("PPD"))
                {
                    continue;
                }
                headers[i] = "ATM";
                break;
            }
            // Convert our lovely dictionary to a grubby array of arrays
            var volatilities = new object[atmVols.Keys.Count][];
            var row          = 0;

            foreach (var key in atmVols.Keys)
            {
                volatilities[row]    = new object[3];
                volatilities[row][0] = key;
                volatilities[row][1] = atmVols[key];
                volatilities[row][2] = volType[row++];
            }
            var convertedCapFloor = new CapFloorATMMatrix(headers, volatilities, capFloor.GetVolatilitySettings(),
                                                          capFloor.baseDate.Value, capFloor.id);

            return(ProcessCapFloorATM(logger, cache, nameSpace, rateCurve, convertedCapFloor));
        }
Exemplo n.º 17
0
        ///<summary>
        ///</summary>
        ///<param name="directionDateGeneration"></param>
        ///<param name="effectiveDate"></param>
        ///<param name="terminationDate"></param>
        ///<param name="periodInterval"></param>
        ///<param name="rollDayConvention"></param>
        ///<returns></returns>
        ///<exception cref="ArgumentOutOfRangeException"></exception>
        public static DateTime[] GetUnadjustedDates(int directionDateGeneration, DateTime effectiveDate, DateTime terminationDate, Period periodInterval, RollConventionEnum rollDayConvention)
        {
            DateTime firstRegularPeriodStartDate;
            DateTime lastRegularPeriodEndDate;

            switch (directionDateGeneration)
            {
            case 1:
            {
                var result =
                    new List <DateTime>(GetUnadjustedDatesFromEffectiveDate(effectiveDate,
                                                                            terminationDate,
                                                                            periodInterval,
                                                                            rollDayConvention,
                                                                            out
                                                                            firstRegularPeriodStartDate,
                                                                            out
                                                                            lastRegularPeriodEndDate));

                //  remove extra(faulty-generated) date from the end if a swap is shorter than a period
                //
                if (periodInterval.Add(effectiveDate) > terminationDate)
                {
                    result.RemoveAt(result.Count - 1);         //remove last element
                }
                // if there is a long stub at the back
                //
                if (result[0] != lastRegularPeriodEndDate &&
                    periodInterval.Add(lastRegularPeriodEndDate) < result[result.Count - 1])         //
                {
                    //  it it is  long - make it short
                    //
                    DateTime realLastRegularPeriodEndDate = periodInterval.Add(lastRegularPeriodEndDate);

                    result.Insert(result.Count - 1, realLastRegularPeriodEndDate);
                }
                return(result.ToArray());
            }

            case 2:
            {
                var result =
                    new List <DateTime>(GetUnadjustedDatesFromTerminationDate(effectiveDate,
                                                                              terminationDate,
                                                                              periodInterval,
                                                                              rollDayConvention,
                                                                              out
                                                                              firstRegularPeriodStartDate,
                                                                              out
                                                                              lastRegularPeriodEndDate));

                // if there is a long stub at the front
                //
                if (result[0] != firstRegularPeriodStartDate &&
                    periodInterval.Subtract(firstRegularPeriodStartDate) > result[0])
                // add a check if a period is short ...
                {
                    //  it it is long - make it short
                    //
                    DateTime realFirstRegularPeriodStartDate = periodInterval.Subtract(firstRegularPeriodStartDate);

                    result.Insert(1, realFirstRegularPeriodStartDate);
                }
                return(result.ToArray());
            }

            default:
            {
                const string message =
                    "Argument value is out of range. Only 1 and 2 are the valid values for this argument";

                throw new ArgumentOutOfRangeException(nameof(directionDateGeneration), directionDateGeneration,
                                                      message);
            }
            }
        }