Exemplo n.º 1
0
        static void Main(string[] args)
        {
            // boost::timer timer;

             Date today = new Date(16,Month.October,2007);
             Settings.setEvaluationDate(today);

             Console.WriteLine();
             Console.WriteLine("Pricing a callable fixed rate bond using");
             Console.WriteLine("Hull White model w/ reversion parameter = 0.03");
             Console.WriteLine("BAC4.65 09/15/12  ISIN: US06060WBJ36");
             Console.WriteLine("roughly five year tenor, ");
             Console.WriteLine("quarterly coupon and call dates");
             Console.WriteLine("reference date is : " + today );

             /* Bloomberg OAS1: "N" model (Hull White)
               varying volatility parameter

               The curve entered into Bloomberg OAS1 is a flat curve,
               at constant yield = 5.5%, semiannual compounding.
               Assume here OAS1 curve uses an ACT/ACT day counter,
               as documented in PFC1 as a "default" in the latter case.
             */

             // set up a flat curve corresponding to Bloomberg flat curve

             double bbCurveRate = 0.055;
             DayCounter bbDayCounter = new ActualActual(ActualActual.Convention.Bond);
             InterestRate bbIR = new InterestRate(bbCurveRate,bbDayCounter,Compounding.Compounded ,Frequency.Semiannual);

             Handle<YieldTermStructure> termStructure = new Handle<YieldTermStructure>(flatRate( today,
                                                              bbIR.rate(),
                                                              bbIR.dayCounter(),
                                                              bbIR.compounding(),
                                                              bbIR.frequency()));
             // set up the call schedule

             CallabilitySchedule callSchedule = new CallabilitySchedule();
             double callPrice = 100.0;
             int numberOfCallDates = 24;
             Date callDate = new Date(15,Month.September,2006);

             for (int i=0; i< numberOfCallDates; i++)
             {
            Calendar nullCalendar = new NullCalendar();

            Callability.Price myPrice = new Callability.Price(callPrice, Callability.Price.Type.Clean);
            callSchedule.Add( new Callability(myPrice,Callability.Type.Call, callDate ));
            callDate = nullCalendar.advance(callDate, 3, TimeUnit.Months);
             }

             // set up the callable bond

             Date dated = new Date(16,Month.September,2004);
             Date issue = dated;
             Date maturity = new Date(15,Month.September,2012);
             int settlementDays = 3;  // Bloomberg OAS1 settle is Oct 19, 2007
             Calendar bondCalendar = new UnitedStates(UnitedStates.Market.GovernmentBond);
             double coupon = .0465;
             Frequency frequency = Frequency.Quarterly;
             double redemption = 100.0;
             double faceAmount = 100.0;

             /* The 30/360 day counter Bloomberg uses for this bond cannot
            reproduce the US Bond/ISMA (constant) cashflows used in PFC1.
            Therefore use ActAct(Bond)
             */
             DayCounter bondDayCounter = new ActualActual(ActualActual.Convention.Bond);

             // PFC1 shows no indication dates are being adjusted
             // for weekends/holidays for vanilla bonds
             BusinessDayConvention accrualConvention = BusinessDayConvention.Unadjusted;
             BusinessDayConvention paymentConvention = BusinessDayConvention.Unadjusted;

             Schedule sch = new Schedule( dated, maturity, new Period(frequency), bondCalendar,
                                      accrualConvention, accrualConvention,
                                      DateGeneration.Rule.Backward, false);

             int maxIterations = 1000;
             double accuracy = 1e-8;
             int gridIntervals = 40;
             double reversionParameter = .03;

             // output price/yield results for varying volatility parameter

             double sigma = Const.QL_Epsilon; // core dumps if zero on Cygwin

             ShortRateModel hw0 = new HullWhite(termStructure,reversionParameter,sigma);

             IPricingEngine engine0 = new TreeCallableFixedRateBondEngine(hw0, gridIntervals, termStructure);

             CallableFixedRateBond callableBond = new CallableFixedRateBond( settlementDays, faceAmount, sch,
                                                                         new InitializedList<double>(1, coupon),
                                                                         bondDayCounter, paymentConvention,
                                                                         redemption, issue, callSchedule);
             callableBond.setPricingEngine(engine0);

             Console.WriteLine("sigma/vol (%) = {0:0.00}", (100.0 * sigma));

             Console.WriteLine("QuantLib price/yld (%)  ");
             Console.WriteLine(  "{0:0.00} / {1:0.00} ", callableBond.cleanPrice() ,
                                                     100.0 * callableBond.yield(bondDayCounter,
                                                                                Compounding.Compounded,
                                                                                frequency,
                                                                                accuracy,
                                                                                maxIterations));
             Console.WriteLine("Bloomberg price/yld (%) ");
             Console.WriteLine("96.50 / 5.47");

             //

             sigma = .01;

             Console.WriteLine("sigma/vol (%) = {0:0.00}", (100.0 * sigma));

             ShortRateModel hw1 = new HullWhite(termStructure,reversionParameter,sigma);

             IPricingEngine engine1 = new TreeCallableFixedRateBondEngine(hw1,gridIntervals,termStructure);

             callableBond.setPricingEngine(engine1);

             Console.WriteLine("QuantLib price/yld (%)  ");
             Console.WriteLine(  "{0:0.00} / {1:0.00} ", callableBond.cleanPrice() ,
                                                     100.0 * callableBond.yield(bondDayCounter,
                                                                                Compounding.Compounded,
                                                                                frequency,
                                                                                accuracy,
                                                                                maxIterations));

             Console.WriteLine("Bloomberg price/yld (%) ");
             Console.WriteLine("95.68 / 5.66");

             //

             sigma = .03;

             Console.WriteLine("sigma/vol (%) = {0:0.00}", (100.0 * sigma));

             ShortRateModel hw2 = new HullWhite(termStructure, reversionParameter, sigma);

             IPricingEngine engine2 = new TreeCallableFixedRateBondEngine(hw2, gridIntervals, termStructure);

             callableBond.setPricingEngine(engine2);

             Console.WriteLine("QuantLib price/yld (%)  ");
             Console.WriteLine("{0:0.00} / {1:0.00} ", callableBond.cleanPrice(),
                                                     100.0 * callableBond.yield(bondDayCounter,
                                                                                Compounding.Compounded,
                                                                                frequency,
                                                                                accuracy,
                                                                                maxIterations));

             Console.WriteLine("Bloomberg price/yld (%) ");
             Console.WriteLine("92.34 / 6.49");

             //

             sigma = .06;

             Console.WriteLine("sigma/vol (%) = {0:0.00}", (100.0 * sigma));

             ShortRateModel hw3 = new HullWhite(termStructure, reversionParameter, sigma);

             IPricingEngine engine3 = new TreeCallableFixedRateBondEngine(hw3, gridIntervals, termStructure);

             callableBond.setPricingEngine(engine3);

             Console.WriteLine("QuantLib price/yld (%)  ");
             Console.WriteLine("{0:0.00} / {1:0.00} ", callableBond.cleanPrice(),
                                                     100.0 * callableBond.yield(bondDayCounter,
                                                                                Compounding.Compounded,
                                                                                frequency,
                                                                                accuracy,
                                                                                maxIterations));

             Console.WriteLine("Bloomberg price/yld (%) ");
             Console.WriteLine("87.16 / 7.83");

             //

             sigma = .12;

             Console.WriteLine("sigma/vol (%) = {0:0.00}", (100.0 * sigma));

             ShortRateModel hw4 = new HullWhite(termStructure, reversionParameter, sigma);

             IPricingEngine engine4 = new TreeCallableFixedRateBondEngine(hw4, gridIntervals, termStructure);

             callableBond.setPricingEngine(engine4);

             Console.WriteLine("QuantLib price/yld (%)  ");
             Console.WriteLine("{0:0.00} / {1:0.00} ", callableBond.cleanPrice(),
                                                     100.0 * callableBond.yield(bondDayCounter,
                                                                                Compounding.Compounded,
                                                                                frequency,
                                                                                accuracy,
                                                                                maxIterations));

             Console.WriteLine("Bloomberg price/yld (%) ");
             Console.WriteLine("77.31 / 10.65");
        }