boost::shared_ptr<FdmStepConditionComposite> FdmStepConditionComposite::vanillaComposite( const DividendSchedule& cashFlow, const boost::shared_ptr<Exercise>& exercise, const boost::shared_ptr<FdmMesher>& mesher, const boost::shared_ptr<FdmInnerValueCalculator>& calculator, const Date& refDate, const DayCounter& dayCounter) { std::list<std::vector<Time> > stoppingTimes; std::list<boost::shared_ptr<StepCondition<Array> > > stepConditions; if(!cashFlow.empty()) { boost::shared_ptr<FdmDividendHandler> dividendCondition( new FdmDividendHandler(cashFlow, mesher, refDate, dayCounter, 0)); stepConditions.push_back(dividendCondition); stoppingTimes.push_back(dividendCondition->dividendTimes()); } QL_REQUIRE( exercise->type() == Exercise::American || exercise->type() == Exercise::European || exercise->type() == Exercise::Bermudan, "exercise type is not supported"); if (exercise->type() == Exercise::American) { stepConditions.push_back(boost::shared_ptr<StepCondition<Array> >( new FdmAmericanStepCondition(mesher,calculator))); } else if (exercise->type() == Exercise::Bermudan) { boost::shared_ptr<FdmBermudanStepCondition> bermudanCondition( new FdmBermudanStepCondition(exercise->dates(), refDate, dayCounter, mesher, calculator)); stepConditions.push_back(bermudanCondition); stoppingTimes.push_back(bermudanCondition->exerciseTimes()); } return boost::shared_ptr<FdmStepConditionComposite>( new FdmStepConditionComposite(stoppingTimes, stepConditions)); }
void FdBlackScholesVanillaEngine::calculate() const { // 1. Layout std::vector<Size> dim; dim.push_back(xGrid_); const boost::shared_ptr<FdmLinearOpLayout> layout( new FdmLinearOpLayout(dim)); const boost::shared_ptr<StrikedTypePayoff> payoff = boost::dynamic_pointer_cast<StrikedTypePayoff>(arguments_.payoff); // 2. Mesher const Time maturity = process_->time(arguments_.exercise->lastDate()); const boost::shared_ptr<Fdm1dMesher> equityMesher( new FdmBlackScholesMesher( xGrid_, process_, maturity, payoff->strike(), Null<Real>(), Null<Real>(), 0.0001, 1.5, std::pair<Real, Real>(payoff->strike(), 0.1))); std::vector<boost::shared_ptr<Fdm1dMesher> > meshers; meshers.push_back(equityMesher); boost::shared_ptr<FdmMesher> mesher ( new FdmMesherComposite(layout, meshers)); // 3. Calculator boost::shared_ptr<FdmInnerValueCalculator> calculator( new FdmLogInnerValue(payoff, mesher, 0)); // 4. Step conditions std::list<boost::shared_ptr<StepCondition<Array> > > stepConditions; std::list<std::vector<Time> > stoppingTimes; // 4.1 Step condition if discrete dividends if(!arguments_.cashFlow.empty()) { boost::shared_ptr<FdmDividendHandler> dividendCondition( new FdmDividendHandler(arguments_.cashFlow, mesher, process_->riskFreeRate()->referenceDate(), process_->riskFreeRate()->dayCounter(), 0)); stepConditions.push_back(dividendCondition); stoppingTimes.push_back(dividendCondition->dividendTimes()); } // 4.2 Step condition if american or bermudan exercise QL_REQUIRE( arguments_.exercise->type() == Exercise::American || arguments_.exercise->type() == Exercise::European || arguments_.exercise->type() == Exercise::Bermudan, "exercise type is not supported"); if (arguments_.exercise->type() == Exercise::American) { stepConditions.push_back(boost::shared_ptr<StepCondition<Array> >( new FdmAmericanStepCondition(mesher,calculator))); } else if (arguments_.exercise->type() == Exercise::Bermudan) { boost::shared_ptr<FdmBermudanStepCondition> bermudanCondition( new FdmBermudanStepCondition( arguments_.exercise->dates(), process_->riskFreeRate()->referenceDate(), process_->riskFreeRate()->dayCounter(), mesher, calculator)); stepConditions.push_back(bermudanCondition); stoppingTimes.push_back(bermudanCondition->exerciseTimes()); } boost::shared_ptr<FdmStepConditionComposite> conditions( new FdmStepConditionComposite(stoppingTimes, stepConditions)); // 5. Boundary conditions std::vector<boost::shared_ptr<FdmDirichletBoundary> > boundaries; // 6. Solver boost::shared_ptr<FdmBlackScholesSolver> solver( new FdmBlackScholesSolver( Handle<GeneralizedBlackScholesProcess>(process_), mesher, boundaries, conditions, calculator, payoff->strike(), maturity, tGrid_, dampingSteps_, schemeDesc_, localVol_, illegalLocalVolOverwrite_)); const Real spot = process_->x0(); results_.value = solver->valueAt(spot); results_.delta = solver->deltaAt(spot); results_.gamma = solver->gammaAt(spot); results_.theta = solver->thetaAt(spot); }
void Fd2dBlackScholesVanillaEngine::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)); const boost::shared_ptr<BasketPayoff> payoff = boost::dynamic_pointer_cast<BasketPayoff>(arguments_.payoff); // 2. Mesher const Time maturity = p1_->time(arguments_.exercise->lastDate()); const boost::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 boost::shared_ptr<Fdm1dMesher> em2( new FdmBlackScholesMesher( xGrid_, p2_, maturity, p2_->x0(), Null<Real>(), Null<Real>(), 0.0001, 1.5, std::pair<Real, Real>(p2_->x0(), 0.1))); std::vector<boost::shared_ptr<Fdm1dMesher> > meshers; meshers.push_back(em1); meshers.push_back(em2); boost::shared_ptr<FdmMesher> mesher ( new FdmMesherComposite(layout, meshers)); // 3. Calculator boost::shared_ptr<FdmInnerValueCalculator> calculator( new FdmLogBasketInnerValue(payoff, mesher)); // 4. Step conditions std::list<boost::shared_ptr<StepCondition<Array> > > stepConditions; std::list<std::vector<Time> > stoppingTimes; // 4.2 Step condition if american or bermudan exercise QL_REQUIRE( arguments_.exercise->type() == Exercise::American || arguments_.exercise->type() == Exercise::European || arguments_.exercise->type() == Exercise::Bermudan, "exercise type is not supported"); if (arguments_.exercise->type() == Exercise::American) { stepConditions.push_back(boost::shared_ptr<StepCondition<Array> >( new FdmAmericanStepCondition(mesher,calculator))); } else if (arguments_.exercise->type() == Exercise::Bermudan) { boost::shared_ptr<FdmBermudanStepCondition> bermudanCondition( new FdmBermudanStepCondition( arguments_.exercise->dates(), p1_->riskFreeRate()->referenceDate(), p1_->riskFreeRate()->dayCounter(), mesher, calculator)); stepConditions.push_back(bermudanCondition); stoppingTimes.push_back(bermudanCondition->exerciseTimes()); } boost::shared_ptr<FdmStepConditionComposite> conditions( new FdmStepConditionComposite(stoppingTimes, stepConditions)); // 5. Boundary conditions std::vector<boost::shared_ptr<FdmDirichletBoundary> > boundaries; // 6. Solver boost::shared_ptr<Fdm2dBlackScholesSolver> solver( new Fdm2dBlackScholesSolver( Handle<GeneralizedBlackScholesProcess>(p1_), Handle<GeneralizedBlackScholesProcess>(p2_), correlation_, mesher, boundaries, conditions, calculator, maturity, tGrid_, dampingSteps_, schemeDesc_)); const Real x = p1_->x0(); const Real y = p2_->x0(); results_.value = solver->valueAt(x, y); results_.theta = solver->thetaAt(x, y); }