public double GetVolForAbsoluteStrike(double strike, double maturity, double forward) { var expiry = OriginDate.AddYearFraction(maturity, DayCountBasis.Act365F); var pair = FundingModel.FxMatrix.GetFxPair(AssetSurface.Currency, Currency); var fxFwd = FundingModel.GetFxRate(pair.SpotDate(expiry), pair.Domestic, pair.Foreign); double vA, vF; switch (CalculationType) { case CompositeVolType.Black: vA = AssetSurface.GetVolForAbsoluteStrike(forward / fxFwd, expiry, forward / fxFwd); vF = FundingModel.GetVolSurface(pair.ToString()).GetVolForAbsoluteStrike(fxFwd, expiry, fxFwd); break; case CompositeVolType.AssetSkewOnly: vA = AssetSurface.GetVolForAbsoluteStrike(strike / fxFwd, expiry, forward / fxFwd); vF = FundingModel.GetVolSurface(pair.ToString()).GetVolForAbsoluteStrike(fxFwd, expiry, fxFwd); break; default: throw new Exception($"Unable to handle calc type {CalculationType}"); } var vC = System.Math.Sqrt(vA * vA + vF * vF + 2.0 * Correlation * vA * vF); return(vC); }
public double PV_LinearApprox(HazzardCurve hazzardCurve, IIrCurve discountCurve, double recoveryRate, bool payAccruedOnDefault = true) { var nodeDates = DatePeriodType.M.GenerateDateSchedule(hazzardCurve.OriginDate, FinalSensitivityDate); var ts = nodeDates.Select(d => discountCurve.BuildDate.CalculateYearFraction(d, DayCountBasis.ACT365F)).ToArray(); var integrandD = new Func <DateTime, double> (d => discountCurve.GetDf(discountCurve.BuildDate, d) * -hazzardCurve.GetSurvivalProbabilitySlope(d)); var integrandT = new Func <double, double>(t => integrandD(OriginDate.AddYearFraction(t, DayCountBasis.ACT365F))); //contingent leg var pv = (1.0 - recoveryRate) * Notional * Integration.SimpsonsRuleExtended(integrandT, 0, ts.Last(), 100); //fixed leg foreach (var f in FixedSchedule.Flows) { pv -= f.Notional * f.YearFraction * Spread * discountCurve.GetDf(discountCurve.BuildDate, f.SettleDate) * hazzardCurve.GetSurvivalProbability(f.SettleDate); if (payAccruedOnDefault) { pv -= 0.5 * f.Notional * f.YearFraction * Spread * hazzardCurve.GetDefaultProbability(f.AccrualPeriodStart, f.AccrualPeriodEnd) * discountCurve.GetDf(discountCurve.BuildDate, f.SettleDate); } } return(pv); }