/// <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)); }
/// <summary> /// if x < y return -1 /// if x > y return 1 /// if x = y return 0 /// </summary> /// <param name="x">The key - x</param> /// <param name="y">The key - y</param> /// <returns>An indication of the relative positions of x and y</returns> public int Compare(ExpiryTenorStrikeKey x, ExpiryTenorStrikeKey y) { // Test x and y as intervals Expiry before Tenor? var xExpiryAsInterval = x.Expiry; var xTenorAsInterval = x.Tenor; var yExpiryAsInterval = y.Expiry; var yTenorAsInterval = y.Tenor; var xStrike = x.Strike; var yStrike = y.Strike; // Test equality if (IntervalHelper.Less(xExpiryAsInterval, yExpiryAsInterval)) { return(-1); } if (IntervalHelper.Greater(xExpiryAsInterval, yExpiryAsInterval)) { return(1); } if (IntervalHelper.Less(xTenorAsInterval, yTenorAsInterval)) { return(-1); } if (IntervalHelper.Greater(xTenorAsInterval, yTenorAsInterval)) { return(1); } if (xStrike < yStrike) { return(-1); } return(xStrike > yStrike ? 1 : 0); }
public void ValidateInputRequest(ILogger log) { const string NO_INTERVAL = "Device model telemetry must contains a valid interval"; const string NO_MESSAGE_TEMPLATE = "Device model telemetry must contains a valid message template"; const string NO_MESSAGE_SCHEMA = "Device model telemetry must contains a valid message schema"; try { IntervalHelper.ValidateInterval(this.Interval); } catch (InvalidIntervalException exception) { log.Error(NO_INTERVAL, () => new { deviceModelTelemetry = this, exception }); throw new BadRequestException(NO_INTERVAL); } if (string.IsNullOrEmpty(this.MessageTemplate)) { log.Error(NO_MESSAGE_TEMPLATE, () => new { deviceModelTelemetry = this }); throw new BadRequestException(NO_MESSAGE_TEMPLATE); } if (this.MessageSchema.IsEmpty()) { log.Error(NO_MESSAGE_SCHEMA, () => new { deviceModelTelemetry = this }); throw new BadRequestException(NO_MESSAGE_SCHEMA); } }
public void GetUnadjustedDates3Forward() { DateTime startDate = new DateTime(2008, 04, 10); DateTime endDate = new DateTime(2009, 04, 24); //Period interval = IntervalHelper.FromMonths(3); RollConventionEnum rollConventionEnum = RollConventionEnumHelper.Parse(startDate.Day.ToString()); List<MetaScheduleItem> rollsMetaSchedule = new List<MetaScheduleItem>(); MetaScheduleItem item1 = new MetaScheduleItem(); item1.Period = IntervalHelper.FromMonths(6); item1.RollFrequency = IntervalHelper.FromMonths(1); item1.RollConvention = rollConventionEnum; rollsMetaSchedule.Add(item1); MetaScheduleItem item2 = new MetaScheduleItem(); item2.Period = IntervalHelper.FromMonths(6); item2.RollFrequency = IntervalHelper.FromMonths(3); item2.RollConvention = rollConventionEnum; rollsMetaSchedule.Add(item2); List<DateTime> unadjustedDates = DatesMetaSchedule.GetUnadjustedDates3(startDate, endDate, rollsMetaSchedule, false); Debug.Print("Meta schedule:"); // Debug.Print(ParameterFormatter.FormatObject(ObjectToArrayOfPropertiesConverter.ConvertListToHorizontalArrayRange(rollsMetaSchedule))); Debug.Print("Start date: {0}", startDate); Debug.Print("End date: {0}", endDate); Debug.Print("Schedule:"); PrintListOfDates(unadjustedDates); }
// Validate device model simulation state: // Required fields: Interval and Scripts public void ValidateInputRequest(ILogger log) { const string NO_INTERVAL = "Device model simulation state must contains a valid interval"; const string NO_SCRIPTS = "Device model simulation state must contains a valid script"; try { IntervalHelper.ValidateInterval(this.Interval); } catch (InvalidIntervalException exception) { log.Error(NO_INTERVAL, () => new { deviceModelSimulation = this, exception }); throw new BadRequestException(NO_INTERVAL); } if (this.Scripts == null || this.Scripts.Count == 0) { log.Error(NO_SCRIPTS, () => new { deviceModelSimulation = this }); throw new BadRequestException(NO_SCRIPTS); } else { foreach (var script in this.Scripts) { script.ValidateInputRequest(log); } } }
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(); } }
//use this to set up time buckets for trade private static int[] GetDayIntervalOffsets(DateTime referenceDate, DateTime maturityDate, string intervalString, out DateTime[] dates) { List <int> result = new List <int>(); List <DateTime> datesList = new List <DateTime>(); DateTime baseDate = new DateTime(referenceDate.Year, referenceDate.Month, referenceDate.Day); const int cZeroDaysOffset = 0; DateTime offSetDate = baseDate; if (offSetDate.CompareTo(maturityDate) <= 0) { result.Add(cZeroDaysOffset); datesList.Add(offSetDate); } Interval interval = IntervalHelper.Parse(intervalString); DateTime newDate = DateHelper.AddPeriod(offSetDate, interval, 1); while (newDate.CompareTo(maturityDate) <= 0) { int noOfDaysOffset = (newDate - offSetDate).Days; result.Add(result[result.Count - 1] + noOfDaysOffset); offSetDate = newDate; datesList.Add(offSetDate); newDate = DateHelper.AddPeriod(offSetDate, interval, 1); } dates = datesList.ToArray(); return(result.ToArray()); }
/// <summary> /// Deal settle. /// </summary> /// <param name="dealDate"></param> /// <param name="settC"></param> /// <param name="hols"></param> /// <returns></returns> public static DateTime SettFromDeal(DateTime dealDate, BondSettlementEnum settC, IBusinessCalendar hols) { switch (settC) { case BondSettlementEnum.SC_dealDate: return(dealDate); case BondSettlementEnum.SC_1bd: return(hols.Advance(dealDate, OffsetHelper.FromInterval(IntervalHelper.FromDays(1), DayTypeEnum.Business), BusinessDayConventionEnum.FOLLOWING)); case BondSettlementEnum.SC_2bd: return(hols.Advance(dealDate, OffsetHelper.FromInterval(IntervalHelper.FromDays(2), DayTypeEnum.Business), BusinessDayConventionEnum.FOLLOWING)); case BondSettlementEnum.SC_1b1cd: return(hols.Advance(dealDate, OffsetHelper.FromInterval(IntervalHelper.FromDays(1), DayTypeEnum.Business), BusinessDayConventionEnum.FOLLOWING).AddDays(1)); case BondSettlementEnum.SC_3bd: case BondSettlementEnum.SC_3bd_6bdLO: return(hols.Advance(dealDate, OffsetHelper.FromInterval(IntervalHelper.FromDays(3), DayTypeEnum.Business), BusinessDayConventionEnum.FOLLOWING)); case BondSettlementEnum.SC_3b1cd: return(hols.Advance(dealDate, OffsetHelper.FromInterval(IntervalHelper.FromDays(3), DayTypeEnum.Business), BusinessDayConventionEnum.FOLLOWING).AddDays(1)); case BondSettlementEnum.SC_4bd: case BondSettlementEnum.SC_4bd_6bdLO: return(hols.Advance(dealDate, OffsetHelper.FromInterval(IntervalHelper.FromDays(4), DayTypeEnum.Business), BusinessDayConventionEnum.FOLLOWING)); case BondSettlementEnum.SC_5bd: return(hols.Advance(dealDate, OffsetHelper.FromInterval(IntervalHelper.FromDays(5), DayTypeEnum.Business), BusinessDayConventionEnum.FOLLOWING)); case BondSettlementEnum.SC_7bd: return(hols.Advance(dealDate, OffsetHelper.FromInterval(IntervalHelper.FromDays(7), DayTypeEnum.Business), BusinessDayConventionEnum.FOLLOWING)); case BondSettlementEnum.SC_3d: return(hols.Roll(dealDate.AddDays(3), BusinessDayConventionEnum.FOLLOWING)); case BondSettlementEnum.SC_7d: return(hols.Roll(dealDate.AddDays(7), BusinessDayConventionEnum.FOLLOWING)); case BondSettlementEnum.SC_7c1bd: return(hols.Advance(dealDate, OffsetHelper.FromInterval(IntervalHelper.FromDays(7), DayTypeEnum.Business), BusinessDayConventionEnum.FOLLOWING)); case BondSettlementEnum.SC_3cd: return(hols.Roll(dealDate.AddDays(3), BusinessDayConventionEnum.FOLLOWING)); // case BondSettlementHelper.BondSettlementEnum.SC_Canada: // return default: return(hols.Advance(dealDate, OffsetHelper.FromInterval(IntervalHelper.FromDays(1), DayTypeEnum.Business), BusinessDayConventionEnum.FOLLOWING)); } /* switch (settC) * { * case SC_Canada: * CalendarDate(ym, mm, dm, maturityDate); * return TCs->NextBizDay(dealDate, 2 + (dealDate <= UnadjustedDate(ym - 3, mm, dm))); * * case SC_Austria: return TCs->NextBizDay(dealDate + 15 - DayOfWeek(dealDate), 0); * * case SC_Australia: * CalendarDate(ym, mm, dm, maturityDate); * return TCs->NextBizDay(dealDate, dealDate > UnadjustedDate(ym, mm - 6, dm) ? 1 : 3); * * case SC_SouthAfrica: * settDate = dealDate + 15 - DayOfWeek(dealDate + 4); * if (!TCs->IsBizDay(settDate + 1)) settDate--; * return settDate; * } * return dealDate;*/ }
/// <summary> /// </summary> /// <param name="cache"></param> /// <param name="interestRateStream"></param> /// <param name="listCalculationPeriods"></param> /// <param name="fixingCalendar"></param> /// <param name="nameSpace"></param> /// <returns></returns> /// <exception cref="NotSupportedException"></exception> /// <exception cref="NotImplementedException"></exception> public static List <DateTime> GetAdjustedResetDates(ICoreCache cache, InterestRateStream interestRateStream, List <CalculationPeriod> listCalculationPeriods, IBusinessCalendar fixingCalendar, string nameSpace) { var adjustedResetDates = new List <DateTime>(); ResetDates resetDates = interestRateStream.resetDates; Period resetFrequency = IntervalHelper.FromFrequency(resetDates.resetFrequency); Period calculationPeriodFrequency = IntervalHelper.FromFrequency(interestRateStream.calculationPeriodDates.calculationPeriodFrequency); if (resetFrequency.period != calculationPeriodFrequency.period) { throw new NotSupportedException( $"Reset period type ({resetFrequency.period}) and calculation period type ({calculationPeriodFrequency.period}) are different. This is not supported."); } if (int.Parse(resetFrequency.periodMultiplier) != int.Parse(calculationPeriodFrequency.periodMultiplier)) { throw new NotSupportedException( $"Reset period frequency ({resetFrequency.period}) is not equal to calculation period frequency ({calculationPeriodFrequency.period}). This is not supported."); } BusinessDayAdjustments resetDatesAdjustments = resetDates.resetDatesAdjustments; ResetRelativeToEnum resetRelativeTo = resetDates.resetRelativeTo; if (fixingCalendar == null) { fixingCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, resetDatesAdjustments.businessCenters, nameSpace); } foreach (CalculationPeriod calculationPeriodsInPaymentPeriod in listCalculationPeriods) { switch (resetRelativeTo) { case ResetRelativeToEnum.CalculationPeriodStartDate: { DateTime unadjustedResetDate = calculationPeriodsInPaymentPeriod.unadjustedStartDate; DateTime adjustedResetDate = AdjustedDateHelper.ToAdjustedDate(fixingCalendar, unadjustedResetDate, resetDatesAdjustments); adjustedResetDates.Add(adjustedResetDate); break; } case ResetRelativeToEnum.CalculationPeriodEndDate: { DateTime unadjustedResetDate = calculationPeriodsInPaymentPeriod.unadjustedEndDate; DateTime adjustedResetDate = AdjustedDateHelper.ToAdjustedDate(fixingCalendar, unadjustedResetDate, resetDatesAdjustments); adjustedResetDates.Add(adjustedResetDate); break; } default: { throw new NotImplementedException("resetRelativeTo"); } } } return(adjustedResetDates); }
public void GetUnadjustedDates2Forward() { DateTime startDate = new DateTime(2008, 04, 10); DateTime endDate = new DateTime(2009, 04, 24); Period interval = IntervalHelper.FromMonths(3); RollConventionEnum rollConventionEnum = RollConventionEnumHelper.Parse(startDate.Day.ToString()); List<DateTime> unadjustedDates = DatesMetaSchedule.GetUnadjustedDates2(startDate, endDate, interval, rollConventionEnum, false); PrintListOfDates(unadjustedDates); }
public void GetLastMounthTest() { //Arrange var currentTime = new DateTime(2013, 01, 25, 12, 35, 10).AddTicks(12376584687);; var helper = new IntervalHelper(); //Act var interval = helper.GetLastMonth(currentTime); //Assert Assert.AreEqual(new DateTime(2012, 12, 27, 0, 0, 0), interval.Start); Assert.AreEqual(new DateTime(2013, 01, 26, 0, 0, 0), interval.Finish); }
public void GetMillisecondsToEndDayTest() { //Arrange var currentTime = new DateTime(2013, 01, 25, 12, 35, 10); var appenedTime = new TimeSpan(0, 0, 1, 0); var helper = new IntervalHelper(); //Act var interval = helper.GetMillisecondsToEndDay(appenedTime, currentTime); //Assert Assert.AreEqual(41090000 + 60000, interval); }
public void GetLastDateTest() { //Arrange var currentTime = new DateTime(2013, 01, 25, 12, 35, 10).AddTicks(12376584687); var helper = new IntervalHelper(); //Act var yesterday = helper.GetLastDate(1, currentTime); var twoDayBefore = helper.GetLastDate(2, currentTime); //Assert Assert.AreEqual(new DateTime(2013, 01, 24, 0, 0, 0), yesterday); Assert.AreEqual(new DateTime(2013, 01, 23, 0, 0, 0), twoDayBefore); }
public void GetAllDaysTest() { //Arrange var dateTime = new DateTime(2013, 02, 25, 12, 35, 10); var helper = new IntervalHelper(); //Act var interval = helper.GetAllDays(dateTime); //Assert Assert.AreEqual(new DateTime(2013, 02, 26), interval.Finish); Assert.AreEqual(new DateTime(2013, 01, 31), interval.Start); }
public void GetIntervalTest() { //Arrange var start = new DateTime(2013, 8, 1); var end = new DateTime(2013, 8, 12); var helper = new IntervalHelper(); //Act var interval = helper.GetInterval(start, end); //Assert Assert.AreEqual(start, interval.Start); Assert.AreEqual(new DateTime(2013, 8, 13), interval.Finish); }
/// <summary> /// Calculates the modes of a collection of numbers using the specified discretization unit epsilon. /// </summary> /// <param name="numbers">The collection whose modes are to be calculated.</param> /// <param name="discretizationEpsilon">Discretization unit epsilon.</param> /// <returns> /// An array containing the arithmetic mean of all intervals /// (that are at most one epsilon wide) with the most occurences. /// </returns> public static double[] Modes(IEnumerable <double> numbers, double discretizationEpsilon) { if (numbers == null) { throw ArgumentNullException; } if (!numbers.Any()) { throw EmptyNumbersCollectionException; } LinkedList <Interval> bestIntervals = new LinkedList <Interval>(); int maxCount = 0; // Sort numbers IOrderedEnumerable <double> sorted = numbers.OrderBy(x => x); // Iterate over all maximum-sized intervals foreach (Interval interval in IntervalHelper.Intervals(sorted, discretizationEpsilon)) { // If new maximum found, delete all maximums until now if (interval.ElementsInside > maxCount) { maxCount = interval.ElementsInside; bestIntervals.Clear(); } // Save this interval as a maximum one if necessary if (interval.ElementsInside == maxCount) { bestIntervals.AddLast(interval); } } // Return the arithmetic mean of the mid points return(bestIntervals .Select(x => x.MidPoint) .ToArray()); }
/// <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); }
public static List <PaymentCalculationPeriod> GetPaymentCalculationPeriods(InterestRateStream interestRateStream, CalculationPeriodsPrincipalExchangesAndStubs listCalculationPeriods, IBusinessCalendar paymentCalendar) { var result = new List <PaymentCalculationPeriod>(); // Calculate how much calculation periods comprise one payment calculation period // PaymentDates paymentDates = interestRateStream.paymentDates; Period paymentFrequency = IntervalHelper.FromFrequency(paymentDates.paymentFrequency); Period calculationPeriodFrequency = IntervalHelper.FromFrequency(interestRateStream.calculationPeriodDates.calculationPeriodFrequency); // If the payment frequency is less frequent than the frequency defined in the calculation period dates component //then more than one calculation period will contribute to e payment amount. // A payment frequency more frequent than the calculation period frequency //or one that is not a multiple of the calculation period frequency is invalid. if (paymentFrequency.period != calculationPeriodFrequency.period) { throw new NotSupportedException( $"Payment period type ({paymentFrequency.period}) and calculation period type ({calculationPeriodFrequency.period}) are different. This is not supported."); } if (0 != int.Parse(paymentFrequency.periodMultiplier) % int.Parse(calculationPeriodFrequency.periodMultiplier)) { throw new NotSupportedException(String.Format("Payment period frequency is not a multiple of the calculation period frequency. This is not supported.")); } if (int.Parse(paymentFrequency.periodMultiplier) < int.Parse(calculationPeriodFrequency.periodMultiplier)) { throw new NotSupportedException(String.Format("A payment frequency more frequent than the calculation period frequency. This is not supported.")); } int calculationPeriodsInPaymentPeriod = int.Parse(paymentFrequency.periodMultiplier) / int.Parse(calculationPeriodFrequency.periodMultiplier); IEnumerable <List <CalculationPeriod> > listOfCalculationPeriodsInSinglePayPeriod = SplitCalculationPeriodsByPaymentPeriods(listCalculationPeriods, calculationPeriodsInPaymentPeriod); Offset paymentDaysOffset = paymentDates.paymentDaysOffset; BusinessDayAdjustments paymentDatesBusinessDayAdjustments = paymentDates.paymentDatesAdjustments; PayRelativeToEnum payRelativeTo = paymentDates.payRelativeTo; //if (paymentCalendar == null) //{ // paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, paymentDatesBusinessDayAdjustments.businessCenters); //} // Initial stub // if (listCalculationPeriods.HasInitialStub) { var paymentCalculationPeriod = new PaymentCalculationPeriod { adjustedPaymentDate = CalculatePaymentDate(paymentDates, payRelativeTo, new List <CalculationPeriod>( new[] { listCalculationPeriods. InitialStubCalculationPeriod }), paymentDaysOffset, paymentDatesBusinessDayAdjustments, paymentCalendar), adjustedPaymentDateSpecified = true }; XsdClassesFieldResolver.SetPaymentCalculationPeriodCalculationPeriodArray(paymentCalculationPeriod, new[] { listCalculationPeriods.InitialStubCalculationPeriod }); result.Add(paymentCalculationPeriod); } // Regular periods // foreach (List <CalculationPeriod> calculationPeriodsInPamentPeriod in listOfCalculationPeriodsInSinglePayPeriod) { var paymentCalculationPeriod = new PaymentCalculationPeriod { adjustedPaymentDate = CalculatePaymentDate(paymentDates, payRelativeTo, calculationPeriodsInPamentPeriod, paymentDaysOffset, paymentDatesBusinessDayAdjustments, paymentCalendar), adjustedPaymentDateSpecified = true }; XsdClassesFieldResolver.SetPaymentCalculationPeriodCalculationPeriodArray(paymentCalculationPeriod, calculationPeriodsInPamentPeriod.ToArray()); result.Add(paymentCalculationPeriod); } // Final stub // if (listCalculationPeriods.HasFinalStub) { var paymentCalculationPeriod = new PaymentCalculationPeriod { adjustedPaymentDate = CalculatePaymentDate(paymentDates, payRelativeTo, new List <CalculationPeriod>( new[] { listCalculationPeriods. FinalStubCalculationPeriod }), paymentDaysOffset, paymentDatesBusinessDayAdjustments, paymentCalendar), adjustedPaymentDateSpecified = true }; XsdClassesFieldResolver.SetPaymentCalculationPeriodCalculationPeriodArray(paymentCalculationPeriod, new[] { listCalculationPeriods.FinalStubCalculationPeriod }); result.Add(paymentCalculationPeriod); } return(result); }
public static void GeneratePeriods(DateTime unadjustedStartDate, DateTime unadjustedTerminationDate, DateTime?firstUnadjustedRegularPeriodStartDate, DateTime?lastUnadjustedRegularPeriodEndDate, //StubPeriodTypeEnum? initialStubType, //StubPeriodTypeEnum? finalStubType, CalculationPeriodFrequency frequency, BusinessDayAdjustments calculationPeriodDatesAdjustments, CalculationPeriodsPrincipalExchangesAndStubs result, IBusinessCalendar paymentCalendar) { DateTime periodEndDate = unadjustedTerminationDate; DateTime periodStartDate; bool isInitialStub = firstUnadjustedRegularPeriodStartDate != null; var startDate = unadjustedStartDate; if (isInitialStub) { startDate = (DateTime)firstUnadjustedRegularPeriodStartDate; } var isFinalStub = lastUnadjustedRegularPeriodEndDate != null; if (isFinalStub) { periodStartDate = (DateTime)lastUnadjustedRegularPeriodEndDate; } else { periodStartDate = AddPeriod(periodEndDate, IntervalHelper.FromFrequency(frequency), -1); } var isFirstPeriod = true; do { var calculationPeriod = Create(periodStartDate, periodEndDate, frequency, calculationPeriodDatesAdjustments, paymentCalendar, isFirstPeriod); isFirstPeriod = false; //adjust for roll convention. periodStartDate = calculationPeriod.unadjustedStartDate; periodEndDate = calculationPeriod.unadjustedEndDate; if (isFinalStub)//Always at least one period. { result.FinalStubCalculationPeriod = calculationPeriod; periodEndDate = periodStartDate; periodStartDate = AddPeriod(periodEndDate, IntervalHelper.FromFrequency(frequency), -1); isFinalStub = false; } else if (calculationPeriod.unadjustedStartDate.Date >= startDate.Date) { result.Add(calculationPeriod); periodEndDate = periodStartDate; periodStartDate = AddPeriod(periodEndDate, IntervalHelper.FromFrequency(frequency), -1); } else if (calculationPeriod.unadjustedStartDate.Date == startDate.Date)//first period - not stub { result.Add(calculationPeriod); break; } else if (calculationPeriod.unadjustedStartDate.Date < startDate.Date)//first period - not stub { var number = result.CalculationPeriods.Count; result.CalculationPeriods[number - 1].unadjustedStartDate = startDate.Date; result.CalculationPeriods[number - 1].adjustedStartDate = startDate.Date; break; } if (calculationPeriod.unadjustedEndDate.Date <= startDate.Date)//first period - not stub { break; } } while (true); if (isInitialStub)//TODO -Fix the unadjustedstartdate which is affected by the roll convention. { var calculationPeriod = CreateStub(unadjustedStartDate, startDate.Date, calculationPeriodDatesAdjustments, paymentCalendar); result.InitialStubCalculationPeriod = calculationPeriod; } }
//<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()); }
public static CalculationPeriodsPrincipalExchangesAndStubs GenerateCalculationPeriodsPrincipalExchangesAndStubs( InterestRateStream interestRateStream, IBusinessCalendar fixingCalendar, IBusinessCalendar paymentCalendar) { CalculationPeriodDates calculationPeriodDates = interestRateStream.calculationPeriodDates; AdjustableDate adjustableEffectiveDate = XsdClassesFieldResolver.CalculationPeriodDatesGetEffectiveDate(calculationPeriodDates); AdjustableDate adjustableTerminationDate = XsdClassesFieldResolver.CalculationPeriodDatesGetTerminationDate(calculationPeriodDates); AdjustableDate adjustableFirstPeriodDate = adjustableEffectiveDate; DateTime?firstRegularPeriodStartDate = XsdClassesFieldResolver.CalculationPeriodDatesGetFirstRegularPeriodStartDate(calculationPeriodDates); var tempDate = XsdClassesFieldResolver.CalculationPeriodDatesGetFirstPeriodStartDate(calculationPeriodDates); if (tempDate != null && firstRegularPeriodStartDate != null) { adjustableFirstPeriodDate = tempDate; Frequency frequency = calculationPeriodDates.calculationPeriodFrequency; var startDate = CalculationPeriodGenerator.AddPeriod((DateTime)firstRegularPeriodStartDate, IntervalHelper.FromFrequency(frequency), -1); adjustableFirstPeriodDate.unadjustedDate = IdentifiedDateHelper.Create(startDate); } DateTime?lastRegularPeriodEndDate = XsdClassesFieldResolver.CalculationPeriodDatesGetLastRegularPeriodEndDate(calculationPeriodDates); // This assumes automatic adjustment of calculationperiods. CalculationPeriodsPrincipalExchangesAndStubs result = CalculationPeriodGenerator.GenerateAdjustedCalculationPeriods( adjustableFirstPeriodDate.unadjustedDate.Value, adjustableTerminationDate.unadjustedDate.Value, firstRegularPeriodStartDate, lastRegularPeriodEndDate, calculationPeriodDates.calculationPeriodFrequency, calculationPeriodDates.calculationPeriodDatesAdjustments, paymentCalendar); //Determine whether the reset dates must be calcuated. Calculation calculation = XsdClassesFieldResolver.CalculationPeriodAmountGetCalculation(interestRateStream.calculationPeriodAmount); // Add principle exchanges if this need is defined in parametric representation of the interest rate steam. // if (null != interestRateStream.principalExchanges) { //if (paymentCalendar == null) //{ // paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, adjustableEffectiveDate.dateAdjustments.businessCenters); //} // Initial PE // if (interestRateStream.principalExchanges.initialExchange) { PrincipalExchange initialExchange = PrincipalExchangeHelper.Create(AdjustedDateHelper.ToAdjustedDate(paymentCalendar, adjustableEffectiveDate)); result.InitialPrincipalExchange = initialExchange; } // intermediatory PE // if (interestRateStream.principalExchanges.intermediateExchange) { // Generate a list of intermediatory PE exchanges // Notional notionalSchedule = XsdClassesFieldResolver.CalculationGetNotionalSchedule(calculation); if (null != notionalSchedule.notionalStepSchedule.step)//there should be steps - otherwise NO interm. exchanges. { foreach (DateTime stepDate in ScheduleHelper.GetStepDates(notionalSchedule.notionalStepSchedule)) { PrincipalExchange intermediatoryExchange = PrincipalExchangeHelper.Create(stepDate); result.Add(intermediatoryExchange); } } } // Final PE // Assume the same calendar is used for the termination date as well! if (interestRateStream.principalExchanges.finalExchange) { PrincipalExchange finalExchange = PrincipalExchangeHelper.Create(AdjustedDateHelper.ToAdjustedDate(paymentCalendar, adjustableTerminationDate)); result.FinalPrincipalExchange = finalExchange; } } //Only does upfront resetRelativeTo start date. if (interestRateStream.resetDates != null && calculation.Items[0].GetType() == typeof(FloatingRateCalculation)) { //Get the fixing date convention. var fixingDateConvention = interestRateStream.resetDates.resetDatesAdjustments; //if (fixingCalendar == null) //{ // fixingCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, fixingDateConvention.businessCenters); //} foreach (var calculationPeriod in result.CalculationPeriods) { if (calculationPeriod.adjustedStartDateSpecified) { //Set the adjusted fixing date. var adjustedFixingDate = AdjustedDateHelper.ToAdjustedDate(fixingCalendar, calculationPeriod.adjustedStartDate, fixingDateConvention); var floatingRateDefinition = new FloatingRateDefinition(); var rateObservation = new RateObservation { observedRateSpecified = false, adjustedFixingDateSpecified = true, adjustedFixingDate = adjustedFixingDate }; floatingRateDefinition.rateObservation = new[] { rateObservation }; calculationPeriod.Item1 = floatingRateDefinition; } } //The initial stub period. if (result.InitialStubCalculationPeriod != null) { if (result.InitialStubCalculationPeriod.adjustedStartDateSpecified) { //Set the adjusted fixing date. var adjustedFixingDate = AdjustedDateHelper.ToAdjustedDate(fixingCalendar, result.InitialStubCalculationPeriod.adjustedStartDate, fixingDateConvention); var floatingRateDefinition = new FloatingRateDefinition(); var rateObservation = new RateObservation { observedRateSpecified = false, adjustedFixingDateSpecified = true, adjustedFixingDate = adjustedFixingDate }; floatingRateDefinition.rateObservation = new[] { rateObservation }; result.InitialStubCalculationPeriod.Item1 = floatingRateDefinition; } } //The final stub period if (result.FinalStubCalculationPeriod != null) { if (result.FinalStubCalculationPeriod.adjustedStartDateSpecified) { //Set the adjusted fixing date. var adjustedFixingDate = AdjustedDateHelper.ToAdjustedDate(fixingCalendar, result.FinalStubCalculationPeriod.adjustedStartDate, fixingDateConvention); var floatingRateDefinition = new FloatingRateDefinition(); var rateObservation = new RateObservation { observedRateSpecified = false, adjustedFixingDateSpecified = true, adjustedFixingDate = adjustedFixingDate }; floatingRateDefinition.rateObservation = new[] { rateObservation }; result.FinalStubCalculationPeriod.Item1 = floatingRateDefinition; } } } return(result); }