Esempio n. 1
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(BondFunctions obj) {
   return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
 }
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(BondFunctions obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }
Esempio n. 3
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;
            }
        }
Esempio n. 4
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();
            }
        }