Example #1
0
        //double fixedRate = 0.001;
        //double notional = 10000.0;
        //double recoveryRate = 0.4;

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Calculates the cds. </summary>
        ///
        /// <param name="msg">          [in,out] The message. </param>
        /// <param name="fixedRate">    The fixed rate. </param>
        /// <param name="notional">     The notional. </param>
        /// <param name="recoveryRate"> The recovery rate. </param>
        ///
        /// <returns>   True if it succeeds, false if it fails. </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        public bool CalcCDS(ref CreditDefaultSwapRequestMessage msg, double fixedRate, double notional, double recoveryRate)
        {
            // Testing fair-spread calculation for credit-default swaps...
            using (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 = calendar.advance(today, -1, TimeUnit.Years);
                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
                DayCounter dayCount = new Actual360();

                IPricingEngine    engine = new MidPointCdsEngine(probabilityCurve, recoveryRate, discountCurve);
                CreditDefaultSwap cds    = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate,
                                                                 schedule, convention, dayCount, true, true);
                cds.setPricingEngine(engine);
                double            fairRate = cds.fairSpread();
                CreditDefaultSwap fairCds  = new CreditDefaultSwap(Protection.Side.Seller, notional, fairRate,
                                                                   schedule, convention, dayCount, true, true);
                fairCds.setPricingEngine(engine);

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

                msg.fairRate = fairRate;
                msg.fairNPV  = fairNPV;
                return(Math.Abs(fairNPV) <= tolerance);
            }
        }
Example #2
0
        public void testFlatHazardRate()
        {
            // Testing flat hazard rate...

            double         hazardRate      = 0.0100;
            Handle <Quote> hazardRateQuote = new Handle <Quote>(new SimpleQuote(hazardRate));
            DayCounter     dayCounter      = new Actual360();
            Calendar       calendar        = new TARGET();
            int            n = 20;

            double tolerance = 1.0e-10;
            Date   today     = Settings.evaluationDate();
            Date   startDate = today;
            Date   endDate   = startDate;

            FlatHazardRate flatHazardRate = new FlatHazardRate(today, hazardRateQuote, dayCounter);

            for (int i = 0; i < n; i++)
            {
                endDate = calendar.advance(endDate, 1, TimeUnit.Years);
                double t                   = dayCounter.yearFraction(startDate, endDate);
                double probability         = 1.0 - Math.Exp(-hazardRate * t);
                double computedProbability = flatHazardRate.defaultProbability(t);

                if (Math.Abs(probability - computedProbability) > tolerance)
                {
                    QAssert.Fail("Failed to reproduce probability for flat hazard rate\n"
                                 + "    calculated probability: " + computedProbability + "\n"
                                 + "    expected probability:   " + probability);
                }
            }
        }
Example #3
0
        public void testCashedValues()
        {
            Date     startDate = new Date(01, 03, 2007);
            Period   period    = new Period(360, TimeUnit.Months);
            Calendar calendar  = new TARGET();
            Date     endDate   = calendar.advance(startDate, period, BusinessDayConvention.Unadjusted);

            Schedule schedule = new Schedule(startDate, endDate, new Period(1, TimeUnit.Months), calendar,
                                             BusinessDayConvention.Unadjusted,
                                             BusinessDayConvention.Unadjusted,
                                             DateGeneration.Rule.Backward, false);

            // PSA 100%
            PSACurve psa100 = new PSACurve(startDate);

            double[] listCPR = { 0.2000, 0.4000, 0.6000, 0.8000, 1.0000, 1.2000, 1.4000, 1.6000, 1.8000, 2.0000, 2.2000, 2.4000, 2.6000, 2.8000,
                                 3.0000, 3.2000, 3.4000, 3.6000, 3.8000, 4.0000, 4.2000, 4.4000, 4.6000, 4.8000, 5.0000, 5.2000, 5.4000, 5.6000,
                                 5.8000, 6.0000 };

            for (int i = 0; i < schedule.Count; i++)
            {
                if (i <= 29)
                {
                    QAssert.AreEqual(listCPR[i], psa100.getCPR(schedule[i]) * 100, 0.001);
                }
                else
                {
                    QAssert.AreEqual(6.0000, psa100.getCPR(schedule[i]) * 100);
                }
            }
        }
Example #4
0
        public void testImpliedHazardRate()
        {
            // Testing implied hazard-rate for credit-default swaps...

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

                double     h1 = 0.30, h2 = 0.40;
                DayCounter dayCounter = new Actual365Fixed();

                List <Date>   dates       = new List <Date>(3);
                List <double> hazardRates = new List <double>(3);
                dates.Add(today);
                hazardRates.Add(h1);

                dates.Add(today + new Period(5, TimeUnit.Years));
                hazardRates.Add(h1);

                dates.Add(today + new Period(10, TimeUnit.Years));
                hazardRates.Add(h2);

                RelinkableHandle <DefaultProbabilityTermStructure> probabilityCurve =
                    new RelinkableHandle <DefaultProbabilityTermStructure>();
                probabilityCurve.linkTo(new InterpolatedHazardRateCurve <BackwardFlat>(dates,
                                                                                       hazardRates,
                                                                                       dayCounter));

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

                Frequency             frequency  = Frequency.Semiannual;
                BusinessDayConvention convention = BusinessDayConvention.ModifiedFollowing;

                Date       issueDate    = calendar.advance(today, -6, TimeUnit.Months);
                double     fixedRate    = 0.0120;
                DayCounter cdsDayCount  = new Actual360();
                double     notional     = 10000.0;
                double     recoveryRate = 0.4;

                double?latestRate = null;
                for (int n = 6; n <= 10; ++n)
                {
                    Date     maturity = calendar.advance(issueDate, n, TimeUnit.Years);
                    Schedule schedule = new Schedule(issueDate, maturity, new Period(frequency), calendar,
                                                     convention, convention,
                                                     DateGeneration.Rule.Forward, false);

                    CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate,
                                                                  schedule, convention, cdsDayCount, true, true);
                    cds.setPricingEngine(new MidPointCdsEngine(probabilityCurve, recoveryRate, discountCurve));

                    double NPV      = cds.NPV();
                    double flatRate = cds.impliedHazardRate(NPV, discountCurve,
                                                            dayCounter,
                                                            recoveryRate);

                    if (flatRate < h1 || flatRate > h2)
                    {
                        Assert.Fail("implied hazard rate outside expected range\n"
                                    + "    maturity: " + n + " years\n"
                                    + "    expected minimum: " + h1 + "\n"
                                    + "    expected maximum: " + h2 + "\n"
                                    + "    implied rate:     " + flatRate);
                    }

                    if (n > 6 && flatRate < latestRate)
                    {
                        Assert.Fail("implied hazard rate decreasing with swap maturity\n"
                                    + "    maturity: " + n + " years\n"
                                    + "    previous rate: " + latestRate + "\n"
                                    + "    implied rate:  " + flatRate);
                    }

                    latestRate = flatRate;

                    RelinkableHandle <DefaultProbabilityTermStructure> probability = new RelinkableHandle <DefaultProbabilityTermStructure>();
                    probability.linkTo(new FlatHazardRate(today, new Handle <Quote>(new SimpleQuote(flatRate)), dayCounter));

                    CreditDefaultSwap cds2 = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate,
                                                                   schedule, convention, cdsDayCount, true, true);
                    cds2.setPricingEngine(new MidPointCdsEngine(probability, recoveryRate, discountCurve));

                    double NPV2      = cds2.NPV();
                    double tolerance = 1.0;
                    if (Math.Abs(NPV - NPV2) > tolerance)
                    {
                        Assert.Fail("failed to reproduce NPV with implied rate\n"
                                    + "    expected:   " + NPV + "\n"
                                    + "    calculated: " + NPV2);
                    }
                }
            }
        }
Example #5
0
        public void testDefaultProbability()
        {
            // Testing default-probability structure...

            double         hazardRate      = 0.0100;
            Handle <Quote> hazardRateQuote = new Handle <Quote>(new SimpleQuote(hazardRate));
            DayCounter     dayCounter      = new Actual360();
            Calendar       calendar        = new TARGET();
            int            n = 20;

            double tolerance = 1.0e-10;
            Date   today     = Settings.evaluationDate();
            Date   startDate = today;
            Date   endDate   = startDate;

            FlatHazardRate flatHazardRate = new FlatHazardRate(startDate, hazardRateQuote, dayCounter);

            for (int i = 0; i < n; i++)
            {
                startDate = endDate;
                endDate   = calendar.advance(endDate, 1, TimeUnit.Years);

                double pStart = flatHazardRate.defaultProbability(startDate);
                double pEnd   = flatHazardRate.defaultProbability(endDate);

                double pBetweenComputed =
                    flatHazardRate.defaultProbability(startDate, endDate);

                double pBetween = pEnd - pStart;

                if (Math.Abs(pBetween - pBetweenComputed) > tolerance)
                {
                    QAssert.Fail("Failed to reproduce probability(d1, d2) "
                                 + "for default probability structure\n"
                                 + "    calculated probability: " + pBetweenComputed + "\n"
                                 + "    expected probability:   " + pBetween);
                }

                double t2 = dayCounter.yearFraction(today, endDate);
                double timeProbability = flatHazardRate.defaultProbability(t2);
                double dateProbability =
                    flatHazardRate.defaultProbability(endDate);

                if (Math.Abs(timeProbability - dateProbability) > tolerance)
                {
                    QAssert.Fail("single-time probability and single-date probability do not match\n"
                                 + "    time probability: " + timeProbability + "\n"
                                 + "    date probability: " + dateProbability);
                }

                double t1 = dayCounter.yearFraction(today, startDate);
                timeProbability = flatHazardRate.defaultProbability(t1, t2);
                dateProbability = flatHazardRate.defaultProbability(startDate, endDate);

                if (Math.Abs(timeProbability - dateProbability) > tolerance)
                {
                    QAssert.Fail("double-time probability and double-date probability do not match\n"
                                 + "    time probability: " + timeProbability + "\n"
                                 + "    date probability: " + dateProbability);
                }
            }
        }
Example #6
0
        public void testSwaps()
        {
            //BOOST_MESSAGE("Testing Hull-White swap pricing against known values...");

            Date today;  //=Settings::instance().evaluationDate();;

            Calendar calendar = new TARGET();

            today = calendar.adjust(Date.Today);
            Settings.setEvaluationDate(today);

            Date settlement = calendar.advance(today, 2, TimeUnit.Days);

            Date[] dates =
            {
                settlement,
                calendar.advance(settlement,  1, TimeUnit.Weeks),
                calendar.advance(settlement,  1, TimeUnit.Months),
                calendar.advance(settlement,  3, TimeUnit.Months),
                calendar.advance(settlement,  6, TimeUnit.Months),
                calendar.advance(settlement,  9, TimeUnit.Months),
                calendar.advance(settlement,  1, TimeUnit.Years),
                calendar.advance(settlement,  2, TimeUnit.Years),
                calendar.advance(settlement,  3, TimeUnit.Years),
                calendar.advance(settlement,  5, TimeUnit.Years),
                calendar.advance(settlement, 10, TimeUnit.Years),
                calendar.advance(settlement, 15, TimeUnit.Years)
            };
            double[] discounts =
            {
                1.0,
                0.999258,
                0.996704,
                0.990809,
                0.981798,
                0.972570,
                0.963430,
                0.929532,
                0.889267,
                0.803693,
                0.596903,
                0.433022
            };

            //for (int i = 0; i < dates.Length; i++)
            //    dates[i] + dates.Length;

            LogLinear Interpolator = new LogLinear();

            Handle <YieldTermStructure> termStructure =
                new Handle <YieldTermStructure>(
                    new InterpolatedDiscountCurve <LogLinear>(
                        dates.ToList <Date>(),
                        discounts.ToList <double>(),
                        new Actual365Fixed(), new Calendar(), null, null, Interpolator)
                    );

            HullWhite model = new HullWhite(termStructure);

            int[]     start   = { -3, 0, 3 };
            int[]     length  = { 2, 5, 10 };
            double[]  rates   = { 0.02, 0.04, 0.06 };
            IborIndex euribor = new Euribor6M(termStructure);

            IPricingEngine engine = new TreeVanillaSwapEngine(model, 120, termStructure);

            #if QL_USE_INDEXED_COUPON
            double tolerance = 4.0e-3;
            #else
            double tolerance = 1.0e-8;
            #endif

            for (int i = 0; i < start.Length; i++)
            {
                Date startDate = calendar.advance(settlement, start[i], TimeUnit.Months);
                if (startDate < today)
                {
                    Date fixingDate = calendar.advance(startDate, -2, TimeUnit.Days);
                    //TimeSeries<double> pastFixings;
                    ObservableValue <TimeSeries <double> > pastFixings = new ObservableValue <TimeSeries <double> >();
                    pastFixings.value()[fixingDate] = 0.03;
                    IndexManager.instance().setHistory(euribor.name(),
                                                       pastFixings);
                }

                for (int j = 0; j < length.Length; j++)
                {
                    Date     maturity      = calendar.advance(startDate, length[i], TimeUnit.Years);
                    Schedule fixedSchedule = new Schedule(startDate, maturity, new Period(Frequency.Annual),
                                                          calendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                                          DateGeneration.Rule.Forward, false);
                    Schedule floatSchedule = new Schedule(startDate, maturity, new Period(Frequency.Semiannual),
                                                          calendar, BusinessDayConvention.Following, BusinessDayConvention.Following,
                                                          DateGeneration.Rule.Forward, false);
                    for (int k = 0; k < rates.Length; k++)
                    {
                        VanillaSwap swap = new VanillaSwap(VanillaSwap.Type.Payer, 1000000.0,
                                                           fixedSchedule, rates[k], new Thirty360(),
                                                           floatSchedule, euribor, 0.0, new Actual360());
                        swap.setPricingEngine(new DiscountingSwapEngine(termStructure));
                        double expected = swap.NPV();
                        swap.setPricingEngine(engine);
                        double calculated = swap.NPV();

                        double error = Math.Abs((expected - calculated) / expected);
                        if (error > tolerance)
                        {
                            Assert.Fail("Failed to reproduce swap NPV:"
                                        //+ QL_FIXED << std::setprecision(9)
                                        + "\n    calculated: " + calculated
                                        + "\n    expected:   " + expected
                                        //+ QL_SCIENTIFIC
                                        + "\n    rel. error: " + error);
                        }
                    }
                }
            }
        }
Example #7
0
        private static void Main()
        {
            DateTime startTime = DateTime.Now;

            var todaysDate = new DateTime(2002, 2, 15);

            Settings.instance().setEvaluationDate(todaysDate);

            Calendar calendar       = new TARGET();
            var      settlementDate = new Date(19, Month.February, 2002);

            // flat yield term structure impling 1x5 swap at 5%
            Quote flatRate        = new SimpleQuote(0.04875825);
            var   myTermStructure = new FlatForward(settlementDate, new QuoteHandle(flatRate), new Actual365Fixed());
            var   rhTermStructure = new RelinkableYieldTermStructureHandle();

            rhTermStructure.linkTo(myTermStructure);

            // Define the ATM/OTM/ITM swaps
            var fixedLegTenor = new Period(1, TimeUnit.Years);
            const BusinessDayConvention fixedLegConvention    = BusinessDayConvention.Unadjusted;
            const BusinessDayConvention floatingLegConvention = BusinessDayConvention.ModifiedFollowing;
            DayCounter   fixedLegDayCounter = new Thirty360(Thirty360.Convention.European);
            var          floatingLegTenor   = new Period(6, TimeUnit.Months);
            const double dummyFixedRate     = 0.03;
            IborIndex    indexSixMonths     = new Euribor6M(rhTermStructure);

            Date startDate     = calendar.advance(settlementDate, 1, TimeUnit.Years, floatingLegConvention);
            Date maturity      = calendar.advance(startDate, 5, TimeUnit.Years, floatingLegConvention);
            var  fixedSchedule = new Schedule(startDate, maturity, fixedLegTenor, calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false);
            var  floatSchedule = new Schedule(startDate, maturity, floatingLegTenor, calendar, floatingLegConvention, floatingLegConvention, DateGeneration.Rule.Forward, false);
            var  swap          = new VanillaSwap(VanillaSwap.Type.Payer, 1000.0,
                                                 fixedSchedule, dummyFixedRate, fixedLegDayCounter,
                                                 floatSchedule, indexSixMonths, 0.0, indexSixMonths.dayCounter());
            var swapEngine = new DiscountingSwapEngine(rhTermStructure);

            swap.setPricingEngine(swapEngine);
            double fixedAtmRate = swap.fairRate();
            double fixedOtmRate = fixedAtmRate * 1.2;
            double fixedItmRate = fixedAtmRate * 0.8;

            var atmSwap = new VanillaSwap(VanillaSwap.Type.Payer, 1000.0,
                                          fixedSchedule, fixedAtmRate, fixedLegDayCounter,
                                          floatSchedule, indexSixMonths, 0.0,
                                          indexSixMonths.dayCounter());
            var otmSwap = new VanillaSwap(VanillaSwap.Type.Payer, 1000.0,
                                          fixedSchedule, fixedOtmRate, fixedLegDayCounter,
                                          floatSchedule, indexSixMonths, 0.0,
                                          indexSixMonths.dayCounter());
            var itmSwap = new VanillaSwap(VanillaSwap.Type.Payer, 1000.0,
                                          fixedSchedule, fixedItmRate, fixedLegDayCounter,
                                          floatSchedule, indexSixMonths, 0.0,
                                          indexSixMonths.dayCounter());

            atmSwap.setPricingEngine(swapEngine);
            otmSwap.setPricingEngine(swapEngine);
            itmSwap.setPricingEngine(swapEngine);

            // defining the swaptions to be used in model calibration
            var swaptionMaturities = new PeriodVector
            {
                new Period(1, TimeUnit.Years),
                new Period(2, TimeUnit.Years),
                new Period(3, TimeUnit.Years),
                new Period(4, TimeUnit.Years),
                new Period(5, TimeUnit.Years)
            };

            var swaptions = new CalibrationHelperVector();

            // List of times that have to be included in the timegrid
            var times = new DoubleVector();

            for (int i = 0; i < NUM_ROWS; i++)
            {
                int   j      = NUM_COLS - i - 1; // 1x5, 2x4, 3x3, 4x2, 5x1
                int   k      = i * NUM_COLS + j;
                Quote vol    = new SimpleQuote(SWAPTION_VOLS[k]);
                var   helper = new SwaptionHelper(swaptionMaturities[i], new Period(SWAP_LENGHTS[j], TimeUnit.Years),
                                                  new QuoteHandle(vol),
                                                  indexSixMonths, indexSixMonths.tenor(),
                                                  indexSixMonths.dayCounter(),
                                                  indexSixMonths.dayCounter(),
                                                  rhTermStructure);
                swaptions.Add(helper);
                times.AddRange(helper.times());
            }

            // Building time-grid
            var grid = new TimeGrid(times, 30);

            // defining the models
            // G2 modelG2 = new G2(rhTermStructure));
            var modelHw  = new HullWhite(rhTermStructure);
            var modelHw2 = new HullWhite(rhTermStructure);
            var modelBk  = new BlackKarasinski(rhTermStructure);

            // model calibrations
            Console.WriteLine("Hull-White (analytic formulae) calibration");
            foreach (CalibrationHelper calibrationHelper in swaptions)
            {
                NQuantLibc.as_black_helper(calibrationHelper).setPricingEngine(new JamshidianSwaptionEngine(modelHw));
            }
            CalibrateModel(modelHw, swaptions, 0.05);

            Console.WriteLine("Hull-White (numerical) calibration");
            foreach (CalibrationHelper calibrationHelper in swaptions)
            {
                NQuantLibc.as_black_helper(calibrationHelper).setPricingEngine(new TreeSwaptionEngine(modelHw2, grid));
            }
            CalibrateModel(modelHw2, swaptions, 0.05);

            Console.WriteLine("Black-Karasinski (numerical) calibration");
            foreach (CalibrationHelper calibrationHelper in swaptions)
            {
                NQuantLibc.as_black_helper(calibrationHelper).setPricingEngine(new TreeSwaptionEngine(modelBk, grid));
            }
            CalibrateModel(modelBk, swaptions, 0.05);

            // ATM Bermudan swaption pricing
            Console.WriteLine("Payer bermudan swaption struck at {0} (ATM)", fixedAtmRate);

            var bermudanDates = new DateVector();
            var schedule      = new Schedule(startDate, maturity,
                                             new Period(3, TimeUnit.Months), calendar,
                                             BusinessDayConvention.Following,
                                             BusinessDayConvention.Following,
                                             DateGeneration.Rule.Forward, false);

            for (uint i = 0; i < schedule.size(); i++)
            {
                bermudanDates.Add(schedule.date(i));
            }
            Exercise bermudaExercise = new BermudanExercise(bermudanDates);

            var bermudanSwaption = new Swaption(atmSwap, bermudaExercise);

            bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50));
            Console.WriteLine("HW: " + bermudanSwaption.NPV());

            bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50));
            Console.WriteLine("HW (num): " + bermudanSwaption.NPV());

            bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50));
            Console.WriteLine("BK (num): " + bermudanSwaption.NPV());

            DateTime endTime = DateTime.Now;
            TimeSpan delta   = endTime - startTime;

            Console.WriteLine();
            Console.WriteLine("Run completed in {0} s", delta.TotalSeconds);
            Console.WriteLine();
        }
