예제 #1
0
        public void testCurveConsistency <T, I, B>(CommonVars vars, I interpolator, double tolerance)
            where T : ITraits <YieldTermStructure>, new()
            where I : IInterpolationFactory, new()
            where B : IBootStrap <PiecewiseYieldCurve>, new()
        {
            vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.instruments,
                                                                   new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator);

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

            curveHandle.linkTo(vars.termStructure);

            // check deposits
            for (int i = 0; i < vars.deposits; i++)
            {
                Euribor index         = new Euribor(new Period(vars.depositData[i].n, vars.depositData[i].units), curveHandle);
                double  expectedRate  = vars.depositData[i].rate / 100,
                        estimatedRate = index.fixing(vars.today);
                QAssert.IsTrue(Math.Abs(expectedRate - estimatedRate) < tolerance,
                               vars.depositData[i].n + " "
                               + (vars.depositData[i].units == TimeUnit.Weeks ? "week(s)" : "month(s)")
                               + " deposit:"
                               + "\n    estimated rate: " + estimatedRate
                               + "\n    expected rate:  " + expectedRate);
            }

            // check swaps
            IborIndex euribor6m = new Euribor6M(curveHandle);

            for (int i = 0; i < vars.swaps; i++)
            {
                Period tenor = new Period(vars.swapData[i].n, vars.swapData[i].units);

                VanillaSwap swap = new MakeVanillaSwap(tenor, euribor6m, 0.0)
                                   .withEffectiveDate(vars.settlement)
                                   .withFixedLegDayCount(vars.fixedLegDayCounter)
                                   .withFixedLegTenor(new Period(vars.fixedLegFrequency))
                                   .withFixedLegConvention(vars.fixedLegConvention)
                                   .withFixedLegTerminationDateConvention(vars.fixedLegConvention);

                double expectedRate  = vars.swapData[i].rate / 100,
                       estimatedRate = swap.fairRate();
                double error         = Math.Abs(expectedRate - estimatedRate);
                QAssert.IsTrue(error < tolerance,
                               vars.swapData[i].n + " year(s) swap:\n"
                               + "\n estimated rate: " + estimatedRate
                               + "\n expected rate:  " + expectedRate
                               + "\n error:          " + error
                               + "\n tolerance:      " + tolerance);
            }

            // check bonds
            vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.bondHelpers,
                                                                   new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator);
            curveHandle.linkTo(vars.termStructure);

            for (int i = 0; i < vars.bonds; i++)
            {
                Date          maturity = vars.calendar.advance(vars.today, vars.bondData[i].n, vars.bondData[i].units);
                Date          issue    = vars.calendar.advance(maturity, -vars.bondData[i].length, TimeUnit.Years);
                List <double> coupons  = new List <double>()
                {
                    vars.bondData[i].coupon / 100.0
                };

                FixedRateBond bond = new FixedRateBond(vars.bondSettlementDays, 100.0,
                                                       vars.schedules[i], coupons,
                                                       vars.bondDayCounter, vars.bondConvention,
                                                       vars.bondRedemption, issue);

                IPricingEngine bondEngine = new DiscountingBondEngine(curveHandle);
                bond.setPricingEngine(bondEngine);

                double expectedPrice  = vars.bondData[i].price,
                       estimatedPrice = bond.cleanPrice();
                QAssert.IsTrue(Math.Abs(expectedPrice - estimatedPrice) < tolerance,
                               i + 1 + " bond failure:" +
                               "\n  estimated price: " + estimatedPrice +
                               "\n  expected price:  " + expectedPrice);
            }

            // check FRA
            vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.fraHelpers,
                                                                   new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator);
            curveHandle.linkTo(vars.termStructure);

            IborIndex euribor3m = new Euribor3M(curveHandle);

            for (int i = 0; i < vars.fras; i++)
            {
                Date start = vars.calendar.advance(vars.settlement,
                                                   vars.fraData[i].n,
                                                   vars.fraData[i].units,
                                                   euribor3m.businessDayConvention(),
                                                   euribor3m.endOfMonth());
                Date end = vars.calendar.advance(start, 3, TimeUnit.Months,
                                                 euribor3m.businessDayConvention(),
                                                 euribor3m.endOfMonth());

                ForwardRateAgreement fra = new ForwardRateAgreement(start, end, Position.Type.Long, vars.fraData[i].rate / 100,
                                                                    100.0, euribor3m, curveHandle);
                double expectedRate  = vars.fraData[i].rate / 100,
                       estimatedRate = fra.forwardRate().rate();
                QAssert.IsTrue(Math.Abs(expectedRate - estimatedRate) < tolerance,
                               i + 1 + " FRA failure:" +
                               "\n  estimated rate: " + estimatedRate +
                               "\n  expected rate:  " + expectedRate);
            }
        }
