public void GetPrice2Vanilla()
        {
            DateTime valuationDate    = DateTime.Today;
            var      irCapFloorPricer = new CapFloorPricer();
            var      curveId          = BuildAndCacheRateCurve(valuationDate);

            foreach (CapFloorType capFloorType in new[] { CapFloorType.Cap, CapFloorType.Floor })
            {
                Debug.Print("Type: {0}", capFloorType);
                CapFloorLegParametersRange_Old capLeg = GetCapFloorInputParameters(valuationDate, valuationDate.AddMonths(6), valuationDate.AddYears(5),
                                                                                   capFloorType, "Standard", curveId, curveId);
                ValuationRange valuationRange                 = CreateValuationRangeForNAB(valuationDate);
                List <DateTimeDoubleRangeItem>   notional     = GetAmortNotional(capLeg, 3);
                List <DetailedCashflowRangeItem> cashflowList =
                    irCapFloorPricer.GetDetailedCashflowsWithNotionalSchedule(Engine.Logger, Engine.Cache, Engine.NameSpace, null, null, capLeg, notional, valuationRange);
                TradeRange tradeRange            = null;
                var        leg1BulletPaymentList = new List <AdditionalPaymentRangeItem>();
                List <FeePaymentRangeItem> feePaymentRangeItems = GetFeeList("counterparty", "book");
                //  Get price and swap representation using non-vanilla PRICE function.
                //
                var newCashflowList = cashflowList.Cast <InputCashflowRangeItem>().ToList();
                Pair <ValuationResultRange, CapFloor> nonVanillaPriceImpl = CapFloorPricer.GetPriceAndGeneratedFpML(Engine.Logger, Engine.Cache, Engine.NameSpace, null, null,
                                                                                                                    valuationRange, tradeRange, capLeg,
                                                                                                                    newCashflowList, null, leg1BulletPaymentList, feePaymentRangeItems);
                // NO PExs
                //
                CollectionAssertExtension.IsEmpty(nonVanillaPriceImpl.Second.capFloorStream.cashflows.principalExchange);
                // No payments
                //
                CollectionAssertExtension.IsEmpty(nonVanillaPriceImpl.Second.additionalPayment);
                Debug.Print(ValuationResultRangeToString(nonVanillaPriceImpl.First));
            }
        }
        private static CapFloorLegParametersRange_Old GetCapFloorInputParameters(DateTime effectiveDate, DateTime firstRollDate, DateTime matDate,
                                                                                 CapFloorType capFloorType, string discountingType, string discountCurve, string forwardCurve)
        {
            var result = new CapFloorLegParametersRange_Old
            {
                EffectiveDate = effectiveDate,
                FirstRegularPeriodStartDate = firstRollDate,
                MaturityDate     = matDate,
                Payer            = "NAB",
                Receiver         = "CounterParty",
                RollConvention   = "14",
                InitialStubType  = StubPeriodTypeEnum.ShortInitial.ToString(),
                FinalStubType    = StubPeriodTypeEnum.ShortFinal.ToString(),
                NotionalAmount   = 50000000,
                Currency         = "AUD",
                PaymentFrequency = "1Y",
                DayCount         = "30E/360",
                PaymentCalendar  = "Sydney",
                PaymentBusinessDayAdjustments = "FOLLOWING",
                FixingCalendar = "London",
                FixingBusinessDayAdjustments = "FOLLOWING",
                DiscountCurve   = discountCurve,
                ForecastCurve   = forwardCurve,
                DiscountingType = discountingType,
                CapOrFloor      = capFloorType,
                StrikeRate      = 0.080m
            };

            return(result);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="capFloorLeg"></param>
        /// <param name="fixingCalendar"></param>
        /// <param name="paymentCalendar"></param>
        /// <param name="spreadSchedule"></param>
        /// <param name="capOrFloorSchedule"></param>
        /// <param name="notionalSchedule"></param>
        /// <returns></returns>
        public static CapFloor GenerateDefinitionCashflows(IBusinessCalendar fixingCalendar,
                                                           IBusinessCalendar paymentCalendar,
                                                           CapFloorLegParametersRange_Old capFloorLeg,
                                                           Schedule spreadSchedule,
                                                           Schedule capOrFloorSchedule,
                                                           NonNegativeAmountSchedule notionalSchedule)

        {
            CapFloor capFloor = GenerateDefiniton(capFloorLeg, spreadSchedule, capOrFloorSchedule, notionalSchedule);

            if (null != spreadSchedule)
            {
                InterestRateStreamParametricDefinitionGenerator.SetSpreadSchedule(capFloor.capFloorStream, spreadSchedule);
            }
            if (null != notionalSchedule)
            {
                InterestRateStreamParametricDefinitionGenerator.SetNotionalSchedule(capFloor.capFloorStream, notionalSchedule);
            }
            if (null != capOrFloorSchedule)
            {
                if (capFloorLeg.CapOrFloor == CapFloorType.Cap)
                {
                    InterestRateStreamParametricDefinitionGenerator.SetCapRateSchedule(capFloor.capFloorStream, capOrFloorSchedule, true);
                }
                else
                {
                    InterestRateStreamParametricDefinitionGenerator.SetFloorRateSchedule(capFloor.capFloorStream, capOrFloorSchedule, true);
                }
            }
            capFloor.capFloorStream.cashflows = FixedAndFloatingRateStreamCashflowGenerator.GetCashflows(capFloor.capFloorStream, fixingCalendar, paymentCalendar);
            return(capFloor);
        }
        public void TestGetCapPremiumAUD_6M100M_5YExpiry05Vol20Pct()
        {
            var valuationDate = new DateTime(1994, 12, 14);
            var curveId       = BuildAndCacheRateCurve(valuationDate);
            CapFloorLegParametersRange_Old capLeg = GetCapFloorInputParameters(valuationDate, valuationDate.AddMonths(6), valuationDate.AddYears(5),
                                                                               CapFloorType.Cap, "Standard", curveId, curveId);
            InterestRateStream floatStream = InterestRateStreamParametricDefinitionGenerator.GenerateStreamDefinition(capLeg);

            floatStream.cashflows = FixedAndFloatingRateStreamCashflowGenerator.GetCashflows(floatStream, FixingCalendar, PaymentCalendar);
            double sumOfCapletPremiums = 0;
            var    rateCurve           = (RateCurve)Engine.GetCurve(curveId, false);

            foreach (PaymentCalculationPeriod paymentCalculationPeriod in floatStream.cashflows.paymentCalculationPeriod)
            {
                DateTime startDate      = PaymentCalculationPeriodHelper.GetCalculationPeriodStartDate(paymentCalculationPeriod);
                DateTime endDate        = PaymentCalculationPeriodHelper.GetCalculationPeriodEndDate(paymentCalculationPeriod);
                double   accrualFactor  = (endDate - startDate).TotalDays / 365.0;
                var      discountFactor = (double)paymentCalculationPeriod.discountFactor;
                var      rate           = (double)PaymentCalculationPeriodHelper.GetRate(paymentCalculationPeriod);
                double   rate2          = rateCurve.GetForwardRate(startDate, endDate, "ACT/365.FIXED");
                double   diff           = rate - rate2;
                Debug.Print("Diff in forward rate: {0}", diff);
                var          strikeRate   = (double)capLeg.StrikeRate; //fixed - replace with a schedule
                const double volatility   = 0.2;                       //fixed - replace with a schedule
                double       timeToExpiry = (startDate - valuationDate).TotalDays / 365.0;
                double       optionValue  = accrualFactor * BlackModel.GetSwaptionValue(rate, strikeRate, volatility, timeToExpiry) * discountFactor;
                Debug.Print("Expiry:\t{0},\tPremium:\t{1}'", timeToExpiry, optionValue);
                sumOfCapletPremiums += optionValue;
            }
            Debug.Print("Premium : '{0}'", sumOfCapletPremiums * (double)capLeg.NotionalAmount);
        }
        public void CreateValuationVanilla()
        {
            DateTime valuationDate    = DateTime.Today;
            var      irCapFloorPricer = new CapFloorPricer();
            var      curveId          = BuildAndCacheRateCurve(valuationDate);

            foreach (CapFloorType capFloorType in new[] { CapFloorType.Cap, CapFloorType.Floor })
            {
                Debug.Print("Type: {0}", capFloorType);
                CapFloorLegParametersRange_Old capLeg = GetCapFloorInputParameters(valuationDate, valuationDate.AddMonths(6), valuationDate.AddYears(5),
                                                                                   capFloorType, "Standard", curveId, curveId);
                ValuationRange valuationRange                 = CreateValuationRangeForNAB(valuationDate);
                List <DateTimeDoubleRangeItem>   notional     = GetAmortNotional(capLeg, 3);
                List <DetailedCashflowRangeItem> cashflowList =
                    irCapFloorPricer.GetDetailedCashflowsWithNotionalSchedule(Engine.Logger, Engine.Cache, Engine.NameSpace, null, null, capLeg, notional, valuationRange);
                switch (capFloorType)
                {
                case CapFloorType.Cap:
                    cashflowList[0].CouponType = "cap";    // that should test case insensitive nature of the coupons
                    cashflowList[1].CouponType = "Cap";    //

                    break;

                case CapFloorType.Floor:
                    cashflowList[0].CouponType = "floor";    // that should test case insensitive nature of the coupons
                    cashflowList[1].CouponType = "Floor";    //

                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                var tradeRange = new TradeRange {
                    TradeDate = DateTime.Now
                };
                var leg1BulletPaymentList = new List <AdditionalPaymentRangeItem>();
                var newCashflowList       = cashflowList.Cast <InputCashflowRangeItem>().ToList();
                //  Get price and swap representation using non-vanilla PRICE function.
                //
                List <StringObjectRangeItem>      valuationSetList            = CreateValuationSetList2(1111, 12);
                List <PartyIdRangeItem>           partyList                   = GetPartyList("NAB", "book", "MCHammer", "counterparty");
                List <OtherPartyPaymentRangeItem> otherPartyPaymentRangeItems = GetOtherPartyPaymentList("counterparty", "cost center");
                List <FeePaymentRangeItem>        feePaymentRangeItems        = GetFeeList("counterparty", "book");
                string id = irCapFloorPricer.CreateValuation(Engine.Logger, Engine.Cache, Engine.NameSpace, null, null,
                                                             valuationSetList, valuationRange, tradeRange,
                                                             capLeg, newCashflowList, null, leg1BulletPaymentList,
                                                             partyList, otherPartyPaymentRangeItems, feePaymentRangeItems);
                var valuationReport = Engine.Cache.LoadObject <ValuationReport>(Engine.NameSpace + "." + id);
                Debug.Print(XmlSerializerHelper.SerializeToString(valuationReport));
            }
        }
        public static CapFloor GenerateDefiniton(CapFloorLegParametersRange_Old capFloorLeg,
                                                 Schedule spreadSchedule,
                                                 Schedule capOrFloorSchedule,
                                                 NonNegativeSchedule notionalSchedule)
        {
            InterestRateStream capFloorStream = InterestRateStreamParametricDefinitionGenerator.GenerateStreamDefinition(capFloorLeg);

            InterestRateStreamHelper.SetPayerAndReceiver(capFloorStream, capFloorLeg.Payer, capFloorLeg.Receiver);
            var capFloor = new CapFloor {
                capFloorStream = capFloorStream
            };

            return(capFloor);
        }
Example #7
0
        private static InterestRateStream GetCashflowsScheduleWithNotionalSchedule(
            IBusinessCalendar fixingCalendar,
            IBusinessCalendar paymentCalendar,
            CapFloorLegParametersRange_Old legParametersRange,
            NonNegativeAmountSchedule notionalSchedule)
        {
            InterestRateStream stream = InterestRateStreamParametricDefinitionGenerator.GenerateStreamDefinition(legParametersRange);

            InterestRateStreamParametricDefinitionGenerator.SetNotionalSchedule(stream, notionalSchedule);
            Cashflows cashflows = FixedAndFloatingRateStreamCashflowGenerator.GetCashflows(stream, fixingCalendar, paymentCalendar);

            stream.cashflows = cashflows;
            return(stream);
        }
Example #8
0
        public string CreateValuation(
            ILogger logger, ICoreCache cache,
            String nameSpace,
            IBusinessCalendar fixingCalendar,
            IBusinessCalendar paymentCalendar,
            List <StringObjectRangeItem> valuationSet,
            ValuationRange valuationRange,
            TradeRange tradeRange,
            CapFloorLegParametersRange_Old legParametersRange,
            List <InputCashflowRangeItem> legDetailedCashflowsListArray,
            List <InputPrincipalExchangeCashflowRangeItem> legPrincipleExchangeCashflowListArray,
            List <AdditionalPaymentRangeItem> legAdditionalPaymentListArray,
            List <PartyIdRangeItem> partyIdList,                     //optional
            List <OtherPartyPaymentRangeItem> otherPartyPaymentList, //optional
            List <FeePaymentRangeItem> feePaymentList                //optional
            )
        {
            Pair <ValuationResultRange, CapFloor> fpML = GetPriceAndGeneratedFpML(logger, cache, nameSpace, fixingCalendar, paymentCalendar, valuationRange, tradeRange,
                                                                                  legParametersRange, legDetailedCashflowsListArray, legPrincipleExchangeCashflowListArray,
                                                                                  legAdditionalPaymentListArray, feePaymentList);
            CapFloor capFloor = fpML.Second;
            string   valuationReportAndProductId = tradeRange.Id ?? Guid.NewGuid().ToString();

            capFloor.id = valuationReportAndProductId;
            AssetValuation assetValuation = InterestRateProduct.CreateAssetValuationFromValuationSet(valuationSet);
            //Valuation valuation = new Valuation();
            //  TODO: add Trade Id & Trade data into valuation. (Trade.Id & Trade.TradeHeader.TradeDate)
            //
            string baseParty    = valuationRange.BaseParty;
            var    uniqueCurves = new List <IRateCurve>();

            foreach (string curveName in new[] { legParametersRange.ForecastCurve, legParametersRange.DiscountCurve })
            {
                if (!String.IsNullOrEmpty(curveName))
                {
                    var curve = CurveLoader.LoadInterestRateCurve(logger, cache, nameSpace, curveName);
                    if (!uniqueCurves.Contains(curve))
                    {
                        uniqueCurves.Add(curve);
                    }
                }
            }
            Market          fpMLMarket      = InterestRateProduct.CreateFpMLMarketFromCurves(uniqueCurves);
            ValuationReport valuationReport = ValuationReportGenerator.Generate(valuationReportAndProductId, baseParty, valuationReportAndProductId, tradeRange.TradeDate, capFloor, fpMLMarket, assetValuation);

            cache.SaveObject(valuationReport, valuationReportAndProductId, null);
            InterestRateProduct.ReplacePartiesInValuationReport(valuationReport, partyIdList);
            InterestRateProduct.AddOtherPartyPayments(valuationReport, otherPartyPaymentList);
            return(valuationReportAndProductId);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="fixingCalendar"></param>
        /// <param name="paymentCalendar"></param>
        /// <param name="capFloorLeg"></param>
        /// <param name="spreadSchedule"></param>
        /// <param name="capOrFloorSchedule"></param>
        /// <param name="notionalSchedule"></param>
        /// <param name="marketEnvironment"></param>
        /// <param name="valuationDate"></param>
        /// <returns></returns>
        public static CapFloor GenerateDefinitionCashflowsAmounts(IBusinessCalendar fixingCalendar,
                                                                  IBusinessCalendar paymentCalendar,
                                                                  CapFloorLegParametersRange_Old capFloorLeg,
                                                                  Schedule spreadSchedule,
                                                                  Schedule capOrFloorSchedule,
                                                                  NonNegativeAmountSchedule notionalSchedule,
                                                                  ISwapLegEnvironment marketEnvironment,
                                                                  DateTime valuationDate)
        {
            CapFloor   capFloor = GenerateDefinitionCashflows(fixingCalendar, paymentCalendar, capFloorLeg, spreadSchedule, capOrFloorSchedule, notionalSchedule);
            IRateCurve payStreamDiscountingCurve = marketEnvironment.GetDiscountRateCurve();
            IRateCurve payStreamForecastCurve    = marketEnvironment.GetForecastRateCurve();

            FixedAndFloatingRateStreamCashflowGenerator.UpdateCashflowsAmounts(capFloor.capFloorStream, payStreamForecastCurve, payStreamDiscountingCurve, valuationDate);
            return(capFloor);
        }
        static List <DateTimeDoubleRangeItem> GetAmortNotional(CapFloorLegParametersRange_Old leg, int rollEveryNMonth)
        {
            var list = new List <DateTimeDoubleRangeItem>
            {
                DateTimeDoubleRangeItem.Create(leg.EffectiveDate, (double)leg.NotionalAmount),
                DateTimeDoubleRangeItem.Create(leg.EffectiveDate.AddMonths(rollEveryNMonth * 1),
                                               (double)(leg.NotionalAmount * 0.9m)),
                DateTimeDoubleRangeItem.Create(leg.EffectiveDate.AddMonths(rollEveryNMonth * 2),
                                               (double)(leg.NotionalAmount * 0.8m)),
                DateTimeDoubleRangeItem.Create(leg.EffectiveDate.AddMonths(rollEveryNMonth * 3),
                                               (double)(leg.NotionalAmount * 0.7m)),
                DateTimeDoubleRangeItem.Create(leg.EffectiveDate.AddMonths(rollEveryNMonth * 4),
                                               (double)(leg.NotionalAmount * 0.6m))
            };

            return(list);
        }
Example #11
0
        private static void UpdateCashflowsWithAmounts(ILogger logger, ICoreCache cache,
                                                       String nameSpace, InterestRateStream stream,
                                                       CapFloorLegParametersRange_Old legParametersRange, ValuationRange valuationRange)
        {
            //  Get a forecast curve
            //
            IRateCurve forecastCurve = null;

            if (!String.IsNullOrEmpty(legParametersRange.ForecastCurve) && legParametersRange.ForecastCurve.ToLower() != "none")
            {
                forecastCurve = CurveLoader.LoadInterestRateCurve(logger, cache, nameSpace, legParametersRange.ForecastCurve);
            }
            //  Get a discount curve
            //
            var discountCurve = CurveLoader.LoadInterestRateCurve(logger, cache, nameSpace, legParametersRange.DiscountCurve);

            FixedAndFloatingRateStreamCashflowGenerator.UpdateCashflowsAmounts(stream, forecastCurve, discountCurve, valuationRange.ValuationDate);
        }
        public void GetDetailedCapFloorCashflowsVanilla()
        {
            DateTime valuationDate    = DateTime.Today;
            var      irCapFloorPricer = new CapFloorPricer();
            var      curveId          = BuildAndCacheRateCurve(valuationDate);

            foreach (CapFloorType legType in new[] { CapFloorType.Cap, CapFloorType.Floor })
            {
                Debug.Print("LegType: {0}", legType);
                CapFloorLegParametersRange_Old capLeg = GetCapFloorInputParameters(valuationDate, valuationDate.AddMonths(6), valuationDate.AddYears(5),
                                                                                   legType, "Standard", curveId, curveId);

                ValuationRange valuationRange                 = CreateValuationRange(valuationDate);
                List <DateTimeDoubleRangeItem>   notional     = GetAmortNotional(capLeg, 3);
                List <DetailedCashflowRangeItem> cashflowList =
                    irCapFloorPricer.GetDetailedCashflowsWithNotionalSchedule(Engine.Logger, Engine.Cache, Engine.NameSpace, null, null, capLeg, notional, valuationRange);
                object[,] arrayOfCashflows = ObjectToArrayOfPropertiesConverter.ConvertListToHorizontalArrayRange(cashflowList);
                Debug.WriteLine("Cashflows:");
                Debug.WriteLine(ParameterFormatter.FormatObject(arrayOfCashflows));
            }
        }
Example #13
0
        public static Pair <ValuationResultRange, CapFloor> GetPriceAndGeneratedFpML(
            ILogger logger, ICoreCache cache,
            String nameSpace,
            IBusinessCalendar fixingCalendar,
            IBusinessCalendar paymentCalendar,
            ValuationRange valuationRange, TradeRange tradeRange,
            CapFloorLegParametersRange_Old leg1ParametersRange,
            List <InputCashflowRangeItem> leg1DetailedCashflowsList,
            List <InputPrincipalExchangeCashflowRangeItem> legPrincipalExchangeCashflowListArray,
            List <AdditionalPaymentRangeItem> leg1AdditionalPaymentList,
            List <FeePaymentRangeItem> feePaymentList
            )
        {
            //Check if the calendars are null. If not build them!
            InterestRateStream stream1 = GetCashflowsSchedule(fixingCalendar, paymentCalendar, leg1ParametersRange);//parametric definiton + cashflows schedule

            // Update FpML cashflows
            //
            stream1.cashflows = UpdateCashflowsWithDetailedCashflows(leg1DetailedCashflowsList);
            if (null != legPrincipalExchangeCashflowListArray)
            {
                // create principal exchanges
                //
                InterestRateSwapPricer.CreatePrincipalExchangesFromListOfRanges(stream1.cashflows, legPrincipalExchangeCashflowListArray);
            }
            //  Add bullet payments...
            //
            var bulletPaymentList = new List <Payment>();

            if (null != leg1AdditionalPaymentList)
            {
                bulletPaymentList.AddRange(leg1AdditionalPaymentList.Select(bulletPaymentRangeItem => new Payment
                {
                    payerPartyReference    = PartyReferenceFactory.Create(leg1ParametersRange.Payer),
                    receiverPartyReference = PartyReferenceFactory.Create(leg1ParametersRange.Receiver),
                    paymentAmount          = MoneyHelper.GetNonNegativeAmount(bulletPaymentRangeItem.Amount, bulletPaymentRangeItem.Currency),
                    paymentDate            = DateTypesHelper.ToAdjustableOrAdjustedDate(bulletPaymentRangeItem.PaymentDate)
                }));
            }
            CapFloor capFloor = CapFloorFactory.Create(stream1);

            capFloor.additionalPayment = bulletPaymentList.ToArray();
            var feeList = new List <Payment>();

            if (null != feePaymentList)
            {
                feeList.AddRange(feePaymentList.Select(feePaymentRangeItem => new Payment
                {
                    paymentDate            = DateTypesHelper.ToAdjustableOrAdjustedDate(feePaymentRangeItem.PaymentDate),
                    paymentAmount          = MoneyHelper.GetNonNegativeAmount(feePaymentRangeItem.Amount, feePaymentRangeItem.Currency),
                    payerPartyReference    = PartyReferenceFactory.Create(feePaymentRangeItem.Payer),
                    receiverPartyReference = PartyReferenceFactory.Create(feePaymentRangeItem.Receiver)
                }));
            }
            capFloor.premium = feeList.ToArray();
            // Update FpML cashflows with DF,FV,PV, etc (LegParametersRange needed to access curve functionality)
            //
            UpdateCashflowsWithAmounts(logger, cache, nameSpace, stream1, leg1ParametersRange, valuationRange);
            //  Update additional payments
            //
            var leg1DiscountCurve = CurveLoader.LoadInterestRateCurve(logger, cache, nameSpace, leg1ParametersRange.DiscountCurve);

            CapFloorGenerator.UpdatePaymentsAmounts(paymentCalendar, capFloor, leg1ParametersRange, leg1DiscountCurve, valuationRange.ValuationDate);
            //~  Update additional payments
            string baseParty = valuationRange.BaseParty;

            return(new Pair <ValuationResultRange, CapFloor>(CreateValuationRange(capFloor, baseParty), capFloor));
        }
Example #14
0
        public List <DetailedCashflowRangeItem> GetDetailedCashflowsWithNotionalSchedule(
            ILogger logger, ICoreCache cache,
            String nameSpace,
            IBusinessCalendar fixingCalendar,
            IBusinessCalendar paymentCalendar,
            CapFloorLegParametersRange_Old legParametersRange,
            List <DateTimeDoubleRangeItem> notionalValueItems,
            ValuationRange valuationRange)
        {
            //Check if the calendars are null. If not build them!
            var list1 = notionalValueItems.Select(item => new Pair <DateTime, decimal>(item.DateTime, Convert.ToDecimal(item.Value))).ToList();
            NonNegativeSchedule       notionalScheduleFpML = NonNegativeScheduleHelper.Create(list1);
            Currency                  currency             = CurrencyHelper.Parse(legParametersRange.Currency);
            NonNegativeAmountSchedule amountSchedule       = NonNegativeAmountScheduleHelper.Create(notionalScheduleFpML, currency);
            InterestRateStream        interestRateStream   = GetCashflowsScheduleWithNotionalSchedule(fixingCalendar, paymentCalendar, legParametersRange, amountSchedule);
            //Add the principal exchanges to the cashflows.
            var principalExchangeList = list1.Select(cashflow => new PrincipalExchange
            {
                adjustedPrincipalExchangeDate = cashflow.First, adjustedPrincipalExchangeDateSpecified = true, principalExchangeAmount = cashflow.Second, principalExchangeAmountSpecified = true
            }).ToArray();

            interestRateStream.cashflows.principalExchange = principalExchangeList;
            UpdateCashflowsWithAmounts(logger, cache, nameSpace, interestRateStream, legParametersRange, valuationRange);
            var list = new List <DetailedCashflowRangeItem>();

            foreach (PaymentCalculationPeriod paymentCalculationPeriod in interestRateStream.cashflows.paymentCalculationPeriod)
            {
                var detailedCashflowRangeItem = new DetailedCashflowRangeItem();
                detailedCashflowRangeItem.PaymentDate    = paymentCalculationPeriod.adjustedPaymentDate;
                detailedCashflowRangeItem.StartDate      = PaymentCalculationPeriodHelper.GetCalculationPeriodStartDate(paymentCalculationPeriod);
                detailedCashflowRangeItem.EndDate        = PaymentCalculationPeriodHelper.GetCalculationPeriodEndDate(paymentCalculationPeriod);
                detailedCashflowRangeItem.NumberOfDays   = PaymentCalculationPeriodHelper.GetNumberOfDays(paymentCalculationPeriod);
                detailedCashflowRangeItem.FutureValue    = MoneyHelper.ToDouble(paymentCalculationPeriod.forecastPaymentAmount);
                detailedCashflowRangeItem.PresentValue   = MoneyHelper.ToDouble(paymentCalculationPeriod.presentValueAmount);
                detailedCashflowRangeItem.DiscountFactor = (double)paymentCalculationPeriod.discountFactor;
                detailedCashflowRangeItem.NotionalAmount = (double)PaymentCalculationPeriodHelper.GetNotionalAmount(paymentCalculationPeriod);
                detailedCashflowRangeItem.CouponType     = GetCouponType(paymentCalculationPeriod);
                detailedCashflowRangeItem.Rate           = (double)PaymentCalculationPeriodHelper.GetRate(paymentCalculationPeriod);
                CalculationPeriod      calculationPeriod      = PaymentCalculationPeriodHelper.GetCalculationPeriods(paymentCalculationPeriod)[0];
                FloatingRateDefinition floatingRateDefinition = XsdClassesFieldResolver.CalculationPeriodGetFloatingRateDefinition(calculationPeriod);
                switch (detailedCashflowRangeItem.CouponType.ToLower())
                {
                case "cap":
                {
                    Strike strike = floatingRateDefinition.capRate[0];
                    detailedCashflowRangeItem.StrikeRate = (double)strike.strikeRate;
                    break;
                }

                case "floor":
                {
                    Strike strike = floatingRateDefinition.floorRate[0];
                    detailedCashflowRangeItem.StrikeRate = (double)strike.strikeRate;
                    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);
                }
                }
                //  If  floating rate - retrieve the spread.
                //
                detailedCashflowRangeItem.Spread = (double)PaymentCalculationPeriodHelper.GetSpread(paymentCalculationPeriod);
                var fixingDate = new DateTime();
                var tempDate   = PaymentCalculationPeriodHelper.GetFirstFloatingFixingDate(paymentCalculationPeriod);
                if (tempDate != null)
                {
                    fixingDate = (DateTime)tempDate;
                }
                detailedCashflowRangeItem.FixingDate = fixingDate;
                detailedCashflowRangeItem.Currency   = "Not Specified";
                if (currency != null)
                {
                    detailedCashflowRangeItem.Currency = currency.Value;
                }
                list.Add(detailedCashflowRangeItem);
            }
            return(list);
        }