Example #8
0
        static void Main(string[] args)
        {
            DateTime timer = DateTime.Now;

            ////////////////  DATES  //////////////////////////////////////////////

            Calendar calendar       = new TARGET();
            Date     todaysDate     = new Date(15, Month.January, 2017);
            Date     settlementDate = new Date(todaysDate);

            Settings.setEvaluationDate(todaysDate);
            DayCounter dayCounter = new Actual365Fixed();


            ////////////////  MARKET  //////////////////////////////////////////////

            // Spot
            double         underlying  = 4468.17;
            Handle <Quote> underlyingH = new Handle <Quote>(new SimpleQuote(underlying));

            // riskfree
            double riskFreeRate = 0.035;
            Handle <YieldTermStructure> flatTermStructure = new Handle <YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter));

            // dividend
            double dividendYield = 0.0;
            double fixedDiv      = 5.0;

            Handle <YieldTermStructure> flatDividendTS        = new Handle <YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter));
            Handle <YieldTermStructure> FixedDivTermStructure = new Handle <YieldTermStructure>(new FixedForward(settlementDate, fixedDiv, underlying, dayCounter));

            // vol surface

            Date StartDateVol = settlementDate + new Period(1, TimeUnit.Months);


            List <int> maturityInDays = new InitializedList <int>()
            {
                0, 13, 41, 90, 165, 256, 345, 524, 703
            };
            List <Date> datesVol = new InitializedList <Date>();

            for (int d = 1; d < maturityInDays.Count; d++)
            {
                datesVol.Add(calendar.advance(settlementDate, new Period(maturityInDays[d], TimeUnit.Days)));
            }

            List <double> strikes = new InitializedList <double>()
            {
                3400, 3600, 3800, 4000, 4200, 4400, 4500, 4600, 4800, 5000, 5200, 5400, 5600
            };

            Matrix blackVolMatrix = new Matrix(maturityInDays.Count - 1, strikes.Count, 0.2);
            var    vols           = new InitializedList <double>()
            {
                0.6625, 0.4875, 0.4204, 0.3667, 0.3431, 0.3267, 0.3121, 0.3121,
                0.6007, 0.4543, 0.3967, 0.3511, 0.3279, 0.3154, 0.2984, 0.2921,
                0.5084, 0.4221, 0.3718, 0.3327, 0.3155, 0.3027, 0.2919, 0.2889,
                0.4541, 0.3869, 0.3492, 0.3149, 0.2963, 0.2926, 0.2819, 0.2800,
                0.4060, 0.3607, 0.3330, 0.2999, 0.2887, 0.2811, 0.2751, 0.2775,
                0.3726, 0.3396, 0.3108, 0.2781, 0.2788, 0.2722, 0.2661, 0.2686,
                0.3550, 0.3277, 0.3012, 0.2781, 0.2781, 0.2661, 0.2661, 0.2681,
                0.3428, 0.3209, 0.2958, 0.2740, 0.2688, 0.2627, 0.2580, 0.2620,
                0.3302, 0.3062, 0.2799, 0.2631, 0.2573, 0.2533, 0.2504, 0.2544,
                0.3343, 0.2959, 0.2705, 0.2540, 0.2504, 0.2464, 0.2448, 0.2462,
                0.3460, 0.2845, 0.2624, 0.2463, 0.2425, 0.2385, 0.2373, 0.2422,
                0.3857, 0.2860, 0.2578, 0.2399, 0.2357, 0.2327, 0.2312, 0.2351,
                0.3976, 0.2860, 0.2607, 0.2356, 0.2297, 0.2268, 0.2241, 0.2320
            };


            for (int i = 0; i < vols.Count; i++)
            {
                int testraw = (int)(i % (datesVol.Count));
                int testcol = (int)(i / (datesVol.Count));

                blackVolMatrix[testraw, testcol] = vols[i];
            }



            BlackVarianceSurface mySurface = new BlackVarianceSurface(settlementDate, calendar, datesVol,
                                                                      strikes, Matrix.transpose(blackVolMatrix), dayCounter);

            Handle <BlackVolTermStructure> mySurfaceH = new Handle <BlackVolTermStructure>(mySurface);


            ////////////////  CALIBRATION  //////////////////////////////////////////////

            Period helperPeriod = new Period();

            //helpers
            List <CalibrationHelper> calibrationHelpers = new List <CalibrationHelper>();

            for (int k = 0; k < strikes.Count; k++)
            {
                for (int d = 0; d < datesVol.Count; d++)
                {
                    helperPeriod = new Period(datesVol[d] - settlementDate, TimeUnit.Days);
                    calibrationHelpers.Add(new HestonModelHelper(helperPeriod,
                                                                 calendar,
                                                                 underlying,
                                                                 strikes[k],
                                                                 new Handle <Quote>(new SimpleQuote(blackVolMatrix[d, k])),
                                                                 flatTermStructure,
                                                                 flatDividendTS,
                                                                 CalibrationHelper.CalibrationErrorType.ImpliedVolError));
                }
            }


            // starting data
            double v0    = 0.1;
            double kappa = 1.0;
            double theta = 0.1;
            double sigma = 0.5;
            double rho   = -0.5;

            // model
            HestonProcess hestonProcess = new HestonProcess(flatTermStructure,
                                                            flatDividendTS,
                                                            underlyingH,
                                                            v0, kappa, theta, sigma, rho);

            HestonModel hestonmodel = new HestonModel(hestonProcess);

            AnalyticHestonEngine analyticHestonEngine = new AnalyticHestonEngine(hestonmodel);


            foreach (HestonModelHelper hmh in calibrationHelpers)
            {
                hmh.setPricingEngine(analyticHestonEngine);
            }


            // optimization
            double             tolerance          = 1.0e-8;
            LevenbergMarquardt optimizationmethod = new LevenbergMarquardt(tolerance, tolerance, tolerance);

            hestonmodel.calibrate(calibrationHelpers, optimizationmethod, new EndCriteria(400, 40, tolerance, tolerance, tolerance));

            double        error     = 0.0;
            List <double> errorList = new InitializedList <double>();


            ////////////////  CALIBRATION RESULTS  //////////////////////////////////////////////
            Console.WriteLine("Calbration :");
            Console.WriteLine("-----------");

            foreach (HestonModelHelper hmh in calibrationHelpers)
            {
                error += Math.Abs(hmh.calibrationError());
                errorList.Add(Math.Abs(hmh.calibrationError()));
            }

            Vector hestonParameters = hestonmodel.parameters();

            Console.WriteLine("v0    = {0:0.00%}", hestonParameters[4]);
            Console.WriteLine("kappa = {0:0.00%}", hestonParameters[1]);
            Console.WriteLine("theta = {0:0.00%}", hestonParameters[0]);
            Console.WriteLine("sigma = {0:0.00%}", hestonParameters[2]);
            Console.WriteLine("rho   = {0:0.00%}", hestonParameters[3]);
            Console.WriteLine();
            Console.WriteLine("Total error = {0:0.0000}", error);
            Console.WriteLine("Mean error  = {0:0.0000%}", error / (errorList.Count - 1));
            Console.WriteLine();

            int    StepsPerYear      = 52;
            double absoluteTolerance = 80.0;
            ulong  mcSeed            = 42;

            // MC Heston process
            HestonProcess calibratedHestonProcess = new HestonProcess(flatTermStructure,
                                                                      flatDividendTS,
                                                                      underlyingH,
                                                                      hestonParameters[4],
                                                                      hestonParameters[1],
                                                                      hestonParameters[0],
                                                                      hestonParameters[2],
                                                                      hestonParameters[3]);

            // BS process
            GeneralizedBlackScholesProcessTolerance bsmProcess = new GeneralizedBlackScholesProcessTolerance(underlyingH, FixedDivTermStructure, flatTermStructure, mySurfaceH);

            ////////////////  ENGINES  /////////////////////////////////////////////////


            IPricingEngine mcHestonEngine = new MakeMCEuropeanHestonEngine <PseudoRandom, Statistics>(calibratedHestonProcess)
                                            .withStepsPerYear(StepsPerYear)
                                            .withAbsoluteTolerance(absoluteTolerance)
                                            .withSeed(mcSeed)
                                            .getAsPricingEngine();

            double         absoluteTolerance2      = 1.0;
            IPricingEngine mcGenHestonEngineTestbs = new MakeMCGenericScriptInstrument <PseudoRandom>(bsmProcess)
                                                     .withStepsPerYear(StepsPerYear)
                                                     .withAbsoluteTolerance(absoluteTolerance2)
                                                     .withSeed(mcSeed)
                                                     .value();

            IPricingEngine mcGenHestonEngineTestbs2 = new MakeMCGenericScriptInstrument <PseudoRandom>(calibratedHestonProcess)
                                                      .withStepsPerYear(StepsPerYear)
                                                      .withAbsoluteTolerance(absoluteTolerance2)
                                                      .withSeed(mcSeed)
                                                      .value();


            ////////////////  PRICING  //////////////////////////////////////////////
            Console.WriteLine("Pricing Vanilla:");
            Console.WriteLine("---------------");


            Date     maturity         = new Date(17, Month.May, 2019);
            Exercise europeanExercise = new EuropeanExercise(maturity);

            Option.Type       type           = Option.Type.Call;
            double            strike         = underlying;
            StrikedTypePayoff payoff         = new PlainVanillaPayoff(type, strike);
            VanillaOption     europeanOption = new VanillaOption(payoff, europeanExercise);

            // heston
            europeanOption.setPricingEngine(analyticHestonEngine);
            Console.Write("Heston pricing = {0:0.0000}", europeanOption.NPV());
            Console.WriteLine("  ->   {0:0.0000%}", europeanOption.NPV() / underlying);

            // Mc heston
            europeanOption.setPricingEngine(mcHestonEngine);
            Console.Write("HestMC pricing = {0:0.0000}", europeanOption.NPV());
            Console.Write("  ->   {0:0.0000%}", europeanOption.NPV() / underlying);
            Console.WriteLine("  tolerance   {0:0.0} / {1:0.00%}", absoluteTolerance, absoluteTolerance / underlying);

            // analytic bs
            europeanOption.setPricingEngine(new AnalyticEuropeanEngine(bsmProcess));
            Console.Write("BS pricing     = {0:0.0000}", europeanOption.NPV());
            Console.WriteLine("  ->   {0:0.0000%}", europeanOption.NPV() / underlying);


            Console.WriteLine();
            ////////////////  AUTOCALL HESTON //////////////////////////////////////////////

            List <Date> fixingdates = new InitializedList <Date>();
            double      coupon      = 0.05;
            double      barrierlvl  = 0.6;

            for (int i = 1; i <= 4; i++)
            {
                fixingdates.Add(settlementDate + new Period(i, TimeUnit.Years));
            }

            ScriptGenericAutocall myGenericAutocallHTTEst = new ScriptGenericAutocall(fixingdates, coupon, barrierlvl, underlying);

            myGenericAutocallHTTEst.setPricingEngine(mcGenHestonEngineTestbs);

            Console.WriteLine("Pricing Autocall BS :");
            Console.WriteLine("---------------------");
            Console.WriteLine("test = {0:0.0000}", myGenericAutocallHTTEst.NPV());
            Console.WriteLine("Err = {0:0.0000%}", myGenericAutocallHTTEst.errorEstimate() / myGenericAutocallHTTEst.NPV());
            Console.WriteLine("Samples = {0}", myGenericAutocallHTTEst.samples());
            Console.Write("\n");

            for (int i = 0; i < 4; i++)
            {
                Console.WriteLine("ProbaCall {1} = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaCall " + i), i + 1);
            }
            Console.WriteLine("ProbaMid = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaMid"));
            Console.WriteLine("probaDown = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaDown"));
            Console.WriteLine("test = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaDown"));
            Console.WriteLine("AvgDown/Proba = {0:0.0000%}", myGenericAutocallHTTEst.inspout("AvgDown") / myGenericAutocallHTTEst.inspout("ProbaDown"));
            Console.Write("\n");


            myGenericAutocallHTTEst.setPricingEngine(mcGenHestonEngineTestbs2);

            Console.WriteLine("Pricing Autocall Heston:");
            Console.WriteLine("------------------------");
            Console.WriteLine("test = {0:0.0000}", myGenericAutocallHTTEst.NPV());
            Console.WriteLine("Err = {0:0.0000%}", myGenericAutocallHTTEst.errorEstimate() / myGenericAutocallHTTEst.NPV());
            Console.WriteLine("Samples = {0}", myGenericAutocallHTTEst.samples());
            Console.Write("\n");

            for (int i = 0; i < 4; i++)
            {
                Console.WriteLine("ProbaCall {1} = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaCall " + i), i + 1);
            }
            Console.WriteLine("ProbaMid = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaMid"));
            Console.WriteLine("probaDown = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaDown"));
            Console.WriteLine("test = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaDown"));
            Console.WriteLine("AvgDown/Proba = {0:0.0000%}", myGenericAutocallHTTEst.inspout("AvgDown") / myGenericAutocallHTTEst.inspout("ProbaDown"));
            Console.Write("\n");


            ////////////////  END TEST  //////////////////////////////////////////////
            Console.WriteLine();
            Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer);
            Console.WriteLine();

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }
Example #9
0
        static void Main(string[] args)
        {
            DateTime startTime = DateTime.Now;

            Date     todaysDate     = new Date(15, Month.February, 2002);
            Calendar calendar       = new TARGET();
            Date     settlementDate = new Date(19, Month.February, 2002);

            Settings.instance().setEvaluationDate(todaysDate);

            // flat yield term structure impling 1x5 swap at 5%
            Quote       flatRate        = new SimpleQuote(0.04875825);
            FlatForward myTermStructure = new FlatForward(
                settlementDate,
                new QuoteHandle(flatRate),
                new Actual365Fixed());
            RelinkableYieldTermStructureHandle rhTermStructure =
                new RelinkableYieldTermStructureHandle();

            rhTermStructure.linkTo(myTermStructure);

            // Define the ATM/OTM/ITM swaps
            Period fixedLegTenor = new Period(1, TimeUnit.Years);
            BusinessDayConvention fixedLegConvention =
                BusinessDayConvention.Unadjusted;
            BusinessDayConvention floatingLegConvention =
                BusinessDayConvention.ModifiedFollowing;
            DayCounter fixedLegDayCounter =
                new Thirty360(Thirty360.Convention.European);
            Period    floatingLegTenor = new Period(6, TimeUnit.Months);
            double    dummyFixedRate   = 0.03;
            IborIndex indexSixMonths   = new Euribor6M(rhTermStructure);

            Date startDate = calendar.advance(settlementDate, 1, TimeUnit.Years,
                                              floatingLegConvention);
            Date maturity = calendar.advance(startDate, 5, TimeUnit.Years,
                                             floatingLegConvention);
            Schedule fixedSchedule = new Schedule(startDate, maturity,
                                                  fixedLegTenor, calendar, fixedLegConvention, fixedLegConvention,
                                                  DateGeneration.Rule.Forward, false);
            Schedule floatSchedule = new Schedule(startDate, maturity,
                                                  floatingLegTenor, calendar, floatingLegConvention,
                                                  floatingLegConvention, DateGeneration.Rule.Forward, false);
            VanillaSwap swap = new VanillaSwap(
                VanillaSwap.Type.Payer, 1000.0,
                fixedSchedule, dummyFixedRate, fixedLegDayCounter,
                floatSchedule, indexSixMonths, 0.0,
                indexSixMonths.dayCounter());
            DiscountingSwapEngine swapEngine =
                new DiscountingSwapEngine(rhTermStructure);

            swap.setPricingEngine(swapEngine);
            double fixedATMRate = swap.fairRate();
            double fixedOTMRate = fixedATMRate * 1.2;
            double fixedITMRate = fixedATMRate * 0.8;

            VanillaSwap atmSwap = new VanillaSwap(
                VanillaSwap.Type.Payer, 1000.0,
                fixedSchedule, fixedATMRate, fixedLegDayCounter,
                floatSchedule, indexSixMonths, 0.0,
                indexSixMonths.dayCounter());
            VanillaSwap otmSwap = new VanillaSwap(
                VanillaSwap.Type.Payer, 1000.0,
                fixedSchedule, fixedOTMRate, fixedLegDayCounter,
                floatSchedule, indexSixMonths, 0.0,
                indexSixMonths.dayCounter());
            VanillaSwap itmSwap = new VanillaSwap(
                VanillaSwap.Type.Payer, 1000.0,
                fixedSchedule, fixedITMRate, fixedLegDayCounter,
                floatSchedule, indexSixMonths, 0.0,
                indexSixMonths.dayCounter());

            atmSwap.setPricingEngine(swapEngine);
            otmSwap.setPricingEngine(swapEngine);
            itmSwap.setPricingEngine(swapEngine);

            // defining the swaptions to be used in model calibration
            PeriodVector swaptionMaturities = new PeriodVector();

            swaptionMaturities.Add(new Period(1, TimeUnit.Years));
            swaptionMaturities.Add(new Period(2, TimeUnit.Years));
            swaptionMaturities.Add(new Period(3, TimeUnit.Years));
            swaptionMaturities.Add(new Period(4, TimeUnit.Years));
            swaptionMaturities.Add(new Period(5, TimeUnit.Years));

            CalibrationHelperVector swaptions = new CalibrationHelperVector();

            // List of times that have to be included in the timegrid
            DoubleVector times = new DoubleVector();

            for (int i = 0; i < numRows; i++)
            {
                int            j      = numCols - i - 1; // 1x5, 2x4, 3x3, 4x2, 5x1
                int            k      = i * numCols + j;
                Quote          vol    = new SimpleQuote(swaptionVols[k]);
                SwaptionHelper helper = new SwaptionHelper(
                    swaptionMaturities[i],
                    new Period(swapLengths[j], TimeUnit.Years),
                    new QuoteHandle(vol),
                    indexSixMonths,
                    indexSixMonths.tenor(),
                    indexSixMonths.dayCounter(),
                    indexSixMonths.dayCounter(),
                    rhTermStructure);
                swaptions.Add(helper);
                times.AddRange(helper.times());
            }

            // Building time-grid
            TimeGrid grid = new TimeGrid(times, 30);

            // defining the models
            // G2 modelG2 = new G2(rhTermStructure));
            HullWhite       modelHW  = new HullWhite(rhTermStructure);
            HullWhite       modelHW2 = new HullWhite(rhTermStructure);
            BlackKarasinski modelBK  = new BlackKarasinski(rhTermStructure);

            // model calibrations

//          Console.WriteLine( "G2 (analytic formulae) calibration" );
//          for (int i=0; i<swaptions.Count; i++)
//              NQuantLibc.as_black_helper(swaptions[i]).setPricingEngine(
//                  new G2SwaptionEngine( modelG2, 6.0, 16 ) );
//
//          calibrateModel( modelG2, swaptions, 0.05);
//          Console.WriteLine( "calibrated to:" );
//          Console.WriteLine( "a     = " + modelG2.parameters()[0] );
//          Console.WriteLine( "sigma = " + modelG2.parameters()[1] );
//          Console.WriteLine( "b     = " + modelG2.parameters()[2] );
//          Console.WriteLine( "eta   = " + modelG2.parameters()[3] );
//          Console.WriteLine( "rho   = " + modelG2.parameters()[4] );

            Console.WriteLine("Hull-White (analytic formulae) calibration");
            for (int i = 0; i < swaptions.Count; i++)
            {
                NQuantLibc.as_black_helper(swaptions[i]).setPricingEngine(
                    new JamshidianSwaptionEngine(modelHW));
            }

            calibrateModel(modelHW, swaptions, 0.05);
//          Console.WriteLine( "calibrated to:" );
//            Console.WriteLine( "a = " + modelHW.parameters()[0] );
//            Console.WriteLine( "sigma = " + modelHW.parameters()[1] );


            Console.WriteLine("Hull-White (numerical) calibration");
            for (int i = 0; i < swaptions.Count; i++)
            {
                NQuantLibc.as_black_helper(swaptions[i]).setPricingEngine(
                    new TreeSwaptionEngine(modelHW2, grid));
            }

            calibrateModel(modelHW2, swaptions, 0.05);
//        std::cout << "calibrated to:\n"
//                  << "a = " << modelHW2->params()[0] << ", "
//                  << "sigma = " << modelHW2->params()[1]
//                  << std::endl << std::endl;


            Console.WriteLine("Black-Karasinski (numerical) calibration");
            for (int i = 0; i < swaptions.Count; i++)
            {
                NQuantLibc.as_black_helper(swaptions[i]).setPricingEngine(
                    new TreeSwaptionEngine(modelBK, grid));
            }

            calibrateModel(modelBK, swaptions, 0.05);
//        std::cout << "calibrated to:\n"
//                  << "a = " << modelBK->params()[0] << ", "
//                  << "sigma = " << modelBK->params()[1]
//                  << std::endl << std::endl;

            // ATM Bermudan swaption pricing

            Console.WriteLine("Payer bermudan swaption struck at {0} (ATM)",
                              fixedATMRate);

            DateVector bermudanDates = new DateVector();
            Schedule   schedule      = new Schedule(startDate, maturity,
                                                    new Period(3, TimeUnit.Months), calendar,
                                                    BusinessDayConvention.Following,
                                                    BusinessDayConvention.Following,
                                                    DateGeneration.Rule.Forward, false);

            for (uint i = 0; i < schedule.size(); i++)
            {
                bermudanDates.Add(schedule.date(i));
            }
            Exercise bermudaExercise = new BermudanExercise(bermudanDates);

            Swaption bermudanSwaption =
                new Swaption(atmSwap, bermudaExercise);

            bermudanSwaption.setPricingEngine(
                new TreeSwaptionEngine(modelHW, 50));
            Console.WriteLine("HW: " + bermudanSwaption.NPV());

            bermudanSwaption.setPricingEngine(
                new TreeSwaptionEngine(modelHW2, 50));
            Console.WriteLine("HW (num): " + bermudanSwaption.NPV());

            bermudanSwaption.setPricingEngine(
                new TreeSwaptionEngine(modelBK, 50));
            Console.WriteLine("BK (num): " + bermudanSwaption.NPV());

            DateTime endTime = DateTime.Now;
            TimeSpan delta   = endTime - startTime;

            Console.WriteLine();
            Console.WriteLine("Run completed in {0} s", delta.TotalSeconds);
            Console.WriteLine();
        }
