Пример #1
0
 Real SmileSection::volatility(Rate strike, VolatilityType volatilityType,
                               Real shift) const {
     if(volatilityType == volatilityType_ && close(shift,this->shift()))
         return volatility(strike);
     Real atm = atmLevel();
     QL_REQUIRE(atm != Null<Real>(),
                "smile section must provide atm level to compute converted volatilties");
     Option::Type type = strike >= atm ? Option::Call : Option::Put;
     Real premium = optionPrice(strike,type);
     Real premiumAtm = optionPrice(atm,type);
     if (volatilityType == ShiftedLognormal) {
         try {
             return blackFormulaImpliedStdDev(type, strike, atm, premium,
                                              1.0, shift) /
                    std::sqrt(exerciseTime());
         } catch(...) {
             return blackFormulaImpliedStdDevChambers(
                 type, strike, atm, premium, premiumAtm, 1.0, shift) /
                    std::sqrt(exerciseTime());
         }
     } else {
             return bachelierBlackFormulaImpliedVol(type, strike, atm,
                                                    exerciseTime(), premium);
         }
 }
Пример #2
0
 Real SmileSection::digitalOptionPrice(Rate strike,
                                       Option::Type type,
                                       Real discount,
                                       Real gap) const {
     Real m = volatilityType() == ShiftedLognormal ? -shift() : -QL_MAX_REAL;
     Real kl = std::max(strike-gap/2.0,m);
     Real kr = kl+gap;
     return (type==Option::Call ? 1.0 : -1.0) *
         (optionPrice(kl,type,discount)-optionPrice(kr,type,discount)) / gap;
 }
    Disposable<Array> SplineDensitySmileSection::setDensity(const Array& d) {
        
        Array errors(c_.size()-2);
        
        std::cout << "***************************" << std::endl;
        Real signChanges = 0.0;
        for(Size i=1;i<d_.size()-1;i++) {
            d_[i] = d[i-1]*d[i-1];
            std::cout << "knot " <<  i << " dens " << d_[i] << std::endl;
            if( (d_[i]-d_[i-1]) * (d_[i+1]-d_[i]) < 0.0)
                signChanges+=1.0;
        }
        if(signChanges > 0.0) signChanges -= 1.0;

        density_->update();
        update();

        Real penalty =
            1.0 + /*((std::exp(10.0* (f_ - expectation_) * (f_ - expectation_)) - 1.0) +*/
            (std::exp((1.0 - adjustment_) * (1.0 - adjustment_)) - 1.0);
            //(std::exp(signChanges)-1.0);

        for (Size i = 1; i < c_.size() - 1; i++) {
            errors[i-1] = (c_[i] - optionPrice(k_[i])) * penalty;
            std::cout << "strike " << k_[i] << " market " << c_[i] << " spline " << c_[i] - errors[i-1] << std::endl;
        }
        std::cout << "penatly = " << penalty << std::endl;

        return errors;

    }
Пример #4
0
 Real BdkSmileSection::volatilityImpl(Rate strike) const {
     Real vol = 0.0;
     try {
         vol = blackFormulaImpliedStdDev(Option::Call, strike, f_,
                                         optionPrice(strike)) /
               sqrt(source_->exerciseTime());
     }
     catch (QuantLib::Error) {
     }
     return vol;
 }
Real Gaussian1dSmileSection::volatilityImpl(Rate strike) const {
    Real vol = 0.0;
    try {
        Option::Type type = strike >= atm_ ? Option::Call : Option::Put;
        Real o = optionPrice(strike, type);
        vol = blackFormulaImpliedStdDev(type, strike, atm_, o) /
              sqrt(exerciseTime());
    } catch (...) {
    }
    return vol;
}
    Real SplineDensitySmileSection::setDensity(const Real d, const Size i) {
        
        d_[i] = d*d;

        density_->update();
        update();

        Real p = optionPrice(k_[i]);
        std::cout << std::setprecision(16) << "strike " << k_[i] << " dens " << d << " market " << c_[i] << " spline " << p << " error " << (p-c_[i]) << std::endl;
        
        return p-c_[i];

    }
    Real SplineDensitySmileSection::volatilityImpl(Rate strike) const {
        strike = std::max(strike,0.00001);  // assume only non shifted lognormal
                                            // here ... TODO later ... (should be
                                            // shifted lognormal with shift equal
                                            // to minus lowerBound_

        Option::Type type = strike >= f_ ? Option::Call : Option::Put;        
        Real p = optionPrice(strike,type);
        Real vol = 0.0;
        try {
            vol = blackFormulaImpliedStdDev(type, strike, f_, p) /
                  sqrt(exerciseTime());
        }
        catch (...) {
        }
        return vol;
    }
    Real SplineDensitySmileSection::optionPrice(Rate strike, Option::Type type, Real discount) const {
        
        if(type == Option::Put) return discount*(optionPrice(strike, Option::Call, 1.0) - f_ + strike);

        //strike += expectation_-f_;

        if(strike <= lowerBound_) return f_-strike;
        if(strike >= upperBound_) return 0.0;

        Real price = f_- lowerBound_;// + expectation_-f_;

        // const std::vector<Real> &pa_ = density_->cCoefficients(); // just for our convenience
        // const std::vector<Real> &pb_ = density_->bCoefficients();
        // const std::vector<Real> &pc_ = density_->aCoefficients();
        const std::vector<Real> &pd_ = d_;

        for(Size j=0; j<=index(strike); j++) {

            Real mu = std::min(k_[j+1],strike);
            Real dk = mu - k_[j];
            Real dk2 = dk*dk;

            // price += (dk * (adjustment_*lambda_[j] - 1.0) + adjustment_*(
            //                         1.0 / 20.0 * pa_[j] * dk2*dk2*dk +
            //                         1.0 / 12.0 * pb_[j] * dk2*dk2 +
            //                         1.0 / 6.0 * pc_[j] * dk2*dk +
            //                         1.0 / 2.0 * pd_[j] * dk2));
            
            // linear interpolation
            Real pa=0.0,pb=0.0;
            Real pc=(d_[j+1]-d_[j])/(k_[j+1]-k_[j]);
            price += (dk * (adjustment_*lambda_[j] - 1.0) + adjustment_*(
                                    1.0 / 20.0 * pa * dk2*dk2*dk +
                                    1.0 / 12.0 * pb * dk2*dk2 +
                                    1.0 / 6.0 * pc * dk2*dk +
                                    1.0 / 2.0 * pd_[j] * dk2));

        }

        return price;

    }
Пример #9
0
Real NoArbSabrSmileSection::volatilityImpl(Rate strike) const {

    Real impliedVol = 0.0;
    try {
        Option::Type type;
        if (strike >= forward_)
            type = Option::Call;
        else
            type = Option::Put;
        impliedVol =
            blackFormulaImpliedStdDev(type, strike, forward_,
                                      optionPrice(strike, type, 1.0), 1.0) /
            std::sqrt(exerciseTime());
    } catch (...) {
    }
    if (impliedVol == 0.0)
        // fall back on Hagan 2002 expansion
        impliedVol =
            unsafeSabrVolatility(strike, forward_, exerciseTime(), params_[0],
                                 params_[1], params_[2], params_[3]);

    return impliedVol;
}