/// <summary>
        ///
        /// </summary>
        /// <param name="payerIsBase"></param>
        /// <param name="calculation"></param>
        /// <param name="coupon"></param>
        /// <param name="fOCalculationMethod"></param>
        /// <param name="fixingCalendar"></param>
        /// <param name="paymentCalendar"></param>
        /// <returns></returns>
        public static PriceableRateCoupon CreatePriceableCoupon(bool payerIsBase, Calculation calculation, PaymentCalculationPeriod coupon, bool fOCalculationMethod
                                                                , IBusinessCalendar fixingCalendar, IBusinessCalendar paymentCalendar)
        {
            var notional         = (Notional)calculation.Item;
            var currency         = notional.notionalStepSchedule.currency;
            var dayCountFraction = calculation.dayCountFraction;
            var paymentDate      = coupon.adjustedPaymentDateSpecified
                                  ? coupon.adjustedPaymentDate
                                  : coupon.unadjustedPaymentDate;
            var calculationPeriods      = XsdClassesFieldResolver.GetPaymentCalculationPeriodCalculationPeriodArray(coupon);
            var discountFactorSpecified = coupon.discountFactorSpecified;

            if (calculationPeriods.Length == 1)
            {
                var calculationPeriod = calculationPeriods[0];
                var notionalAmount    = XsdClassesFieldResolver.CalculationPeriodGetNotionalAmount(calculationPeriod);
                var money             = payerIsBase ? MoneyHelper.GetAmount(-1 * notionalAmount, currency) : MoneyHelper.GetAmount(notionalAmount, currency);
                var accrualStartDate  = calculationPeriod.adjustedStartDateSpecified
                                           ? calculationPeriod.adjustedStartDate
                                           : calculationPeriod.unadjustedStartDate;
                var accrualEndDate = calculationPeriod.adjustedEndDateSpecified
                                         ? calculationPeriod.adjustedEndDate
                                         : calculationPeriod.unadjustedEndDate;
                //  If has a fixed rate (fixed rate coupon)
                var isThereDiscounting = XsdClassesFieldResolver.CalculationHasDiscounting(calculation);
                PriceableRateCoupon rateCoupon;
                if (XsdClassesFieldResolver.CalculationPeriodHasFixedRate(calculationPeriod))
                {
                    decimal finalRate = XsdClassesFieldResolver.CalculationPeriodGetFixedRate(calculationPeriod);
                    //The discount rate must be set. It would normally be the final rate. The assumption is that, it the discounting rate is zero then the final rate should be used.
                    if (isThereDiscounting)
                    {
                        var discounting = XsdClassesFieldResolver.CalculationGetDiscounting(calculation);
                        //This test works because if the rate is zero, then the coupon is not discounted and discounting Type should be null.
                        var discountRate = discounting.discountRate == 0.0m ? finalRate : discounting.discountRate;
                        rateCoupon = new PriceableFixedRateCoupon(coupon.id, payerIsBase, accrualStartDate, accrualEndDate,
                                                                  dayCountFraction, finalRate, money, null, paymentDate, discounting.discountingType, discountRate,
                                                                  null, paymentCalendar);
                        if (discountFactorSpecified)
                        {
                            rateCoupon.PaymentDiscountFactor = coupon.discountFactor;
                        }
                        return(rateCoupon);
                    }
                    rateCoupon = new PriceableFixedRateCoupon(coupon.id, payerIsBase, accrualStartDate, accrualEndDate,
                                                              dayCountFraction, finalRate, money, null, paymentDate, null, null,
                                                              null, paymentCalendar);
                    if (discountFactorSpecified)
                    {
                        rateCoupon.PaymentDiscountFactor = coupon.discountFactor;
                    }
                    return(rateCoupon);
                }
                if (XsdClassesFieldResolver.CalculationPeriodHasFloatingRateDefinition(calculationPeriod))
                {
                    //The floating rate definition.
                    FloatingRateDefinition floatingRateDefinition = XsdClassesFieldResolver.CalculationPeriodGetFloatingRateDefinition(calculationPeriod);
                    //The floating rate Calculation.
                    Debug.Assert(calculation.Items != null);
                    Debug.Assert(calculation.Items.Length > 0);
                    Debug.Assert(calculation.Items[0] is FloatingRateCalculation);
                    var floatingRateCalculation = (FloatingRateCalculation)calculation.Items[0];
                    //The forecast rate index.
                    var floatingRateIndex = floatingRateCalculation.floatingRateIndex;
                    var indexTenor        = floatingRateCalculation.indexTenor.ToString();
                    var forecastRate      = ForecastRateIndexHelper.Parse(floatingRateIndex.Value, indexTenor);
                    //The rate observation
                    // Apply spread from schedule if it hasn't been specified yet.
                    var margin = 0m;
                    if (floatingRateDefinition.spreadSpecified)
                    {
                        margin = floatingRateDefinition.spread;
                    }
                    //The observed rate.
                    Decimal?observedRate = null;
                    Decimal?capStrike    = null;
                    Decimal?floorStrike  = null;
                    if (floatingRateDefinition.capRate != null)
                    {
                        capStrike = floatingRateDefinition.capRate[0].strikeRate;
                    }
                    if (floatingRateDefinition.floorRate != null)
                    {
                        floorStrike = floatingRateDefinition.floorRate[0].strikeRate;
                    }
                    if (floatingRateDefinition.rateObservation != null)//TODO This is a big problem. Need to handle the case of no fixing date!
                    {
                        var rateObservation = floatingRateDefinition.rateObservation[0];
                        if (rateObservation.observedRateSpecified)
                        {
                            observedRate = rateObservation.observedRate;
                        }
                        //Removed because Igor's old code populates these fields when the trade is created. This means the coupon is not recalculated!
                        //Now the coupon will ignore any previous calculations and only treat as a fixed coupon if the observed rate has been specified.
                        if (isThereDiscounting)
                        {
                            var discounting = XsdClassesFieldResolver.CalculationGetDiscounting(calculation);
                            if (capStrike != null || floorStrike != null)
                            {
                                rateCoupon = new PriceableCapFloorCoupon(coupon.id, !payerIsBase,
                                                                         capStrike, floorStrike, accrualStartDate, accrualEndDate,
                                                                         rateObservation.adjustedFixingDate, dayCountFraction,
                                                                         margin, observedRate, money, paymentDate,
                                                                         forecastRate, discounting.discountingType,
                                                                         observedRate, null, fixingCalendar, paymentCalendar);
                            }
                            else
                            {
                                rateCoupon = new PriceableFloatingRateCoupon(coupon.id, !payerIsBase, accrualStartDate, accrualEndDate,
                                                                             rateObservation.adjustedFixingDate, dayCountFraction,
                                                                             margin, observedRate, money, paymentDate,
                                                                             forecastRate, discounting.discountingType,
                                                                             observedRate, null, fixingCalendar, paymentCalendar);
                            }
                        }
                        else
                        {
                            if (capStrike != null || floorStrike != null)
                            {
                                rateCoupon = new PriceableCapFloorCoupon(coupon.id, !payerIsBase, capStrike, floorStrike,
                                                                         accrualStartDate, accrualEndDate,
                                                                         rateObservation.adjustedFixingDate, dayCountFraction,
                                                                         margin, observedRate, money, paymentDate,
                                                                         forecastRate, null, null, null,
                                                                         fixingCalendar, paymentCalendar);
                            }
                            else
                            {
                                rateCoupon = new PriceableFloatingRateCoupon(coupon.id, payerIsBase, accrualStartDate, accrualEndDate,
                                                                             rateObservation.adjustedFixingDate, dayCountFraction,
                                                                             margin, observedRate, money, paymentDate,
                                                                             forecastRate, null, null, null,
                                                                             fixingCalendar, paymentCalendar);
                            }
                        }
                        if (fOCalculationMethod)
                        {
                            ((PriceableFloatingRateCoupon)rateCoupon).ForecastRateInterpolation = true;
                        }
                        if (discountFactorSpecified)
                        {
                            rateCoupon.PaymentDiscountFactor = coupon.discountFactor;
                        }
                        return(rateCoupon);
                    }
                    throw new NotImplementedException("Need to return a rate coupon, Alex!");
                }
                throw new System.Exception("CalculationPeriod has neither fixedRate nor floatingRateDefinition.");
            }
            throw new System.Exception("PaymentCalculationPeriod has zero, or multiple CalculationPeriods.");
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="buyerIsBase"></param>
        /// <param name="calculation"></param>
        /// <param name="coupon"></param>
        /// <param name="fOCalculationMethod"></param>
        /// <param name="fixingCalendar"></param>
        /// <param name="paymentCalendar"></param>
        /// <returns></returns>
        public static PriceableCapFloorCoupon CreatePriceableCapFloorCoupon(bool buyerIsBase,
                                                                            Calculation calculation, PaymentCalculationPeriod coupon, bool fOCalculationMethod
                                                                            , IBusinessCalendar fixingCalendar, IBusinessCalendar paymentCalendar)
        {
            var notional         = (Notional)calculation.Item;
            var currency         = notional.notionalStepSchedule.currency;
            var dayCountFraction = calculation.dayCountFraction;
            var paymentDate      = coupon.adjustedPaymentDateSpecified
                                  ? coupon.adjustedPaymentDate
                                  : coupon.unadjustedPaymentDate;
            var calculationPeriods =
                XsdClassesFieldResolver.GetPaymentCalculationPeriodCalculationPeriodArray(coupon);

            if (calculationPeriods.Length == 1)
            {
                var calculationPeriod = calculationPeriods[0];
                //Money expectedCashFlow = null;
                decimal notionalamount   = XsdClassesFieldResolver.CalculationPeriodGetNotionalAmount(calculationPeriod);
                Money   money            = buyerIsBase ? MoneyHelper.GetAmount(-1 * notionalamount, currency) : MoneyHelper.GetAmount(notionalamount, currency);
                var     accrualStartDate = calculationPeriod.adjustedStartDateSpecified
                                           ? calculationPeriod.adjustedStartDate
                                           : calculationPeriod.unadjustedStartDate;
                var accrualEndDate = calculationPeriod.adjustedEndDateSpecified
                                         ? calculationPeriod.adjustedEndDate
                                         : calculationPeriod.unadjustedEndDate;
                //  If has a fixed rate (fixed rate coupon)
                var isThereDiscounting = XsdClassesFieldResolver.CalculationHasDiscounting(calculation);
                if (XsdClassesFieldResolver.CalculationPeriodHasFloatingRateDefinition(calculationPeriod))
                {
                    //The floating rate definition.
                    FloatingRateDefinition floatingRateDefinition = XsdClassesFieldResolver.CalculationPeriodGetFloatingRateDefinition(calculationPeriod);
                    //The floatingrateCalculation.
                    Debug.Assert(calculation.Items != null);
                    Debug.Assert(calculation.Items.Length > 0);
                    Debug.Assert(calculation.Items[0] is FloatingRateCalculation);
                    var floatingRateCalculation = (FloatingRateCalculation)calculation.Items[0];
                    //The forecast rate index.
                    var floatingRateIndex = floatingRateCalculation.floatingRateIndex;
                    var indexTenor        = floatingRateCalculation.indexTenor.ToString();
                    var forecastRate      = ForecastRateIndexHelper.Parse(floatingRateIndex.Value, indexTenor);
                    //The rate observation
                    // Apply spread from schedule if it hasn't been specified yet.
                    decimal margin = 0m;
                    if (floatingRateDefinition.spreadSpecified)
                    {
                        margin = floatingRateDefinition.spread;
                    }
                    //The observed rate.
                    Decimal?observedRate = null;
                    Decimal?capStrike    = null;
                    Decimal?floorStrike  = null;
                    if (floatingRateDefinition.capRate != null)
                    {
                        capStrike = floatingRateDefinition.capRate[0].strikeRate;
                    }
                    if (floatingRateDefinition.floorRate != null)
                    {
                        floorStrike = floatingRateDefinition.floorRate[0].strikeRate;
                    }
                    if (floatingRateDefinition.rateObservation != null)
                    {
                        var rateObservation = floatingRateDefinition.rateObservation[0];
                        if (rateObservation.observedRateSpecified)
                        {
                            observedRate = rateObservation.observedRate;
                        }
                        PriceableCapFloorCoupon rateCoupon;
                        if (isThereDiscounting)
                        {
                            var discounting = XsdClassesFieldResolver.CalculationGetDiscounting(calculation);
                            var floatingCouponWithDiscounting = new PriceableCapFloorCoupon(coupon.id, buyerIsBase,
                                                                                            capStrike, floorStrike, accrualStartDate, accrualEndDate,
                                                                                            rateObservation.adjustedFixingDate, dayCountFraction,
                                                                                            margin, observedRate, money, paymentDate,
                                                                                            forecastRate, discounting.discountingType,
                                                                                            observedRate, null, fixingCalendar, paymentCalendar);
                            if (fOCalculationMethod)
                            {
                                floatingCouponWithDiscounting.ForecastRateInterpolation = true;
                            }
                            rateCoupon = floatingCouponWithDiscounting;
                            return(rateCoupon);
                        }
                        var floatingCoupon = new PriceableCapFloorCoupon(coupon.id, buyerIsBase, capStrike, floorStrike,
                                                                         accrualStartDate, accrualEndDate,
                                                                         rateObservation.adjustedFixingDate, dayCountFraction,
                                                                         margin, observedRate, money, paymentDate,
                                                                         forecastRate, null, null, null,
                                                                         fixingCalendar, paymentCalendar);
                        if (fOCalculationMethod)
                        {
                            floatingCoupon.ForecastRateInterpolation = true;
                        }
                        rateCoupon = floatingCoupon;
                        return(rateCoupon);
                    }
                    throw new NotImplementedException("Need to return a rate coupon, Alex!");
                }
                throw new System.Exception("CalculationPeriod has neither fixedRate nor floatingRateDefinition.");
            }
            throw new System.Exception("PaymentCalculationPeriod has zero, or multiple CalculationPeriods.");
        }
Example #3
0
        private static void CalculateForecastPaymentAmount(Calculation calculation,
                                                           FloatingRateCalculation floatingRateCalculation,
                                                           PaymentCalculationPeriod paymentCalculationPeriod,
                                                           IRateCurve forecastCurve,
                                                           IRateCurve discountCurve,
                                                           DateTime valuationDate)
        {
            var      amountAccruedPerPaymentPeriod = new List <Money>();
            decimal  interestFromPreviousPeriods   = 0;
            Notional notionalSchedule = XsdClassesFieldResolver.CalculationGetNotionalSchedule(calculation);
            Currency notionalCurrency = notionalSchedule.notionalStepSchedule.currency;

            //  Cashflows
            //
            foreach (CalculationPeriod calculationPeriod in XsdClassesFieldResolver.GetPaymentCalculationPeriodCalculationPeriodArray(paymentCalculationPeriod))
            {
                decimal notional  = XsdClassesFieldResolver.CalculationPeriodGetNotionalAmount(calculationPeriod);
                decimal finalRate = 0.0m;
                //  If has a fixed rate (fixed rate coupon)
                //
                if (XsdClassesFieldResolver.CalculationPeriodHasFixedRate(calculationPeriod))
                {
                    finalRate = XsdClassesFieldResolver.CalculationPeriodGetFixedRate(calculationPeriod);
                }
                else if (XsdClassesFieldResolver.CalculationPeriodHasFloatingRateDefinition(calculationPeriod))
                {
                    if (null != forecastCurve)
                    {
                        FloatingRateDefinition floatingRateDefinition = XsdClassesFieldResolver.CalculationPeriodGetFloatingRateDefinition(calculationPeriod);
                        // Apply spread from schedule if it hasn't been specified yet.
                        //
                        if (!floatingRateDefinition.spreadSpecified)
                        {
                            floatingRateDefinition.spread          = floatingRateCalculation.spreadSchedule[0].initialValue;
                            floatingRateDefinition.spreadSpecified = true;
                        }
                        ForecastRateHelper.UpdateFloatingRateDefinition(floatingRateDefinition, floatingRateCalculation,
                                                                        calculation.dayCountFraction,
                                                                        calculationPeriod,
                                                                        forecastCurve);
                        calculationPeriod.Item1 = floatingRateDefinition;
                        decimal calculatedRate = floatingRateDefinition.calculatedRate;
                        //  final rate after application of Cap/Floor  rates
                        //
                        finalRate = calculatedRate;
                        //  If has a Cap rate, finalRate = MAX(0, FinalRate - CapRate)
                        //
                        if (null != floatingRateDefinition.capRate)
                        {
                            Strike strike = floatingRateDefinition.capRate[0];
                            finalRate = System.Math.Max(0, finalRate - strike.strikeRate);
                        }
                        //  If has a Floor rate, finalRate = MAX(0, FloorRate - FinalRate)
                        //
                        if (null != floatingRateDefinition.floorRate)
                        {
                            Strike strike = floatingRateDefinition.floorRate[0];
                            finalRate = System.Math.Max(0, strike.strikeRate - finalRate);
                        }
                    }
                }
                else
                {
                    throw new System.Exception("CalculationPeriod has neither fixedRate nor floatngRateDefinition.");
                }
                // Compound interest accrued during previos calculation periods in this payment period.
                //
                decimal notionalAdjustedForInterestFromPreviousPeriods = notional + interestFromPreviousPeriods;
                if (calculation.discounting == null)
                {
                    interestFromPreviousPeriods = notionalAdjustedForInterestFromPreviousPeriods * finalRate * calculationPeriod.dayCountYearFraction;
                }
                else if (calculation.discounting.discountingType == DiscountingTypeEnum.FRA || calculation.discounting.discountingType == DiscountingTypeEnum.Standard)
                {
                    interestFromPreviousPeriods = notionalAdjustedForInterestFromPreviousPeriods * (1.0m - 1.0m / (1.0m + finalRate * calculationPeriod.dayCountYearFraction));
                }
                else
                {
                    throw new NotSupportedException("The specified discountingType is not supported.");
                }
                Money amountAccruedPerCalculationPeriod = MoneyHelper.GetAmount(interestFromPreviousPeriods, notionalCurrency);
                amountAccruedPerPaymentPeriod.Add(amountAccruedPerCalculationPeriod);
            }
            paymentCalculationPeriod.forecastPaymentAmount   = MoneyHelper.Sum(amountAccruedPerPaymentPeriod);
            paymentCalculationPeriod.discountFactor          = (decimal)discountCurve.GetDiscountFactor(valuationDate, paymentCalculationPeriod.adjustedPaymentDate);
            paymentCalculationPeriod.discountFactorSpecified = true;
            paymentCalculationPeriod.presentValueAmount      = MoneyHelper.Mul(paymentCalculationPeriod.forecastPaymentAmount, paymentCalculationPeriod.discountFactor);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="calculation"></param>
        /// <param name="coupon"></param>
        /// <param name="fOCalculationMethod"></param>
        /// <param name="fixingCalendar"></param>
        /// <param name="paymentCalendar"></param>
        /// <returns></returns>
        public static PriceableRateCoupon CreatePriceableCoupon(Calculation calculation, PaymentCalculationPeriod coupon, bool fOCalculationMethod,
                                                                IBusinessCalendar fixingCalendar, IBusinessCalendar paymentCalendar)
        {
            var rateCoupon = CreatePriceableCoupon(false, calculation, coupon, fOCalculationMethod, fixingCalendar, paymentCalendar);

            return(rateCoupon);
        }
Example #5
0
        private static Cashflows UpdateCashflowsWithDetailedCashflows(IEnumerable <InputCashflowRangeItem> listDetailedCashflows /*, bool fixedLeg*/)
        {
            var cashflows = new Cashflows();
            var paymentCalculationPeriods = new List <PaymentCalculationPeriod>();

            foreach (var detailedCashflowRangeItem in listDetailedCashflows)
            {
                var paymentCalculationPeriod = new PaymentCalculationPeriod();
                var calculationPeriod        = new CalculationPeriod();
                paymentCalculationPeriod.Items = new object[] { calculationPeriod };
                paymentCalculationPeriod.adjustedPaymentDate          = detailedCashflowRangeItem.PaymentDate;
                paymentCalculationPeriod.adjustedPaymentDateSpecified = true;
                PaymentCalculationPeriodHelper.SetCalculationPeriodStartDate(paymentCalculationPeriod, detailedCashflowRangeItem.StartDate);
                PaymentCalculationPeriodHelper.SetCalculationPeriodEndDate(paymentCalculationPeriod, detailedCashflowRangeItem.EndDate);
                // Update notional amount
                //
                PaymentCalculationPeriodHelper.SetNotionalAmount(paymentCalculationPeriod, (decimal)detailedCashflowRangeItem.NotionalAmount);
                switch (detailedCashflowRangeItem.CouponType.ToLower())
                {
                case "cap":
                {
                    var floatingRateDefinition = new FloatingRateDefinition();
                    calculationPeriod.Item1 = floatingRateDefinition;
                    // After the spread is reset - we need to update calculated rate.
                    //
                    PaymentCalculationPeriodHelper.SetSpread(paymentCalculationPeriod, (decimal)detailedCashflowRangeItem.Spread);
                    floatingRateDefinition.capRate = new[] { new Strike() };
                    floatingRateDefinition.capRate[0].strikeRate = (decimal)detailedCashflowRangeItem.StrikeRate;        //tODO There is no fixing date.
                    {
                        var rateObservation = new RateObservation
                        {
                            adjustedFixingDate =
                                detailedCashflowRangeItem.FixingDate,
                            adjustedFixingDateSpecified = true
                        };
                        floatingRateDefinition.rateObservation = new[] { rateObservation };
                    }
                    break;
                }

                case "floor":
                {
                    var floatingRateDefinition = new FloatingRateDefinition();
                    //XsdClassesFieldResolver.CalculationPeriod_SetFloatingRateDefinition(calculationPeriod, floatingRateDefinition);
                    calculationPeriod.Item1 = floatingRateDefinition;
                    // After the spread is reset - we need to update calculated rate.
                    //
                    PaymentCalculationPeriodHelper.SetSpread(paymentCalculationPeriod, (decimal)detailedCashflowRangeItem.Spread);
                    floatingRateDefinition.capRate = new[] { new Strike() };
                    floatingRateDefinition.capRate[0].strikeRate = (decimal)detailedCashflowRangeItem.StrikeRate;

                    {
                        var rateObservation = new RateObservation
                        {
                            adjustedFixingDate =
                                detailedCashflowRangeItem.FixingDate,
                            adjustedFixingDateSpecified = true
                        };
                        floatingRateDefinition.rateObservation = new[] { rateObservation };
                    }
                    break;
                }

                default:
                {
                    string message = String.Format("Specified coupon type : '{0}' is not supported. Please use one of these: 'cap, floor'", detailedCashflowRangeItem.CouponType.ToLower());
                    throw new NotSupportedException(message);
                }
                }
                paymentCalculationPeriods.Add(paymentCalculationPeriod);
            }
            cashflows.cashflowsMatchParameters = true;
            cashflows.paymentCalculationPeriod = paymentCalculationPeriods.ToArray();
            return(cashflows);
        }
Example #6
0
 public static decimal[] GetPaymentCalculationPeriodFixedPaymentAmountArray(PaymentCalculationPeriod paymentCalculationPeriod)
 {
     return(paymentCalculationPeriod.Items.Select(item => (decimal)item).ToArray());
 }
 public static DateTime GetCalculationPeriodEndDate(PaymentCalculationPeriod paymentCalculationPeriod)
 {
     CalculationPeriod[] calculationPeriodArray = XsdClassesFieldResolver.GetPaymentCalculationPeriodCalculationPeriodArray(paymentCalculationPeriod);
     return(calculationPeriodArray[calculationPeriodArray.Length - 1].adjustedEndDate);
 }
Example #8
0
        private static string GetCouponType(PaymentCalculationPeriod pcalculationPeriod)
        {
            CalculationPeriod calculationPeriod = PaymentCalculationPeriodHelper.GetCalculationPeriods(pcalculationPeriod)[0];

            return(XsdClassesFieldResolver.CalculationPeriodHasFloatingRateDefinition(calculationPeriod) ? "Float" : "Fixed");
        }
 public static DateTime GetCalculationPeriodStartDate(PaymentCalculationPeriod paymentCalculationPeriod)
 {
     CalculationPeriod[] calculationPeriodArray = XsdClassesFieldResolver.GetPaymentCalculationPeriodCalculationPeriodArray(paymentCalculationPeriod);
     return(calculationPeriodArray[0].adjustedStartDate);
 }
 public static void SetCalculationPeriodStartDate(PaymentCalculationPeriod paymentCalculationPeriod, DateTime startDate)
 {
     CalculationPeriod[] calculationPeriodArray = XsdClassesFieldResolver.GetPaymentCalculationPeriodCalculationPeriodArray(paymentCalculationPeriod);
     calculationPeriodArray[0].adjustedStartDate          = startDate;
     calculationPeriodArray[0].adjustedStartDateSpecified = true;
 }
 public static int GetNumberOfDays(PaymentCalculationPeriod paymentCalculationPeriod)
 {
     return(XsdClassesFieldResolver.GetPaymentCalculationPeriodCalculationPeriodArray(paymentCalculationPeriod).Sum(calculationPeriod => int.Parse(calculationPeriod.calculationPeriodNumberOfDays)));
 }
 public static CalculationPeriod GetFirstCalculationPeriod(PaymentCalculationPeriod paymentCalculationPeriod)
 {
     return(XsdClassesFieldResolver.GetPaymentCalculationPeriodCalculationPeriodArray(paymentCalculationPeriod)[0]);
 }
 public static CalculationPeriod[] GetCalculationPeriods(PaymentCalculationPeriod paymentCalculationPeriod)
 {
     return(XsdClassesFieldResolver.GetPaymentCalculationPeriodCalculationPeriodArray(paymentCalculationPeriod));
 }
 public static CalculationPeriod[] GetPaymentCalculationPeriodCalculationPeriodArray(PaymentCalculationPeriod paymentCalculationPeriod)
 {
     return(paymentCalculationPeriod.Items.Cast <CalculationPeriod>().ToArray());
 }
 public static void SetCalculationPeriodEndDate(PaymentCalculationPeriod paymentCalculationPeriod, DateTime endDate)
 {
     CalculationPeriod[] calculationPeriodArray = XsdClassesFieldResolver.GetPaymentCalculationPeriodCalculationPeriodArray(paymentCalculationPeriod);
     calculationPeriodArray[calculationPeriodArray.Length - 1].adjustedEndDate          = endDate;
     calculationPeriodArray[calculationPeriodArray.Length - 1].adjustedEndDateSpecified = true;
 }
 public static void SetPaymentCalculationPeriodCalculationPeriodArray(PaymentCalculationPeriod paymentCalculationPeriod, CalculationPeriod[] value)
 {
     paymentCalculationPeriod.Items = value;
 }
        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);
        }