public static double KVA(DateTime originDate, DateTime[] ExEDates, double[] CapExposures, IIrCurve fundingCurve) { if (ExEDates.Length != CapExposures.Length) { throw new Exception("Number of exposure dates and values must be equal"); } var lastDate = originDate; var kva = 0.0; for (var i = 0; i < ExEDates.Length; i++) { if (ExEDates[i] < originDate) { continue; } var fwdDf = fundingCurve.GetDf(lastDate, ExEDates[i]); var df = fundingCurve.GetDf(originDate, ExEDates[i]); kva += CapExposures[i] / fwdDf * df; lastDate = ExEDates[i]; } return(kva); }
public static (double FBA, double FCA) FVA(DateTime originDate, DateTime[] ExEDates, double[] EPEExposures, double[] ENEExposures, HazzardCurve hazzardCurve, IIrCurve discountCurve, IIrCurve fundingCurve) { if (ExEDates.Length != EPEExposures.Length) { throw new Exception("Number of EPE dates and EPE values must be equal"); } if (ExEDates.Length != ENEExposures.Length) { throw new Exception("Number of ENE dates and ENE values must be equal"); } var lastDate = originDate; var fba = 0.0; var fca = 0.0; for (var i = 0; i < ExEDates.Length; i++) { if (ExEDates[i] < originDate) { continue; } var pSurvival = hazzardCurve.GetSurvivalProbability(lastDate, ExEDates[i]); var fwdDf = fundingCurve.GetDf(lastDate, ExEDates[i]) / discountCurve.GetDf(lastDate, ExEDates[i]); var df = fundingCurve.GetDf(originDate, ExEDates[i]); fba += ENEExposures[i] * pSurvival / fwdDf * df; fca += EPEExposures[i] * pSurvival / fwdDf * df; lastDate = ExEDates[i]; } return(fba, fca); }
public static double PvProfile(DateTime originDate, DateTime[] exposureDates, double[] exposures, IIrCurve discountCurve) { var capital = 0.0; var time = 0.0; if (exposureDates.Length != exposures.Length || exposures.Length < 1) { throw new DataMisalignedException(); } if (exposureDates.Length == 1) { return(discountCurve.GetDf(originDate, exposureDates[0]) * exposures[0]); } for (var i = 0; i < exposureDates.Length - 1; i++) { var exposure = (exposures[i] + exposures[i + 1]) / 2.0; var df = discountCurve.GetDf(originDate, exposureDates[i + 1]); var dt = exposureDates[i].CalculateYearFraction(exposureDates[i + 1], DayCountBasis.ACT365F); capital += exposure * dt * df; time += dt; } return(capital / time); }
public double PV_SmallSteps(HazzardCurve hazzardCurve, IIrCurve discountCurve, double recoveryRate, bool payAccruedOnDefault = true) { var nodeDates = DatePeriodType.M.GenerateDateSchedule(hazzardCurve.OriginDate, FinalSensitivityDate); //contingent leg var pv = 0.0; for (var i = 1; i < nodeDates.Length; i++) { pv += discountCurve.GetDf(discountCurve.BuildDate, nodeDates[i]) * hazzardCurve.GetDefaultProbability(nodeDates[i - 1], nodeDates[i]); } pv *= (1.0 - recoveryRate) * Notional; //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); }
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); }
public static double CVA(DateTime originDate, DateTime[] EPEDates, double[] EPEExposures, HazzardCurve hazzardCurve, IIrCurve discountCurve, double LGD) { if (EPEDates.Length != EPEExposures.Length) { throw new Exception("Number of EPE dates and EPE values must be equal"); } var lastDate = originDate; var cva = 0.0; for (var i = 0; i < EPEDates.Length; i++) { if (EPEDates[i] < originDate) { continue; } var pDefault = hazzardCurve.GetDefaultProbability(lastDate, EPEDates[i]); var df = discountCurve.GetDf(originDate, EPEDates[i]); cva += EPEExposures[i] * pDefault * df * LGD; lastDate = EPEDates[i]; } return(-cva); }
public double RiskyDiscountFactor(DateTime startDate, DateTime endDate, IIrCurve discountCurve, double LGD) { var dp = GetDefaultProbability(startDate, endDate); var el = dp * LGD; var df = discountCurve.GetDf(startDate, endDate); return((1.0 - el) * df); }
public static double SwapPv(IPriceCurve priceCurve, AsianSwapStrip swap, IIrCurve discountCurve) { var swapletPVs = swap.Swaplets.Select(s => (priceCurve.GetAveragePriceForDates(s.FixingDates.AddPeriod(RollType.F, s.FixingCalendar, s.SpotLag)) - s.Strike) * (s.Direction == TradeDirection.Long ? 1.0 : -1.0) * discountCurve.GetDf(priceCurve.BuildDate, s.PaymentDate)); return(swapletPVs.Sum()); }
public static IrCurve StripFxBasisCurve(string cmeFwdFileName, string ccyPair, Currency curveCcy, string curveName, DateTime valDate, IIrCurve baseCurve) { var fwds = GetFwdFxRatesFromFwdFile(cmeFwdFileName, ccyPair); var dfs = fwds.ToDictionary(f => f.Key, f => fwds[valDate] / f.Value * baseCurve.GetDf(valDate, f.Key)); if (ccyPair.EndsWith("USD")) //flip dfs { dfs = dfs.ToDictionary(x => x.Key, x => 1.0 / x.Value); } var pillars = dfs.Keys.OrderBy(k => k).ToArray(); var dfsValues = pillars.Select(p => dfs[p]).ToArray(); var curve = new IrCurve(pillars, dfsValues, valDate, curveName, Interpolator1DType.Linear, curveCcy, null, RateType.DF); return(curve); }
//http://www.bnikolic.co.uk/cds/cdsvaluation.html //var contingentLeg = (1.0 - recoveryRate) * public double PV_PiecewiseFlat(HazzardCurve hazzardCurve, IIrCurve discountCurve, double recoveryRate, bool payAccruedOnDefault = true) { var nodeDates = FixedSchedule.Flows.Select(f => f.AccrualPeriodEnd).ToArray(); var pv = 0.0; //contingent leg var d = hazzardCurve.OriginDate; foreach (var nd in nodeDates) { var deltaT = d.CalculateYearFraction(nd, hazzardCurve.Basis); var s = hazzardCurve.GetSurvivalProbability(d); var dd = discountCurve.GetDf(discountCurve.BuildDate, d); var lambda = System.Math.Log(s / hazzardCurve.GetSurvivalProbability(nd)) / deltaT; var f = System.Math.Log(dd / discountCurve.GetDf(discountCurve.BuildDate, nd)) / deltaT; var term1 = (lambda == 0 && f == 0) ? 1.0 : lambda / (lambda + f); pv += term1 * (1.0 - System.Math.Exp(-deltaT * (lambda + f))) * s * dd; d = nd; } pv *= (1.0 - recoveryRate) * Notional; //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); }