Example #10
0
        void testBootstrapFromUpfront <T, I>()
            where T : ITraits <DefaultProbabilityTermStructure>, new()
            where I : class, IInterpolationFactory, new()
        {
            Calendar calendar = new TARGET();

            Date today = Settings.Instance.evaluationDate();

            int settlementDays = 1;

            List <double> quote = new List <double>();

            quote.Add(0.01);
            quote.Add(0.02);
            quote.Add(0.04);
            quote.Add(0.06);

            List <int> n = new List <int>();

            n.Add(2);
            n.Add(3);
            n.Add(5);
            n.Add(7);

            double                fixedRate  = 0.05;
            Frequency             frequency  = Frequency.Quarterly;
            BusinessDayConvention convention = BusinessDayConvention.ModifiedFollowing;

            DateGeneration.Rule rule       = DateGeneration.Rule.CDS;
            DayCounter          dayCounter = new Actual360();
            double recoveryRate            = 0.4;
            int    upfrontSettlementDays   = 3;

            RelinkableHandle <YieldTermStructure> discountCurve = new RelinkableHandle <YieldTermStructure>();

            discountCurve.linkTo(new FlatForward(today, 0.06, new Actual360()));

            List <CdsHelper> helpers = new List <CdsHelper>();

            for (int i = 0; i < n.Count; i++)
            {
                helpers.Add(
                    new UpfrontCdsHelper(quote[i], fixedRate,
                                         new Period(n[i], TimeUnit.Years),
                                         settlementDays, calendar,
                                         frequency, convention, rule,
                                         dayCounter, recoveryRate,
                                         discountCurve,
                                         upfrontSettlementDays,
                                         true, true, null, new Actual360(true)));
            }

            RelinkableHandle <DefaultProbabilityTermStructure> piecewiseCurve = new RelinkableHandle <DefaultProbabilityTermStructure>();

            piecewiseCurve.linkTo(new PiecewiseDefaultCurve <T, I>(today, helpers, new Thirty360()));

            double notional  = 1.0;
            double tolerance = 1.0e-6;

            SavedSettings backup = new SavedSettings();

            // ensure apple-to-apple comparison
            Settings.Instance.includeTodaysCashFlows = true;

            for (int i = 0; i < n.Count; i++)
            {
                Date protectionStart = today + settlementDays;
                Date startDate       = calendar.adjust(protectionStart, convention);
                Date endDate         = today + new Period(n[i], TimeUnit.Years);
                Date upfrontDate     = calendar.advance(today,
                                                        upfrontSettlementDays,
                                                        TimeUnit.Days,
                                                        convention);

                Schedule schedule = new Schedule(startDate, endDate, new Period(frequency), calendar,
                                                 convention, BusinessDayConvention.Unadjusted, rule, false);

                schedule.isRegular().Insert(0, schedule.isRegular()[0]);
                schedule.dates().Insert(0, protectionStart);

                CreditDefaultSwap cds = new CreditDefaultSwap(CreditDefaultSwap.Protection.Side.Buyer, notional,
                                                              quote[i], fixedRate,
                                                              schedule, convention, dayCounter,
                                                              true, true, protectionStart,
                                                              upfrontDate,
                                                              null,
                                                              new Actual360(true),
                                                              true);

                cds.setPricingEngine(new MidPointCdsEngine(piecewiseCurve, recoveryRate,
                                                           discountCurve, true));

                // test
                double inputUpfront    = quote[i];
                double computedUpfront = cds.fairUpfront();
                if (Math.Abs(inputUpfront - computedUpfront) > tolerance)
                {
                    QAssert.Fail(
                        "\nFailed to reproduce fair upfront for " + n[i] +
                        "Y credit-default swaps\n"
                        + "    computed: " + computedUpfront.ToString() + "\n"
                        + "    expected: " + inputUpfront.ToString());
                }
            }

            backup.Dispose();
        }
