예제 #1
0
            // setup
            public CommonVars()
            {
                // data
                calendar       = new TARGET();
                settlementDays = 2;
                today          = calendar.adjust(Date.Today);
                Settings.setEvaluationDate(today);
                settlement         = calendar.advance(today, settlementDays, TimeUnit.Days);
                fixedLegConvention = BusinessDayConvention.Unadjusted;
                fixedLegFrequency  = Frequency.Annual;
                fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European);
                bondSettlementDays = 3;
                bondDayCounter     = new ActualActual();
                bondConvention     = BusinessDayConvention.Following;
                bondRedemption     = 100.0;
                bmaFrequency       = Frequency.Quarterly;
                bmaConvention      = BusinessDayConvention.Following;
                bmaDayCounter      = new ActualActual();

                deposits = depositData.Length;
                fras     = fraData.Length;
                swaps    = swapData.Length;
                bonds    = bondData.Length;
                bmas     = bmaData.Length;

                // market elements
                rates     = new List <SimpleQuote>(deposits + swaps);
                fraRates  = new List <SimpleQuote>(fras);
                prices    = new List <SimpleQuote>(bonds);
                fractions = new List <SimpleQuote>(bmas);
                for (int i = 0; i < deposits; i++)
                {
                    rates.Add(new SimpleQuote(depositData[i].rate / 100));
                }
                for (int i = 0; i < swaps; i++)
                {
                    rates.Add(new SimpleQuote(swapData[i].rate / 100));
                }
                for (int i = 0; i < fras; i++)
                {
                    fraRates.Add(new SimpleQuote(fraData[i].rate / 100));
                }
                for (int i = 0; i < bonds; i++)
                {
                    prices.Add(new SimpleQuote(bondData[i].price));
                }
                for (int i = 0; i < bmas; i++)
                {
                    fractions.Add(new SimpleQuote(bmaData[i].rate / 100));
                }

                // rate helpers
                instruments = new List <RateHelper>(deposits + swaps);
                fraHelpers  = new List <RateHelper>(fras);
                bondHelpers = new List <RateHelper>(bonds);
                schedules   = new List <Schedule>(bonds);
                bmaHelpers  = new List <RateHelper>(bmas);

                IborIndex euribor6m = new Euribor6M();

                for (int i = 0; i < deposits; i++)
                {
                    Handle <Quote> r = new Handle <Quote>(rates[i]);
                    instruments.Add(new DepositRateHelper(r, new Period(depositData[i].n, depositData[i].units),
                                                          euribor6m.fixingDays(), calendar,
                                                          euribor6m.businessDayConvention(),
                                                          euribor6m.endOfMonth(),
                                                          euribor6m.dayCounter()));
                }
                for (int i = 0; i < swaps; i++)
                {
                    Handle <Quote> r = new Handle <Quote>(rates[i + deposits]);
                    instruments.Add(new SwapRateHelper(r, new Period(swapData[i].n, swapData[i].units), calendar,
                                                       fixedLegFrequency, fixedLegConvention, fixedLegDayCounter, euribor6m));
                }

                Euribor3M euribor3m = new Euribor3M();

                for (int i = 0; i < fras; i++)
                {
                    Handle <Quote> r = new Handle <Quote>(fraRates[i]);
                    fraHelpers.Add(new FraRateHelper(r, fraData[i].n, fraData[i].n + 3,
                                                     euribor3m.fixingDays(),
                                                     euribor3m.fixingCalendar(),
                                                     euribor3m.businessDayConvention(),
                                                     euribor3m.endOfMonth(),
                                                     euribor3m.dayCounter()));
                }

                for (int i = 0; i < bonds; i++)
                {
                    Handle <Quote> p        = new Handle <Quote>(prices[i]);
                    Date           maturity = calendar.advance(today, bondData[i].n, bondData[i].units);
                    Date           issue    = calendar.advance(maturity, -bondData[i].length, TimeUnit.Years);
                    List <double>  coupons  = new List <double>()
                    {
                        bondData[i].coupon / 100.0
                    };
                    schedules.Add(new Schedule(issue, maturity, new Period(bondData[i].frequency), calendar,
                                               bondConvention, bondConvention, DateGeneration.Rule.Backward, false));
                    bondHelpers.Add(new FixedRateBondHelper(p, bondSettlementDays, bondRedemption, schedules[i],
                                                            coupons, bondDayCounter, bondConvention, bondRedemption, issue));
                }
            }
