예제 #1
0
 boost::shared_ptr<SmileSection>
 SwaptionVolCube2::smileSectionImpl(const Date& optionDate,
                                    const Period& swapTenor) const {
     calculate();
     Rate atmForward = atmStrike(optionDate, swapTenor);
     Volatility atmVol = atmVol_->volatility(optionDate,
                                             swapTenor,
                                             atmForward);
     Time optionTime = timeFromReference(optionDate);
     Real exerciseTimeSqrt = std::sqrt(optionTime);
     std::vector<Real> strikes, stdDevs;
     strikes.reserve(nStrikes_);
     stdDevs.reserve(nStrikes_);
     Time length = swapLength(swapTenor);
     for (Size i=0; i<nStrikes_; ++i) {
         strikes.push_back(atmForward + strikeSpreads_[i]);
         stdDevs.push_back(exerciseTimeSqrt*(
             atmVol + volSpreadsInterpolator_[i](length, optionTime)));
     }
     Real shift = atmVol_->shift(optionTime,length);
     return boost::shared_ptr<SmileSection>(new
         InterpolatedSmileSection<Linear>(optionTime,
                                          strikes,
                                          stdDevs,
                                          atmForward,
                                          Linear(),
                                          Actual365Fixed(),
                                          volatilityType(),
                                          shift));
 }
예제 #2
0
 inline Volatility
 SwaptionVolatilityStructure::volatilityImpl(const Date& optionDate,
                                             const Period& swapTenor,
                                             Rate strike) const {
     return volatilityImpl(timeFromReference(optionDate),
                           swapLength(swapTenor),
                           strike);
 }
예제 #3
0
inline Real
SwaptionVolatilityStructure::shift(Time optionTime,
                                   const Period& swapTenor,
                                   bool extrapolate) const {
    checkSwapTenor(swapTenor, extrapolate);
    checkRange(optionTime, extrapolate);
    Time length = swapLength(swapTenor);
    return shiftImpl(optionTime, length);
}
예제 #4
0
 inline Volatility
 SwaptionVolatilityStructure::volatility(Time optionTime,
                                         const Period& swapTenor,
                                         Rate strike,
                                         bool extrapolate) const {
     checkSwapTenor(swapTenor, extrapolate);
     checkRange(optionTime, extrapolate);
     checkStrike(strike, extrapolate);
     Time length = swapLength(swapTenor);
     return volatilityImpl(optionTime, length, strike);
 }
예제 #5
0
 inline Time SwaptionVolatilityStructure::maxSwapLength() const {
     return swapLength(maxSwapTenor());
 }
예제 #6
0
 // 4. default implementation of Date-based xxxImpl methods
 //    relying on the equivalent Time-based methods
 inline boost::shared_ptr<SmileSection>
 SwaptionVolatilityStructure::smileSectionImpl(const Date& optionDate,
                                               const Period& swapT) const {
     return smileSectionImpl(timeFromReference(optionDate),
                             swapLength(swapT));
 }
 //@}
 //! \name Other inspectors
 //@{
 //! returns the lower indexes of surrounding volatility matrix corners
 std::pair<Size,Size> locate(const Date& optionDate,
                             const Period& swapTenor) const {
     return locate(timeFromReference(optionDate),
                   swapLength(swapTenor));
 }