Example #11
0
        static void Main(string[] args)
        {
            DateTime timer = DateTime.Now;

            Date     todaysDate     = new Date(15, 2, 2002);
            Calendar calendar       = new TARGET();
            Date     settlementDate = new Date(19, 2, 2002);

            Settings.setEvaluationDate(todaysDate);

            // flat yield term structure impling 1x5 swap at 5%
            Quote flatRate = new SimpleQuote(0.04875825);
            Handle <YieldTermStructure> rhTermStructure = new Handle <YieldTermStructure>(
                new FlatForward(settlementDate, new Handle <Quote>(flatRate),
                                new Actual365Fixed()));

            // Define the ATM/OTM/ITM swaps
            Frequency             fixedLegFrequency     = Frequency.Annual;
            BusinessDayConvention fixedLegConvention    = BusinessDayConvention.Unadjusted;
            BusinessDayConvention floatingLegConvention = BusinessDayConvention.ModifiedFollowing;
            DayCounter            fixedLegDayCounter    = new Thirty360(Thirty360.Thirty360Convention.European);
            Frequency             floatingLegFrequency  = Frequency.Semiannual;

            VanillaSwap.Type type           = VanillaSwap.Type.Payer;
            double           dummyFixedRate = 0.03;
            IborIndex        indexSixMonths = new Euribor6M(rhTermStructure);

            Date startDate = calendar.advance(settlementDate, 1, TimeUnit.Years,
                                              floatingLegConvention);
            Date maturity = calendar.advance(startDate, 5, TimeUnit.Years,
                                             floatingLegConvention);
            Schedule fixedSchedule = new Schedule(startDate, maturity, new Period(fixedLegFrequency),
                                                  calendar, fixedLegConvention, fixedLegConvention,
                                                  DateGeneration.Rule.Forward, false);
            Schedule floatSchedule = new Schedule(startDate, maturity, new Period(floatingLegFrequency),
                                                  calendar, floatingLegConvention, floatingLegConvention,
                                                  DateGeneration.Rule.Forward, false);

            VanillaSwap swap = new VanillaSwap(
                type, 1000.0,
                fixedSchedule, dummyFixedRate, fixedLegDayCounter,
                floatSchedule, indexSixMonths, 0.0,
                indexSixMonths.dayCounter());

            swap.setPricingEngine(new DiscountingSwapEngine(rhTermStructure));
            double fixedAtmRate = swap.fairRate();
            double fixedOtmRate = fixedAtmRate * 1.2;
            double fixedItmRate = fixedAtmRate * 0.8;

            VanillaSwap atmSwap = new VanillaSwap(
                type, 1000.0,
                fixedSchedule, fixedAtmRate, fixedLegDayCounter,
                floatSchedule, indexSixMonths, 0.0,
                indexSixMonths.dayCounter());
            VanillaSwap otmSwap = new VanillaSwap(
                type, 1000.0,
                fixedSchedule, fixedOtmRate, fixedLegDayCounter,
                floatSchedule, indexSixMonths, 0.0,
                indexSixMonths.dayCounter());
            VanillaSwap itmSwap = new VanillaSwap(
                type, 1000.0,
                fixedSchedule, fixedItmRate, fixedLegDayCounter,
                floatSchedule, indexSixMonths, 0.0,
                indexSixMonths.dayCounter());

            // defining the swaptions to be used in model calibration
            List <Period> swaptionMaturities = new List <Period>(5);

            swaptionMaturities.Add(new Period(1, TimeUnit.Years));
            swaptionMaturities.Add(new Period(2, TimeUnit.Years));
            swaptionMaturities.Add(new Period(3, TimeUnit.Years));
            swaptionMaturities.Add(new Period(4, TimeUnit.Years));
            swaptionMaturities.Add(new Period(5, TimeUnit.Years));

            List <CalibrationHelper> swaptions = new List <CalibrationHelper>();

            // List of times that have to be included in the timegrid
            List <double> times = new List <double>();

            for (int i = 0; i < NumRows; i++)
            {
                int   j   = NumCols - i - 1; // 1x5, 2x4, 3x3, 4x2, 5x1
                int   k   = i * NumCols + j;
                Quote vol = new SimpleQuote(SwaptionVols[k]);
                swaptions.Add(new SwaptionHelper(swaptionMaturities[i],
                                                 new Period(SwapLenghts[j], TimeUnit.Years),
                                                 new Handle <Quote>(vol),
                                                 indexSixMonths,
                                                 indexSixMonths.tenor(),
                                                 indexSixMonths.dayCounter(),
                                                 indexSixMonths.dayCounter(),
                                                 rhTermStructure, false));
                swaptions.Last().addTimesTo(times);
            }

            // Building time-grid
            TimeGrid grid = new TimeGrid(times, 30);


            // defining the models
            G2              modelG2  = new G2(rhTermStructure);
            HullWhite       modelHw  = new HullWhite(rhTermStructure);
            HullWhite       modelHw2 = new HullWhite(rhTermStructure);
            BlackKarasinski modelBk  = new BlackKarasinski(rhTermStructure);


            // model calibrations

            Console.WriteLine("G2 (analytic formulae) calibration");
            for (int i = 0; i < swaptions.Count; i++)
            {
                swaptions[i].setPricingEngine(new G2SwaptionEngine(modelG2, 6.0, 16));
            }
            CalibrateModel(modelG2, swaptions);
            Console.WriteLine("calibrated to:\n" +
                              "a     = {0:0.000000}, " +
                              "sigma = {1:0.0000000}\n" +
                              "b     = {2:0.000000}, " +
                              "eta   = {3:0.0000000}\n" +
                              "rho   = {4:0.00000}\n",
                              modelG2.parameters()[0],
                              modelG2.parameters()[1],
                              modelG2.parameters()[2],
                              modelG2.parameters()[3],
                              modelG2.parameters()[4]);

            Console.WriteLine("Hull-White (analytic formulae) calibration");
            for (int i = 0; i < swaptions.Count; i++)
            {
                swaptions[i].setPricingEngine(new JamshidianSwaptionEngine(modelHw));
            }
            CalibrateModel(modelHw, swaptions);
            Console.WriteLine("calibrated to:\n" +
                              "a = {0:0.000000}, " +
                              "sigma = {1:0.0000000}\n",
                              modelHw.parameters()[0],
                              modelHw.parameters()[1]);

            Console.WriteLine("Hull-White (numerical) calibration");
            for (int i = 0; i < swaptions.Count(); i++)
            {
                swaptions[i].setPricingEngine(new TreeSwaptionEngine(modelHw2, grid));
            }
            CalibrateModel(modelHw2, swaptions);
            Console.WriteLine("calibrated to:\n" +
                              "a = {0:0.000000}, " +
                              "sigma = {1:0.0000000}\n",
                              modelHw2.parameters()[0],
                              modelHw2.parameters()[1]);

            Console.WriteLine("Black-Karasinski (numerical) calibration");
            for (int i = 0; i < swaptions.Count; i++)
            {
                swaptions[i].setPricingEngine(new TreeSwaptionEngine(modelBk, grid));
            }
            CalibrateModel(modelBk, swaptions);
            Console.WriteLine("calibrated to:\n" +
                              "a = {0:0.000000}, " +
                              "sigma = {1:0.00000}\n",
                              modelBk.parameters()[0],
                              modelBk.parameters()[1]);


            // ATM Bermudan swaption pricing
            Console.WriteLine("Payer bermudan swaption "
                              + "struck at {0:0.00000 %} (ATM)",
                              fixedAtmRate);

            List <Date>     bermudanDates = new List <Date>();
            List <CashFlow> leg           = swap.fixedLeg();

            for (int i = 0; i < leg.Count; i++)
            {
                Coupon coupon = (Coupon)leg[i];
                bermudanDates.Add(coupon.accrualStartDate());
            }

            Exercise bermudanExercise = new BermudanExercise(bermudanDates);

            Swaption bermudanSwaption = new Swaption(atmSwap, bermudanExercise);

            // Do the pricing for each model

            // G2 price the European swaption here, it should switch to bermudan
            bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50));
            Console.WriteLine("G2:       {0:0.00}", bermudanSwaption.NPV());

            bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50));
            Console.WriteLine("HW:       {0:0.000}", bermudanSwaption.NPV());

            bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50));
            Console.WriteLine("HW (num): {0:0.000}", bermudanSwaption.NPV());

            bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50));
            Console.WriteLine("BK:       {0:0.000}", bermudanSwaption.NPV());


            // OTM Bermudan swaption pricing
            Console.WriteLine("Payer bermudan swaption "
                              + "struck at {0:0.00000 %} (OTM)",
                              fixedOtmRate);

            Swaption otmBermudanSwaption = new Swaption(otmSwap, bermudanExercise);

            // Do the pricing for each model
            otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50));
            Console.WriteLine("G2:       {0:0.0000}", otmBermudanSwaption.NPV());

            otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50));
            Console.WriteLine("HW:       {0:0.0000}", otmBermudanSwaption.NPV());

            otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50));
            Console.WriteLine("HW (num): {0:0.000}", otmBermudanSwaption.NPV());

            otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50));
            Console.WriteLine("BK:       {0:0.0000}", otmBermudanSwaption.NPV());

            // ITM Bermudan swaption pricing
            Console.WriteLine("Payer bermudan swaption "
                              + "struck at {0:0.00000 %} (ITM)",
                              fixedItmRate);

            Swaption itmBermudanSwaption = new Swaption(itmSwap, bermudanExercise);

            // Do the pricing for each model
            itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50));
            Console.WriteLine("G2:       {0:0.000}", itmBermudanSwaption.NPV());

            itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50));
            Console.WriteLine("HW:       {0:0.000}", itmBermudanSwaption.NPV());

            itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50));
            Console.WriteLine("HW (num): {0:0.000}", itmBermudanSwaption.NPV());

            itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50));
            Console.WriteLine("BK:       {0:0.000}", itmBermudanSwaption.NPV());


            Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer);
            Console.WriteLine();

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }
Example #12
0
        static void Main(string[] args)
        {
            try
            {
                var timer = new System.Diagnostics.Stopwatch();
                timer.Start();

                #region MARKET DATA

                var calendar = new TARGET();

                var settlementDate = new Date(18, Month.September, 2008);
                // must be a business day
                settlementDate = calendar.adjust(settlementDate);

                int  fixingDays     = 3;
                uint settlementDays = 3;

                var todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days);
                // nothing to do with Date::todaysDate
                Settings.instance().setEvaluationDate(todaysDate);

                Console.WriteLine("Today: {0} {1} {2} {3}", todaysDate.weekday(), todaysDate.dayOfMonth(), todaysDate.month(), todaysDate.year());
                Console.WriteLine("Settlement date: {0} {1} {2} {3}", settlementDate.weekday(), settlementDate.dayOfMonth(), settlementDate.month(), settlementDate.year());

                // Building of the bonds discounting yield curve

                #endregion

                #region RATE HELPERS

                // RateHelpers are built from the above quotes together with
                // other instrument dependant infos.  Quotes are passed in
                // relinkable handles which could be relinked to some other
                // data source later.

                // Common data

                // ZC rates for the short end
                double zc3mQuote = 0.0096;
                double zc6mQuote = 0.0145;
                double zc1yQuote = 0.0194;

                var zc3mRate = new SimpleQuote(zc3mQuote);
                var zc6mRate = new SimpleQuote(zc6mQuote);
                var zc1yRate = new SimpleQuote(zc1yQuote);

                var zcBondsDayCounter = new Actual365Fixed();

                var zc3m = new DepositRateHelper(new QuoteHandle(zc3mRate),
                                                 new Period(3, TimeUnit.Months),
                                                 (uint)fixingDays,
                                                 calendar,
                                                 BusinessDayConvention.ModifiedFollowing,
                                                 true,
                                                 zcBondsDayCounter);

                var zc6m = new DepositRateHelper(new QuoteHandle(zc6mRate),
                                                 new Period(6, TimeUnit.Months),
                                                 (uint)fixingDays,
                                                 calendar,
                                                 BusinessDayConvention.ModifiedFollowing,
                                                 true,
                                                 zcBondsDayCounter);

                var zc1y = new DepositRateHelper(new QuoteHandle(zc1yRate),
                                                 new Period(1, TimeUnit.Years),
                                                 (uint)fixingDays,
                                                 calendar,
                                                 BusinessDayConvention.ModifiedFollowing,
                                                 true,
                                                 zcBondsDayCounter);

                // setup bonds
                double redemption = 100.0;

                const uint numberOfBonds = 5;

                var issueDates = new Date[] { new Date(15, Month.March, 2005),
                                              new Date(15, Month.June, 2005),
                                              new Date(30, Month.June, 2006),
                                              new Date(15, Month.November, 2002),
                                              new Date(15, Month.May, 1987) };

                var maturities = new Date[] { new Date(31, Month.August, 2010),
                                              new Date(31, Month.August, 2011),
                                              new Date(31, Month.August, 2013),
                                              new Date(15, Month.August, 2018),
                                              new Date(15, Month.May, 2038) };

                var couponRates = new double[] { 0.02375,
                                                 0.04625,
                                                 0.03125,
                                                 0.04000,
                                                 0.04500 };

                var marketQuotes = new double[] { 100.390625,
                                                  106.21875,
                                                  100.59375,
                                                  101.6875,
                                                  102.140625 };

                var quote = new QuoteVector((int)numberOfBonds);
                for (uint i = 0; i < numberOfBonds; i++)
                {
                    var cp = new SimpleQuote(marketQuotes[i]);
                    quote.Add(cp);
                }

                var quoteHandle = new RelinkableQuoteHandleVector((int)numberOfBonds);
                for (int i = 0; i < (int)numberOfBonds; i++)
                {
                    quoteHandle.Add(new RelinkableQuoteHandle());
                    quoteHandle[i].linkTo(quote[i]);
                }

                // Definition of the rate helpers
                var bondsHelpers = new RateHelperVector((int)numberOfBonds);
                for (int i = 0; i < (int)numberOfBonds; i++)
                {
                    var schedule = new Schedule(issueDates[i],
                                                maturities[i],
                                                new Period(Frequency.Semiannual),
                                                new UnitedStates(UnitedStates.Market.GovernmentBond),
                                                BusinessDayConvention.Unadjusted,
                                                BusinessDayConvention.Unadjusted,
                                                DateGeneration.Rule.Backward,
                                                false);

                    var bondHelper = new FixedRateBondHelper(quoteHandle[i],
                                                             settlementDays,
                                                             100.0,
                                                             schedule,
                                                             new DoubleVector(1)
                    {
                        couponRates[i]
                    },
                                                             new ActualActual(ActualActual.Convention.Bond),
                                                             BusinessDayConvention.Unadjusted,
                                                             redemption,
                                                             issueDates[i]);

                    bondsHelpers.Add(bondHelper);
                }

                #endregion

                #region CURVE BUILDING

                // Any DayCounter would be fine.
                // ActualActual::ISDA ensures that 30 years is 30.0
                var termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA);
                //double tolerance = 1.0e-15;

                // A depo-bond curve
                var bondInstruments = new RateHelperVector();

                // Adding the ZC bonds to the curve for the short end
                bondInstruments.Add(zc3m);
                bondInstruments.Add(zc6m);
                bondInstruments.Add(zc1y);

                // Adding the Fixed rate bonds to the curve for the long end
                for (int i = 0; i < numberOfBonds; i++)
                {
                    bondInstruments.Add(bondsHelpers[3]);
                }

                var bondDiscountingTermStructure = new PiecewiseFlatForward(settlementDate,
                                                                            bondInstruments,
                                                                            termStructureDayCounter);

                // Building of the Libor forecasting curve
                // deposits
                double d1wQuote = 0.043375;
                double d1mQuote = 0.031875;
                double d3mQuote = 0.0320375;
                double d6mQuote = 0.03385;
                double d9mQuote = 0.0338125;
                double d1yQuote = 0.0335125;
                // swaps
                double s2yQuote  = 0.0295;
                double s3yQuote  = 0.0323;
                double s5yQuote  = 0.0359;
                double s10yQuote = 0.0412;
                double s15yQuote = 0.0433;

                #endregion

                #region QUOTES

                // SimpleQuote stores a value which can be manually changed;
                // other Quote subclasses could read the value from a database
                // or some kind of data feed.

                // deposits
                var d1wRate = new SimpleQuote(d1wQuote);
                var d1mRate = new SimpleQuote(d1mQuote);
                var d3mRate = new SimpleQuote(d3mQuote);
                var d6mRate = new SimpleQuote(d6mQuote);
                var d9mRate = new SimpleQuote(d9mQuote);
                var d1yRate = new SimpleQuote(d1yQuote);
                // swaps
                var s2yRate  = new SimpleQuote(s2yQuote);
                var s3yRate  = new SimpleQuote(s3yQuote);
                var s5yRate  = new SimpleQuote(s5yQuote);
                var s10yRate = new SimpleQuote(s10yQuote);
                var s15yRate = new SimpleQuote(s15yQuote);

                #endregion

                #region RATE HELPERS

                // RateHelpers are built from the above quotes together with
                // other instrument dependant infos.  Quotes are passed in
                // relinkable handles which could be relinked to some other
                // data source later.

                // deposits
                var depositDayCounter = new Actual360();

                var d1w = new DepositRateHelper(new QuoteHandle(d1wRate),
                                                new Period(1, TimeUnit.Weeks),
                                                (uint)fixingDays,
                                                calendar,
                                                BusinessDayConvention.ModifiedFollowing,
                                                true,
                                                depositDayCounter);

                var d1m = new DepositRateHelper(new QuoteHandle(d1mRate),
                                                new Period(1, TimeUnit.Months),
                                                (uint)fixingDays,
                                                calendar,
                                                BusinessDayConvention.ModifiedFollowing,
                                                true,
                                                depositDayCounter);

                var d3m = new DepositRateHelper(new QuoteHandle(d3mRate),
                                                new Period(3, TimeUnit.Months),
                                                (uint)fixingDays,
                                                calendar,
                                                BusinessDayConvention.ModifiedFollowing,
                                                true,
                                                depositDayCounter);

                var d6m = new DepositRateHelper(new QuoteHandle(d6mRate),
                                                new Period(6, TimeUnit.Months),
                                                (uint)fixingDays,
                                                calendar,
                                                BusinessDayConvention.ModifiedFollowing,
                                                true,
                                                depositDayCounter);

                var d9m = new DepositRateHelper(new QuoteHandle(d9mRate),
                                                new Period(9, TimeUnit.Months),
                                                (uint)fixingDays,
                                                calendar,
                                                BusinessDayConvention.ModifiedFollowing,
                                                true,
                                                depositDayCounter);

                var d1y = new DepositRateHelper(new QuoteHandle(d1yRate),
                                                new Period(1, TimeUnit.Years),
                                                (uint)fixingDays,
                                                calendar,
                                                BusinessDayConvention.ModifiedFollowing,
                                                true,
                                                depositDayCounter);

                // setup swaps
                var swFixedLegFrequency  = Frequency.Annual;
                var swFixedLegConvention = BusinessDayConvention.Unadjusted;
                var swFixedLegDayCounter = new Thirty360(Thirty360.Convention.European);
                var swFloatingLegIndex   = new Euribor6M();

                var forwardStart = new Period(1, TimeUnit.Days);

                var s2y = new SwapRateHelper(new QuoteHandle(s2yRate),
                                             new Period(2, TimeUnit.Years),
                                             calendar,
                                             swFixedLegFrequency,
                                             swFixedLegConvention,
                                             swFixedLegDayCounter,
                                             swFloatingLegIndex,
                                             new QuoteHandle(),
                                             forwardStart);

                var s3y = new SwapRateHelper(new QuoteHandle(s3yRate),
                                             new Period(3, TimeUnit.Years),
                                             calendar,
                                             swFixedLegFrequency,
                                             swFixedLegConvention,
                                             swFixedLegDayCounter,
                                             swFloatingLegIndex,
                                             new QuoteHandle(),
                                             forwardStart);

                var s5y = new SwapRateHelper(new QuoteHandle(s5yRate),
                                             new Period(5, TimeUnit.Years),
                                             calendar,
                                             swFixedLegFrequency,
                                             swFixedLegConvention,
                                             swFixedLegDayCounter,
                                             swFloatingLegIndex,
                                             new QuoteHandle(),
                                             forwardStart);

                var s10y = new SwapRateHelper(new QuoteHandle(s10yRate),
                                              new Period(10, TimeUnit.Years),
                                              calendar,
                                              swFixedLegFrequency,
                                              swFixedLegConvention,
                                              swFixedLegDayCounter,
                                              swFloatingLegIndex,
                                              new QuoteHandle(),
                                              forwardStart);

                var s15y = new SwapRateHelper(new QuoteHandle(s15yRate),
                                              new Period(15, TimeUnit.Years),
                                              calendar,
                                              swFixedLegFrequency,
                                              swFixedLegConvention,
                                              swFixedLegDayCounter,
                                              swFloatingLegIndex,
                                              new QuoteHandle(),
                                              forwardStart);

                #endregion

                #region CURVE BUILDING

                // Any DayCounter would be fine.
                // ActualActual::ISDA ensures that 30 years is 30.0

                // A depo-swap curve
                var depoSwapInstruments = new RateHelperVector();
                depoSwapInstruments.Add(d1w);
                depoSwapInstruments.Add(d1m);
                depoSwapInstruments.Add(d3m);
                depoSwapInstruments.Add(d6m);
                depoSwapInstruments.Add(d9m);
                depoSwapInstruments.Add(d1y);
                depoSwapInstruments.Add(s2y);
                depoSwapInstruments.Add(s3y);
                depoSwapInstruments.Add(s5y);
                depoSwapInstruments.Add(s10y);
                depoSwapInstruments.Add(s15y);

                var depoSwapTermStructure = new PiecewiseFlatForward(settlementDate,
                                                                     depoSwapInstruments,
                                                                     termStructureDayCounter);

                // Term structures that will be used for pricing:
                // the one used for discounting cash flows
                var discountingTermStructure = new RelinkableYieldTermStructureHandle();
                // the one used for forward rate forecasting
                //var forecastingTermStructure = new RelinkableYieldTermStructureHandle();

                #endregion

                #region BONDS TO BE PRICED

                // Common data
                double faceAmount = 100;

                // Pricing engine
                var bondEngine = new DiscountingBondEngine(new YieldTermStructureHandle(bondDiscountingTermStructure));

                // Zero coupon bond
                var zeroCouponBond = new ZeroCouponBond(settlementDays,
                                                        new UnitedStates(UnitedStates.Market.GovernmentBond),
                                                        faceAmount,
                                                        new Date(15, Month.August, 2013),
                                                        BusinessDayConvention.Following,
                                                        116.92,
                                                        new Date(15, Month.August, 2003));

                zeroCouponBond.setPricingEngine(bondEngine);

                // Fixed 4.5% US Treasury Note
                var fixedBondSchedule = new Schedule(new Date(15, Month.May, 2007),
                                                     new Date(15, Month.May, 2017),
                                                     new Period(Frequency.Semiannual),
                                                     new UnitedStates(UnitedStates.Market.GovernmentBond),
                                                     BusinessDayConvention.Unadjusted,
                                                     BusinessDayConvention.Unadjusted,
                                                     DateGeneration.Rule.Backward,
                                                     false);

                var fixedRateBond = new FixedRateBond((int)settlementDays,
                                                      faceAmount,
                                                      fixedBondSchedule,
                                                      new DoubleVector(1)
                {
                    0.045
                },
                                                      new ActualActual(ActualActual.Convention.Bond),
                                                      BusinessDayConvention.ModifiedFollowing,
                                                      100.0,
                                                      new Date(15, Month.May, 2007));

                fixedRateBond.setPricingEngine(bondEngine);

                // Floating rate bond (3M USD Libor + 0.1%)
                // Should and will be priced on another curve later...

                var liborTermStructure = new RelinkableYieldTermStructureHandle();
                var libor3m            = new USDLibor(new Period(3, TimeUnit.Months),
                                                      liborTermStructure);
                libor3m.addFixing(new Date(17, Month.July, 2008), 0.0278625);

                var floatingBondSchedule = new Schedule(new Date(21, Month.October, 2005),
                                                        new Date(21, Month.October, 2010),
                                                        new Period(Frequency.Quarterly),
                                                        new UnitedStates(UnitedStates.Market.NYSE),
                                                        BusinessDayConvention.Unadjusted,
                                                        BusinessDayConvention.Unadjusted,
                                                        DateGeneration.Rule.Backward,
                                                        true);

                var floatingRateBond = new FloatingRateBond(settlementDays,
                                                            faceAmount,
                                                            floatingBondSchedule,
                                                            libor3m,
                                                            new Actual360(),
                                                            BusinessDayConvention.ModifiedFollowing,
                                                            2,
                                                            // Gearings
                                                            new DoubleVector(1)
                {
                    1.0
                },
                                                            // Spreads
                                                            new DoubleVector(1)
                {
                    0.001
                },
                                                            // Caps
                                                            new DoubleVector(),
                                                            // Floors
                                                            new DoubleVector(),
                                                            // Fixing in arrears
                                                            true,
                                                            100.0,
                                                            new Date(21, Month.October, 2005));

                floatingRateBond.setPricingEngine(bondEngine);

                // Coupon pricers
                var pricer = new BlackIborCouponPricer();

                // optionLet volatilities
                double volatility = 0.0;
                var    vol        = new OptionletVolatilityStructureHandle(new ConstantOptionletVolatility(settlementDays,
                                                                                                           calendar,
                                                                                                           BusinessDayConvention.ModifiedFollowing,
                                                                                                           volatility,
                                                                                                           new Actual365Fixed()));

                pricer.setCapletVolatility(vol);
                NQuantLibc.setCouponPricer(floatingRateBond.cashflows(), pricer);

                // Yield curve bootstrapping
                //forecastingTermStructure.linkTo(depoSwapTermStructure);
                discountingTermStructure.linkTo(bondDiscountingTermStructure);

                // We are using the depo & swap curve to estimate the future Libor rates
                liborTermStructure.linkTo(depoSwapTermStructure);

                #endregion

                #region BOND PRICING

                Console.WriteLine();

                // write column headings
                int[] widths = new int[] { 0, 28, 38, 48 };

                Console.CursorLeft = widths[0]; Console.Write("                 ");
                Console.CursorLeft = widths[1]; Console.Write("ZC");
                Console.CursorLeft = widths[2]; Console.Write("Fixed");
                Console.CursorLeft = widths[3]; Console.WriteLine("Floating");

                //string separator = " | ";
                int    width   = widths[3];
                string rule    = new string('-', width);
                string dblrule = new string('=', width);
                string tab     = new string(' ', 8);

                Console.WriteLine(rule);

                Console.CursorLeft = widths[0]; Console.Write("Net present value");
                Console.CursorLeft = widths[1]; Console.Write(zeroCouponBond.NPV().ToString("000.00"));
                Console.CursorLeft = widths[2]; Console.Write(fixedRateBond.NPV().ToString("000.00"));
                Console.CursorLeft = widths[3]; Console.WriteLine(floatingRateBond.NPV().ToString("000.00"));

                Console.CursorLeft = widths[0]; Console.Write("Clean price");
                Console.CursorLeft = widths[1]; Console.Write(zeroCouponBond.cleanPrice().ToString("000.00"));
                Console.CursorLeft = widths[2]; Console.Write(fixedRateBond.cleanPrice().ToString("000.00"));
                Console.CursorLeft = widths[3]; Console.WriteLine(floatingRateBond.cleanPrice().ToString("000.00"));

                Console.CursorLeft = widths[0]; Console.Write("Dirty price");
                Console.CursorLeft = widths[1]; Console.Write(zeroCouponBond.dirtyPrice().ToString("000.00"));
                Console.CursorLeft = widths[2]; Console.Write(fixedRateBond.dirtyPrice().ToString("000.00"));
                Console.CursorLeft = widths[3]; Console.WriteLine(floatingRateBond.dirtyPrice().ToString("000.00"));

                Console.CursorLeft = widths[0]; Console.Write("Accrued coupon");
                Console.CursorLeft = widths[1]; Console.Write(zeroCouponBond.accruedAmount().ToString("000.00"));
                Console.CursorLeft = widths[2]; Console.Write(fixedRateBond.accruedAmount().ToString("000.00"));
                Console.CursorLeft = widths[3]; Console.WriteLine(floatingRateBond.accruedAmount().ToString("000.00"));

                Console.CursorLeft = widths[0]; Console.Write("Previous coupon");
                Console.CursorLeft = widths[1]; Console.Write("N/A");
                Console.CursorLeft = widths[2]; Console.Write(fixedRateBond.previousCouponRate().ToString("000.00"));
                Console.CursorLeft = widths[3]; Console.WriteLine(floatingRateBond.previousCouponRate().ToString("000.00"));

                Console.CursorLeft = widths[0]; Console.Write("Next coupon");
                Console.CursorLeft = widths[1]; Console.Write("N/A");
                Console.CursorLeft = widths[2]; Console.Write(fixedRateBond.nextCouponRate().ToString("000.00"));
                Console.CursorLeft = widths[3]; Console.WriteLine(floatingRateBond.nextCouponRate().ToString("000.00"));

                Console.CursorLeft = widths[0]; Console.Write("Yield");
                Console.CursorLeft = widths[1]; Console.Write(zeroCouponBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual).ToString("000.00"));
                Console.CursorLeft = widths[2]; Console.Write(fixedRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual).ToString("000.00"));
                Console.CursorLeft = widths[3]; Console.WriteLine(floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual).ToString("000.00"));

                double yield = fixedRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual);
                Console.CursorLeft = widths[2]; Console.Write(BondFunctions.duration(fixedRateBond, new InterestRate(yield, fixedRateBond.dayCounter(), Compounding.Compounded, Frequency.Annual), Duration.Type.Modified));

                Console.WriteLine();

                // Other computations
                Console.WriteLine("Sample indirect computations (for the floating rate bond): ");
                Console.WriteLine(rule);

                Console.WriteLine("Yield to Clean Price: {0}", floatingRateBond.cleanPrice(floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual), new Actual360(), Compounding.Compounded, Frequency.Annual, settlementDate).ToString("000.00"));

                Console.WriteLine("Clean Price to Yield: {0}", floatingRateBond.yield(floatingRateBond.cleanPrice(), new Actual360(), Compounding.Compounded, Frequency.Annual, settlementDate).ToString("000.00"));

                /* "Yield to Price"
                *  "Price to Yield" */

                double milliseconds = timer.ElapsedMilliseconds;
                Console.WriteLine();
                Console.WriteLine("Run completed in " + milliseconds + "ms");

                #endregion
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                Console.Read();
            }
        }
