public static void SetFloorRateSchedule(InterestRateStream stream, Schedule floorRateSchedule, bool isReceiverBuyer) { Calculation calculation = XsdClassesFieldResolver.CalculationPeriodAmountGetCalculation(stream.calculationPeriodAmount); FloatingRateCalculation floatingRateCalculation = XsdClassesFieldResolver.CalculationGetFloatingRateCalculation(calculation); var schedule = new StrikeSchedule { initialValue = floorRateSchedule.initialValue, step = floorRateSchedule.step }; floatingRateCalculation.floorRateSchedule = new[] { schedule }; if (isReceiverBuyer) { floatingRateCalculation.floorRateSchedule[0].buyer = new IdentifiedPayerReceiver { Value = PayerReceiverEnum.Receiver }; floatingRateCalculation.floorRateSchedule[0].seller = new IdentifiedPayerReceiver { Value = PayerReceiverEnum.Payer }; } else { floatingRateCalculation.floorRateSchedule[0].buyer = new IdentifiedPayerReceiver { Value = PayerReceiverEnum.Payer }; floatingRateCalculation.floorRateSchedule[0].seller = new IdentifiedPayerReceiver { Value = PayerReceiverEnum.Receiver }; } }
/// <summary> /// Updates forecastRate, forecastPaymentAmount, discountFactor and presentValueAmount of each paymentCalculation period. /// </summary> /// <param name="interestRateStream">The interest rate stream.</param> /// <param name="forecastCurve">The forecast curve.</param> /// <param name="discountCurve">The discount curve.</param> /// <param name="valuationDate">The valuation date.</param> public static void UpdateCashflowsAmounts(InterestRateStream interestRateStream, IRateCurve forecastCurve, IRateCurve discountCurve, DateTime valuationDate) { //FixAfterManualUpdate(interestRateStream);//should it be removed, since it might produce subtle errors which will be effectively hidden. Calculation calculation = XsdClassesFieldResolver.CalculationPeriodAmountGetCalculation(interestRateStream.calculationPeriodAmount); UpdateNumberOfDaysAndYearFraction(new List <PaymentCalculationPeriod>(interestRateStream.cashflows.paymentCalculationPeriod), calculation); FloatingRateCalculation floatingRateCalculation = XsdClassesFieldResolver.CalculationHasFloatingRateCalculation(calculation) ? XsdClassesFieldResolver.CalculationGetFloatingRateCalculation(calculation) : null; // calculate forecast payment amount for each payment calculation period // foreach (PaymentCalculationPeriod period in interestRateStream.cashflows.paymentCalculationPeriod) { CalculateForecastPaymentAmount(calculation, floatingRateCalculation, period, forecastCurve, discountCurve, valuationDate); } // principle exchanges // if (interestRateStream.cashflows.principalExchange != null) { foreach (PrincipalExchange principalExchange in interestRateStream.cashflows.principalExchange) { CalculateForecastPaymentAmount(principalExchange, discountCurve, valuationDate); } } }
public static FloatingRateCalculation Create(string floatingRateIndex, string indexTenor, decimal spreadInitialValue) { FloatingRateCalculation result = new FloatingRateCalculation(); result.floatingRateIndex = FloatingRateIndexHelper.Parse(floatingRateIndex); result.indexTenor = PeriodHelper.Parse(indexTenor); result.spreadSchedule = new SpreadSchedule[] { SpreadScheduleFactory.Create(spreadInitialValue) }; return(result); }
public static FloatingRateCalculation CreateFloating(FloatingRateIndex floatingRateIndex, Period tenor) { FloatingRateCalculation floatingRateCalculation = new FloatingRateCalculation(); floatingRateCalculation.floatingRateIndex = floatingRateIndex; floatingRateCalculation.indexTenor = tenor; return(floatingRateCalculation); }
public static void SetCalculationSpreadSchedule(Calculation calculation, Schedule schedule) { FloatingRateCalculation floatingRateCalculation = CalculationGetFloatingRateCalculation(calculation); var spreadSchedule = new SpreadSchedule { initialValue = schedule.initialValue, step = schedule.step }; floatingRateCalculation.spreadSchedule = new[] { spreadSchedule }; }
public static FloatingRateCalculation CreateFloating(FloatingRateIndex floatingRateIndex, Period tenor) { var floatingRateCalculation = new FloatingRateCalculation { floatingRateIndex = floatingRateIndex, indexTenor = tenor }; return(floatingRateCalculation); }
public static void SetSpreadSchedule(InterestRateStream stream, Schedule spreadSchedule) { Calculation calculation = XsdClassesFieldResolver.CalculationPeriodAmountGetCalculation(stream.calculationPeriodAmount); FloatingRateCalculation floatingRateCalculation = XsdClassesFieldResolver.CalculationGetFloatingRateCalculation(calculation); var schedule = new SpreadSchedule { initialValue = spreadSchedule.initialValue, step = spreadSchedule.step }; floatingRateCalculation.spreadSchedule = new[] { schedule }; }
public static bool CalculationHasSpreadSchedule(Calculation calculation) { FloatingRateCalculation floatingRateCalculation = CalculationGetFloatingRateCalculation(calculation); if (null != floatingRateCalculation.spreadSchedule && floatingRateCalculation.spreadSchedule.Length > 0 && null != floatingRateCalculation.spreadSchedule[0] ) { return(true); } return(false); }
public static void UpdateFloatingRateDefinition(FloatingRateDefinition floatingRateDefinition, FloatingRateCalculation floatingRateCalculation, DayCountFraction dayCountFraction, CalculationPeriod calculationPeriod, IRateCurve forecastCurve) { var rateObservation = new RateObservation(); if (floatingRateDefinition.rateObservation != null) { if (floatingRateDefinition.rateObservation[0].adjustedFixingDateSpecified) { rateObservation.adjustedFixingDate = floatingRateDefinition.rateObservation[0].adjustedFixingDate; rateObservation.adjustedFixingDateSpecified = true; } } floatingRateDefinition.rateObservation = new[] { rateObservation }; rateObservation.forecastRate = GetForecastRate(calculationPeriod, forecastCurve, dayCountFraction); rateObservation.forecastRateSpecified = true; Decimal finalRate = rateObservation.forecastRate; // If spread specified - add it to the final rate. // if (floatingRateDefinition.spreadSpecified) { finalRate += floatingRateDefinition.spread; } // Apply rounding (if it's been specified) // if (null != floatingRateCalculation.finalRateRounding) { Rounding finalRateRounding = floatingRateCalculation.finalRateRounding; floatingRateDefinition.calculatedRate = RoundingHelper.Round(finalRate, finalRateRounding); } else { floatingRateDefinition.calculatedRate = finalRate; } floatingRateDefinition.calculatedRateSpecified = true; }
public List <ValuationInfoRangeItem> GetInfo(ICoreCache cache, string nameSpace, string valuationId) { var list = new List <ValuationInfoRangeItem>(); var item = cache.LoadItem <ValuationReport>(nameSpace + "." + valuationId); if (item != null) { var valuationReport = (ValuationReport)item.Data; var envelope = new ValuationInfoRangeItem { Id = valuationReport.header.messageId.Value, Description = "envelope" }; list.Add(envelope); foreach (TradeValuationItem tradeValuationItem in valuationReport.tradeValuationItem) { foreach (Trade trade in tradeValuationItem.Items) { if (trade.tradeHeader.partyTradeIdentifier[0].Items[0] is TradeId tradeId) { var product = new ValuationInfoRangeItem { Id = tradeId.Value }; if (trade.Item is Swap swap1) { product.Description = "swap"; var swap = swap1; string leg1Type = GetInterestRateStreamType(swap.swapStream[0]); string leg2Type = GetInterestRateStreamType(swap.swapStream[1]); product.Description += $"({leg1Type}/{leg2Type})"; } else if (trade.Item is Swaption) { product.Description = "swaption"; } else { if (trade.Item is CapFloor floor)//could be cap, floor, or collar { var capFloor = floor; Calculation calculation = XsdClassesFieldResolver.CalculationPeriodAmountGetCalculation( capFloor.capFloorStream.calculationPeriodAmount); FloatingRateCalculation floatingRateCalculation = XsdClassesFieldResolver.CalculationGetFloatingRateCalculation(calculation); if (null != floatingRateCalculation.capRateSchedule & null != floatingRateCalculation.floorRateSchedule) { product.Description = "collar"; } else if (null != floatingRateCalculation.capRateSchedule) { product.Description = "cap"; } else { product.Description = null != floatingRateCalculation.floorRateSchedule ? "floor" : "unknown product"; } } else { product.Description = "unknown product"; } } list.Add(product); } } } } return(list); }
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); }
private static InterestRateStream GenerateCapFloorStreamDefinition(CapFloorLegParametersRange legParametersRange) { Discounting discounting = null; InterestRateStream stream; if (legParametersRange.DiscountingType != null && legParametersRange.DiscountingType.ToUpper() != "NONE") { discounting = new Discounting { discountingType = EnumHelper.Parse <DiscountingTypeEnum>(legParametersRange.DiscountingType) }; stream = InterestRateStreamFactory.CreateFloatingRateStream(DiscountingTypeToPayRelativeTo(discounting.discountingType)); } // Create the stream object // else { stream = InterestRateStreamFactory.CreateFloatingRateStream(DiscountingTypeToPayRelativeTo(null)); } // Set effective and termination dates of the stream. // SetEffectiveAndTerminationDates(stream, legParametersRange.EffectiveDate, legParametersRange.MaturityDate, legParametersRange.PaymentBusinessDayAdjustments, legParametersRange.PaymentCalendar); // Adjusted or unadjusted swap // stream.calculationPeriodDates.calculationPeriodDatesAdjustments = AdjustedType.Adjusted != legParametersRange.AdjustedType ? BusinessDayAdjustmentsHelper.Create(BusinessDayConventionEnum.NONE, legParametersRange.PaymentCalendar) : BusinessDayAdjustmentsHelper.Create(legParametersRange.PaymentBusinessDayAdjustments, legParametersRange.PaymentCalendar); stream.calculationPeriodDates.calculationPeriodFrequency = CalculationPeriodFrequencyHelper.Parse(legParametersRange.PaymentFrequency, legParametersRange.RollConvention); stream.paymentDates.paymentFrequency = PeriodHelper.Parse(legParametersRange.PaymentFrequency).ToFrequency(); stream.paymentDates.paymentDatesAdjustments = BusinessDayAdjustmentsHelper.Create(legParametersRange.PaymentBusinessDayAdjustments, legParametersRange.PaymentCalendar); stream.resetDates.fixingDates = RelativeDateOffsetHelper.Create(legParametersRange.PaymentFrequency, DayTypeEnum.Business, BusinessDayConventionEnum.NONE.ToString(), legParametersRange.FixingCalendar, "resetDates");//"NONE" & "resedDates" - hardcoded stream.resetDates.resetFrequency = ResetFrequencyHelper.Parse(legParametersRange.PaymentFrequency); stream.resetDates.resetDatesAdjustments = BusinessDayAdjustmentsHelper.Create(legParametersRange.FixingBusinessDayAdjustments, legParametersRange.FixingCalendar); Calculation calculation = XsdClassesFieldResolver.CalculationPeriodAmountGetCalculation(stream.calculationPeriodAmount); // Set discounting type // calculation.discounting = discounting; // Set notional amount (as the initial value in notional schedule) // SetNotional(calculation, legParametersRange.NotionalAmount, legParametersRange.Currency); // Set floating rate index name // string indexTenor = legParametersRange.PaymentFrequency; string indexName = legParametersRange.ForecastIndexName; FloatingRateCalculation floatingRateCalculation = FloatingRateCalculationFactory.Create(indexName, indexTenor, legParametersRange.FloatingRateSpread); XsdClassesFieldResolver.CalculationSetFloatingRateCalculation(calculation, floatingRateCalculation); if (legParametersRange.CapOrFloor == CapFloorType.Cap) { floatingRateCalculation.capRateSchedule = new[] { new StrikeSchedule() }; floatingRateCalculation.capRateSchedule[0].initialValue = legParametersRange.StrikeRate; floatingRateCalculation.capRateSchedule[0].buyer = new IdentifiedPayerReceiver { Value = PayerReceiverEnum.Receiver }; floatingRateCalculation.capRateSchedule[0].seller = new IdentifiedPayerReceiver { Value = PayerReceiverEnum.Payer }; } else { floatingRateCalculation.floorRateSchedule = new[] { new StrikeSchedule() }; floatingRateCalculation.floorRateSchedule[0].initialValue = legParametersRange.StrikeRate; floatingRateCalculation.floorRateSchedule[0].buyer = new IdentifiedPayerReceiver { Value = PayerReceiverEnum.Receiver }; floatingRateCalculation.floorRateSchedule[0].seller = new IdentifiedPayerReceiver { Value = PayerReceiverEnum.Payer }; } // Set day count convention // calculation.dayCountFraction = DayCountFractionHelper.Parse(legParametersRange.DayCount); return(stream); }
private static InterestRateStream GenerateFloatingStreamDefinition(SwapLegParametersRange legParametersRange) { Discounting discounting = null; InterestRateStream stream; if (legParametersRange.DiscountingType != null && legParametersRange.DiscountingType.ToUpper() != "NONE") { discounting = new Discounting { discountingType = EnumHelper.Parse <DiscountingTypeEnum>(legParametersRange.DiscountingType) }; // Create the stream object stream = InterestRateStreamFactory.CreateFloatingRateStream(DiscountingTypeToPayRelativeTo(discounting.discountingType)); } else { // Create the stream object // stream = InterestRateStreamFactory.CreateFloatingRateStream(DiscountingTypeToPayRelativeTo(null)); } // Set effective and termination dates of the stream. // SetEffectiveAndTerminationDates(stream, legParametersRange.EffectiveDate, legParametersRange.MaturityDate, legParametersRange.PaymentBusinessDayAdjustments, legParametersRange.PaymentCalendar); //Set the FirstRegularPeriodStartDate SetFirstRegularPeriodStartDate(stream, legParametersRange.FirstRegularPeriodStartDate); //Set the LastRegularPeriodEndDate SetLastRegularPeriodEndDate(stream, legParametersRange.LastRegularPeriodEndDate); // Adjusted or unadjusted swap //Set the stub period type var dateAdjustments = AdjustedType.Adjusted != legParametersRange.AdjustedType ? BusinessDayAdjustmentsHelper.Create(BusinessDayConventionEnum.NONE, legParametersRange.PaymentCalendar) : BusinessDayAdjustmentsHelper.Create(legParametersRange.PaymentBusinessDayAdjustments, legParametersRange.PaymentCalendar); stream.calculationPeriodDates.calculationPeriodDatesAdjustments = dateAdjustments; stream.calculationPeriodDates.calculationPeriodFrequency = CalculationPeriodFrequencyHelper.Parse(legParametersRange.PaymentFrequency, legParametersRange.RollConvention); if (legParametersRange.FirstCouponType == FirstCouponType.Full) { var firstCouponStartDate = new AdjustableDate { dateAdjustments = dateAdjustments, id = "FullFirstCoupon" }; SetFirstPeriodStartDate(stream, firstCouponStartDate); } //Set the payment dates stream.paymentDates.paymentFrequency = PeriodHelper.Parse(legParametersRange.PaymentFrequency).ToFrequency(); stream.paymentDates.paymentDatesAdjustments = BusinessDayAdjustmentsHelper.Create(legParametersRange.PaymentBusinessDayAdjustments, legParametersRange.PaymentCalendar); stream.resetDates.fixingDates = RelativeDateOffsetHelper.Create(legParametersRange.PaymentFrequency, DayTypeEnum.Business, BusinessDayConventionEnum.NONE.ToString(), legParametersRange.FixingCalendar, "resetDates");//"NONE" & "resedDates" - hardcoded stream.resetDates.resetFrequency = ResetFrequencyHelper.Parse(legParametersRange.PaymentFrequency); stream.resetDates.resetDatesAdjustments = BusinessDayAdjustmentsHelper.Create(legParametersRange.FixingBusinessDayAdjustments, legParametersRange.FixingCalendar); Calculation calculation = XsdClassesFieldResolver.CalculationPeriodAmountGetCalculation(stream.calculationPeriodAmount); // Set discounting type // calculation.discounting = discounting; // Set notional amount (as the initial value in notional schedule) // SetNotional(calculation, legParametersRange.NotionalAmount, legParametersRange.Currency); // Set floating rate index name // string indexTenor = legParametersRange.PaymentFrequency; //string indexName = legParametersRange.ForecastCurve; string indexName = legParametersRange.ForecastIndexName; FloatingRateCalculation floatingRateCalculation = FloatingRateCalculationFactory.Create(indexName, indexTenor, legParametersRange.FloatingRateSpread); XsdClassesFieldResolver.CalculationSetFloatingRateCalculation(calculation, floatingRateCalculation); // Set day count convention // calculation.dayCountFraction = DayCountFractionHelper.Parse(legParametersRange.DayCount); return(stream); }
public static void CalculationSetFloatingRateCalculation(Calculation calculation, FloatingRateCalculation floatingRateCalculation) { calculation.Items = new object[] { floatingRateCalculation }; }
private static void UpdateCalculationPeriodData(Calculation calculation, CalculationPeriod calculationPeriod, Notional notinalSchedule) { bool hasFloatingRateCalculation = XsdClassesFieldResolver.CalculationHasFloatingRateCalculation(calculation); bool hasFixedRate = XsdClassesFieldResolver.CalculationHasFixedRateSchedule(calculation); if (!(hasFloatingRateCalculation ^ hasFixedRate)) { throw new System.Exception("at least one type of rate (floating or fixed) must be specified."); } decimal notional = NotionalHelper.GetNotionalValue(notinalSchedule, calculationPeriod.adjustedStartDate); // Notional amount // XsdClassesFieldResolver.CalculationPeriodSetNotionalAmount(calculationPeriod, notional); // Fixed rate // if (hasFixedRate) { Schedule fixedRateSchedule = XsdClassesFieldResolver.CalculationGetFixedRateSchedule(calculation); decimal fixedRate = ScheduleHelper.GetValue(fixedRateSchedule, calculationPeriod.adjustedStartDate); XsdClassesFieldResolver.SetCalculationPeriodFixedRate(calculationPeriod, fixedRate); } // Floating rate // else// if (hasFloatingRateCalculation) { // no observed, no calculated rate, spread == 0.0 // var floatingRateDefinition = (FloatingRateDefinition)calculationPeriod.Item1 ?? new FloatingRateDefinition(); // check if stream has spreadSchedule // if (XsdClassesFieldResolver.CalculationHasSpreadSchedule(calculation)) { Schedule spreadSchedule = XsdClassesFieldResolver.GetCalculationSpreadSchedule(calculation); decimal spread = ScheduleHelper.GetValue(spreadSchedule, calculationPeriod.adjustedStartDate); floatingRateDefinition.spread = spread; floatingRateDefinition.spreadSpecified = true; } FloatingRateCalculation floatingRateCalculation = XsdClassesFieldResolver.CalculationGetFloatingRateCalculation(calculation); // Check if there's a capRateSchedule // if (null != floatingRateCalculation.capRateSchedule) { StrikeSchedule capRateSchedule = floatingRateCalculation.capRateSchedule[0]; var capStrike = new Strike(); var capRate = ScheduleHelper.GetValue(capRateSchedule, calculationPeriod.adjustedStartDate); capStrike.strikeRate = capRate; floatingRateDefinition.capRate = new[] { capStrike }; } // Check if there's a capRateSchedule // if (null != floatingRateCalculation.floorRateSchedule) { StrikeSchedule floorRateSchedule = floatingRateCalculation.floorRateSchedule[0]; var floorStrike = new Strike(); decimal floorRate = ScheduleHelper.GetValue(floorRateSchedule, calculationPeriod.adjustedStartDate); floorStrike.strikeRate = floorRate; floatingRateDefinition.floorRate = new[] { floorStrike }; } calculationPeriod.Item1 = floatingRateDefinition; } }
public static Schedule GetCalculationSpreadSchedule(Calculation calculation) { FloatingRateCalculation floatingRateCalculation = CalculationGetFloatingRateCalculation(calculation); return(floatingRateCalculation.spreadSchedule[0]); }
///<summary> /// Gets all the Forecast curve name. ///</summary> ///<returns></returns> private static string GetForecastCurveName(PricingStructureTypeEnum curveType, FloatingRateCalculation floatingRateIndex) { return(curveType + "." + floatingRateIndex.floatingRateIndex.Value + "-" + floatingRateIndex.indexTenor.ToString()); }
///<summary> /// Gets all the Discount curve name. ///</summary> ///<returns></returns> public static string GetForecastCurveName(FloatingRateCalculation floatingRateIndex) { return(GetForecastCurveName(PricingStructureTypeEnum.RateCurve, floatingRateIndex)); }