Exemplo n.º 1
0
    FdmHestonEquityPart::FdmHestonEquityPart(
        const boost::shared_ptr<FdmMesher>& mesher,
        const boost::shared_ptr<YieldTermStructure>& rTS,
        const boost::shared_ptr<YieldTermStructure>& qTS,
        const boost::shared_ptr<FdmQuantoHelper>& quantoHelper,
        const boost::shared_ptr<LocalVolTermStructure>& leverageFct)
    : varianceValues_(0.5*mesher->locations(1)),
      dxMap_ (FirstDerivativeOp(0, mesher)),
      dxxMap_(SecondDerivativeOp(0, mesher).mult(0.5*mesher->locations(1))),
      mapT_  (0, mesher),
      mesher_(mesher),
      rTS_(rTS),
      qTS_(qTS),
      quantoHelper_(quantoHelper),
      leverageFct_(leverageFct) {

        // on the boundary s_min and s_max the second derivative
        // d^2V/dS^2 is zero and due to Ito's Lemma the variance term
        // in the drift should vanish.
        boost::shared_ptr<FdmLinearOpLayout> layout = mesher_->layout();
        FdmLinearOpIterator endIter = layout->end();
        for (FdmLinearOpIterator iter = layout->begin(); iter != endIter;
            ++iter) {
            if (   iter.coordinates()[0] == 0
                || iter.coordinates()[0] == layout->dim()[0]-1) {
                varianceValues_[iter.index()] = 0.0;
            }
        }
        volatilityValues_ = Sqrt(2*varianceValues_);
    }
    FdmHestonHullWhiteOp::FdmHestonHullWhiteOp(
                    const boost::shared_ptr<FdmMesher>& mesher,
                    const boost::shared_ptr<HestonProcess>& hestonProcess,
                    const boost::shared_ptr<HullWhiteProcess>& hwProcess,
                    Real equityShortRateCorrelation)
    : v0_(hestonProcess->v0()),
      kappa_(hestonProcess->kappa()),
      theta_(hestonProcess->theta()),
      sigma_(hestonProcess->sigma()),
      rho_(hestonProcess->rho()),
      hwModel_(new HullWhite(hestonProcess->riskFreeRate(),
                             hwProcess->a(), hwProcess->sigma())),
      hestonCorrMap_(SecondOrderMixedDerivativeOp(0, 1, mesher)
                     .mult(rho_*sigma_*mesher->locations(1))),
      equityIrCorrMap_(SecondOrderMixedDerivativeOp(0, 2, mesher)
                       .mult(Sqrt(mesher->locations(1))
                              * hwProcess->sigma()
                              * equityShortRateCorrelation)),
      dyMap_(SecondDerivativeOp(1u, mesher)
              .mult(0.5*sigma_*sigma_*mesher->locations(1))
            .add(FirstDerivativeOp(1, mesher)
              .mult(kappa_*(theta_ - mesher->locations(1))))),
      dxMap_(mesher, hwModel_, hestonProcess->dividendYield().currentLink()),
      hullWhiteOp_(mesher, hwModel_, 2) {

        QL_REQUIRE(  equityShortRateCorrelation*equityShortRateCorrelation
                   + hestonProcess->rho()*hestonProcess->rho() <= 1.0,
                   "correlation matrix has negative eigenvalues");
    }
Exemplo n.º 3
0
    FdmZabrUnderlyingPart::FdmZabrUnderlyingPart(const boost::shared_ptr<FdmMesher>& mesher, const Real beta, const Real nu, const Real rho, const Real gamma) :
	  forwardValues_(mesher->locations(0)),
      volatilityValues_(mesher->locations(1)),
      mapT_  (SecondDerivativeOp(0, mesher).mult(0.5*volatilityValues_*volatilityValues_*Pow(Abs(forwardValues_),2.0*beta))),
      mesher_(mesher) {
        
    }
    FdmHestonHullWhiteEquityPart::FdmHestonHullWhiteEquityPart(
        const boost::shared_ptr<FdmMesher>& mesher,
        const boost::shared_ptr<HullWhite>& hwModel,
        const boost::shared_ptr<YieldTermStructure>& qTS)
    : x_(mesher->locations(2)),
      varianceValues_(0.5*mesher->locations(1)),
      dxMap_ (FirstDerivativeOp(0, mesher)),
      dxxMap_(SecondDerivativeOp(0, mesher).mult(0.5*mesher->locations(1))),
      mapT_   (0, mesher),
      hwModel_(hwModel),
      mesher_ (mesher),
      qTS_(qTS) {

        // on the boundary s_min and s_max the second derivative
        // d²V/dS² is zero and due to Ito's Lemma the variance term
        // in the drift should vanish.
        const boost::shared_ptr<FdmLinearOpLayout> layout = mesher_->layout();
        const FdmLinearOpIterator endIter = layout->end();
        for (FdmLinearOpIterator iter = layout->begin(); iter != endIter;
            ++iter) {
            if (   iter.coordinates()[0] == 0
                || iter.coordinates()[0] == layout->dim()[0]-1) {
                varianceValues_[iter.index()] = 0.0;
            }
        }
        volatilityValues_ = Sqrt(2*varianceValues_);
    }
 FdmHestonHullWhiteVariancePart::FdmHestonHullWhiteVariancePart(
     const boost::shared_ptr<FdmMesher>& mesher,
     Real sigma, Real kappa, Real theta)
 : dyMap_(SecondDerivativeOp(1, mesher)
            .mult(0.5*sigma*sigma*mesher->locations(1))
          .add(FirstDerivativeOp(1, mesher)
            .mult(kappa*(theta - mesher->locations(1))))) {
 }
