コード例 #1
0
        public double[] bucketedCS01FromCreditCurve(
            CDS cds,
            double cdsCoupon,
            CDS[] bucketCDSs,
            YieldTermStructure yieldCurve,
            PiecewiseconstantHazardRate creditCurve)
        {
            int             n       = bucketCDSs.Length;
            Vector <double> vLambda = Vector <double> .Build.Random(n);

            for (int i = 0; i < n; i++)
            {
                vLambda[i] = _pricer.pvCreditSensitivity(cds, yieldCurve, creditCurve, cdsCoupon, i);
            }

            Matrix <double> jacT = Matrix <double> .Build.Random(n, n);

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    jacT[i, j] = _pricer.parSpreadCreditSensitivity(bucketCDSs[j], yieldCurve, creditCurve, i);
                }
            }

            LU <double>     LUResult = jacT.LU();
            Vector <double> vS       = LUResult.Solve(vLambda);

            return(vS.ToArray());
        }
コード例 #2
0
        /**
         * Put any CDS market quote into the form needed for the curve builder,
         * namely coupon and points up-front (which can be zero).
         *
         * @param calibrationCDS
         * @param marketQuote
         * @param yieldCurve
         * @return The market quotes in the form required by the curve builder
         */
        private double[] getStandardQuoteForm(
            CDS calibrationCDS,
            CdsQuoteConvention marketQuote,
            YieldTermStructure yieldCurve)
        {
            AnalyticalCdsPricer pricer = new AnalyticalCdsPricer();

            double[] res = new double[2];
            if (marketQuote is CdsParSpread)
            {
                res[0] = marketQuote.getCoupon();
            }
            else if (marketQuote is CdsQuotedSpread)
            {
                CdsQuotedSpread             temp    = (CdsQuotedSpread)marketQuote;
                double                      coupon  = temp.getCoupon();
                double                      qSpread = temp.getQuotedSpread();
                PiecewiseconstantHazardRate cc      = calibrateCreditCurve(
                    new CDS[] { calibrationCDS }, new double[] { qSpread }, yieldCurve, new double[1]);
                res[0] = coupon;
                res[1] = pricer.pv(calibrationCDS, yieldCurve, cc, coupon, CdsPriceType.CLEAN);
            }
            else if (marketQuote is PointsUpFront)
            {
                PointsUpFront temp = (PointsUpFront)marketQuote;
                res[0] = temp.getCoupon();
                res[1] = temp.getPointsUpFront();
            }
            return(res);
        }
コード例 #3
0
            public PiecewiseconstantHazardRate calibrate(double[] premiums, double[] puf)
            {
                _protLegElmtPV = new double[_nCDS][];
                _premLegElmtPV = new double[_nCoupons][];

                // use continuous premiums as initial guess
                double[] guess = new double[_nCDS];
                for (int i = 0; i < _nCDS; i++)
                {
                    guess[i] = (premiums[i] + puf[i] / _t[i]) / _lgd[i];
                }
                PiecewiseconstantHazardRate hazard = new PiecewiseconstantHazardRate(baseline, null, null, null, null);

                _creditCurve = hazard.makeFromR(_t.ToList(), guess);
                for (int i = 0; i < _nCDS; i++)
                {
                    Func <double, double> func = getPointFunction(i, premiums[i], puf[i]);
                    Func <double, double> grad = getPointDerivative(i, premiums[i]);

                    double zeroRate = ROOTFINDER.getRoot(func, grad, guess[i]);
                    updateAll(zeroRate, i);
                }


                return(_creditCurve);
            }
コード例 #4
0
            public double rpv01(PiecewiseconstantHazardRate creditCurve, CdsPriceType cleanOrDirty)
            {
                double pv = 0.0;

                for (int i = 0; i < _nPayments; i++)
                {
                    CdsCoupon c = _cds.getCoupon(i);
                    double    q = Math.Exp(-creditCurve.getRT_(c.getEffEnd()));
                    pv += c.getYearFrac() * _paymentDF[i] * q;
                }

                if (_cds.isPayAccOnDefault())
                {
                    double accPV = 0.0;
                    for (int i = 0; i < _nPayments; i++)
                    {
                        accPV += calculateSinglePeriodAccrualOnDefault(i, creditCurve);
                    }
                    pv += accPV;
                }

                pv /= _valuationDF;

                if (cleanOrDirty == CdsPriceType.CLEAN)
                {
                    pv -= _cds.getAccruedYearFraction();
                }
                return(pv);
            }
