Example #1
0
const Real Gaussian1dModel::forwardRate(const Date &fixing,
                                        const Date &referenceDate, const Real y,
                                        boost::shared_ptr<IborIndex> iborIdx) const {

    QL_REQUIRE(iborIdx != NULL, "no ibor index given");

    calculate();

    if (fixing <= (evaluationDate_ + (enforcesTodaysHistoricFixings_ ? 0 : -1)))
        return iborIdx->fixing(fixing);

    Handle<YieldTermStructure> yts =
        iborIdx->forwardingTermStructure(); // might be empty, then use
    // model curve

    Date valueDate = iborIdx->valueDate(fixing);
    Date endDate = iborIdx->fixingCalendar().advance(
                       valueDate, iborIdx->tenor(), iborIdx->businessDayConvention(),
                       iborIdx->endOfMonth());
    // FIXME Here we should use the calculation date calendar ?
    Real dcf = iborIdx->dayCounter().yearFraction(valueDate, endDate);

    return (zerobond(valueDate, referenceDate, y, yts) -
            zerobond(endDate, referenceDate, y, yts)) /
           (dcf * zerobond(endDate, referenceDate, y, yts));
}
const Real
Gaussian1dModel::swapRate(const Date &fixing, const Period &tenor,
                          const Date &referenceDate, const Real y,
                          boost::shared_ptr<SwapIndex> swapIdx) const {

    QL_REQUIRE(swapIdx != NULL, "no swap index given");

    calculate();

    if (fixing <=
            (evaluationDate_ + (enforcesTodaysHistoricFixings_ ? 0 : -1)))
        return swapIdx->fixing(fixing);

    Handle<YieldTermStructure> ytsf =
        swapIdx->iborIndex()->forwardingTermStructure();
    Handle<YieldTermStructure> ytsd =
        swapIdx->discountingTermStructure(); // either might be empty, then
    // use model curve

    Schedule sched, floatSched;

    boost::shared_ptr<VanillaSwap> underlying = underlyingSwap(swapIdx, fixing, tenor);

    sched = underlying->fixedSchedule();

    boost::shared_ptr<OvernightIndexedSwapIndex> oisIdx =
        boost::dynamic_pointer_cast<OvernightIndexedSwapIndex>(swapIdx);
    if (oisIdx != NULL) {
        floatSched = sched;
    } else {
        floatSched = underlying->floatingSchedule();
    }

    Real annuity = swapAnnuity(fixing, tenor, referenceDate, y,
                               swapIdx); // should be fine for
    // overnightindexed swap indices as
    // well
    Rate floatleg = 0.0;
    if (ytsf.empty() && ytsd.empty()) { // simple 100-formula can be used
        // only in one curve setup
        floatleg = (zerobond(sched.dates().front(), referenceDate, y) -
                    zerobond(sched.calendar().adjust(
                                 sched.dates().back(),
                                 underlying->paymentConvention()),
                             referenceDate, y));
    } else {
        for (Size i = 1; i < floatSched.size(); i++) {
            floatleg +=
                (zerobond(floatSched[i - 1], referenceDate, y, ytsf) /
                 zerobond(floatSched[i], referenceDate, y, ytsf) -
                 1.0) *
                zerobond(
                    floatSched.calendar().adjust(
                        floatSched[i], underlying->paymentConvention()),
                    referenceDate, y, ytsd);
        }
    }
    return floatleg / annuity;
}
Example #3
0
const Real Gaussian1dModel::swapAnnuity(const Date &fixing, const Period &tenor,
                                        const Date &referenceDate, const Real y,
                                        boost::shared_ptr<SwapIndex> swapIdx) const {

    QL_REQUIRE(swapIdx != NULL, "no swap index given");

    calculate();

    Handle<YieldTermStructure> ytsd =
        swapIdx->discountingTermStructure(); // might be empty, then use
    // model curve

    boost::shared_ptr<VanillaSwap> underlying =
        underlyingSwap(swapIdx, fixing, tenor);

    Schedule sched = underlying->fixedSchedule();

    Real annuity = 0.0;
    for (unsigned int j = 1; j < sched.size(); j++) {
        annuity += zerobond(sched.calendar().adjust(
                                sched.date(j), underlying->paymentConvention()),
                            referenceDate, y, ytsd) *
                   swapIdx->dayCounter().yearFraction(sched.date(j - 1),
                           sched.date(j));
    }
    return annuity;
}
Real Qg1dLocalVolModel::zerobond(const Date &maturity,
                                 const Date &referenceDate, const Real x,
                                 const Real y,
                                 const Handle<YieldTermStructure> &yts) {
    return zerobond(termStructure()->timeFromReference(maturity),
                    termStructure()->timeFromReference(referenceDate), x, y,
                    yts);
}
Example #5
0
    const Real Gsr::numeraireImpl(const Time t, const Real y,
                                  const Handle<YieldTermStructure> &yts) const {

        calculate();

        boost::shared_ptr<GsrProcess> p =
            boost::dynamic_pointer_cast<GsrProcess>(stateProcess_);

        if (t == 0)
            return yts.empty() ? this->termStructure()->discount(
                                     p->getForwardMeasureTime(), true)
                               : yts->discount(p->getForwardMeasureTime());
        return zerobond(p->getForwardMeasureTime(), t, y, yts);
    }
