public double ProtectionLegNPV_Exact(List <CashFlow> cf, double notional, PiecewiseconstantHazardRate hazard, YieldTermStructure yt, DateTime tradedate, DateTime settlementDate, double recoveryrate, List <DateTime> Jumps, List <DateTime> creditCurveKnot) { DateTime Stepindate = tradedate.AddDays(1); OMLib.Conventions.DayCount.Actual360 dc = new OMLib.Conventions.DayCount.Actual360(); if (cf.Count() == 0) { return(0.0); } DateTime t0 = tradedate; DateTime T = cf.Last().CashFlowDate; List <DateTime> JumpNodes = new List <DateTime>(); JumpNodes.Add(t0); for (int j = 0; j < Jumps.Count; j++) { if ((DateTime.Compare(Jumps[j], T) < 0)) { JumpNodes.Add(Jumps[j]); } } JumpNodes.Add(T); double ht0 = hazard.getRT(JumpNodes[0]); double rt0 = yt.getRT(JumpNodes[0]); double b0 = Math.Exp(-ht0 - rt0); // risky discount factor double pv = 0.0; double dPV = 0.0; for (int i = 1; i < JumpNodes.Count; ++i) { double ht1 = hazard.getRT(JumpNodes[i]); double rt1 = yt.getRT(JumpNodes[i]); double b1 = Math.Exp(-ht1 - rt1); double dht = ht1 - ht0; double drt = rt1 - rt0; double dhrt = dht + drt; // The formula has been modified from ISDA (but is equivalent) to avoid log(exp(x)) and explicitly // calculating the time step - it also handles the limit if (Math.Abs(dhrt) < 1e-5) { dPV = dht * b0 * (Math.Exp(-dhrt) - 1) / (-dhrt); } else { dPV = (b0 - b1) * dht / dhrt; } pv += dPV; ht0 = ht1; rt0 = rt1; b0 = b1; } return(pv * notional * (1 - recoveryrate) / yt.discount(settlementDate)); }
public double PremiumLegNPV_Exact(List <CashFlow> cf, PiecewiseconstantHazardRate hazard, YieldTermStructure yt, DateTime tradedate, DateTime settlementDate, double notional, double coupon, List <DateTime> Jumps, DateTime lastpayment) { if (cf.Count() == 0) { return(0.0); } double ita = (double)365 / 360; double totalNPV = 0.0; for (int i = 0; i < cf.Count; ++i) { totalNPV += cf[i].Amount * cf[i].DiscountFactor * cf[i].Survivalprobability; } double accrualpaidondefault = calculateSinglePeriodAccrualOnDefault(cf, coupon, tradedate, yt, hazard, Jumps, lastpayment); totalNPV += ita * coupon * accrualpaidondefault * notional / yt.discount(tradedate.AddDays(3)); OMLib.Conventions.DayCount.Actual360 dc = new OMLib.Conventions.DayCount.Actual360(); Calendar calendar = new UnitedStates(); return(totalNPV / yt.discount(settlementDate)); }
public double PremiumLegNPV_Exact(CDS cds, PiecewiseconstantHazardRate hazard, YieldTermStructure yt, DateTime tradedate, DateTime settlementDate, double notional, double coupon, List <double> Jumps, DateTime lastpayment) { double ita = (double)365 / 360; double totalNPV = 0.0; CdsCoupon[] cf = cds.getCoupons(); for (int i = 0; i < cf.Length; ++i) { totalNPV += cf[i].getYearFrac() * notional * Math.Exp(-hazard.getRT_(cf[i].getEffEnd())) * Math.Exp(-yt.getRT_(cf[i].getEffEnd())); } double accrualpaidondefault = calculateSinglePeriodAccrualOnDefault(cf, coupon, tradedate, yt, hazard, lastpayment); totalNPV += ita * coupon * accrualpaidondefault * notional / yt.discount(tradedate.AddDays(3)); OMLib.Conventions.DayCount.Actual360 dc = new OMLib.Conventions.DayCount.Actual360(); Calendar calendar = new UnitedStates(); return(totalNPV / Math.Exp(-yt.getRT_(cds.getCashSettleTime()))); }
public void curve_output(YieldTermStructure yt, PiecewiseconstantHazardRate ct) { double it = ct.SurvivalProb(new DateTime(2021, 06, 20)); List <double> yield = new List <double>(); for (int j = 1; j < 120; j++) { DateTime t = this.evalDate.AddMonths(j); double t_ = (double)j / 12; yield.Add(-Math.Log(yt.discount(t)) / t_); } this.yield_series = yield; List <double> survival = new List <double>(); for (int j = 1; j < 120; j++) { DateTime t = this.tradedate.AddMonths(j); survival.Add(ct.SurvivalProb(t)); } this.survival_prob = survival; }
public List <CashFlow> Calculation(double fixrate, double initialNotional, List <DateTime> fixedSchedule, DateTime tradedate, YieldTermStructure yt, PiecewiseconstantHazardRate piecewiseFlatHazardRate, int settlement, DateTime lastpaymentdate) { List <CashFlow> result = new List <CashFlow>(); OMLib.Conventions.DayCount.Actual360 daycountconvention = new OMLib.Conventions.DayCount.Actual360(); for (int i = 0; i < fixedSchedule.Count; i++) { CashFlow cf = new CashFlow(); Calendar calendar = new UnitedStates(); //fixedSchedule[i] = calendar.adjust(fixedSchedule[i], BusinessDayConvention.Following); cf.CashFlowDate = fixedSchedule[i]; if (i == 0) { //The protection buyer pays the next coupon in full on the coupon date, //(even if this is the next day); in return the buyer receives (from the protection seller) the accrued //interest[Geoff Chaplin. Credit Derivatives.], which is paid on the cash settlement date. if (lastpaymentdate != null) { lastpaymentdate = calendar.adjust(lastpaymentdate, BusinessDayConvention.Following); cf.Amount = (double)initialNotional * fixrate * (daycountconvention.DayCount(lastpaymentdate, fixedSchedule[i])) / 360; } else { cf.Amount = (double)initialNotional * fixrate * (daycountconvention.DayCount(tradedate, fixedSchedule[i])) / 360; } } else { //Each coupon is equal to (annual coupon/360) (# of days in accrual period). //The accrual period always stretches from (previous coupon payment date) through (this coupon //payment date–1), inclusive; except a contract's last accrual period, which ends with (and //includes) the unadjusted maturity date. if (i == fixedSchedule.Count - 1) { cf.Amount = (double)initialNotional * fixrate * (daycountconvention.DayCount(fixedSchedule[i - 1], fixedSchedule[i].AddDays(1))) / 360; } else { cf.Amount = (double)initialNotional * fixrate * (daycountconvention.DayCount(fixedSchedule[i - 1], fixedSchedule[i])) / 360; } } //Assume all cash flows are discounted to the cash settlement date cf.DiscountFactor = yt.discount(fixedSchedule[i]); if (i == fixedSchedule.Count - 1) { cf.Survivalprobability = piecewiseFlatHazardRate.SurvivalProb(fixedSchedule[i].AddDays(1)); } else { cf.Survivalprobability = piecewiseFlatHazardRate.SurvivalProb(fixedSchedule[i]); } result.Add(cf); } return(result); }