コード例 #5
0
        /**
         * The value of the annuity (or RPV01 - the premium leg per unit of coupon) at a specified valuation time.
         * The actual value of the leg is this multiplied by the notional and the fractional coupon (i.e. coupon
         * in basis points divided by 10,000).
         * <p>
         * If this is a spot starting CDS (effective protection start = 0) then cash flows from premium payments
         * and accrual-on-default are risky discounted to t=0 ('today'), then rolled forward (risk-free) to the
         * valuation time; if the annuity is requested clean, the accrued premium (paid at the cash-settle time) is
         * rolled (again risk-free) to the valuation time; the absolute value of this amount is subtracted from the
         * other cash flows to give the clean annuity.
         * <p>
         * If this is a forward starting CDS (effective protection start > 0), then the premium payments are again
         * risky discounted to t=0; if the annuity is requested clean, the accrued premium is risk-free discounted
         * to the effective protection start, then risky discounted to t=0 - this gives the t=0 value of the annuity
         * including the chance that a default occurs before protection starts.
         * <p>
         * If valuationTime > 0, the value of the annuity is rolled forward (risk-free) to that time.
         * To compute the Expected value of the annuity conditional on no default before the valuationTime,
         * one must divide this number by the survival probability to the valuationTime (for unit coupon).
         *
         * @param cds  the analytic description of a CDS traded at a certain time
         * @param yieldCurve  the yield (or discount) curve
         * @param creditCurve  the credit (or survival) curve
         * @param cleanOrDirty  the clean or dirty price
         * @param valuationTime  the valuation time
         * @return 10,000 times the RPV01 (on a notional of 1)
         */
        public double Annuity(CDS cds, PiecewiseconstantHazardRate hazard,
                              YieldTermStructure yt, CdsPriceType cleanOrDirt)
        {
            List <CashFlow> cf             = cds.FixLeg;
            DateTime        tradedate      = cds.tradedate;
            DateTime        settlementDate = tradedate.AddDays(cds.Cashsettlement);
            double          recoveryrate   = cds.Recovery;
            DateTime        Stepindate     = tradedate.AddDays(1);

            OMLib.Conventions.DayCount.Actual360 dc = new OMLib.Conventions.DayCount.Actual360();
            double   notional    = cds.Notional;
            double   coupon      = cds.PremiumRate;
            DateTime lastpayment = cds.formerpaymentdate;

            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(cds, yt, hazard);

            totalNPV += ita * coupon * accrualpaidondefault * notional / yt.discount(tradedate.AddDays(3));
            Calendar calendar = new UnitedStates();


            return(totalNPV / yt.discount(settlementDate));
        }
コード例 #6
0
        public virtual double[] pvAndSense(PiecewiseconstantHazardRate creditCurve)
        {
            double pv      = _riskLessValue * Math.Exp(-creditCurve.getRT_(_effEnd));
            double pvSense = -pv *creditCurve.getSingleNodeRTSensitivity(_effEnd, _creditCurveKnot);

            return(new double[] { pv, pvSense });
        }
コード例 #7
0
            public double apply_(double x, int index, PiecewiseconstantHazardRate creditCurve)
            {
                PiecewiseconstantHazardRate cc = creditCurve.withRate(x, index);
                double rpv01_ = rpv01(cc, CdsPriceType.CLEAN);
                double pro    = protectionLeg(cc);

                return(pro - _fracSpread * rpv01_ - _pointsUpfront);
            }
