示例#1
0
    const Handle<LocalVolTermStructure>&
    GeneralizedBlackScholesProcess::localVolatility() const {
        if (hasExternalLocalVol_)
            return externalLocalVolTS_;

        if (!updated_) {
            isStrikeIndependent_=true;

            // constant Black vol?
            ext::shared_ptr<BlackConstantVol> constVol =
                ext::dynamic_pointer_cast<BlackConstantVol>(
                                                          *blackVolatility());
            if (constVol) {
                // ok, the local vol is constant too.
                localVolatility_.linkTo(ext::make_shared<LocalConstantVol>(
                    constVol->referenceDate(),
                    constVol->blackVol(0.0, x0_->value()),
                    constVol->dayCounter()));
                updated_ = true;
                return localVolatility_;
            }

            // ok, so it's not constant. Maybe it's strike-independent?
            ext::shared_ptr<BlackVarianceCurve> volCurve =
                ext::dynamic_pointer_cast<BlackVarianceCurve>(
                                                          *blackVolatility());
            if (volCurve) {
                // ok, we can use the optimized algorithm
                localVolatility_.linkTo(ext::make_shared<LocalVolCurve>(
                    Handle<BlackVarianceCurve>(volCurve)));
                updated_ = true;
                return localVolatility_;
            }

            // ok, so it's strike-dependent. Never mind.
            localVolatility_.linkTo(
                ext::make_shared<LocalVolSurface>(blackVolatility_, riskFreeRate_,
                                                    dividendYield_, x0_->value()));
            updated_ = true;
            isStrikeIndependent_ = false;
            return localVolatility_;

        } else {
            return localVolatility_;
        }
    }
示例#2
0
    void ForwardVanillaEngine<Engine>::setup() const {

        ext::shared_ptr<StrikedTypePayoff> argumentsPayoff =
            ext::dynamic_pointer_cast<StrikedTypePayoff>(
                this->arguments_.payoff);
        QL_REQUIRE(argumentsPayoff, "wrong payoff given");

        ext::shared_ptr<StrikedTypePayoff> payoff(
                   new PlainVanillaPayoff(argumentsPayoff->optionType(),
                                          this->arguments_.moneyness *
                                          process_->x0()));

        // maybe the forward value is "better", in some fashion
        // the right level is needed in order to interpolate
        // the vol
        Handle<Quote> spot = process_->stateVariable();
        QL_REQUIRE(spot->value() >= 0.0, "negative or null underlting given");
        Handle<YieldTermStructure> dividendYield(
            ext::shared_ptr<YieldTermStructure>(
               new ImpliedTermStructure(process_->dividendYield(),
                                        this->arguments_.resetDate)));
        Handle<YieldTermStructure> riskFreeRate(
            ext::shared_ptr<YieldTermStructure>(
               new ImpliedTermStructure(process_->riskFreeRate(),
                                        this->arguments_.resetDate)));
        // The following approach is ok if the vol is at most
        // time dependant. It is plain wrong if it is asset dependant.
        // In the latter case the right solution would be stochastic
        // volatility or at least local volatility (which unfortunately
        // implies an unrealistic time-decreasing smile)
        Handle<BlackVolTermStructure> blackVolatility(
            ext::shared_ptr<BlackVolTermStructure>(
                new ImpliedVolTermStructure(process_->blackVolatility(),
                                            this->arguments_.resetDate)));

        ext::shared_ptr<GeneralizedBlackScholesProcess> fwdProcess(
                       new GeneralizedBlackScholesProcess(spot, dividendYield,
                                                          riskFreeRate,
                                                          blackVolatility));

        originalEngine_ = ext::shared_ptr<Engine>(new Engine(fwdProcess));
        originalEngine_->reset();

        originalArguments_ =
            dynamic_cast<VanillaOption::arguments*>(
                                             originalEngine_->getArguments());
        QL_REQUIRE(originalArguments_, "wrong engine type");
        originalResults_ =
            dynamic_cast<const VanillaOption::results*>(
                                               originalEngine_->getResults());
        QL_REQUIRE(originalResults_, "wrong engine type");

        originalArguments_->payoff = payoff;
        originalArguments_->exercise = this->arguments_.exercise;

        originalArguments_->validate();
    }
示例#3
0
 const Handle<LocalVolTermStructure>& VarianceGammaProcess::localVolatility() const{
     
     if(!updated_)
     {
         // Constant Volatility
         boost::shared_ptr<BlackConstantVol> constant = boost::dynamic_pointer_cast<BlackConstantVol>(*blackVolatility());
         if(constant)
         {
             localVolatility_.linkTo(boost::shared_ptr<LocalVolTermStructure>(new LocalConstantVol(constant->referenceDate(), constant->blackVol(0.0, s0_->value()), constant->dayCounter())));
             
             updated_ = true;
             return localVolatility_;
         }
         boost::shared_ptr<BlackVarianceCurve> volCurve = boost::dynamic_pointer_cast<BlackVarianceCurve>(*blackVolatility());
         if(volCurve)
         {
             localVolatility_.linkTo(boost::shared_ptr<LocalVolTermStructure>(new LocalVolCurve(Handle<BlackVarianceCurve>(volCurve))));
             
             updated_ = true;
             return localVolatility_;
         }
         // ok, so it's strike-dependent. Never mind.
         localVolatility_.linkTo(boost::shared_ptr<LocalVolTermStructure>(new LocalVolSurface(blackVolatility_,riskFreeRate_,dividendYield_, s0_->value())));
         
         updated_ = true;
         return localVolatility_;
     }
     else
     {
         return localVolatility_;
     }
 }