/// <summary> /// Calculates the specified model data. /// </summary> /// <param name="valuationDate">The valuation date.</param> /// <param name="discountCurve">The discount curve.</param> /// <param name="forecastCurve">The forward curve.</param> /// <param name="volCurve">The volatility surface. /// and discount curves when called with ForecastRateCurve.</param> /// <param name="curveToPerturb">The curve to perturb: the discount curve, the forecast curve or both.</param> /// <returns></returns> public IDictionary <string, double> CalculateRatePDH(DateTime valuationDate, IRateCurve discountCurve, IRateCurve forecastCurve, IVolatilitySurface volCurve, CurvePerturbation curveToPerturb) { var result = new Dictionary <string, double>(); AnalyticResults = new RateOptionAssetResults(); switch (ModelIdentifier) { case "CapAsset": AnalyticsModel = new RateOptionAssetAnalytic(); break; case "DiscountCapAsset": AnalyticsModel = new RateOptionAssetAnalytic(); break; } ForecastCurveName = forecastCurve.GetPricingStructureId().UniqueIdentifier; DiscountCurveName = discountCurve.GetPricingStructureId().UniqueIdentifier; VolatilityCurveName = volCurve.GetPricingStructureId().UniqueIdentifier; var analyticModelParameters = new RateOptionAssetParameters { IsPut = !IsCap, Notionals = Notionals }; //and the rest rates if (ResetRates != null) { analyticModelParameters.ForwardRates = ResetRates; } //2. Get the discount factors analyticModelParameters.ForecastDiscountFactors = GetDiscountFactors(forecastCurve, AdjustedPeriodDates.ToArray(), valuationDate); analyticModelParameters.PaymentDiscountFactors = GetDiscountFactors(discountCurve, AdjustedPeriodDates.ToArray(), valuationDate); //3. Get the respective year fractions analyticModelParameters.YearFractions = YearFractions; //4. set the expiry times. TimesToExpiry = GetTimesToExpiry(ExpiryDates, valuationDate); analyticModelParameters.TimesToExpiry = TimesToExpiry; //5. Get the vols analyticModelParameters.Volatilities = GetVolatilties(volCurve, TimesToExpiry, Strikes); //8. Get the Strikes analyticModelParameters.Strikes = Strikes; //9. Set the analytic input parameters and Calculate the respective metrics var analyticResults = AnalyticsModel.Calculate <IRateOptionAssetResults, RateOptionAssetResults>(analyticModelParameters, new[] { RateOptionMetrics.NPV }); AnalyticResults = analyticResults; var baseNPV = SumDoubleList(AnalyticResults.NPV, 0); //Now loop through the risk curves. if (curveToPerturb == CurvePerturbation.DiscountCurve) { var riskCurves = discountCurve.CreateCurveRiskSet(1); foreach (var curve in riskCurves) { var perturbedAsset = curve.GetPricingStructureId().Properties.GetValue <string>("PerturbedAsset"); analyticResults = RiskCalculationHelper((IRateCurve)curve, analyticModelParameters); result.Add("DiscountCurve:" + perturbedAsset, baseNPV - SumDoubleList(analyticResults.NPV, 0)); } } if (curveToPerturb == CurvePerturbation.ForecastCurve) { var riskCurves = forecastCurve.CreateCurveRiskSet(1); foreach (var curve in riskCurves) { var perturbedAsset = curve.GetPricingStructureId().Properties.GetValue <string>("PerturbedAsset"); analyticResults = ForecastRiskCalculationHelper((IRateCurve)curve, analyticModelParameters); result.Add("ForecastCurve:" + perturbedAsset, baseNPV - SumDoubleList(analyticResults.NPV, 0)); } } if (curveToPerturb == CurvePerturbation.Both) { var riskCurves1 = discountCurve.CreateCurveRiskSet(1); foreach (var curve in riskCurves1) { var perturbedAsset = curve.GetPricingStructureId().Properties.GetValue <string>("PerturbedAsset"); analyticResults = RiskCalculationHelper((IRateCurve)curve, analyticModelParameters); result.Add("DiscountCurve:" + perturbedAsset, baseNPV - SumDoubleList(analyticResults.NPV, 0)); } var riskCurves2 = forecastCurve.CreateCurveRiskSet(1); foreach (var curve in riskCurves2) { var perturbedAsset = curve.GetPricingStructureId().Properties.GetValue <string>("PerturbedAsset"); analyticResults = ForecastRiskCalculationHelper((IRateCurve)curve, analyticModelParameters); result.Add("ForecastCurve:" + perturbedAsset, baseNPV - SumDoubleList(analyticResults.NPV, 0)); } } return(result); }