public static Greeks GetOptionOnFutureGreeks(double underlyingPrice, double strike, double riskFreeRate,
                                                     DateTime expirationDate, DateTime calculationDate, string optionType, string exerciseType,
                                                     double optionPrice = double.NaN, double impliedVol = 0.15, string engineName = "baw")
        {
            QLNet.Date ExpirationDateObj  = new QLNet.Date(expirationDate.Day, expirationDate.Month, expirationDate.Year);
            QLNet.Date CalculationDateObj = new QLNet.Date(calculationDate.Day, calculationDate.Month, calculationDate.Year);

            QLNet.DayCounter DayCountObj = new QLNet.Actual365Fixed();
            QLNet.Calendar   CalendarObj = new QLNet.UnitedStates();

            Greeks GreeksOutput = new Greeks();

            QLNet.Option.Type OptionTypeObj;
            QLNet.Exercise    ExerciseObj;
            double            ImpliedVol;
            double            OptionPrice;

            int CalDte = DayCountObj.dayCount(CalculationDateObj, ExpirationDateObj);

            GreeksOutput.CalDte = CalDte;

            if (!double.IsNaN(optionPrice))
            {
                if (optionType.ToUpper() == "C")
                {
                    if (optionPrice + strike - underlyingPrice <= 1.0e-12)
                    {
                        GreeksOutput.Delta = 1;
                        return(GreeksOutput);
                    }
                }
                else if (optionType.ToUpper() == "P")
                {
                    if (optionPrice - strike + underlyingPrice <= 1.0e-12)
                    {
                        GreeksOutput.Delta = -1;
                        return(GreeksOutput);
                    }
                }
            }

            if (CalDte == 0)
            {
                if (optionType.ToUpper() == "C")
                {
                    if (strike <= underlyingPrice)
                    {
                        GreeksOutput.Delta = 1;
                    }
                    else
                    {
                        GreeksOutput.Delta = 0;
                    }
                }
                else if (optionType.ToUpper() == "P")
                {
                    if (strike >= underlyingPrice)
                    {
                        GreeksOutput.Delta = -1;
                    }
                    else
                    {
                        GreeksOutput.Delta = 0;
                    }
                }
                return(GreeksOutput);
            }

            if (optionType.ToUpper() == "C")
            {
                OptionTypeObj = QLNet.Option.Type.Call;
            }
            else if (optionType.ToUpper() == "P")
            {
                OptionTypeObj = QLNet.Option.Type.Put;
            }
            else
            {
                return(GreeksOutput);
            }

            if (exerciseType.ToUpper() == "E")
            {
                ExerciseObj = new QLNet.EuropeanExercise(ExpirationDateObj);
            }
            else if (exerciseType.ToUpper() == "A")
            {
                ExerciseObj = new QLNet.AmericanExercise(CalculationDateObj, ExpirationDateObj);
            }
            else
            {
                return(GreeksOutput);
            }

            QLNet.Settings.setEvaluationDate(CalculationDateObj);

            QLNet.Handle <Quote> UnderlyingObj = new QLNet.Handle <Quote>(new QLNet.SimpleQuote(underlyingPrice));
            QLNet.Handle <YieldTermStructure>    FlatRateObj  = new QLNet.Handle <YieldTermStructure>(new QLNet.FlatForward(CalculationDateObj, riskFreeRate, DayCountObj));
            QLNet.Handle <BlackVolTermStructure> FlatVolTsObj = new QLNet.Handle <BlackVolTermStructure>(new QLNet.BlackConstantVol(CalculationDateObj, CalendarObj, impliedVol, DayCountObj));

            QLNet.BlackProcess       BlackProc = new QLNet.BlackProcess(UnderlyingObj, FlatRateObj, FlatVolTsObj);
            QLNet.PlainVanillaPayoff PayoffObj = new QLNet.PlainVanillaPayoff(OptionTypeObj, strike);

            QLNet.VanillaOption OptionObj = new QLNet.VanillaOption(PayoffObj, ExerciseObj);

            if (engineName == "baw")
            {
                OptionObj.setPricingEngine(new QLNet.BaroneAdesiWhaleyApproximationEngine(BlackProc));
            }
            else if (engineName == "fda")
            {
                OptionObj.setPricingEngine(new QLNet.FDAmericanEngine(BlackProc, 100, 100));
            }
            else
            {
                return(GreeksOutput);
            }


            if (!double.IsNaN(optionPrice))
            {
                try
                {
                    ImpliedVol = OptionObj.impliedVolatility(targetValue: optionPrice, process: BlackProc, accuracy: 1e-5);
                }
                catch
                {
                    return(GreeksOutput);
                }

                FlatVolTsObj = new QLNet.Handle <BlackVolTermStructure>(new QLNet.BlackConstantVol(CalculationDateObj, CalendarObj, ImpliedVol, DayCountObj));
                BlackProc    = new QLNet.BlackProcess(UnderlyingObj, FlatRateObj, FlatVolTsObj);

                if (engineName == "baw")
                {
                    OptionObj.setPricingEngine(new QLNet.BaroneAdesiWhaleyApproximationEngine(BlackProc));
                }
                else if (engineName == "fda")
                {
                    OptionObj.setPricingEngine(new QLNet.FDAmericanEngine(BlackProc, 100, 100));
                }
                OptionPrice = optionPrice;
            }
            else
            {
                OptionPrice = OptionObj.NPV();
                ImpliedVol  = impliedVol;
            }

            OptionObj = new QLNet.VanillaOption(PayoffObj, new QLNet.EuropeanExercise(ExpirationDateObj));
            OptionObj.setPricingEngine(new QLNet.AnalyticEuropeanEngine(BlackProc));

            GreeksOutput.Delta       = OptionObj.delta();
            GreeksOutput.Vega        = OptionObj.vega();
            GreeksOutput.Theta       = OptionObj.thetaPerDay();
            GreeksOutput.Gamma       = OptionObj.gamma();
            GreeksOutput.OptionPrice = OptionPrice;
            GreeksOutput.ImpliedVol  = ImpliedVol;

            return(GreeksOutput);
        }