Exemplo n.º 6
0
FdmZabrVolatilityPart::FdmZabrVolatilityPart(
    const ext::shared_ptr<FdmMesher> &mesher, const Real beta, const Real nu,
    const Real rho, const Real gamma)
    : volatilityValues_(mesher->locations(1)),
      forwardValues_(mesher->locations(0)),
      mapT_(SecondDerivativeOp(1, mesher).mult(
          0.5 * nu * nu * Pow(volatilityValues_, 2.0 * gamma))),
      mesher_(mesher) {}
Exemplo n.º 7
0
 FdmHestonVariancePart::FdmHestonVariancePart(
     const boost::shared_ptr<FdmMesher>& mesher,
     const boost::shared_ptr<YieldTermStructure>& rTS,
     Real sigma, Real kappa, Real theta)
 : dyMap_(SecondDerivativeOp(1, mesher)
             .mult(0.5*sigma*sigma*mesher->locations(1))
          .add(FirstDerivativeOp(1, mesher)
               .mult(kappa*(theta - mesher->locations(1))))),
   mapT_(1, mesher),
   rTS_(rTS) {
 }
 FdmHestonHullWhiteRatesPart::FdmHestonHullWhiteRatesPart(
     const boost::shared_ptr<FdmMesher>& mesher,
     const boost::shared_ptr<HullWhiteProcess>& hwProcess)
 : rates_(mesher->locations(2)),
   dzMap_(FirstDerivativeOp(2, mesher)),
   dzzMap_(SecondDerivativeOp(2, mesher)
              .mult(0.5*hwProcess->sigma()*hwProcess->sigma()
                    *Array(mesher->layout()->size(), 1.))
              .add(-mesher->locations(2))),
   mapT_(2, mesher),
   hwProcess_(hwProcess) {
 }
Exemplo n.º 9
0
 FdmHullWhiteOp::FdmHullWhiteOp(
     const boost::shared_ptr<FdmMesher>& mesher,
     const boost::shared_ptr<HullWhite>& model,
     Size direction)
 : direction_(direction),
   x_(mesher->locations(direction)),
   dzMap_(FirstDerivativeOp(direction, mesher).mult(-x_*model->a()).add(
             SecondDerivativeOp(direction, mesher)
                 .mult(0.5*model->sigma()*model->sigma()
                       *Array(mesher->layout()->size(), 1.0)))),
   mapT_(direction, mesher),
   model_(model) {
 }
Exemplo n.º 10
0
    FdmHestonFwdOp::FdmHestonFwdOp(
            const boost::shared_ptr<FdmMesher>& mesher,
            const boost::shared_ptr<HestonProcess>& process,
            FdmSquareRootFwdOp::TransformationType type)
    : type_ (type),
      kappa_(process->kappa()),
      theta_(process->theta()),
      sigma_(process->sigma()),
      rho_  (process->rho()),
      v0_   (process->v0()),
      rTS_  (process->riskFreeRate().currentLink()),
      qTS_  (process->dividendYield().currentLink()),
      varianceValues_(0.5*mesher->locations(1)),
      dxMap_ (new FirstDerivativeOp(0, mesher)),
      dxxMap_(new ModTripleBandLinearOp(TripleBandLinearOp(
          SecondDerivativeOp(0, mesher).mult(0.5*mesher->locations(1))))),
      mapX_  (new TripleBandLinearOp(0, mesher)),
      mapY_  (new FdmSquareRootFwdOp(mesher,kappa_,theta_,sigma_, 1, type)),
      correlation_(new NinePointLinearOp(
          SecondOrderMixedDerivativeOp(0, 1, mesher)
              .mult(rho_*sigma_*mesher->locations(1))))
    {
        const boost::shared_ptr<FdmLinearOpLayout> layout = mesher->layout();

        if (type_ == FdmSquareRootFwdOp::Plain) {
            // zero flux boundary condition
            const Size n = layout->dim()[1];
            const Real alpha = 2*rho_*mapY_->v(0)/sigma_*mapY_->f0();
            const Real beta  = 2*rho_*mapY_->v(n)/sigma_*mapY_->f1();
            ModTripleBandLinearOp fDx(FirstDerivativeOp(0, mesher));

            const FdmLinearOpIterator endIter = layout->end();
            for (FdmLinearOpIterator iter = layout->begin(); iter != endIter;
                    ++iter) {
                if (iter.coordinates()[1] == 0) {
                    const Size idx = iter.index();

                    dxxMap_->upper()[idx] += alpha*fDx.upper()[idx];
                    dxxMap_->diag()[idx]  += alpha*fDx.diag()[idx];
                    dxxMap_->lower()[idx] += alpha*fDx.lower()[idx];
                }
                else if (iter.coordinates()[1] == n-1) {
                    const Size idx = iter.index();

                    dxxMap_->upper()[idx] += beta*fDx.upper()[idx];
                    dxxMap_->diag()[idx]  += beta*fDx.diag()[idx];
                    dxxMap_->lower()[idx] += beta*fDx.lower()[idx];
                }
            }
        }
    }
