예제 #1
0
        //! Conventional/standard upfront-to-spread conversion

        /*! Under a standard ISDA model and a set of standardised
         *  instrument characteristics, it is the running only quoted
         *  spread that will make a CDS contract have an NPV of 0 when
         *  quoted for that running only spread.  Refer to: "ISDA
         *  Standard CDS converter specification." May 2009.
         *
         *  The conventional recovery rate to apply in the calculation
         *  is as specified by ISDA, not necessarily equal to the
         *  market-quoted one.  It is typically 0.4 for SeniorSec and
         *  0.2 for subordinate.
         *
         *  \note The conversion employs a flat hazard rate. As a result,
         *        you will not recover the market quotes.
         *
         *  \note This method performs the calculation with the
         *        instrument characteristics. It will coincide with
         *        the ISDA calculation if your object has the standard
         *        characteristics. Notably:
         *        - The calendar should have no bank holidays, just
         *          weekends.
         *        - The yield curve should be LIBOR piecewise ant
         *          in fwd rates, with a discount factor of 1 on the
         *          calculation date, which coincides with the trade
         *          date.
         *        - Convention should be Following for yield curve and
         *          contract cashflows.
         *        - The CDS should pay accrued and mature on standard
         *          IMM dates, settle on trade date +1 and upfront
         *          settle on trade date +3.
         */
        public double?conventionalSpread(double conventionalRecovery,
                                         Handle <YieldTermStructure> discountCurve,
                                         DayCounter dayCounter)
        {
            double flatHazardRate = impliedHazardRate(0.0,
                                                      discountCurve,
                                                      dayCounter,
                                                      conventionalRecovery);

            Handle <DefaultProbabilityTermStructure> probability = new Handle <DefaultProbabilityTermStructure>(
                new FlatHazardRate(0, new WeekendsOnly(), flatHazardRate, dayCounter));

            MidPointCdsEngine engine = new MidPointCdsEngine(probability, conventionalRecovery, discountCurve, true);

            setupArguments(engine.getArguments());
            engine.calculate();
            CreditDefaultSwap.Results results = engine.getResults() as CreditDefaultSwap.Results;
            return(results.fairSpread);
        }
예제 #2
0
        /// <summary>
        /// Implied hazard rate calculation
        /// </summary>
        /// <remarks>
        /// This method performs the calculation with the
        /// instrument characteristics. It will coincide with
        /// the ISDA calculation if your object has the standard
        ///  characteristics. Notably:
        /// - The calendar should have no bank holidays, just
        ///   weekends.
        /// - The yield curve should be LIBOR piecewise ant
        ///   in fwd rates, with a discount factor of 1 on the
        ///   calculation date, which coincides with the trade
        ///   date.
        /// - Convention should be Following for yield curve and
        ///   contract cashflows.
        /// - The CDS should pay accrued and mature on standard
        ///   IMM dates, settle on trade date +1 and upfront
        ///   settle on trade date +3.
        /// </remarks>
        /// <param name="targetNPV"></param>
        /// <param name="discountCurve"></param>
        /// <param name="dayCounter"></param>
        /// <param name="recoveryRate"></param>
        /// <param name="accuracy"></param>
        /// <returns></returns>
        public double impliedHazardRate(double targetNPV,
                                        Handle <YieldTermStructure> discountCurve,
                                        DayCounter dayCounter,
                                        double recoveryRate = 0.4,
                                        double accuracy     = 1.0e-6,
                                        PricingModel model  = PricingModel.Midpoint)
        {
            SimpleQuote flatRate = new SimpleQuote(0.0);

            Handle <DefaultProbabilityTermStructure> probability = new Handle <DefaultProbabilityTermStructure>(
                new FlatHazardRate(0, new WeekendsOnly(), new Handle <Quote>(flatRate), dayCounter));

            IPricingEngine engine = null;

            switch (model)
            {
            case PricingModel.Midpoint:
                engine = new MidPointCdsEngine(probability, recoveryRate, discountCurve);
                break;

            case PricingModel.ISDA:
                engine = new IsdaCdsEngine(probability, recoveryRate, discountCurve);
                break;

            default:
                Utils.QL_FAIL("unknown CDS pricing model: " + model);
                break;
            }


            setupArguments(engine.getArguments());
            CreditDefaultSwap.Results results = engine.getResults() as CreditDefaultSwap.Results;

            ObjectiveFunction f     = new ObjectiveFunction(targetNPV, flatRate, engine, results);
            double            guess = runningSpread_ / (1 - recoveryRate) * 365.0 / 360.0;
            double            step  = guess * 0.1;

            return(new Brent().solve(f, accuracy, guess, step));
        }