コード例 #8
0
 /**
  * This is the present value of the premium leg per unit coupon, seen at the cash-settlement date.
  * It is equal to 10,000 times the RPV01 (Risky PV01). The actual PV of the leg is this multiplied by the
  * notional and the fractional spread (i.e. coupon in basis points divided by 10,000).
  *
  * @param cds  the analytic description of a CDS traded at a certain time
  * @param yieldCurve  the yield (or discount) curve
  * @param creditCurve  the credit (or survival) curve
  * @param cleanOrDirty  the clean or dirty price
  * @return 10,000 times the RPV01 (on a notional of 1)
  * @see #annuity
  * @see #dirtyAnnuity
  */
 public double annuity(
     CDS cds,
     YieldTermStructure yieldCurve,
     PiecewiseconstantHazardRate creditCurve,
     CdsPriceType cleanOrDirty)
 {
     return(annuity(cds, yieldCurve, creditCurve, cleanOrDirty, cds.getCashSettleTime()));
 }
コード例 #9
0
 /**
  * Present value (clean price) for the payer of premiums (i.e. the buyer of protection).
  *
  * @param cds  the analytic description of a CDS traded at a certain time
  * @param yieldCurve  the yield (or discount) curve
  * @param creditCurve  the credit (or survival) curve
  * @param fractionalSpread  the <b>fraction</b> spread
  * @return the PV
  */
 public double pv(
     CDS cds,
     YieldTermStructure yieldCurve,
     PiecewiseconstantHazardRate creditCurve,
     double fractionalSpread)
 {
     return(pv(cds, yieldCurve, creditCurve, fractionalSpread, CdsPriceType.CLEAN));
 }
コード例 #10
0
        /**
         * The sensitivity of a CDS to the recovery rate. Note this is per unit amount, so the change
         * in PV due to a one percent (say from 40% to 41%) rise is RR will be 0.01 * the returned value.
         *
         * @param cds  the analytic description of a CDS traded at a certain time
         * @param yieldCurve  the yield (or discount) curve
         * @param creditCurve  the credit (or survival) curve
         * @return the recovery rate sensitivity (on a unit notional)
         */
        public double recoveryRateSensitivity(
            CDS cds,
            YieldTermStructure yieldCurve,
            PiecewiseconstantHazardRate creditCurve)
        {
            CDS zeroRR = cds.withRecoveryRate(0);

            return(-_pricer.protectionLeg(zeroRR, yieldCurve, creditCurve));
        }
コード例 #11
0
        private double calculateSinglePeriodAccrualOnDefault(
            CdsCoupon coupon,
            double effectiveStart,
            double[] integrationPoints,
            YieldTermStructure yieldCurve,
            PiecewiseconstantHazardRate creditCurve)
        {
            double start = Math.Max(coupon.getEffStart(), effectiveStart);

            if (start >= coupon.getEffEnd())
            {
                return(0.0); //this coupon has already expired
            }

            double[] knots = DoublesScheduleGenerator.truncateSetInclusive(start, coupon.getEffEnd(), integrationPoints);

            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

            double t0     = t - coupon.getEffStart() + _omega;
            double pv     = 0.0;
            int    nItems = knots.Length;

            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;

                double tPV;
                double t1 = t - coupon.getEffStart() + _omega;
                if (Math.Abs(dhrt) < 1e-5)
                {
                    tPV = dht * b0 * (t0 * Maths.Epsilon.epsilon(-dhrt) + dt * Maths.Epsilon.epsilonP(-dhrt));
                }
                else
                {
                    tPV = dht / dhrt * (t0 * b0 - t1 * b1 + dt / dhrt * (b0 - b1));
                }
                t0  = t1;
                pv += tPV;
                ht0 = ht1;
                rt0 = rt1;
                b0  = b1;
            }
            return(coupon.getYFRatio() * pv);
        }
コード例 #12
0
        /**
         * Immediately prior to default, the CDS has some value V (to the protection buyer).
         * After default, the contract cancelled, so there is an immediate loss of -V (or a gain if V was negative).
         * The protection buyer pays the accrued interest A and receives 1-RR, so the full
         * Value on Default (VoD) is -V + (1-RR) (where the A has been absorbed as we use the clean price for V).
         *
         * @param cds  the analytic description of a CDS traded at a certain time
         * @param yieldCurve  the yield (or discount) curve
         * @param creditCurve  the credit (or survival) curve
         * @param coupon  the coupon of the CDS
         * @return the value on default or jump to default
         */
        public double valueOnDefault(
            CDS cds,
            YieldTermStructure yieldCurve,
            PiecewiseconstantHazardRate creditCurve,
            double coupon)
        {
            double pv = _pricer.pv(cds, yieldCurve, creditCurve, coupon);

            return(-pv + cds.getLGD());
        }
