/// <summary> /// Return a Cashflows object containing array of the payment calculation periods and array of principal exchanges. /// </summary> /// <param name="paymentCalendar"> </param> /// <param name="interestRateStream">The interest rate stream.</param> /// <param name="rollDates">The list of roll dates.</param> /// <returns></returns> public static Cashflows GetCashflows(List <DateTime> rollDates, IBusinessCalendar paymentCalendar, InterestRateStream interestRateStream) { CalculationPeriodsPrincipalExchangesAndStubs calculationPeriodsPrincipalExchangesAndStubs = StreamCashflowsGenerator.GenerateCalculationPeriodsPrincipalExchangesAndStubsFromRollDates(interestRateStream, rollDates, paymentCalendar); return(GetCashfows(interestRateStream, calculationPeriodsPrincipalExchangesAndStubs, paymentCalendar)); }
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(); } }
/// <summary> /// Return a Cashflows object containing array of the payment calculation periods and array of principal exchanges. /// </summary> /// <param name="interestRateStream">The interest rate stream.</param> /// <param name="fixingCalendar"> </param> /// <param name="paymentCalendar"> </param> /// <returns></returns> public static Cashflows GetCashflows(InterestRateStream interestRateStream, IBusinessCalendar fixingCalendar, IBusinessCalendar paymentCalendar) { CalculationPeriodsPrincipalExchangesAndStubs calculationPeriodsPrincipalExchangesAndStubs = StreamCashflowsGenerator.GenerateCalculationPeriodsPrincipalExchangesAndStubs(interestRateStream, fixingCalendar, paymentCalendar); return(GetCashfows(interestRateStream, calculationPeriodsPrincipalExchangesAndStubs, paymentCalendar)); }
private static Cashflows GetCashfows( InterestRateStream interestRateStream, CalculationPeriodsPrincipalExchangesAndStubs calculationPeriodsPrincipalExchangesAndStubs, IBusinessCalendar paymentCalendar) { // Assign notionals, rates, cap/floor rate, etc // StreamCashflowsGenerator.UpdateCalculationPeriodsData(interestRateStream, calculationPeriodsPrincipalExchangesAndStubs); List <PaymentCalculationPeriod> paymentCalculationPeriods = StreamCashflowsGenerator.GetPaymentCalculationPeriods(interestRateStream, calculationPeriodsPrincipalExchangesAndStubs, paymentCalendar); Calculation calculation = XsdClassesFieldResolver.CalculationPeriodAmountGetCalculation(interestRateStream.calculationPeriodAmount); UpdateNumberOfDaysAndYearFraction(paymentCalculationPeriods, calculation); return(CashflowsFactory.Create(paymentCalculationPeriods, calculationPeriodsPrincipalExchangesAndStubs.GetAllPrincipalExchanges(), true));//TODO THe cashflowsmatch paraqmeter at the end could be a problem! }
public List <DateTime> BuildDates(ILogger logger, ICoreCache cache, String nameSpace, BillSwapPricerDatesRange billSwapPricerDatesRange, IBusinessCalendar paymentCalendar) { CalculationPeriodFrequency frequency = CalculationPeriodFrequencyHelper.Parse(billSwapPricerDatesRange.RollFrequency, billSwapPricerDatesRange.RollConvention); StubPeriodTypeEnum? initialStub = null; if (!String.IsNullOrEmpty(billSwapPricerDatesRange.InitialStubPeriod)) { initialStub = EnumHelper.Parse <StubPeriodTypeEnum>(billSwapPricerDatesRange.InitialStubPeriod); } StubPeriodTypeEnum?finalStub = null; if (!String.IsNullOrEmpty(billSwapPricerDatesRange.FinalStubPeriod)) { finalStub = EnumHelper.Parse <StubPeriodTypeEnum>(billSwapPricerDatesRange.FinalStubPeriod); } //BusinessDayAdjustments adjustments = BusinessDayAdjustmentsHelper.Create(BusinessDayConventionEnum.NONE, ""); //if (paymentCalendar == null) //{ // paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, adjustments.businessCenters);//Make sure this builds a valid calendar! //} BusinessDayAdjustments calculationPeriodDayAdjustments = BusinessDayAdjustmentsHelper.Create(billSwapPricerDatesRange.BusinessDayConvention, billSwapPricerDatesRange.Calendar); if (paymentCalendar == null) { paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, calculationPeriodDayAdjustments.businessCenters, nameSpace); } CalculationPeriodsPrincipalExchangesAndStubs result = CalculationPeriodGenerator.GenerateAdjustedCalculationPeriods( billSwapPricerDatesRange.StartDate, billSwapPricerDatesRange.EndDate, billSwapPricerDatesRange.FirstRegularPeriodStartDate, frequency, calculationPeriodDayAdjustments, initialStub, finalStub, paymentCalendar ); foreach (CalculationPeriod regularCalculationPeriod in result.GetRegularAndStubPeriods()) { // Adjust both startDate & endDate of period // CalculationPeriodHelper.SetAdjustedDates(regularCalculationPeriod, AdjustedDateHelper.ToAdjustedDate(paymentCalendar, regularCalculationPeriod.unadjustedStartDate, calculationPeriodDayAdjustments), AdjustedDateHelper.ToAdjustedDate(paymentCalendar, regularCalculationPeriod.unadjustedEndDate, calculationPeriodDayAdjustments)); } var listResult = result.GetRegularAndStubPeriods().Select(regularCalculationPeriod => regularCalculationPeriod.adjustedStartDate).ToList(); listResult.Add(result.GetRegularAndStubPeriods()[result.GetRegularAndStubPeriods().Count - 1].adjustedEndDate); return(listResult); }
public static CalculationPeriodsPrincipalExchangesAndStubs GenerateAdjustedCalculationPeriods( DateTime unadjustedEffectiveDate, DateTime unadjustedTerminationDate, DateTime unadjustedFirstRollDate, //this one is still UN adjusted CalculationPeriodFrequency frequency, BusinessDayAdjustments calculationPeriodDatesAdjustments, StubPeriodTypeEnum?initialStubType, StubPeriodTypeEnum?finalStubType, IBusinessCalendar paymentCalendar) { #region Param check if (initialStubType.HasValue) { if ((initialStubType != StubPeriodTypeEnum.LongInitial) && (initialStubType != StubPeriodTypeEnum.ShortInitial)) { throw new ArgumentOutOfRangeException(nameof(initialStubType), initialStubType, "Wrong stub type."); } } if (finalStubType.HasValue) { if ((finalStubType == StubPeriodTypeEnum.LongFinal) && (initialStubType == StubPeriodTypeEnum.ShortFinal)) { throw new ArgumentOutOfRangeException(nameof(finalStubType), finalStubType, "Wrong stub type."); } } // if (!RollConventionEnumHelper.IsAdjusted(frequency.rollConvention, unadjustedFirstRollDate)) // { // string message = String.Format("First roll date {0}, should be pre-adjusted according to RollConvention {1}", unadjustedFirstRollDate, frequency.rollConvention); // throw new Exception(message); // } #endregion var result = new CalculationPeriodsPrincipalExchangesAndStubs(); // Start calculations from 'first roll date' and generate dates backwards and forwards // // Generate periods backwards (toward the unadjustedEffectiveDate) // GeneratePeriodsBackward(unadjustedFirstRollDate, frequency, calculationPeriodDatesAdjustments, result, unadjustedEffectiveDate, initialStubType, paymentCalendar); // Generate periods forwards (toward the unadjustedTerminationDate) // GeneratePeriodsForward(unadjustedFirstRollDate, frequency, calculationPeriodDatesAdjustments, result, unadjustedTerminationDate, finalStubType, paymentCalendar); return(result); }
//public static CalculationPeriodsPrincipalExchangesAndStubs GenerateUnadjustedCalculationPeriods( // IBusinessCalendar paymentCalendar, // DateTime unadjustedStartDate, // DateTime unadjustedEndDate, // CalculationPeriodFrequency frequency, // StubPeriodTypeEnum? initialStubType, // StubPeriodTypeEnum? finalStubType // ) //{ // // If first roll date not specified - calculate it from the start date. // // // DateTime unadjustedFirstRollDate = AddPeriod(unadjustedStartDate, frequency, 1); // return GenerateUnadjustedCalculationPeriods(unadjustedStartDate, unadjustedEndDate, unadjustedFirstRollDate, frequency, initialStubType, finalStubType); //} public static CalculationPeriodsPrincipalExchangesAndStubs GenerateAdjustedCalculationPeriods( DateTime unadjustedStartDate, DateTime unadjustedTerminationDate, DateTime?firstUnadjustedRegularPeriodStartDate, DateTime?lastUnadjustedRegularPeriodEndDate, CalculationPeriodFrequency frequency, BusinessDayAdjustments calculationPeriodDatesAdjustments, IBusinessCalendar paymentCalendar) { var result = new CalculationPeriodsPrincipalExchangesAndStubs(); // Generate periods backwards (toward the unadjustedEffectiveDate) // GeneratePeriods(unadjustedStartDate, unadjustedTerminationDate, firstUnadjustedRegularPeriodStartDate, lastUnadjustedRegularPeriodEndDate, frequency, calculationPeriodDatesAdjustments, result, paymentCalendar); result.CalculationPeriods.Sort((calculationPeriod1, calculationPeriod2) => calculationPeriod1.adjustedEndDate.CompareTo(calculationPeriod2.adjustedEndDate)); 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; } }
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); }
/// <summary> /// Update calculation periods with rates/notional. /// </summary> /// <param name="interestRateStream"></param> /// <param name="calculationPeriodsPrincipalExchangesAndStubs"></param> public static void UpdateCalculationPeriodsData(InterestRateStream interestRateStream, CalculationPeriodsPrincipalExchangesAndStubs calculationPeriodsPrincipalExchangesAndStubs) { Calculation calculation = XsdClassesFieldResolver.CalculationPeriodAmountGetCalculation(interestRateStream.calculationPeriodAmount); Notional notionalSchedule = XsdClassesFieldResolver.CalculationGetNotionalSchedule(calculation); #region Generate FUTURE amounts for principle exchanges // Initial PE // if (null != calculationPeriodsPrincipalExchangesAndStubs.InitialPrincipalExchange) { // initial OUTflow // decimal initialNotionalValue = ScheduleHelper.GetValue(notionalSchedule.notionalStepSchedule, calculationPeriodsPrincipalExchangesAndStubs.InitialPrincipalExchange.adjustedPrincipalExchangeDate); calculationPeriodsPrincipalExchangesAndStubs.InitialPrincipalExchange.principalExchangeAmount = -initialNotionalValue; calculationPeriodsPrincipalExchangesAndStubs.InitialPrincipalExchange.principalExchangeAmountSpecified = true; } // intermediatory PE // foreach (PrincipalExchange intermediatoryExchange in calculationPeriodsPrincipalExchangesAndStubs.IntermediatePrincipalExchanges) { DateTime principleExchangeDate = intermediatoryExchange.adjustedPrincipalExchangeDate; //value at the day before principle exchange day // decimal prevNotionalValue = ScheduleHelper.GetValue(notionalSchedule.notionalStepSchedule, principleExchangeDate.AddDays(-1)); //value at principle exchange day .. // decimal newNotionalValue = ScheduleHelper.GetValue(notionalSchedule.notionalStepSchedule, principleExchangeDate); decimal principalExchangeAmount = prevNotionalValue - newNotionalValue; intermediatoryExchange.principalExchangeAmount = principalExchangeAmount; intermediatoryExchange.principalExchangeAmountSpecified = true; } // Final PE // if (null != calculationPeriodsPrincipalExchangesAndStubs.FinalPrincipalExchange) { // pay the rest ot the notional back // decimal newNotionalValue = ScheduleHelper.GetValue(notionalSchedule.notionalStepSchedule, calculationPeriodsPrincipalExchangesAndStubs.FinalPrincipalExchange.adjustedPrincipalExchangeDate); calculationPeriodsPrincipalExchangesAndStubs.FinalPrincipalExchange.principalExchangeAmount = newNotionalValue; calculationPeriodsPrincipalExchangesAndStubs.FinalPrincipalExchange.principalExchangeAmountSpecified = true; } #endregion // Process standard calculation periods // foreach (CalculationPeriod calculationPeriod in calculationPeriodsPrincipalExchangesAndStubs.CalculationPeriods) { UpdateCalculationPeriodData(calculation, calculationPeriod, notionalSchedule); } // Process stub calculation periods // if (null != interestRateStream.stubCalculationPeriodAmount) { if ((null == interestRateStream.stubCalculationPeriodAmount.initialStub) && (null == interestRateStream.stubCalculationPeriodAmount.finalStub)) { throw new System.Exception( "interestRateStream.stubCalculationPeriodAmount.initialStub && interestRateStream.stubCalculationPeriodAmount.finalStub are null"); } StubValue initialStub = interestRateStream.stubCalculationPeriodAmount.initialStub; StubValue finalStub = interestRateStream.stubCalculationPeriodAmount.finalStub; if (null != calculationPeriodsPrincipalExchangesAndStubs.InitialStubCalculationPeriod && null != initialStub) { UpdateStubCalculationPeriodData(interestRateStream, calculationPeriodsPrincipalExchangesAndStubs.InitialStubCalculationPeriod, initialStub, notionalSchedule); } if (null != calculationPeriodsPrincipalExchangesAndStubs.FinalStubCalculationPeriod && null != finalStub) { UpdateStubCalculationPeriodData(interestRateStream, calculationPeriodsPrincipalExchangesAndStubs.FinalStubCalculationPeriod, finalStub, notionalSchedule); } } else { foreach (CalculationPeriod calculationPeriod in new[] { calculationPeriodsPrincipalExchangesAndStubs.InitialStubCalculationPeriod, calculationPeriodsPrincipalExchangesAndStubs.FinalStubCalculationPeriod }) { if (null != calculationPeriod) { UpdateCalculationPeriodData(calculation, calculationPeriod, notionalSchedule); } } } }
/// <summary> /// Don't generate stubs? /// </summary> /// <param name="interestRateStream"></param> /// <param name="rollDates">from #1st roll date to last roll date (last roll dates is effectively the end of the swap)</param> /// <param name="paymentCalendar"></param> /// <returns></returns> public static CalculationPeriodsPrincipalExchangesAndStubs GenerateCalculationPeriodsPrincipalExchangesAndStubsFromRollDates(InterestRateStream interestRateStream, List <DateTime> rollDates, IBusinessCalendar paymentCalendar) { CalculationPeriodDates calculationPeriodDates = interestRateStream.calculationPeriodDates; AdjustableDate adjustableEffectiveDate = XsdClassesFieldResolver.CalculationPeriodDatesGetEffectiveDate(calculationPeriodDates); var result = new CalculationPeriodsPrincipalExchangesAndStubs(); for (int rollDateIndex = 0; rollDateIndex < rollDates.Count - 1; ++rollDateIndex) { DateTime startOfThePeriod = rollDates[rollDateIndex]; DateTime endOfThePeriod = rollDates[rollDateIndex + 1]; var calculationPeriod = new CalculationPeriod(); // Set adjusted period dates // CalculationPeriodHelper.SetAdjustedDates(calculationPeriod, startOfThePeriod, endOfThePeriod); result.Add(calculationPeriod); } // Add principle exchanges if this need is defined in parametric representation of the interest rate steam. // if (null != interestRateStream.principalExchanges) { // Initial PE // if (interestRateStream.principalExchanges.initialExchange) { //if (paymentCalendar == null) //{ // paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, adjustableEffectiveDate.dateAdjustments.businessCenters); //} PrincipalExchange initialExchange = PrincipalExchangeHelper.Create(AdjustedDateHelper.ToAdjustedDate(paymentCalendar, adjustableEffectiveDate)); result.InitialPrincipalExchange = initialExchange; } // intermediatory PE // if (interestRateStream.principalExchanges.intermediateExchange) { // Generate a list of intermediatory PE exchanges // Calculation calculation = XsdClassesFieldResolver.CalculationPeriodAmountGetCalculation(interestRateStream.calculationPeriodAmount); 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); } } } //AdjustableDate adjustableTerminationDate = XsdClassesFieldResolver.CalculationPeriodDates_GetTerminationDate(calculationPeriodDates); DateTime lastRollDate = rollDates[rollDates.Count - 1]; // Final PE // if (interestRateStream.principalExchanges.finalExchange) { //PrincipalExchange finalExchange = PrincipalExchangeHelper.Create(DateTypesHelper.ToAdjustedDate(adjustableTerminationDate)); PrincipalExchange finalExchange = PrincipalExchangeHelper.Create(lastRollDate); result.FinalPrincipalExchange = finalExchange; } } return(result); }
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); }
private static IEnumerable <List <CalculationPeriod> > SplitCalculationPeriodsByPaymentPeriods(CalculationPeriodsPrincipalExchangesAndStubs calculationPeriods, int calculationPeriodsInPaymentPeriod) { var result = new List <List <CalculationPeriod> >(); if (0 != calculationPeriods.CalculationPeriods.Count % calculationPeriodsInPaymentPeriod) { throw new System.Exception( $"Invalid number of calculation periods {calculationPeriods.CalculationPeriods.Count}. Calculation periods per payment period : {calculationPeriodsInPaymentPeriod}"); } int calculationPeriodIndex = 0; while (calculationPeriodIndex < calculationPeriods.CalculationPeriods.Count) { List <CalculationPeriod> item = calculationPeriods.CalculationPeriods.GetRange(calculationPeriodIndex, calculationPeriodsInPaymentPeriod); result.Add(item); calculationPeriodIndex += calculationPeriodsInPaymentPeriod; } return(result); }