Exemplo n.º 11
0
 FdmG2Op::FdmG2Op(
     const boost::shared_ptr<FdmMesher>& mesher,
     const boost::shared_ptr<G2>& model,
     Size direction1, Size direction2)
 : direction1_(direction1),
   direction2_(direction2),
   x_(mesher->locations(direction1)),
   y_(mesher->locations(direction2)),
   dxMap_(FirstDerivativeOp(direction1, mesher).mult(-x_*model->a()).add(
             SecondDerivativeOp(direction1, mesher)
                 .mult(0.5*model->sigma()*model->sigma()
                       *Array(mesher->layout()->size(), 1.0)))),
   dyMap_(FirstDerivativeOp(direction2, mesher).mult(-y_*model->b()).add(
             SecondDerivativeOp(direction2, mesher)
                 .mult(0.5*model->eta()*model->eta()
                       *Array(mesher->layout()->size(), 1.0)))),
   corrMap_(SecondOrderMixedDerivativeOp(direction1, direction2, mesher)
           .mult(Array(mesher->layout()->size(),
                       model->rho()*model->sigma()*model->eta()))),
   mapX_(direction1, mesher),
   mapY_(direction2, mesher),
   model_(model) {
 }
 FdmExtendedOrnsteinUhlenbackOp::FdmExtendedOrnsteinUhlenbackOp(
         const boost::shared_ptr<FdmMesher>& mesher,
         const boost::shared_ptr<ExtendedOrnsteinUhlenbeckProcess>& process,
         const boost::shared_ptr<YieldTermStructure>& rTS,
         const FdmBoundaryConditionSet& bcSet,
         Size direction)
 : mesher_   (mesher),
   process_  (process),
   rTS_      (rTS),
   bcSet_    (bcSet),
   direction_(direction),
   x_        (mesher->locations(direction)),
   dxMap_    (direction, mesher),
   dxxMap_   (SecondDerivativeOp(direction, mesher)
             .mult(0.5*square<Real>()(process_->volatility())
               *Array(mesher->layout()->size(), 1.))),
   mapX_     (direction, mesher) {
 }
Exemplo n.º 13
0
FdmBlackScholesOp::FdmBlackScholesOp(
    const boost::shared_ptr<FdmMesher>& mesher,
    const boost::shared_ptr<GeneralizedBlackScholesProcess> & bsProcess,
    Real strike,
    bool localVol,
    Real illegalLocalVolOverwrite,
    Size direction)
    : mesher_(mesher),
      rTS_   (bsProcess->riskFreeRate().currentLink()),
      qTS_   (bsProcess->dividendYield().currentLink()),
      volTS_ (bsProcess->blackVolatility().currentLink()),
      localVol_((localVol) ? bsProcess->localVolatility().currentLink()
                : boost::shared_ptr<LocalVolTermStructure>()),
      x_     ((localVol) ? Array(Exp(mesher->locations(direction))) : Array()),
      dxMap_ (FirstDerivativeOp(direction, mesher)),
      dxxMap_(SecondDerivativeOp(direction, mesher)),
      mapT_  (direction, mesher),
      strike_(strike),
      illegalLocalVolOverwrite_(illegalLocalVolOverwrite),
      direction_(direction) {
}
Exemplo n.º 14
0
FdmDupire1dOp::FdmDupire1dOp(const boost::shared_ptr<FdmMesher> &mesher,
                             const Array &localVolatility)
    : mesher_(mesher), localVolatility_(localVolatility),
      mapT_(SecondDerivativeOp(0, mesher)
                .mult(0.5 * localVolatility * localVolatility)) {}