Example #13
0
        static void Main(string[] args)
        {
            DateTime timer = DateTime.Now;

            /*********************
            ***  MARKET DATA  ***
            *********************/

            Calendar calendar = new TARGET();

            Date settlementDate = new Date(22, Month.September, 2004);

            // must be a business day
            settlementDate = calendar.adjust(settlementDate);

            int  fixingDays = 2;
            Date todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days);

            // nothing to do with Date::todaysDate
            Settings.setEvaluationDate(todaysDate);


            todaysDate = Settings.evaluationDate();
            Console.WriteLine("Today: {0}, {1}", todaysDate.DayOfWeek, todaysDate);
            Console.WriteLine("Settlement date: {0}, {1}", settlementDate.DayOfWeek, settlementDate);


            // deposits
            double d1wQuote = 0.0382;
            double d1mQuote = 0.0372;
            double d3mQuote = 0.0363;
            double d6mQuote = 0.0353;
            double d9mQuote = 0.0348;
            double d1yQuote = 0.0345;
            // FRAs
            double fra3x6Quote  = 0.037125;
            double fra6x9Quote  = 0.037125;
            double fra6x12Quote = 0.037125;
            // futures
            double fut1Quote = 96.2875;
            double fut2Quote = 96.7875;
            double fut3Quote = 96.9875;
            double fut4Quote = 96.6875;
            double fut5Quote = 96.4875;
            double fut6Quote = 96.3875;
            double fut7Quote = 96.2875;
            double fut8Quote = 96.0875;
            // swaps
            double s2yQuote  = 0.037125;
            double s3yQuote  = 0.0398;
            double s5yQuote  = 0.0443;
            double s10yQuote = 0.05165;
            double s15yQuote = 0.055175;


            /********************
            ***    QUOTES    ***
            ********************/

            // SimpleQuote stores a value which can be manually changed;
            // other Quote subclasses could read the value from a database
            // or some kind of data feed.

            // deposits
            Quote d1wRate = new SimpleQuote(d1wQuote);
            Quote d1mRate = new SimpleQuote(d1mQuote);
            Quote d3mRate = new SimpleQuote(d3mQuote);
            Quote d6mRate = new SimpleQuote(d6mQuote);
            Quote d9mRate = new SimpleQuote(d9mQuote);
            Quote d1yRate = new SimpleQuote(d1yQuote);
            // FRAs
            Quote fra3x6Rate  = new SimpleQuote(fra3x6Quote);
            Quote fra6x9Rate  = new SimpleQuote(fra6x9Quote);
            Quote fra6x12Rate = new SimpleQuote(fra6x12Quote);
            // futures
            Quote fut1Price = new SimpleQuote(fut1Quote);
            Quote fut2Price = new SimpleQuote(fut2Quote);
            Quote fut3Price = new SimpleQuote(fut3Quote);
            Quote fut4Price = new SimpleQuote(fut4Quote);
            Quote fut5Price = new SimpleQuote(fut5Quote);
            Quote fut6Price = new SimpleQuote(fut6Quote);
            Quote fut7Price = new SimpleQuote(fut7Quote);
            Quote fut8Price = new SimpleQuote(fut8Quote);
            // swaps
            Quote s2yRate  = new SimpleQuote(s2yQuote);
            Quote s3yRate  = new SimpleQuote(s3yQuote);
            Quote s5yRate  = new SimpleQuote(s5yQuote);
            Quote s10yRate = new SimpleQuote(s10yQuote);
            Quote s15yRate = new SimpleQuote(s15yQuote);


            /*********************
            ***  RATE HELPERS ***
            *********************/

            // RateHelpers are built from the above quotes together with
            // other instrument dependant infos.  Quotes are passed in
            // relinkable handles which could be relinked to some other
            // data source later.

            // deposits
            DayCounter depositDayCounter = new Actual360();

            RateHelper d1w = new DepositRateHelper(new Handle <Quote>(d1wRate), new Period(1, TimeUnit.Weeks),
                                                   fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper d1m = new DepositRateHelper(new Handle <Quote>(d1mRate), new Period(1, TimeUnit.Months),
                                                   fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper d3m = new DepositRateHelper(new Handle <Quote>(d3mRate), new Period(3, TimeUnit.Months),
                                                   fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper d6m = new DepositRateHelper(new Handle <Quote>(d6mRate), new Period(6, TimeUnit.Months),
                                                   fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper d9m = new DepositRateHelper(new Handle <Quote>(d9mRate), new Period(9, TimeUnit.Months),
                                                   fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper d1y = new DepositRateHelper(new Handle <Quote>(d1yRate), new Period(1, TimeUnit.Years),
                                                   fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            // setup FRAs
            RateHelper fra3x6 = new FraRateHelper(new Handle <Quote>(fra3x6Rate), 3, 6, fixingDays, calendar,
                                                  BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper fra6x9 = new FraRateHelper(new Handle <Quote>(fra6x9Rate), 6, 9, fixingDays, calendar,
                                                  BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper fra6x12 = new FraRateHelper(new Handle <Quote>(fra6x12Rate), 6, 12, fixingDays, calendar,
                                                   BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);


            // setup futures
            // Handle<Quote> convexityAdjustment = new Handle<Quote>(new SimpleQuote(0.0));
            int  futMonths = 3;
            Date imm       = IMM.nextDate(settlementDate);

            RateHelper fut1 = new FuturesRateHelper(new Handle <Quote>(fut1Price), imm, futMonths, calendar,
                                                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut2 = new FuturesRateHelper(new Handle <Quote>(fut2Price), imm, futMonths, calendar,
                                                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut3 = new FuturesRateHelper(new Handle <Quote>(fut3Price), imm, futMonths, calendar,
                                                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut4 = new FuturesRateHelper(new Handle <Quote>(fut4Price), imm, futMonths, calendar,
                                                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut5 = new FuturesRateHelper(new Handle <Quote>(fut5Price), imm, futMonths, calendar,
                                                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut6 = new FuturesRateHelper(new Handle <Quote>(fut6Price), imm, futMonths, calendar,
                                                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut7 = new FuturesRateHelper(new Handle <Quote>(fut7Price), imm, futMonths, calendar,
                                                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut8 = new FuturesRateHelper(new Handle <Quote>(fut8Price), imm, futMonths, calendar,
                                                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);


            // setup swaps
            Frequency             swFixedLegFrequency  = Frequency.Annual;
            BusinessDayConvention swFixedLegConvention = BusinessDayConvention.Unadjusted;
            DayCounter            swFixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European);

            IborIndex swFloatingLegIndex = new Euribor6M();

            RateHelper s2y = new SwapRateHelper(new Handle <Quote>(s2yRate), new Period(2, TimeUnit.Years),
                                                calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex);
            RateHelper s3y = new SwapRateHelper(new Handle <Quote>(s3yRate), new Period(3, TimeUnit.Years),
                                                calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex);
            RateHelper s5y = new SwapRateHelper(new Handle <Quote>(s5yRate), new Period(5, TimeUnit.Years),
                                                calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex);
            RateHelper s10y = new SwapRateHelper(new Handle <Quote>(s10yRate), new Period(10, TimeUnit.Years),
                                                 calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex);
            RateHelper s15y = new SwapRateHelper(new Handle <Quote>(s15yRate), new Period(15, TimeUnit.Years),
                                                 calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex);



            /*********************
            **  CURVE BUILDING **
            *********************/

            // Any DayCounter would be fine.
            // ActualActual::ISDA ensures that 30 years is 30.0
            DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA);

            double tolerance = 1.0e-15;

            // A depo-swap curve
            List <RateHelper> depoSwapInstruments = new List <RateHelper>();

            depoSwapInstruments.Add(d1w);
            depoSwapInstruments.Add(d1m);
            depoSwapInstruments.Add(d3m);
            depoSwapInstruments.Add(d6m);
            depoSwapInstruments.Add(d9m);
            depoSwapInstruments.Add(d1y);
            depoSwapInstruments.Add(s2y);
            depoSwapInstruments.Add(s3y);
            depoSwapInstruments.Add(s5y);
            depoSwapInstruments.Add(s10y);
            depoSwapInstruments.Add(s15y);
            YieldTermStructure depoSwapTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                settlementDate, depoSwapInstruments, termStructureDayCounter, new List <Handle <Quote> >(), new List <Date>(), tolerance);


            // A depo-futures-swap curve
            List <RateHelper> depoFutSwapInstruments = new List <RateHelper>();

            depoFutSwapInstruments.Add(d1w);
            depoFutSwapInstruments.Add(d1m);
            depoFutSwapInstruments.Add(fut1);
            depoFutSwapInstruments.Add(fut2);
            depoFutSwapInstruments.Add(fut3);
            depoFutSwapInstruments.Add(fut4);
            depoFutSwapInstruments.Add(fut5);
            depoFutSwapInstruments.Add(fut6);
            depoFutSwapInstruments.Add(fut7);
            depoFutSwapInstruments.Add(fut8);
            depoFutSwapInstruments.Add(s3y);
            depoFutSwapInstruments.Add(s5y);
            depoFutSwapInstruments.Add(s10y);
            depoFutSwapInstruments.Add(s15y);
            YieldTermStructure depoFutSwapTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                settlementDate, depoFutSwapInstruments, termStructureDayCounter, new List <Handle <Quote> >(), new List <Date>(), tolerance);


            // A depo-FRA-swap curve
            List <RateHelper> depoFRASwapInstruments = new List <RateHelper>();

            depoFRASwapInstruments.Add(d1w);
            depoFRASwapInstruments.Add(d1m);
            depoFRASwapInstruments.Add(d3m);
            depoFRASwapInstruments.Add(fra3x6);
            depoFRASwapInstruments.Add(fra6x9);
            depoFRASwapInstruments.Add(fra6x12);
            depoFRASwapInstruments.Add(s2y);
            depoFRASwapInstruments.Add(s3y);
            depoFRASwapInstruments.Add(s5y);
            depoFRASwapInstruments.Add(s10y);
            depoFRASwapInstruments.Add(s15y);
            YieldTermStructure depoFRASwapTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                settlementDate, depoFRASwapInstruments, termStructureDayCounter, new List <Handle <Quote> >(), new List <Date>(), tolerance);

            // Term structures that will be used for pricing:
            // the one used for discounting cash flows
            RelinkableHandle <YieldTermStructure> discountingTermStructure = new RelinkableHandle <YieldTermStructure>();
            // the one used for forward rate forecasting
            RelinkableHandle <YieldTermStructure> forecastingTermStructure = new RelinkableHandle <YieldTermStructure>();


            /*********************
             * SWAPS TO BE PRICED *
             **********************/

            // constant nominal 1,000,000 Euro
            double nominal = 1000000.0;
            // fixed leg
            Frequency             fixedLegFrequency     = Frequency.Annual;
            BusinessDayConvention fixedLegConvention    = BusinessDayConvention.Unadjusted;
            BusinessDayConvention floatingLegConvention = BusinessDayConvention.ModifiedFollowing;
            DayCounter            fixedLegDayCounter    = new Thirty360(Thirty360.Thirty360Convention.European);
            double     fixedRate             = 0.04;
            DayCounter floatingLegDayCounter = new Actual360();

            // floating leg
            Frequency floatingLegFrequency = Frequency.Semiannual;
            IborIndex euriborIndex         = new Euribor6M(forecastingTermStructure);
            double    spread = 0.0;

            int lenghtInYears = 5;

            VanillaSwap.Type swapType = VanillaSwap.Type.Payer;

            Date     maturity      = settlementDate + new Period(lenghtInYears, TimeUnit.Years);
            Schedule fixedSchedule = new Schedule(settlementDate, maturity, new Period(fixedLegFrequency),
                                                  calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false);
            Schedule floatSchedule = new Schedule(settlementDate, maturity, new Period(floatingLegFrequency),
                                                  calendar, floatingLegConvention, floatingLegConvention, DateGeneration.Rule.Forward, false);
            VanillaSwap spot5YearSwap = new VanillaSwap(swapType, nominal, fixedSchedule, fixedRate, fixedLegDayCounter,
                                                        floatSchedule, euriborIndex, spread, floatingLegDayCounter);

            Date     fwdStart         = calendar.advance(settlementDate, 1, TimeUnit.Years);
            Date     fwdMaturity      = fwdStart + new Period(lenghtInYears, TimeUnit.Years);
            Schedule fwdFixedSchedule = new Schedule(fwdStart, fwdMaturity, new Period(fixedLegFrequency),
                                                     calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false);
            Schedule fwdFloatSchedule = new Schedule(fwdStart, fwdMaturity, new Period(floatingLegFrequency),
                                                     calendar, floatingLegConvention, floatingLegConvention, DateGeneration.Rule.Forward, false);
            VanillaSwap oneYearForward5YearSwap = new VanillaSwap(swapType, nominal, fwdFixedSchedule, fixedRate, fixedLegDayCounter,
                                                                  fwdFloatSchedule, euriborIndex, spread, floatingLegDayCounter);


            /***************
             * SWAP PRICING *
             ****************/

            // utilities for reporting
            List <string> headers = new List <string>();

            headers.Add("term structure");
            headers.Add("net present value");
            headers.Add("fair spread");
            headers.Add("fair fixed rate");
            string separator = " | ";
            int    width     = headers[0].Length + separator.Length
                               + headers[1].Length + separator.Length
                               + headers[2].Length + separator.Length
                               + headers[3].Length + separator.Length - 1;
            string rule = string.Format("").PadLeft(width, '-'), dblrule = string.Format("").PadLeft(width, '=');
            string tab = string.Format("").PadLeft(8, ' ');

            // calculations

            Console.WriteLine(dblrule);
            Console.WriteLine("5-year market swap-rate = {0:0.00%}", s5yRate.value());
            Console.WriteLine(dblrule);

            Console.WriteLine(tab + "5-years swap paying {0:0.00%}", fixedRate);
            Console.WriteLine(headers[0] + separator
                              + headers[1] + separator
                              + headers[2] + separator
                              + headers[3] + separator);
            Console.WriteLine(rule);

            double NPV;
            double fairRate;
            double fairSpread;

            IPricingEngine swapEngine = new DiscountingSwapEngine(discountingTermStructure);

            spot5YearSwap.setPricingEngine(swapEngine);
            oneYearForward5YearSwap.setPricingEngine(swapEngine);

            // Of course, you're not forced to really use different curves
            forecastingTermStructure.linkTo(depoSwapTermStructure);
            discountingTermStructure.linkTo(depoSwapTermStructure);

            NPV        = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate   = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            // let's check that the 5 years swap has been correctly re-priced
            if (!(Math.Abs(fairRate - s5yQuote) < 1e-8))
            {
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yQuote));
            }


            forecastingTermStructure.linkTo(depoFutSwapTermStructure);
            discountingTermStructure.linkTo(depoFutSwapTermStructure);

            NPV        = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate   = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            if (!(Math.Abs(fairRate - s5yQuote) < 1e-8))
            {
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yQuote));
            }

            forecastingTermStructure.linkTo(depoFRASwapTermStructure);
            discountingTermStructure.linkTo(depoFRASwapTermStructure);

            NPV        = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate   = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            if (!(Math.Abs(fairRate - s5yQuote) < 1e-8))
            {
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yQuote));
            }

            Console.WriteLine(rule);

            // now let's price the 1Y forward 5Y swap
            Console.WriteLine(tab + "5-years, 1-year forward swap paying {0:0.00%}", fixedRate);
            Console.WriteLine(headers[0] + separator
                              + headers[1] + separator
                              + headers[2] + separator
                              + headers[3] + separator);
            Console.WriteLine(rule);

            forecastingTermStructure.linkTo(depoSwapTermStructure);
            discountingTermStructure.linkTo(depoSwapTermStructure);

            NPV        = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate   = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            forecastingTermStructure.linkTo(depoFutSwapTermStructure);
            discountingTermStructure.linkTo(depoFutSwapTermStructure);

            NPV        = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate   = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            forecastingTermStructure.linkTo(depoFRASwapTermStructure);
            discountingTermStructure.linkTo(depoFRASwapTermStructure);

            NPV        = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate   = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            // now let's say that the 5-years swap rate goes up to 4.60%.
            // A smarter market element--say, connected to a data source-- would
            // notice the change itself. Since we're using SimpleQuotes,
            // we'll have to change the value manually--which forces us to
            // downcast the handle and use the SimpleQuote
            // interface. In any case, the point here is that a change in the
            // value contained in the Quote triggers a new bootstrapping
            // of the curve and a repricing of the swap.

            SimpleQuote fiveYearsRate = s5yRate as SimpleQuote;

            fiveYearsRate.setValue(0.0460);

            Console.WriteLine(dblrule);
            Console.WriteLine("5-year market swap-rate = {0:0.00%}", s5yRate.value());
            Console.WriteLine(dblrule);

            Console.WriteLine(tab + "5-years swap paying {0:0.00%}", fixedRate);
            Console.WriteLine(headers[0] + separator
                              + headers[1] + separator
                              + headers[2] + separator
                              + headers[3] + separator);
            Console.WriteLine(rule);

            // now get the updated results
            forecastingTermStructure.linkTo(depoSwapTermStructure);
            discountingTermStructure.linkTo(depoSwapTermStructure);

            NPV        = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate   = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            if (!(Math.Abs(fairRate - s5yRate.value()) < 1e-8))
            {
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yRate.value()));
            }

            forecastingTermStructure.linkTo(depoFutSwapTermStructure);
            discountingTermStructure.linkTo(depoFutSwapTermStructure);

            NPV        = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate   = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            if (!(Math.Abs(fairRate - s5yRate.value()) < 1e-8))
            {
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yRate.value()));
            }

            forecastingTermStructure.linkTo(depoFRASwapTermStructure);
            discountingTermStructure.linkTo(depoFRASwapTermStructure);

            NPV        = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate   = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            if (!(Math.Abs(fairRate - s5yRate.value()) < 1e-8))
            {
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yRate.value()));
            }

            Console.WriteLine(rule);

            // the 1Y forward 5Y swap changes as well

            Console.WriteLine(tab + "5-years, 1-year forward swap paying {0:0.00%}", fixedRate);
            Console.WriteLine(headers[0] + separator
                              + headers[1] + separator
                              + headers[2] + separator
                              + headers[3] + separator);
            Console.WriteLine(rule);

            forecastingTermStructure.linkTo(depoSwapTermStructure);
            discountingTermStructure.linkTo(depoSwapTermStructure);

            NPV        = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate   = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            forecastingTermStructure.linkTo(depoFutSwapTermStructure);
            discountingTermStructure.linkTo(depoFutSwapTermStructure);

            NPV        = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate   = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            forecastingTermStructure.linkTo(depoFRASwapTermStructure);
            discountingTermStructure.linkTo(depoFRASwapTermStructure);

            NPV        = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate   = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);


            Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer);

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }
Example #14
0
        static void Main(string[] args)
        {
            /*
             * TODO:
             *  FIXES
             *      1. WAC vs Net Coupon (meanings are reversed, names are bad)
             *      2. CashFlows needs to be replaced with Expected CashFlows to get the correct price
             *  NEW IMPLEMENTATION
             *      1. Add delay
             *      2. Add SecType enum PT, PO, IO
             */

            Date referenceDate = new Date(16, 11, 2015);

            Settings.setEvaluationDate(referenceDate);
            int                   settlementDays    = 0;
            Calendar              calendar          = new TARGET();
            int                   origTerm          = 360;
            Frequency             sinkingFrequency  = Frequency.Monthly;
            DayCounter            accrualDayCounter = new Thirty360();
            BusinessDayConvention paymentConvention = BusinessDayConvention.Unadjusted;


            double wac          = 0.03875;
            int    wam          = 357;
            int    wala         = origTerm - wam;
            Date   factorDate   = new Date(1, 12, 2015);
            Date   issueDate    = calendar.advance(factorDate, -wala, TimeUnit.Months, BusinessDayConvention.Unadjusted);
            double factor       = 1.0;
            double currentFace  = 1000000;
            double originalFace = currentFace / factor;
            int    statedDelay  = 30; //54;
            double netCoupon    = 0.030;
            string secType      = "PT";
            Date   settleDate   = referenceDate;

            double yield_be = 0.0270;
            //double price;


            double speed = 0.08;

            IPrepayModel prepaymodel = new ConstantCPR(speed);
            //IPrepayModel prepaymodel = new PSACurve(factorDate, speed);

            MBSFixedRateBond mbs = new MBSFixedRateBond(
                settlementDays,
                calendar,
                currentFace,
                factorDate,
                new Period(wam, TimeUnit.Months),
                new Period(origTerm, TimeUnit.Months),
                sinkingFrequency,
                wac,
                netCoupon,
                accrualDayCounter,
                prepaymodel,
                paymentConvention,
                issueDate);

            YieldTermStructure discountCurve = new FlatForward(referenceDate, yield_be, new Thirty360(), Compounding.Compounded, Frequency.Semiannual);

            DiscountingBondEngine discountingBondEngine = new DiscountingBondEngine(new Handle <YieldTermStructure>(discountCurve));

            mbs.setPricingEngine(discountingBondEngine);

            // display results
            Console.WriteLine("WAC         : {0:F5}", wac);
            Console.WriteLine("WALA        : {0}", wala);
            Console.WriteLine("WAM         : {0}", wam);
            Console.WriteLine("Factor Date : {0}", factorDate.ToShortDateString());
            Console.WriteLine("Factor      : {0:F10}", factor);
            Console.WriteLine("Orig Face   : {0:N}", originalFace);
            Console.WriteLine("Curr Face   : {0:N}", currentFace);
            Console.WriteLine("Stated Delay: {0}", statedDelay);
            Console.WriteLine("Net Coupon  : {0:F3}", netCoupon);
            Console.WriteLine("Sec Type    : {0}", secType);
            Console.WriteLine("Settle Date : {0}", settleDate.ToShortDateString());
            Console.WriteLine("Model Type  : {0}", prepaymodel.GetType().ToString());
            Console.WriteLine("Model Speed : {0:F3}", speed);
            Console.WriteLine("Yield       : {0:F5}", yield_be);

            Console.WriteLine("Clean Price : {0:F6}", mbs.cleanPrice());
            Console.WriteLine("Dirty Price : {0:F6}", mbs.dirtyPrice());
            Console.WriteLine("Accrued     : {0:F6}", mbs.accruedAmount());

            // month, factor, pay date, ending prin, interest, reg principal, prepaid principal, total principal, net flow, cpr, smm, wala, wam, p&i payment, i payment, beg balance, days, discount, pv
            double ebal = currentFace;

            using (System.IO.StreamWriter sw = new System.IO.StreamWriter("output.csv"))
            {
                DayCounter dc      = discountCurve.dayCounter();
                Date       refdate = discountCurve.referenceDate();



                sw.WriteLine("month,factor date,factor,pay date,ending principal,interest,regular principal,prepaid principal,total principal,net flow,cpr,smm,wala,wam,p&i payment,interest payment,beginning balance,days,discount,pv");
                for (int i = 0; i < wam; i++)
                {
                    double upmt = 0;
                    double ppmt = 0;
                    double ipmt = 0;
                    double bbal = ebal;

                    Date paydate = null;

                    for (int j = 0; j <= 2; j++)
                    {
                        int      k  = i * 3 + j;
                        CashFlow cf = mbs.expectedCashflows()[k];
                        if (cf.GetType() == typeof(VoluntaryPrepay))
                        {
                            upmt    = cf.amount();
                            paydate = cf.date();
                        }
                        if (cf.GetType() == typeof(AmortizingPayment))
                        {
                            ppmt = cf.amount();
                        }
                        if (cf.GetType() == typeof(FixedRateCoupon))
                        {
                            ipmt = cf.amount();
                        }
                    }
                    int    days = dc.dayCount(refdate, paydate);
                    double df   = discountCurve.discount(paydate);
                    ebal = bbal - upmt - ppmt;
                    double smm = upmt / (bbal - ppmt);

                    sw.Write("{0},", i + 1);                                                                              //month
                    sw.Write("{0},", calendar.advance(factorDate, i, TimeUnit.Months, BusinessDayConvention.Unadjusted)); //factor date
                    sw.Write("{0:F10},", factor * bbal / currentFace);                                                    //factor
                    sw.Write("{0},", paydate.ToShortDateString());                                                        //pay date
                    sw.Write("{0:F2},", ebal);                                                                            //ending principal
                    sw.Write("{0:F2},", ipmt);                                                                            //interest
                    sw.Write("{0:F2},", ppmt);                                                                            //regular principal
                    sw.Write("{0:F2},", upmt);                                                                            //prepaid principal
                    sw.Write("{0:F2},", ppmt + upmt);                                                                     //total principal
                    sw.Write("{0:F2},", ipmt + ppmt + upmt);                                                              //net flow
                    sw.Write("{0:F4},", 1 - Math.Pow(1 - smm, 12));                                                       //cpr
                    sw.Write("{0:F6},", smm);                                                                             //smm
                    sw.Write("{0},", wala + i);                                                                           //wala
                    sw.Write("{0},", wam - i);                                                                            //wam
                    sw.Write("{0},", i);                                                                                  //p&i payment
                    sw.Write("{0},", i);                                                                                  //interest payment
                    sw.Write("{0:F2},", bbal);                                                                            //beginning balance
                    sw.Write("{0},", days);                                                                               //days
                    sw.Write("{0:F8},", df);                                                                              //discount
                    sw.WriteLine("{0}", df * (ipmt + ppmt + upmt));                                                       //pv
                }
            }
        }
