public void FloatingRateCouponAnalyicsDiscounted() { IRateCouponParameters analyticModelParameters = new RateCouponParameters { Rate = .05m, DiscountType = DiscountType.AFMA, YearFraction = 0.25m, NotionalAmount = 10000000m, HasReset = false, EndDiscountFactor = 0.9m, PaymentDiscountFactor = 0.99m, StartDiscountFactor = 1.0m, CurveYearFraction = 3.0m, DiscountRate = .05m }; var model = new FloatingRateCouponAnalytic { AnalyticParameters = analyticModelParameters }; var value = analyticModelParameters.NotionalAmount * analyticModelParameters.Rate * analyticModelParameters.YearFraction; var result = model.ImpliedQuote; var delta1 = (double)model.Delta1; var delta0 = (double)model.Delta0; var expectedValue = (double)model.ExpectedValue; Debug.Print(result.ToString()); Debug.Print(value.ToString()); Debug.Print(delta1.ToString()); Debug.Print(delta0.ToString()); Debug.Print(expectedValue.ToString()); Assert.AreEqual(delta1, 297, 10 - 6); Assert.AreEqual(delta0, -24.6913580246914, 10 - 6); Assert.AreEqual(expectedValue, 1000000, 10 - 6); }
public void FloatingRateCouponAnalyicsDiscounted() { IRateCouponParameters anlayticModelParameters = new RateCouponParameters(); anlayticModelParameters.Rate = .05m; anlayticModelParameters.IsDiscounted = true; anlayticModelParameters.YearFraction = 0.25m; anlayticModelParameters.NotionalAmount = 10000000m; anlayticModelParameters.HasReset = false; anlayticModelParameters.EndDiscountFactor = 0.9m; anlayticModelParameters.PaymentDiscountFactor = 0.99m; anlayticModelParameters.StartDiscountFactor = 1.0m; anlayticModelParameters.CurveYearFraction = 3.0m; var model = new FloatingRateCouponAnalytic { AnalyticParameters = anlayticModelParameters }; var value = anlayticModelParameters.NotionalAmount * anlayticModelParameters.Rate * anlayticModelParameters.YearFraction; var result = model.ImpliedQuote; var delta1 = model.Delta1; var delta0 = model.Delta0; var expectedValue = model.ExpectedValue; Debug.Print(result.ToString()); Debug.Print(value.ToString()); Debug.Print(delta1.ToString()); Debug.Print(delta0.ToString()); Debug.Print(expectedValue.ToString()); Assert.AreEqual(delta1, -36.66666666666666666666666663m); Assert.AreEqual(delta0, 2444444.444444444444444444442m); Assert.AreEqual(expectedValue, 123456.79012345679012345679m); }
public void TestBucketedDelta2() { DateTime swapStartDate = new DateTime(2008, 7, 22); int len = _bucketedDates.Length; var couponAnalytics = new FloatingRateCouponAnalytic[len - 1]; IRateCouponParameters[] analyticModelParameters = new RateCouponParameters[len - 1]; int index = 0; for (int i = 1; i < len; ++i) { IRateCouponParameters cp = new RateCouponParameters(); cp.BucketedDates = CreateArray <DateTime>(_bucketedDates, 0, i + 1); cp.BucketedDiscountFactors = CreateArray <Decimal>(_bucketedDiscountFactors, 0, i + 1); analyticModelParameters[index] = cp; FloatingRateCouponAnalytic am = new FloatingRateCouponAnalytic(); am.AnalyticParameters = cp; am.AnalyticParameters.YearFraction = (_bucketedDates[index + 1] - _bucketedDates[index]).Days / 365.0m; am.AnalyticParameters.StartDiscountFactor = _bucketedDiscountFactors[index]; am.AnalyticParameters.EndDiscountFactor = _bucketedDiscountFactors[index + 1]; am.AnalyticParameters.NotionalAmount = 1.0m; am.AnalyticParameters.CurveYearFraction = (_bucketedDates[i] - swapStartDate).Days / 365; am.AnalyticParameters.PeriodAsTimesPerYear = 0.5m; am.AnalyticParameters.Rate = 0.08m; //am.GetRate(_bucketedDates[index], _bucketedDates[index + 1], _bucketedDiscountFactors[index + 1]); couponAnalytics[index] = am; ++index; } Decimal bucketedDelta = 0.0m; for (int i = 0; i < analyticModelParameters.Length; ++i) { bucketedDelta += couponAnalytics[i].BucketedDelta1; } }
public void Test3BucketedDelta1() { Decimal[] bucketedDFs = { 1.0m, 0.982613396m, 0.967914626m, 0.951866237m, 0.935722838m, 0.920271649m, 0.90599351m, 0.891917121m, 0.876331328m, 0.857381051m, 0.838427108m, 0.819274593m, 0.800559587m, 0.786315952m, 0.77267004m, 0.75896562m, 0.745504268m, 0.731916167m, 0.719003072m, 0.705894128m, 0.693024188m, 0.682143198m, 0.671798015m, 0.661269003m, 0.650905012m, 0.641254932m, 0.632061478m, 0.622696653m, 0.61347058m }; Decimal[] curveYearFractions = { 0.0m, 0.4958904110m, 1.0m, 1.495890411m, 2.005479452m, 2.495890411m, 3.002739726m, 3.501369863m, 4.002739726m, 4.498630137m, 5.002739726m, 5.498630137m, 6.002739726m, 6.498630137m }; Decimal[] floatingRates = { 0.066847m, 0.068245m, 0.066172m, 0.067239m, 0.091327m, 0.093843m, 0.072271m, 0.072278m, 0.074327m, 0.074361m, 0.063716m, 0.063673m, 0.06012m, 0.060115m }; int len = curveYearFractions.Length; IRateCouponParameters[] analyticModelParameters = new RateCouponParameters[len]; var couponAnalytics = new FloatingRateCouponAnalytic[len]; for (int i = 0; i < len; ++i) { IRateCouponParameters cp = new RateCouponParameters(); cp.BucketedDiscountFactors = bucketedDFs; analyticModelParameters[i] = cp; FloatingRateCouponAnalytic am = new FloatingRateCouponAnalytic { AnalyticParameters = cp }; am.AnalyticParameters.StartDiscountFactor = bucketedDFs[0]; am.AnalyticParameters.EndDiscountFactor = bucketedDFs[len - 1]; am.AnalyticParameters.NotionalAmount = 10000000.0m; am.AnalyticParameters.Rate = floatingRates[i]; am.AnalyticParameters.YearFraction = 0.495890411m; am.AnalyticParameters.CurveYearFraction = curveYearFractions[i]; am.AnalyticParameters.PeriodAsTimesPerYear = 0.252054795m; couponAnalytics[i] = am; } Decimal bucketedDelta = 0.0m; for (int i = 0; i < analyticModelParameters.Length; ++i) { bucketedDelta += couponAnalytics[i].BucketedDelta1; } }
/// <summary> /// Calculates the specified model data. /// </summary> /// <param name="modelData">The model data.</param> /// <returns></returns> public override AssetValuation Calculate(IInstrumentControllerData modelData) { ModelData = modelData; AnalyticModelParameters = null; AnalyticsModel = new FloatingRateCouponAnalytic(); RequiresReset = modelData.ValuationDate > ResetDate; IsRealised = HasBeenRealised(ModelData.ValuationDate); //Make sure there are some bucket dates even if not set previously. if (BucketedDates.Length < 1) { UpdateBucketingInterval(ModelData.ValuationDate, PeriodHelper.Parse(CDefaultBucketingInterval)); } //Add the extra metrics required var quotes = ModelData.AssetValuation.quote.ToList(); if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.BreakEvenRate.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.BreakEvenRate.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.AccrualFactor.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.AccrualFactor.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.FloatingNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.FloatingNPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.NPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.NPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.RiskNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.RiskNPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.LocalCurrencyNPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyExpectedValue.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.LocalCurrencyExpectedValue.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } //Check if risk calc are required. bool delta1PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta1PDH.ToString()) != null || AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta1PDH.ToString()) != null; //Check if risk calc are required. bool delta0PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta0PDH.ToString()) != null || AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta0PDH.ToString()) != null; ModelData.AssetValuation.quote = quotes.ToArray(); var metrics = ResolveModelMetrics(AnalyticsModel.Metrics); IFxCurve fxCurve = null; IRateCurve discountCurve = null; IRateCurve forecastCurve = null; //// Determine if DFAM has been requested - if so thats all we evaluate - every other metric is ignored //if (metrics.Contains(InstrumentMetrics.DiscountFactorAtMaturity)) //{ // metrics.RemoveAll(metricItem => metricItem != InstrumentMetrics.DiscountFactorAtMaturity); //} //Set the forrecast rate dates. The ForecastRateInterpolation shhould have been set. ForwardStartDate = AccrualStartDate; ForwardEndDate = ForecastRateInterpolation ? AccrualEndDate : AdjustedDateHelper.ToAdjustedDate(FixingCalendar, ForecastRateIndex.indexTenor.Add(ForwardStartDate), AccrualBusinessDayAdjustments); //var metricsToEvaluate = metrics.ToArray(); if (metrics.Count > 0) { YearFractionToCashFlowPayment = GetPaymentYearFraction(ModelData.ValuationDate, PaymentDate); var reportingCurrency = ModelData.ReportingCurrency == null ? PaymentCurrency.Value : ModelData.ReportingCurrency.Value; var amount = NotionalAmount.amount; IRateCouponParameters analyticModelParameters = new RateCouponParameters { Multiplier = Multiplier, ValuationDate = modelData.ValuationDate, PaymentDate = PaymentDate, Currency = PaymentCurrency.Value, ReportingCurrency = reportingCurrency, DiscountType = DiscountType, IsRealised = IsRealised, HasReset = RequiresReset, NotionalAmount = amount, Spread = Margin, YearFraction = CouponYearFraction, CurveYearFraction = YearFractionToCashFlowPayment }; decimal?discountRate = null; // Curve Related if (modelData.MarketEnvironment is ISwapLegEnvironment environment) { var streamMarket = environment; discountCurve = streamMarket.GetDiscountRateCurve(); discountCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; forecastCurve = streamMarket.GetForecastRateCurve(); forecastCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; DiscountCurveName = discountCurve.GetPricingStructureId().UniqueIdentifier; analyticModelParameters.DiscountCurve = discountCurve; ForecastCurveName = forecastCurve.GetPricingStructureId().UniqueIdentifier; analyticModelParameters.ForecastCurve = forecastCurve; // Bucketed Delta if (BucketedDates.Length > 1) { analyticModelParameters.PeriodAsTimesPerYear = GetPaymentYearFraction(BucketedDates[0], BucketedDates[1]); analyticModelParameters.BucketedDiscountFactors = GetBucketedDiscountFactors(discountCurve, ModelData. ValuationDate, BucketedDates); } //Check for currency. if (ModelData.ReportingCurrency != null) { if (ModelData.ReportingCurrency.Value != PaymentCurrency.Value) { fxCurve = streamMarket.GetReportingCurrencyFxCurve(); fxCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.ReportingCurrencyFxCurve = fxCurve; } } AnalyticModelParameters = analyticModelParameters; } else if (modelData.MarketEnvironment.GetType() == typeof(MarketEnvironment)) { var market = (MarketEnvironment)modelData.MarketEnvironment; discountCurve = (IRateCurve)market.SearchForPricingStructureType(DiscountCurveName); discountCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; forecastCurve = (IRateCurve)market.SearchForPricingStructureType(ForecastCurveName); forecastCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.DiscountCurve = discountCurve; analyticModelParameters.ForecastCurve = forecastCurve; // Bucketed Delta if (BucketedDates.Length > 1) { analyticModelParameters.PeriodAsTimesPerYear = GetPaymentYearFraction(BucketedDates[0], BucketedDates[1]); analyticModelParameters.BucketedDiscountFactors = GetBucketedDiscountFactors(discountCurve, ModelData. ValuationDate, BucketedDates); } if (delta1PDH) { var riskMarket = market.SearchForPerturbedPricingStructures(DiscountCurveName, "delta1PDH"); analyticModelParameters.Delta1PDHCurves = riskMarket; analyticModelParameters.Delta1PDHPerturbation = 10; } if (delta0PDH) { var riskMarket = market.SearchForPerturbedPricingStructures(ForecastCurveName, "delta0PDH"); analyticModelParameters.Delta0PDHCurves = riskMarket; analyticModelParameters.Delta0PDHPerturbation = 10; } //Check for currency. if (ModelData.ReportingCurrency != null) { if (ModelData.ReportingCurrency.Value != PaymentCurrency.Value) { string curveName = MarketEnvironmentHelper.ResolveFxCurveNames(PaymentCurrency.Value, modelData.ReportingCurrency.Value); fxCurve = (IFxCurve)market.SearchForPricingStructureType(curveName); fxCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.ReportingCurrencyFxCurve = fxCurve; } } AnalyticModelParameters = analyticModelParameters; } //Set the base rate. Default is zero if (AnalyticModelParameters != null) { AnalyticModelParameters.BaseRate = BaseRate; } if (UseObservedRate) { AnalyticsModel = new FixedRateCouponAnalytic(ModelData.ValuationDate, AccrualStartDate, AccrualEndDate, PaymentDate, Rate, analyticModelParameters.YearFraction, DiscountType, fxCurve, discountCurve, forecastCurve); if (Rate != null) { analyticModelParameters.Rate = (decimal)Rate; } } else { if (Rate != null) { discountRate = Rate; } if (DiscountRate != null) { discountRate = DiscountRate; } AnalyticsModel = new FloatingRateCouponAnalytic(ModelData.ValuationDate, AccrualStartDate, AccrualEndDate, PaymentDate, discountRate, analyticModelParameters.YearFraction, DiscountType, fxCurve, discountCurve, forecastCurve); } CalculationResults = AnalyticsModel.Calculate <IRateInstrumentResults, RateInstrumentResults>(AnalyticModelParameters, metrics.ToArray()); CalculationPerfomedIndicator = true; PaymentDiscountFactor = ((FixedRateCouponAnalytic)AnalyticsModel).PaymentDiscountFactor; if (!UseObservedRate) { Rate = CalculationResults.BreakEvenRate; } ForecastAmount = MoneyHelper.GetAmount(CalculationResults.LocalCurrencyExpectedValue, PaymentAmount.currency); NPV = MoneyHelper.GetAmount(CalculationResults.LocalCurrencyNPV, PaymentAmount.currency); } AssetValuation valuation = GetValue(CalculationResults, modelData.ValuationDate); valuation.id = Id; return(valuation); }
public PriceableComplexRateCoupon() { PriceableCouponType = CouponType.ComplexRate; AnalyticsModel = new FloatingRateCouponAnalytic(); }
// <summary> // Initializes a new instance of the <see cref="PriceableRateCoupon"/> class. // </summary> // <param name="cashlfowId">The stream id.</param> // <param name="accrualStartDate">The accrual start date. If adjusted, the adjustCalculationDatesIndicator should be false.</param> // <param name="accrualEndDate">The accrual end date. If adjusted, the adjustCalculationDatesIndicator should be false.</param> // <param name="adjustCalculationDatesIndicator">if set to <c>true</c> [adjust calculation dates indicator].</param> // <param name="accrualBusinessCenters">The accrual business centers.</param> // <param name="margin">The margin.</param> // <param name="observedRate">The observed Rate.</param> // <param name="notionalAmount">The notional amount.</param> // <param name="dayCountfraction">Type of day Countfraction.</param> // <param name="paymentDate">The payment date.</param> // <param name="accrualRollConvention">The accrual roll convention.</param> // <param name="resetRelativeTo">reset relative to?</param> // <param name="fixingDateRelativeOffset">The fixing date offset.</param> // <param name="forecastRateIndex">The forecastrateindex.</param> // <param name="discountingType">The swap discounting type.</param> // <param name="discountRate">The discount rate.</param> // <param name="fraDiscounting">Determines whether the coupon is discounted or not. If this parameter is null, // then it is assumed that there is no fradiscounting</param> //public PriceableComplexRateCoupon // ( // string cashlfowId // , DateTime accrualStartDate // , DateTime accrualEndDate // , Boolean adjustCalculationDatesIndicator // , BusinessCenters accrualBusinessCenters // , BusinessDayConventionEnum accrualRollConvention // , DayCountFraction dayCountfraction // , ResetRelativeToEnum resetRelativeTo // , RelativeDateOffset fixingDateRelativeOffset // , Decimal margin // , Decimal? observedRate // , Money notionalAmount // , AdjustableDate paymentDate // , ForecastRateIndex forecastRateIndex // , DiscountingTypeEnum? discountingType // , Decimal? discountRate // , FraDiscountingEnum? fraDiscounting) // : base( // cashlfowId // , CouponType.FloatingRate // , accrualStartDate // , accrualEndDate // , adjustCalculationDatesIndicator // , accrualBusinessCenters // , accrualRollConvention // , dayCountfraction // , observedRate // , notionalAmount // , paymentDate // , discountingType // , discountRate // , fraDiscounting // ) //{ //} //public PriceableComplexRateCoupon // (string uniqueId // , DateTime accrualStartDate // , DateTime accrualEndDate // , Boolean adjustCalculationDatesIndicator // , AdjustableDate paymentDate // , Money notionalAmount // , ResetRelativeToEnum resetRelativeTo // , RelativeDateOffset fixingDateRelativeOffset // , Decimal margin // , Calculation calculation // , ForecastRateIndex forecastRateIndex // ) // : base // (uniqueId // , CouponType.FloatingRate // , accrualStartDate // , accrualEndDate // , adjustCalculationDatesIndicator // , BusinessDayAdjustmentsHelper.Create(fixingDateRelativeOffset.businessDayConvention, fixingDateRelativeOffset.businessCenters) // , calculation // , notionalAmount // , paymentDate // ) //{ //} #endregion #region Metrics for Valuation /// <summary> /// Calculates the specified model data. /// </summary> /// <param name="modelData">The model data.</param> /// <returns></returns> override public AssetValuation Calculate(IInstrumentControllerData modelData) { ModelData = modelData; AnalyticModelParameters = null; RequiresReset = modelData.ValuationDate > ResetDate; IsRealised = HasBeenRealised(ModelData.ValuationDate); if (AnalyticsModel == null) { AnalyticsModel = new FloatingRateCouponAnalytic(); } var metrics = ResolveModelMetrics(AnalyticsModel.Metrics); // Determine if DFAM has been requested - if so thats all we evaluate - every other metric is ignored if (metrics.Contains(RateInstrumentMetrics.DiscountFactorAtMaturity)) { metrics.RemoveAll(metricItem => metricItem != RateInstrumentMetrics.DiscountFactorAtMaturity); } var metricsToEvaluate = metrics.ToArray(); if (metricsToEvaluate.Length > 0) { //May need to adapt for fra discounting. var isDiscounted = (GetDiscountingTypeEnum() == DiscountingTypeEnum.Standard ? true : false); var reportingCurrency = ModelData.ReportingCurrency == null ? PaymentCurrency.Value : ModelData.ReportingCurrency.Value; IRateCouponParameters analyticModelParameters = new RateCouponParameters { Currency = PaymentCurrency.Value, ReportingCurrency = reportingCurrency, IsDiscounted = isDiscounted, IsRealised = IsRealised, HasReset = RequiresReset, NotionalAmount = NotionalAmount.amount, Spread = Margin, Rate = GetRate(), DiscountRate = GetRate(), YearFraction = CouponYearFraction }; // Curve Related var streamMarket = (ISwapLegEnvironment)modelData.MarketEnvironment; var discountCurve = streamMarket.GetDiscountRateCurve(); discountCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; var fwdCurve = streamMarket.GetForecastRateCurve(); fwdCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; DiscountCurveName = discountCurve.GetPricingStructureId().UniqueIdentifier; ForecastCurveName = fwdCurve.GetPricingStructureId().UniqueIdentifier; //Setting the parameters analyticModelParameters.StartDiscountFactor = (decimal)fwdCurve.GetDiscountFactor(ModelData.ValuationDate, AccrualStartDate); analyticModelParameters.EndDiscountFactor = (decimal)fwdCurve.GetDiscountFactor(ModelData.ValuationDate, AccrualEndDate); analyticModelParameters.PaymentDiscountFactor = (decimal)discountCurve.GetDiscountFactor(ModelData.ValuationDate, PaymentDate); analyticModelParameters.CurveYearFraction = GetPaymentYearFraction(ModelData.ValuationDate, PaymentDate); // Bucketed Delta if (BucketedDates.Count > 1) { analyticModelParameters.PeriodAsTimesPerYear = GetPaymentYearFraction(BucketedDates[0], BucketedDates[1]); analyticModelParameters.BucketedDiscountFactors = GetBucketedDiscountFactors(discountCurve, ModelData.ValuationDate, BucketedDates); } IRateInstrumentResults analyticResults = AnalyticsModel.Calculate <IRateInstrumentResults, RateInstrumentResults>(analyticModelParameters, metricsToEvaluate); UpdateResults(metricsToEvaluate, analyticResults); // store inputs and results from this run AnalyticModelParameters = analyticModelParameters; CalculationPerfomedIndicator = true; } AssetValuation valuation = GetValue(CalculationResults); valuation.id = Id; return(valuation); }