예제 #8
0
    std::vector<Real> SwaptionVolCube1::spreadVolInterpolation(
        const Date& atmOptionDate, const Period& atmSwapTenor) const {

        Time atmOptionTime = timeFromReference(atmOptionDate);
        Time atmTimeLength = swapLength(atmSwapTenor);

        std::vector<Real> result;
        const std::vector<Time>& optionTimes(sparseParameters_.optionTimes());
        const std::vector<Time>& swapLengths(sparseParameters_.swapLengths());
        const std::vector<Date>& optionDates =
            sparseParameters_.optionDates();
        const std::vector<Period>& swapTenors = sparseParameters_.swapTenors();

        std::vector<Real>::const_iterator optionTimesPreviousNode,
                                          swapLengthsPreviousNode;

        optionTimesPreviousNode = std::lower_bound(optionTimes.begin(),
                                                   optionTimes.end(),
                                                   atmOptionTime);
        Size optionTimesPreviousIndex =
            optionTimesPreviousNode - optionTimes.begin();
        if (optionTimesPreviousIndex >0)
            optionTimesPreviousIndex --;

        swapLengthsPreviousNode = std::lower_bound(swapLengths.begin(),
                                                   swapLengths.end(),
                                                   atmTimeLength);
        Size swapLengthsPreviousIndex = swapLengthsPreviousNode - swapLengths.begin();
        if (swapLengthsPreviousIndex >0)
            swapLengthsPreviousIndex --;

        std::vector< std::vector<boost::shared_ptr<SmileSection> > > smiles;
        std::vector<boost::shared_ptr<SmileSection> >  smilesOnPreviousExpiry;
        std::vector<boost::shared_ptr<SmileSection> >  smilesOnNextExpiry;

        QL_REQUIRE(optionTimesPreviousIndex+1 < sparseSmiles_.size(),
                   "optionTimesPreviousIndex+1 >= sparseSmiles_.size()");
        QL_REQUIRE(swapLengthsPreviousIndex+1 < sparseSmiles_[0].size(),
                   "swapLengthsPreviousIndex+1 >= sparseSmiles_[0].size()");
        smilesOnPreviousExpiry.push_back(
              sparseSmiles_[optionTimesPreviousIndex][swapLengthsPreviousIndex]);
        smilesOnPreviousExpiry.push_back(
              sparseSmiles_[optionTimesPreviousIndex][swapLengthsPreviousIndex+1]);
        smilesOnNextExpiry.push_back(
              sparseSmiles_[optionTimesPreviousIndex+1][swapLengthsPreviousIndex]);
        smilesOnNextExpiry.push_back(
              sparseSmiles_[optionTimesPreviousIndex+1][swapLengthsPreviousIndex+1]);

        smiles.push_back(smilesOnPreviousExpiry);
        smiles.push_back(smilesOnNextExpiry);

        std::vector<Real> optionsNodes(2);
        optionsNodes[0] = optionTimes[optionTimesPreviousIndex];
        optionsNodes[1] = optionTimes[optionTimesPreviousIndex+1];

        std::vector<Date> optionsDateNodes(2);
        optionsDateNodes[0] = optionDates[optionTimesPreviousIndex];
        optionsDateNodes[1] = optionDates[optionTimesPreviousIndex+1];

        std::vector<Real> swapLengthsNodes(2);
        swapLengthsNodes[0] = swapLengths[swapLengthsPreviousIndex];
        swapLengthsNodes[1] = swapLengths[swapLengthsPreviousIndex+1];

        std::vector<Period> swapTenorNodes(2);
        swapTenorNodes[0] = swapTenors[swapLengthsPreviousIndex];
        swapTenorNodes[1] = swapTenors[swapLengthsPreviousIndex+1];

        Rate atmForward = atmStrike(atmOptionDate, atmSwapTenor);

        Matrix atmForwards(2, 2, 0.0);
        Matrix atmVols(2, 2, 0.0);
        for (Size i=0; i<2; i++) {
            for (Size j=0; j<2; j++) {
                atmForwards[i][j] = atmStrike(optionsDateNodes[i],
                                              swapTenorNodes[j]);
                // atmVols[i][j] = smiles[i][j]->volatility(atmForwards[i][j]);
                atmVols[i][j] = atmVol_->volatility(
                    optionsDateNodes[i], swapTenorNodes[j], atmForwards[i][j]);
                /* With the old implementation the interpolated spreads on ATM
                   volatilities were null even if the spreads on ATM volatilities to be
                   interpolated were non-zero. The new implementation removes
                   this behaviour, but introduces a small ERROR in the cube:
                   even if no spreads are applied on any cube ATM volatility corresponding
                   to quoted smile sections (that is ATM volatilities in sparse cube), the
                   cube ATM volatilities corresponding to not quoted smile sections (that
                   is ATM volatilities in dense cube) are no more exactly the quoted values,
                   but that ones PLUS the linear interpolation of the fit errors on the ATM
                   volatilities in sparse cube whose spreads are used in the calculation.
                   A similar imprecision is introduced to the volatilities in dense cube
                   whith moneyness near to 1.
                   (See below how spreadVols are calculated).
                   The extent of this error depends on the quality of the fit: in case of
                   good fits it is negligibile.
                */
            }
        }

        for (Size k=0; k<nStrikes_; k++){
            const Real strike = std::max(atmForward + strikeSpreads_[k],MINSTRIKE);
            const Real moneyness = atmForward/strike;

            Matrix strikes(2,2,0.);
            Matrix spreadVols(2,2,0.);
            for (Size i=0; i<2; i++){
                for (Size j=0; j<2; j++){
                    strikes[i][j] = atmForwards[i][j]/moneyness;
                    spreadVols[i][j] =
                        smiles[i][j]->volatility(strikes[i][j]) - atmVols[i][j];
                }
            }
           Cube localInterpolator(optionsDateNodes, swapTenorNodes,
                                  optionsNodes, swapLengthsNodes, 1);
           localInterpolator.setLayer(0, spreadVols);
           localInterpolator.updateInterpolators();

           result.push_back(localInterpolator(atmOptionTime, atmTimeLength)[0]);
        }
        return result;
    }
예제 #9
0
inline Real
SwaptionVolatilityStructure::shiftImpl(const Date &optionDate,
                                       const Period &swapTenor) const {
    return shiftImpl(timeFromReference(optionDate), swapLength(swapTenor));
}