예제 #2
0
        public void testBootstrap()
        {
            // Testing Eonia-swap curve building...
            CommonVars vars = new CommonVars();

            List <RateHelper> eoniaHelpers  = new List <RateHelper>();
            List <RateHelper> swap3mHelpers = new List <RateHelper>();

            IborIndex euribor3m = new Euribor3M();
            Eonia     eonia     = new Eonia();

            for (int i = 0; i < depositData.Length; i++)
            {
                double         rate   = 0.01 * depositData[i].rate;
                SimpleQuote    simple = new SimpleQuote(rate);
                Handle <Quote> quote  = new Handle <Quote>(simple);

                Period     term   = new Period(depositData[i].n, depositData[i].unit);
                RateHelper helper = new DepositRateHelper(quote,
                                                          term,
                                                          depositData[i].settlementDays,
                                                          euribor3m.fixingCalendar(),
                                                          euribor3m.businessDayConvention(),
                                                          euribor3m.endOfMonth(),
                                                          euribor3m.dayCounter());


                if (term <= new Period(2, TimeUnit.Days))
                {
                    eoniaHelpers.Add(helper);
                }
                if (term <= new Period(3, TimeUnit.Months))
                {
                    swap3mHelpers.Add(helper);
                }
            }


            for (int i = 0; i < fraData.Length; i++)
            {
                double         rate   = 0.01 * fraData[i].rate;
                SimpleQuote    simple = new SimpleQuote(rate);
                Handle <Quote> quote  = new Handle <Quote>(simple);
                RateHelper     helper = new FraRateHelper(quote,
                                                          fraData[i].nExpiry,
                                                          fraData[i].nMaturity,
                                                          fraData[i].settlementDays,
                                                          euribor3m.fixingCalendar(),
                                                          euribor3m.businessDayConvention(),
                                                          euribor3m.endOfMonth(),
                                                          euribor3m.dayCounter());
                swap3mHelpers.Add(helper);
            }

            for (int i = 0; i < eoniaSwapData.Length; i++)
            {
                double         rate   = 0.01 * eoniaSwapData[i].rate;
                SimpleQuote    simple = new SimpleQuote(rate);
                Handle <Quote> quote  = new Handle <Quote>(simple);
                Period         term   = new Period(eoniaSwapData[i].n, eoniaSwapData[i].unit);
                RateHelper     helper = new OISRateHelper(eoniaSwapData[i].settlementDays,
                                                          term,
                                                          quote,
                                                          eonia);
                eoniaHelpers.Add(helper);
            }


            for (int i = 0; i < swapData.Length; i++)
            {
                double         rate   = 0.01 * swapData[i].rate;
                SimpleQuote    simple = new SimpleQuote(rate);
                Handle <Quote> quote  = new Handle <Quote>(simple);
                Period         tenor  = new Period(swapData[i].nIndexUnits, swapData[i].indexUnit);
                Period         term   = new Period(swapData[i].nTermUnits, swapData[i].termUnit);

                RateHelper helper = new SwapRateHelper(quote,
                                                       term,
                                                       vars.calendar,
                                                       vars.fixedSwapFrequency,
                                                       vars.fixedSwapConvention,
                                                       vars.fixedSwapDayCount,
                                                       euribor3m);
                if (tenor == new Period(3, TimeUnit.Months))
                {
                    swap3mHelpers.Add(helper);
                }
            }


            PiecewiseYieldCurve <Discount, LogLinear> eoniaTS = new PiecewiseYieldCurve <Discount, LogLinear>(vars.today,
                                                                                                              eoniaHelpers,
                                                                                                              new Actual365Fixed());

            PiecewiseYieldCurve <Discount, LogLinear> swapTS = new PiecewiseYieldCurve <Discount, LogLinear>(vars.today,
                                                                                                             swap3mHelpers,
                                                                                                             new Actual365Fixed());

            vars.eoniaTermStructure.linkTo(eoniaTS);

            // test curve consistency
            double tolerance = 1.0e-10;

            for (int i = 0; i < eoniaSwapData.Length; i++)
            {
                double expected           = eoniaSwapData[i].rate;
                Period term               = new Period(eoniaSwapData[i].n, eoniaSwapData[i].unit);
                OvernightIndexedSwap swap = vars.makeSwap(term, 0.0, 0.0);
                double?calculated         = 100.0 * swap.fairRate();

                if (Math.Abs(expected - calculated.Value) > tolerance)
                {
                    QAssert.Fail("curve inconsistency:\n"
                                 + "    swap length:     " + term + "\n"
                                 + "    quoted rate:     " + expected + "\n"
                                 + "    calculated rate: " + calculated);
                }
            }
        }