Example #15
0
        static void Main(string[] args)
        {
            try
            {
                Option.Type type       = Option.Type.Put;
                double      underlying = 36.0;
                double      spreadRate = 0.005;

                double dividendYield = 0.02;
                double riskFreeRate  = 0.06;
                double volatility    = 0.2;

                int    settlementDays  = 3;
                int    length          = 5;
                double redemption      = 100.0;
                double conversionRatio = redemption / underlying; // at the money

                // set up dates/schedules
                Calendar calendar = new TARGET();
                Date     today    = calendar.adjust(Date.Today);

                Settings.setEvaluationDate(today);
                Date settlementDate = calendar.advance(today, settlementDays, TimeUnit.Days);
                Date exerciseDate   = calendar.advance(settlementDate, length, TimeUnit.Years);
                Date issueDate      = calendar.advance(exerciseDate, -length, TimeUnit.Years);

                BusinessDayConvention convention = BusinessDayConvention.ModifiedFollowing;

                Frequency frequency = Frequency.Annual;

                Schedule schedule = new Schedule(issueDate, exerciseDate,
                                                 new Period(frequency), calendar, convention, convention,
                                                 DateGeneration.Rule.Backward, false);

                DividendSchedule    dividends   = new DividendSchedule();
                CallabilitySchedule callability = new CallabilitySchedule();

                List <double> coupons      = new InitializedList <double>(1, 0.05);
                DayCounter    bondDayCount = new Thirty360();

                int[] callLength = { 2, 4 }; // Call dates, years 2,4.
                int[] putLength  = { 3 };    // Put dates year 3.

                double[] callPrices = { 101.5, 100.85 };
                double[] putPrices  = { 105.0 };

                // Load call schedules
                for (int i = 0; i < callLength.Length; i++)
                {
                    SoftCallability s = new SoftCallability(
                        new Callability.Price(callPrices[i], Callability.Price.Type.Clean), schedule.date(callLength[i]),
                        1.20);
                    callability.Add(s);
                }

                for (int j = 0; j < putLength.Length; j++)
                {
                    Callability s = new Callability(new Callability.Price(putPrices[j], Callability.Price.Type.Clean),
                                                    Callability.Type.Put, schedule.date(putLength[j]));
                    callability.Add(s);
                }

                // Assume dividends are paid every 6 months .
                for (Date d = today + new Period(6, TimeUnit.Months); d < exerciseDate; d += new Period(6, TimeUnit.Months))
                {
                    Dividend div = new FixedDividend(1.0, d);
                    dividends.Add(div);
                }

                DayCounter dayCounter = new Actual365Fixed();
                double     maturity   = dayCounter.yearFraction(settlementDate, exerciseDate);

                Console.WriteLine("option type = " + type);
                Console.WriteLine("Time to maturity = " + maturity);
                Console.WriteLine("Underlying price = " + underlying);
                Console.WriteLine("Risk-free interest rate = {0:0.0%}", riskFreeRate);
                Console.WriteLine("Dividend yield = {0:0.0%}%", dividendYield);
                Console.WriteLine("Volatility = {0:0.0%}%", volatility);
                Console.WriteLine("");


                // write column headings
                int[]  widths     = { 35, 14, 14 };
                int    totalWidth = widths[0] + widths[1] + widths[2];
                string rule       = new string('-', totalWidth);
                string dblrule    = new string('=', totalWidth);

                Console.WriteLine(dblrule);
                Console.WriteLine("Tsiveriotis-Fernandes method");
                Console.WriteLine(dblrule);
                Console.WriteLine("Tree Type                           European     American        ");
                Console.WriteLine(rule);


                Exercise exercise   = new EuropeanExercise(exerciseDate);
                Exercise amexercise = new AmericanExercise(settlementDate, exerciseDate);

                Handle <Quote> underlyingH = new Handle <Quote>(new SimpleQuote(underlying));
                Handle <YieldTermStructure> flatTermStructure =
                    new Handle <YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter));
                Handle <YieldTermStructure> flatDividendTS =
                    new Handle <YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter));
                Handle <BlackVolTermStructure> flatVolTS =
                    new Handle <BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility,
                                                                            dayCounter));

                BlackScholesMertonProcess stochasticProcess =
                    new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS);

                int timeSteps = 801;

                Handle <Quote> creditSpread = new Handle <Quote>(new SimpleQuote(spreadRate));

                Quote rate = new SimpleQuote(riskFreeRate);

                Handle <YieldTermStructure> discountCurve =
                    new Handle <YieldTermStructure>(new FlatForward(today, new Handle <Quote>(rate), dayCounter));

                IPricingEngine engine = new BinomialConvertibleEngine <JarrowRudd>(stochasticProcess, timeSteps);

                ConvertibleFixedCouponBond europeanBond = new ConvertibleFixedCouponBond(exercise, conversionRatio,
                                                                                         dividends, callability, creditSpread, issueDate, settlementDays, coupons, bondDayCount, schedule,
                                                                                         redemption);

                europeanBond.setPricingEngine(engine);

                ConvertibleFixedCouponBond americanBond = new ConvertibleFixedCouponBond(amexercise, conversionRatio,
                                                                                         dividends, callability, creditSpread, issueDate, settlementDays, coupons, bondDayCount, schedule,
                                                                                         redemption);
                americanBond.setPricingEngine(engine);


                Console.WriteLine("Jarrow-Rudd                         {0:0.000000}   {1:0.000000}", europeanBond.NPV(), americanBond.NPV());

                americanBond.setPricingEngine(new BinomialConvertibleEngine <CoxRossRubinstein>(stochasticProcess, timeSteps));
                europeanBond.setPricingEngine(new BinomialConvertibleEngine <CoxRossRubinstein>(stochasticProcess, timeSteps));

                Console.WriteLine("CoxRossRubinstein                   {0:0.000000}   {1:0.000000}", europeanBond.NPV(), americanBond.NPV());

                americanBond.setPricingEngine(new BinomialConvertibleEngine <AdditiveEQPBinomialTree>(stochasticProcess, timeSteps));
                europeanBond.setPricingEngine(new BinomialConvertibleEngine <AdditiveEQPBinomialTree>(stochasticProcess, timeSteps));

                Console.WriteLine("AdditiveEQPBinomialTree             {0:0.000000}   {1:0.000000}", europeanBond.NPV(), americanBond.NPV());

                americanBond.setPricingEngine(new BinomialConvertibleEngine <Trigeorgis>(stochasticProcess, timeSteps));
                europeanBond.setPricingEngine(new BinomialConvertibleEngine <Trigeorgis>(stochasticProcess, timeSteps));

                Console.WriteLine("Trigeorgis                          {0:0.000000}   {1:0.000000}", europeanBond.NPV(), americanBond.NPV());

                americanBond.setPricingEngine(new BinomialConvertibleEngine <Tian>(stochasticProcess, timeSteps));
                europeanBond.setPricingEngine(new BinomialConvertibleEngine <Tian>(stochasticProcess, timeSteps));

                Console.WriteLine("Tian                                {0:0.000000}   {1:0.000000}", europeanBond.NPV(), americanBond.NPV());

                americanBond.setPricingEngine(new BinomialConvertibleEngine <LeisenReimer>(stochasticProcess, timeSteps));
                europeanBond.setPricingEngine(new BinomialConvertibleEngine <LeisenReimer>(stochasticProcess, timeSteps));

                Console.WriteLine("LeisenReimer                        {0:0.000000}   {1:0.000000}", europeanBond.NPV(), americanBond.NPV());

                americanBond.setPricingEngine(new BinomialConvertibleEngine <Joshi4>(stochasticProcess, timeSteps));
                europeanBond.setPricingEngine(new BinomialConvertibleEngine <Joshi4>(stochasticProcess, timeSteps));

                Console.WriteLine("Joshi4                              {0:0.000000}   {1:0.000000}", europeanBond.NPV(), americanBond.NPV());
                Console.WriteLine("===========================================================================");
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            Console.ReadKey();
        }
Example #16
0
        public void testCachedValue()
        {
            // Testing credit-default swap against cached values...

            using (SavedSettings backup = new SavedSettings())
            {
                // Initialize curves
                Settings.setEvaluationDate(new Date(9, Month.June, 2006));
                Date     today    = Settings.evaluationDate();
                Calendar calendar = new TARGET();

                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  = calendar.advance(today, -1, TimeUnit.Years);
                Date                  maturity   = calendar.advance(issueDate, 10, TimeUnit.Years);
                Frequency             frequency  = Frequency.Semiannual;
                BusinessDayConvention convention = BusinessDayConvention.ModifiedFollowing;

                Schedule schedule = new Schedule(issueDate, maturity, new Period(frequency), calendar,
                                                 convention, convention, DateGeneration.Rule.Forward, false);

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

                CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate,
                                                              schedule, convention, dayCount, true, true);
                cds.setPricingEngine(new MidPointCdsEngine(probabilityCurve, recoveryRate, discountCurve));

                double npv      = 295.0153398;
                double fairRate = 0.007517539081;

                double calculatedNpv      = cds.NPV();
                double calculatedFairRate = cds.fairSpread();
                double tolerance          = 1.0e-7;

                if (Math.Abs(calculatedNpv - npv) > tolerance)
                {
                    Assert.Fail(
                        "Failed to reproduce NPV with mid-point engine\n"
                        + "    calculated NPV: " + calculatedNpv + "\n"
                        + "    expected NPV:   " + npv);
                }

                if (Math.Abs(calculatedFairRate - fairRate) > tolerance)
                {
                    Assert.Fail(
                        "Failed to reproduce fair rate with mid-point engine\n"
                        + "    calculated fair rate: " + calculatedFairRate + "\n"
                        + "    expected fair rate:   " + fairRate);
                }

                cds.setPricingEngine(new IntegralCdsEngine(new Period(1, TimeUnit.Days), probabilityCurve,
                                                           recoveryRate, discountCurve));

                calculatedNpv      = cds.NPV();
                calculatedFairRate = cds.fairSpread();
                tolerance          = 1.0e-5;

                if (Math.Abs(calculatedNpv - npv) > notional * tolerance * 10)
                {
                    Assert.Fail(
                        "Failed to reproduce NPV with integral engine "
                        + "(step = 1 day)\n"
                        + "    calculated NPV: " + calculatedNpv + "\n"
                        + "    expected NPV:   " + npv);
                }

                if (Math.Abs(calculatedFairRate - fairRate) > tolerance)
                {
                    Assert.Fail(
                        "Failed to reproduce fair rate with integral engine "
                        + "(step = 1 day)\n"
                        + "    calculated fair rate: " + calculatedFairRate + "\n"
                        + "    expected fair rate:   " + fairRate);
                }

                cds.setPricingEngine(new IntegralCdsEngine(new Period(1, TimeUnit.Weeks), probabilityCurve, recoveryRate, discountCurve));

                calculatedNpv      = cds.NPV();
                calculatedFairRate = cds.fairSpread();
                tolerance          = 1.0e-5;

                if (Math.Abs(calculatedNpv - npv) > notional * tolerance * 10)
                {
                    Assert.Fail(
                        "Failed to reproduce NPV with integral engine "
                        + "(step = 1 week)\n"
                        + "    calculated NPV: " + calculatedNpv + "\n"
                        + "    expected NPV:   " + npv);
                }

                if (Math.Abs(calculatedFairRate - fairRate) > tolerance)
                {
                    Assert.Fail(
                        "Failed to reproduce fair rate with integral engine "
                        + "(step = 1 week)\n"
                        + "    calculated fair rate: " + calculatedFairRate + "\n"
                        + "    expected fair rate:   " + fairRate);
                }
            }
        }
Example #17
0
        public void testFairUpfront()
        {
            // Testing fair-upfront calculation for credit-default swaps...

            using (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);
                }
            }
        }
