Real HullWhiteSmileSection::volatilityImpl(Rate strike) const {
		
		boost::shared_ptr<VanillaSwap> underlying = MakeVanillaSwap(swapLength_,swapIndex_->iborIndex(),strike)
																	.withEffectiveDate(swapIndex_->valueDate(optionDate_))  
																	.withFixedLegCalendar(swapIndex_->fixingCalendar())
													                .withFixedLegDayCount(swapIndex_->dayCounter())
													                .withFixedLegTenor(swapIndex_->fixedLegTenor())
													                .withFixedLegConvention(swapIndex_->fixedLegConvention())
													                .withFixedLegTerminationDateConvention(swapIndex_->fixedLegConvention())
																	.withType(VanillaSwap::Payer);
		underlying->setPricingEngine(discountingEngine_);
		boost::shared_ptr<Exercise> exercise(new EuropeanExercise(optionDate_));
		Swaption swaption(underlying,exercise);
		swaption.setPricingEngine(jamshidianEngine_);
		Real npv = swaption.NPV();
		Real annuity = fabs(underlying->fixedLegBPS() * 10000.0);

		//Real blackNpv=blackFormula(Option::Call,strike,atm,0.30*sqrt(exerciseTime()));
		//std::cout << std::setprecision(8) << "SECTION atm=" << atm_ << " annuity=" << annuity << " npv=" << npv << " strike= " << strike << std::endl;

		Real vol=0.0;
		try {
			vol=blackFormulaImpliedStdDev(Option::Call,strike,atm_,npv,annuity) / sqrt(exerciseTime());
		} catch(QuantLib::Error) {
			//std::cout << " can not imply vol for npv " << npv << " black(300%)=" << blackFormula(Option::Call,strike,atm_,sqrt(exerciseTime())*3.00,annuity) << 
			//	" black(1%)=" << blackFormula(Option::Call,strike,atm_,sqrt(exerciseTime())*0.01,annuity) << std::endl;
			if(npv>blackFormula(Option::Call,strike,atm_,3.00,annuity)) vol =3.0/sqrt(exerciseTime());
			else vol=0.0;
		}
		return vol;

     }
Example #2
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);
         }
 }
 InterpolatedSmileSection<Interpolator>::InterpolatedSmileSection(
                        const Date& d,
                        const std::vector<Rate>& strikes,
                        const std::vector<Real>& stdDevs,
                        Real atmLevel,
                        const DayCounter& dc,
                        const Interpolator& interpolator,
                        const Date& referenceDate,
                        const Real shift)
 : SmileSection(d, dc, referenceDate, ShiftedLognormal, shift),
   exerciseTimeSquareRoot_(std::sqrt(exerciseTime())), strikes_(strikes),
   stdDevHandles_(stdDevs.size()), vols_(stdDevs.size())
 {
     //fill dummy handles to allow generic handle-based
     // computations later on
     for (Size i=0; i<stdDevs.size(); ++i)
         stdDevHandles_[i] = Handle<Quote>(boost::shared_ptr<Quote>(new
             SimpleQuote(stdDevs[i])));
     atmLevel_ = Handle<Quote>
        (boost::shared_ptr<Quote>(new SimpleQuote(atmLevel)));
     // check strikes!!!!!!!!!!!!!!!!!!!!
     interpolation_ = interpolator.interpolate(strikes_.begin(),
                                               strikes_.end(),
                                               vols_.begin());
 }
 void SabrInterpolatedSmileSection::createInterpolation() const {
      boost::shared_ptr<SABRInterpolation> tmp(new SABRInterpolation(
                  actualStrikes_.begin(), actualStrikes_.end(), vols_.begin(),
                  exerciseTime(), forwardValue_,
                  alpha_, beta_, nu_, rho_,
                  isAlphaFixed_, isBetaFixed_, isNuFixed_, isRhoFixed_, vegaWeighted_,
                  endCriteria_, method_, 0.0020, false, 50, shift()));
      swap(tmp, sabrInterpolation_);
 }