コード例 #13
0
        /**
         * The par spread par spread for a given yield and credit (hazard rate/survival) curve).
         *
         * @param cds analytic description of a CDS traded at a certain time
         * @param yieldCurve  the yield (or discount) curve
         * @param creditCurve  the credit (or survival) curve
         * @return the par spread
         */
        public double parSpread(CDS cds, YieldTermStructure yieldCurve, PiecewiseconstantHazardRate creditCurve)
        {
            if (cds.getProtectionEnd() <= 0.0)
            { //short cut already Expired CDSs
            }

            double rpv01  = annuity(cds, yieldCurve, creditCurve, CdsPriceType.CLEAN, 0.0);
            double proLeg = protectionLeg(cds, yieldCurve, creditCurve, 0.0);

            return(proLeg / rpv01);
        }
コード例 #14
0
        //***************************************************************************************************************
        // bucketed CS01 of a CDS from single market quote of that CDS
        //***************************************************************************************************************

        public double[] bucketedCS01FromSpread(
            CDS cds,
            double coupon,
            YieldTermStructure yieldCurve,
            double marketSpread,
            CDS[] buckets)
        {
            PiecewiseconstantHazardRate cc = _curveBuilder.calibrateCreditCurve(cds, marketSpread, yieldCurve);

            return(bucketedCS01FromCreditCurve(cds, coupon, buckets, yieldCurve, cc));
        }
コード例 #15
0
        public double[][] bucketedCS01(
            CDS[] cds,
            double[] cdsCoupons,
            CDS[] pillarCDSs,
            CdsQuoteConvention[] marketQuotes,
            YieldTermStructure yieldCurve)
        {
            PiecewiseconstantHazardRate creditCurve = _curveBuilder.calibrateCreditCurve(pillarCDSs, marketQuotes, yieldCurve);

            return(bucketedCS01FromCreditCurve(cds, cdsCoupons, pillarCDSs, yieldCurve, creditCurve));
        }
コード例 #16
0
        public double[] bucketedCS01FromParSpreads(
            CDS cds,
            double cdsCoupon,
            YieldTermStructure yieldCurve,
            CDS[] pillarCDSs,
            double[] spreads)
        {
            PiecewiseconstantHazardRate creditCurve = _curveBuilder.calibrateCreditCurve(pillarCDSs, spreads, yieldCurve);

            return(bucketedCS01FromCreditCurve(cds, cdsCoupon, pillarCDSs, yieldCurve, creditCurve));
        }
コード例 #17
0
 /**
  * Hedge a CDS with other CDSs on the same underlying (single-name or index) at different maturities.
  * <p>
  * The hedge is such that the total portfolio (the CDS <b>minus</b> the hedging CDSs, with notionals of the
  * CDS notional times the computed hedge ratios) is insensitive to infinitesimal changes to the the credit curve.
  * <p>
  * If the number of hedge-CDSs equals the number of credit-curve knots, the system is square
  * and is solved exactly (see below).<br>
  * If the number of hedge-CDSs is less than the number of credit-curve knots, the system is
  * solved in a least-square sense (i.e. is hedge is not exact).<br>
  * If the number of hedge-CDSs is greater than the number of credit-curve knots, the system
  * cannot be solved. <br>
  * The system may not solve if the maturities if the hedging CDSs and very different from the
  * knot times (i.e. the sensitivity matrix is singular).
  *
  * @param cds  the CDS to be hedged
  * @param coupon  the coupon of the CDS to be hedged
  * @param hedgeCDSs  the CDSs to hedge with - these are also used to build the credit curve
  * @param hedgeCDSCoupons  the coupons of the CDSs to hedge with/build credit curve
  * @param creditCurve The credit curve
  * @param yieldCurve the yield curve
  * @return the hedge ratios,
  *  since we use a unit notional, the ratios should be multiplied by -notional to give the hedge notional amounts
  */
 public double[] getHedgeRatios(
     CDS cds,
     double coupon,
     CDS[] hedgeCDSs,
     double[] hedgeCDSCoupons,
     PiecewiseconstantHazardRate creditCurve,
     YieldTermStructure yieldCurve)
 {
     double[] cdsSense = getCurveSensitivities(cds, coupon, creditCurve, yieldCurve);
     double[,] hedgeSense = getCurveSensitivities(hedgeCDSs, hedgeCDSCoupons, creditCurve, yieldCurve);
     return(getHedgeRatios(cdsSense, hedgeSense));
 }