예제 #3
0
        static void Main()
        {
            DateTime timer = DateTime.Now;

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

            RelinkableHandle <YieldTermStructure> euriborTermStructure = new RelinkableHandle <YieldTermStructure>();
            IborIndex euribor3m = new Euribor3M(euriborTermStructure);

            Date todaysDate = new Date(23, Month.May, 2006);

            Settings.setEvaluationDate(todaysDate);

            Calendar calendar       = euribor3m.fixingCalendar();
            int      fixingDays     = euribor3m.fixingDays();
            Date     settlementDate = calendar.advance(todaysDate, fixingDays, TimeUnit.Days);

            Console.WriteLine("Today: " + todaysDate.DayOfWeek + ", " + todaysDate);
            Console.WriteLine("Settlement date: " + settlementDate.DayOfWeek + ", " + settlementDate);


            // 3 month term FRA quotes (index refers to monthsToStart)
            double[] threeMonthFraQuote = new double[10];

            threeMonthFraQuote[1] = 0.030;
            threeMonthFraQuote[2] = 0.031;
            threeMonthFraQuote[3] = 0.032;
            threeMonthFraQuote[6] = 0.033;
            threeMonthFraQuote[9] = 0.034;

            /********************
            ***    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.


            // FRAs
            SimpleQuote fra1x4Rate  = new SimpleQuote(threeMonthFraQuote[1]);
            SimpleQuote fra2x5Rate  = new SimpleQuote(threeMonthFraQuote[2]);
            SimpleQuote fra3x6Rate  = new SimpleQuote(threeMonthFraQuote[3]);
            SimpleQuote fra6x9Rate  = new SimpleQuote(threeMonthFraQuote[6]);
            SimpleQuote fra9x12Rate = new SimpleQuote(threeMonthFraQuote[9]);

            RelinkableHandle <Quote> h1x4  = new RelinkableHandle <Quote>();  h1x4.linkTo(fra1x4Rate);
            RelinkableHandle <Quote> h2x5  = new RelinkableHandle <Quote>();  h2x5.linkTo(fra2x5Rate);
            RelinkableHandle <Quote> h3x6  = new RelinkableHandle <Quote>();  h3x6.linkTo(fra3x6Rate);
            RelinkableHandle <Quote> h6x9  = new RelinkableHandle <Quote>();  h6x9.linkTo(fra6x9Rate);
            RelinkableHandle <Quote> h9x12 = new RelinkableHandle <Quote>(); h9x12.linkTo(fra9x12Rate);

            /*********************
            ***  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.

            DayCounter            fraDayCounter = euribor3m.dayCounter();
            BusinessDayConvention convention    = euribor3m.businessDayConvention();
            bool endOfMonth = euribor3m.endOfMonth();

            RateHelper fra1x4 = new FraRateHelper(h1x4, 1, 4,
                                                  fixingDays, calendar, convention,
                                                  endOfMonth, fraDayCounter);

            RateHelper fra2x5 = new FraRateHelper(h2x5, 2, 5,
                                                  fixingDays, calendar, convention,
                                                  endOfMonth, fraDayCounter);

            RateHelper fra3x6 = new FraRateHelper(h3x6, 3, 6,
                                                  fixingDays, calendar, convention,
                                                  endOfMonth, fraDayCounter);

            RateHelper fra6x9 = new FraRateHelper(h6x9, 6, 9,
                                                  fixingDays, calendar, convention,
                                                  endOfMonth, fraDayCounter);

            RateHelper fra9x12 = new FraRateHelper(h9x12, 9, 12,
                                                   fixingDays, calendar, convention,
                                                   endOfMonth, fraDayCounter);


            /*********************
            **  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 FRA curve
            List <RateHelper> fraInstruments = new List <RateHelper>();

            fraInstruments.Add(fra1x4);
            fraInstruments.Add(fra2x5);
            fraInstruments.Add(fra3x6);
            fraInstruments.Add(fra6x9);
            fraInstruments.Add(fra9x12);

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


            // Term structures used for pricing/discounting
            RelinkableHandle <YieldTermStructure> discountingTermStructure = new RelinkableHandle <YieldTermStructure>();

            discountingTermStructure.linkTo(fraTermStructure);


            /***********************
            ***  construct FRA's ***
            ***********************/

            Calendar fraCalendar = euribor3m.fixingCalendar();
            BusinessDayConvention fraBusinessDayConvention = euribor3m.businessDayConvention();

            Position.Type fraFwdType    = Position.Type.Long;
            double        fraNotional   = 100.0;
            const int     FraTermMonths = 3;

            int[] monthsToStart = new [] { 1, 2, 3, 6, 9 };

            euriborTermStructure.linkTo(fraTermStructure);

            Console.WriteLine("\nTest FRA construction, NPV calculation, and FRA purchase\n");

            int i;

            for (i = 0; i < monthsToStart.Length; i++)
            {
                Date fraValueDate = fraCalendar.advance(
                    settlementDate, monthsToStart[i], TimeUnit.Months,
                    fraBusinessDayConvention);

                Date fraMaturityDate = fraCalendar.advance(
                    fraValueDate, FraTermMonths, TimeUnit.Months,
                    fraBusinessDayConvention);

                double fraStrikeRate = threeMonthFraQuote[monthsToStart[i]];

                ForwardRateAgreement myFRA = new ForwardRateAgreement(fraValueDate, fraMaturityDate,
                                                                      fraFwdType, fraStrikeRate,
                                                                      fraNotional, euribor3m,
                                                                      discountingTermStructure);

                Console.WriteLine("3m Term FRA, Months to Start: " + monthsToStart[i]);

                Console.WriteLine("strike FRA rate: {0:0.00%}", fraStrikeRate);
                Console.WriteLine("FRA 3m forward rate: {0:0.00%}", myFRA.forwardRate());
                Console.WriteLine("FRA market quote: {0:0.00%}", threeMonthFraQuote[monthsToStart[i]]);
                Console.WriteLine("FRA spot value: " + myFRA.spotValue());
                Console.WriteLine("FRA forward value: " + myFRA.forwardValue());
                Console.WriteLine("FRA implied Yield: {0:0.00%}",
                                  myFRA.impliedYield(myFRA.spotValue(), myFRA.forwardValue(), settlementDate, Compounding.Simple, fraDayCounter));
                Console.WriteLine("market Zero Rate: {0:0.00%}",
                                  discountingTermStructure.link.zeroRate(fraMaturityDate, fraDayCounter, Compounding.Simple));
                Console.WriteLine("FRA NPV [should be zero]: {0}\n", myFRA.NPV());
            }



            Console.WriteLine("\n");
            Console.WriteLine("Now take a 100 basis-point upward shift in FRA quotes and examine NPV\n");


            const double BpsShift = 0.01;

            threeMonthFraQuote[1] = 0.030 + BpsShift;
            threeMonthFraQuote[2] = 0.031 + BpsShift;
            threeMonthFraQuote[3] = 0.032 + BpsShift;
            threeMonthFraQuote[6] = 0.033 + BpsShift;
            threeMonthFraQuote[9] = 0.034 + BpsShift;

            fra1x4Rate.setValue(threeMonthFraQuote[1]);
            fra2x5Rate.setValue(threeMonthFraQuote[2]);
            fra3x6Rate.setValue(threeMonthFraQuote[3]);
            fra6x9Rate.setValue(threeMonthFraQuote[6]);
            fra9x12Rate.setValue(threeMonthFraQuote[9]);


            for (i = 0; i < monthsToStart.Length; i++)
            {
                Date fraValueDate = fraCalendar.advance(
                    settlementDate, monthsToStart[i], TimeUnit.Months,
                    fraBusinessDayConvention);

                Date fraMaturityDate = fraCalendar.advance(
                    fraValueDate, FraTermMonths, TimeUnit.Months,
                    fraBusinessDayConvention);

                double fraStrikeRate = threeMonthFraQuote[monthsToStart[i]] - BpsShift;

                ForwardRateAgreement myFRA = new ForwardRateAgreement(fraValueDate, fraMaturityDate,
                                                                      fraFwdType, fraStrikeRate,
                                                                      fraNotional, euribor3m,
                                                                      discountingTermStructure);

                Console.WriteLine("3m Term FRA, 100 notional, Months to Start: " + monthsToStart[i]);
                Console.WriteLine("strike FRA rate: {0:0.00%}", fraStrikeRate);
                Console.WriteLine("FRA 3m forward rate: {0:0.00%}", myFRA.forwardRate());
                Console.WriteLine("FRA market quote: {0:0.00%}", threeMonthFraQuote[monthsToStart[i]]);
                Console.WriteLine("FRA spot value: " + myFRA.spotValue());
                Console.WriteLine("FRA forward value: " + myFRA.forwardValue());
                Console.WriteLine("FRA implied Yield: {0:0.00%}",
                                  myFRA.impliedYield(myFRA.spotValue(), myFRA.forwardValue(), settlementDate, Compounding.Simple, fraDayCounter));
                Console.WriteLine("market Zero Rate: {0:0.00%}",
                                  discountingTermStructure.link.zeroRate(fraMaturityDate, fraDayCounter, Compounding.Simple));
                Console.WriteLine("FRA NPV [should be positive]: {0}\n", myFRA.NPV());
            }

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

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