void Fd2dBlackScholesVanillaEngine::calculate() const { // 1. Payoff const ext::shared_ptr<BasketPayoff> payoff = ext::dynamic_pointer_cast<BasketPayoff>(arguments_.payoff); // 2. Mesher const Time maturity = p1_->time(arguments_.exercise->lastDate()); const ext::shared_ptr<Fdm1dMesher> em1( new FdmBlackScholesMesher( xGrid_, p1_, maturity, p1_->x0(), Null<Real>(), Null<Real>(), 0.0001, 1.5, std::pair<Real, Real>(p1_->x0(), 0.1))); const ext::shared_ptr<Fdm1dMesher> em2( new FdmBlackScholesMesher( yGrid_, p2_, maturity, p2_->x0(), Null<Real>(), Null<Real>(), 0.0001, 1.5, std::pair<Real, Real>(p2_->x0(), 0.1))); const ext::shared_ptr<FdmMesher> mesher ( new FdmMesherComposite(em1, em2)); // 3. Calculator const ext::shared_ptr<FdmInnerValueCalculator> calculator( new FdmLogBasketInnerValue(payoff, mesher)); // 4. Step conditions const ext::shared_ptr<FdmStepConditionComposite> conditions = FdmStepConditionComposite::vanillaComposite( DividendSchedule(), arguments_.exercise, mesher, calculator, p1_->riskFreeRate()->referenceDate(), p1_->riskFreeRate()->dayCounter()); // 5. Boundary conditions const FdmBoundaryConditionSet boundaries; // 6. Solver const FdmSolverDesc solverDesc = { mesher, boundaries, conditions, calculator, maturity, tGrid_, dampingSteps_ }; ext::shared_ptr<Fdm2dBlackScholesSolver> solver( new Fdm2dBlackScholesSolver( Handle<GeneralizedBlackScholesProcess>(p1_), Handle<GeneralizedBlackScholesProcess>(p2_), correlation_, solverDesc, schemeDesc_, localVol_, illegalLocalVolOverwrite_)); const Real x = p1_->x0(); const Real y = p2_->x0(); results_.value = solver->valueAt(x, y); results_.delta = solver->deltaXat(x, y) + solver->deltaYat(x, y); results_.gamma = solver->gammaXat(x, y) + solver->gammaYat(x, y) + 2*solver->gammaXYat(x, y); results_.theta = solver->thetaAt(x, y); }
void FdExtOUJumpVanillaEngine::calculate() const { // 1. Layout std::vector<Size> dim; dim.push_back(xGrid_); dim.push_back(yGrid_); const boost::shared_ptr<FdmLinearOpLayout> layout( new FdmLinearOpLayout(dim)); // 2. Mesher const Time maturity = rTS_->dayCounter().yearFraction(rTS_->referenceDate(), arguments_.exercise->lastDate()); const boost::shared_ptr<StochasticProcess1D> ouProcess( process_->getExtendedOrnsteinUhlenbeckProcess()); const boost::shared_ptr<Fdm1dMesher> xMesher( new FdmSimpleProcess1dMesher(xGrid_, ouProcess,maturity)); const boost::shared_ptr<Fdm1dMesher> yMesher( new ExponentialJump1dMesher(yGrid_, process_->beta(), process_->jumpIntensity(), process_->eta())); std::vector<boost::shared_ptr<Fdm1dMesher> > meshers; meshers.push_back(xMesher); meshers.push_back(yMesher); const boost::shared_ptr<FdmMesher> mesher ( new FdmMesherComposite(layout, meshers)); // 3. Calculator const boost::shared_ptr<FdmInnerValueCalculator> calculator( new FdmExtOUJumpModelInnerValue(arguments_.payoff, mesher)); // 4. Step conditions const boost::shared_ptr<FdmStepConditionComposite> conditions = FdmStepConditionComposite::vanillaComposite( DividendSchedule(), arguments_.exercise, mesher, calculator, rTS_->referenceDate(), rTS_->dayCounter()); // 5. Boundary conditions const std::vector<boost::shared_ptr<FdmDirichletBoundary> > boundaries; // 6. set-up solver FdmSolverDesc solverDesc = { mesher, boundaries, conditions, calculator, maturity, tGrid_, 0 }; const boost::shared_ptr<FdmExtOUJumpSolver> solver( new FdmExtOUJumpSolver(Handle<ExtOUWithJumpsProcess>(process_), rTS_, solverDesc, schemeDesc_)); const Real x = process_->initialValues()[0]; const Real y = process_->initialValues()[1]; results_.value = solver->valueAt(x, y); }
void FdHullWhiteSwaptionEngine::calculate() const { const Handle<YieldTermStructure> ts = model_->termStructure(); // 1. Layout const boost::shared_ptr<FdmLinearOpLayout> layout( new FdmLinearOpLayout(std::vector<Size>(1u, xGrid_))); // 2. Mesher const DayCounter dc = ts->dayCounter(); const Date referenceDate = ts->referenceDate(); const Time maturity = dc.yearFraction(referenceDate, arguments_.exercise->lastDate()); const boost::shared_ptr<OrnsteinUhlenbeckProcess> process( new OrnsteinUhlenbeckProcess(model_->a(), model_->sigma())); const boost::shared_ptr<Fdm1dMesher> shortRateMesher( new FdmSimpleProcess1dMesher(xGrid_, process, maturity,1,invEps_)); const boost::shared_ptr<FdmMesher> mesher( new FdmMesherComposite(layout, std::vector<boost::shared_ptr<Fdm1dMesher> >( 1, shortRateMesher))); // 3. Inner Value Calculator const std::vector<Date>& exerciseDates = arguments_.exercise->dates(); std::map<Time, Date> t2d; for (Size i=0; i < exerciseDates.size(); ++i) { const Time t = dc.yearFraction(referenceDate, exerciseDates[i]); QL_REQUIRE(t >= 0, "exercise dates must not contain past date"); t2d[t] = exerciseDates[i]; } const Handle<YieldTermStructure> disTs = model_->termStructure(); const Handle<YieldTermStructure> fwdTs = arguments_.swap->iborIndex()->forwardingTermStructure(); QL_REQUIRE(fwdTs->dayCounter() == disTs->dayCounter(), "day counter of forward and discount curve must match"); QL_REQUIRE(fwdTs->referenceDate() == disTs->referenceDate(), "reference date of forward and discount curve must match"); const boost::shared_ptr<HullWhite> fwdModel( new HullWhite(fwdTs, model_->a(), model_->sigma())); const boost::shared_ptr<FdmInnerValueCalculator> calculator( new FdmAffineModelSwapInnerValue<HullWhite>( model_.currentLink(), fwdModel, arguments_.swap, t2d, mesher, 0)); // 4. Step conditions const boost::shared_ptr<FdmStepConditionComposite> conditions = FdmStepConditionComposite::vanillaComposite( DividendSchedule(), arguments_.exercise, mesher, calculator, referenceDate, dc); // 5. Boundary conditions const std::vector<boost::shared_ptr<FdmDirichletBoundary> > boundaries; // 6. Solver FdmSolverDesc solverDesc = { mesher, boundaries, conditions, calculator, maturity, tGrid_, dampingSteps_ }; const boost::scoped_ptr<FdmHullWhiteSolver> solver( new FdmHullWhiteSolver(model_, solverDesc, schemeDesc_)); results_.value = solver->valueAt(0.0); }