コード例 #18
0
        //-------------------------------------------------------------------------

        /**
         * Hedge a CDS with other CDSs on the same underlying (single-name or index) at different maturities.
         * <p>
         * The hedge is such that the total portfolio (the CDS <b>minus</b> the hedging CDSs, with notionals of the
         * CDS notional times the computed hedge ratios) is insensitive to infinitesimal changes to the the credit curve.
         * <p>
         * Here the credit curve is built using the hedging CDSs as pillars.
         *
         * @param cds  the CDS to be hedged
         * @param coupon  the coupon of the CDS to be hedged
         * @param hedgeCDSs  the CDSs to hedge with - these are also used to build the credit curve
         * @param hedgeCDSCoupons  the coupons of the CDSs to hedge with/build credit curve
         * @param hegdeCDSPUF  the PUF of the CDSs to build credit curve
         * @param yieldCurve  the yield curve
         * @return the hedge ratios,
         *  since we use a unit notional, the ratios should be multiplied by -notional to give the hedge notional amounts
         */
        public double[] getHedgeRatios(
            CDS cds,
            double coupon,
            CDS[] hedgeCDSs,
            double[] hedgeCDSCoupons,
            double[] hegdeCDSPUF,
            YieldTermStructure yieldCurve)
        {
            PiecewiseconstantHazardRate cc = _builder.calibrateCreditCurve(hedgeCDSs, hedgeCDSCoupons, yieldCurve, hegdeCDSPUF);

            return(getHedgeRatios(cds, coupon, hedgeCDSs, hedgeCDSCoupons, cc, yieldCurve));
        }
コード例 #19
0
        /**
         * The analytic CS01 (or credit DV01).
         *
         * @param cds  the analytic description of a CDS traded at a certain time
         * @param coupon  the of the traded CDS  (expressed as <b>fractions not basis points</b>)
         * @param yieldCurve  the yield (or discount) curve
         * @param puf  the points up-front (as a fraction)
         * @return the credit DV01
         */
        public double parallelCS01FromPUF(CDS cds, double coupon, YieldTermStructure yieldCurve, double puf)
        {
            PiecewiseconstantHazardRate cc = _curveBuilder.calibrateCreditCurve(cds, coupon, yieldCurve, puf);
            double a      = _pricer.protectionLeg(cds, yieldCurve, cc);
            double b      = _pricer.annuity(cds, yieldCurve, cc, CdsPriceType.CLEAN);
            double aPrime = _pricer.protectionLegCreditSensitivity(cds, yieldCurve, cc, 0);
            double bPrime = _pricer.pvPremiumLegCreditSensitivity(cds, yieldCurve, cc, 0);
            double s      = a / b;
            double dPVdh  = aPrime - coupon * bPrime;
            double dSdh   = (aPrime - s * bPrime) / b;

            return(dPVdh / dSdh);
        }
コード例 #20
0
        public double parSpreadCreditSensitivity(
            CDS cds,
            YieldTermStructure yieldCurve,
            PiecewiseconstantHazardRate creditCurve,
            int creditCurveNode)
        {
            double a      = protectionLeg(cds, yieldCurve, creditCurve);
            double b      = annuity(cds, yieldCurve, creditCurve, CdsPriceType.CLEAN);
            double spread = a / b;
            double dadh   = protectionLegCreditSensitivity(cds, yieldCurve, creditCurve, creditCurveNode);
            double dbdh   = pvPremiumLegCreditSensitivity(cds, yieldCurve, creditCurve, creditCurveNode);

            return(spread * (dadh / a - dbdh / b));
        }