예제 #3
0
        public double impliedHazardRate(double targetNPV,
                                        Handle <YieldTermStructure> discountCurve,
                                        DayCounter dayCounter,
                                        double recoveryRate = 0.4,
                                        double accuracy     = 1.0e-6)
        {
            SimpleQuote flatRate = new SimpleQuote(0.0);

            Handle <DefaultProbabilityTermStructure> probability = new Handle <DefaultProbabilityTermStructure>(
                new FlatHazardRate(0, new WeekendsOnly(), new Handle <Quote>(flatRate), dayCounter));

            MidPointCdsEngine engine = new MidPointCdsEngine(probability, recoveryRate, discountCurve);

            setupArguments(engine.getArguments());
            CreditDefaultSwap.Results results = engine.getResults() as CreditDefaultSwap.Results;

            ObjectiveFunction f     = new ObjectiveFunction(targetNPV, flatRate, engine, results);
            double            guess = 0.001;
            double            step  = guess * 0.1;

            return(new Brent().solve(f, accuracy, guess, step));
        }
예제 #4
0
        public void testFairUpfront()
        {
            // Testing fair-upfront calculation for credit-default swaps...

            SavedSettings backup = new SavedSettings();

            // Initialize curves
            Calendar calendar = new TARGET();
            Date today = calendar.adjust(Date.Today);
            Settings.setEvaluationDate(today);

            Handle<Quote> hazardRate = new Handle<Quote>(new SimpleQuote(0.01234));
            RelinkableHandle<DefaultProbabilityTermStructure> probabilityCurve =
                new RelinkableHandle<DefaultProbabilityTermStructure>();
            probabilityCurve.linkTo(new FlatHazardRate(0, calendar, hazardRate, new Actual360()));

            RelinkableHandle<YieldTermStructure> discountCurve =
                new RelinkableHandle<YieldTermStructure>();
            discountCurve.linkTo(new FlatForward(today,0.06,new Actual360()));

            // Build the schedule
            Date issueDate = today;
            Date maturity = calendar.advance(issueDate, 10, TimeUnit.Years);
            BusinessDayConvention convention = BusinessDayConvention.Following;

            Schedule schedule =
                new MakeSchedule().from(issueDate)
                                       .to(maturity)
                                       .withFrequency(Frequency.Quarterly)
                                       .withCalendar(calendar)
                                       .withTerminationDateConvention(convention)
                                       .withRule(DateGeneration.Rule.TwentiethIMM).value();

            // Build the CDS
            double fixedRate = 0.05;
            double upfront = 0.001;
            DayCounter dayCount = new Actual360();
            double notional = 10000.0;
            double recoveryRate = 0.4;

            IPricingEngine engine = new MidPointCdsEngine(probabilityCurve, recoveryRate,	discountCurve, true);

            CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, upfront, fixedRate,
                                        schedule, convention, dayCount, true, true);
            cds.setPricingEngine(engine);

            double fairUpfront = cds.fairUpfront();

            CreditDefaultSwap fairCds = new CreditDefaultSwap(Protection.Side.Seller, notional,
                                            fairUpfront, fixedRate,	schedule, convention, dayCount, true, true);
            fairCds.setPricingEngine(engine);

            double fairNPV = fairCds.NPV();
            double tolerance = 1e-10;

            if (Math.Abs(fairNPV) > tolerance)
                Assert.Fail(
                    "Failed to reproduce null NPV with calculated fair upfront\n"
                    + "    calculated upfront: " + fairUpfront + "\n"
                    + "    calculated NPV:     " + fairNPV);

            // same with null upfront to begin with
            upfront = 0.0;
            CreditDefaultSwap cds2 = new CreditDefaultSwap(Protection.Side.Seller, notional, upfront, fixedRate,
                                        schedule, convention, dayCount, true, true);
            cds2.setPricingEngine(engine);

            fairUpfront = cds2.fairUpfront();

            CreditDefaultSwap fairCds2 = new CreditDefaultSwap(Protection.Side.Seller, notional,
                                                fairUpfront, fixedRate,	schedule, convention, dayCount, true, true);
            fairCds2.setPricingEngine(engine);

            fairNPV = fairCds2.NPV();

            if (Math.Abs(fairNPV) > tolerance)
                Assert.Fail(
                    "Failed to reproduce null NPV with calculated fair upfront\n"
                    + "    calculated upfront: " + fairUpfront + "\n"
                    + "    calculated NPV:     " + fairNPV);
        }