Example #1
0
        public double ProtectionLegNPV_Exact(CDS cds, double notional, PiecewiseconstantHazardRate hazard,
                                             YieldTermStructure yt, DateTime tradedate, DateTime settlementDate, double recoveryrate, List <double> Jumps, List <double> creditCurveKnot)
        {
            DateTime Stepindate = tradedate.AddDays(1);

            OMLib.Conventions.DayCount.Actual360 dc = new OMLib.Conventions.DayCount.Actual360();


            double        t0        = 0;
            double        T         = cds.getProtectionEnd();
            List <double> JumpNodes = new List <double>();

            JumpNodes.Add(t0);
            for (int j = 0; j < Jumps.Count; j++)
            {
                if (Jumps[j] < T)
                {
                    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));
        }
        /**
         * The normalised expected default settlement value paid on the exercise settlement
         * date <b>when no defaults have yet occurred</b>.
         * The actual default settlement is this multiplied by the (initial)
         * index notional. This calculation assumes an homogeneous pool that can be described by a single index curve.
         *
         * @param timeToExpiry Time to expiry
         * @param indexCurve Pseudo credit curve for the index.
         * @param lgd The index Loss Given Default (LGD)
         * @return  The normalised expected default settlement value
         */
        public double expectedDefaultSettlementValue(
            double timeToExpiry,
            PiecewiseconstantHazardRate indexCurve,
            double lgd)
        {
            double q = Math.Exp(-indexCurve.getRT_(timeToExpiry));
            double d = lgd * (1 - q);

            return(d);
        }
        /**
         * The normalised expected default settlement value paid on the  exercise settlement date.
         * The actual default settlement is this multiplied by the (initial)
         * index notional.   This calculation assumes an homogeneous pool that can be described by a single index curve.
         * @param initialIndexSize Initial index size
         * @param timeToExpiry Time to expiry
         * @param indexCurve Pseudo credit curve for the index.
         * @param lgd The index Loss Given Default (LGD)
         * @param initialDefaultSettlement  The (normalised) value of any defaults that have already occurred
         *  (e.g. if two defaults have occurred from an index with
         *  initially 100 entries, and the realised recovery rates are 0.2 and 0.35, the this value is (0.8 + 0.65)/100 )
         * @param numDefaults The number of defaults that have already occurred
         * @return The normalised expected default settlement value
         */
        public double expectedDefaultSettlementValue(
            int initialIndexSize,
            double timeToExpiry,
            PiecewiseconstantHazardRate indexCurve,
            double lgd,
            double initialDefaultSettlement,
            int numDefaults)
        {
            double defFrac = numDefaults / ((double)initialIndexSize);
            // this upper range is if all current defaults have zero recovery
            double q = Math.Exp(-indexCurve.getRT_(timeToExpiry));
            double d = (1 - defFrac) * lgd * (1 - q) + initialDefaultSettlement;

            return(d);
        }
Example #4
0
        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())));
        }
Example #5
0
        public double calculateSinglePeriodAccrualOnDefault(CdsCoupon[] cf, double coupon,
                                                            DateTime tradedate,
                                                            YieldTermStructure yieldCurve,
                                                            PiecewiseconstantHazardRate creditCurve, DateTime lastpayment)
        {
            double   Acc            = 0;
            DateTime effectiveStart = tradedate.AddDays(1);

            for (int i = 0; i < cf.Length; ++i)
            {
                //Accured on default
                double t_0 = (i > 0) ? cf[i].getEffStart() : 0;
                double T   = cf[i].getEffEnd();

                T = cf[i].getPaymentTime();
                List <double> knots = new List <double>();
                knots.Add(t_0);
                for (int j = 0; j < yieldCurve.t.Count; j++)
                {
                    if ((yieldCurve.t[j] < T) && (t_0 < yieldCurve.t[j]))
                    {
                        knots.Add(yieldCurve.t[j]);
                    }
                }
                knots.Add(T);

                double 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 = knots[0] - cf[0].getEffStart();
                }
                else
                {
                    t0 = knots[0] - cf[i].getEffStart();
                }
                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 = knots[j] - knots[j - 1];

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

                    double tPV;
                    double t1;
                    if (i == 0)
                    {
                        t1 = knots[j] - cf[0].getEffStart();
                    }
                    else
                    {
                        t1 = knots[j] - cf[i].getEffStart();
                    }
                    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);
        }