Example #5
0
 Real SmileSection::vega(Rate strike, Real discount) const {
     Real atm = atmLevel();
     QL_REQUIRE(atm != Null<Real>(),
                "smile section must provide atm level to compute option vega");
     if (volatilityType() == ShiftedLognormal)
         return blackFormulaVolDerivative(strike,atmLevel(),
                                          sqrt(variance(strike)),
                                          exerciseTime(),discount,shift())*0.01;
     else
         QL_FAIL("vega for normal smilesection not yet implemented");
 }
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 KahaleSmileSection::volatilityImpl(Rate strike) const {
     strike = std::max ( strike, QL_KAHALE_EPS );
     int i = index(strike);
     if(!interpolate_ && !(i==0 || i==(int) (rightIndex_-leftIndex_+1))) return source_->volatility(strike);
     Real c = cFunctions_[i]->operator()(strike);
     Real vol=0.0;
     try {
         vol = blackFormulaImpliedStdDev(Option::Call,strike,f_,c) / sqrt(exerciseTime());
     } catch(...) { }
     return vol;
 }
Example #8
0
void NoArbSabrSmileSection::init() {
    QL_REQUIRE(params_.size() >= 4,
               "sabr expects 4 parameters (alpha,beta,nu,rho) but ("
                   << params_.size() << ") given");
    QL_REQUIRE(forward_ > 0.0, "forward (" << forward_ << ") must be positive");
    QL_REQUIRE(
        shift_ == 0.0,
        "shift (" << shift_
                  << ") must be zero, other shifts are not implemented yet");
    model_ =
        boost::make_shared<NoArbSabrModel>(exerciseTime(), forward_, params_[0],
                                           params_[1], params_[2], params_[3]);
}
Example #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;
}
    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;
    }
 InterpolatedSmileSection<Interpolator>::InterpolatedSmileSection(
                        const Date& d,
                        const std::vector<Rate>& strikes,
                        const std::vector<Handle<Quote> >& stdDevHandles,
                        const Handle<Quote>& atmLevel,
                        const DayCounter& dc,
                        const Interpolator& interpolator,
                        const Date& referenceDate,
                        const Real shift)
 : SmileSection(d, dc, referenceDate, ShiftedLognormal, shift),
   exerciseTimeSquareRoot_(std::sqrt(exerciseTime())), strikes_(strikes),
   stdDevHandles_(stdDevHandles), atmLevel_(atmLevel), vols_(stdDevHandles.size())
 {
     for (Size i=0; i<stdDevHandles_.size(); ++i)
         LazyObject::registerWith(stdDevHandles_[i]);
     LazyObject::registerWith(atmLevel_);
     // check strikes!!!!!!!!!!!!!!!!!!!!
     interpolation_ = interpolator.interpolate(strikes_.begin(),
                                               strikes_.end(),
                                               vols_.begin());
 }
 InterpolatedSmileSection<Interpolator>::InterpolatedSmileSection(
                            Time timeToExpiry,
                            const std::vector<Rate>& strikes,
                            const std::vector<Handle<Quote> >& stdDevHandles,
                            const Handle<Quote>& atmLevel,
                            const Interpolator& interpolator,
                            const DayCounter& dc,
                            const VolatilityType type,
                            const Real shift)
 : SmileSection(timeToExpiry, dc, type, shift),
   exerciseTimeSquareRoot_(std::sqrt(exerciseTime())), strikes_(strikes),
   stdDevHandles_(stdDevHandles), atmLevel_(atmLevel),
   vols_(stdDevHandles.size())
 {
     for (Size i=0; i<stdDevHandles_.size(); ++i)
         LazyObject::registerWith(stdDevHandles_[i]);
     LazyObject::registerWith(atmLevel_);
     // check strikes!!!!!!!!!!!!!!!!!!!!
     interpolation_ = interpolator.interpolate(strikes_.begin(),
                                               strikes_.end(),
                                               vols_.begin());
 }
 Real InterpolatedSmileSection<Interpolator>::varianceImpl(Real strike) const {
     calculate();
     Real v = interpolation_(strike, true);
     return v*v*exerciseTime();
 }