コード例 #21
0
        //-------------------------------------------------------------------------

        /**
         * The sensitivity of the PV of a CDS to the zero hazard rates at the knots of the credit curve.
         *
         * @param cds  the CDS
         * @param coupon  the coupon
         * @param creditCurve  the credit Curve
         * @param yieldCurve  the yield curve
         * @return vector of sensitivities
         */
        public double[] getCurveSensitivities(
            CDS cds,
            double coupon,
            PiecewiseconstantHazardRate creditCurve,
            YieldTermStructure yieldCurve)
        {
            int n = creditCurve.getNumberOfKnots();

            double[] CurveSen = new double[n];
            for (int i = 0; i < n; i++)
            {
                CurveSen[i] = _pricer.pvCreditSensitivity(cds, yieldCurve, creditCurve, coupon, i);
            }
            return(CurveSen);
        }
コード例 #22
0
            private double calculateSinglePeriodAccrualOnDefault(int paymentIndex, PiecewiseconstantHazardRate creditCurve)
            {
                double[] knots = _premLegIntPoints[paymentIndex];
                if (knots == null)
                {
                    return(0.0);
                }
                double[] df       = _premDF[paymentIndex];
                double[] deltaT   = _premDt[paymentIndex];
                double[] rt       = _rt[paymentIndex];
                double   accRate  = _accRate[paymentIndex];
                double   accStart = _offsetAccStart[paymentIndex];

                double t   = knots[0];
                double ht0 = creditCurve.getRT_(t);
                double rt0 = rt[0];
                double b0  = df[0] * Math.Exp(-ht0);

                double t0     = t - accStart + _omega;
                double pv     = 0.0;
                int    nItems = knots.Length;

                for (int j = 1; j < nItems; ++j)
                {
                    t = knots[j];
                    double ht1 = creditCurve.getRT_(t);
                    double rt1 = rt[j];
                    double b1  = df[j] * Math.Exp(-ht1);
                    double dt  = deltaT[j - 1];

                    double dht  = ht1 - ht0;
                    double drt  = rt1 - rt0;
                    double dhrt = dht + drt + 1e-50; // to keep consistent with ISDA c code

                    double tPV;

                    if (Math.Abs(dhrt) < 1e-5)
                    {
                        tPV = dht * dt * b0 * Epsilon.epsilonP(-dhrt);
                    }
                    else
                    {
                        tPV = dht * dt / dhrt * ((b0 - b1) / dhrt - b1);
                    }
                }

                return(accRate * pv);
            }
コード例 #23
0
        public double pvPremiumLegCreditSensitivity(
            CDS cds,
            YieldTermStructure yieldCurve,
            PiecewiseconstantHazardRate creditCurve,
            int creditCurveNode)
        {
            if (cds.getProtectionEnd() <= 0.0)
            { //short cut already expired CDSs
                return(0.0);
            }

            int    n       = cds.getNumPayments();
            double pvSense = 0.0;

            for (int i = 0; i < n; i++)
            {
                CdsCoupon c             = cds.getCoupon(i);
                double    paymentTime   = c.getPaymentTime();
                double    creditObsTime = c.getEffEnd();
                double    dqdh          = creditCurve.getSingleNodeDiscountFactorSensitivity(creditObsTime, creditCurveNode);
                if (dqdh == 0)
                {
                    continue;
                }
                double p = Math.Exp(-yieldCurve.getRT_(paymentTime));
                pvSense += c.getYearFrac() * p * dqdh;
            }

            if (cds.isPayAccOnDefault())
            {
                double   start = cds.getNumPayments() == 1 ? cds.getEffectiveProtectionStart() : cds.getAccStart();
                double[] integrationSchedule = DoublesScheduleGenerator.getIntegrationsPoints(start, cds.getProtectionEnd(), yieldCurve, creditCurve);

                double accPVSense = 0.0;
                for (int i = 0; i < n; i++)
                {
                    accPVSense += calculateSinglePeriodAccrualOnDefaultCreditSensitivity(
                        cds.getCoupon(i),
                        cds.getEffectiveProtectionStart(), integrationSchedule, yieldCurve, creditCurve, creditCurveNode);
                }
                pvSense += accPVSense;
            }

            double df = Math.Exp(-yieldCurve.getRT_(cds.getCashSettleTime()));

            pvSense /= df;
            return(pvSense);
        }