예제 #2
0
        public void testLiborFixing()
        {
            // "Testing use of today's LIBOR fixings in swap curve...");

            CommonVars vars = new CommonVars();

            var       swapHelpers = new InitializedList <RateHelper>();
            IborIndex euribor6m   = new Euribor6M();

            for (int i = 0; i < vars.swaps; i++)
            {
                Handle <Quote> r = new Handle <Quote>(vars.rates[i + vars.deposits]);
                swapHelpers.Add(new SwapRateHelper(r, new Period(vars.swapData[i].n, vars.swapData[i].units),
                                                   vars.calendar,
                                                   vars.fixedLegFrequency, vars.fixedLegConvention,
                                                   vars.fixedLegDayCounter, euribor6m));
            }

            vars.termStructure = new PiecewiseYieldCurve <Discount, LogLinear>(vars.settlement, swapHelpers, new Actual360());

            Handle <YieldTermStructure> curveHandle = new Handle <YieldTermStructure>(vars.termStructure);

            IborIndex index = new Euribor6M(curveHandle);

            for (int i = 0; i < vars.swaps; i++)
            {
                Period tenor = new Period(vars.swapData[i].n, vars.swapData[i].units);

                VanillaSwap swap = new MakeVanillaSwap(tenor, index, 0.0)
                                   .withEffectiveDate(vars.settlement)
                                   .withFixedLegDayCount(vars.fixedLegDayCounter)
                                   .withFixedLegTenor(new Period(vars.fixedLegFrequency))
                                   .withFixedLegConvention(vars.fixedLegConvention)
                                   .withFixedLegTerminationDateConvention(vars.fixedLegConvention)
                                   .value();

                double expectedRate  = vars.swapData[i].rate / 100,
                       estimatedRate = swap.fairRate();
                double tolerance     = 1.0e-9;
                if (Math.Abs(expectedRate - estimatedRate) > tolerance)
                {
                    QAssert.Fail("before LIBOR fixing:\n"
                                 + vars.swapData[i].n + " year(s) swap:\n"
                                 + "    estimated rate: "
                                 + (estimatedRate) + "\n"
                                 + "    expected rate:  "
                                 + (expectedRate));
                }
            }

            Flag f = new Flag();

            vars.termStructure.registerWith(f.update);
            f.lower();

            index.addFixing(vars.today, 0.0425);

            if (!f.isUp())
            {
                QAssert.Fail("Observer was not notified of rate fixing");
            }

            for (int i = 0; i < vars.swaps; i++)
            {
                Period tenor = new Period(vars.swapData[i].n, vars.swapData[i].units);

                VanillaSwap swap = new MakeVanillaSwap(tenor, index, 0.0)
                                   .withEffectiveDate(vars.settlement)
                                   .withFixedLegDayCount(vars.fixedLegDayCounter)
                                   .withFixedLegTenor(new Period(vars.fixedLegFrequency))
                                   .withFixedLegConvention(vars.fixedLegConvention)
                                   .withFixedLegTerminationDateConvention(vars.fixedLegConvention)
                                   .value();

                double expectedRate  = vars.swapData[i].rate / 100,
                       estimatedRate = swap.fairRate();
                double tolerance     = 1.0e-9;
                if (Math.Abs(expectedRate - estimatedRate) > tolerance)
                {
                    QAssert.Fail("after LIBOR fixing:\n"
                                 + vars.swapData[i].n + " year(s) swap:\n"
                                 + "    estimated rate: "
                                 + (estimatedRate) + "\n"
                                 + "    expected rate:  "
                                 + (expectedRate));
                }
            }
        }
예제 #3
0
        public void testJpyLibor()
        {
            //"Testing bootstrap over JPY LIBOR swaps...");

            CommonVars vars = new CommonVars();

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

            vars.calendar   = new Japan();
            vars.settlement = vars.calendar.advance(vars.today, vars.settlementDays, TimeUnit.Days);

            // market elements
            vars.rates = new InitializedList <SimpleQuote>(vars.swaps);
            for (int i = 0; i < vars.swaps; i++)
            {
                vars.rates[i] = new SimpleQuote(vars.swapData[i].rate / 100);
            }

            // rate helpers
            vars.instruments = new InitializedList <RateHelper>(vars.swaps);

            IborIndex index = new JPYLibor(new Period(6, TimeUnit.Months));

            for (int i = 0; i < vars.swaps; i++)
            {
                Handle <Quote> r = new Handle <Quote>(vars.rates[i]);
                vars.instruments[i] = new SwapRateHelper(r, new Period(vars.swapData[i].n, vars.swapData[i].units),
                                                         vars.calendar,
                                                         vars.fixedLegFrequency, vars.fixedLegConvention,
                                                         vars.fixedLegDayCounter, index);
            }

            vars.termStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                vars.settlement, vars.instruments,
                new Actual360(),
                new List <Handle <Quote> >(),
                new List <Date>(),
                1.0e-12);

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

            curveHandle.linkTo(vars.termStructure);

            // check swaps
            IborIndex jpylibor6m = new JPYLibor(new Period(6, TimeUnit.Months), curveHandle);

            for (int i = 0; i < vars.swaps; i++)
            {
                Period tenor = new Period(vars.swapData[i].n, vars.swapData[i].units);

                VanillaSwap swap = new MakeVanillaSwap(tenor, jpylibor6m, 0.0)
                                   .withEffectiveDate(vars.settlement)
                                   .withFixedLegDayCount(vars.fixedLegDayCounter)
                                   .withFixedLegTenor(new Period(vars.fixedLegFrequency))
                                   .withFixedLegConvention(vars.fixedLegConvention)
                                   .withFixedLegTerminationDateConvention(vars.fixedLegConvention)
                                   .withFixedLegCalendar(vars.calendar)
                                   .withFloatingLegCalendar(vars.calendar)
                                   .value();

                double expectedRate  = vars.swapData[i].rate / 100,
                       estimatedRate = swap.fairRate();
                double error         = Math.Abs(expectedRate - estimatedRate);
                double tolerance     = 1.0e-9;

                if (error > tolerance)
                {
                    QAssert.Fail(vars.swapData[i].n + " year(s) swap:\n"
                                 + "\n estimated rate: " + (estimatedRate)
                                 + "\n expected rate:  " + (expectedRate)
                                 + "\n error:          " + (error)
                                 + "\n tolerance:      " + (tolerance));
                }
            }
        }