Example #2
0
        public void testUSNewYorkStockExchange()
        {
            List<Date> expectedHol = new List<Date>();
            expectedHol.Add(new Date(1, Month.January, 2004));
            expectedHol.Add(new Date(19, Month.January, 2004));
            expectedHol.Add(new Date(16, Month.February, 2004));
            expectedHol.Add(new Date(9, Month.April, 2004));
            expectedHol.Add(new Date(31, Month.May, 2004));
            expectedHol.Add(new Date(11, Month.June, 2004));
            expectedHol.Add(new Date(5, Month.July, 2004));
            expectedHol.Add(new Date(6, Month.September, 2004));
            expectedHol.Add(new Date(25, Month.November, 2004));
            expectedHol.Add(new Date(24, Month.December, 2004));

            expectedHol.Add(new Date(17, Month.January, 2005));
            expectedHol.Add(new Date(21, Month.February, 2005));
            expectedHol.Add(new Date(25, Month.March, 2005));
            expectedHol.Add(new Date(30, Month.May, 2005));
            expectedHol.Add(new Date(4, Month.July, 2005));
            expectedHol.Add(new Date(5, Month.September, 2005));
            expectedHol.Add(new Date(24, Month.November, 2005));
            expectedHol.Add(new Date(26, Month.December, 2005));

            expectedHol.Add(new Date(2, Month.January, 2006));
            expectedHol.Add(new Date(16, Month.January, 2006));
            expectedHol.Add(new Date(20, Month.February, 2006));
            expectedHol.Add(new Date(14, Month.April, 2006));
            expectedHol.Add(new Date(29, Month.May, 2006));
            expectedHol.Add(new Date(4, Month.July, 2006));
            expectedHol.Add(new Date(4, Month.September, 2006));
            expectedHol.Add(new Date(23, Month.November, 2006));
            expectedHol.Add(new Date(25, Month.December, 2006));

            Calendar c = new UnitedStates(UnitedStates.Market.NYSE);
            List<Date> hol = Calendar.holidayList(c, new Date(1, Month.January, 2004), new Date(31, Month.December, 2006));

            int i;
            for (i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) {
                if (hol[i] != expectedHol[i])
                    Assert.Fail("expected holiday was " + expectedHol[i] + " while calculated holiday is " + hol[i]);
            }
            if (hol.Count != expectedHol.Count)
                Assert.Fail("there were " + expectedHol.Count +
                            " expected holidays, while there are " + hol.Count +
                            " calculated holidays");

            List<Date> histClose = new List<Date>();
            histClose.Add(new Date(11, Month.June, 2004));     // Reagan's funeral
            histClose.Add(new Date(14, Month.September, 2001));// September 11, 2001
            histClose.Add(new Date(13, Month.September, 2001));// September 11, 2001
            histClose.Add(new Date(12, Month.September, 2001));// September 11, 2001
            histClose.Add(new Date(11, Month.September, 2001));// September 11, 2001
            histClose.Add(new Date(14, Month.July, 1977));     // 1977 Blackout
            histClose.Add(new Date(25, Month.January, 1973));  // Johnson's funeral.
            histClose.Add(new Date(28, Month.December, 1972)); // Truman's funeral
            histClose.Add(new Date(21, Month.July, 1969));     // Lunar exploration nat. day
            histClose.Add(new Date(31, Month.March, 1969));    // Eisenhower's funeral
            histClose.Add(new Date(10, Month.February, 1969)); // heavy snow
            histClose.Add(new Date(5, Month.July, 1968));      // Day after Independence Day
            // June 12-Dec. 31, 1968
            // Four day week (closed on Wednesdays) - Paperwork Crisis
            histClose.Add(new Date(12, Month.Jun, 1968));
            histClose.Add(new Date(19, Month.Jun, 1968));
            histClose.Add(new Date(26, Month.Jun, 1968));
            histClose.Add(new Date(3, Month.Jul, 1968));
            histClose.Add(new Date(10, Month.Jul, 1968));
            histClose.Add(new Date(17, Month.Jul, 1968));
            histClose.Add(new Date(20, Month.Nov, 1968));
            histClose.Add(new Date(27, Month.Nov, 1968));
            histClose.Add(new Date(4, Month.Dec, 1968));
            histClose.Add(new Date(11, Month.Dec, 1968));
            histClose.Add(new Date(18, Month.Dec, 1968));
            // Presidential election days
            histClose.Add(new Date(4, Month.Nov, 1980));
            histClose.Add(new Date(2, Month.Nov, 1976));
            histClose.Add(new Date(7, Month.Nov, 1972));
            histClose.Add(new Date(5, Month.Nov, 1968));
            histClose.Add(new Date(3, Month.Nov, 1964));

            for (i = 0; i < histClose.Count; i++) {
                if (!c.isHoliday(histClose[i]))
                    Assert.Fail(histClose[i] + " should be holiday (historical close)");
            }
        }