コード例 #24
0
        public override double[] pvAndSense(PiecewiseconstantHazardRate creditCurve)
        {
            double[] pv = base.pvAndSense(creditCurve);

            double[] aod = new double[2];
            if (_formula == AccrualOnDefaultFormulae.MARKIT_FIX)
            {
                aod = accOnDefaultMarkitFix(creditCurve);
            }
            else
            {
                aod = accOnDefault(creditCurve);
            }
            QLNet.Rounding round = new QLNet.Rounding(18);
            return(new double[] { round.Round(pv[0] + aod[0]), pv[1] + aod[1] });
        }
コード例 #25
0
        /**
         * Sensitivity of the present value (for the payer of premiums, i.e. the buyer of protection) to
         * the zero hazard rate of a given node (knot) of the credit curve. This is per unit of notional.
         *
         * @param cds  the analytic description of a CDS traded at a certain time
         * @param yieldCurve  the yield (or discount) curve
         * @param creditCurve  the credit (or survival) curve
         * @param fractionalSpread  the <b>fraction</b> spread
         * @param creditCurveNode  the credit curve node
         * @return PV sensitivity to one node (knot) on the credit (hazard rate/survival) curve
         */
        public double pvCreditSensitivity(
            CDS cds,
            YieldTermStructure yieldCurve,
            PiecewiseconstantHazardRate creditCurve,
            double fractionalSpread,
            int creditCurveNode)
        {
            if (cds.getProtectionEnd() <= 0.0)
            { //short cut already expired CDSs
                return(0.0);
            }
            double rpv01Sense  = pvPremiumLegCreditSensitivity(cds, yieldCurve, creditCurve, creditCurveNode);
            double proLegSense = protectionLegCreditSensitivity(cds, yieldCurve, creditCurve, creditCurveNode);

            return(proLegSense - fractionalSpread * rpv01Sense);
        }
コード例 #26
0
        public double parallelCS01FromCreditCurve(
            CDS cds,
            double cdsCoupon,
            CDS[] bucketCDSs,
            YieldTermStructure yieldCurve,
            PiecewiseconstantHazardRate creditCurve)
        {
            double[] temp = bucketedCS01FromCreditCurve(cds, cdsCoupon, bucketCDSs, yieldCurve, creditCurve);
            double   sum  = 0;

            foreach (double cs in temp)
            {
                sum += cs;
            }
            return(sum);
        }
コード例 #27
0
        /**
         * CDS value for the payer of premiums (i.e. the buyer of protection) at the cash-settle date.
         *
         * @param cds  the analytic description of a CDS traded at a certain time
         * @param yieldCurve  the yield (or discount) curve
         * @param creditCurve  the credit (or survival) curve
         * @param fractionalSpread  the <b>fraction</b> spread
         * @param cleanOrDirty  the clean or dirty price
         * @return the value of a unit notional payer CDS on the cash-settle date
         */
        public double pv(
            CDS cds,
            YieldTermStructure yieldCurve,
            PiecewiseconstantHazardRate creditCurve,
            double fractionalSpread,
            CdsPriceType cleanOrDirty)
        {
            if (cds.getProtectionEnd() <= 0.0)
            { //short cut already Expired CDSs
                return(0.0);
            }
            // TODO check for any repeat calculations
            double rpv01  = annuity(cds, yieldCurve, creditCurve, cleanOrDirty);
            double proLeg = protectionLeg(cds, yieldCurve, creditCurve);

            return(proLeg - fractionalSpread * rpv01);
        }