Example #18
0
        static void Main(string[] args)
        {
            try
            {
                DateTime timer = DateTime.Now;

                int numberOfBonds = 15;

                double[] cleanPrice = new double[numberOfBonds];

                for (int i = 0; i < numberOfBonds; i++)
                {
                    cleanPrice[i] = 100.0;
                }

                List <SimpleQuote> quote = new List <SimpleQuote>();
                for (int i = 0; i < numberOfBonds; i++)
                {
                    SimpleQuote cp = new SimpleQuote(cleanPrice[i]);
                    quote.Add(cp);
                }

                RelinkableHandle <Quote>[] quoteHandle = new RelinkableHandle <Quote> [numberOfBonds];
                for (int i = 0; i < numberOfBonds; i++)
                {
                    quoteHandle[i] = new RelinkableHandle <Quote>();
                    quoteHandle[i].linkTo(quote[i]);
                }

                int[]    lengths = { 2,  4,  6,  8, 10, 12, 14, 16,
                                     18,   20, 22, 24, 26, 28, 30 };
                double[] coupons = { 0.0200, 0.0225, 0.0250, 0.0275, 0.0300,
                                     0.0325, 0.0350, 0.0375, 0.0400, 0.0425,
                                     0.0450, 0.0475, 0.0500, 0.0525, 0.0550 };

                Frequency             frequency         = Frequency.Annual;
                DayCounter            dc                = new SimpleDayCounter();
                BusinessDayConvention accrualConvention = BusinessDayConvention.ModifiedFollowing;
                BusinessDayConvention convention        = BusinessDayConvention.ModifiedFollowing;
                double redemption = 100.0;

                Calendar calendar  = new TARGET();
                Date     today     = calendar.adjust(Date.Today);
                Date     origToday = today;
                Settings.setEvaluationDate(today);

                // changing bondSettlementDays=3 increases calculation
                // time of exponentialsplines fitting method
                int bondSettlementDays  = 0;
                int curveSettlementDays = 0;

                Date bondSettlementDate = calendar.advance(today, new Period(bondSettlementDays, TimeUnit.Days));

                Console.WriteLine();
                Console.WriteLine("Today's date: " + today);
                Console.WriteLine("Bonds' settlement date: " + bondSettlementDate);
                Console.WriteLine("Calculating fit for 15 bonds.....\n");

                List <BondHelper> instrumentsA = new List <BondHelper>();
                List <RateHelper> instrumentsB = new List <RateHelper>();

                for (int j = 0; j < lengths.Length; j++)
                {
                    Date maturity = calendar.advance(bondSettlementDate, new Period(lengths[j], TimeUnit.Years));

                    Schedule schedule = new Schedule(bondSettlementDate, maturity, new Period(frequency),
                                                     calendar, accrualConvention, accrualConvention,
                                                     DateGeneration.Rule.Backward, false);

                    BondHelper helperA = new FixedRateBondHelper(quoteHandle[j],
                                                                 bondSettlementDays,
                                                                 100.0,
                                                                 schedule,
                                                                 new InitializedList <double>(1, coupons[j]),
                                                                 dc,
                                                                 convention,
                                                                 redemption);

                    RateHelper helperB = new FixedRateBondHelper(quoteHandle[j],
                                                                 bondSettlementDays,
                                                                 100.0,
                                                                 schedule,
                                                                 new InitializedList <double>(1, coupons[j]),
                                                                 dc,
                                                                 convention,
                                                                 redemption);
                    instrumentsA.Add(helperA);
                    instrumentsB.Add(helperB);
                }


                bool   constrainAtZero = true;
                double tolerance       = 1.0e-10;
                int    max             = 5000;

                YieldTermStructure ts0 = new PiecewiseYieldCurve <Discount, LogLinear>(curveSettlementDays,
                                                                                       calendar,
                                                                                       instrumentsB,
                                                                                       dc);

                ExponentialSplinesFitting exponentialSplines = new ExponentialSplinesFitting(constrainAtZero);

                FittedBondDiscountCurve ts1 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                          calendar,
                                                                          instrumentsA,
                                                                          dc,
                                                                          exponentialSplines,
                                                                          tolerance,
                                                                          max);

                printOutput("(a) exponential splines", ts1);


                SimplePolynomialFitting simplePolynomial = new SimplePolynomialFitting(3, constrainAtZero);

                FittedBondDiscountCurve ts2 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                          calendar,
                                                                          instrumentsA,
                                                                          dc,
                                                                          simplePolynomial,
                                                                          tolerance,
                                                                          max);

                printOutput("(b) simple polynomial", ts2);


                NelsonSiegelFitting nelsonSiegel = new NelsonSiegelFitting();

                FittedBondDiscountCurve ts3 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                          calendar,
                                                                          instrumentsA,
                                                                          dc,
                                                                          nelsonSiegel,
                                                                          tolerance,
                                                                          max);

                printOutput("(c) Nelson-Siegel", ts3);


                // a cubic bspline curve with 11 knot points, implies
                // n=6 (constrained problem) basis functions

                double[] knots = { -30.0, -20.0,  0.0,  5.0, 10.0, 15.0,
                                   20.0,   25.0, 30.0, 40.0, 50.0 };

                List <double> knotVector = new List <double>();
                for (int i = 0; i < knots.Length; i++)
                {
                    knotVector.Add(knots[i]);
                }

                CubicBSplinesFitting cubicBSplines = new CubicBSplinesFitting(knotVector, constrainAtZero);

                FittedBondDiscountCurve ts4 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                          calendar,
                                                                          instrumentsA,
                                                                          dc,
                                                                          cubicBSplines,
                                                                          tolerance,
                                                                          max);

                printOutput("(d) cubic B-splines", ts4);

                SvenssonFitting svensson = new SvenssonFitting();

                FittedBondDiscountCurve ts5 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                          calendar,
                                                                          instrumentsA,
                                                                          dc,
                                                                          svensson,
                                                                          tolerance,
                                                                          max);

                printOutput("(e) Svensson", ts5);

                Handle <YieldTermStructure> discountCurve = new Handle <YieldTermStructure>(
                    new FlatForward(curveSettlementDays, calendar, 0.01, dc));

                SpreadFittingMethod nelsonSiegelSpread = new SpreadFittingMethod(new NelsonSiegelFitting(), discountCurve);

                FittedBondDiscountCurve ts6 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                          calendar,
                                                                          instrumentsA,
                                                                          dc,
                                                                          nelsonSiegelSpread,
                                                                          tolerance,
                                                                          max);

                printOutput("(f) Nelson-Siegel spreaded", ts6);


                Console.WriteLine("Output par rates for each curve. In this case, ");
                Console.WriteLine("par rates should equal coupons for these par bonds.\n");

                Console.WriteLine(" tenor" + " | "
                                  + "coupon" + " | "
                                  + "bstrap" + " | "
                                  + "   (a)" + " | "
                                  + "   (b)" + " | "
                                  + "   (c)" + " | "
                                  + "   (d)" + " | "
                                  + "   (e)" + " | "
                                  + "   (f)");

                for (int i = 0; i < instrumentsA.Count; i++)
                {
                    List <CashFlow> cfs = instrumentsA[i].bond().cashflows();

                    int         cfSize   = instrumentsA[i].bond().cashflows().Count;
                    List <Date> keyDates = new List <Date>();
                    keyDates.Add(bondSettlementDate);

                    for (int j = 0; j < cfSize - 1; j++)
                    {
                        if (!cfs[j].hasOccurred(bondSettlementDate, false))
                        {
                            Date myDate = cfs[j].date();
                            keyDates.Add(myDate);
                        }
                    }

                    double tenor = dc.yearFraction(today, cfs[cfSize - 1].date());
                    double test  = parRate(ts0, keyDates, dc);

                    Console.WriteLine(tenor.ToString("##.000").PadLeft(6) + " | "
                                      + (100.0 * coupons[i]).ToString("##.000").PadLeft(6) + " | "
                                      // piecewise bootstrap
                                      + (100.0 * parRate(ts0, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // exponential splines
                                      + (100.0 * parRate(ts1, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // simple polynomial
                                      + (100.0 * parRate(ts2, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Nelson-Siegel
                                      + (100.0 * parRate(ts3, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // cubic bsplines
                                      + (100.0 * parRate(ts4, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Svensson
                                      + (100.0 * parRate(ts5, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Nelson-Siegel Spreaded
                                      + (100.0 * parRate(ts6, keyDates, dc)).ToString("##.000").PadLeft(6));
                }

                Console.WriteLine("\n\n");
                Console.WriteLine("Now add 23 months to today. Par rates should be ");
                Console.WriteLine("automatically recalculated because today's date ");
                Console.WriteLine("changes.  Par rates will NOT equal coupons (YTM ");
                Console.WriteLine("will, with the correct compounding), but the ");
                Console.WriteLine("piecewise yield curve par rates can be used as ");
                Console.WriteLine("a benchmark for correct par rates.");
                Console.WriteLine();

                today = calendar.advance(origToday, 23, TimeUnit.Months, convention);
                Settings.setEvaluationDate(today);
                bondSettlementDate = calendar.advance(today, new Period(bondSettlementDays, TimeUnit.Days));

                printOutput("(a) exponential splines", ts1);

                printOutput("(b) simple polynomial", ts2);

                printOutput("(c) Nelson-Siegel", ts3);

                printOutput("(d) cubic B-splines", ts4);

                printOutput("(e) Svensson", ts5);

                printOutput("(f) Nelson-Siegel spreaded", ts6);

                Console.WriteLine("\n");


                Console.WriteLine(" tenor" + " | "
                                  + "coupon" + " | "
                                  + "bstrap" + " | "
                                  + "   (a)" + " | "
                                  + "   (b)" + " | "
                                  + "   (c)" + " | "
                                  + "   (d)" + " | "
                                  + "   (e)" + " | "
                                  + "   (f)");

                for (int i = 0; i < instrumentsA.Count; i++)
                {
                    List <CashFlow> cfs = instrumentsA[i].bond().cashflows();

                    int         cfSize   = instrumentsA[i].bond().cashflows().Count;
                    List <Date> keyDates = new List <Date>();
                    keyDates.Add(bondSettlementDate);

                    for (int j = 0; j < cfSize - 1; j++)
                    {
                        if (!cfs[j].hasOccurred(bondSettlementDate, false))
                        {
                            Date myDate = cfs[j].date();
                            keyDates.Add(myDate);
                        }
                    }

                    double tenor = dc.yearFraction(today, cfs[cfSize - 1].date());

                    double test = parRate(ts0, keyDates, dc);

                    Console.WriteLine(tenor.ToString("##.000").PadLeft(6) + " | "
                                      + (100.0 * coupons[i]).ToString("#.000").PadLeft(6) + " | "
                                      // piecewise bootstrap
                                      + (100.0 * parRate(ts0, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // exponential splines
                                      + (100.0 * parRate(ts1, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // simple polynomial
                                      + (100.0 * parRate(ts2, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Nelson-Siegel
                                      + (100.0 * parRate(ts3, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // cubic bsplines
                                      + (100.0 * parRate(ts4, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Svensson
                                      + (100.0 * parRate(ts5, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Nelson-Siegel Spreaded
                                      + (100.0 * parRate(ts6, keyDates, dc)).ToString("##.000").PadLeft(6));
                }

                Console.WriteLine("\n\n");
                Console.WriteLine("Now add one more month, for a total of two years ");
                Console.WriteLine("from the original date. The first instrument is ");
                Console.WriteLine("now expired and par rates should again equal ");
                Console.WriteLine("coupon values, since clean prices did not change.");
                Console.WriteLine("\n");

                instrumentsA.RemoveRange(0, 1); // TODO
                instrumentsB.RemoveRange(0, 1); // TODO

                today = calendar.advance(origToday, 24, TimeUnit.Months, convention);
                Settings.setEvaluationDate(today);
                bondSettlementDate = calendar.advance(today, new Period(bondSettlementDays, TimeUnit.Days));

                YieldTermStructure ts00 = new PiecewiseYieldCurve <Discount, LogLinear>(curveSettlementDays,
                                                                                        calendar,
                                                                                        instrumentsB,
                                                                                        dc);

                FittedBondDiscountCurve ts11 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                           calendar,
                                                                           instrumentsA,
                                                                           dc,
                                                                           exponentialSplines,
                                                                           tolerance,
                                                                           max);

                printOutput("(a) exponential splines", ts11);


                FittedBondDiscountCurve ts22 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                           calendar,
                                                                           instrumentsA,
                                                                           dc,
                                                                           simplePolynomial,
                                                                           tolerance,
                                                                           max);

                printOutput("(b) simple polynomial", ts22);


                FittedBondDiscountCurve ts33 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                           calendar,
                                                                           instrumentsA,
                                                                           dc,
                                                                           nelsonSiegel,
                                                                           tolerance,
                                                                           max);

                printOutput("(c) Nelson-Siegel", ts33);


                FittedBondDiscountCurve ts44 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                           calendar,
                                                                           instrumentsA,
                                                                           dc,
                                                                           cubicBSplines,
                                                                           tolerance,
                                                                           max);

                printOutput("(d) cubic B-splines", ts44);

                FittedBondDiscountCurve ts55 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                           calendar,
                                                                           instrumentsA,
                                                                           dc,
                                                                           svensson,
                                                                           tolerance,
                                                                           max);

                printOutput("(e) Svensson", ts55);

                FittedBondDiscountCurve ts66 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                           calendar,
                                                                           instrumentsA,
                                                                           dc,
                                                                           nelsonSiegelSpread,
                                                                           tolerance,
                                                                           max);

                printOutput("(f) Nelson-Siegel spreaded", ts66);

                Console.WriteLine(" tenor" + " | "
                                  + "coupon" + " | "
                                  + "bstrap" + " | "
                                  + "   (a)" + " | "
                                  + "   (b)" + " | "
                                  + "   (c)" + " | "
                                  + "   (d)" + " | "
                                  + "   (e)" + " | "
                                  + "   (f)");

                for (int i = 0; i < instrumentsA.Count; i++)
                {
                    List <CashFlow> cfs = instrumentsA[i].bond().cashflows();

                    int         cfSize   = instrumentsA[i].bond().cashflows().Count;
                    List <Date> keyDates = new List <Date>();
                    keyDates.Add(bondSettlementDate);

                    for (int j = 0; j < cfSize - 1; j++)
                    {
                        if (!cfs[j].hasOccurred(bondSettlementDate, false))
                        {
                            Date myDate = cfs[j].date();
                            keyDates.Add(myDate);
                        }
                    }

                    double tenor = dc.yearFraction(today, cfs[cfSize - 1].date());

                    Console.WriteLine(tenor.ToString("##.000").PadLeft(6) + " | "
                                      + (100.0 * coupons[i + 1]).ToString("##.000").PadLeft(6) + " | "
                                      // piecewise bootstrap
                                      + (100.0 * parRate(ts00, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // exponential splines
                                      + (100.0 * parRate(ts11, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // simple polynomial
                                      + (100.0 * parRate(ts22, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Nelson-Siegel
                                      + (100.0 * parRate(ts33, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // cubic bsplines
                                      + (100.0 * parRate(ts44, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Svensson
                                      + (100.0 * parRate(ts55, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Nelson-Siegel Spreaded
                                      + (100.0 * parRate(ts66, keyDates, dc)).ToString("##.000").PadLeft(6));
                }


                Console.WriteLine("\n\n");
                Console.WriteLine("Now decrease prices by a small amount, corresponding");
                Console.WriteLine("to a theoretical five basis point parallel + shift of");
                Console.WriteLine("the yield curve. Because bond quotes change, the new ");
                Console.WriteLine("par rates should be recalculated automatically.");
                Console.WriteLine("\n");

                for (int k = 0; k < lengths.Length - 1; k++)
                {
                    double P   = instrumentsA[k].quote().link.value();
                    Bond   b   = instrumentsA[k].bond();
                    double ytm = BondFunctions.yield(b, P, dc, Compounding.Compounded, frequency, today);
                    double dur = BondFunctions.duration(b, ytm, dc, Compounding.Compounded, frequency,
                                                        Duration.Type.Modified, today);

                    const double bpsChange = 5.0;
                    // dP = -dur * P * dY
                    double deltaP = -dur * P * (bpsChange / 10000.0);
                    quote[k + 1].setValue(P + deltaP);
                }


                Console.WriteLine(" tenor" + " | "
                                  + "coupon" + " | "
                                  + "bstrap" + " | "
                                  + "   (a)" + " | "
                                  + "   (b)" + " | "
                                  + "   (c)" + " | "
                                  + "   (d)" + " | "
                                  + "   (e)" + " | "
                                  + "   (f)");

                for (int i = 0; i < instrumentsA.Count; i++)
                {
                    List <CashFlow> cfs = instrumentsA[i].bond().cashflows();

                    int         cfSize   = instrumentsA[i].bond().cashflows().Count;
                    List <Date> keyDates = new List <Date>();
                    keyDates.Add(bondSettlementDate);

                    for (int j = 0; j < cfSize - 1; j++)
                    {
                        if (!cfs[j].hasOccurred(bondSettlementDate, false))
                        {
                            Date myDate = cfs[j].date();
                            keyDates.Add(myDate);
                        }
                    }

                    double tenor = dc.yearFraction(today, cfs[cfSize - 1].date());

                    Console.WriteLine(tenor.ToString("##.000").PadLeft(6) + " | "
                                      + (100.0 * coupons[i + 1]).ToString("##.000").PadLeft(6) + " | "
                                      // piecewise bootstrap
                                      + (100.0 * parRate(ts00, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // exponential splines
                                      + (100.0 * parRate(ts11, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // simple polynomial
                                      + (100.0 * parRate(ts22, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Nelson-Siegel
                                      + (100.0 * parRate(ts33, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // cubic bsplines
                                      + (100.0 * parRate(ts44, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Svensson
                                      + (100.0 * parRate(ts55, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Nelson-Siegel Spreaded
                                      + (100.0 * parRate(ts66, keyDates, dc)).ToString("##.000").PadLeft(6));
                }



                Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer);
                Console.WriteLine();

                Console.Write("Press any key to continue ...");
                Console.ReadKey();
            }

            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return;
            }
        }
Example #19
0
        static void Main(string[] args)
        {
            DateTime timer = DateTime.Now;

            /*********************
            ***  MARKET DATA  ***
            *********************/

            Calendar calendar = new TARGET();

            Date settlementDate = new Date(18, Month.September, 2008);

            // must be a business day
            settlementDate = calendar.adjust(settlementDate);

            int fixingDays     = 3;
            int settlementDays = 3;

            Date todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days);

            // nothing to do with Date::todaysDate
            Settings.setEvaluationDate(todaysDate);

            Console.WriteLine("Today: {0}, {1}", todaysDate.DayOfWeek, todaysDate);
            Console.WriteLine("Settlement date: {0}, {1}", settlementDate.DayOfWeek, settlementDate);


            // Building of the bonds discounting yield curve

            /*********************
            ***  RATE HELPERS ***
            *********************/

            // RateHelpers are built from the above quotes together with
            // other instrument dependant infos.  Quotes are passed in
            // relinkable handles which could be relinked to some other
            // data source later.

            // Common data

            // ZC rates for the short end
            double zc3mQuote = 0.0096;
            double zc6mQuote = 0.0145;
            double zc1yQuote = 0.0194;

            Quote zc3mRate = new SimpleQuote(zc3mQuote);
            Quote zc6mRate = new SimpleQuote(zc6mQuote);
            Quote zc1yRate = new SimpleQuote(zc1yQuote);

            DayCounter zcBondsDayCounter = new Actual365Fixed();

            RateHelper zc3m = new DepositRateHelper(new Handle <Quote>(zc3mRate),
                                                    new Period(3, TimeUnit.Months), fixingDays,
                                                    calendar, BusinessDayConvention.ModifiedFollowing,
                                                    true, zcBondsDayCounter);
            RateHelper zc6m = new DepositRateHelper(new Handle <Quote>(zc6mRate),
                                                    new Period(6, TimeUnit.Months), fixingDays,
                                                    calendar, BusinessDayConvention.ModifiedFollowing,
                                                    true, zcBondsDayCounter);
            RateHelper zc1y = new DepositRateHelper(new Handle <Quote>(zc1yRate),
                                                    new Period(1, TimeUnit.Years), fixingDays,
                                                    calendar, BusinessDayConvention.ModifiedFollowing,
                                                    true, zcBondsDayCounter);

            // setup bonds
            double redemption = 100.0;

            const int numberOfBonds = 5;

            Date[] issueDates =
            {
                new Date(15, Month.March,    2005),
                new Date(15, Month.June,     2005),
                new Date(30, Month.June,     2006),
                new Date(15, Month.November, 2002),
                new Date(15, Month.May, 1987)
            };

            Date[] maturities =
            {
                new Date(31, Month.August, 2010),
                new Date(31, Month.August, 2011),
                new Date(31, Month.August, 2013),
                new Date(15, Month.August, 2018),
                new Date(15, Month.May, 2038)
            };

            double[] couponRates =
            {
                0.02375,
                0.04625,
                0.03125,
                0.04000,
                0.04500
            };

            double[] marketQuotes =
            {
                100.390625,
                106.21875,
                100.59375,
                101.6875,
                102.140625
            };

            List <SimpleQuote> quote = new List <SimpleQuote>();

            for (int i = 0; i < numberOfBonds; i++)
            {
                SimpleQuote cp = new SimpleQuote(marketQuotes[i]);
                quote.Add(cp);
            }

            List <RelinkableHandle <Quote> > quoteHandle = new InitializedList <RelinkableHandle <Quote> >(numberOfBonds);

            for (int i = 0; i < numberOfBonds; i++)
            {
                quoteHandle[i].linkTo(quote[i]);
            }

            // Definition of the rate helpers
            List <FixedRateBondHelper> bondsHelpers = new List <FixedRateBondHelper>();

            for (int i = 0; i < numberOfBonds; i++)
            {
                Schedule schedule = new Schedule(issueDates[i], maturities[i], new Period(Frequency.Semiannual),
                                                 new UnitedStates(UnitedStates.Market.GovernmentBond),
                                                 BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                                 DateGeneration.Rule.Backward, false);

                FixedRateBondHelper bondHelper = new FixedRateBondHelper(quoteHandle[i],
                                                                         settlementDays,
                                                                         100.0,
                                                                         schedule,
                                                                         new List <double>()
                {
                    couponRates[i]
                },
                                                                         new ActualActual(ActualActual.Convention.Bond),
                                                                         BusinessDayConvention.Unadjusted,
                                                                         redemption,
                                                                         issueDates[i]);

                bondsHelpers.Add(bondHelper);
            }

            /*********************
            **  CURVE BUILDING **
            *********************/

            // Any DayCounter would be fine.
            // ActualActual::ISDA ensures that 30 years is 30.0
            DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA);

            double tolerance = 1.0e-15;

            // A depo-bond curve
            List <RateHelper> bondInstruments = new List <RateHelper>();

            // Adding the ZC bonds to the curve for the short end
            bondInstruments.Add(zc3m);
            bondInstruments.Add(zc6m);
            bondInstruments.Add(zc1y);

            // Adding the Fixed rate bonds to the curve for the long end
            for (int i = 0; i < numberOfBonds; i++)
            {
                bondInstruments.Add(bondsHelpers[i]);
            }

            YieldTermStructure bondDiscountingTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                settlementDate, bondInstruments,
                termStructureDayCounter,
                new List <Handle <Quote> >(),
                new List <Date>(),
                tolerance);

            // Building of the Libor forecasting curve
            // deposits
            double d1wQuote = 0.043375;
            double d1mQuote = 0.031875;
            double d3mQuote = 0.0320375;
            double d6mQuote = 0.03385;
            double d9mQuote = 0.0338125;
            double d1yQuote = 0.0335125;
            // swaps
            double s2yQuote  = 0.0295;
            double s3yQuote  = 0.0323;
            double s5yQuote  = 0.0359;
            double s10yQuote = 0.0412;
            double s15yQuote = 0.0433;


            /********************
            ***    QUOTES    ***
            ********************/

            // SimpleQuote stores a value which can be manually changed;
            // other Quote subclasses could read the value from a database
            // or some kind of data feed.

            // deposits
            Quote d1wRate = new SimpleQuote(d1wQuote);
            Quote d1mRate = new SimpleQuote(d1mQuote);
            Quote d3mRate = new SimpleQuote(d3mQuote);
            Quote d6mRate = new SimpleQuote(d6mQuote);
            Quote d9mRate = new SimpleQuote(d9mQuote);
            Quote d1yRate = new SimpleQuote(d1yQuote);
            // swaps
            Quote s2yRate  = new SimpleQuote(s2yQuote);
            Quote s3yRate  = new SimpleQuote(s3yQuote);
            Quote s5yRate  = new SimpleQuote(s5yQuote);
            Quote s10yRate = new SimpleQuote(s10yQuote);
            Quote s15yRate = new SimpleQuote(s15yQuote);

            /*********************
            ***  RATE HELPERS ***
            *********************/

            // RateHelpers are built from the above quotes together with
            // other instrument dependant infos.  Quotes are passed in
            // relinkable handles which could be relinked to some other
            // data source later.

            // deposits
            DayCounter depositDayCounter = new Actual360();

            RateHelper d1w = new DepositRateHelper(
                new Handle <Quote>(d1wRate),
                new Period(1, TimeUnit.Weeks), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);
            RateHelper d1m = new DepositRateHelper(
                new Handle <Quote>(d1mRate),
                new Period(1, TimeUnit.Months), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);
            RateHelper d3m = new DepositRateHelper(
                new Handle <Quote>(d3mRate),
                new Period(3, TimeUnit.Months), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);
            RateHelper d6m = new DepositRateHelper(
                new Handle <Quote>(d6mRate),
                new Period(6, TimeUnit.Months), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);
            RateHelper d9m = new DepositRateHelper(
                new Handle <Quote>(d9mRate),
                new Period(9, TimeUnit.Months), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);
            RateHelper d1y = new DepositRateHelper(
                new Handle <Quote>(d1yRate),
                new Period(1, TimeUnit.Years), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);

            // setup swaps
            Frequency             swFixedLegFrequency  = Frequency.Annual;
            BusinessDayConvention swFixedLegConvention = BusinessDayConvention.Unadjusted;
            DayCounter            swFixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European);
            IborIndex             swFloatingLegIndex   = new Euribor6M();

            Period forwardStart = new Period(1, TimeUnit.Days);

            RateHelper s2y = new SwapRateHelper(
                new Handle <Quote>(s2yRate), new Period(2, TimeUnit.Years),
                calendar, swFixedLegFrequency,
                swFixedLegConvention, swFixedLegDayCounter,
                swFloatingLegIndex, new Handle <Quote>(), forwardStart);
            RateHelper s3y = new SwapRateHelper(
                new Handle <Quote>(s3yRate), new Period(3, TimeUnit.Years),
                calendar, swFixedLegFrequency,
                swFixedLegConvention, swFixedLegDayCounter,
                swFloatingLegIndex, new Handle <Quote>(), forwardStart);
            RateHelper s5y = new SwapRateHelper(
                new Handle <Quote>(s5yRate), new Period(5, TimeUnit.Years),
                calendar, swFixedLegFrequency,
                swFixedLegConvention, swFixedLegDayCounter,
                swFloatingLegIndex, new Handle <Quote>(), forwardStart);
            RateHelper s10y = new SwapRateHelper(
                new Handle <Quote>(s10yRate), new Period(10, TimeUnit.Years),
                calendar, swFixedLegFrequency,
                swFixedLegConvention, swFixedLegDayCounter,
                swFloatingLegIndex, new Handle <Quote>(), forwardStart);
            RateHelper s15y = new SwapRateHelper(
                new Handle <Quote>(s15yRate), new Period(15, TimeUnit.Years),
                calendar, swFixedLegFrequency,
                swFixedLegConvention, swFixedLegDayCounter,
                swFloatingLegIndex, new Handle <Quote>(), forwardStart);


            /*********************
            **  CURVE BUILDING **
            *********************/

            // Any DayCounter would be fine.
            // ActualActual::ISDA ensures that 30 years is 30.0

            // A depo-swap curve
            List <RateHelper> depoSwapInstruments = new List <RateHelper>();

            depoSwapInstruments.Add(d1w);
            depoSwapInstruments.Add(d1m);
            depoSwapInstruments.Add(d3m);
            depoSwapInstruments.Add(d6m);
            depoSwapInstruments.Add(d9m);
            depoSwapInstruments.Add(d1y);
            depoSwapInstruments.Add(s2y);
            depoSwapInstruments.Add(s3y);
            depoSwapInstruments.Add(s5y);
            depoSwapInstruments.Add(s10y);
            depoSwapInstruments.Add(s15y);
            YieldTermStructure depoSwapTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                settlementDate, depoSwapInstruments,
                termStructureDayCounter,
                new List <Handle <Quote> >(),
                new List <Date>(),
                tolerance);

            // Term structures that will be used for pricing:
            // the one used for discounting cash flows
            RelinkableHandle <YieldTermStructure> discountingTermStructure = new RelinkableHandle <YieldTermStructure>();
            // the one used for forward rate forecasting
            RelinkableHandle <YieldTermStructure> forecastingTermStructure = new RelinkableHandle <YieldTermStructure>();

            /*********************
             * BONDS TO BE PRICED *
             **********************/

            // Common data
            double faceAmount = 100;

            // Pricing engine
            IPricingEngine bondEngine = new DiscountingBondEngine(discountingTermStructure);

            // Zero coupon bond
            ZeroCouponBond zeroCouponBond = new ZeroCouponBond(
                settlementDays,
                new UnitedStates(UnitedStates.Market.GovernmentBond),
                faceAmount,
                new Date(15, Month.August, 2013),
                BusinessDayConvention.Following,
                116.92,
                new Date(15, Month.August, 2003));

            zeroCouponBond.setPricingEngine(bondEngine);

            // Fixed 4.5% US Treasury Note
            Schedule fixedBondSchedule = new Schedule(new Date(15, Month.May, 2007),
                                                      new Date(15, Month.May, 2017), new Period(Frequency.Semiannual),
                                                      new UnitedStates(UnitedStates.Market.GovernmentBond),
                                                      BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false);

            FixedRateBond fixedRateBond = new FixedRateBond(
                settlementDays,
                faceAmount,
                fixedBondSchedule,
                new List <double>()
            {
                0.045
            },
                new ActualActual(ActualActual.Convention.Bond),
                BusinessDayConvention.ModifiedFollowing,
                100.0, new Date(15, Month.May, 2007));

            fixedRateBond.setPricingEngine(bondEngine);

            // Floating rate bond (3M USD Libor + 0.1%)
            // Should and will be priced on another curve later...

            RelinkableHandle <YieldTermStructure> liborTermStructure = new RelinkableHandle <YieldTermStructure>();
            IborIndex libor3m = new USDLibor(new Period(3, TimeUnit.Months), liborTermStructure);

            libor3m.addFixing(new Date(17, Month.July, 2008), 0.0278625);

            Schedule floatingBondSchedule = new Schedule(new Date(21, Month.October, 2005),
                                                         new Date(21, Month.October, 2010), new Period(Frequency.Quarterly),
                                                         new UnitedStates(UnitedStates.Market.NYSE),
                                                         BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, true);

            FloatingRateBond floatingRateBond = new FloatingRateBond(
                settlementDays,
                faceAmount,
                floatingBondSchedule,
                libor3m,
                new Actual360(),
                BusinessDayConvention.ModifiedFollowing,
                2,
                // Gearings
                new List <double>()
            {
                1.0
            },
                // Spreads
                new List <double>()
            {
                0.001
            },
                // Caps
                new List <double?>(),
                // Floors
                new List <double?>(),
                // Fixing in arrears
                true,
                100.0,
                new Date(21, Month.October, 2005));

            floatingRateBond.setPricingEngine(bondEngine);

            // Coupon pricers
            IborCouponPricer pricer = new BlackIborCouponPricer();

            // optionLet volatilities
            double volatility = 0.0;
            Handle <OptionletVolatilityStructure> vol;

            vol = new Handle <OptionletVolatilityStructure>(
                new ConstantOptionletVolatility(
                    settlementDays,
                    calendar,
                    BusinessDayConvention.ModifiedFollowing,
                    volatility,
                    new Actual365Fixed()));

            pricer.setCapletVolatility(vol);
            Utils.setCouponPricer(floatingRateBond.cashflows(), pricer);

            // Yield curve bootstrapping
            forecastingTermStructure.linkTo(depoSwapTermStructure);
            discountingTermStructure.linkTo(bondDiscountingTermStructure);

            // We are using the depo & swap curve to estimate the future Libor rates
            liborTermStructure.linkTo(depoSwapTermStructure);

            /***************
             * BOND PRICING *
             ****************/

            // write column headings
            int[] widths = { 18, 10, 10, 10 };

            Console.WriteLine("{0,18}{1,10}{2,10}{3,10}", "", "ZC", "Fixed", "Floating");

            int width = widths[0]
                        + widths[1]
                        + widths[2]
                        + widths[3];
            string rule = "".PadLeft(width, '-'), dblrule = "".PadLeft(width, '=');
            string tab = "".PadLeft(8, ' ');

            Console.WriteLine(rule);

            Console.WriteLine("Net present value".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}",
                              zeroCouponBond.NPV(),
                              fixedRateBond.NPV(),
                              floatingRateBond.NPV());

            Console.WriteLine("Clean price".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}",
                              zeroCouponBond.cleanPrice(),
                              fixedRateBond.cleanPrice(),
                              floatingRateBond.cleanPrice());

            Console.WriteLine("Dirty price".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}",
                              zeroCouponBond.dirtyPrice(),
                              fixedRateBond.dirtyPrice(),
                              floatingRateBond.dirtyPrice());

            Console.WriteLine("Accrued coupon".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}",
                              zeroCouponBond.accruedAmount(),
                              fixedRateBond.accruedAmount(),
                              floatingRateBond.accruedAmount());

            Console.WriteLine("Previous coupon".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}",
                              "N/A",
                              fixedRateBond.previousCouponRate(),
                              floatingRateBond.previousCouponRate());

            Console.WriteLine("Next coupon".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}",
                              "N/A",
                              fixedRateBond.nextCouponRate(),
                              floatingRateBond.nextCouponRate());

            Console.WriteLine("Yield".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}",
                              zeroCouponBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual),
                              fixedRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual),
                              floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual));

            Console.WriteLine();

            // Other computations
            Console.WriteLine("Sample indirect computations (for the floating rate bond): ");
            Console.WriteLine(rule);

            Console.WriteLine("Yield to Clean Price: {0:n2}",
                              floatingRateBond.cleanPrice(floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual),
                                                          new Actual360(), Compounding.Compounded, Frequency.Annual,
                                                          settlementDate));

            Console.WriteLine("Clean Price to Yield: {0:0.00%}",
                              floatingRateBond.yield(floatingRateBond.cleanPrice(), new Actual360(), Compounding.Compounded, Frequency.Annual,
                                                     settlementDate));

            /* "Yield to Price"
            *  "Price to Yield" */

            Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer);
            Console.WriteLine();

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }
Example #20
0
        static void Main(string[] args)
        {
            double nominal = 575000000;

            Date _marketDate;
            Date _settlementDate;
            Dictionary <string, double> _depositRates;
            Dictionary <string, double> _swapRates;
            List <RateHelper>           _rateHelpers;
            Calendar _calendar   = new TARGET();
            int      _fixingDays = 2;

            _marketDate = new Date(new DateTime(2015, 12, 17));
            Settings.setEvaluationDate(_marketDate);

            _depositRates = new Dictionary <string, double>();
            _depositRates.Add("1M", 0.0045);
            _depositRates.Add("3M", 0.0070);
            _depositRates.Add("6M", 0.0090);

            _swapRates = new Dictionary <string, double>();
            _swapRates.Add("1Y", 0.0080);
            _swapRates.Add("2Y", 0.0109);
            _swapRates.Add("3Y", 0.0134);
            _swapRates.Add("4Y", 0.0153);
            _swapRates.Add("5Y", 0.0169);
            _swapRates.Add("7Y", 0.0193);
            _swapRates.Add("10Y", 0.0218);
            _swapRates.Add("30Y", 0.0262);

            _rateHelpers = new List <RateHelper>();
            foreach (var v in _depositRates)
            {
                SimpleQuote sq = new SimpleQuote(v.Value);
                _rateHelpers.Add(new DepositRateHelper(new Handle <Quote>(sq), new Period(v.Key),
                                                       _fixingDays, _calendar, BusinessDayConvention.ModifiedFollowing, true, new Actual360()));
            }
            foreach (var v in _swapRates)
            {
                SimpleQuote sq = new SimpleQuote(v.Value);
                _rateHelpers.Add(new SwapRateHelper(new Handle <Quote>(sq), new Period(v.Key),
                                                    _calendar, Frequency.Semiannual, BusinessDayConvention.Unadjusted,
                                                    new Thirty360(Thirty360.Thirty360Convention.USA), new Euribor3M()));
            }

            _marketDate     = _calendar.adjust(_marketDate);
            _settlementDate = _calendar.advance(_marketDate, _fixingDays, TimeUnit.Days);

            YieldTermStructure yieldTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                _settlementDate, _rateHelpers, new ActualActual(ActualActual.Convention.ISDA));

            RelinkableHandle <YieldTermStructure> yieldTermStructureHandle = new RelinkableHandle <YieldTermStructure>();


            Frequency             fixedLegFrequency  = Frequency.Semiannual;
            BusinessDayConvention fixedLegConvention = BusinessDayConvention.ModifiedFollowing;
            DayCounter            fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.USA);
            double fixedRate = 0.0144;

            Frequency             floatLegFrequency  = Frequency.Quarterly;
            BusinessDayConvention floatLegConvention = BusinessDayConvention.ModifiedFollowing;
            DayCounter            floatLegDayCounter = new Actual360();
            IborIndex             iborIndex          = new Euribor3M(yieldTermStructureHandle);

            iborIndex.addFixing(new Date(18, Month.Aug, 2015), 0.0033285);
            iborIndex.addFixing(new Date(18, Month.Nov, 2015), 0.0036960);
            double floatSpread = 0.0;

            VanillaSwap.Type swapType = VanillaSwap.Type.Receiver;

            Date     maturity      = new Date(20, Month.Nov, 2018);
            Date     effective     = new Date(20, Month.Nov, 2013);
            Schedule fixedSchedule = new Schedule(effective, maturity, new Period(fixedLegFrequency), _calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false);
            Schedule floatSchedule = new Schedule(effective, maturity, new Period(floatLegFrequency), _calendar, floatLegConvention, floatLegConvention, DateGeneration.Rule.Forward, false);

            VanillaSwap vanillaSwap = new VanillaSwap(swapType, nominal, fixedSchedule, fixedRate, fixedLegDayCounter, floatSchedule, iborIndex, floatSpread, floatLegDayCounter);

            InterestRate        interestRate = new InterestRate(fixedRate, fixedLegDayCounter, Compounding.Simple, fixedLegFrequency);
            List <InterestRate> coupons      = new List <InterestRate>();

            for (int i = 0; i < fixedSchedule.Count; i++)
            {
                coupons.Add(interestRate);
            }
            FixedRateBond    fixedBond = new FixedRateBond(_fixingDays, nominal, fixedSchedule, coupons, BusinessDayConvention.ModifiedFollowing);
            FloatingRateBond floatBond = new FloatingRateBond(_fixingDays, nominal, floatSchedule, iborIndex, floatLegDayCounter);

            IPricingEngine bondPricingEngine = new DiscountingBondEngine(yieldTermStructureHandle);

            fixedBond.setPricingEngine(bondPricingEngine);
            floatBond.setPricingEngine(bondPricingEngine);

            IPricingEngine swapPricingEngine = new DiscountingSwapEngine(yieldTermStructureHandle);

            vanillaSwap.setPricingEngine(swapPricingEngine);

            yieldTermStructureHandle.linkTo(yieldTermStructure);

            double swapNPV      = vanillaSwap.NPV();
            double swapFixedNPV = vanillaSwap.fixedLegNPV();
            double swapFloatNPV = vanillaSwap.floatingLegNPV();

            double bondFixedNPV = fixedBond.NPV();
            double bondFloatNPV = floatBond.NPV();

            int    w = (swapType == VanillaSwap.Type.Receiver ? 1 : -1);
            double asBondsMarketValue      = w * (bondFixedNPV - bondFloatNPV);
            double asBondsMarketValueNoAcc = w * (fixedBond.cleanPrice() - floatBond.cleanPrice()) / 100.0 * nominal;
            double asBondsAccruedInterest  = asBondsMarketValue - asBondsMarketValueNoAcc;

            Console.WriteLine("Vanilla Swap Maket Value      : {0:N}", swapNPV);
            Console.WriteLine("As Bonds Market Value         : {0:N}", asBondsMarketValue);
            Console.WriteLine("As Bonds Market Value (no acc): {0:N}", asBondsMarketValueNoAcc);
            Console.WriteLine("As Bonds Accrued Interest     : {0:N}", asBondsAccruedInterest);

            Date   rollDate      = new Date(1, Month.Nov, 2015);
            double bondFixedCash = 0;

            foreach (CashFlow cf in fixedBond.cashflows())
            {
                if (cf.date() > rollDate & cf.date() <= _marketDate)
                {
                    bondFixedCash += cf.amount();
                }
            }
            double bondFloatCash = 0;

            foreach (CashFlow cf in floatBond.cashflows())
            {
                if (cf.date() > rollDate & cf.date() <= _marketDate)
                {
                    bondFloatCash += cf.amount();
                }
            }
            double asBondsCash = w * (bondFixedCash - bondFloatCash);

            Console.WriteLine("As Bonds Settled Cash         : {0:N}", asBondsCash);
        }