Example #14
0
 inline Real SmileSection::varianceImpl(Rate strike) const {
     Volatility v = volatilityImpl(strike);
     return v*v*exerciseTime();
 }
 Real SabrInterpolatedSmileSection::varianceImpl(Real strike) const {
     calculate();
     Real v = (*sabrInterpolation_)(strike, true);
     return v*v*exerciseTime();
 }
 Real SabrSmileSection::volatilityImpl(Rate strike) const {
    strike = std::max(0.00001,strike);
    return unsafeSabrVolatility(strike, forward_,
        exerciseTime(), alpha_, beta_, nu_, rho_);
 }
    SplineDensitySmileSection::SplineDensitySmileSection(
        const boost::shared_ptr<SmileSection> source, const Real atm,
        const Real lowerBound, const Real upperBound,
        const bool deleteArbitragePoints,
        const std::vector<Real> &moneynessGrid)
        : SmileSection(*source), source_(source),
          lowerBound_(lowerBound), upperBound_(upperBound) {

        adjustment_ = 1.0;

        ssutils_ = boost::shared_ptr<SmileSectionUtils>(new SmileSectionUtils(
            *source, moneynessGrid, atm, deleteArbitragePoints));

        std::pair<Size, Size> af = ssutils_->arbitragefreeIndices();

        Size leftIndex = af.first;
        Size rightIndex = af.second;
        
        f_ = ssutils_->atmLevel();

        const std::vector<Real> &strikes = ssutils_->strikeGrid();
        const std::vector<Real> &calls = ssutils_->callPrices();

        k_.clear();
        c_.clear();
        d_.clear();
        
        k_.push_back(lowerBound_);
        c_.push_back(f_-lowerBound_);
        d_.push_back(0.0);

        Real vol = 0.10; // start with a lognormal density
        Real mu = std::log(f_) - vol*vol*exerciseTime()/2.0;
        NormalDistribution norm(mu,vol*sqrt(exerciseTime()));


        std::vector<Real> initialv;

        for(Size i=leftIndex; i<=rightIndex; i++) {
            if( strikes[i] > lowerBound_ && strikes[i] < upperBound_ ) {
                k_.push_back(strikes[i]);
                c_.push_back(calls[i]);
                d_.push_back( norm(std::log(strikes[i]))/ strikes[i] );
                initialv.push_back(std::sqrt(d_.back()));
            }
        }

        Array initial(initialv.begin(),initialv.end());

        k_.push_back(upperBound_);
        c_.push_back(0.0);
        d_.push_back(0.0);


        // density_ = boost::shared_ptr<CubicInterpolation>(new CubicInterpolation(k_.begin(), k_.end(),
        //                                                                    d_.begin(), CubicInterpolation::Spline, true,
        //                                                                    CubicInterpolation::SecondDerivative, 0.0,
        //                                                                    CubicInterpolation::SecondDerivative, 0.0));

        density_ = boost::shared_ptr<LinearInterpolation>(new LinearInterpolation(k_.begin(), k_.end(), d_.begin()));
        
        // // global calibration
        // SplineDensityCostFunction cost(this);
        // NoConstraint constraint;
        // Problem p(cost,constraint,initial);

   		// LevenbergMarquardt lm;
		// //Simplex lm(0.01);
		// //BFGS lm;
		// EndCriteria ec(5000,100,1e-16,1e-16,1e-16);

		// EndCriteria::Type ret = lm.minimize(p,ec);
		// QL_REQUIRE(ret!=EndCriteria::MaxIterations,"Optimizer returns maxiterations");

		// Array res = p.currentValue();
        // setDensity(res); // just to make really sure, we are at the optimal point

        // iterative calibration
        // for(Size i=1; i<k_.size()-1; i++) {
        //     SplineDensityCostFunction2 cost(this,i);
        //     NoConstraint constraint;
        //     Array initial2(1,initial[i-1]);
        //     Problem p(cost,constraint,initial2);

        //     LevenbergMarquardt lm;
        //     //Simplex lm(0.01);
        //     //BFGS lm;
        //     EndCriteria ec(5000,100,1e-35,1e-35,1e-35);

        //     EndCriteria::Type ret = lm.minimize(p,ec);
        //     QL_REQUIRE(ret!=EndCriteria::MaxIterations,"Optimizer returns maxiterations");

        //     Array res = p.currentValue();
        //     setDensity(res[0],i); // just to make really sure, we are at the optimal point
        // }

        update();

    }