コード例 #28
0
        /**
         * CDS value for the payer of premiums (i.e. the buyer of protection) at the specified valuation time.
         *
         * @param cds analytic description of a CDS traded at a certain time
         * @param yieldCurve  the yield (or discount) curve
         * @param creditCurve  the credit (or survival) curve
         * @param fractionalSpread  the <b>fraction</b> spread
         * @param cleanOrDirty  the clean or dirty price
         * @param valuationTime  the valuation time, if time is zero, leg is valued today,
         *  value often quoted for cash-settlement date
         * @return the value of a unit notional payer CDS at the specified valuation time
         */
        public double pv(
            CDS cds,
            YieldTermStructure yieldCurve,
            PiecewiseconstantHazardRate creditCurve,
            double fractionalSpread,
            CdsPriceType cleanOrDirty,
            double valuationTime)
        {
            if (cds.getProtectionEnd() <= 0.0)
            { //short cut already Expired CDSs
                return(0.0);
            }

            double rpv01  = annuity(cds, yieldCurve, creditCurve, cleanOrDirty, 0.0);
            double proLeg = protectionLeg(cds, yieldCurve, creditCurve, 0.0);
            double df     = Math.Exp(-yieldCurve.getRT_(valuationTime));

            return((proLeg - fractionalSpread * rpv01) / df);
        }
コード例 #29
0
        /**
         * The sensitivity of a set of CDSs to the zero hazard rates at the knots of the credit curve.
         * The element (i,j) is the sensitivity of the PV of the jth CDS to the ith knot.
         *
         * @param cds  the set of CDSs
         * @param coupons  the coupons of the CDSs
         * @param creditCurve  the credit Curve
         * @param yieldCurve  the yield curve
         * @return matrix of sensitivities
         */
        public double[,] getCurveSensitivities(
            CDS[] cds,
            double[] coupons,
            PiecewiseconstantHazardRate creditCurve,
            YieldTermStructure yieldCurve)
        {
            int nCDS   = cds.Length;
            int nKnots = creditCurve.getNumberOfKnots();

            double[,] sense = new double[nKnots, nCDS];

            for (int i = 0; i < nCDS; i++)
            {
                for (int j = 0; j < nKnots; j++)
                {
                    sense[j, i] = _pricer.pvCreditSensitivity(cds[i], yieldCurve, creditCurve, coupons[i], j);
                }
            }
            return(sense);
        }
コード例 #30
0
        public override PiecewiseconstantHazardRate calibrateCreditCurve(
            CDS[] cds,
            double[] premiums,
            YieldTermStructure yieldCurve,
            double[] pointsUpfront)
        {
            int    n        = cds.Length;
            double proStart = cds[0].getEffectiveProtectionStart();

            // use continuous premiums as initial guess
            double[] guess = new double[n];
            double[] t     = new double[n];
            for (int i = 0; i < n; i++)
            {
                t[i]     = cds[i].getProtectionEnd();
                guess[i] = (premiums[i] + pointsUpfront[i] / t[i]) / cds[i].getLGD();
            }
            PiecewiseconstantHazardRate hazard      = new PiecewiseconstantHazardRate(yieldCurve.latestReference_, null, null, null, null);
            PiecewiseconstantHazardRate creditCurve = hazard.makeFromRT(t.ToList(), guess);

            for (int i = 0; i < n; i++)
            {
                Pricer pricer = new Pricer(cds[i], yieldCurve, t, premiums[i], pointsUpfront[i]);
                Func <double, double> func = pricer.getPointFunction(i, creditCurve);

                double minValue = i == 0 ? 0.0 : creditCurve.getRTAtIndex(i - 1) / creditCurve.getTimeAtIndex(i);
                if (i > 0 && func(minValue) > 0.0)
                {             //can never fail on the first spread
                    creditCurve = creditCurve.withRate(minValue, i);
                }
                else
                {
                    guess[i] = Math.Max(minValue, guess[i]);
                    double[] bracket  = BRACKER.getBracketedPoints(func, guess[i], 1.2 * guess[i], minValue, double.PositiveInfinity);
                    double   zeroRate = ROOTFINDER.getRoot(func, bracket[0], bracket[1]);
                    creditCurve = creditCurve.withRate(zeroRate, i);
                }
                break;
            }
            return(creditCurve);
        }