void Qg1dLocalVolModel::swapRate_d0_d1_d2(
    const Real T0, const Real t, const std::vector<Real> &fixedTimes,
    const std::vector<Real> &taus, const Real x, const Real y,
    const Handle<YieldTermStructure> &yts, Real &result_d0, Real &result_d1,
    Real &result_d2, const bool compute_d0, const bool compute_d1,
    const bool compute_d2) const {

    Real a = 0.0, sum = 0.0, sum2 = 0.0;

    for (Size i = 0; i < fixedTimes.size(); ++i) {
        Real tmp = taus[i] * zerobond(fixedTimes[i], t, x, y, yts);
        a += tmp;
        if (compute_d1 || compute_d2) {
            Real g = G(t, fixedTimes[i]);
            sum += tmp * g;
            if (compute_d2)
                sum2 += tmp * g * g;
        }
    }
    Real Tn = fixedTimes.back();
    Real z0 = zerobond(T0, t, x, y, yts);
    Real zn = zerobond(Tn, t, x, y, yts);
    Real g0 = 0.0, gn = 0.0; // avoid maybe-uninitialized warnings
    if (compute_d2 || compute_d1) {
        g0 = G(t, T0);
        gn = G(t, Tn);
    }
    if (compute_d0 || compute_d2)
        result_d0 = (z0 - zn) / a;
    if (compute_d1 || compute_d2)
        result_d1 = (-g0 * z0 + gn * zn) / a + (z0 - zn) / (a * a) * sum;
    if (compute_d2)
        result_d2 =
            ((g0 * g0 * z0 - gn * gn * zn) * a + (gn * zn - g0 * z0) * sum +
             (result_d1 * sum - result_d0 * sum2) * a + result_d0 * sum * sum) /
            (a * a);
}
Example #7
0
const Real Gaussian1dModel::zerobondOption(
    const Option::Type &type, const Date &expiry, const Date &valueDate,
    const Date &maturity, const Rate strike, const Date &referenceDate,
    const Real y, const Handle<YieldTermStructure> &yts, const Real yStdDevs,
    const Size yGridPoints, const bool extrapolatePayoff,
    const bool flatPayoffExtrapolation) const {

    calculate();

    Time fixingTime = termStructure()->timeFromReference(expiry);
    Time referenceTime =
        referenceDate == Null<Date>()
        ? 0.0
        : termStructure()->timeFromReference(referenceDate);

    Array yg = yGrid(yStdDevs, yGridPoints, fixingTime, referenceTime, y);
    Array z = yGrid(yStdDevs, yGridPoints);

    Array p(yg.size());

    for (Size i = 0; i < yg.size(); i++) {
        Real expValDsc = zerobond(valueDate, expiry, yg[i], yts);
        Real discount =
            zerobond(maturity, expiry, yg[i], yts) / expValDsc;
        p[i] =
            std::max((type == Option::Call ? 1.0 : -1.0) * (discount - strike),
                     0.0) /
            numeraire(fixingTime, yg[i], yts) * expValDsc;
    }

    CubicInterpolation payoff(
        z.begin(), z.end(), p.begin(), CubicInterpolation::Spline, true,
        CubicInterpolation::Lagrange, 0.0, CubicInterpolation::Lagrange, 0.0);

    Real price = 0.0;
    for (Size i = 0; i < z.size() - 1; i++) {
        price += gaussianShiftedPolynomialIntegral(
                     0.0, payoff.cCoefficients()[i], payoff.bCoefficients()[i],
                     payoff.aCoefficients()[i], p[i], z[i], z[i], z[i + 1]);
    }
    if (extrapolatePayoff) {
        if (flatPayoffExtrapolation) {
            price += gaussianShiftedPolynomialIntegral(
                         0.0, 0.0, 0.0, 0.0, p[z.size() - 2], z[z.size() - 2],
                         z[z.size() - 1], 100.0);
            price += gaussianShiftedPolynomialIntegral(0.0, 0.0, 0.0, 0.0, p[0],
                     z[0], -100.0, z[0]);
        } else {
            if (type == Option::Call)
                price += gaussianShiftedPolynomialIntegral(
                             0.0, payoff.cCoefficients()[z.size() - 2],
                             payoff.bCoefficients()[z.size() - 2],
                             payoff.aCoefficients()[z.size() - 2], p[z.size() - 2],
                             z[z.size() - 2], z[z.size() - 1], 100.0);
            if (type == Option::Put)
                price += gaussianShiftedPolynomialIntegral(
                             0.0, payoff.cCoefficients()[0], payoff.bCoefficients()[0],
                             payoff.aCoefficients()[0], p[0], z[0], -100.0, z[0]);
        }
    }

    return numeraire(referenceTime, y, yts) * price;
}