void DefaultProbabilityCurveTest::testSingleInstrumentBootstrap() {
    BOOST_TEST_MESSAGE("Testing single-instrument curve bootstrap...");

    Calendar calendar = TARGET();

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

    Integer settlementDays = 0;

    Real quote = 0.005;
    Period tenor = 2*Years;

    Frequency frequency = Quarterly;
    BusinessDayConvention convention = Following;
    DateGeneration::Rule rule = DateGeneration::TwentiethIMM;
    DayCounter dayCounter = Thirty360();
    Real recoveryRate = 0.4;

    RelinkableHandle<YieldTermStructure> discountCurve;
    discountCurve.linkTo(boost::shared_ptr<YieldTermStructure>(
                                    new FlatForward(today,0.06,Actual360())));

    std::vector<boost::shared_ptr<DefaultProbabilityHelper> > helpers(1);

    helpers[0] = boost::shared_ptr<DefaultProbabilityHelper>(
                        new SpreadCdsHelper(quote, tenor,
                                            settlementDays, calendar,
                                            frequency, convention, rule,
                                            dayCounter, recoveryRate,
                                            discountCurve));

    PiecewiseDefaultCurve<HazardRate,BackwardFlat> defaultCurve(today, helpers,
                                                                dayCounter);
    defaultCurve.recalculate();
}
Пример #2
0
void OptionletStripperTest::testSwitchStrike() {
    BOOST_TEST_MESSAGE("Testing switch strike level and recalibration of level "
                       "in case of curve relinking...");

    CommonVars vars;
    Settings::instance().evaluationDate() = Date(28, October, 2013);
    vars.setCapFloorTermVolSurface();

    RelinkableHandle< YieldTermStructure > yieldTermStructure;
    yieldTermStructure.linkTo(boost::shared_ptr< FlatForward >(
        new FlatForward(0, vars.calendar, 0.03, vars.dayCounter)));

    shared_ptr< IborIndex > iborIndex(new Euribor6M(yieldTermStructure));

    boost::shared_ptr< OptionletStripper1 > optionletStripper1(
        new OptionletStripper1(vars.capFloorVolSurface, iborIndex,
                               Null< Rate >(), vars.accuracy));


    #if defined(QL_USE_INDEXED_COUPON)
    Real expected = 0.02981258;
    #else
    Real expected = 0.02981223;
    #endif

    Real error = std::fabs(optionletStripper1->switchStrike() - expected);
    if (error > vars.tolerance)
        BOOST_FAIL("\nSwitchstrike not correctly computed:  "
                   << "\nexpected switch strike: " << io::rate(expected)
                   << "\ncomputed switch strike: "
                   << io::rate(optionletStripper1->switchStrike())
                   << "\nerror:         " << io::rate(error)
                   << "\ntolerance:     " << io::rate(vars.tolerance));

    yieldTermStructure.linkTo(boost::shared_ptr< FlatForward >(
        new FlatForward(0, vars.calendar, 0.05, vars.dayCounter)));

    #if defined(QL_USE_INDEXED_COUPON)
    expected = 0.0499381;
    #else
    expected = 0.0499371;
    #endif

    error = std::fabs(optionletStripper1->switchStrike() - expected);
    if (error > vars.tolerance)
        BOOST_FAIL("\nSwitchstrike not correctly computed:  "
                   << "\nexpected switch strike: " << io::rate(expected)
                   << "\ncomputed switch strike: "
                   << io::rate(optionletStripper1->switchStrike())
                   << "\nerror:         " << io::rate(error)
                   << "\ntolerance:     " << io::rate(vars.tolerance));
}
Пример #3
0
void TermStructureTest::testCreateWithNullUnderlying() {
    BOOST_TEST_MESSAGE(
        "Testing that a zero-spreaded curve can be created with "
        "a null underlying curve...");

    CommonVars vars;

    Handle<Quote> spread(ext::shared_ptr<Quote>(new SimpleQuote(0.01)));
    RelinkableHandle<YieldTermStructure> underlying;
    // this shouldn't throw
    ext::shared_ptr<YieldTermStructure> spreaded(
        new ZeroSpreadedTermStructure(underlying,spread));
    // if we do this, the curve can work.
    underlying.linkTo(vars.termStructure);
    // check that we can use it
    spreaded->referenceDate();
}
Пример #4
0
void TermStructureTest::testImpliedObs() {

    BOOST_TEST_MESSAGE("Testing observability of implied term structure...");

    CommonVars vars;

    Date today = Settings::instance().evaluationDate();
    Date newToday = today + 3*Years;
    Date newSettlement = vars.calendar.advance(newToday,
                                               vars.settlementDays,Days);
    RelinkableHandle<YieldTermStructure> h;
    ext::shared_ptr<YieldTermStructure> implied(
                                  new ImpliedTermStructure(h, newSettlement));
    Flag flag;
    flag.registerWith(implied);
    h.linkTo(vars.termStructure);
    if (!flag.isUp())
        BOOST_ERROR("Observer was not notified of term structure change");
}
Пример #5
0
void TermStructureTest::testFSpreadedObs() {

    BOOST_TEST_MESSAGE("Testing observability of forward-spreaded "
                       "term structure...");

    CommonVars vars;

    ext::shared_ptr<SimpleQuote> me(new SimpleQuote(0.01));
    Handle<Quote> mh(me);
    RelinkableHandle<YieldTermStructure> h; //(vars.dummyTermStructure);
    ext::shared_ptr<YieldTermStructure> spreaded(
        new ForwardSpreadedTermStructure(h,mh));
    Flag flag;
    flag.registerWith(spreaded);
    h.linkTo(vars.termStructure);
    if (!flag.isUp())
        BOOST_ERROR("Observer was not notified of term structure change");
    flag.lower();
    me->setValue(0.005);
    if (!flag.isUp())
        BOOST_ERROR("Observer was not notified of spread change");
}
Пример #6
0
void NthToDefaultTest::testGaussStudent() {
    BOOST_MESSAGE ("Testing nth-to-default against Hull-White values "
                   "with Gaussian and Student copula...");

    SavedSettings backup;

    /*************************
     * Tolerances
     */
    Real relTolerance = 0.015; // relative difference
    Real absTolerance = 1; // absolute difference in bp

    Period timeUnit = 1*Weeks; // required to reach accuracy

    Size names = 10;
    QL_REQUIRE (LENGTH(hwDataDist) == names,
                "hwDataDist length does not match");

    Real rate = 0.05;
    DayCounter dc = Actual365Fixed();
    Compounding cmp = Continuous; // Simple;


    Real recovery = 0.4;
    vector<Real> lambda (names, 0.01);

    Schedule schedule = MakeSchedule().from(Date (1, September, 2006))
                                      .to(Date (1, September, 2011))
                                      .withTenor(3*Months)
                                      .withCalendar(TARGET());

    Date asofDate(31, August, 2006);

    Settings::instance().evaluationDate() = asofDate;

    vector<Date> gridDates;
    gridDates.push_back (asofDate);
    gridDates.push_back (TARGET().advance (asofDate, Period (1, Years)));
    gridDates.push_back (TARGET().advance (asofDate, Period (5, Years)));
    gridDates.push_back (TARGET().advance (asofDate, Period (7, Years)));

    shared_ptr<YieldTermStructure> yieldPtr (new FlatForward (asofDate, rate, dc, cmp));
    Handle<YieldTermStructure> yieldHandle (yieldPtr);

    vector<Handle<DefaultProbabilityTermStructure> > probabilities;
    Period maxTerm (10, Years);
    for (Size i = 0; i < lambda.size(); i++) {
        Handle<Quote> h(shared_ptr<Quote>(new SimpleQuote(lambda[i])));
        shared_ptr<DefaultProbabilityTermStructure> ptr (
                                         new FlatHazardRate(asofDate, h, dc));
        probabilities.push_back(Handle<DefaultProbabilityTermStructure>(ptr));
    }

    shared_ptr<SimpleQuote> simpleQuote (new SimpleQuote(0.3));
    Handle<Quote> correlationHandle (simpleQuote);

    shared_ptr<OneFactorCopula> gaussianCopula (
                             new OneFactorGaussianCopula (correlationHandle));
    shared_ptr<OneFactorCopula> studentCopula (
                        new OneFactorStudentCopula (correlationHandle, 5, 5));
    RelinkableHandle<OneFactorCopula> copula;

    vector<NthToDefault> ntd;
    for (Size i = 1; i <= probabilities.size(); i++)
        ntd.push_back (NthToDefault (i, probabilities, recovery,
                                     copula, Protection::Seller,
                                     100.0, schedule, 0.02, Actual360(),
                                     true, yieldHandle, timeUnit));

    QL_REQUIRE (LENGTH(hwCorrelation) == 3,
                "correlation length does not match");

    Real maxDiff = 0;

    simpleQuote->setValue (0.3);

    copula.linkTo (gaussianCopula);

    for (Size i = 0; i < ntd.size(); i++) {
        QL_REQUIRE (ntd[i].rank() == hwDataDist[i].rank, "rank does not match");

        Real diff = 1e4 * ntd[i].fairPremium() - hwDataDist[i].spread[0];
        maxDiff = max (maxDiff, fabs (diff));
        BOOST_CHECK_MESSAGE (fabs(diff / hwDataDist[i].spread[0]) ||
                             fabs(diff) < absTolerance,
                             "tolerance " << relTolerance << "|"
                             << absTolerance << " exceeded");
    }

    copula.linkTo (studentCopula);

    maxDiff = 0;
    for (Size i = 0; i < ntd.size(); i++) {
        QL_REQUIRE (ntd[i].rank() == hwDataDist[i].rank, "rank does not match");

        Real diff = 1e4 * ntd[i].fairPremium() - hwDataDist[i].spread[3];
        maxDiff = max (maxDiff, fabs (diff));
        BOOST_CHECK_MESSAGE (fabs(diff / hwDataDist[i].spread[3]) ||
                             fabs(diff) < absTolerance,
                             "tolerance " << relTolerance << "|"
                             << absTolerance << " exceeded");
    }
}
Пример #7
0
void CreditDefaultSwapTest::testCachedValue() {

    BOOST_TEST_MESSAGE("Testing credit-default swap against cached values...");

    SavedSettings backup;

    // Initialize curves
    Settings::instance().evaluationDate() = Date(9,June,2006);
    Date today = Settings::instance().evaluationDate();
    Calendar calendar = TARGET();

    Handle<Quote> hazardRate = Handle<Quote>(
                ext::shared_ptr<Quote>(new SimpleQuote(0.01234)));
    RelinkableHandle<DefaultProbabilityTermStructure> probabilityCurve;
    probabilityCurve.linkTo(
        ext::shared_ptr<DefaultProbabilityTermStructure>(
                   new FlatHazardRate(0, calendar, hazardRate, Actual360())));

    RelinkableHandle<YieldTermStructure> discountCurve;

    discountCurve.linkTo(ext::shared_ptr<YieldTermStructure>(
                            new FlatForward(today,0.06,Actual360())));

    // Build the schedule
    Date issueDate = calendar.advance(today, -1, Years);
    Date maturity = calendar.advance(issueDate, 10, Years);
    Frequency frequency = Semiannual;
    BusinessDayConvention convention = ModifiedFollowing;

    Schedule schedule(issueDate, maturity, Period(frequency), calendar,
                      convention, convention, DateGeneration::Forward, false);

    // Build the CDS
    Rate fixedRate = 0.0120;
    DayCounter dayCount = Actual360();
    Real notional = 10000.0;
    Real recoveryRate = 0.4;

    CreditDefaultSwap cds(Protection::Seller, notional, fixedRate,
                          schedule, convention, dayCount, true, true);
    cds.setPricingEngine(ext::shared_ptr<PricingEngine>(
         new MidPointCdsEngine(probabilityCurve,recoveryRate,discountCurve)));

    Real npv = 295.0153398;
    Rate fairRate = 0.007517539081;

    Real calculatedNpv = cds.NPV();
    Rate calculatedFairRate = cds.fairSpread();
    Real tolerance = 1.0e-7;

    if (std::fabs(calculatedNpv - npv) > tolerance)
        BOOST_ERROR(
            "Failed to reproduce NPV with mid-point engine\n"
            << std::setprecision(10)
            << "    calculated NPV: " << calculatedNpv << "\n"
            << "    expected NPV:   " << npv);

    if (std::fabs(calculatedFairRate - fairRate) > tolerance)
        BOOST_ERROR(
            "Failed to reproduce fair rate with mid-point engine\n"
            << std::setprecision(10)
            << "    calculated fair rate: " << calculatedFairRate << "\n"
            << "    expected fair rate:   " << fairRate);

    cds.setPricingEngine(ext::shared_ptr<PricingEngine>(
                          new IntegralCdsEngine(1*Days,probabilityCurve,
                                                recoveryRate,discountCurve)));

    calculatedNpv = cds.NPV();
    calculatedFairRate = cds.fairSpread();
    tolerance = 1.0e-5;

    if (std::fabs(calculatedNpv - npv) > notional*tolerance*10)
        BOOST_ERROR(
            "Failed to reproduce NPV with integral engine "
            "(step = 1 day)\n"
            << std::setprecision(10)
            << "    calculated NPV: " << calculatedNpv << "\n"
            << "    expected NPV:   " << npv);

    if (std::fabs(calculatedFairRate - fairRate) > tolerance)
        BOOST_ERROR(
            "Failed to reproduce fair rate with integral engine "
            "(step = 1 day)\n"
            << std::setprecision(10)
            << "    calculated fair rate: " << calculatedFairRate << "\n"
            << "    expected fair rate:   " << fairRate);

    cds.setPricingEngine(ext::shared_ptr<PricingEngine>(
                          new IntegralCdsEngine(1*Weeks,probabilityCurve,
                                                recoveryRate,discountCurve)));

    calculatedNpv = cds.NPV();
    calculatedFairRate = cds.fairSpread();
    tolerance = 1.0e-5;

    if (std::fabs(calculatedNpv - npv) > notional*tolerance*10)
        BOOST_ERROR(
            "Failed to reproduce NPV with integral engine "
            "(step = 1 week)\n"
            << std::setprecision(10)
            << "    calculated NPV: " << calculatedNpv << "\n"
            << "    expected NPV:   " << npv);

    if (std::fabs(calculatedFairRate - fairRate) > tolerance)
        BOOST_ERROR(
            "Failed to reproduce fair rate with integral engine "
            "(step = 1 week)\n"
            << std::setprecision(10)
            << "    calculated fair rate: " << calculatedFairRate << "\n"
            << "    expected fair rate:   " << fairRate);
}
Пример #8
0
void CreditDefaultSwapTest::testImpliedHazardRate() {

    BOOST_TEST_MESSAGE("Testing implied hazard-rate for credit-default swaps...");

    SavedSettings backup;

    // Initialize curves
    Calendar calendar = TARGET();
    Date today = calendar.adjust(Date::todaysDate());
    Settings::instance().evaluationDate() = today;

    Rate h1 = 0.30, h2 = 0.40;
    DayCounter dayCounter = Actual365Fixed();

    std::vector<Date> dates(3);
    std::vector<Real> hazardRates(3);
    dates[0] = today;
    hazardRates[0] = h1;

    dates[1] = today + 5*Years;
    hazardRates[1] = h1;

    dates[2] = today + 10*Years;
    hazardRates[2] = h2;

    RelinkableHandle<DefaultProbabilityTermStructure> probabilityCurve;
    probabilityCurve.linkTo(ext::shared_ptr<DefaultProbabilityTermStructure>(
                    new InterpolatedHazardRateCurve<BackwardFlat>(dates,
                                                                  hazardRates,
                                                                  dayCounter)));

    RelinkableHandle<YieldTermStructure> discountCurve;
    discountCurve.linkTo(ext::shared_ptr<YieldTermStructure>(
                            new FlatForward(today,0.03,Actual360())));


    Frequency frequency = Semiannual;
    BusinessDayConvention convention = ModifiedFollowing;

    Date issueDate = calendar.advance(today, -6, Months);
    Rate fixedRate = 0.0120;
    DayCounter cdsDayCount = Actual360();
    Real notional = 10000.0;
    Real recoveryRate = 0.4;

    Rate latestRate = Null<Rate>();
    for (Integer n=6; n<=10; ++n) {

        Date maturity = calendar.advance(issueDate, n, Years);
        Schedule schedule(issueDate, maturity, Period(frequency), calendar,
                          convention, convention,
                          DateGeneration::Forward, false);

        CreditDefaultSwap cds(Protection::Seller, notional, fixedRate,
                              schedule, convention, cdsDayCount,
                              true, true);
        cds.setPricingEngine(ext::shared_ptr<PricingEngine>(
                         new MidPointCdsEngine(probabilityCurve,
                                               recoveryRate, discountCurve)));

        Real NPV = cds.NPV();
        Rate flatRate = cds.impliedHazardRate(NPV, discountCurve,
                                              dayCounter,
                                              recoveryRate);

        if (flatRate < h1 || flatRate > h2) {
            BOOST_ERROR("implied hazard rate outside expected range\n"
                        << "    maturity: " << n << " years\n"
                        << "    expected minimum: " << h1 << "\n"
                        << "    expected maximum: " << h2 << "\n"
                        << "    implied rate:     " << flatRate);
        }

        if (n > 6 && flatRate < latestRate) {
            BOOST_ERROR("implied hazard rate decreasing with swap maturity\n"
                        << "    maturity: " << n << " years\n"
                        << "    previous rate: " << latestRate << "\n"
                        << "    implied rate:  " << flatRate);
        }

        latestRate = flatRate;

        RelinkableHandle<DefaultProbabilityTermStructure> probability;
        probability.linkTo(ext::shared_ptr<DefaultProbabilityTermStructure>(
         new FlatHazardRate(
           today,
           Handle<Quote>(ext::shared_ptr<Quote>(new SimpleQuote(flatRate))),
           dayCounter)));

        CreditDefaultSwap cds2(Protection::Seller, notional, fixedRate,
                               schedule, convention, cdsDayCount,
                               true, true);
        cds2.setPricingEngine(ext::shared_ptr<PricingEngine>(
                               new MidPointCdsEngine(probability,recoveryRate,
                                                     discountCurve)));

        Real NPV2 = cds2.NPV();
        Real tolerance = 1.0;
        if (std::fabs(NPV-NPV2) > tolerance) {
            BOOST_ERROR("failed to reproduce NPV with implied rate\n"
                        << "    expected:   " << NPV << "\n"
                        << "    calculated: " << NPV2);
        }
    }
}
Пример #9
0
int main(int, char* []) {

    try {

        boost::timer timer;
        std::cout << std::endl;

        /*********************
         ***  MARKET DATA  ***
         *********************/

        RelinkableHandle<YieldTermStructure> euriborTermStructure;
        boost::shared_ptr<IborIndex> euribor3m(
                                       new Euribor3M(euriborTermStructure));

        Date todaysDate = Date(23, May, 2006);
        Settings::instance().evaluationDate() = todaysDate;

        Calendar calendar = euribor3m->fixingCalendar();
        Integer fixingDays = euribor3m->fixingDays();
        Date settlementDate = calendar.advance(todaysDate, fixingDays, Days);

        std::cout << "Today: " << todaysDate.weekday()
                  << ", " << todaysDate << std::endl;

        std::cout << "Settlement date: " << settlementDate.weekday()
                  << ", " << settlementDate << std::endl;


        // 3 month term FRA quotes (index refers to monthsToStart)
        Rate threeMonthFraQuote[10];

        threeMonthFraQuote[1]=0.030;
        threeMonthFraQuote[2]=0.031;
        threeMonthFraQuote[3]=0.032;
        threeMonthFraQuote[6]=0.033;
        threeMonthFraQuote[9]=0.034;

        /********************
         ***    QUOTES    ***
         ********************/

        // SimpleQuote stores a value which can be manually changed;
        // other Quote subclasses could read the value from a database
        // or some kind of data feed.


        // FRAs
        boost::shared_ptr<SimpleQuote> fra1x4Rate(
                                      new SimpleQuote(threeMonthFraQuote[1]));
        boost::shared_ptr<SimpleQuote> fra2x5Rate(
                                      new SimpleQuote(threeMonthFraQuote[2]));
        boost::shared_ptr<SimpleQuote> fra3x6Rate(
                                      new SimpleQuote(threeMonthFraQuote[3]));
        boost::shared_ptr<SimpleQuote> fra6x9Rate(
                                      new SimpleQuote(threeMonthFraQuote[6]));
        boost::shared_ptr<SimpleQuote> fra9x12Rate(
                                      new SimpleQuote(threeMonthFraQuote[9]));

        RelinkableHandle<Quote> h1x4;  h1x4.linkTo(fra1x4Rate);
        RelinkableHandle<Quote> h2x5;  h2x5.linkTo(fra2x5Rate);
        RelinkableHandle<Quote> h3x6;  h3x6.linkTo(fra3x6Rate);
        RelinkableHandle<Quote> h6x9;  h6x9.linkTo(fra6x9Rate);
        RelinkableHandle<Quote> h9x12; h9x12.linkTo(fra9x12Rate);

        /*********************
         ***  RATE HELPERS ***
         *********************/

        // RateHelpers are built from the above quotes together with
        // other instrument dependant infos.  Quotes are passed in
        // relinkable handles which could be relinked to some other
        // data source later.

        DayCounter fraDayCounter = euribor3m->dayCounter();
        BusinessDayConvention convention = euribor3m->businessDayConvention();
        bool endOfMonth = euribor3m->endOfMonth();

        boost::shared_ptr<RateHelper> fra1x4(
                           new FraRateHelper(h1x4, 1, 4,
                                             fixingDays, calendar, convention,
                                             endOfMonth, fraDayCounter));

        boost::shared_ptr<RateHelper> fra2x5(
                           new FraRateHelper(h2x5, 2, 5,
                                             fixingDays, calendar, convention,
                                             endOfMonth, fraDayCounter));

        boost::shared_ptr<RateHelper> fra3x6(
                           new FraRateHelper(h3x6, 3, 6,
                                             fixingDays, calendar, convention,
                                             endOfMonth, fraDayCounter));

        boost::shared_ptr<RateHelper> fra6x9(
                           new FraRateHelper(h6x9, 6, 9,
                                             fixingDays, calendar, convention,
                                             endOfMonth, fraDayCounter));

        boost::shared_ptr<RateHelper> fra9x12(
                           new FraRateHelper(h9x12, 9, 12,
                                             fixingDays, calendar, convention,
                                             endOfMonth, fraDayCounter));


        /*********************
         **  CURVE BUILDING **
         *********************/

        // Any DayCounter would be fine.
        // ActualActual::ISDA ensures that 30 years is 30.0
        DayCounter termStructureDayCounter =
            ActualActual(ActualActual::ISDA);

        double tolerance = 1.0e-15;

        // A FRA curve
        std::vector<boost::shared_ptr<RateHelper> > fraInstruments;

        fraInstruments.push_back(fra1x4);
        fraInstruments.push_back(fra2x5);
        fraInstruments.push_back(fra3x6);
        fraInstruments.push_back(fra6x9);
        fraInstruments.push_back(fra9x12);

        boost::shared_ptr<YieldTermStructure> fraTermStructure(
                     new PiecewiseYieldCurve<Discount,LogLinear>(
                                         settlementDate, fraInstruments,
                                         termStructureDayCounter,
                                         tolerance));


        // Term structures used for pricing/discounting

        RelinkableHandle<YieldTermStructure> discountingTermStructure;
        discountingTermStructure.linkTo(fraTermStructure);


        /***********************
         ***  construct FRA's ***
         ***********************/

        Calendar fraCalendar = euribor3m->fixingCalendar();
        BusinessDayConvention fraBusinessDayConvention =
            euribor3m->businessDayConvention();
        Position::Type fraFwdType = Position::Long;
        Real fraNotional = 100.0;
        const Integer FraTermMonths = 3;
        Integer monthsToStart[] = { 1, 2, 3, 6, 9 };

        euriborTermStructure.linkTo(fraTermStructure);

        cout << endl;
        cout << "Test FRA construction, NPV calculation, and FRA purchase"
             << endl
             << endl;

        Size i;
        for (i=0; i<LENGTH(monthsToStart); i++) {

            Date fraValueDate = fraCalendar.advance(
                                       settlementDate,monthsToStart[i],Months,
                                       fraBusinessDayConvention);

            Date fraMaturityDate = fraCalendar.advance(
                                            fraValueDate,FraTermMonths,Months,
                                            fraBusinessDayConvention);

            Rate fraStrikeRate = threeMonthFraQuote[monthsToStart[i]];

            ForwardRateAgreement myFRA(fraValueDate, fraMaturityDate,
                                       fraFwdType,fraStrikeRate,
                                       fraNotional, euribor3m,
                                       discountingTermStructure);

            cout << "3m Term FRA, Months to Start: "
                 << monthsToStart[i]
                 << endl;
            cout << "strike FRA rate: "
                 << io::rate(fraStrikeRate)
                 << endl;
            cout << "FRA 3m forward rate: "
                 << myFRA.forwardRate()
                 << endl;
            cout << "FRA market quote: "
                 << io::rate(threeMonthFraQuote[monthsToStart[i]])
                 << endl;
            cout << "FRA spot value: "
                 << myFRA.spotValue()
                 << endl;
            cout << "FRA forward value: "
                 << myFRA.forwardValue()
                 << endl;
            cout << "FRA implied Yield: "
                 << myFRA.impliedYield(myFRA.spotValue(),
                                       myFRA.forwardValue(),
                                       settlementDate,
                                       Simple,
                                       fraDayCounter)
                 << endl;
            cout << "market Zero Rate: "
                 << discountingTermStructure->zeroRate(fraMaturityDate,
                                                       fraDayCounter,
                                                       Simple)
                 << endl;
            cout << "FRA NPV [should be zero]: "
                 << myFRA.NPV()
                 << endl
                 << endl;

        }




        cout << endl << endl;
        cout << "Now take a 100 basis-point upward shift in FRA quotes "
             << "and examine NPV"
             << endl
             << endl;

        const Real BpsShift = 0.01;

        threeMonthFraQuote[1]=0.030+BpsShift;
        threeMonthFraQuote[2]=0.031+BpsShift;
        threeMonthFraQuote[3]=0.032+BpsShift;
        threeMonthFraQuote[6]=0.033+BpsShift;
        threeMonthFraQuote[9]=0.034+BpsShift;

        fra1x4Rate->setValue(threeMonthFraQuote[1]);
        fra2x5Rate->setValue(threeMonthFraQuote[2]);
        fra3x6Rate->setValue(threeMonthFraQuote[3]);
        fra6x9Rate->setValue(threeMonthFraQuote[6]);
        fra9x12Rate->setValue(threeMonthFraQuote[9]);


        for (i=0; i<LENGTH(monthsToStart); i++) {

            Date fraValueDate = fraCalendar.advance(
                                       settlementDate,monthsToStart[i],Months,
                                       fraBusinessDayConvention);

            Date fraMaturityDate = fraCalendar.advance(
                                            fraValueDate,FraTermMonths,Months,
                                            fraBusinessDayConvention);

            Rate fraStrikeRate =
                threeMonthFraQuote[monthsToStart[i]] - BpsShift;

            ForwardRateAgreement myFRA(fraValueDate, fraMaturityDate,
                                       fraFwdType, fraStrikeRate,
                                       fraNotional, euribor3m,
                                       discountingTermStructure);

            cout << "3m Term FRA, 100 notional, Months to Start = "
                 << monthsToStart[i]
                 << endl;
            cout << "strike FRA rate: "
                 << io::rate(fraStrikeRate)
                 << endl;
            cout << "FRA 3m forward rate: "
                 << myFRA.forwardRate()
                 << endl;
            cout << "FRA market quote: "
                 << io::rate(threeMonthFraQuote[monthsToStart[i]])
                 << endl;
            cout << "FRA spot value: "
                 << myFRA.spotValue()
                 << endl;
            cout << "FRA forward value: "
                 << myFRA.forwardValue()
                 << endl;
            cout << "FRA implied Yield: "
                 << myFRA.impliedYield(myFRA.spotValue(),
                                       myFRA.forwardValue(),
                                       settlementDate,
                                       Simple,
                                       fraDayCounter)
                 << endl;
            cout << "market Zero Rate: "
                 << discountingTermStructure->zeroRate(fraMaturityDate,
                                                       fraDayCounter,
                                                       Simple)
                 << endl;
            cout << "FRA NPV [should be positive]: "
                 << myFRA.NPV()
                 << endl
                 << endl;
        }

        double seconds = timer.elapsed();
        Integer hours = int(seconds/3600);
        seconds -= hours * 3600;
        Integer minutes = int(seconds/60);
        seconds -= minutes * 60;
        cout << " \nRun completed in ";
        if (hours > 0)
            cout << hours << " h ";
        if (hours > 0 || minutes > 0)
            cout << minutes << " m ";
        cout << fixed << setprecision(0)
             << seconds << " s\n" << endl;

        return 0;

    } catch (exception& e) {
        cerr << e.what() << endl;
        return 1;
    } catch (...) {
        cerr << "unknown error" << endl;
        return 1;
    }
}
/*Market Data ->  FRA Quote -> FRA rate helper -> Curve Building -> Construct FRA*/
int main(int, char* []) {

    try {

        boost::timer timer;
        std::cout << std::endl;
        std::ifstream       file("data.csv");
        CSVRow data_row;
        file >> data_row;
        const size_t num_data = data_row.size()/2;



        /*********************
         ***  MARKET DATA  ***
         *********************/

        RelinkableHandle<YieldTermStructure> euriborTermStructure;
        boost::shared_ptr<IborIndex> euribor3m(
                                       new Euribor3M(euriborTermStructure));

        Date todaysDate = Date(23, May, 2006);
        Settings::instance().evaluationDate() = todaysDate;

        Calendar calendar = euribor3m->fixingCalendar();
        Integer fixingDays = euribor3m->fixingDays();
        Date settlementDate = calendar.advance(todaysDate, fixingDays, Days);

        std::cout << "Today: " << todaysDate.weekday()
                  << ", " << todaysDate << std::endl;

        std::cout << "Settlement date: " << settlementDate.weekday()
                  << ", " << settlementDate << std::endl;


        // 3 month term FRA quotes (index refers to monthsToStart)
        vector <stFRAMarketData> vecMarketData;

        for(size_t i = 0 ; i < num_data; i++) {
          stFRAMarketData element_data;
          convertFromString(element_data.iMonthToStart, data_row[i]);
          element_data.iTermDuration = 3; //3 month term
          convertFromString(element_data.rateFraQuote, data_row[i + num_data]);
          vecMarketData.push_back(element_data);
        }



        /********************
         ***    QUOTES    ***
         ********************/

        // SimpleQuote stores a value which can be manually changed;
        // other Quote subclasses could read the value from a database
        // or some kind of data feed.


        // FRAs
        std::vector <boost::shared_ptr<SimpleQuote> > vecFRAQuote;

        for(size_t i = 0 ; i < num_data; i++) {
          boost::shared_ptr<SimpleQuote> fraRate(new SimpleQuote(vecMarketData[i].rateFraQuote));
          vecFRAQuote.push_back(fraRate);
        }
        std::vector <RelinkableHandle<Quote> > vecQuoteHandle;

        for(size_t i = 0 ; i < num_data; i++) { 
          RelinkableHandle<Quote> hQuote;
          hQuote.linkTo(vecFRAQuote[i]);
          vecQuoteHandle.push_back(hQuote);
        }

        /*********************
         ***  RATE HELPERS ***
         *********************/

        // RateHelpers are built from the above quotes together with
        // other instrument dependant infos.  Quotes are passed in
        // relinkable handles which could be relinked to some other
        // data source later.

        DayCounter fraDayCounter = euribor3m->dayCounter();
        BusinessDayConvention convention = euribor3m->businessDayConvention();
        bool endOfMonth = euribor3m->endOfMonth();
        std::vector < boost::shared_ptr<RateHelper> > vecRateHelper;

        for(size_t i = 0 ; i < num_data; i++) {
          boost::shared_ptr<RateHelper> fra_helper(
                           new FraRateHelper(vecQuoteHandle[i],vecMarketData[i].iMonthToStart, 
                                             vecMarketData[i].iMonthToStart + vecMarketData[i].iTermDuration,
                                             fixingDays, calendar, convention,
                                             endOfMonth, fraDayCounter));

          vecRateHelper.push_back(fra_helper);
        }

        /*********************
         **  CURVE BUILDING **
         *********************/

        // Any DayCounter would be fine.
        // ActualActual::ISDA ensures that 30 years is 30.0
        DayCounter termStructureDayCounter =
            ActualActual(ActualActual::ISDA);

        double tolerance = 1.0e-15;

        // A FRA curve
        boost::shared_ptr<YieldTermStructure> fraTermStructure(
                     new PiecewiseYieldCurve<Discount,LogLinear>(
                                         settlementDate, vecRateHelper,
                                         termStructureDayCounter,
                                         tolerance));

        // Term structures used for pricing/discounting

        RelinkableHandle<YieldTermStructure> discountingTermStructure;
        discountingTermStructure.linkTo(fraTermStructure);


        /***********************
         ***  construct FRA's ***
         ***********************/

        Calendar fraCalendar = euribor3m->fixingCalendar();
        BusinessDayConvention fraBusinessDayConvention =
            euribor3m->businessDayConvention();
        Position::Type fraFwdType = Position::Long;
        Real fraNotional = 100.0;
        //const Integer FraTermMonths = 3;
        //Integer monthsToStart[] = { 1, 2, 3, 6, 9 };

        euriborTermStructure.linkTo(fraTermStructure);

        cout << endl;
        cout << "Test FRA construction, NPV calculation, and FRA purchase"
             << endl
             << endl;

        Size i;
        for (i=0; i < num_data; i++) {

            Date fraValueDate = fraCalendar.advance(
                                       settlementDate,vecMarketData[i].iMonthToStart, Months,
                                       fraBusinessDayConvention);

            Date fraMaturityDate = fraCalendar.advance(
                                            fraValueDate,vecMarketData[i].iTermDuration,Months,
                                            fraBusinessDayConvention);

            Rate fraStrikeRate = vecMarketData[i].rateFraQuote;

            ForwardRateAgreement myFRA(fraValueDate, fraMaturityDate,
                                       fraFwdType,fraStrikeRate,
                                       fraNotional, euribor3m,
                                       discountingTermStructure);

            cout << vecMarketData[i].iTermDuration<<"m Term FRA, Months to Start: "
                 << vecMarketData[i].iMonthToStart
                 << endl;
            cout << "strike FRA rate: "
                 << io::rate(fraStrikeRate)
                 << endl;
            cout << "FRA 3m forward rate: "
                 << myFRA.forwardRate()
                 << endl;
            cout << "FRA market quote: "
                 << io::rate(vecMarketData[i].rateFraQuote)
                 << endl;
            cout << "FRA spot value: "
                 << myFRA.spotValue()
                 << endl;
            cout << "FRA forward value: "
                 << myFRA.forwardValue()
                 << endl;
            cout << "FRA implied Yield: "
                 << myFRA.impliedYield(myFRA.spotValue(),
                                       myFRA.forwardValue(),
                                       settlementDate,
                                       Simple,
                                       fraDayCounter)
                 << endl;
            cout << "market Zero Rate: "
                 << discountingTermStructure->zeroRate(fraMaturityDate,
                                                       fraDayCounter,
                                                       Simple)
                 << endl;
            cout << "FRA NPV [should be zero]: "
                 << myFRA.NPV()
                 << endl
                 << endl;

        }




        cout << endl << endl;
        cout << "Now take a 100 basis-point upward shift in FRA quotes "
             << "and examine NPV"
             << endl
             << endl;

        const Real BpsShift = 0.01;

        for(size_t i = 0; i< num_data; i++ ) {
          vecMarketData[i].rateFraQuote += BpsShift;
          vecFRAQuote[i]->setValue(vecMarketData[i].rateFraQuote);
        }

        for (i=0; i<num_data; i++) {

            Date fraValueDate = fraCalendar.advance(
                                       settlementDate,vecMarketData[i].iMonthToStart,Months,
                                       fraBusinessDayConvention);

            Date fraMaturityDate = fraCalendar.advance(
                                            fraValueDate,vecMarketData[i].iTermDuration,Months,
                                            fraBusinessDayConvention);

            Rate fraStrikeRate =
                vecMarketData[i].rateFraQuote - BpsShift;

            ForwardRateAgreement myFRA(fraValueDate, fraMaturityDate,
                                       fraFwdType, fraStrikeRate,
                                       fraNotional, euribor3m,
                                       discountingTermStructure);

            cout << vecMarketData[i].iTermDuration <<"m Term FRA, 100 notional, Months to Start = "
                 << vecMarketData[i].iMonthToStart
                 << endl;
            cout << "strike FRA rate: "
                 << io::rate(fraStrikeRate)
                 << endl;
            cout << "FRA 3m forward rate: "
                 << myFRA.forwardRate()
                 << endl;
            cout << "FRA market quote: "
                 << io::rate(vecMarketData[i].rateFraQuote)
                 << endl;
            cout << "FRA spot value: "
                 << myFRA.spotValue()
                 << endl;
            cout << "FRA forward value: "
                 << myFRA.forwardValue()
                 << endl;
            cout << "FRA implied Yield: "
                 << myFRA.impliedYield(myFRA.spotValue(),
                                       myFRA.forwardValue(),
                                       settlementDate,
                                       Simple,
                                       fraDayCounter)
                 << endl;
            cout << "market Zero Rate: "
                 << discountingTermStructure->zeroRate(fraMaturityDate,
                                                       fraDayCounter,
                                                       Simple)
                 << endl;
            cout << "FRA NPV [should be positive]: "
                 << myFRA.NPV()
                 << endl
                 << endl;
        }

        Real seconds = timer.elapsed();
        Integer hours = int(seconds/3600);
        seconds -= hours * 3600;
        Integer minutes = int(seconds/60);
        seconds -= minutes * 60;
        cout << " \nRun completed in ";
        if (hours > 0)
            cout << hours << " h ";
        if (hours > 0 || minutes > 0)
            cout << minutes << " m ";
        cout << fixed << setprecision(0)
             << seconds << " s\n" << endl;

        return 0;

    } catch (exception& e) {
        cerr << e.what() << endl;
        return 1;
    } catch (...) {
        cerr << "unknown error" << endl;
        return 1;
    }
}
Пример #11
0
void CreditDefaultSwapTest::testCachedMarketValue() {

    BOOST_TEST_MESSAGE(
        "Testing credit-default swap against cached market values...");

    SavedSettings backup;

    Settings::instance().evaluationDate() = Date(9,June,2006);
    Date evalDate = Settings::instance().evaluationDate();
    Calendar calendar = UnitedStates();

    std::vector<Date> discountDates;
    discountDates.push_back(evalDate);
    discountDates.push_back(calendar.advance(evalDate, 1, Weeks,  ModifiedFollowing));
    discountDates.push_back(calendar.advance(evalDate, 1, Months, ModifiedFollowing));
    discountDates.push_back(calendar.advance(evalDate, 2, Months, ModifiedFollowing));
    discountDates.push_back(calendar.advance(evalDate, 3, Months, ModifiedFollowing));
    discountDates.push_back(calendar.advance(evalDate, 6, Months, ModifiedFollowing));
    discountDates.push_back(calendar.advance(evalDate,12, Months, ModifiedFollowing));
    discountDates.push_back(calendar.advance(evalDate, 2, Years, ModifiedFollowing));
    discountDates.push_back(calendar.advance(evalDate, 3, Years, ModifiedFollowing));
    discountDates.push_back(calendar.advance(evalDate, 4, Years, ModifiedFollowing));
    discountDates.push_back(calendar.advance(evalDate, 5, Years, ModifiedFollowing));
    discountDates.push_back(calendar.advance(evalDate, 6, Years, ModifiedFollowing));
    discountDates.push_back(calendar.advance(evalDate, 7, Years, ModifiedFollowing));
    discountDates.push_back(calendar.advance(evalDate, 8, Years, ModifiedFollowing));
    discountDates.push_back(calendar.advance(evalDate, 9, Years, ModifiedFollowing));
    discountDates.push_back(calendar.advance(evalDate,10, Years, ModifiedFollowing));
    discountDates.push_back(calendar.advance(evalDate,15, Years, ModifiedFollowing));

    std::vector<DiscountFactor> dfs;
    dfs.push_back(1.0);
    dfs.push_back(0.9990151375768731);
    dfs.push_back(0.99570502636871183);
    dfs.push_back(0.99118260474528685);
    dfs.push_back(0.98661167950906203);
    dfs.push_back(0.9732592953359388 );
    dfs.push_back(0.94724424481038083);
    dfs.push_back(0.89844996737120875  );
    dfs.push_back(0.85216647839921411  );
    dfs.push_back(0.80775477692556874  );
    dfs.push_back(0.76517289234200347  );
    dfs.push_back(0.72401019553182933  );
    dfs.push_back(0.68503909569219212  );
    dfs.push_back(0.64797499814013748  );
    dfs.push_back(0.61263171936255534  );
    dfs.push_back(0.5791942350748791   );
    dfs.push_back(0.43518868769953606  );

    const DayCounter& curveDayCounter=Actual360();

    RelinkableHandle<YieldTermStructure> discountCurve;
    discountCurve.linkTo(
        ext::shared_ptr<YieldTermStructure>(
            new DiscountCurve(discountDates, dfs, curveDayCounter)));

    DayCounter dayCounter = Thirty360();
    std::vector<Date> dates;
    dates.push_back(evalDate);
    dates.push_back(calendar.advance(evalDate, 6, Months, ModifiedFollowing));
    dates.push_back(calendar.advance(evalDate, 1, Years, ModifiedFollowing));
    dates.push_back(calendar.advance(evalDate, 2, Years, ModifiedFollowing));
    dates.push_back(calendar.advance(evalDate, 3, Years, ModifiedFollowing));
    dates.push_back(calendar.advance(evalDate, 4, Years, ModifiedFollowing));
    dates.push_back(calendar.advance(evalDate, 5, Years, ModifiedFollowing));
    dates.push_back(calendar.advance(evalDate, 7, Years, ModifiedFollowing));
    dates.push_back(calendar.advance(evalDate,10, Years, ModifiedFollowing));

    std::vector<Probability> defaultProbabilities;
    defaultProbabilities.push_back(0.0000);
    defaultProbabilities.push_back(0.0047);
    defaultProbabilities.push_back(0.0093);
    defaultProbabilities.push_back(0.0286);
    defaultProbabilities.push_back(0.0619);
    defaultProbabilities.push_back(0.0953);
    defaultProbabilities.push_back(0.1508);
    defaultProbabilities.push_back(0.2288);
    defaultProbabilities.push_back(0.3666);

    std::vector<Real> hazardRates;
    hazardRates.push_back(0.0);
    for (Size i=1; i<dates.size(); ++i) {
        Time t1 = dayCounter.yearFraction(dates[0], dates[i-1]);
        Time t2 = dayCounter.yearFraction(dates[0], dates[i]);
        Probability S1 = 1.0 - defaultProbabilities[i-1];
        Probability S2 = 1.0 - defaultProbabilities[i];
        hazardRates.push_back(std::log(S1/S2)/(t2-t1));
    }

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

    // Testing credit default swap

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

    Schedule schedule(issueDate, maturity, Period(cdsFrequency), calendar,
                      cdsConvention, cdsConvention,
                      DateGeneration::Forward, false);

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

    CreditDefaultSwap cds(Protection::Seller, cdsNotional, fixedRate,
                          schedule, cdsConvention, dayCount, true, true);
    cds.setPricingEngine(ext::shared_ptr<PricingEngine>(
                          new MidPointCdsEngine(piecewiseFlatHazardRate,
                                                recoveryRate,discountCurve)));

    Real calculatedNpv = cds.NPV();
    Real 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;

    Real tolerance = 1e-9;

    if (std::fabs(npv - calculatedNpv) > tolerance)
        BOOST_ERROR(
            "Failed to reproduce the npv for the given credit-default swap\n"
            << std::setprecision(10)
            << "    computed NPV:  " << calculatedNpv << "\n"
            << "    Given NPV:     " << npv);

    if (std::fabs(fairRate - calculatedFairRate) > tolerance)
        BOOST_ERROR(
            "Failed to reproduce the fair rate for the given credit-default swap\n"
            << std::setprecision(10)
            << "    computed fair rate:  " << calculatedFairRate << "\n"
            << "    Given fair rate:     " << fairRate);
}
Пример #12
0
void QtSwap::qtswap() {

    try {

        boost::timer timer;
        std::cout << std::endl;

        /*********************
         ***  MARKET DATA  ***
         *********************/

        Calendar calendar = TARGET();
        Date settlementDate(22, September, 2004);
        // must be a business day
        settlementDate = calendar.adjust(settlementDate);

        Integer fixingDays = 2;
        Date todaysDate = calendar.advance(settlementDate, -fixingDays, Days);
        // nothing to do with Date::todaysDate
        Settings::instance().evaluationDate() = todaysDate;


        todaysDate = Settings::instance().evaluationDate();
        std::cout << "Today: " << todaysDate.weekday()
                  << ", " << todaysDate << std::endl;

        std::cout << "Settlement date: " << settlementDate.weekday()
                  << ", " << settlementDate << std::endl;

        // deposits
        Rate d1wQuote=0.0382;
        Rate d1mQuote=0.0372;
        Rate d3mQuote=0.0363;
        Rate d6mQuote=0.0353;
        Rate d9mQuote=0.0348;
        Rate d1yQuote=0.0345;
        // FRAs
        Rate fra3x6Quote=0.037125;
        Rate fra6x9Quote=0.037125;
        Rate fra6x12Quote=0.037125;
        // futures
        Real fut1Quote=96.2875;
        Real fut2Quote=96.7875;
        Real fut3Quote=96.9875;
        Real fut4Quote=96.6875;
        Real fut5Quote=96.4875;
        Real fut6Quote=96.3875;
        Real fut7Quote=96.2875;
        Real fut8Quote=96.0875;
        // swaps
        Rate s2yQuote=0.037125;
        Rate s3yQuote=0.0398;
        Rate s5yQuote=0.0443;
        Rate s10yQuote=0.05165;
        Rate s15yQuote=0.055175;


        /********************
         ***    QUOTES    ***
         ********************/

        // SimpleQuote stores a value which can be manually changed;
        // other Quote subclasses could read the value from a database
        // or some kind of data feed.

        // deposits
        boost::shared_ptr<Quote> d1wRate(new SimpleQuote(d1wQuote));
        boost::shared_ptr<Quote> d1mRate(new SimpleQuote(d1mQuote));
        boost::shared_ptr<Quote> d3mRate(new SimpleQuote(d3mQuote));
        boost::shared_ptr<Quote> d6mRate(new SimpleQuote(d6mQuote));
        boost::shared_ptr<Quote> d9mRate(new SimpleQuote(d9mQuote));
        boost::shared_ptr<Quote> d1yRate(new SimpleQuote(d1yQuote));
        // FRAs
        boost::shared_ptr<Quote> fra3x6Rate(new SimpleQuote(fra3x6Quote));
        boost::shared_ptr<Quote> fra6x9Rate(new SimpleQuote(fra6x9Quote));
        boost::shared_ptr<Quote> fra6x12Rate(new SimpleQuote(fra6x12Quote));
        // futures
        boost::shared_ptr<Quote> fut1Price(new SimpleQuote(fut1Quote));
        boost::shared_ptr<Quote> fut2Price(new SimpleQuote(fut2Quote));
        boost::shared_ptr<Quote> fut3Price(new SimpleQuote(fut3Quote));
        boost::shared_ptr<Quote> fut4Price(new SimpleQuote(fut4Quote));
        boost::shared_ptr<Quote> fut5Price(new SimpleQuote(fut5Quote));
        boost::shared_ptr<Quote> fut6Price(new SimpleQuote(fut6Quote));
        boost::shared_ptr<Quote> fut7Price(new SimpleQuote(fut7Quote));
        boost::shared_ptr<Quote> fut8Price(new SimpleQuote(fut8Quote));
        // swaps
        boost::shared_ptr<Quote> s2yRate(new SimpleQuote(s2yQuote));
        boost::shared_ptr<Quote> s3yRate(new SimpleQuote(s3yQuote));
        boost::shared_ptr<Quote> s5yRate(new SimpleQuote(s5yQuote));
        boost::shared_ptr<Quote> s10yRate(new SimpleQuote(s10yQuote));
        boost::shared_ptr<Quote> s15yRate(new SimpleQuote(s15yQuote));


        /*********************
         ***  RATE HELPERS ***
         *********************/

        // RateHelpers are built from the above quotes together with
        // other instrument dependant infos.  Quotes are passed in
        // relinkable handles which could be relinked to some other
        // data source later.

        // deposits
        DayCounter depositDayCounter = Actual360();

        boost::shared_ptr<RateHelper> d1w(new DepositRateHelper(
                                              Handle<Quote>(d1wRate),
                                              1*Weeks, fixingDays,
                                              calendar, ModifiedFollowing,
                                              true, depositDayCounter));
        boost::shared_ptr<RateHelper> d1m(new DepositRateHelper(
                                              Handle<Quote>(d1mRate),
                                              1*Months, fixingDays,
                                              calendar, ModifiedFollowing,
                                              true, depositDayCounter));
        boost::shared_ptr<RateHelper> d3m(new DepositRateHelper(
                                              Handle<Quote>(d3mRate),
                                              3*Months, fixingDays,
                                              calendar, ModifiedFollowing,
                                              true, depositDayCounter));
        boost::shared_ptr<RateHelper> d6m(new DepositRateHelper(
                                              Handle<Quote>(d6mRate),
                                              6*Months, fixingDays,
                                              calendar, ModifiedFollowing,
                                              true, depositDayCounter));
        boost::shared_ptr<RateHelper> d9m(new DepositRateHelper(
                                              Handle<Quote>(d9mRate),
                                              9*Months, fixingDays,
                                              calendar, ModifiedFollowing,
                                              true, depositDayCounter));
        boost::shared_ptr<RateHelper> d1y(new DepositRateHelper(
                                              Handle<Quote>(d1yRate),
                                              1*Years, fixingDays,
                                              calendar, ModifiedFollowing,
                                              true, depositDayCounter));


        // setup FRAs
        boost::shared_ptr<RateHelper> fra3x6(new FraRateHelper(
                Handle<Quote>(fra3x6Rate),
                3, 6, fixingDays, calendar, ModifiedFollowing,
                true, depositDayCounter));
        boost::shared_ptr<RateHelper> fra6x9(new FraRateHelper(
                Handle<Quote>(fra6x9Rate),
                6, 9, fixingDays, calendar, ModifiedFollowing,
                true, depositDayCounter));
        boost::shared_ptr<RateHelper> fra6x12(new FraRateHelper(
                Handle<Quote>(fra6x12Rate),
                6, 12, fixingDays, calendar, ModifiedFollowing,
                true, depositDayCounter));


        // setup futures
        // Rate convexityAdjustment = 0.0;
        Integer futMonths = 3;
        Date imm = IMM::nextDate(settlementDate);
        boost::shared_ptr<RateHelper> fut1(new FuturesRateHelper(
                                               Handle<Quote>(fut1Price),
                                               imm,
                                               futMonths, calendar, ModifiedFollowing,
                                               true, depositDayCounter));
        imm = IMM::nextDate(imm+1);
        boost::shared_ptr<RateHelper> fut2(new FuturesRateHelper(
                                               Handle<Quote>(fut2Price),
                                               imm,
                                               futMonths, calendar, ModifiedFollowing,
                                               true, depositDayCounter));
        imm = IMM::nextDate(imm+1);
        boost::shared_ptr<RateHelper> fut3(new FuturesRateHelper(
                                               Handle<Quote>(fut3Price),
                                               imm,
                                               futMonths, calendar, ModifiedFollowing,
                                               true, depositDayCounter));
        imm = IMM::nextDate(imm+1);
        boost::shared_ptr<RateHelper> fut4(new FuturesRateHelper(
                                               Handle<Quote>(fut4Price),
                                               imm,
                                               futMonths, calendar, ModifiedFollowing,
                                               true, depositDayCounter));
        imm = IMM::nextDate(imm+1);
        boost::shared_ptr<RateHelper> fut5(new FuturesRateHelper(
                                               Handle<Quote>(fut5Price),
                                               imm,
                                               futMonths, calendar, ModifiedFollowing,
                                               true, depositDayCounter));
        imm = IMM::nextDate(imm+1);
        boost::shared_ptr<RateHelper> fut6(new FuturesRateHelper(
                                               Handle<Quote>(fut6Price),
                                               imm,
                                               futMonths, calendar, ModifiedFollowing,
                                               true, depositDayCounter));
        imm = IMM::nextDate(imm+1);
        boost::shared_ptr<RateHelper> fut7(new FuturesRateHelper(
                                               Handle<Quote>(fut7Price),
                                               imm,
                                               futMonths, calendar, ModifiedFollowing,
                                               true, depositDayCounter));
        imm = IMM::nextDate(imm+1);
        boost::shared_ptr<RateHelper> fut8(new FuturesRateHelper(
                                               Handle<Quote>(fut8Price),
                                               imm,
                                               futMonths, calendar, ModifiedFollowing,
                                               true, depositDayCounter));


        // setup swaps
        Frequency swFixedLegFrequency = Annual;
        BusinessDayConvention swFixedLegConvention = Unadjusted;
        DayCounter swFixedLegDayCounter = Thirty360(Thirty360::European);
        boost::shared_ptr<IborIndex> swFloatingLegIndex(new Euribor6M);

        boost::shared_ptr<RateHelper> s2y(new SwapRateHelper(
                                              Handle<Quote>(s2yRate), 2*Years,
                                              calendar, swFixedLegFrequency,
                                              swFixedLegConvention, swFixedLegDayCounter,
                                              swFloatingLegIndex));
        boost::shared_ptr<RateHelper> s3y(new SwapRateHelper(
                                              Handle<Quote>(s3yRate), 3*Years,
                                              calendar, swFixedLegFrequency,
                                              swFixedLegConvention, swFixedLegDayCounter,
                                              swFloatingLegIndex));
        boost::shared_ptr<RateHelper> s5y(new SwapRateHelper(
                                              Handle<Quote>(s5yRate), 5*Years,
                                              calendar, swFixedLegFrequency,
                                              swFixedLegConvention, swFixedLegDayCounter,
                                              swFloatingLegIndex));
        boost::shared_ptr<RateHelper> s10y(new SwapRateHelper(
                                               Handle<Quote>(s10yRate), 10*Years,
                                               calendar, swFixedLegFrequency,
                                               swFixedLegConvention, swFixedLegDayCounter,
                                               swFloatingLegIndex));
        boost::shared_ptr<RateHelper> s15y(new SwapRateHelper(
                                               Handle<Quote>(s15yRate), 15*Years,
                                               calendar, swFixedLegFrequency,
                                               swFixedLegConvention, swFixedLegDayCounter,
                                               swFloatingLegIndex));


        /*********************
         **  CURVE BUILDING **
         *********************/

        // Any DayCounter would be fine.
        // ActualActual::ISDA ensures that 30 years is 30.0
        DayCounter termStructureDayCounter =
            ActualActual(ActualActual::ISDA);


        double tolerance = 1.0e-15;

        // A depo-swap curve
        std::vector<boost::shared_ptr<RateHelper> > depoSwapInstruments;
        depoSwapInstruments.push_back(d1w);
        depoSwapInstruments.push_back(d1m);
        depoSwapInstruments.push_back(d3m);
        depoSwapInstruments.push_back(d6m);
        depoSwapInstruments.push_back(d9m);
        depoSwapInstruments.push_back(d1y);
        depoSwapInstruments.push_back(s2y);
        depoSwapInstruments.push_back(s3y);
        depoSwapInstruments.push_back(s5y);
        depoSwapInstruments.push_back(s10y);
        depoSwapInstruments.push_back(s15y);
        boost::shared_ptr<YieldTermStructure> depoSwapTermStructure(
            new PiecewiseYieldCurve<Discount,LogLinear>(
                settlementDate, depoSwapInstruments,
                termStructureDayCounter,
                tolerance));


        // A depo-futures-swap curve
        std::vector<boost::shared_ptr<RateHelper> > depoFutSwapInstruments;
        depoFutSwapInstruments.push_back(d1w);
        depoFutSwapInstruments.push_back(d1m);
        depoFutSwapInstruments.push_back(fut1);
        depoFutSwapInstruments.push_back(fut2);
        depoFutSwapInstruments.push_back(fut3);
        depoFutSwapInstruments.push_back(fut4);
        depoFutSwapInstruments.push_back(fut5);
        depoFutSwapInstruments.push_back(fut6);
        depoFutSwapInstruments.push_back(fut7);
        depoFutSwapInstruments.push_back(fut8);
        depoFutSwapInstruments.push_back(s3y);
        depoFutSwapInstruments.push_back(s5y);
        depoFutSwapInstruments.push_back(s10y);
        depoFutSwapInstruments.push_back(s15y);
        boost::shared_ptr<YieldTermStructure> depoFutSwapTermStructure(
            new PiecewiseYieldCurve<Discount,LogLinear>(
                settlementDate, depoFutSwapInstruments,
                termStructureDayCounter,
                tolerance));


        // A depo-FRA-swap curve
        std::vector<boost::shared_ptr<RateHelper> > depoFRASwapInstruments;
        depoFRASwapInstruments.push_back(d1w);
        depoFRASwapInstruments.push_back(d1m);
        depoFRASwapInstruments.push_back(d3m);
        depoFRASwapInstruments.push_back(fra3x6);
        depoFRASwapInstruments.push_back(fra6x9);
        depoFRASwapInstruments.push_back(fra6x12);
        depoFRASwapInstruments.push_back(s2y);
        depoFRASwapInstruments.push_back(s3y);
        depoFRASwapInstruments.push_back(s5y);
        depoFRASwapInstruments.push_back(s10y);
        depoFRASwapInstruments.push_back(s15y);
        boost::shared_ptr<YieldTermStructure> depoFRASwapTermStructure(
            new PiecewiseYieldCurve<Discount,LogLinear>(
                settlementDate, depoFRASwapInstruments,
                termStructureDayCounter,
                tolerance));


        // Term structures that will be used for pricing:
        // the one used for discounting cash flows
        RelinkableHandle<YieldTermStructure> discountingTermStructure;
        // the one used for forward rate forecasting
        RelinkableHandle<YieldTermStructure> forecastingTermStructure;


        /*********************
        * SWAPS TO BE PRICED *
        **********************/

        // constant nominal 1,000,000 Euro
        Real nominal = 1000000.0;
        // fixed leg
        Frequency fixedLegFrequency = Annual;
        BusinessDayConvention fixedLegConvention = Unadjusted;
        BusinessDayConvention floatingLegConvention = ModifiedFollowing;
        DayCounter fixedLegDayCounter = Thirty360(Thirty360::European);
        Rate fixedRate = 0.04;
        DayCounter floatingLegDayCounter = Actual360();

        // floating leg
        Frequency floatingLegFrequency = Semiannual;
        boost::shared_ptr<IborIndex> euriborIndex(
            new Euribor6M(forecastingTermStructure));
        Spread spread = 0.0;

        Integer lenghtInYears = 5;
        VanillaSwap::Type swapType = VanillaSwap::Payer;

        Date maturity = settlementDate + lenghtInYears*Years;
        Schedule fixedSchedule(settlementDate, maturity,
                               Period(fixedLegFrequency),
                               calendar, fixedLegConvention,
                               fixedLegConvention,
                               DateGeneration::Forward, false);
        Schedule floatSchedule(settlementDate, maturity,
                               Period(floatingLegFrequency),
                               calendar, floatingLegConvention,
                               floatingLegConvention,
                               DateGeneration::Forward, false);

        VanillaSwap spot5YearSwap(swapType, nominal,
                                  fixedSchedule, fixedRate, fixedLegDayCounter,
                                  floatSchedule, euriborIndex, spread,
                                  floatingLegDayCounter);

        Date fwdStart = calendar.advance(settlementDate, 1, Years);
        Date fwdMaturity = fwdStart + lenghtInYears*Years;
        Schedule fwdFixedSchedule(fwdStart, fwdMaturity,
                                  Period(fixedLegFrequency),
                                  calendar, fixedLegConvention,
                                  fixedLegConvention,
                                  DateGeneration::Forward, false);
        Schedule fwdFloatSchedule(fwdStart, fwdMaturity,
                                  Period(floatingLegFrequency),
                                  calendar, floatingLegConvention,
                                  floatingLegConvention,
                                  DateGeneration::Forward, false);
        VanillaSwap oneYearForward5YearSwap(swapType, nominal,
                                            fwdFixedSchedule, fixedRate, fixedLegDayCounter,
                                            fwdFloatSchedule, euriborIndex, spread,
                                            floatingLegDayCounter);


        /***************
        * SWAP PRICING *
        ****************/

        // utilities for reporting
        std::vector<std::string> headers(4);
        headers[0] = "term structure";
        headers[1] = "net present value";
        headers[2] = "fair spread";
        headers[3] = "fair fixed rate";
        std::string separator = " | ";
        Size width = headers[0].size() + separator.size()
                     + headers[1].size() + separator.size()
                     + headers[2].size() + separator.size()
                     + headers[3].size() + separator.size() - 1;
        std::string rule(width, '-'), dblrule(width, '=');
        std::string tab(8, ' ');

        // calculations
        std::cout << dblrule << std::endl;
        std::cout <<  "5-year market swap-rate = "
                  << std::setprecision(2) << io::rate(s5yRate->value())
                  << std::endl;
        std::cout << dblrule << std::endl;

        std::cout << tab << "5-years swap paying "
                  << io::rate(fixedRate) << std::endl;
        std::cout << headers[0] << separator
                  << headers[1] << separator
                  << headers[2] << separator
                  << headers[3] << separator << std::endl;
        std::cout << rule << std::endl;

        Real NPV;
        Rate fairRate;
        Spread fairSpread;

        boost::shared_ptr<PricingEngine> swapEngine(
            new DiscountingSwapEngine(discountingTermStructure));

        spot5YearSwap.setPricingEngine(swapEngine);
        oneYearForward5YearSwap.setPricingEngine(swapEngine);

        // Of course, you're not forced to really use different curves
        forecastingTermStructure.linkTo(depoSwapTermStructure);
        discountingTermStructure.linkTo(depoSwapTermStructure);

        NPV = spot5YearSwap.NPV();
        fairSpread = spot5YearSwap.fairSpread();
        fairRate = spot5YearSwap.fairRate();

        std::cout << std::setw(headers[0].size())
                  << "depo-swap" << separator;
        std::cout << std::setw(headers[1].size())
                  << std::fixed << std::setprecision(2) << NPV << separator;
        std::cout << std::setw(headers[2].size())
                  << io::rate(fairSpread) << separator;
        std::cout << std::setw(headers[3].size())
                  << io::rate(fairRate) << separator;
        std::cout << std::endl;


        // let's check that the 5 years swap has been correctly re-priced
        QL_REQUIRE(std::fabs(fairRate-s5yQuote)<1e-8,
                   "5-years swap mispriced by "
                   << io::rate(std::fabs(fairRate-s5yQuote)));


        forecastingTermStructure.linkTo(depoFutSwapTermStructure);
        discountingTermStructure.linkTo(depoFutSwapTermStructure);

        NPV = spot5YearSwap.NPV();
        fairSpread = spot5YearSwap.fairSpread();
        fairRate = spot5YearSwap.fairRate();

        std::cout << std::setw(headers[0].size())
                  << "depo-fut-swap" << separator;
        std::cout << std::setw(headers[1].size())
                  << std::fixed << std::setprecision(2) << NPV << separator;
        std::cout << std::setw(headers[2].size())
                  << io::rate(fairSpread) << separator;
        std::cout << std::setw(headers[3].size())
                  << io::rate(fairRate) << separator;
        std::cout << std::endl;

        QL_REQUIRE(std::fabs(fairRate-s5yQuote)<1e-8,
                   "5-years swap mispriced!");


        forecastingTermStructure.linkTo(depoFRASwapTermStructure);
        discountingTermStructure.linkTo(depoFRASwapTermStructure);

        NPV = spot5YearSwap.NPV();
        fairSpread = spot5YearSwap.fairSpread();
        fairRate = spot5YearSwap.fairRate();

        std::cout << std::setw(headers[0].size())
                  << "depo-FRA-swap" << separator;
        std::cout << std::setw(headers[1].size())
                  << std::fixed << std::setprecision(2) << NPV << separator;
        std::cout << std::setw(headers[2].size())
                  << io::rate(fairSpread) << separator;
        std::cout << std::setw(headers[3].size())
                  << io::rate(fairRate) << separator;
        std::cout << std::endl;

        QL_REQUIRE(std::fabs(fairRate-s5yQuote)<1e-8,
                   "5-years swap mispriced!");


        std::cout << rule << std::endl;

        // now let's price the 1Y forward 5Y swap

        std::cout << tab << "5-years, 1-year forward swap paying "
                  << io::rate(fixedRate) << std::endl;
        std::cout << headers[0] << separator
                  << headers[1] << separator
                  << headers[2] << separator
                  << headers[3] << separator << std::endl;
        std::cout << rule << std::endl;


        forecastingTermStructure.linkTo(depoSwapTermStructure);
        discountingTermStructure.linkTo(depoSwapTermStructure);

        NPV = oneYearForward5YearSwap.NPV();
        fairSpread = oneYearForward5YearSwap.fairSpread();
        fairRate = oneYearForward5YearSwap.fairRate();

        std::cout << std::setw(headers[0].size())
                  << "depo-swap" << separator;
        std::cout << std::setw(headers[1].size())
                  << std::fixed << std::setprecision(2) << NPV << separator;
        std::cout << std::setw(headers[2].size())
                  << io::rate(fairSpread) << separator;
        std::cout << std::setw(headers[3].size())
                  << io::rate(fairRate) << separator;
        std::cout << std::endl;


        forecastingTermStructure.linkTo(depoFutSwapTermStructure);
        discountingTermStructure.linkTo(depoFutSwapTermStructure);

        NPV = oneYearForward5YearSwap.NPV();
        fairSpread = oneYearForward5YearSwap.fairSpread();
        fairRate = oneYearForward5YearSwap.fairRate();

        std::cout << std::setw(headers[0].size())
                  << "depo-fut-swap" << separator;
        std::cout << std::setw(headers[1].size())
                  << std::fixed << std::setprecision(2) << NPV << separator;
        std::cout << std::setw(headers[2].size())
                  << io::rate(fairSpread) << separator;
        std::cout << std::setw(headers[3].size())
                  << io::rate(fairRate) << separator;
        std::cout << std::endl;


        forecastingTermStructure.linkTo(depoFRASwapTermStructure);
        discountingTermStructure.linkTo(depoFRASwapTermStructure);

        NPV = oneYearForward5YearSwap.NPV();
        fairSpread = oneYearForward5YearSwap.fairSpread();
        fairRate = oneYearForward5YearSwap.fairRate();

        std::cout << std::setw(headers[0].size())
                  << "depo-FRA-swap" << separator;
        std::cout << std::setw(headers[1].size())
                  << std::fixed << std::setprecision(2) << NPV << separator;
        std::cout << std::setw(headers[2].size())
                  << io::rate(fairSpread) << separator;
        std::cout << std::setw(headers[3].size())
                  << io::rate(fairRate) << separator;
        std::cout << std::endl;


        // now let's say that the 5-years swap rate goes up to 4.60%.
        // A smarter market element--say, connected to a data source-- would
        // notice the change itself. Since we're using SimpleQuotes,
        // we'll have to change the value manually--which forces us to
        // downcast the handle and use the SimpleQuote
        // interface. In any case, the point here is that a change in the
        // value contained in the Quote triggers a new bootstrapping
        // of the curve and a repricing of the swap.

        boost::shared_ptr<SimpleQuote> fiveYearsRate =
            boost::dynamic_pointer_cast<SimpleQuote>(s5yRate);
        fiveYearsRate->setValue(0.0460);

        std::cout << dblrule << std::endl;
        std::cout <<  "5-year market swap-rate = "
                  << io::rate(s5yRate->value()) << std::endl;
        std::cout << dblrule << std::endl;

        std::cout << tab << "5-years swap paying "
                  << io::rate(fixedRate) << std::endl;
        std::cout << headers[0] << separator
                  << headers[1] << separator
                  << headers[2] << separator
                  << headers[3] << separator << std::endl;
        std::cout << rule << std::endl;

        // now get the updated results
        forecastingTermStructure.linkTo(depoSwapTermStructure);
        discountingTermStructure.linkTo(depoSwapTermStructure);

        NPV = spot5YearSwap.NPV();
        fairSpread = spot5YearSwap.fairSpread();
        fairRate = spot5YearSwap.fairRate();

        std::cout << std::setw(headers[0].size())
                  << "depo-swap" << separator;
        std::cout << std::setw(headers[1].size())
                  << std::fixed << std::setprecision(2) << NPV << separator;
        std::cout << std::setw(headers[2].size())
                  << io::rate(fairSpread) << separator;
        std::cout << std::setw(headers[3].size())
                  << io::rate(fairRate) << separator;
        std::cout << std::endl;

        QL_REQUIRE(std::fabs(fairRate-s5yRate->value())<1e-8,
                   "5-years swap mispriced!");


        forecastingTermStructure.linkTo(depoFutSwapTermStructure);
        discountingTermStructure.linkTo(depoFutSwapTermStructure);

        NPV = spot5YearSwap.NPV();
        fairSpread = spot5YearSwap.fairSpread();
        fairRate = spot5YearSwap.fairRate();

        std::cout << std::setw(headers[0].size())
                  << "depo-fut-swap" << separator;
        std::cout << std::setw(headers[1].size())
                  << std::fixed << std::setprecision(2) << NPV << separator;
        std::cout << std::setw(headers[2].size())
                  << io::rate(fairSpread) << separator;
        std::cout << std::setw(headers[3].size())
                  << io::rate(fairRate) << separator;
        std::cout << std::endl;

        QL_REQUIRE(std::fabs(fairRate-s5yRate->value())<1e-8,
                   "5-years swap mispriced!");


        forecastingTermStructure.linkTo(depoFRASwapTermStructure);
        discountingTermStructure.linkTo(depoFRASwapTermStructure);

        NPV = spot5YearSwap.NPV();
        fairSpread = spot5YearSwap.fairSpread();
        fairRate = spot5YearSwap.fairRate();

        std::cout << std::setw(headers[0].size())
                  << "depo-FRA-swap" << separator;
        std::cout << std::setw(headers[1].size())
                  << std::fixed << std::setprecision(2) << NPV << separator;
        std::cout << std::setw(headers[2].size())
                  << io::rate(fairSpread) << separator;
        std::cout << std::setw(headers[3].size())
                  << io::rate(fairRate) << separator;
        std::cout << std::endl;

        QL_REQUIRE(std::fabs(fairRate-s5yRate->value())<1e-8,
                   "5-years swap mispriced!");

        std::cout << rule << std::endl;

        // the 1Y forward 5Y swap changes as well

        std::cout << tab << "5-years, 1-year forward swap paying "
                  << io::rate(fixedRate) << std::endl;
        std::cout << headers[0] << separator
                  << headers[1] << separator
                  << headers[2] << separator
                  << headers[3] << separator << std::endl;
        std::cout << rule << std::endl;


        forecastingTermStructure.linkTo(depoSwapTermStructure);
        discountingTermStructure.linkTo(depoSwapTermStructure);

        NPV = oneYearForward5YearSwap.NPV();
        fairSpread = oneYearForward5YearSwap.fairSpread();
        fairRate = oneYearForward5YearSwap.fairRate();

        std::cout << std::setw(headers[0].size())
                  << "depo-swap" << separator;
        std::cout << std::setw(headers[1].size())
                  << std::fixed << std::setprecision(2) << NPV << separator;
        std::cout << std::setw(headers[2].size())
                  << io::rate(fairSpread) << separator;
        std::cout << std::setw(headers[3].size())
                  << io::rate(fairRate) << separator;
        std::cout << std::endl;


        forecastingTermStructure.linkTo(depoFutSwapTermStructure);
        discountingTermStructure.linkTo(depoFutSwapTermStructure);

        NPV = oneYearForward5YearSwap.NPV();
        fairSpread = oneYearForward5YearSwap.fairSpread();
        fairRate = oneYearForward5YearSwap.fairRate();

        std::cout << std::setw(headers[0].size())
                  << "depo-fut-swap" << separator;
        std::cout << std::setw(headers[1].size())
                  << std::fixed << std::setprecision(2) << NPV << separator;
        std::cout << std::setw(headers[2].size())
                  << io::rate(fairSpread) << separator;
        std::cout << std::setw(headers[3].size())
                  << io::rate(fairRate) << separator;
        std::cout << std::endl;


        forecastingTermStructure.linkTo(depoFRASwapTermStructure);
        discountingTermStructure.linkTo(depoFRASwapTermStructure);

        NPV = oneYearForward5YearSwap.NPV();
        fairSpread = oneYearForward5YearSwap.fairSpread();
        fairRate = oneYearForward5YearSwap.fairRate();

        std::cout << std::setw(headers[0].size())
                  << "depo-FRA-swap" << separator;
        std::cout << std::setw(headers[1].size())
                  << std::fixed << std::setprecision(2) << NPV << separator;
        std::cout << std::setw(headers[2].size())
                  << io::rate(fairSpread) << separator;
        std::cout << std::setw(headers[3].size())
                  << io::rate(fairRate) << separator;
        std::cout << std::endl;

        Real seconds = timer.elapsed();
        Integer hours = int(seconds/3600);
        seconds -= hours * 3600;
        Integer minutes = int(seconds/60);
        seconds -= minutes * 60;
        std::cout << " \nRun completed in ";
        if (hours > 0)
            std::cout << hours << " h ";
        if (hours > 0 || minutes > 0)
            std::cout << minutes << " m ";
        std::cout << std::fixed << std::setprecision(0)
                  << seconds << " s\n" << std::endl;

    } catch (std::exception& e) {
        std::cerr << e.what() << std::endl;
    } catch (...) {
        std::cerr << "unknown error" << std::endl;
    }
}
Пример #13
0
void InflationTest::testYYTermStructure() {
    BOOST_MESSAGE("Testing year-on-year inflation term structure...");

    SavedSettings backup;

    // try the YY UK
    Calendar calendar = UnitedKingdom();
    BusinessDayConvention bdc = ModifiedFollowing;
    Date evaluationDate(13, August, 2007);
    evaluationDate = calendar.adjust(evaluationDate);
    Settings::instance().evaluationDate() = evaluationDate;


    // fixing data
    Date from(1, January, 2005);
    Date to(13, August, 2007);
    Schedule rpiSchedule = MakeSchedule().from(from).to(to)
    .withTenor(1*Months)
    .withCalendar(UnitedKingdom())
    .withConvention(ModifiedFollowing);
    Real fixData[] = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0,
        192.2, 192.2, 192.6, 193.1, 193.3, 193.6,
        194.1, 193.4, 194.2, 195.0, 196.5, 197.7,
        198.5, 198.5, 199.2, 200.1, 200.4, 201.1,
        202.7, 201.6, 203.1, 204.4, 205.4, 206.2,
        207.3, -999.0, -999 };

    RelinkableHandle<YoYInflationTermStructure> hy;
    bool interp = false;
    boost::shared_ptr<YYUKRPIr> iir(new YYUKRPIr(interp, hy));
    for (Size i=0; i<rpiSchedule.size();i++) {
        iir->addFixing(rpiSchedule[i], fixData[i]);
    }



    boost::shared_ptr<YieldTermStructure> nominalTS = nominalTermStructure();

    // now build the YoY inflation curve
    Datum yyData[] = {
        { Date(13, August, 2008), 2.95 },
        { Date(13, August, 2009), 2.95 },
        { Date(13, August, 2010), 2.93 },
        { Date(15, August, 2011), 2.955 },
        { Date(13, August, 2012), 2.945 },
        { Date(13, August, 2013), 2.985 },
        { Date(13, August, 2014), 3.01 },
        { Date(13, August, 2015), 3.035 },
        { Date(13, August, 2016), 3.055 },  // note that
        { Date(13, August, 2017), 3.075 },  // some dates will be on
        { Date(13, August, 2019), 3.105 },  // holidays but the payment
        { Date(15, August, 2022), 3.135 },  // calendar will roll them
        { Date(13, August, 2027), 3.155 },
        { Date(13, August, 2032), 3.145 },
        { Date(13, August, 2037), 3.145 }
    };

    Period observationLag = Period(2,Months);
    DayCounter dc = Thirty360();

    // now build the helpers ...
    std::vector<boost::shared_ptr<BootstrapHelper<YoYInflationTermStructure> > > helpers =
    makeHelpers<YoYInflationTermStructure,YearOnYearInflationSwapHelper,
    YoYInflationIndex>(yyData, LENGTH(yyData), iir,
                        observationLag,
                        calendar, bdc, dc);

    Rate baseYYRate = yyData[0].rate/100.0;
    boost::shared_ptr<PiecewiseYoYInflationCurve<Linear> > pYYTS(
        new PiecewiseYoYInflationCurve<Linear>(
                evaluationDate, calendar, dc, observationLag,
                iir->frequency(),iir->interpolated(), baseYYRate,
                Handle<YieldTermStructure>(nominalTS), helpers));
    pYYTS->recalculate();

    // validation
    // yoy swaps should reprice to zero
    // yy rates should not equal yySwap rates
    Real eps = 0.000001;
    // usual swap engine
    Handle<YieldTermStructure> hTS(nominalTS);
    boost::shared_ptr<PricingEngine> sppe(new DiscountingSwapEngine(hTS));

    // make sure that the index has the latest yoy term structure
    hy.linkTo(pYYTS);

    for (Size j = 1; j < LENGTH(yyData); j++) {

        from = nominalTS->referenceDate();
        to = yyData[j].date;
        Schedule yoySchedule = MakeSchedule().from(from).to(to)
        .withConvention(Unadjusted) // fixed leg gets calendar from
        .withCalendar(calendar)     // schedule
        .withTenor(1*Years)
        .backwards()
        ;

        YearOnYearInflationSwap yyS2(YearOnYearInflationSwap::Payer,
                                        1000000.0,
                                        yoySchedule,//fixed schedule, but same as yoy
                                        yyData[j].rate/100.0,
                                        dc,
                                        yoySchedule,
                                        iir,
                                        observationLag,
                                        0.0,        //spread on index
                                        dc,
                                        UnitedKingdom());

        yyS2.setPricingEngine(sppe);



        BOOST_CHECK_MESSAGE(fabs(yyS2.NPV())<eps,"fresh yoy swap NPV!=0 from TS "
                <<"swap quote for pt " << j
                << ", is " << yyData[j].rate/100.0
                <<" vs YoY rate "<< pYYTS->yoyRate(yyData[j].date-observationLag)
                <<" at quote date "<<(yyData[j].date-observationLag)
                <<", NPV of a fresh yoy swap is " << yyS2.NPV()
                <<"\n      fair rate " << yyS2.fairRate()
                <<" payment "<<yyS2.paymentConvention());
    }

    Size jj=3;
    for (Size k = 0; k < 14; k++) {

        from = nominalTS->referenceDate() - k*Months;
        to = yyData[jj].date - k*Months;
        Schedule yoySchedule = MakeSchedule().from(from).to(to)
        .withConvention(Unadjusted) // fixed leg gets calendar from
        .withCalendar(calendar)     // schedule
        .withTenor(1*Years)
        .backwards()
        ;

        YearOnYearInflationSwap yyS3(YearOnYearInflationSwap::Payer,
                                    1000000.0,
                                    yoySchedule,//fixed schedule, but same as yoy
                                    yyData[jj].rate/100.0,
                                    dc,
                                    yoySchedule,
                                    iir,
                                    observationLag,
                                    0.0,        //spread on index
                                    dc,
                                    UnitedKingdom());

        yyS3.setPricingEngine(sppe);

        BOOST_CHECK_MESSAGE(fabs(yyS3.NPV())< 20000.0,
                            "unexpected size of aged YoY swap, aged "
                            <<k<<" months: YY aged NPV = " << yyS3.NPV()
                            <<", legs "<< yyS3.legNPV(0) << " and " << yyS3.legNPV(1)
                            );
    }

}
Пример #14
0
void CreditDefaultSwapTest::testFairUpfront() {

    BOOST_TEST_MESSAGE(
        "Testing fair-upfront calculation for credit-default swaps...");

    SavedSettings backup;

    // Initialize curves
    Calendar calendar = TARGET();
    Date today = calendar.adjust(Date::todaysDate());
    Settings::instance().evaluationDate() = today;

    Handle<Quote> hazardRate = Handle<Quote>(
                ext::shared_ptr<Quote>(new SimpleQuote(0.01234)));
    RelinkableHandle<DefaultProbabilityTermStructure> probabilityCurve;
    probabilityCurve.linkTo(
        ext::shared_ptr<DefaultProbabilityTermStructure>(
                   new FlatHazardRate(0, calendar, hazardRate, Actual360())));

    RelinkableHandle<YieldTermStructure> discountCurve;
    discountCurve.linkTo(ext::shared_ptr<YieldTermStructure>(
                            new FlatForward(today,0.06,Actual360())));

    // Build the schedule
    Date issueDate = today;
    Date maturity = calendar.advance(issueDate, 10, Years);
    BusinessDayConvention convention = Following;

    Schedule schedule =
        MakeSchedule().from(issueDate)
                      .to(maturity)
                      .withFrequency(Quarterly)
                      .withCalendar(calendar)
                      .withTerminationDateConvention(convention)
                      .withRule(DateGeneration::TwentiethIMM);

    // Build the CDS
    Rate fixedRate = 0.05;
    Rate upfront = 0.001;
    DayCounter dayCount = Actual360();
    Real notional = 10000.0;
    Real recoveryRate = 0.4;

    ext::shared_ptr<PricingEngine> engine(
          new MidPointCdsEngine(probabilityCurve, recoveryRate,
                                discountCurve, true));

    CreditDefaultSwap cds(Protection::Seller, notional, upfront, fixedRate,
                          schedule, convention, dayCount, true, true);
    cds.setPricingEngine(engine);

    Rate fairUpfront = cds.fairUpfront();

    CreditDefaultSwap fairCds(Protection::Seller, notional,
                              fairUpfront, fixedRate,
                              schedule, convention, dayCount, true, true);
    fairCds.setPricingEngine(engine);

    Real fairNPV = fairCds.NPV();
    Real tolerance = 1e-10;

    if (std::fabs(fairNPV) > tolerance)
        BOOST_ERROR(
            "Failed to reproduce null NPV with calculated fair upfront\n"
            << "    calculated upfront: " << io::rate(fairUpfront) << "\n"
            << "    calculated NPV:     " << fairNPV);

    // same with null upfront to begin with
    upfront = 0.0;
    CreditDefaultSwap cds2(Protection::Seller, notional, upfront, fixedRate,
                           schedule, convention, dayCount, true, true);
    cds2.setPricingEngine(engine);

    fairUpfront = cds2.fairUpfront();

    CreditDefaultSwap fairCds2(Protection::Seller, notional,
                               fairUpfront, fixedRate,
                               schedule, convention, dayCount, true, true);
    fairCds2.setPricingEngine(engine);

    fairNPV = fairCds2.NPV();

    if (std::fabs(fairNPV) > tolerance)
        BOOST_ERROR(
            "Failed to reproduce null NPV with calculated fair upfront\n"
            << "    calculated upfront: " << io::rate(fairUpfront) << "\n"
            << "    calculated NPV:     " << fairNPV);
}
Пример #15
0
int main(int, char* []) {

    try {

        boost::timer timer;
        std::cout << std::endl;

        /*********************
         ***  MARKET DATA  ***
         *********************/

        Calendar calendar = TARGET();

        Date settlementDate(18, September, 2008);
        // must be a business day
        settlementDate = calendar.adjust(settlementDate);

        Integer fixingDays = 3;
        Natural settlementDays = 3;

        Date todaysDate = calendar.advance(settlementDate, -fixingDays, Days);
        // nothing to do with Date::todaysDate
        Settings::instance().evaluationDate() = todaysDate;

        std::cout << "Today: " << todaysDate.weekday()
        << ", " << todaysDate << std::endl;

        std::cout << "Settlement date: " << settlementDate.weekday()
        << ", " << settlementDate << std::endl;


        // Building of the bonds discounting yield curve

        /*********************
         ***  RATE HELPERS ***
         *********************/

        // RateHelpers are built from the above quotes together with
        // other instrument dependant infos.  Quotes are passed in
        // relinkable handles which could be relinked to some other
        // data source later.

        // Common data

        // ZC rates for the short end
         Rate zc3mQuote=0.0096;
         Rate zc6mQuote=0.0145;
         Rate zc1yQuote=0.0194;

         boost::shared_ptr<Quote> zc3mRate(new SimpleQuote(zc3mQuote));
         boost::shared_ptr<Quote> zc6mRate(new SimpleQuote(zc6mQuote));
         boost::shared_ptr<Quote> zc1yRate(new SimpleQuote(zc1yQuote));

         DayCounter zcBondsDayCounter = Actual365Fixed();

         boost::shared_ptr<RateHelper> zc3m(new DepositRateHelper(
                 Handle<Quote>(zc3mRate),
                 3*Months, fixingDays,
                 calendar, ModifiedFollowing,
                 true, zcBondsDayCounter));
         boost::shared_ptr<RateHelper> zc6m(new DepositRateHelper(
                 Handle<Quote>(zc6mRate),
                 6*Months, fixingDays,
                 calendar, ModifiedFollowing,
                 true, zcBondsDayCounter));
         boost::shared_ptr<RateHelper> zc1y(new DepositRateHelper(
                 Handle<Quote>(zc1yRate),
                 1*Years, fixingDays,
                 calendar, ModifiedFollowing,
                 true, zcBondsDayCounter));

        // setup bonds
        Real redemption = 100.0;

        const Size numberOfBonds = 5;

        Date issueDates[] = {
                Date (15, March, 2005),
                Date (15, June, 2005),
                Date (30, June, 2006),
                Date (15, November, 2002),
                Date (15, May, 1987)
        };

        Date maturities[] = {
                Date (31, August, 2010),
                Date (31, August, 2011),
                Date (31, August, 2013),
                Date (15, August, 2018),
                Date (15, May, 2038)
        };

        Real couponRates[] = {
                0.02375,
                0.04625,
                0.03125,
                0.04000,
                0.04500
        };

        Real marketQuotes[] = {
                100.390625,
                106.21875,
                100.59375,
                101.6875,
                102.140625
        };

        std::vector< boost::shared_ptr<SimpleQuote> > quote;
        for (Size i=0; i<numberOfBonds; i++) {
            boost::shared_ptr<SimpleQuote> cp(new SimpleQuote(marketQuotes[i]));
            quote.push_back(cp);
        }

        RelinkableHandle<Quote> quoteHandle[numberOfBonds];
        for (Size i=0; i<numberOfBonds; i++) {
            quoteHandle[i].linkTo(quote[i]);
        }

        // Definition of the rate helpers
        std::vector<boost::shared_ptr<BondHelper> > bondsHelpers;

        for (Size i=0; i<numberOfBonds; i++) {

            Schedule schedule(issueDates[i], maturities[i], Period(Semiannual), UnitedStates(UnitedStates::GovernmentBond),
                    Unadjusted, Unadjusted, DateGeneration::Backward, false);

            boost::shared_ptr<FixedRateBondHelper> bondHelper(new FixedRateBondHelper(
                    quoteHandle[i],
                    settlementDays,
                    100.0,
                    schedule,
                    std::vector<Rate>(1,couponRates[i]),
                    ActualActual(ActualActual::Bond),
                    Unadjusted,
                    redemption,
                    issueDates[i]));

            // the above could also be done by creating a
            // FixedRateBond instance and writing:
            //
            // boost::shared_ptr<BondHelper> bondHelper(
            //         new BondHelper(quoteHandle[i], bond));
            //
            // This would also work for bonds that still don't have a
            // specialized helper, such as floating-rate bonds.


            bondsHelpers.push_back(bondHelper);
        }

        /*********************
         **  CURVE BUILDING **
         *********************/

         // Any DayCounter would be fine.
         // ActualActual::ISDA ensures that 30 years is 30.0
         DayCounter termStructureDayCounter =
             ActualActual(ActualActual::ISDA);

         double tolerance = 1.0e-15;

         // A depo-bond curve
         std::vector<boost::shared_ptr<RateHelper> > bondInstruments;

         // Adding the ZC bonds to the curve for the short end
         bondInstruments.push_back(zc3m);
         bondInstruments.push_back(zc6m);
         bondInstruments.push_back(zc1y);

         // Adding the Fixed rate bonds to the curve for the long end
         for (Size i=0; i<numberOfBonds; i++) {
             bondInstruments.push_back(bondsHelpers[i]);
         }

         boost::shared_ptr<YieldTermStructure> bondDiscountingTermStructure(
                 new PiecewiseYieldCurve<Discount,LogLinear>(
                         settlementDate, bondInstruments,
                         termStructureDayCounter,
                         tolerance));

         // Building of the Libor forecasting curve
         // deposits
         Rate d1wQuote=0.043375;
         Rate d1mQuote=0.031875;
         Rate d3mQuote=0.0320375;
         Rate d6mQuote=0.03385;
         Rate d9mQuote=0.0338125;
         Rate d1yQuote=0.0335125;
         // swaps
         Rate s2yQuote=0.0295;
         Rate s3yQuote=0.0323;
         Rate s5yQuote=0.0359;
         Rate s10yQuote=0.0412;
         Rate s15yQuote=0.0433;


         /********************
          ***    QUOTES    ***
          ********************/

         // SimpleQuote stores a value which can be manually changed;
         // other Quote subclasses could read the value from a database
         // or some kind of data feed.

         // deposits
         boost::shared_ptr<Quote> d1wRate(new SimpleQuote(d1wQuote));
         boost::shared_ptr<Quote> d1mRate(new SimpleQuote(d1mQuote));
         boost::shared_ptr<Quote> d3mRate(new SimpleQuote(d3mQuote));
         boost::shared_ptr<Quote> d6mRate(new SimpleQuote(d6mQuote));
         boost::shared_ptr<Quote> d9mRate(new SimpleQuote(d9mQuote));
         boost::shared_ptr<Quote> d1yRate(new SimpleQuote(d1yQuote));
         // swaps
         boost::shared_ptr<Quote> s2yRate(new SimpleQuote(s2yQuote));
         boost::shared_ptr<Quote> s3yRate(new SimpleQuote(s3yQuote));
         boost::shared_ptr<Quote> s5yRate(new SimpleQuote(s5yQuote));
         boost::shared_ptr<Quote> s10yRate(new SimpleQuote(s10yQuote));
         boost::shared_ptr<Quote> s15yRate(new SimpleQuote(s15yQuote));

         /*********************
          ***  RATE HELPERS ***
          *********************/

         // RateHelpers are built from the above quotes together with
         // other instrument dependant infos.  Quotes are passed in
         // relinkable handles which could be relinked to some other
         // data source later.

         // deposits
         DayCounter depositDayCounter = Actual360();

         boost::shared_ptr<RateHelper> d1w(new DepositRateHelper(
                 Handle<Quote>(d1wRate),
                 1*Weeks, fixingDays,
                 calendar, ModifiedFollowing,
                 true, depositDayCounter));
         boost::shared_ptr<RateHelper> d1m(new DepositRateHelper(
                 Handle<Quote>(d1mRate),
                 1*Months, fixingDays,
                 calendar, ModifiedFollowing,
                 true, depositDayCounter));
         boost::shared_ptr<RateHelper> d3m(new DepositRateHelper(
                 Handle<Quote>(d3mRate),
                 3*Months, fixingDays,
                 calendar, ModifiedFollowing,
                 true, depositDayCounter));
         boost::shared_ptr<RateHelper> d6m(new DepositRateHelper(
                 Handle<Quote>(d6mRate),
                 6*Months, fixingDays,
                 calendar, ModifiedFollowing,
                 true, depositDayCounter));
         boost::shared_ptr<RateHelper> d9m(new DepositRateHelper(
                 Handle<Quote>(d9mRate),
                 9*Months, fixingDays,
                 calendar, ModifiedFollowing,
                 true, depositDayCounter));
         boost::shared_ptr<RateHelper> d1y(new DepositRateHelper(
                 Handle<Quote>(d1yRate),
                 1*Years, fixingDays,
                 calendar, ModifiedFollowing,
                 true, depositDayCounter));

         // setup swaps
         Frequency swFixedLegFrequency = Annual;
         BusinessDayConvention swFixedLegConvention = Unadjusted;
         DayCounter swFixedLegDayCounter = Thirty360(Thirty360::European);
         boost::shared_ptr<IborIndex> swFloatingLegIndex(new Euribor6M);

         const Period forwardStart(1*Days);

         boost::shared_ptr<RateHelper> s2y(new SwapRateHelper(
                 Handle<Quote>(s2yRate), 2*Years,
                 calendar, swFixedLegFrequency,
                 swFixedLegConvention, swFixedLegDayCounter,
                 swFloatingLegIndex, Handle<Quote>(),forwardStart));
         boost::shared_ptr<RateHelper> s3y(new SwapRateHelper(
                 Handle<Quote>(s3yRate), 3*Years,
                 calendar, swFixedLegFrequency,
                 swFixedLegConvention, swFixedLegDayCounter,
                 swFloatingLegIndex, Handle<Quote>(),forwardStart));
         boost::shared_ptr<RateHelper> s5y(new SwapRateHelper(
                 Handle<Quote>(s5yRate), 5*Years,
                 calendar, swFixedLegFrequency,
                 swFixedLegConvention, swFixedLegDayCounter,
                 swFloatingLegIndex, Handle<Quote>(),forwardStart));
         boost::shared_ptr<RateHelper> s10y(new SwapRateHelper(
                 Handle<Quote>(s10yRate), 10*Years,
                 calendar, swFixedLegFrequency,
                 swFixedLegConvention, swFixedLegDayCounter,
                 swFloatingLegIndex, Handle<Quote>(),forwardStart));
         boost::shared_ptr<RateHelper> s15y(new SwapRateHelper(
                 Handle<Quote>(s15yRate), 15*Years,
                 calendar, swFixedLegFrequency,
                 swFixedLegConvention, swFixedLegDayCounter,
                 swFloatingLegIndex, Handle<Quote>(),forwardStart));


         /*********************
          **  CURVE BUILDING **
          *********************/

         // Any DayCounter would be fine.
         // ActualActual::ISDA ensures that 30 years is 30.0

         // A depo-swap curve
         std::vector<boost::shared_ptr<RateHelper> > depoSwapInstruments;
         depoSwapInstruments.push_back(d1w);
         depoSwapInstruments.push_back(d1m);
         depoSwapInstruments.push_back(d3m);
         depoSwapInstruments.push_back(d6m);
         depoSwapInstruments.push_back(d9m);
         depoSwapInstruments.push_back(d1y);
         depoSwapInstruments.push_back(s2y);
         depoSwapInstruments.push_back(s3y);
         depoSwapInstruments.push_back(s5y);
         depoSwapInstruments.push_back(s10y);
         depoSwapInstruments.push_back(s15y);
         boost::shared_ptr<YieldTermStructure> depoSwapTermStructure(
                 new PiecewiseYieldCurve<Discount,LogLinear>(
                         settlementDate, depoSwapInstruments,
                         termStructureDayCounter,
                         tolerance));

         // Term structures that will be used for pricing:
         // the one used for discounting cash flows
         RelinkableHandle<YieldTermStructure> discountingTermStructure;
         // the one used for forward rate forecasting
         RelinkableHandle<YieldTermStructure> forecastingTermStructure;

         /*********************
          * BONDS TO BE PRICED *
          **********************/

         // Common data
         Real faceAmount = 100;

         // Pricing engine
         boost::shared_ptr<PricingEngine> bondEngine(
                 new DiscountingBondEngine(discountingTermStructure));

         // Zero coupon bond
         ZeroCouponBond zeroCouponBond(
                 settlementDays,
                 UnitedStates(UnitedStates::GovernmentBond),
                 faceAmount,
                 Date(15,August,2013),
                 Following,
                 Real(116.92),
                 Date(15,August,2003));

         zeroCouponBond.setPricingEngine(bondEngine);

         // Fixed 4.5% US Treasury Note
         Schedule fixedBondSchedule(Date(15, May, 2007),
                 Date(15,May,2017), Period(Semiannual),
                 UnitedStates(UnitedStates::GovernmentBond),
                 Unadjusted, Unadjusted, DateGeneration::Backward, false);

         FixedRateBond fixedRateBond(
                 settlementDays,
                 faceAmount,
                 fixedBondSchedule,
                 std::vector<Rate>(1, 0.045),
                 ActualActual(ActualActual::Bond),
                 ModifiedFollowing,
                 100.0, Date(15, May, 2007));

         fixedRateBond.setPricingEngine(bondEngine);

         // Floating rate bond (3M USD Libor + 0.1%)
         // Should and will be priced on another curve later...

         RelinkableHandle<YieldTermStructure> liborTermStructure;
         const boost::shared_ptr<IborIndex> libor3m(
                 new USDLibor(Period(3,Months),liborTermStructure));
         libor3m->addFixing(Date(17, July, 2008),0.0278625);

         Schedule floatingBondSchedule(Date(21, October, 2005),
                 Date(21, October, 2010), Period(Quarterly),
                 UnitedStates(UnitedStates::NYSE),
                 Unadjusted, Unadjusted, DateGeneration::Backward, true);

         FloatingRateBond floatingRateBond(
                 settlementDays,
                 faceAmount,
                 floatingBondSchedule,
                 libor3m,
                 Actual360(),
                 ModifiedFollowing,
                 Natural(2),
                 // Gearings
                 std::vector<Real>(1, 1.0),
                 // Spreads
                 std::vector<Rate>(1, 0.001),
                 // Caps
                 std::vector<Rate>(),
                 // Floors
                 std::vector<Rate>(),
                 // Fixing in arrears
                 true,
                 Real(100.0),
                 Date(21, October, 2005));

         floatingRateBond.setPricingEngine(bondEngine);

         // Coupon pricers
         boost::shared_ptr<IborCouponPricer> pricer(new BlackIborCouponPricer);

         // optionLet volatilities
         Volatility volatility = 0.0;
         Handle<OptionletVolatilityStructure> vol;
         vol = Handle<OptionletVolatilityStructure>(
                 boost::shared_ptr<OptionletVolatilityStructure>(new
                         ConstantOptionletVolatility(
                                 settlementDays,
                                 calendar,
                                 ModifiedFollowing,
                                 volatility,
                                 Actual365Fixed())));

         pricer->setCapletVolatility(vol);
         setCouponPricer(floatingRateBond.cashflows(),pricer);

         // Yield curve bootstrapping
         forecastingTermStructure.linkTo(depoSwapTermStructure);
         discountingTermStructure.linkTo(bondDiscountingTermStructure);

         // We are using the depo & swap curve to estimate the future Libor rates
         liborTermStructure.linkTo(depoSwapTermStructure);

         /***************
          * BOND PRICING *
          ****************/

         std::cout << std::endl;

         // write column headings
         Size widths[] = { 18, 10, 10, 10 };

         std::cout << std::setw(widths[0]) <<  "                 "
         << std::setw(widths[1]) << "ZC"
         << std::setw(widths[2]) << "Fixed"
         << std::setw(widths[3]) << "Floating"
         << std::endl;

         std::string separator = " | ";
         Size width = widths[0]
                             + widths[1]
                                      + widths[2]
                                               + widths[3];
         std::string rule(width, '-'), dblrule(width, '=');
         std::string tab(8, ' ');

         std::cout << rule << std::endl;

         std::cout << std::fixed;
         std::cout << std::setprecision(2);

         std::cout << std::setw(widths[0]) << "Net present value"
         << std::setw(widths[1]) << zeroCouponBond.NPV()
         << std::setw(widths[2]) << fixedRateBond.NPV()
         << std::setw(widths[3]) << floatingRateBond.NPV()
         << std::endl;

         std::cout << std::setw(widths[0]) << "Clean price"
         << std::setw(widths[1]) << zeroCouponBond.cleanPrice()
         << std::setw(widths[2]) << fixedRateBond.cleanPrice()
         << std::setw(widths[3]) << floatingRateBond.cleanPrice()
         << std::endl;

         std::cout << std::setw(widths[0]) << "Dirty price"
         << std::setw(widths[1]) << zeroCouponBond.dirtyPrice()
         << std::setw(widths[2]) << fixedRateBond.dirtyPrice()
         << std::setw(widths[3]) << floatingRateBond.dirtyPrice()
         << std::endl;

         std::cout << std::setw(widths[0]) << "Accrued coupon"
         << std::setw(widths[1]) << zeroCouponBond.accruedAmount()
         << std::setw(widths[2]) << fixedRateBond.accruedAmount()
         << std::setw(widths[3]) << floatingRateBond.accruedAmount()
         << std::endl;

         std::cout << std::setw(widths[0]) << "Previous coupon"
         << std::setw(widths[1]) << "N/A" // zeroCouponBond
         << std::setw(widths[2]) << io::rate(fixedRateBond.previousCouponRate())
         << std::setw(widths[3]) << io::rate(floatingRateBond.previousCouponRate())
         << std::endl;

         std::cout << std::setw(widths[0]) << "Next coupon"
         << std::setw(widths[1]) << "N/A" // zeroCouponBond
         << std::setw(widths[2]) << io::rate(fixedRateBond.nextCouponRate())
         << std::setw(widths[3]) << io::rate(floatingRateBond.nextCouponRate())
         << std::endl;

         std::cout << std::setw(widths[0]) << "Yield"
         << std::setw(widths[1])
         << io::rate(zeroCouponBond.yield(Actual360(),Compounded,Annual))
         << std::setw(widths[2])
         << io::rate(fixedRateBond.yield(Actual360(),Compounded,Annual))
         << std::setw(widths[3])
         << io::rate(floatingRateBond.yield(Actual360(),Compounded,Annual))
         << std::endl;

         std::cout << std::endl;

         // Other computations
         std::cout << "Sample indirect computations (for the floating rate bond): " << std::endl;
         std::cout << rule << std::endl;

         std::cout << "Yield to Clean Price: "
         << floatingRateBond.cleanPrice(floatingRateBond.yield(Actual360(),Compounded,Annual),Actual360(),Compounded,Annual,settlementDate) << std::endl;

         std::cout << "Clean Price to Yield: "
         << io::rate(floatingRateBond.yield(floatingRateBond.cleanPrice(),Actual360(),Compounded,Annual,settlementDate)) << std::endl;

         /* "Yield to Price"
            "Price to Yield" */

         double seconds = timer.elapsed();
         Integer hours = int(seconds/3600);
         seconds -= hours * 3600;
         Integer minutes = int(seconds/60);
         seconds -= minutes * 60;
         std::cout << " \nRun completed in ";
         if (hours > 0)
             std::cout << hours << " h ";
         if (hours > 0 || minutes > 0)
             std::cout << minutes << " m ";
         std::cout << std::fixed << std::setprecision(0)
         << seconds << " s\n" << std::endl;

         return 0;

    } catch (std::exception& e) {
        std::cerr << e.what() << std::endl;
        return 1;
    } catch (...) {
        std::cerr << "unknown error" << std::endl;
        return 1;
    }
}
Пример #16
0
void MainWindow::showSwapNPV()
{
    //ui->lineEdit_SwapNPV->setText(tr("1000000000"));
    //ui->lineEdit_SwapFairRate->setText(QString::number(3.141659));
    //ui->lineEdit_SwapFairSpread->setText(QString::number(2.68796451));


    /*********************
    ***  MARKET DATA  ***
    *********************/

    Calendar calendar = TARGET();

    /////■ Date settlementDate(22, September, 2004);
    QDate qtFormSettlementDate = ui->dateEdit_settlementDate->date();
    QuantLib::Date settlementDate(22, September, 2004);
    if(!qtFormSettlementDate.isNull() && qtFormSettlementDate.isValid()) {
        QuantLib::Date settlementDate_(qtFormSettlementDate.day(), (QuantLib::Month)(qtFormSettlementDate.month()), qtFormSettlementDate.year());
        settlementDate = settlementDate_;
    }

    // must be a business day
    settlementDate = calendar.adjust(settlementDate);

    Integer fixingDays = 2;
    Date todaysDate = calendar.advance(settlementDate, -fixingDays, Days);
    // nothing to do with Date::todaysDate
    Settings::instance().evaluationDate() = todaysDate;


    todaysDate = Settings::instance().evaluationDate();
    std::cout << "Today: " << todaysDate.weekday()
              << ", " << todaysDate << std::endl;

    std::cout << "Settlement date: " << settlementDate.weekday()
              << ", " << settlementDate << std::endl;

    // deposits
    Rate d1wQuote=0.0382;
    d1wQuote = static_cast<Rate>(ui->tableWidget_RatesDeposites->item(-1,1)->text().toDouble()*0.01);
    Rate d1mQuote=0.0372;
    d1mQuote = static_cast<Rate>(ui->tableWidget_RatesDeposites->item(0,1)->text().toDouble()*0.01);
    Rate d3mQuote=0.0363;
    d3mQuote = static_cast<Rate>(ui->tableWidget_RatesDeposites->item(1,1)->text().toDouble()*0.01);
    Rate d6mQuote=0.0353;
    d6mQuote = static_cast<Rate>(ui->tableWidget_RatesDeposites->item(2,1)->text().toDouble()*0.01);
    Rate d9mQuote=0.0348;
    d9mQuote = static_cast<Rate>(ui->tableWidget_RatesDeposites->item(3,1)->text().toDouble()*0.01);
    Rate d1yQuote=0.0345;
    d1yQuote = static_cast<Rate>(ui->tableWidget_RatesDeposites->item(4,1)->text().toDouble()*0.01);

    // FRAs
    Rate fra3x6Quote=0.037125;
    fra3x6Quote = static_cast<Rate>(ui->tableWidget_RatesFRAs->item(-1,1)->text().toDouble()*0.01);
    Rate fra6x9Quote=0.037125;
    fra6x9Quote = static_cast<Rate>(ui->tableWidget_RatesFRAs->item(0,1)->text().toDouble()*0.01);
    Rate fra6x12Quote=0.037125;
    fra6x12Quote = static_cast<Rate>(ui->tableWidget_RatesFRAs->item(1,1)->text().toDouble()*0.01);

    // futures
    Real fut1Quote=96.2875;
    fut1Quote = static_cast<Real>(ui->tableWidget_RatesFutures->item(-1,1)->text().toDouble());
    Real fut2Quote=96.7875;
    fut2Quote = static_cast<Real>(ui->tableWidget_RatesFutures->item(0,1)->text().toDouble());
    Real fut3Quote=96.9875;
    fut3Quote = static_cast<Real>(ui->tableWidget_RatesFutures->item(1,1)->text().toDouble());
    Real fut4Quote=96.6875;
    fut4Quote = static_cast<Real>(ui->tableWidget_RatesFutures->item(2,1)->text().toDouble());
    Real fut5Quote=96.4875;
    fut5Quote = static_cast<Real>(ui->tableWidget_RatesFutures->item(3,1)->text().toDouble());
    Real fut6Quote=96.3875;
    fut6Quote = static_cast<Real>(ui->tableWidget_RatesFutures->item(4,1)->text().toDouble());
    Real fut7Quote=96.2875;
    fut7Quote = static_cast<Real>(ui->tableWidget_RatesFutures->item(5,1)->text().toDouble());
    Real fut8Quote=96.0875;
    fut8Quote = static_cast<Real>(ui->tableWidget_RatesFutures->item(6,1)->text().toDouble());

    // swaps
    Rate s2yQuote=0.037125;
    s2yQuote = static_cast<Rate>(ui->tableWidget_RatesSwaps->item(-1,1)->text().toDouble()*0.01);
    Rate s3yQuote=0.0398;
    s3yQuote = static_cast<Rate>(ui->tableWidget_RatesSwaps->item(0,1)->text().toDouble()*0.01);
    Rate s5yQuote=0.0443;
    s5yQuote = static_cast<Rate>(ui->tableWidget_RatesSwaps->item(1,1)->text().toDouble()*0.01);
    Rate s10yQuote=0.05165;
    s10yQuote = static_cast<Rate>(ui->tableWidget_RatesSwaps->item(2,1)->text().toDouble()*0.01);
    Rate s15yQuote=0.055175;
    s15yQuote = static_cast<Rate>(ui->tableWidget_RatesSwaps->item(3,1)->text().toDouble()*0.01);


    /********************
    ***    QUOTES    ***
    ********************/

    // SimpleQuote stores a value which can be manually changed;
    // other Quote subclasses could read the value from a database
    // or some kind of data feed.

    // deposits
    boost::shared_ptr<Quote> d1wRate(new SimpleQuote(d1wQuote));
    boost::shared_ptr<Quote> d1mRate(new SimpleQuote(d1mQuote));
    boost::shared_ptr<Quote> d3mRate(new SimpleQuote(d3mQuote));
    boost::shared_ptr<Quote> d6mRate(new SimpleQuote(d6mQuote));
    boost::shared_ptr<Quote> d9mRate(new SimpleQuote(d9mQuote));
    boost::shared_ptr<Quote> d1yRate(new SimpleQuote(d1yQuote));
    // FRAs
    boost::shared_ptr<Quote> fra3x6Rate(new SimpleQuote(fra3x6Quote));
    boost::shared_ptr<Quote> fra6x9Rate(new SimpleQuote(fra6x9Quote));
    boost::shared_ptr<Quote> fra6x12Rate(new SimpleQuote(fra6x12Quote));
    // futures
    boost::shared_ptr<Quote> fut1Price(new SimpleQuote(fut1Quote));
    boost::shared_ptr<Quote> fut2Price(new SimpleQuote(fut2Quote));
    boost::shared_ptr<Quote> fut3Price(new SimpleQuote(fut3Quote));
    boost::shared_ptr<Quote> fut4Price(new SimpleQuote(fut4Quote));
    boost::shared_ptr<Quote> fut5Price(new SimpleQuote(fut5Quote));
    boost::shared_ptr<Quote> fut6Price(new SimpleQuote(fut6Quote));
    boost::shared_ptr<Quote> fut7Price(new SimpleQuote(fut7Quote));
    boost::shared_ptr<Quote> fut8Price(new SimpleQuote(fut8Quote));
    // swaps
    boost::shared_ptr<Quote> s2yRate(new SimpleQuote(s2yQuote));
    boost::shared_ptr<Quote> s3yRate(new SimpleQuote(s3yQuote));
    boost::shared_ptr<Quote> s5yRate(new SimpleQuote(s5yQuote));
    boost::shared_ptr<Quote> s10yRate(new SimpleQuote(s10yQuote));
    boost::shared_ptr<Quote> s15yRate(new SimpleQuote(s15yQuote));


    /*********************
    	***  RATE HELPERS ***
    	*********************/

    // RateHelpers are built from the above quotes together with
    // other instrument dependant infos.  Quotes are passed in
    // relinkable handles which could be relinked to some other
    // data source later.

    // deposits
    DayCounter depositDayCounter = Actual360();

    boost::shared_ptr<RateHelper> d1w(new DepositRateHelper(
                                          Handle<Quote>(d1wRate),
                                          1*Weeks, fixingDays,
                                          calendar, ModifiedFollowing,
                                          true, depositDayCounter));
    boost::shared_ptr<RateHelper> d1m(new DepositRateHelper(
                                          Handle<Quote>(d1mRate),
                                          1*Months, fixingDays,
                                          calendar, ModifiedFollowing,
                                          true, depositDayCounter));
    boost::shared_ptr<RateHelper> d3m(new DepositRateHelper(
                                          Handle<Quote>(d3mRate),
                                          3*Months, fixingDays,
                                          calendar, ModifiedFollowing,
                                          true, depositDayCounter));
    boost::shared_ptr<RateHelper> d6m(new DepositRateHelper(
                                          Handle<Quote>(d6mRate),
                                          6*Months, fixingDays,
                                          calendar, ModifiedFollowing,
                                          true, depositDayCounter));
    boost::shared_ptr<RateHelper> d9m(new DepositRateHelper(
                                          Handle<Quote>(d9mRate),
                                          9*Months, fixingDays,
                                          calendar, ModifiedFollowing,
                                          true, depositDayCounter));
    boost::shared_ptr<RateHelper> d1y(new DepositRateHelper(
                                          Handle<Quote>(d1yRate),
                                          1*Years, fixingDays,
                                          calendar, ModifiedFollowing,
                                          true, depositDayCounter));


    // setup FRAs
    boost::shared_ptr<RateHelper> fra3x6(new FraRateHelper(
            Handle<Quote>(fra3x6Rate),
            3, 6, fixingDays, calendar, ModifiedFollowing,
            true, depositDayCounter));
    boost::shared_ptr<RateHelper> fra6x9(new FraRateHelper(
            Handle<Quote>(fra6x9Rate),
            6, 9, fixingDays, calendar, ModifiedFollowing,
            true, depositDayCounter));
    boost::shared_ptr<RateHelper> fra6x12(new FraRateHelper(
            Handle<Quote>(fra6x12Rate),
            6, 12, fixingDays, calendar, ModifiedFollowing,
            true, depositDayCounter));


    // setup futures
    // Rate convexityAdjustment = 0.0;
    Integer futMonths = 3;
    Date imm = IMM::nextDate(settlementDate);
    boost::shared_ptr<RateHelper> fut1(new FuturesRateHelper(
                                           Handle<Quote>(fut1Price),
                                           imm,
                                           futMonths, calendar, ModifiedFollowing,
                                           true, depositDayCounter));
    imm = IMM::nextDate(imm+1);
    boost::shared_ptr<RateHelper> fut2(new FuturesRateHelper(
                                           Handle<Quote>(fut2Price),
                                           imm,
                                           futMonths, calendar, ModifiedFollowing,
                                           true, depositDayCounter));
    imm = IMM::nextDate(imm+1);
    boost::shared_ptr<RateHelper> fut3(new FuturesRateHelper(
                                           Handle<Quote>(fut3Price),
                                           imm,
                                           futMonths, calendar, ModifiedFollowing,
                                           true, depositDayCounter));
    imm = IMM::nextDate(imm+1);
    boost::shared_ptr<RateHelper> fut4(new FuturesRateHelper(
                                           Handle<Quote>(fut4Price),
                                           imm,
                                           futMonths, calendar, ModifiedFollowing,
                                           true, depositDayCounter));
    imm = IMM::nextDate(imm+1);
    boost::shared_ptr<RateHelper> fut5(new FuturesRateHelper(
                                           Handle<Quote>(fut5Price),
                                           imm,
                                           futMonths, calendar, ModifiedFollowing,
                                           true, depositDayCounter));
    imm = IMM::nextDate(imm+1);
    boost::shared_ptr<RateHelper> fut6(new FuturesRateHelper(
                                           Handle<Quote>(fut6Price),
                                           imm,
                                           futMonths, calendar, ModifiedFollowing,
                                           true, depositDayCounter));
    imm = IMM::nextDate(imm+1);
    boost::shared_ptr<RateHelper> fut7(new FuturesRateHelper(
                                           Handle<Quote>(fut7Price),
                                           imm,
                                           futMonths, calendar, ModifiedFollowing,
                                           true, depositDayCounter));
    imm = IMM::nextDate(imm+1);
    boost::shared_ptr<RateHelper> fut8(new FuturesRateHelper(
                                           Handle<Quote>(fut8Price),
                                           imm,
                                           futMonths, calendar, ModifiedFollowing,
                                           true, depositDayCounter));


    // setup swaps
    Frequency swFixedLegFrequency = Annual;
    BusinessDayConvention swFixedLegConvention = Unadjusted;
    DayCounter swFixedLegDayCounter = Thirty360(Thirty360::European);
    boost::shared_ptr<IborIndex> swFloatingLegIndex(new Euribor6M);

    boost::shared_ptr<RateHelper> s2y(new SwapRateHelper(
                                          Handle<Quote>(s2yRate), 2*Years,
                                          calendar, swFixedLegFrequency,
                                          swFixedLegConvention, swFixedLegDayCounter,
                                          swFloatingLegIndex));
    boost::shared_ptr<RateHelper> s3y(new SwapRateHelper(
                                          Handle<Quote>(s3yRate), 3*Years,
                                          calendar, swFixedLegFrequency,
                                          swFixedLegConvention, swFixedLegDayCounter,
                                          swFloatingLegIndex));
    boost::shared_ptr<RateHelper> s5y(new SwapRateHelper(
                                          Handle<Quote>(s5yRate), 5*Years,
                                          calendar, swFixedLegFrequency,
                                          swFixedLegConvention, swFixedLegDayCounter,
                                          swFloatingLegIndex));
    boost::shared_ptr<RateHelper> s10y(new SwapRateHelper(
                                           Handle<Quote>(s10yRate), 10*Years,
                                           calendar, swFixedLegFrequency,
                                           swFixedLegConvention, swFixedLegDayCounter,
                                           swFloatingLegIndex));
    boost::shared_ptr<RateHelper> s15y(new SwapRateHelper(
                                           Handle<Quote>(s15yRate), 15*Years,
                                           calendar, swFixedLegFrequency,
                                           swFixedLegConvention, swFixedLegDayCounter,
                                           swFloatingLegIndex));


    /*********************
    	**  CURVE BUILDING **
    	*********************/

    // Any DayCounter would be fine.
    // ActualActual::ISDA ensures that 30 years is 30.0
    DayCounter termStructureDayCounter =
        ActualActual(ActualActual::ISDA);


    double tolerance = 1.0e-15;

    // A depo-swap curve
    std::vector<boost::shared_ptr<RateHelper> > depoSwapInstruments;
    depoSwapInstruments.push_back(d1w);
    depoSwapInstruments.push_back(d1m);
    depoSwapInstruments.push_back(d3m);
    depoSwapInstruments.push_back(d6m);
    depoSwapInstruments.push_back(d9m);
    depoSwapInstruments.push_back(d1y);
    depoSwapInstruments.push_back(s2y);
    depoSwapInstruments.push_back(s3y);
    depoSwapInstruments.push_back(s5y);
    depoSwapInstruments.push_back(s10y);
    depoSwapInstruments.push_back(s15y);
    boost::shared_ptr<YieldTermStructure> depoSwapTermStructure(
        new PiecewiseYieldCurve<Discount,LogLinear>(
            settlementDate, depoSwapInstruments,
            termStructureDayCounter,
            tolerance));


    // A depo-futures-swap curve
    std::vector<boost::shared_ptr<RateHelper> > depoFutSwapInstruments;
    depoFutSwapInstruments.push_back(d1w);
    depoFutSwapInstruments.push_back(d1m);
    depoFutSwapInstruments.push_back(fut1);
    depoFutSwapInstruments.push_back(fut2);
    depoFutSwapInstruments.push_back(fut3);
    depoFutSwapInstruments.push_back(fut4);
    depoFutSwapInstruments.push_back(fut5);
    depoFutSwapInstruments.push_back(fut6);
    depoFutSwapInstruments.push_back(fut7);
    depoFutSwapInstruments.push_back(fut8);
    depoFutSwapInstruments.push_back(s3y);
    depoFutSwapInstruments.push_back(s5y);
    depoFutSwapInstruments.push_back(s10y);
    depoFutSwapInstruments.push_back(s15y);
    boost::shared_ptr<YieldTermStructure> depoFutSwapTermStructure(
        new PiecewiseYieldCurve<Discount,LogLinear>(
            settlementDate, depoFutSwapInstruments,
            termStructureDayCounter,
            tolerance));


    // A depo-FRA-swap curve
    std::vector<boost::shared_ptr<RateHelper> > depoFRASwapInstruments;
    depoFRASwapInstruments.push_back(d1w);
    depoFRASwapInstruments.push_back(d1m);
    depoFRASwapInstruments.push_back(d3m);
    depoFRASwapInstruments.push_back(fra3x6);
    depoFRASwapInstruments.push_back(fra6x9);
    depoFRASwapInstruments.push_back(fra6x12);
    depoFRASwapInstruments.push_back(s2y);
    depoFRASwapInstruments.push_back(s3y);
    depoFRASwapInstruments.push_back(s5y);
    depoFRASwapInstruments.push_back(s10y);
    depoFRASwapInstruments.push_back(s15y);
    boost::shared_ptr<YieldTermStructure> depoFRASwapTermStructure(
        new PiecewiseYieldCurve<Discount,LogLinear>(
            settlementDate, depoFRASwapInstruments,
            termStructureDayCounter,
            tolerance));


    // Term structures that will be used for pricing:
    // the one used for discounting cash flows
    RelinkableHandle<YieldTermStructure> discountingTermStructure;
    // the one used for forward rate forecasting
    RelinkableHandle<YieldTermStructure> forecastingTermStructure;


    /*********************
    * SWAPS TO BE PRICED *
    **********************/

    // constant nominal 1,000,000 Euro
    /////■ Real nominal = 1000000.0;
    Real nominal = static_cast<Real>(ui->doubleSpinBox_Notional->value());

    // fixed leg
    /////■ Frequency fixedLegFrequency = Annual;
    Frequency fixedLegFrequency = Annual;
    /////■ BusinessDayConvention fixedLegConvention = Unadjusted;
    BusinessDayConvention fixedLegConvention = Unadjusted;
    /////■ DayCounter fixedLegDayCounter = Thirty360(Thirty360::European);
    DayCounter fixedLegDayCounter = Thirty360(Thirty360::European);
    /////■ Rate fixedRate = 0.04;
    Rate fixedRate = static_cast<Real>((ui->doubleSpinBox_fixedRate->value())*0.01);

    // floating leg
    /////■ Frequency floatingLegFrequency = Semiannual;
    Frequency floatingLegFrequency = Semiannual;
    int comboBoxFloatingLegFrequency = ui->comboBox_FloatingLegFrequency->currentIndex();
    switch(comboBoxFloatingLegFrequency) {
    case 0: // Semiannual
        floatingLegFrequency = Semiannual;
        break;
    case 1: // Annual
        floatingLegFrequency = Annual;
        break;
    case 2: // Quarterly
        floatingLegFrequency = Quarterly;
        break;
    }

    /////■ BusinessDayConvention floatingLegConvention = ModifiedFollowing;
    BusinessDayConvention floatingLegConvention = ModifiedFollowing;
    /////■ DayCounter floatingLegDayCounter = Actual360();
    DayCounter floatingLegDayCounter = Actual360();

    boost::shared_ptr<IborIndex> euriborIndex(
        new Euribor6M(forecastingTermStructure));
    /////■ Spread spread = 0.0;
    Spread spread = static_cast<Spread>((ui->doubleSpinBox_spread->value())*0.01);
    /////■ Integer lenghtInYears = 5;
    Integer lenghtInYears =  (Integer)(ui->doubleSpinBox_lenghtInYears->value());
    /////■ VanillaSwap::Type swapType = VanillaSwap::Payer;
    int comboBoxPayerReceiver = ui->comboBox_swapType->currentIndex();
    VanillaSwap::Type swapType = VanillaSwap::Receiver;
    switch(comboBoxPayerReceiver) {
    case 0: // Fix Payer
        swapType = VanillaSwap::Payer;
        break; // VanillaSwap::Payer=1
    case 1: // Fix Receiver
        swapType = VanillaSwap::Receiver;
        break; // VanillaSwap::Receiver=-1
    }

    Date maturity = settlementDate + lenghtInYears*Years;
    Schedule fixedSchedule(settlementDate, maturity,
                           Period(fixedLegFrequency),
                           calendar, fixedLegConvention,
                           fixedLegConvention,
                           DateGeneration::Forward, false);
    Schedule floatSchedule(settlementDate, maturity,
                           Period(floatingLegFrequency),
                           calendar, floatingLegConvention,
                           floatingLegConvention,
                           DateGeneration::Forward, false);
    VanillaSwap spot5YearSwap(swapType, nominal,
                              fixedSchedule, fixedRate, fixedLegDayCounter,
                              floatSchedule, euriborIndex, spread,
                              floatingLegDayCounter);

    Date fwdStart = calendar.advance(settlementDate, 1, Years);
    Date fwdMaturity = fwdStart + lenghtInYears*Years;
    Schedule fwdFixedSchedule(fwdStart, fwdMaturity,
                              Period(fixedLegFrequency),
                              calendar, fixedLegConvention,
                              fixedLegConvention,
                              DateGeneration::Forward, false);
    Schedule fwdFloatSchedule(fwdStart, fwdMaturity,
                              Period(floatingLegFrequency),
                              calendar, floatingLegConvention,
                              floatingLegConvention,
                              DateGeneration::Forward, false);
    VanillaSwap oneYearForward5YearSwap(swapType, nominal,
                                        fwdFixedSchedule, fixedRate, fixedLegDayCounter,
                                        fwdFloatSchedule, euriborIndex, spread,
                                        floatingLegDayCounter);


    /***************
    * SWAP PRICING *
    ****************/

    Real NPV;
    Rate fairRate;
    Spread fairSpread;

    boost::shared_ptr<PricingEngine> swapEngine(
        new DiscountingSwapEngine(discountingTermStructure));

    spot5YearSwap.setPricingEngine(swapEngine);
    oneYearForward5YearSwap.setPricingEngine(swapEngine);

    int swapTermStructureType(0);
    swapTermStructureType = ui->comboBox_TermStructureType->currentIndex();
    //QMessageBox msgBoxTmp(this); msgBoxTmp.setText(QString::number(swapTermStructureType)); msgBoxTmp.exec();
    switch(swapTermStructureType) {
    case 0:
        forecastingTermStructure.linkTo(depoSwapTermStructure);
        discountingTermStructure.linkTo(depoSwapTermStructure);
        break;
    case 1:
        forecastingTermStructure.linkTo(depoFutSwapTermStructure);
        discountingTermStructure.linkTo(depoFutSwapTermStructure);
        break;
    case 2:
        forecastingTermStructure.linkTo(depoFRASwapTermStructure);
        discountingTermStructure.linkTo(depoFRASwapTermStructure);
        break;
    }

    NPV = spot5YearSwap.NPV();
    fairRate = spot5YearSwap.fairRate();
    fairSpread = spot5YearSwap.fairSpread();


    ui->lineEdit_SwapNPV->setText(QString::number(static_cast<double>(NPV),'f'));
    ui->lineEdit_SwapFairRate->setText(QString::number(static_cast<double>(fairRate*100.0),'f'));
    ui->lineEdit_SwapFairSpread->setText(QString::number(static_cast<double>(fairSpread*100.0),'f'));


}
Пример #17
0
void CreditDefaultSwapTest::testIsdaEngine() {

    BOOST_TEST_MESSAGE(
        "Testing ISDA engine calculations for credit-default swaps...");

    SavedSettings backup;

    Date tradeDate(21, May, 2009);
    Settings::instance().evaluationDate() = tradeDate;


    //build an ISDA compliant yield curve
    //data comes from Markit published rates
    std::vector<ext::shared_ptr<RateHelper> > isdaRateHelpers;
    int dep_tenors[] = {1, 2, 3, 6, 9, 12};
    double dep_quotes[] = {0.003081,
                           0.005525,
                           0.007163,
                           0.012413,
                           0.014,
                           0.015488};

    for(size_t i = 0; i < sizeof(dep_tenors) / sizeof(int); i++) {
        isdaRateHelpers.push_back(ext::make_shared<DepositRateHelper>(
                                     dep_quotes[i], dep_tenors[i] * Months, 2,
                                     WeekendsOnly(), ModifiedFollowing,
                                     false, Actual360()
                                     )
            );
    }
    int swap_tenors[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20, 25, 30};
    double swap_quotes[] = {0.011907,
                            0.01699,
                            0.021198,
                            0.02444,
                            0.026937,
                            0.028967,
                            0.030504,
                            0.031719,
                            0.03279,
                            0.034535,
                            0.036217,
                            0.036981,
                            0.037246,
                            0.037605};

    ext::shared_ptr<IborIndex> isda_ibor = ext::make_shared<IborIndex>(
        "IsdaIbor", 3 * Months, 2, USDCurrency(), WeekendsOnly(),
        ModifiedFollowing, false, Actual360());
    for(size_t i = 0; i < sizeof(swap_tenors) / sizeof(int); i++) {
        isdaRateHelpers.push_back(ext::make_shared<SwapRateHelper>(
                                      swap_quotes[i], swap_tenors[i] * Years,
                                      WeekendsOnly(),
                                      Semiannual,
                                      ModifiedFollowing, Thirty360(), isda_ibor
                                      )
            );
    }

    RelinkableHandle<YieldTermStructure> discountCurve;
    discountCurve.linkTo(
            ext::make_shared<PiecewiseYieldCurve<Discount, LogLinear> >(
                0, WeekendsOnly(), isdaRateHelpers, Actual365Fixed())
        );


    RelinkableHandle<DefaultProbabilityTermStructure> probabilityCurve;
    Date termDates[] = {Date(20, June, 2010),
                        Date(20, June, 2011),
                        Date(20, June, 2012),
                        Date(20, June, 2016),
                        Date(20, June, 2019)};
    Rate spreads[] = {0.001, 0.1};
    Rate recoveries[] = {0.2, 0.4};

    double markitValues[] = {97798.29358, //0.001
                             97776.11889, //0.001
                             -914971.5977, //0.1
                             -894985.6298, //0.1
                             186921.3594, //0.001
                             186839.8148, //0.001
                             -1646623.672, //0.1
                             -1579803.626, //0.1
                             274298.9203,
                             274122.4725,
                             -2279730.93,
                             -2147972.527,
                             592420.2297,
                             591571.2294,
                             -3993550.206,
                             -3545843.418,
                             797501.1422,
                             795915.9787,
                             -4702034.688,
                             -4042340.999};
    #ifndef QL_USE_INDEXED_COUPON
    Real tolerance = 1.0e-6;
    #else
    /* The risk-free curve is a bit off. We might skip the tests
       altogether and rely on running them with indexed coupons
       disabled, but leaving them can be useful anyway. */
    Real tolerance = 1.0e-3;
    #endif

    size_t l = 0;

    for(size_t i = 0; i < sizeof(termDates) / sizeof(Date); i++) {
        for(size_t j = 0; j < 2; j++) {
            for(size_t k = 0; k < 2; k++) {

            ext::shared_ptr<CreditDefaultSwap> quotedTrade =
                MakeCreditDefaultSwap(termDates[i], spreads[j])
                .withNominal(10000000.);

            Rate h = quotedTrade->impliedHazardRate(0.,
                                                    discountCurve,
                                                    Actual365Fixed(),
                                                    recoveries[k],
                                                    1e-10,
                                                    CreditDefaultSwap::ISDA);

            probabilityCurve.linkTo(
                ext::make_shared<FlatHazardRate>(
                    0, WeekendsOnly(), h, Actual365Fixed())
                );

            ext::shared_ptr<IsdaCdsEngine> engine = ext::make_shared<IsdaCdsEngine>(
                probabilityCurve, recoveries[k], discountCurve,
                boost::none, IsdaCdsEngine::Taylor, IsdaCdsEngine::HalfDayBias,
                IsdaCdsEngine::Piecewise);

            ext::shared_ptr<CreditDefaultSwap> conventionalTrade =
                MakeCreditDefaultSwap(termDates[i], 0.01)
                .withNominal(10000000.)
                .withPricingEngine(engine);

            BOOST_CHECK_CLOSE(conventionalTrade->notional() * conventionalTrade->fairUpfront(),
                              markitValues[l],
                              tolerance);

            l++;

            }
        }
    }

}
Пример #18
0
void InflationTest::testZeroTermStructure() {
    BOOST_MESSAGE("Testing zero inflation term structure...");

    SavedSettings backup;

    // try the Zero UK
    Calendar calendar = UnitedKingdom();
    BusinessDayConvention bdc = ModifiedFollowing;
    Date evaluationDate(13, August, 2007);
    evaluationDate = calendar.adjust(evaluationDate);
    Settings::instance().evaluationDate() = evaluationDate;

    // fixing data
    Date from(1, January, 2005);
    Date to(13, August, 2007);
    Schedule rpiSchedule = MakeSchedule().from(from).to(to)
    .withTenor(1*Months)
    .withCalendar(UnitedKingdom())
    .withConvention(ModifiedFollowing);

    Real fixData[] = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0,
        192.2, 192.2, 192.6, 193.1, 193.3, 193.6,
        194.1, 193.4, 194.2, 195.0, 196.5, 197.7,
        198.5, 198.5, 199.2, 200.1, 200.4, 201.1,
        202.7, 201.6, 203.1, 204.4, 205.4, 206.2,
        207.3, 206.1,  -999.0 };

    RelinkableHandle<ZeroInflationTermStructure> hz;
    bool interp = false;
    boost::shared_ptr<UKRPI> iiUKRPI(new UKRPI(interp, hz));
    for (Size i=0; i<rpiSchedule.size();i++) {
        iiUKRPI->addFixing(rpiSchedule[i], fixData[i]);
    }

    boost::shared_ptr<ZeroInflationIndex> ii = boost::dynamic_pointer_cast<ZeroInflationIndex>(iiUKRPI);
    boost::shared_ptr<YieldTermStructure> nominalTS = nominalTermStructure();

    // now build the zero inflation curve
    Datum zcData[] = {
        { Date(13, August, 2008), 2.93 },
        { Date(13, August, 2009), 2.95 },
        { Date(13, August, 2010), 2.965 },
        { Date(15, August, 2011), 2.98 },
        { Date(13, August, 2012), 3.0 },
        { Date(13, August, 2014), 3.06 },
        { Date(13, August, 2017), 3.175 },
        { Date(13, August, 2019), 3.243 },
        { Date(15, August, 2022), 3.293 },
        { Date(14, August, 2027), 3.338 },
        { Date(13, August, 2032), 3.348 },
        { Date(15, August, 2037), 3.348 },
        { Date(13, August, 2047), 3.308 },
        { Date(13, August, 2057), 3.228 }
    };

    Period observationLag = Period(2,Months);
    DayCounter dc = Thirty360();
    Frequency frequency = Monthly;
    std::vector<boost::shared_ptr<BootstrapHelper<ZeroInflationTermStructure> > > helpers =
    makeHelpers<ZeroInflationTermStructure,ZeroCouponInflationSwapHelper,
                ZeroInflationIndex>(zcData, LENGTH(zcData), ii,
                                    observationLag,
                                    calendar, bdc, dc);

    Rate baseZeroRate = zcData[0].rate/100.0;
    boost::shared_ptr<PiecewiseZeroInflationCurve<Linear> > pZITS(
                        new PiecewiseZeroInflationCurve<Linear>(
                        evaluationDate, calendar, dc, observationLag,
                        frequency, ii->interpolated(), baseZeroRate,
                        Handle<YieldTermStructure>(nominalTS), helpers));
    pZITS->recalculate();

    // first check that the zero rates on the curve match the data
    // and that the helpers give the correct impled rates
    const Real eps = 0.00000001;
    bool forceLinearInterpolation = false;
    for (Size i=0; i<LENGTH(zcData); i++) {
        BOOST_REQUIRE_MESSAGE(std::fabs(zcData[i].rate/100.0
            - pZITS->zeroRate(zcData[i].date, observationLag, forceLinearInterpolation)) < eps,
            "ZITS zeroRate != instrument "
            << pZITS->zeroRate(zcData[i].date, observationLag, forceLinearInterpolation)
            << " vs " << zcData[i].rate/100.0
            << " interpolation: " << ii->interpolated()
            << " forceLinearInterpolation " << forceLinearInterpolation);
        BOOST_REQUIRE_MESSAGE(std::fabs(helpers[i]->impliedQuote()
            - zcData[i].rate/100.0) < eps,
            "ZITS implied quote != instrument "
            << helpers[i]->impliedQuote()
            << " vs " << zcData[i].rate/100.0);
    }


    // now test the forecasting capability of the index.
    hz.linkTo(pZITS);
    from = hz->baseDate();
    to = hz->maxDate()-1*Months; // a bit of margin for adjustments
    Schedule testIndex = MakeSchedule().from(from).to(to)
                            .withTenor(1*Months)
                            .withCalendar(UnitedKingdom())
                            .withConvention(ModifiedFollowing);


    // we are testing UKRPI which is not interpolated
    Date bd = hz->baseDate();
    Real bf = ii->fixing(bd);
    for (Size i=0; i<testIndex.size();i++) {
        Date d = testIndex[i];
        Real z = hz->zeroRate(d, Period(0,Days));
        Real t = hz->dayCounter().yearFraction(bd, d);
        if(!ii->interpolated()) // because fixing constant over period
            t = hz->dayCounter().yearFraction(bd,
                inflationPeriod(d, ii->frequency()).first);
        Real calc = bf * pow( 1+z, t);
        if (t<=0)
            calc = ii->fixing(d,false); // still historical
        if (std::fabs(calc - ii->fixing(d,true))/10000.0 > eps)
            BOOST_ERROR("ZC index does not forecast correctly for date " << d
                        << " from base date " << bd
                        << " with fixing " << bf
                        << ", correct:  " << calc
                        << ", fix: " << ii->fixing(d,true)
                        << ", t " << t);
    }


    //===========================================================================================
    // Test zero-inflation-indexed (i.e. cpi ratio) cashflow
    // just ordinary indexed cashflow with a zero inflation index

    Date baseDate(1, January, 2006);
    Date fixDate(1, August, 2014);
    Date payDate=UnitedKingdom().adjust(fixDate+Period(3,Months),ModifiedFollowing);
    boost::shared_ptr<Index> ind = boost::dynamic_pointer_cast<Index>(ii);
    BOOST_REQUIRE_MESSAGE(ind,"dynamic_pointer_cast to Index from InflationIndex failed");

    Real notional = 1000000.0;//1m
    IndexedCashFlow iicf(notional,ind,baseDate,fixDate,payDate);
    Real correctIndexed = ii->fixing(iicf.fixingDate())/ii->fixing(iicf.baseDate());
    Real calculatedIndexed = iicf.amount()/iicf.notional();
    BOOST_REQUIRE_MESSAGE(std::fabs(correctIndexed - calculatedIndexed) < eps,
               "IndexedCashFlow indexing wrong: " << calculatedIndexed << " vs correct = "
               << correctIndexed);


    //===========================================================================================
    // Test zero coupon swap

    // first make one ...

    boost::shared_ptr<ZeroInflationIndex> zii = boost::dynamic_pointer_cast<ZeroInflationIndex>(ii);
    BOOST_REQUIRE_MESSAGE(zii,"dynamic_pointer_cast to ZeroInflationIndex from UKRPI failed");
    ZeroCouponInflationSwap nzcis(ZeroCouponInflationSwap::Payer,
                                     1000000.0,
                                     evaluationDate,
                                     zcData[6].date,    // end date = maturity
                                     calendar, bdc, dc, zcData[6].rate/100.0, // fixed rate
                                     zii, observationLag);

    // N.B. no coupon pricer because it is not a coupon, effect of inflation curve via
    //      inflation curve attached to the inflation index.
    Handle<YieldTermStructure> hTS(nominalTS);
    boost::shared_ptr<PricingEngine> sppe(new DiscountingSwapEngine(hTS));
    nzcis.setPricingEngine(sppe);

    // ... and price it, should be zero
    BOOST_CHECK_MESSAGE(fabs(nzcis.NPV())<0.00001,"ZCIS does not reprice to zero "
                        << nzcis.NPV()
                        << evaluationDate << " to " << zcData[6].date << " becoming " << nzcis.maturityDate()
                        << " rate " << zcData[6].rate
                        << " fixed leg " << nzcis.legNPV(0)
                        << " indexed-predicted inflated leg " << nzcis.legNPV(1)
                        << " discount " << nominalTS->discount(nzcis.maturityDate())
                        );


    //===========================================================================================
    // Test multiplicative seasonality in price
    //

    //Seasonality factors NOT normalized
    //and UKRPI is not interpolated
    Date trueBaseDate = inflationPeriod(hz->baseDate(), ii->frequency()).second;
    Date seasonallityBaseDate(31,January,trueBaseDate.year());
    std::vector<Rate> seasonalityFactors(12);
    seasonalityFactors[0] = 1.003245;
    seasonalityFactors[1] = 1.000000;
    seasonalityFactors[2] = 0.999715;
    seasonalityFactors[3] = 1.000495;
    seasonalityFactors[4] = 1.000929;
    seasonalityFactors[5] = 0.998687;
    seasonalityFactors[6] = 0.995949;
    seasonalityFactors[7] = 0.994682;
    seasonalityFactors[8] = 0.995949;
    seasonalityFactors[9] = 1.000519;
    seasonalityFactors[10] = 1.003705;
    seasonalityFactors[11] = 1.004186;

    //Creating two different seasonality objects
    //
    boost::shared_ptr<MultiplicativePriceSeasonality> seasonality_1(new MultiplicativePriceSeasonality());
    std::vector<Rate> seasonalityFactors_1(12, 1.0);
    seasonality_1->set(seasonallityBaseDate,Monthly,seasonalityFactors_1);

    boost::shared_ptr<MultiplicativePriceSeasonality> seasonality_real(
        new MultiplicativePriceSeasonality(seasonallityBaseDate,Monthly,seasonalityFactors));
    //Testing seasonality correction when seasonality factors are = 1
    //
    Rate fixing[] = {
        ii->fixing(Date(14,January  ,2013),true),
        ii->fixing(Date(14,February ,2013),true),
        ii->fixing(Date(14,March    ,2013),true),
        ii->fixing(Date(14,April    ,2013),true),
        ii->fixing(Date(14,May      ,2013),true),
        ii->fixing(Date(14,June     ,2013),true),
        ii->fixing(Date(14,July     ,2013),true),
        ii->fixing(Date(14,August   ,2013),true),
        ii->fixing(Date(14,September,2013),true),
        ii->fixing(Date(14,October  ,2013),true),
        ii->fixing(Date(14,November ,2013),true),
        ii->fixing(Date(14,December ,2013),true)
    };

    hz->setSeasonality(seasonality_1);
    QL_REQUIRE(hz->hasSeasonality(),"[44] incorrectly believes NO seasonality correction");

    Rate seasonalityFixing_1[] = {
        ii->fixing(Date(14,January  ,2013),true),
        ii->fixing(Date(14,February ,2013),true),
        ii->fixing(Date(14,March    ,2013),true),
        ii->fixing(Date(14,April    ,2013),true),
        ii->fixing(Date(14,May      ,2013),true),
        ii->fixing(Date(14,June     ,2013),true),
        ii->fixing(Date(14,July     ,2013),true),
        ii->fixing(Date(14,August   ,2013),true),
        ii->fixing(Date(14,September,2013),true),
        ii->fixing(Date(14,October  ,2013),true),
        ii->fixing(Date(14,November ,2013),true),
        ii->fixing(Date(14,December ,2013),true)

    };

    for(int i=0;i<12;i++){
        if(std::fabs(fixing[i] - seasonalityFixing_1[i]) > eps) {
            BOOST_ERROR("Seasonality doesn't work correctly when seasonality factors are set = 1");
        }
    }

    //Testing seasonality correction when seasonality factors are different from 1
    //
    //0.998687 is the seasonality factor corresponding to June (the base CPI curve month)
    //
    Rate expectedFixing[] = {
        ii->fixing(Date(14,January  ,2013),true) * 1.003245/0.998687,
        ii->fixing(Date(14,February ,2013),true) * 1.000000/0.998687,
        ii->fixing(Date(14,March    ,2013),true) * 0.999715/0.998687,
        ii->fixing(Date(14,April    ,2013),true) * 1.000495/0.998687,
        ii->fixing(Date(14,May      ,2013),true) * 1.000929/0.998687,
        ii->fixing(Date(14,June     ,2013),true) * 0.998687/0.998687,
        ii->fixing(Date(14,July     ,2013),true) * 0.995949/0.998687,
        ii->fixing(Date(14,August   ,2013),true) * 0.994682/0.998687,
        ii->fixing(Date(14,September,2013),true) * 0.995949/0.998687,
        ii->fixing(Date(14,October  ,2013),true) * 1.000519/0.998687,
        ii->fixing(Date(14,November ,2013),true) * 1.003705/0.998687,
        ii->fixing(Date(14,December ,2013),true) * 1.004186/0.998687
    };

    hz->setSeasonality(seasonality_real);

    Rate seasonalityFixing_real[] = {
        ii->fixing(Date(14,January  ,2013),true),
        ii->fixing(Date(14,February ,2013),true),
        ii->fixing(Date(14,March    ,2013),true),
        ii->fixing(Date(14,April    ,2013),true),
        ii->fixing(Date(14,May      ,2013),true),
        ii->fixing(Date(14,June     ,2013),true),
        ii->fixing(Date(14,July     ,2013),true),
        ii->fixing(Date(14,August   ,2013),true),
        ii->fixing(Date(14,September,2013),true),
        ii->fixing(Date(14,October  ,2013),true),
        ii->fixing(Date(14,November ,2013),true),
        ii->fixing(Date(14,December ,2013),true)
    };

    for(int i=0;i<12;i++){
        if(std::fabs(expectedFixing[i] - seasonalityFixing_real[i]) > 0.01) {
            BOOST_ERROR("Seasonality doesn't work correctly when considering seasonality factors != 1 "
                        << expectedFixing[i] << " vs " << seasonalityFixing_real[i]);
        }
    }

    //Testing Unset function
    //
    QL_REQUIRE(hz->hasSeasonality(),"[4] incorrectly believes NO seasonality correction");
    hz->setSeasonality();
    QL_REQUIRE(!hz->hasSeasonality(),"[5] incorrectly believes HAS seasonality correction");

    Rate seasonalityFixing_unset[] = {
        ii->fixing(Date(14,January  ,2013),true),
        ii->fixing(Date(14,February ,2013),true),
        ii->fixing(Date(14,March    ,2013),true),
        ii->fixing(Date(14,April    ,2013),true),
        ii->fixing(Date(14,May      ,2013),true),
        ii->fixing(Date(14,June     ,2013),true),
        ii->fixing(Date(14,July     ,2013),true),
        ii->fixing(Date(14,August   ,2013),true),
        ii->fixing(Date(14,September,2013),true),
        ii->fixing(Date(14,October  ,2013),true),
        ii->fixing(Date(14,November ,2013),true),
        ii->fixing(Date(14,December ,2013),true)
    };

    for(int i=0;i<12;i++){
        if(std::fabs(seasonalityFixing_unset[i] - seasonalityFixing_1[i]) > eps) {
            BOOST_ERROR("UnsetSeasonality doesn't work correctly "
                        << seasonalityFixing_unset[i] << " vs " << seasonalityFixing_1[i]);
        }
    }



    //==============================================================================
    // now do an INTERPOLATED index, i.e. repeat everything on a fake version of
    // UKRPI (to save making another term structure)

    bool interpYES = true;
    boost::shared_ptr<UKRPI> iiUKRPIyes(new UKRPI(interpYES, hz));
    for (Size i=0; i<rpiSchedule.size();i++) {
        iiUKRPIyes->addFixing(rpiSchedule[i], fixData[i]);
    }

    boost::shared_ptr<ZeroInflationIndex> iiyes
        = boost::dynamic_pointer_cast<ZeroInflationIndex>(iiUKRPIyes);

    // now build the zero inflation curve
    // same data, bigger lag or it will be a self-contradiction
    Period observationLagyes = Period(3,Months);
    std::vector<boost::shared_ptr<BootstrapHelper<ZeroInflationTermStructure> > > helpersyes =
    makeHelpers<ZeroInflationTermStructure,ZeroCouponInflationSwapHelper,
    ZeroInflationIndex>(zcData, LENGTH(zcData), iiyes,
                        observationLagyes,
                        calendar, bdc, dc);

    boost::shared_ptr<PiecewiseZeroInflationCurve<Linear> > pZITSyes(
            new PiecewiseZeroInflationCurve<Linear>(
            evaluationDate, calendar, dc, observationLagyes,
            frequency, iiyes->interpolated(), baseZeroRate,
            Handle<YieldTermStructure>(nominalTS), helpersyes));
    pZITSyes->recalculate();

    // first check that the zero rates on the curve match the data
    // and that the helpers give the correct impled rates
    forceLinearInterpolation = false;   // still
    for (Size i=0; i<LENGTH(zcData); i++) {
        BOOST_CHECK_MESSAGE(std::fabs(zcData[i].rate/100.0
                    - pZITSyes->zeroRate(zcData[i].date, observationLagyes, forceLinearInterpolation)) < eps,
                    "ZITS INTERPOLATED zeroRate != instrument "
                    << pZITSyes->zeroRate(zcData[i].date, observationLagyes, forceLinearInterpolation)
                    << " date " << zcData[i].date << " observationLagyes " << observationLagyes
                    << " vs " << zcData[i].rate/100.0
                    << " interpolation: " << iiyes->interpolated()
                    << " forceLinearInterpolation " << forceLinearInterpolation);
        BOOST_CHECK_MESSAGE(std::fabs(helpersyes[i]->impliedQuote()
                        - zcData[i].rate/100.0) < eps,
                    "ZITS INTERPOLATED implied quote != instrument "
                    << helpersyes[i]->impliedQuote()
                    << " vs " << zcData[i].rate/100.0);
    }


    //======================================================================================
    // now test the forecasting capability of the index.
    hz.linkTo(pZITSyes);
    from = hz->baseDate()+1*Months; // to avoid historical linear bit for rest of base month
    to = hz->maxDate()-1*Months; // a bit of margin for adjustments
    testIndex = MakeSchedule().from(from).to(to)
    .withTenor(1*Months)
    .withCalendar(UnitedKingdom())
    .withConvention(ModifiedFollowing);

    // we are testing UKRPI which is FAKE interpolated for testing here
    bd = hz->baseDate();
    bf = iiyes->fixing(bd);
    for (Size i=0; i<testIndex.size();i++) {
        Date d = testIndex[i];
        Real z = hz->zeroRate(d, Period(0,Days));
        Real t = hz->dayCounter().yearFraction(bd, d);
        Real calc = bf * pow( 1+z, t);
        if (t<=0) calc = iiyes->fixing(d); // still historical
        if (std::fabs(calc - iiyes->fixing(d)) > eps)
            BOOST_ERROR("ZC INTERPOLATED index does not forecast correctly for date " << d
                        << " from base date " << bd
                        << " with fixing " << bf
                        << ", correct:  " << calc
                        << ", fix: " << iiyes->fixing(d)
                        << ", t " << t
                        << ", zero " << z);
    }



    //===========================================================================================
    // Test zero coupon swap

    boost::shared_ptr<ZeroInflationIndex> ziiyes = boost::dynamic_pointer_cast<ZeroInflationIndex>(iiyes);
    BOOST_REQUIRE_MESSAGE(ziiyes,"dynamic_pointer_cast to ZeroInflationIndex from UKRPI-I failed");
    ZeroCouponInflationSwap nzcisyes(ZeroCouponInflationSwap::Payer,
                                     1000000.0,
                                     evaluationDate,
                                     zcData[6].date,    // end date = maturity
                                     calendar, bdc, dc, zcData[6].rate/100.0, // fixed rate
                                     ziiyes, observationLagyes);

    // N.B. no coupon pricer because it is not a coupon, effect of inflation curve via
    //      inflation curve attached to the inflation index.
    nzcisyes.setPricingEngine(sppe);

    // ... and price it, should be zero
    BOOST_CHECK_MESSAGE(fabs(nzcisyes.NPV())<0.00001,"ZCIS-I does not reprice to zero "
                        << nzcisyes.NPV()
                        << evaluationDate << " to " << zcData[6].date << " becoming " << nzcisyes.maturityDate()
                        << " rate " << zcData[6].rate
                        << " fixed leg " << nzcisyes.legNPV(0)
                        << " indexed-predicted inflated leg " << nzcisyes.legNPV(1)
                        << " discount " << nominalTS->discount(nzcisyes.maturityDate())
                        );

}
Пример #19
0
int main(int, char* []) {

    try {

        boost::timer timer;
        std::cout << std::endl;

        Date repoSettlementDate(14,February,2000);;
        Date repoDeliveryDate(15,August,2000);
        Rate repoRate = 0.05;
        DayCounter repoDayCountConvention = Actual360();
        Integer repoSettlementDays = 0;
        Compounding repoCompounding = Simple;
        Frequency repoCompoundFreq = Annual;

        // assume a ten year bond- this is irrelevant
        Date bondIssueDate(15,September,1995);
        Date bondDatedDate(15,September,1995);
        Date bondMaturityDate(15,September,2005);
        Real bondCoupon = 0.08;
        Frequency bondCouponFrequency = Semiannual;
        // unknown what calendar fincad is using
        Calendar bondCalendar = NullCalendar();
        DayCounter bondDayCountConvention = Thirty360(Thirty360::BondBasis);
        // unknown what fincad is using. this may affect accrued calculation
        Integer bondSettlementDays = 0;
        BusinessDayConvention bondBusinessDayConvention = Unadjusted;
        Real bondCleanPrice = 89.97693786;
        Real bondRedemption = 100.0;
        Real faceAmount = 100.0;


        Settings::instance().evaluationDate() = repoSettlementDate;

        RelinkableHandle<YieldTermStructure> bondCurve;
        bondCurve.linkTo(boost::shared_ptr<YieldTermStructure>(
                                       new FlatForward(repoSettlementDate,
                                                       .01, // dummy rate
                                                       bondDayCountConvention,
                                                       Compounded,
                                                       bondCouponFrequency)));

        /*
        boost::shared_ptr<FixedRateBond> bond(
                       new FixedRateBond(faceAmount,
                                         bondIssueDate,
                                         bondDatedDate,
                                         bondMaturityDate,
                                         bondSettlementDays,
                                         std::vector<Rate>(1,bondCoupon),
                                         bondCouponFrequency,
                                         bondCalendar,
                                         bondDayCountConvention,
                                         bondBusinessDayConvention,
                                         bondBusinessDayConvention,
                                         bondRedemption,
                                         bondCurve));
        */

        Schedule bondSchedule(bondDatedDate, bondMaturityDate,
                              Period(bondCouponFrequency),
                              bondCalendar,bondBusinessDayConvention,
                              bondBusinessDayConvention,
                              DateGeneration::Backward,false);
        boost::shared_ptr<FixedRateBond> bond(
                       new FixedRateBond(bondSettlementDays,
                                         faceAmount,
                                         bondSchedule,
                                         std::vector<Rate>(1,bondCoupon),
                                         bondDayCountConvention,
                                         bondBusinessDayConvention,
                                         bondRedemption,
                                         bondIssueDate));
        bond->setPricingEngine(boost::shared_ptr<PricingEngine>(
                                       new DiscountingBondEngine(bondCurve)));

        bondCurve.linkTo(boost::shared_ptr<YieldTermStructure> (
                   new FlatForward(repoSettlementDate,
                                   bond->yield(bondCleanPrice,
                                               bondDayCountConvention,
                                               Compounded,
                                               bondCouponFrequency),
                                   bondDayCountConvention,
                                   Compounded,
                                   bondCouponFrequency)));

        Position::Type fwdType = Position::Long;
        double dummyStrike = 91.5745;

        RelinkableHandle<YieldTermStructure> repoCurve;
        repoCurve.linkTo(boost::shared_ptr<YieldTermStructure> (
                                       new FlatForward(repoSettlementDate,
                                                       repoRate,
                                                       repoDayCountConvention,
                                                       repoCompounding,
                                                       repoCompoundFreq)));


        FixedRateBondForward bondFwd(repoSettlementDate,
                                     repoDeliveryDate,
                                     fwdType,
                                     dummyStrike,
                                     repoSettlementDays,
                                     repoDayCountConvention,
                                     bondCalendar,
                                     bondBusinessDayConvention,
                                     bond,
                                     repoCurve,
                                     repoCurve);


        cout << "Underlying bond clean price: "
             << bond->cleanPrice()
             << endl;
        cout << "Underlying bond dirty price: "
             << bond->dirtyPrice()
             << endl;
        cout << "Underlying bond accrued at settlement: "
             << bond->accruedAmount(repoSettlementDate)
             << endl;
        cout << "Underlying bond accrued at delivery:   "
             << bond->accruedAmount(repoDeliveryDate)
             << endl;
        cout << "Underlying bond spot income: "
             << bondFwd.spotIncome(repoCurve)
             << endl;
        cout << "Underlying bond fwd income:  "
             << bondFwd.spotIncome(repoCurve)/
                repoCurve->discount(repoDeliveryDate)
             << endl;
        cout << "Repo strike: "
             << dummyStrike
             << endl;
        cout << "Repo NPV:    "
             << bondFwd.NPV()
             << endl;
        cout << "Repo clean forward price: "
             << bondFwd.cleanForwardPrice()
             << endl;
        cout << "Repo dirty forward price: "
             << bondFwd.forwardPrice()
             << endl;
        cout << "Repo implied yield: "
             << bondFwd.impliedYield(bond->dirtyPrice(),
                                     dummyStrike,
                                     repoSettlementDate,
                                     repoCompounding,
                                     repoDayCountConvention)
             << endl;
        cout << "Market repo rate:   "
             << repoCurve->zeroRate(repoDeliveryDate,
                                    repoDayCountConvention,
                                    repoCompounding,
                                    repoCompoundFreq)
             << endl
             << endl;

        cout << "Compare with example given at \n"
             << "http://www.fincad.com/support/developerFunc/mathref/BFWD.htm"
             <<  endl;
        cout << "Clean forward price = 88.2408"
             <<  endl
             <<  endl;
        cout << "In that example, it is unknown what bond calendar they are\n"
             << "using, as well as settlement Days. For that reason, I have\n"
             << "made the simplest possible assumptions here: NullCalendar\n"
             << "and 0 settlement days."
             << endl;


        double seconds = timer.elapsed();
        Integer hours = int(seconds/3600);
        seconds -= hours * 3600;
        Integer minutes = int(seconds/60);
        seconds -= minutes * 60;
        cout << " \nRun completed in ";
        if (hours > 0)
            cout << hours << " h ";
        if (hours > 0 || minutes > 0)
            cout << minutes << " m ";
        cout << fixed << setprecision(0)
             << seconds << " s\n" << endl;

        return 0;

    } catch (exception& e) {
        cerr << e.what() << endl;
        return 1;
    } catch (...) {
        cerr << "unknown error" << endl;
        return 1;
    }
}
void MCLongstaffSchwartzEngineTest::testAmericanMaxOption() {

    // reference values taken from
    // "Monte Carlo Methods in Financial Engineering",
    // by Paul Glasserman, 2004 Springer Verlag, p. 462

    BOOST_TEST_MESSAGE("Testing Monte-Carlo pricing of American max options...");

    SavedSettings backup;

    // most of the example taken from the EquityOption.cpp
    const Option::Type type(Option::Call);
    const Real strike = 100;
    const Spread dividendYield = 0.10;
    const Rate riskFreeRate = 0.05;
    const Volatility volatility = 0.20;

    const Date todaysDate(15, May, 1998);
    const Date settlementDate(17, May, 1998);
    Settings::instance().evaluationDate() = todaysDate;

    const Date maturity(16, May, 2001);
    const DayCounter dayCounter = Actual365Fixed();

    boost::shared_ptr<Exercise> americanExercise(
        new AmericanExercise(settlementDate, maturity));

    // bootstrap the yield/dividend/vol curves
    Handle<YieldTermStructure> flatTermStructure(
        boost::shared_ptr<YieldTermStructure>(
            new FlatForward(settlementDate, riskFreeRate, dayCounter)));
    Handle<YieldTermStructure> flatDividendTS(
        boost::shared_ptr<YieldTermStructure>(
            new FlatForward(settlementDate, dividendYield, dayCounter)));

    Handle<BlackVolTermStructure> flatVolTS(
        boost::shared_ptr<BlackVolTermStructure>(new
            BlackConstantVol(settlementDate, NullCalendar(),
                             volatility, dayCounter)));

    boost::shared_ptr<StrikedTypePayoff> payoff(
        new PlainVanillaPayoff(type, strike));

    RelinkableHandle<Quote> underlyingH;

    boost::shared_ptr<GeneralizedBlackScholesProcess> stochasticProcess(new
        GeneralizedBlackScholesProcess(
            underlyingH, flatDividendTS, flatTermStructure, flatVolTS));

    const Size numberAssets = 2;
    Matrix corr(numberAssets, numberAssets, 0.0);
    std::vector<boost::shared_ptr<StochasticProcess1D> > v;

    for (Size i=0; i<numberAssets; ++i) {
        v.push_back(stochasticProcess);
        corr[i][i] = 1.0;
    }

    boost::shared_ptr<StochasticProcessArray> process(
        new StochasticProcessArray(v, corr));
    VanillaOption americanMaxOption(payoff, americanExercise);

    boost::shared_ptr<PricingEngine> mcengine(
        new MCAmericanMaxEngine<PseudoRandom>(process, 25, Null<Size>(), false,
                                              true, false, 4096,
                                              Null<Real>(), Null<Size>(),
                                              42, 1024));
    americanMaxOption.setPricingEngine(mcengine);

    const Real expected[] = {8.08, 13.90, 21.34};
    for (Size i = 0; i < 3; ++i) {

        const Real underlying = 90.0 + i*10.0;
        underlyingH.linkTo(
            boost::shared_ptr<Quote>(new SimpleQuote(underlying)));

        const Real calculated  = americanMaxOption.NPV();
        const Real errorEstimate = americanMaxOption.errorEstimate();
        if (std::fabs(calculated - expected[i]) > 2.34*errorEstimate) {
                BOOST_ERROR("Failed to reproduce american option prices"
                            << "\n    expected: " << expected[i]
                            << "\n    calculated:   " << calculated
                            << " +/- " << errorEstimate);
        }
    }
}
Пример #21
0
void CdsOptionTest::testCached() {

    BOOST_TEST_MESSAGE("Testing CDS-option value against cached values...");

    SavedSettings backup;

    Date cachedToday = Date(10,December,2007);
    Settings::instance().evaluationDate() = cachedToday;

    Calendar calendar = TARGET();

    RelinkableHandle<YieldTermStructure> riskFree;
    riskFree.linkTo(boost::shared_ptr<YieldTermStructure>(
                              new FlatForward(cachedToday,0.02,Actual360())));

    Date expiry = calendar.advance(cachedToday,9,Months);
    Date startDate = calendar.advance(expiry,1,Months);
    Date maturity = calendar.advance(startDate,7,Years);

    DayCounter dayCounter = Actual360();
    BusinessDayConvention convention = ModifiedFollowing;
    Real notional = 1000000.0;

    Handle<Quote> hazardRate(boost::shared_ptr<Quote>(new SimpleQuote(0.001)));

    Schedule schedule(startDate,maturity, Period(Quarterly),
                      calendar, convention, convention,
                      DateGeneration::Forward, false);

    Real recoveryRate = 0.4;
    Handle<DefaultProbabilityTermStructure> defaultProbability(
        boost::shared_ptr<DefaultProbabilityTermStructure>(
                    new FlatHazardRate(0, calendar, hazardRate, dayCounter)));

    boost::shared_ptr<PricingEngine> swapEngine(
           new MidPointCdsEngine(defaultProbability, recoveryRate, riskFree));

    CreditDefaultSwap swap(Protection::Seller, notional, 0.001, schedule,
                           convention, dayCounter);
    swap.setPricingEngine(swapEngine);
    Rate strike = swap.fairSpread();

    Handle<Quote> cdsVol(boost::shared_ptr<Quote>(new SimpleQuote(0.20)));

    boost::shared_ptr<CreditDefaultSwap> underlying(
         new CreditDefaultSwap(Protection::Seller, notional, strike, schedule,
                               convention, dayCounter));
    underlying->setPricingEngine(swapEngine);

    boost::shared_ptr<Exercise> exercise(new EuropeanExercise(expiry));
    CdsOption option1(underlying, exercise);
    option1.setPricingEngine(boost::shared_ptr<PricingEngine>(
                    new BlackCdsOptionEngine(defaultProbability, recoveryRate,
                                             riskFree, cdsVol)));

    Real cachedValue = 270.976348;
    if (std::fabs(option1.NPV() - cachedValue) > 1.0e-5)
        BOOST_ERROR("failed to reproduce cached value:\n"
                    << std::fixed << std::setprecision(6)
                    << "    calculated: " << option1.NPV() << "\n"
                    << "    expected:   " << cachedValue);

    underlying = boost::shared_ptr<CreditDefaultSwap>(
         new CreditDefaultSwap(Protection::Buyer, notional, strike, schedule,
                               convention, dayCounter));
    underlying->setPricingEngine(swapEngine);

    CdsOption option2(underlying, exercise);
    option2.setPricingEngine(boost::shared_ptr<PricingEngine>(
                    new BlackCdsOptionEngine(defaultProbability, recoveryRate,
                                             riskFree, cdsVol)));

    cachedValue = 270.976348;
    if (std::fabs(option2.NPV() - cachedValue) > 1.0e-5)
        BOOST_ERROR("failed to reproduce cached value:\n"
                    << std::fixed << std::setprecision(6)
                    << "    calculated: " << option2.NPV() << "\n"
                    << "    expected:   " << cachedValue);
}