Example #3
0
        public void testUSGovernmentBondMarket()
        {
            List<Date> expectedHol = new List<Date>();
            expectedHol.Add(new Date(1, Month.January, 2004));
            expectedHol.Add(new Date(19, Month.January, 2004));
            expectedHol.Add(new Date(16, Month.February, 2004));
            expectedHol.Add(new Date(9, Month.April, 2004));
            expectedHol.Add(new Date(31, Month.May, 2004));
            expectedHol.Add(new Date(5, Month.July, 2004));
            expectedHol.Add(new Date(6, Month.September, 2004));
            expectedHol.Add(new Date(11, Month.October, 2004));
            expectedHol.Add(new Date(11, Month.November, 2004));
            expectedHol.Add(new Date(25, Month.November, 2004));
            expectedHol.Add(new Date(24, Month.December, 2004));

            Calendar c = new UnitedStates(UnitedStates.Market.GovernmentBond);
            List<Date> hol = Calendar.holidayList(c, new Date(1, Month.January, 2004), new Date(31, Month.December, 2004));

            for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) {
                if (hol[i] != expectedHol[i])
                    Assert.Fail("expected holiday was " + expectedHol[i] + " while calculated holiday is " + hol[i]);
            }
            if (hol.Count != expectedHol.Count)
                Assert.Fail("there were " + expectedHol.Count +
                            " expected holidays, while there are " + hol.Count +
                            " calculated holidays");
        }