예제 #4
0
        public void testImpliedVolatility()
        {
            //"Testing implied volatility for swaptions...";

            CommonVars vars = new CommonVars();

            int    maxEvaluations = 100;
            double tolerance      = 1.0e-08;

            Settlement.Type[] types = { Settlement.Type.Physical, Settlement.Type.Cash };
            // test data
            double[] strikes = { 0.02, 0.03, 0.04, 0.05, 0.06, 0.07 };
            double[] vols    = { 0.01, 0.05, 0.10, 0.20, 0.30, 0.70, 0.90 };

            for (int i = 0; i < exercises.Length; i++)
            {
                for (int j = 0; j < lengths.Length; j++)
                {
                    Date exerciseDate = vars.calendar.advance(vars.today, exercises[i]);
                    Date startDate    = vars.calendar.advance(exerciseDate,
                                                              vars.settlementDays, TimeUnit.Days);
                    Date maturity = vars.calendar.advance(startDate, lengths[j],
                                                          vars.floatingConvention);
                    for (int t = 0; t < strikes.Length; t++)
                    {
                        for (int k = 0; k < type.Length; k++)
                        {
                            VanillaSwap swap = new MakeVanillaSwap(lengths[j], vars.index, strikes[t])
                                               .withEffectiveDate(startDate)
                                               .withFloatingLegSpread(0.0)
                                               .withType(type[k]);
                            for (int h = 0; h < types.Length; h++)
                            {
                                for (int u = 0; u < vols.Length; u++)
                                {
                                    Swaption swaption = vars.makeSwaption(swap, exerciseDate,
                                                                          vols[u], types[h]);
                                    // Black price
                                    double value   = swaption.NPV();
                                    double implVol = 0.0;
                                    try
                                    {
                                        implVol =
                                            swaption.impliedVolatility(value,
                                                                       vars.termStructure,
                                                                       0.10,
                                                                       tolerance,
                                                                       maxEvaluations);
                                    }
                                    catch (System.Exception e)
                                    {
                                        // couldn't bracket?
                                        swaption.setPricingEngine(vars.makeEngine(0.0));
                                        double value2 = swaption.NPV();
                                        if (Math.Abs(value - value2) < tolerance)
                                        {
                                            // ok, just skip:
                                            continue;
                                        }
                                        // otherwise, report error
                                        Assert.Fail("implied vol failure: " +
                                                    exercises[i] + "x" + lengths[j] + " " + type[k] +
                                                    "\nsettlement: " + types[h] +
                                                    "\nstrike      " + strikes[t] +
                                                    "\natm level:  " + swap.fairRate() +
                                                    "\nvol:        " + vols[u] +
                                                    "\nprice:      " + value +
                                                    "\n" + e.Message.ToString());
                                    }
                                    if (Math.Abs(implVol - vols[u]) > tolerance)
                                    {
                                        // the difference might not matter
                                        swaption.setPricingEngine(vars.makeEngine(implVol));
                                        double value2 = swaption.NPV();
                                        if (Math.Abs(value - value2) > tolerance)
                                        {
                                            Assert.Fail("implied vol failure: " +
                                                        exercises[i] + "x" + lengths[j] + " " + type[k] +
                                                        "\nsettlement:    " + types[h] +
                                                        "\nstrike         " + strikes[t] +
                                                        "\natm level:     " + swap.fairRate() +
                                                        "\nvol:           " + vols[u] +
                                                        "\nprice:         " + value +
                                                        "\nimplied vol:   " + implVol +
                                                        "\nimplied price: " + value2);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }