Ejemplo n.º 1
0
        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));
        }
Ejemplo n.º 2
0
        //public double ProtectionLeg_Approx(List<CashFlow> cf, double notional, PiecewiseconstantHazardRate HazardTermStructure,
        //    YieldTermStructure yt, DateTime tradedate, DateTime settlementDate, double recoveryrate)
        //{
        //    if (cf.Count() == 0)
        //    {
        //        return 0.0;
        //    }
        //    double totalNPV = 0.0;
        //    for (int i = 0; i < cf.Count; ++i)
        //    {
        //        if (i == 0)
        //        {
        //            totalNPV += (1 - recoveryrate)*notional * cf[i].DiscountFactor * (1- cf[i].Survivalprobability);

        //        }
        //        else
        //        {
        //            totalNPV += notional * cf[i].DiscountFactor * (cf[i - 1].Survivalprobability
        //            - cf[i].Survivalprobability) * (1 - recoveryrate);

        //        }
        //    }
        //    return totalNPV/yt.discount(settlementDate);
        //}


        public double calculateSinglePeriodAccrualOnDefault(List <CashFlow> cf, double coupon,
                                                            DateTime tradedate,
                                                            YieldTermStructure yieldCurve,
                                                            PiecewiseconstantHazardRate creditCurve, List <DateTime> Jumps, DateTime lastpayment)
        {
            double   Acc            = 0;
            DateTime effectiveStart = tradedate.AddDays(1);

            for (int i = 0; i < cf.Count; ++i)
            {
                //Accured on default
                DateTime t_0 = (i > 0) ? cf[i - 1].CashFlowDate.AddDays(-1) : tradedate;
                DateTime T   = cf[i].CashFlowDate;
                if (i == cf.Count - 1)
                {
                    T = cf[i].CashFlowDate;
                }
                else
                {
                    T = cf[i].CashFlowDate.AddDays(-1);
                }

                List <DateTime> knots = new List <DateTime>();
                knots.Add(t_0);
                for (int j = 0; j < Jumps.Count; j++)
                {
                    if ((DateTime.Compare(Jumps[j], T) < 0) && (DateTime.Compare(t_0, Jumps[j]) < 0))
                    {
                        knots.Add(Jumps[j]);
                    }
                }
                knots.Add(T);

                DateTime t   = knots[0];
                double   ht0 = creditCurve.getRT(t);
                double   rt0 = yieldCurve.getRT(t);
                double   b0  = Math.Exp(-rt0 - ht0); // this is the risky discount factor

                OMLib.Conventions.DayCount.Actual365 dc = new OMLib.Conventions.DayCount.Actual365();
                double t0;
                if (i == 0)
                {
                    t0 = (double)dc.DayCount(lastpayment.AddDays(1), knots[0]) / 365;
                }
                else
                {
                    t0 = (double)dc.DayCount(cf[i].CashFlowDate.AddDays(1), knots[0]) / 365;
                }
                double pv     = 0.0;
                int    nItems = knots.Count;
                for (int j = 1; j < nItems; ++j)
                {
                    t = knots[j];
                    double ht1 = creditCurve.getRT(t);
                    double rt1 = yieldCurve.getRT(t);
                    double b1  = Math.Exp(-rt1 - ht1);

                    double dt = (double)dc.DayCount(knots[j - 1], knots[j]) / 365;

                    double dht  = ht1 - ht0;
                    double drt  = rt1 - rt0;
                    double dhrt = dht + drt + 1e-50;

                    double tPV;
                    double t1;
                    if (i == 0)
                    {
                        t1 = (double)dc.DayCount(lastpayment.AddDays(1), knots[j]) / 365;
                    }
                    else
                    {
                        t1 = (double)dc.DayCount(cf[i].CashFlowDate.AddDays(1), knots[j]) / 365;
                    }
                    if (Math.Abs(dhrt) < 1e-5)
                    {
                        tPV = dht * b0 * (t0 * (Math.Exp(-dhrt) - 1) / (-dhrt) + dt * ((-dhrt - 1) * (Math.Exp(-dhrt) - 1) - dhrt) / (dhrt * dhrt));
                    }
                    else
                    {
                        tPV = dht * dt / dhrt * ((b0 - b1) / dhrt - b1);
                    }
                    t0  = t1;
                    pv += tPV;
                    ht0 = ht1;
                    rt0 = rt1;
                    b0  = b1;
                }
                Acc += pv;
            }
            return(Acc);
        }