Example #4
0
        public void testModifiedCalendars()
        {
            Calendar c1 = new TARGET();
            Calendar c2 = new UnitedStates(UnitedStates.Market.NYSE);
            Date d1 = new Date(1, Month.May, 2004);      // holiday for both calendars
            Date d2 = new Date(26, Month.April, 2004);   // business day

            Assert.IsTrue(c1.isHoliday(d1), "wrong assumption---correct the test");
            Assert.IsTrue(c1.isBusinessDay(d2), "wrong assumption---correct the test");

            Assert.IsTrue(c2.isHoliday(d1), "wrong assumption---correct the test");
            Assert.IsTrue(c2.isBusinessDay(d2), "wrong assumption---correct the test");

            // modify the TARGET calendar
            c1.removeHoliday(d1);
            c1.addHoliday(d2);

            // test
            Assert.IsFalse(c1.isHoliday(d1), d1 + " still a holiday for original TARGET instance");
            Assert.IsFalse(c1.isBusinessDay(d2), d2 + " still a business day for original TARGET instance");

            // any instance of TARGET should be modified...
            Calendar c3 = new TARGET();
            Assert.IsFalse(c3.isHoliday(d1), d1 + " still a holiday for generic TARGET instance");
            Assert.IsFalse(c3.isBusinessDay(d2), d2 + " still a business day for generic TARGET instance");

            // ...but not other calendars
            Assert.IsFalse(c2.isBusinessDay(d1), d1 + " business day for New York");
            Assert.IsFalse(c2.isHoliday(d2), d2 + " holiday for New York");

            // restore original holiday set---test the other way around
            c3.addHoliday(d1);
            c3.removeHoliday(d2);

            Assert.IsFalse(c1.isBusinessDay(d1), d1 + " still a business day");
            Assert.IsFalse(c1.isHoliday(d2), d2 + " still a holiday");
        }
Example #5
0
        public void testJointCalendars()
        {
            Calendar c1 = new TARGET(),
                     c2 = new UnitedKingdom(),
                     c3 = new UnitedStates(UnitedStates.Market.NYSE),
                     c4 = new Japan();

            Calendar c12h = new JointCalendar(c1, c2, JointCalendar.JointCalendarRule.JoinHolidays),
                     c12b = new JointCalendar(c1,c2,JointCalendar.JointCalendarRule.JoinBusinessDays),
                     c123h = new JointCalendar(c1,c2,c3,JointCalendar.JointCalendarRule.JoinHolidays),
                     c123b = new JointCalendar(c1,c2,c3,JointCalendar.JointCalendarRule.JoinBusinessDays),
                     c1234h = new JointCalendar(c1,c2,c3,c4,JointCalendar.JointCalendarRule.JoinHolidays),
                     c1234b = new JointCalendar(c1,c2,c3,c4,JointCalendar.JointCalendarRule.JoinBusinessDays);

            // test one year, starting today
            Date firstDate = Date.Today,
                 endDate = firstDate + new Period(1, TimeUnit.Years);

            for (Date d = firstDate; d < endDate; d++) {

                bool b1 = c1.isBusinessDay(d),
                     b2 = c2.isBusinessDay(d),
                     b3 = c3.isBusinessDay(d),
                     b4 = c4.isBusinessDay(d);

                if ((b1 && b2) != c12h.isBusinessDay(d))
                    Assert.Fail("At date " + d + ":\n"
                               + "    inconsistency between joint calendar "
                               + c12h.name() + " (joining holidays)\n"
                               + "    and its components");

                if ((b1 || b2) != c12b.isBusinessDay(d))
                    Assert.Fail("At date " + d + ":\n"
                               + "    inconsistency between joint calendar "
                               + c12b.name() + " (joining business days)\n"
                               + "    and its components");

                if ((b1 && b2 && b3) != c123h.isBusinessDay(d))
                    Assert.Fail("At date " + d + ":\n"
                               + "    inconsistency between joint calendar "
                               + c123h.name() + " (joining holidays)\n"
                               + "    and its components");

                if ((b1 || b2 || b3) != c123b.isBusinessDay(d))
                    Assert.Fail("At date " + d + ":\n"
                               + "    inconsistency between joint calendar "
                               + c123b.name() + " (joining business days)\n"
                               + "    and its components");

                if ((b1 && b2 && b3 && b4) != c1234h.isBusinessDay(d))
                    Assert.Fail("At date " + d + ":\n"
                               + "    inconsistency between joint calendar "
                               + c1234h.name() + " (joining holidays)\n"
                               + "    and its components");

                if ((b1 || b2 || b3 || b4) != c1234b.isBusinessDay(d))
                    Assert.Fail("At date " + d + ":\n"
                               + "    inconsistency between joint calendar "
                               + c1234b.name() + " (joining business days)\n"
                               + "    and its components");

            }
        }
Example #6
0
        public void testUSSettlement()
        {
            Debug.Print("Testing US settlement holiday list...");
            List<Date> expectedHol = new List<Date>();

            expectedHol.Add(new Date(1, Month.January, 2004));
            expectedHol.Add(new Date(19, Month.January, 2004));
            expectedHol.Add(new Date(16, Month.February, 2004));
            expectedHol.Add(new Date(31, Month.May, 2004));
            expectedHol.Add(new Date(5, Month.July, 2004));
            expectedHol.Add(new Date(6, Month.September, 2004));
            expectedHol.Add(new Date(11, Month.October, 2004));
            expectedHol.Add(new Date(11, Month.November, 2004));
            expectedHol.Add(new Date(25, Month.November, 2004));
            expectedHol.Add(new Date(24, Month.December, 2004));

            expectedHol.Add(new Date(31, Month.December, 2004));
            expectedHol.Add(new Date(17, Month.January, 2005));
            expectedHol.Add(new Date(21, Month.February, 2005));
            expectedHol.Add(new Date(30, Month.May, 2005));
            expectedHol.Add(new Date(4, Month.July, 2005));
            expectedHol.Add(new Date(5, Month.September, 2005));
            expectedHol.Add(new Date(10, Month.October, 2005));
            expectedHol.Add(new Date(11, Month.November, 2005));
            expectedHol.Add(new Date(24, Month.November, 2005));
            expectedHol.Add(new Date(26, Month.December, 2005));

            Calendar c = new UnitedStates(UnitedStates.Market.Settlement);
            List<Date> hol = Calendar.holidayList(c, new Date(1, Month.January, 2004),
                                                     new Date(31, Month.December, 2005));

            for (int i = 0; i < Math.Min(hol.Count, expectedHol.Count); i++) {
                if (hol[i] != expectedHol[i])
                    Assert.Fail("expected holiday was " + expectedHol[i] + " while calculated holiday is " + hol[i]);
            }

            if (hol.Count != expectedHol.Count)
                Assert.Fail("there were " + expectedHol.Count +
                             " expected holidays, while there are " + hol.Count +
                             " calculated holidays");
        }
Example #7
0
        public void testCachedMarketValue()
        {
            // Testing credit-default swap against cached market values...

            SavedSettings backup = new SavedSettings();

            Settings.setEvaluationDate(new Date(9,Month.June,2006));
            Date evalDate = Settings.evaluationDate();
            Calendar calendar = new UnitedStates();

            List<Date> discountDates = new List<Date>();
            discountDates.Add(evalDate);
            discountDates.Add(calendar.advance(evalDate, 1, TimeUnit.Weeks,  BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 1, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 2, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 3, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 6, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate,12, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 2, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 3, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 4, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 5, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 6, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 7, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 8, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 9, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate,10, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate,15, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));

            List<double> dfs = new List<double>();
            dfs.Add(1.0);
            dfs.Add(0.9990151375768731);
            dfs.Add(0.99570502636871183);
            dfs.Add(0.99118260474528685);
            dfs.Add(0.98661167950906203);
            dfs.Add(0.9732592953359388 );
            dfs.Add(0.94724424481038083);
            dfs.Add(0.89844996737120875 );
            dfs.Add(0.85216647839921411 );
            dfs.Add(0.80775477692556874 );
            dfs.Add(0.76517289234200347 );
            dfs.Add(0.72401019553182933 );
            dfs.Add(0.68503909569219212 );
            dfs.Add(0.64797499814013748 );
            dfs.Add(0.61263171936255534 );
            dfs.Add(0.5791942350748791  );
            dfs.Add(0.43518868769953606 );

            DayCounter curveDayCounter = new Actual360();

            RelinkableHandle<YieldTermStructure> discountCurve = new RelinkableHandle<YieldTermStructure>();
            discountCurve.linkTo( new InterpolatedDiscountCurve<LogLinear>( discountDates, dfs, curveDayCounter,null,null,null,new LogLinear() ) );

            DayCounter dayCounter = new Thirty360();
            List<Date> dates = new List<Date>();
            dates.Add(evalDate);
            dates.Add(calendar.advance(evalDate, 6, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
            dates.Add(calendar.advance(evalDate, 1, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            dates.Add(calendar.advance(evalDate, 2, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            dates.Add(calendar.advance(evalDate, 3, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            dates.Add(calendar.advance(evalDate, 4, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            dates.Add(calendar.advance(evalDate, 5, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            dates.Add(calendar.advance(evalDate, 7, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            dates.Add(calendar.advance(evalDate,10, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));

            List<double> defaultProbabilities = new List<double>();
            defaultProbabilities.Add(0.0000);
            defaultProbabilities.Add(0.0047);
            defaultProbabilities.Add(0.0093);
            defaultProbabilities.Add(0.0286);
            defaultProbabilities.Add(0.0619);
            defaultProbabilities.Add(0.0953);
            defaultProbabilities.Add(0.1508);
            defaultProbabilities.Add(0.2288);
            defaultProbabilities.Add(0.3666);

            List<double> hazardRates = new List<double>();
            hazardRates.Add(0.0);
            for (int i=1; i<dates.Count; ++i)
            {
                double t1 = dayCounter.yearFraction(dates[0], dates[i-1]);
                double t2 = dayCounter.yearFraction(dates[0], dates[i]);
                double S1 = 1.0 - defaultProbabilities[i-1];
                double S2 = 1.0 - defaultProbabilities[i];
                hazardRates.Add(Math.Log(S1/S2)/(t2-t1));
            }

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

            // Testing credit default swap

            // Build the schedule
            Date issueDate = new Date(20, Month.March, 2006);
            Date maturity = new Date(20, Month.June, 2013);
            Frequency cdsFrequency = Frequency.Semiannual;
            BusinessDayConvention cdsConvention = BusinessDayConvention.ModifiedFollowing;

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

            // Build the CDS
            double recoveryRate = 0.25;
            double fixedRate=0.0224;
            DayCounter dayCount= new Actual360();
            double cdsNotional=100.0;

            CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, cdsNotional, fixedRate,
                                        schedule, cdsConvention, dayCount, true, true);
            cds.setPricingEngine(new MidPointCdsEngine(piecewiseFlatHazardRate, recoveryRate,discountCurve));

            double calculatedNpv = cds.NPV();
            double calculatedFairRate = cds.fairSpread();

            double npv = -1.364048777;        // from Bloomberg we have 98.15598868 - 100.00;
            double fairRate =  0.0248429452; // from Bloomberg we have 0.0258378;

            double tolerance = 1e-9;

            if (Math.Abs(npv - calculatedNpv) > tolerance)
                Assert.Fail(
                    "Failed to reproduce the npv for the given credit-default swap\n"
                    + "    computed NPV:  " + calculatedNpv + "\n"
                    + "    Given NPV:     " + npv);

            if ( Math.Abs( fairRate - calculatedFairRate ) > tolerance )
                Assert.Fail( "Failed to reproduce the fair rate for the given credit-default swap\n"
                    + "    computed fair rate:  " + calculatedFairRate + "\n"
                    + "    Given fair rate:     " + fairRate );
        }
        public static Greeks GetOptionOnFutureGreeks(double underlyingPrice,double strike,double riskFreeRate, 
            DateTime expirationDate, DateTime calculationDate, string optionType, string exerciseType,
            double optionPrice=double.NaN,double impliedVol=0.15,string engineName="baw")
        {
            QLNet.Date ExpirationDateObj = new QLNet.Date(expirationDate.Day, expirationDate.Month, expirationDate.Year);
            QLNet.Date CalculationDateObj = new QLNet.Date(calculationDate.Day, calculationDate.Month, calculationDate.Year);

            QLNet.DayCounter DayCountObj = new QLNet.Actual365Fixed();
            QLNet.Calendar CalendarObj = new QLNet.UnitedStates();

            Greeks GreeksOutput = new Greeks();
            QLNet.Option.Type OptionTypeObj;
            QLNet.Exercise ExerciseObj;
            double ImpliedVol;
            double OptionPrice;

            int CalDte = DayCountObj.dayCount(CalculationDateObj, ExpirationDateObj);
            GreeksOutput.CalDte = CalDte;

            if (!double.IsNaN(optionPrice))
            {
                if (optionType.ToUpper() == "C")
                {
                    if (optionPrice + strike - underlyingPrice <= 1.0e-12)
                    {
                        GreeksOutput.Delta = 1;
                        return GreeksOutput;
                    }
                }
                else if (optionType.ToUpper() == "P")
                {
                    if (optionPrice - strike + underlyingPrice <= 1.0e-12)
                    {
                        GreeksOutput.Delta = -1;
                        return GreeksOutput;
                    }
                }
            }

            if (CalDte == 0)
            {
                if (optionType.ToUpper() == "C")
                {
                    if (strike <= underlyingPrice)
                    {
                        GreeksOutput.Delta = 1;
                    }
                    else
                    {
                        GreeksOutput.Delta = 0;
                    }
                }
                else if (optionType.ToUpper() == "P")
                {
                    if (strike >= underlyingPrice)
                    {
                        GreeksOutput.Delta = -1;
                    }
                    else
                    {
                        GreeksOutput.Delta = 0;
                    }
                }
                return GreeksOutput;
            }

            if (optionType.ToUpper() == "C")
            {
                OptionTypeObj = QLNet.Option.Type.Call;
            }
            else if (optionType.ToUpper() == "P")
            {
                OptionTypeObj = QLNet.Option.Type.Put;
            }
            else
            {
                return GreeksOutput;
            }

            if (exerciseType.ToUpper() == "E")
            {
                ExerciseObj = new QLNet.EuropeanExercise(ExpirationDateObj);
            }
            else if (exerciseType.ToUpper() == "A")
            {
                ExerciseObj = new QLNet.AmericanExercise(CalculationDateObj, ExpirationDateObj);
            }
            else
            {
                return GreeksOutput;
            }

            QLNet.Settings.setEvaluationDate(CalculationDateObj);

            QLNet.Handle<Quote> UnderlyingObj = new QLNet.Handle<Quote>(new QLNet.SimpleQuote(underlyingPrice));
            QLNet.Handle<YieldTermStructure> FlatRateObj = new QLNet.Handle<YieldTermStructure>(new QLNet.FlatForward(CalculationDateObj, riskFreeRate, DayCountObj));
            QLNet.Handle<BlackVolTermStructure> FlatVolTsObj = new QLNet.Handle<BlackVolTermStructure>(new QLNet.BlackConstantVol(CalculationDateObj, CalendarObj, impliedVol, DayCountObj));

            QLNet.BlackProcess BlackProc = new QLNet.BlackProcess(UnderlyingObj, FlatRateObj, FlatVolTsObj);
            QLNet.PlainVanillaPayoff PayoffObj = new QLNet.PlainVanillaPayoff(OptionTypeObj, strike);

            QLNet.VanillaOption OptionObj = new QLNet.VanillaOption(PayoffObj, ExerciseObj);

            if (engineName == "baw")
            {
                OptionObj.setPricingEngine(new QLNet.BaroneAdesiWhaleyApproximationEngine(BlackProc));
            }
            else if (engineName == "fda")
            {
                OptionObj.setPricingEngine(new QLNet.FDAmericanEngine(BlackProc, 100, 100));
            }
            else
            {
                return GreeksOutput;
            }


            if (!double.IsNaN(optionPrice))
            {
                try
                {

                    ImpliedVol = OptionObj.impliedVolatility(targetValue:optionPrice, process:BlackProc,accuracy:1e-5);
                }
                catch
                {
                    return GreeksOutput;
                }
                
                FlatVolTsObj = new QLNet.Handle<BlackVolTermStructure>(new QLNet.BlackConstantVol(CalculationDateObj, CalendarObj, ImpliedVol, DayCountObj));
                BlackProc = new QLNet.BlackProcess(UnderlyingObj, FlatRateObj, FlatVolTsObj);

                if (engineName == "baw")
                {
                    OptionObj.setPricingEngine(new QLNet.BaroneAdesiWhaleyApproximationEngine(BlackProc));
                }
                else if (engineName == "fda")
                {
                    OptionObj.setPricingEngine(new QLNet.FDAmericanEngine(BlackProc, 100, 100));
                }
                OptionPrice = optionPrice;
            }
            else
            {
                OptionPrice = OptionObj.NPV();
                ImpliedVol = impliedVol;
            }

            OptionObj = new QLNet.VanillaOption(PayoffObj, new QLNet.EuropeanExercise(ExpirationDateObj));
            OptionObj.setPricingEngine(new QLNet.AnalyticEuropeanEngine(BlackProc));

            GreeksOutput.Delta = OptionObj.delta();
            GreeksOutput.Vega = OptionObj.vega();
            GreeksOutput.Theta = OptionObj.thetaPerDay();
            GreeksOutput.Gamma = OptionObj.gamma();
            GreeksOutput.OptionPrice = OptionPrice;
            GreeksOutput.ImpliedVol = ImpliedVol;

            return GreeksOutput;

        }
Example #9
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");
        }
Example #10
0
        public DateTime ExpirationDate(int year, int month, string calendarType = "US")
        {
            DateTime referenceDay = new DateTime(year, month, 1);
            referenceDay = referenceDay.AddMonths((int)Rule.ReferenceRelativeMonth);

            Calendar calendar = new UnitedStates(UnitedStates.Market.NYSE); //todo add functionality to allow changing this to other countries

            int day;
            if (Rule.ReferenceDayIsLastBusinessDayOfMonth)
            {
                var tmpDay = referenceDay.AddMonths(1);
                tmpDay = tmpDay.AddDays(-1);
                while (!calendar.isBusinessDay(tmpDay))
                {
                    tmpDay = tmpDay.AddDays(-1);
                }
                day = tmpDay.Day;
            }
            else if (Rule.ReferenceUsesDays) //we use a fixed number of days from the start of the month
            {
                day = Rule.ReferenceDays;
            }
            else //we use a number of weeks and then a weekday of that week
            {
                if (Rule.ReferenceWeekDayCount == WeekDayCount.Last) //the last week of the month
                {
                    var tmpDay = referenceDay.AddMonths(1);
                    tmpDay = tmpDay.AddDays(-1);
                    while (tmpDay.DayOfWeek.ToInt() != (int)Rule.ReferenceWeekDay)
                    {
                        tmpDay = tmpDay.AddDays(-1);
                    }
                    day = tmpDay.Day;
                }
                else //1st to 4th week of the month, just loop until we find the right day
                {
                    int weekCount = 0;
                    while (weekCount < (int)Rule.ReferenceWeekDayCount + 1)
                    {
                        if (referenceDay.DayOfWeek.ToInt() == (int)Rule.ReferenceWeekDay)
                            weekCount++;

                        referenceDay = referenceDay.AddDays(1);
                    }

                    day = referenceDay.Day - 1;
                }
            }

            referenceDay = new DateTime(year, month, day);
            referenceDay = referenceDay.AddMonths((int)Rule.ReferenceRelativeMonth);

            if (Rule.DayType == DayType.BusinessDay)
            {
                int daysLeft = Rule.DaysBefore;
                int daysBack = 0;
                while (daysLeft > 0)
                {
                    daysBack++;

                    if (calendar.isBusinessDay(referenceDay.AddDays(-daysBack))) //todo fix here...
                        daysLeft--;
                }
                return referenceDay.AddDays(-daysBack);
            }
            else if (Rule.DayType == DayType.CalendarDay)
            {
                return referenceDay.AddDays(-Rule.DaysBefore);
            }
            return referenceDay;
        }