void OvernightIndexedSwapTest::testCachedValue() {

    BOOST_TEST_MESSAGE("Testing Eonia-swap calculation against cached value...");

    CommonVars vars;

    Settings::instance().evaluationDate() = vars.today;
    vars.settlement =
        vars.calendar.advance(vars.today,vars.settlementDays,Days);
    Real flat = 0.05;
    vars.eoniaTermStructure.linkTo(flatRate(vars.settlement,flat,Actual360()));
    Real fixedRate = exp(flat) - 1;
    shared_ptr<OvernightIndexedSwap> swap = vars.makeSwap(1*Years, fixedRate, 0.0,false);
    shared_ptr<OvernightIndexedSwap> swap2 = vars.makeSwap(1*Years, fixedRate, 0.0,true);
    Real cachedNPV   = 0.001730450147;
    Real tolerance = 1.0e-11;
    if (std::fabs(swap->NPV()-cachedNPV) > tolerance)
        BOOST_ERROR("\nfailed to reproduce cached swap value (non telescopic value dates):" <<
                    std::fixed << std::setprecision(12) <<
                    "\ncalculated: " << swap->NPV() <<
                    "\n  expected: " << cachedNPV <<
                    "\n tolerance:" << tolerance);
    if (std::fabs(swap2->NPV()-cachedNPV) > tolerance)
        BOOST_ERROR("\nfailed to reproduce cached swap value (telescopic value dates):" <<
                    std::fixed << std::setprecision(12) <<
                    "\ncalculated: " << swap->NPV() <<
                    "\n  expected: " << cachedNPV <<
                    "\n tolerance:" << tolerance);
}
void OvernightIndexedSwapTest::testSeasonedSwaps() {

    BOOST_TEST_MESSAGE("Testing seasoned Eonia-swap calculation...");

    CommonVars vars;

    Period lengths[] = { 1*Years, 2*Years, 5*Years, 10*Years, 20*Years };
    Spread spreads[] = { -0.001, -0.01, 0.0, 0.01, 0.001 };

    Date effectiveDate = Date(2, February, 2009);

    vars.eoniaIndex->addFixing(Date(2,February,2009), 0.0010); // fake fixing values
    vars.eoniaIndex->addFixing(Date(3,February,2009), 0.0011);
    vars.eoniaIndex->addFixing(Date(4,February,2009), 0.0012);
    vars.eoniaIndex->addFixing(Date(5,February,2009), 0.0013);

    for (Size i=0; i<LENGTH(lengths); i++) {
        for (Size j=0; j<LENGTH(spreads); j++) {

            shared_ptr<OvernightIndexedSwap> swap =
                vars.makeSwap(lengths[i],0.0,spreads[j],false,effectiveDate);
            shared_ptr<OvernightIndexedSwap> swap2 =
                vars.makeSwap(lengths[i],0.0,spreads[j],true,effectiveDate);
            if (std::fabs(swap->NPV() - swap2->NPV()) > 1.0e-10) {
                BOOST_ERROR("swap npv is different:\n"
                            << std::setprecision(2)
                            << "    length: " << lengths[i] << " \n"
                            << "    floating spread: "
                            << io::rate(spreads[j]) << "\n"
                            << "    swap value (non telescopic value dates): " << swap->NPV()
                            << "\n    swap value (telescopic value dates    ): " << swap2->NPV());
            }
        }
    }
}
void OvernightIndexedSwapTest::testFairSpread() {

    BOOST_TEST_MESSAGE("Testing Eonia-swap calculation of "
                       "fair floating spread...");

    CommonVars vars;

    Period lengths[] = { 1*Years, 2*Years, 5*Years, 10*Years, 20*Years };
    Rate rates[] = { 0.04, 0.05, 0.06, 0.07 };

    for (Size i=0; i<LENGTH(lengths); i++) {
        for (Size j=0; j<LENGTH(rates); j++) {

            shared_ptr<OvernightIndexedSwap> swap =
                vars.makeSwap(lengths[i], rates[j], 0.0);
            Spread fairSpread = swap->fairSpread();
            swap = vars.makeSwap(lengths[i], rates[j], fairSpread);

            if (std::fabs(swap->NPV()) > 1.0e-10) {
                BOOST_ERROR("\nrecalculating with implied spread:" <<
                            std::setprecision(2) <<
                            "\n     length: " << lengths[i] <<
                            "\n fixed rate: " << io::rate(rates[j]) <<
                            "\nfair spread: " << io::rate(fairSpread) <<
                            "\n swap value: " << swap->NPV());
            }
        }
    }

}
void OvernightIndexedSwapTest::testFairRate() {

    BOOST_TEST_MESSAGE("Testing Eonia-swap calculation of fair fixed rate...");

    CommonVars vars;

    Period lengths[] = { 1*Years, 2*Years, 5*Years, 10*Years, 20*Years };
    Spread spreads[] = { -0.001, -0.01, 0.0, 0.01, 0.001 };

    for (Size i=0; i<LENGTH(lengths); i++) {
        for (Size j=0; j<LENGTH(spreads); j++) {

            shared_ptr<OvernightIndexedSwap> swap =
                vars.makeSwap(lengths[i],0.0,spreads[j]);
            swap = vars.makeSwap(lengths[i],swap->fairRate(),spreads[j]);
            if (std::fabs(swap->NPV()) > 1.0e-10) {
                BOOST_ERROR("recalculating with implied rate:\n"
                            << std::setprecision(2)
                            << "    length: " << lengths[i] << " \n"
                            << "    floating spread: "
                            << io::rate(spreads[j]) << "\n"
                            << "    swap value: " << swap->NPV());
            }
        }
    }
}
Beispiel #5
0
void SwapTest::testFairSpread() {

    BOOST_TEST_MESSAGE("Testing vanilla-swap calculation of "
                       "fair floating spread...");

    CommonVars vars;

    Integer lengths[] = { 1, 2, 5, 10, 20 };
    Rate rates[] = { 0.04, 0.05, 0.06, 0.07 };

    for (Size i=0; i<LENGTH(lengths); i++) {
        for (Size j=0; j<LENGTH(rates); j++) {

            boost::shared_ptr<VanillaSwap> swap =
                vars.makeSwap(lengths[i],rates[j],0.0);
            swap = vars.makeSwap(lengths[i],rates[j],swap->fairSpread());
            if (std::fabs(swap->NPV()) > 1.0e-10) {
                BOOST_ERROR("recalculating with implied spread:\n"
                            << std::setprecision(2)
                            << "    length: " << lengths[i] << " years\n"
                            << "    fixed rate: " << io::rate(rates[j]) << "\n"
                            << "    swap value: " << swap->NPV());
            }
        }
    }
}
Beispiel #6
0
void SwapTest::testCachedValue() {

    BOOST_TEST_MESSAGE("Testing vanilla-swap calculation against cached value...");

    CommonVars vars;

    vars.today = Date(17,June,2002);
    Settings::instance().evaluationDate() = vars.today;
    vars.settlement =
        vars.calendar.advance(vars.today,vars.settlementDays,Days);
    vars.termStructure.linkTo(flatRate(vars.settlement,0.05,Actual365Fixed()));

    boost::shared_ptr<VanillaSwap> swap = vars.makeSwap(10, 0.06, 0.001);
    #ifndef QL_USE_INDEXED_COUPON
    Real cachedNPV   = -5.872863313209;
    #else
    Real cachedNPV   = -5.872342992212;
    #endif

    if (std::fabs(swap->NPV()-cachedNPV) > 1.0e-11)
        BOOST_ERROR("failed to reproduce cached swap value:\n"
                    << QL_FIXED << std::setprecision(12)
                    << "    calculated: " << swap->NPV() << "\n"
                    << "    expected:   " << cachedNPV);
}
Beispiel #7
0
void SwapTest::testSpreadDependency() {

    BOOST_TEST_MESSAGE("Testing vanilla-swap dependency on floating spread...");

    CommonVars vars;

    Integer lengths[] = { 1, 2, 5, 10, 20 };
    Rate rates[] = { 0.04, 0.05, 0.06, 0.07 };
    Spread spreads[] = { -0.01, -0.002, -0.001, 0.0, 0.001, 0.002, 0.01 };

    for (Size i=0; i<LENGTH(lengths); i++) {
        for (Size j=0; j<LENGTH(rates); j++) {
            // store the results for different spreads...
            std::vector<Real> swap_values;
            for (Size k=0; k<LENGTH(spreads); k++) {
                boost::shared_ptr<VanillaSwap> swap =
                    vars.makeSwap(lengths[i],rates[j],spreads[k]);
                swap_values.push_back(swap->NPV());
            }
            // and check that they go the right way
            std::vector<Real>::iterator it =
                std::adjacent_find(swap_values.begin(),swap_values.end(),
                                   std::greater<Real>());
            if (it != swap_values.end()) {
                Size n = it - swap_values.begin();
                BOOST_ERROR(
                    "NPV is decreasing with the floating spread in a swap: \n"
                    << "    length: " << lengths[i] << " years\n"
                    << "    value:  " << swap_values[n]
                    << " receiving spread: " << io::rate(spreads[n]) << "\n"
                    << "    value:  " << swap_values[n+1]
                    << " receiving spread: " << io::rate(spreads[n+1]));
            }
        }
    }
}
void OvernightIndexedSwapTest::testBootstrap() {

    BOOST_TEST_MESSAGE("Testing Eonia-swap curve building...");

    CommonVars vars;

    std::vector<shared_ptr<RateHelper> > eoniaHelpers;
    std::vector<shared_ptr<RateHelper> > swap3mHelpers;

    shared_ptr<IborIndex> euribor3m(new Euribor3M);
    shared_ptr<Eonia> eonia(new Eonia);

    for (Size i = 0; i < LENGTH(depositData); i++) {
        Real rate = 0.01 * depositData[i].rate;
        shared_ptr<SimpleQuote> simple = shared_ptr<SimpleQuote>(new SimpleQuote(rate));
        shared_ptr<Quote> quote (simple);
        Period term = depositData[i].n * depositData[i].unit;
        shared_ptr<RateHelper> helper(new
                                      DepositRateHelper(Handle<Quote>(quote),
                                              term,
                                              depositData[i].settlementDays,
                                              euribor3m->fixingCalendar(),
                                              euribor3m->businessDayConvention(),
                                              euribor3m->endOfMonth(),
                                              euribor3m->dayCounter()));

        if (term <= 2*Days)
            eoniaHelpers.push_back(helper);
        if (term <= 3*Months)
            swap3mHelpers.push_back(helper);
    }

    for (Size i = 0; i < LENGTH(fraData); i++) {
        Real rate = 0.01 * fraData[i].rate;
        shared_ptr<SimpleQuote> simple = shared_ptr<SimpleQuote>(new SimpleQuote(rate));
        shared_ptr<Quote> quote (simple);
        shared_ptr<RateHelper> helper(new
                                      FraRateHelper(Handle<Quote>(quote),
                                              fraData[i].nExpiry,
                                              fraData[i].nMaturity,
                                              fraData[i].settlementDays,
                                              euribor3m->fixingCalendar(),
                                              euribor3m->businessDayConvention(),
                                              euribor3m->endOfMonth(),
                                              euribor3m->dayCounter()));
        swap3mHelpers.push_back(helper);
    }

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

    for (Size i = 0; i < LENGTH(swapData); i++) {
        Real rate = 0.01 * swapData[i].rate;
        shared_ptr<SimpleQuote> simple = shared_ptr<SimpleQuote>(new SimpleQuote(rate));
        shared_ptr<Quote> quote (simple);
        Period tenor = swapData[i].nIndexUnits * swapData[i].indexUnit;
        Period term = swapData[i].nTermUnits * swapData[i].termUnit;
        shared_ptr<RateHelper> helper(new SwapRateHelper(
                                          Handle<Quote>(quote),
                                          term,
                                          vars.calendar,
                                          vars.fixedSwapFrequency,
                                          vars.fixedSwapConvention,
                                          vars.fixedSwapDayCount,
                                          euribor3m));
        if (tenor == 3*Months)
            swap3mHelpers.push_back(helper);
    }

    shared_ptr<PiecewiseFlatForward> eoniaTS(new
            PiecewiseFlatForward (vars.today, eoniaHelpers, Actual365Fixed()));

    shared_ptr<PiecewiseFlatForward> swapTS(new
                                            PiecewiseFlatForward (vars.today, swap3mHelpers, Actual365Fixed()));

    vars.eoniaTermStructure.linkTo(eoniaTS);

    /*
    std::cout.setf (std::ios::fixed, std::ios::floatfield);
    std::cout.setf (std::ios::showpoint);
    */

    // test curve consistency
    Real tolerance = 1.0e-8;
    for (Size i = 0; i < LENGTH(eoniaSwapData); i++) {
        Rate expected = eoniaSwapData[i].rate;
        Period term = eoniaSwapData[i].n * eoniaSwapData[i].unit;
        shared_ptr<OvernightIndexedSwap> swap = vars.makeSwap(term, 0.0, 0.0);
        Rate calculated = 100.0 * swap->fairRate();
        Rate error = std::fabs(expected-calculated);

        if (error>tolerance)
            BOOST_FAIL("curve inconsistency:" << std::setprecision(10) <<
                       "\n swap length:     " << term <<
                       "\n quoted rate:     " << expected <<
                       "\n calculated rate: " << calculated <<
                       "\n error:           " << error <<
                       "\n tolerance:       " << tolerance);
    }

    // zero spread
    /*
    std::cout << "zero spread:" << std::endl;
    std::cout << "years date zero3m/% zero1d/% spread/bp" << std::endl;
    DayCounter dc = Actual365Fixed();
    for (Size i = 1; i <= 10; i++) {
        Date d = vars.today + i*Years;
        Rate zero1d = eoniaTS->zeroRate(d, dc, Continuous, Annual,false).rate();
        Rate zero3m = swapTS->zeroRate(d, dc, Continuous, Annual,false).rate();
        std::cout << std::setw(2) << i << "y  " << io::iso_date(d) << "  "
                  << std::setprecision(3)
                  << zero3m * 100.0 << " "
                  << zero1d * 100.0 << " "
                  << std::setprecision(1)
                  << (zero3m - zero1d) * 10000.0 << std::endl;
    }
    */
}
void BermudanSwaptionTest::testCachedValues() {

    BOOST_MESSAGE("Testing Bermudan swaption against cached values...");

    CommonVars vars;

    vars.today = Date(15, February, 2002);

    Settings::instance().evaluationDate() = vars.today;

    vars.settlement = Date(19, February, 2002);
    // flat yield term structure impling 1x5 swap at 5%
    vars.termStructure.linkTo(flatRate(vars.settlement,
                                          0.04875825,
                                          Actual365Fixed()));

    Rate atmRate = vars.makeSwap(0.0)->fairRate();

    boost::shared_ptr<VanillaSwap> itmSwap = vars.makeSwap(0.8*atmRate);
    boost::shared_ptr<VanillaSwap> atmSwap = vars.makeSwap(atmRate);
    boost::shared_ptr<VanillaSwap> otmSwap = vars.makeSwap(1.2*atmRate);

    Real a = 0.048696, sigma = 0.0058904;
    boost::shared_ptr<ShortRateModel> model(new HullWhite(vars.termStructure,
                                                          a, sigma));
    std::vector<Date> exerciseDates;
    const Leg& leg = atmSwap->fixedLeg();
    for (Size i=0; i<leg.size(); i++) {
        boost::shared_ptr<Coupon> coupon =
            boost::dynamic_pointer_cast<Coupon>(leg[i]);
        exerciseDates.push_back(coupon->accrualStartDate());
    }
    boost::shared_ptr<Exercise> exercise(new BermudanExercise(exerciseDates));

    boost::shared_ptr<PricingEngine> engine(new TreeSwaptionEngine(model, 50));

    #if defined(QL_USE_INDEXED_COUPON)
    Real itmValue = 42.2413, atmValue = 12.8789, otmValue = 2.4759;
    #else
    Real itmValue = 42.2470, atmValue = 12.8826, otmValue = 2.4769;
    #endif

    Real tolerance = 1.0e-4;

    Swaption swaption(itmSwap, exercise);
    swaption.setPricingEngine(engine);
    if (std::fabs(swaption.NPV()-itmValue) > tolerance)
        BOOST_ERROR("failed to reproduce cached in-the-money swaption value:\n"
                    << "calculated: " << swaption.NPV() << "\n"
                    << "expected:   " << itmValue);
    swaption = Swaption(atmSwap, exercise);
    swaption.setPricingEngine(engine);
    if (std::fabs(swaption.NPV()-atmValue) > tolerance)
        BOOST_ERROR("failed to reproduce cached at-the-money swaption value:\n"
                    << "calculated: " << swaption.NPV() << "\n"
                    << "expected:   " << atmValue);
    swaption = Swaption(otmSwap, exercise);
    swaption.setPricingEngine(engine);
    if (std::fabs(swaption.NPV()-otmValue) > tolerance)
        BOOST_ERROR("failed to reproduce cached out-of-the-money "
                    << "swaption value:\n"
                    << "calculated: " << swaption.NPV() << "\n"
                    << "expected:   " << otmValue);

    for (Size j=0; j<exerciseDates.size(); j++)
        exerciseDates[j] = vars.calendar.adjust(exerciseDates[j]-10);
    exercise =
        boost::shared_ptr<Exercise>(new BermudanExercise(exerciseDates));

    #if defined(QL_USE_INDEXED_COUPON)
    itmValue = 42.1917; atmValue = 12.7788; otmValue = 2.4388;
    #else
    itmValue = 42.1974; atmValue = 12.7825; otmValue = 2.4399;
    #endif

    swaption = Swaption(itmSwap, exercise);
    swaption.setPricingEngine(engine);
    if (std::fabs(swaption.NPV()-itmValue) > tolerance)
        BOOST_ERROR("failed to reproduce cached in-the-money swaption value:\n"
                    << "calculated: " << swaption.NPV() << "\n"
                    << "expected:   " << itmValue);
    swaption = Swaption(atmSwap, exercise);
    swaption.setPricingEngine(engine);
    if (std::fabs(swaption.NPV()-atmValue) > tolerance)
        BOOST_ERROR("failed to reproduce cached at-the-money swaption value:\n"
                    << "calculated: " << swaption.NPV() << "\n"
                    << "expected:   " << atmValue);
    swaption = Swaption(otmSwap, exercise);
    swaption.setPricingEngine(engine);
    if (std::fabs(swaption.NPV()-otmValue) > tolerance)
        BOOST_ERROR("failed to reproduce cached out-of-the-money "
                    << "swaption value:\n"
                    << "calculated: " << swaption.NPV() << "\n"
                    << "expected:   " << otmValue);
}